blob: 61adbe36725a236cf50ae832b9cebebf222eb542 [file] [log] [blame]
#include "aos/events/shm-event-loop.h"
#include "aos/events/event-loop_param_test.h"
#include "aos/testing/test_shm.h"
#include "gtest/gtest.h"
namespace aos {
namespace testing {
namespace {
namespace chrono = ::std::chrono;
class ShmEventLoopTestFactory : public EventLoopTestFactory {
public:
::std::unique_ptr<EventLoop> Make() override {
return ::std::unique_ptr<EventLoop>(new ShmEventLoop());
}
::std::unique_ptr<EventLoop> MakePrimary() override {
::std::unique_ptr<ShmEventLoop> loop =
::std::unique_ptr<ShmEventLoop>(new ShmEventLoop());
primary_event_loop_ = loop.get();
return ::std::move(loop);
}
void Run() override { CHECK_NOTNULL(primary_event_loop_)->Run(); }
private:
::aos::testing::TestSharedMemory my_shm_;
::aos::ShmEventLoop *primary_event_loop_;
};
INSTANTIATE_TEST_CASE_P(ShmEventLoopTest, AbstractEventLoopTest,
::testing::Values([]() {
return new ShmEventLoopTestFactory();
}));
INSTANTIATE_TEST_CASE_P(ShmEventLoopDeathTest, AbstractEventLoopDeathTest,
::testing::Values([]() {
return new ShmEventLoopTestFactory();
}));
struct TestMessage : public ::aos::Message {
enum { kQueueLength = 100, kHash = 0x696c0cdc };
int msg_value;
void Zero() { msg_value = 0; }
static size_t Size() { return 1 + ::aos::Message::Size(); }
size_t Print(char *buffer, size_t length) const;
TestMessage() { Zero(); }
};
} // namespace
bool IsRealtime() {
int scheduler;
if ((scheduler = sched_getscheduler(0)) == -1) {
PLOG(FATAL, "sched_getscheduler(0) failed\n");
}
LOG(INFO, "scheduler is %d\n", scheduler);
return scheduler == SCHED_FIFO || scheduler == SCHED_RR;
}
// Tests that every handler type is realtime and runs. There are threads
// involved and it's easy to miss one.
TEST(ShmEventLoopTest, AllHandlersAreRealtime) {
ShmEventLoopTestFactory factory;
auto loop = factory.MakePrimary();
auto loop2 = factory.Make();
loop->SetRuntimeRealtimePriority(1);
auto sender = loop2->MakeSender<TestMessage>("/test");
bool did_onrun = false;
bool did_timer = false;
bool did_watcher = false;
auto timer = loop->AddTimer([&did_timer, &loop]() {
EXPECT_TRUE(IsRealtime());
did_timer = true;
loop->Exit();
});
loop->MakeWatcher("/test", [&did_watcher](const TestMessage &) {
EXPECT_TRUE(IsRealtime());
did_watcher = true;
});
loop->OnRun([&loop, &did_onrun, &sender, timer]() {
EXPECT_TRUE(IsRealtime());
did_onrun = true;
timer->Setup(loop->monotonic_now() + chrono::milliseconds(100));
auto msg = sender.MakeMessage();
msg->msg_value = 200;
msg.Send();
});
factory.Run();
EXPECT_TRUE(did_onrun);
EXPECT_TRUE(did_timer);
EXPECT_TRUE(did_watcher);
}
} // namespace testing
} // namespace aos