blob: 6d1026173f166e70d254e7ef5ff2248554e10481 [file] [edit]
#include <thread> // NOLINT(build/c++11)
#include <vector>
#include "event.h"
#include "event_queue.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "bmc/test_util.h"
namespace safepower_agent {
namespace {
TEST(EventQueueThreadTest, PushAndPopSingleEvent) {
EventQueue queue;
queue.Push(Event{});
ASSERT_OK_AND_ASSIGN(auto events,
queue.PopAllWithTimeout(absl::ZeroDuration()));
EXPECT_EQ(events.size(), 1);
}
TEST(EventQueueThreadTest, PopAllDrainsQueue) {
EventQueue queue;
queue.Push(Event{});
queue.Push(Event{});
queue.Push(Event{});
ASSERT_OK_AND_ASSIGN(auto events,
queue.PopAllWithTimeout(absl::ZeroDuration()));
EXPECT_EQ(events.size(), 3);
// Subsequent pop should be empty.
ASSERT_OK_AND_ASSIGN(auto empty_events,
queue.PopAllWithTimeout(absl::ZeroDuration()));
EXPECT_TRUE(empty_events.empty());
}
TEST(EventQueueThreadTest, PopWithTimeoutBlocksUntilEvent) {
EventQueue queue;
std::thread writer_thread([&queue]() {
absl::SleepFor(absl::Milliseconds(50));
queue.Push(Event{});
});
auto start = absl::Now();
ASSERT_OK_AND_ASSIGN(auto events, queue.PopAllWithTimeout(absl::Seconds(2)));
auto duration = absl::Now() - start;
EXPECT_EQ(events.size(), 1);
EXPECT_LT(duration, absl::Seconds(1));
writer_thread.join();
}
TEST(EventQueueThreadTest, PopWithTimeoutBlocksUntilClose) {
EventQueue queue;
std::thread writer_thread([&queue]() {
absl::SleepFor(absl::Milliseconds(50));
queue.Close();
});
auto start = absl::Now();
auto events = queue.PopAllWithTimeout(absl::Seconds(2));
auto duration = absl::Now() - start;
// It should return error because it was closed and empty.
EXPECT_EQ(events.status().code(), absl::StatusCode::kAborted);
EXPECT_LT(duration, absl::Seconds(1));
writer_thread.join();
}
TEST(EventQueueThreadTest, PopWithTimeoutTimesOut) {
EventQueue queue;
ASSERT_OK_AND_ASSIGN(auto events,
queue.PopAllWithTimeout(absl::Milliseconds(10)));
EXPECT_TRUE(events.empty());
}
TEST(EventQueueThreadTest, PopAfterCloseReturnsError) {
EventQueue queue;
queue.Close();
auto events = queue.PopAllWithTimeout(absl::ZeroDuration());
EXPECT_FALSE(events.ok());
EXPECT_EQ(events.status().code(), absl::StatusCode::kAborted);
}
TEST(EventQueueThreadTest, PopDrainsRemainingEventsAfterClose) {
EventQueue queue;
queue.Push(Event{});
queue.Close();
// First pop should succeed and return the pushed event.
ASSERT_OK_AND_ASSIGN(auto first_events,
queue.PopAllWithTimeout(absl::ZeroDuration()));
EXPECT_EQ(first_events.size(), 1);
// Second pop should return error because it is empty and closed.
auto second_events = queue.PopAllWithTimeout(absl::ZeroDuration());
EXPECT_FALSE(second_events.ok());
EXPECT_EQ(second_events.status().code(), absl::StatusCode::kAborted);
}
} // namespace
} // namespace safepower_agent