Skip to content

Commit 54a6022

Browse files
committed
add XL blob + short_expiry dataset, for QE tests
1 parent 8d8c370 commit 54a6022

11 files changed

Lines changed: 1238 additions & 59 deletions

File tree

client/src/cbltest/api/syncgateway.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,12 @@ def replication_url(self, db_name: str):
427427
_assert_not_null(db_name, "db_name")
428428
return urljoin(self.__replication_url, db_name)
429429

430+
def get_expvars(self):
431+
"""
432+
Gets the expvars for the Sync Gateway
433+
"""
434+
return urljoin(self.__admin_url, "_expvar")
435+
430436
async def _put_database(
431437
self, db_name: str, payload: PutDatabasePayload, retry_count: int = 0
432438
) -> None:
@@ -740,6 +746,54 @@ async def update_documents(
740746
JSONDictionary(body),
741747
)
742748

749+
async def upsert_documents(
750+
self,
751+
db_name: str,
752+
updates: list[DocumentUpdateEntry],
753+
scope: str = "_default",
754+
collection: str = "_default",
755+
) -> None:
756+
"""
757+
Upserts a list of documents on Sync Gateway.
758+
Its different from update_documents in that it will not overwrite the doc body in case the
759+
doc already exists.
760+
It will preserve the existing body fields and only add / update whatever is being passed,
761+
like the behaviour shown by the function batch_upsert used in CBL updates.
762+
763+
:param db_name: The name of the DB endpoint to upsert
764+
:param updates: A list of upserts to perform
765+
:param scope: The scope that the upserts will be applied to (default '_default')
766+
:param collection: The collection that the upserts will be applied to (default '_default')
767+
"""
768+
with self.__tracer.start_as_current_span(
769+
"update_documents",
770+
attributes={
771+
"cbl.database.name": db_name,
772+
"cbl.scope.name": scope,
773+
"cbl.collection.name": collection,
774+
},
775+
):
776+
merged_updates = []
777+
for update in updates:
778+
try:
779+
current_doc = await self.get_document(db_name, update.id, scope, collection)
780+
current_body = dict(current_doc.body)
781+
current_body.update(update.to_json())
782+
current_body["_id"] = update.id
783+
if update.rev:
784+
current_body["_rev"] = update.rev
785+
except Exception:
786+
current_body = update.to_json()
787+
merged_updates.append(DocumentUpdateEntry(update.id, update.rev, current_body))
788+
789+
await self._rewrite_rev_ids(db_name, merged_updates, scope, collection)
790+
body = {"docs": list(u.to_json() for u in merged_updates)}
791+
await self._send_request(
792+
"post",
793+
f"/{db_name}.{scope}.{collection}/_bulk_docs",
794+
JSONDictionary(body),
795+
)
796+
743797
@deprecated("Only should be used until 4.0 SGW gets close to GA")
744798
async def _replaced_revid(
745799
self, doc_id: str, revid: str, db_name: str, scope: str, collection: str

dataset/server/blobs/xl1.jpg

Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"config": {
3+
"bucket": "posts",
4+
"old_rev_expiry_seconds": 60,
5+
"scopes": {
6+
"_default": {
7+
"collections": {
8+
"_default": {
9+
"sync": "function foo(doc,oldDoc,meta){if(doc._deleted){channel(oldDoc.channels)}else{channel(doc.channels)}}"
10+
}
11+
}
12+
}
13+
},
14+
"num_index_replicas": 0
15+
},
16+
"config_options": {
17+
"delta_sync": {
18+
"delta_sync": {
19+
"enabled": true,
20+
"rev_max_age_seconds": 60
21+
}
22+
},
23+
"delta_sync_with_expiry": {
24+
"delta_sync": {
25+
"enabled": true,
26+
"rev_max_age_seconds": 60
27+
}
28+
}
29+
},
30+
"users": {
31+
"user1": {
32+
"password": "pass",
33+
"collection_access": {
34+
"_default": {
35+
"_default": {
36+
"admin_channels": ["*"]
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}

dataset/sg/short_expiry-sg.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"_id": "doc1", "scope": "_default", "collection": "_default", "channels": ["*"], "type": "test", "value": "This is a test document for short_expiry dataset."}

jenkins/pipelines/QE/ios/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ pushd "${QE_TESTS_DIR}" > /dev/null
3232
create_venv venv
3333
. venv/bin/activate
3434
pip install -r requirements.txt
35-
pytest -v --no-header -W ignore::DeprecationWarning --config config.json test_delta_sync.py::TestDeltaSync::test_delta_sync_utf8_strings
35+
pytest -v --no-header -W ignore::DeprecationWarning --config config.json test_replication_eventing.py
3636
deactivate
3737
popd > /dev/null

spec/dataset/blobs.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
| l9.jpg | image/jpeg | sha1-sKmH8rJtV3JardoWTE7nJ1yk0gE= | 2838244 |
1616
| l10.jpg | image/jpeg | sha1-TSC2gaaEZbi0kC3zBwdzc7wIOcc= | 1986238 |
1717

18+
## Extra Large Size
19+
20+
| name | content_type | digest | length |
21+
| :------- | ------------ | ------------------------------------------- | --------- |
22+
| xl1.jpg | image/jpeg | sha1-35626dfbdafb966833ee60121cb7edcf9884bd3f | 21200000 |
23+
1824
## Small Size
1925

2026
| name | content_type | digest | length |

spec/dataset/dataset.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,4 +547,63 @@ curl --location --request POST 'http://<sg-address>:4985/todo/_role/' \
547547
"owner" : "user1"
548548
}
549549
}
550+
```
551+
552+
## 5. short_expiry
553+
554+
### CBL Dataset
555+
556+
| Collections | #Docs |
557+
| :------------------ | ----------- |
558+
| _default._default | 1 | doc1 |
559+
560+
### SG Dataset
561+
562+
| Collections | #Docs | Doc ID |
563+
| :------------------ | ----------- | -----------------|
564+
| _default._default | 1 | doc1 |
565+
566+
### SG Config
567+
568+
| Config | Value |
569+
| ----------- | ------------------|
570+
| Database | short_expiry |
571+
| Port | 4984 / 4985 |
572+
| Collections | _default._default |
573+
574+
#### Sync Function
575+
576+
```js
577+
function (doc, oldDoc, meta) {
578+
if (doc._deleted) {
579+
channel(oldDoc.channels)
580+
} else {
581+
channel(doc.channels)
582+
}
583+
}
584+
```
585+
586+
#### Options
587+
588+
| Name | Description |
589+
| ----------------- | --------------------- |
590+
| delta_sync | Enabled, 3 min expiry |
591+
592+
#### Users
593+
594+
| Username | Password | admin_channels |
595+
| :------- | --------- |----------------|
596+
| user1 | pass | ["*"] |
597+
598+
### Sample Docs
599+
600+
```JSON
601+
{
602+
"_id": "doc1",
603+
"scope": "_default",
604+
"collection": "_default",
605+
"channels": ["*"],
606+
"type": "test",
607+
"value": "This is a test document for short_expiry dataset."
608+
}
550609
```

spec/tests/QE/test_delta_sync.md

Lines changed: 97 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ Verify push/pull replication works with large data and delta sync. Ensures that
1515
7. Start push-pull replication and verify only the updated documents are processed due to delta sync.
1616
8. Check delta sync stats for number of docs updated.
1717

18+
### Key Assertions
19+
- The number of processed documents after modification matches the number of changed documents.
20+
- No unnecessary documents are replicated.
21+
- The document IDs of updated documents match the expected set.
22+
- The document count in the database remains consistent before and after delta sync replication.
23+
1824
## #2 test_delta_sync_nested_doc
1925

2026
### Description
@@ -30,22 +36,97 @@ Verify delta sync works with nested documents. Ensures that only changed nested
3036
7. Start push-pull replication and verify only the updated nested document is processed due to delta sync.
3137
8. Check delta sync stats for number of docs updated.
3238

33-
## Purpose
34-
This test verifies delta sync functionality in Couchbase Lite and Sync Gateway. It ensures that only changed documents are processed and replicated, and that delta sync bandwidth savings are realized.
35-
36-
## Test Steps
37-
1. **Setup**: Reset Sync Gateway and load the required dataset with delta sync enabled.
38-
2. **Database Initialization**: Reset the local database and load the dataset.
39-
3. **Initial Replication**: Start a replicator and perform initial replication to ensure all documents are present.
40-
4. **Document Modification**: Modify a subset of documents in Couchbase Lite.
41-
5. **Delta Sync Replication**: Start replication again and verify that only the modified documents are processed due to delta sync.
42-
6. **Assertions**:
43-
- Only the changed documents are processed during the second replication.
44-
- The total document count remains unchanged.
45-
- Delta sync is enabled and functioning as expected.
46-
47-
## Key Assertions
39+
### Key Assertions
4840
- The number of processed documents after modification matches the number of changed documents.
4941
- No unnecessary documents are replicated.
5042
- The document IDs of updated documents match the expected set.
51-
- The document count in the database remains consistent before and after delta sync replication.
43+
- The document count in the database remains consistent before and after delta sync replication.
44+
45+
## #3 test_delta_sync_utf8_strings
46+
47+
### Description
48+
Verify delta sync works with documents containing large UTF-8 strings. Ensures that delta sync can handle multi-byte and non-ASCII data efficiently.
49+
50+
### Steps
51+
1. Reset Sync Gateway and load the `travel` dataset with delta sync enabled.
52+
2. Reset the local database and load the `travel` dataset.
53+
3. Start a replicator and perform initial replication.
54+
4. Create a document in Couchbase Lite with a large UTF-8 string field.
55+
5. Push the document to Sync Gateway.
56+
6. Update the document in Sync Gateway with a new UTF-8 string value.
57+
7. Pull the changes to Couchbase Lite.
58+
8. Verify that only the delta is transferred (bytes transferred < doc size).
59+
60+
### Key Assertions
61+
- The document is replicated successfully with UTF-8 content.
62+
- The bytes transferred for the delta are less than the full document size.
63+
64+
## #4 test_delta_sync_enabled_disabled
65+
66+
### Description
67+
Verify delta sync behavior when toggling delta sync enabled/disabled. Ensures that full documents are transferred when delta sync is disabled and deltas are used when enabled.
68+
69+
### Steps
70+
1. Reset Sync Gateway and load the `travel` dataset with delta sync enabled.
71+
2. Reset the local database and load the `travel` dataset.
72+
3. Create and update documents in Couchbase Lite.
73+
4. Replicate and record bytes transferred (delta sync enabled).
74+
5. Reset Sync Gateway and load the `posts` dataset with delta sync disabled.
75+
6. Reset the local database and load the `posts` dataset.
76+
7. Create and update documents in Couchbase Lite.
77+
8. Replicate and record bytes transferred (delta sync disabled).
78+
9. Compare bytes transferred in both cases.
79+
80+
### Key Assertions
81+
- When delta sync is enabled, bytes transferred for updates are less than the full doc size.
82+
- When delta sync is disabled, bytes transferred are close to the full doc size.
83+
84+
## #5 test_delta_sync_within_expiry
85+
86+
### Description
87+
Verify delta sync behavior within and after the delta revision expiry window. Ensures that deltas are used before expiry and full docs are sent after expiry.
88+
89+
### Steps
90+
1. Reset Sync Gateway and load a dataset with short delta sync expiry.
91+
2. Create and update documents in Couchbase Lite.
92+
3. Replicate to Sync Gateway and record bytes transferred.
93+
4. Update the document in Sync Gateway.
94+
5. Wait for the delta revision to expire.
95+
6. Replicate back to Couchbase Lite and record bytes transferred.
96+
7. Compare bytes transferred before and after expiry.
97+
98+
### Key Assertions
99+
- Before expiry, delta sync is used (bytes transferred < doc size).
100+
- After expiry, a full document is transferred (bytes transferred ≈ doc size).
101+
102+
## #6 test_delta_sync_with_no_deltas
103+
104+
### Description
105+
Test the case where an update does not produce any changes (empty delta). Ensures that no unnecessary data is transferred and document content remains consistent.
106+
107+
### Steps
108+
1. Create new documents in Couchbase Lite and/or Sync Gateway.
109+
2. Replicate documents between CBL and SGW.
110+
3. Update a document with the same value as the previous revision (no actual change).
111+
4. Replicate again and verify no unnecessary data is transferred.
112+
5. Ensure document content matches between CBL and SGW.
113+
114+
### Key Assertions
115+
- No unnecessary data is transferred for empty delta updates.
116+
- Document content is consistent between CBL and SGW after all updates.
117+
118+
## #7 test_delta_sync_larger_than_doc
119+
120+
### Description
121+
Verify delta sync behavior when the delta is larger than the document itself. Ensures that Sync Gateway falls back to sending the full document in such cases.
122+
123+
### Steps
124+
1. Reset Sync Gateway and load the `travel` dataset with delta sync enabled.
125+
2. Create and replicate a document in Couchbase Lite.
126+
3. Update the document in Sync Gateway with a very large change (delta > doc size).
127+
4. Replicate the document to Couchbase Lite.
128+
5. Record and compare bytes transferred.
129+
130+
### Key Assertions
131+
- When the delta is larger than the document, a full document is transferred.
132+
- The bytes transferred are close to the full document size, not the delta size.

0 commit comments

Comments
 (0)