blob: c175fe686bd1693a799c7c62d5bc282fc3786282 [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_) {
25 CHECK(!NextTimestamp()) << ": At the end but there is more data.";
26 }
27}
28
29void TestingTimeConverter::StartEqual() {
30 CHECK(first_);
31 first_ = false;
32 ts_.emplace_back(std::make_tuple(last_distributed_, last_monotonic_));
33}
34
35chrono::nanoseconds TestingTimeConverter::AddMonotonic(
36 std::vector<monotonic_clock::duration> times) {
37 CHECK_EQ(times.size(), last_monotonic_.size());
38 for (size_t i = 0; i < times.size(); ++i) {
39 CHECK_GT(times[i].count(), 0);
Austin Schuh66168842021-08-17 19:42:21 -070040 last_monotonic_[i].time += times[i];
Austin Schuha9abc032021-01-01 16:46:19 -080041 }
42 chrono::nanoseconds dt(0);
43 if (!first_) {
44 dt = *std::max_element(times.begin(), times.end());
45 last_distributed_ += dt;
46 } else {
47 first_ = false;
48 }
49 ts_.emplace_back(std::make_tuple(last_distributed_, last_monotonic_));
50 return dt;
51}
52
53chrono::nanoseconds TestingTimeConverter::AddMonotonic(
Austin Schuh66168842021-08-17 19:42:21 -070054 std::vector<logger::BootTimestamp> times) {
Austin Schuha9abc032021-01-01 16:46:19 -080055 CHECK_EQ(times.size(), last_monotonic_.size());
56 chrono::nanoseconds dt(0);
57 if (!first_) {
Austin Schuh66168842021-08-17 19:42:21 -070058 CHECK_EQ(times[0].boot, last_monotonic_[0].boot);
59 dt = times[0].time - last_monotonic_[0].time;
Austin Schuha9abc032021-01-01 16:46:19 -080060 for (size_t i = 0; i < times.size(); ++i) {
61 CHECK_GT(times[i], last_monotonic_[i]);
Austin Schuh66168842021-08-17 19:42:21 -070062 dt = std::max(dt, times[i].time - times[0].time);
Austin Schuha9abc032021-01-01 16:46:19 -080063 }
64 last_distributed_ += dt;
65 last_monotonic_ = times;
66 } else {
67 first_ = false;
68 last_monotonic_ = times;
69 }
70 ts_.emplace_back(std::make_tuple(last_distributed_, std::move(times)));
71 return dt;
72}
73
Austin Schuh58646e22021-08-23 23:51:46 -070074void TestingTimeConverter::RebootAt(size_t node_index,
75 distributed_clock::time_point t) {
76 CHECK(!first_);
77 const chrono::nanoseconds dt = t - last_distributed_;
78
79 for (size_t i = 0; i < last_monotonic_.size(); ++i) {
80 last_monotonic_[i].time += dt;
81 }
82
83 ++last_monotonic_[node_index].boot;
84 last_monotonic_[node_index].time = monotonic_clock::epoch();
85
86 last_distributed_ = t;
87 ts_.emplace_back(std::make_tuple(last_distributed_, last_monotonic_));
88}
89
Austin Schuha9abc032021-01-01 16:46:19 -080090void TestingTimeConverter::AddNextTimestamp(
91 distributed_clock::time_point time,
Austin Schuh66168842021-08-17 19:42:21 -070092 std::vector<logger::BootTimestamp> times) {
Austin Schuha9abc032021-01-01 16:46:19 -080093 CHECK_EQ(times.size(), last_monotonic_.size());
94 if (!first_) {
95 CHECK_GT(time, last_distributed_);
96 for (size_t i = 0; i < times.size(); ++i) {
97 CHECK_GT(times[i], last_monotonic_[i]);
98 }
99 } else {
100 first_ = false;
101 }
102 last_distributed_ = time;
103 last_monotonic_ = times;
104
105 ts_.emplace_back(std::make_tuple(time, std::move(times)));
106}
107
108std::optional<std::tuple<distributed_clock::time_point,
Austin Schuh66168842021-08-17 19:42:21 -0700109 std::vector<logger::BootTimestamp>>>
Austin Schuha9abc032021-01-01 16:46:19 -0800110TestingTimeConverter::NextTimestamp() {
111 CHECK(!first_) << ": Tried to pull a timestamp before one was added. This "
112 "is unlikely to be what you want.";
113 if (ts_.empty()) {
114 return std::nullopt;
115 }
116 auto result = ts_.front();
117 ts_.pop_front();
118 return result;
119}
120
121} // namespace message_bridge
122} // namespace aos