Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@ scala_compiler.xml
# Keep 'build' packages in src directories
!**/src/**/build/
!**/src/**/build/**
dokka-cache/
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@
import it.unibo.alchemist.model.positions.Euclidean2DPosition;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.TimeoutException;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand All @@ -38,6 +41,7 @@ class LsaNodeConcurrencyTest {

private static final int MIN_MOLECULES = 5;
private static final int TIMEOUT_SECONDS = 30;
private static final String SECONDS = " seconds";

@Test
void testConcurrentGetContentsAndModification() throws InterruptedException {
Expand All @@ -52,11 +56,11 @@ void testConcurrentGetContentsAndModification() throws InterruptedException {
final int numberOfOperations = 100;
final ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
final CountDownLatch latch = new CountDownLatch(numberOfThreads);
final AtomicBoolean exceptionOccurred = new AtomicBoolean(false);
final List<Future<?>> tasks = new ArrayList<>(numberOfThreads);
// Start threads that modify the node while others read from it
for (int i = 0; i < numberOfThreads; i++) {
final int threadId = i;
executor.submit(() -> {
tasks.add(executor.submit(() -> {
try {
for (int j = 0; j < numberOfOperations; j++) {
if (threadId % 2 == 0) {
Expand All @@ -69,7 +73,7 @@ void testConcurrentGetContentsAndModification() throws InterruptedException {
assertNotNull(lsaSpace);
} else {
// Writer threads
final ILsaMolecule newMolecule = new LsaMolecule("thread" + threadId + "_" + j);
final ILsaMolecule newMolecule = new LsaMolecule("thread" + threadId + "x" + j);
node.setConcentration(newMolecule);
// Sometimes remove molecules to simulate real concurrent modification
if (j % 10 == 0 && node.getMoleculeCount() > MIN_MOLECULES) {
Expand All @@ -81,19 +85,59 @@ void testConcurrentGetContentsAndModification() throws InterruptedException {
}
}
}
} catch (final IllegalStateException | java.util.ConcurrentModificationException e) {
exceptionOccurred.set(true);
e.printStackTrace();
} finally {
latch.countDown();
}
});
return null;
}));
}
// Wait for all threads to complete
assertTrue(latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS), "Test should complete within 30 seconds");
executor.shutdown();
// No exceptions should have occurred (especially no ConcurrentModificationException)
assertFalse(exceptionOccurred.get(), "No exceptions should occur during concurrent access");
AssertionError primaryFailure = null;
try {
assertTrue(
latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS),
"Test should complete within " + TIMEOUT_SECONDS + SECONDS);
for (final Future<?> task : tasks) {
try {
task.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw new AssertionError("Test interrupted while waiting for task", e);
} catch (final ExecutionException e) {
throw new AssertionError("Task failed with exception", e.getCause());
} catch (final TimeoutException e) {
task.cancel(true);
throw new AssertionError("Task timed out after " + TIMEOUT_SECONDS + SECONDS, e);
}
}
} catch (final AssertionError e) {
primaryFailure = e;
} finally {
executor.shutdownNow();
Comment thread
DanySK marked this conversation as resolved.
try {
if (!executor.awaitTermination(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
final AssertionError terminationError = new AssertionError(
"Executor did not terminate within " + TIMEOUT_SECONDS + SECONDS);
if (primaryFailure != null) {
primaryFailure.addSuppressed(terminationError);
} else {
throw terminationError;
}
}
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
final AssertionError terminationError = new AssertionError(
"Interrupted while waiting for executor termination", e);
if (primaryFailure != null) {
primaryFailure.addSuppressed(terminationError);
} else {
throw terminationError;
}
}
Comment thread
DanySK marked this conversation as resolved.
}
if (primaryFailure != null) {
throw primaryFailure;
}
// Verify the node is still in a valid state
final Map<Molecule, List<ILsaMolecule>> finalContents = node.getContents();
assertNotNull(finalContents);
Expand Down
29 changes: 0 additions & 29 deletions dokka-cache/ch.qos.logback/logback-classic/1.5.32.list

This file was deleted.

3 changes: 0 additions & 3 deletions dokka-cache/com.github.ben-manes.caffeine/caffeine/3.2.4.list

This file was deleted.

9 changes: 0 additions & 9 deletions dokka-cache/com.github.davidmoten/rtree/0.12.list

This file was deleted.

This file was deleted.

3 changes: 0 additions & 3 deletions dokka-cache/com.google.code.findbugs/jsr305/3.0.2.list

This file was deleted.

5 changes: 0 additions & 5 deletions dokka-cache/com.google.code.gson/gson/2.14.0.list

This file was deleted.

This file was deleted.

16 changes: 0 additions & 16 deletions dokka-cache/com.google.guava/guava/33.6.0-jre.list

This file was deleted.

33 changes: 0 additions & 33 deletions dokka-cache/com.graphhopper/graphhopper-core/11.0.list

This file was deleted.

3 changes: 0 additions & 3 deletions dokka-cache/com.javadocmd/simplelatlng/1.4.0.list

This file was deleted.

2 changes: 0 additions & 2 deletions dokka-cache/com.miglayout/miglayout-swing/11.4.3.list

This file was deleted.

19 changes: 0 additions & 19 deletions dokka-cache/com.uchuhimo/konf-js/1.1.2.list

This file was deleted.

7 changes: 0 additions & 7 deletions dokka-cache/commons-codec/commons-codec/1.22.0.list

This file was deleted.

15 changes: 0 additions & 15 deletions dokka-cache/commons-io/commons-io/2.22.0.list

This file was deleted.

This file was deleted.

13 changes: 0 additions & 13 deletions dokka-cache/guru.nidi.com.kitfox/svgSalamander/1.1.3.list

This file was deleted.

Loading