SyncTreeHandler tests
This commit is contained in:
parent
b18bb02176
commit
100e7e04c3
@ -1,5 +1,5 @@
|
|||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/anyproto/any-sync/commonspace/object/tree/synctree (interfaces: SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory)
|
// Source: github.com/anyproto/any-sync/commonspace/object/tree/synctree (interfaces: SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory,TreeSyncProtocol)
|
||||||
|
|
||||||
// Package mock_synctree is a generated GoMock package.
|
// Package mock_synctree is a generated GoMock package.
|
||||||
package mock_synctree
|
package mock_synctree
|
||||||
@ -822,3 +822,70 @@ func (mr *MockRequestFactoryMockRecorder) CreateNewTreeRequest() *gomock.Call {
|
|||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockRequestFactory)(nil).CreateNewTreeRequest))
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockRequestFactory)(nil).CreateNewTreeRequest))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MockTreeSyncProtocol is a mock of TreeSyncProtocol interface.
|
||||||
|
type MockTreeSyncProtocol struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockTreeSyncProtocolMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockTreeSyncProtocolMockRecorder is the mock recorder for MockTreeSyncProtocol.
|
||||||
|
type MockTreeSyncProtocolMockRecorder struct {
|
||||||
|
mock *MockTreeSyncProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockTreeSyncProtocol creates a new mock instance.
|
||||||
|
func NewMockTreeSyncProtocol(ctrl *gomock.Controller) *MockTreeSyncProtocol {
|
||||||
|
mock := &MockTreeSyncProtocol{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockTreeSyncProtocolMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockTreeSyncProtocol) EXPECT() *MockTreeSyncProtocolMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullSyncRequest mocks base method.
|
||||||
|
func (m *MockTreeSyncProtocol) FullSyncRequest(arg0 context.Context, arg1 string, arg2 *treechangeproto.TreeFullSyncRequest) (*treechangeproto.TreeSyncMessage, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "FullSyncRequest", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullSyncRequest indicates an expected call of FullSyncRequest.
|
||||||
|
func (mr *MockTreeSyncProtocolMockRecorder) FullSyncRequest(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullSyncRequest", reflect.TypeOf((*MockTreeSyncProtocol)(nil).FullSyncRequest), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullSyncResponse mocks base method.
|
||||||
|
func (m *MockTreeSyncProtocol) FullSyncResponse(arg0 context.Context, arg1 string, arg2 *treechangeproto.TreeFullSyncResponse) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "FullSyncResponse", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullSyncResponse indicates an expected call of FullSyncResponse.
|
||||||
|
func (mr *MockTreeSyncProtocolMockRecorder) FullSyncResponse(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullSyncResponse", reflect.TypeOf((*MockTreeSyncProtocol)(nil).FullSyncResponse), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeadUpdate mocks base method.
|
||||||
|
func (m *MockTreeSyncProtocol) HeadUpdate(arg0 context.Context, arg1 string, arg2 *treechangeproto.TreeHeadUpdate) (*treechangeproto.TreeSyncMessage, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "HeadUpdate", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeadUpdate indicates an expected call of HeadUpdate.
|
||||||
|
func (mr *MockTreeSyncProtocolMockRecorder) HeadUpdate(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadUpdate", reflect.TypeOf((*MockTreeSyncProtocol)(nil).HeadUpdate), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anyproto/any-sync/commonspace/object/tree/synctree SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory
|
//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anyproto/any-sync/commonspace/object/tree/synctree SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory,TreeSyncProtocol
|
||||||
package synctree
|
package synctree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@ -2,19 +2,15 @@ package synctree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree"
|
||||||
"github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync"
|
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/anyproto/any-sync/app/logger"
|
|
||||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
|
|
||||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
|
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
|
||||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
|
||||||
"github.com/anyproto/any-sync/commonspace/syncstatus"
|
"github.com/anyproto/any-sync/commonspace/syncstatus"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type testObjTreeMock struct {
|
type testObjTreeMock struct {
|
||||||
@ -54,9 +50,13 @@ func (t *testObjTreeMock) TryRLock() bool {
|
|||||||
|
|
||||||
type syncHandlerFixture struct {
|
type syncHandlerFixture struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
syncClientMock *mock_objectsync.MockSyncClient
|
syncClientMock *mock_synctree.MockSyncClient
|
||||||
objectTreeMock *testObjTreeMock
|
objectTreeMock *testObjTreeMock
|
||||||
receiveQueueMock ReceiveQueue
|
receiveQueueMock ReceiveQueue
|
||||||
|
syncProtocolMock *mock_synctree.MockTreeSyncProtocol
|
||||||
|
spaceId string
|
||||||
|
senderId string
|
||||||
|
treeId string
|
||||||
|
|
||||||
syncHandler *syncTreeHandler
|
syncHandler *syncTreeHandler
|
||||||
}
|
}
|
||||||
@ -64,19 +64,29 @@ type syncHandlerFixture struct {
|
|||||||
func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture {
|
func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture {
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
objectTreeMock := newTestObjMock(mock_objecttree.NewMockObjectTree(ctrl))
|
objectTreeMock := newTestObjMock(mock_objecttree.NewMockObjectTree(ctrl))
|
||||||
|
syncClientMock := mock_synctree.NewMockSyncClient(ctrl)
|
||||||
|
syncProtocolMock := mock_synctree.NewMockTreeSyncProtocol(ctrl)
|
||||||
|
spaceId := "spaceId"
|
||||||
receiveQueue := newReceiveQueue(5)
|
receiveQueue := newReceiveQueue(5)
|
||||||
|
|
||||||
syncHandler := &syncTreeHandler{
|
syncHandler := &syncTreeHandler{
|
||||||
objTree: objectTreeMock,
|
objTree: objectTreeMock,
|
||||||
//syncClient: syncClientMock,
|
syncClient: syncClientMock,
|
||||||
queue: receiveQueue,
|
syncProtocol: syncProtocolMock,
|
||||||
syncStatus: syncstatus.NewNoOpSyncStatus(),
|
spaceId: spaceId,
|
||||||
|
queue: receiveQueue,
|
||||||
|
syncStatus: syncstatus.NewNoOpSyncStatus(),
|
||||||
}
|
}
|
||||||
return &syncHandlerFixture{
|
return &syncHandlerFixture{
|
||||||
ctrl: ctrl,
|
ctrl: ctrl,
|
||||||
objectTreeMock: objectTreeMock,
|
objectTreeMock: objectTreeMock,
|
||||||
receiveQueueMock: receiveQueue,
|
receiveQueueMock: receiveQueue,
|
||||||
|
syncProtocolMock: syncProtocolMock,
|
||||||
|
syncClientMock: syncClientMock,
|
||||||
syncHandler: syncHandler,
|
syncHandler: syncHandler,
|
||||||
|
spaceId: spaceId,
|
||||||
|
senderId: "senderId",
|
||||||
|
treeId: "treeId",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,341 +94,128 @@ func (fx *syncHandlerFixture) stop() {
|
|||||||
fx.ctrl.Finish()
|
fx.ctrl.Finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
|
func TestSyncTreeHandler_HandleMessage(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
log = logger.CtxLogger{Logger: zap.NewNop()}
|
|
||||||
fullRequest := &treechangeproto.TreeSyncMessage{
|
|
||||||
Content: &treechangeproto.TreeSyncContentValue{
|
|
||||||
Value: &treechangeproto.TreeSyncContentValue_FullSyncRequest{
|
|
||||||
FullSyncRequest: &treechangeproto.TreeFullSyncRequest{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("head update non empty all heads added", func(t *testing.T) {
|
t.Run("handle head update message", func(t *testing.T) {
|
||||||
fx := newSyncHandlerFixture(t)
|
fx := newSyncHandlerFixture(t)
|
||||||
defer fx.stop()
|
defer fx.stop()
|
||||||
treeId := "treeId"
|
treeId := "treeId"
|
||||||
senderId := "senderId"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
headUpdate := &treechangeproto.TreeHeadUpdate{
|
headUpdate := &treechangeproto.TreeHeadUpdate{}
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId)
|
syncReq := &treechangeproto.TreeSyncMessage{}
|
||||||
fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2)
|
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId)
|
||||||
fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false)
|
fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(syncReq, nil)
|
||||||
fx.objectTreeMock.EXPECT().
|
fx.syncClientMock.EXPECT().QueueRequest(fx.senderId, fx.treeId, syncReq).Return(nil)
|
||||||
AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{
|
|
||||||
NewHeads: []string{"h1"},
|
|
||||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
})).
|
|
||||||
Return(objecttree.AddResult{}, nil)
|
|
||||||
fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(true)
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("head update non empty heads not added", func(t *testing.T) {
|
t.Run("handle head update message, empty sync request", func(t *testing.T) {
|
||||||
fx := newSyncHandlerFixture(t)
|
fx := newSyncHandlerFixture(t)
|
||||||
defer fx.stop()
|
defer fx.stop()
|
||||||
treeId := "treeId"
|
treeId := "treeId"
|
||||||
senderId := "senderId"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
headUpdate := &treechangeproto.TreeHeadUpdate{
|
headUpdate := &treechangeproto.TreeHeadUpdate{}
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId)
|
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId)
|
||||||
fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes()
|
fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(nil, nil)
|
||||||
fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false)
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{
|
|
||||||
NewHeads: []string{"h1"},
|
|
||||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
})).
|
|
||||||
Return(objecttree.AddResult{}, nil)
|
|
||||||
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().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullRequest), gomock.Eq(""))
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("head update non empty equal heads", func(t *testing.T) {
|
t.Run("handle full sync request returns error", func(t *testing.T) {
|
||||||
fx := newSyncHandlerFixture(t)
|
fx := newSyncHandlerFixture(t)
|
||||||
defer fx.stop()
|
defer fx.stop()
|
||||||
treeId := "treeId"
|
treeId := "treeId"
|
||||||
senderId := "senderId"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
headUpdate := &treechangeproto.TreeHeadUpdate{
|
fullRequest := &treechangeproto.TreeFullSyncRequest{}
|
||||||
Heads: []string{"h1"},
|
treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId)
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId)
|
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId)
|
||||||
fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes()
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg)
|
||||||
require.NoError(t, err)
|
require.Equal(t, err, ErrMessageIsRequest)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("head update empty", func(t *testing.T) {
|
t.Run("handle full sync response", func(t *testing.T) {
|
||||||
fx := newSyncHandlerFixture(t)
|
fx := newSyncHandlerFixture(t)
|
||||||
defer fx.stop()
|
defer fx.stop()
|
||||||
treeId := "treeId"
|
treeId := "treeId"
|
||||||
senderId := "senderId"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
headUpdate := &treechangeproto.TreeHeadUpdate{
|
fullSyncResponse := &treechangeproto.TreeFullSyncResponse{}
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: nil,
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
|
||||||
|
|
||||||
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)
|
|
||||||
fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullRequest), gomock.Eq(""))
|
|
||||||
|
|
||||||
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{}
|
|
||||||
headUpdate := &treechangeproto.TreeHeadUpdate{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: nil,
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId)
|
|
||||||
fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes()
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
|
||||||
require.NoError(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSyncHandler_HandleFullSyncRequest(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
log = logger.CtxLogger{Logger: zap.NewNop()}
|
|
||||||
fullResponse := &treechangeproto.TreeSyncMessage{
|
|
||||||
Content: &treechangeproto.TreeSyncContentValue{
|
|
||||||
Value: &treechangeproto.TreeSyncContentValue_FullSyncResponse{
|
|
||||||
FullSyncResponse: &treechangeproto.TreeFullSyncResponse{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("full sync request with change", func(t *testing.T) {
|
|
||||||
fx := newSyncHandlerFixture(t)
|
|
||||||
defer fx.stop()
|
|
||||||
treeId := "treeId"
|
|
||||||
senderId := "senderId"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
|
||||||
fullSyncRequest := &treechangeproto.TreeFullSyncRequest{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
|
||||||
|
|
||||||
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(objecttree.RawChangesPayload{
|
|
||||||
NewHeads: []string{"h1"},
|
|
||||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
})).
|
|
||||||
Return(objecttree.AddResult{}, nil)
|
|
||||||
fx.syncClientMock.EXPECT().
|
|
||||||
CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})).
|
|
||||||
Return(fullResponse, nil)
|
|
||||||
fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullResponse), gomock.Eq(""))
|
|
||||||
|
|
||||||
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{}
|
|
||||||
fullSyncRequest := &treechangeproto.TreeFullSyncRequest{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
Id().AnyTimes().Return(treeId)
|
|
||||||
fx.objectTreeMock.EXPECT().Header().Return(nil)
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
Heads().
|
|
||||||
Return([]string{"h1"}).AnyTimes()
|
|
||||||
fx.syncClientMock.EXPECT().
|
|
||||||
CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})).
|
|
||||||
Return(fullResponse, nil)
|
|
||||||
fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullResponse), gomock.Eq(""))
|
|
||||||
|
|
||||||
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"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
|
||||||
fullSyncRequest := &treechangeproto.TreeFullSyncRequest{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
|
||||||
objectMsg.RequestId = replyId
|
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
Id().AnyTimes().Return(treeId)
|
|
||||||
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)
|
|
||||||
fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullResponse), gomock.Eq(replyId))
|
|
||||||
|
|
||||||
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{}
|
|
||||||
fullSyncRequest := &treechangeproto.TreeFullSyncRequest{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
Id().AnyTimes().Return(treeId)
|
|
||||||
fx.objectTreeMock.EXPECT().Header().Return(nil)
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
Heads().
|
|
||||||
Return([]string{"h2"})
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
HasChanges(gomock.Eq([]string{"h1"})).
|
|
||||||
Return(false)
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{
|
|
||||||
NewHeads: []string{"h1"},
|
|
||||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
})).
|
|
||||||
Return(objecttree.AddResult{}, fmt.Errorf(""))
|
|
||||||
fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Any(), gomock.Eq(""))
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSyncHandler_HandleFullSyncResponse(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
log = logger.CtxLogger{Logger: zap.NewNop()}
|
|
||||||
|
|
||||||
t.Run("full sync response with change", func(t *testing.T) {
|
|
||||||
fx := newSyncHandlerFixture(t)
|
|
||||||
defer fx.stop()
|
|
||||||
treeId := "treeId"
|
|
||||||
senderId := "senderId"
|
|
||||||
replyId := "replyId"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
|
||||||
fullSyncResponse := &treechangeproto.TreeFullSyncResponse{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId)
|
treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId)
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId)
|
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId)
|
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId)
|
||||||
fx.objectTreeMock.EXPECT().
|
fx.syncProtocolMock.EXPECT().FullSyncResponse(ctx, fx.senderId, gomock.Any()).Return(nil)
|
||||||
Heads().
|
|
||||||
Return([]string{"h2"}).AnyTimes()
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
HasChanges(gomock.Eq([]string{"h1"})).
|
|
||||||
Return(false)
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{
|
|
||||||
NewHeads: []string{"h1"},
|
|
||||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
})).
|
|
||||||
Return(objecttree.AddResult{}, nil)
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
err := fx.syncHandler.HandleMessage(ctx, fx.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"
|
|
||||||
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
|
||||||
fullSyncResponse := &treechangeproto.TreeFullSyncResponse{
|
|
||||||
Heads: []string{"h1"},
|
|
||||||
Changes: []*treechangeproto.RawTreeChangeWithId{chWithId},
|
|
||||||
SnapshotPath: []string{"h1"},
|
|
||||||
}
|
|
||||||
treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId)
|
|
||||||
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId)
|
|
||||||
|
|
||||||
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId)
|
|
||||||
fx.objectTreeMock.EXPECT().
|
|
||||||
Heads().
|
|
||||||
Return([]string{"h1"}).AnyTimes()
|
|
||||||
|
|
||||||
err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSyncTreeHandler_HandleRequest(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
t.Run("handle request", func(t *testing.T) {
|
||||||
|
fx := newSyncHandlerFixture(t)
|
||||||
|
defer fx.stop()
|
||||||
|
treeId := "treeId"
|
||||||
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
|
fullRequest := &treechangeproto.TreeFullSyncRequest{}
|
||||||
|
treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId)
|
||||||
|
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
||||||
|
|
||||||
|
syncResp := &treechangeproto.TreeSyncMessage{}
|
||||||
|
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId)
|
||||||
|
fx.syncProtocolMock.EXPECT().FullSyncRequest(ctx, fx.senderId, gomock.Any()).Return(syncResp, nil)
|
||||||
|
|
||||||
|
res, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, res)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("handle request", func(t *testing.T) {
|
||||||
|
fx := newSyncHandlerFixture(t)
|
||||||
|
defer fx.stop()
|
||||||
|
treeId := "treeId"
|
||||||
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
|
fullRequest := &treechangeproto.TreeFullSyncRequest{}
|
||||||
|
treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId)
|
||||||
|
objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "")
|
||||||
|
|
||||||
|
syncResp := &treechangeproto.TreeSyncMessage{}
|
||||||
|
fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId)
|
||||||
|
fx.syncProtocolMock.EXPECT().FullSyncRequest(ctx, fx.senderId, gomock.Any()).Return(syncResp, nil)
|
||||||
|
|
||||||
|
res, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, res)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("handle other message", func(t *testing.T) {
|
||||||
|
fx := newSyncHandlerFixture(t)
|
||||||
|
defer fx.stop()
|
||||||
|
treeId := "treeId"
|
||||||
|
chWithId := &treechangeproto.RawTreeChangeWithId{}
|
||||||
|
fullResponse := &treechangeproto.TreeFullSyncResponse{}
|
||||||
|
responseMsg := treechangeproto.WrapFullResponse(fullResponse, chWithId)
|
||||||
|
headUpdate := &treechangeproto.TreeHeadUpdate{}
|
||||||
|
headUpdateMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId)
|
||||||
|
for _, msg := range []*treechangeproto.TreeSyncMessage{responseMsg, headUpdateMsg} {
|
||||||
|
objectMsg, _ := MarshallTreeMessage(msg, "spaceId", treeId, "")
|
||||||
|
|
||||||
|
_, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg)
|
||||||
|
require.Equal(t, err, ErrMessageIsNotRequest)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user