From 2680577b9e3b77250c0c6496335fdb7473b456d4 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Fri, 17 May 2019 17:16:05 -0400 Subject: [PATCH 1/4] implement with TimeSource Signed-off-by: Dan Zhang --- .../quiche/platform/envoy_quic_clock.cc | 21 ++++++++++++++ .../quiche/platform/envoy_quic_clock.h | 29 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc create mode 100644 source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc new file mode 100644 index 0000000000000..9ccb325a9911d --- /dev/null +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc @@ -0,0 +1,21 @@ +#include "extensions/quic_listeners/quiche/platform/envoy_quic_clock.h" + +namespace Envoy { +namespace Quic { + +quic::QuicTime EnvoyQuicClock::ApproximateNow() const { + // This might be expensive as Dispatcher doesn't store approximate time_point. + return Now(); +} + +quic::QuicTime EnvoyQuicClock::Now() const { + return quic::QuicTime::Zero() + + quic::QuicTime::Delta::FromMicroseconds(timePointToInt64(time_source_.monotonicTime()); +} + +quic::QuicWallTime EnvoyQuicClock::WallNow() const { + return quic::QuicWallTime::FromUNIXMicroseconds(timePointToInt64(time_source_.systemTime())); +} + +} // namespace Quic +} // namespace Envoy diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h new file mode 100644 index 0000000000000..1f105ceb39e17 --- /dev/null +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "envoy/common/time.h" +#include "quiche/quic/platform/api/quic_clock.h" + +namespace Envoy { +namespace Quic { + +class EnvoyQuicClock : public quic::QuicClock { +public: + EnvoyQuicClock(TimesSource& time_source) : time_source_(time_source), quic::QuicClock() {} + + // quic::QuicClock + quic::QuicTime ApproximateNow() const; + quic::QuicTime Now() const; + quic::QuicWallTime WallNow() const; + +private: + template int64_t timePointToInt64(std::chrono::time_point time) { + return std::chrono::duration_cast(time.time_since_epoch()).count(); + } + + TimesSource& time_source_; +}; + +} // namespace Quic +} // namespace Envoy From 17802f8055ab33809d74a7de5ffe818dc5f9bc0f Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Tue, 21 May 2019 16:54:28 -0400 Subject: [PATCH 2/4] add test Signed-off-by: Dan Zhang --- .../quic_listeners/quiche/platform/BUILD | 11 ++++ .../quiche/platform/envoy_quic_clock.cc | 6 +-- .../quiche/platform/envoy_quic_clock.h | 15 +++--- .../quic_listeners/quiche/platform/BUILD | 10 ++++ .../quiche/platform/envoy_quic_clock_test.cc | 54 +++++++++++++++++++ 5 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc diff --git a/source/extensions/quic_listeners/quiche/platform/BUILD b/source/extensions/quic_listeners/quiche/platform/BUILD index 31fc97de3bb0a..c55ba02a10776 100644 --- a/source/extensions/quic_listeners/quiche/platform/BUILD +++ b/source/extensions/quic_listeners/quiche/platform/BUILD @@ -171,6 +171,17 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "envoy_quic_clock_lib", + srcs = ["envoy_quic_clock.cc"], + hdrs = ["envoy_quic_clock.h"], + visibility = ["//visibility:public"], + deps = [ + "//include/envoy/event:timer_interface", + "@com_googlesource_quiche//:quic_platform", + ], +) + envoy_cc_library( name = "spdy_platform_impl_lib", hdrs = [ diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc index 9ccb325a9911d..455011f7e1e80 100644 --- a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc @@ -9,12 +9,12 @@ quic::QuicTime EnvoyQuicClock::ApproximateNow() const { } quic::QuicTime EnvoyQuicClock::Now() const { - return quic::QuicTime::Zero() + - quic::QuicTime::Delta::FromMicroseconds(timePointToInt64(time_source_.monotonicTime()); + return quic::QuicTime::Zero() + + quic::QuicTime::Delta::FromMicroseconds(timePointToInt64(time_system_.monotonicTime())); } quic::QuicWallTime EnvoyQuicClock::WallNow() const { - return quic::QuicWallTime::FromUNIXMicroseconds(timePointToInt64(time_source_.systemTime())); + return quic::QuicWallTime::FromUNIXMicroseconds(timePointToInt64(time_system_.systemTime())); } } // namespace Quic diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h index 1f105ceb39e17..d774c2e3bb385 100644 --- a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h @@ -2,7 +2,8 @@ #include -#include "envoy/common/time.h" +#include "envoy/event/timer.h" + #include "quiche/quic/platform/api/quic_clock.h" namespace Envoy { @@ -10,19 +11,19 @@ namespace Quic { class EnvoyQuicClock : public quic::QuicClock { public: - EnvoyQuicClock(TimesSource& time_source) : time_source_(time_source), quic::QuicClock() {} + EnvoyQuicClock(Event::TimeSystem& time_system) : quic::QuicClock(), time_system_(time_system) {} // quic::QuicClock - quic::QuicTime ApproximateNow() const; - quic::QuicTime Now() const; - quic::QuicWallTime WallNow() const; + quic::QuicTime ApproximateNow() const override; + quic::QuicTime Now() const override; + quic::QuicWallTime WallNow() const override; private: - template int64_t timePointToInt64(std::chrono::time_point time) { + template int64_t timePointToInt64(std::chrono::time_point time) const { return std::chrono::duration_cast(time.time_since_epoch()).count(); } - TimesSource& time_source_; + Event::TimeSystem& time_system_; }; } // namespace Quic diff --git a/test/extensions/quic_listeners/quiche/platform/BUILD b/test/extensions/quic_listeners/quiche/platform/BUILD index 3b78527b46915..1320d2556d1ce 100644 --- a/test/extensions/quic_listeners/quiche/platform/BUILD +++ b/test/extensions/quic_listeners/quiche/platform/BUILD @@ -179,3 +179,13 @@ envoy_cc_test_library( ":quic_platform_expect_bug_impl_lib", ], ) + +envoy_cc_test( + name = "envoy_quic_clock_test", + srcs = ["envoy_quic_clock_test.cc"], + deps = [ + "//source/extensions/quic_listeners/quiche/platform:envoy_quic_clock_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_time_lib", + ], +) diff --git a/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc b/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc new file mode 100644 index 0000000000000..191e491e22615 --- /dev/null +++ b/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc @@ -0,0 +1,54 @@ +#include + +#include "extensions/quic_listeners/quiche/platform/envoy_quic_clock.h" + +#include "test/test_common/simulated_time_system.h" +#include "test/test_common/test_time.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace Envoy { +namespace Quic { + +TEST(EnvoyQuicClockTest, TestNow) { + Event::SimulatedTimeSystemHelper time_system; + EnvoyQuicClock clock(time_system); + uint64_t mono_time = std::chrono::duration_cast( + time_system.monotonicTime().time_since_epoch()) + .count(); + uint64_t sys_time = std::chrono::duration_cast( + time_system.systemTime().time_since_epoch()) + .count(); + // Advance time by 1000000us. + time_system.sleep(std::chrono::microseconds(1000000)); + EXPECT_EQ(mono_time + 1000000, (clock.Now() - quic::QuicTime::Zero()).ToMicroseconds()); + EXPECT_EQ(sys_time + 1000000, clock.WallNow().ToUNIXMicroseconds()); + + // Advance time by 10us. + time_system.sleep(std::chrono::microseconds(10)); + EXPECT_EQ(mono_time + 1000000 + 10, (clock.Now() - quic::QuicTime::Zero()).ToMicroseconds()); + EXPECT_EQ(sys_time + 1000000 + 10, clock.WallNow().ToUNIXMicroseconds()); + EXPECT_EQ(clock.ApproximateNow(), clock.Now()); + + // Advance time by 2ms. + time_system.sleep(std::chrono::milliseconds(2)); + EXPECT_EQ(mono_time + 1000000 + 10 + 2 * 1000, + (clock.Now() - quic::QuicTime::Zero()).ToMicroseconds()); + EXPECT_EQ(sys_time + 1000000 + 10 + 2 * 1000, clock.WallNow().ToUNIXMicroseconds()); +} + +// Tests that Now() should never go back. +TEST(EnvoyQuicClockTest, TestMonotonicityWithReadTimeSystem) { + Event::TestRealTimeSystem time_system; + EnvoyQuicClock clock(time_system); + quic::QuicTime last_now = clock.Now(); + for (int i = 0; i < 1e5; ++i) { + quic::QuicTime now = clock.Now(); + ASSERT_LE(last_now, now); + last_now = now; + } +} + +} // namespace Quic +} // namespace Envoy From d6af84a47c8dde0c1d9016d0d024ba40a159df15 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Wed, 22 May 2019 12:11:06 -0400 Subject: [PATCH 3/4] rename microsecondsSinceEpoch Signed-off-by: Dan Zhang --- .../quic_listeners/quiche/platform/envoy_quic_clock.cc | 7 ++++--- .../quic_listeners/quiche/platform/envoy_quic_clock.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc index 455011f7e1e80..b582956751da4 100644 --- a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.cc @@ -9,12 +9,13 @@ quic::QuicTime EnvoyQuicClock::ApproximateNow() const { } quic::QuicTime EnvoyQuicClock::Now() const { - return quic::QuicTime::Zero() + - quic::QuicTime::Delta::FromMicroseconds(timePointToInt64(time_system_.monotonicTime())); + return quic::QuicTime::Zero() + quic::QuicTime::Delta::FromMicroseconds( + microsecondsSinceEpoch(time_system_.monotonicTime())); } quic::QuicWallTime EnvoyQuicClock::WallNow() const { - return quic::QuicWallTime::FromUNIXMicroseconds(timePointToInt64(time_system_.systemTime())); + return quic::QuicWallTime::FromUNIXMicroseconds( + microsecondsSinceEpoch(time_system_.systemTime())); } } // namespace Quic diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h index d774c2e3bb385..eb90a1db1b94f 100644 --- a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h @@ -11,7 +11,7 @@ namespace Quic { class EnvoyQuicClock : public quic::QuicClock { public: - EnvoyQuicClock(Event::TimeSystem& time_system) : quic::QuicClock(), time_system_(time_system) {} + EnvoyQuicClock(Event::TimeSystem& time_system) : time_system_(time_system) {} // quic::QuicClock quic::QuicTime ApproximateNow() const override; @@ -19,7 +19,7 @@ class EnvoyQuicClock : public quic::QuicClock { quic::QuicWallTime WallNow() const override; private: - template int64_t timePointToInt64(std::chrono::time_point time) const { + template int64_t microsecondsSinceEpoch(std::chrono::time_point time) const { return std::chrono::duration_cast(time.time_since_epoch()).count(); } From 4d5fccbd0c961083dc13eb47897548dfce12406d Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Tue, 28 May 2019 13:14:13 -0400 Subject: [PATCH 4/4] reduce test loop Signed-off-by: Dan Zhang --- .../quic_listeners/quiche/platform/envoy_quic_clock_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc b/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc index 191e491e22615..8bdf8a9875124 100644 --- a/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/envoy_quic_clock_test.cc @@ -43,7 +43,7 @@ TEST(EnvoyQuicClockTest, TestMonotonicityWithReadTimeSystem) { Event::TestRealTimeSystem time_system; EnvoyQuicClock clock(time_system); quic::QuicTime last_now = clock.Now(); - for (int i = 0; i < 1e5; ++i) { + for (int i = 0; i < 1000; ++i) { quic::QuicTime now = clock.Now(); ASSERT_LE(last_now, now); last_now = now;