Mercurial > hg > thermostat-ng > web-gateway
view tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/MongodTestUtil.java @ 276:0ec0aad214cb
tests: reworked mongodb start and stop wait conditions
author | Zdenek Zambersky <zzambers@redhat.com> |
---|---|
date | Mon, 09 Oct 2017 17:09:00 +0200 |
parents | e159ff4b557f |
children | 4ef47fad072a |
line wrap: on
line source
/* * Copyright 2012-2017 Red Hat, Inc. * * This file is part of Thermostat. * * Thermostat is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2, or (at your * option) any later version. * * Thermostat is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Thermostat; see the file COPYING. If not see * <http://www.gnu.org/licenses/>. * * Linking this code with other modules is making a combined work * based on this code. Thus, the terms and conditions of the GNU * General Public License cover the whole combination. * * As a special exception, the copyright holders of this code give * you permission to link this code with independent modules to * produce an executable, regardless of the license terms of these * independent modules, and to copy and distribute the resulting * executable under terms of your choice, provided that you also * meet, for each linked independent module, the terms and conditions * of the license of that module. An independent module is a module * which is not derived from or based on this code. If you modify * this code, you may extend this exception to your version of the * library, but you are not obligated to do so. If you do not wish * to do so, delete this exception statement from your version. */ package com.redhat.thermostat.gateway.tests.utils; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.ServerAddress; import com.mongodb.client.MongoCollection; import com.redhat.thermostat.gateway.common.util.OS; import java.net.Socket; import java.net.ServerSocket; import java.net.SocketAddress; import java.net.InetSocketAddress; public class MongodTestUtil { private static final int WAIT_FOR_MAX_ITERATIONS = 100; private static final long WAIT_FOR_SLEEP_DURATION = 250L; private static final int DEFAULT_PORT = 27519; private final String databaseName = "thermostat"; private final String host = "127.0.0.1"; private final int port; public final String listenAddress; private MongoClient mongoClient; private Path tempDbDir; private Path tempLogFile; public Process process; private boolean connectedToDatabase; public MongodTestUtil() { this(DEFAULT_PORT); } public MongodTestUtil(int port) { this.port = port; this.listenAddress = host + ":" + port; } public void startMongod() throws IOException, InterruptedException { tempDbDir = Files.createTempDirectory("tms-mongo"); tempDbDir.toFile().deleteOnExit(); Files.createDirectories(tempDbDir.resolve("data/db")); tempLogFile = tempDbDir.resolve("mongod.log"); tempLogFile.toFile().deleteOnExit(); String[] posixCommand = {"mongod", "--dbpath", tempDbDir.resolve("data/db").toAbsolutePath().toString(), "--port", String.valueOf(port), "--fork", "--logpath", tempLogFile.toAbsolutePath().toString()}; String[] windowsCommand = {"cmd", "/c", "mongod", "--dbpath", tempDbDir.resolve("data/db").toAbsolutePath().toString(), "--port", String.valueOf(port), "--logpath", tempLogFile.toAbsolutePath().toString()}; ProcessBuilder builder = new ProcessBuilder(OS.IS_UNIX ? posixCommand : windowsCommand); process = builder.start(); waitForSocketToBind(host, port); mongoClient = new MongoClient(new ServerAddress(host, port)); } public void stopMongod() throws IOException, InterruptedException { if (mongoClient != null) { try { mongoClient.getDatabase("admin").runCommand(new Document("shutdown", 1)); } catch (Exception ignored) { /* following exception is always thrown: com.mongodb.MongoSocketReadException: Prematurely reached end of stream ( probably expected, connection gets closed? ) */ } finally { mongoClient.close(); mongoClient = null; } waitForSocketToClose(port); finish(); } } public void dropCollection(String collectionName) { mongoClient.getDatabase(databaseName).getCollection(collectionName).drop(); } public MongoCollection<Document> getCollection(String collectionName) { return mongoClient.getDatabase(databaseName).getCollection(collectionName); } private void finish() throws IOException { Files.walkFileTree(tempDbDir, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } }); } private void waitForSocketToBind(String host, int port) throws InterruptedException { for (int i = 0; i < WAIT_FOR_MAX_ITERATIONS; ++i) { /* Try to connect to socket, if it fails, port is not bound yet */ try (Socket socket = new Socket()) { SocketAddress address = new InetSocketAddress(host, port); socket.connect(address); return; } catch (IOException e) { /* ignored */ } Thread.sleep(WAIT_FOR_SLEEP_DURATION); } throw new RuntimeException("Timeout waiting for mongodb socket to bind reached!"); } private void waitForSocketToClose(int port) throws InterruptedException { for (int i = 0; i < WAIT_FOR_MAX_ITERATIONS; ++i) { /* Try to bind socket, if it fails, port is still in use */ try (ServerSocket socket = new ServerSocket()) { SocketAddress address = new InetSocketAddress(port); socket.bind(address, 0); return; } catch (IOException e) { /* ignored */ } Thread.sleep(WAIT_FOR_SLEEP_DURATION); } throw new RuntimeException("Timeout waiting for mongodb socket to close reached!"); } }