use of com.hazelcast.internal.util.concurrent.BackoffIdleStrategy in project hazelcast by hazelcast.
the class TestSupport method runTest.
private void runTest(TestMode testMode) throws Exception {
beforeEachRun.run();
assert testMode.isSnapshotsEnabled() || testMode.snapshotRestoreInterval() == 0 : "Illegal combination: don't do snapshots, but do restore";
boolean doSnapshots = testMode.doSnapshots;
int doRestoreEvery = testMode.restoreInterval;
IdleStrategy idler = new BackoffIdleStrategy(0, 0, MICROSECONDS.toNanos(1), MILLISECONDS.toNanos(1));
int idleCount = 0;
System.out.println("### Running the test, mode=" + testMode.toString());
TestInbox inbox = new TestInbox();
int inboxOrdinal = -1;
Processor[] processor = { newProcessorFromSupplier() };
boolean isCooperative = processor[0].isCooperative();
// we'll use 1-capacity outbox to test outbox rejection
TestOutbox[] outbox = { createOutbox() };
List<List<Object>> actualOutputs = new ArrayList<>(outputOrdinalCount);
for (int i = 0; i < outputOrdinalCount; i++) {
actualOutputs.add(new ArrayList<>());
}
// create instance of your processor and call the init() method
initProcessor(processor[0], outbox[0]);
int[] restoreCount = { 0 };
// do snapshot+restore before processing any item. This will test saveToSnapshot() in this edge case
snapshotAndRestore(processor, outbox, actualOutputs, doSnapshots, doRestoreEvery, restoreCount);
// call the process() method
List<ObjectWithOrdinal> input = mixInputs(inputs, priorities);
int inputPosition = 0;
while (inputPosition < input.size() || !inbox.isEmpty()) {
if (inbox.isEmpty() && inputPosition < input.size()) {
inboxOrdinal = input.get(inputPosition).ordinal;
for (int added = 0; inputPosition < input.size() && added < testMode.inboxLimit() && inboxOrdinal == input.get(inputPosition).ordinal && (added == 0 || !(input.get(inputPosition).item instanceof Watermark)); added++) {
ObjectWithOrdinal objectWithOrdinal = input.get(inputPosition++);
inbox.queue().add(objectWithOrdinal.item);
inboxOrdinal = objectWithOrdinal.ordinal;
}
if (logInputOutput) {
System.out.println(LocalTime.now() + " Input-" + inboxOrdinal + ": " + inbox);
}
}
int lastInboxSize = inbox.size();
String methodName;
methodName = processInbox(inbox, inboxOrdinal, isCooperative, processor);
boolean madeProgress = inbox.size() < lastInboxSize || (outbox[0].bucketCount() > 0 && !outbox[0].queue(0).isEmpty());
assertTrue(methodName + "() call without progress", !assertProgress || madeProgress);
idleCount = idle(idler, idleCount, madeProgress);
if (outbox[0].bucketCount() > 0 && outbox[0].queue(0).size() == 1 && !inbox.isEmpty()) {
// if the outbox is full, call the process() method again. Cooperative
// processor must be able to cope with this situation and not try to put
// more items to the outbox.
outbox[0].reset();
processInbox(inbox, inboxOrdinal, isCooperative, processor);
}
outbox[0].drainQueuesAndReset(actualOutputs, logInputOutput);
if (inbox.isEmpty()) {
snapshotAndRestore(processor, outbox, actualOutputs, doSnapshots, doRestoreEvery, restoreCount);
}
}
if (logInputOutput && !inputs.isEmpty()) {
System.out.println(LocalTime.now() + " Input processed, calling complete()");
}
// call the complete() method
if (callComplete) {
long completeStart = System.nanoTime();
long outputMatchedAt = Long.MAX_VALUE;
boolean[] done = { false };
do {
doCall("complete", isCooperative, () -> done[0] = processor[0].complete());
boolean madeProgress = done[0] || (outbox[0].bucketCount() > 0 && !outbox[0].queue(0).isEmpty());
assertTrue("complete() call without progress", !assertProgress || madeProgress);
outbox[0].drainQueuesAndReset(actualOutputs, logInputOutput);
if (outbox[0].hasUnfinishedItem()) {
assertFalse("outbox has unfinished items, but complete() claims to be done", done[0]);
outbox[0].block();
} else {
outbox[0].unblock();
snapshotAndRestore(processor, outbox, actualOutputs, madeProgress && doSnapshots && !done[0], doRestoreEvery, restoreCount);
}
idleCount = idle(idler, idleCount, madeProgress);
long now = System.nanoTime();
if (runUntilOutputMatchesTimeoutMillis >= 0) {
try {
assertOutputFn.accept(testMode, actualOutputs);
outputMatchedAt = Math.min(outputMatchedAt, now);
} catch (AssertionError e) {
if (outputMatchedAt < Long.MAX_VALUE) {
throw new AssertionError("the output already matched, but doesn't match now", e);
}
// ignore the failure otherwise and continue calling complete()
}
long elapsedSinceStart = NANOSECONDS.toMillis(now - completeStart);
long elapsedSinceMatch = NANOSECONDS.toMillis(subtractClamped(now, outputMatchedAt));
if (elapsedSinceStart > runUntilOutputMatchesTimeoutMillis || elapsedSinceMatch > runUntilOutputMatchesExtraTimeMillis) {
break;
}
}
} while (!done[0]);
assertTrue("complete returned true in a run-until-output-matches mode", !done[0] || runUntilOutputMatchesTimeoutMillis <= 0);
}
processor[0].close();
assertOutputFn.accept(testMode, actualOutputs);
}
Aggregations