/** * Tests that receiving an ack for a delta already received by this client * is detected as a server-side error. */ public void testAckForReceivedDeltaIsError() throws ChannelException { final long currentVersion = 57; final int ops1 = 7; final byte[] signature1 = sig(1); final WaveletDelta delta1 = buildDelta(currentVersion, ops1); checkedConnectChannel(currentVersion); // Send delta1. submitDeltaOnConnectedChannel(delta1); // Receive the delta (erroneously), but we can't detect it's an error yet. TransformedWaveletDelta serverDelta1 = buildServerDelta(currentVersion, ops1); receiver.expectDelta(serverDelta1); receiveUpdateOnConnectedChannel(serverDelta1); // Now receive the ack for the delta. Expect failure. try { ackDeltaOnConnectedChannel(currentVersion + ops1, ops1, signature1); fail("ChannelException expected"); } catch (ChannelException expected) { } receiver.checkExpectationsSatisfied(); }
public void testNackTooOldIsRecoverable() throws ChannelException { final long initialVersion = 0; checkedConnectChannel(initialVersion); // Submit delta. final long submitVersion = 0; final byte[] signature = sig(1); final int clientOps = 1; final WaveletDelta clientDelta = buildDelta(submitVersion, clientOps); submitDeltaOnConnectedChannel(clientDelta); // Nack delta immediately with TOO_OLD. try { nackDeltaOnConnectedChannel(submitVersion, signature, "too old", ResponseCode.TOO_OLD); fail("Expected an exception"); } catch (ChannelException e) { assertEquals(Recoverable.RECOVERABLE, e.getRecoverable()); } }
/** * Tests that an ack received for a delta submitted before a channel * reconnects is dropped. */ public void testAckAfterReconnectIgnored() throws ChannelException { final long initialVersion = 57; final byte[] initialSignature = sig(4); checkedConnectChannel(initialVersion); // Submit delta. final int clientOps = 5; final WaveletDelta clientDelta = buildDelta(initialVersion, clientOps); submitDeltaOnConnectedChannel(clientDelta); // Reset channel. deltaChannel.reset(receiver); final List<TransformedWaveletDelta> reconnect = buildReconnect(initialVersion, initialSignature); checkedReconnectChannel(reconnect, 0, new byte[0]); // Acknowledge outstanding submit. final long versionAfterClient = initialVersion + clientOps; final byte[] ackedSignature = sig(1); // Don't expect the ack at the receiver. ackDeltaOnConnectedChannel(versionAfterClient, clientOps, ackedSignature); receiver.checkExpectationsSatisfied(); }
/** * Tests that sending on an unconnected channel fails. */ public void testSendBeforeConnectFails() { try { sendDelta(buildDelta(1, 1)); fail("Expected IllegalStateException"); } catch (IllegalStateException expected) { } waveletChannel.checkExpectationsSatisfied(); }
/** * Tests that a channel with no receivers quietly drops messages. */ public void testChannelWithNoReceiverDropsMessages() throws ChannelException { final long initialVersion = 57; final byte[] signature = sig(1); final ObservableWaveletData wavelet = buildSnapshot(initialVersion, signature); final TransformedWaveletDelta delta = buildServerDelta(initialVersion, 3); deltaChannel.reset(null); // Clear receiver. connectChannel(wavelet); receiveUpdateOnConnectedChannel(delta, initialVersion, signature); receiver.checkExpectationsSatisfied(); }
final long initialVersion = 57; final int serverOps1 = 7; checkedConnectChannel(initialVersion); final TransformedWaveletDelta delta1 = buildServerDelta(initialVersion, serverOps1); receiver.expectDelta(delta1); receiveUpdateOnConnectedChannel(delta1); final WaveletDelta clientDelta = buildDelta(versionAfterServer1, clientOps); submitDeltaOnConnectedChannel(clientDelta); final byte[] ackedSignature = sig(1); receiver.expectAck(clientOps, HashedVersion.of(versionAfterClient, ackedSignature)); ackDeltaOnConnectedChannel(versionAfterClient, clientOps, ackedSignature); final TransformedWaveletDelta delta2 = buildServerDelta(versionAfterClient, serverOps2); receiver.expectDelta(delta2); receiveUpdateOnConnectedChannel(delta2); closeChannel(); receiver.checkExpectationsSatisfied();
/** * Tests that the delta channel detects a gap in the op stream even when there * is an oustanding delta submission if the ack couldn't possibly account for * the version gap. */ public void testMissingDeltaBeyondLateAckKillsChannel() throws ChannelException { final long initialVersion = 57; final int serverOps1 = 7; checkedConnectChannel(initialVersion); // Receive server delta. final TransformedWaveletDelta delta1 = buildServerDelta(initialVersion, serverOps1); receiver.expectDelta(delta1); receiveUpdateOnConnectedChannel(delta1); // Submit delta. final long versionAfterServer1 = initialVersion + serverOps1; final int sigAfterServer1 = 0x11111111; final int clientOps = 5; final WaveletDelta clientDelta = buildDelta(versionAfterServer1, clientOps); submitDeltaOnConnectedChannel(clientDelta); // Receive a second server delta, too far ahead of the client ops. final long versionAfterClient = versionAfterServer1 + clientOps; final int sigAfterClient = 0x22222222; final TransformedWaveletDelta delta2 = buildServerDelta(versionAfterClient + 1, 1); try { receiveUpdateOnConnectedChannel(delta2); fail("Expected a ChannelException"); } catch (ChannelException expected) { } receiver.checkExpectationsSatisfied(); }
/** * Tests that a last-committed-version message with no deltas is correctly * delivered. */ public void testReceiveLastCommittedVersion() throws ChannelException { final long initialVersion = 57; final long committedVersion = 50; final byte[] committedSignature = sig(1); checkedConnectChannel(initialVersion); receiver.expectCommit(committedVersion); receiveUpdateOnConnectedChannel(null, committedVersion, committedSignature); // Close. closeChannel(); receiver.checkExpectationsSatisfied(); }
/** * Tests that a delta sent down the channel is received and the acknowledgment * delivered. */ public void testSubmitDelta() throws ChannelException { final long currentVersion = 57; final int ops1 = 7; final WaveletDelta delta1 = buildDelta(currentVersion, ops1); final byte[] signature1 = sig(1); final WaveletDelta delta2 = buildDelta(currentVersion + ops1, 2); final int opsCommitted = 3; final String errorMsg2 = "SERVER_ERROR"; checkedConnectChannel(currentVersion); // Send delta1. submitDeltaOnConnectedChannel(delta1); // All ops are acked. receiver.expectAck(ops1, HashedVersion.of(currentVersion + ops1, signature1)); ackDeltaOnConnectedChannel(currentVersion + ops1, ops1, signature1); // Send delta2. submitDeltaOnConnectedChannel(delta2); // Nack with a randomly injected error, as if something just went wrong // server-side. receiver.expectNack(errorMsg2, currentVersion + ops1); nackDeltaOnConnectedChannel(currentVersion + ops1, signature1, errorMsg2, ResponseCode.INTERNAL_ERROR); // Close. closeChannel(); receiver.checkExpectationsSatisfied(); }
/** * Tests that the delta channel detects a gap in the op stream and * throws an exception. */ public void testMissingDeltaKillsChannel() throws ChannelException { final long initialVersion = 57; final byte[] signature = sig(1); final int ops = 7; final TransformedWaveletDelta delta1 = buildServerDelta(initialVersion, ops); checkedConnectChannel(initialVersion); // Receive and deliver delta. receiver.expectCommit(initialVersion); receiver.expectDelta(delta1); receiveUpdateOnConnectedChannel(delta1, initialVersion, signature); // Receive delta with a version number too high. final TransformedWaveletDelta delta2 = buildServerDelta(initialVersion + ops + 1, 1); try { receiveUpdateOnConnectedChannel(delta2, initialVersion, signature); fail("Expected a ChannelException"); } catch (ChannelException expected) { } receiver.checkExpectationsSatisfied(); }
/** * Connects the channel and checks expectations. * * @param currentVersion version at which to connect. */ private void checkedConnectChannel(long currentVersion) throws ChannelException { byte[] signature = sig(currentVersion); final HashedVersion signedVersion = HashedVersion.of(currentVersion, sig(currentVersion)); final ObservableWaveletData wavelet = buildSnapshot(currentVersion, signature); receiver.expectConnection(signedVersion, signedVersion); receiver.expectCommit(currentVersion); connectChannel(wavelet); receiver.checkExpectationsSatisfied(); }
/** * Tests that the last committed version sent with a reconnect initial delta is * delivered. */ public void testReconnectReceivesCommittedVersion() throws ChannelException { final long currentVersion = 57; final byte[] signature = sig(1); final long committedVersion = 50; final byte[] committedSignature = sig(2); final HashedVersion signedVersion = HashedVersion.of(currentVersion, signature); final List<TransformedWaveletDelta> reconnect = buildReconnect(currentVersion, signature); // Expect connection. receiver.expectConnection(signedVersion, signedVersion); receiver.expectCommit(committedVersion); reconnectChannel(reconnect, committedVersion, committedSignature); receiver.checkExpectationsSatisfied(); }
/** * Sends a delta on a connected channel. * @param delta1 the delta to send */ private void submitDeltaOnConnectedChannel(final WaveletDelta delta1) { waveletChannel.expectSubmit(delta1); sendState = "initial"; sendDelta(delta1); assertEquals("sending", sendState); }
/** * Tests that when the client terminates the channel the receiver * is not notified. */ public void testClientResetTerminatesSilently() throws ChannelException { checkedConnectChannel(57); deltaChannel.reset(null); receiver.checkExpectationsSatisfied(); }
/** * Connects the channel by sending an initial message with a wavelet snapshot. * The committed version is synthesized to match the snapshot version. * * @param wave initial wavelet snapshot */ private void connectChannel(ObservableWaveletData wave) throws ChannelException { connectChannel(wave, wave.getVersion(), wave.getHashedVersion().getHistoryHash()); }
final long initialVersion = 57; final int serverOps1 = 7; checkedConnectChannel(initialVersion); final WaveletDelta clientDelta = buildDelta(initialVersion, clientOps); submitDeltaOnConnectedChannel(clientDelta); final byte[] ackedSignature = sig(1); ackDeltaOnConnectedChannel(versionAfterClient, clientOps, ackedSignature); final TransformedWaveletDelta delta1 = buildServerDelta(initialVersion, serverOps1); receiver.expectDelta(delta1); receiver.expectAck(clientOps, HashedVersion.of(versionAfterClient, ackedSignature)); receiveUpdateOnConnectedChannel(delta1); final TransformedWaveletDelta delta2 = buildServerDelta(versionAfterClient, serverOps2); receiver.expectDelta(delta2); receiveUpdateOnConnectedChannel(delta2); closeChannel(); receiver.checkExpectationsSatisfied();
final long initialVersion = 57; final int serverOps1 = 7; checkedConnectChannel(initialVersion); final TransformedWaveletDelta delta1 = buildServerDelta(initialVersion, serverOps1); receiver.expectDelta(delta1); receiveUpdateOnConnectedChannel(delta1); final int sigAfterServer1 = 0x11111111; final int clientOps = 5; final WaveletDelta clientDelta = buildDelta(versionAfterServer1, clientOps); submitDeltaOnConnectedChannel(clientDelta); final int sigAfterClient = 0x22222222; final int serverOps2 = 3; final TransformedWaveletDelta delta2 = buildServerDelta(versionAfterClient, serverOps2); receiveUpdateOnConnectedChannel(delta2); final TransformedWaveletDelta delta3 = buildServerDelta(versionAfterServer2 + 1, 1); receiveUpdateOnConnectedChannel(delta3); fail("Expected a ChannelException"); } catch (ChannelException expected) {
/** * Tests that a last-committed-version message with no deltas is correctly * delivered. */ public void testReceiveLastCommittedVersion() throws ChannelException { final long initialVersion = 57; final long committedVersion = 50; final byte[] committedSignature = sig(1); checkedConnectChannel(initialVersion); receiver.expectCommit(committedVersion); receiveUpdateOnConnectedChannel(null, committedVersion, committedSignature); // Close. closeChannel(); receiver.checkExpectationsSatisfied(); }
/** * Tests that a delta sent down the channel is received and the acknowledgment * delivered. */ public void testSubmitDelta() throws ChannelException { final long currentVersion = 57; final int ops1 = 7; final WaveletDelta delta1 = buildDelta(currentVersion, ops1); final byte[] signature1 = sig(1); final WaveletDelta delta2 = buildDelta(currentVersion + ops1, 2); final int opsCommitted = 3; final String errorMsg2 = "SERVER_ERROR"; checkedConnectChannel(currentVersion); // Send delta1. submitDeltaOnConnectedChannel(delta1); // All ops are acked. receiver.expectAck(ops1, HashedVersion.of(currentVersion + ops1, signature1)); ackDeltaOnConnectedChannel(currentVersion + ops1, ops1, signature1); // Send delta2. submitDeltaOnConnectedChannel(delta2); // Nack with a randomly injected error, as if something just went wrong // server-side. receiver.expectNack(errorMsg2, currentVersion + ops1); nackDeltaOnConnectedChannel(currentVersion + ops1, signature1, errorMsg2, ResponseCode.INTERNAL_ERROR); // Close. closeChannel(); receiver.checkExpectationsSatisfied(); }
/** * Tests that a channel with no receivers quietly drops messages. */ public void testChannelWithNoReceiverDropsMessages() throws ChannelException { final long initialVersion = 57; final byte[] signature = sig(1); final ObservableWaveletData wavelet = buildSnapshot(initialVersion, signature); final TransformedWaveletDelta delta = buildServerDelta(initialVersion, 3); deltaChannel.reset(null); // Clear receiver. connectChannel(wavelet); receiveUpdateOnConnectedChannel(delta, initialVersion, signature); receiver.checkExpectationsSatisfied(); }