feat: port pins CLI test
Gus Eggert committed
Dec 12, 2022 at 09:16 UTC
430a65ad5f78dc2aed0f54946b2c5922fa4b1ee1
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