package com.github.drapostolos.rdp4j;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.github.drapostolos.rdp4j.spi.FileElement;
import com.github.drapostolos.rdp4j.spi.PolledDirectory;
public class ScheduledRunnableTest extends EventVerifier {
@Before
public void testFixture() throws Exception {
directoryMock = Mockito.mock(PolledDirectory.class);
listenerMock = Mockito.mock(AbstractRdp4jListener.class);
inOrder = Mockito.inOrder(listenerMock);
directoryPollerMock = Mockito.mock(DirectoryPoller.class);
Mockito.when(directoryPollerMock.getDefaultFileFilter()).thenReturn(new DefaultFileFilter());
directories.add(directoryMock);
directoryPollerMock.directories = directories;
directoryPollerMock.notifier = new ListenerNotifier(new HashSet<Rdp4jListener>(Arrays.asList(listenerMock)));
pollerTask = new ScheduledRunnable(directoryPollerMock);
}
@After
public void cleanup() throws Exception {
if (pollerTask != null) {
pollerTask.shutdown();
pollerTask.awaitTermination();
}
}
@Test
public void filterOutAFile() throws Exception {
// given
// This will change the filter used by the PollerTask
Mockito.when(directoryPollerMock.getDefaultFileFilter()).thenReturn(new RegexFileFilter("file[AB]"));
pollerTask = new ScheduledRunnable(directoryPollerMock);
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1"))
.thenReturn(list("fileA/1", "fileB/1"))
.thenReturn(list("fileA/1", "fileB/1", "fileC/1"));
// when
executeNumberOfPollCycles(3);
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
FileAddedEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#3
BeforePollingCycleEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void addRemoveListeners() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1"))
.thenReturn(list("fileA/1", "fileB/1"))
.thenReturn(list("fileA/1", "fileB/1", "fileC/1"));
// when
pollerTask.run(); // poll-cycle 1
pollerTask.removeListener(listenerMock);
pollerTask.run(); // poll-cycle 2
pollerTask.addListener(listenerMock);
pollerTask.run(); // poll-cycle 3
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
// Nothing should happen
// poll-cycle#3
BeforePollingCycleEvent.class,
FileAddedEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void addRemoveDirectories() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1"))
.thenReturn(list("fileA/1", "fileB/1"));
PolledDirectory directoryMock2 = Mockito.mock(PolledDirectory.class);
Mockito.when(directoryMock2.listFiles())
.thenReturn(list("FileA/1"))
.thenReturn(list("FileA/1", "FileB/1"))
.thenReturn(list("FileA/1", "FileB/1", "FileC/1"));
// when
pollerTask.run(); // poll-cycle 1
pollerTask.addDirectory(directoryMock2);
pollerTask.run(); // poll-cycle 2
pollerTask.removeDirectory(directoryMock);
pollerTask.removeDirectory(directoryMock2);
pollerTask.run(); // poll-cycle 3
pollerTask.addDirectory(directoryMock2);
pollerTask.run(); // poll-cycle 4
pollerTask.run(); // poll-cycle 5
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class, // fileA/1
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
FileAddedEvent.class, // fileB/1
InitialContentEvent.class, // FileA/1
AfterPollingCycleEvent.class,
// poll-cycle#3
BeforePollingCycleEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#4
BeforePollingCycleEvent.class,
InitialContentEvent.class, // FileA/1, FileB/1
AfterPollingCycleEvent.class,
// poll-cycle#5
BeforePollingCycleEvent.class,
FileAddedEvent.class, // FileC/1
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void OneSuccesfulPoll() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list());
// when
executeNumberOfPollCycles(1);
// then
verifyEventsInOrder(
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void initiallyIoErrorRaisedThenCeased() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenThrow(new IOException("thrown from unit test!"))
.thenReturn(null)
.thenReturn(list("fileA/1", "fileB/1"));
// when
executeNumberOfPollCycles(3);
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
IoErrorRaisedEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#3
BeforePollingCycleEvent.class,
IoErrorCeasedEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void IoErrorRaisedByLastModifiedThenCeased() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1", "fileB/1"))
.thenReturn(list("fileA/0", "fileB/1"))
.thenReturn(list("fileA/1", "fileB/1"));
// when
executeNumberOfPollCycles(3);
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
IoErrorRaisedEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#3
BeforePollingCycleEvent.class,
IoErrorCeasedEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void directoryPollerExceptionThrown() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1"))
.thenThrow(new DirectoryPollerException());
// when
executeNumberOfPollCycles(2);
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void addRemoveModifyFiles() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1"))
.thenReturn(list("fileA/1", "fileB/1"))
.thenReturn(list("fileA/2", "fileC/1"));
// when
executeNumberOfPollCycles(4);
// then
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
FileAddedEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#3
BeforePollingCycleEvent.class,
FileRemovedEvent.class,
FileAddedEvent.class,
FileModifiedEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#4
BeforePollingCycleEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
@Test
public void initialContent() throws Exception {
// given
Mockito.when(directoryMock.listFiles())
.thenReturn(list("fileA/1", "fileB/1"))
.thenReturn(list("fileA/1", "fileB/1"));
final List<FileElement> files = new ArrayList<FileElement>();
Mockito.doAnswer(new Answer<InitialContentEvent>() {
@Override
public InitialContentEvent answer(InvocationOnMock invocation) throws Throwable {
Set<FileElement> s = ((InitialContentEvent) invocation.getArguments()[0]).getFiles();
files.addAll(s);
return null;
}
}).when(listenerMock).initialContent(Mockito.any(InitialContentEvent.class));
// when
executeNumberOfPollCycles(2);
// then
assertThat(files).containsAll(list("fileA/1", "fileB/1"));
verifyEventsInOrder(
// poll-cycle#1
BeforePollingCycleEvent.class,
InitialContentEvent.class,
AfterPollingCycleEvent.class,
// poll-cycle#2
BeforePollingCycleEvent.class,
AfterPollingCycleEvent.class);
Mockito.verifyNoMoreInteractions(listenerMock);
}
}