mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-10-16 23:35:02 +02:00
Write tests for AsyncUnregister and TaskCloser
This commit is contained in:
parent
afd4498184
commit
f59a584622
@ -1,5 +1,6 @@
|
|||||||
package fr.xephi.authme.initialization;
|
package fr.xephi.authme.initialization;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
@ -50,7 +51,7 @@ public class TaskCloser implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
sleep();
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
break;
|
break;
|
||||||
@ -73,6 +74,12 @@ public class TaskCloser implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Makes the current thread sleep for one second. */
|
||||||
|
@VisibleForTesting
|
||||||
|
void sleep() throws InterruptedException {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> getPendingTasks() {
|
private List<Integer> getPendingTasks() {
|
||||||
List<Integer> pendingTasks = new ArrayList<>();
|
List<Integer> pendingTasks = new ArrayList<>();
|
||||||
//returns only the async tasks
|
//returns only the async tasks
|
||||||
|
@ -96,6 +96,8 @@ public class AsynchronousUnregister implements AsynchronousProcess {
|
|||||||
ConsoleLogger.info(name + " was unregistered by " + initiator.getName());
|
ConsoleLogger.info(name + " was unregistered by " + initiator.getName());
|
||||||
service.send(initiator, MessageKey.UNREGISTERED_SUCCESS);
|
service.send(initiator, MessageKey.UNREGISTERED_SUCCESS);
|
||||||
}
|
}
|
||||||
|
} else if (initiator != null) {
|
||||||
|
service.send(initiator, MessageKey.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
155
src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java
Normal file
155
src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
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.runners.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.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
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);
|
||||||
|
ReflectionTestUtils.setField(JavaPlugin.class, authMe, "logger", 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).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
|
|||||||
import fr.xephi.authme.task.PlayerDataTaskManager;
|
import fr.xephi.authme.task.PlayerDataTaskManager;
|
||||||
import fr.xephi.authme.util.BukkitService;
|
import fr.xephi.authme.util.BukkitService;
|
||||||
import fr.xephi.authme.util.TeleportationService;
|
import fr.xephi.authme.util.TeleportationService;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -27,6 +28,7 @@ import org.mockito.runners.MockitoJUnitRunner;
|
|||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.only;
|
import static org.mockito.Mockito.only;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
@ -118,4 +120,173 @@ public class AsynchronousUnregisterTest {
|
|||||||
verify(bukkitService).runTask(any(Runnable.class));
|
verify(bukkitService).runTask(any(Runnable.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPerformUnregisterAndNotApplyBlindEffect() {
|
||||||
|
// given
|
||||||
|
Player player = mock(Player.class);
|
||||||
|
String name = "Frank21";
|
||||||
|
given(player.getName()).willReturn(name);
|
||||||
|
given(player.isOnline()).willReturn(true);
|
||||||
|
PlayerAuth auth = mock(PlayerAuth.class);
|
||||||
|
given(playerCache.getAuth(name)).willReturn(auth);
|
||||||
|
HashedPassword password = new HashedPassword("password", "in_auth_obj");
|
||||||
|
given(auth.getPassword()).willReturn(password);
|
||||||
|
String userPassword = "pass";
|
||||||
|
given(passwordSecurity.comparePassword(userPassword, password, name)).willReturn(true);
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.FORCE)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)).willReturn(true);
|
||||||
|
given(service.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.unregister(player, userPassword);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(service).send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||||
|
verify(passwordSecurity).comparePassword(userPassword, password, name);
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(playerCache).removePlayer(name);
|
||||||
|
verify(teleportationService).teleportOnJoin(player);
|
||||||
|
verify(authGroupHandler).setGroup(player, AuthGroupType.UNREGISTERED);
|
||||||
|
verify(bukkitService).runTask(any(Runnable.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotApplyUnregisteredEffectsForNotForcedRegistration() {
|
||||||
|
// given
|
||||||
|
Player player = mock(Player.class);
|
||||||
|
String name = "__FranK";
|
||||||
|
given(player.getName()).willReturn(name);
|
||||||
|
given(player.isOnline()).willReturn(true);
|
||||||
|
String userPassword = "141$$5ad";
|
||||||
|
HashedPassword password = new HashedPassword("ttt123");
|
||||||
|
PlayerAuth auth = PlayerAuth.builder().name(name).password(password).build();
|
||||||
|
given(playerCache.getAuth(name)).willReturn(auth);
|
||||||
|
given(passwordSecurity.comparePassword(userPassword, password, name)).willReturn(true);
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.FORCE)).willReturn(false);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.unregister(player, userPassword);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(service).send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||||
|
verify(passwordSecurity).comparePassword(userPassword, password, name);
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(playerCache).removePlayer(name);
|
||||||
|
verify(authGroupHandler).setGroup(player, AuthGroupType.UNREGISTERED);
|
||||||
|
verifyZeroInteractions(teleportationService, playerDataTaskManager);
|
||||||
|
verify(bukkitService, never()).runTask(any(Runnable.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldHandleDatabaseError() {
|
||||||
|
// given
|
||||||
|
Player player = mock(Player.class);
|
||||||
|
String name = "Frank21";
|
||||||
|
given(player.getName()).willReturn(name);
|
||||||
|
given(player.isOnline()).willReturn(true);
|
||||||
|
PlayerAuth auth = mock(PlayerAuth.class);
|
||||||
|
given(playerCache.getAuth(name)).willReturn(auth);
|
||||||
|
HashedPassword password = new HashedPassword("password", "in_auth_obj");
|
||||||
|
given(auth.getPassword()).willReturn(password);
|
||||||
|
String userPassword = "pass";
|
||||||
|
given(passwordSecurity.comparePassword(userPassword, password, name)).willReturn(true);
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(false);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.unregister(player, userPassword);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(passwordSecurity).comparePassword(userPassword, password, name);
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(service).send(player, MessageKey.ERROR);
|
||||||
|
verifyZeroInteractions(teleportationService, authGroupHandler, bukkitService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotTeleportOfflinePlayer() {
|
||||||
|
// given
|
||||||
|
Player player = mock(Player.class);
|
||||||
|
String name = "Frank21";
|
||||||
|
given(player.getName()).willReturn(name);
|
||||||
|
given(player.isOnline()).willReturn(false);
|
||||||
|
PlayerAuth auth = mock(PlayerAuth.class);
|
||||||
|
given(playerCache.getAuth(name)).willReturn(auth);
|
||||||
|
HashedPassword password = new HashedPassword("password", "in_auth_obj");
|
||||||
|
given(auth.getPassword()).willReturn(password);
|
||||||
|
String userPassword = "pass";
|
||||||
|
given(passwordSecurity.comparePassword(userPassword, password, name)).willReturn(true);
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.FORCE)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)).willReturn(true);
|
||||||
|
given(service.getProperty(RestrictionSettings.TIMEOUT)).willReturn(12);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.unregister(player, userPassword);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(passwordSecurity).comparePassword(userPassword, password, name);
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(playerCache).removePlayer(name);
|
||||||
|
verifyZeroInteractions(teleportationService, authGroupHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiator known and Player object available
|
||||||
|
@Test
|
||||||
|
public void shouldPerformAdminUnregister() {
|
||||||
|
// given
|
||||||
|
Player player = mock(Player.class);
|
||||||
|
String name = "Frank21";
|
||||||
|
given(player.getName()).willReturn(name);
|
||||||
|
given(player.isOnline()).willReturn(true);
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.FORCE)).willReturn(true);
|
||||||
|
given(service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)).willReturn(true);
|
||||||
|
given(service.getProperty(RestrictionSettings.TIMEOUT)).willReturn(12);
|
||||||
|
CommandSender initiator = mock(CommandSender.class);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.adminUnregister(initiator, name, player);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(service).send(player, MessageKey.UNREGISTERED_SUCCESS);
|
||||||
|
verify(service).send(initiator, MessageKey.UNREGISTERED_SUCCESS);
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(playerCache).removePlayer(name);
|
||||||
|
verify(teleportationService).teleportOnJoin(player);
|
||||||
|
verify(authGroupHandler).setGroup(player, AuthGroupType.UNREGISTERED);
|
||||||
|
verify(bukkitService).runTask(any(Runnable.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPerformAdminUnregisterWithoutInitiatorOrPlayer() {
|
||||||
|
// given
|
||||||
|
String name = "billy";
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(true);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.adminUnregister(null, name, null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(playerCache).removePlayer(name);
|
||||||
|
verifyZeroInteractions(authGroupHandler, teleportationService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldHandleDatabaseErrorForAdminUnregister() {
|
||||||
|
// given
|
||||||
|
String name = "TtOoLl";
|
||||||
|
CommandSender initiator = mock(CommandSender.class);
|
||||||
|
given(dataSource.removeAuth(name)).willReturn(false);
|
||||||
|
|
||||||
|
// when
|
||||||
|
asynchronousUnregister.adminUnregister(initiator, name, null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(dataSource).removeAuth(name);
|
||||||
|
verify(service).send(initiator, MessageKey.ERROR);
|
||||||
|
verifyZeroInteractions(playerCache, teleportationService, authGroupHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user