diff options
| author | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2020-11-16 16:56:16 +0100 | 
|---|---|---|
| committer | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2020-11-16 16:56:16 +0100 | 
| commit | 7f06b2de5440a3523594daa2d74cf277c8af89cc (patch) | |
| tree | 2186c59ae5a3fd61745c33adb01b4b0882e75a10 | |
| parent | 38deaf4c6b4923eb4b0e77f151c0169ab439a268 (diff) | |
added get-proof-by-hash handler tests
Ensures that the respective error handling functions are invoked.
| -rw-r--r-- | handler_test.go | 127 | ||||
| -rw-r--r-- | reqres.go | 2 | 
2 files changed, 127 insertions, 2 deletions
| diff --git a/handler_test.go b/handler_test.go index c0a6e68..8ae0987 100644 --- a/handler_test.go +++ b/handler_test.go @@ -11,6 +11,7 @@ import (  	"crypto/ed25519"  	"crypto/tls"  	"crypto/x509" +	"encoding/base64"  	"encoding/json"  	"net/http"  	"net/http/httptest" @@ -208,10 +209,11 @@ func TestAddEntry(t *testing.T) {  			defer th.mockCtrl.Finish()  			url := "http://example.com" + th.instance.LogParameters.Prefix + "/add-entry" -			req, err := http.NewRequest("POST", "application/json", table.breq) +			req, err := http.NewRequest("POST", url, table.breq)  			if err != nil {  				t.Fatalf("failed creating http request: %v", err)  			} +			req.Header.Set("Content-Type", "application/json")  			if table.trsp != nil || table.terr != nil {  				th.client.EXPECT().QueueLeaf(testdata.NewDeadlineMatcher(), gomock.Any()).Return(table.trsp, table.terr) @@ -380,6 +382,115 @@ func TestGetSth(t *testing.T) {  	}  } +func TestGetProofByHash(t *testing.T) { +	fixedProof := [][]byte{ +		make([]byte, 32), +		make([]byte, 32), +	} +	for _, table := range []struct { +		description string +		breq        *GetProofByHashRequest +		trsp        *trillian.GetInclusionProofByHashResponse +		terr        error +		wantCode    int +		wantErrText string +	}{ +		{ +			description: "bad request parameters", +			breq: &GetProofByHashRequest{ +				Hash:     make([]byte, 32), +				TreeSize: 0, +			}, +			wantCode:    http.StatusBadRequest, +			wantErrText: http.StatusText(http.StatusBadRequest) + "\n", +		}, +		{ +			description: "empty trillian response", +			breq: &GetProofByHashRequest{ +				Hash:     make([]byte, 32), +				TreeSize: 128, +			}, +			terr:        fmt.Errorf("back-end failure"), +			wantCode:    http.StatusInternalServerError, +			wantErrText: http.StatusText(http.StatusInternalServerError) + "\n", +		}, +		{ +			description: "valid request and response", +			breq: &GetProofByHashRequest{ +				Hash:     make([]byte, 32), +				TreeSize: 128, +			}, +			trsp:     makeTrillianGetInclusionProofByHashResponse(t, 0, fixedProof), +			wantCode: http.StatusOK, +		}, +	} { +		func() { // run deferred functions at the end of each iteration +			th := newTestHandler(t, nil) +			defer th.mockCtrl.Finish() + +			url := "http://example.com" + th.instance.LogParameters.Prefix + "/get-proof-by-hash" +			req, err := http.NewRequest("GET", url, nil) +			if err != nil { +				t.Fatalf("failed creating http request: %v", err) +			} +			q := req.URL.Query() +			q.Add("hash", base64.StdEncoding.EncodeToString(table.breq.Hash)) +			q.Add("tree_size", fmt.Sprintf("%d", table.breq.TreeSize)) +			req.URL.RawQuery = q.Encode() + +			w := httptest.NewRecorder() +			if table.trsp != nil || table.terr != nil { +				th.client.EXPECT().GetInclusionProofByHash(testdata.NewDeadlineMatcher(), gomock.Any()).Return(table.trsp, table.terr) +			} +			th.getHandler(t, "get-proof-by-hash").ServeHTTP(w, req) +			if w.Code != table.wantCode { +				t.Errorf("GET(%s)=%d, want http status code %d", url, w.Code, table.wantCode) +			} +			body := w.Body.String() +			if w.Code != http.StatusOK { +				if body != table.wantErrText { +					t.Errorf("GET(%s)=%q, want text %q", url, body, table.wantErrText) +				} +				return +			} + +			// status code is http.StatusOK, check response +			var data []byte +			if err := json.Unmarshal([]byte(body), &data); err != nil { +				t.Errorf("failed unmarshaling json: %v, wanted ok", err) +				return +			} +			var item StItem +			if err := item.Unmarshal(data); err != nil { +				t.Errorf("failed unmarshaling StItem: %v, wanted ok", err) +				return +			} +			if item.Format != StFormatInclusionProofV1 { +				t.Errorf("invalid StFormat: got %v, want %v", item.Format, StFormatInclusionProofV1) +			} +			proof := item.InclusionProofV1 +			if !bytes.Equal(proof.LogId, th.instance.LogParameters.LogId) { +				t.Errorf("want log id %X, got %X", proof.LogId, th.instance.LogParameters.LogId) +			} +			if proof.TreeSize != uint64(table.breq.TreeSize) { +				t.Errorf("want tree size %d, got %d", table.breq.TreeSize, proof.TreeSize) +			} +			if proof.LeafIndex != 0 { +				t.Errorf("want index %d, got %d", 0, proof.LeafIndex) +			} +			if got, want := len(proof.InclusionPath), len(fixedProof); got != want { +				t.Errorf("want proof length %d, got %d", want, got) +				return +			} +			for i, nh := range proof.InclusionPath { +				if !bytes.Equal(nh.Data, fixedProof[i]) { +					t.Errorf("want proof[%d]=%X, got %X", i, fixedProof[i], nh.Data) +				} +			} +		}() +	} +} +  // makeTestLeaf creates add-entry test data  func makeTestLeaf(t *testing.T, name, pemChain, pemKey []byte) ([]byte, []byte) {  	t.Helper() @@ -449,3 +560,17 @@ func makeTrillianQueueLeafResponse(t *testing.T, name, pemChain, pemKey []byte)  		},  	}  } + +// makeTrillianGetInclusionProofByHashResponse +func makeTrillianGetInclusionProofByHashResponse(t *testing.T, index int64, path [][]byte) *trillian.GetInclusionProofByHashResponse { +	t.Helper() +	return &trillian.GetInclusionProofByHashResponse{ +		Proof: []*trillian.Proof{ +			&trillian.Proof{ +				LeafIndex: index, +				Hashes:    path, +			}, +		}, +		SignedLogRoot: nil, // not used by stfe +	} +} @@ -113,7 +113,7 @@ func (lp *LogParameters) newGetProofByHashRequest(httpRequest *http.Request) (*G  	if err != nil {  		return nil, fmt.Errorf("bad tree_size parameter: %v", err)  	} -	if size < 0 { +	if size < 1 {  		return nil, fmt.Errorf("bad tree_size parameter: negative value")  	}  	hash, err := deb64(httpRequest.FormValue("hash")) | 
