From d06d99209fa3079a14130bf00ddfe50e5a7044d3 Mon Sep 17 00:00:00 2001 From: Greg Gibeling Date: Fri, 25 Oct 2024 08:04:58 -0700 Subject: [PATCH 1/3] G2-1660 Create basic test --- ax-command/.gitignore | 1 + .../invocation/runner/TestICommandRunner.java | 94 +++++++++++++++++++ .../java/platform/ExecutableSpec.java | 8 ++ 3 files changed, 103 insertions(+) create mode 100644 ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java diff --git a/ax-command/.gitignore b/ax-command/.gitignore index 65cf343b..0c48fbff 100644 --- a/ax-command/.gitignore +++ b/ax-command/.gitignore @@ -3,3 +3,4 @@ /.classpath /.project /.factorypath +/clireport* diff --git a/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java b/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java new file mode 100644 index 00000000..24e3c71b --- /dev/null +++ b/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java @@ -0,0 +1,94 @@ +package com.g2forge.alexandria.command.invocation.runner; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Before; +import org.junit.Test; + +import com.g2forge.alexandria.command.invocation.CommandInvocation; +import com.g2forge.alexandria.command.invocation.environment.SystemEnvironment; +import com.g2forge.alexandria.command.invocation.format.ICommandFormat; +import com.g2forge.alexandria.command.process.HProcess; +import com.g2forge.alexandria.command.stdio.StandardIO; +import com.g2forge.alexandria.java.core.helpers.HCollection; +import com.g2forge.alexandria.java.io.HBinaryIO; +import com.g2forge.alexandria.java.io.HIO; +import com.g2forge.alexandria.java.io.HTextIO; +import com.g2forge.alexandria.java.io.RuntimeIOException; +import com.g2forge.alexandria.java.platform.HPlatform; +import com.g2forge.alexandria.test.HAssert; + +import lombok.Getter; + +public class TestICommandRunner { + protected static final String CLIREPORT_VERSION = "v0.0.1"; + + protected static final String CLIREPORT_FILENAME = "clireport"; + + @Getter + protected Path cliReport; + + @Before + public void before() { + cliReport = Paths.get(HPlatform.getPlatform().getExeSpecs()[0].fromBase(CLIREPORT_FILENAME)); + if (!Files.exists(cliReport)) { + try (final InputStream input = new URL(String.format("https://github.com/g2forge/clireport/releases/download/%1$s/%2$s", CLIREPORT_VERSION, cliReport.getFileName().toString())).openStream(); + final OutputStream output = Files.newOutputStream(cliReport)) { + HBinaryIO.copy(input, output); + } catch (IOException e) { + throw new RuntimeIOException("Failed to download clireport", e); + } + HAssert.assertTrue(Files.exists(cliReport)); + } + } + + @Test + public void test() throws IOException, InterruptedException { + final List arguments = HCollection.asList(getCliReport().toString(), "argument"); + final List output = test(arguments); + final List expected = HCollection.concatenate(HCollection.asList(String.format("CLIReport: %1$d arguments", arguments.size())), arguments.stream().map(argument -> String.format("%1$04d: %2$s", argument.length(), argument)).collect(Collectors.toList())); + HAssert.assertEquals(expected, output); + } + + protected List test(final List arguments) throws IOException, InterruptedException { + final CommandInvocation.CommandInvocationBuilder invocationBuilder = CommandInvocation.builder(); + invocationBuilder.format(ICommandFormat.getDefault()); + invocationBuilder.arguments(arguments); + invocationBuilder.io(new StandardIO<>(ProcessBuilder.Redirect.INHERIT, ProcessBuilder.Redirect.PIPE, ProcessBuilder.Redirect.DISCARD)); + invocationBuilder.working(Paths.get(System.getProperty("user.dir"))); + invocationBuilder.environment(SystemEnvironment.create()); + final CommandInvocation invocation = invocationBuilder.build(); + final CommandInvocation wrapped = ICommandRunner.create(null).wrap(invocation); + final ProcessBuilder processBuilder = HProcess.createProcessBuilder(wrapped); + + final List output = new ArrayList<>(); + final int exitCode; + final Process process = processBuilder.start(); + try { + final Thread thread = new Thread(() -> { + HTextIO.readAll(process.getInputStream(), output::add); + }); + thread.run(); + + exitCode = process.waitFor(); + thread.interrupt(); + } finally { + if (process != null) { + process.descendants().forEach(handle -> handle.destroy()); + process.destroy(); + HIO.closeAll(process.getInputStream(), process.getErrorStream(), process.getOutputStream()); + } + } + HAssert.assertEquals(0, exitCode); + return output; + } +} diff --git a/ax-java/src/main/java/com/g2forge/alexandria/java/platform/ExecutableSpec.java b/ax-java/src/main/java/com/g2forge/alexandria/java/platform/ExecutableSpec.java index b6dacf19..94bef119 100644 --- a/ax-java/src/main/java/com/g2forge/alexandria/java/platform/ExecutableSpec.java +++ b/ax-java/src/main/java/com/g2forge/alexandria/java/platform/ExecutableSpec.java @@ -17,4 +17,12 @@ public enum ExecutableSpec implements IPlatformNamed { protected final String prefix; protected final String suffix; + + public String fromBase(String base) { + final StringBuilder retVal = new StringBuilder(); + if (getPrefix() != null) retVal.append(getPrefix()); + retVal.append(base); + if (getSuffix() != null) retVal.append(getSuffix()); + return retVal.toString(); + } } From 0c4040fd0bde01b5510023f1f620f15100c24b13 Mon Sep 17 00:00:00 2001 From: Greg Gibeling Date: Fri, 25 Oct 2024 08:22:55 -0700 Subject: [PATCH 2/3] G2-1660 Set file permissions --- .../command/invocation/runner/TestICommandRunner.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java b/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java index 24e3c71b..80639a4d 100644 --- a/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java +++ b/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java @@ -7,7 +7,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import java.util.stream.Collectors; @@ -48,6 +50,13 @@ public void before() { throw new RuntimeIOException("Failed to download clireport", e); } HAssert.assertTrue(Files.exists(cliReport)); + try { + Files.setPosixFilePermissions(cliReport, EnumSet.allOf(PosixFilePermission.class)); + } catch (UnsupportedOperationException e) { + // Ignore this - it's not required on platforms where it's not supported + } catch (IOException e) { + throw new RuntimeIOException("Failed to mark clireport executable", e); + } } } From 920cbec9b82704593b503ba2dc22225903002253 Mon Sep 17 00:00:00 2001 From: Greg Gibeling Date: Fri, 25 Oct 2024 16:08:37 -0700 Subject: [PATCH 3/3] G2-1660 Fix testing on linux --- .../invocation/runner/TestICommandRunner.java | 3 ++- .../alexandria/java/platform/PlatformCategory.java | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java b/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java index 80639a4d..9ddc9e72 100644 --- a/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java +++ b/ax-command/src/test/java/com/g2forge/alexandria/command/invocation/runner/TestICommandRunner.java @@ -57,12 +57,13 @@ public void before() { } catch (IOException e) { throw new RuntimeIOException("Failed to mark clireport executable", e); } + HAssert.assertTrue(Files.isExecutable(cliReport)); } } @Test public void test() throws IOException, InterruptedException { - final List arguments = HCollection.asList(getCliReport().toString(), "argument"); + final List arguments = HCollection.asList(HPlatform.getPlatform().getCategory().convertExecutablePathToString(getCliReport()), "argument"); final List output = test(arguments); final List expected = HCollection.concatenate(HCollection.asList(String.format("CLIReport: %1$d arguments", arguments.size())), arguments.stream().map(argument -> String.format("%1$04d: %2$s", argument.length(), argument)).collect(Collectors.toList())); HAssert.assertEquals(expected, output); diff --git a/ax-java/src/main/java/com/g2forge/alexandria/java/platform/PlatformCategory.java b/ax-java/src/main/java/com/g2forge/alexandria/java/platform/PlatformCategory.java index 0b317c0a..07f0ff93 100644 --- a/ax-java/src/main/java/com/g2forge/alexandria/java/platform/PlatformCategory.java +++ b/ax-java/src/main/java/com/g2forge/alexandria/java/platform/PlatformCategory.java @@ -1,6 +1,18 @@ package com.g2forge.alexandria.java.platform; +import java.nio.file.Path; + public enum PlatformCategory { - Posix, + Posix { + @Override + public String convertExecutablePathToString(Path executablePath) { + if (executablePath.isAbsolute()) return executablePath.toString(); + return "./" + executablePath.toString(); + } + }, Microsoft; + + public String convertExecutablePathToString(Path executablePath) { + return executablePath.toString(); + } }