Skip to content

Commit b357171

Browse files
committed
Relax assertion for CBS resurrection
1 parent 5a29d5b commit b357171

7 files changed

+86
-29
lines changed

topologytest/couchbase_lite_mock_peer_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ func (p *CouchbaseLiteMockPeer) WaitForDocVersion(dsName sgbucket.DataStoreName,
142142
return body
143143
}
144144

145+
// WaitForCV waits for a document to reach a specific CV. Returns the state of the document at that version. The test will fail if the document does not reach the expected version in 20s.
146+
func (p *CouchbaseLiteMockPeer) WaitForCV(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) db.Body {
147+
var data []byte
148+
require.EventuallyWithT(p.TB(), func(c *assert.CollectT) {
149+
var actual *DocMetadata
150+
data, actual = p.getLatestDocVersion(dsName, docID)
151+
if !assert.NotNil(c, actual, "Could not find docID:%+v on %p\nVersion %#v", docID, p, expected) {
152+
return
153+
}
154+
assertCVEqual(c, docID, p.name, *actual, data, expected, replications)
155+
}, totalWaitTime, pollInterval)
156+
var body db.Body
157+
require.NoError(p.TB(), base.JSONUnmarshal(data, &body))
158+
return body
159+
}
160+
145161
// WaitForTombstoneVersion waits for a document to reach a specific version, this must be a tombstone. The test will fail if the document does not reach the expected version in 20s.
146162
func (p *CouchbaseLiteMockPeer) WaitForTombstoneVersion(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) {
147163
client := p.getSingleSGBlipClient().CollectionClient(dsName)

topologytest/couchbase_server_peer_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,14 @@ func (p *CouchbaseServerPeer) WaitForDocVersion(dsName sgbucket.DataStoreName, d
184184
return body
185185
}
186186

187+
// WaitForCV waits for a document to reach a specific CV. The test will fail if the document does not reach the expected version in 20s.
188+
func (p *CouchbaseServerPeer) WaitForCV(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) db.Body {
189+
docBytes := p.waitForCV(dsName, docID, expected, replications)
190+
var body db.Body
191+
require.NoError(p.TB(), base.JSONUnmarshal(docBytes, &body), "couldn't unmarshal docID %s: %s", docID, docBytes)
192+
return body
193+
}
194+
187195
// WaitForTombstoneVersion waits for a document to reach a specific version, this must be a tombstone. The test will fail if the document does not reach the expected version in 20s.
188196
func (p *CouchbaseServerPeer) WaitForTombstoneVersion(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) {
189197
docBytes := p.waitForDocVersion(dsName, docID, expected, replications)
@@ -208,6 +216,24 @@ func (p *CouchbaseServerPeer) waitForDocVersion(dsName sgbucket.DataStoreName, d
208216
return docBytes
209217
}
210218

219+
// waitForCV waits for a document to reach a specific CV and returns the body in bytes. The bytes will be nil if the document is a tombstone. The test will fail if the document does not reach the expected version in 20s.
220+
func (p *CouchbaseServerPeer) waitForCV(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) []byte {
221+
var docBytes []byte
222+
var version DocMetadata
223+
require.EventuallyWithT(p.TB(), func(c *assert.CollectT) {
224+
var err error
225+
var xattrs map[string][]byte
226+
var cas uint64
227+
docBytes, xattrs, cas, err = p.getCollection(dsName).GetWithXattrs(p.Context(), docID, metadataXattrNames)
228+
if !assert.NoError(c, err) {
229+
return
230+
}
231+
version = getDocVersion(docID, p, cas, xattrs)
232+
assertCVEqual(c, docID, p.name, version, docBytes, expected, replications)
233+
}, totalWaitTime, pollInterval)
234+
return docBytes
235+
}
236+
211237
// Close will shut down the peer and close any active replications on the peer.
212238
func (p *CouchbaseServerPeer) Close() {
213239
for _, r := range p.pullReplications {

topologytest/hlv_test.go

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515

1616
"github.com/couchbase/sync_gateway/base"
1717
"github.com/couchbase/sync_gateway/db"
18-
"github.com/stretchr/testify/assert"
1918
"github.com/stretchr/testify/require"
2019
)
2120

@@ -60,6 +59,15 @@ func waitForVersionAndBody(t *testing.T, dsName base.ScopeAndCollectionName, pee
6059
}
6160
}
6261

62+
// waitForCVAndBody waits for a document to reach a specific cv on all peers.
63+
func waitForCVAndBody(t *testing.T, dsName base.ScopeAndCollectionName, peers Peers, replications Replications, docID string, expectedVersion BodyAndVersion) {
64+
t.Logf("waiting for doc version on all peers, written from %s: %#v", expectedVersion.updatePeer, expectedVersion)
65+
for _, peer := range peers.SortedPeers() {
66+
t.Logf("waiting for doc version on peer %s, written from %s: %#v", peer, expectedVersion.updatePeer, expectedVersion)
67+
body := peer.WaitForCV(dsName, docID, expectedVersion.docMeta, replications)
68+
requireBodyEqual(t, expectedVersion.body, body)
69+
}
70+
}
6371
func waitForTombstoneVersion(t *testing.T, dsName base.ScopeAndCollectionName, peers Peers, replications Replications, docID string, expectedVersion BodyAndVersion) {
6472
t.Logf("waiting for tombstone version on all peers, written from %s: %#v", expectedVersion.updatePeer, expectedVersion)
6573
for _, peer := range peers.SortedPeers() {
@@ -156,31 +164,6 @@ func getDocID(t *testing.T) string {
156164
return fmt.Sprintf("doc_%s", name)
157165
}
158166

159-
// waitForConvergingVersion waits for the same document version to reach all peers.
160-
func waitForConvergingVersion(t *testing.T, dsName base.ScopeAndCollectionName, peers Peers, replications Replications, docID string) {
161-
t.Logf("waiting for converged doc versions across all peers")
162-
var docMetaA DocMetadata
163-
var bodyA db.Body
164-
if !assert.EventuallyWithT(t, func(c *assert.CollectT) {
165-
for peerAid, peerA := range peers.SortedPeers() {
166-
docMetaA, bodyA = peerA.GetDocument(dsName, docID)
167-
for peerBid, peerB := range peers.SortedPeers() {
168-
if peerAid == peerBid {
169-
continue
170-
}
171-
docMetaB, bodyB := peerB.GetDocument(dsName, docID)
172-
cvA, cvB := docMetaA.CV(t), docMetaB.CV(t)
173-
require.Equalf(c, cvA, cvB, "CV mismatch: %s:%#v != %s:%#v", peerAid, docMetaA, peerBid, docMetaB)
174-
require.Equalf(c, bodyA, bodyB, "body mismatch: %s:%s != %s:%s", peerAid, bodyA, peerBid, bodyB)
175-
}
176-
}
177-
}, totalWaitTime, pollInterval) {
178-
// do if !assert->require pattern so we can delay PrintGlobalDocState evaluation
179-
require.FailNowf(t, "Peers did not converge on version", "Global state for doc %q on all peers:\n%s\nReplications: %s", docID, peers.PrintGlobalDocState(t, dsName, docID), replications)
180-
}
181-
t.Logf("Peers converged on %q version: %#+v body %s", docID, docMetaA, bodyA)
182-
}
183-
184167
// PrintGlobalDocState returns the current state of a document across all peers, and also logs it on `t`.
185168
func (p Peers) PrintGlobalDocState(t testing.TB, dsName base.ScopeAndCollectionName, docID string) string {
186169
var globalState strings.Builder

topologytest/multi_actor_no_conflict_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ func TestMultiActorResurrect(t *testing.T) {
102102

103103
resBody := []byte(fmt.Sprintf(`{"activePeer": "%s", "createPeer": "%s", "deletePeer": "%s", "resurrectPeer": "%s", "topology": "%s", "action": "resurrect"}`, resurrectPeerName, createPeerName, deletePeer, resurrectPeer, topology.description))
104104
resurrectVersion := resurrectPeer.WriteDocument(collectionName, docID, resBody)
105-
waitForVersionAndBody(t, collectionName, peers, replications, docID, resurrectVersion)
105+
// in the case of a Couchbase Server resurrection, the hlv is lost since all system xattrs are lost on a resurrection
106+
if resurrectPeer.Type() == PeerTypeCouchbaseServer {
107+
waitForCVAndBody(t, collectionName, peers, replications, docID, resurrectVersion)
108+
} else {
109+
waitForVersionAndBody(t, collectionName, peers, replications, docID, resurrectVersion)
110+
}
106111
})
107112
}
108113
}

topologytest/peer_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ type Peer interface {
5151
// WaitForDocVersion waits for a document to reach a specific version. Returns the state of the document at that version. The test will fail if the document does not reach the expected version in 20s.
5252
WaitForDocVersion(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) db.Body
5353

54+
// WaitForCV waits for a document to reach a specific CV. Returns the state of the document at that version. The test will fail if the document does not reach the expected version in 20s.
55+
WaitForCV(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) db.Body
56+
5457
// WaitForTombstoneVersion waits for a document to reach a specific version. This document must be a tombstone. The test will fail if the document does not reach the expected version in 20s.
5558
WaitForTombstoneVersion(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications)
5659

topologytest/sync_gateway_peer_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,25 @@ func (p *SyncGatewayPeer) WaitForDocVersion(dsName sgbucket.DataStoreName, docID
153153
return doc.Body(ctx)
154154
}
155155

156+
// WaitForCV waits for a document to reach a specific CV. The test will fail if the document does not reach the expected version in 20s.
157+
func (p *SyncGatewayPeer) WaitForCV(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) db.Body {
158+
collection, ctx := p.getCollection(dsName)
159+
var doc *db.Document
160+
require.EventuallyWithT(p.TB(), func(c *assert.CollectT) {
161+
var err error
162+
doc, err = collection.GetDocument(ctx, docID, db.DocUnmarshalAll)
163+
assert.NoError(c, err)
164+
if doc == nil {
165+
return
166+
}
167+
version := DocMetadataFromDocument(doc)
168+
bodyBytes, err := doc.BodyBytes(ctx)
169+
assert.NoError(c, err)
170+
assertCVEqual(c, docID, p.name, version, bodyBytes, expected, replications)
171+
}, totalWaitTime, pollInterval)
172+
return doc.Body(ctx)
173+
}
174+
156175
// WaitForTombstoneVersion waits for a document to reach a specific version, this must be a tombstone. The test will fail if the document does not reach the expected version in 20s.
157176
func (p *SyncGatewayPeer) WaitForTombstoneVersion(dsName sgbucket.DataStoreName, docID string, expected DocMetadata, replications Replications) {
158177
docBytes := p.WaitForDocVersion(dsName, docID, expected, replications)

topologytest/version_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ type DocMetadata struct {
2929
}
3030

3131
// CV returns the current version of the document.
32-
func (v DocMetadata) CV(t require.TestingT) db.Version {
32+
func (v DocMetadata) CV(t assert.TestingT) db.Version {
3333
if v.ImplicitHLV != nil {
3434
return *v.ImplicitHLV.ExtractCurrentVersionFromHLV()
3535
} else if v.HLV != nil {
3636
return *v.HLV.ExtractCurrentVersionFromHLV()
3737
}
38-
require.FailNowf(t, "no hlv available", "%#v", v)
38+
assert.FailNowf(t, "no hlv available", "%#v", v)
3939
return db.Version{}
4040
}
4141

@@ -92,3 +92,8 @@ func DocMetadataFromDocVersion(t testing.TB, docID string, hlv *db.HybridLogical
9292
func assertHLVEqual(t assert.TestingT, docID string, p string, version DocMetadata, body []byte, expected DocMetadata, replications Replications) {
9393
assert.True(t, version.IsHLVEqual(expected), "Actual HLV does not match expected on %s for peer %s. Expected: %#v, Actual: %#v\nActual Body: %s\nReplications:\n%s", docID, p, expected, version, body, replications.Stats())
9494
}
95+
96+
// assertCV asserts that CV of the version is equal to the expected CV.
97+
func assertCVEqual(t assert.TestingT, docID string, p string, version DocMetadata, body []byte, expected DocMetadata, replications Replications) {
98+
assert.Equal(t, expected.CV(t), version.CV(t), "Actual HLV's CV does not match expected on %s for peer %s. Expected: %#v, Actual: %#v\nActual Body: %s\nReplications:\n%s", docID, p, expected, version, body, replications.Stats())
99+
}

0 commit comments

Comments
 (0)