@cryptotaxi247 / kubo / commits / 145795b14

test: port rcmgr sharness tests to Go

Gus Eggert committed Feb 27, 2023 at 17:42 UTC 145795b14815cc2a0b6f1599ca734966b3bcebf6
4 files changed +394 -284
test/cli/harness/node.go
+13
@@ -1,6 +1,7 @@
1 package harness
2
3 import (
4 + "bytes"
5 "encoding/json"
6 "errors"
7 "fmt"
@@ -62,6 +63,18 @@ func BuildNode(ipfsBin, baseDir string, id int) *Node {
63 }
64 }
65
66 +func (n *Node) WriteBytes(filename string, b []byte) {
67 + f, err := os.Create(filepath.Join(n.Dir, filename))
68 + if err != nil {
69 + panic(err)
70 + }
71 + defer f.Close()
72 + _, err = io.Copy(f, bytes.NewReader(b))
73 + if err != nil {
74 + panic(err)
75 + }
76 +}
77 +
78 func (n *Node) ReadConfig() *config.Config {
79 cfg, err := serial.Load(filepath.Join(n.Dir, "config"))
80 if err != nil {
test/cli/harness/run.go
+4
@@ -38,6 +38,10 @@ type RunResult struct {
38 Cmd *exec.Cmd
39 }
40
41 +func (r *RunResult) ExitCode() int {
42 + return r.Cmd.ProcessState.ExitCode()
43 +}
44 +
45 func environToMap(environ []string) map[string]string {
46 m := map[string]string{}
47 for _, e := range environ {
test/cli/rcmgr_test.go new
+377
@@ -0,0 +1,377 @@
1 +package cli
2 +
3 +import (
4 + "encoding/json"
5 + "testing"
6 +
7 + "github.com/ipfs/kubo/config"
8 + "github.com/ipfs/kubo/core/node/libp2p"
9 + "github.com/ipfs/kubo/test/cli/harness"
10 + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
11 + "github.com/stretchr/testify/assert"
12 + "github.com/stretchr/testify/require"
13 +)
14 +
15 +func TestRcmgr(t *testing.T) {
16 + t.Parallel()
17 +
18 + t.Run("Resource manager disabled", func(t *testing.T) {
19 + t.Parallel()
20 + node := harness.NewT(t).NewNode().Init()
21 + node.UpdateConfig(func(cfg *config.Config) {
22 + cfg.Swarm.ResourceMgr.Enabled = config.False
23 + })
24 +
25 + node.StartDaemon()
26 +
27 + t.Run("swarm limit should fail", func(t *testing.T) {
28 + res := node.RunIPFS("swarm", "limit", "system")
29 + assert.Equal(t, 1, res.ExitCode())
30 + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr")
31 + })
32 + t.Run("swarm stats should fail", func(t *testing.T) {
33 + res := node.RunIPFS("swarm", "stats", "all")
34 + assert.Equal(t, 1, res.ExitCode())
35 + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr")
36 + })
37 + })
38 +
39 + t.Run("Node in offline mode", func(t *testing.T) {
40 + t.Parallel()
41 + node := harness.NewT(t).NewNode().Init()
42 + node.UpdateConfig(func(cfg *config.Config) {
43 + cfg.Swarm.ResourceMgr.Enabled = config.False
44 + })
45 + node.StartDaemon()
46 +
47 + t.Run("swarm limit should fail", func(t *testing.T) {
48 + res := node.RunIPFS("swarm", "limit", "system")
49 + assert.Equal(t, 1, res.ExitCode())
50 + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr")
51 + })
52 + t.Run("swarm stats should fail", func(t *testing.T) {
53 + res := node.RunIPFS("swarm", "stats", "all")
54 + assert.Equal(t, 1, res.ExitCode())
55 + assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr")
56 + })
57 + })
58 +
59 + t.Run("Very high connmgr highwater", func(t *testing.T) {
60 + node := harness.NewT(t).NewNode().Init()
61 + node.UpdateConfig(func(cfg *config.Config) {
62 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(1000)
63 + })
64 + node.StartDaemon()
65 +
66 + res := node.RunIPFS("swarm", "limit", "system", "--enc=json")
67 + require.Equal(t, 0, res.ExitCode())
68 + limits := unmarshalLimits(t, res.Stdout.Bytes())
69 +
70 + assert.GreaterOrEqual(t, limits.ConnsInbound, 2000)
71 + assert.GreaterOrEqual(t, limits.StreamsInbound, 2000)
72 + })
73 +
74 + t.Run("default configuration", func(t *testing.T) {
75 + t.Parallel()
76 + node := harness.NewT(t).NewNode().Init()
77 + node.UpdateConfig(func(cfg *config.Config) {
78 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(1000)
79 + })
80 + node.StartDaemon()
81 +
82 + t.Run("conns and streams are above 800 for default connmgr settings", func(t *testing.T) {
83 + res := node.RunIPFS("swarm", "limit", "system", "--enc=json")
84 + require.Equal(t, 0, res.ExitCode())
85 + limits := unmarshalLimits(t, res.Stdout.Bytes())
86 +
87 + assert.GreaterOrEqual(t, limits.ConnsInbound, 800)
88 + assert.GreaterOrEqual(t, limits.StreamsInbound, 800)
89 + })
90 +
91 + t.Run("limits|stats should succeed", func(t *testing.T) {
92 + res := node.RunIPFS("swarm", "limit", "all")
93 + assert.Equal(t, 0, res.ExitCode())
94 +
95 + limits := map[string]rcmgr.ResourceLimits{}
96 + err := json.Unmarshal(res.Stdout.Bytes(), &limits)
97 + require.NoError(t, err)
98 +
99 + assert.Greater(t, limits["System"].Memory, int64(0))
100 + assert.Greater(t, limits["System"].FD, 0)
101 + assert.Greater(t, limits["System"].Conns, 0)
102 + assert.Greater(t, limits["System"].ConnsInbound, 0)
103 + assert.Greater(t, limits["System"].ConnsOutbound, 0)
104 + assert.Greater(t, limits["System"].Streams, 0)
105 + assert.Greater(t, limits["System"].StreamsInbound, 0)
106 + assert.Greater(t, limits["System"].StreamsOutbound, 0)
107 + assert.Greater(t, limits["Transient"].Memory, int64(0))
108 + })
109 +
110 + t.Run("resetting limits should produce the same default limits", func(t *testing.T) {
111 + resetRes := node.RunIPFS("swarm", "limit", "system", "--reset", "--enc=json")
112 + require.Equal(t, 0, resetRes.ExitCode())
113 + limitRes := node.RunIPFS("swarm", "limit", "system", "--enc=json")
114 + require.Equal(t, 0, limitRes.ExitCode())
115 +
116 + assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes())
117 + })
118 +
119 + t.Run("swarm stats system with filter should fail", func(t *testing.T) {
120 + res := node.RunIPFS("swarm", "stats", "system", "--min-used-limit-perc=99")
121 + assert.Equal(t, 1, res.ExitCode())
122 + assert.Contains(t, res.Stderr.Lines()[0], `Error: "min-used-limit-perc" can only be used when scope is "all"`)
123 + })
124 +
125 + t.Run("swarm limit reset on map values should work", func(t *testing.T) {
126 + resetRes := node.RunIPFS("swarm", "limit", "peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG", "--reset", "--enc=json")
127 + require.Equal(t, 0, resetRes.ExitCode())
128 + limitRes := node.RunIPFS("swarm", "limit", "peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG", "--enc=json")
129 + require.Equal(t, 0, limitRes.ExitCode())
130 +
131 + assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes())
132 + })
133 +
134 + t.Run("scope is required using reset flags", func(t *testing.T) {
135 + res := node.RunIPFS("swarm", "limit", "--reset")
136 + assert.Equal(t, 1, res.ExitCode())
137 + assert.Contains(t, res.Stderr.Lines()[0], `Error: argument "scope" is required`)
138 + })
139 +
140 + t.Run("swarm stats works", func(t *testing.T) {
141 + res := node.RunIPFS("swarm", "stats", "all", "--enc=json")
142 + require.Equal(t, 0, res.ExitCode())
143 +
144 + stats := libp2p.NetStatOut{}
145 + err := json.Unmarshal(res.Stdout.Bytes(), &stats)
146 + require.NoError(t, err)
147 +
148 + // every scope has the same fields, so we only inspect system
149 + assert.Equal(t, rcmgr.LimitVal64(0), stats.System.Memory)
150 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.FD)
151 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.Conns)
152 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.ConnsInbound)
153 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.ConnsOutbound)
154 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.Streams)
155 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.StreamsInbound)
156 + assert.Equal(t, rcmgr.LimitVal(0), stats.System.StreamsOutbound)
157 + assert.Equal(t, rcmgr.LimitVal64(0), stats.Transient.Memory)
158 + })
159 + })
160 +
161 + t.Run("set system conns limit while daemon is not running", func(t *testing.T) {
162 + node := harness.NewT(t).NewNode().Init()
163 + res := node.RunIPFS("config", "--json", "Swarm.ResourceMgr.Limits.System.Conns", "99999")
164 + require.Equal(t, 0, res.ExitCode())
165 +
166 + t.Run("set an invalid limit which should result in a failure", func(t *testing.T) {
167 + res := node.RunIPFS("config", "--json", "Swarm.ResourceMgr.Limits.System.Conns", "asdf")
168 + assert.Equal(t, 1, res.ExitCode())
169 + assert.Contains(t, res.Stderr.String(), "failed to unmarshal")
170 + })
171 +
172 + node.StartDaemon()
173 +
174 + t.Run("new system conns limit is applied", func(t *testing.T) {
175 + res := node.RunIPFS("swarm", "limit", "system", "--enc=json")
176 + limits := unmarshalLimits(t, res.Stdout.Bytes())
177 + assert.Equal(t, limits.Conns, rcmgr.LimitVal(99999))
178 + })
179 + })
180 +
181 + t.Run("set the system memory limit while the daemon is running", func(t *testing.T) {
182 + node := harness.NewT(t).NewNode().Init().StartDaemon()
183 + updateLimitsWithFile(t, node, "system", func(limits *rcmgr.ResourceLimits) {
184 + limits.Memory = 99998
185 + })
186 +
187 + assert.Equal(t, rcmgr.LimitVal64(99998), node.ReadConfig().Swarm.ResourceMgr.Limits.System.Memory)
188 +
189 + res := node.RunIPFS("swarm", "limit", "system", "--enc=json")
190 + limits := unmarshalLimits(t, res.Stdout.Bytes())
191 + assert.Equal(t, rcmgr.LimitVal64(99998), limits.Memory)
192 + })
193 +
194 + t.Run("smoke test transient scope", func(t *testing.T) {
195 + node := harness.NewT(t).NewNode().Init().StartDaemon()
196 + updateLimitsWithFile(t, node, "transient", func(limits *rcmgr.ResourceLimits) {
197 + limits.Memory = 88888
198 + })
199 +
200 + res := node.RunIPFS("swarm", "limit", "transient", "--enc=json")
201 + limits := unmarshalLimits(t, res.Stdout.Bytes())
202 + assert.Equal(t, rcmgr.LimitVal64(88888), limits.Memory)
203 + })
204 +
205 + t.Run("smoke test service scope", func(t *testing.T) {
206 + node := harness.NewT(t).NewNode().Init().StartDaemon()
207 + updateLimitsWithFile(t, node, "svc:foo", func(limits *rcmgr.ResourceLimits) {
208 + limits.Memory = 77777
209 + })
210 +
211 + res := node.RunIPFS("swarm", "limit", "svc:foo", "--enc=json")
212 + limits := unmarshalLimits(t, res.Stdout.Bytes())
213 + assert.Equal(t, rcmgr.LimitVal64(77777), limits.Memory)
214 + })
215 +
216 + t.Run("smoke test protocol scope", func(t *testing.T) {
217 + node := harness.NewT(t).NewNode().Init().StartDaemon()
218 + updateLimitsWithFile(t, node, "proto:foo", func(limits *rcmgr.ResourceLimits) {
219 + limits.Memory = 66666
220 + })
221 +
222 + res := node.RunIPFS("swarm", "limit", "proto:foo", "--enc=json")
223 + limits := unmarshalLimits(t, res.Stdout.Bytes())
224 + assert.Equal(t, rcmgr.LimitVal64(66666), limits.Memory)
225 + })
226 +
227 + t.Run("smoke test peer scope", func(t *testing.T) {
228 + validPeerID := "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"
229 + node := harness.NewT(t).NewNode().Init().StartDaemon()
230 + updateLimitsWithFile(t, node, "peer:"+validPeerID, func(limits *rcmgr.ResourceLimits) {
231 + limits.Memory = 66666
232 + })
233 +
234 + res := node.RunIPFS("swarm", "limit", "peer:"+validPeerID, "--enc=json")
235 + limits := unmarshalLimits(t, res.Stdout.Bytes())
236 + assert.Equal(t, rcmgr.LimitVal64(66666), limits.Memory)
237 +
238 + t.Parallel()
239 +
240 + t.Run("getting limit for invalid peer ID fails", func(t *testing.T) {
241 + res := node.RunIPFS("swarm", "limit", "peer:foo")
242 + assert.Equal(t, 1, res.ExitCode())
243 + assert.Contains(t, res.Stderr.String(), "invalid peer ID")
244 + })
245 +
246 + t.Run("setting limit for invalid peer ID fails", func(t *testing.T) {
247 + filename := "invalid-peer-id.json"
248 + node.WriteBytes(filename, []byte(`{"Memory":"99"}`))
249 + res := node.RunIPFS("swarm", "limit", "peer:foo", filename)
250 + assert.Equal(t, 1, res.ExitCode())
251 + assert.Contains(t, res.Stderr.String(), "invalid peer ID")
252 + })
253 + })
254 +
255 + t.Run("", func(t *testing.T) {
256 + nodes := harness.NewT(t).NewNodes(3).Init()
257 + node0, node1, node2 := nodes[0], nodes[1], nodes[2]
258 + // peerID0, peerID1, peerID2 := node0.PeerID(), node1.PeerID(), node2.PeerID()
259 + peerID1, peerID2 := node1.PeerID().String(), node2.PeerID().String()
260 +
261 + node0.UpdateConfig(func(cfg *config.Config) {
262 + cfg.Swarm.ResourceMgr.Enabled = config.True
263 + cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2}
264 + })
265 +
266 + nodes.StartDaemons()
267 +
268 + // change system limits on node 0
269 + updateLimitsWithFile(t, node0, "system", func(limits *rcmgr.ResourceLimits) {
270 + limits.Conns = rcmgr.BlockAllLimit
271 + limits.ConnsInbound = rcmgr.BlockAllLimit
272 + limits.ConnsOutbound = rcmgr.BlockAllLimit
273 + })
274 +
275 + t.Parallel()
276 + t.Run("node 0 should fail to connect to node 1", func(t *testing.T) {
277 + res := node0.Runner.Run(harness.RunRequest{
278 + Path: node0.IPFSBin,
279 + Args: []string{"swarm", "connect", node1.SwarmAddrs()[0].String()},
280 + })
281 + assert.Equal(t, 1, res.ExitCode())
282 + assert.Contains(t, res.Stderr.String(), "failed to find any peer in table")
283 + })
284 +
285 + t.Run("node 0 should connect to node 2 since it is allowlisted", func(t *testing.T) {
286 + res := node0.Runner.Run(harness.RunRequest{
287 + Path: node0.IPFSBin,
288 + Args: []string{"swarm", "connect", node2.SwarmAddrs()[0].String()},
289 + })
290 + assert.Equal(t, 0, res.ExitCode())
291 + })
292 +
293 + t.Run("node 0 should fail to ping node 1", func(t *testing.T) {
294 + res := node0.RunIPFS("ping", "-n2", peerID1)
295 + assert.Equal(t, 1, res.ExitCode())
296 + assert.Contains(t, res.Stderr.String(), "Error: ping failed")
297 + })
298 +
299 + t.Run("node 0 should be able to ping node 2", func(t *testing.T) {
300 + res := node0.RunIPFS("ping", "-n2", peerID2)
301 + assert.Equal(t, 0, res.ExitCode())
302 + })
303 + })
304 +
305 + t.Run("daemon should refuse to start if connmgr.highwater < resources inbound", func(t *testing.T) {
306 + t.Parallel()
307 + t.Run("system conns", func(t *testing.T) {
308 + node := harness.NewT(t).NewNode().Init()
309 + node.UpdateConfig(func(cfg *config.Config) {
310 + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
311 + cfg.Swarm.ResourceMgr.Limits.System.Conns = 128
312 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
313 + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
314 + })
315 +
316 + res := node.RunIPFS("daemon")
317 + assert.Equal(t, 1, res.ExitCode())
318 + })
319 + t.Run("system conns inbound", func(t *testing.T) {
320 + node := harness.NewT(t).NewNode().Init()
321 + node.UpdateConfig(func(cfg *config.Config) {
322 + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
323 + cfg.Swarm.ResourceMgr.Limits.System.ConnsInbound = 128
324 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
325 + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
326 + })
327 +
328 + res := node.RunIPFS("daemon")
329 + assert.Equal(t, 1, res.ExitCode())
330 + })
331 + t.Run("system streams", func(t *testing.T) {
332 + node := harness.NewT(t).NewNode().Init()
333 + node.UpdateConfig(func(cfg *config.Config) {
334 + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
335 + cfg.Swarm.ResourceMgr.Limits.System.Streams = 128
336 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
337 + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
338 + })
339 +
340 + res := node.RunIPFS("daemon")
341 + assert.Equal(t, 1, res.ExitCode())
342 + })
343 + t.Run("system streams inbound", func(t *testing.T) {
344 + node := harness.NewT(t).NewNode().Init()
345 + node.UpdateConfig(func(cfg *config.Config) {
346 + cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
347 + cfg.Swarm.ResourceMgr.Limits.System.StreamsInbound = 128
348 + cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
349 + cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
350 + })
351 +
352 + res := node.RunIPFS("daemon")
353 + assert.Equal(t, 1, res.ExitCode())
354 + })
355 + })
356 +}
357 +
358 +func updateLimitsWithFile(t *testing.T, node *harness.Node, limit string, f func(*rcmgr.ResourceLimits)) {
359 + filename := limit + ".json"
360 + res := node.RunIPFS("swarm", "limit", limit)
361 + limits := unmarshalLimits(t, res.Stdout.Bytes())
362 +
363 + f(limits)
364 +
365 + limitsOut, err := json.Marshal(limits)
366 + require.NoError(t, err)
367 + node.WriteBytes(filename, limitsOut)
368 + res = node.RunIPFS("swarm", "limit", limit, filename)
369 + assert.Equal(t, 0, res.ExitCode())
370 +}
371 +
372 +func unmarshalLimits(t *testing.T, b []byte) *rcmgr.ResourceLimits {
373 + limits := &rcmgr.ResourceLimits{}
374 + err := json.Unmarshal(b, limits)
375 + require.NoError(t, err)
376 + return limits
377 +}
test/sharness/t0139-swarm-rcmgr.sh deleted
-284
@@ -1,284 +0,0 @@
1 -#!/usr/bin/env bash
2 -#
3 -test_description="Test ipfs swarm ResourceMgr config and commands"
4 -
5 -. lib/test-lib.sh
6 -
7 -test_init_ipfs
8 -
9 -test_expect_success 'Disable resource manager' '
10 - ipfs config --bool Swarm.ResourceMgr.Enabled false
11 -'
12 -
13 -# test correct behavior when resource manager is disabled
14 -test_launch_ipfs_daemon
15 -
16 -test_expect_success 'Swarm limit should fail since RM is disabled' '
17 - test_expect_code 1 ipfs swarm limit system 2> actual &&
18 - test_should_contain "missing ResourceMgr" actual
19 -'
20 -
21 -test_expect_success 'Swarm stats should fail since RM is disabled' '
22 - test_expect_code 1 ipfs swarm stats all 2> actual &&
23 - test_should_contain "missing ResourceMgr" actual
24 -'
25 -
26 -test_kill_ipfs_daemon
27 -
28 -test_expect_success 'Enable resource manager' '
29 - ipfs config --bool Swarm.ResourceMgr.Enabled true
30 -'
31 -
32 -# swarm limit|stats should fail in offline mode
33 -
34 -test_expect_success 'disconnected: swarm limit requires running daemon' '
35 - test_expect_code 1 ipfs swarm limit system 2> actual &&
36 - test_should_contain "missing ResourceMgr" actual
37 -'
38 -test_expect_success 'disconnected: swarm stats requires running daemon' '
39 - test_expect_code 1 ipfs swarm stats all 2> actual &&
40 - test_should_contain "missing ResourceMgr" actual
41 -'
42 -
43 -# test sanity scaling
44 -test_expect_success 'set very high connmgr highwater' '
45 - ipfs config --json Swarm.ConnMgr.HighWater 1000
46 -'
47 -
48 -test_launch_ipfs_daemon
49 -
50 -test_expect_success 'conns and streams are above 2000' '
51 - ipfs swarm limit system --enc=json | tee json &&
52 - [ "$(jq -r .ConnsInbound < json)" -ge 2000 ] &&
53 - [ "$(jq -r .StreamsInbound < json)" -ge 2000 ]
54 -'
55 -
56 -test_kill_ipfs_daemon
57 -
58 -test_expect_success 'set previous connmgr highwater' '
59 - ipfs config --json Swarm.ConnMgr.HighWater 96
60 -'
61 -
62 -test_launch_ipfs_daemon
63 -
64 -test_expect_success 'conns and streams are above 800' '
65 - ipfs swarm limit system --enc=json | tee json &&
66 - [ "$(jq -r .ConnsInbound < json)" -ge 800 ] &&
67 - [ "$(jq -r .StreamsInbound < json)" -ge 800 ]
68 -'
69 -
70 -# swarm limit|stats should succeed in online mode by default
71 -# because Resource Manager is opt-out
72 -
73 -# every scope has the same fields, so we only inspect System
74 -test_expect_success 'ResourceMgr enabled: swarm limit' '
75 - ipfs swarm limit system --enc=json | tee json &&
76 - jq -e .Conns < json &&
77 - jq -e .ConnsInbound < json &&
78 - jq -e .ConnsOutbound < json &&
79 - jq -e .FD < json &&
80 - jq -e .Memory < json &&
81 - jq -e .Streams < json &&
82 - jq -e .StreamsInbound < json &&
83 - jq -e .StreamsOutbound < json
84 -'
85 -test_expect_success 'ResourceMgr enabled: swarm limit reset' '
86 - ipfs swarm limit system --reset --enc=json 2> reset &&
87 - ipfs swarm limit system --enc=json 2> actual &&
88 - test_cmp reset actual
89 -'
90 -
91 -test_expect_success 'Swarm stats system with filter should fail' '
92 - test_expect_code 1 ipfs swarm stats system --min-used-limit-perc=99 2> actual &&
93 - test_should_contain "Error: \"min-used-limit-perc\" can only be used when scope is \"all\"" actual
94 -'
95 -
96 -test_expect_success 'ResourceMgr enabled: swarm limit reset on map values' '
97 - ipfs swarm limit peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG --reset --enc=json 2> reset &&
98 - ipfs swarm limit peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG --enc=json 2> actual &&
99 - test_cmp reset actual
100 -'
101 -
102 -test_expect_success 'ResourceMgr enabled: scope is required using reset flag' '
103 - test_expect_code 1 ipfs swarm limit --reset 2> actual &&
104 - test_should_contain "Error: argument \"scope\" is required" actual
105 -'
106 -
107 -test_expect_success 'connected: swarm stats all working properly' '
108 - test_expect_code 0 ipfs swarm stats all
109 -'
110 -
111 -# every scope has the same fields, so we only inspect System
112 -test_expect_success 'ResourceMgr enabled: swarm stats' '
113 - ipfs swarm stats all --enc=json | tee json &&
114 - jq -e .System.Memory < json &&
115 - jq -e .System.FD < json &&
116 - jq -e .System.Conns < json &&
117 - jq -e .System.ConnsInbound < json &&
118 - jq -e .System.ConnsOutbound < json &&
119 - jq -e .System.Streams < json &&
120 - jq -e .System.StreamsInbound < json &&
121 - jq -e .System.StreamsOutbound < json &&
122 - jq -e .Transient.Memory < json
123 -'
124 -
125 -# shut down the daemon, set a limit in the config, and verify that it's applied
126 -test_kill_ipfs_daemon
127 -
128 -test_expect_success "Set system conns limit while daemon is not running" "
129 - ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 99999
130 -"
131 -
132 -test_expect_success "Set an invalid limit, which should result in a failure" "
133 - test_expect_code 1 ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 'asdf' 2> actual &&
134 - test_should_contain 'failed to unmarshal' actual
135 -"
136 -
137 -test_launch_ipfs_daemon
138 -
139 -test_expect_success 'Ensure the new system conns limit is applied' '
140 - ipfs swarm limit system --enc=json | tee json &&
141 - jq -e ".Conns == 99999" < json
142 -'
143 -
144 -test_expect_success 'Set system memory limit while the daemon is running' '
145 - ipfs swarm limit system | jq ".Memory = 99998" > system.json &&
146 - ipfs swarm limit system system.json
147 -'
148 -
149 -test_expect_success 'The new system limits were written to the config' '
150 - jq -e ".Swarm.ResourceMgr.Limits.System.Memory == \"99998\"" < "$IPFS_PATH/config"
151 -'
152 -
153 -test_expect_success 'The new system limits are in the swarm limit output' '
154 - ipfs swarm limit system --enc=json | jq -e ".Memory == \"99998\""
155 -'
156 -
157 -# now test all the other scopes
158 -test_expect_success 'Set limit on transient scope' '
159 - ipfs swarm limit transient | jq ".Memory = 88888" > transient.json &&
160 - ipfs swarm limit transient transient.json &&
161 - jq -e ".Swarm.ResourceMgr.Limits.Transient.Memory == \"88888\"" < "$IPFS_PATH/config" &&
162 - ipfs swarm limit transient --enc=json | tee limits &&
163 - jq -e ".Memory == \"88888\"" < limits
164 -'
165 -
166 -test_expect_success 'Set limit on service scope' '
167 - ipfs swarm limit svc:foo | jq ".Memory = 77777" > service-foo.json &&
168 - ipfs swarm limit svc:foo service-foo.json --enc=json &&
169 - jq -e ".Swarm.ResourceMgr.Limits.Service.foo.Memory == \"77777\"" < "$IPFS_PATH/config" &&
170 - ipfs swarm limit svc:foo --enc=json | tee limits &&
171 - jq -e ".Memory == \"77777\"" < limits
172 -'
173 -
174 -test_expect_success 'Set limit on protocol scope' '
175 - ipfs swarm limit proto:foo | jq ".Memory = 66666" > proto-foo.json &&
176 - ipfs swarm limit proto:foo proto-foo.json --enc=json &&
177 - jq -e ".Swarm.ResourceMgr.Limits.Protocol.foo.Memory == \"66666\"" < "$IPFS_PATH/config" &&
178 - ipfs swarm limit proto:foo --enc=json | tee limits &&
179 - jq -e ".Memory == \"66666\"" < limits
180 -'
181 -
182 -# any valid peer id
183 -PEER_ID=QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN
184 -
185 -test_expect_success 'Set limit on peer scope' '
186 - ipfs swarm limit peer:$PEER_ID | jq ".Memory = 66666" > peer-$PEER_ID.json &&
187 - ipfs swarm limit peer:$PEER_ID peer-$PEER_ID.json --enc=json &&
188 - jq -e ".Swarm.ResourceMgr.Limits.Peer.${PEER_ID}.Memory == \"66666\"" < "$IPFS_PATH/config" &&
189 - ipfs swarm limit peer:$PEER_ID --enc=json | tee limits &&
190 - jq -e ".Memory == \"66666\"" < limits
191 -'
192 -
193 -test_expect_success 'Get limit for peer scope with an invalid peer ID' '
194 - test_expect_code 1 ipfs swarm limit peer:foo 2> actual &&
195 - test_should_contain "invalid peer ID" actual
196 -'
197 -
198 -test_expect_success 'Set limit for peer scope with an invalid peer ID' '
199 - echo "{\"Memory\": 99}" > invalid-peer-id.json &&
200 - test_expect_code 1 ipfs swarm limit peer:foo invalid-peer-id.json 2> actual &&
201 - test_should_contain "invalid peer ID" actual
202 -'
203 -
204 -test_kill_ipfs_daemon
205 -
206 -## Test allowlist
207 -
208 -test_expect_success 'init iptb' '
209 - iptb testbed create -type localipfs -count 3 -init
210 -'
211 -
212 -test_expect_success 'peer ids' '
213 - PEERID_0=$(iptb attr get 0 id) &&
214 - PEERID_1=$(iptb attr get 1 id) &&
215 - PEERID_2=$(iptb attr get 2 id)
216 -'
217 -
218 -#enable resource manager
219 -test_expect_success 'enable RCMGR' '
220 - ipfsi 0 config --bool Swarm.ResourceMgr.Enabled true &&
221 - ipfsi 0 config --json Swarm.ResourceMgr.Allowlist "[\"/ip4/0.0.0.0/ipcidr/0/p2p/$PEERID_2\"]"
222 -'
223 -
224 -test_expect_success 'start nodes' '
225 - iptb start -wait [0-2]
226 -'
227 -
228 -test_expect_success "change system limits on node 0" '
229 - ipfsi 0 swarm limit system | jq ". + {Conns: 0,ConnsInbound: 0, ConnsOutbound: 0}" > system.json &&
230 - ipfsi 0 swarm limit system system.json
231 -'
232 -
233 -test_expect_success "node 0 fails to connect to 1" '
234 - test_expect_code 1 iptb connect 0 1
235 -'
236 -
237 -test_expect_success "node 0 connects to 2 because it's allowlisted" '
238 - iptb connect 0 2
239 -'
240 -
241 -test_expect_success "node 0 fails to ping 1" '
242 - test_expect_code 1 ipfsi 0 ping -n2 -- "$PEERID_1" 2> actual &&
243 - test_should_contain "Error: ping failed" actual
244 -'
245 -
246 -test_expect_success "node 1 can ping 2" '
247 - ipfsi 0 ping -n2 -- "$PEERID_2"
248 -'
249 -
250 -test_expect_success 'stop iptb' '
251 - iptb stop 0 &&
252 - iptb stop 1 &&
253 - iptb stop 2
254 -'
255 -
256 -## Test daemon refuse to start if connmgr.highwater < ressources inbound
257 -
258 -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Conns <= Swarm.ConnMgr.HighWater" '
259 - ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 128 &&
260 - ipfs config --json Swarm.ConnMgr.HighWater 128 &&
261 - ipfs config --json Swarm.ConnMgr.LowWater 64 &&
262 - test_expect_code 1 ipfs daemon &&
263 - ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 256
264 -'
265 -
266 -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.ConnsInbound <= Swarm.ConnMgr.HighWater" '
267 - ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 128 &&
268 - test_expect_code 1 ipfs daemon &&
269 - ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 256
270 -'
271 -
272 -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.Streams <= Swarm.ConnMgr.HighWater" '
273 - ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 128 &&
274 - test_expect_code 1 ipfs daemon &&
275 - ipfs config --json Swarm.ResourceMgr.Limits.System.Streams 256
276 -'
277 -
278 -test_expect_success "node refuse to start if Swarm.ResourceMgr.Limits.System.StreamsInbound <= Swarm.ConnMgr.HighWater" '
279 - ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 128 &&
280 - test_expect_code 1 ipfs daemon &&
281 - ipfs config --json Swarm.ResourceMgr.Limits.System.StreamsInbound 256
282 -'
283 -
284 -test_done