aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2024-04-30 14:59:03 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2024-05-03 13:07:43 +0200
commitb04cd6ba08a93a88553c1dfceaa725ced1ba381c (patch)
tree762512e8d5a70bd6981706c5d779a982c57ad75a /src
parentfd82dd7b5a54d2042da17baff7088329123797ac (diff)
downloadsonar-scanner-cli-b04cd6ba08a93a88553c1dfceaa725ced1ba381c.tar.gz
sonar-scanner-cli-b04cd6ba08a93a88553c1dfceaa725ced1ba381c.zip
SCANCLI-145 Update to the scanner library 3.0
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/sonarsource/scanner/cli/Cli.java6
-rw-r--r--src/main/java/org/sonarsource/scanner/cli/Conf.java6
-rw-r--r--src/main/java/org/sonarsource/scanner/cli/Logs.java34
-rw-r--r--src/main/java/org/sonarsource/scanner/cli/Main.java52
-rw-r--r--src/main/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactory.java (renamed from src/main/java/org/sonarsource/scanner/cli/ScannerFactory.java)38
-rw-r--r--src/test/java/org/sonarsource/scanner/cli/CliTest.java56
-rw-r--r--src/test/java/org/sonarsource/scanner/cli/ConfTest.java40
-rw-r--r--src/test/java/org/sonarsource/scanner/cli/LogsTest.java36
-rw-r--r--src/test/java/org/sonarsource/scanner/cli/MainTest.java119
-rw-r--r--src/test/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactoryTest.java84
-rw-r--r--src/test/java/org/sonarsource/scanner/cli/ScannerFactoryTest.java105
11 files changed, 263 insertions, 313 deletions
diff --git a/src/main/java/org/sonarsource/scanner/cli/Cli.java b/src/main/java/org/sonarsource/scanner/cli/Cli.java
index aafed18..4de2a36 100644
--- a/src/main/java/org/sonarsource/scanner/cli/Cli.java
+++ b/src/main/java/org/sonarsource/scanner/cli/Cli.java
@@ -20,7 +20,6 @@
package org.sonarsource.scanner.cli;
import java.util.Properties;
-import org.sonarsource.scanner.api.ScannerProperties;
import static java.util.Arrays.asList;
@@ -73,10 +72,7 @@ class Cli {
private int processNextArg(String[] args, int pos) {
String arg = args[pos];
- if (pos == 0 && arg.charAt(0) != '-') {
- props.setProperty(ScannerProperties.TASK, arg);
-
- } else if (asList("-h", "--help").contains(arg)) {
+ if (asList("-h", "--help").contains(arg)) {
printUsage();
exit.exit(Exit.SUCCESS);
diff --git a/src/main/java/org/sonarsource/scanner/cli/Conf.java b/src/main/java/org/sonarsource/scanner/cli/Conf.java
index 19b020e..4e9a53a 100644
--- a/src/main/java/org/sonarsource/scanner/cli/Conf.java
+++ b/src/main/java/org/sonarsource/scanner/cli/Conf.java
@@ -31,7 +31,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.Nullable;
-import org.sonarsource.scanner.api.Utils;
+import org.sonarsource.scanner.lib.EnvironmentConfig;
class Conf {
private static final String SCANNER_HOME = "scanner.home";
@@ -79,8 +79,8 @@ class Conf {
return resolver.resolve();
}
- private Properties loadEnvironmentProperties() {
- return Utils.loadEnvironmentProperties(env);
+ private Map<String, String> loadEnvironmentProperties() {
+ return EnvironmentConfig.load(logger.getLogOutputAdapter());
}
private Properties loadGlobalProperties() {
diff --git a/src/main/java/org/sonarsource/scanner/cli/Logs.java b/src/main/java/org/sonarsource/scanner/cli/Logs.java
index 038e78f..f8b4ce3 100644
--- a/src/main/java/org/sonarsource/scanner/cli/Logs.java
+++ b/src/main/java/org/sonarsource/scanner/cli/Logs.java
@@ -22,6 +22,7 @@ package org.sonarsource.scanner.cli;
import java.io.PrintStream;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
+import org.sonarsource.scanner.lib.LogOutput;
public class Logs {
private DateTimeFormatter timeFormatter;
@@ -77,4 +78,37 @@ public class Logs {
stream.println(msg);
}
}
+
+ /**
+ * Adapter for the scanner library.
+ */
+ public LogOutput getLogOutputAdapter() {
+ return new LogOutputAdapter(this);
+ }
+
+ static class LogOutputAdapter implements LogOutput {
+ private final Logs logs;
+
+ public LogOutputAdapter(Logs logs) {
+ this.logs = logs;
+ }
+
+ @Override
+ public void log(String formattedMessage, Level level) {
+ switch (level) {
+ case TRACE, DEBUG:
+ logs.debug(formattedMessage);
+ break;
+ case ERROR:
+ logs.error(formattedMessage);
+ break;
+ case WARN:
+ logs.warn(formattedMessage);
+ break;
+ case INFO:
+ default:
+ logs.info(formattedMessage);
+ }
+ }
+ }
}
diff --git a/src/main/java/org/sonarsource/scanner/cli/Main.java b/src/main/java/org/sonarsource/scanner/cli/Main.java
index ff7f96f..787cc80 100644
--- a/src/main/java/org/sonarsource/scanner/cli/Main.java
+++ b/src/main/java/org/sonarsource/scanner/cli/Main.java
@@ -19,11 +19,11 @@
*/
package org.sonarsource.scanner.cli;
-import java.util.Locale;
import java.util.Map;
import java.util.Properties;
-import org.sonarsource.scanner.api.EmbeddedScanner;
-import org.sonarsource.scanner.api.ScanProperties;
+import org.sonarsource.scanner.lib.ScanProperties;
+import org.sonarsource.scanner.lib.ScannerEngineBootstrapper;
+import org.sonarsource.scanner.lib.ScannerEngineFacade;
/**
* Arguments :
@@ -42,15 +42,15 @@ public class Main {
private final Exit exit;
private final Cli cli;
private final Conf conf;
- private EmbeddedScanner embeddedScanner;
- private final ScannerFactory runnerFactory;
+ private ScannerEngineBootstrapper scannerEngineBootstrapper;
+ private final ScannerEngineBootstrapperFactory bootstrapperFactory;
private final Logs logger;
- Main(Exit exit, Cli cli, Conf conf, ScannerFactory runnerFactory, Logs logger) {
+ Main(Exit exit, Cli cli, Conf conf, ScannerEngineBootstrapperFactory bootstrapperFactory, Logs logger) {
this.exit = exit;
this.cli = cli;
this.conf = conf;
- this.runnerFactory = runnerFactory;
+ this.bootstrapperFactory = bootstrapperFactory;
this.logger = logger;
}
@@ -58,11 +58,11 @@ public class Main {
Logs logs = new Logs(System.out, System.err);
Exit exit = new Exit();
Cli cli = new Cli(exit, logs).parse(args);
- Main main = new Main(exit, cli, new Conf(cli, logs, System.getenv()), new ScannerFactory(logs), logs);
- main.execute();
+ Main main = new Main(exit, cli, new Conf(cli, logs, System.getenv()), new ScannerEngineBootstrapperFactory(logs), logs);
+ main.analyze();
}
- void execute() {
+ void analyze() {
Stats stats = new Stats(logger).start();
int status = Exit.INTERNAL_ERROR;
@@ -71,15 +71,12 @@ public class Main {
checkSkip(p);
configureLogging(p);
init(p);
- embeddedScanner.start();
- if (isSonarCloud(p)) {
- logger.info("Analyzing on SonarCloud");
- } else {
- String serverVersion = embeddedScanner.serverVersion();
- logger.info(String.format("Analyzing on SonarQube server %s", serverVersion));
+ try (var engine = scannerEngineBootstrapper.bootstrap()) {
+ logServerType(engine);
+ engine.analyze((Map) p);
+ displayExecutionResult(stats, "SUCCESS");
+ status = Exit.SUCCESS;
}
- execute(stats, p);
- status = Exit.SUCCESS;
} catch (Throwable e) {
displayExecutionResult(stats, "FAILURE");
showError("Error during SonarScanner execution", e, cli.isDebugEnabled());
@@ -89,13 +86,13 @@ public class Main {
}
}
- static boolean isSonarCloud(Properties props) {
- String hostUrl = props.getProperty(Conf.PROPERTY_SONAR_HOST_URL);
- if (hostUrl != null) {
- return hostUrl.toLowerCase(Locale.ENGLISH).contains("sonarcloud");
+ private void logServerType(ScannerEngineFacade engine) {
+ if (engine.isSonarCloud()) {
+ logger.info("Analyzing on SonarCloud");
+ } else {
+ String serverVersion = engine.getServerVersion();
+ logger.info(String.format("Analyzing on SonarQube server %s", serverVersion));
}
-
- return false;
}
private void checkSkip(Properties properties) {
@@ -111,7 +108,7 @@ public class Main {
exit.exit(Exit.SUCCESS);
}
- embeddedScanner = runnerFactory.create(p, cli.getInvokedFrom());
+ scannerEngineBootstrapper = bootstrapperFactory.create(p, cli.getInvokedFrom());
}
private void configureLogging(Properties props) {
@@ -122,11 +119,6 @@ public class Main {
}
}
- private void execute(Stats stats, Properties p) {
- embeddedScanner.execute((Map) p);
- displayExecutionResult(stats, "SUCCESS");
- }
-
private void displayExecutionResult(Stats stats, String resultMsg) {
logger.info(SEPARATOR);
logger.info("EXECUTION " + resultMsg);
diff --git a/src/main/java/org/sonarsource/scanner/cli/ScannerFactory.java b/src/main/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactory.java
index d27165e..b67254c 100644
--- a/src/main/java/org/sonarsource/scanner/cli/ScannerFactory.java
+++ b/src/main/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactory.java
@@ -21,47 +21,31 @@ package org.sonarsource.scanner.cli;
import java.util.Map;
import java.util.Properties;
-import org.sonarsource.scanner.api.EmbeddedScanner;
-import org.sonarsource.scanner.api.LogOutput;
+import org.sonarsource.scanner.lib.ScannerEngineBootstrapper;
-class ScannerFactory {
+class ScannerEngineBootstrapperFactory {
private final Logs logger;
- public ScannerFactory(Logs logger) {
+ public ScannerEngineBootstrapperFactory(Logs logger) {
this.logger = logger;
}
- EmbeddedScanner create(Properties props, String isInvokedFrom) {
+ ScannerEngineBootstrapper create(Properties props, String isInvokedFrom) {
String appName = "ScannerCLI";
String appVersion = ScannerVersion.version();
- if (!isInvokedFrom.equals("") && isInvokedFrom.contains("/")) {
+ if (isInvokedFrom.contains("/")) {
appName = isInvokedFrom.split("/")[0];
appVersion = isInvokedFrom.split("/")[1];
}
- return EmbeddedScanner.create(appName, appVersion, new DefaultLogOutput())
- .addGlobalProperties((Map) props);
+ return newScannerEngineBootstrapper(appName, appVersion)
+ .addBootstrapProperties((Map) props);
}
- class DefaultLogOutput implements LogOutput {
- @Override
- public void log(String formattedMessage, Level level) {
- switch (level) {
- case TRACE:
- case DEBUG:
- logger.debug(formattedMessage);
- break;
- case ERROR:
- logger.error(formattedMessage);
- break;
- case WARN:
- logger.warn(formattedMessage);
- break;
- case INFO:
- default:
- logger.info(formattedMessage);
- }
- }
+ ScannerEngineBootstrapper newScannerEngineBootstrapper(String appName, String appVersion) {
+ return new ScannerEngineBootstrapper(appName, appVersion, logger.getLogOutputAdapter());
}
+
+
}
diff --git a/src/test/java/org/sonarsource/scanner/cli/CliTest.java b/src/test/java/org/sonarsource/scanner/cli/CliTest.java
index 961f7d1..ce5b140 100644
--- a/src/test/java/org/sonarsource/scanner/cli/CliTest.java
+++ b/src/test/java/org/sonarsource/scanner/cli/CliTest.java
@@ -22,11 +22,13 @@ package org.sonarsource.scanner.cli;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatNoException;
+import static org.assertj.core.api.Assertions.entry;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class CliTest {
- private Exit exit = mock(Exit.class);
+ private final Exit exit = mock(Exit.class);
private Logs logs = new Logs(System.out, System.err);
private Cli cli = new Cli(exit, logs);
@@ -41,17 +43,18 @@ public class CliTest {
@Test
public void should_extract_properties() {
- cli.parse(new String[] {"-D", "foo=bar", "--define", "hello=world", "-Dboolean"});
- assertThat(cli.properties().get("foo")).isEqualTo("bar");
- assertThat(cli.properties().get("hello")).isEqualTo("world");
- assertThat(cli.properties().get("boolean")).isEqualTo("true");
+ cli.parse(new String[]{"-D", "foo=bar", "--define", "hello=world", "-Dboolean"});
+ assertThat(cli.properties()).contains(
+ entry("foo", "bar"),
+ entry("hello", "world"),
+ entry("boolean", "true"));
}
@Test
public void should_warn_on_duplicate_properties() {
logs = mock(Logs.class);
cli = new Cli(exit, logs);
- cli.parse(new String[] {"-D", "foo=bar", "--define", "foo=baz"});
+ cli.parse(new String[]{"-D", "foo=bar", "--define", "foo=baz"});
verify(logs).warn("Property 'foo' with value 'bar' is overridden with value 'baz'");
}
@@ -59,75 +62,66 @@ public class CliTest {
public void should_fail_on_missing_prop() {
logs = mock(Logs.class);
cli = new Cli(exit, logs);
- cli.parse(new String[] {"-D"});
+ cli.parse(new String[]{"-D"});
verify(logs).error("Missing argument for option -D/--define");
verify(exit).exit(Exit.INTERNAL_ERROR);
}
@Test
public void should_not_fail_with_errors_option() {
- cli.parse(new String[] {"-e"});
- }
-
- @Test
- public void should_parse_optional_task() {
- cli.parse(new String[] {"-D", "foo=bar"});
- assertThat(cli.properties().get("sonar.task")).isNull();
-
- cli.parse(new String[] {"views", "-D", "foo=bar"});
- assertThat(cli.properties().get("sonar.task")).isEqualTo("views");
+ assertThatNoException().isThrownBy(() -> cli.parse(new String[]{"-e"}));
}
@Test
public void should_enable_debug_mode() {
- cli.parse(new String[] {"-X"});
+ cli.parse(new String[]{"-X"});
assertThat(cli.isDebugEnabled()).isTrue();
- assertThat(cli.properties().get("sonar.verbose")).isEqualTo("true");
+ assertThat(cli.properties()).containsEntry("sonar.verbose", "true");
}
@Test
public void should_enable_debug_mode_full() {
- cli.parse(new String[] {"--debug"});
+ cli.parse(new String[]{"--debug"});
assertThat(cli.isDebugEnabled()).isTrue();
- assertThat(cli.properties().get("sonar.verbose")).isEqualTo("true");
+ assertThat(cli.properties()).containsEntry("sonar.verbose", "true");
}
@Test
public void should_show_version() {
- cli.parse(new String[] {"-v"});
+ cli.parse(new String[]{"-v"});
assertThat(cli.isDisplayVersionOnly()).isTrue();
}
@Test
public void should_show_version_full() {
- cli.parse(new String[] {"--version"});
+ cli.parse(new String[]{"--version"});
assertThat(cli.isDisplayVersionOnly()).isTrue();
}
@Test
public void should_enable_stacktrace_log() {
- cli.parse(new String[] {"-e"});
+ cli.parse(new String[]{"-e"});
assertThat(cli.isDebugEnabled()).isFalse();
assertThat(cli.properties().get("sonar.verbose")).isNull();
}
@Test
public void should_enable_stacktrace_log_full() {
- cli.parse(new String[] {"--errors"});
+ cli.parse(new String[]{"--errors"});
assertThat(cli.isDebugEnabled()).isFalse();
assertThat(cli.properties().get("sonar.verbose")).isNull();
}
@Test
public void should_parse_from_argument() {
- cli.parse(new String[] {"--from=ScannerMSBuild/4.8"});
+ cli.parse(new String[]{"--from=ScannerMSBuild/4.8"});
assertThat(cli.getInvokedFrom()).isNotEmpty();
assertThat(cli.getInvokedFrom()).isEqualTo("ScannerMSBuild/4.8");
}
@Test
public void from_argument_is_only_from_let_value_empty() {
- cli.parse(new String[] {"--from="});
+ cli.parse(new String[]{"--from="});
assertThat(cli.getInvokedFrom()).isEmpty();
}
@@ -142,7 +136,7 @@ public class CliTest {
public void should_show_usage() {
logs = mock(Logs.class);
cli = new Cli(exit, logs);
- cli.parse(new String[] {"-h"});
+ cli.parse(new String[]{"-h"});
verify(logs).info("usage: sonar-scanner [options]");
verify(exit).exit(Exit.SUCCESS);
}
@@ -151,7 +145,7 @@ public class CliTest {
public void should_show_usage_full() {
logs = mock(Logs.class);
cli = new Cli(exit, logs);
- cli.parse(new String[] {"--help"});
+ cli.parse(new String[]{"--help"});
verify(logs).info("usage: sonar-scanner [options]");
verify(exit).exit(Exit.SUCCESS);
}
@@ -160,7 +154,7 @@ public class CliTest {
public void should_show_usage_on_bad_syntax() {
logs = mock(Logs.class);
cli = new Cli(exit, logs);
- cli.parse(new String[] {"-w"});
+ cli.parse(new String[]{"-w"});
verify(logs).error("Unrecognized option: -w");
verify(logs).info("usage: sonar-scanner [options]");
verify(exit).exit(Exit.INTERNAL_ERROR);
@@ -168,7 +162,7 @@ public class CliTest {
@Test
public void should_enable_embedded_mode() {
- cli.parse(new String[] {"--embedded"});
+ cli.parse(new String[]{"--embedded"});
assertThat(cli.isEmbedded()).isTrue();
}
}
diff --git a/src/test/java/org/sonarsource/scanner/cli/ConfTest.java b/src/test/java/org/sonarsource/scanner/cli/ConfTest.java
index 5ff2441..d28754a 100644
--- a/src/test/java/org/sonarsource/scanner/cli/ConfTest.java
+++ b/src/test/java/org/sonarsource/scanner/cli/ConfTest.java
@@ -32,7 +32,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
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;
@@ -134,26 +133,6 @@ public class ConfTest {
}
@Test
- public void shouldLoadEnvironmentProperties() {
- env.put("SONARQUBE_SCANNER_PARAMS", "{\"sonar.key1\" : \"v1\", \"sonar.key2\" : \"v2\"}");
- args.put("sonar.key2", "v3");
-
- Properties props = conf.properties();
-
- assertThat(props.getProperty("sonar.key1")).isEqualTo("v1");
- assertThat(props.getProperty("sonar.key2")).isEqualTo("v3");
- }
-
- @Test
- public void shouldFailWithInvalidEnvironmentProperties() {
- env.put("SONARQUBE_SCANNER_PARAMS", "{sonar.key1: \"v1\", \"sonar.key2\" : \"v2\"}");
-
- assertThatIllegalStateException()
- .isThrownBy(conf::properties)
- .withMessage("Failed to parse JSON in SONARQUBE_SCANNER_PARAMS environment variable");
- }
-
- @Test
public void shouldSupportDeepModuleConfigurationInRoot() throws Exception {
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldSupportDeepModuleConfigurationInRoot/project").toURI());
args.setProperty("project.home", projectHome.toAbsolutePath().toString());
@@ -329,23 +308,4 @@ public class ConfTest {
assertThat(properties).containsEntry("sonar.prop", "expected");
}
- // SQSCANNER-61
- @Test
- public void should_load_project_settings_using_env() throws Exception {
- Path home = Paths.get(getClass().getResource("ConfTest/shouldOverrideProjectSettingsPath/").toURI());
- args.setProperty("project.home", home.toAbsolutePath().toString());
-
- Properties properties = conf.properties();
- assertThat(properties).containsEntry("sonar.prop", "default");
-
- String jsonString = Json.object()
- .add("project.settings", home.resolve("conf/sq-project.properties").toAbsolutePath().toString())
- .toString();
-
- env.put("SONARQUBE_SCANNER_PARAMS", jsonString);
-
- properties = conf.properties();
- assertThat(properties).containsEntry("sonar.prop", "expected");
- }
-
}
diff --git a/src/test/java/org/sonarsource/scanner/cli/LogsTest.java b/src/test/java/org/sonarsource/scanner/cli/LogsTest.java
index e664365..82a26ad 100644
--- a/src/test/java/org/sonarsource/scanner/cli/LogsTest.java
+++ b/src/test/java/org/sonarsource/scanner/cli/LogsTest.java
@@ -25,7 +25,10 @@ import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.sonarsource.scanner.lib.LogOutput;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -89,4 +92,37 @@ public class LogsTest {
logs.debug("debug");
verifyNoMoreInteractions(stdOut, stdErr);
}
+
+ @Test
+ public void should_forward_logs() {
+ var mockedLogs = mock(Logs.class);
+ var logOutput = new Logs.LogOutputAdapter(mockedLogs);
+
+ String msg = "test";
+
+ logOutput.log(msg, LogOutput.Level.DEBUG);
+ verify(mockedLogs).debug(msg);
+ verifyNoMoreInteractions(mockedLogs);
+ reset(mockedLogs);
+
+ logOutput.log(msg, LogOutput.Level.INFO);
+ verify(mockedLogs).info(msg);
+ verifyNoMoreInteractions(mockedLogs);
+ reset(mockedLogs);
+
+ logOutput.log(msg, LogOutput.Level.ERROR);
+ verify(mockedLogs).error(msg);
+ verifyNoMoreInteractions(mockedLogs);
+ reset(mockedLogs);
+
+ logOutput.log(msg, LogOutput.Level.WARN);
+ verify(mockedLogs).warn(msg);
+ verifyNoMoreInteractions(mockedLogs);
+ reset(mockedLogs);
+
+ logOutput.log(msg, LogOutput.Level.TRACE);
+ verify(mockedLogs).debug(msg);
+ verifyNoMoreInteractions(mockedLogs);
+ reset(mockedLogs);
+ }
}
diff --git a/src/test/java/org/sonarsource/scanner/cli/MainTest.java b/src/test/java/org/sonarsource/scanner/cli/MainTest.java
index 85f233c..6b8099d 100644
--- a/src/test/java/org/sonarsource/scanner/cli/MainTest.java
+++ b/src/test/java/org/sonarsource/scanner/cli/MainTest.java
@@ -29,14 +29,14 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.sonar.api.utils.MessageException;
-import org.sonarsource.scanner.api.EmbeddedScanner;
-import org.sonarsource.scanner.api.ScanProperties;
+import org.sonarsource.scanner.lib.ScanProperties;
+import org.sonarsource.scanner.lib.ScannerEngineBootstrapper;
+import org.sonarsource.scanner.lib.ScannerEngineFacade;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -53,63 +53,62 @@ public class MainTest {
@Mock
private Properties properties;
@Mock
- private ScannerFactory scannerFactory;
+ private ScannerEngineBootstrapperFactory scannerEngineBootstrapperFactory;
@Mock
- private EmbeddedScanner scanner;
+ private ScannerEngineBootstrapper bootstrapper;
+ @Mock
+ private ScannerEngineFacade engine;
@Mock
private Logs logs;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(scannerFactory.create(any(Properties.class), any(String.class))).thenReturn(scanner);
+ when(scannerEngineBootstrapperFactory.create(any(Properties.class), any(String.class))).thenReturn(bootstrapper);
+ when(bootstrapper.bootstrap()).thenReturn(engine);
when(conf.properties()).thenReturn(properties);
}
@Test
- public void should_execute_runner() {
+ public void should_execute_scanner_engine() {
when(cli.getInvokedFrom()).thenReturn("");
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
verify(exit).exit(Exit.SUCCESS);
- verify(scannerFactory).create(properties, "");
+ verify(scannerEngineBootstrapperFactory).create(properties, "");
- verify(scanner, times(1)).start();
- verify(scanner, times(1)).execute((Map) properties);
+ verify(bootstrapper, times(1)).bootstrap();
+ verify(engine, times(1)).analyze((Map) properties);
}
@Test
public void should_exit_with_error_on_error_during_analysis() {
- EmbeddedScanner runner = mock(EmbeddedScanner.class);
Exception e = new NullPointerException("NPE");
e = new IllegalStateException("Error", e);
- doThrow(e).when(runner).execute(any());
+ doThrow(e).when(engine).analyze(any());
when(cli.getInvokedFrom()).thenReturn("");
- when(scannerFactory.create(any(Properties.class), any(String.class))).thenReturn(runner);
when(cli.isDebugEnabled()).thenReturn(true);
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
verify(exit).exit(Exit.INTERNAL_ERROR);
verify(logs).error("Error during SonarScanner execution", e);
}
@Test
- public void should_exit_with_error_on_error_during_start() {
- EmbeddedScanner runner = mock(EmbeddedScanner.class);
+ public void should_exit_with_error_on_error_during_bootstrap() {
Exception e = new NullPointerException("NPE");
e = new IllegalStateException("Error", e);
- doThrow(e).when(runner).start();
+ doThrow(e).when(bootstrapper).bootstrap();
when(cli.getInvokedFrom()).thenReturn("");
when(cli.isDebugEnabled()).thenReturn(true);
- when(scannerFactory.create(any(Properties.class), any(String.class))).thenReturn(runner);
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
- verify(runner).start();
- verify(runner, never()).execute(any());
+ verify(bootstrapper).bootstrap();
+ verify(engine, never()).analyze(any());
verify(exit).exit(Exit.INTERNAL_ERROR);
verify(logs).error("Error during SonarScanner execution", e);
}
@@ -180,13 +179,13 @@ public class MainTest {
when(cli.isEmbedded()).thenReturn(isEmbedded);
when(cli.getInvokedFrom()).thenReturn("");
- EmbeddedScanner runner = mock(EmbeddedScanner.class);
- doThrow(e).when(runner).execute(any());
- when(scannerFactory.create(any(Properties.class), any(String.class))).thenReturn(runner);
+ doThrow(e).when(engine).analyze(any());
+
+ when(scannerEngineBootstrapperFactory.create(any(Properties.class), any(String.class))).thenReturn(bootstrapper);
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
verify(exit).exit(expectedExitCode);
}
@@ -209,13 +208,13 @@ public class MainTest {
when(cli.getInvokedFrom()).thenReturn("");
when(conf.properties()).thenReturn(p);
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
- InOrder inOrder = Mockito.inOrder(exit, scannerFactory);
+ InOrder inOrder = Mockito.inOrder(exit, scannerEngineBootstrapperFactory);
inOrder.verify(exit, times(1)).exit(Exit.SUCCESS);
- inOrder.verify(scannerFactory, times(1)).create(p, "");
+ inOrder.verify(scannerEngineBootstrapperFactory, times(1)).create(p, "");
inOrder.verify(exit, times(1)).exit(Exit.SUCCESS);
}
@@ -226,67 +225,43 @@ public class MainTest {
when(conf.properties()).thenReturn(p);
when(cli.getInvokedFrom()).thenReturn("");
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
verify(logs).info("SonarScanner analysis skipped");
- InOrder inOrder = Mockito.inOrder(exit, scannerFactory);
+ InOrder inOrder = Mockito.inOrder(exit, scannerEngineBootstrapperFactory);
inOrder.verify(exit, times(1)).exit(Exit.SUCCESS);
- inOrder.verify(scannerFactory, times(1)).create(p, "");
+ inOrder.verify(scannerEngineBootstrapperFactory, times(1)).create(p, "");
inOrder.verify(exit, times(1)).exit(Exit.SUCCESS);
}
@Test
public void shouldLogServerVersion() {
- when(scanner.serverVersion()).thenReturn("5.5");
+ when(engine.isSonarCloud()).thenReturn(false);
+ when(engine.getServerVersion()).thenReturn("5.5");
Properties p = new Properties();
when(cli.isDisplayVersionOnly()).thenReturn(true);
when(cli.getInvokedFrom()).thenReturn("");
when(conf.properties()).thenReturn(p);
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
verify(logs).info("Analyzing on SonarQube server 5.5");
}
@Test
public void should_log_SonarCloud_server() {
+ when(engine.isSonarCloud()).thenReturn(true);
Properties p = new Properties();
- p.setProperty("sonar.host.url", "https://sonarcloud.io");
when(conf.properties()).thenReturn(p);
when(cli.getInvokedFrom()).thenReturn("");
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
verify(logs).info("Analyzing on SonarCloud");
}
- // SQSCANNER-57
- @Test
- public void should_return_true_is_sonar_cloud() {
-
- Properties properties = new Properties();
- properties.setProperty("sonar.host.url", "https://sonarcloud.io");
-
- assertThat(Main.isSonarCloud(properties)).isTrue();
- }
-
- // SQSCANNER-57
- @Test
- public void should_return_false_is_sonar_cloud() {
- Properties properties = new Properties();
- properties.setProperty("sonar.host.url", "https://mysonarqube.com:9000/");
-
- assertThat(Main.isSonarCloud(properties)).isFalse();
- }
-
- // SQSCANNER-57
- @Test
- public void should_return_false_is_sonar_cloud_host_is_null() {
- assertThat(Main.isSonarCloud(new Properties())).isFalse();
- }
-
@Test
public void should_configure_logging() {
Properties analysisProps = testLogging("sonar.verbose", "true");
@@ -327,11 +302,11 @@ public class MainTest {
when(conf.properties()).thenReturn(p);
when(cli.getInvokedFrom()).thenReturn("");
- Main main = new Main(exit, cli, conf, scannerFactory, logs);
- main.execute();
+ Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs);
+ main.analyze();
ArgumentCaptor<Properties> propertiesCapture = ArgumentCaptor.forClass(Properties.class);
- verify(scanner).execute((Map) propertiesCapture.capture());
+ verify(engine).analyze((Map) propertiesCapture.capture());
return propertiesCapture.getValue();
}
diff --git a/src/test/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactoryTest.java b/src/test/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactoryTest.java
new file mode 100644
index 0000000..f3ae408
--- /dev/null
+++ b/src/test/java/org/sonarsource/scanner/cli/ScannerEngineBootstrapperFactoryTest.java
@@ -0,0 +1,84 @@
+/*
+ * SonarScanner CLI
+ * Copyright (C) 2011-2024 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.sonarsource.scanner.cli;
+
+import java.util.Properties;
+import org.junit.Test;
+import org.sonarsource.scanner.lib.ScannerEngineBootstrapper;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ScannerEngineBootstrapperFactoryTest {
+
+ private final Properties props = new Properties();
+ private final Logs logs = mock(Logs.class);
+ private ScannerEngineBootstrapperFactory underTest = new ScannerEngineBootstrapperFactory(logs);
+
+ @Test
+ public void should_create_engine_bootstrapper_and_pass_app_and_properties() {
+ props.setProperty("foo", "bar");
+ var spy = spy(underTest);
+ var mockedBootstrapper = mock(ScannerEngineBootstrapper.class);
+ when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper);
+ when(spy.newScannerEngineBootstrapper(any(), any())).thenReturn(mockedBootstrapper);
+
+ var bootstrapper = spy.create(props, "");
+
+ assertThat(bootstrapper).isNotNull();
+ verify(spy).newScannerEngineBootstrapper(eq("ScannerCLI"), notNull());
+ verify(mockedBootstrapper).addBootstrapProperties(argThat(props::equals));
+ }
+
+ @Test
+ public void should_create_engine_bootstrapper_with_app_from_argument() {
+ var spy = spy(underTest);
+ var mockedBootstrapper = mock(ScannerEngineBootstrapper.class);
+ when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper);
+ when(spy.newScannerEngineBootstrapper(any(), any())).thenReturn(mockedBootstrapper);
+
+ var bootstrapper = spy.create(props, "ScannerMSBuild/4.8.0");
+
+ assertThat(bootstrapper).isNotNull();
+ verify(spy).newScannerEngineBootstrapper("ScannerMSBuild", "4.8.0");
+ }
+
+ @Test
+ public void if_from_argument_is_not_regex_compliant_revert_to_default_scanner_name() {
+ var spy = spy(underTest);
+ var mockedBootstrapper = mock(ScannerEngineBootstrapper.class);
+ when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper);
+ when(spy.newScannerEngineBootstrapper(any(), any())).thenReturn(mockedBootstrapper);
+
+ var bootstrapper = spy.create(props, "ScannerMSBuild4.8.0WithoutSlash");
+
+ assertThat(bootstrapper).isNotNull();
+ verify(spy).newScannerEngineBootstrapper(eq("ScannerCLI"), notNull());
+ }
+
+
+}
diff --git a/src/test/java/org/sonarsource/scanner/cli/ScannerFactoryTest.java b/src/test/java/org/sonarsource/scanner/cli/ScannerFactoryTest.java
deleted file mode 100644
index 289da0a..0000000
--- a/src/test/java/org/sonarsource/scanner/cli/ScannerFactoryTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * SonarScanner CLI
- * Copyright (C) 2011-2024 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.sonarsource.scanner.cli;
-
-import java.util.Properties;
-import org.junit.Test;
-import org.sonarsource.scanner.api.EmbeddedScanner;
-import org.sonarsource.scanner.api.LogOutput;
-import org.sonarsource.scanner.api.LogOutput.Level;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class ScannerFactoryTest {
-
- private final Properties props = new Properties();
- private final Logs logs = mock(Logs.class);
-
- @Test
- public void should_create_embedded_runner() {
- props.setProperty("foo", "bar");
- EmbeddedScanner runner = new ScannerFactory(logs).create(props, "");
-
- assertThat(runner).isInstanceOf(EmbeddedScanner.class);
- assertThat(runner.globalProperties()).containsEntry("foo", "bar");
- assertThat(runner.app()).isEqualTo("ScannerCLI");
- assertThat(runner.appVersion()).isNotNull();
- }
-
- @Test
- public void should_create_embedded_runner_with_scannername_from_argument() {
- props.setProperty("foo", "bar");
- EmbeddedScanner runner = new ScannerFactory(logs).create(props, "ScannerMSBuild/4.8.0");
-
- assertThat(runner).isInstanceOf(EmbeddedScanner.class);
- assertThat(runner.globalProperties()).containsEntry("foo", "bar");
- assertThat(runner.app()).isEqualTo("ScannerMSBuild");
- assertThat(runner.appVersion()).isEqualTo("4.8.0");
- assertThat(runner.appVersion()).isNotNull();
- }
-
- @Test
- public void should_create_embedded_runner_from_argument_is_not_regex_compliant_revert_to_default_scanner_name() {
- props.setProperty("foo", "bar");
- EmbeddedScanner runner = new ScannerFactory(logs).create(props, "ScannerMSBuild4.8.0");
-
- assertThat(runner).isInstanceOf(EmbeddedScanner.class);
- assertThat(runner.globalProperties()).containsEntry("foo", "bar");
- assertThat(runner.app()).isEqualTo("ScannerCLI");
- assertThat(runner.appVersion()).isNotNull();
- }
-
- @Test
- public void should_fwd_logs() {
- LogOutput logOutput = new ScannerFactory(logs).new DefaultLogOutput();
-
- String msg = "test";
-
- logOutput.log(msg, Level.DEBUG);
- verify(logs).debug(msg);
- verifyNoMoreInteractions(logs);
- reset(logs);
-
- logOutput.log(msg, Level.INFO);
- verify(logs).info(msg);
- verifyNoMoreInteractions(logs);
- reset(logs);
-
- logOutput.log(msg, Level.ERROR);
- verify(logs).error(msg);
- verifyNoMoreInteractions(logs);
- reset(logs);
-
- logOutput.log(msg, Level.WARN);
- verify(logs).warn(msg);
- verifyNoMoreInteractions(logs);
- reset(logs);
-
- logOutput.log(msg, Level.TRACE);
- verify(logs).debug(msg);
- verifyNoMoreInteractions(logs);
- reset(logs);
- }
-
-}