/** * Test simple NACK and onDelta. * Nack is not supposed to happen, so it should be death. */ public void testSimpleNackAndReceive() throws Exception { final int initialVersion = 42; connectChannel(initialVersion, SIG1); sendAndCheckRandomOp(operationChannel, initialVersion, SIG1); listener.clear(); try { operationChannel.onNack(ResponseCode.OK, null, 43); fail("Should have thrown ChannelException"); } catch (ChannelException expected) { } checkExpectationsSatisfied(); }
/** * Test simple reconnect. */ public void testSimpleReconnect() throws ChannelException { connectChannel(10, SIG1); listener.checkOpsReceived(0); // Now disconnect server-side, forcing a reconnect. reconnectChannel(10, SIG1); // No new messages. listener.checkOpsReceived(0); checkExpectationsSatisfied(); }
/** * Test a simple connect. */ public void testConnectSuccess() throws ChannelException { connectChannel(10, SIG1); listener.checkOpsReceived(0); checkExpectationsSatisfied(); }
final byte[] initialSignature = SIG1; final byte[] ackSignature = SIG2; connectChannel(initialVersion, initialSignature); sendAndCheckRandomOp(operationChannel, 42, SIG1); operationChannel.onAck(1, HashedVersion.of(43, ackSignature)); assertNotNull(operationChannel.receive()); listener.clear(); sendAndCheckRandomOp(operationChannel, 43, ackSignature); reconnectChannel(43, ackSignature, 47, SIG3, null); operationChannel.onDelta(createRandomTransformedDelta(42, 5, SIG4)); fail("Should have thrown ChannelException"); } catch (ChannelException expected) { checkExpectationsSatisfied();
/** * Test reconnect where there was an unACKed delta during the failure which * was not received by the server, expect the client to immediately resend the * delta. */ public void testReconnectWithPendingAckNotRecievedByServer() throws Exception { final int initialVersion = 42; final byte[] ackSignature = SIG2; connectChannel(initialVersion, SIG1); WaveletDelta delta = sendAndCheckRandomOp(operationChannel, 42, SIG1); // The server's version is still 42 when it responds. Expect a retransmission. reconnectChannel(initialVersion, SIG1, initialVersion, SIG1, delta); // Now ack. listener.checkOpsReceived(0); operationChannel.onAck(1, HashedVersion.of(43, ackSignature)); // There should be a fake op resulting from ack that updates version info listener.checkOpsReceived(1); checkExpectationsSatisfied(); }
/** * Test receiving a simple delta that was committed. */ public void testSimpleReceive() throws ChannelException { final int initialVersion = 42; connectChannel(initialVersion, SIG1); operationChannel.onDelta(createRandomTransformedDelta(initialVersion, 1, SIG2)); listener.checkOpsReceived(1); listener.clear(); assertNotNull(operationChannel.receive()); listener.checkOpsReceived(0); // TODO(anorth): test OnCommit by mocking CC operationChannel.onCommit(initialVersion + 1); checkExpectationsSatisfied(); }
public void testSimpleSendAndAck() throws Exception { final int initialVersion = 42; connectChannel(initialVersion, SIG1); sendAndCheckRandomOp(operationChannel, initialVersion, SIG1); listener.clear(); HashedVersion signature = HashedVersion.of(43, SIG2); operationChannel.onAck(1, signature); // Listener should receive a version update op. listener.checkOpsReceived(1); WaveletOperation op = operationChannel.receive(); WaveletOperationContext context = op.getContext(); assertEquals(1, context.getVersionIncrement()); assertEquals(signature, context.getHashedVersion()); }
public void testSendToInaccessibleChanneFails() throws ChannelException { final HashedVersion connectSig = HashedVersion.unsigned(0); deltaChannel = new MockWaveletDeltaChannel(); cc = new ConcurrencyControl(ccLogger, connectSig); operationChannel = new OperationChannelImpl(opLogger, deltaChannel, cc, Accessibility.READ_ONLY); operationChannel.setListener(listener); operationChannel.onConnection(connectSig, connectSig); try { sendAndCheckRandomOp(operationChannel, connectSig.getVersion(), connectSig.getHistoryHash()); fail("Expected a channel exception"); } catch (ChannelException expected) { } }
/** * Tests reconnection where the server does not provide a matching * signature. Expect failure. */ public void testReconnectionFailure() throws ChannelException { final int initialVersion = 42; final byte[] initialSignature = SIG1; connectChannel(initialVersion, initialSignature); // Simulate failure operationChannel.reset(); // Server presents unknown reconnect version final HashedVersion reconnectVersion = HashedVersion.of(66, SIG2); try { operationChannel.onConnection(reconnectVersion, reconnectVersion); fail("Should have thrown ChannelException"); } catch (ChannelException expected) { } }
/** * Reconnects the channel at the provided version, which is also * the current version. */ private void reconnectChannel(long connectVersion, byte[] connectSignature) throws ChannelException { reconnectChannel(connectVersion, connectSignature, connectVersion, connectSignature, null); }
/** * Fails and reconnects the channel at the provided connection version and * current version. The channel is expected to provide a distinct version * matching the connect version. If expectRetransmission is not null expects * the channel to attempt to send that message on reconnection. */ private void reconnectChannel(long connectVersion, byte[] connectSignature, long currentVersion, byte[] currentSignature, WaveletDelta expectRetransmission) throws ChannelException { final HashedVersion connectHashedVersion = HashedVersion.of(connectVersion, connectSignature); final HashedVersion currentHashedVersion = HashedVersion.of(currentVersion, currentSignature); // Simulate failure elsewhere. operationChannel.reset(); // Check reconnect versions provided by the channel include the // version we'll reconnect at. List<HashedVersion> reconnectVersions = operationChannel.getReconnectVersions(); assertTrue(reconnectVersions.size() > 0); boolean matchedSignature = false; for (HashedVersion rcv : reconnectVersions) { if (connectVersion == rcv.getVersion() && connectSignature.equals(rcv.getHistoryHash())) { matchedSignature = true; } } assertTrue("No matching signature provided", matchedSignature); // Simulate reconnection reconnection message from delta channel. if (expectRetransmission != null) { deltaChannel.expectSend(expectRetransmission); } operationChannel.onConnection(connectHashedVersion, currentHashedVersion); }
final byte[] initialSignature = SIG1; final byte[] ackSignature = SIG2; connectChannel(initialVersion, initialSignature); sendAndCheckRandomOp(operationChannel, 42, SIG1); operationChannel.onAck(1, HashedVersion.of(43, ackSignature)); assertNotNull(operationChannel.receive()); listener.clear(); sendAndCheckRandomOp(operationChannel, 43, ackSignature); reconnectChannel(43, ackSignature, 47, SIG3, null); operationChannel.onDelta(createRandomTransformedDelta(42, 5, SIG4)); fail("Should have thrown ChannelException"); } catch (ChannelException expected) { checkExpectationsSatisfied();
/** * Test reconnect where there was an unACKed delta during the failure which * was not received by the server, expect the client to immediately resend the * delta. */ public void testReconnectWithPendingAckNotRecievedByServer() throws Exception { final int initialVersion = 42; final byte[] ackSignature = SIG2; connectChannel(initialVersion, SIG1); WaveletDelta delta = sendAndCheckRandomOp(operationChannel, 42, SIG1); // The server's version is still 42 when it responds. Expect a retransmission. reconnectChannel(initialVersion, SIG1, initialVersion, SIG1, delta); // Now ack. listener.checkOpsReceived(0); operationChannel.onAck(1, HashedVersion.of(43, ackSignature)); // There should be a fake op resulting from ack that updates version info listener.checkOpsReceived(1); checkExpectationsSatisfied(); }
/** * Test receiving a simple delta that was committed. */ public void testSimpleReceive() throws ChannelException { final int initialVersion = 42; connectChannel(initialVersion, SIG1); operationChannel.onDelta(createRandomTransformedDelta(initialVersion, 1, SIG2)); listener.checkOpsReceived(1); listener.clear(); assertNotNull(operationChannel.receive()); listener.checkOpsReceived(0); // TODO(anorth): test OnCommit by mocking CC operationChannel.onCommit(initialVersion + 1); checkExpectationsSatisfied(); }
public void testSimpleSendAndAck() throws Exception { final int initialVersion = 42; connectChannel(initialVersion, SIG1); sendAndCheckRandomOp(operationChannel, initialVersion, SIG1); listener.clear(); HashedVersion signature = HashedVersion.of(43, SIG2); operationChannel.onAck(1, signature); // Listener should receive a version update op. listener.checkOpsReceived(1); WaveletOperation op = operationChannel.receive(); WaveletOperationContext context = op.getContext(); assertEquals(1, context.getVersionIncrement()); assertEquals(signature, context.getHashedVersion()); }
/** * Test a simple connect. */ public void testConnectSuccess() throws ChannelException { connectChannel(10, SIG1); listener.checkOpsReceived(0); checkExpectationsSatisfied(); }
public void testSendToInaccessibleChanneFails() throws ChannelException { final HashedVersion connectSig = HashedVersion.unsigned(0); deltaChannel = new MockWaveletDeltaChannel(); cc = new ConcurrencyControl(ccLogger, connectSig); operationChannel = new OperationChannelImpl(opLogger, deltaChannel, cc, Accessibility.READ_ONLY); operationChannel.setListener(listener); operationChannel.onConnection(connectSig, connectSig); try { sendAndCheckRandomOp(operationChannel, connectSig.getVersion(), connectSig.getHistoryHash()); fail("Expected a channel exception"); } catch (ChannelException expected) { } }
/** * Tests reconnection where the server does not provide a matching * signature. Expect failure. */ public void testReconnectionFailure() throws ChannelException { final int initialVersion = 42; final byte[] initialSignature = SIG1; connectChannel(initialVersion, initialSignature); // Simulate failure operationChannel.reset(); // Server presents unknown reconnect version final HashedVersion reconnectVersion = HashedVersion.of(66, SIG2); try { operationChannel.onConnection(reconnectVersion, reconnectVersion); fail("Should have thrown ChannelException"); } catch (ChannelException expected) { } }
/** * Reconnects the channel at the provided version, which is also * the current version. */ private void reconnectChannel(long connectVersion, byte[] connectSignature) throws ChannelException { reconnectChannel(connectVersion, connectSignature, connectVersion, connectSignature, null); }
/** * Fails and reconnects the channel at the provided connection version and * current version. The channel is expected to provide a distinct version * matching the connect version. If expectRetransmission is not null expects * the channel to attempt to send that message on reconnection. */ private void reconnectChannel(long connectVersion, byte[] connectSignature, long currentVersion, byte[] currentSignature, WaveletDelta expectRetransmission) throws ChannelException { final HashedVersion connectHashedVersion = HashedVersion.of(connectVersion, connectSignature); final HashedVersion currentHashedVersion = HashedVersion.of(currentVersion, currentSignature); // Simulate failure elsewhere. operationChannel.reset(); // Check reconnect versions provided by the channel include the // version we'll reconnect at. List<HashedVersion> reconnectVersions = operationChannel.getReconnectVersions(); assertTrue(reconnectVersions.size() > 0); boolean matchedSignature = false; for (HashedVersion rcv : reconnectVersions) { if (connectVersion == rcv.getVersion() && connectSignature.equals(rcv.getHistoryHash())) { matchedSignature = true; } } assertTrue("No matching signature provided", matchedSignature); // Simulate reconnection reconnection message from delta channel. if (expectRetransmission != null) { deltaChannel.expectSend(expectRetransmission); } operationChannel.onConnection(connectHashedVersion, currentHashedVersion); }