blob: 40c48b2e8bee74aa6e41fd369a24179b1eaea6d7 [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
11namespace aos {
12namespace testing {
13
Austin Schuhf2a50ba2016-12-24 16:16:26 -080014namespace chrono = ::std::chrono;
15namespace this_thread = ::std::this_thread;
16
Brian Silvermanf5f34902015-03-29 17:57:59 -040017class EventTest : public ::testing::Test {
18 public:
Brian Silverman30608942015-04-08 19:16:46 -040019 Event test_event_;
Brian Silvermanf5f34902015-03-29 17:57:59 -040020
21 protected:
Brian Silverman7b266d92021-02-17 21:24:02 -080022 void SetUp() override { ::aos::testing::EnableTestLogging(); }
Brian Silvermanf5f34902015-03-29 17:57:59 -040023};
24
25// Makes sure that basic operations with no blocking or anything work.
26TEST_F(EventTest, Basic) {
Brian Silverman30608942015-04-08 19:16:46 -040027 EXPECT_FALSE(test_event_.Clear());
28 EXPECT_FALSE(test_event_.Clear());
Brian Silvermanf5f34902015-03-29 17:57:59 -040029
Brian Silverman30608942015-04-08 19:16:46 -040030 test_event_.Set();
31 test_event_.Wait();
32 EXPECT_TRUE(test_event_.Clear());
33 EXPECT_FALSE(test_event_.Clear());
Brian Silvermanf5f34902015-03-29 17:57:59 -040034}
35
36// Tests that tsan understands that events establish a happens-before
37// relationship.
38TEST_F(EventTest, ThreadSanitizer) {
Brian Silvermand6ee9a12015-03-31 01:37:49 -040039 for (int i = 0; i < 3000; ++i) {
Brian Silvermanf5f34902015-03-29 17:57:59 -040040 int variable = 0;
Brian Silverman30608942015-04-08 19:16:46 -040041 test_event_.Clear();
Brian Silvermanf5f34902015-03-29 17:57:59 -040042 ::std::thread thread([this, &variable]() {
Brian Silverman30608942015-04-08 19:16:46 -040043 test_event_.Wait();
Brian Silvermanf5f34902015-03-29 17:57:59 -040044 --variable;
45 });
46 ++variable;
Brian Silverman30608942015-04-08 19:16:46 -040047 test_event_.Set();
Brian Silvermanf5f34902015-03-29 17:57:59 -040048 thread.join();
49 EXPECT_EQ(0, variable);
50 }
51}
52
53// Tests that an event blocks correctly.
54TEST_F(EventTest, Blocks) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080055 monotonic_clock::time_point start_time, finish_time;
Brian Silvermand6ee9a12015-03-31 01:37:49 -040056 // Without this, it sometimes manages to fail under tsan.
57 Event started;
58 ::std::thread thread([this, &start_time, &finish_time, &started]() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080059 start_time = monotonic_clock::now();
Brian Silvermand6ee9a12015-03-31 01:37:49 -040060 started.Set();
Brian Silverman30608942015-04-08 19:16:46 -040061 test_event_.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080062 finish_time = monotonic_clock::now();
Brian Silvermanf5f34902015-03-29 17:57:59 -040063 });
Austin Schuhf2a50ba2016-12-24 16:16:26 -080064 static constexpr auto kWaitTime = chrono::milliseconds(50);
Brian Silvermand6ee9a12015-03-31 01:37:49 -040065 started.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080066 this_thread::sleep_for(kWaitTime);
Brian Silverman30608942015-04-08 19:16:46 -040067 test_event_.Set();
68 thread.join();
69 EXPECT_GE(finish_time - start_time, kWaitTime);
70}
71
72TEST_F(EventTest, WaitTimeout) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080073 EXPECT_FALSE(test_event_.WaitTimeout(chrono::milliseconds(50)));
Brian Silverman30608942015-04-08 19:16:46 -040074
Austin Schuhf2a50ba2016-12-24 16:16:26 -080075 monotonic_clock::time_point start_time, finish_time;
Brian Silverman30608942015-04-08 19:16:46 -040076 // Without this, it sometimes manages to fail under tsan.
77 Event started;
78 ::std::thread thread([this, &start_time, &finish_time, &started]() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080079 start_time = monotonic_clock::now();
Brian Silverman30608942015-04-08 19:16:46 -040080 started.Set();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080081 EXPECT_TRUE(test_event_.WaitTimeout(chrono::milliseconds(500)));
82 finish_time = monotonic_clock::now();
Brian Silverman30608942015-04-08 19:16:46 -040083 });
Austin Schuhf2a50ba2016-12-24 16:16:26 -080084 constexpr auto kWaitTime = chrono::milliseconds(50);
Brian Silverman30608942015-04-08 19:16:46 -040085 started.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080086 this_thread::sleep_for(kWaitTime);
Brian Silverman30608942015-04-08 19:16:46 -040087 test_event_.Set();
Brian Silvermanf5f34902015-03-29 17:57:59 -040088 thread.join();
89 EXPECT_GE(finish_time - start_time, kWaitTime);
90}
91
92} // namespace testing
93} // namespace aos