blob: feb26b38e3b1a7b8a5d8d3ae057dafb446fe5fd3 [file] [log] [blame]
Austin Schuhcc6070c2020-10-10 20:25:56 -07001#include "aos/realtime.h"
2
Austin Schuh99f7c6a2024-06-25 22:07:44 -07003#include "absl/base/internal/raw_logging.h"
4#include "absl/flags/declare.h"
5#include "absl/flags/flag.h"
6#include "absl/log/check.h"
7#include "absl/log/log.h"
Austin Schuhcc6070c2020-10-10 20:25:56 -07008#include "gtest/gtest.h"
9
Philipp Schrader790cb542023-07-05 21:06:52 -070010#include "aos/init.h"
11
Austin Schuh99f7c6a2024-06-25 22:07:44 -070012ABSL_DECLARE_FLAG(bool, die_on_malloc);
Austin Schuh77f3f222022-06-10 16:49:21 -070013
Stephan Pleinesf63bde82024-01-13 15:59:33 -080014namespace aos::testing {
Austin Schuhcc6070c2020-10-10 20:25:56 -070015
16// Tests that ScopedRealtime handles the simple case.
17TEST(RealtimeTest, ScopedRealtime) {
18 CheckNotRealtime();
19 {
20 ScopedRealtime rt;
21 CheckRealtime();
22 }
23 CheckNotRealtime();
24}
25
26// Tests that ScopedRealtime handles nesting.
27TEST(RealtimeTest, DoubleScopedRealtime) {
28 CheckNotRealtime();
29 {
30 ScopedRealtime rt;
31 CheckRealtime();
32 {
33 ScopedRealtime rt2;
34 CheckRealtime();
35 }
36 CheckRealtime();
37 }
38 CheckNotRealtime();
39}
40
41// Tests that ScopedRealtime handles nesting with ScopedNotRealtime.
42TEST(RealtimeTest, ScopedNotRealtime) {
43 CheckNotRealtime();
44 {
45 ScopedRealtime rt;
46 CheckRealtime();
47 {
48 ScopedNotRealtime nrt;
49 CheckNotRealtime();
50 }
51 CheckRealtime();
52 }
53 CheckNotRealtime();
54}
55
56// Tests that ScopedRealtimeRestorer works both when starting RT and nonrt.
57TEST(RealtimeTest, ScopedRealtimeRestorer) {
58 CheckNotRealtime();
59 {
60 ScopedRealtime rt;
61 CheckRealtime();
62 {
63 ScopedRealtimeRestorer restore;
64 CheckRealtime();
65
66 MarkRealtime(false);
67 CheckNotRealtime();
68 }
69 CheckRealtime();
70 }
71 CheckNotRealtime();
72
73 {
74 ScopedRealtimeRestorer restore;
75 CheckNotRealtime();
76
77 MarkRealtime(true);
78 CheckRealtime();
79 }
80 CheckNotRealtime();
81}
82
Austin Schuh34bd4f92022-06-27 16:39:06 -070083// Malloc hooks don't work with asan/msan.
84#if !__has_feature(address_sanitizer) && !__has_feature(memory_sanitizer)
85
Austin Schuh77f3f222022-06-10 16:49:21 -070086// Tests that CHECK statements give real error messages rather than die on
87// malloc.
88TEST(RealtimeDeathTest, Check) {
89 EXPECT_DEATH(
90 {
91 ScopedRealtime rt;
92 CHECK_EQ(1, 2) << ": Numbers aren't equal.";
93 },
94 "Numbers aren't equal");
95 EXPECT_DEATH(
96 {
97 ScopedRealtime rt;
98 CHECK_GT(1, 2) << ": Cute error message";
99 },
100 "Cute error message");
101}
102
103// Tests that CHECK statements give real error messages rather than die on
104// malloc.
105TEST(RealtimeDeathTest, Fatal) {
106 EXPECT_DEATH(
107 {
108 ScopedRealtime rt;
109 LOG(FATAL) << "Cute message here";
110 },
111 "Cute message here");
112}
113
Stephan Pleines4c22d8f2024-07-10 20:01:36 -0700114TEST(RealtimeDeathTest, Malloc) {
115 EXPECT_DEATH(
116 {
117 ScopedRealtime rt;
118 volatile int *a = reinterpret_cast<volatile int *>(malloc(sizeof(int)));
119 *a = 5;
120 EXPECT_EQ(*a, 5);
121 },
122 "RAW: Malloced");
123}
124
125TEST(RealtimeDeathTest, Realloc) {
126 EXPECT_DEATH(
127 {
128 void *a = malloc(sizeof(int));
129 ScopedRealtime rt;
130 volatile int *b =
131 reinterpret_cast<volatile int *>(realloc(a, sizeof(int) * 2));
132 *b = 5;
133 EXPECT_EQ(*b, 5);
134 },
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700135 "RAW: Malloced");
Stephan Pleines4c22d8f2024-07-10 20:01:36 -0700136}
137
138TEST(RealtimeDeathTest, Calloc) {
139 EXPECT_DEATH(
140 {
141 ScopedRealtime rt;
142 volatile int *a =
143 reinterpret_cast<volatile int *>(calloc(1, sizeof(int)));
144 *a = 5;
145 EXPECT_EQ(*a, 5);
146 },
147 "RAW: Malloced");
148}
149
150TEST(RealtimeDeathTest, New) {
151 EXPECT_DEATH(
152 {
153 ScopedRealtime rt;
154 volatile int *a = new int;
155 *a = 5;
156 EXPECT_EQ(*a, 5);
157 },
158 "RAW: Malloced");
159}
160
161TEST(RealtimeDeathTest, NewArray) {
162 EXPECT_DEATH(
163 {
164 ScopedRealtime rt;
165 volatile int *a = new int[3];
166 *a = 5;
167 EXPECT_EQ(*a, 5);
168 },
169 "RAW: Malloced");
170}
171
Austin Schuh77f3f222022-06-10 16:49:21 -0700172// Tests that the signal handler drops RT permission and prints out a real
173// backtrace instead of crashing on the resulting mallocs.
174TEST(RealtimeDeathTest, SignalHandler) {
175 EXPECT_DEATH(
176 {
177 ScopedRealtime rt;
178 int x = reinterpret_cast<const volatile int *>(0)[0];
179 LOG(INFO) << x;
180 },
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700181 "\\*\\*\\* SIGSEGV received at .*");
Austin Schuh77f3f222022-06-10 16:49:21 -0700182}
183
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700184// Tests that ABSL_RAW_LOG(FATAL) explodes properly.
Austin Schuh61226052022-06-20 09:40:08 -0700185TEST(RealtimeDeathTest, RawFatal) {
186 EXPECT_DEATH(
187 {
188 ScopedRealtime rt;
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700189 ABSL_RAW_LOG(FATAL, "Cute message here\n");
Austin Schuh61226052022-06-20 09:40:08 -0700190 },
191 "Cute message here");
192}
193
Austin Schuh34bd4f92022-06-27 16:39:06 -0700194#endif
195
Philipp Schrader36d77932024-02-01 18:31:19 -0800196// Tests that we see which CPUs we tried to set when it fails. This can be
197// useful for debugging.
198TEST(RealtimeDeathTest, SetAffinityErrorMessage) {
199 EXPECT_DEATH({ SetCurrentThreadAffinity(MakeCpusetFromCpus({1000})); },
200 "sched_setaffinity\\(0, sizeof\\(cpuset\\), &cpuset\\) == 0 "
201 "\\{CPUs 1000\\}: Invalid argument");
202 EXPECT_DEATH(
203 {
204 SetCurrentThreadAffinity(MakeCpusetFromCpus({1000, 1001}));
205 },
206 "sched_setaffinity\\(0, sizeof\\(cpuset\\), &cpuset\\) == 0 "
207 "\\{CPUs 1000, 1001\\}: Invalid argument");
208}
209
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800210} // namespace aos::testing
Austin Schuh77f3f222022-06-10 16:49:21 -0700211
212// We need a special gtest main to force die_on_malloc support on. Otherwise
213// we can't test CHECK statements before turning die_on_malloc on globally.
214GTEST_API_ int main(int argc, char **argv) {
215 ::testing::InitGoogleTest(&argc, argv);
Austin Schuh34bd4f92022-06-27 16:39:06 -0700216
217#if !__has_feature(address_sanitizer) && !__has_feature(memory_sanitizer)
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700218 absl::SetFlag(&FLAGS_die_on_malloc, true);
Austin Schuh34bd4f92022-06-27 16:39:06 -0700219#endif
Austin Schuh77f3f222022-06-10 16:49:21 -0700220
221 aos::InitGoogle(&argc, &argv);
222
223 return RUN_ALL_TESTS();
224}