summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2016-07-06 13:05:51 +0200
committerDave Reisner <dreisner@archlinux.org>2016-07-07 14:21:33 +0200
commita089c8622708d5249aa7830590464fb29dc799a4 (patch)
tree17fc700a3a687ff35817d9f0c7c9adf7c49102a2
parentd73d34e017ecb0e89c2de8e39da6b14afd6c5f1c (diff)
downloadmkinitcpio-a089c8622708d5249aa7830590464fb29dc799a4.tar.gz
mkinitcpio-a089c8622708d5249aa7830590464fb29dc799a4.tar.xz
add test harness for parse_cmdline
Some of these tests currently fail including hard failures where the shell quits entirely (this would lead to a kernel panic). A followup commit will rewrite the parse_cmdline function to improve it and fix these deficiencies.
-rw-r--r--Makefile3
-rwxr-xr-xtest/test_parse_cmdline233
2 files changed, 236 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 5af0eb2..6c70718 100644
--- a/Makefile
+++ b/Makefile
@@ -74,6 +74,9 @@ man/%: man/%.txt Makefile
-a manversion=$(VERSION) \
-a manmanual="mkinitcpio manual" $<
+check:
+ @r=0; for t in test/test_*; do $$t || { echo $$t fail; r=1; }; done; exit $$r
+
clean:
$(RM) mkinitcpio-${VERSION}.tar.gz $(MANPAGES)
diff --git a/test/test_parse_cmdline b/test/test_parse_cmdline
new file mode 100755
index 0000000..9afd9cb
--- /dev/null
+++ b/test/test_parse_cmdline
@@ -0,0 +1,233 @@
+#!/lib/initcpio/busybox ash
+
+. ./init_functions
+
+failed=0
+tests=0
+
+e_ok=0
+e_parser_failure=2
+e_assertion_failure=130
+
+assert() {
+ local expect_fail= key= expected_value= actual_value
+
+ if [ "$1" = '--expect-fail' ]; then
+ expect_fail=y
+ shift
+ fi
+
+ key=$1 expected_value=$2
+ eval actual_value=\$"$1"
+
+ case $actual_value in
+ $expected_value)
+ if [ -n "$expect_fail" ]; then
+ echo "EXPECTED FAIL: $key: expected='$expected_value', got='$actual_value'"
+ return 1
+ fi
+ ;;
+ *)
+ if [ -z "$expect_fail" ]; then
+ echo "FAIL: $key: expected='$expected_value', got='$actual_value'"
+ return 1
+ fi
+ ;;
+ esac
+
+ return 0
+}
+
+test_parse() {
+ local flag= cmdline= expect_fail= expect_parse_fail=
+
+ tests=$(( tests + 1 ))
+
+ for flag; do
+ case $flag in
+ --expect-fail)
+ expect_fail='--expect-fail'
+ shift
+ ;;
+ --expect-parse-fail)
+ expect_parse_fail=y
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+
+ cmdline=$1; shift
+ [ -n "$V" ] && echo "testing cmdline: $cmdline"
+
+ echo "$cmdline" | {
+ parse_cmdline
+
+ result=0
+ while [ "$#" -gt 0 ]; do
+ key=$1 expected_value=$2
+ shift 2
+
+ assert $expect_fail "$key" "$expected_value" || result=$e_assertion_failure
+ done
+
+ exit "$result"
+ } 2>/dev/null
+
+ case $? in
+ $e_parser_failure)
+ # parser failure
+ if [ -z "$expect_parse_fail" ]; then
+ echo "FAIL: parse_cmdline failed"
+ failed=$(( failed + 1 ))
+ fi
+ ;;
+ $e_assertion_failure)
+ # test assertion failure
+ failed=$(( failed + 1 ))
+ ;;
+ $e_ok)
+ if [ -n "$expect_parse_fail" ]; then
+ echo "EXPECTED_FAIL: parse_cmdline succeeded"
+ failed=$(( failed + 1 ))
+ fi
+ ;;
+ esac
+}
+
+# bare words
+test_parse 'foo' \
+ 'foo' 'y'
+test_parse 'foo bar' \
+ 'foo' 'y' \
+ 'bar' 'y'
+
+# overwriting
+test_parse 'foo=bar bar=baz foo bar="no pe"' \
+ 'bar' 'no pe' \
+ 'foo' 'y'
+
+# simple key=value assignment
+test_parse 'foo=bar' \
+ 'foo' 'bar'
+test_parse 'foo=bar bar=baz' \
+ 'foo' 'bar' \
+ 'bar' 'baz'
+test_parse '_derpy=hooves' \
+ '_derpy' 'hooves'
+test_parse 'f5=abc f_5_=abc' \
+ 'f5' 'abc' \
+ 'f_5_' 'abc'
+test_parse 'v="foo bar=baz"' \
+ 'v' 'foo bar=baz'
+
+# double quoting
+test_parse 'foo="bar"' \
+ 'foo' 'bar'
+test_parse 'foo="bar baz"' \
+ 'foo' 'bar baz'
+
+# single quoting
+test_parse --expect-fail "foo='bar'" \
+ 'foo' 'bar'
+test_parse --expect-parse-fail "foo='bar baz'" \
+ 'foo' 'bar baz'
+
+# dangling quotes
+test_parse --expect-fail 'foo="bar' \
+ 'foo' '"bar'
+test_parse 'foo=bar"' \
+ 'foo' 'bar"'
+
+# nested quotes
+test_parse --expect-parse-fail "foo='\"bar baz\"' herp='\"de\"rp'" \
+ 'foo' '"bar baz"' \
+ 'herp' '"de"rp'
+
+# escaped quotes
+test_parse 'foo=bar"baz' \
+ 'foo' 'bar"baz'
+
+# neighboring quoted regions
+test_parse --expect-fail 'foo="bar""baz"' \
+ 'foo' 'barbaz'
+test_parse --expect-fail "foo=\"bar\"'baz'" \
+ 'foo' "barbaz"
+test_parse --expect-fail "foo='bar'\"baz\"" \
+ 'foo' "barbaz"
+
+# comments
+test_parse 'foo=bar # ignored content' \
+ 'foo' 'bar' \
+ 'ignored' '' \
+ 'content' ''
+test_parse 'foo=bar #ignored content' \
+ 'foo' 'bar' \
+ 'ignored' '' \
+ 'content' ''
+test_parse 'foo="bar #baz" parse=this' \
+ 'foo' 'bar #baz' \
+ 'parse' 'this'
+
+# shell metachars
+test_parse 'foo=*' \
+ 'foo' '\*'
+test_parse --expect-fail 'Make*' \
+ 'Makefile' ''
+test_parse --expect-fail '[Makefile]*' \
+ 'Makefile' '' \
+ 'init' '' \
+ 'functions' ''
+
+# invalid names
+test_parse 'in-valid=name'
+test_parse '6foo=bar'
+test_parse --expect-parse-fail '"gar bage"' \
+ 'gar' '' \
+ 'bage' ''
+
+# special handling
+test_parse 'rw' \
+ 'ro' '' \
+ 'rw' '' \
+ 'rwopt' 'rw'
+test_parse 'ro' \
+ 'ro' '' \
+ 'rw' '' \
+ 'rwopt' 'ro'
+test_parse --expect-fail 'fstype=btrfs' \
+ 'rootfstype' 'btrfs'
+test_parse 'fsck.mode=force' \
+ 'forcefsck' 'y' \
+ 'fastboot' ''
+test_parse 'fsck.mode=skip' \
+ 'forcefsck' '' \
+ 'fastboot' 'y'
+test_parse 'rd.debug' \
+ 'rd_debug' 'y'
+test_parse 'rd.log' \
+ 'rd_logmask' '6'
+test_parse 'rd.log=all' \
+ 'rd_logmask' '7'
+test_parse 'rd.log=console' \
+ 'rd_logmask' '4'
+test_parse 'rd.log=kmsg' \
+ 'rd_logmask' '2'
+test_parse 'rd.log=file' \
+ 'rd_logmask' '1'
+
+# a mix of stuff
+test_parse 'foo=bar bareword bar="ba az"' \
+ 'foo' 'bar' \
+ 'bareword' 'y' \
+ 'bar' 'ba az'
+
+if [ "$failed" -eq 0 ]; then
+ echo "PASS: ${0##*/test_} ($tests tests)"
+ exit 0
+else
+ echo "FAIL: $failed tests failed"
+ exit 1
+fi