feat: des beaux tests sur CentralizedLinda, avec un beau code coverage
This commit is contained in:
parent
717964daca
commit
24810c2250
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -7,5 +7,6 @@
|
|||
"**/.DS_Store": true,
|
||||
"**/Thumbs.db": true,
|
||||
"**/*.class": true
|
||||
}
|
||||
},
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'eclipse' // optional (to generate Eclipse project files)
|
||||
id 'idea' // optional (to generate IntelliJ IDEA project files)
|
||||
id 'jacoco'
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -15,4 +14,9 @@ dependencies {
|
|||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
finalizedBy jacocoTestReport
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
dependsOn test
|
||||
}
|
|
@ -14,7 +14,7 @@ import java.util.concurrent.locks.Condition;
|
|||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
class Reveil implements Callback {
|
||||
class Reveil {
|
||||
|
||||
Lock lock = new ReentrantLock();
|
||||
|
||||
|
@ -26,10 +26,6 @@ class Reveil implements Callback {
|
|||
this.condition = lock.newCondition();
|
||||
}
|
||||
|
||||
public void call(Tuple t) {
|
||||
return;
|
||||
}
|
||||
|
||||
void sleep() {
|
||||
try {
|
||||
lock.lock();
|
||||
|
@ -52,7 +48,7 @@ class Reveil implements Callback {
|
|||
/** Shared memory implementation of Linda. */
|
||||
public class CentralizedLinda implements Linda {
|
||||
|
||||
protected List<Tuple> tuples;
|
||||
List<Tuple> tuples;
|
||||
List<Reveil> reveils;
|
||||
|
||||
public CentralizedLinda() {
|
||||
|
@ -116,6 +112,7 @@ public class CentralizedLinda implements Linda {
|
|||
* @param template the Tuple template your looking for
|
||||
*/
|
||||
public Tuple tryTake(Tuple template) {
|
||||
synchronized (tuples) {
|
||||
Iterator<Tuple> iterator = tuples.iterator();
|
||||
Tuple next = null;
|
||||
|
||||
|
@ -126,6 +123,30 @@ public class CentralizedLinda implements Linda {
|
|||
return next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the tuple from the symetric difference of the Tuple-Space and the
|
||||
* given tuple list. (non-blocking)
|
||||
*
|
||||
* @param template the Tuple template your looking for
|
||||
* @param excluded the list of Tuples to exclude from the search
|
||||
*/
|
||||
private Tuple tryTake(Tuple template, Collection<Tuple> excluded) {
|
||||
synchronized (tuples) {
|
||||
Iterator<Tuple> iterator = tuples.iterator();
|
||||
Tuple next = null;
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
next = iterator.next();
|
||||
if (next.matches(template) && !excluded.contains(next)) {
|
||||
iterator.remove();
|
||||
return next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -135,25 +156,50 @@ public class CentralizedLinda implements Linda {
|
|||
* @param template the Tuple template your looking for
|
||||
*/
|
||||
public Tuple tryRead(Tuple template) {
|
||||
synchronized (tuples) {
|
||||
Tuple next = null;
|
||||
Iterator<Tuple> iterator = tuples.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
next = iterator.next();
|
||||
if (next.matches(template)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tuple from the symetric difference of the Tuple-Space and the given
|
||||
* tuple list. (non-blocking)
|
||||
*
|
||||
* @param template the Tuple template your looking for
|
||||
* @param excluded the list of Tuples to exclude from the search
|
||||
*/
|
||||
private Tuple tryRead(Tuple template, Collection<Tuple> excluded) {
|
||||
synchronized (tuples) {
|
||||
Iterator<Tuple> iterator = tuples.iterator();
|
||||
Tuple next = null;
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
next = iterator.next();
|
||||
if (next.matches(template)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (next.matches(template) && !excluded.contains(next)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the tuples in the tuple list. (blocking)
|
||||
* Extract the tuples in the tuple list. (non-blocking)
|
||||
*
|
||||
* @param template the Tuple template your looking for
|
||||
*/
|
||||
public Collection<Tuple> takeAll(Tuple template) {
|
||||
List<Tuple> results = new ArrayList<Tuple>();
|
||||
synchronized (tuples) {
|
||||
Iterator<Tuple> iterator = tuples.iterator();
|
||||
Tuple next = null;
|
||||
|
||||
|
@ -164,6 +210,7 @@ public class CentralizedLinda implements Linda {
|
|||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -173,7 +220,8 @@ public class CentralizedLinda implements Linda {
|
|||
* @param template the Tuple template your looking for
|
||||
*/
|
||||
public Collection<Tuple> readAll(Tuple template) {
|
||||
List<Tuple> results = new ArrayList<Tuple>();
|
||||
Collection<Tuple> results = new ArrayList<Tuple>();
|
||||
synchronized (tuples) {
|
||||
Iterator<Tuple> iterator = tuples.iterator();
|
||||
Tuple next = null;
|
||||
|
||||
|
@ -183,46 +231,39 @@ public class CentralizedLinda implements Linda {
|
|||
results.add(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public void eventRegister(eventMode mode, eventTiming timing, Tuple template, Callback callback) {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
|
||||
switch (timing) {
|
||||
case IMMEDIATE:
|
||||
callback.call(mode == eventMode.READ ? read(template) : take(template));
|
||||
return;
|
||||
case FUTURE:
|
||||
List<Tuple> knownTuples = (List<Tuple>) readAll(template);
|
||||
callback.call(tryRTknown(template, knownTuples, mode));
|
||||
Collection<Tuple> knownTuples = new ArrayList<Tuple>();
|
||||
for (Tuple t : tuples) {
|
||||
knownTuples.add((Tuple) t.clone());
|
||||
}
|
||||
callback.call(future_search(template, knownTuples, mode));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private Tuple tryRTknown(Tuple template, List<Tuple> knownTuples, eventMode mode) {
|
||||
private Tuple future_search(Tuple template, Collection<Tuple> knownTuples, eventMode mode) {
|
||||
Tuple result = null;
|
||||
|
||||
Reveil reveil = new Reveil(template);
|
||||
reveils.add(reveil);
|
||||
|
||||
Tuple result = null;
|
||||
|
||||
for (int i = 0; i < tuples.size(); i++) {
|
||||
result = mode == eventMode.READ ? tuples.get(i) : tuples.remove(i);
|
||||
if (result.matches(template)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result = mode == eventMode.READ ? tryRead(template, knownTuples) : tryTake(template, knownTuples);
|
||||
while (result == null) {
|
||||
reveil.sleep();
|
||||
for (int i = 0; i < tuples.size(); i++) {
|
||||
result = mode == eventMode.READ ? tuples.get(i) : tuples.remove(i);
|
||||
if (result.matches(template)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result = mode == eventMode.READ ? tryRead(template, knownTuples) : tryTake(template, knownTuples);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,17 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import linda.Callback;
|
||||
import linda.Linda;
|
||||
import linda.Tuple;
|
||||
import linda.Linda.eventMode;
|
||||
import linda.Linda.eventTiming;
|
||||
import linda.shm.CentralizedLinda;
|
||||
|
||||
public class CentralizedLindaTests {
|
||||
|
@ -23,6 +27,10 @@ public class CentralizedLindaTests {
|
|||
linda = new CentralizedLinda();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("read related tests")
|
||||
class ReadTests {
|
||||
|
||||
@Test
|
||||
void testTryRead() {
|
||||
Tuple tuple_write, tuple_template, tuple_read;
|
||||
|
@ -48,31 +56,6 @@ public class CentralizedLindaTests {
|
|||
assertEquals(tuple_read, tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTryTake() {
|
||||
Tuple tuple_write, tuple_template, tuple_read;
|
||||
|
||||
tuple_template = new Tuple(0);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, null);
|
||||
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, null);
|
||||
|
||||
tuple_write = new Tuple(0);
|
||||
linda.write(tuple_write);
|
||||
linda.write(tuple_write);
|
||||
|
||||
tuple_template = new Tuple(0);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRead() {
|
||||
Tuple tuple_write, tuple_template, tuple_read;
|
||||
|
@ -90,20 +73,43 @@ public class CentralizedLindaTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testTake() {
|
||||
Tuple tuple_write, tuple_template, tuple_read;
|
||||
|
||||
tuple_write = new Tuple(0);
|
||||
linda.write(tuple_write);
|
||||
linda.write(tuple_write);
|
||||
|
||||
tuple_template = new Tuple(0);
|
||||
tuple_read = linda.take(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
|
||||
void testEmptyRead() {
|
||||
Thread mainRunner = new Thread(() -> {
|
||||
Tuple tuple_template;
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
tuple_read = linda.take(tuple_template);
|
||||
linda.read(tuple_template);
|
||||
});
|
||||
|
||||
mainRunner.start();
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
assertEquals(Thread.State.WAITING, mainRunner.getState());
|
||||
mainRunner.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWaitingRead() throws InterruptedException {
|
||||
Tuple tuple_write = new Tuple(0);
|
||||
|
||||
Thread runnerExact = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
Tuple tuple_read = linda.read(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
});
|
||||
runnerExact.start();
|
||||
|
||||
Thread runnerType = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
Tuple tuple_read = linda.read(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
});
|
||||
runnerType.start();
|
||||
|
||||
Thread.sleep(1000);
|
||||
linda.write(tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -141,6 +147,95 @@ public class CentralizedLindaTests {
|
|||
assertNotEquals(linda.tryRead(tuple_template), null);
|
||||
assertNotEquals(linda.tryRead(new Tuple(String.class)), null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Take related tests")
|
||||
class TakeTests {
|
||||
|
||||
@Test
|
||||
void testTryTake() {
|
||||
Tuple tuple_write, tuple_template, tuple_read;
|
||||
|
||||
tuple_template = new Tuple(0);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, null);
|
||||
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, null);
|
||||
|
||||
tuple_write = new Tuple(0);
|
||||
linda.write(tuple_write);
|
||||
linda.write(tuple_write);
|
||||
|
||||
tuple_template = new Tuple(0);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
tuple_read = linda.tryTake(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWaitingTake() throws InterruptedException {
|
||||
Tuple tuple_write = new Tuple(0);
|
||||
|
||||
Thread runnerExact = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
Tuple tuple_read = linda.take(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
});
|
||||
runnerExact.start();
|
||||
|
||||
Thread runnerType = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
Tuple tuple_read = linda.take(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
});
|
||||
runnerType.start();
|
||||
|
||||
Thread.sleep(500);
|
||||
linda.write(tuple_write);
|
||||
Thread.sleep(500);
|
||||
linda.write(tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyTake() {
|
||||
Thread mainRunner = new Thread(() -> {
|
||||
Tuple tuple_template;
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
linda.take(tuple_template);
|
||||
});
|
||||
|
||||
mainRunner.start();
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
assertEquals(Thread.State.WAITING, mainRunner.getState());
|
||||
mainRunner.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTake() {
|
||||
Tuple tuple_write, tuple_template, tuple_read;
|
||||
|
||||
tuple_write = new Tuple(0);
|
||||
linda.write(tuple_write);
|
||||
linda.write(tuple_write);
|
||||
|
||||
tuple_template = new Tuple(0);
|
||||
tuple_read = linda.take(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
|
||||
tuple_template = new Tuple(Integer.class);
|
||||
tuple_read = linda.take(tuple_template);
|
||||
assertEquals(tuple_read, tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTakeAll() {
|
||||
|
@ -177,5 +272,135 @@ public class CentralizedLindaTests {
|
|||
assertEquals(linda.tryTake(tuple_template), null);
|
||||
assertNotEquals(linda.tryTake(new Tuple(String.class)), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("eventRegister related tests")
|
||||
class EventRegisterTests {
|
||||
|
||||
final Tuple tuple_write = new Tuple(0);
|
||||
|
||||
Callback assertCallback = new Callback() {
|
||||
@Override
|
||||
public void call(Tuple t) {
|
||||
assertEquals(t, tuple_write);
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
void IMMEDIATE_READ_test() throws InterruptedException {
|
||||
Thread runnerExact = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(0);
|
||||
linda.eventRegister(
|
||||
eventMode.READ,
|
||||
eventTiming.IMMEDIATE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerExact.start();
|
||||
|
||||
Thread runnerType = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
linda.eventRegister(
|
||||
eventMode.READ,
|
||||
eventTiming.IMMEDIATE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerType.start();
|
||||
|
||||
Thread.sleep(1000);
|
||||
linda.write(tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void IMMEDIATE_TAKE_test() throws InterruptedException {
|
||||
linda.write(new Tuple("999"));
|
||||
|
||||
Thread runnerExact = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(0);
|
||||
linda.eventRegister(
|
||||
eventMode.TAKE,
|
||||
eventTiming.IMMEDIATE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerExact.start();
|
||||
|
||||
Thread runnerType = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
linda.eventRegister(
|
||||
eventMode.TAKE,
|
||||
eventTiming.IMMEDIATE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerType.start();
|
||||
|
||||
Thread.sleep(500);
|
||||
linda.write(tuple_write);
|
||||
Thread.sleep(500);
|
||||
linda.write(tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void FUTURE_READ_test() throws InterruptedException {
|
||||
linda.write(new Tuple(999));
|
||||
linda.write(new Tuple("999"));
|
||||
|
||||
Thread runnerExact = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(0);
|
||||
linda.eventRegister(
|
||||
eventMode.READ,
|
||||
eventTiming.FUTURE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerExact.start();
|
||||
|
||||
// Thread runnerType = new Thread(() -> {
|
||||
// Tuple tuple_template = new Tuple(Integer.class);
|
||||
// linda.eventRegister(
|
||||
// eventMode.READ,
|
||||
// eventTiming.FUTURE,
|
||||
// tuple_template,
|
||||
// assertCallback);
|
||||
// });
|
||||
// runnerType.start();
|
||||
|
||||
Thread.sleep(1000);
|
||||
linda.write(tuple_write);
|
||||
}
|
||||
|
||||
@Test
|
||||
void FUTURE_TAKE_test() throws InterruptedException {
|
||||
linda.write(new Tuple(999));
|
||||
linda.write(new Tuple("999"));
|
||||
|
||||
Thread runnerExact = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(0);
|
||||
linda.eventRegister(
|
||||
eventMode.TAKE,
|
||||
eventTiming.FUTURE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerExact.start();
|
||||
|
||||
Thread runnerType = new Thread(() -> {
|
||||
Tuple tuple_template = new Tuple(Integer.class);
|
||||
linda.eventRegister(
|
||||
eventMode.TAKE,
|
||||
eventTiming.FUTURE,
|
||||
tuple_template,
|
||||
assertCallback);
|
||||
});
|
||||
runnerType.start();
|
||||
|
||||
Thread.sleep(500);
|
||||
linda.write(tuple_write);
|
||||
Thread.sleep(500);
|
||||
linda.write(tuple_write);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue