From 559bccccd40d028e412d9f11709ded0250ba6dcd Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Tue, 24 May 2022 23:33:38 +0200 Subject: implement primary and secondary role, for replication --- internal/node/secondary/secondary_test.go | 138 ++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 internal/node/secondary/secondary_test.go (limited to 'internal/node/secondary/secondary_test.go') diff --git a/internal/node/secondary/secondary_test.go b/internal/node/secondary/secondary_test.go new file mode 100644 index 0000000..164bdf6 --- /dev/null +++ b/internal/node/secondary/secondary_test.go @@ -0,0 +1,138 @@ +package secondary + +import ( + "context" + "fmt" + "testing" + + mocksClient "git.sigsum.org/log-go/internal/mocks/client" + mocksDB "git.sigsum.org/log-go/internal/mocks/db" + "git.sigsum.org/sigsum-go/pkg/merkle" + "git.sigsum.org/sigsum-go/pkg/types" + "github.com/golang/mock/gomock" +) + +var ( + testConfig = Config{ + LogID: fmt.Sprintf("%x", merkle.HashFn([]byte("logid"))[:]), + TreeID: 0, + Prefix: "testonly", + Deadline: 10, + } +) + +// TestHandlers checks that the expected internal handlers are configured +func TestIntHandlers(t *testing.T) { + endpoints := map[types.Endpoint]bool{ + types.EndpointGetTreeHeadToCosign: false, + } + node := Secondary{ + Config: testConfig, + } + for _, handler := range node.InternalHTTPHandlers() { + if _, ok := endpoints[handler.Endpoint]; !ok { + t.Errorf("got unexpected endpoint: %s", handler.Endpoint) + } + endpoints[handler.Endpoint] = true + } + for endpoint, ok := range endpoints { + if !ok { + t.Errorf("endpoint %s is not configured", endpoint) + } + } +} + +func TestFetchLeavesFromPrimary(t *testing.T) { + for _, tbl := range []struct { + desc string + // client.GetUnsignedTreeHead() + primaryTHRet types.TreeHead + primaryTHErr error + // db.GetTreeHead() + trillianTHRet *types.TreeHead + trillianTHErr error + // client.GetLeaves() + primaryGetLeavesRet types.Leaves + primaryGetLeavesErr error + // db.AddSequencedLeaves() + trillianAddLeavesExp bool + trillianAddLeavesErr error + }{ + { + desc: "no tree head from primary", + primaryTHErr: fmt.Errorf("mocked error"), + }, + { + desc: "no tree head from trillian", + primaryTHRet: types.TreeHead{}, + trillianTHErr: fmt.Errorf("mocked error"), + }, + { + desc: "error fetching leaves", + primaryTHRet: types.TreeHead{TreeSize: 6}, + trillianTHRet: &types.TreeHead{TreeSize: 5}, // 6-5 => 1 expected GetLeaves + primaryGetLeavesErr: fmt.Errorf("mocked error"), + }, + { + desc: "error adding leaves", + primaryTHRet: types.TreeHead{TreeSize: 6}, + trillianTHRet: &types.TreeHead{TreeSize: 5}, // 6-5 => 1 expected GetLeaves + primaryGetLeavesRet: types.Leaves{ + types.Leaf{}, + }, + trillianAddLeavesErr: fmt.Errorf("mocked error"), + }, + { + desc: "success", + primaryTHRet: types.TreeHead{TreeSize: 10}, + trillianTHRet: &types.TreeHead{TreeSize: 5}, + primaryGetLeavesRet: types.Leaves{ + types.Leaf{}, + }, + trillianAddLeavesExp: true, + }, + } { + func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + primaryClient := mocksClient.NewMockClient(ctrl) + primaryClient.EXPECT().GetUnsignedTreeHead(gomock.Any()).Return(tbl.primaryTHRet, tbl.primaryTHErr) + + trillianClient := mocksDB.NewMockClient(ctrl) + if tbl.trillianTHErr != nil || tbl.trillianTHRet != nil { + trillianClient.EXPECT().GetTreeHead(gomock.Any()).Return(tbl.trillianTHRet, tbl.trillianTHErr) + } + + if tbl.primaryGetLeavesErr != nil || tbl.primaryGetLeavesRet != nil { + primaryClient.EXPECT().GetLeaves(gomock.Any(), gomock.Any()).Return(tbl.primaryGetLeavesRet, tbl.primaryGetLeavesErr) + if tbl.trillianAddLeavesExp { + for i := tbl.trillianTHRet.TreeSize; i < tbl.primaryTHRet.TreeSize-1; i++ { + primaryClient.EXPECT().GetLeaves(gomock.Any(), gomock.Any()).Return(tbl.primaryGetLeavesRet, tbl.primaryGetLeavesErr) + } + } + } + + if tbl.trillianAddLeavesErr != nil || tbl.trillianAddLeavesExp { + trillianClient.EXPECT().AddSequencedLeaves(gomock.Any(), gomock.Any(), gomock.Any()).Return(tbl.trillianAddLeavesErr) + if tbl.trillianAddLeavesExp { + for i := tbl.trillianTHRet.TreeSize; i < tbl.primaryTHRet.TreeSize-1; i++ { + trillianClient.EXPECT().AddSequencedLeaves(gomock.Any(), gomock.Any(), gomock.Any()).Return(tbl.trillianAddLeavesErr) + } + } + } + + node := Secondary{ + Config: testConfig, + Primary: primaryClient, + TrillianClient: trillianClient, + } + + node.fetchLeavesFromPrimary(context.Background()) + + // NOTE: We are not verifying that + // AddSequencedLeaves() is being called with + // the right data. + }() + } +} -- cgit v1.2.3