From a51c515dc1cdf93edb89484238259c941da8f3b6 Mon Sep 17 00:00:00 2001 From: Felix Date: Sat, 23 Aug 2008 15:03:23 +0200 Subject: [PATCH] Adds a unit test framework based on shunit2 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Includes simple tests for : - uci import - uci export - uci get - uci set - uci add shunit2 : http://code.google.com/p/shunit2/ Signed-off-by: Frédéric Moulins --- Makefile | 3 + test/Makefile | 2 + test/README | 34 + test/references/add_section.result | 1 + test/references/export.data | 6 + test/references/export.result | 7 + test/references/get.data | 2 + test/references/import.data | 7 + test/references/import.result | 6 + test/references/set_existing_option.data | 2 + test/references/set_existing_option.result | 1 + test/references/set_named_section.result | 1 + test/references/set_nonexisting_option.data | 1 + test/references/set_nonexisting_option.result | 1 + test/shunit2/shunit2 | 1040 +++++++++++++++++ test/tests.d/000_import | 5 + test/tests.d/010_export | 6 + test/tests.d/020_get | 13 + test/tests.d/030_set | 20 + test/tests.d/040_add | 8 + test/tests.sh | 59 + 21 files changed, 1225 insertions(+) create mode 100644 test/Makefile create mode 100644 test/README create mode 100644 test/references/add_section.result create mode 100644 test/references/export.data create mode 100644 test/references/export.result create mode 100644 test/references/get.data create mode 100644 test/references/import.data create mode 100644 test/references/import.result create mode 100644 test/references/set_existing_option.data create mode 100644 test/references/set_existing_option.result create mode 100644 test/references/set_named_section.result create mode 100644 test/references/set_nonexisting_option.data create mode 100644 test/references/set_nonexisting_option.result create mode 100644 test/shunit2/shunit2 create mode 100644 test/tests.d/000_import create mode 100644 test/tests.d/010_export create mode 100644 test/tests.d/020_get create mode 100644 test/tests.d/030_set create mode 100644 test/tests.d/040_add create mode 100644 test/tests.sh diff --git a/Makefile b/Makefile index d16a987..1016fac 100644 --- a/Makefile +++ b/Makefile @@ -61,5 +61,8 @@ install: all ln -sf $(SHLIB_FILE) $(DESTDIR)$(prefix)/lib/libuci.$(SHLIB_EXT) $(INSTALL) -m0755 uci $(DESTDIR)/usr/bin/ +test: all + make -C test + FORCE: ; .PHONY: FORCE diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..6716a78 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,2 @@ +all: + sh ./tests.sh diff --git a/test/README b/test/README new file mode 100644 index 0000000..f950199 --- /dev/null +++ b/test/README @@ -0,0 +1,34 @@ +This test script uses shunit2 : +http://code.google.com/p/shunit2/ + +uci-static binary is used during tests. + + +How to add a test +================= + +* Test files are located in './test/tests.d' + +* These files contain shell functions beginning with 'test' : +" +test_get_option () +{ +... +} +... +" + +* shunit2 functions can be used in these functions : +http://shunit2.googlecode.com/svn/trunk/source/2.1/doc/shunit2.html + +* Additional environment variables are available : + - ${CONFIG_DIR} : uci search path for config files. This directory is + reset after each test. + - ${CHANGES_DIR} : uci search path for config change files. This directory is + reset after each test. + - ${TMP_DIR} : path to a directory where can be stored temporary files + during tests. This directory is reset after each test. + - ${UCI} : uci static binary called with above config and changes + directories as parameters. + - ${REF_DIR} : path to a directory where can be stored reference files + or data. diff --git a/test/references/add_section.result b/test/references/add_section.result new file mode 100644 index 0000000..c7daab6 --- /dev/null +++ b/test/references/add_section.result @@ -0,0 +1 @@ ++add.section=type diff --git a/test/references/export.data b/test/references/export.data new file mode 100644 index 0000000..c7e4d39 --- /dev/null +++ b/test/references/export.data @@ -0,0 +1,6 @@ + +config 'type' 'section' + option 'opt' 'val' + list 'list_opt' 'val0' + list 'list_opt' 'val1' + diff --git a/test/references/export.result b/test/references/export.result new file mode 100644 index 0000000..957e687 --- /dev/null +++ b/test/references/export.result @@ -0,0 +1,7 @@ +package 'export' + +config 'type' 'section' + option 'opt' 'val' + list 'list_opt' 'val0' + list 'list_opt' 'val1' + diff --git a/test/references/get.data b/test/references/get.data new file mode 100644 index 0000000..82b7231 --- /dev/null +++ b/test/references/get.data @@ -0,0 +1,2 @@ +config 'type' 'section' + option 'opt' 'val' diff --git a/test/references/import.data b/test/references/import.data new file mode 100644 index 0000000..6a9b737 --- /dev/null +++ b/test/references/import.data @@ -0,0 +1,7 @@ +package 'import' + +config 'type' 'section' + option 'opt' 'val' + list 'list_opt' 'val0' + list 'list_opt' 'val1' + diff --git a/test/references/import.result b/test/references/import.result new file mode 100644 index 0000000..c7e4d39 --- /dev/null +++ b/test/references/import.result @@ -0,0 +1,6 @@ + +config 'type' 'section' + option 'opt' 'val' + list 'list_opt' 'val0' + list 'list_opt' 'val1' + diff --git a/test/references/set_existing_option.data b/test/references/set_existing_option.data new file mode 100644 index 0000000..ff159c4 --- /dev/null +++ b/test/references/set_existing_option.data @@ -0,0 +1,2 @@ +config 'named' 'section' + option 'opt' 'err' diff --git a/test/references/set_existing_option.result b/test/references/set_existing_option.result new file mode 100644 index 0000000..c88deea --- /dev/null +++ b/test/references/set_existing_option.result @@ -0,0 +1 @@ +set.section.opt=val diff --git a/test/references/set_named_section.result b/test/references/set_named_section.result new file mode 100644 index 0000000..2a4145b --- /dev/null +++ b/test/references/set_named_section.result @@ -0,0 +1 @@ +set.section=named diff --git a/test/references/set_nonexisting_option.data b/test/references/set_nonexisting_option.data new file mode 100644 index 0000000..189bd29 --- /dev/null +++ b/test/references/set_nonexisting_option.data @@ -0,0 +1 @@ +config 'named' 'section' diff --git a/test/references/set_nonexisting_option.result b/test/references/set_nonexisting_option.result new file mode 100644 index 0000000..c88deea --- /dev/null +++ b/test/references/set_nonexisting_option.result @@ -0,0 +1 @@ +set.section.opt=val diff --git a/test/shunit2/shunit2 b/test/shunit2/shunit2 new file mode 100644 index 0000000..eef19d4 --- /dev/null +++ b/test/shunit2/shunit2 @@ -0,0 +1,1040 @@ +# $Id: shunit2 189 2008-07-11 11:46:54Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# vim:foldmethod=marker:foldmarker=/**,*/ +# +#/** +# +# +# +# shUnit 2.1.4 +# Shell Unit Test Framework +# +# http://shunit2.sourceforge.net/ +# +# written by Kate Ward <kate.ward@forestent.com> +# released under the LGPL +# +# this module implements a xUnit based unit test framework similar to JUnit +# +#*/ + +SHUNIT_VERSION='2.1.4' + +_shunit_warn() { echo "shunit2:WARN $@" >&2; } +_shunit_error() { echo "shunit2:ERROR $@" >&2; } +_shunit_fatal() { echo "shunit2:FATAL $@" >&2; } + +SHUNIT_TRUE=0 +SHUNIT_FALSE=1 +SHUNIT_ERROR=2 + +# specific shell checks +if [ -n "${ZSH_VERSION:-}" ]; then + setopt |grep "^shwordsplit$" >/dev/null + if [ $? -ne ${SHUNIT_TRUE} ]; then + _shunit_fatal 'zsh shwordsplit option is required for proper operation' + exit ${SHUNIT_ERROR} + fi + if [ -z "${SHUNIT_PARENT:-}" ]; then + _shunit_fatal "zsh does not pass \$0 through properly. please declare \ +\"SHUNIT_PARENT=\$0\" before calling shUnit2" + exit ${SHUNIT_ERROR} + fi +fi + +# shell flags for shunit2: +# u - treat unset variables as an error when performing parameter expansion +__SHUNIT_SHELL_FLAGS='u' + +# save the current set of shell flags, and then set some for ourself +shunit_shellFlags_="$-" +for shunit_shellFlag_ in `echo "${__SHUNIT_SHELL_FLAGS}" |sed 's/\(.\)/\1 /g'` +do + set -${shunit_shellFlag_} +done + +# +# constants +# + +__SHUNIT_ASSERT_MSG_PREFIX='ASSERT:' +__SHUNIT_PARENT=${SHUNIT_PARENT:-$0} + +# set the constants readonly +shunit_constants_=`set |grep "^__SHUNIT_" |cut -d= -f1` +echo "${shunit_constants_}" |grep "^Binary file" >/dev/null +if [ $? -eq 0 ]; then + # deal with binary junk in 'set' output + shunit_constants_=`set |grep -a "^__SHUNIT_" |cut -d= -f1` +fi +for shunit_const_ in ${shunit_constants_}; do + shunit_ro_opts_='' + if [ -n "${ZSH_VERSION:-}" ]; then + case ${ZSH_VERSION} in + [123].*) ;; + *) shunit_ro_opts_='-g' ;; # declare readonly constants globally + esac + fi + readonly ${shunit_ro_opts_} ${shunit_const_} +done +unset shunit_const_ shunit_constants_ shunit_ro_opts_ + +# variables +__shunit_skip=${SHUNIT_FALSE} +__shunit_suite='' + +__shunit_testsPassed=0 +__shunit_testsFailed=0 +__shunit_testsSkipped=0 +__shunit_testsTotal=0 + +# macros +_SHUNIT_LINENO_='eval if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && shunit_message_="[$2]"; shift 2; fi' + +#----------------------------------------------------------------------------- +# assert functions +# + +#/** +# +# +# void +# +# +# +# +# assertEquals +# string [message] +# string expected +# string actual +# +# +# Asserts that expected and +# actual are equal to one another. The message is +# optional. +# +# +#*/ +assertEquals() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error 'assertEquals() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_expected_=$1 + shunit_actual_=$2 + + shunit_return=${SHUNIT_TRUE} + if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then + _shunit_testPassed + else + failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}" + shunit_return=${SHUNIT_FALSE} + fi + + unset shunit_message_ shunit_expected_ shunit_actual_ __shunit_lineno + return ${shunit_return} +} +_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# assertNull +# string [message] +# string value +# +# +# Asserts that value is null, +# or in shell terms a zero-length string. The message is optional. +# +# +#*/ +assertNull() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 1 -o $# -gt 2 ]; then + _shunit_error 'assertNull() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + if [ $# -eq 2 ]; then + assertTrue "${shunit_message_}$1" "[ -z '$2' ]" + else + assertTrue "[ -z '$1' ]" + fi +} +_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# assertNotNull +# string [message] +# string value +# +# +# Asserts that value is not null, or in shell terms not +# a zero-length string. The message is optional. +# +# +#*/ +assertNotNull() +{ + ${_SHUNIT_LINENO_} + if [ $# -gt 2 ]; then # allowing 0 arguments as $1 might actually be null + _shunit_error 'assertNotNull() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + if [ $# -eq 2 ]; then + assertTrue "$1" "[ -n '$2' ]" + else + assertTrue "[ -n '${1:-}' ]" + fi +} +_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# assertSame +# string [message] +# string expected +# string actual +# +# +# This function is functionally equivalent to +# assertEquals. +# +# +#*/ +assertSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error 'assertSame() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + if [ $# -eq 2 ]; then + assertEquals "$1" "$2" + else + assertEquals "$1" "$2" "$3" + fi +} +_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# assertNotSame +# string [message] +# string unexpected +# string actual +# +# +# Asserts that unexpected and +# actual are not +# equal to one another. The message is optional. +# +# +#*/ +assertNotSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error 'assertNotSame() requires two or three arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_unexpected_=$1 + shunit_actual_=$2 + + shunit_return=${SHUNIT_TRUE} + if [ "${shunit_unexpected_}" != "${shunit_actual_}" ]; then + _shunit_testPassed + else + failSame "${shunit_message_}" "$@" + shunit_return=${SHUNIT_FALSE} + fi + + unset shunit_message_ shunit_unexpected_ shunit_actual_ + return ${shunit_return} +} +_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# assertTrue +# string [message] +# string condition +# +# +# Asserts that a given shell test condition is true. The message is +# optional. +# Testing whether something is true or false is easy enough by using +# the assertEquals/assertNotSame functions. Shell supports much more +# complicated tests though, and a means to support them was needed. As such, +# this function tests that conditions are true or false through evaluation +# rather than just looking for a true or false. +# +# The following test will succeed: assertTrue "[ 34 -gt 23 ]" +# The folloing test will fail with a message: assertTrue "test failed" "[ -r '/non/existant/file' ]" +# +# +# +#*/ +assertTrue() +{ + ${_SHUNIT_LINENO_} + if [ $# -gt 2 ]; then + _shunit_error 'assertTrue() takes one two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_condition_=$1 + + # see if condition is an integer, i.e. a return value + shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'` + shunit_return=${SHUNIT_TRUE} + if [ -z "${shunit_condition_}" ]; then + # null condition + shunit_return=${SHUNIT_FALSE} + elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then + # possible return value. treating 0 as true, and non-zero as false. + [ ${shunit_condition_} -ne 0 ] && shunit_return=${SHUNIT_FALSE} + else + # (hopefully) a condition + ( eval ${shunit_condition_} ) >/dev/null 2>&1 + [ $? -ne 0 ] && shunit_return=${SHUNIT_FALSE} + fi + + # record the test + if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then + _shunit_testPassed + else + _shunit_testFailed "${shunit_message_}" + fi + + unset shunit_message_ shunit_condition_ shunit_match_ + return ${shunit_return} +} +_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# assertFalse +# string [message] +# string condition +# +# +# Asserts that a given shell test condition is false. The message is +# optional. +# Testing whether something is true or false is easy enough by using +# the assertEquals/assertNotSame functions. Shell supports much more +# complicated tests though, and a means to support them was needed. As such, +# this function tests that conditions are true or false through evaluation +# rather than just looking for a true or false. +# +# The following test will succeed: assertFalse "[ 'apples' = 'oranges' ]" +# The folloing test will fail with a message: assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]" +# +# +# +#*/ +assertFalse() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 1 -o $# -gt 2 ]; then + _shunit_error 'assertFalse() quires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_condition_=$1 + + # see if condition is an integer, i.e. a return value + shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'` + shunit_return=${SHUNIT_TRUE} + if [ -z "${shunit_condition_}" ]; then + # null condition + shunit_return=${SHUNIT_FALSE} + elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then + # possible return value. treating 0 as true, and non-zero as false. + [ ${shunit_condition_} -eq 0 ] && shunit_return=${SHUNIT_FALSE} + else + # (hopefully) a condition + ( eval ${shunit_condition_} ) >/dev/null 2>&1 + [ $? -eq 0 ] && shunit_return=${SHUNIT_FALSE} + fi + + # record the test + if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then + _shunit_testPassed + else + _shunit_testFailed "${shunit_message_}" + fi + + unset shunit_message_ shunit_condition_ shunit_match_ + return ${shunit_return} +} +_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"' + +#----------------------------------------------------------------------------- +# failure functions +# + +#/** +# +# +# void +# +# +# +# +# fail +# string [message] +# +# +# Fails the test immediately, with the optional message. +# +# +#*/ +fail() +{ + ${_SHUNIT_LINENO_} + if [ $# -gt 1 ]; then + _shunit_error 'fail() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 1 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + + _shunit_testFailed "${shunit_message_}" + + unset shunit_message_ + return ${SHUNIT_FALSE} +} +_FAIL_='eval fail --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# failNotEquals +# string [message] +# string unexpected +# string actual +# +# +# Fails the test if unexpected and +# actual are not +# equal to one another. The message is optional. +# +# +#*/ +failNotEquals() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error 'failNotEquals() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_unexpected_=$1 + shunit_actual_=$2 + + _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected:<${shunit_unexpected_}> but was:<${shunit_actual_}>" + + unset shunit_message_ shunit_unexpected_ shunit_actual_ + return ${SHUNIT_FALSE} +} +_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# failSame +# string [message] +# +# +# Indicate test failure because arguments were not the same. The +# message is optional. +# +# +#*/ +failSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error 'failSame() requires two or three arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + [ -z "${shunit_message_:-}" ] && shunit_message_='' + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + + _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected not same" + + unset shunit_message_ + return ${SHUNIT_FALSE} +} +_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"' + +#/** +# +# +# void +# +# +# +# +# failNotSame +# string [message] +# string expected +# string actual +# +# +# Fails the test if expected and +# actual are equal to one another. The message is +# optional. +# +# +#*/ +failNotSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error 'failNotEquals() requires one or two arguments' + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + if [ $# -eq 2 ]; then + failNotEquals "$1" "$2" + else + failNotEquals "$1" "$2" "$3" + fi +} +_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"' + +#----------------------------------------------------------------------------- +# skipping functions +# + +#/** +# +# +# void +# +# +# +# +# startSkipping +# +# +# +# This function forces the remaining assert and fail functions to be +# "skipped", i.e. they will have no effect. Each function skipped will be +# recorded so that the total of asserts and fails will not be altered. +# +# +#*/ +startSkipping() +{ + __shunit_skip=${SHUNIT_TRUE} +} + +#/** +# +# +# void +# +# +# +# +# endSkipping +# +# +# +# This function returns calls to the assert and fail functions to their +# default behavior, i.e. they will be called. +# +# +#*/ +endSkipping() +{ + __shunit_skip=${SHUNIT_FALSE} +} + +#/** +# +# +# boolean +# +# +# +# +# isSkipping +# +# +# +# This function returns the state of skipping. +# +# +#*/ +isSkipping() +{ + return ${__shunit_skip} +} + +#----------------------------------------------------------------------------- +# suite functions +# + +#/** +# +# +# void +# +# +# +# +# suite +# +# +# +# This function can be optionally overridden by the user in their test +# suite. +# If this function exists, it will be called when +# shunit2 is sourced. If it does not exist, shUnit2 will +# search the parent script for all functions beginning with the word +# test, and they will be added dynamically to the test +# suite. +# +# +#*/ +# Note: see _shunit_mktempFunc() for actual implementation +# suite() { :; } + +#/** +# +# +# void +# +# +# +# +# suite_addTest +# string function +# +# +# This function adds a function name to the list of tests scheduled for +# execution as part of this test suite. This function should only be called +# from within the suite() function. +# +# +#*/ +suite_addTest() +{ + _su_func=${1:-} + + __shunit_suite="${__shunit_suite:+${__shunit_suite} }${_su_func}" + + unset _su_func +} + +#/** +# +# +# void +# +# +# +# +# oneTimeSetUp +# +# +# +# This function can be be optionally overridden by the user in their +# test suite. +# If this function exists, it will be called once before any tests are +# run. It is useful to prepare a common environment for all tests. +# +# +#*/ +# Note: see _shunit_mktempFunc() for actual implementation +# oneTimeSetUp() { :; } + +#/** +# +# +# void +# +# +# +# +# oneTimeTearDown +# +# +# +# This function can be be optionally overridden by the user in their +# test suite. +# If this function exists, it will be called once after all tests are +# completed. It is useful to clean up the environment after all tests. +# +# +#*/ +# Note: see _shunit_mktempFunc() for actual implementation +# oneTimeTearDown() { :; } + +#/** +# +# +# void +# +# +# +# +# setUp +# +# +# +# This function can be be optionally overridden by the user in their +# test suite. +# If this function exists, it will be called before each test is run. +# It is useful to reset the environment before each test. +# +# +#*/ +# Note: see _shunit_mktempFunc() for actual implementation +# setUp() { :; } + +#/** +# +# +# void +# +# +# +# +# tearDown +# +# +# +# This function can be be optionally overridden by the user in their +# test suite. +# If this function exists, it will be called after each test completes. +# It is useful to clean up the environment after each test. +# +# +#*/ +# Note: see _shunit_mktempFunc() for actual implementation +# tearDown() { :; } + +#------------------------------------------------------------------------------ +# internal shUnit2 functions +# + +_shunit_cleanup() +{ + name=$1 + + case ${name} in + EXIT) signal=0 ;; + INT) signal=2 ;; + TERM) signal=15 ;; + *) + _shunit_warn "unrecognized trap value (${name})" + signal=0 + ;; + esac + + # do our work + rm -fr "${__shunit_tmpDir}" + + # exit for all non-EXIT signals + if [ ${name} != 'EXIT' ]; then + _shunit_warn "trapped and now handling the (${name}) signal" + _shunit_generateReport + # disable EXIT trap + trap 0 + # add 128 to signal and exit + exit `expr ${signal} + 128` + fi +} + +_shunit_execSuite() +{ + echo '#' + echo '# Performing tests' + echo '#' + for _su_func in ${__shunit_suite}; do + # disable skipping + endSkipping + + # execute the per-test setup function + setUp + + # execute the test + echo "${_su_func}" + eval ${_su_func} + + # execute the per-test tear-down function + tearDown + done + + unset _su_func +} + +_shunit_generateReport() +{ + _su__awkPercent='{printf("%4d %3.0f%%", $1, $1*100/$2)}' + if [ ${__shunit_testsTotal:-0} -gt 0 ]; then + _su__passed=`echo ${__shunit_testsPassed} ${__shunit_testsTotal} |\ + awk "${_su__awkPercent}"` + _su__failed=`echo ${__shunit_testsFailed} ${__shunit_testsTotal} |\ + awk "${_su__awkPercent}"` + _su__skipped=`echo ${__shunit_testsSkipped} ${__shunit_testsTotal} |\ + awk "${_su__awkPercent}"` + _su__total=`echo ${__shunit_testsTotal} 100 |\ + awk '{printf("%4d %3d%%", $1, $2)}'` + else + _su__passed=`echo 0 0 |awk '{printf("%4d %3d%%", $1, $2)}'` + _su__failed=${_su__passed} + _su__skipped=${_su__passed} + _su__total=${_su__passed} + fi + + cat </dev/null ) && return + + # the standard mktemp didn't work. doing our own. + if [ -r '/dev/urandom' ]; then + _su__random=`od -vAn -N4 -tx4 &2 + exit 1 + } + + echo ${_su__tmpDir} + unset _su__date _su__random _su__tmpDir +} + +# this function is here to work around issues in Cygwin +_shunit_mktempFunc() +{ + for _su__func in oneTimeSetUp oneTimeTearDown setUp tearDown suite; do + _su__file="${__shunit_tmpDir}/${_su__func}" + cat <"${_su__file}" +#! /bin/sh +exit 0 +EOF + chmod +x "${_su__file}" + done + + unset _su__file +} + +_shunit_shouldSkip() +{ + [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE} + _shunit_testSkipped +} + +_shunit_testPassed() +{ + __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1` + __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1` +} + +_shunit_testFailed() +{ + _su__msg=$1 + + __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1` + __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1` + echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_su__msg}" >&2 + + unset _su__msg +} + +_shunit_testSkipped() +{ + __shunit_testsSkipped=`expr ${__shunit_testsSkipped} + 1` + __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1` +} + +#------------------------------------------------------------------------------ +# main +# + +# create a temporary storage location +__shunit_tmpDir=`_shunit_mktempDir` + +# setup traps to clean up after ourselves +trap '_shunit_cleanup EXIT' 0 +trap '_shunit_cleanup INT' 2 +trap '_shunit_cleanup TERM' 15 + +# create phantom functions to work around issues with Cygwin +_shunit_mktempFunc +PATH="${__shunit_tmpDir}:${PATH}" + +# execute the oneTimeSetUp function (if it exists) +oneTimeSetUp + +# execute the suite function defined in the parent test script +# deprecated as of 2.1.0 +suite + +# if no suite function was defined, dynamically build a list of functions +if [ -z "${__shunit_suite}" ]; then + shunit_funcs_=`grep "^[ \t]*test[A-Za-z0-9_]* *()" ${__SHUNIT_PARENT} \ + |sed 's/[^A-Za-z0-9_]//g'` + for shunit_func_ in ${shunit_funcs_}; do + suite_addTest ${shunit_func_} + done +fi +unset shunit_func_ shunit_funcs_ + +# execute the tests +_shunit_execSuite + +# execute the oneTimeTearDown function (if it exists) +oneTimeTearDown + +# generate report +_shunit_generateReport + +# restore the previous set of shell flags +for shunit_shellFlag_ in ${__SHUNIT_SHELL_FLAGS}; do + echo ${shunit_shellFlags_} |grep ${shunit_shellFlag_} >/dev/null \ + || set +${shunit_shellFlag_} +done +unset shunit_shellFlag_ shunit_shellFlags_ + +[ ${__shunit_testsFailed} -eq 0 ] || exit 1 + +#/** +# +#*/ diff --git a/test/tests.d/000_import b/test/tests.d/000_import new file mode 100644 index 0000000..a8a250c --- /dev/null +++ b/test/tests.d/000_import @@ -0,0 +1,5 @@ +test_import () +{ + ${UCI} import < ${REF_DIR}/import.data + assertSameFile ${REF_DIR}/import.result ${CONFIG_DIR}/import +} diff --git a/test/tests.d/010_export b/test/tests.d/010_export new file mode 100644 index 0000000..259f988 --- /dev/null +++ b/test/tests.d/010_export @@ -0,0 +1,6 @@ +test_export () +{ + cp ${REF_DIR}/export.data ${CONFIG_DIR}/export + ${UCI} export > ${TMP_DIR}/export.result + assertSameFile ${REF_DIR}/export.result ${TMP_DIR}/export.result +} diff --git a/test/tests.d/020_get b/test/tests.d/020_get new file mode 100644 index 0000000..6b6029a --- /dev/null +++ b/test/tests.d/020_get @@ -0,0 +1,13 @@ +test_get_option() +{ + cp ${REF_DIR}/get.data ${CONFIG_DIR}/test + value=$($UCI get test.section.opt) + assertEquals 'val' "$value" +} + +test_get_section() +{ + cp ${REF_DIR}/get.data ${CONFIG_DIR}/test + type=$($UCI get test.section) + assertEquals 'type' "$type" +} diff --git a/test/tests.d/030_set b/test/tests.d/030_set new file mode 100644 index 0000000..8f695ed --- /dev/null +++ b/test/tests.d/030_set @@ -0,0 +1,20 @@ +test_set_named_section() +{ + touch ${CONFIG_DIR}/set + ${UCI} set set.section=named + assertSameFile ${REF_DIR}/set_named_section.result ${CHANGES_DIR}/set +} + +test_set_nonexisting_option() +{ + cp ${REF_DIR}/set_nonexisting_option.data ${CONFIG_DIR}/set + ${UCI} set set.section.opt=val + assertSameFile ${REF_DIR}/set_nonexisting_option.result ${CHANGES_DIR}/set +} + +test_set_existing_option() +{ + cp ${REF_DIR}/set_existing_option.data ${CONFIG_DIR}/set + ${UCI} set set.section.opt=val + assertSameFile ${REF_DIR}/set_existing_option.result ${CHANGES_DIR}/set +} diff --git a/test/tests.d/040_add b/test/tests.d/040_add new file mode 100644 index 0000000..fbb14b4 --- /dev/null +++ b/test/tests.d/040_add @@ -0,0 +1,8 @@ +test_add_section() +{ + touch ${CONFIG_DIR}/add + section_name=$(${UCI} add add type) + assertNotNull "uci add does not return a section name." $section_name + sed 's/section/'$section_name'/' ${REF_DIR}/add_section.result > ${TMP_DIR}/add_section.result + assertSameFile ${TMP_DIR}/add_section.result ${CHANGES_DIR}/add +} diff --git a/test/tests.sh b/test/tests.sh new file mode 100644 index 0000000..52f1384 --- /dev/null +++ b/test/tests.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +TESTS_DIR="./tests" +CONFIG_DIR=${TESTS_DIR}"/config" +CHANGES_DIR="/tmp/.uci" +TMP_DIR=${TESTS_DIR}"/tmp" +FULL_SUITE=${TESTS_DIR}"/full_suite.sh" + +UCI_STATIC="../uci-static" +[ -x $UCI_STATIC ] || { + echo "uci-static is not present." + return 1 +} +UCI="${UCI_STATIC} -c ${CONFIG_DIR} -p ${CHANGES_DIR}" + +REF_DIR="./references" +SCRIPTS_DIR="./tests.d" +DO_TEST="./shunit2/shunit2" + +rm -rf ${TESTS_DIR} +mkdir -p ${TESTS_DIR} + +cat << 'EOF' > ${FULL_SUITE} +setUp() { + mkdir -p ${CONFIG_DIR} ${CHANGES_DIR} ${TMP_DIR} +} +tearDown() { + rm -rf ${CONFIG_DIR} ${CHANGES_DIR} ${TMP_DIR} +} +assertSameFile() { + local ref=$1 + local test=$2 + diff -qr $ref $test + assertTrue $? || { + echo "REF:" + cat $ref + echo "----" + echo "TEST:" + cat $test + echo "----" + } +} +EOF + +for suite in $(ls ${SCRIPTS_DIR}/*) +do + cat ${suite} >> ${FULL_SUITE} +done + +echo ". ${DO_TEST}" >> ${FULL_SUITE} + +REF_DIR="${REF_DIR}" \ +CONFIG_DIR="${CONFIG_DIR}" \ +CHANGES_DIR="${CHANGES_DIR}" \ +TMP_DIR="${TMP_DIR}" \ +UCI="${UCI}" \ +/bin/sh ${FULL_SUITE} + +rm -rf ${TESTS_DIR} -- 2.41.1