From 8ce674db7ea92f6b3e551280b462c4f52ac74116 Mon Sep 17 00:00:00 2001 From: davidovski Date: Sun, 13 Feb 2022 17:52:07 +0000 Subject: added test suite for parseconf --- Makefile | 24 ++++++++-- src/colors.h | 48 -------------------- src/colors.list | 42 +++++++++++++++++ src/generate_colors.sh | 45 ++++++++++++++++++ src/parseconf | 106 +++++++++++++++++++++++++++++++++++++++++++ src/shtests | 60 ++++++++++++++++++++++++ src/shtests.sh | 60 ++++++++++++++++++++++++ test/external.conf | 4 ++ test/parseconf.sh | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ test/simple.conf | 18 ++++++++ test/test.conf | 2 + 11 files changed, 478 insertions(+), 52 deletions(-) delete mode 100644 src/colors.h create mode 100644 src/colors.list create mode 100644 src/generate_colors.sh create mode 100755 src/parseconf create mode 100755 src/shtests create mode 100644 src/shtests.sh create mode 100644 test/external.conf create mode 100755 test/parseconf.sh create mode 100644 test/simple.conf create mode 100644 test/test.conf diff --git a/Makefile b/Makefile index 414324a..4836466 100755 --- a/Makefile +++ b/Makefile @@ -6,19 +6,35 @@ PREFIX=/usr .DEFAULT_GOAL := build -install: install-hbar install-headers -build: build-hbar +install: install-hbar install-colors install-parseconf +build: build-hbar install-headers: src/*.h install -m644 src/*.h ${DESTDIR}${PREFIX}/include +install-shtests: src/shtests + install -m755 src/shtests.sh ${DESTDIR}${PREFIX}/bin/shtests + install-chroot: src/xichroot install -m755 src/xichroot ${DESTDIR}${PREFIX}/bin/ -install-hbar: bin/hbar +install-parseconf: src/parseconf + install -m755 src/parseconf ${DESTDIR}${PREFIX}/bin/ + +check-parseconf: + shtests ./test/parseconf.sh + +install-hbar: build-hbar install -m755 bin/hbar ${DESTDIR}${PREFIX}/bin -build-hbar: src/hbar.c +install-colors: src/colors.list + sh src/generate_colors.sh ${DESTDIR}${PREFIX} src/colors.list + + +clean: + rm -r bin + +build-hbar: src/hbar.c install-colors mkdir -pv bin ${CC} src/hbar.c -o bin/hbar ${FLAGS} diff --git a/src/colors.h b/src/colors.h deleted file mode 100644 index 627fa67..0000000 --- a/src/colors.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Color values - * - * provided by xiutils - */ -#define RESET "\033[0m" - -#define BOLD "\033[0;1m" - -#define BLACK "\033[0;30m" -#define RED "\033[0;31m" -#define GREEN "\033[0;32m" -#define YELLOW "\033[0;33m" -#define BLUE "\033[0;34m" -#define MAGENTA "\033[0;35m" -#define CYAN "\033[0;36m" -#define WHITE "\033[0;37m" -#define DEFAULT "\033[0;39m" - -#define BG_BLACK "\033[40m" -#define BG_RED "\033[41m" -#define BG_GREEN "\033[42m" -#define BG_YELLOW "\033[43m" -#define BG_BLUE "\033[44m" -#define BG_MAGENTA "\033[45m" -#define BG_CYAN "\033[46m" -#define BG_WHITE "\033[47m" -#define BG_DEFAULT "\033[49m" - -#define LIGHT_BLACK "\033[0;90m" -#define LIGHT_RED "\033[0;91m" -#define LIGHT_GREEN "\033[0;92m" -#define LIGHT_YELLOW "\033[0;93m" -#define LIGHT_BLUE "\033[0;94m" -#define LIGHT_MAGENTA "\033[0;95m" -#define LIGHT_CYAN "\033[0;96m" -#define LIGHT_WHITE "\033[0;97m" -#define LIGHT_DEFAULT "\033[0;99m" - -#define BOLDBLACK "\033[1;30m" -#define BOLDRED "\033[1;31m" -#define BOLDGREEN "\033[1;32m" -#define BOLDYELLOW "\033[1;33m" -#define BOLDBLUE "\033[1;34m" -#define BOLDMAGENTA "\033[1;35m" -#define BOLDCYAN "\033[1;36m" -#define BOLDWHITE "\033[1;37m" -#define GREY46 "\033[38;5;243m" diff --git a/src/colors.list b/src/colors.list new file mode 100644 index 0000000..0829a63 --- /dev/null +++ b/src/colors.list @@ -0,0 +1,42 @@ +RESET "\033[0m" + +BOLD "\033[0;1m" + +BLACK "\033[0;30m" +RED "\033[0;31m" +GREEN "\033[0;32m" +YELLOW "\033[0;33m" +BLUE "\033[0;34m" +MAGENTA "\033[0;35m" +CYAN "\033[0;36m" +WHITE "\033[0;37m" +DEFAULT "\033[0;39m" + +BG_BLACK "\033[40m" +BG_RED "\033[41m" +BG_GREEN "\033[42m" +BG_YELLOW "\033[43m" +BG_BLUE "\033[44m" +BG_MAGENTA "\033[45m" +BG_CYAN "\033[46m" +BG_WHITE "\033[47m" +BG_DEFAULT "\033[49m" + +LIGHT_BLACK "\033[0;90m" +LIGHT_RED "\033[0;91m" +LIGHT_GREEN "\033[0;92m" +LIGHT_YELLOW "\033[0;93m" +LIGHT_BLUE "\033[0;94m" +LIGHT_MAGENTA "\033[0;95m" +LIGHT_CYAN "\033[0;96m" +LIGHT_WHITE "\033[0;97m" +LIGHT_DEFAULT "\033[0;99m" + +BOLDBLACK "\033[1;30m" +BOLDRED "\033[1;31m" +BOLDGREEN "\033[1;32m" +BOLDYELLOW "\033[1;33m" +BOLDBLUE "\033[1;34m" +BOLDMAGENTA "\033[1;35m" +BOLDCYAN "\033[1;36m" +BOLDWHITE "\033[1;37m" diff --git a/src/generate_colors.sh b/src/generate_colors.sh new file mode 100644 index 0000000..3d2ba93 --- /dev/null +++ b/src/generate_colors.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +PREFIX=$1 + +headerfile=${PREFIX}"/include/colors.h" +shlib=${PREFIX}"/lib/colors.sh" + +cat > $shlib << "EOF" +# +# colors.h +# +# list of ansi color codes +# provided by xiutils +# + +EOF + +cat > $headerfile << "EOF" +/* + * colors.h + * + * list of ansi color codes + * provided by xiutils + * + */ + +EOF + +append_header() { + echo "#define $1 $2" >> $headerfile +} + +append_sh() { + echo "export $1=$2" >> $shlib +} + +while IFS= read -r line; do + grep -q "." <<< "$line" || continue + name=$(echo $line | awk '{ print $1 }') + code=$(echo $line | awk '{ print $2 }') + + append_header $name $code + append_sh $name $code + +done < "$2" diff --git a/src/parseconf b/src/parseconf new file mode 100755 index 0000000..c5ed801 --- /dev/null +++ b/src/parseconf @@ -0,0 +1,106 @@ +#!/bin/bash + +usage () { + printf "Usage $0 " + echo << "EOF" +OPTIONS... [FILTER] + +Print the parsed config file filtering by the keys +Arguments: + -f file read configuration from a file, uses /dev/sdtin otherwise + -v only print values + -c n print the last [n] +EOF +} + +# print the parsed values from the config file in key:value format +# +parse () { + local file="$1" + local level="" + local list="" + while IFS= read -r line; do + line=$(sed "s/\s\+/ /g" <<< "$line" | sed "s/^\s\|\s$\|;*$//g") + + grep -q "^#" <<< "$line" && continue + grep -q "." <<< "$line" || continue + + local key=$(echo $line | cut -d" " -f1) + local value=$(echo $line | cut -d" " -f2-) + + [ "$key" = "include" ] && parse $value && continue + + case ${value: -1} in + "{") + level="$level$key." + ;; + "[") + list="$list$key." + printf "$level$key:" + ;; + "}") + level=$(sed "s/[^\.]\w*\.$//g" <<< "$level") + ;; + "]") + printf "\n" + list=$(sed "s/[^\.]\w*\.$//g" <<< "$list") + ;; + *) + + grep -q "." <<< "$list" && + printf "$line " || + printf "$level$key:$value\n" + ;; + esac + done < "$file" +} + +# Filter the parsed file for specific keys +# +filter () { + local pattern= + + [ $# = 0 ] && + pattern=".*" || + pattern=$(sed "s/\*/.*/g"<<< "$@") + + $print_keys && + pattern="s/^($pattern:.+)/\1/p" || + pattern="s/^$pattern:(.+)/\1/p" + + + parse $CONF_FILE | sed -rn $pattern +} + +# Use the env variable if exists +[ -z ${CONF_FILE} ] && CONF_FILE="/dev/stdin" + +# initialise options +print_keys=true +count= + +while getopts ":f:c:v" opt; do + case "${opt}" in + f) + [ "${OPTARG}" = "-" ] && + CONF_FILE="/dev/stdin" || + CONF_FILE="${OPTARG}" + ;; + + v) + print_keys=false + ;; + c) + count="${OPTARG}" + ;; + *) + esac +done + +shift $((OPTIND-1)) + +[ -z ${count} ] && + filter "$@" || + filter "$@" | tail -n $count + + diff --git a/src/shtests b/src/shtests new file mode 100755 index 0000000..9994d7b --- /dev/null +++ b/src/shtests @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Simple shell test suite +# +# will run all functions with a name starting with test_ +# the return value of said function will determine if its a pass or fail +# +# to run a shell file full of unit tests, run: +# shtests [FILE] +# + +. /usr/lib/colors.sh + +PASS="${BLUE}[ ${GREEN}PASS${BLUE} ]${RESET}" +FAIL="${BLUE}[ ${RED}FAIL${BLUE} ]${RESET}" + +runtest () { + test_name=$(sed "s/_/ /g" <<< "$1") + test_func="$2" + printf "${BLUE}[ ] ${RESET}$test_name\r"; + if "$test_func" ; then + printf "$PASS\n" + return 0 + else + printf "$FAIL\n" + return 1 + fi +} + +if [ $# = "0" ]; then + printf "${RED}No tests file has been provided\n" + exit 1; +else + source $@ +fi + + +tests=$(declare -F | sed -rn "s/declare -f test_(.+)/\1/p") + +total=$(echo $tests | wc -w) +passed=0 +failed=0 + +printf "${BLUE}Running $total tests: \n" +for name in $tests; do + if runtest "$name" "test_$name"; then + passed=$((passed+1)) + else + failed=$((failed+1)) + fi +done + +printf "\n${BLUE}Summary for $total tests:\n" +printf "\t${PASS} $passed\n" +printf "\t${FAIL} $failed\n" +printf "\n" + +[ "$passed" = "$total" ] || exit 1 + + diff --git a/src/shtests.sh b/src/shtests.sh new file mode 100644 index 0000000..9994d7b --- /dev/null +++ b/src/shtests.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Simple shell test suite +# +# will run all functions with a name starting with test_ +# the return value of said function will determine if its a pass or fail +# +# to run a shell file full of unit tests, run: +# shtests [FILE] +# + +. /usr/lib/colors.sh + +PASS="${BLUE}[ ${GREEN}PASS${BLUE} ]${RESET}" +FAIL="${BLUE}[ ${RED}FAIL${BLUE} ]${RESET}" + +runtest () { + test_name=$(sed "s/_/ /g" <<< "$1") + test_func="$2" + printf "${BLUE}[ ] ${RESET}$test_name\r"; + if "$test_func" ; then + printf "$PASS\n" + return 0 + else + printf "$FAIL\n" + return 1 + fi +} + +if [ $# = "0" ]; then + printf "${RED}No tests file has been provided\n" + exit 1; +else + source $@ +fi + + +tests=$(declare -F | sed -rn "s/declare -f test_(.+)/\1/p") + +total=$(echo $tests | wc -w) +passed=0 +failed=0 + +printf "${BLUE}Running $total tests: \n" +for name in $tests; do + if runtest "$name" "test_$name"; then + passed=$((passed+1)) + else + failed=$((failed+1)) + fi +done + +printf "\n${BLUE}Summary for $total tests:\n" +printf "\t${PASS} $passed\n" +printf "\t${FAIL} $failed\n" +printf "\n" + +[ "$passed" = "$total" ] || exit 1 + + diff --git a/test/external.conf b/test/external.conf new file mode 100644 index 0000000..05f61d8 --- /dev/null +++ b/test/external.conf @@ -0,0 +1,4 @@ +external1 value +external2 value +external3 value +external4 value diff --git a/test/parseconf.sh b/test/parseconf.sh new file mode 100755 index 0000000..3095e18 --- /dev/null +++ b/test/parseconf.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +PARSECONF="./src/parseconf" + +SIMPLECONF="./test/simple.conf" + +test_simple_loading () { + cat ${SIMPLECONF} | ${PARSECONF} > /dev/null +} + +test_simple_parsing () { + config=" +key value + " + retval=$(${PARSECONF} key <<< "$config") + [ "$retval" = "key:value" ] +} + +test_bad_formatting () { + config=" + key value + " + retval=$(${PARSECONF} key <<< "$config") + [ "$retval" = "key:value" ] +} + +test_unecessary_semicolons () { + config=" +key value; + " + retval=$(${PARSECONF} key <<< "$config") + [ "$retval" = "key:value" ] +} + +test_extra_unecessary_semicolons () { + config=" +key value;;;;; + " + retval=$(${PARSECONF} key <<< "$config") + [ "$retval" = "key:value" ] +} + +test_mutlikey_parsing() { + config=" +key1 value1 +key2 value2 +key3 value3 +key4 value4 + " + retval=$(${PARSECONF} key2 <<< "$config") + [ "$retval" = "key2:value2" ] +} + + +test_list_parsing() { + config=" +list [ + a + b + c + d + e +] + " + retval=$(${PARSECONF} list <<< "$config") + [ "$retval" = "list:a b c d e " ] +} + +test_dict_parsing() { + config=" +dict { + a 1 + b 2 + c 3 + d 4 + e 5 +} + " + retval=$(${PARSECONF} dict.a <<< "$config") + [ "$retval" = "dict.a:1" ] +} + +test_file_input () { + retval=$(${PARSECONF} -f ${SIMPLECONF} key2) + [ "$retval" = "key2:value2" ] +} + +test_include () { + config=" +include test/simple.conf + " + retval=$(${PARSECONF} key2 <<< "$config") + [ "$retval" = "key2:value2" ] +} + +test_glob_matching () { + config=" +dict { + a 1 + b 2 + c 3 + d 4 +} + " + retval=$(${PARSECONF} "dict.*" <<< "$config" | wc -l) + [ "$retval" = "4" ] +} + +test_glob_max_count () { + config=" +dict { + a 1 + b 2 + c 3 + d 4 +} + " + retval=$(${PARSECONF} -c 1 "dict.*" <<< "$config") + [ "$retval" = "dict.d:4" ] +} + diff --git a/test/simple.conf b/test/simple.conf new file mode 100644 index 0000000..605f3f5 --- /dev/null +++ b/test/simple.conf @@ -0,0 +1,18 @@ +key1 value1 +key2 value2 +key3 value3 +key4 value4 + +dict { + a 1 + b 2 + c 3 + d 4 +} + +list [ + alpha + beta + gamma + delta +] diff --git a/test/test.conf b/test/test.conf new file mode 100644 index 0000000..139597f --- /dev/null +++ b/test/test.conf @@ -0,0 +1,2 @@ + + -- cgit v1.2.1