Skip to content

Commit 99b215d

Browse files
torcolvinbbrksclaude
committed
[4.1.2 Backport] CBG-5547: Fix norev handling in BlipTesterCollectionClient
Cherry-picked from be474ebbdd0c8b0f26ba9c1c3b56cd6f83e9df15 (CBG-5547, #8459) and 1646aec (CBG-5547, #8552), squashed. rest/cbl_conflict_test.go imports github.com/stretchr/testify for assert and require instead of the testing/assert and testing/require wrappers, which 4.1.2 does not have. Co-authored-by: Tor Colvin <tor.colvin@couchbase.com> Co-authored-by: Ben Brooks <ben.brooks@couchbase.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 76d9a40 commit 99b215d

3 files changed

Lines changed: 354 additions & 174 deletions

File tree

rest/blip_api_crud_test.go

Lines changed: 5 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,18 +1964,12 @@ func TestSendReplacementRevision(t *testing.T) {
19641964
base.RequireWaitForStat(t, rt.GetDatabase().DbStats.CBLReplicationPull().NoRevSendCount.Value, 0)
19651965
} else {
19661966
// requested revision (or any alternative) did not get replicated
1967-
data := btcRunner.SingleCollection(btc.id).WaitForVersion(docID, version1)
1968-
assert.Nil(t, data)
1967+
btcRunner.SingleCollection(btc.id).WaitForPullNoRevMessage(docID, version1)
19691968

19701969
// no message for rev 2
19711970
_, ok := btcRunner.SingleCollection(btc.id).GetPullRevMessage(docID, version2)
19721971
require.False(t, ok)
19731972

1974-
// norev message for the requested rev
1975-
msg, ok := btcRunner.SingleCollection(btc.id).GetPullRevMessage(docID, version1)
1976-
require.True(t, ok)
1977-
assert.Equal(t, db.MessageNoRev, msg.Profile())
1978-
19791973
base.RequireWaitForStat(t, rt.GetDatabase().DbStats.CBLReplicationPull().NoRevSendCount.Value, 1)
19801974
base.RequireWaitForStat(t, rt.GetDatabase().DbStats.CBLReplicationPull().ReplacementRevSendCount.Value, 0)
19811975
}
@@ -3097,11 +3091,8 @@ func TestImportInvalidSyncGetsNoRev(t *testing.T) {
30973091
require.NoError(t, err)
30983092

30993093
btcRunner.StartOneshotPull(btc.id)
3100-
msg := btcRunner.WaitForPullRevMessage(btc.id, docID, version)
3101-
require.Equal(t, db.MessageNoRev, msg.Profile())
3102-
3103-
msg = btcRunner.WaitForPullRevMessage(btc.id, docID2, version2)
3104-
require.Equal(t, db.MessageNoRev, msg.Profile())
3094+
btcRunner.WaitForPullNoRevMessage(btc.id, docID, version)
3095+
btcRunner.WaitForPullNoRevMessage(btc.id, docID2, version2)
31053096
})
31063097
}
31073098

@@ -3220,8 +3211,7 @@ func TestOnDemandImportBlipFailure(t *testing.T) {
32203211

32213212
btcRunner.StartOneshotPull(btc2.id)
32223213

3223-
msg := btcRunner.WaitForPullRevMessage(btc2.id, docID, revID)
3224-
require.Equal(t, db.MessageNoRev, msg.Profile())
3214+
btcRunner.WaitForPullNoRevMessage(btc2.id, docID, revID)
32253215
})
32263216
}
32273217
})
@@ -3501,57 +3491,6 @@ func TestBlipPushRevOnResurrection(t *testing.T) {
35013491
})
35023492
}
35033493

3504-
func TestBlipPullConflict(t *testing.T) {
3505-
base.SetUpTestLogging(t, base.LevelDebug, base.KeySync, base.KeySyncMsg, base.KeySGTest)
3506-
btcRunner := NewBlipTesterClientRunner(t)
3507-
3508-
btcRunner.SkipSubtest[RevtreeSubtestName] = true
3509-
3510-
btcRunner.Run(func(t *testing.T) {
3511-
rt := NewRestTesterPersistentConfig(t)
3512-
defer rt.Close()
3513-
3514-
const (
3515-
alice = "alice"
3516-
cblBody = `{"actor": "cbl"}`
3517-
sgBody = `{"actor": "sg"}`
3518-
docID = "doc1"
3519-
)
3520-
rt.CreateUser(alice, []string{"*"})
3521-
sgVersion := rt.PutDoc(docID, `{"actor": "sg"}`)
3522-
rt.WaitForPendingChanges()
3523-
3524-
opts := &BlipTesterClientOpts{
3525-
Username: alice,
3526-
}
3527-
btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, opts)
3528-
defer btc.Close()
3529-
3530-
client := btcRunner.SingleCollection(btc.id)
3531-
preConflictCBLVersion := btcRunner.AddRev(btc.id, docID, EmptyDocVersion(), []byte(cblBody))
3532-
require.NotEqual(t, sgVersion, preConflictCBLVersion)
3533-
_, preConflictHLV, _ := client.GetDoc(docID)
3534-
require.Empty(t, preConflictHLV.PreviousVersions)
3535-
require.Empty(t, preConflictHLV.MergeVersions)
3536-
3537-
btcRunner.StartOneshotPull(btc.id)
3538-
3539-
// expect resolution as CBL wins (local wins)
3540-
require.EventuallyWithT(t, func(c *assert.CollectT) {
3541-
body, postConflictHLV, _ := client.GetDoc(docID)
3542-
assert.Equal(c, db.HybridLogicalVector{
3543-
CurrentVersionCAS: 0,
3544-
Version: preConflictCBLVersion.CV.Value,
3545-
SourceID: preConflictCBLVersion.CV.SourceID,
3546-
PreviousVersions: db.HLVVersions{
3547-
sgVersion.CV.SourceID: sgVersion.CV.Value,
3548-
},
3549-
}, *postConflictHLV)
3550-
assert.Equal(c, string(body), cblBody)
3551-
}, time.Second*10, time.Millisecond*10)
3552-
})
3553-
}
3554-
35553494
func TestManyChannelsRemovedOnDocUpdate(t *testing.T) {
35563495
base.SetUpTestLogging(t, base.LevelDebug, base.KeyHTTP, base.KeySync, base.KeySyncMsg, base.KeyChanges, base.KeyCache, base.KeySGTest)
35573496

@@ -3766,113 +3705,7 @@ func TestBlipNoRevOnCorruptHistory(t *testing.T) {
37663705
expectedVersion := DocVersion{RevTreeID: "3-c"}
37673706

37683707
btcRunner.StartOneshotPull(btc.id)
3769-
msg := btcRunner.WaitForPullRevMessage(btc.id, docID, expectedVersion)
3770-
require.Equal(t, db.MessageNoRev, msg.Profile())
3771-
})
3772-
}
3773-
3774-
func TestBlipNoRevOnCorruptHistoryDelta(t *testing.T) {
3775-
base.TestRequiresDeltaSync(t)
3776-
base.SetUpTestLogging(t, base.LevelDebug, base.KeyHTTP, base.KeySync, base.KeySyncMsg, base.KeyCache, base.KeyCRUD, base.KeySGTest)
3777-
btcRunner := NewBlipTesterClientRunner(t)
3778-
// a norev message is only sent on delta sync when v2 protocol is used, otherwise the deleted flag on a changes
3779-
// message is used
3780-
btcRunner.RunSubprotocolV2(func(t *testing.T) {
3781-
rt := NewRestTester(t,
3782-
&RestTesterConfig{
3783-
PersistentConfig: true,
3784-
SyncFn: channels.DocChannelsSyncFunction,
3785-
},
3786-
)
3787-
defer rt.Close()
3788-
3789-
dbConfig := rt.NewDbConfig()
3790-
dbConfig.DeltaSync = &DeltaSyncConfig{Enabled: base.Ptr(true)}
3791-
dbConfig.AutoImport = false
3792-
RequireStatus(t, rt.CreateDatabase("db", dbConfig), http.StatusCreated)
3793-
3794-
const user = "user"
3795-
const channelA = "A"
3796-
rt.CreateUser(user, []string{channelA})
3797-
btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, &BlipTesterClientOpts{
3798-
Username: user,
3799-
ClientDeltas: true,
3800-
})
3801-
defer btc.Close()
3802-
3803-
ctx := rt.Context()
3804-
docID := SafeDocumentName(t, t.Name())
3805-
docRev1 := rt.CreateDocNoHLV(docID, db.Body{"delta": true, "channels": []string{channelA}})
3806-
btcRunner.StartOneshotPull(btc.id)
3807-
btcRunner.WaitForVersion(btc.id, docID, DocVersion{RevTreeID: docRev1.GetRevTreeID()})
3808-
seq, err := rt.GetDatabase().NextSequence(ctx)
3809-
require.NoError(t, err)
3810-
// document contains an invalid revtree
3811-
//
3812-
// 3-c is a child of 3-d, a revision must be one or more generations higher than it its parent, not equal
3813-
badSyncRaw := `{
3814-
"cas": "expand",
3815-
"channel_set": [
3816-
{
3817-
"end": {{.rev3seq}},
3818-
"name": "A",
3819-
"start": {{.rev1seq}}
3820-
}
3821-
],
3822-
"channels": {
3823-
"A": {
3824-
"rev": "{{.rev1}}",
3825-
"seq": {{.rev3seq}}
3826-
}
3827-
},
3828-
"channel_set_history": null,
3829-
"history": {
3830-
"parents": [
3831-
3,
3832-
0,
3833-
-1,
3834-
2
3835-
],
3836-
"revs": [
3837-
"3-d",
3838-
"3-c",
3839-
"{{.rev1}}",
3840-
"2-b"
3841-
]
3842-
},
3843-
"rev": "3-c",
3844-
"sequence": {{.rev3seq}},
3845-
"value_crc32c": "expand"
3846-
}`
3847-
tmpl := template.Must(template.New("badSync").Option("missingkey=error").Parse(badSyncRaw))
3848-
var badSyncData bytes.Buffer
3849-
require.NoError(t, tmpl.Execute(&badSyncData, map[string]any{
3850-
"rev1": docRev1.GetRevTreeID(),
3851-
"rev1seq": docRev1.Sequence,
3852-
"rev3seq": seq,
3853-
}))
3854-
3855-
mutateInOptions := db.DefaultMutateInOpts()
3856-
_, err = rt.GetSingleDataStore().WriteWithXattrs(
3857-
ctx,
3858-
docID,
3859-
0,
3860-
docRev1.Cas,
3861-
[]byte(`{"key":"value"}`),
3862-
map[string][]byte{
3863-
base.SyncXattrName: badSyncData.Bytes(),
3864-
},
3865-
nil,
3866-
mutateInOptions,
3867-
)
3868-
require.NoError(t, err)
3869-
3870-
rt.WaitForPendingChanges()
3871-
expectedVersion := DocVersion{RevTreeID: "3-c"}
3872-
3873-
btcRunner.StartOneshotPull(btc.id)
3874-
msg := btcRunner.WaitForPullRevMessage(btc.id, docID, expectedVersion)
3875-
require.Equal(t, db.MessageNoRev, msg.Profile())
3708+
btcRunner.WaitForPullNoRevMessage(btc.id, docID, expectedVersion)
38763709
})
38773710
}
38783711

0 commit comments

Comments
 (0)