testcases/lib: Add test.sh test library + docs.
* Add test.sh test library
* Add documentation into test-writing-guidelines
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index 3e51a00..c79f914 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -42,6 +42,9 @@
1.3 Coding style
~~~~~~~~~~~~~~~~
+1.3.1 C coding style
+^^^^^^^^^^^^^^^^^^^^
+
LTP adopted Linux kernel coding style. If you aren't familiar with its rules
locate 'linux/Documentation/CodingStyle' in the kernel sources and read it,
it's a well written introduction.
@@ -52,7 +55,27 @@
NOTE: If checkpatch does not report any problems, the code still may be wrong
as the tool only looks for common mistakes.
-TODO: bash code coding style?
+1.3.2 Shell coding style
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+When writing testcases in shell write in portable shell only, it's a good idea
+to try to run the test using alternative shell (alternative to bash, for
+example dash) too.
+
+Here are some common sense style rules for shell
+
+* Keep lines under 80 chars
+
+* Use tabs for indentation
+
+* Keep things simple, avoid unnecessary shubshells
+
+* Don't do confusing things (i.e. don't name your functions like common shell
+ commands, etc.)
+
+* Quote variables
+
+* Be consistent
1.4 Commenting code
~~~~~~~~~~~~~~~~~~~
@@ -648,6 +671,99 @@
}
-------------------------------------------------------------------------------
+2.3 Writing a testcase in shell
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LTP supports testcases to be written in a portable shell too.
+
+There is a shell library modeled closely to the C interface (the source is
+located at 'testcases/lib/test.sh') and is installed to the same directory as
+the rest of the LTP test binaries.
+
+WARNING: All identifiers starting with TST_ or tst_ are reserved for the
+ 'test.sh' library.
+
+2.3.1 Basic shell test structure
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+[source,sh]
+-------------------------------------------------------------------------------
+#!/bin/sh
+#
+# This is a basic test for true shell buildin
+#
+
+TCID=true01
+TST_TOTAL=1
+. test.sh
+
+true
+ret=$?
+
+if [ $ret -eq 0 ]; then
+ tst_resm TPASS "true returned 0"
+else
+ tst_resm TFAIL "true rturned $ret"
+fi
+
+tst_exit
+-------------------------------------------------------------------------------
+
+TIP: To execute this test the 'test.sh' library must be in '$PATH'. If you are
+ executing the test from a git checkout you can run it as
+ 'PATH="$PATH:../../lib" ./foo01.sh'
+
+WARNING: Do not forget to add the 'tst_exit' at the end of the test,
+ otherwise the test return value would be the return value of last
+ executed command.
+
+2.3.2 Basic test interface
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Following functions similar to the LTP C intearface are available.
+
+* tst_resm()
+* tst_brkm()
+* tst_exit()
+* tst_require_root()
+* tst_tmpdir()
+* tst_rmdir()
+
+There is one more function called 'tst_check_cmds()' that gets unspecified
+number of parameters and asserts that each parameter is a name of an
+executable in '$PATH' and exits the test with 'TCONF' on first missing.
+
+2.3.3 Cleanup
+^^^^^^^^^^^^^
+
+Due to differencies in C and shell, the cleanup callback is done using a
+'TST_CLEANUP' shell variable that, if not empty, is evaluated before the test
+exits (either after calling 'tst_exit()' or 'tst_brkm()'). See example below.
+
+[source,sh]
+-------------------------------------------------------------------------------
+#!/bin/sh
+#
+# Test cleanup example
+#
+
+TCID=true01
+TST_TOTAL=1
+. test.sh
+
+cleanup()
+{
+ tst_rmdir
+}
+
+tst_tmpdir
+TST_CLEANUP=cleanup
+
+# Do the test here
+
+tst_exit
+-------------------------------------------------------------------------------
+
3. Test Contribution Checklist
------------------------------
diff --git a/testcases/lib/test.sh b/testcases/lib/test.sh
new file mode 100644
index 0000000..b857dc4
--- /dev/null
+++ b/testcases/lib/test.sh
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# Copyright (c) Linux Test Project, 2014
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Written by Cyril Hrubis <chrubis@suse.cz>
+#
+# This is a LTP test library for shell.
+#
+
+export LTP_RET_VAL=0
+export LTP_TST_CNT=1
+
+# Exit values map
+tst_flag2mask()
+{
+ case "$1" in
+ TPASS) return 0;;
+ TFAIL) return 1;;
+ TBROK) return 2;;
+ TWARN) return 4;;
+ TRETR) return 8;;
+ TINFO) return 16;;
+ TCONF) return 32;;
+ *) tst_brkm TBROK "Invalid resm type '$1'";;
+ esac
+}
+
+tst_resm()
+{
+ tst_flag2mask "$1"
+ local mask=$?
+ LTP_RET_VAL=$((LTP_RET_VAL|mask))
+
+ echo "$TCID $LTP_TST_CNT $1 : $2"
+
+ case "$1" in
+ TPASS|TFAIL)
+ LTP_TST_CNT=$((LTP_TST_CNT+1));;
+ esac
+}
+
+tst_brkm()
+{
+ case "$1" in
+ TFAIL) ;;
+ TBROK) ;;
+ TCONF) ;;
+ TRETR) ;;
+ *) tst_brkm TBROK "Invalid tst_brkm type '$1'";;
+ esac
+
+ tst_resm "$1" "$2"
+ tst_exit
+}
+
+tst_require_root()
+{
+ if [ "$(id -ru)" != 0 ]; then
+ tst_brkm TCONF "Must be super/root for this test!"
+ fi
+}
+
+tst_exit()
+{
+ if [ -n "$TST_CLEANUP" ]; then
+ $TST_CLEANUP
+ fi
+
+ # Mask out TRETR, TINFO and TCONF
+ exit $((LTP_RET_VAL & ~(8 | 16 | 32)))
+}
+
+tst_tmpdir()
+{
+ if [ -z "$TMPDIR" ]; then
+ export TMPDIR="/tmp"
+ fi
+
+ TST_TMPDIR=$(mktemp -d "$TMPDIR/$TCID.XXXXXXXXXX")
+
+ cd "$TST_TMPDIR"
+}
+
+tst_rmdir()
+{
+ cd "$LTPROOT"
+ rm -r "$TST_TMPDIR"
+}
+
+#
+# Checks if coomands passed as arguments exists
+#
+tst_check_cmds()
+{
+ for cmd in $*; do
+ if ! command -v $cmd > /dev/null 2>&1; then
+ tst_brkm TCONF "'$cmd' not found"
+ fi
+ done
+}
+
+# Check that test name is set
+if [ -z "$TCID" ]; then
+ tst_brkm TBROK "TCID is not defined"
+fi
+
+if [ -z "$TST_TOTAL" ]; then
+ tst_brkm TBROK "TST_TOTAL is not defined"
+fi
+
+# Setup LTPROOT, default to current directory if not set
+if [ -z "$LTPROOT" ]; then
+ export LTPROOT="$PWD"
+fi