Skip to content

Commit

Permalink
TaskSchedulingIntegrationSpec: fixed shutdown not waiting for the tas…
Browse files Browse the repository at this point in the history
…ks and worker threads to finish, made tests more robust
  • Loading branch information
luontola committed Nov 28, 2008
1 parent c4e1b7b commit df20d1f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 19 deletions.
Expand Up @@ -78,14 +78,31 @@ public int getRunningTasks() {


public void shutdown() { public void shutdown() {
logger.info("Shutting down {}...", getClass().getSimpleName()); logger.info("Shutting down {}...", getClass().getSimpleName());
shutdownConsumer();
shutdownWorkers();
logger.info("{} has been shut down", getClass().getSimpleName());
}

private void shutdownConsumer() {
consumer.interrupt(); consumer.interrupt();
try { try {
consumer.join(); consumer.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
logger.error("Interrupted while shutting down", e); logger.error("Interrupted while shutting down", e);
throw new RuntimeException(e);
} }
}

private void shutdownWorkers() {
workers.shutdown(); workers.shutdown();
logger.info("{} has been shut down", getClass().getSimpleName()); try {
awaitForCurrentTasksToFinish();
workers.awaitTermination(10, TimeUnit.SECONDS);
workers.shutdownNow();
} catch (InterruptedException e) {
logger.error("Interrupted while shutting down", e);
throw new RuntimeException(e);
}
} }


@SuppressWarnings({"ToArrayCallWithZeroLengthArrayArgument"}) @SuppressWarnings({"ToArrayCallWithZeroLengthArrayArgument"})
Expand Down
Expand Up @@ -44,6 +44,7 @@


import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.logging.*;


/** /**
* @author Esko Luontola * @author Esko Luontola
Expand All @@ -57,15 +58,33 @@ public class TaskSchedulingIntegrationSpec extends Specification<Object> {
private TaskExecutor taskContext; private TaskExecutor taskContext;
private Provider<TaskScheduler> scheduler; private Provider<TaskScheduler> scheduler;
private TestSpy spy; private TestSpy spy;
private Logger[] hideLifecycleInfoLogs;


private Provider<ServerLifecycleManager> server; private Provider<ServerLifecycleManager> server;


public void create() throws Exception { public void create() throws Exception {
hideLifecycleInfoLogs = new Logger[]{
Logger.getLogger(ServerLifecycleManager.class.getName()),
Logger.getLogger(TaskThreadPool.class.getName()),
};
for (Logger logger : hideLifecycleInfoLogs) {
logger.setLevel(Level.WARNING);
}

startupTheServer(new CommonModules()); startupTheServer(new CommonModules());
} }


public void destroy() throws Exception {
shutdownTheServer();

for (Logger logger : hideLifecycleInfoLogs) {
logger.setLevel(Level.ALL);
}
}

private void startupTheServer(Module... modules) { private void startupTheServer(Module... modules) {
injector = Guice.createInjector(modules); injector = Guice.createInjector(modules);

server = injector.getProvider(ServerLifecycleManager.class); server = injector.getProvider(ServerLifecycleManager.class);
server.get().start(); server.get().start();


Expand All @@ -79,24 +98,18 @@ private void shutdownTheServer() {
} }


private void restartTheServer() { private void restartTheServer() {
shutdownTheServer(); final InMemoryDatabaseManager dbBackup = injector.getInstance(InMemoryDatabaseManager.class);
final InMemoryDatabaseManager db = injector.getInstance(InMemoryDatabaseManager.class); final EntityIdFactoryImpl idFactoryBackup = injector.getInstance(EntityIdFactoryImpl.class);
final EntityIdFactoryImpl idFactory = injector.getInstance(EntityIdFactoryImpl.class);

startupTheServer( startupTheServer(
new CommonModules(), new CommonModules(),
new AbstractModule() { new AbstractModule() {
protected void configure() { protected void configure() {
bind(InMemoryDatabaseManager.class).toInstance(db); bind(InMemoryDatabaseManager.class).toInstance(dbBackup);
bind(EntityIdFactoryImpl.class).toInstance(idFactory); bind(EntityIdFactoryImpl.class).toInstance(idFactoryBackup);
} }
}); });
} }


public void destroy() throws Exception {
shutdownTheServer();
}



public class WhenAOneTimeTaskIsScheduled { public class WhenAOneTimeTaskIsScheduled {


Expand Down Expand Up @@ -137,10 +150,19 @@ public void afterShuttingDownItIsNoMoreExecuted() throws InterruptedException {
} }


public void afterRestartTheExecutionIsContinued() throws InterruptedException { public void afterRestartTheExecutionIsContinued() throws InterruptedException {
shutdownTheServer();

List<String> executedBeforeRestart = new ArrayList<String>(spy.executions);
specify(executedBeforeRestart, executedBeforeRestart.size() >= 2);

restartTheServer(); restartTheServer();
spy.executionCount.acquire(1); spy.executionCount.acquire(1);
specify(spy.executions, should.not().containAny("A:1", "A:2"));
specify(spy.executions, should.containAny("A:3", "A:4")); // If there were some executions and none of the two first executions are included
// (i.e. the execution count was correctly reset on shutdown), then the server must
// have continued execution after restart from where it was left.
specify(spy.executions, spy.executions.size() >= 1);
specify(spy.executions, should.not().containAny(executedBeforeRestart));
} }
} }


Expand Down Expand Up @@ -169,12 +191,9 @@ public ExecutionLoggingTask(String dummyId) {
public void run() { public void run() {
myExecutionCount++; myExecutionCount++;
spy.logExecution(getDummyId(), myExecutionCount); spy.logExecution(getDummyId(), myExecutionCount);
System.err.println("TaskSchedulingIntegrationSpec$ExecutionLoggingTask.run"); // System.err.println("*** TaskSchedulingIntegrationSpec$ExecutionLoggingTask.run");
System.err.println("getDummyId() = " + getDummyId()); // System.err.println("*** getDummyId() = " + getDummyId());
System.err.println("myExecutionCount = " + myExecutionCount); // System.err.println("*** myExecutionCount = " + myExecutionCount);
} }
} }

// TODO: configure Guice modules
// TODO: to monitor tests, use a dummy object in @Singleton scope - the tasks can have it injected to them
} }

0 comments on commit df20d1f

Please sign in to comment.