diff options
author | Brooks Davis <brooks@FreeBSD.org> | 2020-03-17 16:56:50 +0000 |
---|---|---|
committer | Brooks Davis <brooks@FreeBSD.org> | 2020-03-17 16:56:50 +0000 |
commit | 08334c51dbb99d9ecd2bb86a2d94ed06da9e167a (patch) | |
tree | c43eb24d59bd5c963583a5190caef80fc8387322 /bootstrap | |
download | src-08334c51dbb99d9ecd2bb86a2d94ed06da9e167a.tar.gz src-08334c51dbb99d9ecd2bb86a2d94ed06da9e167a.zip |
Import the kyua testing framework for infrastructure softwarevendor/kyua/0.13-a685f91
Imported at 0.13 plus assumulated changes to git hash a685f91.
Obtained from: https://github.com/jmmv/kyua
Sponsored by: DARPA
Notes
Notes:
svn path=/vendor/kyua/dist/; revision=359042
svn path=/vendor/kyua/0.13-a685f91/; revision=359043; tag=vendor/kyua/0.13-a685f91
Diffstat (limited to 'bootstrap')
-rw-r--r-- | bootstrap/.gitignore | 4 | ||||
-rw-r--r-- | bootstrap/Kyuafile | 5 | ||||
-rw-r--r-- | bootstrap/Makefile.am.inc | 90 | ||||
-rw-r--r-- | bootstrap/atf_helpers.cpp | 71 | ||||
-rw-r--r-- | bootstrap/plain_helpers.cpp | 141 | ||||
-rw-r--r-- | bootstrap/testsuite.at | 200 |
6 files changed, 511 insertions, 0 deletions
diff --git a/bootstrap/.gitignore b/bootstrap/.gitignore new file mode 100644 index 000000000000..effaef8e6b4a --- /dev/null +++ b/bootstrap/.gitignore @@ -0,0 +1,4 @@ +atconfig +package.m4 +testsuite +testsuite.log diff --git a/bootstrap/Kyuafile b/bootstrap/Kyuafile new file mode 100644 index 000000000000..0f161b2d66eb --- /dev/null +++ b/bootstrap/Kyuafile @@ -0,0 +1,5 @@ +syntax(2) + +test_suite("kyua") + +plain_test_program{name="testsuite"} diff --git a/bootstrap/Makefile.am.inc b/bootstrap/Makefile.am.inc new file mode 100644 index 000000000000..0dbf26002ce9 --- /dev/null +++ b/bootstrap/Makefile.am.inc @@ -0,0 +1,90 @@ +# Copyright 2010 The Kyua Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Google Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if WITH_ATF +tests_bootstrapdir = $(pkgtestsdir)/bootstrap + +tests_bootstrap_DATA = bootstrap/Kyuafile +EXTRA_DIST += $(tests_bootstrap_DATA) + +DISTCLEANFILES = bootstrap/atconfig \ + bootstrap/testsuite.lineno \ + bootstrap/testsuite.log + +distclean-local: distclean-testsuite +distclean-testsuite: + -rm -rf bootstrap/testsuite.dir + +EXTRA_DIST += bootstrap/Kyuafile \ + bootstrap/testsuite \ + bootstrap/package.m4 \ + bootstrap/testsuite.at + +tests_bootstrap_PROGRAMS = bootstrap/atf_helpers +bootstrap_atf_helpers_SOURCES = bootstrap/atf_helpers.cpp +bootstrap_atf_helpers_CXXFLAGS = $(ATF_CXX_CFLAGS) +bootstrap_atf_helpers_LDADD = $(ATF_CXX_LIBS) + +tests_bootstrap_PROGRAMS += bootstrap/plain_helpers +bootstrap_plain_helpers_SOURCES = bootstrap/plain_helpers.cpp +bootstrap_plain_helpers_CXXFLAGS = $(UTILS_CFLAGS) + +tests_bootstrap_SCRIPTS = bootstrap/testsuite +@target_srcdir@bootstrap/package.m4: $(top_srcdir)/configure.ac + $(AM_V_GEN){ \ + echo '# Signature of the current package.'; \ + echo 'm4_define(AT_PACKAGE_NAME, @PACKAGE_NAME@)'; \ + echo 'm4_define(AT_PACKAGE_TARNAME, @PACKAGE_TARNAME@)'; \ + echo 'm4_define(AT_PACKAGE_VERSION, @PACKAGE_VERSION@)'; \ + echo 'm4_define(AT_PACKAGE_STRING, @PACKAGE_STRING@)'; \ + echo 'm4_define(AT_PACKAGE_BUGREPORT, @PACKAGE_BUGREPORT@)'; \ + } >$(srcdir)/bootstrap/package.m4 + +@target_srcdir@bootstrap/testsuite: $(srcdir)/bootstrap/testsuite.at \ + @target_srcdir@bootstrap/package.m4 + $(AM_V_GEN)autom4te --language=Autotest -I $(srcdir) \ + -I $(srcdir)/bootstrap \ + $(srcdir)/bootstrap/testsuite.at -o $@.tmp; \ + mv $@.tmp $@ + +CHECK_LOCAL += check-bootstrap +PHONY_TARGETS += check-bootstrap +check-bootstrap: @target_srcdir@bootstrap/testsuite $(check_PROGRAMS) \ + $(CHECK_BOOTSTRAP_DEPS) + cd bootstrap && $(CHECK_ENVIRONMENT) $(TESTS_ENVIRONMENT) \ + ./testsuite + +if !TARGET_SRCDIR_EMPTY +CHECK_BOOTSTRAP_DEPS += copy-bootstrap-testsuite +CHECK_KYUA_DEPS += copy-bootstrap-testsuite +PHONY_TARGETS += copy-bootstrap-testsuite +copy-bootstrap-testsuite: + cp -f @target_srcdir@bootstrap/testsuite bootstrap/testsuite +CLEANFILES += bootstrap/testsuite +endif +endif diff --git a/bootstrap/atf_helpers.cpp b/bootstrap/atf_helpers.cpp new file mode 100644 index 000000000000..6a31b4ced994 --- /dev/null +++ b/bootstrap/atf_helpers.cpp @@ -0,0 +1,71 @@ +// Copyright 2010 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <cstdlib> +#include <string> + +#include <atf-c++.hpp> + + +ATF_TEST_CASE_WITHOUT_HEAD(fails); +ATF_TEST_CASE_BODY(fails) +{ + fail("Failed on purpose"); +} + + +ATF_TEST_CASE_WITHOUT_HEAD(passes); +ATF_TEST_CASE_BODY(passes) +{ +} + + +ATF_TEST_CASE_WITHOUT_HEAD(skips); +ATF_TEST_CASE_BODY(skips) +{ + skip("Skipped on purpose"); +} + + +ATF_INIT_TEST_CASES(tcs) +{ + std::string enabled; + + const char* tests = std::getenv("TESTS"); + if (tests == NULL) + enabled = "fails passes skips"; + else + enabled = tests; + + if (enabled.find("fails") != std::string::npos) + ATF_ADD_TEST_CASE(tcs, fails); + if (enabled.find("passes") != std::string::npos) + ATF_ADD_TEST_CASE(tcs, passes); + if (enabled.find("skips") != std::string::npos) + ATF_ADD_TEST_CASE(tcs, skips); +} diff --git a/bootstrap/plain_helpers.cpp b/bootstrap/plain_helpers.cpp new file mode 100644 index 000000000000..7de629a99d4d --- /dev/null +++ b/bootstrap/plain_helpers.cpp @@ -0,0 +1,141 @@ +// Copyright 2010 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <cstdlib> +#include <cstring> +#include <iostream> + +#include "utils/defs.hpp" +#include "utils/test_utils.ipp" + + +namespace { + + +/// Prints a fake but valid test case list and then aborts. +/// +/// \param argv The original arguments of the program. +/// +/// \return Nothing because this dies before returning. +static int +helper_abort_test_cases_list(int /* argc */, char** argv) +{ + for (const char* const* arg = argv; *arg != NULL; arg++) { + if (std::strcmp(*arg, "-l") == 0) { + std::cout << "Content-Type: application/X-atf-tp; " + "version=\"1\"\n\n"; + std::cout << "ident: foo\n"; + } + } + utils::abort_without_coredump(); +} + + +/// Just returns without printing anything as the test case list. +/// +/// \return Always 0, as required for test programs. +static int +helper_empty_test_cases_list(int /* argc */, char** /* argv */) +{ + return EXIT_SUCCESS; +} + + +/// Prints a correctly-formatted test case list but empty. +/// +/// \param argv The original arguments of the program. +/// +/// \return Always 0, as required for test programs. +static int +helper_zero_test_cases(int /* argc */, char** argv) +{ + for (const char* const* arg = argv; *arg != NULL; arg++) { + if (std::strcmp(*arg, "-l") == 0) + std::cout << "Content-Type: application/X-atf-tp; " + "version=\"1\"\n\n"; + } + return EXIT_SUCCESS; +} + + +/// Mapping of the name of a helper to its implementation. +struct helper { + /// The name of the helper, as will be provided by the user on the CLI. + const char* name; + + /// A pointer to the function implementing the helper. + int (*hook)(int, char**); +}; + + +/// NULL-terminated table mapping helper names to their implementations. +static const helper helpers[] = { + { "abort_test_cases_list", helper_abort_test_cases_list, }, + { "empty_test_cases_list", helper_empty_test_cases_list, }, + { "zero_test_cases", helper_zero_test_cases, }, + { NULL, NULL, }, +}; + + +} // anonymous namespace + + +/// Entry point to the ATF-less helpers. +/// +/// The caller must select a helper to execute by defining the HELPER +/// environment variable to the name of the desired helper. Think of this main +/// method as a subprogram dispatcher, to avoid having many individual helper +/// binaries. +/// +/// \todo Maybe we should really have individual helper binaries. It would +/// avoid a significant amount of complexity here and in the tests, at the +/// expense of some extra files and extra build logic. +/// +/// \param argc The user argument count; delegated to the helper. +/// \param argv The user arguments; delegated to the helper. +/// +/// \return The exit code of the helper, which depends on the requested helper. +int +main(int argc, char** argv) +{ + const char* command = std::getenv("HELPER"); + if (command == NULL) { + std::cerr << "Usage error: HELPER must be set to a helper name\n"; + std::exit(EXIT_FAILURE); + } + + const struct helper* iter = helpers; + for (; iter->name != NULL && std::strcmp(iter->name, command) != 0; iter++) + ; + if (iter->name == NULL) { + std::cerr << "Usage error: unknown command " << command << "\n"; + std::exit(EXIT_FAILURE); + } + + return iter->hook(argc, argv); +} diff --git a/bootstrap/testsuite.at b/bootstrap/testsuite.at new file mode 100644 index 000000000000..10200a67a5ca --- /dev/null +++ b/bootstrap/testsuite.at @@ -0,0 +1,200 @@ +dnl Copyright 2010 The Kyua Authors. +dnl All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted provided that the following conditions are +dnl met: +dnl +dnl * Redistributions of source code must retain the above copyright +dnl notice, this list of conditions and the following disclaimer. +dnl * Redistributions in binary form must reproduce the above copyright +dnl notice, this list of conditions and the following disclaimer in the +dnl documentation and/or other materials provided with the distribution. +dnl * Neither the name of Google Inc. nor the names of its contributors +dnl may be used to endorse or promote products derived from this software +dnl without specific prior written permission. +dnl +dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +AT_INIT([bootstrapping tests]) + + +m4_define([GUESS_TOPDIR], { + old=$(pwd) + cd "$(dirname ${as_myself})" + # We need to locate a build product, not a source file, because the + # test suite may be run outside of the source tree (think distcheck). + while test $(pwd) != '/' -a ! -e bootstrap/plain_helpers; do + cd .. + done + topdir=$(pwd) + cd ${old} + echo ${topdir} +}) + + +m4_define([CREATE_ATF_HELPERS], [ + AT_DATA([Kyuafile], [ +syntax(2) +test_suite("bootstrap") +atf_test_program{name="atf_helpers"} +]) + ln -s $(GUESS_TOPDIR)/bootstrap/atf_helpers atf_helpers +]) +m4_define([RUN_ATF_HELPERS], + [HOME=$(pwd) TESTS="$1" kyua --config=none \ + test --results-file=bootstrap.db $2]) + + +m4_define([CREATE_PLAIN_HELPERS], [ + AT_DATA([Kyuafile], [ +syntax(2) +test_suite("bootstrap") +atf_test_program{name="plain_helpers"} +]) + ln -s $(GUESS_TOPDIR)/bootstrap/plain_helpers plain_helpers +]) +m4_define([RUN_PLAIN_HELPER], + [HOME=$(pwd) HELPER="$1" kyua --config=none \ + test --results-file=bootstrap.db]) + + +AT_SETUP([test program crashes in test list]) +AT_TESTED([kyua]) + +CREATE_PLAIN_HELPERS +AT_CHECK([RUN_PLAIN_HELPER([abort_test_cases_list])], [1], [stdout], []) +re='plain_helpers:__test_cases_list__.*broken.*Test program received signal' +AT_CHECK([grep "${re}" stdout], [0], [ignore], []) + +AT_CLEANUP + + +AT_SETUP([test program prints an empty test list]) +AT_TESTED([kyua]) + +CREATE_PLAIN_HELPERS +AT_CHECK([RUN_PLAIN_HELPER([empty_test_cases_list])], [1], [stdout], []) +re="plain_helpers:__test_cases_list__.*broken.*Invalid header.*got ''" +AT_CHECK([grep "${re}" stdout], [0], [ignore], []) + +AT_CLEANUP + + +AT_SETUP([test program with zero test cases]) +AT_TESTED([kyua]) + +CREATE_PLAIN_HELPERS +AT_CHECK([RUN_PLAIN_HELPER([zero_test_cases])], [1], [stdout], []) +re='plain_helpers:__test_cases_list__.*broken.*No test cases' +AT_CHECK([grep "${re}" stdout], [0], [ignore], []) + +AT_CLEANUP + + +AT_SETUP([run test case that passes]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([RUN_ATF_HELPERS([passes])], [0], [stdout], []) +AT_CHECK([grep "atf_helpers:fails" stdout], [1], [], []) +AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], []) +AT_CHECK([grep "atf_helpers:skips" stdout], [1], [], []) + +AT_CLEANUP + + +AT_SETUP([run test case that fails]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([RUN_ATF_HELPERS([fails])], [1], [stdout], []) +AT_CHECK([grep "atf_helpers:fails.*failed.*Failed on purpose" stdout], + [0], [ignore], []) +AT_CHECK([grep "atf_helpers:passes" stdout], [1], [], []) +AT_CHECK([grep "atf_helpers:skips" stdout], [1], [], []) + +AT_CLEANUP + + +AT_SETUP([run test case that skips]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([RUN_ATF_HELPERS([skips])], [0], [stdout], []) +AT_CHECK([grep "atf_helpers:fails" stdout], [1], [], []) +AT_CHECK([grep "atf_helpers:passes" stdout], [1], [], []) +AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout], + [0], [ignore], []) + +AT_CLEANUP + + +AT_SETUP([run two test cases, success]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([RUN_ATF_HELPERS([passes skips])], [0], [stdout], []) +AT_CHECK([grep "atf_helpers:fails" stdout], [1], [], []) +AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], []) +AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout], + [0], [ignore], []) + +AT_CLEANUP + + +AT_SETUP([run two test cases, failure]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([RUN_ATF_HELPERS([fails passes])], [1], [stdout], []) +AT_CHECK([grep "atf_helpers:fails.*failure.*Failed on purpose" stdout], + [1], [], []) +AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], []) +AT_CHECK([grep "atf_helpers:skips" stdout], [1], [], []) + +AT_CLEANUP + + +AT_SETUP([run mixed test cases]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([RUN_ATF_HELPERS([fails passes skips])], [1], [stdout], []) +AT_CHECK([grep "atf_helpers:fails.*failure.*Failed on purpose" stdout], + [1], [], []) +AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], []) +AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout], + [0], [ignore], []) + +AT_CLEANUP + + +AT_SETUP([run tests from build directories]) +AT_TESTED([kyua]) + +CREATE_ATF_HELPERS +AT_CHECK([mkdir src], [0], [], []) +AT_CHECK([mv Kyuafile src], [0], [], []) +AT_CHECK([mkdir obj], [0], [], []) +AT_CHECK([mv atf_helpers obj], [0], [], []) +AT_CHECK([RUN_ATF_HELPERS([fails passes skips], + [--kyuafile=src/Kyuafile --build-root=obj])], + [1], [stdout], []) +AT_CHECK([grep "atf_helpers:fails.*failure.*Failed on purpose" stdout], + [1], [], []) +AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], []) +AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout], + [0], [ignore], []) + +AT_CLEANUP |