156 lines
5.7 KiB
Java
156 lines
5.7 KiB
Java
package fr.xephi.authme.initialization;
|
|
|
|
import fr.xephi.authme.AuthMe;
|
|
import fr.xephi.authme.ReflectionTestUtils;
|
|
import fr.xephi.authme.datasource.DataSource;
|
|
import org.bukkit.Server;
|
|
import org.bukkit.plugin.Plugin;
|
|
import org.bukkit.plugin.PluginLogger;
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
import org.bukkit.scheduler.BukkitScheduler;
|
|
import org.bukkit.scheduler.BukkitWorker;
|
|
import org.junit.Before;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.mockito.ArgumentCaptor;
|
|
import org.mockito.Mock;
|
|
import org.mockito.junit.MockitoJUnitRunner;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
|
|
import static org.hamcrest.Matchers.contains;
|
|
import static org.hamcrest.MatcherAssert.assertThat;
|
|
import static org.mockito.ArgumentMatchers.anyInt;
|
|
import static org.mockito.BDDMockito.given;
|
|
import static org.mockito.Mockito.doNothing;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.times;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
/**
|
|
* Test for {@link TaskCloser}.
|
|
*/
|
|
@RunWith(MockitoJUnitRunner.class)
|
|
public class TaskCloserTest {
|
|
|
|
private static final int[] ACTIVE_WORKERS_ID = {2, 5};
|
|
|
|
private TaskCloser taskCloser;
|
|
@Mock
|
|
private AuthMe authMe;
|
|
@Mock
|
|
private PluginLogger logger;
|
|
@Mock
|
|
private BukkitScheduler bukkitScheduler;
|
|
@Mock
|
|
private DataSource dataSource;
|
|
|
|
@Before
|
|
public void initAuthMe() {
|
|
Server server = mock(Server.class);
|
|
given(server.getScheduler()).willReturn(bukkitScheduler);
|
|
ReflectionTestUtils.setField(JavaPlugin.class, authMe, "server", server);
|
|
given(authMe.getLogger()).willReturn(logger);
|
|
taskCloser = spy(new TaskCloser(authMe, dataSource));
|
|
}
|
|
|
|
@Test
|
|
public void shouldWaitForTasksToClose() throws InterruptedException {
|
|
// given
|
|
doNothing().when(taskCloser).sleep(); // avoid sleeping in tests
|
|
mockActiveWorkers();
|
|
given(bukkitScheduler.isCurrentlyRunning(ACTIVE_WORKERS_ID[0])).willReturn(false);
|
|
given(bukkitScheduler.isCurrentlyRunning(ACTIVE_WORKERS_ID[1]))
|
|
.willReturn(true) // first time
|
|
.willReturn(false); // second time
|
|
|
|
// when
|
|
taskCloser.run();
|
|
|
|
// then
|
|
verify(bukkitScheduler, times(3)).isQueued(anyInt());
|
|
ArgumentCaptor<Integer> taskIds = ArgumentCaptor.forClass(Integer.class);
|
|
verify(bukkitScheduler, times(3)).isCurrentlyRunning(taskIds.capture());
|
|
assertThat(taskIds.getAllValues(), contains(ACTIVE_WORKERS_ID[0], ACTIVE_WORKERS_ID[1], ACTIVE_WORKERS_ID[1]));
|
|
verify(taskCloser, times(2)).sleep();
|
|
verify(dataSource).closeConnection();
|
|
}
|
|
|
|
@Test
|
|
public void shouldAbortForNeverEndingTask() throws InterruptedException {
|
|
// given
|
|
doNothing().when(taskCloser).sleep(); // avoid sleeping in tests
|
|
mockActiveWorkers();
|
|
// This task never ends
|
|
given(bukkitScheduler.isCurrentlyRunning(ACTIVE_WORKERS_ID[0])).willReturn(true);
|
|
given(bukkitScheduler.isCurrentlyRunning(ACTIVE_WORKERS_ID[1])).willReturn(false);
|
|
|
|
// when
|
|
taskCloser.run();
|
|
|
|
// then
|
|
verify(bukkitScheduler, times(3)).isQueued(anyInt());
|
|
verify(bukkitScheduler, times(61)).isCurrentlyRunning(anyInt());
|
|
verify(taskCloser, times(60)).sleep();
|
|
verify(dataSource).closeConnection();
|
|
}
|
|
|
|
@Test
|
|
public void shouldStopForInterruptedThread() throws InterruptedException, ExecutionException {
|
|
// Note ljacqu 20160827: This test must be run in its own thread because we throw an InterruptedException.
|
|
// Somehow the java.nio.Files API used in tests that are run subsequently don't like this and fail otherwise.
|
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
executor.submit(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
shouldStopForInterruptedThread0();
|
|
} catch (Exception e) {
|
|
throw new IllegalStateException(e);
|
|
}
|
|
}
|
|
}).get();
|
|
}
|
|
|
|
/** Test implementation for {@link #shouldStopForInterruptedThread()}. */
|
|
private void shouldStopForInterruptedThread0() throws InterruptedException {
|
|
// given
|
|
taskCloser = spy(new TaskCloser(authMe, null));
|
|
// First two times do nothing, third time throw exception when we sleep
|
|
doNothing().doNothing().doThrow(InterruptedException.class).when(taskCloser).sleep();
|
|
mockActiveWorkers();
|
|
given(bukkitScheduler.isCurrentlyRunning(anyInt())).willReturn(true);
|
|
|
|
// when
|
|
taskCloser.run();
|
|
|
|
// then
|
|
verify(bukkitScheduler, times(4)).isCurrentlyRunning(anyInt());
|
|
verify(taskCloser, times(3)).sleep();
|
|
}
|
|
|
|
private void mockActiveWorkers() {
|
|
Plugin otherOwner = mock(Plugin.class);
|
|
List<BukkitWorker> tasks = Arrays.asList(
|
|
mockBukkitWorker(authMe, ACTIVE_WORKERS_ID[0], false),
|
|
mockBukkitWorker(otherOwner, 3, false),
|
|
mockBukkitWorker(authMe, ACTIVE_WORKERS_ID[1], false),
|
|
mockBukkitWorker(authMe, 7, true),
|
|
mockBukkitWorker(otherOwner, 11, true));
|
|
given(bukkitScheduler.getActiveWorkers()).willReturn(tasks);
|
|
}
|
|
|
|
private BukkitWorker mockBukkitWorker(Plugin owner, int taskId, boolean isQueued) {
|
|
BukkitWorker worker = mock(BukkitWorker.class);
|
|
given(worker.getOwner()).willReturn(owner);
|
|
given(worker.getTaskId()).willReturn(taskId);
|
|
given(bukkitScheduler.isQueued(taskId)).willReturn(isQueued);
|
|
return worker;
|
|
}
|
|
}
|