package com.zendesk.maxwell.util; import org.apache.commons.lang3.tuple.MutablePair; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeoutException; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; public class TaskManagerTest { class SampleTask implements StoppableTask { private final List<Event> log; public String name; SampleTask(List<Event> eventLog, String name) { this.log = eventLog; this.name = name; } @Override public void requestStop() { log.add(new Event(EventType.REQUEST_STOP, this.name)); } @Override public void awaitStop(Long timeout) throws TimeoutException { log.add(new Event(EventType.AWAIT_STOP, this.name)); } } enum EventType { REQUEST_STOP, AWAIT_STOP }; class UnstoppableTask implements StoppableTask { UnstoppableTask() { } @Override public void requestStop() { } @Override public void awaitStop(Long timeout) throws TimeoutException { throw new TimeoutException("can't stop this"); } } class Event extends MutablePair<EventType, String> { Event(EventType left, String right) { super(left, right); } } @Test public void shutsDownAllTasksAndWaitsForCompletion() { List<Event> log = new ArrayList<>(); StoppableTask task1 = new SampleTask(log, "task1"); StoppableTask task2 = new SampleTask(log, "task2"); TaskManager manager = new TaskManager(); manager.add(task1); manager.add(task2); manager.stop(null); assertThat(log, equalTo(Arrays.asList( // stop tasks first new Event(EventType.REQUEST_STOP, "task1"), new Event(EventType.REQUEST_STOP, "task2"), // ... then wait new Event(EventType.AWAIT_STOP, "task1"), new Event(EventType.AWAIT_STOP, "task2") ))); } @Test public void continuesOnAwaitTimeout() { List<Event> log = new ArrayList<>(); StoppableTask task1 = new UnstoppableTask(); StoppableTask task2 = new SampleTask(log, "task2"); TaskManager manager = new TaskManager(); manager.add(task1); manager.add(task2); manager.stop(null); // does not throw assertThat(log, hasItem( new Event(EventType.AWAIT_STOP, "task2") )); } @Test public void onlyStopsTasksOnce() { List<Event> log = new ArrayList<>(); StoppableTask task = new SampleTask(log, "task"); TaskManager manager = new TaskManager(); manager.add(task); assertThat(manager.requestStop(), equalTo(true)); assertThat(manager.requestStop(), equalTo(false)); manager.stop(null); manager.stop(null); assertThat(log, equalTo(Arrays.asList( new Event(EventType.REQUEST_STOP, "task"), new Event(EventType.AWAIT_STOP, "task") ))); } }