@@ -720,7 +720,7 @@ func TestConflictWithInvalidAttachment(t *testing.T) {
720
720
require .NoError (t , base .JSONUnmarshal (response .Body .Bytes (), & body ))
721
721
722
722
// Modify Doc
723
- parentRevList := [3 ]string {"foo3" , "foo2" , version .Digest ()}
723
+ parentRevList := [3 ]string {"foo3" , "foo2" , version .RevIDDigest ()}
724
724
body ["_rev" ] = "3-foo3"
725
725
body ["rev" ] = "3-foo3"
726
726
body ["_revisions" ].(map [string ]interface {})["ids" ] = parentRevList
@@ -786,13 +786,13 @@ func TestConflictingBranchAttachments(t *testing.T) {
786
786
787
787
// //Create diverging tree
788
788
789
- reqBodyRev2 := `{"_rev": "2-two", "_revisions": {"ids": ["two", "` + version .Digest () + `"], "start": 2}}`
789
+ reqBodyRev2 := `{"_rev": "2-two", "_revisions": {"ids": ["two", "` + version .RevIDDigest () + `"], "start": 2}}`
790
790
response := rt .SendAdminRequest ("PUT" , "/{{.keyspace}}/doc1?new_edits=false" , reqBodyRev2 )
791
791
RequireStatus (t , response , http .StatusCreated )
792
792
793
793
docVersion2 := DocVersionFromPutResponse (t , response )
794
794
795
- reqBodyRev2a := `{"_rev": "2-two", "_revisions": {"ids": ["twoa", "` + version .Digest () + `"], "start": 2}}`
795
+ reqBodyRev2a := `{"_rev": "2-two", "_revisions": {"ids": ["twoa", "` + version .RevIDDigest () + `"], "start": 2}}`
796
796
response = rt .SendAdminRequest ("PUT" , "/{{.keyspace}}/doc1?new_edits=false" , reqBodyRev2a )
797
797
RequireStatus (t , response , http .StatusCreated )
798
798
docVersion2a := DocVersionFromPutResponse (t , response )
@@ -2104,10 +2104,10 @@ func TestAttachmentRemovalWithConflicts(t *testing.T) {
2104
2104
losingVersion3 := rt .UpdateDoc (docID , version , `{"_attachments": {"hello.txt": {"revpos":2,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` )
2105
2105
2106
2106
// Create doc conflicting with previous revid referencing previous attachment too
2107
- winningVersion3 := rt .PutNewEditsFalse (docID , NewDocVersionFromFakeRev ("3-b" ), version , `{"_attachments": {"hello.txt": {"revpos":2,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}, "Winning Rev": true}` )
2107
+ winningVersion3 := rt .PutNewEditsFalse (docID , NewDocVersionFromFakeRev ("3-b" ), & version , `{"_attachments": {"hello.txt": {"revpos":2,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}, "Winning Rev": true}` )
2108
2108
2109
2109
// Update the winning rev 3 and ensure attachment remains around as the other leaf still references this attachment
2110
- finalVersion4 := rt .UpdateDoc (docID , winningVersion3 , `{"update": 2}` )
2110
+ finalVersion4 := rt .UpdateDoc (docID , * winningVersion3 , `{"update": 2}` )
2111
2111
2112
2112
type docResp struct {
2113
2113
Attachments db.AttachmentsMeta `json:"_attachments"`
@@ -2158,7 +2158,7 @@ func TestAttachmentsMissing(t *testing.T) {
2158
2158
2159
2159
version2 := rt .UpdateDoc (docID , version1 , `{"_attachments": {"hello.txt": {"revpos":1,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}, "testval": ["xxx","xxx"]}` )
2160
2160
2161
- _ = rt .PutNewEditsFalse (docID , NewDocVersionFromFakeRev ("2-b" ), version1 , `{"_rev": "2-b", "_revisions": {"ids": ["b", "ca9ad22802b66f662ff171f226211d5c"], "start": 2}, "Winning Rev": true}` )
2161
+ _ = rt .PutNewEditsFalse (docID , NewDocVersionFromFakeRev ("2-b" ), & version1 , `{"_rev": "2-b", "_revisions": {"ids": ["b", "ca9ad22802b66f662ff171f226211d5c"], "start": 2}, "Winning Rev": true}` )
2162
2162
2163
2163
rt .GetDatabase ().FlushRevisionCacheForTest ()
2164
2164
@@ -2177,7 +2177,7 @@ func TestAttachmentsMissingNoBody(t *testing.T) {
2177
2177
2178
2178
version2 := rt .UpdateDoc (docID , version1 , `{"_attachments": {"hello.txt": {"revpos":1,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` )
2179
2179
2180
- _ = rt .PutNewEditsFalse (docID , NewDocVersionFromFakeRev ("2-b" ), version1 , `{}` )
2180
+ _ = rt .PutNewEditsFalse (docID , NewDocVersionFromFakeRev ("2-b" ), & version1 , `{}` )
2181
2181
2182
2182
rt .GetDatabase ().FlushRevisionCacheForTest ()
2183
2183
@@ -2272,38 +2272,41 @@ func TestUpdateExistingAttachment(t *testing.T) {
2272
2272
btc := btcRunner .NewBlipTesterClientOptsWithRT (rt , opts )
2273
2273
defer btc .Close ()
2274
2274
2275
+ btcRunner .StartPull (btc .id )
2276
+ btcRunner .StartPush (btc .id )
2277
+
2275
2278
doc1Version := rt .PutDoc (doc1ID , `{}` )
2276
2279
doc2Version := rt .PutDoc (doc2ID , `{}` )
2277
-
2278
2280
rt .WaitForPendingChanges ()
2279
- btcRunner . StartOneshotPull ( btc . id )
2281
+
2280
2282
btcRunner .WaitForVersion (btc .id , doc1ID , doc1Version )
2281
2283
btcRunner .WaitForVersion (btc .id , doc2ID , doc2Version )
2282
2284
2283
2285
attachmentAData := base64 .StdEncoding .EncodeToString ([]byte ("attachmentA" ))
2284
2286
attachmentBData := base64 .StdEncoding .EncodeToString ([]byte ("attachmentB" ))
2285
2287
2286
- doc1Version , err := btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentAData + `"}}}` ))
2288
+ var err error
2289
+ doc1Version , err = btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentAData + `"}}}` ))
2287
2290
require .NoError (t , err )
2288
- doc2Version , err = btcRunner .PushRev (btc .id , doc2ID , doc2Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentBData + `"}}}` ))
2291
+ doc2Version , err = btcRunner .AddRev (btc .id , doc2ID , & doc2Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentBData + `"}}}` ))
2289
2292
require .NoError (t , err )
2290
2293
2291
- assert .NoError (t , rt .WaitForVersion (doc1ID , doc1Version ))
2292
- assert .NoError (t , rt .WaitForVersion (doc2ID , doc2Version ))
2294
+ require .NoError (t , rt .WaitForVersion (doc1ID , doc1Version ))
2295
+ require .NoError (t , rt .WaitForVersion (doc2ID , doc2Version ))
2293
2296
2294
2297
collection , ctx := rt .GetSingleTestDatabaseCollection ()
2295
2298
_ , err = collection .GetDocument (ctx , "doc1" , db .DocUnmarshalAll )
2296
2299
require .NoError (t , err )
2297
2300
_ , err = collection .GetDocument (ctx , "doc2" , db .DocUnmarshalAll )
2298
2301
require .NoError (t , err )
2299
2302
2300
- doc1Version , err = btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=","length":11,"content_type":"","stub":true,"revpos":3}}}` ))
2303
+ doc1Version , err = btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=","length":11,"content_type":"","stub":true,"revpos":3}}}` ))
2301
2304
require .NoError (t , err )
2302
2305
2303
2306
assert .NoError (t , rt .WaitForVersion (doc1ID , doc1Version ))
2304
2307
2305
2308
doc1 , err := collection .GetDocument (ctx , "doc1" , db .DocUnmarshalAll )
2306
- assert .NoError (t , err )
2309
+ require .NoError (t , err )
2307
2310
2308
2311
assert .Equal (t , "sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=" , doc1 .Attachments ["attachment" ].(map [string ]interface {})["digest" ])
2309
2312
@@ -2328,11 +2331,13 @@ func TestPushUnknownAttachmentAsStub(t *testing.T) {
2328
2331
opts := BlipTesterClientOpts {SupportedBLIPProtocols : SupportedBLIPProtocols }
2329
2332
btc := btcRunner .NewBlipTesterClientOptsWithRT (rt , & opts )
2330
2333
defer btc .Close ()
2334
+
2335
+ btcRunner .StartPull (btc .id )
2336
+ btcRunner .StartPush (btc .id )
2337
+
2331
2338
// Add doc1 and doc2
2332
2339
doc1Version := btc .rt .PutDoc (doc1ID , `{}` )
2333
-
2334
2340
btc .rt .WaitForPendingChanges ()
2335
- btcRunner .StartOneshotPull (btc .id )
2336
2341
2337
2342
btcRunner .WaitForVersion (btc .id , doc1ID , doc1Version )
2338
2343
@@ -2343,7 +2348,7 @@ func TestPushUnknownAttachmentAsStub(t *testing.T) {
2343
2348
length , digest , err := btcRunner .saveAttachment (btc .id , contentType , attachmentAData )
2344
2349
require .NoError (t , err )
2345
2350
// Update doc1, include reference to non-existing attachment with recent revpos
2346
- doc1Version , err = btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (fmt .Sprintf (`{"key": "val", "_attachments":{"attachment":{"digest":"%s","length":%d,"content_type":"%s","stub":true,"revpos":1}}}` , digest , length , contentType )))
2351
+ doc1Version , err = btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (fmt .Sprintf (`{"key": "val", "_attachments":{"attachment":{"digest":"%s","length":%d,"content_type":"%s","stub":true,"revpos":1}}}` , digest , length , contentType )))
2347
2352
require .NoError (t , err )
2348
2353
2349
2354
require .NoError (t , btc .rt .WaitForVersion (doc1ID , doc1Version ))
@@ -2356,7 +2361,6 @@ func TestPushUnknownAttachmentAsStub(t *testing.T) {
2356
2361
}
2357
2362
2358
2363
func TestMinRevPosWorkToAvoidUnnecessaryProveAttachment (t * testing.T ) {
2359
- base .SetUpTestLogging (t , base .LevelDebug , base .KeyAll )
2360
2364
rtConfig := & RestTesterConfig {
2361
2365
GuestEnabled : true ,
2362
2366
DatabaseConfig : & DatabaseConfig {
@@ -2376,25 +2380,44 @@ func TestMinRevPosWorkToAvoidUnnecessaryProveAttachment(t *testing.T) {
2376
2380
opts := BlipTesterClientOpts {SupportedBLIPProtocols : SupportedBLIPProtocols }
2377
2381
btc := btcRunner .NewBlipTesterClientOptsWithRT (rt , & opts )
2378
2382
defer btc .Close ()
2379
- // Push an initial rev with attachment data
2383
+
2384
+ btcRunner .StartPull (btc .id )
2385
+
2386
+ // Write an initial rev with attachment data
2380
2387
initialVersion := btc .rt .PutDoc (docID , `{"_attachments": {"hello.txt": {"data": "aGVsbG8gd29ybGQ="}}}` )
2381
2388
2382
2389
// Replicate data to client and ensure doc arrives
2383
2390
btc .rt .WaitForPendingChanges ()
2384
- btcRunner .StartOneshotPull (btc .id )
2385
2391
btcRunner .WaitForVersion (btc .id , docID , initialVersion )
2386
2392
2387
- // Push a revision with a bunch of history simulating doc updated on mobile device
2388
- // Note this references revpos 1 and therefore SGW has it - Shouldn't need proveAttachment
2393
+ // Create a set of revisions before we start the replicator to ensure there's a significant amount of history to push
2394
+ version := initialVersion
2395
+ for i := 0 ; i < 25 ; i ++ {
2396
+ var err error
2397
+ version , err = btcRunner .AddRev (btc .id , docID , & version , []byte (`{"update_count":` + strconv .Itoa (i )+ `,"_attachments": {"hello.txt": {"revpos":1,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` ))
2398
+ require .NoError (t , err )
2399
+ }
2400
+
2401
+ // Note this references revpos 1 and therefore SGW has it - Shouldn't need proveAttachment, even when we replicate it
2389
2402
proveAttachmentBefore := btc .pushReplication .replicationStats .ProveAttachment .Value ()
2390
- revid , err := btcRunner .PushRevWithHistory (btc .id , docID , initialVersion .RevID , []byte (`{"_attachments": {"hello.txt": {"revpos":1,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` ), 25 , 5 )
2391
- assert .NoError (t , err )
2403
+ btcRunner .StartPushWithOpts (btc .id , BlipTesterPushOptions {Continuous : false })
2404
+ require .NoError (t , rt .WaitForVersion (docID , version ))
2405
+
2392
2406
proveAttachmentAfter := btc .pushReplication .replicationStats .ProveAttachment .Value ()
2393
2407
assert .Equal (t , proveAttachmentBefore , proveAttachmentAfter )
2394
2408
2395
- // Push another bunch of history
2396
- _ , err = btcRunner .PushRevWithHistory (btc .id , docID , revid , []byte (`{"_attachments": {"hello.txt": {"revpos":1,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` ), 25 , 5 )
2397
- assert .NoError (t , err )
2409
+ // start another push to run in the background from where we last left off
2410
+ latestSeq := btcRunner .SingleCollection (btc .id ).lastSeq ()
2411
+ btcRunner .StartPushWithOpts (btc .id , BlipTesterPushOptions {Continuous : true , Since : strconv .Itoa (int (latestSeq ))})
2412
+
2413
+ // Push another bunch of history, this time whilst a replicator is actively pushing them
2414
+ for i := 25 ; i < 50 ; i ++ {
2415
+ var err error
2416
+ version , err = btcRunner .AddRev (btc .id , docID , & version , []byte (`{"update_count":` + strconv .Itoa (i )+ `,"_attachments": {"hello.txt": {"revpos":1,"stub":true,"digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0="}}}` ))
2417
+ require .NoError (t , err )
2418
+ }
2419
+
2420
+ require .NoError (t , rt .WaitForVersion (docID , version ))
2398
2421
proveAttachmentAfter = btc .pushReplication .replicationStats .ProveAttachment .Value ()
2399
2422
assert .Equal (t , proveAttachmentBefore , proveAttachmentAfter )
2400
2423
})
@@ -2430,7 +2453,7 @@ func TestAttachmentWithErroneousRevPos(t *testing.T) {
2430
2453
btcRunner .AttachmentsLock (btc .id ).Unlock ()
2431
2454
2432
2455
// Put doc with an erroneous revpos 1 but with a different digest, referring to the above attachment
2433
- _ , err := btcRunner .PushRevWithHistory (btc .id , docID , version . RevID , []byte (`{"_attachments": {"hello.txt": {"revpos":1,"stub":true,"length": 19,"digest":"sha1-l+N7VpXGnoxMm8xfvtWPbz2YvDc="}}}` ), 1 , 0 )
2456
+ _ , err := btcRunner .PushRevWithHistory (btc .id , docID , & version , []byte (`{"_attachments": {"hello.txt": {"revpos":1,"stub":true,"length": 19,"digest":"sha1-l+N7VpXGnoxMm8xfvtWPbz2YvDc="}}}` ), 1 , 0 )
2434
2457
require .NoError (t , err )
2435
2458
2436
2459
// Ensure message and attachment is pushed up
@@ -2605,12 +2628,14 @@ func TestCBLRevposHandling(t *testing.T) {
2605
2628
btcRunner .WaitForVersion (btc .id , doc1ID , doc1Version )
2606
2629
btcRunner .WaitForVersion (btc .id , doc2ID , doc2Version )
2607
2630
2631
+ btcRunner .StartPush (btc .id )
2632
+
2608
2633
attachmentAData := base64 .StdEncoding .EncodeToString ([]byte ("attachmentA" ))
2609
2634
attachmentBData := base64 .StdEncoding .EncodeToString ([]byte ("attachmentB" ))
2610
2635
2611
- doc1Version , err := btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentAData + `"}}}` ))
2636
+ doc1Version , err := btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentAData + `"}}}` ))
2612
2637
require .NoError (t , err )
2613
- doc2Version , err = btcRunner .PushRev (btc .id , doc2ID , doc2Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentBData + `"}}}` ))
2638
+ doc2Version , err = btcRunner .AddRev (btc .id , doc2ID , & doc2Version , []byte (`{"key": "val", "_attachments": {"attachment": {"data": "` + attachmentBData + `"}}}` ))
2614
2639
require .NoError (t , err )
2615
2640
2616
2641
assert .NoError (t , btc .rt .WaitForVersion (doc1ID , doc1Version ))
@@ -2623,25 +2648,29 @@ func TestCBLRevposHandling(t *testing.T) {
2623
2648
require .NoError (t , err )
2624
2649
2625
2650
// Update doc1, don't change attachment, use correct revpos
2626
- doc1Version , err = btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-wzp8ZyykdEuZ9GuqmxQ7XDrY7Co=","length":11,"content_type":"","stub":true,"revpos":2}}}` ))
2651
+ doc1Version , err = btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-wzp8ZyykdEuZ9GuqmxQ7XDrY7Co=","length":11,"content_type":"","stub":true,"revpos":2}}}` ))
2627
2652
require .NoError (t , err )
2628
2653
2629
2654
assert .NoError (t , btc .rt .WaitForVersion (doc1ID , doc1Version ))
2630
2655
2631
2656
// Update doc1, don't change attachment, use revpos=generation of revid, as CBL 2.x does. Should not proveAttachment on digest match.
2632
- doc1Version , err = btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-wzp8ZyykdEuZ9GuqmxQ7XDrY7Co=","length":11,"content_type":"","stub":true,"revpos":4}}}` ))
2657
+ doc1Version , err = btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-wzp8ZyykdEuZ9GuqmxQ7XDrY7Co=","length":11,"content_type":"","stub":true,"revpos":4}}}` ))
2633
2658
require .NoError (t , err )
2634
2659
2660
+ require .NoError (t , rt .WaitForVersion (doc1ID , doc1Version ))
2661
+
2635
2662
// Validate attachment exists
2636
2663
attResponse := btc .rt .SendAdminRequest ("GET" , "/{{.keyspace}}/doc1/attachment" , "" )
2637
2664
assert .Equal (t , 200 , attResponse .Code )
2638
2665
assert .Equal (t , "attachmentA" , string (attResponse .BodyBytes ()))
2639
2666
2640
2667
attachmentPushCount := btc .rt .GetDatabase ().DbStats .CBLReplicationPushStats .AttachmentPushCount .Value ()
2641
2668
// Update doc1, change attachment digest with CBL revpos=generation. Should getAttachment
2642
- _ , err = btcRunner .PushRev (btc .id , doc1ID , doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=","length":11,"content_type":"","stub":true,"revpos":5}}}` ))
2669
+ doc1Version , err = btcRunner .AddRev (btc .id , doc1ID , & doc1Version , []byte (`{"key": "val", "_attachments":{"attachment":{"digest":"sha1-SKk0IV40XSHW37d3H0xpv2+z9Ck=","length":11,"content_type":"","stub":true,"revpos":5}}}` ))
2643
2670
require .NoError (t , err )
2644
2671
2672
+ require .NoError (t , rt .WaitForVersion (doc1ID , doc1Version ))
2673
+
2645
2674
// Validate attachment exists and is updated
2646
2675
attResponse = btc .rt .SendAdminRequest ("GET" , "/{{.keyspace}}/doc1/attachment" , "" )
2647
2676
assert .Equal (t , 200 , attResponse .Code )
0 commit comments