Package org.waveprotocol.box.server.persistence

Source Code of org.waveprotocol.box.server.persistence.DeltaStoreTestBase

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.persistence;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.protobuf.ByteString;

import junit.framework.TestCase;

import org.waveprotocol.box.common.ExceptionalIterator;
import org.waveprotocol.box.server.common.CoreWaveletOperationSerializer;
import org.waveprotocol.box.server.util.testing.TestingConstants;
import org.waveprotocol.box.server.waveserver.ByteStringMessage;
import org.waveprotocol.box.server.waveserver.DeltaStore;
import org.waveprotocol.box.server.waveserver.WaveletDeltaRecord;
import org.waveprotocol.box.server.waveserver.DeltaStore.DeltasAccess;
import org.waveprotocol.wave.federation.Proto.ProtocolAppliedWaveletDelta;
import org.waveprotocol.wave.federation.Proto.ProtocolSignature;
import org.waveprotocol.wave.federation.Proto.ProtocolSignedDelta;
import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta;
import org.waveprotocol.wave.federation.Proto.ProtocolSignature.SignatureAlgorithm;
import org.waveprotocol.wave.model.id.WaveId;
import org.waveprotocol.wave.model.id.WaveletId;
import org.waveprotocol.wave.model.id.WaveletName;
import org.waveprotocol.wave.model.operation.wave.TransformedWaveletDelta;
import org.waveprotocol.wave.model.operation.wave.WaveletOperation;
import org.waveprotocol.wave.model.testing.DeltaTestUtil;
import org.waveprotocol.wave.model.util.Pair;
import org.waveprotocol.wave.model.version.HashedVersion;

import java.util.List;
import java.util.NoSuchElementException;

/**
* Tests for all DeltaStore implementations.
*
* @author Joseph Gentle (josephg@gmail.com)
*/
public abstract class DeltaStoreTestBase extends TestCase {
  private final WaveletName WAVE1_WAVELET1 =
    WaveletName.of(WaveId.of("example.com", "wave1"), WaveletId.of("example.com", "wavelet1"));
  private final WaveletName WAVE2_WAVELET1 =
    WaveletName.of(WaveId.of("example.com", "wave2"), WaveletId.of("example.com", "wavelet1"));
  private final DeltaTestUtil UTIL = new DeltaTestUtil(TestingConstants.PARTICIPANT);


  /** Create and return a new delta store instance of the type being tested. */
  protected abstract DeltaStore newDeltaStore() throws Exception;

  public void testOpenNonexistantWavelet() throws Exception {
    DeltaStore store = newDeltaStore();
    DeltasAccess wavelet = store.open(WAVE1_WAVELET1);

    // Sanity check a bunch of values in the wavelet.
    assertTrue(wavelet.isEmpty());
    assertEquals(WAVE1_WAVELET1, wavelet.getWaveletName());
    assertNull(wavelet.getEndVersion());
    assertNull(wavelet.getDelta(0));
    assertNull(wavelet.getDeltaByEndVersion(0));
    assertNull(wavelet.getAppliedAtVersion(0));
    assertNull(wavelet.getResultingVersion(0));
    assertNull(wavelet.getAppliedDelta(0));
    assertNull(wavelet.getTransformedDelta(0));

    wavelet.close();
  }

  public void testWriteToNewWavelet() throws Exception {
    Pair<DeltaStore,WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;
    WaveletDeltaRecord record = pair.second;

    DeltasAccess wavelet = store.open(WAVE1_WAVELET1);

    assertFalse(wavelet.isEmpty());
    assertEquals(WAVE1_WAVELET1, wavelet.getWaveletName());
    assertEquals(record.getResultingVersion(), wavelet.getEndVersion());
    assertEquals(record, wavelet.getDelta(0));
    assertEquals(record, wavelet.getDeltaByEndVersion(record.getResultingVersion().getVersion()));
    assertEquals(record.getAppliedAtVersion(), wavelet.getAppliedAtVersion(0));
    assertEquals(record.getAppliedDelta(), wavelet.getAppliedDelta(0));
    assertEquals(record.getTransformedDelta(), wavelet.getTransformedDelta(0));

    wavelet.close();
  }

  public void testDeleteWaveletRemovesDeltas() throws Exception {
    Pair<DeltaStore, WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;

    store.delete(WAVE1_WAVELET1);
    DeltasAccess wavelet = store.open(WAVE1_WAVELET1);
    assertTrue(wavelet.isEmpty());
    wavelet.close();
  }

  public void testLookupReturnsWavelets() throws Exception {
    Pair<DeltaStore,WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;

    assertEquals(ImmutableSet.of(WAVE1_WAVELET1.waveletId), store.lookup(WAVE1_WAVELET1.waveId));
  }

  public void testLookupDoesNotReturnEmptyWavelets() throws Exception {
    DeltaStore store = newDeltaStore();
    DeltasAccess wavelet = store.open(WAVE1_WAVELET1);
    wavelet.close();

    assertTrue(store.lookup(WAVE1_WAVELET1.waveId).isEmpty());
  }

  public void testLookupDoesNotReturnDeletedWavelets() throws Exception {
    Pair<DeltaStore, WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;
    store.delete(WAVE1_WAVELET1);

    assertTrue(store.lookup(WAVE1_WAVELET1.waveId).isEmpty());
  }

  public void testWaveIdIteratorReturnsWaveIds() throws Exception {
    Pair<DeltaStore,WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;

    ImmutableSet<WaveId> waveIds = setFromExceptionalIterator(store.getWaveIdIterator());

    assertEquals(ImmutableSet.of(WAVE1_WAVELET1.waveId), waveIds);
  }

  public void testWaveIdIteratorDoesNotReturnEmptyWavelets() throws Exception {
    DeltaStore store = newDeltaStore();
    DeltasAccess wavelet = store.open(WAVE1_WAVELET1);
    wavelet.close();

    assertFalse(store.getWaveIdIterator().hasNext());
  }

  public void testWaveIdIteratorDoesNotReturnDeletedWavelets() throws Exception {
    Pair<DeltaStore, WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;
    store.delete(WAVE1_WAVELET1);

    assertFalse(store.getWaveIdIterator().hasNext());
  }

  public void testWaveIdIteratorLimits() throws Exception {
    Pair<DeltaStore,WaveletDeltaRecord> pair = newDeltaStoreWithRecord(WAVE1_WAVELET1);
    DeltaStore store = pair.first;

    DeltasAccess wavelet = store.open(WAVE2_WAVELET1);

    WaveletDeltaRecord record = createRecord();
    wavelet.append(ImmutableList.of(record));
    wavelet.close();

    ExceptionalIterator<WaveId, PersistenceException> iterator = store.getWaveIdIterator();
    assertTrue(iterator.hasNext());

    WaveId waveId1 = iterator.next();
    assertTrue(iterator.hasNext());

    WaveId waveId2 = iterator.next();

    // This is necessary because the order of waveIds is implementation specific.
    if (WAVE1_WAVELET1.waveId.equals(waveId1)) {
      assertEquals(WAVE2_WAVELET1.waveId, waveId2);
    } else {
      assertEquals(WAVE2_WAVELET1.waveId, waveId1);
      assertEquals(WAVE1_WAVELET1.waveId, waveId2);
    }

    assertFalse(iterator.hasNext());
    try {
      waveId1 = iterator.next();
      // Fail the test, it should have thrown an exception.
      fail();
    } catch (NoSuchElementException e) {
      // Test passes.
    }
  }

  // *** Helpers

  protected WaveletDeltaRecord createRecord() {
    HashedVersion targetVersion = HashedVersion.of(0, new byte[] {3, 2, 1});
    HashedVersion resultingVersion = HashedVersion.of(2, new byte[] {1, 2, 3});

    List<WaveletOperation> ops =
        ImmutableList.of(UTIL.noOp(), UTIL.addParticipant(TestingConstants.OTHER_PARTICIPANT));
    TransformedWaveletDelta transformed = TransformedWaveletDelta.cloneOperations(
        TestingConstants.PARTICIPANT, resultingVersion, 1234567890, ops);

    ProtocolWaveletDelta serializedDelta = CoreWaveletOperationSerializer.serialize(transformed);

    ProtocolSignature signature =
        ProtocolSignature.newBuilder().setSignatureAlgorithm(SignatureAlgorithm.SHA1_RSA)
            .setSignatureBytes(ByteString.copyFrom(new byte[] {1, 2, 3})).setSignerId(
                ByteString.copyFromUtf8("somebody")).build();
    ProtocolSignedDelta signedDelta =
        ProtocolSignedDelta.newBuilder().setDelta(
            ByteStringMessage.serializeMessage(serializedDelta).getByteString()).addAllSignature(
            ImmutableList.of(signature)).build();

    ProtocolAppliedWaveletDelta delta =
        ProtocolAppliedWaveletDelta.newBuilder().setApplicationTimestamp(1234567890)
            .setHashedVersionAppliedAt(CoreWaveletOperationSerializer.serialize(targetVersion))
            .setSignedOriginalDelta(signedDelta).setOperationsApplied(2).build();

    return new WaveletDeltaRecord(targetVersion, ByteStringMessage.serializeMessage(delta),
        transformed);
  }

  private Pair<DeltaStore, WaveletDeltaRecord> newDeltaStoreWithRecord(WaveletName waveletName)
      throws Exception {
    DeltaStore store = newDeltaStore();
    DeltasAccess wavelet = store.open(waveletName);

    WaveletDeltaRecord record = createRecord();
    wavelet.append(ImmutableList.of(record));
    wavelet.close();

    return new Pair<DeltaStore, WaveletDeltaRecord>(store, record);
  }

  private static <T, E extends Exception> ImmutableSet<T> setFromExceptionalIterator(
      ExceptionalIterator<T, E> iterator) throws E {
    ImmutableSet.Builder<T> builder = ImmutableSet.builder();
    while(iterator.hasNext()) {
      builder.add(iterator.next());
    }
    return builder.build();
  }
}
TOP

Related Classes of org.waveprotocol.box.server.persistence.DeltaStoreTestBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.