-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(gateway): add harness tests for gateway over libp2p
- Loading branch information
1 parent
bf548a3
commit 2a1d91f
Showing
1 changed file
with
106 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package cli | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/ipfs/go-cid" | ||
"github.com/ipfs/kubo/core/commands" | ||
"github.com/ipfs/kubo/test/cli/harness" | ||
"github.com/libp2p/go-libp2p" | ||
"github.com/libp2p/go-libp2p/core/peer" | ||
libp2phttp "github.com/libp2p/go-libp2p/p2p/http" | ||
"github.com/multiformats/go-multiaddr" | ||
manet "github.com/multiformats/go-multiaddr/net" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGatewayOverLibp2p(t *testing.T) { | ||
t.Parallel() | ||
nodes := harness.NewT(t).NewNodes(2).Init() | ||
|
||
// Setup streaming functionality | ||
nodes.ForEachPar(func(node *harness.Node) { | ||
node.IPFS("config", "--json", "Experimental.Libp2pStreamMounting", "true") | ||
}) | ||
|
||
gwNode := nodes[0] | ||
p2pProxyNode := nodes[1] | ||
|
||
nodes.StartDaemons().Connect() | ||
|
||
// Add data to the gateway node | ||
cidDataOnGatewayNode := cid.MustParse(gwNode.IPFSAddStr("Hello Worlds2!")) | ||
r := gwNode.GatewayClient().Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataOnGatewayNode)) | ||
blockDataOnGatewayNode := []byte(r.Body) | ||
|
||
// Add data to the non-gateway node | ||
cidDataNotOnGatewayNode := cid.MustParse(p2pProxyNode.IPFSAddStr("Hello Worlds!")) | ||
r = p2pProxyNode.GatewayClient().Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataNotOnGatewayNode)) | ||
blockDataNotOnGatewayNode := []byte(r.Body) | ||
_ = blockDataNotOnGatewayNode | ||
|
||
// Setup one of the nodes as http to http-over-libp2p proxy | ||
p2pProxyNode.IPFS("p2p", "forward", "--allow-custom-protocol", "/http/1.1", "/ip4/127.0.0.1/tcp/0", fmt.Sprintf("/p2p/%s", gwNode.PeerID())) | ||
lsOutput := commands.P2PLsOutput{} | ||
if err := json.Unmarshal(p2pProxyNode.IPFS("p2p", "ls", "--enc=json").Stdout.Bytes(), &lsOutput); err != nil { | ||
t.Fatal(err) | ||
} | ||
require.Len(t, lsOutput.Listeners, 1) | ||
p2pProxyNodeHTTPListenMA, err := multiaddr.NewMultiaddr(lsOutput.Listeners[0].ListenAddress) | ||
require.NoError(t, err) | ||
|
||
p2pProxyNodeHTTPListenAddr, err := manet.ToNetAddr(p2pProxyNodeHTTPListenMA) | ||
require.NoError(t, err) | ||
|
||
// Note: the bare HTTP requests here assume that the gateway is mounted at `/` | ||
t.Run("WillNotServeRemoteContent", func(t *testing.T) { | ||
resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataNotOnGatewayNode)) | ||
require.NoError(t, err) | ||
require.Equal(t, 500, resp.StatusCode) | ||
}) | ||
|
||
t.Run("WillNotServeDeserializedResponses", func(t *testing.T) { | ||
resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode)) | ||
require.NoError(t, err) | ||
require.Equal(t, http.StatusNotAcceptable, resp.StatusCode) | ||
}) | ||
|
||
t.Run("ServeBlock", func(t *testing.T) { | ||
t.Run("UsingKuboProxy", func(t *testing.T) { | ||
resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode)) | ||
require.NoError(t, err) | ||
defer resp.Body.Close() | ||
require.Equal(t, 200, resp.StatusCode) | ||
body, err := io.ReadAll(resp.Body) | ||
require.NoError(t, err) | ||
require.Equal(t, blockDataOnGatewayNode, body) | ||
}) | ||
t.Run("UsingLibp2pClientWithPathDiscovery", func(t *testing.T) { | ||
clientHost, err := libp2p.New(libp2p.NoListenAddrs) | ||
require.NoError(t, err) | ||
err = clientHost.Connect(context.Background(), peer.AddrInfo{ | ||
ID: gwNode.PeerID(), | ||
Addrs: gwNode.SwarmAddrs(), | ||
}) | ||
require.NoError(t, err) | ||
|
||
client, err := (&libp2phttp.Host{StreamHost: clientHost}).NamespacedClient("/ipfs/gateway", peer.AddrInfo{ID: gwNode.PeerID()}) | ||
require.NoError(t, err) | ||
|
||
resp, err := client.Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataOnGatewayNode)) | ||
require.NoError(t, err) | ||
defer resp.Body.Close() | ||
require.Equal(t, 200, resp.StatusCode) | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, blockDataOnGatewayNode, body) | ||
}) | ||
}) | ||
} |