| 1 | package cli |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "os" |
| 6 | "path/filepath" |
| 7 | "testing" |
| 8 | |
| 9 | "github.com/ipfs/go-test/random" |
| 10 | "github.com/ipfs/go-test/random/files" |
| 11 | "github.com/ipfs/kubo/config" |
| 12 | "github.com/ipfs/kubo/test/cli/harness" |
| 13 | "github.com/stretchr/testify/assert" |
| 14 | "github.com/stretchr/testify/require" |
| 15 | ) |
| 16 | |
| 17 | func TestTransports(t *testing.T) { |
| 18 | disableRouting := func(nodes harness.Nodes) { |
| 19 | nodes.ForEachPar(func(n *harness.Node) { |
| 20 | n.UpdateConfig(func(cfg *config.Config) { |
| 21 | cfg.Routing.Type = config.NewOptionalString("none") |
| 22 | cfg.Bootstrap = nil |
| 23 | }) |
| 24 | }) |
| 25 | } |
| 26 | checkSingleFile := func(nodes harness.Nodes) { |
| 27 | s := string(random.Bytes(100)) |
| 28 | hash := nodes[0].IPFSAddStr(s) |
| 29 | nodes.ForEachPar(func(n *harness.Node) { |
| 30 | val := n.IPFS("cat", hash).Stdout.String() |
| 31 | assert.Equal(t, s, val) |
| 32 | }) |
| 33 | } |
| 34 | checkRandomDir := func(nodes harness.Nodes) { |
| 35 | randDir := filepath.Join(nodes[0].Dir, "foobar") |
| 36 | require.NoError(t, os.Mkdir(randDir, 0o777)) |
| 37 | rfCfg := files.DefaultConfig() |
| 38 | rfCfg.Dirs = 3 |
| 39 | rfCfg.Files = 6 |
| 40 | rfCfg.Depth = 4 |
| 41 | require.NoError(t, files.Create(rfCfg, randDir)) |
| 42 | |
| 43 | hash := nodes[1].IPFS("add", "-r", "-Q", randDir).Stdout.Trimmed() |
| 44 | nodes.ForEachPar(func(n *harness.Node) { |
| 45 | res := n.RunIPFS("refs", "-r", hash) |
| 46 | assert.Equal(t, 0, res.ExitCode()) |
| 47 | }) |
| 48 | } |
| 49 | |
| 50 | runTests := func(nodes harness.Nodes) { |
| 51 | checkSingleFile(nodes) |
| 52 | checkRandomDir(nodes) |
| 53 | } |
| 54 | |
| 55 | tcpNodes := func(t *testing.T) harness.Nodes { |
| 56 | nodes := harness.NewT(t).NewNodes(2).Init() |
| 57 | nodes.ForEachPar(func(n *harness.Node) { |
| 58 | n.UpdateConfig(func(cfg *config.Config) { |
| 59 | cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/tcp/0"} |
| 60 | cfg.Swarm.Transports.Network.QUIC = config.False |
| 61 | cfg.Swarm.Transports.Network.Relay = config.False |
| 62 | cfg.Swarm.Transports.Network.WebTransport = config.False |
| 63 | cfg.Swarm.Transports.Network.WebRTCDirect = config.False |
| 64 | cfg.Swarm.Transports.Network.Websocket = config.False |
| 65 | // Disable AutoTLS since we're disabling WebSocket transport |
| 66 | cfg.AutoTLS.Enabled = config.False |
| 67 | }) |
| 68 | }) |
| 69 | disableRouting(nodes) |
| 70 | return nodes |
| 71 | } |
| 72 | |
| 73 | t.Run("tcp", func(t *testing.T) { |
| 74 | t.Parallel() |
| 75 | nodes := tcpNodes(t).StartDaemons().Connect() |
| 76 | runTests(nodes) |
| 77 | nodes.StopDaemons() |
| 78 | }) |
| 79 | |
| 80 | t.Run("tcp with NOISE", func(t *testing.T) { |
| 81 | t.Parallel() |
| 82 | nodes := tcpNodes(t) |
| 83 | nodes.ForEachPar(func(n *harness.Node) { |
| 84 | n.UpdateConfig(func(cfg *config.Config) { |
| 85 | cfg.Swarm.Transports.Security.TLS = config.Disabled |
| 86 | }) |
| 87 | }) |
| 88 | nodes.StartDaemons().Connect() |
| 89 | runTests(nodes) |
| 90 | nodes.StopDaemons() |
| 91 | }) |
| 92 | |
| 93 | t.Run("QUIC", func(t *testing.T) { |
| 94 | t.Parallel() |
| 95 | nodes := harness.NewT(t).NewNodes(5).Init() |
| 96 | nodes.ForEachPar(func(n *harness.Node) { |
| 97 | n.UpdateConfig(func(cfg *config.Config) { |
| 98 | cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1"} |
| 99 | cfg.Swarm.Transports.Network.TCP = config.False |
| 100 | cfg.Swarm.Transports.Network.QUIC = config.True |
| 101 | cfg.Swarm.Transports.Network.WebTransport = config.False |
| 102 | cfg.Swarm.Transports.Network.WebRTCDirect = config.False |
| 103 | cfg.Swarm.Transports.Network.Websocket = config.False |
| 104 | }) |
| 105 | }) |
| 106 | disableRouting(nodes) |
| 107 | nodes.StartDaemons().Connect() |
| 108 | runTests(nodes) |
| 109 | nodes.StopDaemons() |
| 110 | }) |
| 111 | |
| 112 | t.Run("QUIC+Webtransport", func(t *testing.T) { |
| 113 | t.Parallel() |
| 114 | nodes := harness.NewT(t).NewNodes(5).Init() |
| 115 | nodes.ForEachPar(func(n *harness.Node) { |
| 116 | n.UpdateConfig(func(cfg *config.Config) { |
| 117 | cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/quic-v1/webtransport"} |
| 118 | cfg.Swarm.Transports.Network.TCP = config.False |
| 119 | cfg.Swarm.Transports.Network.QUIC = config.True |
| 120 | cfg.Swarm.Transports.Network.WebTransport = config.True |
| 121 | cfg.Swarm.Transports.Network.WebRTCDirect = config.False |
| 122 | cfg.Swarm.Transports.Network.Websocket = config.False |
| 123 | }) |
| 124 | }) |
| 125 | disableRouting(nodes) |
| 126 | nodes.StartDaemons().Connect() |
| 127 | runTests(nodes) |
| 128 | nodes.StopDaemons() |
| 129 | }) |
| 130 | |
| 131 | t.Run("QUIC connects with non-dialable transports", func(t *testing.T) { |
| 132 | // This test targets specific Kubo internals which may change later. This checks |
| 133 | // if we can announce an address we do not listen on, and then are able to connect |
| 134 | // via a different address that is available. |
| 135 | t.Parallel() |
| 136 | nodes := harness.NewT(t).NewNodes(5).Init() |
| 137 | nodes.ForEachPar(func(n *harness.Node) { |
| 138 | n.UpdateConfig(func(cfg *config.Config) { |
| 139 | // We need a specific port to announce so we first generate a random port. |
| 140 | // We can't use 0 here to automatically assign an available port because |
| 141 | // that would only work with Swarm, but not for the announcing. |
| 142 | port := harness.NewRandPort() |
| 143 | quicAddr := fmt.Sprintf("/ip4/127.0.0.1/udp/%d/quic-v1", port) |
| 144 | cfg.Addresses.Swarm = []string{quicAddr} |
| 145 | cfg.Addresses.Announce = []string{quicAddr, quicAddr + "/webtransport"} |
| 146 | }) |
| 147 | }) |
| 148 | disableRouting(nodes) |
| 149 | nodes.StartDaemons().Connect() |
| 150 | runTests(nodes) |
| 151 | nodes.StopDaemons() |
| 152 | }) |
| 153 | |
| 154 | t.Run("WebRTC Direct", func(t *testing.T) { |
| 155 | t.Parallel() |
| 156 | nodes := harness.NewT(t).NewNodes(5).Init() |
| 157 | nodes.ForEachPar(func(n *harness.Node) { |
| 158 | n.UpdateConfig(func(cfg *config.Config) { |
| 159 | cfg.Addresses.Swarm = []string{"/ip4/127.0.0.1/udp/0/webrtc-direct"} |
| 160 | cfg.Swarm.Transports.Network.TCP = config.False |
| 161 | cfg.Swarm.Transports.Network.QUIC = config.False |
| 162 | cfg.Swarm.Transports.Network.WebTransport = config.False |
| 163 | cfg.Swarm.Transports.Network.WebRTCDirect = config.True |
| 164 | cfg.Swarm.Transports.Network.Websocket = config.False |
| 165 | }) |
| 166 | }) |
| 167 | disableRouting(nodes) |
| 168 | nodes.StartDaemons().Connect() |
| 169 | runTests(nodes) |
| 170 | nodes.StopDaemons() |
| 171 | }) |
| 172 | } |