TestAssignSequenceReleaseLoop repros conditions seen in CBG-3516 (where each sequence between nextSequence and docSequence has an unusedSeq doc)
(t *testing.T)
| 1552 | |
| 1553 | // TestAssignSequenceReleaseLoop repros conditions seen in CBG-3516 (where each sequence between nextSequence and docSequence has an unusedSeq doc) |
| 1554 | func TestAssignSequenceReleaseLoop(t *testing.T) { |
| 1555 | if !base.TestUseXattrs() { |
| 1556 | t.Skip("This test only works with XATTRS enabled") |
| 1557 | } |
| 1558 | |
| 1559 | base.SetUpTestLogging(t, base.LevelDebug, base.KeyCache, base.KeyChanges, base.KeyCRUD, base.KeyDCP) |
| 1560 | |
| 1561 | // import disabled |
| 1562 | db, ctx := SetupTestDBWithOptions(t, DatabaseContextOptions{}) |
| 1563 | defer db.Close(ctx) |
| 1564 | |
| 1565 | // positive sequence gap (other cluster's sequencing is higher) |
| 1566 | const otherClusterSequenceOffset = 10 |
| 1567 | |
| 1568 | startReleasedSequenceCount := db.DbStats.Database().SequenceReleasedCount.Value() |
| 1569 | |
| 1570 | collection, ctx := GetSingleDatabaseCollectionWithUser(ctx, t, db) |
| 1571 | rev, doc, err := collection.Put(ctx, "doc1", Body{"foo": "bar"}) |
| 1572 | require.NoError(t, err) |
| 1573 | t.Logf("doc sequence: %d", doc.Sequence) |
| 1574 | |
| 1575 | // but we can fiddle with the sequence in the metadata of the doc write to simulate a doc from a different cluster (with a higher sequence) |
| 1576 | var newSyncData map[string]interface{} |
| 1577 | sd, err := json.Marshal(doc.SyncData) |
| 1578 | require.NoError(t, err) |
| 1579 | err = json.Unmarshal(sd, &newSyncData) |
| 1580 | require.NoError(t, err) |
| 1581 | newSyncData["sequence"] = doc.SyncData.Sequence + otherClusterSequenceOffset |
| 1582 | _, err = collection.dataStore.UpdateXattrs(ctx, doc.ID, 0, doc.Cas, map[string][]byte{base.SyncXattrName: base.MustJSONMarshal(t, newSyncData)}, DefaultMutateInOpts()) |
| 1583 | require.NoError(t, err) |
| 1584 | |
| 1585 | _, doc, err = collection.Put(ctx, "doc1", Body{"foo": "buzz", BodyRev: rev}) |
| 1586 | require.NoError(t, err) |
| 1587 | require.Greaterf(t, doc.Sequence, uint64(otherClusterSequenceOffset), "Expected new doc sequence %d to be greater than other cluster's sequence %d", doc.Sequence, otherClusterSequenceOffset) |
| 1588 | |
| 1589 | // wait for the doc to be received |
| 1590 | err = db.changeCache.waitForSequence(ctx, doc.Sequence, time.Second*30) |
| 1591 | require.NoError(t, err) |
| 1592 | |
| 1593 | expectedReleasedSequenceCount := otherClusterSequenceOffset |
| 1594 | releasedSequenceCount := db.DbStats.Database().SequenceReleasedCount.Value() - startReleasedSequenceCount |
| 1595 | assert.Equal(t, int64(expectedReleasedSequenceCount), releasedSequenceCount) |
| 1596 | } |
| 1597 | |
| 1598 | // TestReleaseSequenceOnDocWrite: |
| 1599 | // - Define a leaky bucket callback for a conflicting write + define key to return a timeout error for |
nothing calls this directly
no test coverage detected