Mercurial > hg > release > thermostat-0.13
changeset 191:4a33f41c7782
Merge
author | Roman Kennke <rkennke@redhat.com> |
---|---|
date | Mon, 02 Apr 2012 22:27:05 +0200 |
parents | b196e5b5ba8c (current diff) cf6babcbd925 (diff) |
children | 7630545a635f f2ce7773b93c |
files | distribution/scripts/localmongo.sh |
diffstat | 8 files changed, 388 insertions(+), 253 deletions(-) [+] |
line wrap: on
line diff
--- a/README Mon Apr 02 22:25:51 2012 +0200 +++ b/README Mon Apr 02 22:27:05 2012 +0200 @@ -2,15 +2,23 @@ REQUIREMENTS: -MongoDB and associated Java driver +Maven (it will download all the java dependencies for you) + +MongoDB http://www.mongodb.org/ -JFreeChart -http://www.jfree.org/jfreechart/ BUILDING THERMOSTAT: -1. Read ant-build.properties, including in-line documentation, and edit as appropriate to - ensure required libraries can be found and the build otherwise configured to your liking. -2. Run "ant dist". -3. The resultant Thermostat system can now be found under the directory dist/ +1. Run "mvn clean package". All tests should pass and the build should succeed. + Requires a graphical environment for the ui tests. +2. The resultant Thermostat system can now be found under the directory + distribution/target. + +RUNNING THERMOSTAT: + +1. To start the agent and the db: + bin/thermostat-service --start + +2. To start the client: + bin/thermostat-client-gui
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java Mon Apr 02 22:25:51 2012 +0200 +++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java Mon Apr 02 22:27:05 2012 +0200 @@ -57,8 +57,11 @@ Chunk query = new Chunk(VmMemoryStatDAO.vmMemoryStatsCategory, false); query.put(Key.AGENT_ID, ref.getAgent().getAgentId()); query.put(VmMemoryStatDAO.vmIdKey, ref.getId()); - Cursor cursor = storage.findAll(query).sort(Key.AGENT_ID, Cursor.SortDirection.DESCENDING).limit(1); - return new VmMemoryStatConverter().chunkToVmMemoryStat(cursor.next()); + Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1); + if (cursor.hasNext()) { + return new VmMemoryStatConverter().chunkToVmMemoryStat(cursor.next()); + } + return null; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/src/main/java/com/redhat/thermostat/tools/ApplicationException.java Mon Apr 02 22:27:05 2012 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright 2012 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.tools; + +public class ApplicationException extends Exception { + + public ApplicationException() { + } + + public ApplicationException(String message) { + super(message); + } + + public ApplicationException(Throwable cause) { + super(cause); + } + + public ApplicationException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +}
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Mon Apr 02 22:25:51 2012 +0200 +++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Mon Apr 02 22:27:05 2012 +0200 @@ -38,12 +38,24 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.Collection; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import com.redhat.thermostat.common.model.VmMemoryStat; +import com.redhat.thermostat.common.storage.Chunk; +import com.redhat.thermostat.common.storage.Cursor; +import com.redhat.thermostat.common.storage.Cursor.SortDirection; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Storage; public class VmMemoryStatDAOTest { @Test @@ -81,4 +93,73 @@ assertTrue(keys.contains(new Key<Long>("perm.used", false))); assertEquals(27, keys.size()); } + + @Test + public void testGetLatest() { + final int VM_ID = 0xcafe; + final String AGENT_ID = "agent"; + + HostRef hostRef = mock(HostRef.class); + when(hostRef.getAgentId()).thenReturn(AGENT_ID); + + VmRef vmRef = mock(VmRef.class); + when(vmRef.getAgent()).thenReturn(hostRef); + when(vmRef.getId()).thenReturn(VM_ID); + + Storage storage = mock(Storage.class); + + final Object[] savedQuery = new Object[1]; + final Cursor cursor = mock(Cursor.class); + when(storage.findAll(any(Chunk.class))).thenAnswer(new Answer<Cursor>() { + @Override + public Cursor answer(InvocationOnMock invocation) throws Throwable { + savedQuery[0] = invocation.getArguments()[0]; + return cursor; + } + + }); + when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor); + when(cursor.limit(any(Integer.class))).thenReturn(cursor); + when(cursor.hasNext()).thenReturn(false); + + VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage, vmRef); + impl.getLatestMemoryStat(); + + ArgumentCaptor<Key> sortKey = ArgumentCaptor.forClass(Key.class); + ArgumentCaptor<SortDirection> sortDirection = ArgumentCaptor.forClass(SortDirection.class); + verify(cursor).sort(sortKey.capture(), sortDirection.capture()); + + Chunk query = (Chunk) savedQuery[0]; + assertEquals(AGENT_ID, query.get(Key.AGENT_ID)); + assertEquals((Integer)VM_ID, query.get(VmMemoryStatDAO.vmIdKey)); + + assertTrue(sortKey.getValue().equals(Key.TIMESTAMP)); + assertTrue(sortDirection.getValue().equals(SortDirection.DESCENDING)); + } + + @Test + public void testGetLatestReturnsNullWhenStorageEmpty() { + final int VM_ID = 0xcafe; + final String AGENT_ID = "agent"; + + HostRef hostRef = mock(HostRef.class); + when(hostRef.getAgentId()).thenReturn(AGENT_ID); + + VmRef vmRef = mock(VmRef.class); + when(vmRef.getAgent()).thenReturn(hostRef); + when(vmRef.getId()).thenReturn(VM_ID); + + Cursor cursor = mock(Cursor.class); + when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor); + when(cursor.limit(any(Integer.class))).thenReturn(cursor); + when(cursor.hasNext()).thenReturn(false); + when(cursor.next()).thenReturn(null); + + Storage storage = mock(Storage.class); + when(storage.findAll(any(Chunk.class))).thenReturn(cursor); + + VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage, vmRef); + VmMemoryStat latest = impl.getLatestMemoryStat(); + assertTrue(latest == null); + } }
--- a/distribution/scripts/localmongo.sh Mon Apr 02 22:25:51 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -#!/bin/bash -# -# Copyright 2012 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. -# -##################################################################### -# -# Find the directory where thermostat is installed. -# Note this will not work if there are symlinks to resolve that -# are not full paths. -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done -THERM_DIR=`dirname "$( cd -P "$( dirname "$SOURCE" )" && pwd )"` -# Some variables are sourced from properties file -. "${THERM_DIR}/config/agent.properties" -# Other relevant directory/file locations -USER_THERM_DIR="${HOME}/.thermostat" -MONGO_DIR="${USER_THERM_DIR}/mongod" -MONGO_PIDDIR="${MONGO_DIR}/run" -MONGO_PIDFILE="${MONGO_PIDDIR}/mongod.pid" -MONGO_PID=`cat ${MONGO_PIDFILE}` -MONGO_LOGDIR="${MONGO_DIR}/log" -MONGO_LOGFILE="${MONGO_LOGDIR}/mongod.log" -# FIXME noauth is not really appropriate. -MONGO_ARGS="--quiet --fork --nojournal --noauth --bind_ip 127.0.0.1 \ - --dbpath ${MONGO_DIR} --logpath ${MONGO_LOGFILE} \ - --pidfilepath ${MONGO_PIDFILE} --port ${mongod_port}" - -function make_directories { - mkdir -p "${MONGO_PIDDIR}" - mkdir -p "${MONGO_LOGDIR}" -} - -function do_start { - if [ ! -z ${MONGO_PID} ]; then - echo "Private mongo instance already running" - exit -1 - fi - make_directories - mongod ${MONGO_ARGS} -} - -function do_stop { - if [ -z ${MONGO_PID} ]; then - echo "Private mongo instance not running" - exit -1 - fi - MONGO_PID=`cat ${MONGO_PIDFILE}` - kill ${MONGO_PID} - rm -f ${MONGO_PIDFILE} -} - -function usage { - echo "Usage:" - echo " localmongo.sh <start|stop>" -} - -if [ $# != 1 ]; then - usage - exit -1 -fi - -if [ $1 = "start" ]; then - do_start -elif [ $1 = "stop" ]; then - do_stop -else - usage - exit -1 -fi -
--- a/tools/src/main/java/com/redhat/thermostat/tools/db/DBService.java Mon Apr 02 22:25:51 2012 +0200 +++ b/tools/src/main/java/com/redhat/thermostat/tools/db/DBService.java Mon Apr 02 22:27:05 2012 +0200 @@ -36,20 +36,16 @@ package com.redhat.thermostat.tools.db; -import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import com.redhat.thermostat.common.config.ConfigUtils; import com.redhat.thermostat.common.config.InvalidConfigurationException; -import com.redhat.thermostat.common.utils.LoggedExternalProcess; +import com.redhat.thermostat.tools.ApplicationException; import com.redhat.thermostat.tools.BasicApplication; public class DBService extends BasicApplication { @@ -57,13 +53,7 @@ private DBStartupConfiguration configuration; private DBOptionParser parser; - private static final String [] MONGO_BASIC_ARGS = { - "mongod", "--quiet", "--fork", "--nojournal", "--noauth", "--bind_ip" - }; - - private static final String [] MONGO_SHUTDOWN_ARGS = { - "mongod", "--shutdown", "--dbpath" - }; + private MongoProcessRunner runner; @Override public void parseArguments(List<String> args) throws InvalidConfigurationException { @@ -123,105 +113,16 @@ } } - private void startService() throws IOException, InterruptedException { - - String pid = checkPid(); - if (pid != null) { - String message = "cannot start server " + configuration.getDBPath() + - ", found pid file rom previous run, please, cleanup"; - display(message); - notifyFail(); - return; - } - - List<String> commands = new ArrayList<>(Arrays.asList(MONGO_BASIC_ARGS)); - - // check that the db directory exist - display("starting storage server..."); - - commands.add(configuration.getBindIP()); - - commands.add("--dbpath"); - commands.add(configuration.getDBPath().getCanonicalPath()); - - commands.add("--logpath"); - commands.add(configuration.getLogFile().getCanonicalPath()); - - commands.add("--pidfilepath"); - commands.add(configuration.getPidFile().getCanonicalPath()); - - commands.add("--port"); - if (configuration.isLocal()) { - commands.add(Long.toString(configuration.getLocalPort())); - } else { - commands.add(Long.toString(configuration.getClusterPort())); - } - - LoggedExternalProcess process = new LoggedExternalProcess(commands); - int status = process.runAndReturnResult(); - if (status == 0) { - pid = checkPid(); - if (pid == null) status = -1; - } - - if (status == 0) { - display("server listening on ip: " + configuration.getDBConnectionString()); - display("log file is here: " + configuration.getLogFile()); - display("pid: " + pid); - notifySuccess(); - - } else { - - String message = "cannot start server " + configuration.getDBPath() + - ", exit status: " + status + - ". Please check that your configuration is valid"; - display(message); - notifyFail(); - } + private void startService() throws IOException, InterruptedException, InvalidConfigurationException, ApplicationException { + runner.startService(); + notifySuccess(); } - private String checkPid() { - String pid = null; - // check the pid to be sure - File pidfile = configuration.getPidFile(); - Charset charset = Charset.defaultCharset(); - if (pidfile.exists()) { - try (BufferedReader reader = Files.newBufferedReader(pidfile.toPath(), charset)) { - pid = reader.readLine(); - if (pid == null || pid.isEmpty()) { - pid = null; - } - } catch (IOException ignore) { - ignore.printStackTrace(); - pid = null; - } - } - - return pid; - } - private void stopService() throws IOException, InterruptedException, InvalidConfigurationException { + private void stopService() throws IOException, InterruptedException, InvalidConfigurationException, ApplicationException { check(); - - List<String> commands = new ArrayList<>(Arrays.asList(MONGO_SHUTDOWN_ARGS)); - commands.add(configuration.getDBPath().getCanonicalPath()); - - LoggedExternalProcess process = new LoggedExternalProcess(commands); - int status = process.runAndReturnResult(); - if (status == 0) { - display("server shutdown complete: " + configuration.getDBPath()); - display("log file is here: " + configuration.getLogFile()); - notifySuccess(); - - } else { - // TODO: check the pid and see if it's running or not - // perhaps was already down - String message = "cannot shutdown server " + configuration.getDBPath() + - ", exit status: " + status + - ". Please check that your configuration is valid"; - display(message); - notifyFail(); - } + runner.stopService(); + notifySuccess(); } @Override @@ -229,6 +130,8 @@ if (parser.isDryRun()) return; + runner = createRunner(); + try { switch (parser.getAction()) { case START: @@ -244,10 +147,14 @@ } } + MongoProcessRunner createRunner() { + return new MongoProcessRunner(configuration, parser.isQuiet()); + } + private void check() throws InvalidConfigurationException { if (!configuration.getDBPath().exists() || - !configuration.getLogFile().getParentFile().exists() || - !configuration.getPidFile().getParentFile().exists()) + !configuration.getLogFile().getParentFile().exists() || + !configuration.getPidFile().getParentFile().exists()) { throw new InvalidConfigurationException("database directories do not exist..."); } @@ -263,12 +170,6 @@ return configuration; } - private void display(String message) { - if (!parser.isQuiet()) { - System.out.println(message); - } - } - public static void main(String[] args) throws InvalidConfigurationException { DBService service = new DBService(); service.parseArguments(Arrays.asList(args));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/db/MongoProcessRunner.java Mon Apr 02 22:27:05 2012 +0200 @@ -0,0 +1,173 @@ +/* + * Copyright 2012 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.tools.db; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.redhat.thermostat.common.config.InvalidConfigurationException; +import com.redhat.thermostat.common.utils.LoggedExternalProcess; + +import com.redhat.thermostat.tools.ApplicationException; + +class MongoProcessRunner { + + private static final String [] MONGO_BASIC_ARGS = { + "mongod", "--quiet", "--fork", "--nojournal", "--noauth", "--bind_ip" + }; + + private static final String [] MONGO_SHUTDOWN_ARGS = { + "mongod", "--shutdown", "--dbpath" + }; + + private DBStartupConfiguration configuration; + private boolean isQuiet; + + MongoProcessRunner(DBStartupConfiguration configuration, boolean quiet) { + this.configuration = configuration; + this.isQuiet = quiet; + } + + private String checkPid() { + String pid = null; + // check the pid to be sure + File pidfile = configuration.getPidFile(); + Charset charset = Charset.defaultCharset(); + if (pidfile.exists()) { + try (BufferedReader reader = Files.newBufferedReader(pidfile.toPath(), charset)) { + pid = reader.readLine(); + if (pid == null || pid.isEmpty()) { + pid = null; + } + } catch (IOException ignore) { + ignore.printStackTrace(); + pid = null; + } + } + + return pid; + } + + void stopService() throws IOException, InterruptedException, InvalidConfigurationException, ApplicationException { + + List<String> commands = new ArrayList<>(Arrays.asList(MONGO_SHUTDOWN_ARGS)); + commands.add(configuration.getDBPath().getCanonicalPath()); + + LoggedExternalProcess process = new LoggedExternalProcess(commands); + int status = process.runAndReturnResult(); + if (status == 0) { + display("server shutdown complete: " + configuration.getDBPath()); + display("log file is here: " + configuration.getLogFile()); + + } else { + // TODO: check the pid and see if it's running or not + // perhaps was already down + String message = "cannot shutdown server " + configuration.getDBPath() + + ", exit status: " + status + + ". Please check that your configuration is valid"; + display(message); + throw new ApplicationException(message); + } + } + + void startService() throws IOException, InterruptedException, ApplicationException { + + String pid = checkPid(); + if (pid != null) { + String message = "cannot start server " + configuration.getDBPath() + + ", found pid file rom previous run, please, cleanup"; + display(message); + throw new ApplicationException(message); + } + + List<String> commands = new ArrayList<>(Arrays.asList(MONGO_BASIC_ARGS)); + + // check that the db directory exist + display("starting storage server..."); + + commands.add(configuration.getBindIP()); + + commands.add("--dbpath"); + commands.add(configuration.getDBPath().getCanonicalPath()); + + commands.add("--logpath"); + commands.add(configuration.getLogFile().getCanonicalPath()); + + commands.add("--pidfilepath"); + commands.add(configuration.getPidFile().getCanonicalPath()); + + commands.add("--port"); + if (configuration.isLocal()) { + commands.add(Long.toString(configuration.getLocalPort())); + } else { + commands.add(Long.toString(configuration.getClusterPort())); + } + + LoggedExternalProcess process = new LoggedExternalProcess(commands); + int status = process.runAndReturnResult(); + if (status == 0) { + pid = checkPid(); + if (pid == null) status = -1; + } + + if (status == 0) { + display("server listening on ip: " + configuration.getDBConnectionString()); + display("log file is here: " + configuration.getLogFile()); + display("pid: " + pid); + + } else { + + String message = "cannot start server " + configuration.getDBPath() + + ", exit status: " + status + + ". Please check that your configuration is valid"; + display(message); + throw new ApplicationException(message); + } + } + + private void display(String message) { + if (!isQuiet) { + System.out.println(message); + } + } +}
--- a/tools/src/test/java/com/redhat/thermostat/tools/db/DBServiceTest.java Mon Apr 02 22:25:51 2012 +0200 +++ b/tools/src/test/java/com/redhat/thermostat/tools/db/DBServiceTest.java Mon Apr 02 22:27:05 2012 +0200 @@ -36,6 +36,9 @@ package com.redhat.thermostat.tools.db; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.doThrow; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -53,6 +56,7 @@ import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.common.config.InvalidConfigurationException; +import com.redhat.thermostat.tools.ApplicationException; import com.redhat.thermostat.tools.ApplicationState; public class DBServiceTest { @@ -121,14 +125,37 @@ Assert.assertEquals(URL, conf.getUrl()); } - //@Test - public void testListeners() throws InvalidConfigurationException, InterruptedException { + private DBService prepareService(boolean startSuccess) throws IOException, + InterruptedException, InvalidConfigurationException, ApplicationException + { + final MongoProcessRunner runner = mock(MongoProcessRunner.class); + if (!startSuccess) { + doThrow(new ApplicationException("mock exception")).when(runner).startService(); + } + + // TODO: stop not tested yet, but be sure it's not called from the code + doThrow(new ApplicationException("mock exception")).when(runner).stopService(); + List<String> args = new ArrayList<>(); args.add("--quiet"); args.add("--start"); + + DBService service = new DBService() { + @Override + MongoProcessRunner createRunner() { + return runner; + } + }; + service.parseArguments(args); - DBService service = new DBService(); - service.parseArguments(args); + return service; + } + + @Test + public void testListeners() throws InvalidConfigurationException, + InterruptedException, IOException, ApplicationException + { + DBService service = prepareService(true); final CountDownLatch latch = new CountDownLatch(0); final boolean[] result = new boolean[1]; @@ -151,31 +178,14 @@ latch.await(); Assert.assertTrue(result[0]); - - // FIXME: the server doesn't stop right away, but it's detached - // so we need to give some time... but there should be a better - // way than sleep... - Thread.sleep(2500); - - args = new ArrayList<>(); - args.add("--quiet"); - args.add("--stop"); - - // stop everything - service.parseArguments(args); - service.run(); } - //@Test - public void testListenersFail() throws InvalidConfigurationException, InterruptedException { - List<String> args = new ArrayList<>(); - args.add("--quiet"); - - // unlikely is already running, since it's a random db directory... - args.add("--stop"); - - DBService service = new DBService(); - service.parseArguments(args); + + @Test + public void testListenersFail() throws InvalidConfigurationException, + InterruptedException, IOException, ApplicationException + { + DBService service = prepareService(false); final CountDownLatch latch = new CountDownLatch(0); final boolean[] result = new boolean[1];