Conversation
9357195 to
580166d
Compare
run -N, etc.)
e73b626 to
5fb7f31
Compare
run -N, etc.)run -N)
87cf0b4 to
5fb7f31
Compare
d9deecf to
6bd8318
Compare
run -N)function runc, use run -N)
function runc, use run -N)runc(), use run -N, add asserts)
4d160e8 to
a5cbc11
Compare
1bf73d7 to
60daed2
Compare
|
@AkihiroSuda @cyphar @thaJeztah @lifubang @rata PTAL (this changes our bats tests considerably, and so I have to rebase this manually every time we merge something involving bats tests). If you agree with the concept and the implementation, can we please merge this to reduce my load? One note on reimplementing asserts vs using bats' own -- unfortunately, they don't come with bats-core and the installation is a real PITA, on the other hand the re-implementation is pretty straightforward and probably wouldn't change much. Yet if you don't like it, I can remove the last few commits which add/use asserts. |
|
Sorry, looks like I missed the previous ping; are the failures expected, or something broken in the current PR? |
@thaJeztah It got broken because since it's been written we have added other tests (for example, in commit 5f76d4d), and they all use the old syntax (like I am fixing this right now, but this is basically why I keep asking for reviews -- this changes the tests style slightly, and thus I need to maintain it until it's merged. |
29d3a5d to
2cdc568
Compare
|
I'd love this to be included into 1.6 (but not setting the milestone to not block 1.6-rc1 release); while it does touch runc directly (it's just CI), it will reshape the way we're writing the tests and I'd rather have it sooner than later (it's a big patch set and hard to keep updated as we move along). |
When runc is used as the right hand side of a pipe, it runs in a subshell, so the $status and $output set by bats' run helper (called from the runc wrapper) do not propagate to the test. As a result, the checks that follow such a call silently test the values left over from the previous runc call. Use a heredoc redirection instead of piping the heredoc in. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
We already have a function called runc, and adding a variable with the same name, while not technically incorrect, does not help readability. Fixes: a38f42a Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Until now, runc in integration tests was a bash function, wrapping the actual binary to add the flags all tests need (--root and, sometimes, --systemd-cgroup). A function can not be used where a real binary is required, which is why we also had setup_runc_cmdline and RUNC_CMDLINE, used by the tests that run runc under taskset or in a separate mount namespace. Add tests/integration/bin/runc, a small wrapper script doing the same thing, and prepend its directory to PATH. This way runc can be used both directly and after commands like taskset, nsenter, or timeout, and RUNC_CMDLINE is no longer needed. Note that the runc bash function still takes precedence for a plain "runc ..." call in tests, so their behavior is unchanged. The directory is always put first in PATH, and the runc found in PATH is checked to be the wrapper, so that the tests can not silently use some other runc binary instead. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
With this option, bats prints the value of $output for a failed test, which is exactly what the sane_run wrapper does manually (and what the next commit removes it for). The option requires bats v1.7.0, so bump the minimum version. Our CI uses v1.12.0 on GHA and builds the same version from source on EL8; other platforms use their distro package, which is expected to be new enough (and bats_require_minimum_version makes it obvious if it isn't). Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Now that runc is a real binary (a wrapper script in PATH), tests can
call it the way any other command is called, using bats' run helper
directly:
run -0 runc start ctr
instead of the old
runc start ctr
[ "$status" -eq 0 ]
where runc was a bash function hiding a call to run. The exit code check
is now part of the call: -N for an expected exit code, ! for "any
failure", and no argument where the exit code is checked later or not at
all.
This has to be done in one go: while the runc function exists, "run runc"
would call it, resulting in a nested run.
Other changes made necessary or possible by this:
- The runc and sane_run functions are gone. The output of a failed
command is now printed by bats itself, see the previous commit.
- __runc (a raw runc call, not using run) is now simply runc.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
A fair number of runc calls do not check the exit code at all, although they should. Fix that. Note that two of the checks added to update.bats expect an error (exit code 1), as the test cases there are about runc rejecting a combination of options. The remaining calls that do not check the exit code are the ones that check $status themselves (in an if, or against different values), the one in a background subshell (where a failure can not be detected), and the one that is explicitly documented as being allowed to fail. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
When a test fails on a string comparison, all we see is the failed expression, which usually means adding some debug output and rerunning the test to find out what the actual value was. The bats-assert library solves this, but it (together with its bats-support dependency) has to be installed separately on every distro we test on, which is more trouble than it's worth for a few functions. Add assert_output, refute_output, and assert_line, implementing a subset of the bats-assert API (so that the tests read the same way, and this code can be dropped should bats-assert ever be added as a dependency), and use them for the comparisons against an exact value. Now, when such a check fails, the test log shows what was expected and what was there: -- output does not match (exact) -- expected: '/override' actual: $'\0/override' -- Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The point of the assert helpers is that a failed test says what it wanted and what it got, so leaving most comparisons as bare [[ ]] defeats it. Convert the rest of the checks on $output and $lines. Those using a glob to look for a substring become --partial, the rest become --regexp (the patterns are translated to extended regular expressions, and anchored where the glob was). The few remaining [[ ]] are not assertions: one is an if condition, and another one is the left hand side of ||, offering an alternative to the assert that follows it. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The "Writing integration tests" section only pointed at helpers.bash, which does not say much about how a test is supposed to be written. Now that tests call runc via bats' run helper and check the output with assert_output and friends, document that: how the expected exit code is given to run, which assertions are available, and why they are preferred over a bare test expression. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
|
A somewhat heavy rebase after merging #5455. I'd rather have this one merged (unless there are any objections) to avoid further rebase work. PTAL @lifubang @AkihiroSuda |
This supersedes #4946, taking a different approach to the problems
discussed there (see this comment and below).
The end result is that integration tests call runc the way any other
command is called, and check its output with helpers that say what went
wrong:
run -0 runc start ctr assert_output --partial "something"instead of the current
where
runcis a bash function hiding a call to bats'runhelper, anda failed comparison only shows the expression, not the values.
What a failure looks like now
To see this in practice, four deliberate bugs were introduced (
runc -vprinting
spec :,runc list -qadding a trailing space to the ID, areworded hook error, and
runc delete --forcefailing on a missingcontainer), and the tests were run with and without this PR:
list -qadds a trailing spaceexpected: 'test_box1'actual: 'test_box1 'spec :instead ofspec:runc -voutput to eyeballexpected: 'spec: [0-9]+\.[0-9]+\.[0-9]+'actual: 'spec : 1.3.0'expected: 'error running createRuntime hook #1:'actual: '...failure in createRuntime hook #1...'delete --forcefails[ "$status" -eq 0 ]' failed-- but after which call?run -0 runc delete --force notexists' failed, expected exit code 0, got 1The trailing space one is the point of the whole exercise. Before:
The expected value is not shown, the actual one looks correct, and the
difference is invisible. Now: