blob: 764dd498917d21b262377e47f0193d0c2ece579c [file] [log] [blame]
Brian Silvermanf5f34902015-03-29 17:57:59 -04001#include "aos/common/event.h"
2
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
Brian Silvermanf5f34902015-03-29 17:57:59 -04004#include <thread>
5
6#include "gtest/gtest.h"
7
Brian Silvermanf5f34902015-03-29 17:57:59 -04008#include "aos/common/time.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -08009#include "aos/testing/test_logging.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:
22 void SetUp() override {
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050023 ::aos::testing::EnableTestLogging();
Brian Silvermanf5f34902015-03-29 17:57:59 -040024 }
25};
26
27// Makes sure that basic operations with no blocking or anything work.
28TEST_F(EventTest, Basic) {
Brian Silverman30608942015-04-08 19:16:46 -040029 EXPECT_FALSE(test_event_.Clear());
30 EXPECT_FALSE(test_event_.Clear());
Brian Silvermanf5f34902015-03-29 17:57:59 -040031
Brian Silverman30608942015-04-08 19:16:46 -040032 test_event_.Set();
33 test_event_.Wait();
34 EXPECT_TRUE(test_event_.Clear());
35 EXPECT_FALSE(test_event_.Clear());
Brian Silvermanf5f34902015-03-29 17:57:59 -040036}
37
38// Tests that tsan understands that events establish a happens-before
39// relationship.
40TEST_F(EventTest, ThreadSanitizer) {
Brian Silvermand6ee9a12015-03-31 01:37:49 -040041 for (int i = 0; i < 3000; ++i) {
Brian Silvermanf5f34902015-03-29 17:57:59 -040042 int variable = 0;
Brian Silverman30608942015-04-08 19:16:46 -040043 test_event_.Clear();
Brian Silvermanf5f34902015-03-29 17:57:59 -040044 ::std::thread thread([this, &variable]() {
Brian Silverman30608942015-04-08 19:16:46 -040045 test_event_.Wait();
Brian Silvermanf5f34902015-03-29 17:57:59 -040046 --variable;
47 });
48 ++variable;
Brian Silverman30608942015-04-08 19:16:46 -040049 test_event_.Set();
Brian Silvermanf5f34902015-03-29 17:57:59 -040050 thread.join();
51 EXPECT_EQ(0, variable);
52 }
53}
54
55// Tests that an event blocks correctly.
56TEST_F(EventTest, Blocks) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080057 monotonic_clock::time_point start_time, finish_time;
Brian Silvermand6ee9a12015-03-31 01:37:49 -040058 // Without this, it sometimes manages to fail under tsan.
59 Event started;
60 ::std::thread thread([this, &start_time, &finish_time, &started]() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080061 start_time = monotonic_clock::now();
Brian Silvermand6ee9a12015-03-31 01:37:49 -040062 started.Set();
Brian Silverman30608942015-04-08 19:16:46 -040063 test_event_.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080064 finish_time = monotonic_clock::now();
Brian Silvermanf5f34902015-03-29 17:57:59 -040065 });
Austin Schuhf2a50ba2016-12-24 16:16:26 -080066 static constexpr auto kWaitTime = chrono::milliseconds(50);
Brian Silvermand6ee9a12015-03-31 01:37:49 -040067 started.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080068 this_thread::sleep_for(kWaitTime);
Brian Silverman30608942015-04-08 19:16:46 -040069 test_event_.Set();
70 thread.join();
71 EXPECT_GE(finish_time - start_time, kWaitTime);
72}
73
74TEST_F(EventTest, WaitTimeout) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080075 EXPECT_FALSE(test_event_.WaitTimeout(chrono::milliseconds(50)));
Brian Silverman30608942015-04-08 19:16:46 -040076
Austin Schuhf2a50ba2016-12-24 16:16:26 -080077 monotonic_clock::time_point start_time, finish_time;
Brian Silverman30608942015-04-08 19:16:46 -040078 // Without this, it sometimes manages to fail under tsan.
79 Event started;
80 ::std::thread thread([this, &start_time, &finish_time, &started]() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080081 start_time = monotonic_clock::now();
Brian Silverman30608942015-04-08 19:16:46 -040082 started.Set();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080083 EXPECT_TRUE(test_event_.WaitTimeout(chrono::milliseconds(500)));
84 finish_time = monotonic_clock::now();
Brian Silverman30608942015-04-08 19:16:46 -040085 });
Austin Schuhf2a50ba2016-12-24 16:16:26 -080086 constexpr auto kWaitTime = chrono::milliseconds(50);
Brian Silverman30608942015-04-08 19:16:46 -040087 started.Wait();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080088 this_thread::sleep_for(kWaitTime);
Brian Silverman30608942015-04-08 19:16:46 -040089 test_event_.Set();
Brian Silvermanf5f34902015-03-29 17:57:59 -040090 thread.join();
91 EXPECT_GE(finish_time - start_time, kWaitTime);
92}
93
94} // namespace testing
95} // namespace aos