From 1ca345dda4f00cc210b4dd1d0286eb33531fd4c0 Mon Sep 17 00:00:00 2001 From: raararaara Date: Thu, 14 Nov 2024 15:11:21 +0900 Subject: [PATCH 1/6] Fix manual update of clientInfo to allow version vector removal when client deactivation --- server/clients/clients.go | 4 ++++ test/integration/gc_test.go | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/server/clients/clients.go b/server/clients/clients.go index 9f9b5a187..3cd2b1632 100644 --- a/server/clients/clients.go +++ b/server/clients/clients.go @@ -88,6 +88,10 @@ func Deactivate( return nil, err } + if err = info.DetachDocument(docID); err != nil { + return nil, err + } + if err := be.DB.UpdateVersionVector( ctx, info, diff --git a/test/integration/gc_test.go b/test/integration/gc_test.go index f7830d6eb..d1b6b640a 100644 --- a/test/integration/gc_test.go +++ b/test/integration/gc_test.go @@ -1190,10 +1190,8 @@ func TestGarbageCollection(t *testing.T) { assert.Equal(t, d2.GarbageLen(), 2) assert.Equal(t, len(d2.VersionVector()), 2) - // TODO(JOOHOJANG): remove below comments after https://github.com/yorkie-team/yorkie/issues/1058 resolved - // Due to https://github.com/yorkie-team/yorkie/issues/1058, removing deactivated client's version vector is not working properly now. - // assert.NoError(t, c2.Sync(ctx)) - // assert.Equal(t, d2.GarbageLen(), 0) - // assert.Equal(t, len(d2.VersionVector()), 1) + assert.NoError(t, c2.Sync(ctx)) + assert.Equal(t, d2.GarbageLen(), 0) + assert.Equal(t, len(d2.VersionVector()), 1) }) } From 719022d119763fea39be87ed8c3a3734b12ff185 Mon Sep 17 00:00:00 2001 From: raararaara Date: Tue, 19 Nov 2024 15:11:59 +0900 Subject: [PATCH 2/6] Move `UpdateVersionVector` handling to cluster server detach --- server/clients/clients.go | 16 ---------------- server/rpc/cluster_server.go | 12 ++++++++++++ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/server/clients/clients.go b/server/clients/clients.go index 3cd2b1632..7c47ee7b6 100644 --- a/server/clients/clients.go +++ b/server/clients/clients.go @@ -87,22 +87,6 @@ func Deactivate( if err := cli.DetachDocument(ctx, project, actorID, docID, project.PublicKey, docInfo.Key); err != nil { return nil, err } - - if err = info.DetachDocument(docID); err != nil { - return nil, err - } - - if err := be.DB.UpdateVersionVector( - ctx, - info, - types.DocRefKey{ - ProjectID: refKey.ProjectID, - DocID: docID, - }, - nil, - ); err != nil { - return nil, err - } } return be.DB.DeactivateClient(ctx, refKey) diff --git a/server/rpc/cluster_server.go b/server/rpc/cluster_server.go index bf3e001a8..ffb9089ff 100644 --- a/server/rpc/cluster_server.go +++ b/server/rpc/cluster_server.go @@ -132,5 +132,17 @@ func (s *clusterServer) DetachDocument( return nil, err } + if err = s.backend.DB.UpdateVersionVector( + ctx, + clientInfo, + types.DocRefKey{ + ProjectID: project.ID, + DocID: summary.ID, + }, + nil, + ); err != nil { + return nil, err + } + return connect.NewResponse(&api.ClusterServiceDetachDocumentResponse{}), nil } From e18af1e7f6ece03c343b4571e29f6ab8d5651e3f Mon Sep 17 00:00:00 2001 From: raararaara Date: Tue, 19 Nov 2024 16:07:50 +0900 Subject: [PATCH 3/6] Erase duplicate vv update --- server/rpc/cluster_server.go | 12 ------------ test/integration/gc_test.go | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/server/rpc/cluster_server.go b/server/rpc/cluster_server.go index ffb9089ff..bf3e001a8 100644 --- a/server/rpc/cluster_server.go +++ b/server/rpc/cluster_server.go @@ -132,17 +132,5 @@ func (s *clusterServer) DetachDocument( return nil, err } - if err = s.backend.DB.UpdateVersionVector( - ctx, - clientInfo, - types.DocRefKey{ - ProjectID: project.ID, - DocID: summary.ID, - }, - nil, - ); err != nil { - return nil, err - } - return connect.NewResponse(&api.ClusterServiceDetachDocumentResponse{}), nil } diff --git a/test/integration/gc_test.go b/test/integration/gc_test.go index d1b6b640a..2e4ca2dc2 100644 --- a/test/integration/gc_test.go +++ b/test/integration/gc_test.go @@ -1142,35 +1142,35 @@ func TestGarbageCollection(t *testing.T) { d1 := document.New(helper.TestDocKey(t)) assert.NoError(t, c1.Attach(ctx, d1)) // d2.vv =[c1:1], minvv =[c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv =[c1:1, c2:1], minvv =[c1:0, c2:0], db.vv {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewText("text").Edit(0, 0, "a").Edit(1, 1, "b").Edit(2, 2, "c") return nil }, "sets text") //d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv =[c1:3, c2:1], minvv =[c1:0, c2:0], db.vv {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:2, c2:3], minvv =[c1:0, c2:0], db.vv {c1: [c1:2], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(2, 2, "c") return nil }, "insert c") //d2.vv =[c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -1178,7 +1178,7 @@ func TestGarbageCollection(t *testing.T) { return nil }, "delete bd") //d1.vv = [c1:4, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.Equal(t, 2, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) @@ -1187,11 +1187,11 @@ func TestGarbageCollection(t *testing.T) { assert.NoError(t, c2.Sync(ctx)) assert.NoError(t, c1.Deactivate(ctx)) - assert.Equal(t, d2.GarbageLen(), 2) - assert.Equal(t, len(d2.VersionVector()), 2) + assert.Equal(t, 2, d2.GarbageLen()) + assert.Equal(t, 2, len(d2.VersionVector())) assert.NoError(t, c2.Sync(ctx)) - assert.Equal(t, d2.GarbageLen(), 0) - assert.Equal(t, len(d2.VersionVector()), 1) + assert.Equal(t, 0, d2.GarbageLen()) + assert.Equal(t, 1, len(d2.VersionVector())) }) } From fce25c1a05cd71ab99d6f23e0b33fb7d7187f82e Mon Sep 17 00:00:00 2001 From: raararaara Date: Tue, 19 Nov 2024 17:29:27 +0900 Subject: [PATCH 4/6] Swap order of arguments in assert.Equal for gc tests --- test/integration/gc_test.go | 416 +++++++++++++++++------------------- 1 file changed, 202 insertions(+), 214 deletions(-) diff --git a/test/integration/gc_test.go b/test/integration/gc_test.go index 2e4ca2dc2..18cc95c52 100644 --- a/test/integration/gc_test.go +++ b/test/integration/gc_test.go @@ -73,12 +73,12 @@ func TestGarbageCollection(t *testing.T) { d1 := document.New(helper.TestDocKey(t)) assert.NoError(t, c1.Attach(ctx, d1)) // d1.vv = [c1:1], minvv = [c1:1], db.vv = {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv = [c1: 1, c2:2], minvv = [c1:0, c2:0], db.vv = {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) assert.NoError(t, d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetInteger("1", 1) @@ -88,140 +88,129 @@ func TestGarbageCollection(t *testing.T) { }, "sets 1,2,3")) // d1.vv = [c1: 2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:3, c2:1], minvv = [c1:0, c2:0], db.vv = {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:2, c2:3], minvv = [c1:1, c2:0], db.vv = {c1: [c1:2], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) assert.NoError(t, d2.Update(func(root *json.Object, p *presence.Presence) error { root.Delete("2") return nil }, "removes 2")) // d2.vv = [c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 4, d2.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1: 2, c2:4], minvv = [c1: 2, c2:0], db.vv = {c1: [c1:2], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 4, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1: 5, c2:4], minvv = [c1: 2, c2:1], db.vv = {c1: [c1:3, c2:1], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) assert.Equal(t, 4, d1.GarbageLen()) assert.Equal(t, 4, d2.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1: 2, c2:4], minvv = [c1: 2, c2:1], db.vv = {c1: [c1:3, c2:1], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.Equal(t, 4, d1.GarbageLen()) assert.Equal(t, 4, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1: 5, c2:4], minvv = [c1: 2, c2:4], db.vv = {c1: [c1:5, c2:4], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 4, d2.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1: 2, c2:4], minvv = [c1: 2, c2:4], db.vv = {c1: [c1:5 c2:4], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.Equal(t, 0, d1.GarbageLen()) // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition assert.Equal(t, 0, d2.GarbageLen()) }) - t.Run("garbage collection for text type test", func(t *testing.T) { - ctx := context.Background() - d1 := document.New(helper.TestDocKey(t)) - assert.NoError(t, c1.Attach(ctx, d1)) - // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) - - d2 := document.New(helper.TestDocKey(t)) - assert.NoError(t, c2.Attach(ctx, d2)) - // d2.vv = [c1: 1, c2:2], minvv = [c1: 0, c2:0], db.vv = {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) - - assert.NoError(t, - d1.Update(func(root *json.Object, p *presence.Presence) error { - root.SetNewText("text"). - Edit(0, 0, "Hello world") - root.SetNewText("richText"). - Edit(0, 0, "Hello world", nil) - return nil - }, "sets test and richText"), - ) - // d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) - assert.Equal(t, 0, d1.GarbageLen()) - assert.Equal(t, 0, d2.GarbageLen()) + t.Run("garbage collection for tree type test", func(t *testing.T) { + doc := document.New(helper.TestDocKey(t)) - assert.NoError(t, c1.Sync(ctx)) - // d1.vv = [c1:3, c2:1], minvv = [c1:0, c2:0], db.vv = {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + err := doc.Update(func(root *json.Object, p *presence.Presence) error { + root.SetNewTree("t", &json.TreeNode{ + Type: "doc", + Children: []json.TreeNode{{ + Type: "p", Children: []json.TreeNode{{ + Type: "tn", Children: []json.TreeNode{{ + Type: "text", Value: "a", + }, { + Type: "text", Value: "b", + }}, + }, { + Type: "tn", Children: []json.TreeNode{{ + Type: "text", Value: "cd", + }}, + }}, + }}, + }) + assert.Equal(t, `

abcd

`, root.GetTree("t").ToXML()) + return nil + }) + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 1))) + assert.NoError(t, err) - assert.NoError(t, c2.Sync(ctx)) - // d2.vv = [c1:2, c2:3], minvv = [c1:1, c2:0], db.vv = {c1: [c1:2], c2: [c1:1 c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) - - assert.NoError(t, - d2.Update(func(root *json.Object, p *presence.Presence) error { - root.GetText("text"). - Edit(0, 1, "a"). - Edit(1, 2, "b") - root.GetText("richText"). - Edit(0, 1, "a", map[string]string{"b": "1"}) - return nil - }, "edit text type elements"), - ) - // d2.vv = [c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) - assert.Equal(t, 0, d1.GarbageLen()) - assert.Equal(t, 3, d2.GarbageLen()) + err = doc.Update(func(root *json.Object, p *presence.Presence) error { + root.GetTree("t").EditByPath([]int{0, 0, 0}, []int{0, 0, 2}, &json.TreeNode{Type: "text", Value: "gh"}, 0) + assert.Equal(t, `

ghcd

`, root.GetTree("t").ToXML()) + return nil + }) - assert.NoError(t, c2.Sync(ctx)) - // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:0], db.vv = {c1: [c1:2], c2: [c1:2 c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) - assert.Equal(t, 0, d1.GarbageLen()) - assert.Equal(t, 3, d2.GarbageLen()) + // [text(a), text(b)] + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 2))) + assert.NoError(t, err) + assert.Equal(t, 2, doc.GarbageLen()) + assert.Equal(t, 2, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID()))) + assert.Equal(t, 0, doc.GarbageLen()) - assert.NoError(t, c1.Sync(ctx)) - // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:1], db.vv = {c1: [c1:3, c2:1], c2: [c1:2 c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) - assert.Equal(t, 3, d1.GarbageLen()) - assert.Equal(t, 3, d2.GarbageLen()) + err = doc.Update(func(root *json.Object, p *presence.Presence) error { + root.GetTree("t").EditByPath([]int{0, 0, 0}, []int{0, 0, 2}, &json.TreeNode{Type: "text", Value: "cv"}, 0) + assert.Equal(t, `

cvcd

`, root.GetTree("t").ToXML()) + return nil + }) - assert.NoError(t, c2.Sync(ctx)) - // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:0], db.vv = {c1: [c1:3, c2:1], c2: [c1:2 c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) - assert.Equal(t, 3, d1.GarbageLen()) - assert.Equal(t, 3, d2.GarbageLen()) + // [text(gh)] + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 3))) + assert.NoError(t, err) + assert.Equal(t, 1, doc.GarbageLen()) + assert.Equal(t, 1, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID()))) + assert.Equal(t, 0, doc.GarbageLen()) - assert.NoError(t, c1.Sync(ctx)) - // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:4], db.vv = {c1: [c1:5, c2:4], c2: [c1:2 c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) - // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition - assert.Equal(t, 0, d1.GarbageLen()) - assert.Equal(t, 3, d2.GarbageLen()) + err = doc.Update(func(root *json.Object, p *presence.Presence) error { + root.GetTree("t").EditByPath([]int{0}, []int{1}, &json.TreeNode{ + Type: "p", Children: []json.TreeNode{{ + Type: "tn", Children: []json.TreeNode{{ + Type: "text", Value: "ab", + }}, + }}}, 0) + assert.Equal(t, `

ab

`, root.GetTree("t").ToXML()) + return nil + }) - assert.NoError(t, c2.Sync(ctx)) - // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:4], db.vv = {c1: [c1:5, c2:4], c2: [c1:2 c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) - assert.Equal(t, 0, d1.GarbageLen()) - // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition - assert.Equal(t, 0, d2.GarbageLen()) + // [p, tn, tn, text(cv), text(cd)] + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 4))) + assert.NoError(t, err) + assert.Equal(t, 5, doc.GarbageLen()) + assert.Equal(t, 5, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID()))) + assert.Equal(t, 0, doc.GarbageLen()) }) t.Run("garbage collection for tree type test", func(t *testing.T) { @@ -248,7 +237,7 @@ func TestGarbageCollection(t *testing.T) { return nil }) - assert.Equal(t, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 1))) assert.NoError(t, err) err = doc.Update(func(root *json.Object, p *presence.Presence) error { @@ -258,7 +247,7 @@ func TestGarbageCollection(t *testing.T) { }) // [text(a), text(b)] - assert.Equal(t, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 2))) assert.NoError(t, err) assert.Equal(t, doc.GarbageLen(), 2) assert.Equal(t, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID())), 2) @@ -271,7 +260,7 @@ func TestGarbageCollection(t *testing.T) { }) // [text(gh)] - assert.Equal(t, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 3))) assert.NoError(t, err) assert.Equal(t, doc.GarbageLen(), 1) assert.Equal(t, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID())), 1) @@ -289,7 +278,7 @@ func TestGarbageCollection(t *testing.T) { }) // [p, tn, tn, text(cv), text(cd)] - assert.Equal(t, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 4))) assert.NoError(t, err) assert.Equal(t, doc.GarbageLen(), 5) assert.Equal(t, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID())), 5) @@ -301,12 +290,12 @@ func TestGarbageCollection(t *testing.T) { d1 := document.New(helper.TestDocKey(t)) assert.NoError(t, c1.Attach(ctx, d1)) // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv = [c1:1, c2:2], minvv = [c1:0, c2:0], db.vv {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewTree("t", &json.TreeNode{ @@ -326,64 +315,64 @@ func TestGarbageCollection(t *testing.T) { return nil }) //d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:3, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:2, c2:3], minvv = [c1:1, c2:0], db.vv {c1: [c1:2], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetTree("t").EditByPath([]int{0, 0, 0}, []int{0, 0, 2}, &json.TreeNode{Type: "text", Value: "gh"}, 0) return nil }) // d2.vv = [c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) - assert.Equal(t, d1.GarbageLen(), 0) - assert.Equal(t, d2.GarbageLen(), 2) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 2, d2.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:0], db.vv {c1: [c1:2], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) - assert.Equal(t, d1.GarbageLen(), 0) - assert.Equal(t, d2.GarbageLen(), 2) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 2, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:1], db.vv {c1: [c1:3, c2:1], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) - assert.Equal(t, d1.GarbageLen(), 2) - assert.Equal(t, d2.GarbageLen(), 2) + assert.Equal(t, 2, d1.GarbageLen()) + assert.Equal(t, 2, d2.GarbageLen()) err = d1.Update(func(root *json.Object, p *presence.Presence) error { root.GetTree("t").EditByPath([]int{0, 0, 0}, []int{0, 0, 0}, &json.TreeNode{Type: "text", Value: "g"}, 0) return nil }) //d1.vv = [c1:6, c2:4] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 4))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:6, c2:4], minvv = [c1:2, c2:4], db.vv {c1: [c1:6, c2:4], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition - assert.Equal(t, d1.GarbageLen(), 0) - assert.Equal(t, d2.GarbageLen(), 2) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 2, d2.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:6, c2:7], minvv = [c1:2, c2:4], db.vv {c1: [c1:6, c2:4], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 7)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 7))) assert.NoError(t, err) - assert.Equal(t, d1.GarbageLen(), 0) + assert.Equal(t, 0, d1.GarbageLen()) // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition - assert.Equal(t, d2.GarbageLen(), 0) + assert.Equal(t, 0, d2.GarbageLen()) }) t.Run("garbage collection with detached document test", func(t *testing.T) { @@ -391,12 +380,12 @@ func TestGarbageCollection(t *testing.T) { d1 := document.New(helper.TestDocKey(t)) assert.NoError(t, c1.Attach(ctx, d1)) // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv = [c1:1, c2:2], minvv = [c1:0, c2:0], db.vv {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetInteger("1", 1) @@ -407,18 +396,18 @@ func TestGarbageCollection(t *testing.T) { return nil }, "sets 1,2,3,4,5") // d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:3, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:2, c2:3], minvv = [c1:1, c2:0], db.vv {c1: [c1:2], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) err = d1.Update(func(root *json.Object, p *presence.Presence) error { root.Delete("2") @@ -427,14 +416,14 @@ func TestGarbageCollection(t *testing.T) { return nil }, "removes 2 and edit text type elements") //d1.vv = [c1:4, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.Equal(t, 6, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d2.vv = [c1:4, c2:1], minvv = [c1:1, c2:1], db.vv {c1: [c1:4, c2:1], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1))) assert.Equal(t, 6, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) @@ -444,7 +433,7 @@ func TestGarbageCollection(t *testing.T) { assert.NoError(t, c1.Sync(ctx)) // remove c2 lamport from d1.vv after GC // d1.vv = [c1:5], minvv = [c1:4], db.vv {c1: [c1:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5))) assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 6, d2.GarbageLen()) }) @@ -457,7 +446,7 @@ func TestGarbageCollection(t *testing.T) { assert.NoError(t, c1.Attach(ctx, d1)) // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewObject("point"). @@ -466,22 +455,22 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:2], minvv = [c1:2], db.vv {c1: [c1:2]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, c2.Attach(ctx, d2)) // d1.vv = [c1:2, c2:3], minvv = [c1:0, c2:0], db.vv {c1: [c1:2], [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) err = d1.Update(func(root *json.Object, p *presence.Presence) error { root.Delete("point") return nil }) // d1.vv = [c1:3] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3))) assert.NoError(t, err) assert.Equal(t, 3, d1.GarbageLen()) @@ -490,32 +479,32 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d2.vv = [c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) assert.Equal(t, 1, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:4, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:3], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:3, c2:5], minvv = [c1:2, c2:0], db.vv {c1: [c1:3], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 5))) assert.Equal(t, 3, d1.GarbageLen()) assert.Equal(t, 3, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:1], db.vv {c1: [c1:4, c2:1], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:3, c2:5], minvv = [c1:3, c2:0], db.vv {c1: [c1:3], c2: [c1:3, c2:5]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 5))) // node removedAt = 3@c1, minVV[c1] = 3 meet GC condition assert.Equal(t, 3, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) - assert.Equal(t, d1.GarbageCollect(helper.MaxVersionVector(d1.ActorID(), d2.ActorID())), 3) - assert.Equal(t, d2.GarbageCollect(helper.MaxVersionVector(d1.ActorID(), d2.ActorID())), 0) + assert.Equal(t, 3, d1.GarbageCollect(helper.MaxVersionVector(d1.ActorID(), d2.ActorID()))) + assert.Equal(t, 0, d2.GarbageCollect(helper.MaxVersionVector(d1.ActorID(), d2.ActorID()))) }) t.Run("deregister nested object gc test", func(t *testing.T) { @@ -523,7 +512,7 @@ func TestGarbageCollection(t *testing.T) { d1 := document.New(helper.TestDocKey(t)) assert.NoError(t, c1.Attach(ctx, d1)) - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { json := map[string]interface{}{ @@ -534,7 +523,7 @@ func TestGarbageCollection(t *testing.T) { root.Delete("obj") return nil }) - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) assert.Equal(t, 5, d1.GarbageLen()) @@ -547,19 +536,19 @@ func TestGarbageCollection(t *testing.T) { assert.NoError(t, c1.Attach(ctx, d1)) // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d1.vv = [c1:1, c2:2], minvv = [c1:0, c2:0], db.vv {c1: [c1:1], c2:[c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewText("text").Edit(0, 0, "z") return nil }) // d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) // "z" revmoedAt 3@c1 @@ -568,7 +557,7 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv = [c1:3] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -576,7 +565,7 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv = [c1:4] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -584,17 +573,17 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv = [c1:5] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:6, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:5], c2:[c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) err = c2.Sync(ctx) // d2.vv = [c1:5, c2:6], minvv = [c1:1, c2:0], db.vv {c1: [c1:5], c2:[c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 6))) assert.Equal(t, `{"text":[{"val":"a"},{"val":"b"},{"val":"d"}]}`, d1.Marshal()) assert.Equal(t, `{"text":[{"val":"a"},{"val":"b"},{"val":"d"}]}`, d2.Marshal()) @@ -605,16 +594,16 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv = [c1:7, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:7, c2:1], minvv = [c1:1, c2:1], db.vv {c1: [c1:7, c2:1], c2:[c1:1, c2:2]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:7, c2:8], minvv = [c1:6, c2:1], db.vv {c1: [c1:7, c2:1], c2:[c1:6, c2:7]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 8)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 8))) assert.Equal(t, `{"text":[{"val":"a"},{"val":"b"},{"val":"c"},{"val":"d"}]}`, d1.Marshal()) assert.Equal(t, `{"text":[{"val":"a"},{"val":"b"},{"val":"c"},{"val":"d"}]}`, d2.Marshal()) @@ -623,12 +612,12 @@ func TestGarbageCollection(t *testing.T) { return nil }) //d1.vv = [c1:8, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:8, c2:1], minvv = [c1:6, c2:1], db.vv {c1: [c1:8, c2:1], c2:[c1:6, c2:7]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1))) // "z"'s removedAt = 6@c1, minvv[c1] =6 meet GC Condition assert.Equal(t, `{"text":[{"val":"a"},{"val":"d"}]}`, d1.Marshal()) assert.Equal(t, 2, d1.GarbageLen()) // a,b,c @@ -638,28 +627,28 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d2.vv = [c1:7, c2:9] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 9)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 9))) assert.NoError(t, err) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:8, c2:10], minvv = [c1:7, c2:1], db.vv {c1: [c1:8, c2:1], c2:[c1:7, c2:9]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 10)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 10))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:10, c2:9], minvv = [c1:7, c2:1], db.vv {c1: [c1:8, c2:1], c2:[c1:7, c2:9]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 10), versionOf(d2.ActorID(), 9)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 10), versionOf(d2.ActorID(), 9))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:8, c2:10], minvv = [c1:7, c2:1], db.vv {c1: [c1:8, c2:1], c2:[c1:8, c2:10]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 10)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 10))) assert.NoError(t, c1.Sync(ctx)) // d2.vv = [c1:10, c2:9], minvv = [c1:8, c2:9], db.vv {c1: [c1:10, c2:9], c2:[c1:8, c2:10]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 10), versionOf(d2.ActorID(), 9)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 10), versionOf(d2.ActorID(), 9))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:8, c2:10], minvv = [c1:8, c2:9], db.vv {c1: [c1:10, c2:9], c2:[c1:8, c2:10]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 10)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 10))) assert.Equal(t, `{"text":[{"val":"a"},{"val":"a"},{"val":"d"}]}`, d1.Marshal()) assert.Equal(t, `{"text":[{"val":"a"},{"val":"a"},{"val":"d"}]}`, d2.Marshal()) assert.Equal(t, 0, d1.GarbageLen()) @@ -672,12 +661,12 @@ func TestGarbageCollection(t *testing.T) { assert.NoError(t, c1.Attach(ctx, d1)) // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv = [c1:1, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewTree("tree", &json.TreeNode{ @@ -689,7 +678,7 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv =[c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -697,7 +686,7 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv =[c1:3] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -705,7 +694,7 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv =[c1:4] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -713,16 +702,16 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv =[c1:5] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:6, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:5], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:5, c2:6], minvv = [c1:1, c2:0], db.vv {c1: [c1:5], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 6))) assert.Equal(t, `abd`, d1.Root().GetTree("tree").ToXML()) assert.Equal(t, `abd`, d2.Root().GetTree("tree").ToXML()) @@ -733,22 +722,22 @@ func TestGarbageCollection(t *testing.T) { return nil }) //d1.vv =[c1:7, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv =[c1:7, c2:1], minvv = [c1:1, c2:1], db.vv {c1: [c1:7, c2:1], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:7, c2:8], minvv =[c1:5, c2:1], db.vv {c1: [c1:7, c2:1], c2: [c1:5, c2:6]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 8)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 8))) // "z" removedAt = 3@c1, minvv[c1] =5 meet GC condition - assert.Equal(t, d2.GarbageLen(), 0) + assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:7, c2:8], minvv =[c1:7, c2:1], db.vv {c1: [c1:7, c2:1], c2: [c1:7, c2:8]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 8)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 8))) assert.Equal(t, `abcd`, d1.Root().GetTree("tree").ToXML()) assert.Equal(t, `abcd`, d2.Root().GetTree("tree").ToXML()) @@ -758,39 +747,38 @@ func TestGarbageCollection(t *testing.T) { return nil }) // d1.vv = [c1:8, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:8, c2:1], minvv = [c1:7, c2:1], db.vv {c1: [c1:8, c2:1], c2: [c1:7, c2:8]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1))) assert.Equal(t, `ad`, d1.Root().GetTree("tree").ToXML()) assert.Equal(t, 2, d1.GarbageLen()) // b,c assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:8, c2:9], minvv =[c1:7, c2:1], db.vv {c1: [c1:8, c2:1], c2: [c1:7, c2:8]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 9)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 9))) assert.NoError(t, c1.Sync(ctx)) // d1.vv =[c1:8, c2:1], minvv =[c1:7, c2:1], db.vv {c1: [c1:8, c2:1], c2: [c1:7, c2:8]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1))) assert.Equal(t, `ad`, d2.Root().GetTree("tree").ToXML()) assert.Equal(t, 2, d1.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:8, c2:9], minvv =[c1:8, c2:1], db.vv {c1: [c1:8, c2:1], c2: [c1:8, c2:9]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 9)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 9))) assert.NoError(t, c1.Sync(ctx)) // d1.vv =[c1:8, c2:1], minvv =[c1:8, c2:1], db.vv {c1: [c1:8, c2:1], c2: [c1:8, c2:9]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 1))) // "b", "c" removedAt = 8@c1, minvv[c1] = 8 meet GC condition assert.Equal(t, 0, d1.GarbageLen()) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:8, c2:9], minvv =[c1:8, c2:1], db.vv {c1: [c1:8, c2:1], c2: [c1:8, c2:9]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 9)), true) - // "b", "c" removedAt = 8@c1, minvv[c1] = 8 meet GC condition + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 9))) assert.NoError(t, err) assert.Equal(t, 0, d1.GarbageLen()) }) @@ -828,13 +816,13 @@ func TestGarbageCollection(t *testing.T) { root.SetNewText("text").Edit(0, 0, "-") return nil })) - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) for i := 0; i < int(conf.Backend.SnapshotInterval); i++ { assert.NoError(t, d1.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(0, 1, strconv.Itoa(i)) return nil })) - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), int64(2+i+1))), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), int64(2+i+1)))) } assert.Equal(t, int(conf.Backend.SnapshotInterval), d1.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) @@ -861,35 +849,35 @@ func TestGarbageCollection(t *testing.T) { d1 := document.New(helper.TestDocKey(t)) assert.NoError(t, c1.Attach(ctx, d1)) // d2.vv =[c1:1], minvv =[c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv =[c1:1, c2:1], minvv =[c1:0, c2:0], db.vv {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewText("text").Edit(0, 0, "a").Edit(1, 1, "b").Edit(2, 2, "c") return nil }, "sets text") //d1.vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv =[c1:3, c2:1], minvv =[c1:0, c2:0], db.vv {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:2, c2:3], minvv =[c1:0, c2:0], db.vv {c1: [c1:2], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(2, 2, "c") return nil }, "insert c") //d2.vv =[c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -897,18 +885,18 @@ func TestGarbageCollection(t *testing.T) { return nil }, "delete bd") //d1.vv = [c1:4, c2:1] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1))) assert.NoError(t, err) assert.Equal(t, 2, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:5, c2:1], minvv = [c1:1, c2:1], db.vv {c1: [c1:4, c2:1], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:4, c2:5], minvv = [c1:2, c2:1], db.vv {c1: [c1:4, c2:1], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 5))) assert.Equal(t, 2, d1.GarbageLen()) assert.Equal(t, 2, d2.GarbageLen()) @@ -917,19 +905,19 @@ func TestGarbageCollection(t *testing.T) { return nil }, "insert 1") //d2.vv =[c1:4, c2:6] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 6))) assert.NoError(t, err) assert.NoError(t, c2.Sync(ctx)) // d2.vv =[c1:4, c2:6], minvv = [c1:4, c2:1], db.vv {c1: [c1:4, c2:1], c2: [c1:4, c2:6]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 4), versionOf(d2.ActorID(), 6))) // "b", "c" removedAt = 4@c1, minvv[c1] = 4 meet GC condition assert.Equal(t, 2, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:7, c2:6], minvv = [c1:4, c2:1], db.vv {c1: [c1:5, c2:1], c2: [c1:4, c2:6]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 6))) // "b", "c" removedAt = 4@c1, minvv[c1] = 4 meet GC condition assert.Equal(t, 0, d1.GarbageLen()) assert.Equal(t, 0, d2.GarbageLen()) @@ -941,52 +929,52 @@ func TestGarbageCollection(t *testing.T) { assert.NoError(t, c1.Attach(ctx, d1)) // d2.vv =[c1:1], minvv =[c1:1], db.vv {c1: [c1:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) d2 := document.New(helper.TestDocKey(t)) assert.NoError(t, c2.Attach(ctx, d2)) // d2.vv =[c1:1, c2:2], minvv =[c1:0, c2:0], db.vv {c1: [c1:1], c2: [c2:1]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) err := d1.Update(func(root *json.Object, p *presence.Presence) error { root.SetNewText("text").Edit(0, 0, "a").Edit(1, 1, "b") return nil }, "insert ab") // d1/vv = [c1:2] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) assert.NoError(t, err) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:3, c2:1], minvv = [c1:0, c2:0], db.vv {c1: [c1:2], c2: [c2:1]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:2, c2:3], minvv = [c1:1, c2:0], db.vv {c1: [c1:2], c2: [c1:1, c2:2]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(2, 2, "d") return nil }, "insert d") //d2.vv = [c1:2, c2:4] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:0], db.vv {c1: [c1:2], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:1], db.vv {c1: [c1:3, c2:1], c2: [c1:2, c2:4]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(2, 2, "c") return nil }, "insert c") //d2.vv = [c1:2, c2:5] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 5))) assert.NoError(t, err) err = d1.Update(func(root *json.Object, p *presence.Presence) error { @@ -994,73 +982,73 @@ func TestGarbageCollection(t *testing.T) { return nil }, "remove ac") //c1.vv = [c1:6, c2:4] - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 4)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 4))) assert.NoError(t, err) // sync pushonly assert.NoError(t, c2.Sync(ctx, client.WithDocKey(d2.Key()).WithPushOnly())) // d2.vv = [c1:2, c2:5], minvv = [c1:2, c2:1], db.vv {c1: [c1:3, c2:1], c2: [c1:2, c2:5]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 5))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:7, c2:5], minvv = [c1:2, c2:4], db.vv {c1: [c1:6, c2:4], c2: [c1:2, c2:5]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 5)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 7), versionOf(d2.ActorID(), 5))) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(2, 2, "1") return nil }, "insert 1 (pushonly)") //d2.vv = [c1:2, c2:6] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 6))) assert.NoError(t, err) assert.NoError(t, c2.Sync(ctx, client.WithDocKey(d2.Key()).WithPushOnly())) // d2.vv = [c1:2, c2:6], minvv = [c1:2, c2:4], db.vv {c1: [c1:6, c2:4], c2: [c1:2, c2:6]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 6)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 6))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:8, c2:6], minvv = [c1:2, c2:5], db.vv {c1: [c1:7, c2:5], c2: [c1:2, c2:6]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 6)), true) - assert.Equal(t, d1.GarbageLen(), 2) - assert.Equal(t, d2.GarbageLen(), 0) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 8), versionOf(d2.ActorID(), 6))) + assert.Equal(t, 2, d1.GarbageLen()) + assert.Equal(t, 0, d2.GarbageLen()) err = d2.Update(func(root *json.Object, p *presence.Presence) error { root.GetText("text").Edit(2, 2, "2") return nil }, "insert 2 (pushonly)") //c2.vv = [c1:2, c2:7] - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 7)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 7))) assert.NoError(t, err) assert.NoError(t, c2.Sync(ctx, client.WithDocKey(d2.Key()).WithPushOnly())) // d2.vv = [c1:2, c2:7], minvv = [c1:2, c2:5], db.vv {c1: [c1:7, c2:5], c2: [c1:2, c2:7]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 7)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 7))) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:6, c2:8], minvv = [c1:2, c2:5], db.vv {c1: [c1:7, c2:5], c2: [c1:2, c2:7]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 8)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 8))) assert.NoError(t, c1.Sync(ctx)) // d1.vv = [c1:9, c2:7]], minvv = [c1:2, c2:6], db.vv {c1: [c1:8, c2:6], c2: [c1:2, c2:7]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 9), versionOf(d2.ActorID(), 7)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 9), versionOf(d2.ActorID(), 7))) assert.Equal(t, d1.GarbageLen(), 2) assert.Equal(t, d2.GarbageLen(), 2) assert.NoError(t, c2.Sync(ctx)) // d2.vv = [c1:6, c2:8], minvv = [c1:6, c2:6], db.vv {c1: [c1:8, c2:6], c2: [c1:6, c2:8]} - assert.Equal(t, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 8)), true) + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 6), versionOf(d2.ActorID(), 8))) // removedAt = 6@c1, minvv[c1] = 6, meet GC condition - assert.Equal(t, d1.GarbageLen(), 2) - assert.Equal(t, d2.GarbageLen(), 0) + assert.Equal(t, 2, d1.GarbageLen()) + assert.Equal(t, 0, d2.GarbageLen()) assert.NoError(t, c1.Sync(ctx)) // d2.vv = [c1:9, c2:7], minvv = [c1:6, c2:7], db.vv {c1: [c1:9, c2:7], c2: [c1:6, c2:8]} - assert.Equal(t, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 9), versionOf(d2.ActorID(), 7)), true) + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 9), versionOf(d2.ActorID(), 7))) // removedAt = 6@c1, minvv[c1] = 6, meet GC condition - assert.Equal(t, d1.GarbageLen(), 0) - assert.Equal(t, d2.GarbageLen(), 0) - assert.Equal(t, d1.Marshal(), `{"text":[{"val":"a"},{"val":"2"},{"val":"1"},{"val":"c"}]}`) - assert.Equal(t, d2.Marshal(), `{"text":[{"val":"a"},{"val":"2"},{"val":"1"},{"val":"c"}]}`) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 0, d2.GarbageLen()) + assert.Equal(t, `{"text":[{"val":"a"},{"val":"2"},{"val":"1"},{"val":"c"}]}`, d1.Marshal()) + assert.Equal(t, `{"text":[{"val":"a"},{"val":"2"},{"val":"1"},{"val":"c"}]}`, d2.Marshal()) }) t.Run("gc doesn't run when detached client's version vector remains in db", func(t *testing.T) { From 3cf29bfc3700adba1b5aa17a8c58db62babe20b7 Mon Sep 17 00:00:00 2001 From: raararaara Date: Tue, 19 Nov 2024 17:34:19 +0900 Subject: [PATCH 5/6] Add missing test --- test/integration/gc_test.go | 82 +++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/test/integration/gc_test.go b/test/integration/gc_test.go index 18cc95c52..b1e4978f0 100644 --- a/test/integration/gc_test.go +++ b/test/integration/gc_test.go @@ -142,6 +142,88 @@ func TestGarbageCollection(t *testing.T) { assert.Equal(t, 0, d2.GarbageLen()) }) + t.Run("garbage collection for text type test", func(t *testing.T) { + ctx := context.Background() + d1 := document.New(helper.TestDocKey(t)) + assert.NoError(t, c1.Attach(ctx, d1)) + // d1.vv = [c1:1], minvv = [c1:1], db.vv {c1: [c1:1]} + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 1))) + + d2 := document.New(helper.TestDocKey(t)) + assert.NoError(t, c2.Attach(ctx, d2)) + // d2.vv = [c1: 1, c2:2], minvv = [c1: 0, c2:0], db.vv = {c1: [c1:1], c2: [c2:1]} + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 1), versionOf(d2.ActorID(), 2))) + + assert.NoError(t, + d1.Update(func(root *json.Object, p *presence.Presence) error { + root.SetNewText("text"). + Edit(0, 0, "Hello world") + root.SetNewText("richText"). + Edit(0, 0, "Hello world", nil) + return nil + }, "sets test and richText"), + ) + // d1.vv = [c1:2] + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 2))) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 0, d2.GarbageLen()) + + assert.NoError(t, c1.Sync(ctx)) + // d1.vv = [c1:3, c2:1], minvv = [c1:0, c2:0], db.vv = {c1: [c1:2], c2: [c2:1]} + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 3), versionOf(d2.ActorID(), 1))) + + assert.NoError(t, c2.Sync(ctx)) + // d2.vv = [c1:2, c2:3], minvv = [c1:1, c2:0], db.vv = {c1: [c1:2], c2: [c1:1 c2:2]} + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 3))) + + assert.NoError(t, + d2.Update(func(root *json.Object, p *presence.Presence) error { + root.GetText("text"). + Edit(0, 1, "a"). + Edit(1, 2, "b") + root.GetText("richText"). + Edit(0, 1, "a", map[string]string{"b": "1"}) + return nil + }, "edit text type elements"), + ) + // d2.vv = [c1:2, c2:4] + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 3, d2.GarbageLen()) + + assert.NoError(t, c2.Sync(ctx)) + // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:0], db.vv = {c1: [c1:2], c2: [c1:2 c2:4]} + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 3, d2.GarbageLen()) + + assert.NoError(t, c1.Sync(ctx)) + // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:1], db.vv = {c1: [c1:3, c2:1], c2: [c1:2 c2:4]} + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) + assert.Equal(t, 3, d1.GarbageLen()) + assert.Equal(t, 3, d2.GarbageLen()) + + assert.NoError(t, c2.Sync(ctx)) + // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:0], db.vv = {c1: [c1:3, c2:1], c2: [c1:2 c2:4]} + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) + assert.Equal(t, 3, d1.GarbageLen()) + assert.Equal(t, 3, d2.GarbageLen()) + + assert.NoError(t, c1.Sync(ctx)) + // d1.vv = [c1:5, c2:4], minvv = [c1:2, c2:4], db.vv = {c1: [c1:5, c2:4], c2: [c1:2 c2:4]} + assert.Equal(t, true, checkVV(d1.VersionVector(), versionOf(d1.ActorID(), 5), versionOf(d2.ActorID(), 4))) + // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition + assert.Equal(t, 0, d1.GarbageLen()) + assert.Equal(t, 3, d2.GarbageLen()) + + assert.NoError(t, c2.Sync(ctx)) + // d2.vv = [c1:2, c2:4], minvv = [c1:2, c2:4], db.vv = {c1: [c1:5, c2:4], c2: [c1:2 c2:4]} + assert.Equal(t, true, checkVV(d2.VersionVector(), versionOf(d1.ActorID(), 2), versionOf(d2.ActorID(), 4))) + assert.Equal(t, 0, d1.GarbageLen()) + // node removedAt = 4@c2, minVV[c2] = 4 meet GC condition + assert.Equal(t, 0, d2.GarbageLen()) + }) + t.Run("garbage collection for tree type test", func(t *testing.T) { doc := document.New(helper.TestDocKey(t)) From c7770f22374b7925ef204adae15bb6b9714a5b8a Mon Sep 17 00:00:00 2001 From: raararaara Date: Tue, 19 Nov 2024 17:38:38 +0900 Subject: [PATCH 6/6] Erase duplicate test --- test/integration/gc_test.go | 72 ------------------------------------- 1 file changed, 72 deletions(-) diff --git a/test/integration/gc_test.go b/test/integration/gc_test.go index b1e4978f0..39c9f2c78 100644 --- a/test/integration/gc_test.go +++ b/test/integration/gc_test.go @@ -295,78 +295,6 @@ func TestGarbageCollection(t *testing.T) { assert.Equal(t, 0, doc.GarbageLen()) }) - t.Run("garbage collection for tree type test", func(t *testing.T) { - doc := document.New(helper.TestDocKey(t)) - - err := doc.Update(func(root *json.Object, p *presence.Presence) error { - root.SetNewTree("t", &json.TreeNode{ - Type: "doc", - Children: []json.TreeNode{{ - Type: "p", Children: []json.TreeNode{{ - Type: "tn", Children: []json.TreeNode{{ - Type: "text", Value: "a", - }, { - Type: "text", Value: "b", - }}, - }, { - Type: "tn", Children: []json.TreeNode{{ - Type: "text", Value: "cd", - }}, - }}, - }}, - }) - assert.Equal(t, `

abcd

`, root.GetTree("t").ToXML()) - - return nil - }) - assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 1))) - assert.NoError(t, err) - - err = doc.Update(func(root *json.Object, p *presence.Presence) error { - root.GetTree("t").EditByPath([]int{0, 0, 0}, []int{0, 0, 2}, &json.TreeNode{Type: "text", Value: "gh"}, 0) - assert.Equal(t, `

ghcd

`, root.GetTree("t").ToXML()) - return nil - }) - - // [text(a), text(b)] - assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 2))) - assert.NoError(t, err) - assert.Equal(t, doc.GarbageLen(), 2) - assert.Equal(t, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID())), 2) - assert.Equal(t, doc.GarbageLen(), 0) - - err = doc.Update(func(root *json.Object, p *presence.Presence) error { - root.GetTree("t").EditByPath([]int{0, 0, 0}, []int{0, 0, 2}, &json.TreeNode{Type: "text", Value: "cv"}, 0) - assert.Equal(t, `

cvcd

`, root.GetTree("t").ToXML()) - return nil - }) - - // [text(gh)] - assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 3))) - assert.NoError(t, err) - assert.Equal(t, doc.GarbageLen(), 1) - assert.Equal(t, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID())), 1) - assert.Equal(t, doc.GarbageLen(), 0) - - err = doc.Update(func(root *json.Object, p *presence.Presence) error { - root.GetTree("t").EditByPath([]int{0}, []int{1}, &json.TreeNode{ - Type: "p", Children: []json.TreeNode{{ - Type: "tn", Children: []json.TreeNode{{ - Type: "text", Value: "ab", - }}, - }}}, 0) - assert.Equal(t, `

ab

`, root.GetTree("t").ToXML()) - return nil - }) - - // [p, tn, tn, text(cv), text(cd)] - assert.Equal(t, true, checkVV(doc.VersionVector(), versionOf(doc.ActorID(), 4))) - assert.NoError(t, err) - assert.Equal(t, doc.GarbageLen(), 5) - assert.Equal(t, doc.GarbageCollect(helper.MaxVersionVector(doc.ActorID())), 5) - assert.Equal(t, doc.GarbageLen(), 0) - }) - t.Run("garbage collection for tree type test (multi clients)", func(t *testing.T) { ctx := context.Background() d1 := document.New(helper.TestDocKey(t))