1
0
Fork 0
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:
mcrakhman 2025-02-05 14:27:23 +01:00
parent 4de44b020a
commit 541f96f0cb
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
6 changed files with 176 additions and 77 deletions

View file

@ -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)

View file

@ -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))
}

View file

@ -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 (

View file

@ -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)
}

View file

@ -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) {

View file

@ -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) {