test(stealth): await complete main-thread admin callbacks
This commit is contained in:
@@ -80,7 +80,10 @@ class StealthAdminCommandTest {
|
||||
fixture.command.onCommand(
|
||||
sender, command, "stealthadmin", new String[] {"sleepcount", "include"});
|
||||
|
||||
verify(sender, org.mockito.Mockito.timeout(1000)).sendMessage(contains("now included"));
|
||||
verify(sender, never()).sendMessage(contains("now included"));
|
||||
assertEquals(List.of(), fixture.audit);
|
||||
fixture.runMainThreadCallback();
|
||||
verify(sender).sendMessage(contains("now included"));
|
||||
assertEquals(SleepCountPolicy.INCLUDE, fixture.manager.snapshot().sleepCountPolicy());
|
||||
verify(fixture.presentation).refreshSleepCountPolicy();
|
||||
org.junit.jupiter.api.Assertions.assertTrue(fixture.audit.stream()
|
||||
@@ -125,7 +128,10 @@ class StealthAdminCommandTest {
|
||||
try (Fixture fixture = fixture(playerId)) {
|
||||
CommandSender sender = sender(true);
|
||||
fixture.command.onCommand(sender, mock(Command.class), "stealthadmin", new String[] {"grant", playerId.toString()});
|
||||
verify(sender, org.mockito.Mockito.timeout(1000)).sendMessage(contains("granted"));
|
||||
verify(sender, never()).sendMessage(contains("granted"));
|
||||
assertEquals(List.of(), fixture.audit);
|
||||
fixture.runMainThreadCallback();
|
||||
verify(sender).sendMessage(contains("granted"));
|
||||
org.junit.jupiter.api.Assertions.assertTrue(fixture.manager.snapshot().player(playerId).unlocked());
|
||||
org.junit.jupiter.api.Assertions.assertTrue(fixture.audit.stream().anyMatch(message -> message.contains("grant") && message.contains(playerId.toString())));
|
||||
}
|
||||
@@ -167,16 +173,30 @@ class StealthAdminCommandTest {
|
||||
manager, progression, presentation, ignored -> { }, List::of);
|
||||
KnownPlayerResolver resolver = new KnownPlayerResolver(manager::snapshot, List::of);
|
||||
ArrayList<String> audit = new ArrayList<>();
|
||||
var mainThread = new java.util.concurrent.LinkedBlockingQueue<Runnable>();
|
||||
StealthAdminCommand command = new StealthAdminCommand(
|
||||
administration, resolver, Runnable::run, audit::add, Duration.ofHours(8));
|
||||
return new Fixture(manager, command, presentation, audit);
|
||||
administration, resolver, mainThread::add, audit::add, Duration.ofHours(8));
|
||||
return new Fixture(manager, command, presentation, audit, mainThread);
|
||||
}
|
||||
|
||||
private record Fixture(
|
||||
StealthStateManager manager,
|
||||
StealthAdminCommand command,
|
||||
IdentityPresentation presentation,
|
||||
ArrayList<String> audit) implements AutoCloseable {
|
||||
ArrayList<String> audit,
|
||||
java.util.concurrent.BlockingQueue<Runnable> mainThread) implements AutoCloseable {
|
||||
void runMainThreadCallback() {
|
||||
// A reply is emitted before the audit append. Await and run the whole scheduled callback,
|
||||
// not just the reply invocation, and never read the ArrayList concurrently with the I/O thread.
|
||||
try {
|
||||
Runnable callback = mainThread.poll(5, java.util.concurrent.TimeUnit.SECONDS);
|
||||
org.junit.jupiter.api.Assertions.assertNotNull(callback, "Expected a scheduled main-thread completion");
|
||||
callback.run();
|
||||
} catch (InterruptedException exception) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new AssertionError("Interrupted waiting for command completion", exception);
|
||||
}
|
||||
}
|
||||
@Override public void close() { manager.close(); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user