diff --git a/test/BUILD b/test/BUILD index 013fb042..1435ae1a 100644 --- a/test/BUILD +++ b/test/BUILD @@ -23,6 +23,7 @@ java_library( deps = [ "//:common", "@maven//:commons_io_commons_io", + "@maven//:info_picocli_picocli", "@maven//:junit_junit", "@maven//:org_zeroturnaround_zt_exec", "@maven//:org_slf4j_slf4j_api" diff --git a/test/Util.java b/test/Util.java index 9a9ccd89..29416255 100644 --- a/test/Util.java +++ b/test/Util.java @@ -21,6 +21,7 @@ import org.zeroturnaround.exec.ProcessExecutor; import org.zeroturnaround.exec.ProcessResult; import org.zeroturnaround.exec.StartedProcess; +import picocli.CommandLine; import java.io.File; import java.io.IOException; @@ -36,12 +37,12 @@ import java.util.List; import java.util.Timer; import java.util.TimerTask; +import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import static org.junit.Assert.fail; public class Util { @@ -52,16 +53,24 @@ public class Util { private static final int SERVER_ALIVE_POLL_INTERVAL_MILLIS = 500; private static final int SERVER_ALIVE_POLL_MAX_RETRIES = SERVER_STARTUP_TIMEOUT_MILLIS / SERVER_ALIVE_POLL_INTERVAL_MILLIS; - public static File getArchivePath(int index) { + public static File getServerArchiveFile() { String[] args = System.getProperty("sun.java.command").split(" "); - if (index >= args.length) { - throw new IllegalArgumentException("Distribution archive at index '" + index + "' is not defined"); + Optional maybeOptions = CLIOptions.parseCLIOptions(args); + if (!maybeOptions.isPresent()) { + throw new IllegalArgumentException("No archives were passed as arguments"); } - File file = new File(args[index]); - if (!file.exists()) { - throw new IllegalArgumentException("Distribution archive '" + file.getAbsolutePath() + "' is missing"); + CLIOptions options = maybeOptions.get(); + return new File(options.getServerArchive()); + } + + public static File getConsoleArchiveFile() { + String[] args = System.getProperty("sun.java.command").split(" "); + Optional maybeOptions = CLIOptions.parseCLIOptions(args); + if (!maybeOptions.isPresent()) { + throw new IllegalArgumentException("No archives were passed as arguments"); } - return file; + CLIOptions options = maybeOptions.get(); + return new File(options.getConsoleArchive()); } public static Path unarchive(File archive) throws IOException, TimeoutException, InterruptedException { @@ -199,4 +208,44 @@ public static ProcessExecutor createProcessExecutor(Path directory) { .readOutput(true) .destroyOnExit(); } + + @CommandLine.Command(name = "java") + private static class CLIOptions { + @CommandLine.Parameters String mainClass; + @CommandLine.Option( + names = {"--server"}, + description = "Location of the archive containing a server artifact." + ) + private String serverArchive; + + @CommandLine.Option( + names = {"--console"}, + description = "Location of the archive containing a console artifact." + ) + private String consoleArchive; + + public String getServerArchive() { + return serverArchive; + } + + public String getConsoleArchive() { + return consoleArchive; + } + + public static Optional parseCLIOptions(String[] args) { + CommandLine commandLine = new CommandLine(new CLIOptions()); + try { + CommandLine.ParseResult result = commandLine.parseArgs(args); + return Optional.of(result.asCommandLineList().get(0).getCommand()); + } catch (CommandLine.ParameterException ex) { + commandLine.getErr().println(ex.getMessage()); + if (!CommandLine.UnmatchedArgumentException.printSuggestions(ex, commandLine.getErr())) { + ex.getCommandLine().usage(commandLine.getErr()); + } + return Optional.empty(); + } + } + } } + + diff --git a/test/cluster/TypeDBClusterServerRunner.java b/test/cluster/TypeDBClusterServerRunner.java index bc09f84f..1dca134e 100644 --- a/test/cluster/TypeDBClusterServerRunner.java +++ b/test/cluster/TypeDBClusterServerRunner.java @@ -34,7 +34,7 @@ import java.util.concurrent.TimeoutException; import static com.vaticle.typedb.common.test.Util.createProcessExecutor; -import static com.vaticle.typedb.common.test.Util.getArchivePath; +import static com.vaticle.typedb.common.test.Util.getServerArchiveFile; import static com.vaticle.typedb.common.test.Util.unarchive; public interface TypeDBClusterServerRunner extends TypeDBRunner { @@ -54,15 +54,13 @@ protected TypeDBClusterServerRunner createServerRunner(Map optio class Standalone implements TypeDBClusterServerRunner { - private static final int ARCHIVE_INDEX = 1; - protected final Path distribution; protected final Map serverOptions; private StartedProcess process; protected ProcessExecutor executor; public Standalone(Map serverOptions) throws IOException, InterruptedException, TimeoutException { - distribution = unarchive(getArchivePath(ARCHIVE_INDEX)); + distribution = unarchive(getServerArchiveFile()); this.serverOptions = serverOptions; System.out.println(addresses() + ": " + name() + " constructing runner..."); Files.createDirectories(ClusterServerOpts.storageData(serverOptions)); diff --git a/test/console/TypeDBConsoleRunner.java b/test/console/TypeDBConsoleRunner.java index 41133738..75840126 100644 --- a/test/console/TypeDBConsoleRunner.java +++ b/test/console/TypeDBConsoleRunner.java @@ -28,20 +28,18 @@ import java.util.concurrent.TimeoutException; import static com.vaticle.typedb.common.collection.Collections.list; -import static com.vaticle.typedb.common.test.Util.getArchivePath; +import static com.vaticle.typedb.common.test.Util.getConsoleArchiveFile; import static com.vaticle.typedb.common.test.Util.unarchive; public class TypeDBConsoleRunner { - private static final int ARCHIVE_INDEX = 2; - protected final Path distribution; protected ProcessExecutor executor; public TypeDBConsoleRunner() throws InterruptedException, TimeoutException, IOException { System.out.println("Constructing " + name() + " runner"); System.out.println("Extracting " + name() + " distribution archive."); - distribution = unarchive(getArchivePath(ARCHIVE_INDEX)); + distribution = unarchive(getConsoleArchiveFile()); System.out.println(name() + " distribution archive extracted."); executor = new ProcessExecutor() .directory(distribution.toFile()) diff --git a/test/core/TypeDBCoreRunner.java b/test/core/TypeDBCoreRunner.java index 25f65022..a1f2423b 100644 --- a/test/core/TypeDBCoreRunner.java +++ b/test/core/TypeDBCoreRunner.java @@ -31,14 +31,12 @@ import static com.vaticle.typedb.common.test.Util.createProcessExecutor; import static com.vaticle.typedb.common.test.Util.findUnusedPorts; -import static com.vaticle.typedb.common.test.Util.getArchivePath; +import static com.vaticle.typedb.common.test.Util.getServerArchiveFile; import static com.vaticle.typedb.common.test.Util.typeDBCommand; import static com.vaticle.typedb.common.test.Util.unarchive; public class TypeDBCoreRunner implements TypeDBRunner { - private static final int ARCHIVE_INDEX = 1; - private final Path distribution; private final Path dataDir; private final Path logsDir; @@ -50,7 +48,7 @@ public TypeDBCoreRunner() throws InterruptedException, TimeoutException, IOExcep port = findUnusedPorts(1).get(0); System.out.println(address() + ": Constructing " + name() + " runner"); System.out.println(address() + ": Extracting distribution archive..."); - distribution = unarchive(getArchivePath(ARCHIVE_INDEX)); + distribution = unarchive(getServerArchiveFile()); System.out.println(address() + ": Distribution archive extracted."); dataDir = distribution.resolve("server").resolve("data"); logsDir = distribution.resolve("server").resolve("logs"); diff --git a/test/rules.bzl b/test/rules.bzl index 07d70963..58336680 100644 --- a/test/rules.bzl +++ b/test/rules.bzl @@ -16,42 +16,78 @@ # load("@vaticle_dependencies//builder/java:rules.bzl", "native_dep_for_host_platform") +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_test") def typedb_java_test(name, server_mac_artifact, server_linux_artifact, server_windows_artifact, console_mac_artifact = None, console_linux_artifact = None, console_windows_artifact = None, native_libraries_deps = [], deps = [], classpath_resources = [], data = [], args = [], **kwargs): + native_server_artifact_paths, native_server_artifact_labels = native_artifact_paths_and_labels( - server_mac_artifact, server_linux_artifact, server_windows_artifact - ) - native_console_artifact_paths, native_console_artifact_labels = [], [] - if console_mac_artifact and console_linux_artifact and console_windows_artifact: - native_console_artifact_paths, native_console_artifact_labels = native_artifact_paths_and_labels( - console_mac_artifact, console_linux_artifact, console_windows_artifact + server_mac_artifact, server_linux_artifact, server_windows_artifact + ) + + native_console_artifact_paths, native_console_artifact_labels = native_artifact_paths_and_labels( + console_mac_artifact, console_linux_artifact, console_windows_artifact, mandatory = False ) - native_deps = [] - for dep in native_libraries_deps: - native_deps = native_deps + native_dep_for_host_platform(dep) + + native_dependencies = get_native_dependencies(native_libraries_deps) + native.java_test( name = name, - deps = depset(deps + ["@vaticle_typedb_common//test:typedb-runner"]).to_list() + native_deps, + deps = depset(deps + ["@vaticle_typedb_common//test:typedb-runner"]).to_list() + native_dependencies, classpath_resources = depset(classpath_resources + ["@vaticle_typedb_common//test:logback"]).to_list(), data = data + select(native_server_artifact_labels) + (select(native_console_artifact_labels) if native_console_artifact_labels else []), - args = select(native_server_artifact_paths) + (select(native_console_artifact_paths) if native_console_artifact_paths else []) + args, + args = ["--server"] + select(native_server_artifact_paths) + ((["--console"] + select(native_console_artifact_paths)) if native_console_artifact_paths else []) + args, **kwargs ) -def native_artifact_paths_and_labels(mac_artifact, linux_artifact, windows_artifact): - native_artifacts = { - "@vaticle_dependencies//util/platform:is_mac": mac_artifact, - "@vaticle_dependencies//util/platform:is_linux": linux_artifact, - "@vaticle_dependencies//util/platform:is_windows": windows_artifact, - } - native_artifact_paths = {} - native_artifact_labels = {} - for key in native_artifacts.keys(): - native_artifact_labels[key] = [ native_artifacts[key] ] - native_artifact_paths[key] = [ "$(location {})".format(native_artifacts[key]) ] - return native_artifact_paths, native_artifact_labels +def typedb_kt_test(name, server_mac_artifact, server_linux_artifact, server_windows_artifact, + console_mac_artifact = None, console_linux_artifact = None, console_windows_artifact = None, + native_libraries_deps = [], deps = [], data = [], args = [], **kwargs): + + native_server_artifact_paths, native_server_artifact_labels = native_artifact_paths_and_labels( + server_mac_artifact, server_linux_artifact, server_windows_artifact + ) + + native_console_artifact_paths, native_console_artifact_labels = native_artifact_paths_and_labels( + console_mac_artifact, console_linux_artifact, console_windows_artifact, mandatory = False + ) + + native_dependencies = get_native_dependencies(native_libraries_deps) + + kt_jvm_test( + name = name, + deps = depset(deps + ["@vaticle_typedb_common//test:typedb-runner"]).to_list() + native_dependencies, + data = data + select(native_server_artifact_labels) + (select(native_console_artifact_labels) if native_console_artifact_labels else []), + args = ["--server"] + select(native_server_artifact_paths) + ((["--console"] + select(native_console_artifact_paths)) if native_console_artifact_paths else []) + args, + **kwargs + ) + +def get_native_dependencies(native_libraries_deps): + native_dependencies = [] + for dep in native_libraries_deps: + native_dependencies = native_dependencies + native_dep_for_host_platform(dep) + return native_dependencies + + +def native_artifact_paths_and_labels(mac_artifact, linux_artifact, windows_artifact, mandatory = True): + if mac_artifact and linux_artifact and windows_artifact: + native_artifacts = { + "@vaticle_dependencies//util/platform:is_mac": mac_artifact, + "@vaticle_dependencies//util/platform:is_linux": linux_artifact, + "@vaticle_dependencies//util/platform:is_windows": windows_artifact, + } + native_artifact_paths = {} + native_artifact_labels = {} + for key in native_artifacts.keys(): + native_artifact_labels[key] = [ native_artifacts[key] ] + native_artifact_paths[key] = [ "$(location {})".format(native_artifacts[key]) ] + return native_artifact_paths, native_artifact_labels + elif mandatory: + fail("Mandatory artifacts weren't available.") + else: + return [], [] + def native_typedb_artifact(name, mac_artifact, linux_artifact, windows_artifact, output, **kwargs): native.genrule(