<!-- Unit tests --> | <!-- Unit tests --> | ||||
<dependency> | <dependency> | ||||
<groupId>junit</groupId> | |||||
<artifactId>junit</artifactId> | |||||
<version>4.13.2</version> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>commons-lang</groupId> | |||||
<artifactId>commons-lang</artifactId> | |||||
<version>2.6</version> | |||||
<groupId>org.junit.jupiter</groupId> | |||||
<artifactId>junit-jupiter-engine</artifactId> | |||||
<version>5.10.1</version> | |||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> |
*/ | */ | ||||
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.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.assertThatNoException; | ||||
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 { | |||||
class CliTest { | |||||
private final 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_parse_empty_arguments() { | |||||
void should_parse_empty_arguments() { | |||||
cli.parse(new String[0]); | cli.parse(new String[0]); | ||||
assertThat(cli.properties()).isNotEmpty(); | assertThat(cli.properties()).isNotEmpty(); | ||||
assertThat(cli.isDebugEnabled()).isFalse(); | assertThat(cli.isDebugEnabled()).isFalse(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_extract_properties() { | |||||
void should_extract_properties() { | |||||
cli.parse(new String[]{"-D", "foo=bar", "--define", "hello=world", "-Dboolean"}); | cli.parse(new String[]{"-D", "foo=bar", "--define", "hello=world", "-Dboolean"}); | ||||
assertThat(cli.properties()).contains( | assertThat(cli.properties()).contains( | ||||
entry("foo", "bar"), | entry("foo", "bar"), | ||||
} | } | ||||
@Test | @Test | ||||
public void should_warn_on_duplicate_properties() { | |||||
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"}); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_fail_on_missing_prop() { | |||||
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"}); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_not_fail_with_errors_option() { | |||||
void should_not_fail_with_errors_option() { | |||||
assertThatNoException().isThrownBy(() -> cli.parse(new String[]{"-e"})); | assertThatNoException().isThrownBy(() -> cli.parse(new String[]{"-e"})); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_enable_debug_mode() { | |||||
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()).containsEntry("sonar.verbose", "true"); | assertThat(cli.properties()).containsEntry("sonar.verbose", "true"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_enable_debug_mode_full() { | |||||
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()).containsEntry("sonar.verbose", "true"); | assertThat(cli.properties()).containsEntry("sonar.verbose", "true"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_show_version() { | |||||
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() { | |||||
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() { | |||||
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() { | |||||
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() { | |||||
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() { | |||||
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(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_disable_debug_mode_and_stacktrace_log_by_default() { | |||||
void should_disable_debug_mode_and_stacktrace_log_by_default() { | |||||
cli.parse(new String[0]); | cli.parse(new String[0]); | ||||
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_show_usage() { | |||||
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"}); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_show_usage_full() { | |||||
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"}); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_show_usage_on_bad_syntax() { | |||||
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"}); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_enable_embedded_mode() { | |||||
void should_enable_embedded_mode() { | |||||
cli.parse(new String[]{"--embedded"}); | cli.parse(new String[]{"--embedded"}); | ||||
assertThat(cli.isEmbedded()).isTrue(); | assertThat(cli.isEmbedded()).isTrue(); | ||||
} | } |
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import org.apache.commons.lang.SystemUtils; | |||||
import org.junit.Before; | |||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.junit.rules.TemporaryFolder; | |||||
import org.apache.commons.lang3.SystemUtils; | |||||
import org.junit.jupiter.api.BeforeEach; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.junit.jupiter.api.io.TempDir; | |||||
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; | ||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException; | import static org.assertj.core.api.Assertions.assertThatIllegalStateException; | ||||
import static org.junit.Assume.assumeTrue; | |||||
import static org.junit.jupiter.api.Assumptions.assumeTrue; | |||||
import static org.mockito.Mockito.mock; | import static org.mockito.Mockito.mock; | ||||
import static org.mockito.Mockito.when; | import static org.mockito.Mockito.when; | ||||
public class ConfTest { | |||||
@Rule | |||||
public TemporaryFolder temp = new TemporaryFolder(); | |||||
class ConfTest { | |||||
private final Map<String, String> env = new HashMap<>(); | private final Map<String, String> env = new HashMap<>(); | ||||
private final Properties args = new Properties(); | private final Properties args = new Properties(); | ||||
private final Cli cli = mock(Cli.class); | private final Cli cli = mock(Cli.class); | ||||
private final Conf conf = new Conf(cli, logs, env); | private final Conf conf = new Conf(cli, logs, env); | ||||
@Before | |||||
public void initConf() { | |||||
@BeforeEach | |||||
void initConf() { | |||||
env.clear(); | env.clear(); | ||||
when(cli.properties()).thenReturn(args); | when(cli.properties()).thenReturn(args); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_load_global_settings_by_home() throws Exception { | |||||
void should_load_global_settings_by_home() throws Exception { | |||||
Path home = Paths.get(getClass().getResource("ConfTest/shouldLoadRunnerSettingsByHome/").toURI()); | Path home = Paths.get(getClass().getResource("ConfTest/shouldLoadRunnerSettingsByHome/").toURI()); | ||||
args.setProperty("scanner.home", home.toAbsolutePath().toString()); | args.setProperty("scanner.home", home.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_not_fail_if_no_home() { | |||||
void should_not_fail_if_no_home() { | |||||
assertThat(conf.properties()).isNotEmpty(); | assertThat(conf.properties()).isNotEmpty(); | ||||
// worst case, use current path | // worst case, use current path | ||||
assertThat(conf.properties().getProperty("sonar.projectBaseDir")).isEqualTo(Paths.get("").toAbsolutePath().toString()); | assertThat(conf.properties().getProperty("sonar.projectBaseDir")).isEqualTo(Paths.get("").toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_set_bootstrap_time_only_once() { | |||||
void should_set_bootstrap_time_only_once() { | |||||
Properties properties = conf.properties(); | Properties properties = conf.properties(); | ||||
assertThat(properties).containsKey("sonar.scanner.bootstrapStartTime"); | assertThat(properties).containsKey("sonar.scanner.bootstrapStartTime"); | ||||
} | } | ||||
@Test | @Test | ||||
public void base_dir_can_be_relative() throws URISyntaxException { | |||||
void base_dir_can_be_relative() throws URISyntaxException { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | ||||
args.setProperty("project.home", projectHome.getParent().toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.getParent().toAbsolutePath().toString()); | ||||
args.setProperty("sonar.projectBaseDir", "project"); | args.setProperty("sonar.projectBaseDir", "project"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_load_conf_by_direct_path() throws Exception { | |||||
void should_load_conf_by_direct_path() throws Exception { | |||||
Path settings = Paths.get(getClass().getResource("ConfTest/shouldLoadRunnerSettingsByDirectPath/other-conf.properties").toURI()); | Path settings = Paths.get(getClass().getResource("ConfTest/shouldLoadRunnerSettingsByDirectPath/other-conf.properties").toURI()); | ||||
args.setProperty("scanner.settings", settings.toAbsolutePath().toString()); | args.setProperty("scanner.settings", settings.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldLoadCompleteConfiguration() throws Exception { | |||||
void shouldLoadCompleteConfiguration() throws Exception { | |||||
Path runnerHome = Paths.get(getClass().getResource("ConfTest/shouldLoadCompleteConfiguration/runner").toURI()); | Path runnerHome = Paths.get(getClass().getResource("ConfTest/shouldLoadCompleteConfiguration/runner").toURI()); | ||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadCompleteConfiguration/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadCompleteConfiguration/project").toURI()); | ||||
args.setProperty("scanner.home", runnerHome.toAbsolutePath().toString()); | args.setProperty("scanner.home", runnerHome.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldLoadModuleConfiguration() throws Exception { | |||||
void shouldLoadModuleConfiguration() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldSupportDeepModuleConfigurationInRoot() throws Exception { | |||||
void shouldSupportDeepModuleConfigurationInRoot() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldSupportDeepModuleConfigurationInRoot/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldSupportDeepModuleConfigurationInRoot/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldLoadModuleConfigurationOverrideBasedir() throws Exception { | |||||
void shouldLoadModuleConfigurationOverrideBasedir() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldCliOverrideSettingFiles() throws Exception { | |||||
void shouldCliOverrideSettingFiles() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
args.setProperty("module1.sonar.projectName", "mod1"); | args.setProperty("module1.sonar.projectName", "mod1"); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldUseCliToDiscoverModules() throws Exception { | |||||
void shouldUseCliToDiscoverModules() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
args.setProperty("sonar.modules", "module1"); | args.setProperty("sonar.modules", "module1"); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldNotUseCurrentDir() throws Exception { | |||||
void shouldNotUseCurrentDir() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationOverrideBasedir/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldLoadModuleConfigurationWithoutRootConf() throws Exception { | |||||
void shouldLoadModuleConfigurationWithoutRootConf() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationWithoutRootConf/project").toURI()); | Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfigurationWithoutRootConf/project").toURI()); | ||||
args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | args.setProperty("project.home", projectHome.toAbsolutePath().toString()); | ||||
} | } | ||||
@Test | @Test | ||||
public void failModuleBaseDirDoesNotExist() { | |||||
void failModuleBaseDirDoesNotExist() { | |||||
args.setProperty("sonar.modules", "module1"); | args.setProperty("sonar.modules", "module1"); | ||||
args.setProperty("module1.sonar.projectBaseDir", "invalid"); | args.setProperty("module1.sonar.projectBaseDir", "invalid"); | ||||
} | } | ||||
@Test | @Test | ||||
public void failModulePropertyFileDoesNotExist() { | |||||
void failModulePropertyFileDoesNotExist() { | |||||
args.setProperty("sonar.modules", "module1"); | args.setProperty("sonar.modules", "module1"); | ||||
args.setProperty("module1.sonar.projectConfigFile", "invalid"); | args.setProperty("module1.sonar.projectConfigFile", "invalid"); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldSupportSettingBaseDirFromCli() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | |||||
args.setProperty("project.home", temp.newFolder().getCanonicalPath()); | |||||
args.setProperty("sonar.projectBaseDir", projectHome.toAbsolutePath().toString()); | |||||
void shouldSupportSettingBaseDirFromCli(@TempDir Path projectHome) throws Exception { | |||||
Path projectBaseDir = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | |||||
args.setProperty("project.home", projectHome.toString()); | |||||
args.setProperty("sonar.projectBaseDir", projectBaseDir.toAbsolutePath().toString()); | |||||
Properties properties = conf.properties(); | Properties properties = conf.properties(); | ||||
assertThat(properties.getProperty("module1.sonar.projectName")).isEqualTo("Module 1"); | assertThat(properties.getProperty("module1.sonar.projectName")).isEqualTo("Module 1"); | ||||
assertThat(properties.getProperty("module2.sonar.projectName")).isEqualTo("Module 2"); | assertThat(properties.getProperty("module2.sonar.projectName")).isEqualTo("Module 2"); | ||||
assertThat(properties.getProperty("sonar.projectBaseDir")).isEqualTo(projectHome.toString()); | |||||
assertThat(properties.getProperty("sonar.projectBaseDir")).isEqualTo(projectBaseDir.toString()); | |||||
} | } | ||||
@Test | @Test | ||||
public void ignoreEmptyModule() throws Exception { | |||||
Path projectHome = Paths.get(getClass().getResource("ConfTest/emptyModules/project").toURI()); | |||||
args.setProperty("project.home", temp.newFolder().getCanonicalPath()); | |||||
args.setProperty("sonar.projectBaseDir", projectHome.toAbsolutePath().toString()); | |||||
void ignoreEmptyModule(@TempDir Path projectHome) throws Exception { | |||||
Path projectBaseDir = Paths.get(getClass().getResource("ConfTest/emptyModules/project").toURI()); | |||||
args.setProperty("project.home", projectHome.toString()); | |||||
args.setProperty("sonar.projectBaseDir", projectBaseDir.toAbsolutePath().toString()); | |||||
assertThatCode(conf::properties) | assertThatCode(conf::properties) | ||||
.doesNotThrowAnyException(); | .doesNotThrowAnyException(); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldGetList() { | |||||
void shouldGetList() { | |||||
Properties props = new Properties(); | Properties props = new Properties(); | ||||
props.put("prop", " foo ,, bar , \n\ntoto,tutu"); | props.put("prop", " foo ,, bar , \n\ntoto,tutu"); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldNotResolveSymlinks() throws IOException, URISyntaxException { | |||||
void shouldNotResolveSymlinks(@TempDir Path root) throws IOException, URISyntaxException { | |||||
assumeTrue(SystemUtils.IS_OS_UNIX); | assumeTrue(SystemUtils.IS_OS_UNIX); | ||||
Path root = temp.getRoot().toPath(); | |||||
Path realProjectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | Path realProjectHome = Paths.get(getClass().getResource("ConfTest/shouldLoadModuleConfiguration/project").toURI()); | ||||
Path linkProjectHome = root.resolve("link"); | Path linkProjectHome = root.resolve("link"); | ||||
try { | try { | ||||
// SQSCANNER-24 | // SQSCANNER-24 | ||||
@Test | @Test | ||||
public void should_load_project_settings_using_property() throws Exception { | |||||
void should_load_project_settings_using_property() throws Exception { | |||||
Path home = Paths.get(getClass().getResource("ConfTest/shouldOverrideProjectSettingsPath/").toURI()); | Path home = Paths.get(getClass().getResource("ConfTest/shouldOverrideProjectSettingsPath/").toURI()); | ||||
args.setProperty("project.home", home.toAbsolutePath().toString()); | args.setProperty("project.home", home.toAbsolutePath().toString()); | ||||
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.BeforeEach; | |||||
import org.junit.jupiter.api.Test; | |||||
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 static org.mockito.Mockito.verify; | import static org.mockito.Mockito.verify; | ||||
import static org.mockito.Mockito.verifyNoMoreInteractions; | import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
public class LogsTest { | |||||
class LogsTest { | |||||
@Mock | @Mock | ||||
private PrintStream stdOut; | private PrintStream stdOut; | ||||
private Logs logs; | private Logs logs; | ||||
@Before | |||||
public void setUp() { | |||||
@BeforeEach | |||||
void setUp() { | |||||
MockitoAnnotations.initMocks(this); | MockitoAnnotations.initMocks(this); | ||||
logs = new Logs(stdOut, stdErr); | logs = new Logs(stdOut, stdErr); | ||||
} | } | ||||
@Test | @Test | ||||
public void testInfo() { | |||||
void testInfo() { | |||||
logs.info("info"); | logs.info("info"); | ||||
verify(stdOut).println("INFO: info"); | verify(stdOut).println("INFO: info"); | ||||
verifyNoMoreInteractions(stdOut, stdErr); | verifyNoMoreInteractions(stdOut, stdErr); | ||||
} | } | ||||
@Test | @Test | ||||
public void testWarn() { | |||||
void testWarn() { | |||||
logs.warn("warn"); | logs.warn("warn"); | ||||
verify(stdOut).println("WARN: warn"); | verify(stdOut).println("WARN: warn"); | ||||
verifyNoMoreInteractions(stdOut, stdErr); | verifyNoMoreInteractions(stdOut, stdErr); | ||||
} | } | ||||
@Test | @Test | ||||
public void testWarnWithTimestamp() { | |||||
void testWarnWithTimestamp() { | |||||
logs.setDebugEnabled(true); | logs.setDebugEnabled(true); | ||||
logs.warn("warn"); | logs.warn("warn"); | ||||
verify(stdOut).println(ArgumentMatchers.matches("\\d\\d:\\d\\d:\\d\\d.\\d\\d\\d WARN: warn")); | verify(stdOut).println(ArgumentMatchers.matches("\\d\\d:\\d\\d:\\d\\d.\\d\\d\\d WARN: warn")); | ||||
} | } | ||||
@Test | @Test | ||||
public void testError() { | |||||
void testError() { | |||||
Exception e = new NullPointerException("exception"); | Exception e = new NullPointerException("exception"); | ||||
logs.error("error1"); | logs.error("error1"); | ||||
verify(stdErr).println("ERROR: error1"); | verify(stdErr).println("ERROR: error1"); | ||||
} | } | ||||
@Test | @Test | ||||
public void testDebug() { | |||||
void testDebug() { | |||||
logs.setDebugEnabled(true); | logs.setDebugEnabled(true); | ||||
logs.debug("debug"); | logs.debug("debug"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_forward_logs() { | |||||
void should_forward_logs() { | |||||
var mockedLogs = mock(Logs.class); | var mockedLogs = mock(Logs.class); | ||||
var logOutput = new Logs.LogOutputAdapter(mockedLogs); | var logOutput = new Logs.LogOutputAdapter(mockedLogs); | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.BeforeEach; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.mockito.ArgumentCaptor; | import org.mockito.ArgumentCaptor; | ||||
import org.mockito.InOrder; | import org.mockito.InOrder; | ||||
import org.mockito.Mock; | import org.mockito.Mock; | ||||
@Mock | @Mock | ||||
private Logs logs; | private Logs logs; | ||||
@Before | |||||
public void setUp() { | |||||
@BeforeEach | |||||
void setUp() { | |||||
MockitoAnnotations.initMocks(this); | MockitoAnnotations.initMocks(this); | ||||
when(scannerEngineBootstrapperFactory.create(any(Properties.class), any(String.class))).thenReturn(bootstrapper); | when(scannerEngineBootstrapperFactory.create(any(Properties.class), any(String.class))).thenReturn(bootstrapper); | ||||
when(bootstrapper.bootstrap()).thenReturn(engine); | when(bootstrapper.bootstrap()).thenReturn(engine); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_execute_scanner_engine() { | |||||
void should_execute_scanner_engine() { | |||||
when(cli.getInvokedFrom()).thenReturn(""); | when(cli.getInvokedFrom()).thenReturn(""); | ||||
Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs); | Main main = new Main(exit, cli, conf, scannerEngineBootstrapperFactory, logs); | ||||
main.analyze(); | main.analyze(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_exit_with_error_on_error_during_analysis() { | |||||
void should_exit_with_error_on_error_during_analysis() { | |||||
Exception e = new NullPointerException("NPE"); | Exception e = new NullPointerException("NPE"); | ||||
e = new IllegalStateException("Error", e); | e = new IllegalStateException("Error", e); | ||||
doThrow(e).when(engine).analyze(any()); | doThrow(e).when(engine).analyze(any()); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_exit_with_error_on_error_during_bootstrap() { | |||||
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(bootstrapper).bootstrap(); | doThrow(e).when(bootstrapper).bootstrap(); | ||||
} | } | ||||
@Test | @Test | ||||
public void show_stacktrace() { | |||||
void show_stacktrace() { | |||||
Exception e = createException(false); | Exception e = createException(false); | ||||
testException(e, false, false, Exit.INTERNAL_ERROR); | testException(e, false, false, Exit.INTERNAL_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void dont_show_MessageException_stacktrace() { | |||||
void dont_show_MessageException_stacktrace() { | |||||
Exception e = createException(true); | Exception e = createException(true); | ||||
testException(e, false, false, Exit.USER_ERROR); | testException(e, false, false, Exit.USER_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void dont_show_MessageException_stacktrace_embedded() { | |||||
void dont_show_MessageException_stacktrace_embedded() { | |||||
Exception e = createException(true); | Exception e = createException(true); | ||||
testException(e, false, true, Exit.USER_ERROR); | testException(e, false, true, Exit.USER_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void show_MessageException_stacktrace_in_debug() { | |||||
void show_MessageException_stacktrace_in_debug() { | |||||
Exception e = createException(true); | Exception e = createException(true); | ||||
testException(e, true, false, Exit.USER_ERROR); | testException(e, true, false, Exit.USER_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void show_MessageException_stacktrace_in_debug_embedded() { | |||||
void show_MessageException_stacktrace_in_debug_embedded() { | |||||
Exception e = createException(true); | Exception e = createException(true); | ||||
testException(e, true, true, Exit.USER_ERROR); | testException(e, true, true, Exit.USER_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void show_stacktrace_in_debug() { | |||||
void show_stacktrace_in_debug() { | |||||
Exception e = createException(false); | Exception e = createException(false); | ||||
testException(e, true, false, Exit.INTERNAL_ERROR); | testException(e, true, false, Exit.INTERNAL_ERROR); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_only_display_version() { | |||||
void should_only_display_version() { | |||||
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(""); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_skip() { | |||||
void should_skip() { | |||||
Properties p = new Properties(); | Properties p = new Properties(); | ||||
p.setProperty(ScannerProperties.SKIP, "true"); | p.setProperty(ScannerProperties.SKIP, "true"); | ||||
when(conf.properties()).thenReturn(p); | when(conf.properties()).thenReturn(p); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldLogServerVersion() { | |||||
void shouldLogServerVersion() { | |||||
when(engine.isSonarCloud()).thenReturn(false); | when(engine.isSonarCloud()).thenReturn(false); | ||||
when(engine.getServerVersion()).thenReturn("5.5"); | when(engine.getServerVersion()).thenReturn("5.5"); | ||||
Properties p = new Properties(); | Properties p = new Properties(); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_log_SonarCloud_server() { | |||||
void should_log_SonarCloud_server() { | |||||
when(engine.isSonarCloud()).thenReturn(true); | when(engine.isSonarCloud()).thenReturn(true); | ||||
Properties p = new Properties(); | Properties p = new Properties(); | ||||
when(conf.properties()).thenReturn(p); | when(conf.properties()).thenReturn(p); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_configure_logging() { | |||||
void should_configure_logging() { | |||||
Properties analysisProps = testLogging("sonar.verbose", "true"); | Properties analysisProps = testLogging("sonar.verbose", "true"); | ||||
assertThat(analysisProps.getProperty("sonar.verbose")).isEqualTo("true"); | assertThat(analysisProps.getProperty("sonar.verbose")).isEqualTo("true"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_configure_logging_trace() { | |||||
void should_configure_logging_trace() { | |||||
Properties analysisProps = testLogging("sonar.log.level", "TRACE"); | Properties analysisProps = testLogging("sonar.log.level", "TRACE"); | ||||
assertThat(analysisProps.getProperty("sonar.log.level")).isEqualTo("TRACE"); | assertThat(analysisProps.getProperty("sonar.log.level")).isEqualTo("TRACE"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_set_bootstrap_start_time_in_millis() { | |||||
void should_set_bootstrap_start_time_in_millis() { | |||||
Properties analysisProps = execute("sonar.scanner.bootstrapStartTime", "1714137496104"); | Properties analysisProps = execute("sonar.scanner.bootstrapStartTime", "1714137496104"); | ||||
assertThat(analysisProps.getProperty("sonar.scanner.bootstrapStartTime")).isEqualTo("1714137496104"); | assertThat(analysisProps.getProperty("sonar.scanner.bootstrapStartTime")).isEqualTo("1714137496104"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_configure_logging_debug() { | |||||
void should_configure_logging_debug() { | |||||
Properties analysisProps = testLogging("sonar.log.level", "DEBUG"); | Properties analysisProps = testLogging("sonar.log.level", "DEBUG"); | ||||
assertThat(analysisProps.getProperty("sonar.log.level")).isEqualTo("DEBUG"); | assertThat(analysisProps.getProperty("sonar.log.level")).isEqualTo("DEBUG"); | ||||
} | } |
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.junit.rules.ExpectedException; | |||||
import org.junit.jupiter.api.Test; | |||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | |||||
public class PropertyResolverTest { | |||||
@Rule | |||||
public ExpectedException exception = ExpectedException.none(); | |||||
class PropertyResolverTest { | |||||
@Test | @Test | ||||
public void resolve_properties() { | |||||
void resolve_properties() { | |||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
} | } | ||||
@Test | @Test | ||||
public void use_env() { | |||||
void use_env() { | |||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
} | } | ||||
@Test | @Test | ||||
public void resolve_recursively() { | |||||
void resolve_recursively() { | |||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
map.put("A", "value a"); | map.put("A", "value a"); | ||||
} | } | ||||
@Test | @Test | ||||
public void dont_resolve_nested() { | |||||
void dont_resolve_nested() { | |||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
map.put("A", "value a"); | map.put("A", "value a"); | ||||
} | } | ||||
@Test | @Test | ||||
public void missing_var() { | |||||
void missing_var() { | |||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
map.put("A", "/path/${missing} var/"); | map.put("A", "/path/${missing} var/"); | ||||
} | } | ||||
@Test | @Test | ||||
public void fail_loop_properties_resolution() { | |||||
void fail_loop_properties_resolution() { | |||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
map.put("A", "${B}"); | map.put("A", "${B}"); | ||||
map.put("B", "${A}"); | map.put("B", "${A}"); | ||||
exception.expect(IllegalArgumentException.class); | |||||
exception.expectMessage("variable: B"); | |||||
PropertyResolver resolver = new PropertyResolver(map, env); | PropertyResolver resolver = new PropertyResolver(map, env); | ||||
resolver.resolve(); | |||||
assertThatThrownBy(resolver::resolve).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("variable: B"); | |||||
} | } | ||||
@Test | @Test | ||||
public void preserve_empty() { | |||||
void preserve_empty() { | |||||
Properties map = new Properties(); | Properties map = new Properties(); | ||||
Map<String, String> env = new HashMap<>(); | Map<String, String> env = new HashMap<>(); | ||||
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.sonarsource.scanner.lib.ScannerEngineBootstrapper; | import org.sonarsource.scanner.lib.ScannerEngineBootstrapper; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.mockito.Mockito.verify; | import static org.mockito.Mockito.verify; | ||||
import static org.mockito.Mockito.when; | import static org.mockito.Mockito.when; | ||||
public class ScannerEngineBootstrapperFactoryTest { | |||||
class ScannerEngineBootstrapperFactoryTest { | |||||
private final Properties props = new Properties(); | private final Properties props = new Properties(); | ||||
private final Logs logs = mock(Logs.class); | private final Logs logs = mock(Logs.class); | ||||
private ScannerEngineBootstrapperFactory underTest = new ScannerEngineBootstrapperFactory(logs); | |||||
private final ScannerEngineBootstrapperFactory underTest = new ScannerEngineBootstrapperFactory(logs); | |||||
@Test | @Test | ||||
public void should_create_engine_bootstrapper_and_pass_app_and_properties() { | |||||
void should_create_engine_bootstrapper_and_pass_app_and_properties() { | |||||
props.setProperty("foo", "bar"); | props.setProperty("foo", "bar"); | ||||
var spy = spy(underTest); | var spy = spy(underTest); | ||||
var mockedBootstrapper = mock(ScannerEngineBootstrapper.class); | var mockedBootstrapper = mock(ScannerEngineBootstrapper.class); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_create_engine_bootstrapper_with_app_from_argument() { | |||||
void should_create_engine_bootstrapper_with_app_from_argument() { | |||||
var spy = spy(underTest); | var spy = spy(underTest); | ||||
var mockedBootstrapper = mock(ScannerEngineBootstrapper.class); | var mockedBootstrapper = mock(ScannerEngineBootstrapper.class); | ||||
when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper); | when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper); | ||||
} | } | ||||
@Test | @Test | ||||
public void if_from_argument_is_not_regex_compliant_revert_to_default_scanner_name() { | |||||
void if_from_argument_is_not_regex_compliant_revert_to_default_scanner_name() { | |||||
var spy = spy(underTest); | var spy = spy(underTest); | ||||
var mockedBootstrapper = mock(ScannerEngineBootstrapper.class); | var mockedBootstrapper = mock(ScannerEngineBootstrapper.class); | ||||
when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper); | when(mockedBootstrapper.addBootstrapProperties(any())).thenReturn(mockedBootstrapper); |
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.mockito.Mockito; | import org.mockito.Mockito; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
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 StatsTest { | |||||
class StatsTest { | |||||
private final PrintStream stdOut = mock(PrintStream.class); | private final PrintStream stdOut = mock(PrintStream.class); | ||||
private final PrintStream stdErr = mock(PrintStream.class); | private final PrintStream stdErr = mock(PrintStream.class); | ||||
private final Logs logs = new Logs(stdOut, stdErr); | private final Logs logs = new Logs(stdOut, stdErr); | ||||
@Test | @Test | ||||
public void shouldPrintStats() { | |||||
void shouldPrintStats() { | |||||
new Stats(logs).start().stop(); | new Stats(logs).start().stop(); | ||||
verify(stdOut).println(Mockito.contains("Total time: ")); | verify(stdOut).println(Mockito.contains("Total time: ")); | ||||
} | } | ||||
@Test | @Test | ||||
public void shouldFormatTime() { | |||||
void shouldFormatTime() { | |||||
assertThat(Stats.formatTime(1 * 60 * 60 * 1000 + 2 * 60 * 1000 + 3 * 1000 + 400)).isEqualTo("1:02:03.400s"); | assertThat(Stats.formatTime(1 * 60 * 60 * 1000 + 2 * 60 * 1000 + 3 * 1000 + 400)).isEqualTo("1:02:03.400s"); | ||||
assertThat(Stats.formatTime(2 * 60 * 1000 + 3 * 1000 + 400)).isEqualTo("2:03.400s"); | assertThat(Stats.formatTime(2 * 60 * 1000 + 3 * 1000 + 400)).isEqualTo("2:03.400s"); | ||||
assertThat(Stats.formatTime(3 * 1000 + 400)).isEqualTo("3.400s"); | assertThat(Stats.formatTime(3 * 1000 + 400)).isEqualTo("3.400s"); |
*/ | */ | ||||
package org.sonarsource.scanner.cli; | package org.sonarsource.scanner.cli; | ||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.BeforeEach; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.sonarsource.scanner.cli.SystemInfo.System2; | import org.sonarsource.scanner.cli.SystemInfo.System2; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.mockito.Mockito.verifyNoMoreInteractions; | import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
import static org.mockito.Mockito.when; | import static org.mockito.Mockito.when; | ||||
public class SystemInfoTest { | |||||
class SystemInfoTest { | |||||
private final System2 mockSystem = mock(System2.class); | private final System2 mockSystem = mock(System2.class); | ||||
private final Logs logs = mock(Logs.class); | private final Logs logs = mock(Logs.class); | ||||
@Before | |||||
public void setUp() { | |||||
@BeforeEach | |||||
void setUp() { | |||||
SystemInfo.setSystem(mockSystem); | SystemInfo.setSystem(mockSystem); | ||||
} | } | ||||
@Test | @Test | ||||
public void test_java() { | |||||
void test_java() { | |||||
mockJava(); | mockJava(); | ||||
assertThat(SystemInfo.java()).isEqualTo("Java 1.9 oracle (64-bit)"); | assertThat(SystemInfo.java()).isEqualTo("Java 1.9 oracle (64-bit)"); | ||||
} | } | ||||
@Test | @Test | ||||
public void test_os() { | |||||
void test_os() { | |||||
mockOs(); | mockOs(); | ||||
assertThat(SystemInfo.os()).isEqualTo("linux 2.5 x64"); | assertThat(SystemInfo.os()).isEqualTo("linux 2.5 x64"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_print() { | |||||
void should_print() { | |||||
mockOs(); | mockOs(); | ||||
mockJava(); | mockJava(); | ||||
when(mockSystem.getenv("SONAR_SCANNER_OPTS")).thenReturn("arg"); | when(mockSystem.getenv("SONAR_SCANNER_OPTS")).thenReturn("arg"); | ||||
} | } | ||||
@Test | @Test | ||||
public void should_not_print_sensitive_data() { | |||||
void should_not_print_sensitive_data() { | |||||
mockOs(); | mockOs(); | ||||
mockJava(); | mockJava(); | ||||
when(mockSystem.getenv("SONAR_SCANNER_OPTS")) | when(mockSystem.getenv("SONAR_SCANNER_OPTS")) |