| 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 |