@cryptotaxi247 / kubo / commits / c8442bcf1

feat: port pins CLI test

Gus Eggert committed Dec 12, 2022 at 09:16 UTC c8442bcf191419b7b22ef82775fd97fe991e2fc9
6 files changed +282 -251
test/cli/pins_test.go new
+214
@@ -0,0 +1,214 @@
1 +package cli
2 +
3 +import (
4 + "fmt"
5 + "strings"
6 + "testing"
7 +
8 + "github.com/ipfs/go-cid"
9 + "github.com/ipfs/kubo/test/cli/harness"
10 + . "github.com/ipfs/kubo/test/cli/testutils"
11 + "github.com/stretchr/testify/assert"
12 + "github.com/stretchr/testify/require"
13 +)
14 +
15 +type testPinsArgs struct {
16 + runDaemon bool
17 + pinArg string
18 + lsArg string
19 + baseArg string
20 +}
21 +
22 +func testPins(t *testing.T, args testPinsArgs) {
23 + t.Run(fmt.Sprintf("test pins with args=%+v", args), func(t *testing.T) {
24 + t.Parallel()
25 + node := harness.NewT(t).NewNode().Init()
26 + if args.runDaemon {
27 + node.StartDaemon("--offline")
28 + }
29 +
30 + strs := []string{"a", "b", "c", "d", "e", "f", "g"}
31 + dataToCid := map[string]string{}
32 + cids := []string{}
33 +
34 + ipfsAdd := func(t *testing.T, content string) string {
35 + cidStr := node.IPFSAddStr(content, StrCat(args.baseArg, "--pin=false")...)
36 +
37 + _, err := cid.Decode(cidStr)
38 + require.NoError(t, err)
39 + dataToCid[content] = cidStr
40 + cids = append(cids, cidStr)
41 + return cidStr
42 + }
43 +
44 + ipfsPinAdd := func(cids []string) []string {
45 + input := strings.Join(cids, "\n")
46 + return node.PipeStrToIPFS(input, StrCat("pin", "add", args.pinArg, args.baseArg)...).Stdout.Lines()
47 + }
48 +
49 + ipfsPinLS := func() string {
50 + return node.IPFS(StrCat("pin", "ls", args.lsArg, args.baseArg)...).Stdout.Trimmed()
51 + }
52 +
53 + for _, s := range strs {
54 + ipfsAdd(t, s)
55 + }
56 +
57 + // these subtests run sequentially since they depend on state
58 +
59 + t.Run("check output of pin command", func(t *testing.T) {
60 + resLines := ipfsPinAdd(cids)
61 +
62 + for i, s := range resLines {
63 + assert.Equal(t,
64 + fmt.Sprintf("pinned %s recursively", cids[i]),
65 + s,
66 + )
67 + }
68 + })
69 +
70 + t.Run("pin verify should succeed", func(t *testing.T) {
71 + node.IPFS("pin", "verify")
72 + })
73 +
74 + t.Run("'pin verify --verbose' should include all the cids", func(t *testing.T) {
75 + verboseVerifyOut := node.IPFS(StrCat("pin", "verify", "--verbose", args.baseArg)...).Stdout.String()
76 + for _, cid := range cids {
77 + assert.Contains(t, verboseVerifyOut, fmt.Sprintf("%s ok", cid))
78 + }
79 +
80 + })
81 + t.Run("ls output should contain the cids", func(t *testing.T) {
82 + lsOut := ipfsPinLS()
83 + for _, cid := range cids {
84 + assert.Contains(t, lsOut, cid)
85 + }
86 + })
87 +
88 + t.Run("check 'pin ls hash' output", func(t *testing.T) {
89 + lsHashOut := node.IPFS(StrCat("pin", "ls", args.lsArg, args.baseArg, dataToCid["b"])...)
90 + lsHashOutStr := lsHashOut.Stdout.String()
91 + assert.Equal(t, fmt.Sprintf("%s recursive\n", dataToCid["b"]), lsHashOutStr)
92 + })
93 +
94 + t.Run("unpinning works", func(t *testing.T) {
95 + node.PipeStrToIPFS(strings.Join(cids, "\n"), "pin", "rm")
96 + })
97 +
98 + t.Run("test pin update", func(t *testing.T) {
99 + cidA := dataToCid["a"]
100 + cidB := dataToCid["b"]
101 +
102 + ipfsPinAdd([]string{cidA})
103 + beforeUpdate := ipfsPinLS()
104 +
105 + assert.Contains(t, beforeUpdate, cidA)
106 + assert.NotContains(t, beforeUpdate, cidB)
107 +
108 + node.IPFS("pin", "update", "--unpin=true", cidA, cidB)
109 + afterUpdate := ipfsPinLS()
110 +
111 + assert.NotContains(t, afterUpdate, cidA)
112 + assert.Contains(t, afterUpdate, cidB)
113 +
114 + node.IPFS("pin", "update", "--unpin=true", cidB, cidB)
115 + afterIdempotentUpdate := ipfsPinLS()
116 +
117 + assert.Contains(t, afterIdempotentUpdate, cidB)
118 +
119 + node.IPFS("pin", "rm", cidB)
120 + })
121 + })
122 +}
123 +
124 +func testPinsErrorReporting(t *testing.T, args testPinsArgs) {
125 + t.Run(fmt.Sprintf("test pins error reporting with args=%+v", args), func(t *testing.T) {
126 + t.Parallel()
127 + node := harness.NewT(t).NewNode().Init()
128 + if args.runDaemon {
129 + node.StartDaemon("--offline")
130 + }
131 + randomCID := "Qme8uX5n9hn15pw9p6WcVKoziyyC9LXv4LEgvsmKMULjnV"
132 + res := node.RunIPFS(StrCat("pin", "add", args.pinArg, randomCID)...)
133 + assert.NotEqual(t, 0, res.ExitErr.ExitCode())
134 + assert.Contains(t, res.Stderr.String(), "ipld: could not find")
135 + })
136 +}
137 +
138 +func testPinDAG(t *testing.T, args testPinsArgs) {
139 + t.Run(fmt.Sprintf("test pin DAG with args=%+v", args), func(t *testing.T) {
140 + t.Parallel()
141 + h := harness.NewT(t)
142 + node := h.NewNode().Init()
143 + if args.runDaemon {
144 + node.StartDaemon("--offline")
145 + }
146 + bytes := RandomBytes(1 << 20) // 1 MiB
147 + tmpFile := h.WriteToTemp(string(bytes))
148 + cid := node.IPFS(StrCat("add", args.pinArg, "--pin=false", "-q", tmpFile)...).Stdout.Trimmed()
149 +
150 + node.IPFS("pin", "add", "--recursive=true", cid)
151 + node.IPFS("pin", "rm", cid)
152 +
153 + // remove part of the DAG
154 + part := node.IPFS("refs", cid).Stdout.Lines()[0]
155 + node.IPFS("block", "rm", part)
156 +
157 + res := node.RunIPFS("pin", "add", "--recursive=true", cid)
158 + assert.NotEqual(t, 0, res)
159 + assert.Contains(t, res.Stderr.String(), "ipld: could not find")
160 + })
161 +}
162 +
163 +func testPinProgress(t *testing.T, args testPinsArgs) {
164 + t.Run(fmt.Sprintf("test pin progress with args=%+v", args), func(t *testing.T) {
165 + t.Parallel()
166 + h := harness.NewT(t)
167 + node := h.NewNode().Init()
168 +
169 + if args.runDaemon {
170 + node.StartDaemon("--offline")
171 + }
172 +
173 + bytes := RandomBytes(1 << 20) // 1 MiB
174 + tmpFile := h.WriteToTemp(string(bytes))
175 + cid := node.IPFS(StrCat("add", args.pinArg, "--pin=false", "-q", tmpFile)...).Stdout.Trimmed()
176 +
177 + res := node.RunIPFS("pin", "add", "--progress", cid)
178 + node.Runner.AssertNoError(res)
179 +
180 + assert.Contains(t, res.Stderr.String(), " 5 nodes")
181 + })
182 +}
183 +
184 +func TestPins(t *testing.T) {
185 + t.Parallel()
186 + t.Run("test pinning without daemon running", func(t *testing.T) {
187 + t.Parallel()
188 + testPinsErrorReporting(t, testPinsArgs{})
189 + testPinsErrorReporting(t, testPinsArgs{pinArg: "--progress"})
190 + testPinDAG(t, testPinsArgs{})
191 + testPinDAG(t, testPinsArgs{pinArg: "--raw-leaves"})
192 + testPinProgress(t, testPinsArgs{})
193 + testPins(t, testPinsArgs{})
194 + testPins(t, testPinsArgs{pinArg: "--progress"})
195 + testPins(t, testPinsArgs{pinArg: "--progress", lsArg: "--stream"})
196 + testPins(t, testPinsArgs{baseArg: "--cid-base=base32"})
197 + testPins(t, testPinsArgs{lsArg: "--stream", baseArg: "--cid-base=base32"})
198 +
199 + })
200 +
201 + t.Run("test pinning with daemon running without network", func(t *testing.T) {
202 + t.Parallel()
203 + testPinsErrorReporting(t, testPinsArgs{runDaemon: true})
204 + testPinsErrorReporting(t, testPinsArgs{runDaemon: true, pinArg: "--progress"})
205 + testPinDAG(t, testPinsArgs{runDaemon: true})
206 + testPinDAG(t, testPinsArgs{runDaemon: true, pinArg: "--raw-leaves"})
207 + testPinProgress(t, testPinsArgs{runDaemon: true})
208 + testPins(t, testPinsArgs{runDaemon: true})
209 + testPins(t, testPinsArgs{runDaemon: true, pinArg: "--progress"})
210 + testPins(t, testPinsArgs{runDaemon: true, pinArg: "--progress", lsArg: "--stream"})
211 + testPins(t, testPinsArgs{runDaemon: true, baseArg: "--cid-base=base32"})
212 + testPins(t, testPinsArgs{runDaemon: true, lsArg: "--stream", baseArg: "--cid-base=base32"})
213 + })
214 +}
test/cli/testutils/files.go new
+37
@@ -0,0 +1,37 @@
1 +package testutils
2 +
3 +import (
4 + "log"
5 + "os"
6 + "path/filepath"
7 +)
8 +
9 +func MustOpen(name string) *os.File {
10 + f, err := os.Open(name)
11 + if err != nil {
12 + log.Panicf("opening %s: %s", name, err)
13 + }
14 + return f
15 +}
16 +
17 +// Searches for a file in a dir, then the parent dir, etc.
18 +// If the file is not found, an empty string is returned.
19 +func FindUp(name, dir string) string {
20 + curDir := dir
21 + for {
22 + entries, err := os.ReadDir(curDir)
23 + if err != nil {
24 + panic(err)
25 + }
26 + for _, e := range entries {
27 + if name == e.Name() {
28 + return filepath.Join(curDir, name)
29 + }
30 + }
31 + newDir := filepath.Dir(curDir)
32 + if newDir == curDir {
33 + return ""
34 + }
35 + curDir = newDir
36 + }
37 +}
test/cli/testutils/json.go new
+13
@@ -0,0 +1,13 @@
1 +package testutils
2 +
3 +import "encoding/json"
4 +
5 +type JSONObj map[string]interface{}
6 +
7 +func ToJSONStr(m JSONObj) string {
8 + b, err := json.Marshal(m)
9 + if err != nil {
10 + panic(err)
11 + }
12 + return string(b)
13 +}
test/cli/testutils/random.go new
+12
@@ -0,0 +1,12 @@
1 +package testutils
2 +
3 +import "crypto/rand"
4 +
5 +func RandomBytes(n int) []byte {
6 + bytes := make([]byte, n)
7 + _, err := rand.Read(bytes)
8 + if err != nil {
9 + panic(err)
10 + }
11 + return bytes
12 +}
test/cli/testutils/strings.go renamed
+6 -50
@@ -2,31 +2,10 @@ package testutils
2
3 import (
4 "bufio"
5 - "encoding/json"
5 "fmt"
7 - "log"
8 - "os"
9 - "path/filepath"
6 "strings"
7 )
8
13 -func SplitLines(s string) []string {
14 - var lines []string
15 - scanner := bufio.NewScanner(strings.NewReader(s))
16 - for scanner.Scan() {
17 - lines = append(lines, scanner.Text())
18 - }
19 - return lines
20 -}
21 -
22 -func MustOpen(name string) *os.File {
23 - f, err := os.Open(name)
24 - if err != nil {
25 - log.Panicf("opening %s: %s", name, err)
26 - }
27 - return f
28 -}
29 -
9 // StrCat takes a bunch of strings or string slices
10 // and concats them all together into one string slice.
11 // If an arg is not one of those types, this panics.
@@ -64,34 +43,11 @@ func PreviewStr(s string) string {
43 return s[0:previewLength] + suffix
44 }
45
67 -type JSONObj map[string]interface{}
68 -
69 -func ToJSONStr(m JSONObj) string {
70 - b, err := json.Marshal(m)
71 - if err != nil {
72 - panic(err)
73 - }
74 - return string(b)
75 -}
76 -
77 -// Searches for a file in a dir, then the parent dir, etc.
78 -// If the file is not found, an empty string is returned.
79 -func FindUp(name, dir string) string {
80 - curDir := dir
81 - for {
82 - entries, err := os.ReadDir(curDir)
83 - if err != nil {
84 - panic(err)
85 - }
86 - for _, e := range entries {
87 - if name == e.Name() {
88 - return filepath.Join(curDir, name)
89 - }
90 - }
91 - newDir := filepath.Dir(curDir)
92 - if newDir == curDir {
93 - return ""
94 - }
95 - curDir = newDir
46 +func SplitLines(s string) []string {
47 + var lines []string
48 + scanner := bufio.NewScanner(strings.NewReader(s))
49 + for scanner.Scan() {
50 + lines = append(lines, scanner.Text())
51 }
52 + return lines
53 }
test/sharness/t0085-pins.sh deleted
-201
@@ -1,201 +0,0 @@
1 -#!/usr/bin/env bash
2 -#
3 -# Copyright (c) 2016 Jeromy Johnson
4 -# MIT Licensed; see the LICENSE file in this repository.
5 -#
6 -
7 -test_description="Test ipfs pinning operations"
8 -
9 -. lib/test-lib.sh
10 -
11 -
12 -test_pins() {
13 - PIN_ARGS="$1"
14 - LS_ARGS="$2"
15 - BASE=$3
16 - if [ -n "$BASE" ]; then
17 - BASE_ARGS="--cid-base=$BASE"
18 - fi
19 -
20 - test_expect_success "create some hashes $BASE" '
21 - HASH_A=$(echo "A" | ipfs add $BASE_ARGS -q --pin=false) &&
22 - HASH_B=$(echo "B" | ipfs add $BASE_ARGS -q --pin=false) &&
23 - HASH_C=$(echo "C" | ipfs add $BASE_ARGS -q --pin=false) &&
24 - HASH_D=$(echo "D" | ipfs add $BASE_ARGS -q --pin=false) &&
25 - HASH_E=$(echo "E" | ipfs add $BASE_ARGS -q --pin=false) &&
26 - HASH_F=$(echo "F" | ipfs add $BASE_ARGS -q --pin=false) &&
27 - HASH_G=$(echo "G" | ipfs add $BASE_ARGS -q --pin=false)
28 - '
29 -
30 - test_expect_success "put all those hashes in a file" '
31 - echo $HASH_A > hashes &&
32 - echo $HASH_B >> hashes &&
33 - echo $HASH_C >> hashes &&
34 - echo $HASH_D >> hashes &&
35 - echo $HASH_E >> hashes &&
36 - echo $HASH_F >> hashes &&
37 - echo $HASH_G >> hashes
38 - '
39 -
40 - if [ -n "$BASE" ]; then
41 - test_expect_success "make sure hashes are in $BASE" '
42 - cat hashes | xargs cid-fmt %b | sort -u > actual
43 - echo base32 > expected
44 - test_cmp expected actual
45 - '
46 - fi
47 -
48 - test_expect_success "'ipfs pin add $PIN_ARGS' via stdin" '
49 - cat hashes | ipfs pin add $PIN_ARGS $BASE_ARGS | tee actual
50 - '
51 -
52 - test_expect_success "'ipfs pin add $PIN_ARGS' output looks good" '
53 - sed -e "s/^/pinned /; s/$/ recursively/" hashes > expected &&
54 - test_cmp expected actual
55 - '
56 -
57 - test_expect_success "see if verify works" '
58 - ipfs pin verify
59 - '
60 -
61 - test_expect_success "see if verify --verbose $BASE_ARGS works" '
62 - ipfs pin verify --verbose $BASE_ARGS > verify_out &&
63 - test $(cat verify_out | wc -l) -ge 7 &&
64 - test_should_contain "$HASH_A ok" verify_out &&
65 - test_should_contain "$HASH_B ok" verify_out &&
66 - test_should_contain "$HASH_C ok" verify_out &&
67 - test_should_contain "$HASH_D ok" verify_out &&
68 - test_should_contain "$HASH_E ok" verify_out &&
69 - test_should_contain "$HASH_F ok" verify_out &&
70 - test_should_contain "$HASH_G ok" verify_out
71 - '
72 -
73 - test_expect_success "ipfs pin ls $LS_ARGS $BASE_ARGS works" '
74 - ipfs pin ls $LS_ARGS $BASE_ARGS > ls_out &&
75 - test_should_contain "$HASH_A" ls_out &&
76 - test_should_contain "$HASH_B" ls_out &&
77 - test_should_contain "$HASH_C" ls_out &&
78 - test_should_contain "$HASH_D" ls_out &&
79 - test_should_contain "$HASH_E" ls_out &&
80 - test_should_contain "$HASH_F" ls_out &&
81 - test_should_contain "$HASH_G" ls_out
82 - '
83 -
84 - test_expect_success "test pin ls $LS_ARGS $BASE_ARGS hash" '
85 - echo $HASH_B | test_must_fail grep /ipfs && # just to be sure
86 - ipfs pin ls $LS_ARGS $BASE_ARGS $HASH_B > ls_hash_out &&
87 - echo "$HASH_B recursive" > ls_hash_exp &&
88 - test_cmp ls_hash_exp ls_hash_out
89 - '
90 -
91 - test_expect_success "unpin those hashes" '
92 - cat hashes | ipfs pin rm
93 - '
94 -
95 - test_expect_success "test pin update" '
96 - ipfs pin add "$HASH_A" &&
97 - ipfs pin ls $LS_ARGS $BASE_ARGS | tee before_update &&
98 - test_should_contain "$HASH_A" before_update &&
99 - test_must_fail grep -q "$HASH_B" before_update &&
100 - ipfs pin update --unpin=true "$HASH_A" "$HASH_B" &&
101 - ipfs pin ls $LS_ARGS $BASE_ARGS > after_update &&
102 - test_must_fail grep -q "$HASH_A" after_update &&
103 - test_should_contain "$HASH_B" after_update &&
104 - ipfs pin update --unpin=true "$HASH_B" "$HASH_B" &&
105 - ipfs pin ls $LS_ARGS $BASE_ARGS > after_idempotent_update &&
106 - test_should_contain "$HASH_B" after_idempotent_update &&
107 - ipfs pin rm "$HASH_B"
108 - '
109 -}
110 -
111 -RANDOM_HASH=Qme8uX5n9hn15pw9p6WcVKoziyyC9LXv4LEgvsmKMULjnV
112 -
113 -test_pins_error_reporting() {
114 - PIN_ARGS=$1
115 -
116 - test_expect_success "'ipfs pin add $PIN_ARGS' on non-existent hash should fail" '
117 - test_must_fail ipfs pin add $PIN_ARGS $RANDOM_HASH 2> err &&
118 - grep -q "ipld: could not find" err
119 - '
120 -}
121 -
122 -test_pin_dag_init() {
123 - PIN_ARGS=$1
124 -
125 - test_expect_success "'ipfs add $PIN_ARGS --pin=false' 1MB file" '
126 - random 1048576 56 > afile &&
127 - HASH=`ipfs add $PIN_ARGS --pin=false -q afile`
128 - '
129 -}
130 -
131 -test_pin_dag() {
132 - test_pin_dag_init $1
133 -
134 - test_expect_success "'ipfs pin add --progress' file" '
135 - ipfs pin add --recursive=true $HASH
136 - '
137 -
138 - test_expect_success "'ipfs pin rm' file" '
139 - ipfs pin rm $HASH
140 - '
141 -
142 - test_expect_success "remove part of the dag" '
143 - PART=`ipfs refs $HASH | head -1` &&
144 - ipfs block rm $PART
145 - '
146 -
147 - test_expect_success "pin file, should fail" '
148 - test_must_fail ipfs pin add --recursive=true $HASH 2> err &&
149 - cat err &&
150 - grep -q "ipld: could not find" err
151 - '
152 -}
153 -
154 -test_pin_progress() {
155 - test_pin_dag_init
156 -
157 - test_expect_success "'ipfs pin add --progress' file" '
158 - ipfs pin add --progress $HASH 2> err
159 - '
160 -
161 - test_expect_success "pin progress reported correctly" '
162 - cat err
163 - grep -q " 5 nodes" err
164 - '
165 -}
166 -
167 -test_init_ipfs
168 -
169 -test_pins '' '' ''
170 -test_pins --progress '' ''
171 -test_pins --progress --stream ''
172 -test_pins '' '' base32
173 -test_pins '' --stream base32
174 -
175 -test_pins_error_reporting
176 -test_pins_error_reporting --progress
177 -
178 -test_pin_dag
179 -test_pin_dag --raw-leaves
180 -
181 -test_pin_progress
182 -
183 -test_launch_ipfs_daemon_without_network
184 -
185 -test_pins '' '' ''
186 -test_pins --progress '' ''
187 -test_pins --progress --stream ''
188 -test_pins '' '' base32
189 -test_pins '' --stream base32
190 -
191 -test_pins_error_reporting
192 -test_pins_error_reporting --progress
193 -
194 -test_pin_dag
195 -test_pin_dag --raw-leaves
196 -
197 -test_pin_progress
198 -
199 -test_kill_ipfs_daemon
200 -
201 -test_done