master
sh 513 lines 20.6 KB
Raw
1 #!/usr/bin/env bash
2
3 test_description="Test storing and retrieving mode and mtime"
4
5 . lib/test-lib.sh
6
7 test_init_ipfs
8
9 test_expect_success "set Import defaults to ensure deterministic cids for mod and mtime tests" '
10 ipfs config --json Import.CidVersion 0 &&
11 ipfs config Import.HashFunction sha2-256 &&
12 ipfs config Import.UnixFSChunker size-262144
13 '
14
15 HASH_NO_PRESERVE=QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH
16
17 PRESERVE_MTIME=1604320482
18 PRESERVE_MODE="0640"
19 HASH_PRESERVE_MODE=QmQLgxypSNGNFTuUPGCecq6dDEjb6hNB5xSyVmP3cEuNtq
20 HASH_PRESERVE_MTIME=QmQ6kErEW8kztQFV8vbwNU8E4dmtGsYpRiboiLxUEwibvj
21 HASH_PRESERVE_LINK_MTIME=QmbJwotgtr84JxcnjpwJ86uZiyMoxbZuNH4YrdJMypkYaB
22 HASH_PRESERVE_MODE_AND_MTIME=QmYkvboLsvLFcSYmqVJRxvBdYRQLroLv9kELf3LRiCqBri
23
24 CUSTOM_MTIME=1603539720
25 CUSTOM_MTIME_NSECS=54321
26 CUSTOM_MODE="0764"
27 HASH_CUSTOM_MODE=QmchD3BN8TQ3RW6jPLxSaNkqvfuj7syKhzTRmL4EpyY1Nz
28 HASH_CUSTOM_MTIME=QmT3aY4avDcYXCWpU8CJzqUkW7YEuEsx36S8cTNoLcuK1B
29 HASH_CUSTOM_MTIME_NSECS=QmaKH8H5rXBUBCX4vdxi7ktGQEL7wejV7L9rX2qpZjwncz
30 HASH_CUSTOM_MODE_AND_MTIME=QmUkxrtBA8tPjwCYz1HrsoRfDz6NgKut3asVeHVQNH4C8L
31 HASH_CUSTOM_LINK_MTIME=QmV1Uot2gy4bhY9yvYiZxhhchhyYC6MKKoGV1XtWNmpCLe
32 HASH_CUSTOM_LINK_MTIME_NSECS=QmPHYCxYvvHj6VxiPNJ3kXxcPsnJLDYUJqsDJWjvytmrmY
33
34 mk_name() {
35 tr -dc '[:alnum:]'</dev/urandom|head -c 16
36 }
37
38 mk_file() {
39 mktemp -p "$SHARNESS_TRASH_DIRECTORY" "mk_file_${1}_XXXXXX"
40 }
41
42 mk_dir() {
43 mktemp -d -p "$SHARNESS_TRASH_DIRECTORY" "mk_dir_${1}_XXXXXX"
44 }
45
46 # force umask for deterministic mode on files created via touch
47 # (https://github.com/orgs/community/discussions/40876, https://github.com/ipfs/kubo/pull/10478/#discussion_r1717515514)
48 umask 022
49
50 FIXTURESDIR="$(mk_dir fixtures)"
51
52 test_file() {
53 local TESTFILE="$FIXTURESDIR/test$1.txt"
54 local TESTLINK="$FIXTURESDIR/linkfile$1"
55
56 touch "$TESTFILE"
57 ln -s nothing "$TESTLINK"
58
59 test_expect_success "feature on file has no effect when not used [$1]" '
60 touch "$TESTFILE" &&
61 HASH=$(ipfs add -q "$TESTFILE") &&
62 test "$HASH_NO_PRESERVE" = "$HASH"
63 '
64
65 test_expect_success "can preserve file mode [$1]" '
66 touch "$TESTFILE" &&
67 chmod $PRESERVE_MODE "$TESTFILE" &&
68 HASH=$(ipfs add -q --preserve-mode "$TESTFILE") &&
69 test "$HASH_PRESERVE_MODE" = "$HASH"
70 '
71
72 test_expect_success "can preserve file modification time [$1]" '
73 touch -m -d @$PRESERVE_MTIME "$TESTFILE" &&
74 HASH=$(ipfs add -q --preserve-mtime "$TESTFILE") &&
75 test "$HASH_PRESERVE_MTIME" = "$HASH"
76 '
77
78 test_expect_success "can preserve file mode and modification time [$1]" '
79 touch -m -d @$PRESERVE_MTIME "$TESTFILE" &&
80 chmod $PRESERVE_MODE "$TESTFILE" &&
81 HASH=$(ipfs add -q --preserve-mode --preserve-mtime "$TESTFILE") &&
82 test "$HASH_PRESERVE_MODE_AND_MTIME" = "$HASH"
83 '
84
85 test_expect_success "can preserve symlink modification time [$1]" '
86 touch -h -m -d @$PRESERVE_MTIME "$TESTLINK" &&
87 HASH=$(ipfs add -q --preserve-mtime "$TESTLINK") &&
88 test "$HASH_PRESERVE_LINK_MTIME" = "$HASH"
89 '
90
91 test_expect_success "can set file mode [$1]" '
92 touch "$TESTFILE" &&
93 chmod 0600 "$TESTFILE" &&
94 HASH=$(ipfs add -q --mode=$CUSTOM_MODE "$TESTFILE") &&
95 test "$HASH_CUSTOM_MODE" = "$HASH"
96 '
97
98 test_expect_success "can set file modification time [$1]" '
99 touch -m -t 202011021234.42 "$TESTFILE" &&
100 HASH=$(ipfs add -q --mtime=$CUSTOM_MTIME "$TESTFILE") &&
101 test "$HASH_CUSTOM_MTIME" = "$HASH"
102 '
103
104 test_expect_success "can set file modification time nanoseconds [$1]" '
105 touch -m -t 202011021234.42 "$TESTFILE" &&
106 HASH=$(ipfs add -q --mtime=$CUSTOM_MTIME --mtime-nsecs=$CUSTOM_MTIME_NSECS "$TESTFILE") &&
107 test "$HASH_CUSTOM_MTIME_NSECS" = "$HASH"
108 '
109
110 test_expect_success "can set file mode and modification time [$1]" '
111 touch -m -t 202011021234.42 "$TESTFILE" &&
112 chmod 0600 "$TESTFILE" &&
113 HASH=$(ipfs add -q --mode=$CUSTOM_MODE --mtime=$CUSTOM_MTIME --mtime-nsecs=$CUSTOM_MTIME_NSECS "$TESTFILE") &&
114 test "$HASH_CUSTOM_MODE_AND_MTIME" = "$HASH"
115 '
116
117 test_expect_success "can set symlink modification time [$1]" '
118 touch -h -m -t 202011021234.42 "$TESTLINK" &&
119 HASH=$(ipfs add -q --mtime=$CUSTOM_MTIME "$TESTLINK") &&
120 test "$HASH_CUSTOM_LINK_MTIME" = "$HASH"
121 '
122
123 test_expect_success "cannot set mode on symbolic link" '
124 HASH=$(ipfs add -q --mtime=$CUSTOM_MTIME --mode=$CUSTOM_MODE "$TESTLINK") &&
125 ACTUAL=$(ipfs files stat --format="<mode>" /ipfs/$HASH) &&
126 test "$ACTUAL" = "lrwxrwxrwx"
127 '
128
129
130 test_expect_success "can set symlink modification time nanoseconds [$1]" '
131 touch -h -m -t 202011021234.42 "$TESTLINK" &&
132 HASH=$(ipfs add -q --mtime=$CUSTOM_MTIME --mtime-nsecs=$CUSTOM_MTIME_NSECS "$TESTLINK") &&
133 test "$HASH_CUSTOM_LINK_MTIME_NSECS" = "$HASH"
134 '
135
136 test_expect_success "can get preserved mode and modification time [$1]" '
137 OUTFILE="$(mk_file $HASH_PRESERVE_MODE_AND_MTIME)" &&
138 ipfs get -o "$OUTFILE" $HASH_PRESERVE_MODE_AND_MTIME &&
139 test "$PRESERVE_MODE:$PRESERVE_MTIME" = "$(stat -c "0%a:%Y" "$OUTFILE")"
140 '
141
142 test_expect_success "can get custom mode and modification time [$1]" '
143 OUTFILE="$(mk_file $HASH_CUSTOM_MODE_AND_MTIME)" &&
144 ipfs get -o "$OUTFILE" $HASH_CUSTOM_MODE_AND_MTIME &&
145 TIMESTAMP=$(date +%s%N --date="$(stat -c "%y" "$OUTFILE")") &&
146 MODETIME=$(stat -c "0%a:$TIMESTAMP" "$OUTFILE") &&
147 printf -v EXPECTED "$CUSTOM_MODE:$CUSTOM_MTIME%09d" $CUSTOM_MTIME_NSECS &&
148 test "$EXPECTED" = "$MODETIME"
149 '
150
151 test_expect_success "can get custom symlink modification time [$1]" '
152 OUTFILE="$(mk_file $HASH_CUSTOM_LINK_MTIME_NSECS)" &&
153 ipfs get -o "$OUTFILE" $HASH_CUSTOM_LINK_MTIME_NSECS &&
154 TIMESTAMP=$(date +%s%N --date="$(stat -c "%y" "$OUTFILE")") &&
155 printf -v EXPECTED "$CUSTOM_MTIME%09d" $CUSTOM_MTIME_NSECS &&
156 test "$EXPECTED" = "$TIMESTAMP"
157 '
158
159 test_expect_success "can change file mode [$1]" '
160 NAME=$(mk_name) &&
161 HASH=$(echo testfile | ipfs add -q --mode=0600) &&
162 OUTFILE=$(mk_file "${NAME}") &&
163 ipfs files cp "/ipfs/$HASH" /$NAME &&
164 ipfs files chmod 444 /$NAME &&
165 HASH2=$(ipfs files stat /$NAME|head -1) &&
166 ipfs get -o "$OUTFILE" $HASH2 &&
167 test $(stat -c "%a" "$OUTFILE") = 444
168 '
169
170 # special case, because storing mode requires dag-pb envelope
171 # and when dealing with CIDv1 we can have 'raw' block instead of 'dag-pb'
172 # so it needs to be converted before adding attribute
173 test_expect_success "can add file mode to cidv1 raw block [$1]" '
174 NAME=$(mk_name) &&
175 HASH=$(date | ipfs add -q --cid-version 1 --raw-leaves=true) &&
176 OUTFILE=$(mk_file "${NAME}") &&
177 ipfs files cp "/ipfs/$HASH" /$NAME &&
178 ipfs files chmod 445 /$NAME &&
179 HASH2=$(ipfs files stat /$NAME|head -1) &&
180 ipfs get -o "$OUTFILE" $HASH2 &&
181 test $(stat -c "%a" "$OUTFILE") = 445
182 '
183
184 test_expect_success "can change file modification time [$1]" '
185 NAME=$(mk_name) &&
186 OUTFILE="$(mk_file "$NAME")" &&
187 NOW=$(date +%s) &&
188 HASH=$(echo testfile | ipfs add -q --mtime=$NOW) &&
189 ipfs files cp "/ipfs/$HASH" /$NAME &&
190 sleep 1 &&
191 ipfs files touch /$NAME &&
192 HASH=$(ipfs files stat /$NAME|head -1) &&
193 ipfs get -o "$OUTFILE" "$HASH" &&
194 test $(stat -c "%Y" "$OUTFILE") -gt $NOW
195 '
196
197 # special case, because storing mtime requires dag-pb envelope
198 # and when dealing with CIDv1 we can have 'raw' block instead of 'dag-pb'
199 # so it needs to be converted to dag-pb before adding attribute
200 test_expect_success "can add file modification time to cidv1 raw block [$1]" '
201 NAME=$(mk_name) &&
202 OUTFILE="$(mk_file "$NAME")" &&
203 EXPECTED="$CUSTOM_MTIME" &&
204 HASH=$(date | ipfs add -q --cid-version 1 --raw-leaves=true) &&
205 ipfs files cp "/ipfs/$HASH" /$NAME &&
206 ipfs files touch --mtime=$EXPECTED /$NAME &&
207 test $(ipfs files stat --format="<mtime-secs>" "/$NAME") -eq $EXPECTED &&
208 HASH=$(ipfs files stat /$NAME|head -1) &&
209 ipfs get -o "$OUTFILE" "$HASH" &&
210 test $(stat -c "%Y" "$OUTFILE") -eq $EXPECTED
211 '
212
213 test_expect_success "can change file modification time nanoseconds [$1]" '
214 NAME=$(mk_name) &&
215 echo test|ipfs files write --create /$NAME &&
216 EXPECTED=$(date --date="yesterday" +%s) &&
217 ipfs files touch --mtime=$EXPECTED --mtime-nsecs=55567 /$NAME &&
218 test $(ipfs files stat --format="<mtime-secs>" /$NAME) -eq $EXPECTED &&
219 test $(ipfs files stat --format="<mtime-nsecs>" /$NAME) -eq 55567
220 '
221
222 ## TODO: update these tests if/when symbolic links are fully supported in go-mfs
223 test_expect_success "can change symlink modification time [$1]" '
224 NAME=$(mk_name) &&
225 EXPECTED=$(date +%s) &&
226 ipfs files cp "/ipfs/$HASH_PRESERVE_LINK_MTIME" "/$NAME" ||
227 ipfs files touch --mtime=$EXPECTED "/$NAME" &&
228 test $(ipfs files stat --format="<mtime-secs>" "/$NAME") -eq $EXPECTED
229 '
230
231 test_expect_success "can change symlink modification time nanoseconds [$1]" '
232 NAME=$(mk_name) &&
233 EXPECTED=$(date +%s) &&
234 ipfs files cp "/ipfs/$HASH_PRESERVE_LINK_MTIME" "/$NAME" ||
235 ipfs files touch --mtime=$EXPECTED --mtime-nsecs=938475 "/$NAME" &&
236 test $(ipfs files stat --format="<mtime-secs>" "/$NAME") -eq $EXPECTED &&
237 test $(ipfs files stat --format="<mtime-nsecs>" "/$NAME") -eq 938475
238 '
239 }
240
241 DIR_TIME=1655158632
242
243 setup_directory() {
244
245 local TESTDIR="$(mktemp -d -p "$FIXTURESDIR" "${1}XXXXXX")"
246 mkdir -p "$TESTDIR"/{dir1,dir2/sub1/sub2,dir3}
247 chmod 0755 "$TESTDIR/dir1"
248
249 touch -md @$(($DIR_TIME+10)) "$TESTDIR/dir2/sub1/sub2/file3"
250 ln -s ../sub2/file3 "$TESTDIR/dir2/sub1/link1"
251 touch -h -md @$(($DIR_TIME+20)) "$TESTDIR/dir2/sub1/link1"
252
253 touch -md @$(($DIR_TIME+30)) "$TESTDIR/dir2/sub1/sub2"
254 touch -md @$(($DIR_TIME+40)) "$TESTDIR/dir2/sub1"
255 touch -md @$(($DIR_TIME+50)) "$TESTDIR/dir2"
256
257 touch -md @$(($DIR_TIME+60)) "$TESTDIR/dir3/file2"
258 touch -md @$(($DIR_TIME+70)) "$TESTDIR/dir3"
259
260 touch -md @$(($DIR_TIME+80)) "$TESTDIR/file1"
261 touch -md @$(($DIR_TIME+90)) "$TESTDIR/dir1"
262 touch -md @$DIR_TIME "$TESTDIR"
263
264 echo "$TESTDIR"
265 }
266
267 test_directory() {
268 CUSTOM_DIR_MODE=0713
269 TESTDIR=$(setup_directory $1)
270 TESTDIR1="$TESTDIR/dir1"
271 OUTDIR="$(mk_dir "${1}")"
272 HASH_DIR_ROOT=QmSioyvQuXetxg7uo8FswGn9XKKEsisDq1HTMzGyWbw2R6
273 HASH_DIR1_NO_PRESERVE=QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn
274 HASH_DIR1_PRESERVE_MODE=QmRviohgafvCsbkiTgfQFipbuXJ6k1YtoiaQW4quttJPKu
275 HASH_DIR1_PRESERVE_MTIME=QmYMy7CZGb498QFSQBF5ZFwv1FYbrAtYZMe4VxhDXxAcvf
276 HASH_DIR1_CUSTOM_MODE=QmQ1ABnw2iip7sj23EzzBZ9T77KyyfESP6SUboiXPyzNQe
277 HASH_DIR1_CUSTOM_MTIME=QmfWitW6F13WHFXLbJzXRYmwrS1p4gaAJAfucUSMytRPn3
278 HASH_DIR1_CUSTOM_MTIME_NSECS=QmZFdCLJay31hT3Tx1LygJ7XfiLEs3qLCXtbeBfhf38aZg
279 HASH_DIR_SUB1=QmeQwX5qAX18fcPDxDdkfM6ttuFCZetF5hgeUa6ov8D5oc
280
281 HASH_DIR_MODE_AND_MTIME=(
282 QmRCG3Pprg4jbhfYBzVzfJVyneFHnBquPGXwvXU3jSuf5j
283 QmReHCn4BSJJdtd6Le8Hd8Puai6TmgpPCYb13wyM7FD9AD
284 QmSioyvQuXetxg7uo8FswGn9XKKEsisDq1HTMzGyWbw2R6
285 QmTMoVgJKhPrz9DfkvT132mxyBXNae5azXQ42WbM9abdSE
286 QmVzXqpuQGCAgRwEbGuE9xe8Fidi1HEXaPKsQEFEbPJW9j
287 QmW6Nqy2nziduAp3UGx2a52gtSUsYzhVcZMuPdxBRnwCyP
288 QmeQwX5qAX18fcPDxDdkfM6ttuFCZetF5hgeUa6ov8D5oc
289 QmefofUNwC2U3Xp87rB1x8Aws6AdsDuoXR7B9u2RkEZ4dQ
290 Qmeu24TFarJwLzJgMTDYDJTr4BMGnzafoSnfxov1513abW
291 Qmf82bbFg2e8HmcqiewutVVw5NoMpiXZD57LpLdC1poBuH)
292 HASH_DIR_CUSTOM_MODE=(
293 QmNZ5cyx3f6maXkczwhh3ufjDCh9f3k9zrDhX218ZZGvoV
294 QmRqtFVLkXfWJuqWtYiCPthgomo3gouno8uvMeGAyCVaWS
295 QmSkrWNcyDA7s1qiT6Ps7ey4zcB7uBH3sqGcKRfW4UMKhM
296 QmSkrWNcyDA7s1qiT6Ps7ey4zcB7uBH3sqGcKRfW4UMKhM
297 QmSkrWNcyDA7s1qiT6Ps7ey4zcB7uBH3sqGcKRfW4UMKhM
298 QmZNAZXB6JyJ1cK9h1uJEK4XDo1CKsSuHMPGUUMrzDXCQz
299 QmbSz6GyS8MNR4M9xtCteuGVJQRYkCXLbW174Fdy8jtaoZ
300 QmccnAQQeJGtmtgZoi3hpEmgdxbuX1ao2hQmrKmmwQnCn9
301 QmeTZoiAiduFY2hXaNQP4ehiE71BrQFEnrqduBZ5ZjHuFy
302 Qmf13KNurvAHUfMBhMWvZuftmUikhhGY7ohWVaBDDndFMz)
303 HASH_DIR_CUSTOM_MTIME=(
304 QmPCGFZ8ZFowAwfWdCeGsr9wSbGXwZiHW3bZ7XSYcc1Zby
305 QmT3aY4avDcYXCWpU8CJzqUkW7YEuEsx36S8cTNoLcuK1B
306 QmT3aY4avDcYXCWpU8CJzqUkW7YEuEsx36S8cTNoLcuK1B
307 QmT3aY4avDcYXCWpU8CJzqUkW7YEuEsx36S8cTNoLcuK1B
308 QmUGMu9epCEz5HMsuJFgpJxxt3HoahsTQcC65Jje6LNqYF
309 QmXhzoPKuqmkqbyr4kJFznFRXtGwriCXKGFPr4vviyK3aV
310 QmZ5wKCcL11TckypuDTKLLNFP6JMCBJRCn385XKQQ6PCLt
311 Qmdw3hiAxn6R5MRkkdzLdFvZUa2WJeLCTXXCyB8byFsHSA
312 QmedF4m2Y8341azfkpvaHSkxbSrZa4fo6FT25h6sRUVkpq
313 QmfWitW6F13WHFXLbJzXRYmwrS1p4gaAJAfucUSMytRPn3)
314
315 test_expect_success "feature on directory has no effect when not used [$1]" '
316 HASH=$(ipfs add -qr "$TESTDIR1") &&
317 test "$HASH_DIR1_NO_PRESERVE" = "$HASH"
318 '
319
320 test_expect_success "can preserve directory mode [$1]" '
321 HASH=$(ipfs add -qr --preserve-mode "$TESTDIR1") &&
322 test "$HASH_DIR1_PRESERVE_MODE" = "$HASH"
323 '
324
325 test_expect_success "can preserve directory modification time [$1]" '
326 HASH=$(ipfs add -qr --preserve-mtime "$TESTDIR1") &&
327 test "$HASH_DIR1_PRESERVE_MTIME" = "$HASH"
328 '
329
330 test_expect_success "can set directory mode [$1]" '
331 HASH=$(ipfs add -qr --mode=$CUSTOM_DIR_MODE "$TESTDIR1") &&
332 test "$HASH_DIR1_CUSTOM_MODE" = "$HASH"
333 '
334
335 test_expect_success "can set directory modification time [$1]" '
336 HASH=$(ipfs add -qr --mtime=$CUSTOM_MTIME "$TESTDIR1") &&
337 test "$HASH_DIR1_CUSTOM_MTIME" = "$HASH"
338 '
339
340 test_expect_success "can set directory modification time nanoseconds [$1]" '
341 HASH=$(ipfs add -qr --mtime=$CUSTOM_MTIME --mtime-nsecs=$CUSTOM_MTIME_NSECS "$TESTDIR1") &&
342 test "$HASH_DIR1_CUSTOM_MTIME_NSECS" = "$HASH"
343 '
344
345 test_expect_success "can recursively preserve mode and modification time [$1]" '
346 test "700:$DIR_TIME" = "$(stat -c "%a:%Y" "$TESTDIR")" &&
347 test "644:$((DIR_TIME+10))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1/sub2/file3")" &&
348 test "777:$((DIR_TIME+20))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1/link1")" &&
349 test "755:$((DIR_TIME+30))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1/sub2")" &&
350 test "755:$((DIR_TIME+40))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1")" &&
351 test "755:$((DIR_TIME+50))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2")" &&
352 test "644:$((DIR_TIME+60))" = "$(stat -c "%a:%Y" "$TESTDIR/dir3/file2")" &&
353 test "755:$((DIR_TIME+70))" = "$(stat -c "%a:%Y" "$TESTDIR/dir3")" &&
354 test "644:$((DIR_TIME+80))" = "$(stat -c "%a:%Y" "$TESTDIR/file1")" &&
355 test "755:$((DIR_TIME+90))" = "$(stat -c "%a:%Y" "$TESTDIR/dir1")" &&
356 HASHES=($(ipfs add -qr --preserve-mode --preserve-mtime "$TESTDIR"|sort)) &&
357 test "${HASHES[*]}" = "${HASH_DIR_MODE_AND_MTIME[*]}"
358 '
359
360 test_expect_success "can recursively set directory mode [$1]" '
361 HASHES=($(ipfs add -qr --mode=0753 "$TESTDIR"|sort)) &&
362 test "${HASHES[*]}" = "${HASH_DIR_CUSTOM_MODE[*]}"
363 '
364
365 test_expect_success "can recursively set directory mtime [$1]" '
366 HASHES=($(ipfs add -qr --mtime=$CUSTOM_MTIME "$TESTDIR"|sort)) &&
367 test "${HASHES[*]}" = "${HASH_DIR_CUSTOM_MTIME[*]}"
368 '
369
370 test_expect_success "can recursively restore mode and mtime [$1]" '
371 ipfs get -o "$OUTDIR" $HASH_DIR_ROOT &&
372 test "700:$DIR_TIME" = "$(stat -c "%a:%Y" "$OUTDIR")" &&
373 test "644:$((DIR_TIME+10))" = "$(stat -c "%a:%Y" "$OUTDIR/dir2/sub1/sub2/file3")" &&
374 test "777:$((DIR_TIME+20))" = "$(stat -c "%a:%Y" "$OUTDIR/dir2/sub1/link1")" &&
375 test "755:$((DIR_TIME+30))" = "$(stat -c "%a:%Y" "$OUTDIR/dir2/sub1/sub2")" &&
376 test "755:$((DIR_TIME+40))" = "$(stat -c "%a:%Y" "$OUTDIR/dir2/sub1")" &&
377 test "755:$((DIR_TIME+50))" = "$(stat -c "%a:%Y" "$OUTDIR/dir2")" &&
378 test "644:$((DIR_TIME+60))" = "$(stat -c "%a:%Y" "$OUTDIR/dir3/file2")" &&
379 test "755:$((DIR_TIME+70))" = "$(stat -c "%a:%Y" "$OUTDIR/dir3")" &&
380 test "644:$((DIR_TIME+80))" = "$(stat -c "%a:%Y" "$OUTDIR/file1")" &&
381 test "755:$((DIR_TIME+90))" = "$(stat -c "%a:%Y" "$OUTDIR/dir1")"
382 '
383
384 # basic smoke-test for cidv1 (we dont care about CID, just care about
385 # mode/mtime surviving ipfs import and export if --cid-version 1 is at play)
386 test_expect_success "can recursively preserve and restore mode and mtime with CIDv1 [$1]" '
387 test "700:$DIR_TIME" = "$(stat -c "%a:%Y" "$TESTDIR")" &&
388 test "644:$((DIR_TIME+10))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1/sub2/file3")" &&
389 test "777:$((DIR_TIME+20))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1/link1")" &&
390 test "755:$((DIR_TIME+30))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1/sub2")" &&
391 test "755:$((DIR_TIME+40))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2/sub1")" &&
392 test "755:$((DIR_TIME+50))" = "$(stat -c "%a:%Y" "$TESTDIR/dir2")" &&
393 test "644:$((DIR_TIME+60))" = "$(stat -c "%a:%Y" "$TESTDIR/dir3/file2")" &&
394 test "755:$((DIR_TIME+70))" = "$(stat -c "%a:%Y" "$TESTDIR/dir3")" &&
395 test "644:$((DIR_TIME+80))" = "$(stat -c "%a:%Y" "$TESTDIR/file1")" &&
396 test "755:$((DIR_TIME+90))" = "$(stat -c "%a:%Y" "$TESTDIR/dir1")" &&
397 CIDV1DIR=$(ipfs add -Qr --preserve-mode --preserve-mtime --cid-version 1 "$TESTDIR") &&
398 OUTDIRV1=$(mk_dir cidv1roundtrip$1) &&
399 ipfs get -o "$OUTDIRV1" $CIDV1DIR &&
400 test "700:$DIR_TIME" = "$(stat -c "%a:%Y" "$OUTDIRV1")" &&
401 test "644:$((DIR_TIME+10))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir2/sub1/sub2/file3")" &&
402 test "777:$((DIR_TIME+20))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir2/sub1/link1")" &&
403 test "755:$((DIR_TIME+30))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir2/sub1/sub2")" &&
404 test "755:$((DIR_TIME+40))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir2/sub1")" &&
405 test "755:$((DIR_TIME+50))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir2")" &&
406 test "644:$((DIR_TIME+60))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir3/file2")" &&
407 test "755:$((DIR_TIME+70))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir3")" &&
408 test "644:$((DIR_TIME+80))" = "$(stat -c "%a:%Y" "$OUTDIRV1/file1")" &&
409 test "755:$((DIR_TIME+90))" = "$(stat -c "%a:%Y" "$OUTDIRV1/dir1")"
410 '
411
412 test_expect_success "can change directory mode [$1]" '
413 NAME=$(mk_name) &&
414 ipfs files cp "/ipfs/$HASH_DIR_SUB1" /$NAME &&
415 ipfs files chmod 0710 /$NAME &&
416 test $(ipfs files stat --format="<mode>" /$NAME) = "drwx--x---"
417 '
418
419 test_expect_success "can change directory modification time [$1]" '
420 NAME=$(mk_name) &&
421 ipfs files cp "/ipfs/$HASH_DIR_SUB1" /$NAME &&
422 ipfs files touch --mtime=$CUSTOM_MTIME /$NAME &&
423 test $(ipfs files stat --format="<mtime-secs>" /$NAME) -eq $CUSTOM_MTIME
424 '
425
426 test_expect_success "can change directory modification time nanoseconds [$1]" '
427 NAME=$(mk_name) &&
428 MTIME=$(date --date="yesterday" +%s) &&
429 ipfs files cp "/ipfs/$HASH_DIR_SUB1" /$NAME &&
430 ipfs files touch --mtime=$MTIME --mtime-nsecs=94783 /$NAME &&
431 test $(ipfs files stat --format="<mtime-secs>" /$NAME) -eq $MTIME &&
432 test $(ipfs files stat --format="<mtime-nsecs>" /$NAME) -eq 94783
433 '
434 }
435
436 test_stat_template() {
437 test_expect_success "can stat $2 string mode [$1]" '
438 touch "$STAT_TARGET" &&
439 HASH=$(ipfs add -qr --mode="$STAT_MODE_OCTAL" "$STAT_TARGET") &&
440 ACTUAL=$(ipfs files stat --format="<mode>" /ipfs/$HASH) &&
441 test "$ACTUAL" = "$STAT_MODE_STRING"
442 '
443 test_expect_success "can stat $2 octal mode [$1]" '
444 touch "$STAT_TARGET" &&
445 HASH=$(ipfs add -qr --mode="$STAT_MODE_OCTAL" "$STAT_TARGET") &&
446 ACTUAL=$(ipfs files stat --format="<mode-octal>" /ipfs/$HASH) &&
447 test "$ACTUAL" = "$STAT_MODE_OCTAL"
448 '
449
450 test_expect_success "can stat $2 modification time string [$1]" '
451 touch "$STAT_TARGET" &&
452 HASH=$(ipfs add -qr --mtime=$CUSTOM_MTIME "$STAT_TARGET") &&
453 ACTUAL=$(ipfs files stat --format="<mtime>" /ipfs/$HASH) &&
454 test "$ACTUAL" = "24 Oct 2020, 11:42:00 UTC"
455 '
456
457 test_expect_success "can stat $2 modification time seconds [$1]" '
458 touch "$STAT_TARGET" &&
459 HASH=$(ipfs add -qr --mtime=$CUSTOM_MTIME "$STAT_TARGET") &&
460 ACTUAL=$(ipfs files stat --format="<mtime-secs>" /ipfs/$HASH) &&
461 test $ACTUAL -eq $CUSTOM_MTIME
462 '
463
464 test_expect_success "can stat $2 modification time nanoseconds [$1]" '
465 touch "$STAT_TARGET" &&
466 HASH=$(ipfs add -qr --mtime=$CUSTOM_MTIME --mtime-nsecs=$CUSTOM_MTIME_NSECS "$STAT_TARGET") &&
467 ACTUAL=$(ipfs files stat --format="<mtime-nsecs>" /ipfs/$HASH) &&
468 test $ACTUAL -eq $CUSTOM_MTIME_NSECS
469 '
470 }
471
472 test_stat() {
473 STAT_TARGET="$FIXTURESDIR/statfile$1"
474 STAT_MODE_OCTAL="$CUSTOM_MODE"
475 STAT_MODE_STRING="-rwxrw-r--"
476 test_stat_template "$1" "file"
477
478 STAT_TARGET="$FIXTURESDIR/statdir$1"
479 STAT_MODE_OCTAL="0731"
480 STAT_MODE_STRING="drwx-wx--x"
481 mkdir "$STAT_TARGET"
482 test_stat_template "$1" "directory"
483
484 STAT_TARGET="$FIXTURESDIR/statlink$1"
485 STAT_MODE_OCTAL="0777"
486 STAT_MODE_STRING="lrwxrwxrwx"
487 ln -s nothing "$STAT_TARGET"
488 test_stat_template "$1" "link"
489
490
491 STAT_TARGET="$FIXTURESDIR/statfile$1"
492 test_expect_success "can chain stat template [$1]" '
493 HASH=$(ipfs add -q --mode=0644 --mtime=$CUSTOM_MTIME --mtime-nsecs=$CUSTOM_MTIME_NSECS "$STAT_TARGET") &&
494 ACTUAL=$(ipfs files stat --format="<mtime> <mtime-secs> <mtime-nsecs> <mode> <mode-octal>" /ipfs/$HASH) &&
495 test "$ACTUAL" = "24 Oct 2020, 11:42:00 UTC 1603539720 54321 -rw-r--r-- 0644"
496 '
497 }
498
499 test_all() {
500 test_stat "$1"
501 test_file "$1"
502 test_directory "$1"
503 }
504
505 # test direct
506 test_all "direct"
507
508 # test daemon
509 test_launch_ipfs_daemon_without_network
510 test_all "daemon"
511 test_kill_ipfs_daemon
512
513 test_done