test(stealth): await complete main-thread admin callbacks
This commit is contained in:
@@ -80,7 +80,10 @@ class StealthAdminCommandTest {
|
|||||||
fixture.command.onCommand(
|
fixture.command.onCommand(
|
||||||
sender, command, "stealthadmin", new String[] {"sleepcount", "include"});
|
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());
|
assertEquals(SleepCountPolicy.INCLUDE, fixture.manager.snapshot().sleepCountPolicy());
|
||||||
verify(fixture.presentation).refreshSleepCountPolicy();
|
verify(fixture.presentation).refreshSleepCountPolicy();
|
||||||
org.junit.jupiter.api.Assertions.assertTrue(fixture.audit.stream()
|
org.junit.jupiter.api.Assertions.assertTrue(fixture.audit.stream()
|
||||||
@@ -125,7 +128,10 @@ class StealthAdminCommandTest {
|
|||||||
try (Fixture fixture = fixture(playerId)) {
|
try (Fixture fixture = fixture(playerId)) {
|
||||||
CommandSender sender = sender(true);
|
CommandSender sender = sender(true);
|
||||||
fixture.command.onCommand(sender, mock(Command.class), "stealthadmin", new String[] {"grant", playerId.toString()});
|
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.manager.snapshot().player(playerId).unlocked());
|
||||||
org.junit.jupiter.api.Assertions.assertTrue(fixture.audit.stream().anyMatch(message -> message.contains("grant") && message.contains(playerId.toString())));
|
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);
|
manager, progression, presentation, ignored -> { }, List::of);
|
||||||
KnownPlayerResolver resolver = new KnownPlayerResolver(manager::snapshot, List::of);
|
KnownPlayerResolver resolver = new KnownPlayerResolver(manager::snapshot, List::of);
|
||||||
ArrayList<String> audit = new ArrayList<>();
|
ArrayList<String> audit = new ArrayList<>();
|
||||||
|
var mainThread = new java.util.concurrent.LinkedBlockingQueue<Runnable>();
|
||||||
StealthAdminCommand command = new StealthAdminCommand(
|
StealthAdminCommand command = new StealthAdminCommand(
|
||||||
administration, resolver, Runnable::run, audit::add, Duration.ofHours(8));
|
administration, resolver, mainThread::add, audit::add, Duration.ofHours(8));
|
||||||
return new Fixture(manager, command, presentation, audit);
|
return new Fixture(manager, command, presentation, audit, mainThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private record Fixture(
|
private record Fixture(
|
||||||
StealthStateManager manager,
|
StealthStateManager manager,
|
||||||
StealthAdminCommand command,
|
StealthAdminCommand command,
|
||||||
IdentityPresentation presentation,
|
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(); }
|
@Override public void close() { manager.close(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user