aboutsummaryrefslogtreecommitdiff
path: root/internal/node/secondary/endpoint_internal_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/node/secondary/endpoint_internal_test.go')
-rw-r--r--internal/node/secondary/endpoint_internal_test.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/internal/node/secondary/endpoint_internal_test.go b/internal/node/secondary/endpoint_internal_test.go
new file mode 100644
index 0000000..9637e29
--- /dev/null
+++ b/internal/node/secondary/endpoint_internal_test.go
@@ -0,0 +1,111 @@
+package secondary
+
+import (
+ "crypto"
+ "crypto/ed25519"
+ "fmt"
+ "io"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ mocksDB "git.sigsum.org/log-go/internal/mocks/db"
+ "git.sigsum.org/log-go/internal/node/handler"
+ "git.sigsum.org/sigsum-go/pkg/merkle"
+ "git.sigsum.org/sigsum-go/pkg/types"
+ "github.com/golang/mock/gomock"
+)
+
+// TestSigner implements the signer interface. It can be used to mock
+// an Ed25519 signer that always return the same public key,
+// signature, and error.
+// NOTE: Code duplication with internal/state/single_test.go
+type TestSigner struct {
+ PublicKey [ed25519.PublicKeySize]byte
+ Signature [ed25519.SignatureSize]byte
+ Error error
+}
+
+func (ts *TestSigner) Public() crypto.PublicKey {
+ return ed25519.PublicKey(ts.PublicKey[:])
+}
+
+func (ts *TestSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+ return ts.Signature[:], ts.Error
+}
+
+var (
+ testTH = types.TreeHead{
+ Timestamp: 0,
+ TreeSize: 0,
+ RootHash: *merkle.HashFn([]byte("root hash")),
+ }
+ testSignerFailing = TestSigner{types.PublicKey{}, types.Signature{}, fmt.Errorf("mocked error")}
+ testSignerSucceeding = TestSigner{types.PublicKey{}, types.Signature{}, nil}
+)
+
+func TestGetTreeHeadToCosign(t *testing.T) {
+ for _, tbl := range []struct {
+ desc string
+ trillianTHErr error
+ trillianTHRet *types.TreeHead
+ signer crypto.Signer
+ httpStatus int
+ }{
+ {
+ desc: "trillian GetTreeHead error",
+ trillianTHErr: fmt.Errorf("mocked error"),
+ httpStatus: http.StatusInternalServerError,
+ },
+ {
+ desc: "signer error",
+ trillianTHRet: &testTH,
+ signer: &testSignerFailing,
+ httpStatus: http.StatusInternalServerError,
+ },
+ {
+ desc: "success",
+ trillianTHRet: &testTH,
+ signer: &testSignerSucceeding,
+ httpStatus: http.StatusOK,
+ },
+ } {
+ func() {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+
+ trillianClient := mocksDB.NewMockClient(ctrl)
+ trillianClient.EXPECT().GetTreeHead(gomock.Any()).Return(tbl.trillianTHRet, tbl.trillianTHErr)
+
+ node := Secondary{
+ Config: testConfig,
+ TrillianClient: trillianClient,
+ Signer: tbl.signer,
+ }
+
+ // Create HTTP request
+ url := types.EndpointAddLeaf.Path("http://example.com", node.Prefix())
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ t.Fatalf("must create http request: %v", err)
+ }
+
+ // Run HTTP request
+ w := httptest.NewRecorder()
+ mustHandleInternal(t, node, types.EndpointGetTreeHeadToCosign).ServeHTTP(w, req)
+ if got, want := w.Code, tbl.httpStatus; got != want {
+ t.Errorf("got HTTP status code %v but wanted %v in test %q", got, want, tbl.desc)
+ }
+ }()
+ }
+}
+
+func mustHandleInternal(t *testing.T, s Secondary, e types.Endpoint) handler.Handler {
+ for _, h := range s.InternalHTTPHandlers() {
+ if h.Endpoint == e {
+ return h
+ }
+ }
+ t.Fatalf("must handle endpoint: %v", e)
+ return handler.Handler{}
+}