| #include "aos/realtime.h" |
| |
| #include "glog/logging.h" |
| #include "glog/raw_logging.h" |
| #include "gtest/gtest.h" |
| |
| #include "aos/init.h" |
| |
| DECLARE_bool(die_on_malloc); |
| |
| namespace aos { |
| namespace testing { |
| |
| // Tests that ScopedRealtime handles the simple case. |
| TEST(RealtimeTest, ScopedRealtime) { |
| CheckNotRealtime(); |
| { |
| ScopedRealtime rt; |
| CheckRealtime(); |
| } |
| CheckNotRealtime(); |
| } |
| |
| // Tests that ScopedRealtime handles nesting. |
| TEST(RealtimeTest, DoubleScopedRealtime) { |
| CheckNotRealtime(); |
| { |
| ScopedRealtime rt; |
| CheckRealtime(); |
| { |
| ScopedRealtime rt2; |
| CheckRealtime(); |
| } |
| CheckRealtime(); |
| } |
| CheckNotRealtime(); |
| } |
| |
| // Tests that ScopedRealtime handles nesting with ScopedNotRealtime. |
| TEST(RealtimeTest, ScopedNotRealtime) { |
| CheckNotRealtime(); |
| { |
| ScopedRealtime rt; |
| CheckRealtime(); |
| { |
| ScopedNotRealtime nrt; |
| CheckNotRealtime(); |
| } |
| CheckRealtime(); |
| } |
| CheckNotRealtime(); |
| } |
| |
| // Tests that ScopedRealtimeRestorer works both when starting RT and nonrt. |
| TEST(RealtimeTest, ScopedRealtimeRestorer) { |
| CheckNotRealtime(); |
| { |
| ScopedRealtime rt; |
| CheckRealtime(); |
| { |
| ScopedRealtimeRestorer restore; |
| CheckRealtime(); |
| |
| MarkRealtime(false); |
| CheckNotRealtime(); |
| } |
| CheckRealtime(); |
| } |
| CheckNotRealtime(); |
| |
| { |
| ScopedRealtimeRestorer restore; |
| CheckNotRealtime(); |
| |
| MarkRealtime(true); |
| CheckRealtime(); |
| } |
| CheckNotRealtime(); |
| } |
| |
| // Malloc hooks don't work with asan/msan. |
| #if !__has_feature(address_sanitizer) && !__has_feature(memory_sanitizer) |
| |
| // Tests that CHECK statements give real error messages rather than die on |
| // malloc. |
| TEST(RealtimeDeathTest, Check) { |
| EXPECT_DEATH( |
| { |
| ScopedRealtime rt; |
| CHECK_EQ(1, 2) << ": Numbers aren't equal."; |
| }, |
| "Numbers aren't equal"); |
| EXPECT_DEATH( |
| { |
| ScopedRealtime rt; |
| CHECK_GT(1, 2) << ": Cute error message"; |
| }, |
| "Cute error message"); |
| } |
| |
| // Tests that CHECK statements give real error messages rather than die on |
| // malloc. |
| TEST(RealtimeDeathTest, Fatal) { |
| EXPECT_DEATH( |
| { |
| ScopedRealtime rt; |
| LOG(FATAL) << "Cute message here"; |
| }, |
| "Cute message here"); |
| } |
| |
| // Tests that the signal handler drops RT permission and prints out a real |
| // backtrace instead of crashing on the resulting mallocs. |
| TEST(RealtimeDeathTest, SignalHandler) { |
| EXPECT_DEATH( |
| { |
| ScopedRealtime rt; |
| int x = reinterpret_cast<const volatile int *>(0)[0]; |
| LOG(INFO) << x; |
| }, |
| "\\*\\*\\* Aborted at .*"); |
| } |
| |
| // Tests that RAW_LOG(FATAL) explodes properly. |
| TEST(RealtimeDeathTest, RawFatal) { |
| EXPECT_DEATH( |
| { |
| ScopedRealtime rt; |
| RAW_LOG(FATAL, "Cute message here\n"); |
| }, |
| "Cute message here"); |
| } |
| |
| #endif |
| |
| } // namespace testing |
| } // namespace aos |
| |
| // We need a special gtest main to force die_on_malloc support on. Otherwise |
| // we can't test CHECK statements before turning die_on_malloc on globally. |
| GTEST_API_ int main(int argc, char **argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| FLAGS_logtostderr = true; |
| |
| #if !__has_feature(address_sanitizer) && !__has_feature(memory_sanitizer) |
| FLAGS_die_on_malloc = true; |
| #endif |
| |
| aos::InitGoogle(&argc, &argv); |
| |
| return RUN_ALL_TESTS(); |
| } |