blob: 54fb91a41e21a7c01784902b6270479256451db2 [file] [log] [blame]
Austin Schuhbe69cf32020-08-27 11:38:33 -07001#include "aos/events/event_scheduler.h"
2
3#include <chrono>
4
5#include "gtest/gtest.h"
6
7namespace aos {
8
9namespace chrono = std::chrono;
Austin Schuh58646e22021-08-23 23:51:46 -070010using aos::logger::BootTimestamp;
Austin Schuhbe69cf32020-08-27 11:38:33 -070011
Austin Schuh87dd3832021-01-01 23:07:31 -080012// Legacy time converter for keeping old tests working. Has numerical precision
13// problems.
14class SlopeOffsetTimeConverter final : public TimeConverter {
15 public:
16 SlopeOffsetTimeConverter(size_t nodes_count)
17 : distributed_offset_(nodes_count, std::chrono::seconds(0)),
Austin Schuh58646e22021-08-23 23:51:46 -070018 distributed_slope_(nodes_count, 1.0) {
19 uuids_.reserve(nodes_count);
20 while (uuids_.size() < nodes_count) {
21 uuids_.emplace_back(UUID::Random());
22 }
23 }
Austin Schuh87dd3832021-01-01 23:07:31 -080024
25 // Sets the offset between the distributed and monotonic clock.
26 // monotonic = distributed * slope + offset;
27 void SetDistributedOffset(size_t node_index,
28 std::chrono::nanoseconds distributed_offset,
29 double distributed_slope) {
30 distributed_offset_[node_index] = distributed_offset;
31 distributed_slope_[node_index] = distributed_slope;
32 }
33
34 distributed_clock::time_point ToDistributedClock(
Austin Schuh58646e22021-08-23 23:51:46 -070035 size_t node_index, BootTimestamp time) override {
36 CHECK_EQ(time.boot, 0u);
Austin Schuh87dd3832021-01-01 23:07:31 -080037 return distributed_clock::epoch() +
38 std::chrono::duration_cast<std::chrono::nanoseconds>(
39 (time.time_since_epoch() - distributed_offset_[node_index]) /
40 distributed_slope_[node_index]);
41 }
42
Austin Schuh58646e22021-08-23 23:51:46 -070043 BootTimestamp FromDistributedClock(size_t node_index,
44 distributed_clock::time_point time,
45 size_t boot_index) override {
46 CHECK_EQ(boot_index, 0u);
47 return {
48 .boot = 0u,
49 .time = monotonic_clock::epoch() +
50 std::chrono::duration_cast<std::chrono::nanoseconds>(
51 time.time_since_epoch() * distributed_slope_[node_index]) +
52 distributed_offset_[node_index]};
53 }
54
55 UUID boot_uuid(size_t node_index, size_t boot_count) override {
56 CHECK_EQ(boot_count, 0u);
57 return uuids_[node_index];
Austin Schuh87dd3832021-01-01 23:07:31 -080058 }
59
Austin Schuhb7c8d2a2021-07-19 19:22:12 -070060 void ObserveTimePassed(distributed_clock::time_point /*time*/) override {}
61
Austin Schuh87dd3832021-01-01 23:07:31 -080062 private:
63 // Offset to the distributed clock.
64 // distributed = monotonic + offset;
65 std::vector<std::chrono::nanoseconds> distributed_offset_;
66 std::vector<double> distributed_slope_;
Austin Schuh58646e22021-08-23 23:51:46 -070067 std::vector<UUID> uuids_;
Austin Schuh87dd3832021-01-01 23:07:31 -080068};
69
Austin Schuhbe69cf32020-08-27 11:38:33 -070070// Tests that the default parameters (slope of 1, offest of 0) behave as
71// an identity.
72TEST(EventSchedulerTest, IdentityTimeConversion) {
Austin Schuh87dd3832021-01-01 23:07:31 -080073 SlopeOffsetTimeConverter time(1);
Austin Schuh58646e22021-08-23 23:51:46 -070074 EventScheduler s(0);
Austin Schuh87dd3832021-01-01 23:07:31 -080075 s.SetTimeConverter(0u, &time);
Austin Schuhbe69cf32020-08-27 11:38:33 -070076 EXPECT_EQ(s.FromDistributedClock(distributed_clock::epoch()),
Austin Schuh58646e22021-08-23 23:51:46 -070077 BootTimestamp::epoch());
Austin Schuhbe69cf32020-08-27 11:38:33 -070078
79 EXPECT_EQ(
80 s.FromDistributedClock(distributed_clock::epoch() + chrono::seconds(1)),
Austin Schuh58646e22021-08-23 23:51:46 -070081 BootTimestamp::epoch() + chrono::seconds(1));
Austin Schuhbe69cf32020-08-27 11:38:33 -070082
83 EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch()),
84 distributed_clock::epoch());
85
Austin Schuh87dd3832021-01-01 23:07:31 -080086 EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch() + chrono::seconds(1)),
87 distributed_clock::epoch() + chrono::seconds(1));
Austin Schuhbe69cf32020-08-27 11:38:33 -070088}
89
90// Tests that a non-unity slope is computed correctly.
91TEST(EventSchedulerTest, DoubleTimeConversion) {
Austin Schuh87dd3832021-01-01 23:07:31 -080092 SlopeOffsetTimeConverter time(1);
Austin Schuh58646e22021-08-23 23:51:46 -070093 EventScheduler s(0);
Austin Schuh87dd3832021-01-01 23:07:31 -080094 s.SetTimeConverter(0u, &time);
95 time.SetDistributedOffset(0u, std::chrono::seconds(7), 2.0);
Austin Schuhbe69cf32020-08-27 11:38:33 -070096
97 EXPECT_EQ(s.FromDistributedClock(distributed_clock::epoch()),
Austin Schuh58646e22021-08-23 23:51:46 -070098 BootTimestamp::epoch() + chrono::seconds(7));
Austin Schuhbe69cf32020-08-27 11:38:33 -070099
100 EXPECT_EQ(
101 s.FromDistributedClock(distributed_clock::epoch() + chrono::seconds(1)),
Austin Schuh58646e22021-08-23 23:51:46 -0700102 BootTimestamp::epoch() + chrono::seconds(9));
Austin Schuhbe69cf32020-08-27 11:38:33 -0700103
104 EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch() + chrono::seconds(7)),
105 distributed_clock::epoch());
106
Austin Schuh87dd3832021-01-01 23:07:31 -0800107 EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch() + chrono::seconds(9)),
108 distributed_clock::epoch() + chrono::seconds(1));
Austin Schuhbe69cf32020-08-27 11:38:33 -0700109}
110
111} // namespace aos