Home | History | Annotate | Line # | Download | only in tools
      1  1.1  jmmv //
      2  1.1  jmmv // Automated Testing Framework (atf)
      3  1.1  jmmv //
      4  1.1  jmmv // Copyright (c) 2008 The NetBSD Foundation, Inc.
      5  1.1  jmmv // All rights reserved.
      6  1.1  jmmv //
      7  1.1  jmmv // Redistribution and use in source and binary forms, with or without
      8  1.1  jmmv // modification, are permitted provided that the following conditions
      9  1.1  jmmv // are met:
     10  1.1  jmmv // 1. Redistributions of source code must retain the above copyright
     11  1.1  jmmv //    notice, this list of conditions and the following disclaimer.
     12  1.1  jmmv // 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  jmmv //    notice, this list of conditions and the following disclaimer in the
     14  1.1  jmmv //    documentation and/or other materials provided with the distribution.
     15  1.1  jmmv //
     16  1.1  jmmv // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
     17  1.1  jmmv // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     18  1.1  jmmv // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19  1.1  jmmv // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  1.1  jmmv // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
     21  1.1  jmmv // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  1.1  jmmv // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     23  1.1  jmmv // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  1.1  jmmv // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
     25  1.1  jmmv // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     26  1.1  jmmv // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27  1.1  jmmv // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.1  jmmv //
     29  1.1  jmmv 
     30  1.1  jmmv extern "C" {
     31  1.1  jmmv #include <sys/types.h>
     32  1.1  jmmv #include <signal.h>
     33  1.1  jmmv #include <unistd.h>
     34  1.1  jmmv }
     35  1.1  jmmv 
     36  1.1  jmmv #include <cerrno>
     37  1.1  jmmv #include <cstdlib>
     38  1.1  jmmv #include <iostream>
     39  1.1  jmmv 
     40  1.1  jmmv #include <atf-c++.hpp>
     41  1.1  jmmv 
     42  1.1  jmmv #include "exceptions.hpp"
     43  1.1  jmmv #include "process.hpp"
     44  1.1  jmmv #include "signals.hpp"
     45  1.1  jmmv 
     46  1.1  jmmv // ------------------------------------------------------------------------
     47  1.1  jmmv // Auxiliary functions.
     48  1.1  jmmv // ------------------------------------------------------------------------
     49  1.1  jmmv 
     50  1.1  jmmv namespace sigusr1 {
     51  1.1  jmmv     static bool happened = false;
     52  1.1  jmmv 
     53  1.1  jmmv     static
     54  1.1  jmmv     void
     55  1.2  jmmv     handler(int signo __attribute__((__unused__)))
     56  1.1  jmmv     {
     57  1.1  jmmv         happened = true;
     58  1.1  jmmv     }
     59  1.1  jmmv 
     60  1.1  jmmv     static
     61  1.1  jmmv     void
     62  1.1  jmmv     program(void)
     63  1.1  jmmv     {
     64  1.1  jmmv         struct sigaction sa;
     65  1.1  jmmv         sa.sa_handler = handler;
     66  1.1  jmmv         sigemptyset(&sa.sa_mask);
     67  1.1  jmmv         sa.sa_flags = 0;
     68  1.1  jmmv         if (::sigaction(SIGUSR1, &sa, NULL) == -1)
     69  1.1  jmmv             throw tools::system_error("sigusr1::program",
     70  1.1  jmmv                                     "sigaction(2) failed", errno);
     71  1.1  jmmv     }
     72  1.1  jmmv } // namespace sigusr1
     73  1.1  jmmv 
     74  1.1  jmmv namespace sigusr1_2 {
     75  1.1  jmmv     static bool happened = false;
     76  1.1  jmmv 
     77  1.1  jmmv     static
     78  1.1  jmmv     void
     79  1.2  jmmv     handler(int signo __attribute__((__unused__)))
     80  1.1  jmmv     {
     81  1.1  jmmv         happened = true;
     82  1.1  jmmv     }
     83  1.1  jmmv } // namespace sigusr1_2
     84  1.1  jmmv 
     85  1.1  jmmv // ------------------------------------------------------------------------
     86  1.1  jmmv // Tests for the "signal_holder" class.
     87  1.1  jmmv // ------------------------------------------------------------------------
     88  1.1  jmmv 
     89  1.1  jmmv ATF_TEST_CASE(signal_holder_preserve);
     90  1.1  jmmv ATF_TEST_CASE_HEAD(signal_holder_preserve)
     91  1.1  jmmv {
     92  1.1  jmmv     set_md_var("descr", "Tests that signal_holder preserves the original "
     93  1.1  jmmv                "signal handler and restores it upon destruction");
     94  1.1  jmmv }
     95  1.1  jmmv ATF_TEST_CASE_BODY(signal_holder_preserve)
     96  1.1  jmmv {
     97  1.1  jmmv     using tools::signals::signal_holder;
     98  1.1  jmmv 
     99  1.1  jmmv     sigusr1::program();
    100  1.1  jmmv 
    101  1.1  jmmv     sigusr1::happened = false;
    102  1.1  jmmv     ::kill(::getpid(), SIGUSR1);
    103  1.1  jmmv     ATF_REQUIRE(sigusr1::happened);
    104  1.1  jmmv 
    105  1.1  jmmv     {
    106  1.1  jmmv         signal_holder hld(SIGUSR1);
    107  1.1  jmmv         ::kill(::getpid(), SIGUSR1);
    108  1.1  jmmv     }
    109  1.1  jmmv 
    110  1.1  jmmv     sigusr1::happened = false;
    111  1.1  jmmv     ::kill(::getpid(), SIGUSR1);
    112  1.1  jmmv     ATF_REQUIRE(sigusr1::happened);
    113  1.1  jmmv }
    114  1.1  jmmv 
    115  1.1  jmmv ATF_TEST_CASE(signal_holder_destructor);
    116  1.1  jmmv ATF_TEST_CASE_HEAD(signal_holder_destructor)
    117  1.1  jmmv {
    118  1.1  jmmv     set_md_var("descr", "Tests that signal_holder processes a pending "
    119  1.1  jmmv                "signal upon destruction");
    120  1.1  jmmv }
    121  1.1  jmmv ATF_TEST_CASE_BODY(signal_holder_destructor)
    122  1.1  jmmv {
    123  1.1  jmmv     using tools::signals::signal_holder;
    124  1.1  jmmv 
    125  1.1  jmmv     sigusr1::program();
    126  1.1  jmmv 
    127  1.1  jmmv     sigusr1::happened = false;
    128  1.1  jmmv     ::kill(::getpid(), SIGUSR1);
    129  1.1  jmmv     ATF_REQUIRE(sigusr1::happened);
    130  1.1  jmmv 
    131  1.1  jmmv     {
    132  1.1  jmmv         signal_holder hld(SIGUSR1);
    133  1.1  jmmv 
    134  1.1  jmmv         sigusr1::happened = false;
    135  1.1  jmmv         ::kill(::getpid(), SIGUSR1);
    136  1.1  jmmv         ATF_REQUIRE(!sigusr1::happened);
    137  1.1  jmmv     }
    138  1.1  jmmv     ATF_REQUIRE(sigusr1::happened);
    139  1.1  jmmv }
    140  1.1  jmmv 
    141  1.1  jmmv ATF_TEST_CASE(signal_holder_process);
    142  1.1  jmmv ATF_TEST_CASE_HEAD(signal_holder_process)
    143  1.1  jmmv {
    144  1.1  jmmv     set_md_var("descr", "Tests that signal_holder's process method works "
    145  1.1  jmmv                "to process a delayed signal explicitly");
    146  1.1  jmmv }
    147  1.1  jmmv ATF_TEST_CASE_BODY(signal_holder_process)
    148  1.1  jmmv {
    149  1.1  jmmv     using tools::signals::signal_holder;
    150  1.1  jmmv 
    151  1.1  jmmv     sigusr1::program();
    152  1.1  jmmv 
    153  1.1  jmmv     sigusr1::happened = false;
    154  1.1  jmmv     ::kill(::getpid(), SIGUSR1);
    155  1.1  jmmv     ATF_REQUIRE(sigusr1::happened);
    156  1.1  jmmv 
    157  1.1  jmmv     {
    158  1.1  jmmv         signal_holder hld(SIGUSR1);
    159  1.1  jmmv 
    160  1.1  jmmv         sigusr1::happened = false;
    161  1.1  jmmv         ::kill(::getpid(), SIGUSR1);
    162  1.1  jmmv         ATF_REQUIRE(!sigusr1::happened);
    163  1.1  jmmv 
    164  1.1  jmmv         hld.process();
    165  1.1  jmmv         ATF_REQUIRE(sigusr1::happened);
    166  1.1  jmmv 
    167  1.1  jmmv         sigusr1::happened = false;
    168  1.1  jmmv     }
    169  1.1  jmmv     ATF_REQUIRE(!sigusr1::happened);
    170  1.1  jmmv }
    171  1.1  jmmv 
    172  1.1  jmmv // ------------------------------------------------------------------------
    173  1.1  jmmv // Tests for the "signal_programmer" class.
    174  1.1  jmmv // ------------------------------------------------------------------------
    175  1.1  jmmv 
    176  1.1  jmmv ATF_TEST_CASE(signal_programmer_program);
    177  1.1  jmmv ATF_TEST_CASE_HEAD(signal_programmer_program)
    178  1.1  jmmv {
    179  1.1  jmmv     set_md_var("descr", "Tests that signal_programmer correctly installs a "
    180  1.1  jmmv                "handler");
    181  1.1  jmmv }
    182  1.1  jmmv ATF_TEST_CASE_BODY(signal_programmer_program)
    183  1.1  jmmv {
    184  1.1  jmmv     using tools::signals::signal_programmer;
    185  1.1  jmmv 
    186  1.1  jmmv     signal_programmer sp(SIGUSR1, sigusr1_2::handler);
    187  1.1  jmmv 
    188  1.1  jmmv     sigusr1_2::happened = false;
    189  1.1  jmmv     ::kill(::getpid(), SIGUSR1);
    190  1.1  jmmv     ATF_REQUIRE(sigusr1_2::happened);
    191  1.1  jmmv }
    192  1.1  jmmv 
    193  1.1  jmmv ATF_TEST_CASE(signal_programmer_preserve);
    194  1.1  jmmv ATF_TEST_CASE_HEAD(signal_programmer_preserve)
    195  1.1  jmmv {
    196  1.1  jmmv     set_md_var("descr", "Tests that signal_programmer uninstalls the "
    197  1.1  jmmv                "handler during destruction");
    198  1.1  jmmv }
    199  1.1  jmmv ATF_TEST_CASE_BODY(signal_programmer_preserve)
    200  1.1  jmmv {
    201  1.1  jmmv     using tools::signals::signal_programmer;
    202  1.1  jmmv 
    203  1.1  jmmv     sigusr1::program();
    204  1.1  jmmv     sigusr1::happened = false;
    205  1.1  jmmv 
    206  1.1  jmmv     {
    207  1.1  jmmv         signal_programmer sp(SIGUSR1, sigusr1_2::handler);
    208  1.1  jmmv 
    209  1.1  jmmv         sigusr1_2::happened = false;
    210  1.1  jmmv         ::kill(::getpid(), SIGUSR1);
    211  1.1  jmmv         ATF_REQUIRE(sigusr1_2::happened);
    212  1.1  jmmv     }
    213  1.1  jmmv 
    214  1.1  jmmv     ATF_REQUIRE(!sigusr1::happened);
    215  1.1  jmmv     ::kill(::getpid(), SIGUSR1);
    216  1.1  jmmv     ATF_REQUIRE(sigusr1::happened);
    217  1.1  jmmv }
    218  1.1  jmmv 
    219  1.1  jmmv // ------------------------------------------------------------------------
    220  1.1  jmmv // Tests cases for the free functions.
    221  1.1  jmmv // ------------------------------------------------------------------------
    222  1.1  jmmv 
    223  1.1  jmmv static
    224  1.1  jmmv void
    225  1.2  jmmv reset_child(void *v __attribute__((__unused__)))
    226  1.1  jmmv {
    227  1.1  jmmv     sigusr1::program();
    228  1.1  jmmv 
    229  1.1  jmmv     sigusr1::happened = false;
    230  1.1  jmmv     tools::signals::reset(SIGUSR1);
    231  1.1  jmmv     kill(::getpid(), SIGUSR1);
    232  1.1  jmmv 
    233  1.1  jmmv     if (sigusr1::happened) {
    234  1.1  jmmv         std::cerr << "Signal was not resetted correctly\n";
    235  1.1  jmmv         std::abort();
    236  1.1  jmmv     } else {
    237  1.1  jmmv         std::exit(EXIT_SUCCESS);
    238  1.1  jmmv     }
    239  1.1  jmmv }
    240  1.1  jmmv 
    241  1.1  jmmv ATF_TEST_CASE(reset);
    242  1.1  jmmv ATF_TEST_CASE_HEAD(reset)
    243  1.1  jmmv {
    244  1.1  jmmv     set_md_var("descr", "Tests the reset function");
    245  1.1  jmmv }
    246  1.1  jmmv ATF_TEST_CASE_BODY(reset)
    247  1.1  jmmv {
    248  1.1  jmmv     tools::process::child c =
    249  1.1  jmmv         tools::process::fork(reset_child, tools::process::stream_inherit(),
    250  1.1  jmmv                            tools::process::stream_inherit(), NULL);
    251  1.1  jmmv 
    252  1.1  jmmv     const tools::process::status s = c.wait();
    253  1.1  jmmv     ATF_REQUIRE(s.exited() || s.signaled());
    254  1.1  jmmv     ATF_REQUIRE(!s.signaled() || s.termsig() == SIGUSR1);
    255  1.1  jmmv }
    256  1.1  jmmv 
    257  1.1  jmmv // ------------------------------------------------------------------------
    258  1.1  jmmv // Main.
    259  1.1  jmmv // ------------------------------------------------------------------------
    260  1.1  jmmv 
    261  1.1  jmmv ATF_INIT_TEST_CASES(tcs)
    262  1.1  jmmv {
    263  1.1  jmmv     // Add the tests for the "signal_holder" class.
    264  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, signal_holder_preserve);
    265  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, signal_holder_destructor);
    266  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, signal_holder_process);
    267  1.1  jmmv 
    268  1.1  jmmv     // Add the tests for the "signal_programmer" class.
    269  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, signal_programmer_program);
    270  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, signal_programmer_preserve);
    271  1.1  jmmv 
    272  1.1  jmmv     // Add the test cases for the free functions.
    273  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, reset);
    274  1.1  jmmv }
    275