test(gateway): add harness tests for gateway over libp2p
Adin Schmahmann committed
Aug 31, 2023 at 03:52 UTC
2a1d91f67abda10c02072d14539940b777df500b
1 file changed
+106
test/cli/http_gateway_over_libp2p_test.go
new
+106
@@ -0,0 +1,106 @@
1
+package cli
2
+
3
+import (
4
+ "context"
5
+ "encoding/json"
6
+ "fmt"
7
+ "io"
8
+ "net/http"
9
+ "testing"
10
+
11
+ "github.com/ipfs/go-cid"
12
+ "github.com/ipfs/kubo/core/commands"
13
+ "github.com/ipfs/kubo/test/cli/harness"
14
+ "github.com/libp2p/go-libp2p"
15
+ "github.com/libp2p/go-libp2p/core/peer"
16
+ libp2phttp "github.com/libp2p/go-libp2p/p2p/http"
17
+ "github.com/multiformats/go-multiaddr"
18
+ manet "github.com/multiformats/go-multiaddr/net"
19
+ "github.com/stretchr/testify/require"
20
+)
21
+
22
+func TestGatewayOverLibp2p(t *testing.T) {
23
+ t.Parallel()
24
+ nodes := harness.NewT(t).NewNodes(2).Init()
25
+
26
+ // Setup streaming functionality
27
+ nodes.ForEachPar(func(node *harness.Node) {
28
+ node.IPFS("config", "--json", "Experimental.Libp2pStreamMounting", "true")
29
+ })
30
+
31
+ gwNode := nodes[0]
32
+ p2pProxyNode := nodes[1]
33
+
34
+ nodes.StartDaemons().Connect()
35
+
36
+ // Add data to the gateway node
37
+ cidDataOnGatewayNode := cid.MustParse(gwNode.IPFSAddStr("Hello Worlds2!"))
38
+ r := gwNode.GatewayClient().Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataOnGatewayNode))
39
+ blockDataOnGatewayNode := []byte(r.Body)
40
+
41
+ // Add data to the non-gateway node
42
+ cidDataNotOnGatewayNode := cid.MustParse(p2pProxyNode.IPFSAddStr("Hello Worlds!"))
43
+ r = p2pProxyNode.GatewayClient().Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataNotOnGatewayNode))
44
+ blockDataNotOnGatewayNode := []byte(r.Body)
45
+ _ = blockDataNotOnGatewayNode
46
+
47
+ // Setup one of the nodes as http to http-over-libp2p proxy
48
+ p2pProxyNode.IPFS("p2p", "forward", "--allow-custom-protocol", "/http/1.1", "/ip4/127.0.0.1/tcp/0", fmt.Sprintf("/p2p/%s", gwNode.PeerID()))
49
+ lsOutput := commands.P2PLsOutput{}
50
+ if err := json.Unmarshal(p2pProxyNode.IPFS("p2p", "ls", "--enc=json").Stdout.Bytes(), &lsOutput); err != nil {
51
+ t.Fatal(err)
52
+ }
53
+ require.Len(t, lsOutput.Listeners, 1)
54
+ p2pProxyNodeHTTPListenMA, err := multiaddr.NewMultiaddr(lsOutput.Listeners[0].ListenAddress)
55
+ require.NoError(t, err)
56
+
57
+ p2pProxyNodeHTTPListenAddr, err := manet.ToNetAddr(p2pProxyNodeHTTPListenMA)
58
+ require.NoError(t, err)
59
+
60
+ // Note: the bare HTTP requests here assume that the gateway is mounted at `/`
61
+ t.Run("WillNotServeRemoteContent", func(t *testing.T) {
62
+ resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataNotOnGatewayNode))
63
+ require.NoError(t, err)
64
+ require.Equal(t, 500, resp.StatusCode)
65
+ })
66
+
67
+ t.Run("WillNotServeDeserializedResponses", func(t *testing.T) {
68
+ resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode))
69
+ require.NoError(t, err)
70
+ require.Equal(t, http.StatusNotAcceptable, resp.StatusCode)
71
+ })
72
+
73
+ t.Run("ServeBlock", func(t *testing.T) {
74
+ t.Run("UsingKuboProxy", func(t *testing.T) {
75
+ resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode))
76
+ require.NoError(t, err)
77
+ defer resp.Body.Close()
78
+ require.Equal(t, 200, resp.StatusCode)
79
+ body, err := io.ReadAll(resp.Body)
80
+ require.NoError(t, err)
81
+ require.Equal(t, blockDataOnGatewayNode, body)
82
+ })
83
+ t.Run("UsingLibp2pClientWithPathDiscovery", func(t *testing.T) {
84
+ clientHost, err := libp2p.New(libp2p.NoListenAddrs)
85
+ require.NoError(t, err)
86
+ err = clientHost.Connect(context.Background(), peer.AddrInfo{
87
+ ID: gwNode.PeerID(),
88
+ Addrs: gwNode.SwarmAddrs(),
89
+ })
90
+ require.NoError(t, err)
91
+
92
+ client, err := (&libp2phttp.Host{StreamHost: clientHost}).NamespacedClient("/ipfs/gateway", peer.AddrInfo{ID: gwNode.PeerID()})
93
+ require.NoError(t, err)
94
+
95
+ resp, err := client.Get(fmt.Sprintf("/ipfs/%s?format=raw", cidDataOnGatewayNode))
96
+ require.NoError(t, err)
97
+ defer resp.Body.Close()
98
+ require.Equal(t, 200, resp.StatusCode)
99
+
100
+ body, err := io.ReadAll(resp.Body)
101
+ require.NoError(t, err)
102
+
103
+ require.Equal(t, blockDataOnGatewayNode, body)
104
+ })
105
+ })
106
+}