blob: 57d1d9da302f447cbf27b4f930d1a060862409a9 [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>());
42 writer.QueueSpan(m1.full_span());
43 writer.QueueSpan(m2.full_span());
44 }
45
46 SpanReader reader(logfile);
47
48 EXPECT_EQ(reader.filename(), logfile);
49 EXPECT_EQ(reader.ReadMessage(), m1.full_span());
50 EXPECT_EQ(reader.ReadMessage(), m2.full_span());
51 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>());
72 writer.QueueSpan(config.full_span());
73 writer.QueueSpan(m1.full_span());
74 writer.QueueSpan(m2.full_span());
75 }
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 Schuhc41603c2020-10-11 16:17:37 -070094// Tests that we can transparently re-assemble part files with a
95// PartsMessageReader.
96TEST(PartsMessageReaderTest, ReadWrite) {
97 const std::string logfile0 = aos::testing::TestTmpDir() + "/log0.bfbs";
98 const std::string logfile1 = aos::testing::TestTmpDir() + "/log1.bfbs";
99 unlink(logfile0.c_str());
100 unlink(logfile1.c_str());
101
102 const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config0 =
103 JsonToSizedFlatbuffer<LogFileHeader>(
104 R"({
105 "max_out_of_order_duration": 100000000,
106 "log_event_uuid": "30ef1283-81d7-4004-8c36-1c162dbcb2b2",
107 "parts_uuid": "2a05d725-5d5c-4c0b-af42-88de2f3c3876",
108 "parts_index": 0
109})");
110 const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config1 =
111 JsonToSizedFlatbuffer<LogFileHeader>(
112 R"({
113 "max_out_of_order_duration": 200000000,
114 "monotonic_start_time": 0,
115 "realtime_start_time": 0,
116 "log_event_uuid": "30ef1283-81d7-4004-8c36-1c162dbcb2b2",
117 "parts_uuid": "2a05d725-5d5c-4c0b-af42-88de2f3c3876",
118 "parts_index": 1
119})");
120
121 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m1 =
122 JsonToSizedFlatbuffer<MessageHeader>(
123 R"({ "channel_index": 0, "monotonic_sent_time": 1 })");
124 const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m2 =
125 JsonToSizedFlatbuffer<MessageHeader>(
126 R"({ "channel_index": 0, "monotonic_sent_time": 2 })");
127
128 {
129 DetachedBufferWriter writer(logfile0, std::make_unique<DummyEncoder>());
130 writer.QueueSpan(config0.full_span());
131 writer.QueueSpan(m1.full_span());
132 }
133 {
134 DetachedBufferWriter writer(logfile1, std::make_unique<DummyEncoder>());
135 writer.QueueSpan(config1.full_span());
136 writer.QueueSpan(m2.full_span());
137 }
138
139 const std::vector<LogFile> parts = SortParts({logfile0, logfile1});
140
141 PartsMessageReader reader(parts[0].parts[0]);
142
143 EXPECT_EQ(reader.filename(), logfile0);
144
145 // Confirm that the timestamps track, and the filename also updates.
146 // Read the first message.
147 EXPECT_EQ(reader.newest_timestamp(), monotonic_clock::min_time);
148 EXPECT_EQ(
149 reader.max_out_of_order_duration(),
150 std::chrono::nanoseconds(config0.message().max_out_of_order_duration()));
151 EXPECT_TRUE(reader.ReadMessage());
152 EXPECT_EQ(reader.filename(), logfile0);
153 EXPECT_EQ(reader.newest_timestamp(),
154 monotonic_clock::time_point(chrono::nanoseconds(1)));
155 EXPECT_EQ(
156 reader.max_out_of_order_duration(),
157 std::chrono::nanoseconds(config0.message().max_out_of_order_duration()));
158
159 // Read the second message.
160 EXPECT_TRUE(reader.ReadMessage());
161 EXPECT_EQ(reader.filename(), logfile1);
162 EXPECT_EQ(reader.newest_timestamp(),
163 monotonic_clock::time_point(chrono::nanoseconds(2)));
164 EXPECT_EQ(
165 reader.max_out_of_order_duration(),
166 std::chrono::nanoseconds(config1.message().max_out_of_order_duration()));
167
168 // And then confirm that reading again returns no message.
169 EXPECT_FALSE(reader.ReadMessage());
170 EXPECT_EQ(reader.filename(), logfile1);
171 EXPECT_EQ(
172 reader.max_out_of_order_duration(),
173 std::chrono::nanoseconds(config1.message().max_out_of_order_duration()));
174}
Austin Schuhc243b422020-10-11 15:35:08 -0700175} // namespace testing
176} // namespace logger
177} // namespace aos