use of org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch in project scout.rt by eclipse.
the class ExecutionSemaphoreTest method testThreePermitsAndBlocking.
/**
* Tests execution semaphore with 3 permits and with a blocking condition involved.
* <p>
* In total, 7 jobs are scheduled. Thereby, job-1 and job-3 never finish, and job-2 enters a blocking condition.
* <p>
* This test tests, that because job-2 enters a blocking condition, job-4 starts running. Once job-4 completed, job-5
* starts running. Then, job-5 unblocks the conditions, with lets job-2 to continue after job-5 finished. After job-2
* finished, job-6, and then job-7 start running.
* <p>
*/
@Test
// regression
@Times(500)
public void testThreePermitsAndBlocking() throws InterruptedException {
final IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(3);
// synchronized because modified/read by different threads.
final Set<String> protocol = Collections.synchronizedSet(new HashSet<String>());
final IBlockingCondition condition = Jobs.newBlockingCondition(true);
final BlockingCountDownLatch setupLatch = new BlockingCountDownLatch(3);
final BlockingCountDownLatch finishLatch = new BlockingCountDownLatch(2);
final BlockingCountDownLatch latchJob2 = new BlockingCountDownLatch(1);
final BlockingCountDownLatch latchJob5 = new BlockingCountDownLatch(1);
final BlockingCountDownLatch latchJob6 = new BlockingCountDownLatch(1);
final BlockingCountDownLatch latchJob7 = new BlockingCountDownLatch(1);
// job-1
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-1-running");
setupLatch.countDownAndBlock();
finishLatch.countDownAndBlock();
}
}, Jobs.newInput().withName("job-1").withExecutionSemaphore(semaphore));
// job-2
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-2-running (a)");
condition.waitFor(30, TimeUnit.SECONDS);
protocol.add("job-2-running (b)");
latchJob2.countDownAndBlock();
}
}, Jobs.newInput().withName("job-2").withExecutionSemaphore(semaphore));
// job-3
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-3-running");
setupLatch.countDownAndBlock();
finishLatch.countDownAndBlock();
}
}, Jobs.newInput().withName("job-3").withExecutionSemaphore(semaphore));
// job-4
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-4-running");
setupLatch.countDownAndBlock();
}
}, Jobs.newInput().withName("job-4").withExecutionSemaphore(semaphore));
// job-5
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-5-running");
condition.setBlocking(false);
// Wait until job-2 is competing for a permit anew.
// Otherwise, job-6 might get the permit before job-2.
// permit-owners: job-1, job-3, job-5, queue: job-2 (RE-ACQUIRE), job-6, job-7
JobTestUtil.waitForPermitCompetitors(semaphore, 6);
latchJob5.countDownAndBlock();
}
}, Jobs.newInput().withName("job-5").withExecutionSemaphore(semaphore));
// job-6
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-6-running");
latchJob6.countDownAndBlock();
}
}, Jobs.newInput().withName("job-6").withExecutionSemaphore(semaphore));
// job-7
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-7-running");
latchJob7.countDownAndBlock();
}
}, Jobs.newInput().withName("job-7").withExecutionSemaphore(semaphore));
// verify
assertTrue(setupLatch.await());
assertEquals(CollectionUtility.hashSet("job-1-running", "job-2-running (a)", "job-3-running", "job-4-running"), protocol);
protocol.clear();
setupLatch.unblock();
assertTrue(latchJob5.await());
assertEquals(CollectionUtility.hashSet("job-5-running"), protocol);
protocol.clear();
latchJob5.unblock();
try {
assertTrue(latchJob2.await());
} catch (AssertionError e) {
System.out.println(protocol);
throw e;
}
assertEquals(CollectionUtility.hashSet("job-2-running (b)"), protocol);
protocol.clear();
latchJob2.unblock();
assertTrue(latchJob6.await());
assertEquals(CollectionUtility.hashSet("job-6-running"), protocol);
protocol.clear();
latchJob6.unblock();
assertTrue(latchJob7.await());
assertEquals(CollectionUtility.hashSet("job-7-running"), protocol);
latchJob7.unblock();
finishLatch.unblock();
}
use of org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch in project scout.rt by eclipse.
the class FutureFinishedTest method testNormalCompletion.
@Test
public void testNormalCompletion() throws InterruptedException {
final BlockingCountDownLatch latch = new BlockingCountDownLatch(1);
IFuture<Void> future = Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
latch.countDownAndBlock();
}
}, Jobs.newInput());
// Job still running
assertTrue(latch.await());
assertDone(future, false);
assertFinished(future, false);
// Let the job finish
latch.unblock();
// Job cancelled, but not finished yet
future.awaitFinished(10, TimeUnit.SECONDS);
assertDone(future, true);
assertFinished(future, true);
}
use of org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch in project scout.rt by eclipse.
the class MutualExclusionTest method testAcquisition5.
/**
* Task1 acquires the mutex. Then, task2 tries to acquire the mutex and blocks until acquired. Because task2 cannot
* acquire the mutex (hold by task1), it is cancelled hard (interrupted=true). That causes task2 no longer to wait for
* the mutex, meaning that when task1 releases the mutex, task2 does not become the mutex owner.
*/
@Test(timeout = 5_000)
public void testAcquisition5() throws java.lang.InterruptedException {
final ExecutionSemaphore mutex = (ExecutionSemaphore) m_task1.getExecutionSemaphore();
assertEquals(0, mutex.getCompetitorCount());
// Make task1 to acquire the mutex
IPermitAcquiredCallback callbackTask1 = mock(IPermitAcquiredCallback.class);
assertTrue(mutex.compete(m_task1, QueuePosition.HEAD, callbackTask1));
verify(callbackTask1, times(1)).onPermitAcquired();
assertTrue(mutex.isPermitOwner(m_task1));
assertEquals(1, mutex.getCompetitorCount());
// Task2 tries to acquire the mutex, and blocks until acquired
final BlockingCountDownLatch interruptedLatch = new BlockingCountDownLatch(1);
IFuture<Void> future = Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
try {
mutex.acquire(m_task2, QueuePosition.TAIL);
} catch (ThreadInterruptedError e) {
interruptedLatch.countDown();
}
}
}, Jobs.newInput().withExceptionHandling(null, false));
JobTestUtil.waitForPermitCompetitors(mutex, 2);
assertTrue(mutex.isPermitOwner(m_task1));
assertEquals(2, mutex.getCompetitorCount());
future.cancel(true);
assertTrue(interruptedLatch.await());
assertTrue(mutex.isPermitOwner(m_task1));
assertEquals(2, mutex.getCompetitorCount());
mutex.release(m_task1);
assertFalse(mutex.isPermitOwner(m_task2));
assertEquals(0, mutex.getCompetitorCount());
}
use of org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch in project scout.rt by eclipse.
the class SerialFutureExecutionTest method testAtFixedRate_NowWithExistingCount.
/**
* Tests that a future is not run concurrently.
* <p>
* For that, we schedule a job periodically at a fixed rate (every millisecond), but sleep in the Runnable of the
* first round, so it does not complete. Upon continuation, we expect all pending rounds to be executed.
* <p>
* Misfire policy: {@link SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT}
*/
@Test
public void testAtFixedRate_NowWithExistingCount() throws InterruptedException {
// synchronized because modified/read by different threads.
final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
final String jobIdentifier = UUID.randomUUID().toString();
final BlockingCountDownLatch latch = new BlockingCountDownLatch(1);
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("before");
latch.countDownAndBlock();
protocol.add("after");
}
}, Jobs.newInput().withExecutionHint(jobIdentifier).withExecutionTrigger(Jobs.newExecutionTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(1).withMisfireHandlingInstructionNowWithExistingCount().withRepeatCount(// see JavaDoc of withRepeatCount: first + repeat count
99))));
latch.await();
// Wait some time until trigger fired for all rounds
Thread.sleep(2000);
// Verify no concurrent execution
List<String> expectedProtocol = new ArrayList<>();
// first round started
expectedProtocol.add("before");
assertEquals(expectedProtocol, protocol);
latch.unblock();
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(jobIdentifier).toFilter(), 10, TimeUnit.SECONDS);
// first round completed
expectedProtocol.add("after");
for (int i = 0; i < 99; i++) {
// other 99 rounds
expectedProtocol.add("before");
// other 99 rounds
expectedProtocol.add("after");
}
assertEquals(expectedProtocol, protocol);
}
use of org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch in project scout.rt by eclipse.
the class JmsMomImplementorTest method testSubscribeTransactional.
@Test
public void testSubscribeTransactional() throws InterruptedException {
IDestination<String> queue = MOM.newDestination("test/mom/testSubscribeTransactional", DestinationType.QUEUE, ResolveMethod.DEFINE, null);
m_disposables.add(MOM.registerMarshaller(JmsTestMom.class, queue, BEANS.get(ObjectMarshaller.class)));
MOM.publish(JmsTestMom.class, queue, "message-1", MOM.newPublishInput());
final AtomicInteger messageCounter = new AtomicInteger();
// 1. Receive message, but reject it (rollback)
final BlockingCountDownLatch message1Latch = new BlockingCountDownLatch(1);
final BlockingCountDownLatch message2Latch = new BlockingCountDownLatch(1);
IMessageListener<String> listener = new IMessageListener<String>() {
@Override
public void onMessage(IMessage<String> message) {
switch(message.getTransferObject()) {
case "message-1":
switch(messageCounter.incrementAndGet()) {
case 1:
case 2:
case 3:
ITransaction.CURRENT.get().rollback();
break;
default:
message1Latch.countDown();
break;
}
return;
case "message-2":
message2Latch.countDown();
break;
default:
throw new IllegalArgumentException("illegal message");
}
}
};
// Register transactional subscriber
m_disposables.add(MOM.subscribe(JmsTestMom.class, queue, listener, MOM.newSubscribeInput().withAcknowledgementMode(SubscribeInput.ACKNOWLEDGE_TRANSACTED)));
assertTrue("message expected to be rejected 3 times", message1Latch.await());
// Publish a next message
MOM.publish(JmsTestMom.class, queue, "message-2", MOM.newPublishInput());
// Check that the message was received
assertTrue("message expected to be received", message2Latch.await());
// Wait some time to verify that 'message-1' is no longer received.
Thread.sleep(1000);
assertEquals(messageCounter.get(), 4);
}
Aggregations