From 686b19a2889a5503f55dde29340e072632e915df Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Sat, 26 Jun 2021 12:18:49 +0900 Subject: [PATCH] test/log: Add test suite for public API of log module This commit adds a test suite with test cases to test all functions that are part of the public API of the log module. --- test/log_spec.sh | 776 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 776 insertions(+) create mode 100644 test/log_spec.sh diff --git a/test/log_spec.sh b/test/log_spec.sh new file mode 100644 index 0000000..b140b04 --- /dev/null +++ b/test/log_spec.sh @@ -0,0 +1,776 @@ +#!/bin/bash + +# log_spec.sh - Test cases for the toolbox log module +# Copyright (C) 2021 Matthias Kruk +# +# 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 3 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, see . + +. toolbox.sh + +include "log" +include "array" + +cleanup() { + rm -f "$__log_file" +} + +Describe "log_set_verbosity()" + It "sets the verbosity to the specified value (if valid)" + _test_log_set_verbosity_valid() { + local verb_min + local verb_max + local verb_cur + + verb_min="$__log_error" + verb_max="$__log_debug" + + # Make sure the verbosity is actually changed every time + if (( __log_verbosity == verb_min )); then + ((__log_verbosity++)) + fi + + for (( verb_cur = verb_min; verb_cur <= verb_max; verb_cur++ )); do + if ! log_set_verbosity "$verb_cur"; then + return 1 + fi + + if (( __log_verbosity != verb_cur )); then + return 1 + fi + done + + return 0 + } + + When call _test_log_set_verbosity_valid + The status should equal 0 + End + + It "sets the verbosity to a valid value (if invalid value given)" + _test_log_set_verbosity_invalid() { + local verb_min + local verb_max + local verb_cur + + verb_min="$__log_error" + verb_max="$__log_debug" + + for (( verb_cur = -10; verb_cur <= 10; verb_cur++ )); do + if ! log_set_verbosity "$verb_cur"; then + return 1 + fi + + if (( __log_verbosity < verb_min )) || + (( __log_verbosty > verb_max )); then + return 1 + fi + done + + return 0 + } + + When call _test_log_set_verbosity_invalid + The status should equal 0 + End + +End + +Describe "log_get_verbosity()" + It "returns the current verbosity level" + _test_log_get_verbosity() { + local verb_min + local verb_max + local verb_cur + + verb_min="$__log_error" + verb_max="$__log_debug" + __log_verbosity=-1 + + for (( verb_cur = verb_min; verb_cur <= verb_max; verb_cur++ )); do + local verb_act + + if ! log_set_verbosity "$verb_cur"; then + return 1 + fi + + if ! verb_act=$(log_get_verbosity); then + return 1 + fi + + if (( verb_act != verb_cur )); then + return 1 + fi + + if (( verb_act != __log_verbosity )); then + return 1 + fi + done + + return 0 + } + + When call _test_log_get_verbosity + The status should equal 0 + End +End + +Describe "log_increase_verbosity()" + It "increases the verbosity (if not at highest level)" + _test_log_increase_verbosity_valid() { + local verb_min + local verb_max + local verb_cur + + verb_min="$__log_error" + verb_max="$__log_debug" + + for (( verb_cur = verb_min; verb_cur < verb_max; verb_cur++ )); do + local verb_act + + log_set_verbosity "$verb_cur" + verb_act=$(log_get_verbosity) + + if (( verb_act != verb_cur )); then + return 1 + fi + + log_increase_verbosity + + verb_act=$(log_get_verbosity) + if (( verb_act != (verb_cur + 1) )); then + return 1 + fi + done + + return 0 + } + + When call _test_log_increase_verbosity_valid + The status should equal 0 + End + + It "does not increase the verbosity above the highest level" + _test_log_increase_verbosity_invalid() { + local verb_max + local verb_act + + verb_max="$__log_debug" + + log_set_verbosity "$verb_max" + verb_act=$(log_get_verbosity) + + if (( verb_act != verb_max )); then + return 1 + fi + + log_increase_verbosity + verb_act=$(log_get_verbosity) + + if (( verb_act != verb_max )); then + return 1 + fi + + return 0 + } + + When call _test_log_increase_verbosity_invalid + The status should equal 0 + End +End + +Describe "log_decrease_verbosity()" + It "decreases the verbosity (if not at lowest level)" + _test_log_decrease_verbosity_valid() { + local verb_min + local verb_max + local verb_cur + + verb_min="$__log_error" + verb_max="$__log_debug" + + for (( verb_cur = verb_max; verb_cur > verb_min; verb_cur-- )); do + local verb_act + + log_set_verbosity "$verb_cur" + verb_act=$(log_get_verbosity) + + if (( verb_act != verb_cur )); then + return 1 + fi + + log_decrease_verbosity + + verb_act=$(log_get_verbosity) + if (( verb_act != (verb_cur - 1) )); then + return 1 + fi + done + + return 0 + } + + When call _test_log_decrease_verbosity_valid + The status should equal 0 + End + + It "does not decrease the verbosity below the lowest level" + _test_log_decrease_verbosity_invalid() { + local verb_min + local verb_act + + verb_min="$__log_error" + + log_set_verbosity "$verb_min" + verb_act=$(log_get_verbosity) + + if (( verb_act != verb_min )); then + return 1 + fi + + log_decrease_verbosity + verb_act=$(log_get_verbosity) + + if (( verb_act != verb_min )); then + return 1 + fi + + return 0 + } + + When call _test_log_decrease_verbosity_invalid + The status should equal 0 + End +End + +Describe "log_stacktrace()" + It "prefixes a stacktrace with \"Stacktrace:\"" + When call log_stacktrace + The status should equal 0 + The stdout should start with "Stacktrace:" + End + + It "increases the indentation by 2 spaces per line" + _test_log_stacktrace_indentation() { + local line + local lineno + + lineno=0 + + while read -r line; do + local spaces_needed + local spaces_found + + spaces_needed=$(( lineno * 2 )) + spaces_found=0 + + while [[ "${str:$i:1}" == " " ]]; do + ((spaces_found++)) + done + + if (( spaces_needed != spaces_found )); then + return 1 + fi + + ((needed_spaces++)) + done < <(log_stacktrace) + + return 0 + } + + When call _test_log_stacktrace_indentation + The status should equal 0 + End +End + +Describe "log_highlight()" + It "prefixes the output with ===== BEGIN \$tag =====" + When call log_highlight "test" "foo" "bar" "baz" + The stdout should start with "===== BEGIN test =====" + End + + It "suffixes the output with ===== END \$tag =====" + When call log_highlight "test" "foo" "bar" "baz" + The stdout should end with "===== END test =====" + End + + It "prints lines passed in positional parameters" + When call log_highlight "test" "line" + The stdout should include "line" + End + + It "prints lines passed through stdin" + _test_log_highlight_stdin() { + local needle + local line + + needle="$RANDOM.line.$RANDOM" + + while read -r line; do + if [[ "$line" == "$needle" ]]; then + return 0 + fi + done < <(log_highlight "test" <<< "$needle") + + return 1 + } + + When call _test_log_highlight_stdin + The status should equal 0 + End +End + + +Describe "log_debug()" + BeforeAll 'log_set_verbosity $__log_debug' + AfterAll 'cleanup' + + It "does not print to stdout" + When call log_debug "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "*" + End + + It "prints log messages to stderr" + When call log_debug "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is $__log_debug" + _test_log_debug_verbosity_equal() { + log_set_verbosity "$__log_debug" + log_debug "test" + } + + When call _test_log_debug_verbosity_equal + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is above $__log_debug" + _test_log_debug_verbosity_above() { + log_set_verbosity "$(( __log_debug + 1 ))" + log_debug "test" + } + + When call _test_log_debug_verbosity_above + The stderr should match pattern "* test" + End + + It "does not print a message when the verbosity is below $__log_debug" + _test_log_debug_verbosity_below() { + log_set_verbosity "$(( __log_debug - 1 ))" + log_debug "test" + } + + When call _test_log_debug_verbosity_below + The stderr should equal "" + End + + It "prints the same message to stderr and the logfile" + _test_log_debug_same_output() { + local message + local stderr + local logfile + + message=$(echo "Somewhat $RANDOM message" + echo "For testing purposes $RANDOM") + + rm -f "$__log_file" + output=$(log_debug "$message" 2>&1) + logfile=$(< "$__log_file") + + if [[ "$output" != "$logfile" ]]; then + return 1 + fi + + return 0 + } + + When call _test_log_debug_same_output + The status should equal 0 + End + + It "prints lines passed in positional parameters" + _test_log_debug_lines_in_args() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(log_debug "${lines[@]}" 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_debug_lines_in_args + The status should equal 0 + End + + It "prints lines passed via stdin" + _test_log_debug_lines_via_stdin() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(array_to_lines "${lines[@]}" | log_debug 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_debug_lines_via_stdin + The status should equal 0 + End +End + + +Describe "log_info()" + BeforeAll 'log_set_verbosity $__log_info' + AfterAll 'cleanup' + + It "does not print to stdout" + When call log_info "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "*" + End + + It "prints log messages to stderr" + When call log_info "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is $__log_info" + _test_log_info_verbosity_equal() { + log_set_verbosity "$__log_info" + log_info "test" + } + + When call _test_log_info_verbosity_equal + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is above $__log_info" + _test_log_info_verbosity_above() { + log_set_verbosity "$(( __log_info + 1 ))" + log_info "test" + } + + When call _test_log_info_verbosity_above + The stderr should match pattern "* test" + End + + It "does not print a message when the verbosity is below $__log_info" + _test_log_info_verbosity_below() { + log_set_verbosity "$(( __log_info - 1 ))" + log_info "test" + } + + When call _test_log_info_verbosity_below + The stderr should equal "" + End + + It "prints the same message to stderr and the logfile" + _test_log_info_same_output() { + local message + local stderr + local logfile + + message=$(echo "Somewhat $RANDOM message" + echo "For testing purposes $RANDOM") + + rm -f "$__log_file" + output=$(log_info "$message" 2>&1) + logfile=$(< "$__log_file") + + if [[ "$output" != "$logfile" ]]; then + return 1 + fi + + return 0 + } + + When call _test_log_info_same_output + The status should equal 0 + End + + It "prints lines passed in positional parameters" + _test_log_info_lines_in_args() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(log_info "${lines[@]}" 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_info_lines_in_args + The status should equal 0 + End + + It "prints lines passed via stdin" + _test_log_info_lines_via_stdin() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(array_to_lines "${lines[@]}" | log_info 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_info_lines_via_stdin + The status should equal 0 + End +End + + +Describe "log_warn()" + BeforeAll 'log_set_verbosity $__log_warning' + AfterAll 'cleanup' + + It "does not print to stdout" + When call log_warn "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "*" + End + + It "prints log messages to stderr" + When call log_warn "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is $__log_warning" + _test_log_warn_verbosity_equal() { + log_set_verbosity "$__log_warning" + log_warn "test" + } + + When call _test_log_warn_verbosity_equal + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is above $__log_warning" + _test_log_warn_verbosity_above() { + log_set_verbosity "$(( __log_warning + 1 ))" + log_warn "test" + } + + When call _test_log_warn_verbosity_above + The stderr should match pattern "* test" + End + + It "does not print a message when the verbosity is below $__log_warning" + _test_log_warn_verbosity_below() { + log_set_verbosity "$(( __log_warning - 1 ))" + log_warn "test" + } + + When call _test_log_warn_verbosity_below + The stderr should equal "" + End + + It "prints the same message to stderr and the logfile" + _test_log_warn_same_output() { + local message + local stderr + local logfile + + message=$(echo "Somewhat $RANDOM message" + echo "For testing purposes $RANDOM") + + rm -f "$__log_file" + output=$(log_warn "$message" 2>&1) + logfile=$(< "$__log_file") + + if [[ "$output" != "$logfile" ]]; then + return 1 + fi + + return 0 + } + + When call _test_log_warn_same_output + The status should equal 0 + End + + It "prints lines passed in positional parameters" + _test_log_warn_lines_in_args() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(log_warn "${lines[@]}" 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_warn_lines_in_args + The status should equal 0 + End + + It "prints lines passed via stdin" + _test_log_warn_lines_via_stdin() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(array_to_lines "${lines[@]}" | log_warn 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_warn_lines_via_stdin + The status should equal 0 + End +End + +Describe "log_error()" + BeforeAll 'log_set_verbosity $__log_error' + AfterAll 'cleanup' + + It "does not print to stdout" + When call log_error "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "*" + End + + It "prints log messages to stderr" + When call log_error "test" + The status should equal 0 + The stdout should equal "" + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is $__log_error" + _test_log_error_verbosity_equal() { + log_set_verbosity "$__log_error" + log_error "test" + } + + When call _test_log_error_verbosity_equal + The stderr should match pattern "* test" + End + + It "prints messages when the verbosity is above $__log_error" + _test_log_error_verbosity_above() { + log_set_verbosity "$(( __log_error + 1 ))" + log_error "test" + } + + When call _test_log_error_verbosity_above + The stderr should match pattern "* test" + End + + It "prints the same message to stderr and the logfile" + _test_log_error_same_output() { + local message + local stderr + local logfile + + message=$(echo "Somewhat $RANDOM message" + echo "For testing purposes $RANDOM") + + rm -f "$__log_file" + output=$(log_error "$message" 2>&1) + logfile=$(< "$__log_file") + + if [[ "$output" != "$logfile" ]]; then + return 1 + fi + + return 0 + } + + When call _test_log_error_same_output + The status should equal 0 + End + + It "prints lines passed in positional parameters" + _test_log_error_lines_in_args() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(log_error "${lines[@]}" 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_error_lines_in_args + The status should equal 0 + End + + It "prints lines passed via stdin" + _test_log_error_lines_via_stdin() { + local lines + local num_lines + + lines=("test$RANDOM" + "test$RANDOM") + num_lines=$(array_to_lines "${lines[@]}" | log_error 2>&1 | wc -l) + + if (( num_lines != ${#lines[@]} )); then + return 1 + fi + + return 0 + } + + When call _test_log_error_lines_via_stdin + The status should equal 0 + End +End -- 2.47.3