Skip to content

Commit 7a24d78

Browse files
committed
lib/testing: Add assert_log{,_file}_equals tests
1 parent 1f3840a commit 7a24d78

File tree

3 files changed

+171
-1
lines changed

3 files changed

+171
-1
lines changed

lib/testing/log

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
# You must source `_GO_CORE_DIR/lib/testing/environment` before this file.
66

77
. "${BASH_SOURCE[0]%/*}/stack-trace"
8+
. "$_GO_CORE_DIR/lib/bats/assertions"
9+
10+
# Log timestamps are disabled by for testing by default.
11+
export _GO_LOG_TIMESTAMP_FORMAT=
812

913
# Creates a `./go` script that imports the `log` module
1014
#
@@ -51,6 +55,24 @@ format_log_label() {
5155
printf '%s' "${__GO_LOG_LEVELS_FORMATTED[$__go_log_level_index]}"
5256
}
5357

58+
# Validates that `output` matches the expected `@go.log` output
59+
#
60+
# Each line can be expressed one of two ways:
61+
# - As a pair of strings: first the log level label, then the log message
62+
# - As a single string without a log level label prefix
63+
#
64+
# Each log level label must exist within `_GO_LOG_LEVELS`, and can be either a
65+
# plaintext label or a label formatted with `format_log_label`. Any unknown
66+
# labels will be parsed as "a single string without a log label prefix".
67+
#
68+
# If you aren't looking for exact log output, consider using one of the standard
69+
# assertions from `_GO_CORE_DIR/lib/bats/assertions` instead.
70+
#
71+
# Note that this does NOT handle timestamps. If you wish to validate specific
72+
# timestamps, see `_GO_CORE_DIR/tests/log/timestamp.bats` for ideas.
73+
#
74+
# Arguments:
75+
# ...: Lines of expected log output
5476
assert_log_equals() {
5577
set "$BATS_ASSERTION_DISABLE_SHELL_OPTIONS"
5678
local __log_level_label
@@ -69,7 +91,7 @@ assert_log_equals() {
6991
fi
7092

7193
if ! shift 2; then
72-
echo "ERROR: Wrong number of arguments for log line $i." >&2
94+
printf 'ERROR: Wrong number of arguments for log line %d.\n' "$i" >&2
7395
return_from_bats_assertion 1
7496
return
7597
fi
@@ -86,6 +108,24 @@ assert_log_equals() {
86108
fi
87109
}
88110

111+
# Validates that a file matches the expected `@go.log` output
112+
#
113+
# Aside from the first file path argument, the remaining arguments and semantics
114+
# are exactly the same as `assert_log_equals`.
115+
#
116+
# In cases where `@go.log_add_output_file` is used to add a `TEST_LOG_FILE` to
117+
# all levels, and all test output comes from `@go.log`, this may be invoked
118+
# following `assert_log_equals` like so to ensure the log file output matches
119+
# standard output and standard error:
120+
#
121+
# assert_log_file_equals "$TEST_LOG_FILE" "${lines[@]}"
122+
#
123+
# If you aren't looking for exact log output, consider using one of the standard
124+
# assertions from `_GO_CORE_DIR/lib/bats/assertions` instead.
125+
#
126+
# Arguments:
127+
# log_file: Path to the log file to validate
128+
# ...: Lines of expected log output
89129
assert_log_file_equals() {
90130
set "$BATS_ASSERTION_DISABLE_SHELL_OPTIONS"
91131
local log_file="$1"
@@ -130,6 +170,16 @@ set_log_command_stack_trace_items() {
130170
# None of the functions below this line are part of the public interface.
131171
# --------------------------------
132172

173+
# Determines whether a log level label is a valid member of `_GO_LOG_LEVELS`.
174+
#
175+
# If so, pads the label and assigns it to `__log_level_label`.
176+
#
177+
# Arguments:
178+
# level_label: Log level label to examine
179+
#
180+
# Returns:
181+
# zero if `level_label` exists in `_GO_LOG_LEVELS`, nonzero otherwise
182+
# __log_level_label: Assigned the padded version of `level_label` if valid
133183
__parse_log_level_label() {
134184
local level_label="$1"
135185
local try_level

tests/testing/log.bats

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ teardown() {
1111
remove_test_go_rootdir
1212
}
1313

14+
@test "$SUITE: log timestamps are disabled for testing by default" {
15+
assert_equal '' "$_GO_LOG_TIMESTAMP_FORMAT"
16+
_GO_LOG_TIMESTAMP_FORMAT='%Y:%m:%d %H:%M:%S'
17+
. "$_GO_CORE_DIR/lib/testing/log"
18+
assert_equal '' "$_GO_LOG_TIMESTAMP_FORMAT"
19+
}
20+
1421
@test "$SUITE: create_log_script and run_log_script without log file" {
1522
export TEST_LOG_FILE="$TEST_GO_ROOTDIR/test-script.log"
1623
TEST_LOG_FILE= run_log_script '@go.log INFO Hello, World!'

tests/testing/log/assertions.bats

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#! /usr/bin/env bats
2+
3+
load ../../environment
4+
5+
ASSERTION_SOURCE="$_GO_CORE_DIR/lib/testing/log"
6+
load "$_GO_CORE_DIR/lib/bats/assertion-test-helpers"
7+
8+
setup() {
9+
test_filter
10+
mkdir -p "$TEST_GO_ROOTDIR"
11+
}
12+
13+
teardown() {
14+
remove_test_go_rootdir
15+
}
16+
17+
@test "$SUITE: assert_log_equals empty output" {
18+
expect_assertion_success ':' 'assert_log_equals'
19+
}
20+
21+
@test "$SUITE: assert_log_equals single non-@go.log line" {
22+
expect_assertion_success 'printf "Hello, World!\n"' \
23+
'assert_log_equals "Hello, World!"'
24+
}
25+
26+
@test "$SUITE: assert_log_equals single @go.log line" {
27+
create_log_script '@go.log INFO Hello, World!'
28+
expect_assertion_success "'$TEST_GO_SCRIPT'" \
29+
'assert_log_equals INFO "Hello, World!"'
30+
}
31+
32+
@test "$SUITE: assert_log_equals single formatted @go.log line" {
33+
create_log_script '@go.log INFO Hello, World!'
34+
_GO_LOG_FORMATTING='true' expect_assertion_success "'$TEST_GO_SCRIPT'" \
35+
"assert_log_equals \"\$(format_log_label INFO)\" 'Hello, World!'"
36+
}
37+
38+
@test "$SUITE: assert_log_equals multiple mixed lines" {
39+
create_log_script '@go.log INFO Hello, World!' \
40+
'printf "%s\n" "Not a @go.log line."' \
41+
'@go.log WARN Goodbye, World!' \
42+
'printf "%s\n" "Also not a @go.log line."'
43+
44+
local args=("'INFO' 'Hello, World!'"
45+
"'Not a @go.log line.'"
46+
"'WARN' 'Goodbye, World!'"
47+
"'Also not a @go.log line.'")
48+
expect_assertion_success "'$TEST_GO_SCRIPT'" \
49+
"assert_log_equals ${args[*]}"
50+
}
51+
52+
@test "$SUITE: assert_log_equals multiple mixed lines with formatting" {
53+
create_log_script '@go.log INFO Hello, World!' \
54+
'printf "%s\n" "Not a @go.log line."' \
55+
'@go.log WARN Goodbye, World!' \
56+
'printf "%s\n" "Also not a @go.log line."'
57+
58+
local args=("\"\$(format_log_label INFO)\" 'Hello, World!'"
59+
"'Not a @go.log line.'"
60+
"\"\$(format_log_label WARN)\" 'Goodbye, World!'"
61+
"'Also not a @go.log line.'")
62+
_GO_LOG_FORMATTING='true' expect_assertion_success "'$TEST_GO_SCRIPT'" \
63+
"assert_log_equals ${args[*]}"
64+
}
65+
66+
@test "$SUITE: assert_log_equals error if wrong number of log line args" {
67+
create_log_script '@go.log INFO Hello, World!'
68+
expect_assertion_failure "'$TEST_GO_SCRIPT'" \
69+
"assert_log_equals 'INFO' 'Hello, World!' 'INFO'" \
70+
'ERROR: Wrong number of arguments for log line 1.'
71+
}
72+
73+
@test "$SUITE: assert_log_equals fails if line doesn't match" {
74+
local info_label="$(format_log_label INFO)"
75+
local end_format_code="$(printf '%b' '\e[0m')"
76+
77+
create_log_script '@go.log INFO Goodbye, World!'
78+
_GO_LOG_FORMATTING='true' expect_assertion_failure "'$TEST_GO_SCRIPT'" \
79+
"assert_log_equals \"\$(format_log_label INFO)\" 'Hello, World!'" \
80+
'line 0 not equal to expected value:' \
81+
" expected: '$info_label Hello, World!$end_format_code'" \
82+
" actual: '$info_label Goodbye, World!$end_format_code'" \
83+
'OUTPUT:' \
84+
"$info_label Goodbye, World!$end_format_code"
85+
}
86+
87+
@test "$SUITE: assert_log_file_equals returns error if file doesn't exist" {
88+
expect_assertion_failure ':' "assert_log_file_equals 'nonexistent.log'" \
89+
"'nonexistent.log' doesn't exist or isn't a regular file."
90+
}
91+
92+
@test "$SUITE: assert_log_file_equals empty output" {
93+
expect_assertion_success "printf '' >'$TEST_GO_ROOTDIR/empty.log'" \
94+
"assert_log_file_equals '$TEST_GO_ROOTDIR/empty.log'"
95+
}
96+
97+
@test "$SUITE: assert_log_file_equals multiple mixed lines with formatting" {
98+
export TEST_LOG_FILE="$TEST_GO_ROOTDIR/test.log"
99+
100+
# We need to clear the `TEST_LOG_FILE` between the two runs performed by
101+
# `expect_assertion_success`, since `@go.log` will append to the file.
102+
create_log_script "printf '' >'$TEST_LOG_FILE'" \
103+
'@go.log INFO Hello, World!' \
104+
'printf "%s\n" "Not a @go.log line."' \
105+
'@go.log WARN Goodbye, World!' \
106+
'printf "%s\n" "Also not a @go.log line."'
107+
108+
# Note that the file should only get the `@go.log` lines.
109+
local args=("\"\$(format_log_label INFO)\" 'Hello, World!'"
110+
"\"\$(format_log_label WARN)\" 'Goodbye, World!'")
111+
_GO_LOG_FORMATTING='true' expect_assertion_success "'$TEST_GO_SCRIPT'" \
112+
"assert_log_file_equals \"\$TEST_LOG_FILE\" ${args[*]}"
113+
}

0 commit comments

Comments
 (0)