[arch-projects] [mkinitcpio][PATCH 1/2] add test harness for parse_cmdline

Dave Reisner dreisner at archlinux.org
Thu Jul 7 12:31:39 UTC 2016


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.
---
 Makefile                |   3 +
 test/test_parse_cmdline | 233 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 236 insertions(+)
 create mode 100755 test/test_parse_cmdline

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


More information about the arch-projects mailing list