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