Home | History | Annotate | Line # | Download | only in tools
misc_helpers.cpp revision 1.1
      1 //
      2 // Automated Testing Framework (atf)
      3 //
      4 // Copyright (c) 2007 The NetBSD Foundation, Inc.
      5 // All rights reserved.
      6 //
      7 // Redistribution and use in source and binary forms, with or without
      8 // modification, are permitted provided that the following conditions
      9 // are met:
     10 // 1. Redistributions of source code must retain the above copyright
     11 //    notice, this list of conditions and the following disclaimer.
     12 // 2. Redistributions in binary form must reproduce the above copyright
     13 //    notice, this list of conditions and the following disclaimer in the
     14 //    documentation and/or other materials provided with the distribution.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
     17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
     21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
     25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 //
     29 
     30 extern "C" {
     31 #include <sys/stat.h>
     32 
     33 #include <signal.h>
     34 #include <unistd.h>
     35 }
     36 
     37 #include <cstdlib>
     38 #include <fstream>
     39 #include <iomanip>
     40 #include <ios>
     41 #include <iostream>
     42 #include <string>
     43 
     44 #include <atf-c++.hpp>
     45 
     46 #include "env.hpp"
     47 #include "fs.hpp"
     48 #include "process.hpp"
     49 
     50 // ------------------------------------------------------------------------
     51 // Auxiliary functions.
     52 // ------------------------------------------------------------------------
     53 
     54 static
     55 void
     56 touch(const std::string& path)
     57 {
     58     std::ofstream os(path.c_str());
     59     if (!os)
     60         ATF_FAIL("Could not create file " + path);
     61     os.close();
     62 }
     63 
     64 // ------------------------------------------------------------------------
     65 // Helper tests for "atf-run_test".
     66 // ------------------------------------------------------------------------
     67 
     68 ATF_TEST_CASE(pass);
     69 ATF_TEST_CASE_HEAD(pass)
     70 {
     71     set_md_var("descr", "Helper test case for the t_integration test program");
     72 }
     73 ATF_TEST_CASE_BODY(pass)
     74 {
     75 }
     76 
     77 ATF_TEST_CASE(config);
     78 ATF_TEST_CASE_HEAD(config)
     79 {
     80     set_md_var("descr", "Helper test case for the t_integration test program");
     81 }
     82 ATF_TEST_CASE_BODY(config)
     83 {
     84     std::cout << "1st: " << get_config_var("1st") << "\n";
     85     std::cout << "2nd: " << get_config_var("2nd") << "\n";
     86     std::cout << "3rd: " << get_config_var("3rd") << "\n";
     87     std::cout << "4th: " << get_config_var("4th") << "\n";
     88 }
     89 
     90 ATF_TEST_CASE(fds);
     91 ATF_TEST_CASE_HEAD(fds)
     92 {
     93     set_md_var("descr", "Helper test case for the t_integration test program");
     94 }
     95 ATF_TEST_CASE_BODY(fds)
     96 {
     97     std::cout << "msg1 to stdout" << "\n";
     98     std::cout << "msg2 to stdout" << "\n";
     99     std::cerr << "msg1 to stderr" << "\n";
    100     std::cerr << "msg2 to stderr" << "\n";
    101 }
    102 
    103 ATF_TEST_CASE_WITHOUT_HEAD(mux_streams);
    104 ATF_TEST_CASE_BODY(mux_streams)
    105 {
    106     for (size_t i = 0; i < 10000; i++) {
    107         switch (i % 5) {
    108         case 0:
    109             std::cout << "stdout " << i << "\n";
    110             break;
    111         case 1:
    112             std::cerr << "stderr " << i << "\n";
    113             break;
    114         case 2:
    115             std::cout << "stdout " << i << "\n";
    116             std::cerr << "stderr " << i << "\n";
    117             break;
    118         case 3:
    119             std::cout << "stdout " << i << "\n";
    120             std::cout << "stdout " << i << "\n";
    121             std::cerr << "stderr " << i << "\n";
    122             break;
    123         case 4:
    124             std::cout << "stdout " << i << "\n";
    125             std::cerr << "stderr " << i << "\n";
    126             std::cerr << "stderr " << i << "\n";
    127             break;
    128         default:
    129             std::abort();
    130         }
    131     }
    132 }
    133 
    134 ATF_TEST_CASE(testvar);
    135 ATF_TEST_CASE_HEAD(testvar)
    136 {
    137     set_md_var("descr", "Helper test case for the t_integration test program");
    138 }
    139 ATF_TEST_CASE_BODY(testvar)
    140 {
    141     if (!has_config_var("testvar"))
    142         fail("testvar variable not defined");
    143     std::cout << "testvar: " << get_config_var("testvar") << "\n";
    144 }
    145 
    146 ATF_TEST_CASE(env_list);
    147 ATF_TEST_CASE_HEAD(env_list)
    148 {
    149     set_md_var("descr", "Helper test case for the t_integration test program");
    150 }
    151 ATF_TEST_CASE_BODY(env_list)
    152 {
    153     const tools::process::status s =
    154         tools::process::exec(tools::fs::path("env"),
    155                            tools::process::argv_array("env", NULL),
    156                            tools::process::stream_inherit(),
    157                            tools::process::stream_inherit());
    158     ATF_REQUIRE(s.exited());
    159     ATF_REQUIRE(s.exitstatus() == EXIT_SUCCESS);
    160 }
    161 
    162 ATF_TEST_CASE(env_home);
    163 ATF_TEST_CASE_HEAD(env_home)
    164 {
    165     set_md_var("descr", "Helper test case for the t_integration test program");
    166 }
    167 ATF_TEST_CASE_BODY(env_home)
    168 {
    169     ATF_REQUIRE(tools::env::has("HOME"));
    170     tools::fs::path p(tools::env::get("HOME"));
    171     tools::fs::file_info fi1(p);
    172     tools::fs::file_info fi2(tools::fs::path("."));
    173     ATF_REQUIRE_EQ(fi1.get_device(), fi2.get_device());
    174     ATF_REQUIRE_EQ(fi1.get_inode(), fi2.get_inode());
    175 }
    176 
    177 ATF_TEST_CASE(read_stdin);
    178 ATF_TEST_CASE_HEAD(read_stdin)
    179 {
    180     set_md_var("descr", "Helper test case for the t_integration test program");
    181 }
    182 ATF_TEST_CASE_BODY(read_stdin)
    183 {
    184     char buf[100];
    185     ssize_t len = ::read(STDIN_FILENO, buf, sizeof(buf) - 1);
    186     ATF_REQUIRE(len != -1);
    187 
    188     buf[len + 1] = '\0';
    189     for (ssize_t i = 0; i < len; i++) {
    190         if (buf[i] != '\0') {
    191             fail("The stdin of the test case does not seem to be /dev/zero; "
    192                  "got '" + std::string(buf) + "'");
    193         }
    194     }
    195 }
    196 
    197 ATF_TEST_CASE(umask);
    198 ATF_TEST_CASE_HEAD(umask)
    199 {
    200     set_md_var("descr", "Helper test case for the t_integration test program");
    201 }
    202 ATF_TEST_CASE_BODY(umask)
    203 {
    204     mode_t m = ::umask(0);
    205     std::cout << "umask: " << std::setw(4) << std::setfill('0')
    206               << std::oct << m << "\n";
    207     (void)::umask(m);
    208 }
    209 
    210 ATF_TEST_CASE_WITH_CLEANUP(cleanup_states);
    211 ATF_TEST_CASE_HEAD(cleanup_states)
    212 {
    213     set_md_var("descr", "Helper test case for the t_integration test program");
    214 }
    215 ATF_TEST_CASE_BODY(cleanup_states)
    216 {
    217     touch(get_config_var("statedir") + "/to-delete");
    218     touch(get_config_var("statedir") + "/to-stay");
    219 
    220     if (get_config_var("state") == "fail")
    221         ATF_FAIL("On purpose");
    222     else if (get_config_var("state") == "skip")
    223         ATF_SKIP("On purpose");
    224 }
    225 ATF_TEST_CASE_CLEANUP(cleanup_states)
    226 {
    227     tools::fs::remove(tools::fs::path(get_config_var("statedir") + "/to-delete"));
    228 }
    229 
    230 ATF_TEST_CASE_WITH_CLEANUP(cleanup_curdir);
    231 ATF_TEST_CASE_HEAD(cleanup_curdir)
    232 {
    233     set_md_var("descr", "Helper test case for the t_integration test program");
    234 }
    235 ATF_TEST_CASE_BODY(cleanup_curdir)
    236 {
    237     std::ofstream os("oldvalue");
    238     if (!os)
    239         ATF_FAIL("Failed to create oldvalue file");
    240     os << 1234;
    241     os.close();
    242 }
    243 ATF_TEST_CASE_CLEANUP(cleanup_curdir)
    244 {
    245     std::ifstream is("oldvalue");
    246     if (is) {
    247         int i;
    248         is >> i;
    249         std::cout << "Old value: " << i << "\n";
    250         is.close();
    251     }
    252 }
    253 
    254 ATF_TEST_CASE(require_arch);
    255 ATF_TEST_CASE_HEAD(require_arch)
    256 {
    257     set_md_var("descr", "Helper test case for the t_integration test program");
    258     set_md_var("require.arch", get_config_var("arch", "not-set"));
    259 }
    260 ATF_TEST_CASE_BODY(require_arch)
    261 {
    262 }
    263 
    264 ATF_TEST_CASE(require_config);
    265 ATF_TEST_CASE_HEAD(require_config)
    266 {
    267     set_md_var("descr", "Helper test case for the t_integration test program");
    268     set_md_var("require.config", "var1 var2");
    269 }
    270 ATF_TEST_CASE_BODY(require_config)
    271 {
    272     std::cout << "var1: " << get_config_var("var1") << "\n";
    273     std::cout << "var2: " << get_config_var("var2") << "\n";
    274 }
    275 
    276 ATF_TEST_CASE(require_files);
    277 ATF_TEST_CASE_HEAD(require_files)
    278 {
    279     set_md_var("descr", "Helper test case for the t_integration test program");
    280     set_md_var("require.files", get_config_var("files", "not-set"));
    281 }
    282 ATF_TEST_CASE_BODY(require_files)
    283 {
    284 }
    285 
    286 ATF_TEST_CASE(require_machine);
    287 ATF_TEST_CASE_HEAD(require_machine)
    288 {
    289     set_md_var("descr", "Helper test case for the t_integration test program");
    290     set_md_var("require.machine", get_config_var("machine", "not-set"));
    291 }
    292 ATF_TEST_CASE_BODY(require_machine)
    293 {
    294 }
    295 
    296 ATF_TEST_CASE(require_progs);
    297 ATF_TEST_CASE_HEAD(require_progs)
    298 {
    299     set_md_var("descr", "Helper test case for the t_integration test program");
    300     set_md_var("require.progs", get_config_var("progs", "not-set"));
    301 }
    302 ATF_TEST_CASE_BODY(require_progs)
    303 {
    304 }
    305 
    306 ATF_TEST_CASE(require_user);
    307 ATF_TEST_CASE_HEAD(require_user)
    308 {
    309     set_md_var("descr", "Helper test case for the t_integration test program");
    310     set_md_var("require.user", get_config_var("user", "not-set"));
    311 }
    312 ATF_TEST_CASE_BODY(require_user)
    313 {
    314 }
    315 
    316 ATF_TEST_CASE(timeout);
    317 ATF_TEST_CASE_HEAD(timeout)
    318 {
    319     set_md_var("descr", "Helper test case for the t_integration test program");
    320     set_md_var("timeout", "1");
    321 }
    322 ATF_TEST_CASE_BODY(timeout)
    323 {
    324     sleep(10);
    325     touch(get_config_var("statedir") + "/finished");
    326 }
    327 
    328 ATF_TEST_CASE(timeout_forkexit);
    329 ATF_TEST_CASE_HEAD(timeout_forkexit)
    330 {
    331     set_md_var("descr", "Helper test case for the t_integration test program");
    332 }
    333 ATF_TEST_CASE_BODY(timeout_forkexit)
    334 {
    335     pid_t pid = fork();
    336     ATF_REQUIRE(pid != -1);
    337 
    338     if (pid == 0) {
    339         sigset_t mask;
    340         sigemptyset(&mask);
    341 
    342         std::cout << "Waiting in subprocess\n";
    343         std::cout.flush();
    344         ::sigsuspend(&mask);
    345 
    346         touch(get_config_var("statedir") + "/child-finished");
    347         std::cout << "Subprocess exiting\n";
    348         std::cout.flush();
    349         exit(EXIT_SUCCESS);
    350     } else {
    351         // Don't wait for the child process and let atf-run deal with it.
    352         touch(get_config_var("statedir") + "/parent-finished");
    353         std::cout << "Parent process exiting\n";
    354         ATF_PASS();
    355     }
    356 }
    357 
    358 ATF_TEST_CASE(use_fs);
    359 ATF_TEST_CASE_HEAD(use_fs)
    360 {
    361     set_md_var("descr", "Helper test case for the t_integration test program");
    362     set_md_var("use.fs", "this-is-deprecated");
    363 }
    364 ATF_TEST_CASE_BODY(use_fs)
    365 {
    366     touch("test-file");
    367 }
    368 
    369 // ------------------------------------------------------------------------
    370 // Helper tests for "atf-report_test".
    371 // ------------------------------------------------------------------------
    372 
    373 ATF_TEST_CASE(diff);
    374 ATF_TEST_CASE_HEAD(diff)
    375 {
    376     set_md_var("descr", "Helper test case for the t_integration program");
    377 }
    378 ATF_TEST_CASE_BODY(diff)
    379 {
    380     std::cout << "--- a	2007-11-04 14:00:41.000000000 +0100\n";
    381     std::cout << "+++ b	2007-11-04 14:00:48.000000000 +0100\n";
    382     std::cout << "@@ -1,7 +1,7 @@\n";
    383     std::cout << " This test is meant to simulate a diff.\n";
    384     std::cout << " Blank space at beginning of context lines must be "
    385                  "preserved.\n";
    386     std::cout << " \n";
    387     std::cout << "-First original line.\n";
    388     std::cout << "-Second original line.\n";
    389     std::cout << "+First modified line.\n";
    390     std::cout << "+Second modified line.\n";
    391     std::cout << " \n";
    392     std::cout << " EOF\n";
    393 }
    394 
    395 // ------------------------------------------------------------------------
    396 // Main.
    397 // ------------------------------------------------------------------------
    398 
    399 ATF_INIT_TEST_CASES(tcs)
    400 {
    401     std::string which = tools::env::get("TESTCASE");
    402 
    403     // Add helper tests for atf-run_test.
    404     if (which == "pass")
    405         ATF_ADD_TEST_CASE(tcs, pass);
    406     if (which == "config")
    407         ATF_ADD_TEST_CASE(tcs, config);
    408     if (which == "fds")
    409         ATF_ADD_TEST_CASE(tcs, fds);
    410     if (which == "mux_streams")
    411         ATF_ADD_TEST_CASE(tcs, mux_streams);
    412     if (which == "testvar")
    413         ATF_ADD_TEST_CASE(tcs, testvar);
    414     if (which == "env_list")
    415         ATF_ADD_TEST_CASE(tcs, env_list);
    416     if (which == "env_home")
    417         ATF_ADD_TEST_CASE(tcs, env_home);
    418     if (which == "read_stdin")
    419         ATF_ADD_TEST_CASE(tcs, read_stdin);
    420     if (which == "umask")
    421         ATF_ADD_TEST_CASE(tcs, umask);
    422     if (which == "cleanup_states")
    423         ATF_ADD_TEST_CASE(tcs, cleanup_states);
    424     if (which == "cleanup_curdir")
    425         ATF_ADD_TEST_CASE(tcs, cleanup_curdir);
    426     if (which == "require_arch")
    427         ATF_ADD_TEST_CASE(tcs, require_arch);
    428     if (which == "require_config")
    429         ATF_ADD_TEST_CASE(tcs, require_config);
    430     if (which == "require_files")
    431         ATF_ADD_TEST_CASE(tcs, require_files);
    432     if (which == "require_machine")
    433         ATF_ADD_TEST_CASE(tcs, require_machine);
    434     if (which == "require_progs")
    435         ATF_ADD_TEST_CASE(tcs, require_progs);
    436     if (which == "require_user")
    437         ATF_ADD_TEST_CASE(tcs, require_user);
    438     if (which == "timeout")
    439         ATF_ADD_TEST_CASE(tcs, timeout);
    440     if (which == "timeout_forkexit")
    441         ATF_ADD_TEST_CASE(tcs, timeout_forkexit);
    442     if (which == "use_fs")
    443         ATF_ADD_TEST_CASE(tcs, use_fs);
    444 
    445     // Add helper tests for atf-report_test.
    446     if (which == "diff")
    447         ATF_ADD_TEST_CASE(tcs, diff);
    448 }
    449