diff --git a/rest/access_test.go b/rest/access_test.go index d8a24803e9..4e961001e6 100644 --- a/rest/access_test.go +++ b/rest/access_test.go @@ -1144,7 +1144,7 @@ func TestAllDocsCV(t *testing.T) { defer rt.Close() const docID = "foo" - docVersion := rt.PutDocDirectly(docID, db.Body{"foo": "bar"}) + docVersion := rt.PutDoc(docID, `{"foo": "bar"}`) testCases := []struct { name string diff --git a/rest/api_test.go b/rest/api_test.go index bfbe5f6a56..80fbe728ee 100644 --- a/rest/api_test.go +++ b/rest/api_test.go @@ -2870,7 +2870,7 @@ func TestPvDeltaReadAndWrite(t *testing.T) { version1, _ := rt.GetDoc(docID) // update the above doc, this should push CV to PV and adds a new CV - version2 := rt.UpdateDocDirectly(docID, version1, db.Body{"new": "update!"}) + version2 := rt.UpdateDoc(docID, version1, `{"new": "update!"}`) newDoc, _, err := collection.GetDocWithXattrs(ctx, existingHLVKey, db.DocUnmarshalAll) require.NoError(t, err) casV2 := newDoc.Cas diff --git a/rest/attachment_test.go b/rest/attachment_test.go index e216f9c1f5..56e8a9415e 100644 --- a/rest/attachment_test.go +++ b/rest/attachment_test.go @@ -2314,8 +2314,8 @@ func TestUpdateExistingAttachment(t *testing.T) { btcRunner.StartPull(btc.id) btcRunner.StartPush(btc.id) - doc1Version := rt.PutDocDirectly(doc1ID, db.Body{}) - doc2Version := rt.PutDocDirectly(doc2ID, db.Body{}) + doc1Version := rt.PutDoc(doc1ID, "{}") + doc2Version := rt.PutDoc(doc2ID, "{}") btcRunner.WaitForVersion(btc.id, doc1ID, doc1Version) btcRunner.WaitForVersion(btc.id, doc2ID, doc2Version) @@ -2370,7 +2370,7 @@ func TestPushUnknownAttachmentAsStub(t *testing.T) { btcRunner.StartPush(btc.id) // Add doc1 - doc1Version := rt.PutDocDirectly(doc1ID, db.Body{}) + doc1Version := rt.PutDoc(doc1ID, "{}") btcRunner.WaitForVersion(btc.id, doc1ID, doc1Version) @@ -2588,9 +2588,9 @@ func TestCBLRevposHandling(t *testing.T) { btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, &opts) defer btc.Close() - startingBody := db.Body{"foo": "bar"} - doc1Version1 := rt.PutDocDirectly(doc1ID, startingBody) - doc2Version1 := rt.PutDocDirectly(doc2ID, startingBody) + startingBody := `{"foo": "bar"}` + doc1Version1 := rt.PutDoc(doc1ID, startingBody) + doc2Version1 := rt.PutDoc(doc2ID, startingBody) rt.WaitForPendingChanges() btcRunner.StartOneshotPull(btc.id) diff --git a/rest/blip_api_collections_test.go b/rest/blip_api_collections_test.go index a4235e4d60..3ede7cb493 100644 --- a/rest/blip_api_collections_test.go +++ b/rest/blip_api_collections_test.go @@ -257,7 +257,7 @@ func TestCollectionsReplication(t *testing.T) { btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, opts) defer btc.Close() - version := btc.rt.PutDocDirectly(docID, db.Body{}) + version := btc.rt.PutDoc(docID, "{}") btc.rt.WaitForPendingChanges() btcRunner.StartOneshotPull(btc.id) @@ -283,8 +283,8 @@ func TestBlipReplicationMultipleCollections(t *testing.T) { docName := "doc1" body := `{"foo":"bar"}` versions := make([]DocVersion, 0, len(btc.rt.GetKeyspaces())) - for _, collection := range btc.rt.GetDbCollections() { - docVersion := rt.PutDocDirectlyInCollection(collection, docName, db.Body{"foo": "bar"}) + for _, ks := range btc.rt.GetKeyspaces() { + docVersion := rt.PutDocWithKeyspace(ks, docName, `{"foo": "bar"}`) versions = append(versions, docVersion) } btc.rt.WaitForPendingChanges() @@ -323,7 +323,7 @@ func TestBlipReplicationMultipleCollectionsMismatchedDocSizes(t *testing.T) { collectionDocIDs := make(map[string][]string) collectionVersions := make(map[string][]DocVersion) require.Len(t, btc.rt.GetKeyspaces(), 2) - for i, collection := range btc.rt.GetDbCollections() { + for i, ks := range btc.rt.GetKeyspaces() { // intentionally create collections with different size replications to ensure one collection finishing won't cancel another one docCount := 10 if i == 0 { @@ -332,7 +332,7 @@ func TestBlipReplicationMultipleCollectionsMismatchedDocSizes(t *testing.T) { blipName := btc.rt.getCollectionsForBLIP()[i] for j := 0; j < docCount; j++ { docName := fmt.Sprintf("doc%d", j) - version := rt.PutDocDirectlyInCollection(collection, docName, db.Body{"foo": "bar"}) + version := rt.PutDocWithKeyspace(ks, docName, `{"foo": "bar"}`) collectionVersions[blipName] = append(collectionVersions[blipName], version) collectionDocIDs[blipName] = append(collectionDocIDs[blipName], docName) diff --git a/rest/blip_api_crud_test.go b/rest/blip_api_crud_test.go index c700bc2101..c8a26740a4 100644 --- a/rest/blip_api_crud_test.go +++ b/rest/blip_api_crud_test.go @@ -1269,7 +1269,7 @@ func TestBlipSendAndGetLargeNumberRev(t *testing.T) { // Get non-deleted rev response := bt.restTester.SendAdminRequest("GET", "/{{.keyspace}}/largeNumberRev?rev=1-abc", "") RequireStatus(t, response, 200) // Check the raw bytes, because unmarshalling the response would be another opportunity for the number to get modified - responseString := string(response.Body.Bytes()) + responseString := response.BodyString() if !strings.Contains(responseString, `9223372036854775807`) { t.Errorf("Response does not contain the expected number format. Response: %s", responseString) } @@ -2027,7 +2027,7 @@ func TestSendReplacementRevision(t *testing.T) { defer rt.Close() docID := test.name - version1 := rt.PutDocDirectly(docID, JsonToMap(t, fmt.Sprintf(`{"foo":"bar","channels":["%s"]}`, rev1Channel))) + version1 := rt.PutDoc(docID, fmt.Sprintf(`{"foo":"bar","channels":["%s"]}`, rev1Channel)) updatedVersion := make(chan DocVersion) collection, ctx := rt.GetSingleTestDatabaseCollection() @@ -2130,13 +2130,13 @@ func TestBlipPullRevMessageHistory(t *testing.T) { const docID = "doc1" // create doc1 rev 1-0335a345b6ffed05707ccc4cbc1b67f4 - version1 := rt.PutDocDirectly(docID, db.Body{"hello": "world!"}) + version1 := rt.PutDoc(docID, `{"hello": "world!"}`) data := btcRunner.WaitForVersion(client.id, docID, version1) assert.Equal(t, `{"hello":"world!"}`, string(data)) // create doc1 rev 2-959f0e9ad32d84ff652fb91d8d0caa7e - version2 := rt.UpdateDocDirectly(docID, version1, db.Body{"hello": "alice"}) + version2 := rt.UpdateDoc(docID, version1, `{"hello": "alice"}`) data = btcRunner.WaitForVersion(client.id, docID, version2) assert.Equal(t, `{"hello":"alice"}`, string(data)) @@ -2192,7 +2192,7 @@ func TestPullReplicationUpdateOnOtherHLVAwarePeer(t *testing.T) { _ = btcRunner.WaitForVersion(client.id, docID, version1) // update the above doc - version2 := rt.UpdateDocDirectly(docID, version1, db.Body{"hello": "world!"}) + version2 := rt.UpdateDoc(docID, version1, `{"hello": "world!"}`) data := btcRunner.WaitForVersion(client.id, docID, version2) assert.Equal(t, `{"hello":"world!"}`, string(data)) @@ -2247,7 +2247,7 @@ func TestActiveOnlyContinuous(t *testing.T) { btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, opts) defer btc.Close() - version := rt.PutDocDirectly(docID, db.Body{"test": true}) + version := rt.PutDoc(docID, `{"test": true}`) // start an initial pull btcRunner.StartPullSince(btc.id, BlipTesterPullOptions{Continuous: true, Since: "0", ActiveOnly: true}) @@ -2255,7 +2255,7 @@ func TestActiveOnlyContinuous(t *testing.T) { assert.Equal(t, `{"test":true}`, string(rev)) // delete the doc and make sure the client still gets the tombstone replicated - deletedVersion := rt.DeleteDocDirectly(docID, version) + deletedVersion := rt.DeleteDoc(docID, version) rev = btcRunner.WaitForVersion(btc.id, docID, deletedVersion) assert.Equal(t, `{}`, string(rev)) @@ -2338,7 +2338,7 @@ func TestRemovedMessageWithAlternateAccess(t *testing.T) { defer btc.Close() const docID = "doc" - version := rt.PutDocDirectly(docID, db.Body{"channels": []string{"A", "B"}}) + version := rt.PutDoc(docID, `{"channels": ["A", "B"]}`) changes := rt.WaitForChanges(1, "/{{.keyspace}}/_changes?since=0&revocations=true", "user", true) assert.Equal(t, "doc", changes.Results[0].ID) @@ -2347,7 +2347,7 @@ func TestRemovedMessageWithAlternateAccess(t *testing.T) { btcRunner.StartOneshotPull(btc.id) _ = btcRunner.WaitForVersion(btc.id, docID, version) - version = rt.UpdateDocDirectly(docID, version, db.Body{"channels": []string{"B"}}) + version = rt.UpdateDoc(docID, version, `{"channels": ["B"]}`) changes = rt.WaitForChanges(1, fmt.Sprintf("/{{.keyspace}}/_changes?since=%s&revocations=true", changes.Last_Seq), "user", true) assert.Equal(t, docID, changes.Results[0].ID) @@ -2356,9 +2356,9 @@ func TestRemovedMessageWithAlternateAccess(t *testing.T) { btcRunner.StartOneshotPull(btc.id) _ = btcRunner.WaitForVersion(btc.id, docID, version) - version = rt.UpdateDocDirectly(docID, version, db.Body{"channels": []string{}}) + version = rt.UpdateDoc(docID, version, `{"channels": []}`) const docMarker = "docmarker" - docMarkerVersion := rt.PutDocDirectly(docMarker, db.Body{"channels": []string{"!"}}) + docMarkerVersion := rt.PutDoc(docMarker, `{"channels": ["!"]}`) changes = rt.WaitForChanges(2, fmt.Sprintf("/{{.keyspace}}/_changes?since=%s&revocations=true", changes.Last_Seq), "user", true) assert.Equal(t, "doc", changes.Results[0].ID) @@ -2423,7 +2423,7 @@ func TestRemovedMessageWithAlternateAccessAndChannelFilteredReplication(t *testi const ( docID = "doc" ) - version := rt.PutDocDirectly(docID, db.Body{"channels": []string{"A", "B"}}) + version := rt.PutDoc(docID, `{"channels": ["A", "B"]}`) changes := rt.WaitForChanges(1, "/{{.keyspace}}/_changes?since=0&revocations=true", "user", true) assert.Equal(t, docID, changes.Results[0].ID) @@ -2432,7 +2432,7 @@ func TestRemovedMessageWithAlternateAccessAndChannelFilteredReplication(t *testi btcRunner.StartOneshotPull(btc.id) _ = btcRunner.WaitForVersion(btc.id, docID, version) - version = rt.UpdateDocDirectly(docID, version, db.Body{"channels": []string{"C"}}) + version = rt.UpdateDoc(docID, version, `{"channels": ["C"]}`) rt.WaitForPendingChanges() // At this point changes should send revocation, as document isn't in any of the user's channels @@ -2445,7 +2445,7 @@ func TestRemovedMessageWithAlternateAccessAndChannelFilteredReplication(t *testi _ = rt.UpdateDoc(docID, version, `{"channels": ["B"]}`) markerID := "docmarker" - markerVersion := rt.PutDocDirectly(markerID, db.Body{"channels": []string{"A"}}) + markerVersion := rt.PutDoc(markerID, `{"channels": ["A"]}`) rt.WaitForPendingChanges() // Revocation should not be sent over blip, as document is now in user's channels - only marker document should be received @@ -2792,7 +2792,7 @@ func TestProcessRevIncrementsStat(t *testing.T) { defer func() { require.NoError(t, ar.Stop()) }() activeRT.WaitForPendingChanges() - activeRT.WaitForVersion(docID, version) + activeRT.WaitForRevTreeVersion(docID, version) base.RequireWaitForStat(t, pullStats.HandleRevCount.Value, 1) assert.NotEqualValues(t, 0, pullStats.HandleRevBytes.Value()) @@ -2904,7 +2904,7 @@ func TestSendRevisionNoRevHandling(t *testing.T) { recievedNoRevs <- msg } - version := rt.PutDocDirectly(docName, db.Body{"foo": "bar"}) + version := rt.PutDoc(docName, `{"foo": "bar"}`) // Make the LeakyBucket return an error leakyDataStore.SetGetRawCallback(func(key string) error { @@ -2964,7 +2964,7 @@ func TestUnsubChanges(t *testing.T) { // Sub changes btcRunner.StartPull(btc.id) - doc1Version := rt.PutDocDirectly(doc1ID, db.Body{"key": "val1"}) + doc1Version := rt.PutDoc(doc1ID, `{"key": "val1"}`) _ = btcRunner.WaitForVersion(btc.id, doc1ID, doc1Version) activeReplStat := rt.GetDatabase().DbStats.CBLReplicationPull().NumPullReplActiveContinuous @@ -2975,7 +2975,7 @@ func TestUnsubChanges(t *testing.T) { base.RequireWaitForStat(t, activeReplStat.Value, 0) // Confirm no more changes are being sent - doc2Version := rt.PutDocDirectly(doc2ID, db.Body{"key": "val1"}) + doc2Version := rt.PutDoc(doc2ID, `{"key": "val1"}`) err := rt.WaitForConditionWithOptions(func() bool { _, found := btcRunner.GetVersion(btc.id, "doc2", doc2Version) return found @@ -3148,7 +3148,7 @@ func TestBlipRefreshUser(t *testing.T) { // add chan1 explicitly rt.CreateUser(username, []string{"chan1"}) - version := rt.PutDocDirectly(docID, db.Body{"channels": []string{"chan1"}}) + version := rt.PutDoc(docID, `{"channels": []string{"chan1"}}`) // Start a regular one-shot pull btcRunner.StartPullSince(btc.id, BlipTesterPullOptions{Continuous: true, Since: "0"}) @@ -3202,8 +3202,8 @@ func TestImportInvalidSyncGetsNoRev(t *testing.T) { Channels: []string{"ABC"}, }) defer btc.Close() - version := rt.PutDocDirectly(docID, JsonToMap(t, `{"some":"data", "channels":["ABC"]}`)) - version2 := rt.PutDocDirectly(docID2, JsonToMap(t, `{"some":"data", "channels":["ABC"]}`)) + version := rt.PutDoc(docID, `{"some":"data", "channels":["ABC"]}`) + version2 := rt.PutDoc(docID2, `{"some":"data", "channels":["ABC"]}`) rt.WaitForPendingChanges() // get changes resident in channel cache diff --git a/rest/blip_api_delta_sync_test.go b/rest/blip_api_delta_sync_test.go index eec2ffe82b..3f5af08f01 100644 --- a/rest/blip_api_delta_sync_test.go +++ b/rest/blip_api_delta_sync_test.go @@ -246,7 +246,7 @@ func TestBlipDeltaSyncPushPullNewAttachment(t *testing.T) { // Create doc1 rev 1-77d9041e49931ceef58a1eef5fd032e8 on SG with an attachment bodyText := `{"greetings":[{"hi": "alice"}],"_attachments":{"hello.txt":{"data":"aGVsbG8gd29ybGQ="}}}` // put doc directly needs to be here - version1 := rt.PutDocDirectly(docID, JsonToMap(t, bodyText)) + version1 := rt.PutDoc(docID, bodyText) data := btcRunner.WaitForVersion(btc.id, docID, version1) bodyTextExpected := `{"greetings":[{"hi":"alice"}],"_attachments":{"hello.txt":{"revpos":1,"length":11,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` require.JSONEq(t, bodyTextExpected, string(data)) @@ -309,13 +309,13 @@ func TestBlipDeltaSyncNewAttachmentPull(t *testing.T) { btcRunner.StartPull(client.id) // create doc1 rev 1-0335a345b6ffed05707ccc4cbc1b67f4 - version := rt.PutDocDirectly(doc1ID, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`)) + version := rt.PutDoc(doc1ID, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`) data := btcRunner.WaitForVersion(client.id, doc1ID, version) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) // create doc1 rev 2-10000d5ec533b29b117e60274b1e3653 on SG with the first attachment - version2 := rt.UpdateDocDirectly(doc1ID, version, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}], "_attachments": {"hello.txt": {"data":"aGVsbG8gd29ybGQ="}}}`)) + version2 := rt.UpdateDoc(doc1ID, version, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}], "_attachments": {"hello.txt": {"data":"aGVsbG8gd29ybGQ="}}}`) data = btcRunner.WaitForVersion(client.id, doc1ID, version2) require.Equal(t, db.AttachmentMap{ @@ -408,13 +408,13 @@ func TestBlipDeltaSyncPull(t *testing.T) { btcRunner.StartPull(client.id) // create doc1 rev 1-0335a345b6ffed05707ccc4cbc1b67f4 - version := rt.PutDocDirectly(docID, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`)) + version := rt.PutDoc(docID, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`) data := btcRunner.WaitForVersion(client.id, docID, version) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) // create doc1 rev 2-959f0e9ad32d84ff652fb91d8d0caa7e - version2 := rt.UpdateDocDirectly(docID, version, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}, {"howdy": 1234567890123}]}`)) + version2 := rt.UpdateDoc(docID, version, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}, {"howdy": 1234567890123}]}`) data = btcRunner.WaitForVersion(client.id, docID, version2) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"},{"howdy":1234567890123}]}`, string(data)) @@ -476,7 +476,7 @@ func TestBlipDeltaSyncPullResend(t *testing.T) { docID := "doc1" // create doc1 rev 1 - docVersion1 := rt.PutDocDirectly(docID, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`)) + docVersion1 := rt.PutDoc(docID, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`) deltaSentCount := rt.GetDatabase().DbStats.DeltaSync().DeltasSent.Value() @@ -497,7 +497,7 @@ func TestBlipDeltaSyncPullResend(t *testing.T) { assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) // create doc1 rev 2 - docVersion2 := rt.UpdateDocDirectly(docID, docVersion1, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}, {"howdy": 1234567890123}]}`)) + docVersion2 := rt.UpdateDoc(docID, docVersion1, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}, {"howdy": 1234567890123}]}`) data = btcRunner.WaitForVersion(client.id, docID, docVersion2) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"},{"howdy":1234567890123}]}`, string(data)) @@ -562,14 +562,14 @@ func TestBlipDeltaSyncPullRemoved(t *testing.T) { btcRunner.StartPull(client.id) // create doc1 rev 1-1513b53e2738671e634d9dd111f48de0 - version := rt.PutDocDirectly(docID, JsonToMap(t, `{"channels": ["public"], "greetings": [{"hello": "world!"}]}`)) + version := rt.PutDoc(docID, `{"channels": ["public"], "greetings": [{"hello": "world!"}]}`) data := btcRunner.WaitForVersion(client.id, docID, version) assert.Contains(t, string(data), `"channels":["public"]`) assert.Contains(t, string(data), `"greetings":[{"hello":"world!"}]`) // create doc1 rev 2-ff91e11bc1fd12bbb4815a06571859a9 - version = rt.UpdateDocDirectly(docID, version, JsonToMap(t, `{"channels": ["private"], "greetings": [{"hello": "world!"}, {"hi": "bob"}]}`)) + version = rt.UpdateDoc(docID, version, `{"channels": ["private"], "greetings": [{"hello": "world!"}, {"hi": "bob"}]}`) data = btcRunner.WaitForVersion(client.id, docID, version) assert.Equal(t, `{"_removed":true}`, string(data)) @@ -637,13 +637,13 @@ func TestBlipDeltaSyncPullTombstoned(t *testing.T) { const docID = "doc1" // create doc1 rev 1-e89945d756a1d444fa212bffbbb31941 - version := rt.PutDocDirectly(docID, JsonToMap(t, `{"channels": ["public"], "greetings": [{"hello": "world!"}]}`)) + version := rt.PutDoc(docID, `{"channels": ["public"], "greetings": [{"hello": "world!"}]}`) data := btcRunner.WaitForVersion(client.id, docID, version) assert.Contains(t, string(data), `"channels":["public"]`) assert.Contains(t, string(data), `"greetings":[{"hello":"world!"}]`) // tombstone doc1 at rev 2-2db70833630b396ef98a3ec75b3e90fc - version = rt.DeleteDocDirectly(docID, version) + version = rt.DeleteDoc(docID, version) data = btcRunner.WaitForVersion(client.id, docID, version) assert.Equal(t, `{}`, string(data)) @@ -739,7 +739,7 @@ func TestBlipDeltaSyncPullTombstonedStarChan(t *testing.T) { btcRunner.StartPull(client1.id) // create doc1 rev 1-e89945d756a1d444fa212bffbbb31941 - version := rt.PutDocDirectly(docID, JsonToMap(t, `{"channels": ["public"], "greetings": [{"hello": "world!"}]}`)) + version := rt.PutDoc(docID, `{"channels": ["public"], "greetings": [{"hello": "world!"}]}`) data := btcRunner.WaitForVersion(client1.id, docID, version) assert.Contains(t, string(data), `"channels":["public"]`) @@ -752,7 +752,7 @@ func TestBlipDeltaSyncPullTombstonedStarChan(t *testing.T) { assert.Contains(t, string(data), `"greetings":[{"hello":"world!"}]`) // tombstone doc1 at rev 2-2db70833630b396ef98a3ec75b3e90fc - version = rt.DeleteDocDirectly(docID, version) + version = rt.DeleteDoc(docID, version) data = btcRunner.WaitForVersion(client1.id, docID, version) assert.Equal(t, `{}`, string(data)) @@ -858,7 +858,7 @@ func TestBlipDeltaSyncPullRevCache(t *testing.T) { btcRunner.StartPull(client.id) // create doc1 rev 1-0335a345b6ffed05707ccc4cbc1b67f4 - version1 := rt.PutDocDirectly(docID, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`)) + version1 := rt.PutDoc(docID, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`) data := btcRunner.WaitForVersion(client.id, docID, version1) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) @@ -873,7 +873,7 @@ func TestBlipDeltaSyncPullRevCache(t *testing.T) { assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) // create doc1 rev 2-959f0e9ad32d84ff652fb91d8d0caa7e - version2 := rt.UpdateDocDirectly(docID, version1, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}, {"howdy": "bob"}]}`)) + version2 := rt.UpdateDoc(docID, version1, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}, {"howdy": "bob"}]}`) data = btcRunner.WaitForVersion(client.id, docID, version2) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"},{"howdy":"bob"}]}`, string(data)) @@ -966,7 +966,7 @@ func TestBlipDeltaSyncPush(t *testing.T) { btcRunner.StartPull(client.id) // create doc1 rev 1-0335a345b6ffed05707ccc4cbc1b67f4 - version := rt.PutDocDirectly(docID, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`)) + version := rt.PutDoc(docID, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`) data := btcRunner.WaitForVersion(client.id, docID, version) assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) @@ -1011,7 +1011,7 @@ func TestBlipDeltaSyncPush(t *testing.T) { assert.Equal(t, map[string]interface{}{"howdy": "bob"}, greetings[2]) // tombstone doc1 (gets rev 3-f3be6c85e0362153005dae6f08fc68bb) - deletedVersion := rt.DeleteDocDirectly(docID, newRev) + deletedVersion := rt.DeleteDoc(docID, newRev) data = btcRunner.WaitForVersion(client.id, docID, deletedVersion) assert.Equal(t, `{}`, string(data)) @@ -1100,7 +1100,7 @@ func TestBlipNonDeltaSyncPush(t *testing.T) { var body db.Body require.NoError(t, base.JSONUnmarshal([]byte(rawBody), &body)) // create doc1 rev 1-0335a345b6ffed05707ccc4cbc1b67f4 - version1 := rt.PutDocDirectly(docID, body) + version1 := rt.PutDoc(docID, rawBody) data := btcRunner.WaitForVersion(client.id, docID, version1) assert.Equal(t, rawBody, string(data)) diff --git a/rest/blip_api_replication_test.go b/rest/blip_api_replication_test.go index 3f6ec0ac35..28e564a595 100644 --- a/rest/blip_api_replication_test.go +++ b/rest/blip_api_replication_test.go @@ -13,7 +13,6 @@ import ( "time" "github.com/couchbase/sync_gateway/base" - "github.com/couchbase/sync_gateway/db" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -51,7 +50,7 @@ func TestReplicationBroadcastTickerChange(t *testing.T) { btcRunner.StartPull(client.id) // create doc1 on SG and wait to replicate to client - versionDoc1 := rt.PutDocDirectly(docID, JsonToMap(t, `{"test": "value"}`)) + versionDoc1 := rt.PutDoc(docID, `{"test": "value"}`) btcRunner.WaitForVersion(client.id, docID, versionDoc1) // alter sync data of this doc to artificially create skipped sequences @@ -77,11 +76,11 @@ func TestReplicationBroadcastTickerChange(t *testing.T) { }, time.Second*10, time.Millisecond*100) // assert new change added still replicates to client - versionDoc2 := rt.PutDocDirectly(docID2, JsonToMap(t, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`)) + versionDoc2 := rt.PutDoc(docID2, `{"greetings": [{"hello": "world!"}, {"hi": "alice"}]}`) btcRunner.WaitForVersion(client.id, docID2, versionDoc2) // update doc1 that will trigger unused seq release to clear skipped and assert that update is received - versionDoc1 = rt.UpdateDocDirectly(docID, versionDoc1, JsonToMap(t, `{"test": "new value"}`)) + versionDoc1 = rt.UpdateDoc(docID, versionDoc1, `{"test": "new value"}`) btcRunner.WaitForVersion(client.id, docID, versionDoc1) // assert skipped is cleared and skipped sequence broadcast is not sent @@ -117,12 +116,12 @@ func TestBlipClientPushAndPullReplication(t *testing.T) { btcRunner.StartPush(client.id) // create doc1 on SG - docBody := db.Body{"greetings": []map[string]interface{}{{"hello": "world!"}, {"hi": "alice"}}} - version := rt.PutDocDirectly(docID, docBody) + docBody := `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}` + version := rt.PutDoc(docID, docBody) // wait for doc on client data := btcRunner.WaitForVersion(client.id, docID, version) - assert.Equal(t, `{"greetings":[{"hello":"world!"},{"hi":"alice"}]}`, string(data)) + assert.Equal(t, docBody, string(data)) // update doc1 on client newRev := btcRunner.AddRev(client.id, docID, &version, []byte(`{"greetings":[{"hello":"world!"},{"hi":"alice"},{"howdy":"bob"}]}`)) diff --git a/rest/blip_legacy_revid_test.go b/rest/blip_legacy_revid_test.go index 9f32a1dc55..e101a83432 100644 --- a/rest/blip_legacy_revid_test.go +++ b/rest/blip_legacy_revid_test.go @@ -259,7 +259,7 @@ func TestProcessLegacyRev(t *testing.T) { collection, _ := rt.GetSingleTestDatabaseCollection() // add doc to SGW - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID // Send another rev of same doc @@ -329,7 +329,7 @@ func TestProcessRevWithLegacyHistory(t *testing.T) { ) // 1. CBL sends rev=1010@CBL1, history=1-abc when SGW has current rev 1-abc (document underwent an update before being pushed to SGW) - docVersion := rt.PutDocDirectly(docID, db.Body{"test": "doc"}) + docVersion := rt.PutDoc(docID, `{"test": "doc"}`) rev1ID := docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -349,7 +349,7 @@ func TestProcessRevWithLegacyHistory(t *testing.T) { assert.NotNil(t, bucketDoc.History[rev1ID]) // 2. CBL sends rev=1010@CBL1, history=1000@CBL2,1-abc when SGW has current rev 1-abc (document underwent multiple p2p updates before being pushed to SGW) - docVersion = rt.PutDocDirectly(docID2, db.Body{"test": "doc"}) + docVersion = rt.PutDoc(docID2, `{"test": "doc"}`) rev1ID = docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -370,7 +370,7 @@ func TestProcessRevWithLegacyHistory(t *testing.T) { assert.NotNil(t, bucketDoc.History[rev1ID]) // 3. CBL sends rev=1010@CBL1, history=1000@CBL2,2-abc,1-abc when SGW has current rev 1-abc (document underwent multiple legacy and p2p updates before being pushed to SGW) - docVersion = rt.PutDocDirectly(docID3, db.Body{"test": "doc"}) + docVersion = rt.PutDoc(docID3, `{"test": "doc"}`) rev1ID = docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -405,9 +405,9 @@ func TestProcessRevWithLegacyHistory(t *testing.T) { // 5. CBL sends rev=1010@CBL1, history=2-abc and SGW has 1000@CBL2, 2-abc // although HLV's are in conflict, this should pass conflict check as local current rev is parent of incoming rev - docVersion = rt.PutDocDirectly(docID5, db.Body{"test": "doc"}) + docVersion = rt.PutDoc(docID5, `{"test": "doc"}`) - docVersion = rt.UpdateDocDirectly(docID5, docVersion, db.Body{"some": "update"}) + docVersion = rt.UpdateDoc(docID5, docVersion, `{"some": "update"}`) version := docVersion.CV.Value rev2ID := docVersion.RevTreeID pushedRev := db.Version{ @@ -433,7 +433,7 @@ func TestProcessRevWithLegacyHistory(t *testing.T) { // - a pre 4.0 client pulling this doc on one shot replication // - then this doc being updated a couple of times on client before client gets upgraded to 4.0 // - after the upgrade client updates it again and pushes to SGW - docVersion = rt.PutDocDirectly(docID6, db.Body{"test": "doc"}) + docVersion = rt.PutDoc(docID6, `{"test": "doc"}`) rev1ID = docVersion.RevTreeID pushedRev = db.Version{ @@ -480,13 +480,13 @@ func TestProcessRevWithLegacyHistoryConflict(t *testing.T) { ) // 1. conflicting changes with legacy rev on both sides of communication (no upgrade of doc at all) - docVersion := rt.PutDocDirectly(docID, db.Body{"test": "doc"}) + docVersion := rt.PutDoc(docID, `{"test": "doc"}`) rev1ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly(docID, docVersion, db.Body{"some": "update"}) + docVersion = rt.UpdateDoc(docID, docVersion, `{"some": "update"}`) rev2ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly(docID, docVersion, db.Body{"some": "update2"}) + docVersion = rt.UpdateDoc(docID, docVersion, `{"some": "update2"}`) // remove hlv here to simulate a legacy rev require.NoError(t, ds.RemoveXattrs(base.TestCtx(t), docID, []string{base.VvXattrName}, docVersion.CV.Value)) @@ -498,13 +498,13 @@ func TestProcessRevWithLegacyHistoryConflict(t *testing.T) { require.ErrorContains(t, err, "Document revision conflict") // 2. same as above but not having the rev be legacy on SGW side (don't remove the hlv) - docVersion = rt.PutDocDirectly(docID2, db.Body{"test": "doc"}) + docVersion = rt.PutDoc(docID2, `{"test": "doc"}`) rev1ID = docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly(docID2, docVersion, db.Body{"some": "update"}) + docVersion = rt.UpdateDoc(docID2, docVersion, `{"some": "update"}`) rev2ID = docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly(docID2, docVersion, db.Body{"some": "update2"}) + docVersion = rt.UpdateDoc(docID2, docVersion, `{"some": "update2"}`) history = []string{rev2ID, rev1ID} sent, _, _, err = bt.SendRevWithHistory(docID2, "3-abc", history, []byte(`{"key": "val"}`), blip.Properties{}) @@ -512,10 +512,10 @@ func TestProcessRevWithLegacyHistoryConflict(t *testing.T) { require.ErrorContains(t, err, "Document revision conflict") // 3. CBL sends rev=1010@CBL1, history=1000@CBL2,1-abc when SGW has current rev 2-abc (document underwent multiple p2p updates before being pushed to SGW) - docVersion = rt.PutDocDirectly(docID3, db.Body{"test": "doc"}) + docVersion = rt.PutDoc(docID3, `{"test": "doc"}`) rev1ID = docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly(docID3, docVersion, db.Body{"some": "update"}) + docVersion = rt.UpdateDoc(docID3, docVersion, `{"some": "update"}`) // remove hlv here to simulate a legacy rev require.NoError(t, ds.RemoveXattrs(base.TestCtx(t), docID3, []string{base.VvXattrName}, docVersion.CV.Value)) @@ -545,10 +545,10 @@ func TestChangesResponseLegacyRev(t *testing.T) { defer bt.Close() rt := bt.restTester - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID - docVersion2 := rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update"}) + docVersion2 := rt.UpdateDoc("doc1", docVersion, `{"test": "update"}`) // wait for pending change to avoid flakes where changes feed didn't pick up this change rt.WaitForPendingChanges() receivedChangesRequestWg := sync.WaitGroup{} @@ -646,7 +646,7 @@ func TestChangesResponseWithHLVInHistory(t *testing.T) { rt := bt.restTester collection, ctx := rt.GetSingleTestDatabaseCollection() - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID newDoc, _, err := collection.GetDocWithXattrs(ctx, "doc1", db.DocUnmarshalAll) @@ -753,7 +753,7 @@ func TestCBLHasPreUpgradeMutationThatHasNotBeenReplicated(t *testing.T) { collection, ctx := rt.GetSingleTestDatabaseCollection() ds := rt.GetSingleDataStore() - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -790,10 +790,10 @@ func TestCBLHasOfPreUpgradeMutationThatSGWAlreadyKnows(t *testing.T) { collection, ctx := rt.GetSingleTestDatabaseCollection() ds := rt.GetSingleDataStore() - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update"}) + docVersion = rt.UpdateDoc("doc1", docVersion, `{"test": "update"}`) rev2ID := docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -829,10 +829,10 @@ func TestPushOfPostUpgradeMutationThatHasCommonAncestorToSGWVersion(t *testing.T collection, ctx := rt.GetSingleTestDatabaseCollection() ds := rt.GetSingleDataStore() - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update"}) + docVersion = rt.UpdateDoc("doc1", docVersion, `{"test": "update"}`) rev2ID := docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -868,13 +868,13 @@ func TestPushDocConflictBetweenPreUpgradeCBLMutationAndPreUpgradeSGWMutation(t * collection, ctx := rt.GetSingleTestDatabaseCollection() ds := rt.GetSingleDataStore() - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update"}) + docVersion = rt.UpdateDoc("doc1", docVersion, `{"test": "update"}`) rev2ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update1"}) + docVersion = rt.UpdateDoc("doc1", docVersion, `{"test": "update1"}`) rev3ID := docVersion.RevTreeID // remove hlv here to simulate a legacy rev @@ -910,13 +910,13 @@ func TestPushDocConflictBetweenPreUpgradeCBLMutationAndPostUpgradeSGWMutation(t rt := bt.restTester collection, ctx := rt.GetSingleTestDatabaseCollection() - docVersion := rt.PutDocDirectly("doc1", db.Body{"test": "doc"}) + docVersion := rt.PutDoc("doc1", `{"test": "doc"}`) rev1ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update"}) + docVersion = rt.UpdateDoc("doc1", docVersion, `{"test": "update"}`) rev2ID := docVersion.RevTreeID - docVersion = rt.UpdateDocDirectly("doc1", docVersion, db.Body{"test": "update1"}) + docVersion = rt.UpdateDoc("doc1", docVersion, `{"test": "update1"}`) rev3ID := docVersion.RevTreeID // send rev 3-def @@ -954,7 +954,7 @@ func TestConflictBetweenPostUpgradeCBLMutationAndPostUpgradeSGWMutation(t *testi docID2 = "doc2" ) - docVersion := rt.PutDocDirectly(docID, db.Body{"test": "doc"}) + docVersion := rt.PutDoc(docID, `{"test": "doc"}`) rev1ID := docVersion.RevTreeID history := []string{rev1ID} @@ -970,7 +970,7 @@ func TestConflictBetweenPostUpgradeCBLMutationAndPostUpgradeSGWMutation(t *testi assert.Equal(t, docVersion.CV.Value, bucketDoc.HLV.PreviousVersions[docVersion.CV.SourceID]) // conflict rev - docVersion = rt.PutDocDirectly(docID2, db.Body{"some": "doc"}) + docVersion = rt.PutDoc(docID2, `{"some": "doc"}`) rev1ID = docVersion.RevTreeID history = []string{"1-abc"} @@ -998,7 +998,7 @@ func TestLegacyRevNotInConflict(t *testing.T) { collection, ctx := rt.GetSingleTestDatabaseCollection() const docID = "doc1" - docVersion := rt.PutDocDirectly(docID, db.Body{"test": "doc"}) + docVersion := rt.PutDoc(docID, `{"test": "doc"}`) rev1ID := docVersion.RevTreeID // have two history entries, 1 rev from a different CBL and 1 legacy rev, should generate conflict diff --git a/rest/bootstrap_test.go b/rest/bootstrap_test.go index 189b8a94cd..05045c3c24 100644 --- a/rest/bootstrap_test.go +++ b/rest/bootstrap_test.go @@ -75,7 +75,13 @@ func TestBootstrapRESTAPISetup(t *testing.T) { resp = BootstrapAdminRequest(t, sc, http.MethodGet, "/db1/doc1", ``) resp.RequireStatus(http.StatusNotFound) resp = BootstrapAdminRequest(t, sc, http.MethodPut, "/db1/doc1", `{"foo":"bar"}`) - resp.RequireResponse(http.StatusCreated, `{"id":"doc1","ok":true,"rev":"1-cd809becc169215072fd567eebd8b8de"}`) + resp.RequireStatus(http.StatusCreated) + var body db.Body + require.NoError(t, base.JSONUnmarshal([]byte(resp.Body), &body)) + // check for CV existence, but delete it since the value wil differ each time + require.Contains(t, body, "cv") + delete(body, "cv") + require.Equal(t, db.Body{"id": "doc1", "ok": true, "rev": "1-cd809becc169215072fd567eebd8b8de"}, body) resp = BootstrapAdminRequest(t, sc, http.MethodGet, "/db1/doc1", ``) resp.RequireStatus(http.StatusOK) assert.Contains(t, resp.Body, `"foo":"bar"`) diff --git a/rest/changestest/changes_api_test.go b/rest/changestest/changes_api_test.go index bf166bdb7e..801f213cea 100644 --- a/rest/changestest/changes_api_test.go +++ b/rest/changestest/changes_api_test.go @@ -1809,7 +1809,7 @@ func TestChangesIncludeDocs(t *testing.T) { "type": "pruned", "channels": []string{"gamma"}, } - docVersion := rt.UpdateDocDirectly("doc_pruned", db.DocVersion{RevTreeID: revid}, body) + docVersion := rt.UpdateDoc("doc_pruned", db.DocVersion{RevTreeID: revid}, string(base.MustJSONMarshal(t, body))) revid = docVersion.RevTreeID cvs = append(cvs, docVersion.CV.String()) } diff --git a/rest/doc_api.go b/rest/doc_api.go index 0204a0fd81..40ada481f6 100644 --- a/rest/doc_api.go +++ b/rest/doc_api.go @@ -389,13 +389,14 @@ func (h *handler) handlePutAttachment() error { attachments[attachmentName] = attachment body[db.BodyAttachments] = attachments - newRev, _, err := h.collection.Put(h.ctx(), docid, body) + newRev, doc, err := h.collection.Put(h.ctx(), docid, body) if err != nil { return err } h.setEtag(newRev) - h.writeRawJSONStatus(http.StatusCreated, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`"}`)) + // CBG-4751: add tests for CV + h.writeRawJSONStatus(http.StatusCreated, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`","cv":"`+doc.HLV.GetCurrentVersionString()+`"}`)) return nil } @@ -532,8 +533,12 @@ func (h *handler) handlePutDoc() error { return err } } - - h.writeRawJSONStatus(http.StatusCreated, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`"}`)) + // doc is nil if document already exists, and CV is empty. Consider fixing in CBG-4751 to return current HLV. CBG-4751 will add tests. + if doc == nil { + h.writeRawJSONStatus(http.StatusCreated, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`"}`)) + } else { + h.writeRawJSONStatus(http.StatusCreated, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`","cv":"`+doc.HLV.GetCurrentVersionString()+`"}`)) + } return nil } @@ -671,9 +676,10 @@ func (h *handler) handleDeleteDoc() error { return err } } - newRev, _, err := h.collection.DeleteDoc(h.ctx(), docid, revid) + newRev, doc, err := h.collection.DeleteDoc(h.ctx(), docid, revid) if err == nil { - h.writeRawJSONStatus(http.StatusOK, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`"}`)) + // CBG-4751: should add tests for CV + h.writeRawJSONStatus(http.StatusOK, []byte(`{"id":`+base.ConvertToJSONString(docid)+`,"ok":true,"rev":"`+newRev+`","cv":"`+doc.HLV.GetCurrentVersionString()+`"}`)) } return err } diff --git a/rest/doc_api_test.go b/rest/doc_api_test.go index 77f1f034f3..702315f9bd 100644 --- a/rest/doc_api_test.go +++ b/rest/doc_api_test.go @@ -180,7 +180,8 @@ func TestGetDocWithCV(t *testing.T) { defer rt.Close() docID := "doc1" - docVersion := rt.PutDocDirectly(docID, db.Body{"foo": "bar"}) + docVersion := rt.PutDoc(docID, `{"foo": "bar"}`) + require.NotEmpty(t, docVersion.CV) testCases := []struct { name string url string @@ -231,8 +232,8 @@ func TestBulkGetWithCV(t *testing.T) { doc1ID := "doc1" doc2ID := "doc2" - doc1Version := rt.PutDocDirectly(doc1ID, db.Body{"foo": "bar"}) - doc2Version := rt.PutDocDirectly(doc2ID, db.Body{"foo": "baz"}) + doc1Version := rt.PutDoc(doc1ID, `{"foo": "bar"}`) + doc2Version := rt.PutDoc(doc2ID, `{"foo": "baz"}`) testCases := []struct { name string url string diff --git a/rest/importtest/import_test.go b/rest/importtest/import_test.go index 1c6950894e..51d0890845 100644 --- a/rest/importtest/import_test.go +++ b/rest/importtest/import_test.go @@ -208,12 +208,12 @@ func TestXattrImportOldDocRevHistory(t *testing.T) { // 1. Create revision with history docID := t.Name() - version := rt.PutDocDirectly(docID, rest.JsonToMap(t, `{"val":-1}`)) + version := rt.PutDoc(docID, `{"val":-1}`) cv := version.CV.String() collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser() for i := 0; i < 10; i++ { - version = rt.UpdateDocDirectly(docID, version, rest.JsonToMap(t, fmt.Sprintf(`{"val":%d}`, i))) + version = rt.UpdateDoc(docID, version, fmt.Sprintf(`{"val":%d}`, i)) // Purge old revision JSON to simulate expiry, and to verify import doesn't attempt multiple retrievals // Revs are backed up by hash of CV now, switch to fetch by this till CBG-3748 (backwards compatibility for revID) cvHash := base.Crc32cHashString([]byte(cv)) diff --git a/rest/replicatortest/replicator_test.go b/rest/replicatortest/replicator_test.go index 5f1b9e6867..4740207b6b 100644 --- a/rest/replicatortest/replicator_test.go +++ b/rest/replicatortest/replicator_test.go @@ -2072,7 +2072,7 @@ func TestActiveReplicatorPullBasic(t *testing.T) { rt2.CreateUser(username, []string{username}) docID := t.Name() + "rt2doc1" - version := rt2.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt2","channels":["`+username+`"]}`)) + version := rt2.PutDoc(docID, `{"source":"rt2","channels":["`+username+`"]}`) rt2collection, rt2ctx := rt2.GetSingleTestDatabaseCollection() remoteDoc, err := rt2collection.GetDocument(rt2ctx, docID, db.DocUnmarshalAll) @@ -2189,7 +2189,7 @@ func TestActiveReplicatorPullSkippedSequence(t *testing.T) { docIDPrefix := t.Name() + "rt2doc" docID1 := docIDPrefix + "1" - doc1Version := rt2.PutDocDirectly(docID1, rest.JsonToMap(t, `{"source":"rt2","channels":["`+username+`"]}`)) + doc1Version := rt2.PutDoc(docID1, `{"source":"rt2","channels":["`+username+`"]}`) rt2.WaitForPendingChanges() // Start the replicator (implicit connect) @@ -2580,7 +2580,7 @@ func TestActiveReplicatorPullAttachments(t *testing.T) { attachment := `"_attachments":{"hi.txt":{"data":"aGk=","content_type":"text/plain"}}` docID := t.Name() + "rt2doc1" - version := rt2.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt2","doc_num":1,`+attachment+`,"channels":["alice"]}`)) + version := rt2.PutDoc(docID, `{"source":"rt2","doc_num":1,`+attachment+`,"channels":["alice"]}`) // Active rt1 := rest.NewRestTester(t, nil) @@ -2623,7 +2623,7 @@ func TestActiveReplicatorPullAttachments(t *testing.T) { assert.Equal(t, int64(1), ar.Pull.GetStats().GetAttachment.Value()) docID = t.Name() + "rt2doc2" - version = rt2.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt2","doc_num":2,`+attachment+`,"channels":["alice"]}`)) + version = rt2.PutDoc(docID, `{"source":"rt2","doc_num":2,`+attachment+`,"channels":["alice"]}`) // wait for the new document written to rt2 to arrive at rt1 changesResults = rt1.WaitForChanges(2, "/{{.keyspace}}/_changes?since=0", "", true) @@ -3211,7 +3211,7 @@ func TestActiveReplicatorPushBasic(t *testing.T) { ctx1 := rt1.Context() docID := t.Name() + "rt1doc1" - version := rt1.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt1","channels":["alice"]}`)) + version := rt1.PutDoc(docID, `{"source":"rt1","channels":["alice"]}`) rt1collection, rt1ctx := rt1.GetSingleTestDatabaseCollection() localDoc, err := rt1collection.GetDocument(rt1ctx, docID, db.DocUnmarshalAll) @@ -3283,7 +3283,7 @@ func TestActiveReplicatorPushAttachments(t *testing.T) { attachment := `"_attachments":{"hi.txt":{"data":"aGk=","content_type":"text/plain"}}` docID := t.Name() + "rt1doc1" - version := rt1.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt1","doc_num":1,`+attachment+`,"channels":["alice"]}`)) + version := rt1.PutDoc(docID, `{"source":"rt1","doc_num":1,`+attachment+`,"channels":["alice"]}`) ar, err := db.NewActiveReplicator(ctx1, &db.ActiveReplicatorConfig{ ID: t.Name(), @@ -3322,7 +3322,7 @@ func TestActiveReplicatorPushAttachments(t *testing.T) { assert.Equal(t, int64(1), ar.Push.GetStats().HandleGetAttachment.Value()) docID = t.Name() + "rt1doc2" - version = rt1.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt1","doc_num":2,`+attachment+`,"channels":["alice"]}`)) + version = rt1.PutDoc(docID, `{"source":"rt1","doc_num":2,`+attachment+`,"channels":["alice"]}`) // wait for the new document written to rt1 to arrive at rt2 changesResults = rt2.WaitForChanges(2, "/{{.keyspace}}/_changes?since=0", "", true) @@ -3700,7 +3700,7 @@ func TestActiveReplicatorPushOneshot(t *testing.T) { defer rt1.Close() docID := t.Name() + "rt1doc1" - version := rt1.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt1","channels":["alice"]}`)) + version := rt1.PutDoc(docID, `{"source":"rt1","channels":["alice"]}`) rt1collection, rt1ctx := rt1.GetSingleTestDatabaseCollection() localDoc, err := rt1collection.GetDocument(rt1ctx, docID, db.DocUnmarshalAll) @@ -3751,7 +3751,6 @@ func TestActiveReplicatorPushOneshot(t *testing.T) { // - Uses an ActiveReplicator configured for pull to start pulling changes from rt2. // - Deletes the document in rt2, and waits for the tombstone to get to rt1. func TestActiveReplicatorPullTombstone(t *testing.T) { - base.RequireNumTestBuckets(t, 2) base.SetUpTestLogging(t, base.LevelDebug, base.KeyAll) @@ -3767,7 +3766,7 @@ func TestActiveReplicatorPullTombstone(t *testing.T) { rt2.CreateUser(username, []string{username}) docID := t.Name() + "rt2doc1" - version := rt2.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt2","channels":["alice"]}`)) + version := rt2.PutDoc(docID, `{"source":"rt2","channels":["alice"]}`) // Active @@ -3814,7 +3813,7 @@ func TestActiveReplicatorPullTombstone(t *testing.T) { assert.Equal(t, "rt2", body["source"]) // Tombstone the doc in rt2 - deletedVersion := rt2.DeleteDocDirectly(docID, version) + deletedVersion := rt2.DeleteDoc(docID, version) // wait for the tombstone written to rt2 to arrive at rt1 changesResults = rt1.WaitForChanges(1, "/{{.keyspace}}/_changes?since="+strconv.FormatUint(doc.Sequence, 10), "", true) @@ -3855,7 +3854,7 @@ func TestActiveReplicatorPullPurgeOnRemoval(t *testing.T) { rt2.CreateUser(username, []string{username}) docID := t.Name() + "rt2doc1" - version := rt2.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt2","channels":["alice"]}`)) + version := rt2.PutDoc(docID, `{"source":"rt2","channels":["alice"]}`) // Active rt1 := rest.NewRestTester(t, nil) @@ -4405,7 +4404,7 @@ func TestActiveReplicatorPushBasicWithInsecureSkipVerifyEnabled(t *testing.T) { ctx1 := rt1.Context() docID := t.Name() + "rt1doc1" - version := rt1.PutDocDirectly(docID, rest.JsonToMap(t, `{"source":"rt1","channels":["alice"]}`)) + version := rt1.PutDoc(docID, `{"source":"rt1","channels":["alice"]}`) // Make rt2 listen on an actual HTTP port, so it can receive the blipsync request from rt1. srv := httptest.NewTLSServer(rt2.TestPublicHandler()) @@ -5129,7 +5128,7 @@ func TestActiveReplicatorIgnoreNoConflicts(t *testing.T) { ctx1 := rt1.Context() rt1docID := t.Name() + "rt1doc1" - rt1Version := rt1.PutDocDirectly(rt1docID, rest.JsonToMap(t, `{"source":"rt1","channels":["alice"]}`)) + rt1Version := rt1.PutDoc(rt1docID, `{"source":"rt1","channels":["alice"]}`) // Make rt2 listen on an actual HTTP port, so it can receive the blipsync request from rt1. srv := httptest.NewServer(rt2.TestPublicHandler()) @@ -5184,7 +5183,7 @@ func TestActiveReplicatorIgnoreNoConflicts(t *testing.T) { // write a doc on rt2 ... rt2docID := t.Name() + "rt2doc1" - rt2Version := rt2.PutDocDirectly(rt2docID, rest.JsonToMap(t, `{"source":"rt2","channels":["alice"]}`)) + rt2Version := rt2.PutDoc(rt2docID, `{"source":"rt2","channels":["alice"]}`) // ... and wait to arrive at rt1 changesResults = rt1.WaitForChanges(2, "/{{.keyspace}}/_changes?since=0", "", true) @@ -6077,8 +6076,8 @@ func TestSGR2TombstoneConflictHandling(t *testing.T) { const doc2ID = "docid2" doc2Version := rest.DocVersion{RevTreeID: "3-abc"} - localActiveRT.WaitForVersion(doc2ID, doc2Version) - remotePassiveRT.WaitForVersion(doc2ID, doc2Version) + localActiveRT.WaitForRevTreeVersion(doc2ID, doc2Version) + remotePassiveRT.WaitForRevTreeVersion(doc2ID, doc2Version) // Stop the replication rest.RequireStatus(t, localActiveRT.SendAdminRequest("PUT", "/{{.db}}/_replicationStatus/replication?action=stop", ""), http.StatusOK) @@ -6117,8 +6116,8 @@ func TestSGR2TombstoneConflictHandling(t *testing.T) { localActiveRT.WaitForReplicationStatus("replication", db.ReplicationStateRunning) // Wait for the recently longest branch to show up on both sides - localActiveRT.WaitForTombstone(doc2ID, rest.DocVersion{RevTreeID: "5-4a5f5a35196c37c117737afd5be1fc9b"}) - remotePassiveRT.WaitForTombstone(doc2ID, rest.DocVersion{RevTreeID: "5-4a5f5a35196c37c117737afd5be1fc9b"}) + localActiveRT.WaitForRevTreeTombstone(doc2ID, rest.DocVersion{RevTreeID: "5-4a5f5a35196c37c117737afd5be1fc9b"}) + remotePassiveRT.WaitForRevTreeTombstone(doc2ID, rest.DocVersion{RevTreeID: "5-4a5f5a35196c37c117737afd5be1fc9b"}) // Stop the replication rest.RequireStatus(t, localActiveRT.SendAdminRequest("PUT", "/{{.db}}/_replicationStatus/replication?action=stop", ""), http.StatusOK) @@ -6163,9 +6162,9 @@ func TestSGR2TombstoneConflictHandling(t *testing.T) { expectedVersion := rest.DocVersion{RevTreeID: expectedRevID} // Wait for doc to show up on side that the resurrection was done if test.resurrectLocal { - localActiveRT.WaitForVersion(doc2ID, expectedVersion) + localActiveRT.WaitForRevTreeVersion(doc2ID, expectedVersion) } else { - remotePassiveRT.WaitForVersion(doc2ID, expectedVersion) + remotePassiveRT.WaitForRevTreeVersion(doc2ID, expectedVersion) } // Start the replication @@ -6174,9 +6173,9 @@ func TestSGR2TombstoneConflictHandling(t *testing.T) { // Wait for doc to replicate from side resurrection was done on to the other side if test.resurrectLocal { - remotePassiveRT.WaitForVersion(doc2ID, expectedVersion) + remotePassiveRT.WaitForRevTreeVersion(doc2ID, expectedVersion) } else { - localActiveRT.WaitForVersion(doc2ID, expectedVersion) + localActiveRT.WaitForRevTreeVersion(doc2ID, expectedVersion) } }) } @@ -6276,7 +6275,7 @@ func TestDefaultConflictResolverWithTombstoneLocal(t *testing.T) { defer func() { require.NoError(t, ar.Stop(), "Error stopping replication") }() // Wait for the original document revision written to activeRT to arrive at passiveRT. - passiveRT.WaitForVersion(docID, activeRTVersionCreated) + passiveRT.WaitForRevTreeVersion(docID, activeRTVersionCreated) // Stop replication. require.NoError(t, ar.Stop(), "Error stopping replication") @@ -6302,7 +6301,7 @@ func TestDefaultConflictResolverWithTombstoneLocal(t *testing.T) { // winning revision is a tombstone; tombstone revision wins over non-tombstone revision. expectedVersion := rest.NewDocVersionFromFakeRev(test.expectedRevID) activeRT.WaitForTombstone(docID, expectedVersion) - passiveRT.WaitForTombstone(docID, expectedVersion) + passiveRT.WaitForRevTreeTombstone(docID, expectedVersion) }) } } @@ -6401,7 +6400,7 @@ func TestDefaultConflictResolverWithTombstoneRemote(t *testing.T) { require.NoError(t, ar.Start(ctx1), "Error starting replication") defer func() { require.NoError(t, ar.Stop(), "Error stopping replication") }() - rt1.WaitForVersion(docID, rt2VersionCreated) + rt1.WaitForRevTreeVersion(docID, rt2VersionCreated) // Stop replication. require.NoError(t, ar.Stop(), "Error stopping replication") @@ -6429,8 +6428,8 @@ func TestDefaultConflictResolverWithTombstoneRemote(t *testing.T) { // winning revision is a tombstone; tombstone revision wins over non-tombstone revision. expectedVersion := rest.NewDocVersionFromFakeRev(test.expectedRevID) - rt1.WaitForTombstone(docID, expectedVersion) - rt2.WaitForTombstone(docID, expectedVersion) + rt1.WaitForRevTreeTombstone(docID, expectedVersion) + rt2.WaitForRevTreeTombstone(docID, expectedVersion) }) } } @@ -6559,7 +6558,7 @@ func TestLocalWinsConflictResolution(t *testing.T) { activeRT.CreateReplication(replicationID, remoteURLString, db.ActiveReplicatorTypePushAndPull, nil, true, db.ConflictResolverLocalWins) activeRT.WaitForReplicationStatus(replicationID, db.ReplicationStateRunning) - remoteRT.WaitForVersion(docID, newVersion) + remoteRT.WaitForRevTreeVersion(docID, newVersion) // Stop the replication response := activeRT.SendAdminRequest("PUT", "/{{.db}}/_replicationStatus/"+replicationID+"?action=stop", "") @@ -6756,7 +6755,7 @@ func TestReplicatorConflictAttachment(t *testing.T) { activeRT.CreateReplication(replicationID, remoteURLString, db.ActiveReplicatorTypePushAndPull, nil, true, test.conflictResolution) activeRT.WaitForReplicationStatus(replicationID, db.ReplicationStateRunning) - remoteRT.WaitForVersion(docID, newVersion) + remoteRT.WaitForRevTreeVersion(docID, newVersion) response := activeRT.SendAdminRequest("PUT", "/{{.db}}/_replicationStatus/"+replicationID+"?action=stop", "") rest.RequireStatus(t, response, http.StatusOK) @@ -6788,7 +6787,7 @@ func TestReplicatorConflictAttachment(t *testing.T) { rest.RequireStatus(t, response, http.StatusOK) activeRT.WaitForVersion(docID, test.expectedFinalVersion) - remoteRT.WaitForVersion(docID, test.expectedFinalVersion) + remoteRT.WaitForRevTreeVersion(docID, test.expectedFinalVersion) localDoc := activeRT.GetDocBody(docID) localVersion := localDoc.ExtractRev() @@ -6903,7 +6902,7 @@ func TestReplicatorDoNotSendDeltaWhenSrcIsTombstone(t *testing.T) { activeCtx := activeRT.Context() // Create a document // - version := activeRT.PutDocDirectly("test", rest.JsonToMap(t, `{"field1":"f1_1","field2":"f2_1"}`)) + version := activeRT.PutDoc("test", `{"field1":"f1_1","field2":"f2_1"}`) activeRT.WaitForVersion("test", version) // Set-up replicator // @@ -6932,7 +6931,7 @@ func TestReplicatorDoNotSendDeltaWhenSrcIsTombstone(t *testing.T) { passiveRT.WaitForVersion("test", version) // Delete active document - deletedVersion := activeRT.DeleteDocDirectly("test", fullVersion) + deletedVersion := activeRT.DeleteDoc("test", fullVersion) // Assert that the tombstone is replicated to passive // Get revision 2 on passive peer to assert it has been (a) replicated and (b) deleted @@ -6943,7 +6942,7 @@ func TestReplicatorDoNotSendDeltaWhenSrcIsTombstone(t *testing.T) { passiveRT.WaitForTombstone("test", deletedVersion) // Resurrect tombstoned document - resurrectedVersion := activeRT.UpdateDocDirectly("test", fullVersion, rest.JsonToMap(t, `{"field2":"f2_2"}`)) + resurrectedVersion := activeRT.UpdateDoc("test", fullVersion, `{"field2":"f2_2"}`) // Replicate resurrection to passive // CBG-4790: different rev id being generated on active compared to remote, this wil be fixed in CBG-4791 @@ -6996,7 +6995,7 @@ func TestUnprocessableDeltas(t *testing.T) { activeCtx := activeRT.Context() // Create a document // - version := activeRT.PutDocDirectly("test", rest.JsonToMap(t, `{"field1":"f1_1","field2":"f2_1"}`)) + version := activeRT.PutDoc("test", `{"field1":"f1_1","field2":"f2_1"}`) activeRT.WaitForVersion("test", version) ar, err := db.NewActiveReplicator(activeCtx, &db.ActiveReplicatorConfig{ @@ -7015,7 +7014,7 @@ func TestUnprocessableDeltas(t *testing.T) { require.NoError(t, err) assert.Equal(t, "", ar.GetStatus(activeCtx).LastSeqPush) - assert.NoError(t, ar.Start(activeCtx)) + require.NoError(t, ar.Start(activeCtx)) // CBG-4790: different rev id being generated on active compared to remote, this wil be fixed in CBG-4791 // removing revID ot just use CV to assert @@ -7023,10 +7022,10 @@ func TestUnprocessableDeltas(t *testing.T) { version.RevTreeID = "" passiveRT.WaitForVersion("test", version) - assert.NoError(t, ar.Stop()) + require.NoError(t, ar.Stop()) // Make 2nd revision - version2 := activeRT.UpdateDocDirectly("test", fullVersion, rest.JsonToMap(t, `{"field1":"f1_2","field2":"f2_2"}`)) + version2 := activeRT.UpdateDoc("test", fullVersion, `{"field1":"f1_2","field2":"f2_2"}`) activeRT.WaitForPendingChanges() passiveRTCollection, passiveRTCtx := passiveRT.GetSingleTestDatabaseCollection() @@ -7037,14 +7036,13 @@ func TestUnprocessableDeltas(t *testing.T) { rev.BodyBytes = []byte("{invalid}") passiveRTCollection.GetRevisionCacheForTest().Upsert(base.TestCtx(t), rev) - assert.NoError(t, ar.Start(activeCtx)) + require.NoError(t, ar.Start(activeCtx)) + defer func() { assert.NoError(t, ar.Stop()) }() // Check if it replicated // CBG-4790: different rev id being generated on active compared to remote, this wil be fixed in CBG-4791 // removing revID ot just use CV to assert version2.RevTreeID = "" passiveRT.WaitForVersion("test", version2) - - assert.NoError(t, ar.Stop()) } // CBG-1428 - check for regression of ISGR not ignoring _removed:true bodies when purgeOnRemoval is disabled @@ -7068,15 +7066,15 @@ func TestReplicatorIgnoreRemovalBodies(t *testing.T) { docID := t.Name() // Create the docs // // Doc rev 1 - version1 := activeRT.PutDocDirectly(docID, rest.JsonToMap(t, `{"key":"12","channels": ["rev1chan"]}`)) + version1 := activeRT.PutDoc(docID, `{"key":"12","channels": ["rev1chan"]}`) activeRT.WaitForVersion(docID, version1) // doc rev 2 - version2 := activeRT.UpdateDocDirectly(docID, version1, rest.JsonToMap(t, `{"key":"12","channels":["rev2+3chan"]}`)) + version2 := activeRT.UpdateDoc(docID, version1, `{"key":"12","channels":["rev2+3chan"]}`) activeRT.WaitForVersion(docID, version2) // Doc rev 3 - version3 := activeRT.UpdateDocDirectly(docID, version2, rest.JsonToMap(t, `{"key":"3","channels":["rev2+3chan"]}`)) + version3 := activeRT.UpdateDoc(docID, version2, `{"key":"3","channels":["rev2+3chan"]}`) activeRT.WaitForVersion(docID, version3) activeRT.GetDatabase().FlushRevisionCacheForTest() @@ -7323,7 +7321,7 @@ func TestReplicatorDeprecatedCredentials(t *testing.T) { require.NoError(t, err) docID := "test" - version := activeRT.PutDocDirectly(docID, rest.JsonToMap(t, `{"prop":true}`)) + version := activeRT.PutDoc(docID, `{"prop":true}`) replConfig := ` { diff --git a/rest/revocation_test.go b/rest/revocation_test.go index 991f71581d..5d6bacf5a2 100644 --- a/rest/revocation_test.go +++ b/rest/revocation_test.go @@ -2224,7 +2224,7 @@ func TestRevocationMessage(t *testing.T) { // Skip to seq 4 and then create doc in channel A revocationTester.fillToSeq(4) - version := rt.PutDocDirectly("doc", db.Body{"channels": "A"}) + version := rt.PutDoc("doc", `{"channels": "A"}`) // Start pull rt.WaitForPendingChanges() @@ -2237,10 +2237,10 @@ func TestRevocationMessage(t *testing.T) { revocationTester.removeRole("user", "foo") const doc1ID = "doc1" - version = rt.PutDocDirectly(doc1ID, db.Body{"channels": "!"}) + version = rt.PutDoc(doc1ID, `{"channels": "!"}`) revocationTester.fillToSeq(10) - version = rt.UpdateDocDirectly(doc1ID, version, db.Body{}) + version = rt.UpdateDoc(doc1ID, version, `{}`) // Start a pull since 5 to receive revocation and removal rt.WaitForPendingChanges() @@ -2335,7 +2335,7 @@ func TestRevocationNoRev(t *testing.T) { // Skip to seq 4 and then create doc in channel A revocationTester.fillToSeq(4) - version := rt.PutDocDirectly(docID, db.Body{"channels": "A"}) + version := rt.PutDoc(docID, `{"channels": "A"}`) rt.WaitForPendingChanges() firstOneShotSinceSeq := rt.GetDocumentSequence("doc") @@ -2348,9 +2348,9 @@ func TestRevocationNoRev(t *testing.T) { // Remove role from user revocationTester.removeRole("user", "foo") - _ = rt.UpdateDocDirectly(docID, version, db.Body{"channels": "A", "val": "mutate"}) + _ = rt.UpdateDoc(docID, version, `{"channels": "A", "val": "mutate"}`) - waitMarkerVersion := rt.PutDocDirectly(waitMarkerID, db.Body{"channels": "!"}) + waitMarkerVersion := rt.PutDoc(waitMarkerID, `{"channels": "!"}`) rt.WaitForPendingChanges() lastSeqStr := strconv.FormatUint(firstOneShotSinceSeq, 10) @@ -2416,7 +2416,7 @@ func TestRevocationGetSyncDataError(t *testing.T) { // Skip to seq 4 and then create doc in channel A revocationTester.fillToSeq(4) - version := rt.PutDocDirectly(docID, db.Body{"channels": "A"}) + version := rt.PutDoc(docID, `{"channels": "A"}`) // OneShot pull to grab doc rt.WaitForPendingChanges() @@ -2430,9 +2430,9 @@ func TestRevocationGetSyncDataError(t *testing.T) { // Remove role from user revocationTester.removeRole("user", "foo") - _ = rt.UpdateDocDirectly(docID, version, db.Body{"channels": "A", "val": "mutate"}) + _ = rt.UpdateDoc(docID, version, `{"channels": "A", "val": "mutate"}`) - waitMarkerVersion := rt.PutDocDirectly(waitMarkerID, db.Body{"channels": "!"}) + waitMarkerVersion := rt.PutDoc(waitMarkerID, `{"channels": "!"}`) rt.WaitForPendingChanges() rt.WaitForPendingChanges() diff --git a/rest/utilities_testing.go b/rest/utilities_testing.go index 02a3c01625..43539da540 100644 --- a/rest/utilities_testing.go +++ b/rest/utilities_testing.go @@ -2434,11 +2434,15 @@ func DocVersionFromPutResponse(t testing.TB, response *TestResponse) DocVersion var r struct { DocID *string `json:"id"` RevID *string `json:"rev"` + CV *string `json:"cv"` } require.NoError(t, json.Unmarshal(response.BodyBytes(), &r)) require.NotNil(t, r.RevID, "expecting non-nil rev ID from response: %s", string(response.BodyBytes())) require.NotEqual(t, "", *r.RevID, "expecting non-empty rev ID from response: %s", string(response.BodyBytes())) - return DocVersion{RevTreeID: *r.RevID} + require.NotNil(t, r.CV, "expecting non-nil conflict vector from response: %s", string(response.BodyBytes())) + cv, err := db.ParseVersion(*r.CV) + require.NoError(t, err, "invalid CV from response: %s", string(response.BodyBytes())) + return DocVersion{RevTreeID: *r.RevID, CV: cv} } func MarshalConfig(t *testing.T, config db.ReplicationConfig) string { diff --git a/rest/utilities_testing_resttester.go b/rest/utilities_testing_resttester.go index aee3f630a1..e17c060ce6 100644 --- a/rest/utilities_testing_resttester.go +++ b/rest/utilities_testing_resttester.go @@ -93,7 +93,12 @@ func (rt *RestTester) CreateTestDoc(docid string) DocVersion { // PutDoc will upsert the document with a given contents. func (rt *RestTester) PutDoc(docID string, body string) DocVersion { - rawResponse := rt.SendAdminRequest("PUT", fmt.Sprintf("/%s/%s", rt.GetSingleKeyspace(), docID), body) + return rt.PutDocWithKeyspace(rt.GetSingleKeyspace(), docID, body) +} + +// PutDocWithKeyspace will upsert the document with a given contents in the specified keyspace. +func (rt *RestTester) PutDocWithKeyspace(keyspace, docID string, body string) DocVersion { + rawResponse := rt.SendAdminRequest("PUT", fmt.Sprintf("/%s/%s", keyspace, docID), body) RequireStatus(rt.TB(), rawResponse, 201) return DocVersionFromPutResponse(rt.TB(), rawResponse) } @@ -154,6 +159,21 @@ func (rt *RestTester) WaitForVersion(docID string, version DocVersion) { }, 10*time.Second, 50*time.Millisecond) } +// WaitForRevTreeVersion retries a GET for a given document version until it returns 200 or 201 for a given document and revtree version. If version is not found, the test will fail. +// +// This is a stub for until ISGR supports CV. +func (rt *RestTester) WaitForRevTreeVersion(docID string, version DocVersion) { + require.EventuallyWithT(rt.TB(), func(c *assert.CollectT) { + rawResponse := rt.SendAdminRequest("GET", "/{{.keyspace}}/"+docID, "") + if !assert.Contains(c, []int{200, 201}, rawResponse.Code, "Unexpected status code for %s", rawResponse.Body.String()) { + return + } + var body db.Body + require.NoError(rt.TB(), base.JSONUnmarshal(rawResponse.Body.Bytes(), &body)) + assert.Equal(c, version.RevTreeID, body.ExtractRev()) + }, 10*time.Second, 50*time.Millisecond) +} + // WaitForTombstone waits for a the document version to exist and be tombstoned. If the document is not found, the test will fail. func (rt *RestTester) WaitForTombstone(docID string, deleteVersion DocVersion) { collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser() @@ -172,6 +192,20 @@ func (rt *RestTester) WaitForTombstone(docID string, deleteVersion DocVersion) { }, time.Second*10, time.Millisecond*100) } +// WaitForRevTreeTombstone waits for a the document version to exist and be tombstoned. If the document is not found, the test will fail. +// +// This is a stub for until ISGR supports CV. +func (rt *RestTester) WaitForRevTreeTombstone(docID string, deleteVersion DocVersion) { + collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser() + require.EventuallyWithT(rt.TB(), func(c *assert.CollectT) { + doc, err := collection.GetDocument(ctx, docID, db.DocUnmarshalAll) + if !assert.NoError(c, err) { + return + } + assert.NotEqual(c, int64(0), doc.TombstonedAt) + assert.Equal(c, deleteVersion.RevTreeID, doc.SyncData.CurrentRev) + }, time.Second*10, time.Millisecond*100) +} func (rt *RestTester) WaitForCheckpointLastSequence(expectedName string) (string, error) { var lastSeq string successFunc := func() bool { @@ -452,41 +486,6 @@ func (rt *RestTester) RequireDbOnline() { require.Equal(rt.TB(), "Online", body["state"].(string)) } -// TEMPORARY HELPER METHODS FOR BLIP TEST CLIENT RUNNER -func (rt *RestTester) PutDocDirectly(docID string, body db.Body) DocVersion { - collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser() - rev, doc, err := collection.Put(ctx, docID, body) - require.NoError(rt.TB(), err) - return DocVersion{RevTreeID: rev, CV: db.Version{SourceID: doc.HLV.SourceID, Value: doc.HLV.Version}} -} - -func (rt *RestTester) UpdateDocDirectly(docID string, version DocVersion, body db.Body) DocVersion { - collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser() - body[db.BodyId] = docID - body[db.BodyRev] = version.RevTreeID - rev, doc, err := collection.Put(ctx, docID, body) - require.NoError(rt.TB(), err) - return DocVersion{RevTreeID: rev, CV: db.Version{SourceID: doc.HLV.SourceID, Value: doc.HLV.Version}} -} - -func (rt *RestTester) DeleteDocDirectly(docID string, version DocVersion) DocVersion { - collection, ctx := rt.GetSingleTestDatabaseCollectionWithUser() - // TODO: CBG-4426 - DeleteDocDirectly does not support CV - rev, doc, err := collection.DeleteDoc(ctx, docID, version.RevTreeID) - require.NoError(rt.TB(), err) - return DocVersion{RevTreeID: rev, CV: db.Version{SourceID: doc.HLV.SourceID, Value: doc.HLV.Version}} -} - -func (rt *RestTester) PutDocDirectlyInCollection(collection *db.DatabaseCollection, docID string, body db.Body) DocVersion { - dbUser := &db.DatabaseCollectionWithUser{ - DatabaseCollection: collection, - } - ctx := base.UserLogCtx(collection.AddCollectionContext(rt.Context()), "gotest", base.UserDomainBuiltin, nil) - rev, doc, err := dbUser.Put(ctx, docID, body) - require.NoError(rt.TB(), err) - return DocVersion{RevTreeID: rev, CV: db.Version{SourceID: doc.HLV.SourceID, Value: doc.HLV.Version}} -} - // PutDocWithAttachment will upsert the document with a given contents and attachments. func (rt *RestTester) PutDocWithAttachment(docID string, body string, attachmentName, attachmentBody string) DocVersion { // create new body with a 1.x style inline attachment body like `{"_attachments": {"camera.txt": {"data": "Q2Fub24gRU9TIDVEIE1hcmsgSVY="}}}`. @@ -498,7 +497,7 @@ func (rt *RestTester) PutDocWithAttachment(docID string, body string, attachment rawBody[db.BodyAttachments] = map[string]any{ attachmentName: map[string]any{"data": attachmentBody}, } - return rt.PutDocDirectly(docID, rawBody) + return rt.PutDoc(docID, string(base.MustJSONMarshal(rt.TB(), rawBody))) } type RawDocResponse struct {