blob: 9aae936806d24ccf404ea38e6a2ff535d937a380 [file] [log] [blame]
James Kuszmaul38735e82019-12-07 16:42:06 -08001#include "aos/events/logging/logger.h"
Austin Schuhe309d2a2019-11-29 13:25:21 -08002
3#include "aos/events/event_loop.h"
4#include "aos/events/ping_lib.h"
5#include "aos/events/pong_lib.h"
6#include "aos/events/simulated_event_loop.h"
7#include "glog/logging.h"
8#include "gtest/gtest.h"
9
10namespace aos {
11namespace logger {
12namespace testing {
13
14namespace chrono = std::chrono;
15
16class LoggerTest : public ::testing::Test {
17 public:
18 LoggerTest()
19 : config_(
20 aos::configuration::ReadConfig("aos/events/pingpong_config.json")),
21 event_loop_factory_(&config_.message()),
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080022 ping_event_loop_(event_loop_factory_.MakeEventLoop("ping")),
Austin Schuhe309d2a2019-11-29 13:25:21 -080023 ping_(ping_event_loop_.get()),
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080024 pong_event_loop_(event_loop_factory_.MakeEventLoop("pong")),
Austin Schuhe309d2a2019-11-29 13:25:21 -080025 pong_(pong_event_loop_.get()) {}
26
27 // Config and factory.
28 aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
29 SimulatedEventLoopFactory event_loop_factory_;
30
31 // Event loop and app for Ping
32 std::unique_ptr<EventLoop> ping_event_loop_;
33 Ping ping_;
34
35 // Event loop and app for Pong
36 std::unique_ptr<EventLoop> pong_event_loop_;
37 Pong pong_;
38};
39
40// Tests that we can startup at all. This confirms that the channels are all in
41// the config.
42TEST_F(LoggerTest, Starts) {
43 const ::std::string tmpdir(getenv("TEST_TMPDIR"));
44 const ::std::string logfile = tmpdir + "/logfile.bfbs";
45 // Remove it.
46 unlink(logfile.c_str());
47
48 LOG(INFO) << "Logging data to " << logfile;
49
50 {
51 DetachedBufferWriter writer(logfile);
52 std::unique_ptr<EventLoop> logger_event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080053 event_loop_factory_.MakeEventLoop("logger");
Austin Schuhe309d2a2019-11-29 13:25:21 -080054
55 event_loop_factory_.RunFor(chrono::milliseconds(95));
56
57 Logger logger(&writer, logger_event_loop.get(),
58 std::chrono::milliseconds(100));
59 event_loop_factory_.RunFor(chrono::milliseconds(20000));
60 }
61
62 LogReader reader(logfile);
63
64 LOG(INFO) << "Config " << FlatbufferToJson(reader.configuration());
65
Austin Schuhe309d2a2019-11-29 13:25:21 -080066 SimulatedEventLoopFactory log_reader_factory(reader.configuration());
Austin Schuhe309d2a2019-11-29 13:25:21 -080067
Austin Schuh92547522019-12-28 14:33:43 -080068 // This sends out the fetched messages and advances time to the start of the log file.
69 reader.Register(&log_reader_factory);
Austin Schuhe309d2a2019-11-29 13:25:21 -080070
Austin Schuhe309d2a2019-11-29 13:25:21 -080071 std::unique_ptr<EventLoop> test_event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080072 log_reader_factory.MakeEventLoop("log_reader");
Austin Schuhe309d2a2019-11-29 13:25:21 -080073
74 int ping_count = 10;
75 int pong_count = 10;
76
77 // Confirm that the ping value matches.
78 test_event_loop->MakeWatcher("/test",
79 [&ping_count](const examples::Ping &ping) {
80 EXPECT_EQ(ping.value(), ping_count + 1);
81 ++ping_count;
82 });
83 // Confirm that the ping and pong counts both match, and the value also
84 // matches.
85 test_event_loop->MakeWatcher(
86 "/test", [&pong_count, &ping_count](const examples::Pong &pong) {
87 EXPECT_EQ(pong.value(), pong_count + 1);
88 ++pong_count;
89 EXPECT_EQ(ping_count, pong_count);
90 });
91
92 log_reader_factory.RunFor(std::chrono::seconds(100));
93 EXPECT_EQ(ping_count, 2010);
94
95 reader.Deregister();
96}
97
Austin Schuh4c4e0092019-12-22 16:18:03 -080098// Tests that a large number of messages per second doesn't overwhelm writev.
99TEST_F(LoggerTest, ManyMessages) {
100 const ::std::string tmpdir(getenv("TEST_TMPDIR"));
101 const ::std::string logfile = tmpdir + "/logfile.bfbs";
102 // Remove the log file.
103 unlink(logfile.c_str());
104
105 LOG(INFO) << "Logging data to " << logfile;
106
107 {
108 DetachedBufferWriter writer(logfile);
109 std::unique_ptr<EventLoop> logger_event_loop =
110 event_loop_factory_.MakeEventLoop("logger");
111
112 std::unique_ptr<EventLoop> ping_spammer_event_loop =
113 event_loop_factory_.MakeEventLoop("ping_spammer");
114 aos::Sender<examples::Ping> ping_sender =
115 ping_spammer_event_loop->MakeSender<examples::Ping>("/test");
116
117 aos::TimerHandler *timer_handler =
118 ping_spammer_event_loop->AddTimer([&ping_sender]() {
119 aos::Sender<examples::Ping>::Builder builder =
120 ping_sender.MakeBuilder();
121 examples::Ping::Builder ping_builder =
122 builder.MakeBuilder<examples::Ping>();
123 CHECK(builder.Send(ping_builder.Finish()));
124 });
125
126 // 100 ms / 0.05 ms -> 2000 messages. Should be enough to crash it.
127 ping_spammer_event_loop->OnRun([&ping_spammer_event_loop, timer_handler]() {
128 timer_handler->Setup(ping_spammer_event_loop->monotonic_now(),
129 chrono::microseconds(50));
130 });
131
132 Logger logger(&writer, logger_event_loop.get(),
133 std::chrono::milliseconds(100));
134
135 event_loop_factory_.RunFor(chrono::milliseconds(1000));
136 }
137}
138
Austin Schuhe309d2a2019-11-29 13:25:21 -0800139} // namespace testing
140} // namespace logger
141} // namespace aos