diff --git a/common/commonspace/synctree/synctree_test.go b/common/commonspace/synctree/synctree_test.go index 1a07c880..5c8acc6c 100644 --- a/common/commonspace/synctree/synctree_test.go +++ b/common/commonspace/synctree/synctree_test.go @@ -174,12 +174,11 @@ func Test_BuildSyncTree(t *testing.T) { NewHeads: nil, RawChanges: changes, } - expectedRes := tree.AddResult{ Added: changes, Mode: tree.Nothing, } - objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(payload)). Return(expectedRes, nil) res, err := tr.AddRawChanges(ctx, payload) diff --git a/common/commonspace/synctree/synctreehandler_test.go b/common/commonspace/synctree/synctreehandler_test.go index 70d96c24..40cfa65f 100644 --- a/common/commonspace/synctree/synctreehandler_test.go +++ b/common/commonspace/synctree/synctreehandler_test.go @@ -33,11 +33,17 @@ func (t *testObjTreeMock) Unlock() { t.m.Unlock() } -func TestSyncHandler_HandleHeadUpdate(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() +type syncHandlerFixture struct { + ctrl *gomock.Controller + syncClientMock *mock_synctree.MockSyncClient + objectTreeMock *testObjTreeMock + receiveQueueMock *mock_synctree.MockReceiveQueue - ctx := context.Background() + syncHandler *syncTreeHandler +} + +func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture { + ctrl := gomock.NewController(t) syncClientMock := mock_synctree.NewMockSyncClient(ctrl) objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) receiveQueueMock := mock_synctree.NewMockReceiveQueue(ctrl) @@ -47,9 +53,26 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { syncClient: syncClientMock, queue: receiveQueueMock, } + return &syncHandlerFixture{ + ctrl: ctrl, + syncClientMock: syncClientMock, + objectTreeMock: objectTreeMock, + receiveQueueMock: receiveQueueMock, + syncHandler: syncHandler, + } +} + +func (fx *syncHandlerFixture) stop() { + fx.ctrl.Finish() +} + +func TestSyncHandler_HandleHeadUpdate(t *testing.T) { + ctx := context.Background() log = zap.NewNop().Sugar() t.Run("head update non empty all heads added", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -61,36 +84,29 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") - receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), ""). - Return(false) - receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}).Times(2) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2) + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ NewHeads: []string{"h1"}, RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, })). Return(tree.AddResult{}, nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2", "h1"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(true) - receiveQueueMock.EXPECT().ClearQueue(senderId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2", "h1"}) + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(true) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update non empty heads not added", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -102,39 +118,32 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullRequest := &treechangeproto.TreeSyncMessage{} - receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), ""). - Return(false) - receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}).AnyTimes() - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ NewHeads: []string{"h1"}, RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, })). Return(tree.AddResult{}, nil) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - syncClientMock.EXPECT(). - CreateFullSyncRequest(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.syncClientMock.EXPECT(). + CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullRequest, nil) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - receiveQueueMock.EXPECT().ClearQueue(senderId) - - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update non empty equal heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -145,18 +154,20 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update empty", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -168,26 +179,24 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullRequest := &treechangeproto.TreeSyncMessage{} + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - syncClientMock.EXPECT(). - CreateFullSyncRequest(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.syncClientMock.EXPECT(). + CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullRequest, nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update empty equal heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -198,34 +207,25 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) } func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - ctx := context.Background() - syncClientMock := mock_synctree.NewMockSyncClient(ctrl) - objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) - receiveQueueMock := mock_synctree.NewMockReceiveQueue(ctrl) - syncHandler := &syncTreeHandler{ - objTree: objectTreeMock, - syncClient: syncClientMock, - queue: receiveQueueMock, - } - log = zap.NewNop().Sugar() + t.Run("full sync request with change", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -237,27 +237,32 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullResponse := &treechangeproto.TreeSyncMessage{} - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, nil) - syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullResponse, nil) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync request with change same heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -269,21 +274,28 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullResponse := &treechangeproto.TreeSyncMessage{} - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT(). ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.objectTreeMock.EXPECT(). Heads(). - Return([]string{"h1"}) - syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return([]string{"h1"}).AnyTimes() + fx.syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullResponse, nil) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync request without change but with reply id", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" replyId := "replyId" @@ -295,18 +307,25 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) fullResponse := &treechangeproto.TreeSyncMessage{} - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), replyId).Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, replyId, nil) + + fx.objectTreeMock.EXPECT(). ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullResponse, nil) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq(replyId)) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq(replyId)) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync request with add raw changes error", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -317,41 +336,39 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT(). ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.objectTreeMock.EXPECT(). Heads(). Return([]string{"h2"}) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT(). HasChanges(gomock.Eq([]string{"h1"})). Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, fmt.Errorf("")) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Any(), gomock.Eq("")) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Any(), gomock.Eq("")) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.Error(t, err) }) } func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - ctx := context.Background() - syncClientMock := mock_synctree.NewMockSyncClient(ctrl) - objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) - receiveQueueMock := mock_synctree.NewMockReceiveQueue(ctrl) - syncHandler := &syncTreeHandler{ - objTree: objectTreeMock, - syncClient: syncClientMock, - queue: receiveQueueMock, - } - log = zap.NewNop().Sugar() t.Run("full sync response with change", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" replyId := "replyId" @@ -363,22 +380,31 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) - objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), replyId).Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, replyId, nil) + + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT(). Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). + Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT(). HasChanges(gomock.Eq([]string{"h1"})). Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, nil) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync response with same heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" replyId := "replyId" @@ -390,12 +416,16 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) - objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}) + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), replyId).Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, replyId, nil) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}).AnyTimes() + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) } diff --git a/common/pkg/acl/tree/treebuilder.go b/common/pkg/acl/tree/treebuilder.go index f359d00e..d9e7f531 100644 --- a/common/pkg/acl/tree/treebuilder.go +++ b/common/pkg/acl/tree/treebuilder.go @@ -48,8 +48,10 @@ func (tb *treeBuilder) Build(theirHeads []string, newChanges []*Change) (*Tree, return nil, err } - // TODO: we can actually get this from database - // getting old common snapshot + // TODO: we can actually get this from tree (though not sure, that there would always be + // an invariant where the tree has the closest common snapshot of heads) + // so if optimization is critical we can change this to inject from tree directly + // but then we have to be sure that invariant stays true oldBreakpoint, err := tb.findBreakpoint(heads, true) if err != nil { // this should never error out, because otherwise we have broken data