Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CBG-2206: TestReplicatorDoNotSendDeltaWhenSrcIsTombstone flake #6954

Merged
merged 2 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions db/blip_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1049,17 +1049,19 @@ func (bh *blipHandler) processRev(rq *blip.Message, stats *processRevStats) (err
injectedAttachmentsForDelta = true
}

deltaSrcMap := map[string]interface{}(deltaSrcBody)
err = base.Patch(&deltaSrcMap, newDoc.Body(bh.loggingCtx))
// err should only ever be a FleeceDeltaError here - but to be defensive, handle other errors too (e.g. somehow reaching this code in a CE build)
if err != nil {
// Something went wrong in the diffing library. We want to know about this!
base.WarnfCtx(bh.loggingCtx, "Error patching deltaSrc %s with %s for doc %s with delta - err: %v", deltaSrcRevID, revID, base.UD(docID), err)
return base.HTTPErrorf(http.StatusUnprocessableEntity, "Error patching deltaSrc with delta: %s", err)
}
if !revMessage.Deleted() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't intend to support deltas for deletes (i.e. if deleted and deltaSrc properties are both specified on an incoming rev message, we should ignore deltaSrc, and perform this check up on line 1016).

deltaSrcMap := map[string]interface{}(deltaSrcBody)
err = base.Patch(&deltaSrcMap, newDoc.Body(bh.loggingCtx))
// err should only ever be a FleeceDeltaError here - but to be defensive, handle other errors too (e.g. somehow reaching this code in a CE build)
if err != nil {
// Something went wrong in the diffing library. We want to know about this!
base.WarnfCtx(bh.loggingCtx, "Error patching deltaSrc %s with %s for doc %s with delta - err: %v", deltaSrcRevID, revID, base.UD(docID), err)
return base.HTTPErrorf(http.StatusUnprocessableEntity, "Error patching deltaSrc with delta: %s", err)
}

newDoc.UpdateBody(deltaSrcMap)
base.TracefCtx(bh.loggingCtx, base.KeySync, "docID: %s - body after patching: %v", base.UD(docID), base.UD(deltaSrcMap))
newDoc.UpdateBody(deltaSrcMap)
base.TracefCtx(bh.loggingCtx, base.KeySync, "docID: %s - body after patching: %v", base.UD(docID), base.UD(deltaSrcMap))
}
stats.deltaRecvCount.Add(1)
}

Expand Down
23 changes: 20 additions & 3 deletions rest/replicatortest/replicator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7323,10 +7323,27 @@ func TestReplicatorDoNotSendDeltaWhenSrcIsTombstone(t *testing.T) {
// Delete active document
deletedVersion := activeRT.DeleteDocReturnVersion("test", version)

// Replicate tombstone to passive
// Assert that the tombstone is replicated to passive
// Get revision 2 on passive peer to assert it has been (a) replicated and (b) deleted
var rawResponse *rest.TestResponse
err = passiveRT.WaitForCondition(func() bool {
rawResponse := passiveRT.SendAdminRequest("GET", "/{{.keyspace}}/test?rev="+deletedVersion.RevID, "")
return rawResponse.Code == 404
rawResponse = passiveRT.SendAdminRequest(http.MethodGet, "/{{.keyspace}}/test?rev="+deletedVersion.RevID, "")
return rawResponse.Code == http.StatusOK
})
require.NoError(t, err)

// assert we have deleted revision
var body db.Body
require.NoError(t, base.JSONUnmarshal(rawResponse.BodyBytes(), &body))
assert.True(t, body[db.BodyDeleted].(bool))
// assert the prev body is no longer there
assert.Nil(t, body["field1"])
assert.Nil(t, body["field2"])

// Perform get on docID on passive peer and assert that we get 404 code
err = passiveRT.WaitForCondition(func() bool {
rawResponse = passiveRT.SendAdminRequest(http.MethodGet, "/{{.keyspace}}/test", "")
return rawResponse.Code == http.StatusNotFound
})
require.NoError(t, err)

Expand Down
Loading