/** * Copyright 2010 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.waveprotocol.box.server.waveserver; import static org.mockito.Mockito.mock; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.ByteString; import junit.framework.TestCase; import org.waveprotocol.box.server.common.CoreWaveletOperationSerializer; import org.waveprotocol.box.server.persistence.memory.MemoryDeltaStore; import org.waveprotocol.wave.federation.Proto.ProtocolDocumentOperation; import org.waveprotocol.wave.federation.Proto.ProtocolSignature; import org.waveprotocol.wave.federation.Proto.ProtocolSignature.SignatureAlgorithm; import org.waveprotocol.wave.federation.Proto.ProtocolSignedDelta; import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta; import org.waveprotocol.wave.federation.Proto.ProtocolWaveletOperation; import org.waveprotocol.wave.federation.Proto.ProtocolWaveletOperation.MutateDocument; import org.waveprotocol.wave.model.id.IdURIEncoderDecoder; import org.waveprotocol.wave.model.id.WaveletName; import org.waveprotocol.wave.model.version.HashedVersion; import org.waveprotocol.wave.model.version.HashedVersionFactory; import org.waveprotocol.wave.model.version.HashedVersionFactoryImpl; import org.waveprotocol.wave.util.escapers.jvm.JavaUrlCodec; import java.util.concurrent.Executor; /** * Tests for LocalWaveletContainerImpl. * * @author arb@google.com (Anthony Baxter) */ public class LocalWaveletContainerImplTest extends TestCase { private static final IdURIEncoderDecoder URI_CODEC = new IdURIEncoderDecoder(new JavaUrlCodec()); private static final HashedVersionFactory HASH_FACTORY = new HashedVersionFactoryImpl(URI_CODEC); private static final Executor PERSIST_EXECUTOR = MoreExecutors.sameThreadExecutor(); private static final WaveletName WAVELET_NAME = WaveletName.of("a", "a", "b", "b"); private static final ProtocolSignature SIGNATURE = ProtocolSignature.newBuilder() .setSignatureAlgorithm(SignatureAlgorithm.SHA1_RSA) .setSignatureBytes(ByteString.EMPTY) .setSignerId(ByteString.EMPTY) .build(); private static final String AUTHOR = "kermit@muppetshow.com"; private static final HashedVersion HASHED_VERSION_ZERO = HASH_FACTORY.createVersionZero(WAVELET_NAME); private ProtocolWaveletOperation addParticipantOp; private static final String BLIP_ID = "b+muppet"; private ProtocolWaveletOperation addBlipOp; private LocalWaveletContainerImpl wavelet; @Override protected void setUp() throws Exception { super.setUp(); addParticipantOp = ProtocolWaveletOperation.newBuilder() .setAddParticipant(AUTHOR) .build(); // An empty blip operation - creates a new document. addBlipOp = ProtocolWaveletOperation.newBuilder().setMutateDocument( MutateDocument.newBuilder().setDocumentId(BLIP_ID).setDocumentOperation( ProtocolDocumentOperation.newBuilder().build())).build(); WaveletNotificationSubscriber notifiee = mock(WaveletNotificationSubscriber.class); DeltaStore deltaStore = new MemoryDeltaStore(); WaveletState waveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(WAVELET_NAME), PERSIST_EXECUTOR); wavelet = new LocalWaveletContainerImpl(WAVELET_NAME, notifiee, Futures.immediateFuture(waveletState), null); wavelet.awaitLoad(); } @Override protected void tearDown() throws Exception { super.tearDown(); } /** * Tests that duplicate operations are a no-op. * * @throws Exception should not be thrown. */ public void testDuplicateOperations() throws Exception { assertEquals(0L, wavelet.getCurrentVersion().getVersion()); // create the wavelet. WaveletDeltaRecord v0Response = wavelet.submitRequest( WAVELET_NAME, createProtocolSignedDelta(addParticipantOp, HASHED_VERSION_ZERO)); assertEquals(1L, wavelet.getCurrentVersion().getVersion()); ProtocolSignedDelta psd = createProtocolSignedDelta( addBlipOp, v0Response.getResultingVersion()); WaveletDeltaRecord dar1 = wavelet.submitRequest(WAVELET_NAME, psd); assertEquals(2L, wavelet.getCurrentVersion().getVersion()); WaveletDeltaRecord dar2 = wavelet.submitRequest(WAVELET_NAME, psd); assertEquals(2L, wavelet.getCurrentVersion().getVersion()); assertEquals(dar1.getResultingVersion(), dar2.getResultingVersion()); } private ProtocolSignedDelta createProtocolSignedDelta(ProtocolWaveletOperation operation, HashedVersion protocolHashedVersion) { ProtocolWaveletDelta delta = ProtocolWaveletDelta.newBuilder() .setAuthor(AUTHOR) .setHashedVersion(CoreWaveletOperationSerializer.serialize(protocolHashedVersion)) .addOperation(operation) .build(); return ProtocolSignedDelta.newBuilder() .setDelta(delta.toByteString()) .addSignature(SIGNATURE) .build(); } }