Skip to content

Commit 6690be6

Browse files
committed
test(incarnation-sapere): harden LsaNode concurrency test
1 parent 249a798 commit 6690be6

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

alchemist-incarnation-sapere/src/test/java/it/unibo/alchemist/model/sapere/nodes/LsaNodeConcurrencyTest.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
import java.util.concurrent.CountDownLatch;
2424
import java.util.concurrent.ExecutorService;
2525
import java.util.concurrent.Executors;
26+
import java.util.concurrent.ExecutionException;
27+
import java.util.concurrent.Future;
2628
import java.util.concurrent.TimeUnit;
29+
import java.util.concurrent.TimeoutException;
2730
import java.util.concurrent.atomic.AtomicBoolean;
2831

2932
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -53,10 +56,11 @@ void testConcurrentGetContentsAndModification() throws InterruptedException {
5356
final ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
5457
final CountDownLatch latch = new CountDownLatch(numberOfThreads);
5558
final AtomicBoolean exceptionOccurred = new AtomicBoolean(false);
59+
final List<Future<?>> tasks = new java.util.ArrayList<>(numberOfThreads);
5660
// Start threads that modify the node while others read from it
5761
for (int i = 0; i < numberOfThreads; i++) {
5862
final int threadId = i;
59-
executor.submit(() -> {
63+
tasks.add(executor.submit(() -> {
6064
try {
6165
for (int j = 0; j < numberOfOperations; j++) {
6266
if (threadId % 2 == 0) {
@@ -69,7 +73,7 @@ void testConcurrentGetContentsAndModification() throws InterruptedException {
6973
assertNotNull(lsaSpace);
7074
} else {
7175
// Writer threads
72-
final ILsaMolecule newMolecule = new LsaMolecule("thread" + threadId + "_" + j);
76+
final ILsaMolecule newMolecule = new LsaMolecule("thread" + threadId + "x" + j);
7377
node.setConcentration(newMolecule);
7478
// Sometimes remove molecules to simulate real concurrent modification
7579
if (j % 10 == 0 && node.getMoleculeCount() > MIN_MOLECULES) {
@@ -81,17 +85,25 @@ void testConcurrentGetContentsAndModification() throws InterruptedException {
8185
}
8286
}
8387
}
84-
} catch (final IllegalStateException | java.util.ConcurrentModificationException e) {
85-
exceptionOccurred.set(true);
86-
e.printStackTrace();
8788
} finally {
8889
latch.countDown();
8990
}
90-
});
91+
return null;
92+
}));
9193
}
9294
// Wait for all threads to complete
9395
assertTrue(latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS), "Test should complete within 30 seconds");
9496
executor.shutdown();
97+
for (final Future<?> task : tasks) {
98+
try {
99+
task.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
100+
} catch (final InterruptedException e) {
101+
Thread.currentThread().interrupt();
102+
exceptionOccurred.set(true);
103+
} catch (final ExecutionException | TimeoutException e) {
104+
exceptionOccurred.set(true);
105+
}
106+
}
95107
// No exceptions should have occurred (especially no ConcurrentModificationException)
96108
assertFalse(exceptionOccurred.get(), "No exceptions should occur during concurrent access");
97109
// Verify the node is still in a valid state

0 commit comments

Comments
 (0)