Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 1 | #include "aos/events/event_scheduler.h" |
| 2 | |
| 3 | #include <chrono> |
| 4 | |
| 5 | #include "gtest/gtest.h" |
| 6 | |
| 7 | namespace aos { |
| 8 | |
| 9 | namespace chrono = std::chrono; |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 10 | using aos::logger::BootTimestamp; |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 11 | |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 12 | // Legacy time converter for keeping old tests working. Has numerical precision |
| 13 | // problems. |
| 14 | class SlopeOffsetTimeConverter final : public TimeConverter { |
| 15 | public: |
| 16 | SlopeOffsetTimeConverter(size_t nodes_count) |
| 17 | : distributed_offset_(nodes_count, std::chrono::seconds(0)), |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 18 | 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 Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 24 | |
| 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 Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 35 | size_t node_index, BootTimestamp time) override { |
| 36 | CHECK_EQ(time.boot, 0u); |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 37 | 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 Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 43 | 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 Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 58 | } |
| 59 | |
Austin Schuh | b7c8d2a | 2021-07-19 19:22:12 -0700 | [diff] [blame] | 60 | void ObserveTimePassed(distributed_clock::time_point /*time*/) override {} |
| 61 | |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 62 | 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 Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 67 | std::vector<UUID> uuids_; |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 68 | }; |
| 69 | |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 70 | // Tests that the default parameters (slope of 1, offest of 0) behave as |
| 71 | // an identity. |
| 72 | TEST(EventSchedulerTest, IdentityTimeConversion) { |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 73 | SlopeOffsetTimeConverter time(1); |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 74 | EventScheduler s(0); |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 75 | s.SetTimeConverter(0u, &time); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 76 | EXPECT_EQ(s.FromDistributedClock(distributed_clock::epoch()), |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 77 | BootTimestamp::epoch()); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 78 | |
| 79 | EXPECT_EQ( |
| 80 | s.FromDistributedClock(distributed_clock::epoch() + chrono::seconds(1)), |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 81 | BootTimestamp::epoch() + chrono::seconds(1)); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 82 | |
| 83 | EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch()), |
| 84 | distributed_clock::epoch()); |
| 85 | |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 86 | EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch() + chrono::seconds(1)), |
| 87 | distributed_clock::epoch() + chrono::seconds(1)); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | // Tests that a non-unity slope is computed correctly. |
| 91 | TEST(EventSchedulerTest, DoubleTimeConversion) { |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 92 | SlopeOffsetTimeConverter time(1); |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 93 | EventScheduler s(0); |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 94 | s.SetTimeConverter(0u, &time); |
| 95 | time.SetDistributedOffset(0u, std::chrono::seconds(7), 2.0); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 96 | |
| 97 | EXPECT_EQ(s.FromDistributedClock(distributed_clock::epoch()), |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 98 | BootTimestamp::epoch() + chrono::seconds(7)); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 99 | |
| 100 | EXPECT_EQ( |
| 101 | s.FromDistributedClock(distributed_clock::epoch() + chrono::seconds(1)), |
Austin Schuh | 58646e2 | 2021-08-23 23:51:46 -0700 | [diff] [blame] | 102 | BootTimestamp::epoch() + chrono::seconds(9)); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 103 | |
| 104 | EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch() + chrono::seconds(7)), |
| 105 | distributed_clock::epoch()); |
| 106 | |
Austin Schuh | 87dd383 | 2021-01-01 23:07:31 -0800 | [diff] [blame] | 107 | EXPECT_EQ(s.ToDistributedClock(monotonic_clock::epoch() + chrono::seconds(9)), |
| 108 | distributed_clock::epoch() + chrono::seconds(1)); |
Austin Schuh | be69cf3 | 2020-08-27 11:38:33 -0700 | [diff] [blame] | 109 | } |
| 110 | |
| 111 | } // namespace aos |