Add tests

This commit is contained in:
mcrakhman 2023-05-23 08:48:15 +02:00 committed by Mikhail Iudin
parent 9cd73af53c
commit c348ee2a49
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
4 changed files with 239 additions and 11 deletions

View File

@ -0,0 +1,184 @@
package commonspace
import (
"context"
"fmt"
"github.com/anytypeio/any-sync/commonspace/object/accountdata"
"github.com/anytypeio/any-sync/commonspace/object/tree/objecttree"
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anytypeio/any-sync/commonspace/settings"
"github.com/anytypeio/any-sync/commonspace/settings/settingsstate"
"github.com/anytypeio/any-sync/commonspace/spacestorage"
"github.com/anytypeio/any-sync/util/crypto"
"github.com/stretchr/testify/require"
"math/rand"
"testing"
"time"
)
func addIncorrectSnapshot(settingsObject settings.SettingsObject, acc *accountdata.AccountKeys, partialIds []string, newId string) (err error) {
factory := settingsstate.NewChangeFactory()
bytes, err := factory.CreateObjectDeleteChange(newId, &settingsstate.State{DeletedIds: partialIds}, true)
if err != nil {
return
}
ch, err := settingsObject.PrepareChange(objecttree.SignableChangeContent{
Data: bytes,
Key: acc.SignKey,
IsSnapshot: true,
IsEncrypted: false,
Timestamp: time.Now().Unix(),
})
if err != nil {
return
}
res, err := settingsObject.AddRawChanges(context.Background(), objecttree.RawChangesPayload{
NewHeads: []string{ch.Id},
RawChanges: []*treechangeproto.RawTreeChangeWithId{ch},
})
if err != nil {
return
}
if res.Mode != objecttree.Rebuild {
return fmt.Errorf("incorrect mode: %d", res.Mode)
}
return
}
func TestSpaceDeleteIds(t *testing.T) {
fx := newFixture(t)
acc := fx.account.Account()
rk := crypto.NewAES()
ctx := context.Background()
totalObjs := 3000
// creating space
sp, err := fx.spaceService.CreateSpace(ctx, SpaceCreatePayload{
SigningKey: acc.SignKey,
SpaceType: "type",
ReadKey: rk.Bytes(),
ReplicationKey: 10,
MasterKey: acc.PeerKey,
})
require.NoError(t, err)
require.NotNil(t, sp)
// initializing space
spc, err := fx.spaceService.NewSpace(ctx, sp)
require.NoError(t, err)
require.NotNil(t, spc)
err = spc.Init(ctx)
require.NoError(t, err)
// adding space to tree manager
fx.treeManager.space = spc
var ids []string
for i := 0; i < totalObjs; i++ {
// creating a tree
bytes := make([]byte, 32)
rand.Read(bytes)
doc, err := spc.CreateTree(ctx, objecttree.ObjectTreeCreatePayload{
PrivKey: acc.SignKey,
ChangeType: "some",
SpaceId: spc.Id(),
IsEncrypted: false,
Seed: bytes,
Timestamp: time.Now().Unix(),
})
require.NoError(t, err)
tr, err := spc.PutTree(ctx, doc, nil)
require.NoError(t, err)
ids = append(ids, tr.Id())
tr.Close()
}
// deleting trees
for _, id := range ids {
err = spc.DeleteTree(ctx, id)
require.NoError(t, err)
}
time.Sleep(3 * time.Second)
spc.Close()
require.Equal(t, len(ids), len(fx.treeManager.deletedIds))
}
func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) {
fx := newFixture(t)
acc := fx.account.Account()
rk := crypto.NewAES()
ctx := context.Background()
totalObjs := 3000
partialObjs := 300
// creating space
sp, err := fx.spaceService.CreateSpace(ctx, SpaceCreatePayload{
SigningKey: acc.SignKey,
SpaceType: "type",
ReadKey: rk.Bytes(),
ReplicationKey: 10,
MasterKey: acc.PeerKey,
})
require.NoError(t, err)
require.NotNil(t, sp)
// initializing space
spc, err := fx.spaceService.NewSpace(ctx, sp)
require.NoError(t, err)
require.NotNil(t, spc)
err = spc.Init(ctx)
require.NoError(t, err)
// adding space to tree manager
fx.treeManager.space = spc
settingsObject := spc.(*space).settingsObject
var ids []string
for i := 0; i < totalObjs; i++ {
// creating a tree
bytes := make([]byte, 32)
rand.Read(bytes)
doc, err := spc.CreateTree(ctx, objecttree.ObjectTreeCreatePayload{
PrivKey: acc.SignKey,
ChangeType: "some",
SpaceId: spc.Id(),
IsEncrypted: false,
Seed: bytes,
Timestamp: time.Now().Unix(),
})
require.NoError(t, err)
tr, err := spc.PutTree(ctx, doc, nil)
require.NoError(t, err)
ids = append(ids, tr.Id())
tr.Close()
}
// copying storage, so we will have all the trees locally
inmemory := spc.Storage().(*commonStorage).SpaceStorage.(*spacestorage.InMemorySpaceStorage)
storageCopy := inmemory.CopyStorage()
treesCopy := inmemory.AllTrees()
// deleting trees
for _, id := range ids {
err = spc.DeleteTree(ctx, id)
require.NoError(t, err)
}
// adding snapshot that breaks the state
err = addIncorrectSnapshot(settingsObject, acc, ids[:partialObjs], ids[partialObjs])
require.NoError(t, err)
// copying the contents of the settings tree
treesCopy[settingsObject.Id()] = settingsObject.Storage()
storageCopy.SetTrees(treesCopy)
spc.Close()
time.Sleep(100 * time.Millisecond)
// now we replace the storage, so the trees are back, but the settings object says that they are deleted
fx.storageProvider.(*spacestorage.InMemorySpaceStorageProvider).SetStorage(storageCopy)
spc, err = fx.spaceService.NewSpace(ctx, sp)
require.NoError(t, err)
require.NotNil(t, spc)
err = spc.Init(ctx)
require.NoError(t, err)
fx.treeManager.space = spc
fx.treeManager.deletedIds = nil
// waiting until everything is deleted
time.Sleep(3 * time.Second)
require.Equal(t, len(ids), len(fx.treeManager.deletedIds))
}

View File

@ -52,3 +52,9 @@ func (i *InMemorySpaceStorageProvider) CreateSpaceStorage(payload SpaceStorageCr
i.storages[payload.SpaceHeaderWithId.Id] = spaceStorage i.storages[payload.SpaceHeaderWithId.Id] = spaceStorage
return spaceStorage, nil return spaceStorage, nil
} }
func (i *InMemorySpaceStorageProvider) SetStorage(storage SpaceStorage) {
i.Lock()
defer i.Unlock()
i.storages[storage.Id()] = storage
}

View File

@ -151,3 +151,43 @@ func (i *InMemorySpaceStorage) ReadSpaceHash() (hash string, err error) {
func (i *InMemorySpaceStorage) Close() error { func (i *InMemorySpaceStorage) Close() error {
return nil return nil
} }
func (i *InMemorySpaceStorage) AllTrees() map[string]treestorage.TreeStorage {
i.Lock()
defer i.Unlock()
cp := map[string]treestorage.TreeStorage{}
for id, store := range i.trees {
cp[id] = store
}
return cp
}
func (i *InMemorySpaceStorage) SetTrees(trees map[string]treestorage.TreeStorage) {
i.Lock()
defer i.Unlock()
i.trees = trees
}
func (i *InMemorySpaceStorage) CopyStorage() *InMemorySpaceStorage {
i.Lock()
defer i.Unlock()
copyTreeDeleted := map[string]string{}
for id, status := range i.treeDeleted {
copyTreeDeleted[id] = status
}
copyTrees := map[string]treestorage.TreeStorage{}
for id, store := range i.trees {
copyTrees[id] = store
}
return &InMemorySpaceStorage{
id: i.id,
isDeleted: i.isDeleted,
spaceSettingsId: i.spaceSettingsId,
treeDeleted: copyTreeDeleted,
trees: copyTrees,
aclStorage: i.aclStorage,
spaceHeader: i.spaceHeader,
spaceHash: i.spaceHash,
Mutex: sync.Mutex{},
}
}

View File

@ -122,7 +122,7 @@ func (m *mockConf) NodeTypes(nodeId string) []nodeconf.NodeType {
} }
// //
// Mock PeerManager implementation // Mock PeerManager
// //
type mockPeerManager struct { type mockPeerManager struct {
@ -141,7 +141,7 @@ func (p *mockPeerManager) GetResponsiblePeers(ctx context.Context) (peers []peer
} }
// //
// Mock PeerManagerProvider implementation // Mock PeerManagerProvider
// //
type mockPeerManagerProvider struct { type mockPeerManagerProvider struct {
@ -160,7 +160,7 @@ func (m *mockPeerManagerProvider) NewPeerManager(ctx context.Context, spaceId st
} }
// //
// Mock Pool implementation // Mock Pool
// //
type mockPool struct { type mockPool struct {
@ -191,7 +191,7 @@ func (m *mockPool) DialOneOf(ctx context.Context, peerIds []string) (peer.Peer,
} }
// //
// Mock Config implementation // Mock Config
// //
type mockConfig struct { type mockConfig struct {
@ -214,12 +214,13 @@ func (m *mockConfig) GetSpace() Config {
} }
// //
// Mock TreeManager implementation // Mock TreeManager
// //
type mockTreeManager struct { type mockTreeManager struct {
space Space space Space
cache ocache.OCache cache ocache.OCache
deletedIds []string
} }
func (t *mockTreeManager) Init(a *app.App) (err error) { func (t *mockTreeManager) Init(a *app.App) (err error) {
@ -260,6 +261,7 @@ func (t *mockTreeManager) DeleteTree(ctx context.Context, spaceId, treeId string
if err != nil { if err != nil {
return return
} }
t.deletedIds = append(t.deletedIds, treeId)
_, err = t.cache.Remove(ctx, treeId) _, err = t.cache.Remove(ctx, treeId)
return nil return nil
} }
@ -311,7 +313,3 @@ func newFixture(t *testing.T) *spaceFixture {
require.NoError(t, err) require.NoError(t, err)
return fx return fx
} }
func TestSpace(t *testing.T) {
_ = newFixture(t)
}