Android Open Source - couchbase-lite-android Revisions Test






From Project

Back to project page couchbase-lite-android.

License

The source code is released under:

Apache License

If you think the Android project couchbase-lite-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.couchbase.lite;
//from   ww  w  . j a v  a  2s  .co m
import com.couchbase.lite.internal.RevisionInternal;
import com.couchbase.lite.util.Log;

import junit.framework.Assert;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class RevisionsTest extends LiteTestCase {

    public void testParseRevID() {
        int num;
        String suffix;

        num = Database.parseRevIDNumber("1-utiopturoewpt");
        Assert.assertEquals(1, num);
        suffix = Database.parseRevIDSuffix("1-utiopturoewpt");
        Assert.assertEquals("utiopturoewpt", suffix);

        num = Database.parseRevIDNumber("321-fdjfdsj-e");
        Assert.assertEquals(321, num);
        suffix = Database.parseRevIDSuffix("321-fdjfdsj-e");
        Assert.assertEquals("fdjfdsj-e", suffix);

        num = Database.parseRevIDNumber("0-fdjfdsj-e");
        suffix = Database.parseRevIDSuffix("0-fdjfdsj-e");
        Assert.assertTrue(num == 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("-4-fdjfdsj-e");
        suffix = Database.parseRevIDSuffix("-4-fdjfdsj-e");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("5_fdjfdsj-e");
        suffix = Database.parseRevIDSuffix("5_fdjfdsj-e");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber(" 5-fdjfdsj-e");
        suffix = Database.parseRevIDSuffix(" 5-fdjfdsj-e");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("7 -foo");
        suffix = Database.parseRevIDSuffix("7 -foo");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("7-");
        suffix = Database.parseRevIDSuffix("7-");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("7");
        suffix = Database.parseRevIDSuffix("7");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("eiuwtiu");
        suffix = Database.parseRevIDSuffix("eiuwtiu");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
        num = Database.parseRevIDNumber("");
        suffix = Database.parseRevIDSuffix("");
        Assert.assertTrue(num < 0 || (suffix.length() == 0));
    }

    public void testCBLCompareRevIDs() {

        // Single Digit
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("1-foo", "1-foo") == 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("2-bar", "1-foo") > 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("1-foo", "2-bar") < 0);

        // Multi-digit:
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("123-bar", "456-foo") < 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("456-foo", "123-bar") > 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("456-foo", "456-foo") == 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("456-foo", "456-foofoo") < 0);

        // Different numbers of digits:
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("89-foo", "123-bar") < 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("123-bar", "89-foo") > 0);

        // Edge cases:
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("123-", "89-") > 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("123-a", "123-a") == 0);

        // Invalid rev IDs:
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("-a", "-b") < 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("-", "-") == 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("", "") == 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("", "-b") < 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("bogus", "yo") < 0);
        Assert.assertTrue(RevisionInternal.CBLCollateRevIDs("bogus-x", "yo-y") < 0);

    }

    public void testMakeRevisionHistoryDict() {
        List<RevisionInternal> revs = new ArrayList<RevisionInternal>();
        revs.add(mkrev("4-jkl"));
        revs.add(mkrev("3-ghi"));
        revs.add(mkrev("2-def"));

        List<String> expectedSuffixes = new ArrayList<String>();
        expectedSuffixes.add("jkl");
        expectedSuffixes.add("ghi");
        expectedSuffixes.add("def");
        Map<String,Object> expectedHistoryDict = new HashMap<String,Object>();
        expectedHistoryDict.put("start", 4);
        expectedHistoryDict.put("ids", expectedSuffixes);

        Map<String,Object> historyDict = Database.makeRevisionHistoryDict(revs);
        Assert.assertEquals(expectedHistoryDict, historyDict);


        revs = new ArrayList<RevisionInternal>();
        revs.add(mkrev("4-jkl"));
        revs.add(mkrev("2-def"));

        expectedSuffixes = new ArrayList<String>();
        expectedSuffixes.add("4-jkl");
        expectedSuffixes.add("2-def");
        expectedHistoryDict = new HashMap<String,Object>();
        expectedHistoryDict.put("ids", expectedSuffixes);

        historyDict = Database.makeRevisionHistoryDict(revs);
        Assert.assertEquals(expectedHistoryDict, historyDict);


        revs = new ArrayList<RevisionInternal>();
        revs.add(mkrev("12345"));
        revs.add(mkrev("6789"));

        expectedSuffixes = new ArrayList<String>();
        expectedSuffixes.add("12345");
        expectedSuffixes.add("6789");
        expectedHistoryDict = new HashMap<String,Object>();
        expectedHistoryDict.put("ids", expectedSuffixes);

        historyDict = Database.makeRevisionHistoryDict(revs);
        Assert.assertEquals(expectedHistoryDict, historyDict);

    }

    /**
     * https://github.com/couchbase/couchbase-lite-java-core/issues/164
     */
    public void testRevisionIdDifferentRevisions() throws Exception {

        // two revisions with different json should have different rev-id's
        // because their content will have a different hash (even though
        // they have the same generation number)

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("testName", "testCreateRevisions");
        properties.put("tag", 1337);

        Document doc = database.createDocument();
        UnsavedRevision newRev = doc.createRevision();
        newRev.setUserProperties(properties);
        SavedRevision rev1 = newRev.save();

        SavedRevision rev2a = createRevisionWithRandomProps(rev1, false);

        SavedRevision rev2b = createRevisionWithRandomProps(rev1, true);

        assertNotSame(rev2a.getId(), rev2b.getId());


    }

    /**
     * https://github.com/couchbase/couchbase-lite-java-core/issues/164
     */
    public void testRevisionIdEquivalentRevisions() throws Exception {

        // two revisions with the same content and the same json
        // should have the exact same revision id, because their content
        // will have an identical hash

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("testName", "testCreateRevisions");
        properties.put("tag", 1337);

        Map<String, Object> properties2 = new HashMap<String, Object>();
        properties2.put("testName", "testCreateRevisions");
        properties2.put("tag", 1338);

        Document doc = database.createDocument();
        UnsavedRevision newRev = doc.createRevision();
        newRev.setUserProperties(properties);
        SavedRevision rev1 = newRev.save();

        UnsavedRevision newRev2a = rev1.createRevision();
        newRev2a.setUserProperties(properties2);
        SavedRevision rev2a = newRev2a.save();

        UnsavedRevision newRev2b = rev1.createRevision();
        newRev2b.setUserProperties(properties2);
        SavedRevision rev2b = newRev2b.save(true);

        assertEquals(rev2a.getId(), rev2b.getId());

    }

    /**
     * https://github.com/couchbase/couchbase-lite-java-core/issues/106
     */
    public void testResolveConflict() throws Exception {

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("testName", "testCreateRevisions");
        properties.put("tag", 1337);

        // Create a conflict on purpose
        Document doc = database.createDocument();

        UnsavedRevision newRev1 = doc.createRevision();
        newRev1.setUserProperties(properties);
        SavedRevision rev1 = newRev1.save();

        SavedRevision rev2a = createRevisionWithRandomProps(rev1, false);
        SavedRevision rev2b = createRevisionWithRandomProps(rev1, true);

        SavedRevision winningRev = null;
        SavedRevision losingRev = null;
        if (doc.getCurrentRevisionId().equals(rev2a.getId())) {
            winningRev = rev2a;
            losingRev = rev2b;
        } else {
            winningRev = rev2b;
            losingRev = rev2a;
        }

        assertEquals(2,doc.getConflictingRevisions().size());
        assertEquals(2, doc.getLeafRevisions().size());

        // let's manually choose the losing rev as the winner.  First, delete winner, which will
        // cause losing rev to be the current revision.
        SavedRevision deleteRevision = winningRev.deleteDocument();

        List<SavedRevision> conflictingRevisions = doc.getConflictingRevisions();
        assertEquals(1, conflictingRevisions.size());
        assertEquals(2, doc.getLeafRevisions().size());

        assertEquals(3, deleteRevision.getGeneration());
        assertEquals(losingRev.getId(), doc.getCurrentRevision().getId());

        // Finally create a new revision rev3 based on losing rev
        SavedRevision rev3 = createRevisionWithRandomProps(losingRev, true);

        assertEquals(rev3.getId(), doc.getCurrentRevisionId());

        List<SavedRevision> conflictingRevisions1 = doc.getConflictingRevisions();
        assertEquals(1, conflictingRevisions1.size());
        assertEquals(2, doc.getLeafRevisions().size());

    }

    public void testCorrectWinningRevisionTiebreaker() throws Exception {

        // Create a conflict on purpose
        Document doc = database.createDocument();
        SavedRevision rev1 = doc.createRevision().save();
        SavedRevision rev2a = createRevisionWithRandomProps(rev1, false);
        SavedRevision rev2b = createRevisionWithRandomProps(rev1, true);

        // the tiebreaker will happen based on which rev hash has lexicographically higher sort order
        SavedRevision expectedWinner = null;
        if (rev2a.getId().compareTo(rev2b.getId()) > 0) {
            expectedWinner = rev2a;
        } else if (rev2a.getId().compareTo(rev2b.getId()) < 0) {
            expectedWinner = rev2b;
        }

        RevisionInternal revFound = database.getDocumentWithIDAndRev(doc.getId(), null, EnumSet.noneOf(Database.TDContentOptions.class));
        assertEquals(expectedWinner.getId(), revFound.getRevId());

    }

    public void testCorrectWinningRevisionLongerBranch() throws Exception {

        // Create a conflict on purpose
        Document doc = database.createDocument();
        SavedRevision rev1 = doc.createRevision().save();
        SavedRevision rev2a = createRevisionWithRandomProps(rev1, false);
        SavedRevision rev2b = createRevisionWithRandomProps(rev1, true);
        SavedRevision rev3b = createRevisionWithRandomProps(rev2b, true);

        // rev3b should be picked as the winner since it has a longer branch
        SavedRevision expectedWinner = rev3b;

        RevisionInternal revFound = database.getDocumentWithIDAndRev(doc.getId(), null, EnumSet.noneOf(Database.TDContentOptions.class));
        assertEquals(expectedWinner.getId(), revFound.getRevId());

    }

    /**
     * https://github.com/couchbase/couchbase-lite-java-core/issues/135
     */
    public void testCorrectWinningRevisionHighRevisionNumber() throws Exception {

        // Create a conflict on purpose
        Document doc = database.createDocument();
        SavedRevision rev1 = doc.createRevision().save();
        SavedRevision rev2a = createRevisionWithRandomProps(rev1, false);
        SavedRevision rev2b = createRevisionWithRandomProps(rev1, true);
        SavedRevision rev3b = createRevisionWithRandomProps(rev2b, true);
        SavedRevision rev4b = createRevisionWithRandomProps(rev3b, true);
        SavedRevision rev5b = createRevisionWithRandomProps(rev4b, true);
        SavedRevision rev6b = createRevisionWithRandomProps(rev5b, true);
        SavedRevision rev7b = createRevisionWithRandomProps(rev6b, true);
        SavedRevision rev8b = createRevisionWithRandomProps(rev7b, true);
        SavedRevision rev9b = createRevisionWithRandomProps(rev8b, true);
        SavedRevision rev10b = createRevisionWithRandomProps(rev9b, true);

        RevisionInternal revFound = database.getDocumentWithIDAndRev(doc.getId(), null, EnumSet.noneOf(Database.TDContentOptions.class));
        assertEquals(rev10b.getId(), revFound.getRevId());

    }



    public void testDocumentChangeListener() throws Exception {

        Document doc = database.createDocument();
        final CountDownLatch documentChanged = new CountDownLatch(1);
        doc.addChangeListener(new Document.ChangeListener() {
            @Override
            public void changed(Document.ChangeEvent event) {
                DocumentChange docChange = event.getChange();
                String msg = "New revision added: %s.  Conflict: %s";
                msg = String.format(msg, docChange.getAddedRevision(), docChange.isConflict());
                Log.d(TAG, msg);
                documentChanged.countDown();
            }
        });
        doc.createRevision().save();
        boolean success = documentChanged.await(30, TimeUnit.SECONDS);
        assertTrue(success);

    }

    private static RevisionInternal mkrev(String revID) {
        return new RevisionInternal("docid", revID, false, null);
    }

}




Java Source Code List

com.couchbase.lite.ApiTest.java
com.couchbase.lite.AttachmentsTest.java
com.couchbase.lite.AuthTest.java
com.couchbase.lite.Base64Test.java
com.couchbase.lite.BlobStoreWriterTest.java
com.couchbase.lite.CRUDOperationsTest.java
com.couchbase.lite.CacheTest.java
com.couchbase.lite.ChangesTest.java
com.couchbase.lite.CollationTest.java
com.couchbase.lite.DatabaseTest.java
com.couchbase.lite.DocumentTest.java
com.couchbase.lite.LitePerfTestCase.java
com.couchbase.lite.LiteTestCase.java
com.couchbase.lite.LiteTestContext.java
com.couchbase.lite.LocalDocsTest.java
com.couchbase.lite.ManagerTest.java
com.couchbase.lite.MiscTest.java
com.couchbase.lite.MultipartReaderTest.java
com.couchbase.lite.RevTreeTest.java
com.couchbase.lite.RevisionsTest.java
com.couchbase.lite.RouterTest.java
com.couchbase.lite.SequenceMapTest.java
com.couchbase.lite.ValidationsTest.java
com.couchbase.lite.ViewsTest.java
com.couchbase.lite.android.AndroidContext.java
com.couchbase.lite.android.AndroidLogger.java
com.couchbase.lite.android.AndroidNetworkReachabilityManager.java
com.couchbase.lite.android.AndroidSQLiteStorageEngineFactory.java
com.couchbase.lite.android.AndroidSQLiteStorageEngine.java
com.couchbase.lite.mockserver.MockBulkDocs.java
com.couchbase.lite.mockserver.MockChangesFeedNoResponse.java
com.couchbase.lite.mockserver.MockChangesFeed.java
com.couchbase.lite.mockserver.MockCheckpointGet.java
com.couchbase.lite.mockserver.MockCheckpointPut.java
com.couchbase.lite.mockserver.MockDispatcher.java
com.couchbase.lite.mockserver.MockDocumentBulkGet.java
com.couchbase.lite.mockserver.MockDocumentGet.java
com.couchbase.lite.mockserver.MockDocumentPut.java
com.couchbase.lite.mockserver.MockFacebookAuthPost.java
com.couchbase.lite.mockserver.MockHelper.java
com.couchbase.lite.mockserver.MockPreloadedPullTarget.java
com.couchbase.lite.mockserver.MockRevsDiff.java
com.couchbase.lite.mockserver.MockSessionGet.java
com.couchbase.lite.mockserver.SmartMockResponse.java
com.couchbase.lite.mockserver.WrappedSmartMockResponse.java
com.couchbase.lite.performance2.Test01_CreateDocs.java
com.couchbase.lite.performance2.Test02_CreateDocsUnoptimizedWay.java
com.couchbase.lite.performance2.Test03_CreateDocsWithAttachments.java
com.couchbase.lite.performance2.Test06_PullReplication.java
com.couchbase.lite.performance2.Test07_PushReplication.java
com.couchbase.lite.performance2.Test08_DocRevisions.java
com.couchbase.lite.performance2.Test09_LoadDB.java
com.couchbase.lite.performance2.Test10_DeleteDB.java
com.couchbase.lite.performance2.Test11_DeleteDocs.java
com.couchbase.lite.performance2.Test12_IndexView.java
com.couchbase.lite.performance2.Test13_QueryView.java
com.couchbase.lite.performance2.Test14_ReduceView.java
com.couchbase.lite.performance2.Test28_KeySizes.java
com.couchbase.lite.performance2.Test29_AllDocQuery.java
com.couchbase.lite.performance2.Test30_LiveQuery.java
com.couchbase.lite.performance2.Test31_CompactDB.java
com.couchbase.lite.performance.Test10_DeleteDB.java
com.couchbase.lite.performance.Test11_DeleteDocs.java
com.couchbase.lite.performance.Test12_IndexView.java
com.couchbase.lite.performance.Test13_QueryView.java
com.couchbase.lite.performance.Test14_ReduceView.java
com.couchbase.lite.performance.Test16_ParallelPushReplication.java
com.couchbase.lite.performance.Test1_CreateDocs.java
com.couchbase.lite.performance.Test2_CreateDocsUnoptimizedWay.java
com.couchbase.lite.performance.Test3_CreateDocsWithAttachments.java
com.couchbase.lite.performance.Test6_PushReplication.java
com.couchbase.lite.performance.Test7_PullReplication.java
com.couchbase.lite.performance.Test8_DocRevisions.java
com.couchbase.lite.performance.Test9_LoadDB.java
com.couchbase.lite.replicator.BulkDownloaderTest.java
com.couchbase.lite.replicator.ChangeTrackerTest.java
com.couchbase.lite.replicator.CustomizableMockHttpClient.java
com.couchbase.lite.replicator.ReplicationTest.java
com.couchbase.lite.replicator.ResponderChain.java
com.couchbase.lite.support.BatcherTest.java
com.couchbase.lite.support.JsonDocumentTest.java
com.couchbase.lite.support.PersistentCookieStoreTest.java
com.couchbase.lite.support.RemoteRequestTest.java
com.couchbase.touchdb.RevCollator.java
com.couchbase.touchdb.TDCollateJSON.java