blob: dafb452d8d27a856c7440822f0b15034348fe7cc [file] [log] [blame]
Austin Schuhc243b422020-10-11 15:35:08 -07001#include "aos/events/logging/logfile_utils.h"
2
Austin Schuhe243aaf2020-10-11 15:46:02 -07003#include <chrono>
4#include <string>
Austin Schuhc243b422020-10-11 15:35:08 -07005
Austin Schuhc41603c2020-10-11 16:17:37 -07006#include "aos/events/logging/logfile_sorting.h"
Austin Schuhc243b422020-10-11 15:35:08 -07007#include "aos/events/logging/test_message_generated.h"
Austin Schuhe243aaf2020-10-11 15:46:02 -07008#include "aos/flatbuffers.h"
Austin Schuhc243b422020-10-11 15:35:08 -07009#include "aos/json_to_flatbuffer.h"
10#include "aos/testing/tmpdir.h"
Austin Schuhe243aaf2020-10-11 15:46:02 -070011#include "gtest/gtest.h"
Austin Schuhc243b422020-10-11 15:35:08 -070012
13namespace aos {
14namespace logger {
15namespace testing {
Austin Schuhe243aaf2020-10-11 15:46:02 -070016namespace chrono = std::chrono;
Austin Schuhc243b422020-10-11 15:35:08 -070017
Austin Schuhe243aaf2020-10-11 15:46:02 -070018// Creates a size prefixed flatbuffer from json.
Austin Schuhc243b422020-10-11 15:35:08 -070019template <typename T>
20SizePrefixedFlatbufferDetachedBuffer<T> JsonToSizedFlatbuffer(
21 const std::string_view data) {
22 flatbuffers::FlatBufferBuilder fbb;
23 fbb.ForceDefaults(true);
24 fbb.FinishSizePrefixed(JsonToFlatbuffer<T>(data, &fbb));
25 return fbb.Release();
26}
27
Austin Schuhe243aaf2020-10-11 15:46:02 -070028// Tests that we can write and read 2 flatbuffers to file.
Austin Schuhc243b422020-10-11 15:35:08 -070029TEST(SpanReaderTest, ReadWrite) {
30 const std::string logfile = aos::testing::TestTmpDir() + "/log.bfbs";
31 unlink(logfile.c_str());
32
33 const aos::SizePrefixedFlatbufferDetachedBuffer<TestMessage> m1 =
34 JsonToSizedFlatbuffer<TestMessage>(
35 R"({ "value": 1 })");
36 const aos::SizePrefixedFlatbufferDetachedBuffer<TestMessage> m2 =
37 JsonToSizedFlatbuffer<TestMessage>(
38 R"({ "value": 2 })");
39
40 {
41 DetachedBufferWriter writer(logfile, std::make_unique<DummyEncoder>());
Austin Schuhadd6eb32020-11-09 21:24:26 -080042 writer.QueueSpan(m1.span());
43 writer.QueueSpan(m2.span());
Austin Schuhc243b422020-10-11 15:35:08 -070044 }
45
46 SpanReader reader(logfile);
47
48 EXPECT_EQ(reader.filename(), logfile);
Austin Schuhadd6eb32020-11-09 21:24:26 -080049 EXPECT_EQ(reader.ReadMessage(), m1.span());
50 EXPECT_EQ(reader.ReadMessage(), m2.span());
Austin Schuhc243b422020-10-11 15:35:08 -070051 EXPECT_EQ(reader.ReadMessage(), absl::Span<const uint8_t>());
52}
53
Austin Schuhe243aaf2020-10-11 15:46:02 -070054// Tests that we can actually parse the resulting messages at a basic level
55// through MessageReader.
56TEST(MessageReaderTest, ReadWrite) {
57 const std::string logfile = aos::testing::TestTmpDir() + "/log.bfbs";
58 unlink(logfile.c_str());
59
60 const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config =
61 JsonToSizedFlatbuffer<LogFileHeader>(
62 R"({ "max_out_of_order_duration": 100000000 })");
63 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m1 =
64 JsonToSizedFlatbuffer<MessageHeader>(
65 R"({ "channel_index": 0, "monotonic_sent_time": 1 })");
66 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m2 =
67 JsonToSizedFlatbuffer<MessageHeader>(
68 R"({ "channel_index": 0, "monotonic_sent_time": 2 })");
69
70 {
71 DetachedBufferWriter writer(logfile, std::make_unique<DummyEncoder>());
Austin Schuhadd6eb32020-11-09 21:24:26 -080072 writer.QueueSpan(config.span());
73 writer.QueueSpan(m1.span());
74 writer.QueueSpan(m2.span());
Austin Schuhe243aaf2020-10-11 15:46:02 -070075 }
76
77 MessageReader reader(logfile);
78
79 EXPECT_EQ(reader.filename(), logfile);
80
81 EXPECT_EQ(
82 reader.max_out_of_order_duration(),
83 std::chrono::nanoseconds(config.message().max_out_of_order_duration()));
84 EXPECT_EQ(reader.newest_timestamp(), monotonic_clock::min_time);
85 EXPECT_TRUE(reader.ReadMessage());
86 EXPECT_EQ(reader.newest_timestamp(),
87 monotonic_clock::time_point(chrono::nanoseconds(1)));
88 EXPECT_TRUE(reader.ReadMessage());
89 EXPECT_EQ(reader.newest_timestamp(),
90 monotonic_clock::time_point(chrono::nanoseconds(2)));
91 EXPECT_FALSE(reader.ReadMessage());
92}
93
Austin Schuh32f68492020-11-08 21:45:51 -080094// Tests that we explode when messages are too far out of order.
95TEST(PartsMessageReaderDeathTest, TooFarOutOfOrder) {
96 const std::string logfile0 = aos::testing::TestTmpDir() + "/log0.bfbs";
97 unlink(logfile0.c_str());
98
99 const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config0 =
100 JsonToSizedFlatbuffer<LogFileHeader>(
101 R"({
102 "max_out_of_order_duration": 100000000,
103 "log_event_uuid": "30ef1283-81d7-4004-8c36-1c162dbcb2b2",
104 "parts_uuid": "2a05d725-5d5c-4c0b-af42-88de2f3c3876",
105 "parts_index": 0
106})");
107
108 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m1 =
109 JsonToSizedFlatbuffer<MessageHeader>(
110 R"({ "channel_index": 0, "monotonic_sent_time": 100000000 })");
111 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m2 =
112 JsonToSizedFlatbuffer<MessageHeader>(
113 R"({ "channel_index": 0, "monotonic_sent_time": 0 })");
114 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m3 =
115 JsonToSizedFlatbuffer<MessageHeader>(
116 R"({ "channel_index": 0, "monotonic_sent_time": -1 })");
117
118 {
119 DetachedBufferWriter writer(logfile0, std::make_unique<DummyEncoder>());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800120 writer.QueueSpan(config0.span());
121 writer.QueueSpan(m1.span());
122 writer.QueueSpan(m2.span());
123 writer.QueueSpan(m3.span());
Austin Schuh32f68492020-11-08 21:45:51 -0800124 }
125
126 const std::vector<LogFile> parts = SortParts({logfile0});
127
128 PartsMessageReader reader(parts[0].parts[0]);
129
130 EXPECT_TRUE(reader.ReadMessage());
131 EXPECT_TRUE(reader.ReadMessage());
132 EXPECT_DEATH({ reader.ReadMessage(); }, "-0.000000001sec vs. 0.000000000sec");
133}
134
Austin Schuhc41603c2020-10-11 16:17:37 -0700135// Tests that we can transparently re-assemble part files with a
136// PartsMessageReader.
137TEST(PartsMessageReaderTest, ReadWrite) {
138 const std::string logfile0 = aos::testing::TestTmpDir() + "/log0.bfbs";
139 const std::string logfile1 = aos::testing::TestTmpDir() + "/log1.bfbs";
140 unlink(logfile0.c_str());
141 unlink(logfile1.c_str());
142
143 const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config0 =
144 JsonToSizedFlatbuffer<LogFileHeader>(
145 R"({
146 "max_out_of_order_duration": 100000000,
147 "log_event_uuid": "30ef1283-81d7-4004-8c36-1c162dbcb2b2",
148 "parts_uuid": "2a05d725-5d5c-4c0b-af42-88de2f3c3876",
149 "parts_index": 0
150})");
151 const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config1 =
152 JsonToSizedFlatbuffer<LogFileHeader>(
153 R"({
154 "max_out_of_order_duration": 200000000,
155 "monotonic_start_time": 0,
156 "realtime_start_time": 0,
157 "log_event_uuid": "30ef1283-81d7-4004-8c36-1c162dbcb2b2",
158 "parts_uuid": "2a05d725-5d5c-4c0b-af42-88de2f3c3876",
159 "parts_index": 1
160})");
161
162 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m1 =
163 JsonToSizedFlatbuffer<MessageHeader>(
164 R"({ "channel_index": 0, "monotonic_sent_time": 1 })");
165 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m2 =
166 JsonToSizedFlatbuffer<MessageHeader>(
167 R"({ "channel_index": 0, "monotonic_sent_time": 2 })");
168
169 {
170 DetachedBufferWriter writer(logfile0, std::make_unique<DummyEncoder>());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800171 writer.QueueSpan(config0.span());
172 writer.QueueSpan(m1.span());
Austin Schuhc41603c2020-10-11 16:17:37 -0700173 }
174 {
175 DetachedBufferWriter writer(logfile1, std::make_unique<DummyEncoder>());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800176 writer.QueueSpan(config1.span());
177 writer.QueueSpan(m2.span());
Austin Schuhc41603c2020-10-11 16:17:37 -0700178 }
179
180 const std::vector<LogFile> parts = SortParts({logfile0, logfile1});
181
182 PartsMessageReader reader(parts[0].parts[0]);
183
184 EXPECT_EQ(reader.filename(), logfile0);
185
186 // Confirm that the timestamps track, and the filename also updates.
187 // Read the first message.
188 EXPECT_EQ(reader.newest_timestamp(), monotonic_clock::min_time);
189 EXPECT_EQ(
190 reader.max_out_of_order_duration(),
191 std::chrono::nanoseconds(config0.message().max_out_of_order_duration()));
192 EXPECT_TRUE(reader.ReadMessage());
193 EXPECT_EQ(reader.filename(), logfile0);
194 EXPECT_EQ(reader.newest_timestamp(),
195 monotonic_clock::time_point(chrono::nanoseconds(1)));
196 EXPECT_EQ(
197 reader.max_out_of_order_duration(),
198 std::chrono::nanoseconds(config0.message().max_out_of_order_duration()));
199
200 // Read the second message.
201 EXPECT_TRUE(reader.ReadMessage());
202 EXPECT_EQ(reader.filename(), logfile1);
203 EXPECT_EQ(reader.newest_timestamp(),
204 monotonic_clock::time_point(chrono::nanoseconds(2)));
205 EXPECT_EQ(
206 reader.max_out_of_order_duration(),
207 std::chrono::nanoseconds(config1.message().max_out_of_order_duration()));
208
209 // And then confirm that reading again returns no message.
210 EXPECT_FALSE(reader.ReadMessage());
211 EXPECT_EQ(reader.filename(), logfile1);
212 EXPECT_EQ(
213 reader.max_out_of_order_duration(),
214 std::chrono::nanoseconds(config1.message().max_out_of_order_duration()));
Austin Schuh32f68492020-11-08 21:45:51 -0800215 EXPECT_EQ(reader.newest_timestamp(), monotonic_clock::max_time);
Austin Schuhc41603c2020-10-11 16:17:37 -0700216}
Austin Schuh32f68492020-11-08 21:45:51 -0800217
Austin Schuh1be0ce42020-11-29 22:43:26 -0800218// Tests that Message's operator < works as expected.
219TEST(MessageTest, Sorting) {
220 const aos::monotonic_clock::time_point e = monotonic_clock::epoch();
221
222 Message m1{.channel_index = 0,
223 .queue_index = 0,
224 .timestamp = e + chrono::milliseconds(1),
225 .data = SizePrefixedFlatbufferVector<MessageHeader>::Empty()};
226 Message m2{.channel_index = 0,
227 .queue_index = 0,
228 .timestamp = e + chrono::milliseconds(2),
229 .data = SizePrefixedFlatbufferVector<MessageHeader>::Empty()};
230
231 EXPECT_LT(m1, m2);
232 EXPECT_GE(m2, m1);
233
234 m1.timestamp = e;
235 m2.timestamp = e;
236
237 m1.channel_index = 1;
238 m2.channel_index = 2;
239
240 EXPECT_LT(m1, m2);
241 EXPECT_GE(m2, m1);
242
243 m1.channel_index = 0;
244 m2.channel_index = 0;
245 m1.queue_index = 0;
246 m2.queue_index = 1;
247
248 EXPECT_LT(m1, m2);
249 EXPECT_GE(m2, m1);
250}
251
Austin Schuhc243b422020-10-11 15:35:08 -0700252} // namespace testing
253} // namespace logger
254} // namespace aos