aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-09-06 15:52:43 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-09-13 15:50:55 +0200
commit7e778849d1c669cd87c90de21cb3d1ea6494e759 (patch)
tree0545591c3034fc933cea52b1f63bda9f64b58e90
parent3de079f32f95e92f08f03d599d7b483086b87cfa (diff)
downloadsonarqube-7e778849d1c669cd87c90de21cb3d1ea6494e759.tar.gz
sonarqube-7e778849d1c669cd87c90de21cb3d1ea6494e759.zip
SONAR-9741 add authentication to api/system/health
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java21
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java127
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java59
-rw-r--r--tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java4
-rw-r--r--tests/src/test/java/org/sonarqube/tests/cluster/Node.java6
-rw-r--r--tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java13
-rw-r--r--tests/src/test/java/util/ItUtils.java12
10 files changed, 242 insertions, 13 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
index e2a45829e09..4cedd539219 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
@@ -59,7 +59,7 @@ public class UserSessionInitializer {
"/batch/index", "/batch/file",
"/maintenance/*", "/setup/*",
"/sessions/*", "/oauth2/callback/*",
- "/api/system/db_migration_status", "/api/system/status", "/api/system/migrate_db", "/api/system/health",
+ "/api/system/db_migration_status", "/api/system/status", "/api/system/migrate_db",
"/api/server/version",
"/api/users/identity_providers", "/api/l10n/index",
LOGIN_URL, LOGOUT_URL, VALIDATE_URL);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java
index b4931a745cb..f71f03d3be9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/HealthAction.java
@@ -22,16 +22,23 @@ package org.sonar.server.platform.ws;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.platform.WebServer;
+import org.sonar.server.user.SystemPasscode;
+import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
public class HealthAction implements SystemWsAction {
private final WebServer webServer;
private final HealthActionSupport support;
+ private final SystemPasscode systemPasscode;
+ private final UserSession userSession;
- public HealthAction(WebServer webServer, HealthActionSupport support) {
+ public HealthAction(WebServer webServer, HealthActionSupport support, SystemPasscode systemPasscode, UserSession userSession) {
this.webServer = webServer;
this.support = support;
+ this.systemPasscode = systemPasscode;
+ this.userSession = userSession;
}
@Override
@@ -41,6 +48,10 @@ public class HealthAction implements SystemWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
+ if (!isPassCodeAuthenticated(request) && !isSystemAdmin()) {
+ throw new ForbiddenException("Insufficient privileges");
+ }
+
if (webServer.isStandalone()) {
WsUtils.writeProtobuf(support.checkNodeHealth(), request, response);
} else {
@@ -48,4 +59,12 @@ public class HealthAction implements SystemWsAction {
}
}
+ private boolean isSystemAdmin() {
+ return userSession.isSystemAdministrator();
+ }
+
+ private boolean isPassCodeAuthenticated(Request request) {
+ return systemPasscode.isConfigured() && systemPasscode.isValid(request);
+ }
+
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java
index 1c7f953354a..6793f98ae51 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java
@@ -22,13 +22,17 @@ package org.sonar.server.platform.ws;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.user.SystemPasscode;
import org.sonar.server.ws.WsUtils;
public class SafeModeHealthAction implements SystemWsAction {
private final HealthActionSupport support;
+ private final SystemPasscode systemPasscode;
- public SafeModeHealthAction(HealthActionSupport support) {
+ public SafeModeHealthAction(HealthActionSupport support, SystemPasscode systemPasscode) {
this.support = support;
+ this.systemPasscode = systemPasscode;
}
@Override
@@ -38,6 +42,10 @@ public class SafeModeHealthAction implements SystemWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
+ if (!systemPasscode.isConfigured() || !systemPasscode.isValid(request)) {
+ throw new ForbiddenException("Insufficient privileges");
+ }
+
WsUtils.writeProtobuf(support.checkNodeHealth(), request, response);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
index 7697b6ff590..b8fcf9fd7ce 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
@@ -110,7 +110,6 @@ public class UserSessionInitializerTest {
assertPathIsIgnored("/api/system/db_migration_status");
assertPathIsIgnored("/api/system/status");
assertPathIsIgnored("/api/system/migrate_db");
- assertPathIsIgnored("/api/system/health");
assertPathIsIgnored("/api/server/version");
assertPathIsIgnored("/api/users/identity_providers");
assertPathIsIgnored("/api/l10n/index");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java
index 11522e7aabf..33ed30afca1 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java
@@ -29,14 +29,20 @@ import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import org.apache.commons.lang.RandomStringUtils;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
import org.sonar.cluster.health.NodeDetails;
import org.sonar.cluster.health.NodeHealth;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.health.ClusterHealth;
import org.sonar.server.health.Health;
import org.sonar.server.health.HealthChecker;
import org.sonar.server.platform.WebServer;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.user.SystemPasscode;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
@@ -47,6 +53,7 @@ import static java.util.Collections.singleton;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.utils.DateUtils.formatDateTime;
@@ -58,10 +65,16 @@ import static org.sonar.server.health.Health.newHealthCheckBuilder;
import static org.sonar.test.JsonAssert.assertJson;
public class HealthActionTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
private final Random random = new Random();
private HealthChecker healthChecker = mock(HealthChecker.class);
private WebServer webServer = mock(WebServer.class);
- private WsActionTester underTest = new WsActionTester(new HealthAction(webServer, new HealthActionSupport(healthChecker)));
+ private SystemPasscode systemPasscode = mock(SystemPasscode.class);
+ private WsActionTester underTest = new WsActionTester(new HealthAction(webServer, new HealthActionSupport(healthChecker), systemPasscode, userSessionRule));
@Test
public void verify_definition() {
@@ -77,7 +90,82 @@ public class HealthActionTest {
}
@Test
+ public void request_fails_with_ForbiddenException_when_anonymous() {
+ TestRequest request = underTest.newRequest();
+
+ expectForbiddenException();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_fails_with_SystemPasscode_enabled_and_anonymous() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ TestRequest request = underTest.newRequest();
+
+ expectForbiddenException();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_fails_with_SystemPasscode_enabled_but_no_passcode_and_user_is_not_system_administrator() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(false);
+ userSessionRule.logIn();
+ when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth());
+ TestRequest request = underTest.newRequest();
+
+ expectForbiddenException();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_succeeds_with_SystemPasscode_enabled_and_passcode() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(true);
+ when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth());
+ TestRequest request = underTest.newRequest();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_succeeds_with_SystemPasscode_disabled_and_user_is_system_administrator() {
+ when(systemPasscode.isConfigured()).thenReturn(false);
+ userSessionRule.logIn().setSystemAdministrator();
+ when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth());
+ TestRequest request = underTest.newRequest();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_succeeds_with_SystemPasscode_enabled_but_no_passcode_and_user_is_system_administrator() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(false);
+ userSessionRule.logIn().setSystemAdministrator();
+ when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth());
+ TestRequest request = underTest.newRequest();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_succeeds_with_SystemPasscode_enabled_and_passcode_and_user_is_system_administrator() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(true);
+ userSessionRule.logIn().setSystemAdministrator();
+ when(healthChecker.checkCluster()).thenReturn(randomStatusMinimalClusterHealth());
+ TestRequest request = underTest.newRequest();
+
+ request.execute();
+ }
+
+ @Test
public void verify_response_example() {
+ authenticateWithRandomMethod();
when(webServer.isStandalone()).thenReturn(false);
long time = parseDateTime("2015-08-13T23:34:59+0200").getTime();
when(healthChecker.checkCluster())
@@ -153,6 +241,7 @@ public class HealthActionTest {
@Test
public void request_returns_status_and_causes_from_HealthChecker_checkNode_method_when_standalone() {
+ authenticateWithRandomMethod();
Health.Status randomStatus = Health.Status.values()[new Random().nextInt(Health.Status.values().length)];
Health.Builder builder = newHealthCheckBuilder()
.setStatus(randomStatus);
@@ -169,6 +258,7 @@ public class HealthActionTest {
@Test
public void response_contains_status_and_causes_from_HealthChecker_checkCluster_when_standalone() {
+ authenticateWithRandomMethod();
Health.Status randomStatus = Health.Status.values()[random.nextInt(Health.Status.values().length)];
String[] causes = IntStream.range(0, random.nextInt(33)).mapToObj(i -> randomAlphanumeric(4)).toArray(String[]::new);
Health.Builder healthBuilder = newHealthCheckBuilder()
@@ -186,6 +276,7 @@ public class HealthActionTest {
@Test
public void response_contains_information_of_nodes_when_clustered() {
+ authenticateWithRandomMethod();
NodeHealth nodeHealth = randomNodeHealth();
when(webServer.isStandalone()).thenReturn(false);
when(healthChecker.checkCluster()).thenReturn(new ClusterHealth(GREEN, singleton(nodeHealth)));
@@ -208,6 +299,7 @@ public class HealthActionTest {
@Test
public void response_sort_nodes_by_type_name_host_then_port_when_clustered() {
+ authenticateWithRandomMethod();
// using created field as a unique identifier. pseudo random value to ensure sorting is not based on created field
List<NodeHealth> nodeHealths = new ArrayList<>(Arrays.asList(
randomNodeHealth(NodeDetails.Type.APPLICATION, "1_name", "1_host", 1, 99),
@@ -268,4 +360,37 @@ public class HealthActionTest {
.build();
}
+ private ClusterHealth randomStatusMinimalClusterHealth() {
+ return new ClusterHealth(newHealthCheckBuilder()
+ .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)])
+ .build(), emptySet());
+ }
+
+ private void expectForbiddenException() {
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+ }
+
+ /**
+ * Randomly choose of one the valid authentication method:
+ * <ul>
+ * <li>system administrator and passcode disabled</li>
+ * <li>system administrator and passcode enabled</li>
+ * <li>passcode</li>
+ * </ul>
+ */
+ private void authenticateWithRandomMethod() {
+ if (random.nextBoolean()) {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ if (random.nextBoolean()) {
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(true);
+ } else {
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(false);
+ userSessionRule.logIn().setSystemAdministrator();
+ }
+ } else {
+ userSessionRule.logIn().setSystemAdministrator();
+ }
+ }
+
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java
index 340171ce67c..0ee02bbd5f5 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SafeModeHealthActionTest.java
@@ -23,10 +23,15 @@ import java.util.Arrays;
import java.util.Random;
import java.util.stream.IntStream;
import org.apache.commons.lang.RandomStringUtils;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.health.Health;
import org.sonar.server.health.HealthChecker;
+import org.sonar.server.user.SystemPasscode;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
@@ -34,15 +39,20 @@ import org.sonarqube.ws.WsSystem;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.server.health.Health.newHealthCheckBuilder;
import static org.sonar.test.JsonAssert.assertJson;
public class SafeModeHealthActionTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
private final Random random = new Random();
private HealthChecker healthChecker = mock(HealthChecker.class);
- private WsActionTester underTest = new WsActionTester(new SafeModeHealthAction(new HealthActionSupport(healthChecker)));
+ private SystemPasscode systemPasscode = mock(SystemPasscode.class);
+ private WsActionTester underTest = new WsActionTester(new SafeModeHealthAction(new HealthActionSupport(healthChecker), systemPasscode));
@Test
public void verify_definition() {
@@ -58,7 +68,42 @@ public class SafeModeHealthActionTest {
}
@Test
+ public void request_fails_with_ForbiddenException_when_PassCode_disabled() {
+ when(systemPasscode.isConfigured()).thenReturn(false);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(random.nextBoolean());
+ TestRequest request = underTest.newRequest();
+
+ expectForbiddenException();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_fails_with_ForbiddenException_when_PassCode_enabled_but_no_passcode() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(false);
+ TestRequest request = underTest.newRequest();
+
+ expectForbiddenException();
+
+ request.execute();
+ }
+
+ @Test
+ public void request_succeeds_when_PassCode_enabled_and_valid_passcode() {
+ authenticateWithPasscode();
+ when(healthChecker.checkNode())
+ .thenReturn(newHealthCheckBuilder()
+ .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)])
+ .build());
+ TestRequest request = underTest.newRequest();
+
+ request.execute();
+ }
+
+ @Test
public void verify_response_example() {
+ authenticateWithPasscode();
when(healthChecker.checkNode())
.thenReturn(newHealthCheckBuilder()
.setStatus(Health.Status.RED)
@@ -74,6 +119,7 @@ public class SafeModeHealthActionTest {
@Test
public void request_returns_status_and_causes_from_HealthChecker_checkNode_method() {
+ authenticateWithPasscode();
Health.Status randomStatus = Health.Status.values()[new Random().nextInt(Health.Status.values().length)];
Health.Builder builder = newHealthCheckBuilder()
.setStatus(randomStatus);
@@ -89,6 +135,7 @@ public class SafeModeHealthActionTest {
@Test
public void response_contains_status_and_causes_from_HealthChecker_checkCluster() {
+ authenticateWithPasscode();
Health.Status randomStatus = Health.Status.values()[random.nextInt(Health.Status.values().length)];
String[] causes = IntStream.range(0, random.nextInt(33)).mapToObj(i -> randomAlphanumeric(4)).toArray(String[]::new);
Health.Builder healthBuilder = newHealthCheckBuilder()
@@ -103,4 +150,14 @@ public class SafeModeHealthActionTest {
.containsOnly(causes);
}
+ private void expectForbiddenException() {
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+ }
+
+ private void authenticateWithPasscode() {
+ when(systemPasscode.isConfigured()).thenReturn(true);
+ when(systemPasscode.isValid(any(Request.class))).thenReturn(true);
+ }
+
}
diff --git a/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java b/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java
index 74efbf7b53a..58fb754f4b2 100644
--- a/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java
+++ b/tests/src/test/java/org/sonarqube/tests/cluster/Cluster.java
@@ -37,6 +37,7 @@ class Cluster implements AutoCloseable {
private final String clusterName;
private final List<Node> nodes = new ArrayList<>();
+ private final String systemPassCode = "fooBar2000";
Cluster(@Nullable String name) {
this.clusterName = name;
@@ -50,6 +51,7 @@ class Cluster implements AutoCloseable {
Node addNode(NodeConfig config, Consumer<OrchestratorBuilder> consumer) {
OrchestratorBuilder builder = newOrchestratorBuilder(config);
+ builder.setServerProperty("sonar.web.systemPasscode", systemPassCode);
switch (config.getType()) {
case SEARCH:
@@ -71,7 +73,7 @@ class Cluster implements AutoCloseable {
}
consumer.accept(builder);
Orchestrator orchestrator = builder.build();
- Node node = new Node(config, orchestrator);
+ Node node = new Node(config, orchestrator, systemPassCode);
nodes.add(node);
return node;
}
diff --git a/tests/src/test/java/org/sonarqube/tests/cluster/Node.java b/tests/src/test/java/org/sonarqube/tests/cluster/Node.java
index 7826325d34d..e8846c28042 100644
--- a/tests/src/test/java/org/sonarqube/tests/cluster/Node.java
+++ b/tests/src/test/java/org/sonarqube/tests/cluster/Node.java
@@ -42,12 +42,14 @@ class Node {
private final NodeConfig config;
private final Orchestrator orchestrator;
+ private final String systemPassCode;
private LogsTailer logsTailer;
private final LogsTailer.Content content = new LogsTailer.Content();
- Node(NodeConfig config, Orchestrator orchestrator) {
+ Node(NodeConfig config, Orchestrator orchestrator, String systemPassCode) {
this.config = config;
this.orchestrator = orchestrator;
+ this.systemPassCode = systemPassCode;
}
NodeConfig getConfig() {
@@ -142,7 +144,7 @@ class Node {
return Optional.empty();
}
try {
- return Optional.ofNullable(ItUtils.newAdminWsClient(orchestrator).system().health());
+ return Optional.ofNullable(ItUtils.newSystemUserWsClient(orchestrator, systemPassCode).system().health());
} catch (Exception e) {
return Optional.empty();
}
diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java
index b61b5ba8237..a305187d881 100644
--- a/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/SystemStateTest.java
@@ -24,9 +24,11 @@ import com.sonar.orchestrator.util.NetworkUtils;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
+import java.util.Arrays;
import java.util.Optional;
import java.util.function.Supplier;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.RandomStringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
@@ -38,8 +40,8 @@ import org.sonarqube.ws.WsSystem;
import org.sonarqube.ws.client.WsClient;
import static com.google.common.base.Preconditions.checkState;
-import static java.util.stream.Collectors.joining;
import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.newSystemUserWsClient;
import static util.ItUtils.newWsClient;
import static util.ItUtils.pluginArtifact;
@@ -50,10 +52,11 @@ public class SystemStateTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
-
@Rule
public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
+ private final String systemPassCode = RandomStringUtils.randomAlphanumeric(15);
+
@Test
public void test_status_and_health_during_server_lifecycle() throws Exception {
try (Commander commander = new Commander()) {
@@ -130,6 +133,7 @@ public class SystemStateTest {
.setServerProperty("sonar.web.startupLock.path", lock.webFile.getAbsolutePath())
.setServerProperty("sonar.ce.startupLock.path", lock.ceFile.getAbsolutePath())
.setServerProperty("sonar.search.httpPort", "" + esHttpPort)
+ .setServerProperty("sonar.web.systemPasscode", systemPassCode)
.build();
elasticsearch = new Elasticsearch(esHttpPort);
@@ -185,7 +189,7 @@ public class SystemStateTest {
Optional<WsSystem.HealthResponse> healthResponse() {
if (orchestrator.getServer() != null) {
- WsClient wsClient = newWsClient(orchestrator);
+ WsClient wsClient = newSystemUserWsClient(orchestrator, systemPassCode);
try {
return Optional.of(wsClient.system().health());
} catch (Exception e) {
@@ -203,10 +207,11 @@ public class SystemStateTest {
void verifyHealth(WsSystem.Health expectedHealth, String... expectedMessages) {
WsSystem.HealthResponse response = healthResponse().get();
assertThat(response.getHealth())
- .as(response.getCausesList().stream().map(WsSystem.Cause::getMessage).collect(joining(",")))
+ .describedAs("Expected status %s in response %s", expectedHealth, response)
.isEqualTo(expectedHealth);
assertThat(response.getCausesList())
.extracting(WsSystem.Cause::getMessage)
+ .describedAs("Expected causes %s in response %s", Arrays.asList(expectedMessages), response)
.containsExactlyInAnyOrder(expectedMessages);
}
diff --git a/tests/src/test/java/util/ItUtils.java b/tests/src/test/java/util/ItUtils.java
index d86b0b91ffc..05f231afc6c 100644
--- a/tests/src/test/java/util/ItUtils.java
+++ b/tests/src/test/java/util/ItUtils.java
@@ -130,6 +130,18 @@ public class ItUtils {
}
/**
+ * @deprecated replaced by {@link Tester#wsClient()}
+ */
+ @Deprecated
+ public static WsClient newSystemUserWsClient(Orchestrator orchestrator, @Nullable String systemPassCode) {
+ Server server = orchestrator.getServer();
+ return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder()
+ .url(server.getUrl())
+ .systemPassCode(systemPassCode)
+ .build());
+ }
+
+ /**
* Locate the directory of sample project
*
* @param relativePath path related to the directory it/projects, for example "qualitygate/xoo-sample"