blob: 7331309ed8c476248287457058d592dfba370ce1 [file] [log] [blame]
#include "aos/common/event.h"
#include <thread>
#include "gtest/gtest.h"
#include "aos/common/queue_testutils.h"
#include "aos/common/time.h"
namespace aos {
namespace testing {
class EventTest : public ::testing::Test {
public:
Event test_event_;
protected:
void SetUp() override {
::aos::common::testing::EnableTestLogging();
}
};
// Makes sure that basic operations with no blocking or anything work.
TEST_F(EventTest, Basic) {
EXPECT_FALSE(test_event_.Clear());
EXPECT_FALSE(test_event_.Clear());
test_event_.Set();
test_event_.Wait();
EXPECT_TRUE(test_event_.Clear());
EXPECT_FALSE(test_event_.Clear());
}
// Tests that tsan understands that events establish a happens-before
// relationship.
TEST_F(EventTest, ThreadSanitizer) {
for (int i = 0; i < 3000; ++i) {
int variable = 0;
test_event_.Clear();
::std::thread thread([this, &variable]() {
test_event_.Wait();
--variable;
});
++variable;
test_event_.Set();
thread.join();
EXPECT_EQ(0, variable);
}
}
// Tests that an event blocks correctly.
TEST_F(EventTest, Blocks) {
time::Time start_time, finish_time;
// Without this, it sometimes manages to fail under tsan.
Event started;
::std::thread thread([this, &start_time, &finish_time, &started]() {
start_time = time::Time::Now();
started.Set();
test_event_.Wait();
finish_time = time::Time::Now();
});
static const time::Time kWaitTime = time::Time::InSeconds(0.05);
started.Wait();
time::SleepFor(kWaitTime);
test_event_.Set();
thread.join();
EXPECT_GE(finish_time - start_time, kWaitTime);
}
TEST_F(EventTest, WaitTimeout) {
EXPECT_FALSE(test_event_.WaitTimeout(time::Time::InSeconds(0.05)));
time::Time start_time, finish_time;
// Without this, it sometimes manages to fail under tsan.
Event started;
::std::thread thread([this, &start_time, &finish_time, &started]() {
start_time = time::Time::Now();
started.Set();
EXPECT_TRUE(test_event_.WaitTimeout(time::Time::InSeconds(0.5)));
finish_time = time::Time::Now();
});
static const time::Time kWaitTime = time::Time::InSeconds(0.05);
started.Wait();
time::SleepFor(kWaitTime);
test_event_.Set();
thread.join();
EXPECT_GE(finish_time - start_time, kWaitTime);
}
} // namespace testing
} // namespace aos