blob: 0dd0cb34b8385c21be507481bc1f072461be53e4 [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),
19 last_monotonic_(node_count, monotonic_clock::epoch()) {
20 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);
40 last_monotonic_[i] += times[i];
41 }
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(
54 std::vector<monotonic_clock::time_point> times) {
55 CHECK_EQ(times.size(), last_monotonic_.size());
56 chrono::nanoseconds dt(0);
57 if (!first_) {
58 dt = times[0] - last_monotonic_[0];
59 for (size_t i = 0; i < times.size(); ++i) {
60 CHECK_GT(times[i], last_monotonic_[i]);
61 dt = std::max(dt, times[i] - times[0]);
62 }
63 last_distributed_ += dt;
64 last_monotonic_ = times;
65 } else {
66 first_ = false;
67 last_monotonic_ = times;
68 }
69 ts_.emplace_back(std::make_tuple(last_distributed_, std::move(times)));
70 return dt;
71}
72
73void TestingTimeConverter::AddNextTimestamp(
74 distributed_clock::time_point time,
75 std::vector<monotonic_clock::time_point> times) {
76 CHECK_EQ(times.size(), last_monotonic_.size());
77 if (!first_) {
78 CHECK_GT(time, last_distributed_);
79 for (size_t i = 0; i < times.size(); ++i) {
80 CHECK_GT(times[i], last_monotonic_[i]);
81 }
82 } else {
83 first_ = false;
84 }
85 last_distributed_ = time;
86 last_monotonic_ = times;
87
88 ts_.emplace_back(std::make_tuple(time, std::move(times)));
89}
90
91std::optional<std::tuple<distributed_clock::time_point,
92 std::vector<monotonic_clock::time_point>>>
93TestingTimeConverter::NextTimestamp() {
94 CHECK(!first_) << ": Tried to pull a timestamp before one was added. This "
95 "is unlikely to be what you want.";
96 if (ts_.empty()) {
97 return std::nullopt;
98 }
99 auto result = ts_.front();
100 ts_.pop_front();
101 return result;
102}
103
104} // namespace message_bridge
105} // namespace aos