1 #!/bin/sh 2 3 set -e # exit immediately on error 4 # set -x # print commands before execution (debug) 5 6 unset ZSTD_CLEVEL 7 unset ZSTD_NBTHREADS 8 9 10 die() { 11 println "$@" 1>&2 12 exit 1 13 } 14 15 datagen() { 16 "$DATAGEN_BIN" "$@" 17 } 18 19 zstd() { 20 if [ -z "$EXE_PREFIX" ]; then 21 "$ZSTD_BIN" "$@" 22 else 23 "$EXE_PREFIX" "$ZSTD_BIN" "$@" 24 fi 25 } 26 27 sudoZstd() { 28 if [ -z "$EXE_PREFIX" ]; then 29 sudo "$ZSTD_BIN" "$@" 30 else 31 sudo "$EXE_PREFIX" "$ZSTD_BIN" "$@" 32 fi 33 } 34 35 roundTripTest() { 36 if [ -n "$3" ]; then 37 cLevel="$3" 38 proba="$2" 39 else 40 cLevel="$2" 41 proba="" 42 fi 43 if [ -n "$4" ]; then 44 dLevel="$4" 45 else 46 dLevel="$cLevel" 47 fi 48 49 rm -f tmp1 tmp2 50 println "roundTripTest: datagen $1 $proba | zstd -v$cLevel | zstd -d$dLevel" 51 datagen $1 $proba | $MD5SUM > tmp1 52 datagen $1 $proba | zstd --ultra -v$cLevel | zstd -d$dLevel | $MD5SUM > tmp2 53 $DIFF -q tmp1 tmp2 54 } 55 56 fileRoundTripTest() { 57 if [ -n "$3" ]; then 58 local_c="$3" 59 local_p="$2" 60 else 61 local_c="$2" 62 local_p="" 63 fi 64 if [ -n "$4" ]; then 65 local_d="$4" 66 else 67 local_d="$local_c" 68 fi 69 70 rm -f tmp.zst tmp.md5.1 tmp.md5.2 71 println "fileRoundTripTest: datagen $1 $local_p > tmp && zstd -v$local_c -c tmp | zstd -d$local_d" 72 datagen $1 $local_p > tmp 73 < tmp $MD5SUM > tmp.md5.1 74 zstd --ultra -v$local_c -c tmp | zstd -d$local_d | $MD5SUM > tmp.md5.2 75 $DIFF -q tmp.md5.1 tmp.md5.2 76 } 77 78 truncateLastByte() { 79 dd bs=1 count=$(($(wc -c < "$1") - 1)) if="$1" 80 } 81 82 println() { 83 printf '%b\n' "${*}" 84 } 85 86 if [ -z "${size}" ]; then 87 size= 88 else 89 size=${size} 90 fi 91 92 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) 93 PRGDIR="$SCRIPT_DIR/../programs" 94 TESTDIR="$SCRIPT_DIR/../tests" 95 UNAME=${UNAME:-$(uname)} 96 GREP=${GREP:-grep} 97 98 case "$UNAME" in 99 SunOS) DIFF=${DIFF:-gdiff} ;; 100 *) DIFF=${DIFF:-diff} ;; 101 esac 102 103 detectedTerminal=false 104 if [ -t 0 ] && [ -t 1 ] 105 then 106 detectedTerminal=true 107 fi 108 isTerminal=${isTerminal:-$detectedTerminal} 109 110 isWindows=false 111 INTOVOID="/dev/null" 112 DEVDEVICE="/dev/zero" 113 case "$OS" in 114 Windows*) 115 isWindows=true 116 INTOVOID="NUL" 117 DEVDEVICE="NUL" 118 ;; 119 esac 120 121 case "$UNAME" in 122 Darwin) MD5SUM="md5 -r" ;; 123 NetBSD) MD5SUM="md5 -n" ;; 124 OpenBSD) MD5SUM="md5" ;; 125 *) MD5SUM="md5sum" ;; 126 esac 127 128 MTIME="stat -c %Y" 129 case "$UNAME" in 130 Darwin | FreeBSD | OpenBSD | NetBSD) MTIME="stat -f %m" ;; 131 esac 132 133 assertSameMTime() { 134 MT1=$($MTIME "$1") 135 MT2=$($MTIME "$2") 136 echo MTIME $MT1 $MT2 137 [ "$MT1" = "$MT2" ] || die "mtime on $1 doesn't match mtime on $2 ($MT1 != $MT2)" 138 } 139 140 GET_PERMS="stat -c %a" 141 case "$UNAME" in 142 Darwin | FreeBSD | OpenBSD | NetBSD) GET_PERMS="stat -f %Lp" ;; 143 esac 144 145 assertFilePermissions() { 146 STAT1=$($GET_PERMS "$1") 147 STAT2=$2 148 [ "$STAT1" = "$STAT2" ] || die "permissions on $1 don't match expected ($STAT1 != $STAT2)" 149 } 150 151 assertSamePermissions() { 152 STAT1=$($GET_PERMS "$1") 153 STAT2=$($GET_PERMS "$2") 154 [ "$STAT1" = "$STAT2" ] || die "permissions on $1 don't match those on $2 ($STAT1 != $STAT2)" 155 } 156 157 158 # check if ZSTD_BIN is defined. if not, use the default value 159 if [ -z "${ZSTD_BIN}" ]; then 160 println "\nZSTD_BIN is not set. Using the default value..." 161 ZSTD_BIN="$PRGDIR/zstd" 162 fi 163 164 # check if DATAGEN_BIN is defined. if not, use the default value 165 if [ -z "${DATAGEN_BIN}" ]; then 166 println "\nDATAGEN_BIN is not set. Using the default value..." 167 DATAGEN_BIN="$TESTDIR/datagen" 168 fi 169 170 # Why was this line here ? Generates a strange ZSTD_BIN when EXE_PREFIX is non empty 171 # ZSTD_BIN="$EXE_PREFIX$ZSTD_BIN" 172 173 # assertions 174 [ -n "$ZSTD_BIN" ] || die "zstd not found at $ZSTD_BIN! \n Please define ZSTD_BIN pointing to the zstd binary. You might also consider rebuilding zstd following the instructions in README.md" 175 [ -n "$DATAGEN_BIN" ] || die "datagen not found at $DATAGEN_BIN! \n Please define DATAGEN_BIN pointing to the datagen binary. You might also consider rebuilding zstd tests following the instructions in README.md. " 176 println "\nStarting playTests.sh isWindows=$isWindows EXE_PREFIX='$EXE_PREFIX' ZSTD_BIN='$ZSTD_BIN' DATAGEN_BIN='$DATAGEN_BIN'" 177 178 if echo hello | zstd -v -T2 2>&1 > $INTOVOID | $GREP -q 'multi-threading is disabled' 179 then 180 hasMT="" 181 else 182 hasMT="true" 183 fi 184 185 186 zstd -vvV 187 188 println "\n===> simple tests " 189 190 datagen > tmp 191 zstd -h 192 zstd -H 193 zstd -V 194 println "test : basic compression " 195 zstd -f tmp # trivial compression case, creates tmp.zst 196 zstd -f -z tmp 197 zstd -f -k tmp 198 zstd -f -C tmp 199 println "test : basic decompression" 200 zstd -df tmp.zst # trivial decompression case (overwrites tmp) 201 println "test : too large compression level => auto-fix" 202 zstd -99 -f tmp # too large compression level, automatic sized down 203 zstd -5000000000 -f tmp && die "too large numeric value : must fail" 204 println "test : --fast aka negative compression levels" 205 zstd --fast -f tmp # == -1 206 zstd --fast=3 -f tmp # == -3 207 zstd --fast=200000 -f tmp # too low compression level, automatic fixed 208 zstd --fast=5000000000 -f tmp && die "too large numeric value : must fail" 209 zstd -c --fast=0 tmp > $INTOVOID && die "--fast must not accept value 0" 210 println "test : too large numeric argument" 211 zstd --fast=9999999999 -f tmp && die "should have refused numeric value" 212 println "test : set compression level with environment variable ZSTD_CLEVEL" 213 214 ZSTD_CLEVEL=12 zstd -f tmp # positive compression level 215 ZSTD_CLEVEL=-12 zstd -f tmp # negative compression level 216 ZSTD_CLEVEL=+12 zstd -f tmp # valid: verbose '+' sign 217 ZSTD_CLEVEL='' zstd -f tmp # empty env var, warn and revert to default setting 218 ZSTD_CLEVEL=- zstd -f tmp # malformed env var, warn and revert to default setting 219 ZSTD_CLEVEL=a zstd -f tmp # malformed env var, warn and revert to default setting 220 ZSTD_CLEVEL=+a zstd -f tmp # malformed env var, warn and revert to default setting 221 ZSTD_CLEVEL=3a7 zstd -f tmp # malformed env var, warn and revert to default setting 222 ZSTD_CLEVEL=50000000000 zstd -f tmp # numeric value too large, warn and revert to default setting 223 println "test : override ZSTD_CLEVEL with command line option" 224 ZSTD_CLEVEL=12 zstd --fast=3 -f tmp # overridden by command line option 225 226 # temporary envvar changes in the above tests would actually persist in macos /bin/sh 227 unset ZSTD_CLEVEL 228 229 230 println "test : compress to stdout" 231 zstd tmp -c > tmpCompressed 232 zstd tmp --stdout > tmpCompressed # long command format 233 234 println "test : compress to named file (-o)" 235 rm -f tmpCompressed 236 zstd tmp -o tmpCompressed 237 test -f tmpCompressed # file must be created 238 239 println "test : force write, correct order" 240 zstd tmp -fo tmpCompressed 241 242 println "test : -c + -o : last one wins" 243 rm -f tmpOut 244 zstd tmp -c > tmpCompressed -o tmpOut 245 test -f tmpOut # file must be created 246 rm -f tmpCompressed 247 zstd tmp -o tmpOut -c > tmpCompressed 248 test -f tmpCompressed # file must be created 249 250 println "test : forgotten argument" 251 cp tmp tmp2 252 zstd tmp2 -fo && die "-o must be followed by filename " 253 println "test : implied stdout when input is stdin" 254 println bob | zstd | zstd -d 255 if [ "$isTerminal" = true ]; then 256 println "test : compressed data to terminal" 257 println bob | zstd && die "should have refused : compressed data to terminal" 258 println "test : compressed data from terminal (a hang here is a test fail, zstd is wrongly waiting on data from terminal)" 259 zstd -d > $INTOVOID && die "should have refused : compressed data from terminal" 260 fi 261 println "test : null-length file roundtrip" 262 println -n '' | zstd - --stdout | zstd -d --stdout 263 println "test : ensure small file doesn't add 3-bytes null block" 264 datagen -g1 > tmp1 265 zstd tmp1 -c | wc -c | $GREP "14" 266 zstd < tmp1 | wc -c | $GREP "14" 267 println "test : decompress file with wrong suffix (must fail)" 268 zstd -d tmpCompressed && die "wrong suffix error not detected!" 269 zstd -df tmp && die "should have refused : wrong extension" 270 println "test : decompress into stdout" 271 zstd -d tmpCompressed -c > tmpResult # decompression using stdout 272 zstd --decompress tmpCompressed -c > tmpResult 273 zstd --decompress tmpCompressed --stdout > tmpResult 274 println "test : decompress from stdin into stdout" 275 zstd -dc < tmp.zst > $INTOVOID # combine decompression, stdin & stdout 276 zstd -dc - < tmp.zst > $INTOVOID 277 zstd -d < tmp.zst > $INTOVOID # implicit stdout when stdin is used 278 zstd -d - < tmp.zst > $INTOVOID 279 println "test : impose memory limitation (must fail)" 280 datagen -g500K > tmplimit 281 zstd -f tmplimit 282 zstd -d -f tmplimit.zst -M2K -c > $INTOVOID && die "decompression needs more memory than allowed" 283 zstd -d -f tmplimit.zst --memlimit=2K -c > $INTOVOID && die "decompression needs more memory than allowed" # long command 284 zstd -d -f tmplimit.zst --memory=2K -c > $INTOVOID && die "decompression needs more memory than allowed" # long command 285 zstd -d -f tmplimit.zst --memlimit-decompress=2K -c > $INTOVOID && die "decompression needs more memory than allowed" # long command 286 rm -f tmplimit tmplimit.zst 287 println "test : overwrite protection" 288 zstd -q tmp && die "overwrite check failed!" 289 println "test : force overwrite" 290 zstd -q -f tmp 291 zstd -q --force tmp 292 println "test : overwrite readonly file" 293 rm -f tmpro tmpro.zst 294 println foo > tmpro.zst 295 println foo > tmpro 296 chmod 400 tmpro.zst 297 zstd -q tmpro && die "should have refused to overwrite read-only file" 298 zstd -q -f tmpro 299 println "test: --no-progress flag" 300 zstd tmpro -c --no-progress | zstd -d -f -o "$INTOVOID" --no-progress 301 zstd tmpro -cv --no-progress | zstd -dv -f -o "$INTOVOID" --no-progress 302 println "test: --progress flag" 303 zstd tmpro -c | zstd -d -f -o "$INTOVOID" --progress 2>&1 | $GREP '[A-Za-z0-9._ ]*: [0-9]* bytes' 304 zstd tmpro -c | zstd -d -f -q -o "$INTOVOID" --progress 2>&1 | $GREP '[A-Za-z0-9._ ]*: [0-9]* bytes' 305 zstd tmpro -c | zstd -d -f -v -o "$INTOVOID" 2>&1 | $GREP '[A-Za-z0-9._ ]*: [0-9]* bytes' 306 rm -f tmpro tmpro.zst 307 println "test: overwrite input file (must fail)" 308 zstd tmp -fo tmp && die "zstd compression overwrote the input file" 309 zstd tmp.zst -dfo tmp.zst && die "zstd decompression overwrote the input file" 310 println "test: detect that input file does not exist" 311 zstd nothere && die "zstd hasn't detected that input file does not exist" 312 println "test: --[no-]compress-literals" 313 zstd tmp -c --no-compress-literals -1 | zstd -t 314 zstd tmp -c --no-compress-literals --fast=1 | zstd -t 315 zstd tmp -c --no-compress-literals -19 | zstd -t 316 zstd tmp -c --compress-literals -1 | zstd -t 317 zstd tmp -c --compress-literals --fast=1 | zstd -t 318 zstd tmp -c --compress-literals -19 | zstd -t 319 zstd -b --fast=1 -i0e1 tmp --compress-literals 320 zstd -b --fast=1 -i0e1 tmp --no-compress-literals 321 println "test: --no-check for decompression" 322 zstd -f tmp -o tmp_corrupt.zst --check 323 zstd -f tmp -o tmp.zst --no-check 324 printf '\xDE\xAD\xBE\xEF' | dd of=tmp_corrupt.zst bs=1 seek=$(($(wc -c < "tmp_corrupt.zst") - 4)) count=4 conv=notrunc # corrupt checksum in tmp 325 zstd -d -f tmp_corrupt.zst --no-check 326 zstd -d -f tmp_corrupt.zst --check --no-check # final flag overrides 327 zstd -d -f tmp.zst --no-check 328 329 if [ "$isWindows" = false ] && [ "$UNAME" != "AIX" ]; then 330 if [ -n "$(which readelf)" ]; then 331 println "test: check if binary has executable stack (#2963)" 332 readelf -lW "$ZSTD_BIN" | $GREP 'GNU_STACK .* RW ' || die "zstd binary has executable stack!" 333 fi 334 fi 335 336 println "\n===> multiple_thread test " 337 338 datagen > tmp 339 println "test : single-thread " 340 zstd --fast --single-thread tmp -o tmpMT0 341 println "test : one worker thread (default)" 342 zstd --fast -T1 tmp -o tmpMT1 343 println "test : two worker threads " 344 zstd --fast -T2 tmp -o tmpMT2 345 println "test : 16-thread " 346 zstd --fast -T16 tmp -o tmpMT3 347 println "test : 127-thread " 348 zstd --fast -T127 tmp -o tmpMT4 349 println "test : 128-thread " 350 zstd --fast -T128 tmp -o tmpMT5 351 println "test : max allowed numeric value is 4294967295 " 352 zstd --fast -4294967295 tmp -o tmpMT6 353 println "test : numeric value overflows 32-bit unsigned int " 354 zstd --fast -4294967296 tmp -o tmptest9 && die "max allowed numeric value is 4294967295" 355 356 datagen > tmp 357 println "test : basic compression " 358 zstd -f tmp # trivial compression case, creates tmp.zst 359 println "test : basic decompression" 360 zstd -d -f -T1 tmp.zst 361 println "note : decompression does not support -T mode, but execution support" 362 rm -rf tmpMT* 363 364 println "\n===> --fast_argument test " 365 datagen > tmp 366 println "test : basic compression " 367 zstd -f tmp # trivial compression case, creates tmp.zst 368 println "test: --fast=1" 369 zstd --fast=1 -f tmp 370 println "test: --fast=99" 371 zstd --fast=99 -f tmp 372 println "test: Invalid value -- negative number" 373 zstd --fast=-1 -f tmp && die "error: Invalid value -- negative number" 374 println "test: Invalid value -- zero" 375 zstd --fast=0 -f tmp && die "error: Invalid value -- 0 number" 376 println "test: max allowed numeric argument of --fast is 4294967295" 377 zstd --fast=4294967295 -f tmp 378 println "test: numeric value overflows 32-bit unsigned int " 379 zstd --fast=4294967296 -f tmp && die "max allowed argument of --fast is 4294967295" 380 381 println "\n===> --exclude-compressed flag" 382 rm -rf precompressedFilterTestDir 383 mkdir -p precompressedFilterTestDir 384 datagen $size > precompressedFilterTestDir/input.5 385 datagen $size > precompressedFilterTestDir/input.6 386 zstd --exclude-compressed --long --rm -r precompressedFilterTestDir 387 datagen $size > precompressedFilterTestDir/input.7 388 datagen $size > precompressedFilterTestDir/input.8 389 zstd --exclude-compressed --long --rm -r precompressedFilterTestDir 390 test ! -f precompressedFilterTestDir/input.5.zst.zst 391 test ! -f precompressedFilterTestDir/input.6.zst.zst 392 file1timestamp=`$MTIME precompressedFilterTestDir/input.5.zst` 393 file2timestamp=`$MTIME precompressedFilterTestDir/input.7.zst` 394 if [ $file2timestamp -ge $file1timestamp ]; then 395 println "Test is successful. input.5.zst is precompressed and therefore not compressed/modified again." 396 else 397 println "Test is not successful" 398 fi 399 # File Extension check. 400 datagen $size > precompressedFilterTestDir/input.zstbar 401 zstd --exclude-compressed --long --rm -r precompressedFilterTestDir 402 # zstd should compress input.zstbar 403 test -f precompressedFilterTestDir/input.zstbar.zst 404 # Check without the --exclude-compressed flag 405 zstd --long --rm -r precompressedFilterTestDir 406 # Files should get compressed again without the --exclude-compressed flag. 407 test -f precompressedFilterTestDir/input.5.zst.zst 408 test -f precompressedFilterTestDir/input.6.zst.zst 409 410 # Test some other compressed file extensions 411 datagen $size > precompressedFilterTestDir/input.flac 412 datagen $size > precompressedFilterTestDir/input.mov 413 datagen $size > precompressedFilterTestDir/input.mp3 414 zstd --exclude-compressed --long --rm -r precompressedFilterTestDir 415 test ! -f precompressedFilterTestDir/input.flac.zst 416 test ! -f precompressedFilterTestDir/input.mov.zst 417 test ! -f precompressedFilterTestDir/input.mp3.zst 418 zstd --long --rm -r precompressedFilterTestDir 419 test -f precompressedFilterTestDir/input.flac.zst 420 test -f precompressedFilterTestDir/input.mov.zst 421 test -f precompressedFilterTestDir/input.mp3.zst 422 rm -rf precompressedFilterTestDir 423 println "Test completed" 424 425 426 427 println "\n===> warning prompts should not occur if stdin is an input" 428 println "y" > tmpPrompt 429 println "hello world" >> tmpPrompt 430 zstd tmpPrompt -f 431 zstd < tmpPrompt -o tmpPrompt.zst && die "should have aborted immediately and failed to overwrite" 432 zstd < tmpPrompt -o tmpPrompt.zst -f # should successfully overwrite with -f 433 zstd -q -d -f tmpPrompt.zst -o tmpPromptRegenerated 434 $DIFF tmpPromptRegenerated tmpPrompt # the first 'y' character should not be swallowed 435 436 echo 'yes' | zstd tmpPrompt -v -o tmpPrompt.zst # accept piped "y" input to force overwrite when using files 437 echo 'yes' | zstd < tmpPrompt -v -o tmpPrompt.zst && die "should have aborted immediately and failed to overwrite" 438 zstd tmpPrompt - < tmpPrompt -o tmpPromp.zst --rm && die "should have aborted immediately and failed to remove" 439 440 println "Test completed" 441 442 443 println "\n===> recursive mode test " 444 # combination of -r with empty list of input file 445 zstd -c -r < tmp > tmp.zst 446 447 # combination of -r with empty folder 448 mkdir -p tmpEmptyDir 449 zstd -r tmpEmptyDir 450 rm -rf tmpEmptyDir 451 452 453 println "\n===> file removal" 454 zstd -f --rm tmp 455 test ! -f tmp # tmp should no longer be present 456 zstd -f -d --rm tmp.zst 457 test ! -f tmp.zst # tmp.zst should no longer be present 458 println "test: --rm is disabled when output is stdout" 459 test -f tmp 460 zstd --rm tmp -c > $INTOVOID 461 test -f tmp # tmp shall still be there 462 zstd --rm tmp --stdout > $INTOVOID 463 test -f tmp # tmp shall still be there 464 zstd -f --rm tmp -c > $INTOVOID 465 test -f tmp # tmp shall still be there 466 zstd -f tmp -c > $INTOVOID --rm 467 test -f tmp # tmp shall still be there 468 println "test: --rm is disabled when multiple inputs are concatenated into a single output" 469 cp tmp tmp2 470 zstd --rm tmp tmp2 -c > $INTOVOID 471 test -f tmp 472 test -f tmp2 473 rm -f tmp3.zst 474 echo 'y' | zstd -v tmp tmp2 -o tmp3.zst --rm # prompt for confirmation 475 test -f tmp 476 test -f tmp2 477 zstd -f tmp tmp2 -o tmp3.zst --rm # just warns, no prompt 478 test -f tmp 479 test -f tmp2 480 zstd -q tmp tmp2 -o tmp3.zst --rm && die "should refuse to concatenate" 481 println "test: --rm is active with -o when single input" 482 rm -f tmp2.zst 483 zstd --rm tmp2 -o tmp2.zst 484 test -f tmp2.zst 485 test ! -f tmp2 486 println "test: -c followed by -o => -o wins, so --rm remains active" # (#3719) 487 rm tmp2.zst 488 cp tmp tmp2 489 zstd --rm tmp2 -c > $INTOVOID -o tmp2.zst 490 test ! -f tmp2 491 println "test: -o followed by -c => -c wins, so --rm is disabled" # (#3719) 492 rm tmp3.zst 493 cp tmp tmp2 494 zstd -v --rm tmp2 -o tmp2.zst -c > tmp3.zst 495 test -f tmp2 496 test -f tmp3.zst 497 println "test : should quietly not remove non-regular file" 498 println hello > tmp 499 zstd tmp -f -o "$DEVDEVICE" 2>tmplog > "$INTOVOID" 500 $GREP "Refusing to remove non-regular file" tmplog && die 501 rm -f tmplog 502 zstd tmp -f -o "$INTOVOID" 2>&1 | $GREP "Refusing to remove non-regular file" && die 503 println "test : --rm on stdin" 504 println a | zstd --rm > $INTOVOID # --rm should remain silent 505 rm -f tmp 506 zstd -f tmp && die "tmp not present : should have failed" 507 test ! -f tmp.zst # tmp.zst should not be created 508 println "test : -d -f do not delete destination when source is not present" 509 touch tmp # create destination file 510 zstd -d -f tmp.zst && die "attempt to decompress a non existing file" 511 test -f tmp # destination file should still be present 512 println "test : -f do not delete destination when source is not present" 513 rm -f tmp # erase source file 514 touch tmp.zst # create destination file 515 zstd -f tmp && die "attempt to compress a non existing file" 516 test -f tmp.zst # destination file should still be present 517 rm -rf tmp* # may also erase tmp* directory from previous failed run 518 519 520 println "\n===> decompression only tests " 521 # the following test verifies that the decoder is compatible with RLE as first block 522 # older versions of zstd cli are not able to decode such corner case. 523 # As a consequence, the zstd cli do not generate them, to maintain compatibility with older versions. 524 dd bs=1048576 count=1 if=/dev/zero of=tmp 525 zstd -d -o tmp1 "$TESTDIR/golden-decompression/rle-first-block.zst" 526 $DIFF -s tmp1 tmp 527 528 touch tmp_empty 529 zstd -d -o tmp2 "$TESTDIR/golden-decompression/empty-block.zst" 530 $DIFF -s tmp2 tmp_empty 531 532 zstd -t "$TESTDIR/golden-decompression/zeroSeq_2B.zst" 533 534 zstd -t "$TESTDIR/golden-decompression-errors/zeroSeq_extraneous.zst" && die "invalid Sequences section should have been detected" 535 536 rm -f tmp* 537 538 println "\n===> compress multiple files" 539 println hello > tmp1 540 println world > tmp2 541 zstd tmp1 tmp2 -o "$INTOVOID" -f 542 zstd tmp1 tmp2 -c | zstd -t 543 echo 'y' | zstd -v tmp1 tmp2 -o tmp.zst 544 test ! -f tmp1.zst 545 test ! -f tmp2.zst 546 zstd tmp1 tmp2 547 zstd -t tmp1.zst tmp2.zst 548 zstd -dc tmp1.zst tmp2.zst 549 zstd tmp1.zst tmp2.zst -o "$INTOVOID" -f 550 echo 'y' | zstd -v -d tmp1.zst tmp2.zst -o tmp 551 touch tmpexists 552 zstd tmp1 tmp2 -f -o tmpexists 553 zstd tmp1 tmp2 -q -o tmpexists && die "should have refused to overwrite" 554 println gooder > tmp_rm1 555 println boi > tmp_rm2 556 println worldly > tmp_rm3 557 echo 'y' | zstd -v tmp_rm1 tmp_rm2 -v -o tmp_rm3.zst 558 test -f tmp_rm1 559 test -f tmp_rm2 560 cp tmp_rm3.zst tmp_rm4.zst 561 echo 'Y' | zstd -v -d tmp_rm3.zst tmp_rm4.zst -v -o tmp_rm_out --rm 562 test -f tmp_rm3.zst 563 test -f tmp_rm4.zst 564 println gooder > tmpexists1 565 zstd tmpexists1 tmpexists -c --rm -f > $INTOVOID 566 # Bug: PR #972 567 if [ "$?" -eq 139 ]; then 568 die "should not have segfaulted" 569 fi 570 test -f tmpexists1 571 test -f tmpexists 572 println "\n===> multiple files and shell completion " 573 datagen -s1 > tmp1 2> $INTOVOID 574 datagen -s2 -g100K > tmp2 2> $INTOVOID 575 datagen -s3 -g1M > tmp3 2> $INTOVOID 576 println "compress tmp* : " 577 zstd -f tmp* 578 test -f tmp1.zst 579 test -f tmp2.zst 580 test -f tmp3.zst 581 rm -f tmp1 tmp2 tmp3 582 println "decompress tmp* : " 583 zstd -df ./*.zst 584 test -f tmp1 585 test -f tmp2 586 test -f tmp3 587 println "compress tmp* into stdout > tmpall : " 588 zstd -c tmp1 tmp2 tmp3 > tmpall 589 test -f tmpall # should check size of tmpall (should be tmp1.zst + tmp2.zst + tmp3.zst) 590 println "decompress tmpall* into stdout > tmpdec : " 591 cp tmpall tmpall2 592 zstd -dc tmpall* > tmpdec 593 test -f tmpdec # should check size of tmpdec (should be 2*(tmp1 + tmp2 + tmp3)) 594 println "compress multiple files including a missing one (notHere) : " 595 zstd -f tmp1 notHere tmp2 && die "missing file not detected!" 596 rm -f tmp* 597 598 599 if [ "$isWindows" = false ] ; then 600 println "\n===> zstd fifo named pipe test " 601 echo "Hello World!" > tmp_original 602 mkfifo tmp_named_pipe 603 # note : fifo test doesn't work in combination with `dd` or `cat` 604 echo "Hello World!" > tmp_named_pipe & 605 zstd tmp_named_pipe -o tmp_compressed 606 zstd -d -o tmp_decompressed tmp_compressed 607 $DIFF -s tmp_original tmp_decompressed 608 rm -rf tmp* 609 fi 610 611 println "\n===> zstd created file permissions tests" 612 if [ "$isWindows" = false ] ; then 613 rm -f tmp1 tmp2 tmp1.zst tmp2.zst tmp1.out tmp2.out # todo: remove 614 615 ORIGINAL_UMASK=$(umask) 616 umask 0000 617 618 datagen > tmp1 619 datagen > tmp2 620 assertFilePermissions tmp1 666 621 assertFilePermissions tmp2 666 622 623 println "test : copy 666 permissions in file -> file compression " 624 zstd -f tmp1 -o tmp1.zst 625 assertSamePermissions tmp1 tmp1.zst 626 println "test : copy 666 permissions in file -> file decompression " 627 zstd -f -d tmp1.zst -o tmp1.out 628 assertSamePermissions tmp1.zst tmp1.out 629 630 rm -f tmp1.zst tmp1.out 631 632 println "test : copy 400 permissions in file -> file compression (write to a read-only file) " 633 chmod 0400 tmp1 634 assertFilePermissions tmp1 400 635 zstd -f tmp1 -o tmp1.zst 636 assertSamePermissions tmp1 tmp1.zst 637 println "test : copy 400 permissions in file -> file decompression (write to a read-only file) " 638 zstd -f -d tmp1.zst -o tmp1 639 assertSamePermissions tmp1.zst tmp1 640 641 rm -f tmp1.zst tmp1.out 642 643 println "test : check created permissions from stdin input in compression " 644 zstd -f -o tmp1.zst < tmp1 645 assertFilePermissions tmp1.zst 666 646 println "test : check created permissions from stdin input in decompression " 647 zstd -f -d -o tmp1.out < tmp1.zst 648 assertFilePermissions tmp1.out 666 649 650 rm -f tmp1.zst tmp1.out 651 652 println "test : check created permissions from multiple inputs in compression " 653 zstd -f tmp1 tmp2 -o tmp1.zst 654 assertFilePermissions tmp1.zst 666 655 println "test : check created permissions from multiple inputs in decompression " 656 cp tmp1.zst tmp2.zst 657 zstd -f -d tmp1.zst tmp2.zst -o tmp1.out 658 assertFilePermissions tmp1.out 666 659 660 rm -f tmp1.zst tmp2.zst tmp1.out tmp2.out 661 662 println "test : check permissions on pre-existing output file in compression " 663 chmod 0600 tmp1 664 touch tmp1.zst 665 chmod 0400 tmp1.zst 666 zstd -f tmp1 -o tmp1.zst 667 assertFilePermissions tmp1.zst 600 668 println "test : check permissions on pre-existing output file in decompression " 669 chmod 0400 tmp1.zst 670 touch tmp1.out 671 chmod 0200 tmp1.out 672 zstd -f -d tmp1.zst -o tmp1.out 673 assertFilePermissions tmp1.out 400 674 675 umask 0666 676 chmod 0666 tmp1 tmp2 677 678 rm -f tmp1.zst tmp1.out 679 680 println "test : respect umask when compressing from stdin input " 681 zstd -f -o tmp1.zst < tmp1 682 assertFilePermissions tmp1.zst 0 683 println "test : respect umask when decompressing from stdin input " 684 chmod 0666 tmp1.zst 685 zstd -f -d -o tmp1.out < tmp1.zst 686 assertFilePermissions tmp1.out 0 687 688 rm -f tmp1 tmp2 tmp1.zst tmp2.zst tmp1.out tmp2.out 689 umask $ORIGINAL_UMASK 690 fi 691 692 if [ -n "$DEVNULLRIGHTS" ] ; then 693 # these tests requires sudo rights, which is uncommon. 694 # they are only triggered if DEVNULLRIGHTS macro is defined. 695 println "\n===> checking /dev/null permissions are unaltered " 696 datagen > tmp 697 sudoZstd tmp -o $INTOVOID # sudo rights could modify /dev/null permissions 698 sudoZstd tmp -c > $INTOVOID 699 zstd tmp -f -o tmp.zst 700 sudoZstd -d tmp.zst -c > $INTOVOID 701 sudoZstd -d tmp.zst -o $INTOVOID 702 ls -las $INTOVOID | $GREP "rw-rw-rw-" 703 fi 704 705 if [ -n "$READFROMBLOCKDEVICE" ] ; then 706 # This creates a temporary block device, which is only possible on unix-y 707 # systems, is somewhat invasive, and requires sudo. For these reasons, you 708 # have to specifically ask for this test. 709 println "\n===> checking that zstd can read from a block device" 710 datagen -g65536 > tmp.img 711 sudo losetup -fP tmp.img 712 LOOP_DEV=$(losetup -a | $GREP 'tmp\.img' | cut -f1 -d:) 713 [ -z "$LOOP_DEV" ] && die "failed to get loopback device" 714 sudoZstd $LOOP_DEV -c > tmp.img.zst && die "should fail without -f" 715 sudoZstd -f $LOOP_DEV -c > tmp.img.zst 716 zstd -d tmp.img.zst -o tmp.img.copy 717 sudo losetup -d $LOOP_DEV 718 $DIFF -s tmp.img tmp.img.copy || die "round trip failed" 719 rm -f tmp.img tmp.img.zst tmp.img.copy 720 fi 721 722 println "\n===> zstd created file timestamp tests" 723 datagen > tmp 724 touch -m -t 200001010000.00 tmp 725 println "test : copy mtime in file -> file compression " 726 zstd -f tmp -o tmp.zst 727 assertSameMTime tmp tmp.zst 728 println "test : copy mtime in file -> file decompression " 729 zstd -f -d tmp.zst -o tmp.out 730 assertSameMTime tmp.zst tmp.out 731 rm -f tmp 732 733 println "\n===> compress multiple files into an output directory, --output-dir-flat" 734 println henlo > tmp1 735 mkdir tmpInputTestDir 736 mkdir tmpInputTestDir/we 737 mkdir tmpInputTestDir/we/must 738 mkdir tmpInputTestDir/we/must/go 739 mkdir tmpInputTestDir/we/must/go/deeper 740 println cool > tmpInputTestDir/we/must/go/deeper/tmp2 741 mkdir tmpOutDir 742 zstd tmp1 tmpInputTestDir/we/must/go/deeper/tmp2 --output-dir-flat tmpOutDir 743 test -f tmpOutDir/tmp1.zst 744 test -f tmpOutDir/tmp2.zst 745 println "test : decompress multiple files into an output directory, --output-dir-flat" 746 mkdir tmpOutDirDecomp 747 zstd tmpOutDir -r -d --output-dir-flat tmpOutDirDecomp 748 test -f tmpOutDirDecomp/tmp2 749 test -f tmpOutDirDecomp/tmp1 750 rm -f tmpOutDirDecomp/* 751 zstd tmpOutDir -r -d --output-dir-flat=tmpOutDirDecomp 752 test -f tmpOutDirDecomp/tmp2 753 test -f tmpOutDirDecomp/tmp1 754 rm -rf tmp* 755 756 if [ "$isWindows" = false ] ; then 757 println "\n===> compress multiple files into an output directory and mirror input folder, --output-dir-mirror" 758 println "test --output-dir-mirror" > tmp1 759 mkdir -p tmpInputTestDir/we/.../..must/go/deeper.. 760 println cool > tmpInputTestDir/we/.../..must/go/deeper../tmp2 761 zstd tmp1 -r tmpInputTestDir --output-dir-mirror tmpOutDir 762 test -f tmpOutDir/tmp1.zst 763 test -f tmpOutDir/tmpInputTestDir/we/.../..must/go/deeper../tmp2.zst 764 765 println "test: compress input dir will be ignored if it has '..'" 766 zstd -r tmpInputTestDir/we/.../..must/../..mustgo/deeper.. --output-dir-mirror non-exist && die "input cannot contain '..'" 767 zstd -r tmpInputTestDir/we/.../..must/deeper../.. --output-dir-mirror non-exist && die "input cannot contain '..'" 768 zstd -r ../tests/tmpInputTestDir/we/.../..must/deeper.. --output-dir-mirror non-exist && die "input cannot contain '..'" 769 test ! -d non-exist 770 771 println "test: compress input dir should succeed with benign uses of '..'" 772 zstd -r tmpInputTestDir/we/.../..must/go/deeper.. --output-dir-mirror tmpout 773 test -d tmpout 774 775 println "test : decompress multiple files into an output directory, --output-dir-mirror" 776 zstd tmpOutDir -r -d --output-dir-mirror tmpOutDirDecomp 777 test -f tmpOutDirDecomp/tmpOutDir/tmp1 778 test -f tmpOutDirDecomp/tmpOutDir/tmpInputTestDir/we/.../..must/go/deeper../tmp2 779 780 println "test: decompress input dir will be ignored if it has '..'" 781 zstd -r tmpOutDir/tmpInputTestDir/we/.../..must/../..must --output-dir-mirror non-exist && die "input cannot contain '..'" 782 test ! -d non-exist 783 784 rm -rf tmp* 785 fi 786 787 788 println "test : compress multiple files reading them from a file, --filelist=FILE" 789 println "Hello world!, file1" > tmp1 790 println "Hello world!, file2" > tmp2 791 println tmp1 > tmp_fileList 792 println tmp2 >> tmp_fileList 793 zstd -f --filelist=tmp_fileList 794 test -f tmp2.zst 795 test -f tmp1.zst 796 797 println "test : alternate syntax: --filelist FILE" 798 zstd -f --filelist tmp_fileList 799 test -f tmp2.zst 800 test -f tmp1.zst 801 802 println "test : reading file list from a symlink, --filelist=FILE" 803 rm -f *.zst 804 ln -s tmp_fileList tmp_symLink 805 zstd -f --filelist=tmp_symLink 806 test -f tmp2.zst 807 test -f tmp1.zst 808 809 println "test : compress multiple files reading them from multiple files, --filelist=FILE" 810 rm -f *.zst 811 println "Hello world!, file3" > tmp3 812 println "Hello world!, file4" > tmp4 813 println tmp3 > tmp_fileList2 814 println tmp4 >> tmp_fileList2 815 zstd -f --filelist=tmp_fileList --filelist=tmp_fileList2 816 test -f tmp1.zst 817 test -f tmp2.zst 818 test -f tmp3.zst 819 test -f tmp4.zst 820 821 println "test : decompress multiple files reading them from a file, --filelist=FILE" 822 rm -f tmp1 tmp2 823 println tmp1.zst > tmpZst 824 println tmp2.zst >> tmpZst 825 zstd -d -f --filelist=tmpZst 826 test -f tmp1 827 test -f tmp2 828 829 println "test : decompress multiple files reading them from multiple files, --filelist=FILE" 830 rm -f tmp1 tmp2 tmp3 tmp4 831 println tmp3.zst > tmpZst2 832 println tmp4.zst >> tmpZst2 833 zstd -d -f --filelist=tmpZst --filelist=tmpZst2 834 test -f tmp1 835 test -f tmp2 836 test -f tmp3 837 test -f tmp4 838 839 println "test : survive the list of files with too long filenames (--filelist=FILE)" 840 datagen -g5M > tmp_badList 841 zstd -qq -f --filelist=tmp_badList && die "should have failed : file name length is too long" # printing very long text garbage on console will cause CI failure 842 843 println "test : survive a list of files which is text garbage (--filelist=FILE)" 844 datagen > tmp_badList 845 zstd -qq -f --filelist=tmp_badList && die "should have failed : list is text garbage" # printing very long text garbage on console will cause CI failure 846 847 println "test : survive a list of files which is binary garbage (--filelist=FILE)" 848 datagen -P0 -g1M > tmp_badList 849 zstd -qq -f --filelist=tmp_badList && die "should have failed : list is binary garbage" # let's avoid printing binary garbage on console 850 851 println "test : try to overflow internal list of files (--filelist=FILE)" 852 touch tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 853 ls tmp* > tmpList 854 zstd -f tmp1 --filelist=tmpList --filelist=tmpList tmp2 tmp3 # can trigger an overflow of internal file list 855 rm -rf tmp* 856 857 println "\n===> --[no-]content-size tests" 858 859 datagen > tmp_contentsize 860 zstd -f tmp_contentsize 861 zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" 862 zstd -f --no-content-size tmp_contentsize 863 zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" && die 864 zstd -f --content-size tmp_contentsize 865 zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" 866 zstd -f --content-size --no-content-size tmp_contentsize 867 zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" && die 868 rm -rf tmp* 869 870 println "test : show-default-cparams regular" 871 datagen > tmp 872 zstd --show-default-cparams -f tmp 873 zstd --show-default-cparams -d tmp.zst && die "error: can't use --show-default-cparams in decompression mode" 874 rm -rf tmp* 875 876 println "test : show-default-cparams recursive" 877 mkdir tmp_files 878 datagen -g15000 > tmp_files/tmp1 879 datagen -g129000 > tmp_files/tmp2 880 datagen -g257000 > tmp_files/tmp3 881 zstd --show-default-cparams -f -r tmp_files 882 rm -rf tmp* 883 884 println "test : show compression parameters in verbose mode" 885 datagen > tmp 886 zstd -vv tmp 2>&1 | \ 887 $GREP -q -- "--zstd=wlog=[0-9]*,clog=[0-9]*,hlog=[0-9]*,slog=[0-9]*,mml=[0-9]*,tlen=[0-9]*,strat=[0-9]*" 888 rm -rf tmp* 889 890 println "\n===> Advanced compression parameters " 891 println "Hello world!" | zstd --zstd=windowLog=21, - -o tmp.zst && die "wrong parameters not detected!" 892 println "Hello world!" | zstd --zstd=windowLo=21 - -o tmp.zst && die "wrong parameters not detected!" 893 println "Hello world!" | zstd --zstd=windowLog=21,slog - -o tmp.zst && die "wrong parameters not detected!" 894 println "Hello world!" | zstd --zstd=strategy=10 - -o tmp.zst && die "parameter out of bound not detected!" # > btultra2 : does not exist 895 test ! -f tmp.zst # tmp.zst should not be created 896 roundTripTest -g512K 897 roundTripTest -g512K " --zstd=mml=3,tlen=48,strat=6" 898 roundTripTest -g512K " --zstd=strat=6,wlog=23,clog=23,hlog=22,slog=6" 899 roundTripTest -g512K " --zstd=windowLog=23,chainLog=23,hashLog=22,searchLog=6,minMatch=3,targetLength=48,strategy=6" 900 roundTripTest -g512K " --single-thread --long --zstd=ldmHashLog=20,ldmMinMatch=64,ldmBucketSizeLog=1,ldmHashRateLog=7" 901 roundTripTest -g512K " --single-thread --long --zstd=lhlog=20,lmml=64,lblog=1,lhrlog=7" 902 roundTripTest -g64K "19 --zstd=strat=9" # btultra2 903 904 905 println "\n===> Pass-Through mode " 906 println "Hello world 1!" | zstd -df 907 println "Hello world 2!" | zstd -dcf 908 println "Hello world 3!" > tmp1 909 zstd -dcf tmp1 910 println "" | zstd -df > tmp1 911 println "" > tmp2 912 $DIFF -q tmp1 tmp2 913 println "1" | zstd -df > tmp1 914 println "1" > tmp2 915 $DIFF -q tmp1 tmp2 916 println "12" | zstd -df > tmp1 917 println "12" > tmp2 918 $DIFF -q tmp1 tmp2 919 rm -rf tmp* 920 921 922 println "\n===> frame concatenation " 923 println "hello " > hello.tmp 924 println "world!" > world.tmp 925 cat hello.tmp world.tmp > helloworld.tmp 926 zstd -c hello.tmp > hello.zst 927 zstd -c world.tmp > world.zst 928 zstd -c hello.tmp world.tmp > helloworld.zst 929 zstd -dc helloworld.zst > result.tmp 930 $DIFF helloworld.tmp result.tmp 931 cat hello.zst world.zst > helloworld.zst 932 zstd -dc helloworld.zst > result.tmp 933 cat result.tmp 934 $DIFF helloworld.tmp result.tmp 935 println "frame concatenation without checksum" 936 zstd -c hello.tmp > hello.zst --no-check 937 zstd -c world.tmp > world.zst --no-check 938 cat hello.zst world.zst > helloworld.zstd 939 zstd -dc helloworld.zst > result.tmp 940 $DIFF helloworld.tmp result.tmp 941 println "testing zstdcat symlink" 942 ln -sf "$ZSTD_BIN" zstdcat 943 $EXE_PREFIX ./zstdcat helloworld.zst > result.tmp 944 $DIFF helloworld.tmp result.tmp 945 ln -s helloworld.zst helloworld.link.zst 946 $EXE_PREFIX ./zstdcat helloworld.link.zst > result.tmp 947 $DIFF helloworld.tmp result.tmp 948 rm -f zstdcat 949 rm -f result.tmp 950 println "testing zcat symlink" 951 ln -sf "$ZSTD_BIN" zcat 952 $EXE_PREFIX ./zcat helloworld.zst > result.tmp 953 $DIFF helloworld.tmp result.tmp 954 $EXE_PREFIX ./zcat helloworld.link.zst > result.tmp 955 $DIFF helloworld.tmp result.tmp 956 rm -f zcat 957 rm -f ./*.tmp ./*.zstd 958 println "frame concatenation tests completed" 959 960 961 if [ "$isWindows" = false ] && [ "$UNAME" != 'SunOS' ] && [ "$UNAME" != "OpenBSD" ] && [ "$UNAME" != "AIX" ]; then 962 println "\n**** flush write error test **** " 963 964 println "println foo | zstd > /dev/full" 965 println foo | zstd > /dev/full && die "write error not detected!" 966 println "println foo | zstd | zstd -d > /dev/full" 967 println foo | zstd | zstd -d > /dev/full && die "write error not detected!" 968 969 fi 970 971 972 if [ "$isWindows" = false ] && [ "$UNAME" != 'SunOS' ] ; then 973 974 println "\n===> symbolic link test " 975 976 rm -f hello.tmp world.tmp world2.tmp hello.tmp.zst world.tmp.zst 977 println "hello world" > hello.tmp 978 ln -s hello.tmp world.tmp 979 ln -s hello.tmp world2.tmp 980 zstd world.tmp hello.tmp || true 981 test -f hello.tmp.zst # regular file should have been compressed! 982 test ! -f world.tmp.zst # symbolic link should not have been compressed! 983 zstd world.tmp || true 984 test ! -f world.tmp.zst # symbolic link should not have been compressed! 985 zstd world.tmp world2.tmp || true 986 test ! -f world.tmp.zst # symbolic link should not have been compressed! 987 test ! -f world2.tmp.zst # symbolic link should not have been compressed! 988 zstd world.tmp hello.tmp -f 989 test -f world.tmp.zst # symbolic link should have been compressed with --force 990 rm -f hello.tmp world.tmp world2.tmp hello.tmp.zst world.tmp.zst 991 992 fi 993 994 995 println "\n===> test sparse file support " 996 997 datagen -g5M -P100 > tmpSparse 998 zstd tmpSparse -c | zstd -dv -o tmpSparseRegen 999 $DIFF -s tmpSparse tmpSparseRegen 1000 zstd tmpSparse -c | zstd -dv --sparse -c > tmpOutSparse 1001 $DIFF -s tmpSparse tmpOutSparse 1002 zstd tmpSparse -c | zstd -dv --no-sparse -c > tmpOutNoSparse 1003 $DIFF -s tmpSparse tmpOutNoSparse 1004 ls -ls tmpSparse* # look at file size and block size on disk 1005 datagen -s1 -g1200007 -P100 | zstd | zstd -dv --sparse -c > tmpSparseOdd # Odd size file (to not finish on an exact nb of blocks) 1006 datagen -s1 -g1200007 -P100 | $DIFF -s - tmpSparseOdd 1007 ls -ls tmpSparseOdd # look at file size and block size on disk 1008 println "\n Sparse Compatibility with Console :" 1009 println "Hello World 1 !" | zstd | zstd -d -c 1010 println "Hello World 2 !" | zstd | zstd -d | cat 1011 println "\n Sparse Compatibility with Append :" 1012 datagen -P100 -g1M > tmpSparse1M 1013 cat tmpSparse1M tmpSparse1M > tmpSparse2M 1014 zstd -v -f tmpSparse1M -o tmpSparseCompressed 1015 zstd -d -v -f tmpSparseCompressed -o tmpSparseRegenerated 1016 zstd -d -v -f tmpSparseCompressed -c >> tmpSparseRegenerated 1017 ls -ls tmpSparse* # look at file size and block size on disk 1018 $DIFF tmpSparse2M tmpSparseRegenerated 1019 rm -f tmpSparse* 1020 1021 1022 println "\n===> stream-size mode" 1023 1024 datagen -g11000 > tmp 1025 println "test : basic file compression vs sized streaming compression" 1026 file_size=$(zstd -14 -f tmp -o tmp.zst && wc -c < tmp.zst) 1027 stream_size=$(cat tmp | zstd -14 --stream-size=11000 | wc -c) 1028 if [ "$stream_size" -gt "$file_size" ]; then 1029 die "hinted compression larger than expected" 1030 fi 1031 println "test : sized streaming compression and decompression" 1032 cat tmp | zstd -14 -f tmp -o tmp.zst --stream-size=11000 1033 zstd -df tmp.zst -o tmp_decompress 1034 cmp tmp tmp_decompress || die "difference between original and decompressed file" 1035 println "test : incorrect stream size" 1036 cat tmp | zstd -14 -f -o tmp.zst --stream-size=11001 && die "should fail with incorrect stream size" 1037 1038 println "\n===> zstd zero weight dict test " 1039 rm -f tmp* 1040 cp "$TESTDIR/dict-files/zero-weight-dict" tmp_input 1041 zstd -D "$TESTDIR/dict-files/zero-weight-dict" tmp_input 1042 zstd -D "$TESTDIR/dict-files/zero-weight-dict" -d tmp_input.zst -o tmp_decomp 1043 $DIFF tmp_decomp tmp_input 1044 rm -rf tmp* 1045 1046 println "\n===> zstd (valid) zero weight dict test " 1047 rm -f tmp* 1048 # 0 has a non-zero weight in the dictionary 1049 echo "0000000000000000000000000" > tmp_input 1050 zstd -D "$TESTDIR/dict-files/zero-weight-dict" tmp_input 1051 zstd -D "$TESTDIR/dict-files/zero-weight-dict" -d tmp_input.zst -o tmp_decomp 1052 $DIFF tmp_decomp tmp_input 1053 rm -rf tmp* 1054 1055 println "\n===> size-hint mode" 1056 1057 datagen -g11000 > tmp 1058 datagen -g11000 > tmp2 1059 datagen > tmpDict 1060 println "test : basic file compression vs hinted streaming compression" 1061 file_size=$(zstd -14 -f tmp -o tmp.zst && wc -c < tmp.zst) 1062 stream_size=$(cat tmp | zstd -14 --size-hint=11000 | wc -c) 1063 if [ "$stream_size" -ge "$file_size" ]; then 1064 die "hinted compression larger than expected" 1065 fi 1066 println "test : hinted streaming compression and decompression" 1067 cat tmp | zstd -14 -f -o tmp.zst --size-hint=11000 1068 zstd -df tmp.zst -o tmp_decompress 1069 cmp tmp tmp_decompress || die "difference between original and decompressed file" 1070 println "test : hinted streaming compression with dictionary" 1071 cat tmp | zstd -14 -f -D tmpDict --size-hint=11000 | zstd -t -D tmpDict 1072 println "test : multiple file compression with hints and dictionary" 1073 zstd -14 -f -D tmpDict --size-hint=11000 tmp tmp2 1074 zstd -14 -f -o tmp1_.zst -D tmpDict --size-hint=11000 tmp 1075 zstd -14 -f -o tmp2_.zst -D tmpDict --size-hint=11000 tmp2 1076 cmp tmp.zst tmp1_.zst || die "first file's output differs" 1077 cmp tmp2.zst tmp2_.zst || die "second file's output differs" 1078 println "test : incorrect hinted stream sizes" 1079 cat tmp | zstd -14 -f --size-hint=11050 | zstd -t # slightly too high 1080 cat tmp | zstd -14 -f --size-hint=10950 | zstd -t # slightly too low 1081 cat tmp | zstd -14 -f --size-hint=22000 | zstd -t # considerably too high 1082 cat tmp | zstd -14 -f --size-hint=5500 | zstd -t # considerably too low 1083 println "test : allows and interprets K,KB,KiB,M,MB and MiB suffix" 1084 cat tmp | zstd -14 -f --size-hint=11K | zstd -t 1085 cat tmp | zstd -14 -f --size-hint=11KB | zstd -t 1086 cat tmp | zstd -14 -f --size-hint=11KiB | zstd -t 1087 cat tmp | zstd -14 -f --size-hint=1M | zstd -t 1088 cat tmp | zstd -14 -f --size-hint=1MB | zstd -t 1089 cat tmp | zstd -14 -f --size-hint=1MiB | zstd -t 1090 1091 1092 println "\n===> dictionary tests " 1093 println "- Test high/low compressibility corpus training" 1094 datagen -g12M -P90 > tmpCorpusHighCompress 1095 datagen -g12M -P5 > tmpCorpusLowCompress 1096 zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress 1097 zstd --train -B2K tmpCorpusLowCompress -o tmpDictLowCompress 1098 rm -f tmpCorpusHighCompress tmpCorpusLowCompress tmpDictHighCompress tmpDictLowCompress 1099 println "- Test with raw dict (content only) " 1100 datagen > tmpDict 1101 datagen -g1M | $MD5SUM > tmp1 1102 datagen -g1M | zstd -D tmpDict | zstd -D tmpDict -dvq | $MD5SUM > tmp2 1103 $DIFF -q tmp1 tmp2 1104 println "- Create first dictionary " 1105 TESTFILE="$PRGDIR"/zstdcli.c 1106 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict 1107 cp "$TESTFILE" tmp 1108 println "- Test dictionary compression with tmpDict as an input file and dictionary" 1109 zstd -f tmpDict -D tmpDict && die "compression error not detected!" 1110 println "- Dictionary compression roundtrip" 1111 zstd -f tmp -D tmpDict 1112 zstd -d tmp.zst -D tmpDict -fo result 1113 $DIFF "$TESTFILE" result 1114 println "- Dictionary compression with hlog < clog" 1115 zstd -6f tmp -D tmpDict --zstd=clog=25,hlog=23 1116 println "- Dictionary compression with btlazy2 strategy" 1117 zstd -f tmp -D tmpDict --zstd=strategy=6 1118 zstd -d tmp.zst -D tmpDict -fo result 1119 $DIFF "$TESTFILE" result 1120 if [ -e /proc/self/fd/0 ]; then 1121 println "- Test rejecting irregular dictionary file" 1122 cat tmpDict | zstd -f tmp -D /proc/self/fd/0 && die "Piped dictionary should fail!" 1123 cat tmpDict | zstd -d tmp.zst -D /proc/self/fd/0 -f && die "Piped dictionary should fail!" 1124 fi 1125 if [ -n "$hasMT" ] 1126 then 1127 println "- Test dictionary compression with multithreading " 1128 datagen -g5M | zstd -T2 -D tmpDict | zstd -t -D tmpDict # fails with v1.3.2 1129 fi 1130 println "- Create second (different) dictionary " 1131 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c "$PRGDIR"/*.h -o tmpDictC 1132 zstd -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!" 1133 println "- Create dictionary with short dictID" 1134 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1 1135 cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" 1136 println "- Create dictionary with wrong dictID parameter order (must fail)" 1137 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID -o 1 tmpDict1 && die "wrong order : --dictID must be followed by argument " 1138 println "- Create dictionary with size limit" 1139 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K -v 1140 println "- Create dictionary with small size limit" 1141 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict3 --maxdict=1K -v 1142 println "- Create dictionary with wrong parameter order (must fail)" 1143 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict3 --maxdict -v 4K && die "wrong order : --maxdict must be followed by argument " 1144 println "- Compress without dictID" 1145 zstd -f tmp -D tmpDict1 --no-dictID 1146 zstd -d tmp.zst -D tmpDict -fo result 1147 $DIFF "$TESTFILE" result 1148 println "- Compress multiple files with dictionary" 1149 rm -rf dirTestDict 1150 mkdir dirTestDict 1151 cp "$TESTDIR"/*.c dirTestDict 1152 cp "$PRGDIR"/*.c dirTestDict 1153 cp "$PRGDIR"/*.h dirTestDict 1154 $MD5SUM dirTestDict/* > tmph1 1155 zstd -f --rm dirTestDict/* -D tmpDictC 1156 zstd -d --rm dirTestDict/*.zst -D tmpDictC # note : use internal checksum by default 1157 case "$UNAME" in 1158 Darwin) println "md5sum -c not supported on OS-X : test skipped" ;; # not compatible with OS-X's md5 1159 *) $MD5SUM -c tmph1 ;; 1160 esac 1161 rm -rf dirTestDict 1162 println "- dictionary builder on bogus input" 1163 println "Hello World" > tmp 1164 zstd --train-legacy -q tmp && die "Dictionary training should fail : not enough input source" 1165 datagen -P0 -g10M > tmp 1166 zstd --train-legacy -q tmp && die "Dictionary training should fail : source is pure noise" 1167 println "- Test -o before --train" 1168 rm -f tmpDict dictionary 1169 zstd -o tmpDict --train "$TESTDIR"/*.c "$PRGDIR"/*.c 1170 test -f tmpDict 1171 zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c 1172 test -f dictionary 1173 if [ -n "$hasMT" ] 1174 then 1175 println "- Create dictionary with multithreading enabled" 1176 zstd --train -T0 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict 1177 fi 1178 rm -f tmp* dictionary 1179 1180 println "- Test --memory for dictionary compression" 1181 datagen -g12M -P90 > tmpCorpusHighCompress 1182 zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=10K && die "Dictionary training should fail : --memory too low (10K)" 1183 zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=5MB 2> zstTrainWithMemLimitStdErr 1184 cat zstTrainWithMemLimitStdErr | $GREP "setting manual memory limit for dictionary training data at 5 MB" 1185 cat zstTrainWithMemLimitStdErr | $GREP "Training samples set too large (12 MB); training on 5 MB only..." 1186 rm zstTrainWithMemLimitStdErr 1187 1188 println "\n===> fastCover dictionary builder : advanced options " 1189 TESTFILE="$PRGDIR"/zstdcli.c 1190 datagen > tmpDict 1191 println "- Create first dictionary" 1192 zstd --train-fastcover=k=46,d=8,f=15,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict 1193 cp "$TESTFILE" tmp 1194 zstd -f tmp -D tmpDict 1195 zstd -d tmp.zst -D tmpDict -fo result 1196 $DIFF "$TESTFILE" result 1197 println "- Create second (different) dictionary" 1198 zstd --train-fastcover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c "$PRGDIR"/*.h -o tmpDictC 1199 zstd -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!" 1200 zstd --train-fastcover=k=56,d=8 && die "Create dictionary without input file" 1201 println "- Create dictionary with short dictID" 1202 zstd --train-fastcover=k=46,d=8,f=15,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1 1203 cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" 1204 println "- Create dictionaries with shrink-dict flag enabled" 1205 zstd --train-fastcover=steps=1,shrink "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict 1206 zstd --train-fastcover=steps=1,shrink=1 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict1 1207 zstd --train-fastcover=steps=1,shrink=5 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict2 1208 zstd --train-fastcover=shrink=5,steps=1 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict3 1209 println "- Create dictionary with size limit" 1210 zstd --train-fastcover=steps=1 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K 1211 println "- Create dictionary using all samples for both training and testing" 1212 zstd --train-fastcover=k=56,d=8,split=100 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1213 println "- Create dictionary using f=16" 1214 zstd --train-fastcover=k=56,d=8,f=16 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1215 zstd --train-fastcover=k=56,d=8,accel=15 -r "$TESTDIR"/*.c "$PRGDIR"/*.c && die "Created dictionary using accel=15" 1216 println "- Create dictionary using accel=2" 1217 zstd --train-fastcover=k=56,d=8,accel=2 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1218 println "- Create dictionary using accel=10" 1219 zstd --train-fastcover=k=56,d=8,accel=10 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1220 println "- Create dictionary with multithreading" 1221 zstd --train-fastcover -T4 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1222 println "- Test -o before --train-fastcover" 1223 rm -f tmpDict dictionary 1224 zstd -o tmpDict --train-fastcover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c 1225 test -f tmpDict 1226 zstd --train-fastcover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c 1227 test -f dictionary 1228 rm -f tmp* dictionary 1229 1230 1231 println "\n===> legacy dictionary builder " 1232 1233 TESTFILE="$PRGDIR"/zstdcli.c 1234 datagen > tmpDict 1235 println "- Create first dictionary" 1236 zstd --train-legacy=selectivity=8 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict 1237 cp "$TESTFILE" tmp 1238 zstd -f tmp -D tmpDict 1239 zstd -d tmp.zst -D tmpDict -fo result 1240 $DIFF "$TESTFILE" result 1241 zstd --train-legacy=s=8 && die "Create dictionary without input files (should error)" 1242 println "- Create second (different) dictionary" 1243 zstd --train-legacy=s=5 "$TESTDIR"/*.c "$PRGDIR"/*.c "$PRGDIR"/*.h -o tmpDictC 1244 zstd -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!" 1245 println "- Create dictionary with short dictID" 1246 zstd --train-legacy -s5 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1 1247 cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" 1248 println "- Create dictionary with size limit" 1249 zstd --train-legacy -s9 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K 1250 println "- Test -o before --train-legacy" 1251 rm -f tmpDict dictionary 1252 zstd -o tmpDict --train-legacy "$TESTDIR"/*.c "$PRGDIR"/*.c 1253 test -f tmpDict 1254 zstd --train-legacy "$TESTDIR"/*.c "$PRGDIR"/*.c 1255 test -f dictionary 1256 rm -f tmp* dictionary 1257 1258 1259 println "\n===> integrity tests " 1260 1261 println "test one file (tmp1.zst) " 1262 datagen > tmp1 1263 zstd tmp1 1264 zstd -t tmp1.zst 1265 zstd --test tmp1.zst 1266 println "test multiple files (*.zst) " 1267 zstd -t ./*.zst 1268 println "test bad files (*) " 1269 zstd -t ./* && die "bad files not detected !" 1270 zstd -t tmp1 && die "bad file not detected !" 1271 cp tmp1 tmp2.zst 1272 zstd -t tmp2.zst && die "bad file not detected !" 1273 datagen -g0 > tmp3 1274 zstd -t tmp3 && die "bad file not detected !" # detects 0-sized files as bad 1275 println "test --rm and --test combined " 1276 zstd -t --rm tmp1.zst 1277 test -f tmp1.zst # check file is still present 1278 cp tmp1.zst tmp2.zst 1279 zstd -t tmp1.zst tmp2.zst --rm 1280 test -f tmp1.zst # check file is still present 1281 test -f tmp2.zst # check file is still present 1282 split -b16384 tmp1.zst tmpSplit. 1283 zstd -t tmpSplit.* && die "bad file not detected !" 1284 datagen | zstd -c | zstd -t 1285 1286 1287 println "\n===> golden files tests " 1288 1289 zstd -t -r "$TESTDIR/golden-decompression" 1290 zstd -c -r "$TESTDIR/golden-compression" | zstd -t 1291 zstd -D "$TESTDIR/golden-dictionaries/http-dict-missing-symbols" "$TESTDIR/golden-compression/http" -c | zstd -D "$TESTDIR/golden-dictionaries/http-dict-missing-symbols" -t 1292 1293 1294 println "\n===> benchmark mode tests " 1295 1296 println "bench one file" 1297 datagen > tmp1 1298 zstd -bi0 tmp1 1299 println "bench multiple levels" 1300 zstd -i0b0e3 tmp1 1301 println "bench negative level" 1302 zstd -bi0 --fast tmp1 1303 println "with recursive and quiet modes" 1304 zstd -rqi0b1e2 tmp1 1305 println "benchmark decompression only" 1306 zstd -f tmp1 1307 zstd -b -d -i0 tmp1.zst 1308 println "benchmark can fail - decompression on invalid data" 1309 zstd -b -d -i0 tmp1 && die "invalid .zst data => benchmark should have failed" 1310 1311 GZIPMODE=1 1312 zstd --format=gzip -V || GZIPMODE=0 1313 if [ $GZIPMODE -eq 1 ]; then 1314 println "benchmark mode is only compatible with zstd" 1315 zstd --format=gzip -b tmp1 && die "-b should be incompatible with gzip format!" 1316 fi 1317 1318 println "\n===> zstd compatibility tests " 1319 1320 datagen > tmp 1321 rm -f tmp.zst 1322 zstd --format=zstd -f tmp 1323 test -f tmp.zst 1324 1325 1326 println "\n===> gzip compatibility tests " 1327 1328 GZIPMODE=1 1329 zstd --format=gzip -V || GZIPMODE=0 1330 if [ $GZIPMODE -eq 1 ]; then 1331 println "gzip support detected" 1332 GZIPEXE=1 1333 gzip -V || GZIPEXE=0 1334 if [ $GZIPEXE -eq 1 ]; then 1335 datagen > tmp 1336 zstd --format=gzip -f tmp 1337 gzip -t -v tmp.gz 1338 gzip -f tmp 1339 zstd -d -f -v tmp.gz 1340 rm -f tmp* 1341 else 1342 println "gzip binary not detected" 1343 fi 1344 else 1345 println "gzip mode not supported" 1346 fi 1347 1348 1349 println "\n===> gzip frame tests " 1350 1351 if [ $GZIPMODE -eq 1 ]; then 1352 datagen > tmp 1353 zstd -f --format=gzip tmp 1354 zstd -f tmp 1355 cat tmp.gz tmp.zst tmp.gz tmp.zst | zstd -d -f -o tmp 1356 truncateLastByte tmp.gz | zstd -t > $INTOVOID && die "incomplete frame not detected !" 1357 rm -f tmp* 1358 else 1359 println "gzip mode not supported" 1360 fi 1361 1362 if [ $GZIPMODE -eq 1 ]; then 1363 datagen > tmp 1364 rm -f tmp.zst 1365 zstd --format=gzip --format=zstd -f tmp 1366 test -f tmp.zst 1367 fi 1368 1369 println "\n===> xz compatibility tests " 1370 1371 LZMAMODE=1 1372 zstd --format=xz -V || LZMAMODE=0 1373 if [ $LZMAMODE -eq 1 ]; then 1374 println "xz support detected" 1375 XZEXE=1 1376 xz -Q -V && lzma -Q -V || XZEXE=0 1377 if [ $XZEXE -eq 1 ]; then 1378 println "Testing zstd xz and lzma support" 1379 datagen > tmp 1380 zstd --format=lzma -f tmp 1381 zstd --format=xz -f tmp 1382 xz -Q -t -v tmp.xz 1383 xz -Q -t -v tmp.lzma 1384 xz -Q -f -k tmp 1385 lzma -Q -f -k --lzma1 tmp 1386 zstd -d -f -v tmp.xz 1387 zstd -d -f -v tmp.lzma 1388 rm -f tmp* 1389 println "Creating symlinks" 1390 ln -s "$ZSTD_BIN" ./xz 1391 ln -s "$ZSTD_BIN" ./unxz 1392 ln -s "$ZSTD_BIN" ./lzma 1393 ln -s "$ZSTD_BIN" ./unlzma 1394 println "Testing xz and lzma symlinks" 1395 datagen > tmp 1396 ./xz tmp 1397 xz -Q -d tmp.xz 1398 ./lzma tmp 1399 lzma -Q -d tmp.lzma 1400 println "Testing unxz and unlzma symlinks" 1401 xz -Q tmp 1402 ./xz -d tmp.xz 1403 lzma -Q tmp 1404 ./lzma -d tmp.lzma 1405 rm -f xz unxz lzma unlzma 1406 rm -f tmp* 1407 else 1408 println "xz binary not detected" 1409 fi 1410 else 1411 println "xz mode not supported" 1412 fi 1413 1414 1415 println "\n===> xz frame tests " 1416 1417 if [ $LZMAMODE -eq 1 ]; then 1418 datagen > tmp 1419 zstd -f --format=xz tmp 1420 zstd -f --format=lzma tmp 1421 zstd -f tmp 1422 cat tmp.xz tmp.lzma tmp.zst tmp.lzma tmp.xz tmp.zst | zstd -d -f -o tmp 1423 truncateLastByte tmp.xz | zstd -t > $INTOVOID && die "incomplete frame not detected !" 1424 truncateLastByte tmp.lzma | zstd -t > $INTOVOID && die "incomplete frame not detected !" 1425 rm -f tmp* 1426 else 1427 println "xz mode not supported" 1428 fi 1429 1430 println "\n===> lz4 compatibility tests " 1431 1432 LZ4MODE=1 1433 zstd --format=lz4 -V || LZ4MODE=0 1434 if [ $LZ4MODE -eq 1 ]; then 1435 println "lz4 support detected" 1436 LZ4EXE=1 1437 lz4 -V || LZ4EXE=0 1438 if [ $LZ4EXE -eq 1 ]; then 1439 datagen > tmp 1440 zstd --format=lz4 -f tmp 1441 lz4 -t -v tmp.lz4 1442 lz4 -f -m tmp # ensure result is sent into tmp.lz4, not stdout 1443 zstd -d -f -v tmp.lz4 1444 rm -f tmp* 1445 else 1446 println "lz4 binary not detected" 1447 fi 1448 else 1449 println "lz4 mode not supported" 1450 fi 1451 1452 1453 if [ $LZ4MODE -eq 1 ]; then 1454 println "\n===> lz4 frame tests " 1455 datagen > tmp 1456 zstd -f --format=lz4 tmp 1457 zstd -f tmp 1458 cat tmp.lz4 tmp.zst tmp.lz4 tmp.zst | zstd -d -f -o tmp 1459 truncateLastByte tmp.lz4 | zstd -t > $INTOVOID && die "incomplete frame not detected !" 1460 rm -f tmp* 1461 else 1462 println "\nlz4 mode not supported" 1463 fi 1464 1465 1466 println "\n===> suffix list test" 1467 1468 ! zstd -d tmp.abc 2> tmplg 1469 1470 if [ $GZIPMODE -ne 1 ]; then 1471 $GREP ".gz" tmplg > $INTOVOID && die "Unsupported suffix listed" 1472 fi 1473 1474 if [ $LZMAMODE -ne 1 ]; then 1475 $GREP ".lzma" tmplg > $INTOVOID && die "Unsupported suffix listed" 1476 $GREP ".xz" tmplg > $INTOVOID && die "Unsupported suffix listed" 1477 fi 1478 1479 if [ $LZ4MODE -ne 1 ]; then 1480 $GREP ".lz4" tmplg > $INTOVOID && die "Unsupported suffix listed" 1481 fi 1482 1483 touch tmp1 1484 zstd tmp1 -o tmp1.zstd 1485 zstd -d -f tmp1.zstd # support .zstd suffix even though it's not the default suffix 1486 1487 println "\n===> tar extension tests " 1488 1489 rm -f tmp tmp.tar tmp.tzst tmp.tgz tmp.txz tmp.tlz4 tmp1.zstd 1490 1491 datagen > tmp 1492 tar -cf tmp.tar tmp 1493 zstd tmp.tar -o tmp.tzst 1494 rm -f tmp.tar 1495 zstd -d tmp.tzst 1496 [ -e tmp.tar ] || die ".tzst failed to decompress to .tar!" 1497 rm -f tmp.tar tmp.tzst 1498 1499 if [ $GZIPMODE -eq 1 ]; then 1500 tar -f - -c tmp | gzip > tmp.tgz 1501 zstd -d tmp.tgz 1502 [ -e tmp.tar ] || die ".tgz failed to decompress to .tar!" 1503 rm -f tmp.tar tmp.tgz 1504 fi 1505 1506 if [ $LZMAMODE -eq 1 ]; then 1507 tar -f - -c tmp | zstd --format=xz > tmp.txz 1508 zstd -d tmp.txz 1509 [ -e tmp.tar ] || die ".txz failed to decompress to .tar!" 1510 rm -f tmp.tar tmp.txz 1511 fi 1512 1513 if [ $LZ4MODE -eq 1 ]; then 1514 tar -f - -c tmp | zstd --format=lz4 > tmp.tlz4 1515 zstd -d tmp.tlz4 1516 [ -e tmp.tar ] || die ".tlz4 failed to decompress to .tar!" 1517 rm -f tmp.tar tmp.tlz4 1518 fi 1519 1520 touch tmp.t tmp.tz tmp.tzs 1521 ! zstd -d tmp.t 1522 ! zstd -d tmp.tz 1523 ! zstd -d tmp.tzs 1524 1525 1526 println "\n===> zstd round-trip tests " 1527 1528 roundTripTest 1529 roundTripTest -g15K # TableID==3 1530 roundTripTest -g127K # TableID==2 1531 roundTripTest -g255K # TableID==1 1532 roundTripTest -g522K # TableID==0 1533 roundTripTest -g519K 6 # greedy, hash chain 1534 roundTripTest -g517K 16 # btlazy2 1535 roundTripTest -g516K 19 # btopt 1536 1537 fileRoundTripTest -g500K 1538 1539 println "\n===> zstd long distance matching round-trip tests " 1540 roundTripTest -g0 "2 --single-thread --long" 1541 roundTripTest -g1000K "1 --single-thread --long" 1542 roundTripTest -g517K "6 --single-thread --long" 1543 roundTripTest -g516K "16 --single-thread --long" 1544 roundTripTest -g518K "19 --single-thread --long" 1545 roundTripTest -g2M "22 --single-thread --ultra --long" 1546 fileRoundTripTest -g5M "3 --single-thread --long" 1547 1548 1549 roundTripTest -g96K "5 --single-thread" 1550 if [ -n "$hasMT" ] 1551 then 1552 println "\n===> zstdmt round-trip tests " 1553 roundTripTest -g4M "1 -T0" 1554 roundTripTest -g4M "1 -T0 --auto-threads=physical" 1555 roundTripTest -g4M "1 -T0 --auto-threads=logical" 1556 roundTripTest -g8M "3 -T2" 1557 roundTripTest -g8000K "2 --threads=2" 1558 fileRoundTripTest -g4M "19 -T2 -B1M" 1559 1560 println "\n===> zstdmt long distance matching round-trip tests " 1561 roundTripTest -g8M "3 --long=24 -T2" 1562 1563 println "\n===> zstdmt environment variable tests " 1564 echo "multifoo" >> mt_tmp 1565 ZSTD_NBTHREADS=-3 zstd -f mt_tmp # negative value, warn and revert to default setting 1566 ZSTD_NBTHREADS='' zstd -f mt_tmp # empty env var, warn and revert to default setting 1567 ZSTD_NBTHREADS=- zstd -f mt_tmp # malformed env var, warn and revert to default setting 1568 ZSTD_NBTHREADS=a zstd -f mt_tmp # malformed env var, warn and revert to default setting 1569 ZSTD_NBTHREADS=+a zstd -f mt_tmp # malformed env var, warn and revert to default setting 1570 ZSTD_NBTHREADS=3a7 zstd -f mt_tmp # malformed env var, warn and revert to default setting 1571 ZSTD_NBTHREADS=50000000000 zstd -f mt_tmp # numeric value too large, warn and revert to default setting= 1572 ZSTD_NBTHREADS=2 zstd -f mt_tmp # correct usage 1573 ZSTD_NBTHREADS=1 zstd -f mt_tmp # correct usage: single thread 1574 # temporary envvar changes in the above tests would actually persist in macos /bin/sh 1575 unset ZSTD_NBTHREADS 1576 rm -f mt_tmp* 1577 1578 println "\n===> ovLog tests " 1579 datagen -g2MB > tmp 1580 refSize=$(zstd tmp -6 -c --zstd=wlog=18 | wc -c) 1581 ov9Size=$(zstd tmp -6 -c --zstd=wlog=18,ovlog=9 | wc -c) 1582 ov1Size=$(zstd tmp -6 -c --zstd=wlog=18,ovlog=1 | wc -c) 1583 if [ "$refSize" -eq "$ov9Size" ]; then 1584 echo ov9Size should be different from refSize 1585 exit 1 1586 fi 1587 if [ "$refSize" -eq "$ov1Size" ]; then 1588 echo ov1Size should be different from refSize 1589 exit 1 1590 fi 1591 if [ "$ov9Size" -ge "$ov1Size" ]; then 1592 echo ov9Size="$ov9Size" should be smaller than ov1Size="$ov1Size" 1593 exit 1 1594 fi 1595 1596 else 1597 println "\n===> no multithreading, skipping zstdmt tests " 1598 fi 1599 1600 rm -f tmp* 1601 1602 println "\n===> zstd --list/-l single frame tests " 1603 datagen > tmp1 1604 datagen > tmp2 1605 datagen > tmp3 1606 zstd tmp* 1607 zstd -l ./*.zst 1608 zstd -lv ./*.zst | $GREP "Decompressed Size:" # check that decompressed size is present in header 1609 zstd --list ./*.zst 1610 zstd --list -v ./*.zst 1611 1612 println "\n===> zstd --list/-l multiple frame tests " 1613 cat tmp1.zst tmp2.zst > tmp12.zst 1614 cat tmp12.zst tmp3.zst > tmp123.zst 1615 zstd -l ./*.zst 1616 zstd -lv ./*.zst 1617 1618 println "\n===> zstd --list/-l error detection tests " 1619 zstd -l tmp1 tmp1.zst && die "-l must fail on non-zstd file" 1620 zstd --list tmp* && die "-l must fail on non-zstd file" 1621 zstd -lv tmp1* && die "-l must fail on non-zstd file" 1622 zstd --list -v tmp2 tmp12.zst && die "-l must fail on non-zstd file" 1623 1624 println "test : detect truncated compressed file " 1625 TEST_DATA_FILE=truncatable-input.txt 1626 FULL_COMPRESSED_FILE=${TEST_DATA_FILE}.zst 1627 TRUNCATED_COMPRESSED_FILE=truncated-input.txt.zst 1628 datagen -g50000 > $TEST_DATA_FILE 1629 zstd -f $TEST_DATA_FILE -o $FULL_COMPRESSED_FILE 1630 dd bs=1 count=100 if=$FULL_COMPRESSED_FILE of=$TRUNCATED_COMPRESSED_FILE 1631 zstd --list $TRUNCATED_COMPRESSED_FILE && die "-l must fail on truncated file" 1632 1633 rm -f $TEST_DATA_FILE 1634 rm -f $FULL_COMPRESSED_FILE 1635 rm -f $TRUNCATED_COMPRESSED_FILE 1636 1637 println "\n===> zstd --list/-l errors when presented with stdin / no files" 1638 zstd -l && die "-l must fail on empty list of files" 1639 zstd -l - && die "-l does not work on stdin" 1640 zstd -l < tmp1.zst && die "-l does not work on stdin" 1641 zstd -l - < tmp1.zst && die "-l does not work on stdin" 1642 zstd -l - tmp1.zst && die "-l does not work on stdin" 1643 zstd -l - tmp1.zst < tmp1.zst && die "-l does not work on stdin" 1644 zstd -l tmp1.zst < tmp2.zst # this will check tmp1.zst, but not tmp2.zst, which is not an error : zstd simply doesn't read stdin in this case. It must not error just because stdin is not a tty 1645 1646 println "\n===> zstd --list/-l test with null files " 1647 datagen -g0 > tmp5 1648 zstd tmp5 1649 zstd -l tmp5.zst 1650 zstd -l tmp5* && die "-l must fail on non-zstd file" 1651 zstd -lv tmp5.zst | $GREP "Decompressed Size: 0 B (0 B)" # check that 0 size is present in header 1652 zstd -lv tmp5* && die "-l must fail on non-zstd file" 1653 1654 println "\n===> zstd --list/-l test with no content size field " 1655 datagen -g513K | zstd > tmp6.zst 1656 zstd -l tmp6.zst 1657 zstd -lv tmp6.zst | $GREP "Decompressed Size:" && die "Field :Decompressed Size: should not be available in this compressed file" 1658 1659 println "\n===> zstd --list/-l test with no checksum " 1660 zstd -f --no-check tmp1 1661 zstd -l tmp1.zst 1662 zstd -lv tmp1.zst 1663 1664 println "\n===> zstd trace tests " 1665 zstd -f --trace tmp.trace tmp1 1666 zstd -f --trace tmp.trace tmp1 tmp2 tmp3 1667 zstd -f --trace tmp.trace tmp1 tmp2 tmp3 -o /dev/null 1668 zstd -f --trace tmp.trace tmp1 tmp2 tmp3 --single-thread 1669 zstd -f --trace tmp.trace -D tmp1 tmp2 tmp3 -o /dev/null 1670 zstd -f --trace tmp.trace -D tmp1 tmp2 tmp3 -o /dev/null --single-thread 1671 zstd --trace tmp.trace -t tmp1.zst 1672 zstd --trace tmp.trace -t tmp1.zst tmp2.zst 1673 zstd -f --trace tmp.trace -d tmp1.zst 1674 zstd -f --trace tmp.trace -d tmp1.zst tmp2.zst tmp3.zst 1675 zstd -D tmp1 tmp2 -c | zstd --trace tmp.trace -t -D tmp1 1676 zstd -b1e10i0 --trace tmp.trace tmp1 1677 zstd -b1e10i0 --trace tmp.trace tmp1 tmp2 tmp3 1678 1679 rm -f tmp* 1680 1681 1682 println "\n===> zstd long distance matching tests " 1683 roundTripTest -g0 " --single-thread --long" 1684 roundTripTest -g9M "2 --single-thread --long" 1685 # Test parameter parsing 1686 roundTripTest -g1M -P50 "1 --single-thread --long=29" " --memory=512MB" 1687 roundTripTest -g1M -P50 "1 --single-thread --long=29 --zstd=wlog=28" " --memory=256MB" 1688 roundTripTest -g1M -P50 "1 --single-thread --long=29" " --long=28 --memory=512MB" 1689 roundTripTest -g1M -P50 "1 --single-thread --long=29" " --zstd=wlog=28 --memory=512MB" 1690 1691 1692 if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -ne "1" ]; then 1693 println "\n===> zstd long distance matching with optimal parser compressed size tests " 1694 optCSize16=$(datagen -g511K | zstd -16 -c | wc -c) 1695 longCSize16=$(datagen -g511K | zstd -16 --long -c | wc -c) 1696 optCSize19=$(datagen -g2M | zstd -19 -c | wc -c) 1697 longCSize19=$(datagen -g2M | zstd -19 --long -c | wc -c) 1698 optCSize19wlog23=$(datagen -g2M | zstd -19 -c --zstd=wlog=23 | wc -c) 1699 longCSize19wlog23=$(datagen -g2M | zstd -19 -c --long=23 | wc -c) 1700 if [ "$longCSize16" -gt "$optCSize16" ]; then 1701 echo using --long on compression level 16 should not cause compressed size regression 1702 exit 1 1703 elif [ "$longCSize19" -gt "$optCSize19" ]; then 1704 echo using --long on compression level 19 should not cause compressed size regression 1705 exit 1 1706 elif [ "$longCSize19wlog23" -gt "$optCSize19wlog23" ]; then 1707 echo using --long on compression level 19 with wLog=23 should not cause compressed size regression 1708 exit 1 1709 fi 1710 fi 1711 1712 println "\n===> zstd asyncio tests " 1713 1714 addFrame() { 1715 datagen -g2M -s$2 >> tmp_uncompressed 1716 datagen -g2M -s$2 | zstd -1 --format=$1 >> tmp_compressed.zst 1717 } 1718 1719 addTwoFrames() { 1720 addFrame $1 1 1721 addFrame $1 2 1722 } 1723 1724 testAsyncIO() { 1725 roundTripTest -g2M "3 --asyncio --format=$1" 1726 roundTripTest -g2M "3 --no-asyncio --format=$1" 1727 } 1728 1729 rm -f tmp_compressed tmp_uncompressed 1730 testAsyncIO zstd 1731 addTwoFrames zstd 1732 if [ $GZIPMODE -eq 1 ]; then 1733 testAsyncIO gzip 1734 addTwoFrames gzip 1735 fi 1736 if [ $LZMAMODE -eq 1 ]; then 1737 testAsyncIO lzma 1738 addTwoFrames lzma 1739 fi 1740 if [ $LZ4MODE -eq 1 ]; then 1741 testAsyncIO lz4 1742 addTwoFrames lz4 1743 fi 1744 cat tmp_uncompressed | $MD5SUM > tmp2 1745 zstd -d tmp_compressed.zst --asyncio -c | $MD5SUM > tmp1 1746 $DIFF -q tmp1 tmp2 1747 rm tmp1 1748 zstd -d tmp_compressed.zst --no-asyncio -c | $MD5SUM > tmp1 1749 $DIFF -q tmp1 tmp2 1750 1751 if [ "$1" != "--test-large-data" ]; then 1752 println "Skipping large data tests" 1753 exit 0 1754 fi 1755 1756 1757 ############################################################################# 1758 1759 1760 if [ -n "$hasMT" ] 1761 then 1762 println "\n===> adaptive mode " 1763 roundTripTest -g270000000 " --adapt" 1764 roundTripTest -g27000000 " --adapt=min=1,max=4" 1765 roundTripTest -g27000000 " --adapt=min=-2,max=-1" 1766 println "===> test: --adapt must fail on incoherent bounds " 1767 datagen > tmp 1768 zstd --adapt= tmp && die "invalid compression parameter" 1769 zstd -f -vv --adapt=min=10,max=9 tmp && die "--adapt must fail on incoherent bounds" 1770 1771 println "\n===> rsyncable mode " 1772 roundTripTest -g10M " --rsyncable" 1773 roundTripTest -g10M " --rsyncable -B100K" 1774 println "===> test: --rsyncable must fail with --single-thread" 1775 zstd -f -vv --rsyncable --single-thread tmp && die "--rsyncable must fail with --single-thread" 1776 fi 1777 1778 println "\n===> patch-from=origin tests" 1779 datagen -g1000 -P50 > tmp_dict 1780 datagen -g1000 -P10 > tmp_patch 1781 zstd --patch-from=tmp_dict tmp_patch -o tmp_patch_diff 1782 zstd -d --patch-from=tmp_dict tmp_patch_diff -o tmp_patch_recon 1783 $DIFF -s tmp_patch_recon tmp_patch 1784 1785 println "\n===> alternate syntax: patch-from origin" 1786 zstd -f --patch-from tmp_dict tmp_patch -o tmp_patch_diff 1787 zstd -df --patch-from tmp_dict tmp_patch_diff -o tmp_patch_recon 1788 $DIFF -s tmp_patch_recon tmp_patch 1789 rm -rf tmp_* 1790 1791 println "\n===> patch-from recursive tests" 1792 mkdir tmp_dir 1793 datagen > tmp_dir/tmp1 1794 datagen > tmp_dir/tmp2 1795 datagen > tmp_dict 1796 zstd --patch-from=tmp_dict -r tmp_dir && die 1797 rm -rf tmp* 1798 1799 println "\n===> patch-from long mode trigger larger file test" 1800 if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -eq "1" ]; then 1801 # if binary tree strategies are excluded, the threshold is different 1802 datagen -g10000000 > tmp_dict 1803 datagen -g10000000 > tmp_patch 1804 else 1805 datagen -g5000000 > tmp_dict 1806 datagen -g5000000 > tmp_patch 1807 fi 1808 zstd -15 --patch-from=tmp_dict tmp_patch 2>&1 | $GREP "long mode automatically triggered" 1809 rm -rf tmp* 1810 1811 println "\n===> patch-from very large dictionary and file test" 1812 datagen -g550000000 -P0 > tmp_dict 1813 datagen -g100000000 -P1 > tmp_patch 1814 zstd --long=30 -1f --patch-from tmp_dict tmp_patch 1815 zstd --long=30 -df --patch-from tmp_dict tmp_patch.zst -o tmp_patch_recon 1816 $DIFF -s tmp_patch_recon tmp_patch 1817 rm -rf tmp* 1818 1819 println "\n===> patch-from --stream-size test" 1820 datagen -g1000 -P50 > tmp_dict 1821 datagen -g1000 -P10 > tmp_patch 1822 cat tmp_patch | zstd -f --patch-from=tmp_dict -c -o tmp_patch_diff && die 1823 cat tmp_patch | zstd -f --patch-from=tmp_dict --stream-size=1000 -c -o tmp_patch_diff 1824 rm -rf tmp* 1825 1826 println "\n===> large files tests " 1827 1828 roundTripTest -g270000000 1 1829 roundTripTest -g250000000 2 1830 roundTripTest -g230000000 3 1831 1832 roundTripTest -g140000000 -P60 4 1833 roundTripTest -g130000000 -P62 5 1834 roundTripTest -g120000000 -P65 6 1835 1836 roundTripTest -g70000000 -P70 7 1837 roundTripTest -g60000000 -P71 8 1838 roundTripTest -g50000000 -P73 9 1839 1840 roundTripTest -g35000000 -P75 10 1841 roundTripTest -g30000000 -P76 11 1842 roundTripTest -g25000000 -P78 12 1843 1844 roundTripTest -g18000013 -P80 13 1845 roundTripTest -g18000014 -P80 14 1846 roundTripTest -g18000015 -P81 15 1847 roundTripTest -g18000016 -P84 16 1848 roundTripTest -g18000017 -P88 17 1849 roundTripTest -g18000018 -P94 18 1850 roundTripTest -g18000019 -P96 19 1851 1852 roundTripTest -g8M "19 --long" 1853 1854 roundTripTest -g5000000000 -P99 "1 --zstd=wlog=25" 1855 roundTripTest -g3700000000 -P0 "1 --zstd=strategy=6,wlog=25" # ensure btlazy2 can survive an overflow rescale 1856 1857 fileRoundTripTest -g4193M -P99 1 1858 1859 1860 println "\n===> zstd long, long distance matching round-trip tests " 1861 roundTripTest -g270000000 "1 --single-thread --long" 1862 roundTripTest -g130000000 -P60 "5 --single-thread --long" 1863 roundTripTest -g35000000 -P70 "8 --single-thread --long" 1864 roundTripTest -g18000001 -P80 "18 --single-thread --long" 1865 # Test large window logs 1866 roundTripTest -g700M -P50 "1 --single-thread --long=29" 1867 roundTripTest -g600M -P50 "1 --single-thread --long --zstd=wlog=29,clog=28" 1868 1869 1870 if [ -n "$hasMT" ] 1871 then 1872 println "\n===> zstdmt long round-trip tests " 1873 roundTripTest -g80000000 -P99 "19 -T2" " " 1874 roundTripTest -g5000000000 -P99 "1 -T2" " " 1875 roundTripTest -g500000000 -P97 "1 -T999" " " 1876 fileRoundTripTest -g4103M -P98 " -T0" " " 1877 roundTripTest -g400000000 -P97 "1 --long=24 -T2" " " 1878 # Exposes the bug in https://github.com/facebook/zstd/pull/1678 1879 # This test fails on 4 different travis builds at the time of writing 1880 # because it needs to allocate 8 GB of memory. 1881 # roundTripTest -g10G -P99 "1 -T1 --long=31 --zstd=clog=27 --fast=1000" 1882 else 1883 println "\n**** no multithreading, skipping zstdmt tests **** " 1884 fi 1885 1886 1887 println "\n===> cover dictionary builder : advanced options " 1888 1889 TESTFILE="$PRGDIR"/zstdcli.c 1890 datagen > tmpDict 1891 println "- Create first dictionary" 1892 zstd --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict 1893 cp "$TESTFILE" tmp 1894 zstd -f tmp -D tmpDict 1895 zstd -f tmp -D tmpDict --patch-from=tmpDict && die "error: can't use -D and --patch-from=#at the same time" 1896 zstd -d tmp.zst -D tmpDict -fo result 1897 $DIFF "$TESTFILE" result 1898 zstd --train-cover=k=56,d=8 && die "Create dictionary without input file (should error)" 1899 println "- Create second (different) dictionary" 1900 zstd --train-cover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c "$PRGDIR"/*.h -o tmpDictC 1901 zstd -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!" 1902 println "- Create dictionary using shrink-dict flag" 1903 zstd --train-cover=steps=256,shrink "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict 1904 zstd --train-cover=steps=256,shrink=1 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict1 1905 zstd --train-cover=steps=256,shrink=5 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict2 1906 zstd --train-cover=shrink=5,steps=256 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict3 1907 println "- Create dictionary with short dictID" 1908 zstd --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1 1909 cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" 1910 println "- Create dictionary with size limit" 1911 zstd --train-cover=steps=8 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K 1912 println "- Compare size of dictionary from 90% training samples with 80% training samples" 1913 zstd --train-cover=split=90 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1914 zstd --train-cover=split=80 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1915 println "- Create dictionary using all samples for both training and testing" 1916 zstd --train-cover=split=100 -r "$TESTDIR"/*.c "$PRGDIR"/*.c 1917 println "- Test -o before --train-cover" 1918 rm -f tmpDict dictionary 1919 zstd -o tmpDict --train-cover "$TESTDIR"/*.c "$PRGDIR"/*.c 1920 test -f tmpDict 1921 zstd --train-cover "$TESTDIR"/*.c "$PRGDIR"/*.c 1922 test -f dictionary 1923 rm -f tmp* dictionary 1924 1925 rm -f tmp* 1926