mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-10 18:10:54 +09:00
Fix deletionstate and settingsobject tests
This commit is contained in:
parent
4de44b020a
commit
541f96f0cb
6 changed files with 176 additions and 77 deletions
|
@ -1,29 +1,32 @@
|
|||
package deletionstate
|
||||
|
||||
import (
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/anyproto/any-sync/commonspace/headsync/headstorage"
|
||||
"github.com/anyproto/any-sync/commonspace/headsync/headstorage/mock_headstorage"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
ctrl *gomock.Controller
|
||||
delState *objectDeletionState
|
||||
spaceStorage *mock_spacestorage.MockSpaceStorage
|
||||
ctrl *gomock.Controller
|
||||
delState *objectDeletionState
|
||||
headStorage *mock_headstorage.MockHeadStorage
|
||||
}
|
||||
|
||||
func newFixture(t *testing.T) *fixture {
|
||||
ctrl := gomock.NewController(t)
|
||||
spaceStorage := mock_spacestorage.NewMockSpaceStorage(ctrl)
|
||||
headStorage := mock_headstorage.NewMockHeadStorage(ctrl)
|
||||
delState := New().(*objectDeletionState)
|
||||
delState.storage = spaceStorage
|
||||
delState.storage = headStorage
|
||||
return &fixture{
|
||||
ctrl: ctrl,
|
||||
delState: delState,
|
||||
spaceStorage: spaceStorage,
|
||||
ctrl: ctrl,
|
||||
delState: delState,
|
||||
headStorage: headStorage,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,28 +39,33 @@ func TestDeletionState_Add(t *testing.T) {
|
|||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return("", nil)
|
||||
fx.spaceStorage.EXPECT().SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusQueued).Return(nil)
|
||||
var queued []string
|
||||
fx.delState.AddObserver(func(ids []string) {
|
||||
queued = ids
|
||||
})
|
||||
fx.headStorage.EXPECT().UpdateEntry(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, update headstorage.HeadsUpdate) error {
|
||||
require.Equal(t, headstorage.DeletedStatusQueued, *update.DeletedStatus)
|
||||
return nil
|
||||
})
|
||||
fx.delState.Add(map[string]struct{}{id: {}})
|
||||
require.Contains(t, fx.delState.queued, id)
|
||||
require.Equal(t, []string{id}, queued)
|
||||
})
|
||||
|
||||
t.Run("add existing queued", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return(spacestorage.TreeDeletedStatusQueued, nil)
|
||||
fx.delState.queued[id] = struct{}{}
|
||||
fx.delState.Add(map[string]struct{}{id: {}})
|
||||
require.Contains(t, fx.delState.queued, id)
|
||||
})
|
||||
|
||||
t.Run("add existing deleted", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return(spacestorage.TreeDeletedStatusDeleted, nil)
|
||||
fx.delState.deleted[id] = struct{}{}
|
||||
fx.delState.Add(map[string]struct{}{id: {}})
|
||||
require.Contains(t, fx.delState.deleted, id)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -84,30 +92,16 @@ func TestDeletionState_FilterJoin(t *testing.T) {
|
|||
require.Equal(t, []string{"id3"}, filtered)
|
||||
}
|
||||
|
||||
func TestDeletionState_AddObserver(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
var queued []string
|
||||
|
||||
fx.delState.AddObserver(func(ids []string) {
|
||||
queued = ids
|
||||
})
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return("", nil)
|
||||
fx.spaceStorage.EXPECT().SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusQueued).Return(nil)
|
||||
fx.delState.Add(map[string]struct{}{id: {}})
|
||||
require.Contains(t, fx.delState.queued, id)
|
||||
require.Equal(t, []string{id}, queued)
|
||||
}
|
||||
|
||||
func TestDeletionState_Delete(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
id := "deletedId"
|
||||
fx.delState.queued[id] = struct{}{}
|
||||
fx.spaceStorage.EXPECT().SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusDeleted).Return(nil)
|
||||
fx.headStorage.EXPECT().UpdateEntry(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, update headstorage.HeadsUpdate) error {
|
||||
require.Equal(t, headstorage.DeletedStatusDeleted, *update.DeletedStatus)
|
||||
return nil
|
||||
})
|
||||
err := fx.delState.Delete(id)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, fx.delState.deleted, id)
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anyproto/any-sync/commonspace/headsync/statestorage (interfaces: StateStorage)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -destination mock_statestorage/mock_statestorage.go github.com/anyproto/any-sync/commonspace/headsync/statestorage StateStorage
|
||||
//
|
||||
|
||||
// Package mock_statestorage is a generated GoMock package.
|
||||
package mock_statestorage
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
statestorage "github.com/anyproto/any-sync/commonspace/headsync/statestorage"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockStateStorage is a mock of StateStorage interface.
|
||||
type MockStateStorage struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockStateStorageMockRecorder
|
||||
}
|
||||
|
||||
// MockStateStorageMockRecorder is the mock recorder for MockStateStorage.
|
||||
type MockStateStorageMockRecorder struct {
|
||||
mock *MockStateStorage
|
||||
}
|
||||
|
||||
// NewMockStateStorage creates a new mock instance.
|
||||
func NewMockStateStorage(ctrl *gomock.Controller) *MockStateStorage {
|
||||
mock := &MockStateStorage{ctrl: ctrl}
|
||||
mock.recorder = &MockStateStorageMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockStateStorage) EXPECT() *MockStateStorageMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetState mocks base method.
|
||||
func (m *MockStateStorage) GetState(arg0 context.Context) (statestorage.State, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetState", arg0)
|
||||
ret0, _ := ret[0].(statestorage.State)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetState indicates an expected call of GetState.
|
||||
func (mr *MockStateStorageMockRecorder) GetState(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockStateStorage)(nil).GetState), arg0)
|
||||
}
|
||||
|
||||
// SetHash mocks base method.
|
||||
func (m *MockStateStorage) SetHash(arg0 context.Context, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SetHash", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetHash indicates an expected call of SetHash.
|
||||
func (mr *MockStateStorageMockRecorder) SetHash(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHash", reflect.TypeOf((*MockStateStorage)(nil).SetHash), arg0, arg1)
|
||||
}
|
||||
|
||||
// SetObserver mocks base method.
|
||||
func (m *MockStateStorage) SetObserver(arg0 statestorage.Observer) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetObserver", arg0)
|
||||
}
|
||||
|
||||
// SetObserver indicates an expected call of SetObserver.
|
||||
func (mr *MockStateStorageMockRecorder) SetObserver(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetObserver", reflect.TypeOf((*MockStateStorage)(nil).SetObserver), arg0)
|
||||
}
|
||||
|
||||
// SettingsId mocks base method.
|
||||
func (m *MockStateStorage) SettingsId() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SettingsId")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SettingsId indicates an expected call of SettingsId.
|
||||
func (mr *MockStateStorageMockRecorder) SettingsId() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SettingsId", reflect.TypeOf((*MockStateStorage)(nil).SettingsId))
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:generate mockgen -destination mock_statestorage/mock_statestorage.go github.com/anyproto/any-sync/commonspace/headsync/statestorage StateStorage
|
||||
package statestorage
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,24 +2,29 @@ package settings
|
|||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/anyproto/any-sync/accountservice/mock_accountservice"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionmanager/mock_deletionmanager"
|
||||
"github.com/anyproto/any-sync/commonspace/headsync/headstorage"
|
||||
"github.com/anyproto/any-sync/commonspace/headsync/headstorage/mock_headstorage"
|
||||
"github.com/anyproto/any-sync/commonspace/headsync/statestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/headsync/statestorage/mock_statestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
||||
"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/synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type testSyncTreeMock struct {
|
||||
|
@ -54,8 +59,12 @@ type settingsFixture struct {
|
|||
syncTree *mock_synctree.MockSyncTree
|
||||
historyTree *mock_objecttree.MockObjectTree
|
||||
account *mock_accountservice.MockService
|
||||
stateStorage *mock_statestorage.MockStateStorage
|
||||
headStorage *mock_headstorage.MockHeadStorage
|
||||
}
|
||||
|
||||
var ctx = context.Background()
|
||||
|
||||
func newSettingsFixture(t *testing.T) *settingsFixture {
|
||||
spaceId := "spaceId"
|
||||
objectId := "objectId"
|
||||
|
@ -69,6 +78,8 @@ func newSettingsFixture(t *testing.T) *settingsFixture {
|
|||
changeFactory := mock_settingsstate.NewMockChangeFactory(ctrl)
|
||||
syncTree := mock_synctree.NewMockSyncTree(ctrl)
|
||||
historyTree := mock_objecttree.NewMockObjectTree(ctrl)
|
||||
stateStorage := mock_statestorage.NewMockStateStorage(ctrl)
|
||||
headStorage := mock_headstorage.NewMockHeadStorage(ctrl)
|
||||
|
||||
buildFunc := BuildTreeFunc(func(ctx context.Context, id string, listener updatelistener.UpdateListener) (synctree.SyncTree, error) {
|
||||
require.Equal(t, objectId, id)
|
||||
|
@ -101,11 +112,17 @@ func newSettingsFixture(t *testing.T) *settingsFixture {
|
|||
syncTree: syncTree,
|
||||
account: acc,
|
||||
historyTree: historyTree,
|
||||
stateStorage: stateStorage,
|
||||
headStorage: headStorage,
|
||||
}
|
||||
}
|
||||
|
||||
func (fx *settingsFixture) init(t *testing.T) {
|
||||
fx.spaceStorage.EXPECT().SpaceSettingsId().Return(fx.docId)
|
||||
fx.spaceStorage.EXPECT().StateStorage().AnyTimes().Return(fx.stateStorage)
|
||||
fx.stateStorage.EXPECT().GetState(gomock.Any()).Return(statestorage.State{
|
||||
SettingsId: fx.docId,
|
||||
}, nil)
|
||||
fx.spaceStorage.EXPECT().HeadStorage().AnyTimes().Return(fx.headStorage)
|
||||
fx.stateBuilder.EXPECT().Build(fx.historyTree, nil).Return(&settingsstate.State{}, nil)
|
||||
fx.doc.state = &settingsstate.State{}
|
||||
|
||||
|
@ -129,24 +146,18 @@ func TestSettingsObject_Init(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSettingsObject_DeleteObject_NoSnapshot(t *testing.T) {
|
||||
isDerivedRoot = func(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
|
||||
fx.init(t)
|
||||
|
||||
delId := "delId"
|
||||
DoSnapshot = func(len int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
fx.syncTree.EXPECT().Id().Return("syncId")
|
||||
fx.syncTree.EXPECT().Len().Return(10)
|
||||
treeStorageMock := mock_treestorage.NewMockTreeStorage(fx.ctrl)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Root().Return(&treechangeproto.RawTreeChangeWithId{}, nil)
|
||||
fx.headStorage.EXPECT().GetEntry(gomock.Any(), gomock.Any()).Return(headstorage.HeadsEntry{
|
||||
IsDerived: false,
|
||||
}, nil)
|
||||
res := []byte("settingsData")
|
||||
fx.doc.state = &settingsstate.State{LastIteratedId: "someId"}
|
||||
fx.changeFactory.EXPECT().CreateObjectDeleteChange(delId, fx.doc.state, false).Return(res, nil)
|
||||
|
@ -163,14 +174,11 @@ func TestSettingsObject_DeleteObject_NoSnapshot(t *testing.T) {
|
|||
|
||||
fx.stateBuilder.EXPECT().Build(fx.doc, fx.doc.state).Return(fx.doc.state, nil)
|
||||
fx.deletionManager.EXPECT().UpdateState(gomock.Any(), fx.doc.state).Return(nil)
|
||||
err = fx.doc.DeleteObject(delId)
|
||||
err = fx.doc.DeleteObject(ctx, delId)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSettingsObject_DeleteObject_WithSnapshot(t *testing.T) {
|
||||
isDerivedRoot = func(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
fx.init(t)
|
||||
|
@ -178,12 +186,11 @@ func TestSettingsObject_DeleteObject_WithSnapshot(t *testing.T) {
|
|||
DoSnapshot = func(len int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fx.syncTree.EXPECT().Id().Return("syncId")
|
||||
fx.syncTree.EXPECT().Len().Return(10)
|
||||
treeStorageMock := mock_treestorage.NewMockTreeStorage(fx.ctrl)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Root().Return(&treechangeproto.RawTreeChangeWithId{}, nil)
|
||||
fx.headStorage.EXPECT().GetEntry(gomock.Any(), gomock.Any()).Return(headstorage.HeadsEntry{
|
||||
IsDerived: false,
|
||||
}, nil)
|
||||
res := []byte("settingsData")
|
||||
fx.doc.state = &settingsstate.State{LastIteratedId: "someId"}
|
||||
fx.changeFactory.EXPECT().CreateObjectDeleteChange(delId, fx.doc.state, true).Return(res, nil)
|
||||
|
@ -196,31 +203,28 @@ func TestSettingsObject_DeleteObject_WithSnapshot(t *testing.T) {
|
|||
Key: accountData.SignKey,
|
||||
IsSnapshot: true,
|
||||
IsEncrypted: false,
|
||||
}).Return(objecttree.AddResult{Mode: objecttree.Rebuild}, nil)
|
||||
}).Return(objecttree.AddResult{}, nil)
|
||||
|
||||
fx.stateBuilder.EXPECT().Build(fx.doc, nil).Return(fx.doc.state, nil)
|
||||
fx.stateBuilder.EXPECT().Build(fx.doc, fx.doc.state).Return(fx.doc.state, nil)
|
||||
fx.deletionManager.EXPECT().UpdateState(gomock.Any(), fx.doc.state).Return(nil)
|
||||
err = fx.doc.DeleteObject(delId)
|
||||
err = fx.doc.DeleteObject(ctx, delId)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSettingsObject_DeleteDerivedObject(t *testing.T) {
|
||||
isDerivedRoot = func(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {
|
||||
return true, nil
|
||||
}
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
fx.init(t)
|
||||
delId := "delId"
|
||||
DoSnapshot = func(len int) bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
fx.syncTree.EXPECT().Id().Return("syncId")
|
||||
treeStorageMock := mock_treestorage.NewMockTreeStorage(fx.ctrl)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Root().Return(&treechangeproto.RawTreeChangeWithId{}, nil)
|
||||
err := fx.doc.DeleteObject(delId)
|
||||
fx.headStorage.EXPECT().GetEntry(gomock.Any(), gomock.Any()).Return(headstorage.HeadsEntry{
|
||||
IsDerived: true,
|
||||
}, nil)
|
||||
fx.doc.state = &settingsstate.State{LastIteratedId: "someId"}
|
||||
err := fx.doc.DeleteObject(ctx, delId)
|
||||
require.Equal(t, ErrCantDeleteDerivedObject, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package settingsstate
|
||||
|
||||
import (
|
||||
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
|
||||
"testing"
|
||||
|
||||
"github.com/anyproto/protobuf/proto"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/exp/slices"
|
||||
"testing"
|
||||
|
||||
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
|
||||
)
|
||||
|
||||
func TestChangeFactory_CreateObjectDeleteChange(t *testing.T) {
|
||||
|
|
|
@ -2,13 +2,15 @@ package settingsstate
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
||||
"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/spacesyncproto"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStateBuilder_ProcessChange(t *testing.T) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue