From 773c70fc2bc829183d3915bfbcb968eff4941237 Mon Sep 17 00:00:00 2001 From: Claire Villard Date: Fri, 26 Apr 2024 15:30:23 +0200 Subject: [PATCH] SCANCLI-130 Set sonar.scanner.bootstrapStartTime --- .../org/sonarsource/scanner/cli/Conf.java | 5 ++ .../org/sonarsource/scanner/cli/ConfTest.java | 51 +++++++++++-------- .../org/sonarsource/scanner/cli/MainTest.java | 19 +++++-- 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/sonarsource/scanner/cli/Conf.java b/src/main/java/org/sonarsource/scanner/cli/Conf.java index 3004b59..19b020e 100644 --- a/src/main/java/org/sonarsource/scanner/cli/Conf.java +++ b/src/main/java/org/sonarsource/scanner/cli/Conf.java @@ -43,15 +43,18 @@ class Conf { private static final String PROPERTY_PROJECT_CONFIG_FILE = "sonar.projectConfigFile"; private static final String SONAR_PROJECT_PROPERTIES_FILENAME = "sonar-project.properties"; static final String PROPERTY_SONAR_HOST_URL = "sonar.host.url"; + private static final String BOOTSTRAP_START_TIME = "sonar.scanner.bootstrapStartTime"; private final Cli cli; private final Logs logger; private final Map env; + private final long startTimeMs; Conf(Cli cli, Logs logger, Map env) { this.cli = cli; this.logger = logger; this.env = env; + this.startTimeMs = System.currentTimeMillis(); } Properties properties() { @@ -66,6 +69,8 @@ class Conf { // root project base directory must be present and be absolute result.setProperty(PROPERTY_PROJECT_BASEDIR, getRootProjectBaseDir(result).toString()); result.remove(PROJECT_HOME); + + result.setProperty(BOOTSTRAP_START_TIME, String.valueOf(startTimeMs)); return result; } diff --git a/src/test/java/org/sonarsource/scanner/cli/ConfTest.java b/src/test/java/org/sonarsource/scanner/cli/ConfTest.java index c78839f..5ff2441 100644 --- a/src/test/java/org/sonarsource/scanner/cli/ConfTest.java +++ b/src/test/java/org/sonarsource/scanner/cli/ConfTest.java @@ -31,11 +31,12 @@ import org.apache.commons.lang.SystemUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonarsource.scanner.api.internal.shaded.minimaljson.Json; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.junit.Assume.assumeTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -45,9 +46,6 @@ public class ConfTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); - @Rule - public ExpectedException exception = ExpectedException.none(); - private final Map env = new HashMap<>(); private final Properties args = new Properties(); private final Logs logs = new Logs(System.out, System.err); @@ -66,7 +64,7 @@ public class ConfTest { args.setProperty("scanner.home", home.toAbsolutePath().toString()); Properties properties = conf.properties(); - assertThat(properties.get("sonar.prop")).isEqualTo("value"); + assertThat(properties).containsEntry("sonar.prop", "value"); } @Test @@ -76,6 +74,17 @@ public class ConfTest { assertThat(conf.properties().getProperty("sonar.projectBaseDir")).isEqualTo(Paths.get("").toAbsolutePath().toString()); } + @Test + public void should_set_bootstrap_time_only_once() { + Properties properties = conf.properties(); + + assertThat(properties).containsKey("sonar.scanner.bootstrapStartTime"); + String value = properties.getProperty("sonar.scanner.bootstrapStartTime"); + + assertThat(conf.properties()) + .containsEntry("sonar.scanner.bootstrapStartTime", value); + } + @Test public void base_dir_can_be_relative() throws URISyntaxException { Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); @@ -94,7 +103,7 @@ public class ConfTest { Path settings = Paths.get(getClass().getResource("ConfTest/shouldLoadRunnerSettingsByDirectPath/other-conf.properties").toURI()); args.setProperty("scanner.settings", settings.toAbsolutePath().toString()); - assertThat(conf.properties().get("sonar.prop")).isEqualTo("otherValue"); + assertThat(conf.properties()).containsEntry("sonar.prop", "otherValue"); } @Test @@ -138,9 +147,10 @@ public class ConfTest { @Test public void shouldFailWithInvalidEnvironmentProperties() { env.put("SONARQUBE_SCANNER_PARAMS", "{sonar.key1: \"v1\", \"sonar.key2\" : \"v2\"}"); - exception.expect(IllegalStateException.class); - exception.expectMessage("JSON"); - conf.properties(); + + assertThatIllegalStateException() + .isThrownBy(conf::properties) + .withMessage("Failed to parse JSON in SONARQUBE_SCANNER_PARAMS environment variable"); } @Test @@ -236,9 +246,9 @@ public class ConfTest { args.setProperty("sonar.modules", "module1"); args.setProperty("module1.sonar.projectBaseDir", "invalid"); - exception.expect(IllegalStateException.class); - exception.expectMessage("The base directory of the module 'module1' does not exist"); - conf.properties(); + assertThatIllegalStateException() + .isThrownBy(conf::properties) + .withMessageStartingWith("The base directory of the module 'module1' does not exist"); } @Test @@ -246,9 +256,9 @@ public class ConfTest { args.setProperty("sonar.modules", "module1"); args.setProperty("module1.sonar.projectConfigFile", "invalid"); - exception.expect(IllegalStateException.class); - exception.expectMessage("The properties file of the module 'module1' does not exist"); - conf.properties(); + assertThatIllegalStateException() + .isThrownBy(conf::properties) + .withMessageStartingWith("The properties file of the module 'module1' does not exist"); } @Test @@ -270,7 +280,8 @@ public class ConfTest { args.setProperty("project.home", temp.newFolder().getCanonicalPath()); args.setProperty("sonar.projectBaseDir", projectHome.toAbsolutePath().toString()); - conf.properties(); + assertThatCode(conf::properties) + .doesNotThrowAnyException(); } @Test @@ -310,12 +321,12 @@ public class ConfTest { args.setProperty("project.home", home.toAbsolutePath().toString()); Properties properties = conf.properties(); - assertThat(properties.get("sonar.prop")).isEqualTo("default"); + assertThat(properties).containsEntry("sonar.prop", "default"); args.setProperty("project.settings", home.resolve("conf/sq-project.properties").toAbsolutePath().toString()); properties = conf.properties(); - assertThat(properties.get("sonar.prop")).isEqualTo("expected"); + assertThat(properties).containsEntry("sonar.prop", "expected"); } // SQSCANNER-61 @@ -325,7 +336,7 @@ public class ConfTest { args.setProperty("project.home", home.toAbsolutePath().toString()); Properties properties = conf.properties(); - assertThat(properties.get("sonar.prop")).isEqualTo("default"); + assertThat(properties).containsEntry("sonar.prop", "default"); String jsonString = Json.object() .add("project.settings", home.resolve("conf/sq-project.properties").toAbsolutePath().toString()) @@ -334,7 +345,7 @@ public class ConfTest { env.put("SONARQUBE_SCANNER_PARAMS", jsonString); properties = conf.properties(); - assertThat(properties.get("sonar.prop")).isEqualTo("expected"); + assertThat(properties).containsEntry("sonar.prop", "expected"); } } diff --git a/src/test/java/org/sonarsource/scanner/cli/MainTest.java b/src/test/java/org/sonarsource/scanner/cli/MainTest.java index 3b5b07e..85f233c 100644 --- a/src/test/java/org/sonarsource/scanner/cli/MainTest.java +++ b/src/test/java/org/sonarsource/scanner/cli/MainTest.java @@ -299,6 +299,12 @@ public class MainTest { assertThat(analysisProps.getProperty("sonar.log.level")).isEqualTo("TRACE"); } + @Test + public void should_set_bootstrap_start_time_in_millis() { + Properties analysisProps = execute("sonar.scanner.bootstrapStartTime", "1714137496104"); + assertThat(analysisProps.getProperty("sonar.scanner.bootstrapStartTime")).isEqualTo("1714137496104"); + } + @Test public void should_configure_logging_debug() { Properties analysisProps = testLogging("sonar.log.level", "DEBUG"); @@ -306,17 +312,24 @@ public class MainTest { } private Properties testLogging(String propKey, String propValue) { + Properties actualProps = execute(propKey, propValue); + + // Logger used for callback should have debug enabled + verify(logs).setDebugEnabled(true); + + return actualProps; + } + + private Properties execute(String propKey, String propValue) { Properties p = new Properties(); p.put(propKey, propValue); + when(conf.properties()).thenReturn(p); when(cli.getInvokedFrom()).thenReturn(""); Main main = new Main(exit, cli, conf, scannerFactory, logs); main.execute(); - // Logger used for callback should have debug enabled - verify(logs).setDebugEnabled(true); - ArgumentCaptor propertiesCapture = ArgumentCaptor.forClass(Properties.class); verify(scanner).execute((Map) propertiesCapture.capture()); -- 2.39.5