134 lines
4.2 KiB
C++
134 lines
4.2 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
#include <mission_adapters/event.h>
|
|
|
|
namespace
|
|
{
|
|
using namespace mission_adapters;
|
|
|
|
Event makeEvent(EventType type)
|
|
{
|
|
Event event;
|
|
event.type = type;
|
|
return event;
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// A5 — thứ tự xử lý phải bằng thứ tự phát sinh.
|
|
//
|
|
// Bản trước sắp theo priority toàn phần: CANCEL (1) luôn đứng trước SUBMIT (5). Phát order rồi huỷ
|
|
// ngay thì huỷ được xử lý trước, order vào hàng đợi sau, và robot chạy đúng cái người dùng vừa huỷ.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
TEST(EventBusTest, SubmitThenCancelKeepsCausalOrder)
|
|
{
|
|
EventBus bus;
|
|
|
|
bus.push(makeEvent(EventType::SUBMIT_REQUEST));
|
|
bus.push(makeEvent(EventType::CANCEL));
|
|
|
|
Event event;
|
|
ASSERT_TRUE(bus.pop(event));
|
|
EXPECT_EQ(event.type, EventType::SUBMIT_REQUEST);
|
|
|
|
ASSERT_TRUE(bus.pop(event));
|
|
EXPECT_EQ(event.type, EventType::CANCEL) << "the cancel was processed before the order it "
|
|
"cancels";
|
|
}
|
|
|
|
TEST(EventBusTest, PreservesFifoOrderAcrossEventTypes)
|
|
{
|
|
EventBus bus;
|
|
|
|
const std::vector<EventType> pushed = {
|
|
EventType::PAUSE,
|
|
EventType::SUBMIT_REQUEST,
|
|
EventType::RESUME,
|
|
EventType::NAV_DONE,
|
|
EventType::CANCEL,
|
|
};
|
|
|
|
for (const auto type : pushed)
|
|
bus.push(makeEvent(type));
|
|
|
|
for (size_t i = 0; i < pushed.size(); ++i)
|
|
{
|
|
Event event;
|
|
ASSERT_TRUE(bus.pop(event)) << "event number " << i;
|
|
EXPECT_EQ(event.type, pushed[i]) << "wrong order at position " << i;
|
|
EXPECT_EQ(event.sequence, i);
|
|
}
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Emergency đi ngoài hàng đợi: độ trễ phản ứng không được phụ thuộc độ dài hàng đợi.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
TEST(EventBusTest, EmergencyOvertakesQueue)
|
|
{
|
|
EventBus bus;
|
|
|
|
for (int i = 0; i < 50; ++i)
|
|
bus.push(makeEvent(EventType::SUBMIT_REQUEST));
|
|
|
|
EXPECT_FALSE(bus.emergencyPending());
|
|
bus.pushEmergency(makeEvent(EventType::EMERGENCY));
|
|
|
|
// Thấy được ngay, không phải rút hết 50 sự kiện kia ra trước.
|
|
EXPECT_TRUE(bus.emergencyPending());
|
|
EXPECT_EQ(bus.size(), 51u) << "an EMERGENCY event must still sit in the queue to keep the log "
|
|
"sequence";
|
|
|
|
EXPECT_TRUE(bus.takeEmergency());
|
|
EXPECT_FALSE(bus.takeEmergency()) << "the emergency flag was consumed twice";
|
|
}
|
|
|
|
TEST(EventBusTest, EmergencyEventStillArrivesInOrder)
|
|
{
|
|
EventBus bus;
|
|
|
|
bus.push(makeEvent(EventType::PAUSE));
|
|
bus.pushEmergency(makeEvent(EventType::EMERGENCY));
|
|
|
|
Event event;
|
|
ASSERT_TRUE(bus.pop(event));
|
|
EXPECT_EQ(event.type, EventType::PAUSE);
|
|
|
|
ASSERT_TRUE(bus.pop(event));
|
|
EXPECT_EQ(event.type, EventType::EMERGENCY);
|
|
}
|
|
|
|
TEST(EventBusTest, StopUnblocksPop)
|
|
{
|
|
EventBus bus;
|
|
Event event;
|
|
|
|
std::thread stopper([&bus] { bus.stop(); });
|
|
EXPECT_FALSE(bus.pop(event));
|
|
stopper.join();
|
|
}
|
|
|
|
TEST(EventBusTest, ResetDropsPendingEventsAndEmergencyFlag)
|
|
{
|
|
EventBus bus;
|
|
|
|
bus.push(makeEvent(EventType::PAUSE));
|
|
bus.pushEmergency(makeEvent(EventType::EMERGENCY));
|
|
|
|
bus.reset();
|
|
|
|
EXPECT_TRUE(bus.empty());
|
|
EXPECT_FALSE(bus.emergencyPending());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|