Skip to content

Commit 0901063

Browse files
committed
test(appserver): define same-session execution contract
1 parent 9a93906 commit 0901063

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2018-present, easy-4-java (https://github.com/easy-4-java).
3+
*
4+
* Licensed under the Apache License, Version 2.0.
5+
*/
6+
package io.github.easy4j.codex.appserver;
7+
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
import static org.junit.jupiter.api.Assertions.assertFalse;
10+
11+
import java.util.concurrent.CompletableFuture;
12+
import java.util.concurrent.atomic.AtomicInteger;
13+
14+
import org.junit.jupiter.api.Test;
15+
16+
class SessionExecutionCoordinatorTest {
17+
18+
@Test
19+
void shouldSerializeTasksForSameSessionKey() {
20+
SessionExecutionCoordinator coordinator = new SessionExecutionCoordinator();
21+
CompletableFuture<String> firstGate = new CompletableFuture<>();
22+
AtomicInteger starts = new AtomicInteger();
23+
24+
CompletableFuture<String> first = coordinator.submit("chat", () -> {
25+
starts.incrementAndGet();
26+
return firstGate;
27+
});
28+
CompletableFuture<String> second = coordinator.submit("chat", () -> {
29+
starts.incrementAndGet();
30+
return CompletableFuture.completedFuture("second");
31+
});
32+
33+
assertEquals(1, starts.get(), "second same-session task must wait");
34+
firstGate.complete("first");
35+
36+
assertEquals("first", first.join());
37+
assertEquals("second", second.join());
38+
assertEquals(2, starts.get());
39+
}
40+
41+
@Test
42+
void shouldAllowDifferentSessionsToRunConcurrently() {
43+
SessionExecutionCoordinator coordinator = new SessionExecutionCoordinator();
44+
CompletableFuture<String> gateA = new CompletableFuture<>();
45+
CompletableFuture<String> gateB = new CompletableFuture<>();
46+
AtomicInteger starts = new AtomicInteger();
47+
48+
CompletableFuture<String> a = coordinator.submit("a", () -> {
49+
starts.incrementAndGet();
50+
return gateA;
51+
});
52+
CompletableFuture<String> b = coordinator.submit("b", () -> {
53+
starts.incrementAndGet();
54+
return gateB;
55+
});
56+
57+
assertEquals(2, starts.get(), "different sessions must not block each other");
58+
assertFalse(a.isDone());
59+
assertFalse(b.isDone());
60+
61+
gateA.complete("a");
62+
gateB.complete("b");
63+
assertEquals("a", a.join());
64+
assertEquals("b", b.join());
65+
}
66+
67+
@Test
68+
void shouldRemoveSessionTailAfterCompletionAndFailure() {
69+
SessionExecutionCoordinator coordinator = new SessionExecutionCoordinator();
70+
71+
coordinator.submit("ok", () -> CompletableFuture.completedFuture("ok")).join();
72+
73+
CompletableFuture<String> failed = coordinator.submit("bad", () -> {
74+
CompletableFuture<String> future = new CompletableFuture<>();
75+
future.completeExceptionally(new IllegalStateException("boom"));
76+
return future;
77+
});
78+
try {
79+
failed.join();
80+
} catch (RuntimeException ignored) {
81+
// expected
82+
}
83+
84+
assertEquals(0, coordinator.activeSessionCount());
85+
}
86+
}

0 commit comments

Comments
 (0)