changeset 189:8b2b1bf32131

Make unit tests gracefully exit if mongod is running (currently they hang) Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-June/023804.html
author Christopher Koehler <chkoehle@redhat.com>
date Thu, 29 Jun 2017 10:12:07 -0400
parents 96db1ee35432
children cef59083f9a7
files tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/MongoIntegrationTest.java tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/MongodTestUtil.java
diffstat 3 files changed, 57 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java	Fri Jun 23 08:49:10 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java	Thu Jun 29 10:12:07 2017 -0400
@@ -50,13 +50,10 @@
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
-import com.redhat.thermostat.gateway.tests.utils.MongodTestUtil;
-
 public class IntegrationTest {
     protected static HttpClient client;
     protected static String baseUrl = "http://127.0.0.1:30000";
 
-    protected static final MongodTestUtil mongodTestUtil = new MongodTestUtil();
     protected static final Path distributionImage;
 
     static {
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/MongoIntegrationTest.java	Fri Jun 23 08:49:10 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/MongoIntegrationTest.java	Thu Jun 29 10:12:07 2017 -0400
@@ -36,16 +36,21 @@
 
 package com.redhat.thermostat.gateway.tests.integration;
 
+import static org.junit.Assert.fail;
+
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.Objects;
 
+import com.redhat.thermostat.gateway.tests.utils.MongodTestUtil;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 
 public class MongoIntegrationTest extends IntegrationTest {
 
+    protected static final MongodTestUtil mongodTestUtil = new MongodTestUtil();
+
     protected String collectionName;
 
     public MongoIntegrationTest(String serviceUrl, String collectionName) {
@@ -56,6 +61,9 @@
     @BeforeClass
     public static void beforeClassMongoIntegrationTest() throws Exception {
         mongodTestUtil.startMongod();
+        if (!mongodTestUtil.isConnectedToDatabase()) {
+            fail("Unable to start mongodb database, port in use");
+        }
         setupMongoCredentials();
     }
 
--- a/tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/MongodTestUtil.java	Fri Jun 23 08:49:10 2017 -0400
+++ b/tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/MongodTestUtil.java	Thu Jun 29 10:12:07 2017 -0400
@@ -50,6 +50,10 @@
 import com.mongodb.ServerAddress;
 
 public class MongodTestUtil {
+
+    private static final int WAIT_FOR_MAX_ITERATIONS = 100;
+    private static final long WAIT_FOR_SLEEP_DURATION = 100L;
+
     private final String databaseName = "thermostat";
     private final String host = "127.0.0.1";
     private final int port = 27518;
@@ -59,8 +63,7 @@
     private Path tempDbDir;
     private Path tempLogFile;
     public Process process;
-
-
+    private boolean connectedToDatabase;
 
     public void startMongod() throws IOException, InterruptedException {
         tempDbDir = Files.createTempDirectory("tms-mongo");
@@ -74,19 +77,20 @@
         ProcessBuilder builder = new ProcessBuilder(OS.IS_UNIX ? posixCommand : windowsCommand);
         process = builder.start();
         mongoClient = new MongoClient(new ServerAddress(host, port));
-
-        waitForMongodStart();
+        connectedToDatabase = waitForMongodStart();
     }
 
     public void stopMongod() throws IOException, InterruptedException {
-        try {
-            mongoClient.getDatabase("admin").runCommand(new Document("shutdown", 1));
-        } catch (Exception ignored) {
+        if (connectedToDatabase) {
+            try {
+                mongoClient.getDatabase("admin").runCommand(new Document("shutdown", 1));
+            } catch (Exception ignored) {
+            }
+            mongoClient.close();
+            mongoClient = null;
+            waitForMongodStop();
+            finish();
         }
-        mongoClient.close();
-        mongoClient = null;
-        waitForMongodStop();
-        finish();
     }
 
     public void dropCollection(String collectionName) {
@@ -111,7 +115,7 @@
     }
 
     private boolean waitForMongodStart() throws IOException, InterruptedException {
-        return waitFor("waiting for connections on port");
+        return waitFor("waiting for connections on port", "addr already in use");
     }
 
     private boolean waitForMongodStop() throws IOException, InterruptedException {
@@ -119,16 +123,42 @@
     }
 
     private boolean waitFor(String match) throws IOException, InterruptedException {
-        final String[] s = new String[]{""};
+        return waitFor(match, "");
+    }
 
-        for (int i = 0; i < 100; i++) {
-            if (Files.exists(tempLogFile) && !s[0].contains(match)) {
-                s[0] = new String(Files.readAllBytes(tempLogFile));
-            } else if (s[0].contains(match)) {
-                return true;
+    /**
+     * Keeps checking the temporary log file to see if any of the desired
+     * matches are found in the file. This allows short-circuiting of checking
+     * the files in the event some error happens (like being unable to connect
+     * to the database) so it does not keep cycling for a long period of time.
+     * @param desiredMatch The string to find, returns true if found. Null
+     *                     should not be passed to this argument.
+     * @param errorMatch An error string to return false on finding. An empty
+     *                   string should be used if no error match is needed (it
+     *                   is better to call waitFor(desiredMatch) instead). Null
+     *                   should not be used.
+     * @return True if any of the desired matches were found, false if an error
+     * match was found or it timed out.
+     */
+    private boolean waitFor(String desiredMatch, String errorMatch) throws IOException, InterruptedException {
+        for (int i = 0; i < WAIT_FOR_MAX_ITERATIONS; i++) {
+            if (Files.exists(tempLogFile)) {
+                String logFileText = new String(Files.readAllBytes(tempLogFile));
+                if (logFileText.contains(desiredMatch)) {
+                    return true;
+                }
+                if (!"".equals(errorMatch) && logFileText.contains(errorMatch)) {
+                    return false;
+                }
             }
-            Thread.sleep(100L);
+
+            Thread.sleep(WAIT_FOR_SLEEP_DURATION);
         }
+
         return false;
     }
+
+    public boolean isConnectedToDatabase() {
+        return connectedToDatabase;
+    }
 }
\ No newline at end of file