blob: 9dc5fffc883eadd9fa782b317e07a3196bec44f5 [file] [log] [blame]
Austin Schuha9abc032021-01-01 16:46:19 -08001#include "aos/network/testing_time_converter.h"
2
3#include <chrono>
4#include <deque>
5#include <optional>
6#include <tuple>
7
8#include "aos/events/event_scheduler.h"
9#include "aos/network/multinode_timestamp_filter.h"
10#include "aos/time/time.h"
11
12namespace aos {
13namespace message_bridge {
14
15namespace chrono = std::chrono;
16
17TestingTimeConverter ::TestingTimeConverter(size_t node_count)
18 : InterpolatedTimeConverter(node_count),
Austin Schuh66168842021-08-17 19:42:21 -070019 last_monotonic_(node_count, logger::BootTimestamp::epoch()) {
Austin Schuha9abc032021-01-01 16:46:19 -080020 CHECK_GE(node_count, 1u);
21}
22
23TestingTimeConverter::~TestingTimeConverter() {
24 if (at_end_) {
James Kuszmaulbeaa3c82023-09-07 11:11:27 -070025 auto next_timestamp = NextTimestamp();
26 CHECK(next_timestamp.has_value()) << ": Unexpected error";
27 CHECK(!next_timestamp.value().has_value())
28 << ": At the end but there is more data.";
Austin Schuha9abc032021-01-01 16:46:19 -080029 }
30}
31
32void TestingTimeConverter::StartEqual() {
33 CHECK(first_);
34 first_ = false;
35 ts_.emplace_back(std::make_tuple(last_distributed_, last_monotonic_));
36}
37
38chrono::nanoseconds TestingTimeConverter::AddMonotonic(
39 std::vector<monotonic_clock::duration> times) {
40 CHECK_EQ(times.size(), last_monotonic_.size());
41 for (size_t i = 0; i < times.size(); ++i) {
42 CHECK_GT(times[i].count(), 0);
Austin Schuh66168842021-08-17 19:42:21 -070043 last_monotonic_[i].time += times[i];
Austin Schuha9abc032021-01-01 16:46:19 -080044 }
45 chrono::nanoseconds dt(0);
46 if (!first_) {
47 dt = *std::max_element(times.begin(), times.end());
48 last_distributed_ += dt;
49 } else {
50 first_ = false;
51 }
52 ts_.emplace_back(std::make_tuple(last_distributed_, last_monotonic_));
53 return dt;
54}
55
56chrono::nanoseconds TestingTimeConverter::AddMonotonic(
Austin Schuh66168842021-08-17 19:42:21 -070057 std::vector<logger::BootTimestamp> times) {
Austin Schuha9abc032021-01-01 16:46:19 -080058 CHECK_EQ(times.size(), last_monotonic_.size());
59 chrono::nanoseconds dt(0);
60 if (!first_) {
Austin Schuh66168842021-08-17 19:42:21 -070061 CHECK_EQ(times[0].boot, last_monotonic_[0].boot);
62 dt = times[0].time - last_monotonic_[0].time;
Austin Schuha9abc032021-01-01 16:46:19 -080063 for (size_t i = 0; i < times.size(); ++i) {
64 CHECK_GT(times[i], last_monotonic_[i]);
Austin Schuh66168842021-08-17 19:42:21 -070065 dt = std::max(dt, times[i].time - times[0].time);
Austin Schuha9abc032021-01-01 16:46:19 -080066 }
67 last_distributed_ += dt;
68 last_monotonic_ = times;
69 } else {
70 first_ = false;
71 last_monotonic_ = times;
72 }
73 ts_.emplace_back(std::make_tuple(last_distributed_, std::move(times)));
74 return dt;
75}
76
Austin Schuh58646e22021-08-23 23:51:46 -070077void TestingTimeConverter::RebootAt(size_t node_index,
78 distributed_clock::time_point t) {
79 CHECK(!first_);
80 const chrono::nanoseconds dt = t - last_distributed_;
81
82 for (size_t i = 0; i < last_monotonic_.size(); ++i) {
83 last_monotonic_[i].time += dt;
84 }
85
86 ++last_monotonic_[node_index].boot;
87 last_monotonic_[node_index].time = monotonic_clock::epoch();
88
89 last_distributed_ = t;
90 ts_.emplace_back(std::make_tuple(last_distributed_, last_monotonic_));
91}
92
Austin Schuha9abc032021-01-01 16:46:19 -080093void TestingTimeConverter::AddNextTimestamp(
94 distributed_clock::time_point time,
Austin Schuh66168842021-08-17 19:42:21 -070095 std::vector<logger::BootTimestamp> times) {
Austin Schuha9abc032021-01-01 16:46:19 -080096 CHECK_EQ(times.size(), last_monotonic_.size());
97 if (!first_) {
98 CHECK_GT(time, last_distributed_);
99 for (size_t i = 0; i < times.size(); ++i) {
100 CHECK_GT(times[i], last_monotonic_[i]);
101 }
102 } else {
103 first_ = false;
104 }
105 last_distributed_ = time;
106 last_monotonic_ = times;
107
108 ts_.emplace_back(std::make_tuple(time, std::move(times)));
109}
110
James Kuszmaulbeaa3c82023-09-07 11:11:27 -0700111std::optional<std::optional<std::tuple<distributed_clock::time_point,
112 std::vector<logger::BootTimestamp>>>>
Austin Schuha9abc032021-01-01 16:46:19 -0800113TestingTimeConverter::NextTimestamp() {
114 CHECK(!first_) << ": Tried to pull a timestamp before one was added. This "
115 "is unlikely to be what you want.";
116 if (ts_.empty()) {
James Kuszmaulbeaa3c82023-09-07 11:11:27 -0700117 std::optional<std::optional<std::tuple<distributed_clock::time_point,
118 std::vector<logger::BootTimestamp>>>>
119 result;
120 result.emplace(std::nullopt);
121 return result;
Austin Schuha9abc032021-01-01 16:46:19 -0800122 }
123 auto result = ts_.front();
124 ts_.pop_front();
125 return result;
126}
127
128} // namespace message_bridge
129} // namespace aos