diff --git a/.gitignore b/.gitignore index 399027e..42addb0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .nrepl* +/test/resources/server \ No newline at end of file diff --git a/build.boot b/build.boot index 81da8fa..1f0ce36 100755 --- a/build.boot +++ b/build.boot @@ -1,13 +1,14 @@ (set-env! - :source-paths #{"src"} + :source-paths #{"src" "test"} :dependencies '[; dev - [adzerk/bootlaces "0.1.13" :scope "test"] - [adzerk/boot-test "1.1.2" :scope "test"] - [str-to-argv "0.1.0" :scope "test"] + [adzerk/bootlaces "0.1.13" :scope "test"] + [junit/junit "4.12" :scope "test"] + [radicalzephyr/boot-junit "0.2.1" :scope "test"] + [str-to-argv "0.1.0" :scope "test"] ; needed in order to run the "alda repl" command in dev - [alda/core "0.1.2" :scope "test"] - [alda/sound-engine-clj "0.1.0" :scope "test"] - [alda/repl-clj "0.1.0" :scope "test"] + [alda/core "0.1.2" :scope "test"] + [alda/sound-engine-clj "0.1.0" :scope "test"] + [alda/repl-clj "0.1.0" :scope "test"] ; silence slf4j logging dammit [org.slf4j/slf4j-nop "1.7.21"] @@ -22,7 +23,8 @@ [com.jcabi/jcabi-manifests "1.1"] [org.zeromq/jeromq "0.3.5"]]) -(require '[adzerk.bootlaces :refer :all]) +(require '[adzerk.bootlaces :refer :all] + '[radicalzephyr.boot-junit :refer (junit)]) (def ^:const +version+ "0.1.1") @@ -52,6 +54,12 @@ target {:dir #{"target"}}) +(deftask test + "Compile and run jUnit tests." + [] + (comp (javac) + (junit))) + (deftask dev "Runs the Alda client for development. diff --git a/test/java/alda/integrationtests/AldaClientTest.java b/test/java/alda/integrationtests/AldaClientTest.java new file mode 100644 index 0000000..904c9ec --- /dev/null +++ b/test/java/alda/integrationtests/AldaClientTest.java @@ -0,0 +1,106 @@ +package alda.integrationtests; + +import alda.AldaClient; +import alda.testutils.AldaServerInfo; +import alda.testutils.TestEnvironment; +import alda.testutils.TestEnvironmentStatus; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.Assert.*; + +public class AldaClientTest { + + private final ByteArrayOutputStream stdOutContent = new ByteArrayOutputStream(); + + @BeforeClass + public static void checkTestEnvironment() throws Exception { + if (TestEnvironment.getStatus() == TestEnvironmentStatus.STOPPED){ + TestEnvironment.setUp(); + } + } + + @AfterClass + public static void tearDown() throws Exception { + TestEnvironment.tearDown(); + } + + @Test + public void listProcessesOutput() throws Exception { + + // Redirect StdOut + PrintStream oldStdOut = System.out; + System.setOut(new PrintStream(stdOutContent)); + try { + + AldaClient.listProcesses(30); + + Map serverPortsFound = new HashMap<>(); + Pattern serverPortPattern = Pattern.compile("\\[(.*?)\\]"); + Pattern serverBackendPortPattern = Pattern.compile("backend port\\:(.*?)\\)"); + + String[] stdOutLines = stdOutContent.toString().split("\n"); + for (String line : stdOutLines){ + // Format: [27716] Server up (2/2 workers available, backend port: 39998) + if (line.contains("Server up")){ + Matcher sp = serverPortPattern.matcher(line); + if (sp.find()){ + int srvPort = Integer.parseInt(cleanAnsiEscapes(sp.group(1))); + int numberOfWorkers = 0; + + Matcher sbp = serverBackendPortPattern.matcher(line); + if (sbp.find()){ + int srvBackendPort = Integer.parseInt(sbp.group(1).trim()); + numberOfWorkers = parseOutputForNumberOfWorkersOnBackendPort(stdOutLines, srvBackendPort); + } + + serverPortsFound.put(srvPort, numberOfWorkers); + } + } + } + + for(AldaServerInfo server: TestEnvironment.getRunningServers()) { + assertTrue("Running server not listed.", serverPortsFound.containsKey(server.getPort()) ); + assertEquals("Number of workers for server don't match.", server.getNumberOfWorkers(), serverPortsFound.get(server.getPort()).intValue() ); + } + + } finally { + // Reset StdOut + System.setOut(oldStdOut); + System.out.println(stdOutContent); + } + + } + + private String cleanAnsiEscapes(String string) { + return string.replaceAll("\u001B\\[[;\\d]*m", ""); + } + + private int parseOutputForNumberOfWorkersOnBackendPort(String[] lines, int srv_backend_port) { + int workersFound = 0; + for (String line : lines) { + // Format: [46672] Worker (pid: 6368) + if (line.contains("["+srv_backend_port+"] Worker")) { + workersFound++; + } + } + return workersFound; + } + + @Test + public void testCheckForExistingServer() throws Exception { + for(AldaServerInfo server: TestEnvironment.getRunningServers()) { + assertTrue("Alda Client didn't detect running server.", AldaClient.checkForExistingServer(server.getPort()) ); + } + assertFalse("Alda Client detects running Server on a port where there should be none. ",AldaClient.checkForExistingServer(TestEnvironment.NO_SERVER_RUNNING_PORT)); + } + +} \ No newline at end of file diff --git a/test/java/alda/testutils/AldaServerInfo.java b/test/java/alda/testutils/AldaServerInfo.java new file mode 100644 index 0000000..5ac8518 --- /dev/null +++ b/test/java/alda/testutils/AldaServerInfo.java @@ -0,0 +1,26 @@ +package alda.testutils; + +public class AldaServerInfo { + + private String host; + private int port; + private int numberOfWorkers; + + public AldaServerInfo(String host, int port, int numberOfWorkers) { + this.host = host; + this.port = port; + this.numberOfWorkers = numberOfWorkers; + } + + public void setPort(int port) { + this.port = port; + } + + public int getPort() { + return port; + } + + public int getNumberOfWorkers() { + return numberOfWorkers; + } +} diff --git a/test/java/alda/testutils/TestEnvironment.java b/test/java/alda/testutils/TestEnvironment.java new file mode 100644 index 0000000..99db082 --- /dev/null +++ b/test/java/alda/testutils/TestEnvironment.java @@ -0,0 +1,104 @@ +package alda.testutils; + +import java.io.*; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.List; + +public class TestEnvironment { + + private static final String ALDA_EXEC_ENVIRONMENT_VAR = "ALDA_EXECUTABLE"; + private static final String ALDA_EXEC_INSTALL_PATH_UNIX = "/usr/local/bin/alda"; + private static final String ALDA_EXEC_FALLBACK = "test/resources/server/alda"; + + private static TestEnvironmentStatus STATUS = TestEnvironmentStatus.STOPPED; + private static List RUNNING_SERVERS; + private static String ALDA_EXECUTABLE; + public static int NO_SERVER_RUNNING_PORT; + + public static void setUp() throws Exception { + + STATUS = TestEnvironmentStatus.STARTING; + + ALDA_EXECUTABLE = findAldaExecutable(); + NO_SERVER_RUNNING_PORT = findOpenPort(); + + // Start 2 Servers with different number of workers + RUNNING_SERVERS = new ArrayList<>(2); + RUNNING_SERVERS.add(new AldaServerInfo("localhost", 0, 2)); + RUNNING_SERVERS.add(new AldaServerInfo("localhost", 0, 1)); + + for (AldaServerInfo srv: RUNNING_SERVERS){ + srv.setPort(findOpenPort()); + // We are also checking for correct number of workers, so stop possible running instances + TestEnvironment.stopAldaServer(srv.getPort()); + // start server on port with number of workers + TestEnvironment.startAldaServerIfNotRunning(srv.getPort(), srv.getNumberOfWorkers()); + } + + // ensure that there is no server running on NO_SERVER_RUNNING_PORT + TestEnvironment.stopAldaServer(NO_SERVER_RUNNING_PORT); + + STATUS = TestEnvironmentStatus.STARTED; + } + + private static String findAldaExecutable() { + + // 1. check environment variable + if (System.getenv(ALDA_EXEC_ENVIRONMENT_VAR) != null) { + return System.getenv(ALDA_EXEC_ENVIRONMENT_VAR); + } + // 2. check default alda *nix install path + if (new File(ALDA_EXEC_INSTALL_PATH_UNIX).exists()){ + return ALDA_EXEC_INSTALL_PATH_UNIX; + } + + // 3. default fallback + return ALDA_EXEC_FALLBACK; + } + + public static void tearDown() throws Exception { + for (AldaServerInfo srv: RUNNING_SERVERS){ + TestEnvironment.stopAldaServer(srv.getPort()); + } + STATUS = TestEnvironmentStatus.STOPPED; + } + + public static List getRunningServers() { + return RUNNING_SERVERS; + } + + public static TestEnvironmentStatus getStatus() { + return STATUS; + } + + private static void startAldaServerIfNotRunning(int port, int numberOfWorkers ) throws IOException{ + Process p = Runtime.getRuntime().exec(ALDA_EXECUTABLE+" -p "+port+" -w "+numberOfWorkers+" up"); + printProcessOutput(p.getInputStream()); + } + + private static void stopAldaServer(int port) { + try { + Process p = Runtime.getRuntime().exec(ALDA_EXECUTABLE+" -p "+port+" down"); + printProcessOutput(p.getInputStream()); + } catch (IOException ignore) {} + + } + + private static void printProcessOutput(InputStream inputStream) throws IOException { + InputStreamReader isr = new InputStreamReader(inputStream); + BufferedReader input = new BufferedReader(isr); + String line; + while ((line = input.readLine()) != null) { + System.out.println(line); + } + } + + public static int findOpenPort() throws IOException { + ServerSocket tmpSocket = new ServerSocket(0); + int portNumber = tmpSocket.getLocalPort(); + tmpSocket.close(); + return portNumber; + } + +} diff --git a/test/java/alda/testutils/TestEnvironmentStatus.java b/test/java/alda/testutils/TestEnvironmentStatus.java new file mode 100644 index 0000000..f0382e2 --- /dev/null +++ b/test/java/alda/testutils/TestEnvironmentStatus.java @@ -0,0 +1,5 @@ +package alda.testutils; + +public enum TestEnvironmentStatus { + STARTED, STOPPED, STARTING +}