#!/bin/sh set -e if which valgrind > /dev/null; then VALGRIND='valgrind --error-exitcode=1 --leak-check=full --suppressions=tests/onig.supp' Q=-q else VALGRIND= Q= fi mods=$PWD/tests/modules cat $@ | $VALGRIND $Q ./jq -L "$mods" --run-tests set -x clean=true d= clean () { if ! $clean; then echo "See temp files in $d!" elif [ -n "$d" ]; then rm -rf "$d" fi } trap clean EXIT d=`mktemp -d -t || true` if [ -z "$d" ]; then echo "Your OS does not support mktemp(1) -d" 1>&2 exit 0 fi ## Test constant folding ## XXX If we add a builtin to list the program's disassembly then we can ## move all of these into tests/all.test # String constant folding (addition only) n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '"foo"' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi # Numeric constant folding (not all ops yet) n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '1+1' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '1-1' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '2*3' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '9/3' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '9==3' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '9!=3' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '9<=3' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi n=`$VALGRIND $Q ./jq -n --debug-dump-disasm '9>=3' | wc -l` if [ $n -ne 5 ]; then echo "Constant expression folding for strings didn't work" exit 1 fi ## Test JSON sequence support ## XXX If we add a `stream_fromjson` builtin then we can move these tests ## into tests/all.test cat > $d/expected < /dev/null 2> $d/out cmp $d/out $d/expected cat > $d/expected < /dev/null 2> $d/out cmp $d/out $d/expected # Note that here jq sees no inputs at all but it still succeeds because # --seq ignores parse errors cat > $d/expected < $d/out 2>&1 cmp $d/out $d/expected # Numeric values truncated by EOF are ignored cat > $d/expected < $d/out 2>&1 cmp $d/out $d/expected cat > $d/expected </dev/null 2> $d/out cmp $d/out $d/expected $VALGRIND $Q ./jq -n '0, 1, 2' > $d/a $VALGRIND $Q ./jq -n '3, 4, 5' > $d/b $VALGRIND $Q ./jq -i '.+1' $d/a $d/b $VALGRIND $Q ./jq -se '. == [1,2,3,4,5,6]' $d/a ## Test streaming parser ## If we add an option to stream to the `import ... as $symbol;` directive ## then we can move these tests into tests/all.test. $VALGRIND $Q ./jq -c '. as $d|path(..) as $p|$d|getpath($p)|scalars_or_empty|[$p,.]' < "$PWD/tests/torture/input0.json" > $d/out0 $VALGRIND $Q ./jq --stream -c '.|select(length==2)' < "$PWD/tests/torture/input0.json" > $d/out1 diff $d/out0 $d/out1 ## XXX This test can be moved to tests/all.test _now_ clean=false if which seq > /dev/null 2>&1; then # XXX We should try every prefix of input0.json, but that makes this # test very, very slow when run with valgrind, and the whole point # is to run it with valgrind. # #len=`wc -c < "$PWD/tests/torture/input0.json"` if [ -z "$VALGRIND" ]; then start=1 end=`wc -c < "$PWD/tests/torture/input0.json"` else start=120 end=151 fi for i in `seq $start $end`; do dd "if=tests/torture/input0.json" bs=$i count=1 2>/dev/null | $VALGRIND ./jq -c . > $d/out0 2>$d/err || true if [ -n "$VALGRIND" ]; then grep '^==[0-9][0-9]*== ERROR SUMMARY: 0 errors' $d/err > /dev/null else tail -1 $d/err | egrep -i 'assert|abort|core' && false fi dd "if=tests/torture/input0.json" bs=$i count=1 2>/dev/null | $VALGRIND ./jq -cn --stream -L "$mods" 'import "streaming" as streaming; streaming::tovalues(inputs)' > $d/out1 2>$d/err || true if [ -n "$VALGRIND" ]; then grep '^==[0-9][0-9]*== ERROR SUMMARY: 0 errors' $d/err > /dev/null else tail -1 $d/err | egrep -i 'assert|abort|core' && false fi diff $d/out0 $d/out1 done else echo "Not doing torture tests" fi ## Fuzz parser ## XXX With a `urandom` builtin we could move this test into tests/all.test clean=false if dd if=/dev/urandom bs=16 count=1024 > $d/rand 2>/dev/null; then # Have a /dev/urandom, good $VALGRIND $Q ./jq --seq . $d/rand >/dev/null 2>&1 $VALGRIND $Q ./jq --seq --stream . $d/rand >/dev/null 2>&1 dd if=/dev/urandom bs=16 count=1024 > $d/rand 2>/dev/null $VALGRIND $Q ./jq --seq . $d/rand >/dev/null 2>&1 $VALGRIND $Q ./jq --seq --stream . $d/rand >/dev/null 2>&1 dd if=/dev/urandom bs=16 count=1024 > $d/rand 2>/dev/null $VALGRIND $Q ./jq --seq . $d/rand >/dev/null 2>&1 $VALGRIND $Q ./jq --seq --stream . $d/rand >/dev/null 2>&1 fi clean=true ## Test library/module system # Check handling of ~/.jq; these can't move into jq_test.c yet because # they depend on $HOME if [ "`HOME="$mods" $VALGRIND $Q ./jq -nr fg`" != foobar ]; then echo "Bug #479 appears to be back" 1>&2 exit 1 fi if [ `HOME="$mods" $VALGRIND $Q ./jq --debug-dump-disasm -n fg | grep '^[a-z]' | wc -l` -gt 3 ]; then echo "Binding too many defs into program" 1>&2 exit 1 fi exit 0