blob: eda91565447f46913141b0ef18b15a8fd052a800 [file] [log] [blame]
Brian Silverman7b266d92021-02-17 21:24:02 -08001#include "aos/ipc_lib/event.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -04002
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
Brian Silvermanf5f34902015-03-29 17:57:59 -04004#include <thread>
5
Philipp Schrader790cb542023-07-05 21:06:52 -07006#include "gtest/gtest.h"
7
Austin Schuhf2a50ba2016-12-24 16:16:26 -08008#include "aos/testing/test_logging.h"
Brian Silverman7b266d92021-02-17 21:24:02 -08009#include "aos/time/time.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -040010
Stephan Pleinesf63bde82024-01-13 15:59:33 -080011namespace aos::testing {
Brian Silvermanf5f34902015-03-29 17:57:59 -040012
Austin Schuhf2a50ba2016-12-24 16:16:26 -080013namespace chrono = ::std::chrono;
14namespace this_thread = ::std::this_thread;
15
Brian Silvermanf5f34902015-03-29 17:57:59 -040016class EventTest : public ::testing::Test {
17 public:
Brian Silverman30608942015-04-08 19:16:46 -040018 Event test_event_;
Brian Silvermanf5f34902015-03-29 17:57:59 -040019
20 protected:
Brian Silverman7b266d92021-02-17 21:24:02 -080021 void SetUp() override { ::aos::testing::EnableTestLogging(); }
Brian Silvermanf5f34902015-03-29 17:57:59 -040022};
23
24// Makes sure that basic operations with no blocking or anything work.
25TEST_F(EventTest, Basic) {
Brian Silverman30608942015-04-08 19:16:46 -040026 EXPECT_FALSE(test_event_.Clear());
27 EXPECT_FALSE(test_event_.Clear());
Brian Silvermanf5f34902015-03-29 17:57:59 -040028
Brian Silverman30608942015-04-08 19:16:46 -040029 test_event_.Set();
30 test_event_.Wait();
31 EXPECT_TRUE(test_event_.Clear());
32 EXPECT_FALSE(test_event_.Clear());
Brian Silvermanf5f34902015-03-29 17:57:59 -040033}
34
35// Tests that tsan understands that events establish a happens-before
36// relationship.
37TEST_F(EventTest, ThreadSanitizer) {
Brian Silvermand6ee9a12015-03-31 01:37:49 -040038 for (int i = 0; i < 3000; ++i) {
Brian Silvermanf5f34902015-03-29 17:57:59 -040039 int variable = 0;
Brian Silverman30608942015-04-08 19:16:46 -040040 test_event_.Clear();
Brian Silvermanf5f34902015-03-29 17:57:59 -040041 ::std::thread thread([this, &variable]() {
Brian Silverman30608942015-04-08 19:16:46 -040042 test_event_.Wait();
Brian Silvermanf5f34902015-03-29 17:57:59 -040043 --variable;
44 });
45 ++variable;
Brian Silverman30608942015-04-08 19:16:46 -040046 test_event_.Set();
Brian Silvermanf5f34902015-03-29 17:57:59 -040047 thread.join();
48 EXPECT_EQ(0, variable);
49 }
50}
51
52// Tests that an event blocks correctly.
53TEST_F(EventTest, Blocks) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080054 monotonic_clock::time_point start_time, finish_time;
Brian Silvermand6ee9a12015-03-31 01:37:49 -040055 // Without this, it sometimes manages to fail under tsan.
56 Event started;
57 ::std::thread thread([this, &start_time, &finish_time, &started]() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080058 start_time = monotonic_clock::now();
Brian Silvermand6ee9a12015-03-31 01:37:49 -040059 started.Set();
Brian Silverman30608942015-04-08 19:16:46 -040060 test_event_.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080061 finish_time = monotonic_clock::now();
Brian Silvermanf5f34902015-03-29 17:57:59 -040062 });
Austin Schuhf2a50ba2016-12-24 16:16:26 -080063 static constexpr auto kWaitTime = chrono::milliseconds(50);
Brian Silvermand6ee9a12015-03-31 01:37:49 -040064 started.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080065 this_thread::sleep_for(kWaitTime);
Brian Silverman30608942015-04-08 19:16:46 -040066 test_event_.Set();
67 thread.join();
68 EXPECT_GE(finish_time - start_time, kWaitTime);
69}
70
71TEST_F(EventTest, WaitTimeout) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080072 EXPECT_FALSE(test_event_.WaitTimeout(chrono::milliseconds(50)));
Brian Silverman30608942015-04-08 19:16:46 -040073
Austin Schuhf2a50ba2016-12-24 16:16:26 -080074 monotonic_clock::time_point start_time, finish_time;
Brian Silverman30608942015-04-08 19:16:46 -040075 // Without this, it sometimes manages to fail under tsan.
76 Event started;
77 ::std::thread thread([this, &start_time, &finish_time, &started]() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080078 start_time = monotonic_clock::now();
Brian Silverman30608942015-04-08 19:16:46 -040079 started.Set();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080080 EXPECT_TRUE(test_event_.WaitTimeout(chrono::milliseconds(500)));
81 finish_time = monotonic_clock::now();
Brian Silverman30608942015-04-08 19:16:46 -040082 });
Austin Schuhf2a50ba2016-12-24 16:16:26 -080083 constexpr auto kWaitTime = chrono::milliseconds(50);
Brian Silverman30608942015-04-08 19:16:46 -040084 started.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080085 this_thread::sleep_for(kWaitTime);
Brian Silverman30608942015-04-08 19:16:46 -040086 test_event_.Set();
Brian Silvermanf5f34902015-03-29 17:57:59 -040087 thread.join();
88 EXPECT_GE(finish_time - start_time, kWaitTime);
89}
90
Stephan Pleinesf63bde82024-01-13 15:59:33 -080091} // namespace aos::testing