From 71511c408a6b179340dd9532c7f29643be2331eb Mon Sep 17 00:00:00 2001 From: Tibor Blenessy Date: Wed, 20 Sep 2023 18:34:15 +0200 Subject: [PATCH] Improve coverage & fix code smells --- .../javascript/bridge/EmbeddedNode.java | 6 +- .../javascript/nodejs/NodeCommand.java | 8 -- .../nodejs/NodeCommandBuilderImpl.java | 11 +-- .../bridge/BridgeServerImplTest.java | 15 +++- .../javascript/bridge/EmbeddedNodeTest.java | 59 +++++++++++--- .../javascript/nodejs/NodeCommandTest.java | 76 +++++++++---------- .../org/sonarsource/javascript/XZTest.java | 9 ++- 7 files changed, 110 insertions(+), 74 deletions(-) diff --git a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/bridge/EmbeddedNode.java b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/bridge/EmbeddedNode.java index cb20a502abe..af5aa24a241 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/bridge/EmbeddedNode.java +++ b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/bridge/EmbeddedNode.java @@ -50,10 +50,10 @@ public class EmbeddedNode { private static final String DEPLOY_LOCATION = Path.of(".sonar", "js", "node-runtime").toString(); public static final String VERSION_FILENAME = "version.txt"; private static final Logger LOG = Loggers.get(EmbeddedNode.class); - private Path deployLocation; + private final Path deployLocation; private final Platform platform; private boolean isAvailable; - private Environment env; + private final Environment env; enum Platform { WIN_X64, @@ -149,7 +149,7 @@ public boolean isAvailable() { */ public void deploy() throws IOException { LOG.debug("Detected os: {} arch: {} platform: {}", env.getOsName(), env.getOsArch(), platform); - if (platform == UNSUPPORTED || isAvailable) { + if (platform == UNSUPPORTED) { return; } var is = getClass().getResourceAsStream(platform.archivePathInJar()); diff --git a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommand.java b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommand.java index 56f412f05b4..de55ad171e0 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommand.java +++ b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommand.java @@ -135,12 +135,4 @@ public String toString() { public Version getActualNodeVersion() { return actualNodeVersion; } - - public static NodeCommandBuilder builder() { - return builder(new ProcessWrapperImpl()); - } - - static NodeCommandBuilder builder(ProcessWrapper processWrapper) { - return new NodeCommandBuilderImpl(processWrapper); - } } diff --git a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommandBuilderImpl.java b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommandBuilderImpl.java index 359b29b4d7a..f07ea4e0d2b 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommandBuilderImpl.java +++ b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommandBuilderImpl.java @@ -36,7 +36,6 @@ import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.annotation.Nullable; import org.sonar.api.config.Configuration; import org.sonar.api.utils.Version; import org.sonar.api.utils.log.Logger; @@ -53,7 +52,7 @@ public class NodeCommandBuilderImpl implements NodeCommandBuilder { "package/node_modules/run-node/run-node"; private static final String NODE_EXECUTABLE_PROPERTY = "sonar.nodejs.executable"; - final String NODE_FORCE_HOST_PROPERTY = "sonar.nodejs.forceHost"; + private static final String NODE_FORCE_HOST_PROPERTY = "sonar.nodejs.forceHost"; private static final Pattern NODEJS_VERSION_PATTERN = Pattern.compile( "v?(\\d+)\\.(\\d+)\\.(\\d+)" @@ -254,9 +253,9 @@ private String getVersion(String nodeExecutable) throws NodeCommandException { * @throws NodeCommandException * @throws IOException */ - private String retrieveNodeExecutable(@Nullable Configuration configuration) + private String retrieveNodeExecutable(Configuration configuration) throws NodeCommandException, IOException { - if (configuration != null && configuration.hasKey(NODE_EXECUTABLE_PROPERTY)) { + if (configuration.hasKey(NODE_EXECUTABLE_PROPERTY)) { String nodeExecutable = configuration.get(NODE_EXECUTABLE_PROPERTY).get(); File file = new File(nodeExecutable); if (file.exists()) { @@ -295,9 +294,7 @@ private String locateNode(boolean isForceHost) throws IOException { } private boolean isForceHost(Configuration configuration) { - return ( - configuration != null && configuration.getBoolean(NODE_FORCE_HOST_PROPERTY).orElse(false) - ); + return configuration.getBoolean(NODE_FORCE_HOST_PROPERTY).orElse(false); } private String locateNodeOnMac() throws IOException { diff --git a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/BridgeServerImplTest.java b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/BridgeServerImplTest.java index b8ff074fba7..8d5b7d26c54 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/BridgeServerImplTest.java +++ b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/BridgeServerImplTest.java @@ -73,7 +73,9 @@ import org.sonar.plugins.javascript.bridge.BridgeServer.TsProgramRequest; import org.sonar.plugins.javascript.nodejs.NodeCommand; import org.sonar.plugins.javascript.nodejs.NodeCommandBuilder; +import org.sonar.plugins.javascript.nodejs.NodeCommandBuilderImpl; import org.sonar.plugins.javascript.nodejs.NodeCommandException; +import org.sonar.plugins.javascript.nodejs.ProcessWrapperImpl; class BridgeServerImplTest { @@ -654,7 +656,7 @@ void should_skip_metrics_on_sonarlint() throws Exception { void should_use_default_timeout() { bridgeServer = new BridgeServerImpl( - NodeCommand.builder(), + builder(), mock(Bundle.class), mock(RulesBundles.class), deprecationWarning, @@ -716,7 +718,7 @@ public void execute(SensorContext context) {} assertThat(monitoring.isMonitoringEnabled()).isTrue(); bridgeServer = new BridgeServerImpl( - NodeCommand.builder(), + builder(), TEST_TIMEOUT_SECONDS, new TestBundle(START_SERVER_SCRIPT), emptyRulesBundles, @@ -748,7 +750,7 @@ void test_ucfg_bundle_version() throws Exception { bridgeServer = new BridgeServerImpl( - NodeCommand.builder(), + builder(), TEST_TIMEOUT_SECONDS, new TestBundle(START_SERVER_SCRIPT), rulesBundles, @@ -765,7 +767,7 @@ void test_ucfg_bundle_version() throws Exception { private BridgeServerImpl createBridgeServer(String startServerScript) { return new BridgeServerImpl( - NodeCommand.builder(), + builder(), TEST_TIMEOUT_SECONDS, new TestBundle(startServerScript), emptyRulesBundles, @@ -808,4 +810,9 @@ public String resolve(String relativePath) { return new File(file.getAbsoluteFile(), relativePath).getAbsolutePath(); } } + + private static NodeCommandBuilder builder() { + return new NodeCommandBuilderImpl(new ProcessWrapperImpl()) + .configuration(new MapSettings().asConfig()); + } } diff --git a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/EmbeddedNodeTest.java b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/EmbeddedNodeTest.java index 353282b398c..552ca5a8d56 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/EmbeddedNodeTest.java +++ b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/bridge/EmbeddedNodeTest.java @@ -3,6 +3,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.plugins.javascript.bridge.EmbeddedNode.Platform.DARWIN_ARM64; +import static org.sonar.plugins.javascript.bridge.EmbeddedNode.Platform.LINUX_X64; +import static org.sonar.plugins.javascript.bridge.EmbeddedNode.Platform.UNSUPPORTED; +import static org.sonar.plugins.javascript.bridge.EmbeddedNode.Platform.WIN_X64; import java.io.IOException; import java.nio.file.Files; @@ -12,6 +16,7 @@ import org.junit.jupiter.api.io.TempDir; import org.slf4j.event.Level; import org.sonar.api.testfixtures.log.LogTesterJUnit5; +import org.sonar.plugins.javascript.bridge.EmbeddedNode.Platform; class EmbeddedNodeTest { @@ -31,6 +36,7 @@ void should_extract_if_deployLocation_contains_a_different_version() throws Exce Files.write(runtimeFolder.resolve("version.txt"), "a-different-version".getBytes()); en.deploy(); assertThat(en.binary()).exists(); + assertThat(en.isAvailable()).isTrue(); } @Test @@ -44,6 +50,14 @@ void should_not_extract_if_deployLocation_contains_the_same_version() throws Exc ); en.deploy(); assertThat(en.binary()).doesNotExist(); + assertThat(en.isAvailable()).isTrue(); + } + + @Test + void should_not_be_available() throws Exception { + var en = new EmbeddedNode(createUnsupportedEnvironment()); + en.deploy(); + assertThat(en.isAvailable()).isFalse(); } @Test @@ -55,29 +69,55 @@ void should_extract_if_deployLocation_has_no_version() throws Exception { @Test void should_detect_platform_for_windows_environment() { - var platform = EmbeddedNode.Platform.detect(createWindowsEnvironment()); - assertThat(platform).isEqualTo(EmbeddedNode.Platform.WIN_X64); + var platform = Platform.detect(createWindowsEnvironment()); + assertThat(platform).isEqualTo(WIN_X64); assertThat(platform.archivePathInJar()).isEqualTo("/win-x64/node.exe.xz"); } @Test void should_detect_platform_for_mac_os_environment() { - var platform = EmbeddedNode.Platform.detect(createMacOSEnvironment()); - assertThat(platform).isEqualTo(EmbeddedNode.Platform.DARWIN_ARM64); + var platform = Platform.detect(createMacOSEnvironment()); + assertThat(platform).isEqualTo(DARWIN_ARM64); assertThat(platform.archivePathInJar()).isEqualTo("/darwin-arm64/node.xz"); } + @Test + void should_detect_platform_for_linux_environment() { + var linux = mock(Environment.class); + when(linux.getOsName()).thenReturn("linux"); + when(linux.getOsArch()).thenReturn("amd64"); + var platform = Platform.detect(linux); + assertThat(platform).isEqualTo(LINUX_X64); + assertThat(platform.archivePathInJar()).isEqualTo("/linux-x64/node.xz"); + } + @Test void should_return_unsupported_for_unknown_environment() { - var platform = EmbeddedNode.Platform.detect(createUnsupportedEnvironment()); - assertThat(platform).isEqualTo(EmbeddedNode.Platform.UNSUPPORTED); + var platform = Platform.detect(createUnsupportedEnvironment()); + assertThat(platform).isEqualTo(UNSUPPORTED); assertThat(platform.archivePathInJar()).isEqualTo("node.xz"); } + @Test + void test_unsupported_archs() { + var win = mock(Environment.class); + when(win.getOsName()).thenReturn("Windows"); + when(win.getOsArch()).thenReturn("unknown"); + assertThat(Platform.detect(win)).isEqualTo(UNSUPPORTED); + + var linux = mock(Environment.class); + when(linux.getOsName()).thenReturn("linux"); + when(linux.getOsArch()).thenReturn("unknown"); + assertThat(Platform.detect(linux)).isEqualTo(UNSUPPORTED); + + var macos = mock(Environment.class); + when(macos.getOsName()).thenReturn("mac os"); + when(macos.getOsArch()).thenReturn("unknown"); + assertThat(Platform.detect(macos)).isEqualTo(UNSUPPORTED); + } + private byte[] extractCurrentVersion(Environment env) throws IOException { - return getClass() - .getResourceAsStream(EmbeddedNode.Platform.detect(env).versionPathInJar()) - .readAllBytes(); + return getClass().getResourceAsStream(Platform.detect(env).versionPathInJar()).readAllBytes(); } private Environment createTestEnvironment() { @@ -106,6 +146,7 @@ private Environment createUnsupportedEnvironment() { Environment mockEnvironment = mock(Environment.class); when(mockEnvironment.getOsName()).thenReturn(""); when(mockEnvironment.getOsArch()).thenReturn(""); + when(mockEnvironment.getUserHome()).thenReturn(tempDir.toString()); return mockEnvironment; } } diff --git a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/nodejs/NodeCommandTest.java b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/nodejs/NodeCommandTest.java index 97024685978..feb655c1d82 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/nodejs/NodeCommandTest.java +++ b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/nodejs/NodeCommandTest.java @@ -80,22 +80,20 @@ public void setUp() throws Exception { @Test void test() throws Exception { - NodeCommand nodeCommand = NodeCommand - .builder() + NodeCommand nodeCommand = builder() .script(resourceScript(PATH_TO_SCRIPT)) .pathResolver(getPathResolver()) .build(); nodeCommand.start(); int exitValue = nodeCommand.waitFor(); - assertThat(exitValue).isEqualTo(0); + assertThat(exitValue).isZero(); } @Test void test_output_error_consumer() throws Exception { StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); - NodeCommand nodeCommand = NodeCommand - .builder() + NodeCommand nodeCommand = builder() .script(resourceScript("files/error.js")) .outputConsumer(output::append) .errorConsumer(error::append) @@ -111,11 +109,7 @@ void test_output_error_consumer() throws Exception { @Test void test_min_version() throws IOException { assertThatThrownBy(() -> - NodeCommand - .builder() - .minNodeVersion(Version.create(99, 0)) - .pathResolver(getPathResolver()) - .build() + builder().minNodeVersion(Version.create(99, 0)).pathResolver(getPathResolver()).build() ) .isInstanceOf(NodeCommandException.class) .hasMessageStartingWith("Only Node.js v99.0 or later is supported, got"); @@ -126,7 +120,7 @@ void test_mac_default_executable_not_found() throws IOException { when(mockProcessWrapper.isMac()).thenReturn(true); assertThatThrownBy(() -> - NodeCommand.builder(mockProcessWrapper).pathResolver(p -> "/file/does/not/exist").build() + builder(mockProcessWrapper).pathResolver(p -> "/file/does/not/exist").build() ) .isInstanceOf(NodeCommandException.class) .hasMessage("Default Node.js executable for MacOS does not exist."); @@ -134,8 +128,7 @@ void test_mac_default_executable_not_found() throws IOException { @Test void test_min_version_positive() throws Exception { - NodeCommand nodeCommand = NodeCommand - .builder() + NodeCommand nodeCommand = builder() .minNodeVersion(Version.create(1, 0)) .script(resourceScript(PATH_TO_SCRIPT)) .pathResolver(getPathResolver()) @@ -162,8 +155,7 @@ void test_version_check() { void test_max_old_space_size_setting() throws IOException { String request = "v8.getHeapStatistics()"; StringBuilder output = new StringBuilder(); - NodeCommand command = NodeCommand - .builder() + NodeCommand command = builder() .maxOldSpaceSize(2048) .nodeJsArgs("-p", request) .outputConsumer(output::append) @@ -183,8 +175,7 @@ void test_executable_from_configuration() throws Exception { MapSettings mapSettings = new MapSettings(); mapSettings.setProperty(NODE_EXECUTABLE_PROPERTY, nodeExecutable.toString()); Configuration configuration = mapSettings.asConfig(); - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .configuration(configuration) .script("not-used") .build(); @@ -208,8 +199,7 @@ void test_executable_from_configuration() throws Exception { @Test void test_empty_configuration() throws Exception { - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .configuration(new MapSettings().asConfig()) .script("not-used") .build(); @@ -228,8 +218,7 @@ private List captureProcessWrapperArgument() throws IOException { void test_non_existing_node_file() throws Exception { MapSettings settings = new MapSettings(); settings.setProperty("sonar.nodejs.executable", "non-existing-file"); - NodeCommandBuilder nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommandBuilder nodeCommand = builder(mockProcessWrapper) .configuration(settings.asConfig()) .script("not-used"); @@ -251,8 +240,7 @@ void test_non_existing_node_file() throws Exception { void test_exception_start() throws Exception { IOException cause = new IOException("Error starting process"); when(mockProcessWrapper.startProcess(any(), any(), any(), any())).thenThrow(cause); - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .script(resourceScript(PATH_TO_SCRIPT)) .build(); assertThatThrownBy(nodeCommand::start) @@ -264,8 +252,7 @@ void test_exception_start() throws Exception { @Test void test_interrupted_waitFor() throws Exception { when(mockProcessWrapper.waitFor(any(), anyLong(), any())).thenThrow(new InterruptedException()); - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .script(resourceScript(PATH_TO_SCRIPT)) .build(); nodeCommand.start(); @@ -278,8 +265,7 @@ void test_interrupted_waitFor() throws Exception { @Test void test_timeout_waitFor() throws Exception { when(mockProcessWrapper.waitFor(any(), anyLong(), any())).thenReturn(false); - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .script(resourceScript(PATH_TO_SCRIPT)) .build(); nodeCommand.start(); @@ -291,7 +277,7 @@ void test_timeout_waitFor() throws Exception { @Test void test_no_args() { - NodeCommandBuilder commandBuilder = NodeCommand.builder(mockProcessWrapper); + NodeCommandBuilder commandBuilder = builder(mockProcessWrapper); assertThatThrownBy(commandBuilder::build) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Missing arguments for Node.js."); @@ -299,7 +285,7 @@ void test_no_args() { @Test void test_script_args() { - NodeCommandBuilder commandBuilder = NodeCommand.builder(mockProcessWrapper).scriptArgs("arg"); + NodeCommandBuilder commandBuilder = builder(mockProcessWrapper).scriptArgs("arg"); assertThatThrownBy(commandBuilder::build) .isInstanceOf(IllegalArgumentException.class) .hasMessage("No script provided, but script arguments found."); @@ -309,8 +295,7 @@ void test_script_args() { void test_failed_get_version() throws Exception { when(mockProcessWrapper.waitFor(any(), anyLong(), any())).thenReturn(true); when(mockProcessWrapper.exitValue(any())).thenReturn(1); - NodeCommandBuilder commandBuilder = NodeCommand - .builder(mockProcessWrapper) + NodeCommandBuilder commandBuilder = builder(mockProcessWrapper) .minNodeVersion(Version.create(8, 0)) .script(resourceScript(PATH_TO_SCRIPT)); assertThatThrownBy(commandBuilder::build) @@ -321,8 +306,7 @@ void test_failed_get_version() throws Exception { @Test void test_toString() throws IOException { when(mockProcessWrapper.isMac()).thenReturn(false); - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .nodeJsArgs("-v") .script("script.js") .scriptArgs("arg1", "arg2") @@ -338,8 +322,7 @@ void test_command_on_mac() throws Exception { return; } when(mockProcessWrapper.isMac()).thenReturn(true); - NodeCommand nodeCommand = NodeCommand - .builder(mockProcessWrapper) + NodeCommand nodeCommand = builder(mockProcessWrapper) .script("script.js") .pathResolver(getPathResolver()) .build(); @@ -354,7 +337,10 @@ void test_command_on_mac() throws Exception { void test_missing_node() throws Exception { when(mockProcessWrapper.startProcess(any(), any(), any(), any())) .thenThrow(new IOException("CreateProcess error=2")); - NodeCommand nodeCommand = NodeCommand.builder(mockProcessWrapper).script("not-used").build(); + NodeCommand nodeCommand = builder(mockProcessWrapper) + .configuration(new MapSettings().asConfig()) + .script("not-used") + .build(); assertThatThrownBy(nodeCommand::start).isInstanceOf(NodeCommandException.class); } @@ -384,7 +370,7 @@ void test_windows_default_node() throws Exception { invocation.getArgument(2, Consumer.class).accept("C:\\Program Files\\node.exe"); return mock(Process.class); }); - NodeCommand nodeCommand = NodeCommand.builder(mockProcessWrapper).script("script.js").build(); + NodeCommand nodeCommand = builder(mockProcessWrapper).script("script.js").build(); assertThat(processStartArgument.getValue()) .containsExactly("C:\\Windows\\System32\\where.exe", "$PATH:node.exe"); nodeCommand.start(); @@ -397,7 +383,7 @@ void test_windows_default_node_not_found() throws Exception { when(mockProcessWrapper.isWindows()).thenReturn(true); when(mockProcessWrapper.startProcess(processStartArgument.capture(), any(), any(), any())) .thenReturn(mock(Process.class)); - NodeCommandBuilder builder = NodeCommand.builder(mockProcessWrapper).script("script.js"); + NodeCommandBuilder builder = builder(mockProcessWrapper).script("script.js"); assertThatThrownBy(builder::build) .isInstanceOf(NodeCommandException.class) .hasMessage("Node.js not found in PATH. PATH value was: null"); @@ -409,8 +395,7 @@ void test_windows_default_node_not_found() throws Exception { void test_embedded_runtime() throws Exception { var en = new EmbeddedNode(createTestEnvironment()); en.deploy(); - NodeCommand nodeCommand = NodeCommand - .builder() + NodeCommand nodeCommand = builder() .script(PATH_TO_SCRIPT) .pathResolver(getPathResolver()) .embeddedNode(en) @@ -433,8 +418,7 @@ void test_embedded_runtime_with_forceHost_for_macos() throws Exception { var en = new EmbeddedNode(createTestEnvironment()); en.deploy(); - NodeCommand nodeCommand = NodeCommand - .builder() + NodeCommand nodeCommand = builder() .script(PATH_TO_SCRIPT) .configuration(configuration) .pathResolver(getPathResolver()) @@ -461,4 +445,12 @@ private Environment createTestEnvironment() { when(mockEnvironment.getOsArch()).thenReturn(new Environment().getOsArch()); return mockEnvironment; } + + private static NodeCommandBuilder builder() { + return builder(new ProcessWrapperImpl()); + } + + static NodeCommandBuilder builder(ProcessWrapper processWrapper) { + return new NodeCommandBuilderImpl(processWrapper).configuration(new MapSettings().asConfig()); + } } diff --git a/tools/fetch-node/src/test/java/org/sonarsource/javascript/XZTest.java b/tools/fetch-node/src/test/java/org/sonarsource/javascript/XZTest.java index 11fee379680..ea29ee40d98 100644 --- a/tools/fetch-node/src/test/java/org/sonarsource/javascript/XZTest.java +++ b/tools/fetch-node/src/test/java/org/sonarsource/javascript/XZTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.io.TempDir; import org.tukaani.xz.XZInputStream; -public class XZTest { +class XZTest { @TempDir Path tempDir; @@ -53,6 +53,13 @@ void should_throw_an_error_if_a_filename_doesnt_exists() { .hasMessage("File " + filenames[0] + " does not exist."); } + @Test + void output_already_exists() throws Exception { + var f = Files.createFile(Path.of(origFilePath + ".xz")); + XZ.main(new String[] { origFilePath.toString() }); + assertThat(Files.size(f)).isZero(); + } + /** * Extracts the given `source.xz` to `source` (without the `.xz` extension) *