Skip to content

Commit

Permalink
test: add trustless e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Feb 13, 2024
1 parent f85a354 commit 989df62
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 5 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/mitchellh/go-server-timing v1.0.1
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-multiaddr v0.12.2
github.com/multiformats/go-multicodec v0.9.0
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/prometheus/client_golang v1.18.0
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529
Expand Down Expand Up @@ -126,7 +127,6 @@ require (
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
Expand All @@ -153,6 +153,7 @@ require (
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect
github.com/whyrusleeping/cbor-gen v0.0.0-20240109153615-66e95c3e8a87 // indirect
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opentelemetry.io/contrib/propagators/aws v1.23.0 // indirect
Expand Down
109 changes: 109 additions & 0 deletions handler_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
package main

import (
"bytes"
"context"
"net/http"
"net/http/httptest"
"testing"

chunker "github.com/ipfs/boxo/chunker"
"github.com/ipfs/boxo/ipld/merkledag"
"github.com/ipfs/boxo/ipld/unixfs/importer/balanced"
uih "github.com/ipfs/boxo/ipld/unixfs/importer/helpers"
util "github.com/ipfs/boxo/util"
"github.com/ipfs/go-cid"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/multiformats/go-multicodec"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type rpcRedirectTest struct {
Expand Down Expand Up @@ -85,3 +96,101 @@ func TestRPCNotImplemented(t *testing.T) {
assert.Equal(t, http.StatusNotImplemented, resp.Code)
}
}

func mustTestServer(t *testing.T, cfg Config) (*httptest.Server, *Node) {
cfg.DataDir = t.TempDir()
cfg.BlockstoreType = "flatfs"

ctx := context.Background()

sr := util.NewTimeSeededRand()
sk, _, err := ic.GenerateKeyPairWithReader(ic.Ed25519, 2048, sr)
require.NoError(t, err)

cdns := newCachedDNS(dnsCacheRefreshInterval)

t.Cleanup(func() {
_ = cdns.Close()
})

gnd, err := Setup(ctx, cfg, sk, cdns)
if err != nil {
require.NoError(t, err)
}

handler, err := setupGatewayHandler(cfg, gnd)
if err != nil {
require.NoError(t, err)
}

ts := httptest.NewServer(handler)

return ts, gnd
}

func mustAddFile(t *testing.T, gnd *Node, content []byte) cid.Cid {
dsrv := merkledag.NewDAGService(gnd.bsrv)

// Create a UnixFS graph from our file, parameters described here but can be visualized at https://dag.ipfs.tech/
ufsImportParams := uih.DagBuilderParams{
Maxlinks: uih.DefaultLinksPerBlock, // Default max of 174 links per block
RawLeaves: true, // Leave the actual file bytes untouched instead of wrapping them in a dag-pb protobuf wrapper
CidBuilder: cid.V1Builder{ // Use CIDv1 for all links
Codec: uint64(multicodec.DagPb),
MhType: uint64(multicodec.Sha2_256), // Use SHA2-256 as the hash function
MhLength: -1, // Use the default hash length for the given hash function (in this case 256 bits)
},
Dagserv: dsrv,
NoCopy: false,
}
ufsBuilder, err := ufsImportParams.New(chunker.NewSizeSplitter(bytes.NewReader(content), chunker.DefaultBlockSize)) // Split the file up into fixed sized 256KiB chunks
require.NoError(t, err)

nd, err := balanced.Layout(ufsBuilder) // Arrange the graph with a balanced layout
require.NoError(t, err)

return nd.Cid()
}

func TestTrustless(t *testing.T) {
t.Parallel()

ts, gnd := mustTestServer(t, Config{
TrustlessGatewayDomains: []string{"trustless.com"},
})

content := "hello world"
cid := mustAddFile(t, gnd, []byte(content))
url := ts.URL + "/ipfs/" + cid.String()

t.Run("Non-trustless request returns 406", func(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)
req.Host = "trustless.com"

res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, http.StatusNotAcceptable, res.StatusCode)
})

t.Run("Trustless request with query parameter returns 200", func(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, url+"?format=raw", nil)
require.NoError(t, err)
req.Host = "trustless.com"

res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
})

t.Run("Trustless request with accept header returns 200", func(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)
req.Host = "trustless.com"
req.Header.Set("Accept", "application/vnd.ipld.raw")

res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
})
}
6 changes: 2 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ only websites, but any supported content-addressed Merkle-DAG), in formats
that are suitable for verification client-side (i.e. CAR files).
Rainbow is optimized to perform the tasks of a gateway and only that, making
opinionated choices on the configration and setup of internal
opinionated choices on the configuration and setup of internal

Check warning on line 49 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L49

Added line #L49 was not covered by tests
components. Rainbow aims to serve production environments, where gateways are
deployed as a public service meant to be accessible by anyone. Rainbow acts as
a client to the IPFS network and does not serve or provide content to
it. Rainbow cannot be used to store or pin IPFS content, other than that
temporailly served over HTTP. Rainbow is just a gateway.
temporarily served over HTTP. Rainbow is just a gateway.

Check warning on line 54 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L54

Added line #L54 was not covered by tests
Persistent configuration and data is stored in $RAINBOW_DATADIR (by default,
the folder in which rainbow is run).
Expand All @@ -73,7 +73,6 @@ Generate an identity seed and launch a gateway:
`

app.Flags = []cli.Flag{

&cli.StringFlag{
Name: "datadir",
Value: "",
Expand Down Expand Up @@ -122,7 +121,6 @@ Generate an identity seed and launch a gateway:
EnvVars: []string{"RAINBOW_CTL_LISTEN_ADDRESS"},
Usage: "Listen address for the management api and metrics",
},

&cli.IntFlag{
Name: "connmgr-low",
Value: 100,
Expand Down

0 comments on commit 989df62

Please sign in to comment.