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