Home | History | Annotate | Line # | Download | only in engine
test_case_test.cpp revision 1.1.1.2
      1      1.1  jmmv // Copyright 2010 Google Inc.
      2      1.1  jmmv // All rights reserved.
      3      1.1  jmmv //
      4      1.1  jmmv // Redistribution and use in source and binary forms, with or without
      5      1.1  jmmv // modification, are permitted provided that the following conditions are
      6      1.1  jmmv // met:
      7      1.1  jmmv //
      8      1.1  jmmv // * Redistributions of source code must retain the above copyright
      9      1.1  jmmv //   notice, this list of conditions and the following disclaimer.
     10      1.1  jmmv // * Redistributions in binary form must reproduce the above copyright
     11      1.1  jmmv //   notice, this list of conditions and the following disclaimer in the
     12      1.1  jmmv //   documentation and/or other materials provided with the distribution.
     13      1.1  jmmv // * Neither the name of Google Inc. nor the names of its contributors
     14      1.1  jmmv //   may be used to endorse or promote products derived from this software
     15      1.1  jmmv //   without specific prior written permission.
     16      1.1  jmmv //
     17      1.1  jmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18      1.1  jmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19      1.1  jmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20      1.1  jmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21      1.1  jmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22      1.1  jmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23      1.1  jmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24      1.1  jmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25      1.1  jmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26      1.1  jmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27      1.1  jmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28      1.1  jmmv 
     29      1.1  jmmv #include "engine/test_case.hpp"
     30      1.1  jmmv 
     31      1.1  jmmv extern "C" {
     32      1.1  jmmv #include <sys/stat.h>
     33      1.1  jmmv 
     34      1.1  jmmv #include <signal.h>
     35      1.1  jmmv #include <unistd.h>
     36      1.1  jmmv }
     37      1.1  jmmv 
     38      1.1  jmmv #include <cerrno>
     39      1.1  jmmv #include <cstdlib>
     40      1.1  jmmv #include <fstream>
     41      1.1  jmmv #include <iostream>
     42      1.1  jmmv #include <sstream>
     43      1.1  jmmv #include <stdexcept>
     44      1.1  jmmv #include <string>
     45      1.1  jmmv 
     46      1.1  jmmv #include <atf-c++.hpp>
     47      1.1  jmmv 
     48      1.1  jmmv #include "engine/config.hpp"
     49      1.1  jmmv #include "engine/exceptions.hpp"
     50      1.1  jmmv #include "engine/kyuafile.hpp"
     51      1.1  jmmv #include "engine/test_program.hpp"
     52      1.1  jmmv #include "engine/test_result.hpp"
     53      1.1  jmmv #include "utils/config/tree.ipp"
     54      1.1  jmmv #include "utils/datetime.hpp"
     55      1.1  jmmv #include "utils/env.hpp"
     56      1.1  jmmv #include "utils/format/macros.hpp"
     57      1.1  jmmv #include "utils/fs/operations.hpp"
     58      1.1  jmmv #include "utils/noncopyable.hpp"
     59      1.1  jmmv #include "utils/optional.ipp"
     60      1.1  jmmv #include "utils/passwd.hpp"
     61      1.1  jmmv #include "utils/process/child.ipp"
     62      1.1  jmmv #include "utils/sanity.hpp"
     63      1.1  jmmv #include "utils/stream.hpp"
     64      1.1  jmmv 
     65      1.1  jmmv namespace config = utils::config;
     66      1.1  jmmv namespace datetime = utils::datetime;
     67      1.1  jmmv namespace fs = utils::fs;
     68      1.1  jmmv namespace passwd = utils::passwd;
     69      1.1  jmmv namespace process = utils::process;
     70      1.1  jmmv 
     71      1.1  jmmv using utils::none;
     72      1.1  jmmv using utils::optional;
     73      1.1  jmmv 
     74      1.1  jmmv 
     75      1.1  jmmv namespace {
     76      1.1  jmmv 
     77      1.1  jmmv 
     78      1.1  jmmv /// Test case hooks to capture stdout and stderr in memory.
     79      1.1  jmmv class capture_hooks : public engine::test_case_hooks {
     80      1.1  jmmv public:
     81      1.1  jmmv     /// Contents of the stdout of the test case.
     82      1.1  jmmv     std::string stdout_contents;
     83      1.1  jmmv 
     84      1.1  jmmv     /// Contents of the stderr of the test case.
     85      1.1  jmmv     std::string stderr_contents;
     86      1.1  jmmv 
     87      1.1  jmmv     /// Stores the stdout of the test case into stdout_contents.
     88      1.1  jmmv     ///
     89      1.1  jmmv     /// \param file The path to the file containing the stdout.
     90      1.1  jmmv     void
     91      1.1  jmmv     got_stdout(const fs::path& file)
     92      1.1  jmmv     {
     93      1.1  jmmv         atf::utils::cat_file(file.str(), "helper stdout:");
     94      1.1  jmmv         ATF_REQUIRE(stdout_contents.empty());
     95      1.1  jmmv 
     96      1.1  jmmv         std::ifstream input(file.c_str());
     97      1.1  jmmv         ATF_REQUIRE(input);
     98      1.1  jmmv         stdout_contents = utils::read_stream(input);
     99      1.1  jmmv     }
    100      1.1  jmmv 
    101      1.1  jmmv     /// Stores the stderr of the test case into stderr_contents.
    102      1.1  jmmv     ///
    103      1.1  jmmv     /// \param file The path to the file containing the stderr.
    104      1.1  jmmv     void
    105      1.1  jmmv     got_stderr(const fs::path& file)
    106      1.1  jmmv     {
    107      1.1  jmmv         atf::utils::cat_file(file.str(), "helper stderr:");
    108      1.1  jmmv         ATF_REQUIRE(stderr_contents.empty());
    109      1.1  jmmv 
    110      1.1  jmmv         std::ifstream input(file.c_str());
    111      1.1  jmmv         ATF_REQUIRE(input);
    112      1.1  jmmv         stderr_contents = utils::read_stream(input);
    113      1.1  jmmv     }
    114      1.1  jmmv };
    115      1.1  jmmv 
    116      1.1  jmmv 
    117      1.1  jmmv /// Launcher for the helper test cases.
    118      1.1  jmmv ///
    119      1.1  jmmv /// This builder class can be used to construct the runtime state of the helper
    120      1.1  jmmv /// test cases and later run them.  The class also provides other helper methods
    121      1.1  jmmv /// to interact with the helper binary.
    122      1.1  jmmv class atf_helper : utils::noncopyable {
    123      1.1  jmmv     /// Path to the test program's source directory.
    124      1.1  jmmv     const fs::path _srcdir;
    125      1.1  jmmv 
    126      1.1  jmmv     /// The root of the test suite.
    127      1.1  jmmv     fs::path _root;
    128      1.1  jmmv 
    129      1.1  jmmv     /// Path to the helper test program, relative to _root.
    130      1.1  jmmv     fs::path _binary_path;
    131      1.1  jmmv 
    132      1.1  jmmv     /// Name of the helper test case to run.
    133      1.1  jmmv     const std::string _name;
    134      1.1  jmmv 
    135      1.1  jmmv     /// Metadata of the test case.
    136      1.1  jmmv     engine::metadata_builder _mdbuilder;
    137      1.1  jmmv 
    138      1.1  jmmv     /// Run-time configuration for the test case.
    139      1.1  jmmv     config::tree _user_config;
    140      1.1  jmmv 
    141      1.1  jmmv public:
    142      1.1  jmmv     /// Constructs a new helper.
    143      1.1  jmmv     ///
    144      1.1  jmmv     /// \param atf_tc A pointer to the calling test case.  Needed to obtain
    145      1.1  jmmv     ///     run-time configuration variables.
    146      1.1  jmmv     /// \param name The name of the helper to run.
    147      1.1  jmmv     atf_helper(const atf::tests::tc* atf_tc, const char* name) :
    148      1.1  jmmv         _srcdir(atf_tc->get_config_var("srcdir")),
    149      1.1  jmmv         _root(_srcdir),
    150      1.1  jmmv         _binary_path("test_case_atf_helpers"),
    151      1.1  jmmv         _name(name),
    152      1.1  jmmv         _user_config(engine::default_config())
    153      1.1  jmmv     {
    154      1.1  jmmv         _user_config.set_string("architecture", "mock-architecture");
    155      1.1  jmmv         _user_config.set_string("platform", "mock-platform");
    156      1.1  jmmv     }
    157      1.1  jmmv 
    158      1.1  jmmv     /// Provides raw access to the run-time configuration.
    159      1.1  jmmv     ///
    160      1.1  jmmv     /// To override test-suite-specific variables, use set_config() as it
    161      1.1  jmmv     /// abstracts away the name of the fake test suite.
    162      1.1  jmmv     ///
    163      1.1  jmmv     /// \returns A reference to the test case configuration.
    164      1.1  jmmv     config::tree&
    165      1.1  jmmv     config(void)
    166      1.1  jmmv     {
    167      1.1  jmmv         return _user_config;
    168      1.1  jmmv     }
    169      1.1  jmmv 
    170      1.1  jmmv     /// Sets a test-suite-specific configuration variable for the helper.
    171      1.1  jmmv     ///
    172      1.1  jmmv     /// \param variable The name of the environment variable to set.
    173      1.1  jmmv     /// \param value The value of the variable; must be convertible to a string.
    174      1.1  jmmv     template< typename T >
    175      1.1  jmmv     void
    176      1.1  jmmv     set_config(const char* variable, const T& value)
    177      1.1  jmmv     {
    178      1.1  jmmv         _user_config.set_string(F("test_suites.the-suite.%s") % variable,
    179      1.1  jmmv                                 F("%s") % value);
    180      1.1  jmmv     }
    181      1.1  jmmv 
    182      1.1  jmmv     /// Sets a metadata variable for the helper.
    183      1.1  jmmv     ///
    184      1.1  jmmv     /// \param variable The name of the environment variable to set.
    185      1.1  jmmv     /// \param value The value of the variable; must be convertible to a string.
    186      1.1  jmmv     template< typename T >
    187      1.1  jmmv     void
    188      1.1  jmmv     set_metadata(const char* variable, const T& value)
    189      1.1  jmmv     {
    190      1.1  jmmv         _mdbuilder.set_string(variable, F("%s") % value);
    191      1.1  jmmv     }
    192      1.1  jmmv 
    193      1.1  jmmv     /// Places the helper in a different location.
    194      1.1  jmmv     ///
    195      1.1  jmmv     /// This prepares the helper to be run from a different location than the
    196      1.1  jmmv     /// source directory so that the runtime execution can be validated.
    197      1.1  jmmv     ///
    198      1.1  jmmv     /// \param new_binary_path The new path to the binary, relative to the test
    199      1.1  jmmv     ///     suite root.
    200      1.1  jmmv     /// \param new_root The new test suite root.
    201      1.1  jmmv     ///
    202      1.1  jmmv     /// \pre The directory holding the target test program must exist.
    203      1.1  jmmv     ///     Otherwise, the relocation of the binary will fail.
    204      1.1  jmmv     void
    205      1.1  jmmv     move(const char* new_binary_path, const char* new_root)
    206      1.1  jmmv     {
    207      1.1  jmmv         _binary_path = fs::path(new_binary_path);
    208      1.1  jmmv         _root = fs::path(new_root);
    209      1.1  jmmv 
    210      1.1  jmmv         const fs::path src_path = fs::path(_srcdir / "test_case_atf_helpers");
    211      1.1  jmmv         const fs::path new_path = _root / _binary_path;
    212      1.1  jmmv         ATF_REQUIRE(
    213      1.1  jmmv             ::symlink(src_path.c_str(), new_path.c_str()) != -1);
    214      1.1  jmmv     }
    215      1.1  jmmv 
    216      1.1  jmmv     /// Runs the helper.
    217      1.1  jmmv     ///
    218      1.1  jmmv     /// \return The result of the execution.
    219      1.1  jmmv     engine::test_result
    220      1.1  jmmv     run(void) const
    221      1.1  jmmv     {
    222      1.1  jmmv         engine::test_case_hooks dummy_hooks;
    223      1.1  jmmv         return run(dummy_hooks);
    224      1.1  jmmv     }
    225      1.1  jmmv 
    226      1.1  jmmv     /// Runs the helper.
    227      1.1  jmmv     ///
    228      1.1  jmmv     /// \param hooks The hooks to pass to the test case.
    229      1.1  jmmv     ///
    230      1.1  jmmv     /// \return The result of the execution.
    231      1.1  jmmv     engine::test_result
    232      1.1  jmmv     run(engine::test_case_hooks& hooks) const
    233      1.1  jmmv     {
    234      1.1  jmmv         const engine::test_program test_program(
    235      1.1  jmmv             "atf", _binary_path, _root, "the-suite",
    236      1.1  jmmv             engine::metadata_builder().build());
    237      1.1  jmmv         const engine::test_case test_case("atf", test_program, _name,
    238      1.1  jmmv                                           _mdbuilder.build());
    239      1.1  jmmv 
    240      1.1  jmmv         const fs::path workdir("work");
    241      1.1  jmmv         fs::mkdir(workdir, 0755);
    242      1.1  jmmv 
    243      1.1  jmmv         const engine::test_result result = engine::run_test_case(
    244      1.1  jmmv             &test_case, _user_config, hooks, workdir);
    245      1.1  jmmv         ATF_REQUIRE(::rmdir(workdir.c_str()) != -1);
    246      1.1  jmmv         return result;
    247      1.1  jmmv     }
    248      1.1  jmmv };
    249      1.1  jmmv 
    250      1.1  jmmv 
    251      1.1  jmmv /// Hooks to retrieve stdout and stderr.
    252      1.1  jmmv class fetch_output_hooks : public engine::test_case_hooks {
    253      1.1  jmmv public:
    254      1.1  jmmv     /// Copies the stdout of the test case outside of its work directory.
    255      1.1  jmmv     ///
    256      1.1  jmmv     /// \param file The location of the test case's stdout.
    257      1.1  jmmv     void
    258      1.1  jmmv     got_stdout(const fs::path& file)
    259      1.1  jmmv     {
    260      1.1  jmmv         atf::utils::copy_file(file.str(), "helper-stdout.txt");
    261      1.1  jmmv         atf::utils::cat_file("helper-stdout.txt", "helper stdout: ");
    262      1.1  jmmv     }
    263      1.1  jmmv 
    264      1.1  jmmv     /// Copies the stderr of the test case outside of its work directory.
    265      1.1  jmmv     ///
    266      1.1  jmmv     /// \param file The location of the test case's stderr.
    267      1.1  jmmv     void
    268      1.1  jmmv     got_stderr(const fs::path& file)
    269      1.1  jmmv     {
    270      1.1  jmmv         atf::utils::copy_file(file.str(), "helper-stderr.txt");
    271      1.1  jmmv         atf::utils::cat_file("helper-stderr.txt", "helper stderr: ");
    272      1.1  jmmv     }
    273      1.1  jmmv };
    274      1.1  jmmv 
    275      1.1  jmmv 
    276      1.1  jmmv /// Simplifies the execution of the helper test cases.
    277      1.1  jmmv class plain_helper {
    278      1.1  jmmv     /// Path to the test program's source directory.
    279      1.1  jmmv     const fs::path _srcdir;
    280      1.1  jmmv 
    281      1.1  jmmv     /// The root of the test suite.
    282      1.1  jmmv     fs::path _root;
    283      1.1  jmmv 
    284      1.1  jmmv     /// Path to the helper test program, relative to _root.
    285      1.1  jmmv     fs::path _binary_path;
    286      1.1  jmmv 
    287      1.1  jmmv     /// Optional timeout for the test program.
    288      1.1  jmmv     optional< datetime::delta > _timeout;
    289      1.1  jmmv 
    290      1.1  jmmv public:
    291      1.1  jmmv     /// Constructs a new helper.
    292      1.1  jmmv     ///
    293      1.1  jmmv     /// \param atf_tc A pointer to the calling test case.  Needed to obtain
    294      1.1  jmmv     ///     run-time configuration variables.
    295      1.1  jmmv     /// \param name The name of the helper to run.
    296      1.1  jmmv     /// \param timeout An optional timeout for the test case.
    297      1.1  jmmv     plain_helper(const atf::tests::tc* atf_tc, const char* name,
    298      1.1  jmmv                  const optional< datetime::delta > timeout = none) :
    299      1.1  jmmv         _srcdir(atf_tc->get_config_var("srcdir")),
    300      1.1  jmmv         _root(_srcdir),
    301      1.1  jmmv         _binary_path("test_case_plain_helpers"),
    302      1.1  jmmv         _timeout(timeout)
    303      1.1  jmmv     {
    304      1.1  jmmv         utils::setenv("TEST_CASE", name);
    305      1.1  jmmv     }
    306      1.1  jmmv 
    307      1.1  jmmv     /// Sets an environment variable for the helper.
    308      1.1  jmmv     ///
    309      1.1  jmmv     /// This is simply syntactic sugar for utils::setenv.
    310      1.1  jmmv     ///
    311      1.1  jmmv     /// \param variable The name of the environment variable to set.
    312      1.1  jmmv     /// \param value The value of the variable; must be convertible to a string.
    313      1.1  jmmv     template< typename T >
    314      1.1  jmmv     void
    315      1.1  jmmv     set(const char* variable, const T& value)
    316      1.1  jmmv     {
    317      1.1  jmmv         utils::setenv(variable, F("%s") % value);
    318      1.1  jmmv     }
    319      1.1  jmmv 
    320      1.1  jmmv     /// Places the helper in a different location.
    321      1.1  jmmv     ///
    322      1.1  jmmv     /// This prepares the helper to be run from a different location than the
    323      1.1  jmmv     /// source directory so that the runtime execution can be validated.
    324      1.1  jmmv     ///
    325      1.1  jmmv     /// \param new_binary_path The new path to the binary, relative to the test
    326      1.1  jmmv     ///     suite root.
    327      1.1  jmmv     /// \param new_root The new test suite root.
    328      1.1  jmmv     ///
    329      1.1  jmmv     /// \pre The directory holding the target test program must exist.
    330      1.1  jmmv     ///     Otherwise, the relocation of the binary will fail.
    331      1.1  jmmv     void
    332      1.1  jmmv     move(const char* new_binary_path, const char* new_root)
    333      1.1  jmmv     {
    334      1.1  jmmv         _binary_path = fs::path(new_binary_path);
    335      1.1  jmmv         _root = fs::path(new_root);
    336      1.1  jmmv 
    337      1.1  jmmv         const fs::path src_path = fs::path(_srcdir) / "test_case_plain_helpers";
    338      1.1  jmmv         const fs::path new_path = _root / _binary_path;
    339      1.1  jmmv         ATF_REQUIRE(
    340      1.1  jmmv             ::symlink(src_path.c_str(), new_path.c_str()) != -1);
    341      1.1  jmmv     }
    342      1.1  jmmv 
    343      1.1  jmmv     /// Runs the helper.
    344      1.1  jmmv     ///
    345      1.1  jmmv     /// \param user_config The runtime engine configuration, if different to the
    346      1.1  jmmv     /// defaults.
    347      1.1  jmmv     ///
    348      1.1  jmmv     /// \return The result of the execution.
    349      1.1  jmmv     engine::test_result
    350      1.1  jmmv     run(const config::tree& user_config = engine::default_config()) const
    351      1.1  jmmv     {
    352      1.1  jmmv         engine::metadata_builder mdbuilder;
    353      1.1  jmmv         if (_timeout)
    354      1.1  jmmv             mdbuilder.set_timeout(_timeout.get());
    355      1.1  jmmv         const engine::test_program test_program(
    356      1.1  jmmv             "plain", _binary_path, _root, "unit-tests", mdbuilder.build());
    357      1.1  jmmv         const engine::test_cases_vector& tcs = test_program.test_cases();
    358      1.1  jmmv         fetch_output_hooks fetcher;
    359      1.1  jmmv         const engine::test_result result = engine::run_test_case(
    360      1.1  jmmv             tcs[0].get(), user_config, fetcher, fs::path("."));
    361      1.1  jmmv         std::cerr << "Result is: " << result << '\n';
    362      1.1  jmmv         return result;
    363      1.1  jmmv     }
    364      1.1  jmmv };
    365      1.1  jmmv 
    366      1.1  jmmv 
    367  1.1.1.2  jmmv /// Creates a mock tester that receives a signal.
    368  1.1.1.2  jmmv ///
    369  1.1.1.2  jmmv /// \param interface The name of the interface implemented by the tester.
    370  1.1.1.2  jmmv /// \param term_sig Signal to deliver to the tester.  If the tester does not
    371  1.1.1.2  jmmv ///     exit due to this reason, it exits with an arbitrary non-zero code.
    372  1.1.1.2  jmmv static void
    373  1.1.1.2  jmmv create_mock_tester_signal(const char* interface, const int term_sig)
    374  1.1.1.2  jmmv {
    375  1.1.1.2  jmmv     const std::string tester_name = F("kyua-%s-tester") % interface;
    376  1.1.1.2  jmmv 
    377  1.1.1.2  jmmv     atf::utils::create_file(
    378  1.1.1.2  jmmv         tester_name,
    379  1.1.1.2  jmmv         F("#! /bin/sh\n"
    380  1.1.1.2  jmmv           "echo 'stdout stuff'\n"
    381  1.1.1.2  jmmv           "echo 'stderr stuff' 1>&2\n"
    382  1.1.1.2  jmmv           "kill -%s $$\n"
    383  1.1.1.2  jmmv           "echo 'not reachable' 1>&2\n"
    384  1.1.1.2  jmmv           "exit 0\n") % term_sig);
    385  1.1.1.2  jmmv     ATF_REQUIRE(::chmod(tester_name.c_str(), 0755) != -1);
    386  1.1.1.2  jmmv 
    387  1.1.1.2  jmmv     utils::setenv("KYUA_TESTERSDIR", fs::current_path().str());
    388  1.1.1.2  jmmv }
    389  1.1.1.2  jmmv 
    390  1.1.1.2  jmmv 
    391      1.1  jmmv }  // anonymous namespace
    392      1.1  jmmv 
    393      1.1  jmmv 
    394      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(test_case__ctor_and_getters)
    395      1.1  jmmv ATF_TEST_CASE_BODY(test_case__ctor_and_getters)
    396      1.1  jmmv {
    397      1.1  jmmv     const engine::metadata md = engine::metadata_builder()
    398      1.1  jmmv         .add_custom("first", "value")
    399      1.1  jmmv         .build();
    400      1.1  jmmv     const engine::test_program test_program(
    401      1.1  jmmv         "mock", fs::path("abc"), fs::path("unused-root"),
    402      1.1  jmmv         "unused-suite-name", engine::metadata_builder().build());
    403      1.1  jmmv     const engine::test_case test_case("mock", test_program, "foo", md);
    404      1.1  jmmv     ATF_REQUIRE_EQ(&test_program, &test_case.container_test_program());
    405      1.1  jmmv     ATF_REQUIRE_EQ("foo", test_case.name());
    406      1.1  jmmv     ATF_REQUIRE(md == test_case.get_metadata());
    407      1.1  jmmv }
    408      1.1  jmmv 
    409      1.1  jmmv 
    410      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(test_case__fake_result)
    411      1.1  jmmv ATF_TEST_CASE_BODY(test_case__fake_result)
    412      1.1  jmmv {
    413      1.1  jmmv     const engine::test_result result(engine::test_result::skipped,
    414      1.1  jmmv                                      "Some reason");
    415      1.1  jmmv     const engine::test_program test_program(
    416      1.1  jmmv         "mock", fs::path("abc"), fs::path("unused-root"),
    417      1.1  jmmv         "unused-suite-name", engine::metadata_builder().build());
    418      1.1  jmmv     const engine::test_case test_case("mock", test_program, "__foo__",
    419      1.1  jmmv                                       "Some description", result);
    420      1.1  jmmv     ATF_REQUIRE_EQ(&test_program, &test_case.container_test_program());
    421      1.1  jmmv     ATF_REQUIRE_EQ("__foo__", test_case.name());
    422      1.1  jmmv     ATF_REQUIRE(result == test_case.fake_result().get());
    423      1.1  jmmv }
    424      1.1  jmmv 
    425      1.1  jmmv 
    426      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(test_case__operators_eq_and_ne__copy);
    427      1.1  jmmv ATF_TEST_CASE_BODY(test_case__operators_eq_and_ne__copy)
    428      1.1  jmmv {
    429      1.1  jmmv     const engine::test_program tp(
    430      1.1  jmmv         "plain", fs::path("non-existent"), fs::path("."), "suite-name",
    431      1.1  jmmv         engine::metadata_builder().build());
    432      1.1  jmmv 
    433      1.1  jmmv     const engine::test_case tc1("plain", tp, "name",
    434      1.1  jmmv                                 engine::metadata_builder().build());
    435      1.1  jmmv     const engine::test_case tc2 = tc1;
    436      1.1  jmmv     ATF_REQUIRE(  tc1 == tc2);
    437      1.1  jmmv     ATF_REQUIRE(!(tc1 != tc2));
    438      1.1  jmmv }
    439      1.1  jmmv 
    440      1.1  jmmv 
    441      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(test_case__output);
    442      1.1  jmmv ATF_TEST_CASE_BODY(test_case__output)
    443      1.1  jmmv {
    444      1.1  jmmv     const engine::test_program tp(
    445      1.1  jmmv         "plain", fs::path("non-existent"), fs::path("."), "suite-name",
    446      1.1  jmmv         engine::metadata_builder().build());
    447      1.1  jmmv 
    448      1.1  jmmv     const engine::test_case tc1(
    449      1.1  jmmv         "plain", tp, "the-name", engine::metadata_builder()
    450      1.1  jmmv         .add_allowed_platform("foo").add_custom("X-bar", "baz").build());
    451      1.1  jmmv     std::ostringstream str;
    452      1.1  jmmv     str << tc1;
    453      1.1  jmmv     ATF_REQUIRE_EQ(
    454      1.1  jmmv         "test_case{interface='plain', name='the-name', "
    455      1.1  jmmv         "metadata=metadata{allowed_architectures='', allowed_platforms='foo', "
    456      1.1  jmmv         "custom.X-bar='baz', description='', has_cleanup='false', "
    457      1.1  jmmv         "required_configs='', required_files='', required_memory='0', "
    458      1.1  jmmv         "required_programs='', required_user='', timeout='300'}}",
    459      1.1  jmmv         str.str());
    460      1.1  jmmv }
    461      1.1  jmmv 
    462      1.1  jmmv 
    463      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(test_case__operators_eq_and_ne__not_copy);
    464      1.1  jmmv ATF_TEST_CASE_BODY(test_case__operators_eq_and_ne__not_copy)
    465      1.1  jmmv {
    466      1.1  jmmv     const std::string base_interface("plain");
    467      1.1  jmmv     const engine::test_program base_tp(
    468      1.1  jmmv         "plain", fs::path("non-existent"), fs::path("."), "suite-name",
    469      1.1  jmmv         engine::metadata_builder().build());
    470      1.1  jmmv     const std::string base_name("name");
    471      1.1  jmmv     const engine::metadata base_metadata = engine::metadata_builder()
    472      1.1  jmmv         .add_custom("X-foo", "bar")
    473      1.1  jmmv         .build();
    474      1.1  jmmv 
    475      1.1  jmmv     const engine::test_case base_tc(base_interface, base_tp, base_name,
    476      1.1  jmmv                                     base_metadata);
    477      1.1  jmmv 
    478      1.1  jmmv     // Construct with all same values.
    479      1.1  jmmv     {
    480      1.1  jmmv         const engine::test_case other_tc(base_interface, base_tp, base_name,
    481      1.1  jmmv                                         base_metadata);
    482      1.1  jmmv 
    483      1.1  jmmv         ATF_REQUIRE(  base_tc == other_tc);
    484      1.1  jmmv         ATF_REQUIRE(!(base_tc != other_tc));
    485      1.1  jmmv     }
    486      1.1  jmmv 
    487      1.1  jmmv     // Different interface.
    488      1.1  jmmv     {
    489      1.1  jmmv         const engine::test_case other_tc("atf", base_tp, base_name,
    490      1.1  jmmv                                          base_metadata);
    491      1.1  jmmv 
    492      1.1  jmmv         ATF_REQUIRE(!(base_tc == other_tc));
    493      1.1  jmmv         ATF_REQUIRE(  base_tc != other_tc);
    494      1.1  jmmv     }
    495      1.1  jmmv 
    496      1.1  jmmv     // Different test program, different identifier.
    497      1.1  jmmv     {
    498      1.1  jmmv         const engine::test_program other_tp(
    499      1.1  jmmv             "plain", fs::path("another-name"), fs::path("."), "suite2-name",
    500      1.1  jmmv         engine::metadata_builder().build());
    501      1.1  jmmv         const engine::test_case other_tc(base_interface, other_tp, base_name,
    502      1.1  jmmv                                          base_metadata);
    503      1.1  jmmv 
    504      1.1  jmmv         ATF_REQUIRE(!(base_tc == other_tc));
    505      1.1  jmmv         ATF_REQUIRE(  base_tc != other_tc);
    506      1.1  jmmv     }
    507      1.1  jmmv 
    508      1.1  jmmv     // Different test program, same identifier.  Cannot be detected!
    509      1.1  jmmv     {
    510      1.1  jmmv         const engine::test_program other_tp(
    511      1.1  jmmv             "plain", fs::path("non-existent"), fs::path("."), "suite2-name",
    512      1.1  jmmv         engine::metadata_builder().build());
    513      1.1  jmmv         const engine::test_case other_tc(base_interface, other_tp, base_name,
    514      1.1  jmmv                                          base_metadata);
    515      1.1  jmmv 
    516      1.1  jmmv         ATF_REQUIRE(  base_tc == other_tc);
    517      1.1  jmmv         ATF_REQUIRE(!(base_tc != other_tc));
    518      1.1  jmmv     }
    519      1.1  jmmv 
    520      1.1  jmmv     // Different name.
    521      1.1  jmmv     {
    522      1.1  jmmv         const engine::test_case other_tc(base_interface, base_tp, "other",
    523      1.1  jmmv                                          base_metadata);
    524      1.1  jmmv 
    525      1.1  jmmv         ATF_REQUIRE(!(base_tc == other_tc));
    526      1.1  jmmv         ATF_REQUIRE(  base_tc != other_tc);
    527      1.1  jmmv     }
    528      1.1  jmmv 
    529      1.1  jmmv     // Different metadata.
    530      1.1  jmmv     {
    531      1.1  jmmv         const engine::test_case other_tc(base_interface, base_tp, base_name,
    532      1.1  jmmv                                          engine::metadata_builder().build());
    533      1.1  jmmv 
    534      1.1  jmmv         ATF_REQUIRE(!(base_tc == other_tc));
    535      1.1  jmmv         ATF_REQUIRE(  base_tc != other_tc);
    536      1.1  jmmv     }
    537      1.1  jmmv }
    538      1.1  jmmv 
    539      1.1  jmmv 
    540  1.1.1.2  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__tester_crashes);
    541  1.1.1.2  jmmv ATF_TEST_CASE_BODY(run_test_case__tester_crashes)
    542  1.1.1.2  jmmv {
    543  1.1.1.2  jmmv     atf_helper helper(this, "pass");
    544  1.1.1.2  jmmv     helper.move("program", ".");
    545  1.1.1.2  jmmv     create_mock_tester_signal("atf", SIGSEGV);
    546  1.1.1.2  jmmv     capture_hooks hooks;
    547  1.1.1.2  jmmv     const engine::test_result result = helper.run(hooks);
    548  1.1.1.2  jmmv 
    549  1.1.1.2  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
    550  1.1.1.2  jmmv     ATF_REQUIRE_MATCH("Tester received signal.*bug", result.reason());
    551  1.1.1.2  jmmv 
    552  1.1.1.2  jmmv     ATF_REQUIRE_EQ("stdout stuff\n", hooks.stdout_contents);
    553  1.1.1.2  jmmv     ATF_REQUIRE_EQ("stderr stuff\n", hooks.stderr_contents);
    554  1.1.1.2  jmmv }
    555  1.1.1.2  jmmv 
    556  1.1.1.2  jmmv 
    557      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__current_directory);
    558      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__current_directory)
    559      1.1  jmmv {
    560      1.1  jmmv     atf_helper helper(this, "pass");
    561      1.1  jmmv     helper.move("program", ".");
    562      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    563      1.1  jmmv                    helper.run());
    564      1.1  jmmv }
    565      1.1  jmmv 
    566      1.1  jmmv 
    567      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__subdirectory);
    568      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__subdirectory)
    569      1.1  jmmv {
    570      1.1  jmmv     atf_helper helper(this, "pass");
    571      1.1  jmmv     ATF_REQUIRE(::mkdir("dir1", 0755) != -1);
    572      1.1  jmmv     ATF_REQUIRE(::mkdir("dir1/dir2", 0755) != -1);
    573      1.1  jmmv     helper.move("dir2/program", "dir1");
    574      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    575      1.1  jmmv                    helper.run());
    576      1.1  jmmv }
    577      1.1  jmmv 
    578      1.1  jmmv 
    579      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__config_variables);
    580      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__config_variables)
    581      1.1  jmmv {
    582      1.1  jmmv     atf_helper helper(this, "create_cookie_in_control_dir");
    583      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    584      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    585      1.1  jmmv                    helper.run());
    586      1.1  jmmv 
    587      1.1  jmmv     if (!fs::exists(fs::path("cookie")))
    588      1.1  jmmv         fail("The cookie was not created where we expected; the test program "
    589      1.1  jmmv              "probably received an invalid configuration variable");
    590      1.1  jmmv }
    591      1.1  jmmv 
    592      1.1  jmmv 
    593      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__cleanup_shares_workdir);
    594      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__cleanup_shares_workdir)
    595      1.1  jmmv {
    596      1.1  jmmv     atf_helper helper(this, "check_cleanup_workdir");
    597      1.1  jmmv     helper.set_metadata("has_cleanup", "true");
    598      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    599      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped,
    600      1.1  jmmv                                        "cookie created"), helper.run());
    601      1.1  jmmv 
    602      1.1  jmmv     if (fs::exists(fs::path("missing_cookie")))
    603      1.1  jmmv         fail("The cleanup part did not see the cookie; the work directory "
    604      1.1  jmmv              "is probably not shared");
    605      1.1  jmmv     if (fs::exists(fs::path("invalid_cookie")))
    606      1.1  jmmv         fail("The cleanup part read an invalid cookie");
    607      1.1  jmmv     if (!fs::exists(fs::path("cookie_ok")))
    608      1.1  jmmv         fail("The cleanup part was not executed");
    609      1.1  jmmv }
    610      1.1  jmmv 
    611      1.1  jmmv 
    612      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__has_cleanup__atf__false);
    613      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__has_cleanup__atf__false)
    614      1.1  jmmv {
    615      1.1  jmmv     atf_helper helper(this, "create_cookie_from_cleanup");
    616      1.1  jmmv     helper.set_metadata("has_cleanup", "false");
    617      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    618      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    619      1.1  jmmv                    helper.run());
    620      1.1  jmmv 
    621      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    622      1.1  jmmv         fail("The cleanup part was executed even though the test case set "
    623      1.1  jmmv              "has.cleanup to false");
    624      1.1  jmmv }
    625      1.1  jmmv 
    626      1.1  jmmv 
    627      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__has_cleanup__atf__true);
    628      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__has_cleanup__atf__true)
    629      1.1  jmmv {
    630      1.1  jmmv     atf_helper helper(this, "create_cookie_from_cleanup");
    631      1.1  jmmv     helper.set_metadata("has_cleanup", "true");
    632      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    633      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    634      1.1  jmmv                    helper.run());
    635      1.1  jmmv 
    636      1.1  jmmv     if (!fs::exists(fs::path("cookie")))
    637      1.1  jmmv         fail("The cleanup part was not executed even though the test case set "
    638      1.1  jmmv              "has.cleanup to true");
    639      1.1  jmmv }
    640      1.1  jmmv 
    641      1.1  jmmv 
    642      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__kill_children);
    643      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__kill_children)
    644      1.1  jmmv {
    645      1.1  jmmv     atf_helper helper(this, "spawn_blocking_child");
    646      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    647      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    648      1.1  jmmv                    helper.run());
    649      1.1  jmmv 
    650      1.1  jmmv     if (!fs::exists(fs::path("pid")))
    651      1.1  jmmv         fail("The pid file was not created");
    652      1.1  jmmv     std::ifstream pidfile("pid");
    653      1.1  jmmv     ATF_REQUIRE(pidfile);
    654      1.1  jmmv     pid_t pid;
    655      1.1  jmmv     pidfile >> pid;
    656      1.1  jmmv     pidfile.close();
    657      1.1  jmmv 
    658      1.1  jmmv     int attempts = 30;
    659      1.1  jmmv retry:
    660      1.1  jmmv     if (::kill(pid, SIGCONT) != -1 || errno != ESRCH) {
    661      1.1  jmmv         // Looks like the subchild did not die.
    662      1.1  jmmv         //
    663      1.1  jmmv         // Note that this might be inaccurate for two reasons:
    664      1.1  jmmv         // 1) The system may have spawned a new process with the same pid as
    665      1.1  jmmv         //    our subchild... but in practice, this does not happen because
    666      1.1  jmmv         //    most systems do not immediately reuse pid numbers.  If that
    667      1.1  jmmv         //    happens... well, we get a false test failure.
    668      1.1  jmmv         // 2) We ran so fast that even if the process was sent a signal to
    669      1.1  jmmv         //    die, it has not had enough time to process it yet.  This is why
    670      1.1  jmmv         //    we retry this a few times.
    671      1.1  jmmv         if (attempts > 0) {
    672      1.1  jmmv             std::cout << "Subprocess not dead yet; retrying wait\n";
    673      1.1  jmmv             --attempts;
    674      1.1  jmmv             ::usleep(100000);
    675      1.1  jmmv             goto retry;
    676      1.1  jmmv         }
    677      1.1  jmmv         fail(F("The subprocess %s of our child was not killed") % pid);
    678      1.1  jmmv     }
    679      1.1  jmmv }
    680      1.1  jmmv 
    681      1.1  jmmv 
    682      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__isolation);
    683      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__isolation)
    684      1.1  jmmv {
    685      1.1  jmmv     atf_helper helper(this, "validate_isolation");
    686      1.1  jmmv     // Simple checks to make sure that the test case has been isolated.
    687      1.1  jmmv     utils::setenv("HOME", "fake-value");
    688      1.1  jmmv     utils::setenv("LANG", "C");
    689      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    690      1.1  jmmv                    helper.run());
    691      1.1  jmmv }
    692      1.1  jmmv 
    693      1.1  jmmv 
    694      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__allowed_architectures);
    695      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__allowed_architectures)
    696      1.1  jmmv {
    697      1.1  jmmv     atf_helper helper(this, "create_cookie_in_control_dir");
    698      1.1  jmmv     helper.set_metadata("allowed_architectures", "i386 x86_64");
    699      1.1  jmmv     helper.config().set_string("architecture", "powerpc");
    700      1.1  jmmv     helper.config().set_string("platform", "");
    701      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped, "Current "
    702      1.1  jmmv                                        "architecture 'powerpc' not supported"),
    703      1.1  jmmv                    helper.run());
    704      1.1  jmmv 
    705      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    706      1.1  jmmv         fail("The test case was not really skipped when the requirements "
    707      1.1  jmmv              "check failed");
    708      1.1  jmmv }
    709      1.1  jmmv 
    710      1.1  jmmv 
    711      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__allowed_platforms);
    712      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__allowed_platforms)
    713      1.1  jmmv {
    714      1.1  jmmv     atf_helper helper(this, "create_cookie_in_control_dir");
    715      1.1  jmmv     helper.set_metadata("allowed_platforms", "i386 amd64");
    716      1.1  jmmv     helper.config().set_string("architecture", "");
    717      1.1  jmmv     helper.config().set_string("platform", "macppc");
    718      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped, "Current "
    719      1.1  jmmv                                        "platform 'macppc' not supported"),
    720      1.1  jmmv                    helper.run());
    721      1.1  jmmv 
    722      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    723      1.1  jmmv         fail("The test case was not really skipped when the requirements "
    724      1.1  jmmv              "check failed");
    725      1.1  jmmv }
    726      1.1  jmmv 
    727      1.1  jmmv 
    728      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__required_configs);
    729      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_configs)
    730      1.1  jmmv {
    731      1.1  jmmv     atf_helper helper(this, "create_cookie_in_control_dir");
    732      1.1  jmmv     helper.set_metadata("required_configs", "used-var");
    733      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    734      1.1  jmmv     helper.set_config("unused-var", "value");
    735      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped, "Required "
    736      1.1  jmmv                                        "configuration property 'used-var' not "
    737      1.1  jmmv                                        "defined"),
    738      1.1  jmmv                    helper.run());
    739      1.1  jmmv 
    740      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    741      1.1  jmmv         fail("The test case was not really skipped when the requirements "
    742      1.1  jmmv              "check failed");
    743      1.1  jmmv }
    744      1.1  jmmv 
    745      1.1  jmmv 
    746      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__required_programs);
    747      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_programs)
    748      1.1  jmmv {
    749      1.1  jmmv     atf_helper helper(this, "create_cookie_in_control_dir");
    750      1.1  jmmv     helper.set_metadata("required_programs", "/non-existent/program");
    751      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped, "Required "
    752      1.1  jmmv                                        "program '/non-existent/program' not "
    753      1.1  jmmv                                        "found"),
    754      1.1  jmmv                    helper.run());
    755      1.1  jmmv 
    756      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    757      1.1  jmmv         fail("The test case was not really skipped when the requirements "
    758      1.1  jmmv              "check failed");
    759      1.1  jmmv }
    760      1.1  jmmv 
    761      1.1  jmmv 
    762      1.1  jmmv ATF_TEST_CASE(run_test_case__atf__required_user__atf__root__atf__ok);
    763      1.1  jmmv ATF_TEST_CASE_HEAD(run_test_case__atf__required_user__atf__root__atf__ok)
    764      1.1  jmmv {
    765      1.1  jmmv     set_md_var("require.user", "root");
    766      1.1  jmmv }
    767      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_user__atf__root__atf__ok)
    768      1.1  jmmv {
    769      1.1  jmmv     atf_helper helper(this, "create_cookie_in_workdir");
    770      1.1  jmmv     helper.set_metadata("required_user", "root");
    771      1.1  jmmv     ATF_REQUIRE(passwd::current_user().is_root());
    772      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    773      1.1  jmmv                    helper.run());
    774      1.1  jmmv }
    775      1.1  jmmv 
    776      1.1  jmmv 
    777      1.1  jmmv ATF_TEST_CASE(run_test_case__atf__required_user__atf__root__atf__skip);
    778      1.1  jmmv ATF_TEST_CASE_HEAD(run_test_case__atf__required_user__atf__root__atf__skip)
    779      1.1  jmmv {
    780      1.1  jmmv     set_md_var("require.user", "unprivileged");
    781      1.1  jmmv }
    782      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_user__atf__root__atf__skip)
    783      1.1  jmmv {
    784      1.1  jmmv     atf_helper helper(this, "create_cookie_in_workdir");
    785      1.1  jmmv     helper.set_metadata("required_user", "root");
    786      1.1  jmmv     ATF_REQUIRE(!passwd::current_user().is_root());
    787      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped, "Requires "
    788      1.1  jmmv                                        "root privileges"),
    789      1.1  jmmv                    helper.run());
    790      1.1  jmmv }
    791      1.1  jmmv 
    792      1.1  jmmv 
    793      1.1  jmmv ATF_TEST_CASE(run_test_case__atf__required_user__atf__unprivileged__atf__ok);
    794      1.1  jmmv ATF_TEST_CASE_HEAD(run_test_case__atf__required_user__atf__unprivileged__atf__ok)
    795      1.1  jmmv {
    796      1.1  jmmv     set_md_var("require.user", "unprivileged");
    797      1.1  jmmv }
    798      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_user__atf__unprivileged__atf__ok)
    799      1.1  jmmv {
    800      1.1  jmmv     atf_helper helper(this, "create_cookie_in_workdir");
    801      1.1  jmmv     helper.set_metadata("required_user", "unprivileged");
    802      1.1  jmmv     ATF_REQUIRE(!helper.config().is_set("unprivileged_user"));
    803      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    804      1.1  jmmv                    helper.run());
    805      1.1  jmmv }
    806      1.1  jmmv 
    807      1.1  jmmv 
    808      1.1  jmmv ATF_TEST_CASE(run_test_case__atf__required_user__atf__unprivileged__atf__skip);
    809      1.1  jmmv ATF_TEST_CASE_HEAD(run_test_case__atf__required_user__atf__unprivileged__atf__skip)
    810      1.1  jmmv {
    811      1.1  jmmv     set_md_var("require.user", "root");
    812      1.1  jmmv }
    813      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_user__atf__unprivileged__atf__skip)
    814      1.1  jmmv {
    815      1.1  jmmv     atf_helper helper(this, "create_cookie_in_workdir");
    816      1.1  jmmv     helper.set_metadata("required_user", "unprivileged");
    817      1.1  jmmv     ATF_REQUIRE(!helper.config().is_set("unprivileged_user"));
    818      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::skipped, "Requires "
    819      1.1  jmmv                                        "an unprivileged user but the "
    820      1.1  jmmv                                        "unprivileged-user configuration "
    821      1.1  jmmv                                        "variable is not defined"),
    822      1.1  jmmv                    helper.run());
    823      1.1  jmmv }
    824      1.1  jmmv 
    825      1.1  jmmv 
    826      1.1  jmmv ATF_TEST_CASE(run_test_case__atf__required_user__atf__unprivileged__atf__drop);
    827      1.1  jmmv ATF_TEST_CASE_HEAD(run_test_case__atf__required_user__atf__unprivileged__atf__drop)
    828      1.1  jmmv {
    829      1.1  jmmv     set_md_var("require.config", "unprivileged-user");
    830      1.1  jmmv     set_md_var("require.user", "root");
    831      1.1  jmmv }
    832      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__required_user__atf__unprivileged__atf__drop)
    833      1.1  jmmv {
    834      1.1  jmmv     atf_helper helper(this, "check_unprivileged");
    835      1.1  jmmv     helper.set_metadata("required_user", "unprivileged");
    836      1.1  jmmv     helper.config().set< engine::user_node >(
    837      1.1  jmmv         "unprivileged_user",
    838      1.1  jmmv         passwd::find_user_by_name(get_config_var("unprivileged-user")));
    839      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    840      1.1  jmmv                    helper.run());
    841      1.1  jmmv }
    842      1.1  jmmv 
    843      1.1  jmmv 
    844      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__timeout_body);
    845      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__timeout_body)
    846      1.1  jmmv {
    847      1.1  jmmv     atf_helper helper(this, "timeout_body");
    848      1.1  jmmv     helper.set_metadata("timeout", "1");
    849      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    850      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::broken,
    851      1.1  jmmv                                        "Test case body timed out"),
    852      1.1  jmmv                    helper.run());
    853      1.1  jmmv 
    854      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    855      1.1  jmmv         fail("It seems that the test case was not killed after it timed out");
    856      1.1  jmmv }
    857      1.1  jmmv 
    858      1.1  jmmv 
    859      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__timeout_cleanup);
    860      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__timeout_cleanup)
    861      1.1  jmmv {
    862      1.1  jmmv     atf_helper helper(this, "timeout_cleanup");
    863      1.1  jmmv     helper.set_metadata("has_cleanup", "true");
    864      1.1  jmmv     helper.set_metadata("timeout", "1");
    865      1.1  jmmv     helper.set_config("control_dir", fs::current_path());
    866      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::broken,
    867      1.1  jmmv                                        "Test case cleanup timed out"),
    868      1.1  jmmv                    helper.run());
    869      1.1  jmmv 
    870      1.1  jmmv     if (fs::exists(fs::path("cookie")))
    871      1.1  jmmv         fail("It seems that the test case was not killed after it timed out");
    872      1.1  jmmv }
    873      1.1  jmmv 
    874      1.1  jmmv 
    875      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__stacktrace__atf__body);
    876      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__stacktrace__atf__body)
    877      1.1  jmmv {
    878      1.1  jmmv     atf_helper helper(this, "crash");
    879      1.1  jmmv     capture_hooks hooks;
    880      1.1  jmmv     const engine::test_result result = helper.run(hooks);
    881      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
    882      1.1  jmmv     ATF_REQUIRE_MATCH("received signal.*core dumped", result.reason());
    883      1.1  jmmv 
    884      1.1  jmmv     ATF_REQUIRE(!atf::utils::grep_string("attempting to gather stack trace",
    885      1.1  jmmv                                          hooks.stdout_contents));
    886      1.1  jmmv     ATF_REQUIRE( atf::utils::grep_string("attempting to gather stack trace",
    887      1.1  jmmv                                          hooks.stderr_contents));
    888      1.1  jmmv }
    889      1.1  jmmv 
    890      1.1  jmmv 
    891      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__stacktrace__atf__cleanup);
    892      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__stacktrace__atf__cleanup)
    893      1.1  jmmv {
    894      1.1  jmmv     atf_helper helper(this, "crash_cleanup");
    895      1.1  jmmv     helper.set_metadata("has_cleanup", "true");
    896      1.1  jmmv     capture_hooks hooks;
    897      1.1  jmmv     const engine::test_result result = helper.run(hooks);
    898      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
    899      1.1  jmmv     ATF_REQUIRE_MATCH(F("cleanup received signal %s") % SIGABRT,
    900      1.1  jmmv                       result.reason());
    901      1.1  jmmv 
    902      1.1  jmmv     ATF_REQUIRE(!atf::utils::grep_string("attempting to gather stack trace",
    903      1.1  jmmv                                          hooks.stdout_contents));
    904      1.1  jmmv     ATF_REQUIRE( atf::utils::grep_string("attempting to gather stack trace",
    905      1.1  jmmv                                          hooks.stderr_contents));
    906      1.1  jmmv }
    907      1.1  jmmv 
    908      1.1  jmmv 
    909      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__missing_results_file);
    910      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__missing_results_file)
    911      1.1  jmmv {
    912      1.1  jmmv     atf_helper helper(this, "crash");
    913      1.1  jmmv     const engine::test_result result = helper.run();
    914      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
    915      1.1  jmmv     // Need to match instead of doing an explicit comparison because the string
    916      1.1  jmmv     // may include the "core dumped" substring.
    917      1.1  jmmv     ATF_REQUIRE_MATCH(F("test case received signal %s") % SIGABRT,
    918      1.1  jmmv                       result.reason());
    919      1.1  jmmv }
    920      1.1  jmmv 
    921      1.1  jmmv 
    922      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__missing_test_program);
    923      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__missing_test_program)
    924      1.1  jmmv {
    925      1.1  jmmv     atf_helper helper(this, "crash");
    926      1.1  jmmv     ATF_REQUIRE(::mkdir("dir", 0755) != -1);
    927      1.1  jmmv     helper.move("test_case_atf_helpers", "dir");
    928      1.1  jmmv     ATF_REQUIRE(::unlink("dir/test_case_atf_helpers") != -1);
    929      1.1  jmmv     const engine::test_result result = helper.run();
    930      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
    931      1.1  jmmv     ATF_REQUIRE_MATCH("Test program does not exist", result.reason());
    932      1.1  jmmv }
    933      1.1  jmmv 
    934      1.1  jmmv 
    935      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__atf__output);
    936      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__atf__output)
    937      1.1  jmmv {
    938      1.1  jmmv     atf_helper helper(this, "output");
    939      1.1  jmmv     helper.set_metadata("has_cleanup", "true");
    940      1.1  jmmv 
    941      1.1  jmmv     capture_hooks hooks;
    942      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    943      1.1  jmmv                    helper.run(hooks));
    944      1.1  jmmv 
    945      1.1  jmmv     ATF_REQUIRE_EQ("Body message to stdout\nCleanup message to stdout\n",
    946      1.1  jmmv                    hooks.stdout_contents);
    947      1.1  jmmv     ATF_REQUIRE_EQ("Body message to stderr\nCleanup message to stderr\n",
    948      1.1  jmmv                    hooks.stderr_contents);
    949      1.1  jmmv }
    950      1.1  jmmv 
    951      1.1  jmmv 
    952      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__result_pass);
    953      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__result_pass)
    954      1.1  jmmv {
    955      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    956      1.1  jmmv                    plain_helper(this, "pass").run());
    957      1.1  jmmv }
    958      1.1  jmmv 
    959      1.1  jmmv 
    960      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__result_fail);
    961      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__result_fail)
    962      1.1  jmmv {
    963      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::failed,
    964      1.1  jmmv                                        "Returned non-success exit status 8"),
    965      1.1  jmmv                    plain_helper(this, "fail").run());
    966      1.1  jmmv }
    967      1.1  jmmv 
    968      1.1  jmmv 
    969      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__result_crash);
    970      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__result_crash)
    971      1.1  jmmv {
    972      1.1  jmmv     const engine::test_result result = plain_helper(this, "crash").run();
    973      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
    974      1.1  jmmv     ATF_REQUIRE_MATCH(F("Received signal %s") % SIGABRT, result.reason());
    975      1.1  jmmv }
    976      1.1  jmmv 
    977      1.1  jmmv 
    978      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__current_directory);
    979      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__current_directory)
    980      1.1  jmmv {
    981      1.1  jmmv     plain_helper helper(this, "pass");
    982      1.1  jmmv     helper.move("program", ".");
    983      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    984      1.1  jmmv                    helper.run());
    985      1.1  jmmv }
    986      1.1  jmmv 
    987      1.1  jmmv 
    988      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__subdirectory);
    989      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__subdirectory)
    990      1.1  jmmv {
    991      1.1  jmmv     plain_helper helper(this, "pass");
    992      1.1  jmmv     ATF_REQUIRE(::mkdir("dir1", 0755) != -1);
    993      1.1  jmmv     ATF_REQUIRE(::mkdir("dir1/dir2", 0755) != -1);
    994      1.1  jmmv     helper.move("dir2/program", "dir1");
    995      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
    996      1.1  jmmv                    helper.run());
    997      1.1  jmmv }
    998      1.1  jmmv 
    999      1.1  jmmv 
   1000      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__kill_children);
   1001      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__kill_children)
   1002      1.1  jmmv {
   1003      1.1  jmmv     plain_helper helper(this, "spawn_blocking_child");
   1004      1.1  jmmv     helper.set("CONTROL_DIR", fs::current_path());
   1005      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
   1006      1.1  jmmv                    helper.run());
   1007      1.1  jmmv 
   1008      1.1  jmmv     if (!fs::exists(fs::path("pid")))
   1009      1.1  jmmv         fail("The pid file was not created");
   1010      1.1  jmmv     std::ifstream pidfile("pid");
   1011      1.1  jmmv     ATF_REQUIRE(pidfile);
   1012      1.1  jmmv     pid_t pid;
   1013      1.1  jmmv     pidfile >> pid;
   1014      1.1  jmmv     pidfile.close();
   1015      1.1  jmmv 
   1016      1.1  jmmv     int attempts = 30;
   1017      1.1  jmmv retry:
   1018      1.1  jmmv     if (::kill(pid, SIGCONT) != -1 || errno != ESRCH) {
   1019      1.1  jmmv         // Looks like the subchild did not die.
   1020      1.1  jmmv         //
   1021      1.1  jmmv         // Note that this might be inaccurate for two reasons:
   1022      1.1  jmmv         // 1) The system may have spawned a new process with the same pid as
   1023      1.1  jmmv         //    our subchild... but in practice, this does not happen because
   1024      1.1  jmmv         //    most systems do not immediately reuse pid numbers.  If that
   1025      1.1  jmmv         //    happens... well, we get a false test failure.
   1026      1.1  jmmv         // 2) We ran so fast that even if the process was sent a signal to
   1027      1.1  jmmv         //    die, it has not had enough time to process it yet.  This is why
   1028      1.1  jmmv         //    we retry this a few times.
   1029      1.1  jmmv         if (attempts > 0) {
   1030      1.1  jmmv             std::cout << "Subprocess not dead yet; retrying wait\n";
   1031      1.1  jmmv             --attempts;
   1032      1.1  jmmv             ::usleep(100000);
   1033      1.1  jmmv             goto retry;
   1034      1.1  jmmv         }
   1035      1.1  jmmv         fail(F("The subprocess %s of our child was not killed") % pid);
   1036      1.1  jmmv     }
   1037      1.1  jmmv }
   1038      1.1  jmmv 
   1039      1.1  jmmv 
   1040      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__isolation);
   1041      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__isolation)
   1042      1.1  jmmv {
   1043      1.1  jmmv     const plain_helper helper(this, "validate_isolation");
   1044      1.1  jmmv     utils::setenv("TEST_CASE", "validate_isolation");
   1045      1.1  jmmv     // Simple checks to make sure that the test case has been isolated.
   1046      1.1  jmmv     utils::setenv("HOME", "fake-value");
   1047      1.1  jmmv     utils::setenv("LANG", "C");
   1048      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::passed),
   1049      1.1  jmmv                    helper.run());
   1050      1.1  jmmv }
   1051      1.1  jmmv 
   1052      1.1  jmmv 
   1053      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__timeout);
   1054      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__timeout)
   1055      1.1  jmmv {
   1056      1.1  jmmv     plain_helper helper(this, "timeout",
   1057      1.1  jmmv                         utils::make_optional(datetime::delta(1, 0)));
   1058      1.1  jmmv     helper.set("CONTROL_DIR", fs::current_path());
   1059      1.1  jmmv     ATF_REQUIRE_EQ(engine::test_result(engine::test_result::broken,
   1060      1.1  jmmv                                        "Test case timed out"),
   1061      1.1  jmmv                    helper.run());
   1062      1.1  jmmv 
   1063      1.1  jmmv     if (fs::exists(fs::path("cookie")))
   1064      1.1  jmmv         fail("It seems that the test case was not killed after it timed out");
   1065      1.1  jmmv }
   1066      1.1  jmmv 
   1067      1.1  jmmv 
   1068      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__stacktrace);
   1069      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__stacktrace)
   1070      1.1  jmmv {
   1071      1.1  jmmv     plain_helper helper(this, "crash");
   1072      1.1  jmmv     helper.set("CONTROL_DIR", fs::current_path());
   1073      1.1  jmmv 
   1074      1.1  jmmv     const engine::test_result result = plain_helper(this, "crash").run();
   1075      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
   1076      1.1  jmmv     ATF_REQUIRE_MATCH(F("Received signal %s") % SIGABRT, result.reason());
   1077      1.1  jmmv 
   1078      1.1  jmmv     ATF_REQUIRE(!atf::utils::grep_file("attempting to gather stack trace",
   1079      1.1  jmmv                                        "helper-stdout.txt"));
   1080      1.1  jmmv     ATF_REQUIRE( atf::utils::grep_file("attempting to gather stack trace",
   1081      1.1  jmmv                                        "helper-stderr.txt"));
   1082      1.1  jmmv }
   1083      1.1  jmmv 
   1084      1.1  jmmv 
   1085      1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(run_test_case__plain__missing_test_program);
   1086      1.1  jmmv ATF_TEST_CASE_BODY(run_test_case__plain__missing_test_program)
   1087      1.1  jmmv {
   1088      1.1  jmmv     plain_helper helper(this, "pass");
   1089      1.1  jmmv     ATF_REQUIRE(::mkdir("dir", 0755) != -1);
   1090      1.1  jmmv     helper.move("test_case_helpers", "dir");
   1091      1.1  jmmv     ATF_REQUIRE(::unlink("dir/test_case_helpers") != -1);
   1092      1.1  jmmv     const engine::test_result result = helper.run();
   1093      1.1  jmmv     ATF_REQUIRE(engine::test_result::broken == result.type());
   1094      1.1  jmmv     ATF_REQUIRE_MATCH("Test program does not exist", result.reason());
   1095      1.1  jmmv }
   1096      1.1  jmmv 
   1097      1.1  jmmv 
   1098      1.1  jmmv ATF_INIT_TEST_CASES(tcs)
   1099      1.1  jmmv {
   1100      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, test_case__ctor_and_getters);
   1101      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, test_case__fake_result);
   1102      1.1  jmmv 
   1103      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, test_case__operators_eq_and_ne__copy);
   1104      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, test_case__operators_eq_and_ne__not_copy);
   1105      1.1  jmmv 
   1106      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, test_case__output);
   1107      1.1  jmmv 
   1108  1.1.1.2  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__tester_crashes);
   1109  1.1.1.2  jmmv 
   1110      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__current_directory);
   1111      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__subdirectory);
   1112      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__config_variables);
   1113      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__cleanup_shares_workdir);
   1114      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__has_cleanup__atf__false);
   1115      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__has_cleanup__atf__true);
   1116      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__kill_children);
   1117      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__isolation);
   1118      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__allowed_architectures);
   1119      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__allowed_platforms);
   1120      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_configs);
   1121      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_programs);
   1122      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_user__atf__root__atf__ok);
   1123      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_user__atf__root__atf__skip);
   1124      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_user__atf__unprivileged__atf__ok);
   1125      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_user__atf__unprivileged__atf__skip);
   1126      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__required_user__atf__unprivileged__atf__drop);
   1127      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__timeout_body);
   1128      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__timeout_cleanup);
   1129      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__stacktrace__atf__body);
   1130      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__stacktrace__atf__cleanup);
   1131      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__missing_results_file);
   1132      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__missing_test_program);
   1133      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__atf__output);
   1134      1.1  jmmv 
   1135      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__result_pass);
   1136      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__result_fail);
   1137      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__result_crash);
   1138      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__current_directory);
   1139      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__subdirectory);
   1140      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__kill_children);
   1141      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__isolation);
   1142      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__timeout);
   1143      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__stacktrace);
   1144      1.1  jmmv     ATF_ADD_TEST_CASE(tcs, run_test_case__plain__missing_test_program);
   1145      1.1  jmmv 
   1146      1.1  jmmv     // TODO(jmmv): Add test cases for debug.
   1147      1.1  jmmv }
   1148