aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2020-03-17 16:56:50 +0000
committerBrooks Davis <brooks@FreeBSD.org>2020-03-17 16:56:50 +0000
commit08334c51dbb99d9ecd2bb86a2d94ed06da9e167a (patch)
treec43eb24d59bd5c963583a5190caef80fc8387322 /bootstrap
downloadsrc-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/.gitignore4
-rw-r--r--bootstrap/Kyuafile5
-rw-r--r--bootstrap/Makefile.am.inc90
-rw-r--r--bootstrap/atf_helpers.cpp71
-rw-r--r--bootstrap/plain_helpers.cpp141
-rw-r--r--bootstrap/testsuite.at200
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