Skip to content

Commit

Permalink
[wip] adds error path test for backup endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanlott committed Aug 8, 2023
1 parent 9a6b89d commit 9c75f0e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 32 deletions.
3 changes: 2 additions & 1 deletion persistence/trees/trees.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,8 @@ func (t *treeStore) Load(dir string) error {
nodeStore: nodeStore,
}

// import merkle tree roots trees from worldState
// import merkle trees with the proper hash
t.merkleTrees = make(map[string]*stateTree)
for treeName, treeRootHash := range w.MerkleRoots {
treePath := fmt.Sprintf("%s/%s_nodes", dir, treeName)
nodeStore, err := kvstore.NewKVStore(treePath)
Expand Down
15 changes: 12 additions & 3 deletions rpc/handlers_node.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package rpc

import (
"fmt"

"github.com/labstack/echo/v4"
)

// PostV1NodeBackup triggers a backup of the TreeStore, the BlockStore, the PostgreSQL database.
// TECHDEBT: Run each backup process in a goroutine to as elapsed time will become significant
// with the current waterfall approach when even a moderate amount of data resides in each store.
func (s *rpcServer) PostV1NodeBackup(ctx echo.Context) error {
// TECHDEBT: Wire this up to a default config param if dir == ""
// cfg := s.GetBus().GetRuntimeMgr().GetConfig()

dir := ctx.Param("dir")
if dir == "" {
// TECHDEBT: Wire this up to a config param with a sane default
// cfg := s.GetBus().GetRuntimeMgr().GetConfig()
return fmt.Errorf("must specify a target backup directory")
}

s.logger.Info().Msgf("creating backup in %s", dir)

Expand All @@ -25,6 +29,11 @@ func (s *rpcServer) PostV1NodeBackup(ctx echo.Context) error {
return err
}

// TECHDEBT: backup Postgres
// if err := s.GetBus().GetPersistenceModule().Backup(dir); err != nil {
// return err
// }

s.logger.Info().Msgf("backup created in %s", dir)
return nil
}
48 changes: 22 additions & 26 deletions rpc/handlers_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package rpc

import (
"io"
"net/http"
"net/http/httptest"
"os"
Expand All @@ -18,14 +17,14 @@ import (
)

func Test_RPCPostV1NodeBackup(t *testing.T) {
// THIS WORKS BUT ADJUST LATER
type testCase struct {
name string
setup func(t *testing.T, e echo.Context) *rpcServer
assert func(t *testing.T, tt testCase, e echo.Context, s *rpcServer)
wantErr bool
}

// NB: testDir is used and cleared by each test case
var testDir = t.TempDir()

tests := []testCase{
Expand All @@ -48,16 +47,14 @@ func Test_RPCPostV1NodeBackup(t *testing.T) {
},
wantErr: false,
assert: func(t *testing.T, tt testCase, e echo.Context, s *rpcServer) {
empty, err := isEmpty(testDir)
require.NoError(t, err)
require.False(t, empty)
f, err := os.Open(testDir)
require.NoError(t, err)
dirs, err := f.ReadDir(-1)
require.NoError(t, err)
// assert that we wrote the expected 12 files into this directory
require.True(t, len(dirs) == 12)

Check failure on line 55 in rpc/handlers_test.go

View workflow job for this annotation

GitHub Actions / lint

ruleguard: use require.Equal instead of require.True (gocritic)

// assert worldstate json was written
// assert worldstate.json was written
_, err = os.Open(filepath.Join(testDir, "worldstate.json"))
require.NoError(t, err)

Expand All @@ -71,38 +68,37 @@ func Test_RPCPostV1NodeBackup(t *testing.T) {
})
},
},
{
name: "should error if no directory specified",
setup: func(t *testing.T, e echo.Context) *rpcServer {
_, _, url := test_artifacts.SetupPostgresDocker()
pmod := testutil.NewTestPersistenceModule(t, url)

s := &rpcServer{
logger: *logger.Global.CreateLoggerForModule(modules.RPCModuleName),
}

s.SetBus(pmod.GetBus())

return s
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// create a new echo Context for each test
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/v1/node/backup", nil)

Check failure on line 91 in rpc/handlers_test.go

View workflow job for this annotation

GitHub Actions / lint

httpNoBody: http.NoBody should be preferred to the nil request body (gocritic)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)

// pass the fresh context to setup
s := tt.setup(t, c)

// call and assert
if err := s.PostV1NodeBackup(c); (err != nil) != tt.wantErr {
t.Errorf("rpcServer.PostV1NodeBackup() error = %v, wantErr %v", err, tt.wantErr)
}
tt.assert(t, tt, c, s)
if tt.assert != nil {
tt.assert(t, tt, c, s)
}
})
}
}

// TECHDEBT(#796) - Organize and dedupe this function into testutil package
func isEmpty(dir string) (bool, error) {
f, err := os.Open(dir)
if err != nil {
return false, err
}
defer f.Close()

_, err = f.Readdirnames(1) // Or f.Readdir(1)
if err == io.EOF {
return true, nil
}
return false, err // Either not empty or error, suits both cases
}
4 changes: 2 additions & 2 deletions shared/modules/persistence_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ type PersistenceLocalContext interface {
GetSessionTokensUsed(*coreTypes.Session) (*big.Int, error)
}

// Archivable defines a two function interface for backing up and loading an archive.
// Archivable defines a single function interface for creating a reusable archive of a module.
type Archivable interface {
// Backup creates an archive for the module in the given directory and returns an error if anything went wrong.
Backup(dir string) error
Load(dir string) error
}

0 comments on commit 9c75f0e

Please sign in to comment.