diff --git a/commonspace/object/tree/objecttree/objecttree_test.go b/commonspace/object/tree/objecttree/objecttree_test.go index d107a4ae..0d92791d 100644 --- a/commonspace/object/tree/objecttree/objecttree_test.go +++ b/commonspace/object/tree/objecttree/objecttree_test.go @@ -14,6 +14,7 @@ import ( anystore "github.com/anyproto/any-store" "golang.org/x/exp/slices" + "golang.org/x/sys/unix" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -141,6 +142,7 @@ func createNamedStore(ctx context.Context, t *testing.T, name string) anystore.D t.Cleanup(func() { err := db.Close() require.NoError(t, err) + unix.Rmdir(path) }) return testStore{ DB: db, diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index 6288fd24..efcaf411 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -105,7 +105,7 @@ func (s *spaceService) CreateSpace(ctx context.Context, payload SpaceCreatePaylo if err != nil { return } - store, err := s.createSpaceStorage(storageCreate) + store, err := s.createSpaceStorage(ctx, storageCreate) if err != nil { if err == spacestorage.ErrSpaceStorageExists { return storageCreate.SpaceHeaderWithId.Id, nil @@ -130,7 +130,7 @@ func (s *spaceService) DeriveSpace(ctx context.Context, payload SpaceDerivePaylo if err != nil { return } - store, err := s.createSpaceStorage(storageCreate) + store, err := s.createSpaceStorage(ctx, storageCreate) if err != nil { if err == spacestorage.ErrSpaceStorageExists { return storageCreate.SpaceHeaderWithId.Id, nil @@ -211,7 +211,7 @@ func (s *spaceService) addSpaceStorage(ctx context.Context, spaceDescription Spa Id: spaceDescription.SpaceSettingsId, }, } - st, err = s.createSpaceStorage(payload) + st, err = s.createSpaceStorage(ctx, payload) if err != nil { err = spacesyncproto.ErrUnexpected if err == spacestorage.ErrSpaceStorageExists { @@ -286,7 +286,7 @@ func (s *spaceService) spacePullWithPeer(ctx context.Context, p peer.Peer, id st return } - return s.createSpaceStorage(spacestorage.SpaceStorageCreatePayload{ + return s.createSpaceStorage(ctx, spacestorage.SpaceStorageCreatePayload{ AclWithId: &consensusproto.RawRecordWithId{ Payload: res.Payload.AclPayload, Id: res.Payload.AclPayloadId, @@ -299,10 +299,10 @@ func (s *spaceService) spacePullWithPeer(ctx context.Context, p peer.Peer, id st }) } -func (s *spaceService) createSpaceStorage(payload spacestorage.SpaceStorageCreatePayload) (spacestorage.SpaceStorage, error) { +func (s *spaceService) createSpaceStorage(ctx context.Context, payload spacestorage.SpaceStorageCreatePayload) (spacestorage.SpaceStorage, error) { err := validateSpaceStorageCreatePayload(payload) if err != nil { return nil, err } - return s.storageProvider.CreateSpaceStorage(payload) + return s.storageProvider.CreateSpaceStorage(ctx, payload) } diff --git a/commonspace/spacestorage/spacestorage.go b/commonspace/spacestorage/spacestorage.go index 73a4e190..cc5c51a1 100644 --- a/commonspace/spacestorage/spacestorage.go +++ b/commonspace/spacestorage/spacestorage.go @@ -48,7 +48,7 @@ type SpaceStorageProvider interface { app.Component WaitSpaceStorage(ctx context.Context, id string) (SpaceStorage, error) SpaceExists(id string) bool - CreateSpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error) + CreateSpaceStorage(ctx context.Context, payload SpaceStorageCreatePayload) (SpaceStorage, error) } func Create(ctx context.Context, store anystore.DB, payload SpaceStorageCreatePayload) (SpaceStorage, error) { diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index f5ad8e39..97c5ae1b 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -645,7 +645,7 @@ func newFixture(t *testing.T) *spaceFixture { configurationService: &mockConf{}, streamOpener: newStreamOpener("spaceId"), peerManagerProvider: &testPeerManagerProvider{}, - storageProvider: spacestorage.NewInMemorySpaceStorageProvider(), + storageProvider: &spaceStorageProvider{rootPath: t.TempDir()}, treeManager: newMockTreeManager("spaceId"), pool: &mockPool{}, spaceService: New(), @@ -674,7 +674,10 @@ func newFixture(t *testing.T) *spaceFixture { return fx } -func newPeerFixture(t *testing.T, spaceId string, keys *accountdata.AccountKeys, peerPool *synctest.PeerGlobalPool, provider *spacestorage.InMemorySpaceStorageProvider) *spaceFixture { +func Test(t *testing.T) { +} + +func newPeerFixture(t *testing.T, spaceId string, keys *accountdata.AccountKeys, peerPool *synctest.PeerGlobalPool, provider *spaceStorageProvider) *spaceFixture { ctx, cancel := context.WithTimeout(context.Background(), time.Second) fx := &spaceFixture{ ctx: ctx, @@ -765,26 +768,31 @@ func newMultiPeerFixture(t *testing.T, peerNum int) *multiPeerFixture { var ( allKeys []*accountdata.AccountKeys allRecords []*consensusproto.RawRecordWithId - providers []*spacestorage.InMemorySpaceStorageProvider + providers []*spaceStorageProvider peerIds []string ) allRecords, err = executor.ActualAccounts()["0"].Acl.RecordsAfter(context.Background(), "") require.NoError(t, err) + ctx := context.Background() for i := 0; i < peerNum; i++ { allKeys = append(allKeys, executor.ActualAccounts()[fmt.Sprint(i)].Keys) peerIds = append(peerIds, executor.ActualAccounts()[fmt.Sprint(i)].Keys.PeerId) - provider := spacestorage.NewInMemorySpaceStorageProvider().(*spacestorage.InMemorySpaceStorageProvider) + provider := &spaceStorageProvider{rootPath: t.TempDir()} providers = append(providers, provider) - spaceStore, err := provider.CreateSpaceStorage(createSpace) + spaceStore, err := provider.CreateSpaceStorage(ctx, createSpace) require.NoError(t, err) listStorage, err := spaceStore.AclStorage() require.NoError(t, err) - for _, rec := range allRecords { - err = listStorage.AddRawRecord(context.Background(), rec) + for i, rec := range allRecords { + prevRec := "" + if i > 0 { + prevRec = allRecords[i-1].Id + } + err := listStorage.AddAll(ctx, []list.StorageRecord{ + {RawRecord: rec.Payload, Id: rec.Id, PrevId: prevRec, Order: i + 1, ChangeSize: len(rec.Payload)}, + }) require.NoError(t, err) } - err = listStorage.SetHead(allRecords[len(allRecords)-1].Id) - require.NoError(t, err) } peerPool := synctest.NewPeerGlobalPool(peerIds) peerPool.MakePeers() @@ -808,9 +816,9 @@ func Test_Sync(t *testing.T) { for _, fx := range mpFixture.peerFixtures { sp, err := fx.app.MustComponent(RpcName).(*RpcServer).GetSpace(context.Background(), fx.process.spaceId) require.NoError(t, err) - spaceHash, err := sp.Storage().ReadSpaceHash() + state, err := sp.Storage().StateStorage().GetState(context.Background()) require.NoError(t, err) - hashes = append(hashes, spaceHash) + hashes = append(hashes, state.Hash) } for i := 1; i < len(hashes); i++ { require.Equal(t, hashes[0], hashes[i]) diff --git a/commonspace/storageutils_test.go b/commonspace/storageutils_test.go new file mode 100644 index 00000000..f1ff5647 --- /dev/null +++ b/commonspace/storageutils_test.go @@ -0,0 +1,69 @@ +package commonspace + +import ( + "context" + "os" + "path" + + anystore "github.com/anyproto/any-store" + "golang.org/x/sys/unix" + + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/spacestorage" +) + +type spaceStorageProvider struct { + rootPath string +} + +func (s *spaceStorageProvider) Run(ctx context.Context) (err error) { + return nil +} + +func (s *spaceStorageProvider) Close(ctx context.Context) (err error) { + return unix.Rmdir(s.rootPath) +} + +func (s *spaceStorageProvider) Init(a *app.App) (err error) { + return nil +} + +func (s *spaceStorageProvider) Name() (name string) { + return spacestorage.CName +} + +func (s *spaceStorageProvider) WaitSpaceStorage(ctx context.Context, id string) (spacestorage.SpaceStorage, error) { + dbPath := path.Join(s.rootPath, id) + if _, err := os.Stat(dbPath); err != nil { + return nil, err + } + db, err := anystore.Open(ctx, dbPath, nil) + if err != nil { + return nil, err + } + return spacestorage.New(id, db), nil +} + +func (s *spaceStorageProvider) SpaceExists(id string) bool { + if id == "" { + return false + } + dbPath := path.Join(s.rootPath, id) + if _, err := os.Stat(dbPath); err != nil { + return false + } + return true +} + +func (s *spaceStorageProvider) CreateSpaceStorage(ctx context.Context, payload spacestorage.SpaceStorageCreatePayload) (spacestorage.SpaceStorage, error) { + id := payload.SpaceHeaderWithId.Id + if s.SpaceExists(id) { + return nil, spacestorage.ErrSpaceStorageExists + } + dbPath := path.Join(s.rootPath, id) + db, err := anystore.Open(ctx, dbPath, nil) + if err != nil { + return nil, err + } + return spacestorage.Create(ctx, db, payload) +}