]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12485 add Docker flag in System Info
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 25 Sep 2019 14:41:42 +0000 (16:41 +0200)
committerSonarTech <sonartech@sonarsource.com>
Mon, 7 Oct 2019 18:21:06 +0000 (20:21 +0200)
15 files changed:
server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
server/sonar-server-common/src/main/java/org/sonar/server/util/Paths2.java [new file with mode: 0644]
server/sonar-server-common/src/main/java/org/sonar/server/util/Paths2Impl.java [new file with mode: 0644]
server/sonar-server-common/src/test/java/org/sonar/server/util/Paths2ImplTest.java [new file with mode: 0644]
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DockerSupport.java [new file with mode: 0644]
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DockerSupportImpl.java [new file with mode: 0644]
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/SystemInfoWriterModule.java
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/monitoring/StandaloneSystemSection.java
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/monitoring/cluster/GlobalSystemSection.java
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DockerSupportImplTest.java [new file with mode: 0644]
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/SystemInfoWriterModuleTest.java
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/monitoring/StandaloneSystemSectionTest.java
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/monitoring/cluster/GlobalSystemSectionTest.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java

index 19ffc9671e82c3beac46d1b79e15d9d41162cae3..8059044c19f91ac8f9b949c4c51542f0b177b441 100644 (file)
@@ -147,6 +147,7 @@ import org.sonar.server.setting.ThreadLocalSettings;
 import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexer;
 import org.sonar.server.util.OkHttpClientProvider;
+import org.sonar.server.util.Paths2Impl;
 import org.sonar.server.view.index.ViewIndex;
 import org.sonar.server.view.index.ViewIndexer;
 import org.sonar.server.webhook.WebhookModule;
@@ -293,6 +294,7 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
       ServerFileSystemImpl.class,
       new TempFolderProvider(),
       System2.INSTANCE,
+      Paths2Impl.getInstance(),
       Clock.systemDefaultZone(),
 
       // DB
index 5df6919d05a3b01a90cf4278370f4418487e58da..3ea7555714acea0cff95bfd957a156897f1cc647 100644 (file)
@@ -127,7 +127,7 @@ public class ComputeEngineContainerImplTest {
       );
       assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
         COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION
-          + 26 // level 1
+          + 27 // level 1
           + 63 // content of DaoModule
           + 3 // content of EsModule
           + 51 // content of CorePropertyDefinitions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/util/Paths2.java b/server/sonar-server-common/src/main/java/org/sonar/server/util/Paths2.java
new file mode 100644 (file)
index 0000000..0a101d7
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.sonar.server.util;
+
+import java.net.URI;
+import java.nio.file.Path;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.server.ServerSide;
+
+/**
+ * An interface exposing with the same interface as {@link java.nio.file.Paths} which classes can get injected
+ * with instead of statically binding to {@link java.nio.file.Paths} class.
+ * <p>
+ * This interface can be used to improve testability of classes.
+ */
+@ServerSide
+@ComputeEngineSide
+public interface Paths2 {
+  /**
+   * @see java.nio.file.Paths#get(String, String...)  
+   */
+  Path get(String first, String... more);
+
+  /**
+   * @see java.nio.file.Paths#get(URI) 
+   */
+  Path get(URI uri);
+}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/util/Paths2Impl.java b/server/sonar-server-common/src/main/java/org/sonar/server/util/Paths2Impl.java
new file mode 100644 (file)
index 0000000..cf29db5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.sonar.server.util;
+
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public final class Paths2Impl implements Paths2 {
+  private static final Paths2 INSTANCE = new Paths2Impl();
+
+  public static Paths2 getInstance() {
+    return INSTANCE;
+  }
+
+  private Paths2Impl() {
+    // prevents instantiation and subclassing, use getInstance() instead
+  }
+
+  @Override
+  public Path get(String first, String... more) {
+    return Paths.get(first, more);
+  }
+
+  @Override
+  public Path get(URI uri) {
+    return Paths.get(uri);
+  }
+}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/util/Paths2ImplTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/util/Paths2ImplTest.java
new file mode 100644 (file)
index 0000000..b080855
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.sonar.server.util;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.net.URI;
+import java.nio.file.Paths;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(DataProviderRunner.class)
+public class Paths2ImplTest {
+  @Test
+  public void getInstance_returns_the_same_object_for_every_call() {
+    assertThat(Paths2Impl.getInstance())
+      .isSameAs(Paths2Impl.getInstance())
+      .isSameAs(Paths2Impl.getInstance());
+  }
+
+  @Test
+  @UseDataProvider("getStringParameters")
+  public void get_String_returns_result_of_Paths_get(String first, String... others) {
+    assertThat(Paths2Impl.getInstance().get(first, others))
+      .isEqualTo(Paths.get(first, others));
+  }
+
+  @DataProvider
+  public static Object[][] getStringParameters() {
+    return new Object[][] {
+      {"a", new String[] {}},
+      {"a", new String[] {"b"}},
+      {"a", new String[] {"b", "c"}}
+    };
+  }
+
+  @Test
+  @UseDataProvider("getURIParameter")
+  public void get_URI_returns_result_of_Paths_get(URI uri) {
+    assertThat(Paths2Impl.getInstance().get(uri))
+      .isEqualTo(Paths.get(uri));
+  }
+
+  @DataProvider
+  public static Object[][] getURIParameter() {
+    return new Object[][] {
+      {URI.create("file:///")},
+      {URI.create("file:///a")},
+      {URI.create("file:///b/c")}
+    };
+  }
+}
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DockerSupport.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DockerSupport.java
new file mode 100644 (file)
index 0000000..6931ae5
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.sonar.server.platform;
+
+public interface DockerSupport {
+  /**
+   * @return {@code true} if we can detect that SQ is running inside a docker container
+   */
+  boolean isRunningInDocker();
+
+}
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DockerSupportImpl.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DockerSupportImpl.java
new file mode 100644 (file)
index 0000000..1abc20b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.sonar.server.platform;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.stream.Stream;
+import org.sonar.server.util.Paths2;
+
+public class DockerSupportImpl implements DockerSupport {
+  private final Paths2 paths2;
+
+  public DockerSupportImpl(Paths2 paths2) {
+    this.paths2 = paths2;
+  }
+
+  @Override
+  public boolean isRunningInDocker() {
+    try (Stream<String> stream = Files.lines(paths2.get("/proc/1/cgroup"))) {
+      return stream.anyMatch(line -> line.contains("/docker"));
+    } catch (IOException e) {
+      return false;
+    }
+  }
+}
index e608a80755ee93190233e1c746d0b440f7c020a2..379e7b7eab37a361f08ca179a66b5ed7a14adc18 100644 (file)
@@ -58,7 +58,8 @@ public class SystemInfoWriterModule extends Module {
       EsIndexesSection.class,
       LoggingSection.class,
       PluginsSection.class,
-      SettingsSection.class
+      SettingsSection.class,
+      DockerSupportImpl.class
 
       );
     if (standalone) {
index 1454ae298b02283b6818525080fab7a08c22baa9..6195c6e5299c1edc565665195e139389cb1afb46 100644 (file)
@@ -32,6 +32,7 @@ import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
 import org.sonar.server.authentication.IdentityProviderRepository;
 import org.sonar.server.log.ServerLogging;
+import org.sonar.server.platform.DockerSupport;
 import org.sonar.server.platform.OfficialDistribution;
 import org.sonar.server.user.SecurityRealmFactory;
 
@@ -50,16 +51,18 @@ public class StandaloneSystemSection extends BaseSectionMBean implements SystemS
   private final Server server;
   private final ServerLogging serverLogging;
   private final OfficialDistribution officialDistribution;
+  private final DockerSupport dockerSupport;
 
   public StandaloneSystemSection(Configuration config, SecurityRealmFactory securityRealmFactory,
     IdentityProviderRepository identityProviderRepository, Server server, ServerLogging serverLogging,
-    OfficialDistribution officialDistribution) {
+    OfficialDistribution officialDistribution, DockerSupport dockerSupport) {
     this.config = config;
     this.securityRealmFactory = securityRealmFactory;
     this.identityProviderRepository = identityProviderRepository;
     this.server = server;
     this.serverLogging = serverLogging;
     this.officialDistribution = officialDistribution;
+    this.dockerSupport = dockerSupport;
   }
 
   @Override
@@ -117,6 +120,7 @@ public class StandaloneSystemSection extends BaseSectionMBean implements SystemS
 
     setAttribute(protobuf, "Server ID", server.getId());
     setAttribute(protobuf, "Version", getVersion());
+    setAttribute(protobuf, "Docker", dockerSupport.isRunningInDocker());
     setAttribute(protobuf, "External User Authentication", getExternalUserAuthentication());
     addIfNotEmpty(protobuf, "Accepted external identity providers", getEnabledIdentityProviders());
     addIfNotEmpty(protobuf, "External identity providers whose users are allowed to sign themselves up", getAllowsToSignUpEnabledIdentityProviders());
index 6ebb83d06f071fe058c55a879a8c05dc255ee3b2..fb52ab6ad52c5da60c22c1ac6218bfd298343cfa 100644 (file)
@@ -34,6 +34,7 @@ import org.sonar.process.systeminfo.Global;
 import org.sonar.process.systeminfo.SystemInfoSection;
 import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
 import org.sonar.server.authentication.IdentityProviderRepository;
+import org.sonar.server.platform.DockerSupport;
 import org.sonar.server.user.SecurityRealmFactory;
 
 import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;
@@ -46,13 +47,15 @@ public class GlobalSystemSection implements SystemInfoSection, Global {
   private final Server server;
   private final SecurityRealmFactory securityRealmFactory;
   private final IdentityProviderRepository identityProviderRepository;
+  private final DockerSupport dockerSupport;
 
   public GlobalSystemSection(Configuration config, Server server, SecurityRealmFactory securityRealmFactory,
-    IdentityProviderRepository identityProviderRepository) {
+    IdentityProviderRepository identityProviderRepository, DockerSupport dockerSupport) {
     this.config = config;
     this.server = server;
     this.securityRealmFactory = securityRealmFactory;
     this.identityProviderRepository = identityProviderRepository;
+    this.dockerSupport = dockerSupport;
   }
 
   @Override
@@ -61,6 +64,7 @@ public class GlobalSystemSection implements SystemInfoSection, Global {
     protobuf.setName("System");
 
     setAttribute(protobuf, "Server ID", server.getId());
+    setAttribute(protobuf, "Docker", dockerSupport.isRunningInDocker());
     setAttribute(protobuf, "High Availability", true);
     setAttribute(protobuf, "External User Authentication", getExternalUserAuthentication());
     addIfNotEmpty(protobuf, "Accepted external identity providers", getEnabledIdentityProviders());
diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DockerSupportImplTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DockerSupportImplTest.java
new file mode 100644 (file)
index 0000000..ddf4dba
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.sonar.server.platform;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.server.util.Paths2;
+
+import static java.lang.System.lineSeparator;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DockerSupportImplTest {
+  private static final String CGROUP_DIR = "/proc/1/cgroup";
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  private Paths2 paths2 = mock(Paths2.class);
+  private DockerSupportImpl underTest = new DockerSupportImpl(paths2);
+
+  @Test
+  public void isInDocker_returns_false_if_cgroup_file_does_not_exist() throws IOException {
+    Path emptyFile = temporaryFolder.newFile().toPath();
+    Files.delete(emptyFile);
+    when(paths2.get(CGROUP_DIR)).thenReturn(emptyFile);
+
+    assertThat(underTest.isRunningInDocker()).isFalse();
+  }
+
+  @Test
+  public void isInDocker_returns_false_if_cgroup_file_is_empty() throws IOException {
+    Path emptyFile = temporaryFolder.newFile().toPath();
+    when(paths2.get(CGROUP_DIR)).thenReturn(emptyFile);
+
+    assertThat(underTest.isRunningInDocker()).isFalse();
+  }
+
+  @Test
+  public void isInDocker_returns_false_if_cgroup_dir_contains_no_file_with_slash_docker_string() throws IOException {
+    Path cgroupFile = temporaryFolder.newFile().toPath();
+    String content = "11:name=systemd:/" + lineSeparator() +
+      "10:hugetlb:/" + lineSeparator() +
+      "9:perf_event:/" + lineSeparator() +
+      "8:blkio:/" + lineSeparator() +
+      "7:freezer:/" + lineSeparator() +
+      "6:devices:/" + lineSeparator() +
+      "5:memory:/" + lineSeparator() +
+      "4:cpuacct:/" + lineSeparator() +
+      "3:cpu:/" + lineSeparator() +
+      "2:cpuset:/";
+    FileUtils.write(cgroupFile.toFile(), content, StandardCharsets.UTF_8);
+    when(paths2.get(CGROUP_DIR)).thenReturn(cgroupFile);
+
+    assertThat(underTest.isRunningInDocker()).isFalse();
+  }
+
+  @Test
+  public void isInDocker_returns_true_if_cgroup_dir_contains_file_with_slash_docker_string() throws IOException {
+    Path cgroupFile = temporaryFolder.newFile().toPath();
+    String content = "11:name=systemd:/" + lineSeparator() +
+      "10:hugetlb:/" + lineSeparator() +
+      "9:perf_event:/" + lineSeparator() +
+      "8:blkio:/" + lineSeparator() +
+      "7:freezer:/" + lineSeparator() +
+      "6:devices:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2" + lineSeparator() +
+      "5:memory:/" + lineSeparator() +
+      "4:cpuacct:/" + lineSeparator() +
+      "3:cpu:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2" + lineSeparator() +
+      "2:cpuset:/";
+    FileUtils.write(cgroupFile.toFile(), content, StandardCharsets.UTF_8);
+    when(paths2.get(CGROUP_DIR)).thenReturn(cgroupFile);
+
+    assertThat(underTest.isRunningInDocker()).isTrue();
+  }
+
+}
index a78a5efd40b02cc935a5e0bc5dd31d7172d708af..bf3d7a0f43991435b45b32fc0761cfb1ec89c63e 100644 (file)
@@ -42,7 +42,7 @@ public class SystemInfoWriterModuleTest {
 
     Collection<ComponentAdapter<?>> adapters = container.getPicoContainer().getComponentAdapters();
     assertThat(adapters)
-      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 17);
+      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 18);
   }
 
   @Test
@@ -52,13 +52,9 @@ public class SystemInfoWriterModuleTest {
 
     underTest.configure(container);
 
-    verifyConfigurationStandaloneSQ(container);
-  }
-
-  public void verifyConfigurationStandaloneSQ(ComponentContainer container) {
     Collection<ComponentAdapter<?>> adapters = container.getPicoContainer().getComponentAdapters();
     assertThat(adapters)
-      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 11);
+      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 12);
   }
 
 }
index bc233dab4e9418818e87d172f02a9f1fc9976034..0e284b681bb00f2a1a15929b31b1a9bc46812f02 100644 (file)
  */
 package org.sonar.server.platform.monitoring;
 
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.platform.Server;
 import org.sonar.api.security.SecurityRealm;
@@ -30,6 +34,7 @@ import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
 import org.sonar.server.authentication.IdentityProviderRepositoryRule;
 import org.sonar.server.authentication.TestIdentityProvider;
 import org.sonar.server.log.ServerLogging;
+import org.sonar.server.platform.DockerSupport;
 import org.sonar.server.platform.OfficialDistribution;
 import org.sonar.server.user.SecurityRealmFactory;
 
@@ -39,11 +44,9 @@ import static org.mockito.Mockito.when;
 import static org.sonar.process.systeminfo.SystemInfoUtils.attribute;
 import static org.sonar.server.platform.monitoring.SystemInfoTesting.assertThatAttributeIs;
 
+@RunWith(DataProviderRunner.class)
 public class StandaloneSystemSectionTest {
 
-  private static final String SERVER_ID_PROPERTY = "Server ID";
-  private static final String SERVER_ID_VALIDATED_PROPERTY = "Server ID validated";
-
   @Rule
   public IdentityProviderRepositoryRule identityProviderRepository = new IdentityProviderRepositoryRule();
 
@@ -52,12 +55,13 @@ public class StandaloneSystemSectionTest {
   private ServerLogging serverLogging = mock(ServerLogging.class);
   private SecurityRealmFactory securityRealmFactory = mock(SecurityRealmFactory.class);
   private OfficialDistribution officialDistribution = mock(OfficialDistribution.class);
+  private DockerSupport dockerSupport = mock(DockerSupport.class);
 
   private StandaloneSystemSection underTest = new StandaloneSystemSection(settings.asConfig(), securityRealmFactory, identityProviderRepository, server,
-    serverLogging, officialDistribution);
+    serverLogging, officialDistribution, dockerSupport);
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     when(serverLogging.getRootLoggerLevel()).thenReturn(LoggerLevel.DEBUG);
   }
 
@@ -152,4 +156,20 @@ public class StandaloneSystemSectionTest {
     ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
     assertThat(attribute(protobuf, "Processors").getLongValue()).isGreaterThan(0);
   }
+
+  @Test
+  @UseDataProvider("trueOrFalse")
+  public void return_docker_flag_from_DockerSupport(boolean flag) {
+    when(dockerSupport.isRunningInDocker()).thenReturn(flag);
+    ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
+    assertThat(attribute(protobuf, "Docker").getBooleanValue()).isEqualTo(flag);
+  }
+
+  @DataProvider
+  public static Object[][] trueOrFalse() {
+    return new Object[][] {
+      {true},
+      {false}
+    };
+  }
 }
index f12c7461f1e063d69b1cb4fce0cb725bda88a855..acc9eeaf5e01825bd4acf232e3f09010d3e6ec64 100644 (file)
  */
 package org.sonar.server.platform.monitoring.cluster;
 
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.platform.Server;
 import org.sonar.api.security.SecurityRealm;
 import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
 import org.sonar.server.authentication.IdentityProviderRepositoryRule;
 import org.sonar.server.authentication.TestIdentityProvider;
+import org.sonar.server.platform.DockerSupport;
 import org.sonar.server.user.SecurityRealmFactory;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -35,6 +40,7 @@ import static org.mockito.Mockito.when;
 import static org.sonar.process.systeminfo.SystemInfoUtils.attribute;
 import static org.sonar.server.platform.monitoring.SystemInfoTesting.assertThatAttributeIs;
 
+@RunWith(DataProviderRunner.class)
 public class GlobalSystemSectionTest {
 
   @Rule
@@ -44,8 +50,9 @@ public class GlobalSystemSectionTest {
   private Server server = mock(Server.class);
   private SecurityRealmFactory securityRealmFactory = mock(SecurityRealmFactory.class);
 
+  private DockerSupport dockerSupport = mock(DockerSupport.class);
   private GlobalSystemSection underTest = new GlobalSystemSection(settings.asConfig(),
-    server, securityRealmFactory, identityProviderRepository);
+    server, securityRealmFactory, identityProviderRepository, dockerSupport);
 
   @Test
   public void name_is_not_empty() {
@@ -110,4 +117,21 @@ public class GlobalSystemSectionTest {
     ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
     assertThatAttributeIs(protobuf, "External identity providers whose users are allowed to sign themselves up", "GitHub");
   }
+
+  @Test
+  @UseDataProvider("trueOrFalse")
+  public void get_docker_flag(boolean flag) {
+    when(dockerSupport.isRunningInDocker()).thenReturn(flag);
+
+    ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
+    assertThatAttributeIs(protobuf, "Docker", flag);
+  }
+
+  @DataProvider
+  public static Object[][] trueOrFalse() {
+    return new Object[][] {
+      {true},
+      {false},
+    };
+  }
 }
index 7f6258a699615616ba40e756b50645c02ad2b16e..1fd70e56cadfc28bfd4b3446df727310ed5f0a5e 100644 (file)
@@ -30,6 +30,7 @@ import org.sonar.api.internal.SonarRuntimeImpl;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.Version;
 import org.sonar.server.util.GlobalLockManagerImpl;
+import org.sonar.server.util.Paths2Impl;
 import org.sonar.server.util.TempFolderCleaner;
 import org.sonar.core.config.CorePropertyDefinitions;
 import org.sonar.core.extension.CoreExtensionRepositoryImpl;
@@ -108,6 +109,7 @@ public class PlatformLevel1 extends PlatformLevel {
       TempFolderCleaner.class,
       new TempFolderProvider(),
       System2.INSTANCE,
+      Paths2Impl.getInstance(),
       Clock.systemDefaultZone(),
 
       // user session