From 4c15ffffdd0aaf3b834be88ff7e7d9ea938c45b4 Mon Sep 17 00:00:00 2001 From: Elad Date: Thu, 6 Sep 2018 12:08:39 +0200 Subject: [PATCH] swarm/api/http: added a regression test for resolver bug from #17483 (#17502) --- swarm/api/client/client_test.go | 14 ++-- swarm/api/http/response_test.go | 10 +-- swarm/api/http/server_test.go | 143 ++++++++++++++++++++++++++++++-- swarm/testutil/http.go | 4 +- 4 files changed, 148 insertions(+), 23 deletions(-) diff --git a/swarm/api/client/client_test.go b/swarm/api/client/client_test.go index 2212f5c4c..f9312d48f 100644 --- a/swarm/api/client/client_test.go +++ b/swarm/api/client/client_test.go @@ -47,7 +47,7 @@ func TestClientUploadDownloadRawEncrypted(t *testing.T) { } func testClientUploadDownloadRaw(toEncrypt bool, t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() client := NewClient(srv.URL) @@ -88,7 +88,7 @@ func TestClientUploadDownloadFilesEncrypted(t *testing.T) { } func testClientUploadDownloadFiles(toEncrypt bool, t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() client := NewClient(srv.URL) @@ -186,7 +186,7 @@ func newTestDirectory(t *testing.T) string { // TestClientUploadDownloadDirectory tests uploading and downloading a // directory of files to a swarm manifest func TestClientUploadDownloadDirectory(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() dir := newTestDirectory(t) @@ -252,7 +252,7 @@ func TestClientFileListEncrypted(t *testing.T) { } func testClientFileList(toEncrypt bool, t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() dir := newTestDirectory(t) @@ -310,7 +310,7 @@ func testClientFileList(toEncrypt bool, t *testing.T) { // TestClientMultipartUpload tests uploading files to swarm using a multipart // upload func TestClientMultipartUpload(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() // define an uploader which uploads testDirFiles with some data @@ -376,7 +376,7 @@ func TestClientCreateResourceMultihash(t *testing.T) { signer, _ := newTestSigner() - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) client := NewClient(srv.URL) defer srv.Close() @@ -439,7 +439,7 @@ func TestClientCreateUpdateResource(t *testing.T) { signer, _ := newTestSigner() - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) client := NewClient(srv.URL) defer srv.Close() diff --git a/swarm/api/http/response_test.go b/swarm/api/http/response_test.go index 2e24bda6d..50a704be6 100644 --- a/swarm/api/http/response_test.go +++ b/swarm/api/http/response_test.go @@ -29,7 +29,7 @@ import ( ) func TestError(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() var resp *http.Response @@ -55,7 +55,7 @@ func TestError(t *testing.T) { } func Test404Page(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() var resp *http.Response @@ -81,7 +81,7 @@ func Test404Page(t *testing.T) { } func Test500Page(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() var resp *http.Response @@ -106,7 +106,7 @@ func Test500Page(t *testing.T) { } } func Test500PageWith0xHashPrefix(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() var resp *http.Response @@ -136,7 +136,7 @@ func Test500PageWith0xHashPrefix(t *testing.T) { } func TestJsonResponse(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() var resp *http.Response diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go index 7934e37eb..891deb881 100644 --- a/swarm/api/http/server_test.go +++ b/swarm/api/http/server_test.go @@ -27,6 +27,7 @@ import ( "fmt" "io" "io/ioutil" + "math/big" "mime/multipart" "net/http" "os" @@ -36,6 +37,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/swarm/api" @@ -114,7 +116,7 @@ func TestBzzResourceMultihash(t *testing.T) { signer, _ := newTestSigner() - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() // add the data our multihash aliased manifest will point to @@ -208,7 +210,7 @@ func TestBzzResourceMultihash(t *testing.T) { // Test resource updates using the raw update methods func TestBzzResource(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) signer, _ := newTestSigner() defer srv.Close() @@ -467,7 +469,7 @@ func testBzzGetPath(encrypted bool, t *testing.T) { addr := [3]storage.Address{} - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() for i, mf := range testmanifest { @@ -702,7 +704,7 @@ func TestBzzTar(t *testing.T) { } func testBzzTar(encrypted bool, t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() fileNames := []string{"tmp1.txt", "tmp2.lock", "tmp3.rtf"} fileContents := []string{"tmp1textfilevalue", "tmp2lockfilelocked", "tmp3isjustaplaintextfile"} @@ -827,7 +829,7 @@ func TestBzzRootRedirectEncrypted(t *testing.T) { } func testBzzRootRedirect(toEncrypt bool, t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() // create a manifest with some data at the root path @@ -882,7 +884,7 @@ func testBzzRootRedirect(toEncrypt bool, t *testing.T) { } func TestMethodsNotAllowed(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() databytes := "bar" for _, c := range []struct { @@ -941,7 +943,7 @@ func httpDo(httpMethod string, url string, reqBody io.Reader, headers map[string } func TestGet(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() for _, testCase := range []struct { @@ -1025,7 +1027,7 @@ func TestGet(t *testing.T) { } func TestModify(t *testing.T) { - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() swarmClient := swarm.NewClient(srv.URL) @@ -1126,7 +1128,7 @@ func TestMultiPartUpload(t *testing.T) { // POST /bzz:/ Content-Type: multipart/form-data verbose := false // Setup Swarm - srv := testutil.NewTestSwarmServer(t, serverFunc) + srv := testutil.NewTestSwarmServer(t, serverFunc, nil) defer srv.Close() url := fmt.Sprintf("%s/bzz:/", srv.URL) @@ -1153,3 +1155,126 @@ func TestMultiPartUpload(t *testing.T) { t.Fatalf("expected POST multipart/form-data to return a 64 char manifest but the answer was %d chars long", len(body)) } } + +// TestBzzGetFileWithResolver tests fetching a file using a mocked ENS resolver +func TestBzzGetFileWithResolver(t *testing.T) { + resolver := newTestResolveValidator("") + srv := testutil.NewTestSwarmServer(t, serverFunc, resolver) + defer srv.Close() + fileNames := []string{"dir1/tmp1.txt", "dir2/tmp2.lock", "dir3/tmp3.rtf"} + fileContents := []string{"tmp1textfilevalue", "tmp2lockfilelocked", "tmp3isjustaplaintextfile"} + + buf := &bytes.Buffer{} + tw := tar.NewWriter(buf) + + for i, v := range fileNames { + size := len(fileContents[i]) + hdr := &tar.Header{ + Name: v, + Mode: 0644, + Size: int64(size), + ModTime: time.Now(), + Xattrs: map[string]string{ + "user.swarm.content-type": "text/plain", + }, + } + if err := tw.WriteHeader(hdr); err != nil { + t.Fatal(err) + } + + // copy the file into the tar stream + n, err := io.WriteString(tw, fileContents[i]) + if err != nil { + t.Fatal(err) + } else if n != size { + t.Fatal("size mismatch") + } + } + + if err := tw.Close(); err != nil { + t.Fatal(err) + } + + //post tar stream + url := srv.URL + "/bzz:/" + + req, err := http.NewRequest("POST", url, buf) + if err != nil { + t.Fatal(err) + } + req.Header.Add("Content-Type", "application/x-tar") + client := &http.Client{} + serverResponse, err := client.Do(req) + if err != nil { + t.Fatal(err) + } + if serverResponse.StatusCode != http.StatusOK { + t.Fatalf("err %s", serverResponse.Status) + } + swarmHash, err := ioutil.ReadAll(serverResponse.Body) + serverResponse.Body.Close() + if err != nil { + t.Fatal(err) + } + // set the resolved hash to be the swarm hash of what we've just uploaded + hash := common.HexToHash(string(swarmHash)) + resolver.hash = &hash + for _, v := range []struct { + addr string + path string + expectedStatusCode int + }{ + { + addr: string(swarmHash), + path: fileNames[0], + expectedStatusCode: http.StatusOK, + }, + { + addr: "somebogusensname", + path: fileNames[0], + expectedStatusCode: http.StatusOK, + }, + } { + req, err := http.NewRequest("GET", fmt.Sprintf(srv.URL+"/bzz:/%s/%s", v.addr, v.path), nil) + if err != nil { + t.Fatal(err) + } + serverResponse, err := client.Do(req) + if err != nil { + t.Fatal(err) + } + defer serverResponse.Body.Close() + if serverResponse.StatusCode != v.expectedStatusCode { + t.Fatalf("expected %d, got %d", v.expectedStatusCode, serverResponse.StatusCode) + } + } +} + +// testResolver implements the Resolver interface and either returns the given +// hash if it is set, or returns a "name not found" error +type testResolveValidator struct { + hash *common.Hash +} + +func newTestResolveValidator(addr string) *testResolveValidator { + r := &testResolveValidator{} + if addr != "" { + hash := common.HexToHash(addr) + r.hash = &hash + } + return r +} + +func (t *testResolveValidator) Resolve(addr string) (common.Hash, error) { + if t.hash == nil { + return common.Hash{}, fmt.Errorf("DNS name not found: %q", addr) + } + return *t.hash, nil +} + +func (t *testResolveValidator) Owner(node [32]byte) (addr common.Address, err error) { + return +} +func (t *testResolveValidator) HeaderByNumber(context.Context, *big.Int) (header *types.Header, err error) { + return +} diff --git a/swarm/testutil/http.go b/swarm/testutil/http.go index 7fd60fcc3..074823032 100644 --- a/swarm/testutil/http.go +++ b/swarm/testutil/http.go @@ -45,7 +45,7 @@ func (f *fakeTimeProvider) Now() mru.Timestamp { return mru.Timestamp{Time: f.currentTime} } -func NewTestSwarmServer(t *testing.T, serverFunc func(*api.API) TestServer) *TestSwarmServer { +func NewTestSwarmServer(t *testing.T, serverFunc func(*api.API) TestServer, resolver api.Resolver) *TestSwarmServer { dir, err := ioutil.TempDir("", "swarm-storage-test") if err != nil { t.Fatal(err) @@ -77,7 +77,7 @@ func NewTestSwarmServer(t *testing.T, serverFunc func(*api.API) TestServer) *Tes t.Fatal(err) } - a := api.NewAPI(fileStore, nil, rh.Handler, nil) + a := api.NewAPI(fileStore, resolver, rh.Handler, nil) srv := httptest.NewServer(serverFunc(a)) return &TestSwarmServer{ Server: srv,