1240116Smarcel// 2240116Smarcel// Automated Testing Framework (atf) 3240116Smarcel// 4240116Smarcel// Copyright (c) 2008 The NetBSD Foundation, Inc. 5240116Smarcel// All rights reserved. 6240116Smarcel// 7240116Smarcel// Redistribution and use in source and binary forms, with or without 8240116Smarcel// modification, are permitted provided that the following conditions 9240116Smarcel// are met: 10240116Smarcel// 1. Redistributions of source code must retain the above copyright 11240116Smarcel// notice, this list of conditions and the following disclaimer. 12240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright 13240116Smarcel// notice, this list of conditions and the following disclaimer in the 14240116Smarcel// documentation and/or other materials provided with the distribution. 15240116Smarcel// 16240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28240116Smarcel// 29240116Smarcel 30240116Smarcelextern "C" { 31240116Smarcel#include <sys/types.h> 32240116Smarcel#include <signal.h> 33240116Smarcel#include <unistd.h> 34240116Smarcel} 35240116Smarcel 36240116Smarcel#include <cerrno> 37240116Smarcel#include <cstdlib> 38240116Smarcel#include <iostream> 39240116Smarcel 40240116Smarcel#include "atf-c/defs.h" 41240116Smarcel 42240116Smarcel#include "atf-c++/macros.hpp" 43240116Smarcel 44240116Smarcel#include "atf-c++/detail/exceptions.hpp" 45240116Smarcel#include "atf-c++/detail/process.hpp" 46240116Smarcel 47240116Smarcel#include "signals.hpp" 48240116Smarcel 49240116Smarcel// ------------------------------------------------------------------------ 50240116Smarcel// Auxiliary functions. 51240116Smarcel// ------------------------------------------------------------------------ 52240116Smarcel 53240116Smarcelnamespace sigusr1 { 54240116Smarcel static bool happened = false; 55240116Smarcel 56240116Smarcel static 57240116Smarcel void 58240116Smarcel handler(int signo ATF_DEFS_ATTRIBUTE_UNUSED) 59240116Smarcel { 60240116Smarcel happened = true; 61240116Smarcel } 62240116Smarcel 63240116Smarcel static 64240116Smarcel void 65240116Smarcel program(void) 66240116Smarcel { 67240116Smarcel struct sigaction sa; 68240116Smarcel sa.sa_handler = handler; 69240116Smarcel sigemptyset(&sa.sa_mask); 70240116Smarcel sa.sa_flags = 0; 71240116Smarcel if (::sigaction(SIGUSR1, &sa, NULL) == -1) 72240116Smarcel throw atf::system_error("sigusr1::program", 73240116Smarcel "sigaction(2) failed", errno); 74240116Smarcel } 75240116Smarcel} // namespace sigusr1 76240116Smarcel 77240116Smarcelnamespace sigusr1_2 { 78240116Smarcel static bool happened = false; 79240116Smarcel 80240116Smarcel static 81240116Smarcel void 82240116Smarcel handler(int signo ATF_DEFS_ATTRIBUTE_UNUSED) 83240116Smarcel { 84240116Smarcel happened = true; 85240116Smarcel } 86240116Smarcel} // namespace sigusr1_2 87240116Smarcel 88240116Smarcel// ------------------------------------------------------------------------ 89240116Smarcel// Tests for the "signal_holder" class. 90240116Smarcel// ------------------------------------------------------------------------ 91240116Smarcel 92240116SmarcelATF_TEST_CASE(signal_holder_preserve); 93240116SmarcelATF_TEST_CASE_HEAD(signal_holder_preserve) 94240116Smarcel{ 95240116Smarcel set_md_var("descr", "Tests that signal_holder preserves the original " 96240116Smarcel "signal handler and restores it upon destruction"); 97240116Smarcel} 98240116SmarcelATF_TEST_CASE_BODY(signal_holder_preserve) 99240116Smarcel{ 100240116Smarcel using atf::atf_run::signal_holder; 101240116Smarcel 102240116Smarcel sigusr1::program(); 103240116Smarcel 104240116Smarcel sigusr1::happened = false; 105240116Smarcel ::kill(::getpid(), SIGUSR1); 106240116Smarcel ATF_REQUIRE(sigusr1::happened); 107240116Smarcel 108240116Smarcel { 109240116Smarcel signal_holder hld(SIGUSR1); 110240116Smarcel ::kill(::getpid(), SIGUSR1); 111240116Smarcel } 112240116Smarcel 113240116Smarcel sigusr1::happened = false; 114240116Smarcel ::kill(::getpid(), SIGUSR1); 115240116Smarcel ATF_REQUIRE(sigusr1::happened); 116240116Smarcel} 117240116Smarcel 118240116SmarcelATF_TEST_CASE(signal_holder_destructor); 119240116SmarcelATF_TEST_CASE_HEAD(signal_holder_destructor) 120240116Smarcel{ 121240116Smarcel set_md_var("descr", "Tests that signal_holder processes a pending " 122240116Smarcel "signal upon destruction"); 123240116Smarcel} 124240116SmarcelATF_TEST_CASE_BODY(signal_holder_destructor) 125240116Smarcel{ 126240116Smarcel using atf::atf_run::signal_holder; 127240116Smarcel 128240116Smarcel sigusr1::program(); 129240116Smarcel 130240116Smarcel sigusr1::happened = false; 131240116Smarcel ::kill(::getpid(), SIGUSR1); 132240116Smarcel ATF_REQUIRE(sigusr1::happened); 133240116Smarcel 134240116Smarcel { 135240116Smarcel signal_holder hld(SIGUSR1); 136240116Smarcel 137240116Smarcel sigusr1::happened = false; 138240116Smarcel ::kill(::getpid(), SIGUSR1); 139240116Smarcel ATF_REQUIRE(!sigusr1::happened); 140240116Smarcel } 141240116Smarcel ATF_REQUIRE(sigusr1::happened); 142240116Smarcel} 143240116Smarcel 144240116SmarcelATF_TEST_CASE(signal_holder_process); 145240116SmarcelATF_TEST_CASE_HEAD(signal_holder_process) 146240116Smarcel{ 147240116Smarcel set_md_var("descr", "Tests that signal_holder's process method works " 148240116Smarcel "to process a delayed signal explicitly"); 149240116Smarcel} 150240116SmarcelATF_TEST_CASE_BODY(signal_holder_process) 151240116Smarcel{ 152240116Smarcel using atf::atf_run::signal_holder; 153240116Smarcel 154240116Smarcel sigusr1::program(); 155240116Smarcel 156240116Smarcel sigusr1::happened = false; 157240116Smarcel ::kill(::getpid(), SIGUSR1); 158240116Smarcel ATF_REQUIRE(sigusr1::happened); 159240116Smarcel 160240116Smarcel { 161240116Smarcel signal_holder hld(SIGUSR1); 162240116Smarcel 163240116Smarcel sigusr1::happened = false; 164240116Smarcel ::kill(::getpid(), SIGUSR1); 165240116Smarcel ATF_REQUIRE(!sigusr1::happened); 166240116Smarcel 167240116Smarcel hld.process(); 168240116Smarcel ATF_REQUIRE(sigusr1::happened); 169240116Smarcel 170240116Smarcel sigusr1::happened = false; 171240116Smarcel } 172240116Smarcel ATF_REQUIRE(!sigusr1::happened); 173240116Smarcel} 174240116Smarcel 175240116Smarcel// ------------------------------------------------------------------------ 176240116Smarcel// Tests for the "signal_programmer" class. 177240116Smarcel// ------------------------------------------------------------------------ 178240116Smarcel 179240116SmarcelATF_TEST_CASE(signal_programmer_program); 180240116SmarcelATF_TEST_CASE_HEAD(signal_programmer_program) 181240116Smarcel{ 182240116Smarcel set_md_var("descr", "Tests that signal_programmer correctly installs a " 183240116Smarcel "handler"); 184240116Smarcel} 185240116SmarcelATF_TEST_CASE_BODY(signal_programmer_program) 186240116Smarcel{ 187240116Smarcel using atf::atf_run::signal_programmer; 188240116Smarcel 189240116Smarcel signal_programmer sp(SIGUSR1, sigusr1_2::handler); 190240116Smarcel 191240116Smarcel sigusr1_2::happened = false; 192240116Smarcel ::kill(::getpid(), SIGUSR1); 193240116Smarcel ATF_REQUIRE(sigusr1_2::happened); 194240116Smarcel} 195240116Smarcel 196240116SmarcelATF_TEST_CASE(signal_programmer_preserve); 197240116SmarcelATF_TEST_CASE_HEAD(signal_programmer_preserve) 198240116Smarcel{ 199240116Smarcel set_md_var("descr", "Tests that signal_programmer uninstalls the " 200240116Smarcel "handler during destruction"); 201240116Smarcel} 202240116SmarcelATF_TEST_CASE_BODY(signal_programmer_preserve) 203240116Smarcel{ 204240116Smarcel using atf::atf_run::signal_programmer; 205240116Smarcel 206240116Smarcel sigusr1::program(); 207240116Smarcel sigusr1::happened = false; 208240116Smarcel 209240116Smarcel { 210240116Smarcel signal_programmer sp(SIGUSR1, sigusr1_2::handler); 211240116Smarcel 212240116Smarcel sigusr1_2::happened = false; 213240116Smarcel ::kill(::getpid(), SIGUSR1); 214240116Smarcel ATF_REQUIRE(sigusr1_2::happened); 215240116Smarcel } 216240116Smarcel 217240116Smarcel ATF_REQUIRE(!sigusr1::happened); 218240116Smarcel ::kill(::getpid(), SIGUSR1); 219240116Smarcel ATF_REQUIRE(sigusr1::happened); 220240116Smarcel} 221240116Smarcel 222240116Smarcel// ------------------------------------------------------------------------ 223240116Smarcel// Tests cases for the free functions. 224240116Smarcel// ------------------------------------------------------------------------ 225240116Smarcel 226240116Smarcelstatic 227240116Smarcelvoid 228240116Smarcelreset_child(void *v ATF_DEFS_ATTRIBUTE_UNUSED) 229240116Smarcel{ 230240116Smarcel sigusr1::program(); 231240116Smarcel 232240116Smarcel sigusr1::happened = false; 233240116Smarcel atf::atf_run::reset(SIGUSR1); 234240116Smarcel kill(::getpid(), SIGUSR1); 235240116Smarcel 236240116Smarcel if (sigusr1::happened) { 237240116Smarcel std::cerr << "Signal was not resetted correctly\n"; 238240116Smarcel std::abort(); 239240116Smarcel } else { 240240116Smarcel std::exit(EXIT_SUCCESS); 241240116Smarcel } 242240116Smarcel} 243240116Smarcel 244240116SmarcelATF_TEST_CASE(reset); 245240116SmarcelATF_TEST_CASE_HEAD(reset) 246240116Smarcel{ 247240116Smarcel set_md_var("descr", "Tests the reset function"); 248240116Smarcel} 249240116SmarcelATF_TEST_CASE_BODY(reset) 250240116Smarcel{ 251240116Smarcel atf::process::child c = 252240116Smarcel atf::process::fork(reset_child, atf::process::stream_inherit(), 253240116Smarcel atf::process::stream_inherit(), NULL); 254240116Smarcel 255240116Smarcel const atf::process::status s = c.wait(); 256240116Smarcel ATF_REQUIRE(s.exited() || s.signaled()); 257240116Smarcel ATF_REQUIRE(!s.signaled() || s.termsig() == SIGUSR1); 258240116Smarcel} 259240116Smarcel 260240116Smarcel// ------------------------------------------------------------------------ 261240116Smarcel// Main. 262240116Smarcel// ------------------------------------------------------------------------ 263240116Smarcel 264240116SmarcelATF_INIT_TEST_CASES(tcs) 265240116Smarcel{ 266240116Smarcel // Add the tests for the "signal_holder" class. 267240116Smarcel ATF_ADD_TEST_CASE(tcs, signal_holder_preserve); 268240116Smarcel ATF_ADD_TEST_CASE(tcs, signal_holder_destructor); 269240116Smarcel ATF_ADD_TEST_CASE(tcs, signal_holder_process); 270240116Smarcel 271240116Smarcel // Add the tests for the "signal_programmer" class. 272240116Smarcel ATF_ADD_TEST_CASE(tcs, signal_programmer_program); 273240116Smarcel ATF_ADD_TEST_CASE(tcs, signal_programmer_preserve); 274240116Smarcel 275240116Smarcel // Add the test cases for the free functions. 276240116Smarcel ATF_ADD_TEST_CASE(tcs, reset); 277240116Smarcel} 278