]> source.dussan.org Git - sonarqube.git/blob
8c89e6593e1ecee99477f7b9498b1056c84eb41a
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.application.cluster;
21
22 import com.hazelcast.core.HazelcastInstance;
23 import java.io.IOException;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.junit.rules.DisableOnDebug;
27 import org.junit.rules.ExpectedException;
28 import org.junit.rules.TestRule;
29 import org.junit.rules.Timeout;
30 import org.slf4j.Logger;
31 import org.sonar.application.AppStateListener;
32 import org.sonar.application.config.TestAppSettings;
33 import org.sonar.process.ProcessId;
34 import org.sonar.process.ProcessProperties;
35
36 import static org.assertj.core.api.Assertions.assertThat;
37 import static org.mockito.Matchers.anyString;
38 import static org.mockito.Matchers.eq;
39 import static org.mockito.Mockito.mock;
40 import static org.mockito.Mockito.timeout;
41 import static org.mockito.Mockito.verify;
42 import static org.sonar.application.cluster.HazelcastTestHelper.createHazelcastClient;
43 import static org.sonar.application.cluster.HazelcastTestHelper.newClusterSettings;
44 import static org.sonar.process.cluster.ClusterObjectKeys.SONARQUBE_VERSION;
45
46 public class AppStateClusterImplTest {
47
48   @Rule
49   public ExpectedException expectedException = ExpectedException.none();
50
51   @Rule
52   public TestRule safeGuard = new DisableOnDebug(Timeout.seconds(10));
53
54   @Test
55   public void instantiation_throws_ISE_if_cluster_mode_is_disabled() throws Exception {
56     TestAppSettings settings = new TestAppSettings();
57     settings.set(ProcessProperties.CLUSTER_ENABLED, "false");
58
59     expectedException.expect(IllegalStateException.class);
60     expectedException.expectMessage("Cluster is not enabled on this instance");
61
62     new AppStateClusterImpl(settings);
63   }
64
65   @Test
66   public void tryToLockWebLeader_returns_true_only_for_the_first_call() throws Exception {
67     TestAppSettings settings = newClusterSettings();
68
69     try (AppStateClusterImpl underTest = new AppStateClusterImpl(settings)) {
70       assertThat(underTest.tryToLockWebLeader()).isEqualTo(true);
71       assertThat(underTest.tryToLockWebLeader()).isEqualTo(false);
72     }
73   }
74
75   @Test
76   public void log_when_sonarqube_is_joining_a_cluster () throws IOException, InterruptedException, IllegalAccessException, NoSuchFieldException {
77     // Now launch an instance that try to be part of the hzInstance cluster
78     TestAppSettings settings = newClusterSettings();
79
80     Logger logger = mock(Logger.class);
81     AppStateClusterImpl.setLogger(logger);
82
83     try (AppStateClusterImpl appStateCluster = new AppStateClusterImpl(settings)) {
84       verify(logger).info(
85         eq("Joined the cluster [{}] that contains the following hosts : [{}]"),
86         eq("sonarqube"),
87         anyString()
88       );
89     }
90   }
91
92   @Test
93   public void test_listeners() throws InterruptedException {
94     AppStateListener listener = mock(AppStateListener.class);
95     try (AppStateClusterImpl underTest = new AppStateClusterImpl(newClusterSettings())) {
96       underTest.addListener(listener);
97
98       underTest.setOperational(ProcessId.ELASTICSEARCH);
99       verify(listener, timeout(20_000)).onAppStateOperational(ProcessId.ELASTICSEARCH);
100
101       assertThat(underTest.isOperational(ProcessId.ELASTICSEARCH, true)).isEqualTo(true);
102       assertThat(underTest.isOperational(ProcessId.APP, true)).isEqualTo(false);
103       assertThat(underTest.isOperational(ProcessId.WEB_SERVER, true)).isEqualTo(false);
104       assertThat(underTest.isOperational(ProcessId.COMPUTE_ENGINE, true)).isEqualTo(false);
105     }
106   }
107
108   @Test
109   public void registerSonarQubeVersion_publishes_version_on_first_call() {
110     TestAppSettings settings = newClusterSettings();
111
112     try (AppStateClusterImpl appStateCluster = new AppStateClusterImpl(settings)) {
113       appStateCluster.registerSonarQubeVersion("6.4.1.5");
114
115       HazelcastInstance hzInstance = createHazelcastClient(appStateCluster);
116       assertThat(hzInstance.getAtomicReference(SONARQUBE_VERSION).get())
117         .isNotNull()
118         .isInstanceOf(String.class)
119         .isEqualTo("6.4.1.5");
120     }
121   }
122
123   @Test
124   public void reset_throws_always_ISE() {
125     TestAppSettings settings = newClusterSettings();
126
127     try (AppStateClusterImpl appStateCluster = new AppStateClusterImpl(settings)) {
128       expectedException.expect(IllegalStateException.class);
129       expectedException.expectMessage("state reset is not supported in cluster mode");
130       appStateCluster.reset();
131     }
132   }
133
134   @Test
135   public void registerSonarQubeVersion_throws_ISE_if_initial_version_is_different() throws Exception {
136     // Now launch an instance that try to be part of the hzInstance cluster
137     TestAppSettings settings = newClusterSettings();
138
139     try (AppStateClusterImpl appStateCluster = new AppStateClusterImpl(settings)) {
140       // Register first version
141       appStateCluster.registerSonarQubeVersion("1.0.0");
142
143       expectedException.expect(IllegalStateException.class);
144       expectedException.expectMessage("The local version 2.0.0 is not the same as the cluster 1.0.0");
145
146       // Registering a second different version must trigger an exception
147       appStateCluster.registerSonarQubeVersion("2.0.0");
148     }
149   }
150 }