blob: 261fa746c22a13221f100c720379a75c82116908 [file] [log] [blame]
Martin Stjernholm4fb51112021-04-30 11:53:52 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <signal.h>
Martin Stjernholm4fb51112021-04-30 11:53:52 +010020#include <gtest/gtest.h>
21
satayev499be972022-05-13 15:05:39 +000022#include <array>
23#include <memory>
24
Martin Stjernholm4fb51112021-04-30 11:53:52 +010025#if !defined(__BIONIC__)
26#define sigaction64 sigaction
27#endif
28
satayev499be972022-05-13 15:05:39 +000029// INTRODUCTION
Martin Stjernholm4fb51112021-04-30 11:53:52 +010030//
satayev499be972022-05-13 15:05:39 +000031// It can be useful to disable debuggerd stack traces/tombstones in death tests.
32// Reasons include:
33//
34// 1. speeding up death tests
35// 2. reducing the noise in logcat (for humans)
36// 3. avoiding bots from thinking that expected deaths should be reported in
37// stability metrics/have bugs auto-filed
38//
39// When writing new death tests, inherit the test suite from SilentDeathTest
40// defined below.
41//
42// Only use ScopedSilentDeath in a test case/suite if changing the test base
43// class from testing::Test to SilentDeathTest adds additional complextity when
44// test suite code is shared between death and non-death tests.
45//
46// EXAMPLES
47//
48// For example, use SilentDeathTest for this simple case where there's no shared
49// setup or teardown:
50//
51// using FooDeathTest = SilentDeathTest;
52//
53// TEST(FooTest, DoesThis) {
54// // normal test
55// }
56//
57// TEST_F(FooDeathTest, DoesThat) {
58// // death test
59// }
60//
61// Alternatively, use ScopedSilentDeath if you already have a Test subclass for
62// shared setup or teardown:
63//
64// class FooTest : public testing::Test { ... /* shared setup/teardown */ };
65//
66// using FooDeathTest = FooTest;
67//
68// TEST_F(FooTest, DoesThis) {
69// // normal test
70// }
71//
72// TEST_F(FooDeathTest, DoesThat) {
73// ScopedSilentDeath _silentDeath;
74// // death test
75// }
76//
77// NOTES
78//
79// When writing death tests, consider using ASSERT_EXIT() and EXPECT_EXIT()
80// rather than the more obvious ASSERT_DEATH()/EXPECT_DEATH() macros... The
81// advantage is that you can specify a regular expression that you expect
82// the abort message to match, and can be explicit about what signal you expect
83// to die with, and you can also test for *successful* exits too. Examples:
84//
85// ASSERT_DEATH(foo(), "some text\\. some more\\.");
86//
87// ASSERT_EXIT(bar(), testing::ExitedWithCode(0), "Success");
88//
89// ASSERT_EXIT(baz(), testing::KilledBySignal(SIGABRT),
90// "expected detail message \\(blah\\)");
91//
92// As you can see the regular expression functionality is there for
93// ASSERT_DEATH() too, but it's important to realize that it's a regular
94// expression, so (as in the first and third examples), you'll need to quote
95// any metacharacters (and because it's a string literal, you'll either need
96// extra quoting or want to use a raw string).
97
98class ScopedSilentDeath {
99 public:
100 ScopedSilentDeath() {
101 for (int signo : SUPPRESSED_SIGNALS) {
Martin Stjernholm4fb51112021-04-30 11:53:52 +0100102 struct sigaction64 action = {.sa_handler = SIG_DFL};
103 sigaction64(signo, &action, &previous_);
104 }
105 }
106
satayev499be972022-05-13 15:05:39 +0000107 ~ScopedSilentDeath() {
108 for (int signo : SUPPRESSED_SIGNALS) {
Martin Stjernholm4fb51112021-04-30 11:53:52 +0100109 sigaction64(signo, &previous_, nullptr);
110 }
111 }
112
113 private:
satayev499be972022-05-13 15:05:39 +0000114 static constexpr std::array<int, 4> SUPPRESSED_SIGNALS = {SIGABRT, SIGBUS, SIGSEGV, SIGSYS};
115
Martin Stjernholm4fb51112021-04-30 11:53:52 +0100116 struct sigaction64 previous_;
117};
satayev499be972022-05-13 15:05:39 +0000118
119class SilentDeathTest : public testing::Test {
120 protected:
121 void SetUp() override {
122 silent_death_ = std::unique_ptr<ScopedSilentDeath>(new ScopedSilentDeath);
123 }
124
125 void TearDown() override { silent_death_.reset(); }
126
127 private:
128 std::unique_ptr<ScopedSilentDeath> silent_death_;
129};