aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2017-08-28 13:24:15 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-09-13 15:50:48 +0200
commitd42dbb96cbcefb6f631fc9ddb52ec8755e26f19e (patch)
tree28b33a5ef3cf44fae7a99a200d95640c31c4692d
parentc7697d5366690c86f4a772c74fc621ee5d7b3edb (diff)
downloadsonarqube-d42dbb96cbcefb6f631fc9ddb52ec8755e26f19e.tar.gz
sonarqube-d42dbb96cbcefb6f631fc9ddb52ec8755e26f19e.zip
SONAR-9739 improve integration tests of api/system/status
-rw-r--r--tests/plugins/server-plugin/src/main/java/ServerPlugin.java2
-rw-r--r--tests/plugins/server-plugin/src/main/java/ServerStartupLock.java61
-rw-r--r--tests/src/test/java/org/sonarqube/tests/Category4Suite.java2
-rw-r--r--tests/src/test/java/org/sonarqube/tests/Category5Suite.java2
-rw-r--r--tests/src/test/java/org/sonarqube/tests/serverSystem/ServerSystemTest.java50
-rw-r--r--tests/src/test/java/org/sonarqube/tests/serverSystem/SystemInfoTest.java91
-rw-r--r--tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java140
7 files changed, 299 insertions, 49 deletions
diff --git a/tests/plugins/server-plugin/src/main/java/ServerPlugin.java b/tests/plugins/server-plugin/src/main/java/ServerPlugin.java
index 9ab0dd987de..c7f4c560a25 100644
--- a/tests/plugins/server-plugin/src/main/java/ServerPlugin.java
+++ b/tests/plugins/server-plugin/src/main/java/ServerPlugin.java
@@ -88,6 +88,6 @@ import static org.sonar.api.PropertyType.USER_LOGIN;
public class ServerPlugin extends SonarPlugin {
public List getExtensions() {
return Arrays.asList(
- StartupCrash.class, TempFolderExtension.class, PauseMetric.class, CePauseStep.class);
+ StartupCrash.class, ServerStartupLock.class, TempFolderExtension.class, PauseMetric.class, CePauseStep.class);
}
}
diff --git a/tests/plugins/server-plugin/src/main/java/ServerStartupLock.java b/tests/plugins/server-plugin/src/main/java/ServerStartupLock.java
new file mode 100644
index 00000000000..85aaef2213d
--- /dev/null
+++ b/tests/plugins/server-plugin/src/main/java/ServerStartupLock.java
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import java.io.File;
+import java.util.Optional;
+import org.sonar.api.Startable;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+@ServerSide
+public class ServerStartupLock implements Startable {
+
+ private final Configuration configuration;
+ private static final Logger LOGGER = Loggers.get(ServerStartupLock.class);
+
+ public ServerStartupLock(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ @Override
+ public void start() {
+ Optional<String> path = configuration.get("sonar.test.serverStartupLock.path");
+ if (path.isPresent()) {
+ File lock = new File(path.get());
+ try {
+ while (lock.exists()) {
+ LOGGER.info("ServerStartupLock - Waiting for file to be deleted: " + lock.getAbsolutePath());
+ Thread.sleep(100L);
+ }
+ LOGGER.info("ServerStartupLock - File deleted. Resuming startup.");
+ } catch (InterruptedException e) {
+ LOGGER.info("ServerStartupLock - interrupted");
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/Category4Suite.java b/tests/src/test/java/org/sonarqube/tests/Category4Suite.java
index 84d96dca189..26e5a65c75f 100644
--- a/tests/src/test/java/org/sonarqube/tests/Category4Suite.java
+++ b/tests/src/test/java/org/sonarqube/tests/Category4Suite.java
@@ -42,6 +42,7 @@ import org.sonarqube.tests.serverSystem.HttpHeadersTest;
import org.sonarqube.tests.serverSystem.LogsTest;
import org.sonarqube.tests.serverSystem.PingTest;
import org.sonarqube.tests.serverSystem.ServerSystemTest;
+import org.sonarqube.tests.serverSystem.SystemInfoTest;
import org.sonarqube.tests.ui.SourceViewerTest;
import org.sonarqube.tests.ui.UiExtensionsTest;
import org.sonarqube.tests.ui.UiTest;
@@ -63,6 +64,7 @@ import static util.ItUtils.xooPlugin;
RootUserTest.class,
// server system
ServerSystemTest.class,
+ SystemInfoTest.class,
PingTest.class,
// user
MyAccountPageTest.class,
diff --git a/tests/src/test/java/org/sonarqube/tests/Category5Suite.java b/tests/src/test/java/org/sonarqube/tests/Category5Suite.java
index 9ef6a74a20f..298d51dcabe 100644
--- a/tests/src/test/java/org/sonarqube/tests/Category5Suite.java
+++ b/tests/src/test/java/org/sonarqube/tests/Category5Suite.java
@@ -30,6 +30,7 @@ import org.sonarqube.tests.qualityProfile.BuiltInQualityProfilesNotificationTest
import org.sonarqube.tests.rule.RuleEsResilienceTest;
import org.sonarqube.tests.serverSystem.RestartTest;
import org.sonarqube.tests.serverSystem.ServerSystemRestartingOrchestrator;
+import org.sonarqube.tests.serverSystem.SystemStateTest;
import org.sonarqube.tests.settings.ElasticsearchSettingsTest;
import org.sonarqube.tests.settings.LicensesPageTest;
import org.sonarqube.tests.settings.SettingsTestRestartingOrchestrator;
@@ -52,6 +53,7 @@ import org.sonarqube.tests.user.UserEsResilienceTest;
ServerSystemRestartingOrchestrator.class,
RestartTest.class,
SettingsTestRestartingOrchestrator.class,
+ SystemStateTest.class,
LicensesPageTest.class,
// update center
UpdateCenterTest.class,
diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/ServerSystemTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/ServerSystemTest.java
index ed7784b3db9..5be7753116e 100644
--- a/tests/src/test/java/org/sonarqube/tests/serverSystem/ServerSystemTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/ServerSystemTest.java
@@ -21,11 +21,9 @@ package org.sonarqube.tests.serverSystem;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
-import java.io.File;
import java.io.IOException;
import java.util.Map;
import okhttp3.Response;
-import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.json.simple.JSONValue;
import org.junit.Before;
@@ -67,18 +65,12 @@ public class ServerSystemTest {
Map<String, Object> json = callStatus();
String version = (String) json.get("version");
- if (!startsWithAny(version, new String[] {"6."})) {
+ if (!startsWithAny(version, new String[]{"6."})) {
fail("Bad version: " + version);
}
}
@Test
- public void get_server_status() {
- Map<String, Object> json = callStatus();
- assertThat(json.get("status")).isEqualTo("UP");
- }
-
- @Test
public void generate_server_id() throws IOException {
Navigation nav = tester.openBrowser().openHome().logIn().submitCredentials(ADMIN_USER_LOGIN);
String validIpAddress = getValidIpAddress();
@@ -109,44 +101,6 @@ public class ServerSystemTest {
return ItUtils.jsonToMap(statusResponse.content());
}
- @Test
- public void display_system_info() {
- tester.runHtmlTests("/serverSystem/ServerSystemTest/system_info.html");
- }
-
- @Test
- public void download_system_info() throws Exception {
- waitForComputeEngineToBeUp(orchestrator);
-
- WsResponse response = tester.wsClient().wsConnector().call(
- new GetRequest("api/system/info"));
-
- assertThat(response.code()).isEqualTo(200);
-
- assertThat(response.content()).contains(
- // SONAR-7436 monitor ES and CE
- "\"Compute Engine Database Connection\":", "\"Compute Engine State\":", "\"Compute Engine Tasks\":",
- "\"Elasticsearch\":", "\"State\":\"GREEN\"",
-
- // SONAR-7271 get settings
- "\"Settings\":", "\"sonar.jdbc.url\":", "\"sonar.path.data\":");
- }
-
- private static void waitForComputeEngineToBeUp(Orchestrator orchestrator) throws IOException {
- for (int i = 0; i < 10_000; i++) {
- File logs = orchestrator.getServer().getCeLogs();
- if (FileUtils.readFileToString(logs).contains("Compute Engine is operational")) {
- return;
- }
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // ignored
- }
- }
- throw new IllegalStateException("Compute Engine is not operational");
- }
-
/**
* See http://jira.codehaus.org/browse/SONAR-2727
*/
@@ -163,7 +117,7 @@ public class ServerSystemTest {
*/
@Test
public void hide_jdbc_settings_to_non_admin() {
- tester.runHtmlTests( "/serverSystem/ServerSystemTest/hide-jdbc-settings.html");
+ tester.runHtmlTests("/serverSystem/ServerSystemTest/hide-jdbc-settings.html");
}
@Test
diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemInfoTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemInfoTest.java
new file mode 100644
index 00000000000..62098db3749
--- /dev/null
+++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemInfoTest.java
@@ -0,0 +1,91 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonarqube.tests.serverSystem;
+
+import com.sonar.orchestrator.Orchestrator;
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import org.apache.commons.io.FileUtils;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.tests.Category4Suite;
+import org.sonarqube.tests.Tester;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsResponse;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SystemInfoTest {
+
+ private static final String ADMIN_USER_LOGIN = "admin-user";
+
+ @ClassRule
+ public static final Orchestrator orchestrator = Category4Suite.ORCHESTRATOR;
+
+ @Rule
+ public Tester tester = new Tester(orchestrator).disableOrganizations();
+
+ @Test
+ public void test_system_info_page() {
+ tester.users().generateAdministrator(u -> u.setLogin(ADMIN_USER_LOGIN).setPassword(ADMIN_USER_LOGIN));
+ tester.runHtmlTests("/serverSystem/ServerSystemTest/system_info.html");
+ }
+
+ @Test
+ public void test_system_info_web_service() throws Exception {
+ waitForComputeEngineToBeUp(orchestrator);
+
+ WsResponse response = tester.wsClient().wsConnector().call(
+ new GetRequest("api/system/info"));
+
+ assertThat(response.code()).isEqualTo(200);
+ Map<String, Object> json = ItUtils.jsonToMap(response.content());
+
+ // SONAR-7436 monitor ES and CE
+ assertThat((Map)json.get("Compute Engine Database Connection")).isNotEmpty();
+ assertThat((Map)json.get("Compute Engine State")).isNotEmpty();
+ assertThat((Map)json.get("Compute Engine Tasks")).isNotEmpty();
+ Map<String,Object> esJson = (Map) json.get("Elasticsearch");
+ assertThat(esJson.get("State")).isEqualTo("GREEN");
+
+ // SONAR-7271 get settings
+ Map<String,Object> settingsJson = (Map) json.get("Settings");
+ assertThat(settingsJson.get("sonar.jdbc.url")).isNotNull();
+ assertThat(settingsJson.get("sonar.path.data")).isNotNull();
+ }
+
+ private static void waitForComputeEngineToBeUp(Orchestrator orchestrator) throws IOException {
+ for (int i = 0; i < 10_000; i++) {
+ File logs = orchestrator.getServer().getCeLogs();
+ if (FileUtils.readFileToString(logs).contains("Compute Engine is operational")) {
+ return;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // ignored
+ }
+ }
+ throw new IllegalStateException("Compute Engine is not operational");
+ }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java
new file mode 100644
index 00000000000..b0ac4666913
--- /dev/null
+++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java
@@ -0,0 +1,140 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonarqube.tests.serverSystem;
+
+import com.sonar.orchestrator.Orchestrator;
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Supplier;
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsClient;
+import org.sonarqube.ws.client.WsResponse;
+import util.ItUtils;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.newWsClient;
+import static util.ItUtils.pluginArtifact;
+
+/**
+ * Test system status and health
+ */
+public class SystemStateTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Rule
+ public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
+
+ @Test
+ public void system_status_becomes_UP_when_web_server_is_started() throws Exception {
+ try (Commander commander = new Commander()) {
+ commander.startAsync();
+
+ commander.waitFor(() -> commander.webLogsContain("ServerStartupLock - Waiting for file to be deleted"));
+ assertThat(commander.status()).hasValue("STARTING");
+
+ commander.unlock();
+ commander.waitFor(() -> "UP".equals(commander.status().orElse(null)));
+ }
+ }
+
+ private class Commander implements AutoCloseable {
+ private final File lock = temp.newFile();
+ private final Orchestrator orchestrator = Orchestrator.builderEnv()
+ .addPlugin(pluginArtifact("server-plugin"))
+ .setServerProperty("sonar.test.serverStartupLock.path", lock.getCanonicalPath())
+ .build();
+ private Thread starter;
+
+ Commander() throws Exception {
+
+ }
+
+ void startAsync() {
+ checkState(starter == null);
+ starter = new Thread(orchestrator::start);
+ starter.start();
+ while (orchestrator.getServer() == null) {
+ sleep(100L);
+ }
+ }
+
+ void unlock() throws IOException {
+ FileUtils.forceDelete(lock);
+ }
+
+ boolean webLogsContain(String message) {
+ try {
+ return FileUtils.readFileToString(orchestrator.getServer().getWebLogs()).contains(message);
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ void sleep(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ void waitFor(Supplier<Boolean> predicate) {
+ while (!predicate.get()) {
+ sleep(100L);
+ }
+ }
+
+ Optional<String> status() {
+ if (orchestrator.getServer() != null) {
+ WsClient wsClient = newWsClient(orchestrator);
+ try {
+ WsResponse statusResponse = wsClient.wsConnector().call(new GetRequest("api/system/status"));
+ if (statusResponse.isSuccessful()) {
+ Map<String, Object> json = ItUtils.jsonToMap(statusResponse.content());
+ return Optional.ofNullable((String) json.get("status"));
+ }
+ } catch (Exception e) {
+ // server does not accept connections
+ }
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public void close() {
+ if (starter != null) {
+ starter.interrupt();
+ orchestrator.stop();
+ }
+ }
+ }
+}