<dependencies> | <dependencies> | ||||
<dependency> | <dependency> | ||||
<groupId>org.sonarsource.scanner.api</groupId> | |||||
<artifactId>sonar-scanner-api</artifactId> | |||||
<version>2.16.3.1081</version> | |||||
<groupId>org.sonarsource.scanner.lib</groupId> | |||||
<artifactId>sonar-scanner-java-library</artifactId> | |||||
<version>3.0.0.74</version> | |||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
<groupId>com.google.code.findbugs</groupId> | <groupId>com.google.code.findbugs</groupId> | ||||
<dependency> | <dependency> | ||||
<groupId>org.assertj</groupId> | <groupId>org.assertj</groupId> | ||||
<artifactId>assertj-core</artifactId> | <artifactId>assertj-core</artifactId> | ||||
<version>3.23.1</version> | |||||
<version>3.24.2</version> | |||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
<groupId>org.mockito</groupId> | <groupId>org.mockito</groupId> | ||||
<artifactId>mockito-core</artifactId> | <artifactId>mockito-core</artifactId> | ||||
<version>4.10.0</version> | |||||
<version>5.10.0</version> | |||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
</dependencies> | </dependencies> | ||||
<plugin> | <plugin> | ||||
<groupId>org.apache.maven.plugins</groupId> | <groupId>org.apache.maven.plugins</groupId> | ||||
<artifactId>maven-shade-plugin</artifactId> | <artifactId>maven-shade-plugin</artifactId> | ||||
<version>3.5.0</version> | |||||
<version>3.5.1</version> | |||||
<executions> | <executions> | ||||
<execution> | <execution> | ||||
<phase>package</phase> | <phase>package</phase> | ||||
<configuration> | <configuration> | ||||
<rules> | <rules> | ||||
<requireFilesSize> | <requireFilesSize> | ||||
<minsize>560000</minsize> | |||||
<maxsize>600000</maxsize> | |||||
<minsize>3000000</minsize> | |||||
<maxsize>3100000</maxsize> | |||||
<files> | <files> | ||||
<file>${project.build.directory}/sonar-scanner-${project.version}.zip</file> | <file>${project.build.directory}/sonar-scanner-${project.version}.zip</file> | ||||
</files> | </files> | ||||
</build> | </build> | ||||
<profiles> | <profiles> | ||||
<profile> | |||||
<id>it</id> | |||||
<modules> | |||||
<module>it</module> | |||||
</modules> | |||||
</profile> | |||||
<profile> | <profile> | ||||
<id>dist-linux</id> | <id>dist-linux</id> | ||||
<build> | <build> |
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import org.sonarsource.scanner.api.ScannerProperties; | |||||
import static java.util.Arrays.asList; | import static java.util.Arrays.asList; | ||||
private int processNextArg(String[] args, int pos) { | private int processNextArg(String[] args, int pos) { | ||||
String arg = args[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(); | printUsage(); | ||||
exit.exit(Exit.SUCCESS); | exit.exit(Exit.SUCCESS); | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import javax.annotation.Nullable; | import javax.annotation.Nullable; | ||||
import org.sonarsource.scanner.api.Utils; | |||||
import org.sonarsource.scanner.lib.EnvironmentConfig; | |||||
class Conf { | class Conf { | ||||
private static final String SCANNER_HOME = "scanner.home"; | private static final String SCANNER_HOME = "scanner.home"; | ||||
return resolver.resolve(); | return resolver.resolve(); | ||||
} | } | ||||
private Properties loadEnvironmentProperties() { | |||||
return Utils.loadEnvironmentProperties(env); | |||||
private Map<String, String> loadEnvironmentProperties() { | |||||
return EnvironmentConfig.load(logger.getLogOutputAdapter()); | |||||
} | } | ||||
private Properties loadGlobalProperties() { | private Properties loadGlobalProperties() { |
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import java.time.LocalTime; | import java.time.LocalTime; | ||||
import java.time.format.DateTimeFormatter; | import java.time.format.DateTimeFormatter; | ||||
import org.sonarsource.scanner.lib.LogOutput; | |||||
public class Logs { | public class Logs { | ||||
private DateTimeFormatter timeFormatter; | private DateTimeFormatter timeFormatter; | ||||
stream.println(msg); | 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); | |||||
} | |||||
} | |||||
} | |||||
} | } |
*/ | */ | ||||
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import java.util.Locale; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | 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 : | * Arguments : | ||||
private final Exit exit; | private final Exit exit; | ||||
private final Cli cli; | private final Cli cli; | ||||
private final Conf conf; | private final Conf conf; | ||||
private EmbeddedScanner embeddedScanner; | |||||
private final ScannerFactory runnerFactory; | |||||
private ScannerEngineBootstrapper scannerEngineBootstrapper; | |||||
private final ScannerEngineBootstrapperFactory bootstrapperFactory; | |||||
private final Logs logger; | 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.exit = exit; | ||||
this.cli = cli; | this.cli = cli; | ||||
this.conf = conf; | this.conf = conf; | ||||
this.runnerFactory = runnerFactory; | |||||
this.bootstrapperFactory = bootstrapperFactory; | |||||
this.logger = logger; | this.logger = logger; | ||||
} | } | ||||
Logs logs = new Logs(System.out, System.err); | Logs logs = new Logs(System.out, System.err); | ||||
Exit exit = new Exit(); | Exit exit = new Exit(); | ||||
Cli cli = new Cli(exit, logs).parse(args); | 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(); | Stats stats = new Stats(logger).start(); | ||||
int status = Exit.INTERNAL_ERROR; | int status = Exit.INTERNAL_ERROR; | ||||
checkSkip(p); | checkSkip(p); | ||||
configureLogging(p); | configureLogging(p); | ||||
init(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) { | } catch (Throwable e) { | ||||
displayExecutionResult(stats, "FAILURE"); | displayExecutionResult(stats, "FAILURE"); | ||||
showError("Error during SonarScanner execution", e, cli.isDebugEnabled()); | showError("Error during SonarScanner execution", e, cli.isDebugEnabled()); | ||||
} | } | ||||
} | } | ||||
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) { | private void checkSkip(Properties properties) { | ||||
exit.exit(Exit.SUCCESS); | exit.exit(Exit.SUCCESS); | ||||
} | } | ||||
embeddedScanner = runnerFactory.create(p, cli.getInvokedFrom()); | |||||
scannerEngineBootstrapper = bootstrapperFactory.create(p, cli.getInvokedFrom()); | |||||
} | } | ||||
private void configureLogging(Properties props) { | private void configureLogging(Properties props) { | ||||
} | } | ||||
} | } | ||||
private void execute(Stats stats, Properties p) { | |||||
embeddedScanner.execute((Map) p); | |||||
displayExecutionResult(stats, "SUCCESS"); | |||||
} | |||||
private void displayExecutionResult(Stats stats, String resultMsg) { | private void displayExecutionResult(Stats stats, String resultMsg) { | ||||
logger.info(SEPARATOR); | logger.info(SEPARATOR); | ||||
logger.info("EXECUTION " + resultMsg); | logger.info("EXECUTION " + resultMsg); |
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | 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; | private final Logs logger; | ||||
public ScannerFactory(Logs logger) { | |||||
public ScannerEngineBootstrapperFactory(Logs logger) { | |||||
this.logger = logger; | this.logger = logger; | ||||
} | } | ||||
EmbeddedScanner create(Properties props, String isInvokedFrom) { | |||||
ScannerEngineBootstrapper create(Properties props, String isInvokedFrom) { | |||||
String appName = "ScannerCLI"; | String appName = "ScannerCLI"; | ||||
String appVersion = ScannerVersion.version(); | String appVersion = ScannerVersion.version(); | ||||
if (!isInvokedFrom.equals("") && isInvokedFrom.contains("/")) { | |||||
if (isInvokedFrom.contains("/")) { | |||||
appName = isInvokedFrom.split("/")[0]; | appName = isInvokedFrom.split("/")[0]; | ||||
appVersion = isInvokedFrom.split("/")[1]; | 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()); | |||||
} | } | ||||
} | } |
import org.junit.Test; | import org.junit.Test; | ||||
import static org.assertj.core.api.Assertions.assertThat; | 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.mock; | ||||
import static org.mockito.Mockito.verify; | import static org.mockito.Mockito.verify; | ||||
public class CliTest { | 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 Logs logs = new Logs(System.out, System.err); | ||||
private Cli cli = new Cli(exit, logs); | private Cli cli = new Cli(exit, logs); | ||||
@Test | @Test | ||||
public void should_extract_properties() { | 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 | @Test | ||||
public void should_warn_on_duplicate_properties() { | public void should_warn_on_duplicate_properties() { | ||||
logs = mock(Logs.class); | logs = mock(Logs.class); | ||||
cli = new Cli(exit, logs); | 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'"); | verify(logs).warn("Property 'foo' with value 'bar' is overridden with value 'baz'"); | ||||
} | } | ||||
public void should_fail_on_missing_prop() { | public void should_fail_on_missing_prop() { | ||||
logs = mock(Logs.class); | logs = mock(Logs.class); | ||||
cli = new Cli(exit, logs); | 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(logs).error("Missing argument for option -D/--define"); | ||||
verify(exit).exit(Exit.INTERNAL_ERROR); | verify(exit).exit(Exit.INTERNAL_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_not_fail_with_errors_option() { | 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 | @Test | ||||
public void should_enable_debug_mode() { | public void should_enable_debug_mode() { | ||||
cli.parse(new String[] {"-X"}); | |||||
cli.parse(new String[]{"-X"}); | |||||
assertThat(cli.isDebugEnabled()).isTrue(); | assertThat(cli.isDebugEnabled()).isTrue(); | ||||
assertThat(cli.properties().get("sonar.verbose")).isEqualTo("true"); | |||||
assertThat(cli.properties()).containsEntry("sonar.verbose", "true"); | |||||
} | } | ||||
@Test | @Test | ||||
public void should_enable_debug_mode_full() { | public void should_enable_debug_mode_full() { | ||||
cli.parse(new String[] {"--debug"}); | |||||
cli.parse(new String[]{"--debug"}); | |||||
assertThat(cli.isDebugEnabled()).isTrue(); | assertThat(cli.isDebugEnabled()).isTrue(); | ||||
assertThat(cli.properties().get("sonar.verbose")).isEqualTo("true"); | |||||
assertThat(cli.properties()).containsEntry("sonar.verbose", "true"); | |||||
} | } | ||||
@Test | @Test | ||||
public void should_show_version() { | public void should_show_version() { | ||||
cli.parse(new String[] {"-v"}); | |||||
cli.parse(new String[]{"-v"}); | |||||
assertThat(cli.isDisplayVersionOnly()).isTrue(); | assertThat(cli.isDisplayVersionOnly()).isTrue(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_show_version_full() { | public void should_show_version_full() { | ||||
cli.parse(new String[] {"--version"}); | |||||
cli.parse(new String[]{"--version"}); | |||||
assertThat(cli.isDisplayVersionOnly()).isTrue(); | assertThat(cli.isDisplayVersionOnly()).isTrue(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_enable_stacktrace_log() { | public void should_enable_stacktrace_log() { | ||||
cli.parse(new String[] {"-e"}); | |||||
cli.parse(new String[]{"-e"}); | |||||
assertThat(cli.isDebugEnabled()).isFalse(); | assertThat(cli.isDebugEnabled()).isFalse(); | ||||
assertThat(cli.properties().get("sonar.verbose")).isNull(); | assertThat(cli.properties().get("sonar.verbose")).isNull(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_enable_stacktrace_log_full() { | public void should_enable_stacktrace_log_full() { | ||||
cli.parse(new String[] {"--errors"}); | |||||
cli.parse(new String[]{"--errors"}); | |||||
assertThat(cli.isDebugEnabled()).isFalse(); | assertThat(cli.isDebugEnabled()).isFalse(); | ||||
assertThat(cli.properties().get("sonar.verbose")).isNull(); | assertThat(cli.properties().get("sonar.verbose")).isNull(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_parse_from_argument() { | 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()).isNotEmpty(); | ||||
assertThat(cli.getInvokedFrom()).isEqualTo("ScannerMSBuild/4.8"); | assertThat(cli.getInvokedFrom()).isEqualTo("ScannerMSBuild/4.8"); | ||||
} | } | ||||
@Test | @Test | ||||
public void from_argument_is_only_from_let_value_empty() { | public void from_argument_is_only_from_let_value_empty() { | ||||
cli.parse(new String[] {"--from="}); | |||||
cli.parse(new String[]{"--from="}); | |||||
assertThat(cli.getInvokedFrom()).isEmpty(); | assertThat(cli.getInvokedFrom()).isEmpty(); | ||||
} | } | ||||
public void should_show_usage() { | public void should_show_usage() { | ||||
logs = mock(Logs.class); | logs = mock(Logs.class); | ||||
cli = new Cli(exit, logs); | cli = new Cli(exit, logs); | ||||
cli.parse(new String[] {"-h"}); | |||||
cli.parse(new String[]{"-h"}); | |||||
verify(logs).info("usage: sonar-scanner [options]"); | verify(logs).info("usage: sonar-scanner [options]"); | ||||
verify(exit).exit(Exit.SUCCESS); | verify(exit).exit(Exit.SUCCESS); | ||||
} | } | ||||
public void should_show_usage_full() { | public void should_show_usage_full() { | ||||
logs = mock(Logs.class); | logs = mock(Logs.class); | ||||
cli = new Cli(exit, logs); | cli = new Cli(exit, logs); | ||||
cli.parse(new String[] {"--help"}); | |||||
cli.parse(new String[]{"--help"}); | |||||
verify(logs).info("usage: sonar-scanner [options]"); | verify(logs).info("usage: sonar-scanner [options]"); | ||||
verify(exit).exit(Exit.SUCCESS); | verify(exit).exit(Exit.SUCCESS); | ||||
} | } | ||||
public void should_show_usage_on_bad_syntax() { | public void should_show_usage_on_bad_syntax() { | ||||
logs = mock(Logs.class); | logs = mock(Logs.class); | ||||
cli = new Cli(exit, logs); | cli = new Cli(exit, logs); | ||||
cli.parse(new String[] {"-w"}); | |||||
cli.parse(new String[]{"-w"}); | |||||
verify(logs).error("Unrecognized option: -w"); | verify(logs).error("Unrecognized option: -w"); | ||||
verify(logs).info("usage: sonar-scanner [options]"); | verify(logs).info("usage: sonar-scanner [options]"); | ||||
verify(exit).exit(Exit.INTERNAL_ERROR); | verify(exit).exit(Exit.INTERNAL_ERROR); | ||||
@Test | @Test | ||||
public void should_enable_embedded_mode() { | public void should_enable_embedded_mode() { | ||||
cli.parse(new String[] {"--embedded"}); | |||||
cli.parse(new String[]{"--embedded"}); | |||||
assertThat(cli.isEmbedded()).isTrue(); | assertThat(cli.isEmbedded()).isTrue(); | ||||
} | } | ||||
} | } |
import org.junit.Rule; | import org.junit.Rule; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.junit.rules.TemporaryFolder; | 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.assertThat; | ||||
import static org.assertj.core.api.Assertions.assertThatCode; | import static org.assertj.core.api.Assertions.assertThatCode; | ||||
assertThat(properties.getProperty("sonar.projectBaseDir")).isEqualTo(projectHome.toString()); | assertThat(properties.getProperty("sonar.projectBaseDir")).isEqualTo(projectHome.toString()); | ||||
} | } | ||||
@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 | @Test | ||||
public void shouldSupportDeepModuleConfigurationInRoot() throws Exception { | public void shouldSupportDeepModuleConfigurationInRoot() throws Exception { | ||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldSupportDeepModuleConfigurationInRoot/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldSupportDeepModuleConfigurationInRoot/project").toURI()); | ||||
assertThat(properties).containsEntry("sonar.prop", "expected"); | 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"); | |||||
} | |||||
} | } |
import org.mockito.ArgumentMatchers; | import org.mockito.ArgumentMatchers; | ||||
import org.mockito.Mock; | import org.mockito.Mock; | ||||
import org.mockito.MockitoAnnotations; | 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.verify; | ||||
import static org.mockito.Mockito.verifyNoMoreInteractions; | import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
logs.debug("debug"); | logs.debug("debug"); | ||||
verifyNoMoreInteractions(stdOut, stdErr); | 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); | |||||
} | |||||
} | } |
import org.mockito.Mockito; | import org.mockito.Mockito; | ||||
import org.mockito.MockitoAnnotations; | import org.mockito.MockitoAnnotations; | ||||
import org.sonar.api.utils.MessageException; | 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.assertj.core.api.Assertions.assertThat; | ||||
import static org.mockito.ArgumentMatchers.any; | import static org.mockito.ArgumentMatchers.any; | ||||
import static org.mockito.ArgumentMatchers.anyString; | import static org.mockito.ArgumentMatchers.anyString; | ||||
import static org.mockito.Mockito.doThrow; | import static org.mockito.Mockito.doThrow; | ||||
import static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.never; | import static org.mockito.Mockito.never; | ||||
import static org.mockito.Mockito.times; | import static org.mockito.Mockito.times; | ||||
import static org.mockito.Mockito.verify; | import static org.mockito.Mockito.verify; | ||||
@Mock | @Mock | ||||
private Properties properties; | private Properties properties; | ||||
@Mock | @Mock | ||||
private ScannerFactory scannerFactory; | |||||
private ScannerEngineBootstrapperFactory scannerEngineBootstrapperFactory; | |||||
@Mock | @Mock | ||||
private EmbeddedScanner scanner; | |||||
private ScannerEngineBootstrapper bootstrapper; | |||||
@Mock | |||||
private ScannerEngineFacade engine; | |||||
@Mock | @Mock | ||||
private Logs logs; | private Logs logs; | ||||
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
MockitoAnnotations.initMocks(this); | 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); | when(conf.properties()).thenReturn(properties); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_execute_runner() { | |||||
public void should_execute_scanner_engine() { | |||||
when(cli.getInvokedFrom()).thenReturn(""); | 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(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 | @Test | ||||
public void should_exit_with_error_on_error_during_analysis() { | public void should_exit_with_error_on_error_during_analysis() { | ||||
EmbeddedScanner runner = mock(EmbeddedScanner.class); | |||||
Exception e = new NullPointerException("NPE"); | Exception e = new NullPointerException("NPE"); | ||||
e = new IllegalStateException("Error", e); | e = new IllegalStateException("Error", e); | ||||
doThrow(e).when(runner).execute(any()); | |||||
doThrow(e).when(engine).analyze(any()); | |||||
when(cli.getInvokedFrom()).thenReturn(""); | when(cli.getInvokedFrom()).thenReturn(""); | ||||
when(scannerFactory.create(any(Properties.class), any(String.class))).thenReturn(runner); | |||||
when(cli.isDebugEnabled()).thenReturn(true); | 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(exit).exit(Exit.INTERNAL_ERROR); | ||||
verify(logs).error("Error during SonarScanner execution", e); | verify(logs).error("Error during SonarScanner execution", e); | ||||
} | } | ||||
@Test | @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"); | Exception e = new NullPointerException("NPE"); | ||||
e = new IllegalStateException("Error", e); | e = new IllegalStateException("Error", e); | ||||
doThrow(e).when(runner).start(); | |||||
doThrow(e).when(bootstrapper).bootstrap(); | |||||
when(cli.getInvokedFrom()).thenReturn(""); | when(cli.getInvokedFrom()).thenReturn(""); | ||||
when(cli.isDebugEnabled()).thenReturn(true); | 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(exit).exit(Exit.INTERNAL_ERROR); | ||||
verify(logs).error("Error during SonarScanner execution", e); | verify(logs).error("Error during SonarScanner execution", e); | ||||
} | } | ||||
when(cli.isEmbedded()).thenReturn(isEmbedded); | when(cli.isEmbedded()).thenReturn(isEmbedded); | ||||
when(cli.getInvokedFrom()).thenReturn(""); | 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); | verify(exit).exit(expectedExitCode); | ||||
} | } | ||||
when(cli.getInvokedFrom()).thenReturn(""); | when(cli.getInvokedFrom()).thenReturn(""); | ||||
when(conf.properties()).thenReturn(p); | 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(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); | inOrder.verify(exit, times(1)).exit(Exit.SUCCESS); | ||||
} | } | ||||
when(conf.properties()).thenReturn(p); | when(conf.properties()).thenReturn(p); | ||||
when(cli.getInvokedFrom()).thenReturn(""); | 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"); | 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(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); | inOrder.verify(exit, times(1)).exit(Exit.SUCCESS); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldLogServerVersion() { | public void shouldLogServerVersion() { | ||||
when(scanner.serverVersion()).thenReturn("5.5"); | |||||
when(engine.isSonarCloud()).thenReturn(false); | |||||
when(engine.getServerVersion()).thenReturn("5.5"); | |||||
Properties p = new Properties(); | Properties p = new Properties(); | ||||
when(cli.isDisplayVersionOnly()).thenReturn(true); | when(cli.isDisplayVersionOnly()).thenReturn(true); | ||||
when(cli.getInvokedFrom()).thenReturn(""); | when(cli.getInvokedFrom()).thenReturn(""); | ||||
when(conf.properties()).thenReturn(p); | 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"); | verify(logs).info("Analyzing on SonarQube server 5.5"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_log_SonarCloud_server() { | public void should_log_SonarCloud_server() { | ||||
when(engine.isSonarCloud()).thenReturn(true); | |||||
Properties p = new Properties(); | Properties p = new Properties(); | ||||
p.setProperty("sonar.host.url", "https://sonarcloud.io"); | |||||
when(conf.properties()).thenReturn(p); | when(conf.properties()).thenReturn(p); | ||||
when(cli.getInvokedFrom()).thenReturn(""); | 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"); | 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 | @Test | ||||
public void should_configure_logging() { | public void should_configure_logging() { | ||||
Properties analysisProps = testLogging("sonar.verbose", "true"); | Properties analysisProps = testLogging("sonar.verbose", "true"); | ||||
when(conf.properties()).thenReturn(p); | when(conf.properties()).thenReturn(p); | ||||
when(cli.getInvokedFrom()).thenReturn(""); | 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); | ArgumentCaptor<Properties> propertiesCapture = ArgumentCaptor.forClass(Properties.class); | ||||
verify(scanner).execute((Map) propertiesCapture.capture()); | |||||
verify(engine).analyze((Map) propertiesCapture.capture()); | |||||
return propertiesCapture.getValue(); | return propertiesCapture.getValue(); | ||||
} | } |
/* | |||||
* 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()); | |||||
} | |||||
} |
/* | |||||
* 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); | |||||
} | |||||
} |