use of com.yahoo.documentapi.messagebus.MessageBusVisitorSession in project vespa by vespa-engine.
the class MessageBusVisitorSessionTestCase method testNoDataHandlersImpliesVisitorDataQueue.
@Test
public void testNoDataHandlersImpliesVisitorDataQueue() {
MockSender sender = new MockSender();
MockReceiver receiver = new MockReceiver();
MockAsyncTaskExecutor executor = new MockAsyncTaskExecutor();
VisitorParameters params = createVisitorParameters("");
MessageBusVisitorSession visitorSession = createVisitorSession(sender, receiver, executor, params);
assertNotNull(params.getLocalDataHandler());
assertTrue(params.getLocalDataHandler() instanceof VisitorDataQueue);
}
use of com.yahoo.documentapi.messagebus.MessageBusVisitorSession in project vespa by vespa-engine.
the class MessageBusVisitorSessionTestCase method testMaxPendingVisitorsForSender.
@Test
public void testMaxPendingVisitorsForSender() {
MockSender sender = new MockSender();
MockReceiver receiver = new MockReceiver();
sender.setMaxPending(1);
MockAsyncTaskExecutor executor = new MockAsyncTaskExecutor();
// Visit-all will normally start with 1 distribution bit and send
// to 2 superbuckets if allowed to do so.
VisitorParameters params = createVisitorParameters("");
MessageBusVisitorSession visitorSession = createVisitorSession(sender, receiver, executor, params);
visitorSession.start();
executor.expectAndProcessTasks(1);
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x0400000000000000)\n" + "BucketId(0x0000000000000000)\n" + "]\n)", replyToCreateVisitor(sender, ProgressToken.FINISHED_BUCKET));
// Reply
executor.expectAndProcessTasks(1);
// New visitor
executor.expectAndProcessTasks(1);
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x0400000000000001)\n" + "BucketId(0x0000000000000000)\n" + "]\n)", replyToCreateVisitor(sender, ProgressToken.FINISHED_BUCKET));
}
use of com.yahoo.documentapi.messagebus.MessageBusVisitorSession in project vespa by vespa-engine.
the class MessageBusVisitorSessionTestCase method testDestroyAbortsSessionIfNotDone.
@Test
public void testDestroyAbortsSessionIfNotDone() throws Exception {
MockComponents mc = createDefaultMock("id.user==1234");
mc.visitorSession.start();
mc.executor.expectAndProcessTasks(1);
mc.controlHandler.setSynchronousWaitUntilDone(true);
mc.controlHandler.resetMock();
final MessageBusVisitorSession session = mc.visitorSession;
final SharedValue<Exception> exceptionPropagator = new SharedValue<Exception>();
final CyclicBarrier barrier = new CyclicBarrier(2);
// Have to do this multi-threaded for once since destroy is
// synchronous and any code logic bug could otherwise cause the
// test (and thus the build) to hang indefinitely.
// NOTE: even though the MockControlHandler itself is not thread safe,
// the control flow of the test should guarantee there is no concurrent
// access to it.
Thread t = new Thread(() -> {
try {
session.destroy();
if (!session.isDone()) {
throw new IllegalStateException("Session is not marked as done after destroy()");
}
barrier.await(20000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
exceptionPropagator.setValue(e);
}
});
t.start();
try {
waitUntilTrue(20000, () -> session.isDestroying());
// Reply to visitor. Normally, the visitor would be resent, but
// since destroy aborts the session, this won't happen and the
// session will be marked as completed instead.
replyErrorToCreateVisitor(mc.sender, new Error(DocumentProtocol.ERROR_BUCKET_DELETED, "goner"));
// reply
mc.executor.expectAndProcessTasks(1);
mc.executor.expectNoTasks();
barrier.await(20000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
t.interrupt();
throw e;
} finally {
t.join();
}
if (exceptionPropagator.getValue() != null) {
throw new IllegalStateException("Exception thrown in destruction thread", exceptionPropagator.getValue());
}
assertTrue(mc.sender.isDestroyed());
assertTrue(mc.receiver.isDestroyed());
assertEquals("onDone : ABORTED - 'Session explicitly destroyed before completion'\n", mc.controlHandler.toString());
}
use of com.yahoo.documentapi.messagebus.MessageBusVisitorSession in project vespa by vespa-engine.
the class MessageBusVisitorSessionTestCase method testSynchronousWaitUntilDoneAndDestroy.
/**
* Test that calling waitUntilDone waits until session has completed.
* Test that destroy() destroys the communication interfaces it uses.
* @throws Exception
*/
@Test
public void testSynchronousWaitUntilDoneAndDestroy() throws Exception {
MockComponents mc = createDefaultMock("id.user==1234");
mc.visitorSession.start();
mc.executor.expectAndProcessTasks(1);
mc.controlHandler.setSynchronousWaitUntilDone(true);
mc.controlHandler.resetMock();
final MockControlHandler controlHandler = mc.controlHandler;
final MessageBusVisitorSession session = mc.visitorSession;
final SharedValue<Exception> exceptionPropagator = new SharedValue<Exception>();
final CyclicBarrier barrier = new CyclicBarrier(2);
// Have to do this multi-threaded for once since waitUntilDone/destroy
// are both synchronous and will not return before session is complete,
// either through success or failure.
Thread t = new Thread(() -> {
try {
boolean ok = session.waitUntilDone(20000);
if (!session.isDone()) {
throw new IllegalStateException("waitUntilDone returned, but session is not marked as done");
}
assertTrue(ok);
session.destroy();
barrier.await(20000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
exceptionPropagator.setValue(e);
}
});
t.start();
try {
waitUntilTrue(20000, () -> controlHandler.isWaiting());
// Reply to visitor, causing session to complete
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x80000000000004d2)\n" + "BucketId(0x0000000000000000)\n" + "]\n" + "selection='id.user==1234'\n)", replyToCreateVisitor(mc.sender, ProgressToken.FINISHED_BUCKET));
// reply
mc.executor.expectAndProcessTasks(1);
mc.executor.expectNoTasks();
barrier.await(20000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
t.interrupt();
throw e;
} finally {
t.join();
}
if (exceptionPropagator.getValue() != null) {
throw new IllegalStateException("Exception thrown in destruction thread", exceptionPropagator.getValue());
}
assertTrue(mc.sender.isDestroyed());
assertTrue(mc.receiver.isDestroyed());
assertEquals("waitUntilDone : 20000\n" + "onProgress : 0 active, 0 pending, 1 finished, 1 total\n" + "onVisitorStatistics : 0 buckets visited, 0 docs returned\n" + "onDone : SUCCESS - ''\n", mc.controlHandler.toString());
}
use of com.yahoo.documentapi.messagebus.MessageBusVisitorSession in project vespa by vespa-engine.
the class MessageBusVisitorSessionTestCase method testWrongDistributionAdjustsDistributionBits.
@Test
public void testWrongDistributionAdjustsDistributionBits() {
MockSender sender = new MockSender();
MockReceiver receiver = new MockReceiver();
sender.setMaxPending(2);
MockAsyncTaskExecutor executor = new MockAsyncTaskExecutor();
VisitorParameters params = createVisitorParameters("");
MessageBusVisitorSession visitorSession = createVisitorSession(sender, receiver, executor, params);
visitorSession.start();
executor.expectAndProcessTasks(1);
assertEquals(2, sender.getMessageCount());
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x0400000000000000)\n" + "BucketId(0x0000000000000000)\n" + "]\n)", replyWrongDistributionToCreateVisitor(sender, "version:2 storage:100 distributor:100 bits:16"));
// WDR reply
executor.expectAndProcessTasks(1);
// Replying with WRONG_DISTRIBUTION when there are active visitors
// should not send any new visitors until all active have returned.
// This allows the visitor iterator to consistently adjust the visiting
// progress based on the distribution bit change.
executor.expectNoTasks();
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x0400000000000001)\n" + "BucketId(0x0000000000000000)\n" + "]\n)", replyWrongDistributionToCreateVisitor(sender, "version:2 storage:100 distributor:100 bits:16"));
// WDR reply
executor.expectAndProcessTasks(1);
// Send new visitors, no delay
executor.expectAndProcessTasks(1, new long[] { 0 });
// Now with 16 distribution bits.
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x4000000000000000)\n" + "BucketId(0x0000000000000000)\n" + "]\n)", replyToCreateVisitor(sender, ProgressToken.FINISHED_BUCKET));
assertEquals("CreateVisitorMessage(buckets=[\n" + "BucketId(0x4000000000008000)\n" + "BucketId(0x0000000000000000)\n" + "]\n)", replyToCreateVisitor(sender, ProgressToken.FINISHED_BUCKET));
// .... and 65533 more
}
Aggregations