From da7f24a11f3161eeb554c947acf5c3a5d9887a3a Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Wed, 15 Aug 2018 23:54:27 -0400 Subject: [PATCH 01/22] Remove singletons for time-sources and inject them instead. Signed-off-by: Joshua Marantz --- include/envoy/api/api.h | 3 +- include/envoy/common/time.h | 30 ++++++- include/envoy/event/dispatcher.h | 5 ++ include/envoy/server/filter_config.h | 4 +- include/envoy/server/instance.h | 5 ++ include/envoy/server/worker.h | 2 +- include/envoy/upstream/cluster_manager.h | 2 + source/common/api/api_impl.cc | 4 +- source/common/api/api_impl.h | 2 +- source/common/common/perf_annotation.cc | 5 +- source/common/common/perf_annotation.h | 6 +- source/common/common/token_bucket_impl.cc | 9 +- source/common/common/token_bucket_impl.h | 7 +- source/common/common/utility.cc | 3 - source/common/common/utility.h | 8 +- source/common/config/grpc_mux_impl.cc | 8 +- source/common/config/grpc_mux_impl.h | 5 +- source/common/event/dispatched_thread.h | 2 +- source/common/event/dispatcher_impl.cc | 8 +- source/common/event/dispatcher_impl.h | 7 +- source/common/grpc/async_client_impl.cc | 2 +- source/common/grpc/async_client_impl.h | 2 + .../common/grpc/google_async_client_impl.cc | 2 +- source/common/grpc/google_async_client_impl.h | 2 + source/common/http/async_client_impl.cc | 5 +- source/common/router/rds_impl.cc | 6 +- source/common/router/router.cc | 2 +- source/common/router/router.h | 11 ++- .../common/upstream/cluster_manager_impl.cc | 14 ++- source/common/upstream/cluster_manager_impl.h | 7 +- .../common/upstream/outlier_detection_impl.cc | 2 +- source/exe/main_common.cc | 9 +- source/exe/main_common.h | 3 + source/extensions/tracers/zipkin/tracer.cc | 18 ++-- source/extensions/tracers/zipkin/tracer.h | 7 +- source/extensions/tracers/zipkin/util.cc | 4 +- source/extensions/tracers/zipkin/util.h | 4 +- .../tracers/zipkin/zipkin_core_types.cc | 18 ++-- .../tracers/zipkin/zipkin_core_types.h | 6 +- .../tracers/zipkin/zipkin_tracer_impl.cc | 2 +- source/server/config_validation/api.cc | 4 +- source/server/config_validation/api.h | 2 +- .../server/config_validation/async_client.cc | 2 + .../server/config_validation/async_client.h | 2 + .../config_validation/cluster_manager.cc | 4 +- source/server/config_validation/dispatcher.h | 2 + source/server/config_validation/server.cc | 14 +-- source/server/config_validation/server.h | 7 +- source/server/guarddog_impl.cc | 4 +- source/server/guarddog_impl.h | 4 +- source/server/http/admin.cc | 5 +- source/server/http/admin.h | 7 +- source/server/listener_manager_impl.cc | 9 +- source/server/listener_manager_impl.h | 6 +- source/server/server.cc | 21 ++--- source/server/server.h | 7 +- source/server/watchdog_impl.h | 8 +- source/server/worker_impl.cc | 4 +- source/server/worker_impl.h | 2 +- test/common/common/token_bucket_impl_test.cc | 33 +++---- test/common/config/BUILD | 1 + .../filesystem_subscription_test_harness.h | 4 +- test/common/config/grpc_mux_impl_test.cc | 2 +- test/common/event/BUILD | 3 + .../event/dispatched_thread_impl_test.cc | 6 +- test/common/event/dispatcher_impl_test.cc | 10 ++- test/common/event/file_event_impl_test.cc | 71 ++++++++------- test/common/filesystem/BUILD | 1 + test/common/filesystem/watcher_impl_test.cc | 48 +++++----- test/common/grpc/BUILD | 1 + .../grpc/google_async_client_impl_test.cc | 5 +- test/common/http/BUILD | 4 + test/common/http/codec_client_test.cc | 5 +- .../http/conn_manager_impl_fuzz_test.cc | 12 ++- test/common/http/conn_manager_impl_test.cc | 13 +-- test/common/http/http1/BUILD | 1 + test/common/http/http1/conn_pool_test.cc | 4 +- test/common/http/http2/BUILD | 1 + test/common/http/http2/conn_pool_test.cc | 4 +- test/common/network/BUILD | 3 + test/common/network/connection_impl_test.cc | 35 +++++--- test/common/network/dns_impl_test.cc | 26 ++++-- test/common/network/listener_impl_test.cc | 50 +++++------ test/common/ssl/BUILD | 1 + test/common/ssl/ssl_socket_test.cc | 89 ++++++++++--------- test/common/thread_local/BUILD | 1 + .../thread_local/thread_local_impl_test.cc | 7 +- test/extensions/tracers/zipkin/BUILD | 1 + test/extensions/tracers/zipkin/util_test.cc | 5 +- test/integration/BUILD | 1 + test/integration/fake_upstream.cc | 5 +- test/integration/fake_upstream.h | 2 + test/integration/integration.cc | 4 +- test/integration/integration.h | 3 + test/integration/utility.cc | 7 +- test/integration/utility.h | 5 ++ test/mocks/api/mocks.h | 6 +- test/mocks/common.h | 4 +- test/mocks/event/mocks.cc | 2 +- test/mocks/event/mocks.h | 6 ++ test/mocks/server/mocks.cc | 5 +- test/mocks/server/mocks.h | 10 ++- test/mocks/upstream/mocks.cc | 2 +- test/mocks/upstream/mocks.h | 6 ++ .../config_validation/dispatcher_test.cc | 4 +- test/test_common/BUILD | 9 ++ test/test_common/test_time.cc | 9 ++ test/test_common/test_time.h | 19 ++++ 108 files changed, 571 insertions(+), 350 deletions(-) create mode 100644 test/test_common/test_time.cc create mode 100644 test/test_common/test_time.h diff --git a/include/envoy/api/api.h b/include/envoy/api/api.h index a5e52f9fef9ac..6ab400cd197ff 100644 --- a/include/envoy/api/api.h +++ b/include/envoy/api/api.h @@ -3,6 +3,7 @@ #include #include +#include "envoy/common/time.h" #include "envoy/event/dispatcher.h" #include "envoy/filesystem/filesystem.h" #include "envoy/stats/store.h" @@ -22,7 +23,7 @@ class Api { * Allocate a dispatcher. * @return Event::DispatcherPtr which is owned by the caller. */ - virtual Event::DispatcherPtr allocateDispatcher() PURE; + virtual Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) PURE; /** * Create/open a local file that supports async appending. diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index fb09f1db76abc..7380f383cddb1 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -24,7 +24,7 @@ class SystemTimeSource { /** * @return the current system time. */ - virtual SystemTime currentTime() PURE; + virtual SystemTime currentTime() const PURE; }; /** @@ -37,6 +37,32 @@ class MonotonicTimeSource { /** * @return the current monotonic time. */ - virtual MonotonicTime currentTime() PURE; + virtual MonotonicTime currentTime() const PURE; }; + +class TimeSource { +public: + TimeSource(SystemTimeSource& system, MonotonicTimeSource& monotonic) + : system_(system), monotonic_(monotonic) {} + + /** + * @return the current system time; not guaranteed to be monotonically increasing. + */ + SystemTime systemTime() const { return system_.currentTime(); } + + /** + * @return the current monotonic time. + */ + MonotonicTime monotonicTime() const { return monotonic_.currentTime(); } + + // TODO(jmarantz): Eliminate these methods and the SystemTimeSource and MonotonicTimeSource + // classes, and change method calls to work directly off of TimeSource. + SystemTimeSource& system() { return system_; } + MonotonicTimeSource& monotonic() { return monotonic_; } + +private: + SystemTimeSource& system_; + MonotonicTimeSource& monotonic_; +}; + } // namespace Envoy diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index ab618647085ad..b2b91c6beef48 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -32,6 +32,11 @@ class Dispatcher { public: virtual ~Dispatcher() {} + /** + * Returns a time-source to use with this dispatcher. + */ + virtual TimeSource& timeSource() PURE; + /** * Clear any items in the deferred deletion queue. */ diff --git a/include/envoy/server/filter_config.h b/include/envoy/server/filter_config.h index 307f66fb59cdd..14fff6902733e 100644 --- a/include/envoy/server/filter_config.h +++ b/include/envoy/server/filter_config.h @@ -131,9 +131,9 @@ class FactoryContext { virtual const envoy::api::v2::core::Metadata& listenerMetadata() const PURE; /** - * @return SystemTimeSource& a reference to the top-level SystemTime source. + * @return TimeSource& a reference to the time source. */ - virtual SystemTimeSource& systemTimeSource() PURE; + virtual TimeSource& timeSource() PURE; }; class ListenerFactoryContext : public FactoryContext { diff --git a/include/envoy/server/instance.h b/include/envoy/server/instance.h index 4fef027d9b9dc..b85c2bc045c6e 100644 --- a/include/envoy/server/instance.h +++ b/include/envoy/server/instance.h @@ -192,6 +192,11 @@ class Instance { */ virtual const LocalInfo::LocalInfo& localInfo() PURE; + /** + * @return the time source used for the server. + */ + virtual TimeSource& timeSource() PURE; + /** * @return the flush interval of stats sinks. */ diff --git a/include/envoy/server/worker.h b/include/envoy/server/worker.h index 9f69a7163e739..b68fa75183a62 100644 --- a/include/envoy/server/worker.h +++ b/include/envoy/server/worker.h @@ -84,7 +84,7 @@ class WorkerFactory { /** * @return WorkerPtr a new worker. */ - virtual WorkerPtr createWorker() PURE; + virtual WorkerPtr createWorker(TimeSource&) PURE; }; } // namespace Server diff --git a/include/envoy/upstream/cluster_manager.h b/include/envoy/upstream/cluster_manager.h index c7e7aba180af7..bd93555669886 100644 --- a/include/envoy/upstream/cluster_manager.h +++ b/include/envoy/upstream/cluster_manager.h @@ -209,6 +209,8 @@ class ClusterManager { addThreadLocalClusterUpdateCallbacks(ClusterUpdateCallbacks& callbacks) PURE; virtual ClusterManagerFactory& clusterManagerFactory() PURE; + + virtual TimeSource& timeSource() PURE; }; typedef std::unique_ptr ClusterManagerPtr; diff --git a/source/common/api/api_impl.cc b/source/common/api/api_impl.cc index 86f418939e10f..f36aa7a9724be 100644 --- a/source/common/api/api_impl.cc +++ b/source/common/api/api_impl.cc @@ -9,8 +9,8 @@ namespace Envoy { namespace Api { -Event::DispatcherPtr Impl::allocateDispatcher() { - return Event::DispatcherPtr{new Event::DispatcherImpl()}; +Event::DispatcherPtr Impl::allocateDispatcher(TimeSource& time_source) { + return Event::DispatcherPtr{new Event::DispatcherImpl(time_source)}; } Impl::Impl(std::chrono::milliseconds file_flush_interval_msec) diff --git a/source/common/api/api_impl.h b/source/common/api/api_impl.h index b7f0f6fb609aa..567493fdaa0e2 100644 --- a/source/common/api/api_impl.h +++ b/source/common/api/api_impl.h @@ -17,7 +17,7 @@ class Impl : public Api::Api { Impl(std::chrono::milliseconds file_flush_interval_msec); // Api::Api - Event::DispatcherPtr allocateDispatcher() override; + Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) override; Filesystem::FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, Stats::Store& stats_store) override; diff --git a/source/common/common/perf_annotation.cc b/source/common/common/perf_annotation.cc index 81eee48276dae..77523b8d640f6 100644 --- a/source/common/common/perf_annotation.cc +++ b/source/common/common/perf_annotation.cc @@ -18,11 +18,10 @@ namespace Envoy { PerfOperation::PerfOperation() - : start_time_(ProdMonotonicTimeSource::instance_.currentTime()), - context_(PerfAnnotationContext::getOrCreate()) {} + : context_(PerfAnnotationContext::getOrCreate()), start_time_(context_->currentTime()) {} void PerfOperation::record(absl::string_view category, absl::string_view description) { - const MonotonicTime end_time = ProdMonotonicTimeSource::instance_.currentTime(); + const MonotonicTime end_time = context_->currentTime(); const std::chrono::nanoseconds duration = std::chrono::duration_cast(end_time - start_time_); context_->record(duration, category, description); diff --git a/source/common/common/perf_annotation.h b/source/common/common/perf_annotation.h index 66bdd07deb09b..36442289704d1 100644 --- a/source/common/common/perf_annotation.h +++ b/source/common/common/perf_annotation.h @@ -86,6 +86,9 @@ class PerfAnnotationContext { void record(std::chrono::nanoseconds duration, absl::string_view category, absl::string_view description); + /** @return MonotonicTime the current time */ + MonotonicTime currentTime() { return time_source_.currentTime(); } + /** * Renders the aggregated statistics as a string. * @return std::string the performance data as a formatted string. @@ -138,6 +141,7 @@ class PerfAnnotationContext { #else DurationStatsMap duration_stats_map_; #endif + ProdMonotonicTimeSource time_source_; }; /** @@ -162,8 +166,8 @@ class PerfOperation { void record(absl::string_view category, absl::string_view description); private: - MonotonicTime start_time_; PerfAnnotationContext* context_; + MonotonicTime start_time_; }; } // namespace Envoy diff --git a/source/common/common/token_bucket_impl.cc b/source/common/common/token_bucket_impl.cc index 993a061ddb4b3..07cf3a83c3e59 100644 --- a/source/common/common/token_bucket_impl.cc +++ b/source/common/common/token_bucket_impl.cc @@ -4,14 +4,13 @@ namespace Envoy { -TokenBucketImpl::TokenBucketImpl(uint64_t max_tokens, double fill_rate, - MonotonicTimeSource& time_source) +TokenBucketImpl::TokenBucketImpl(uint64_t max_tokens, TimeSource& time_source, double fill_rate) : max_tokens_(max_tokens), fill_rate_(std::abs(fill_rate)), tokens_(max_tokens), - last_fill_(time_source.currentTime()), time_source_(time_source) {} + last_fill_(time_source.monotonicTime()), time_source_(time_source) {} bool TokenBucketImpl::consume(uint64_t tokens) { if (tokens_ < max_tokens_) { - const auto time_now = time_source_.currentTime(); + const auto time_now = time_source_.monotonicTime(); tokens_ = std::min((std::chrono::duration(time_now - last_fill_).count() * fill_rate_) + tokens_, max_tokens_); @@ -26,4 +25,4 @@ bool TokenBucketImpl::consume(uint64_t tokens) { return true; } -} // namespace Envoy \ No newline at end of file +} // namespace Envoy diff --git a/source/common/common/token_bucket_impl.h b/source/common/common/token_bucket_impl.h index b9f43648e30cf..13bf14435f509 100644 --- a/source/common/common/token_bucket_impl.h +++ b/source/common/common/token_bucket_impl.h @@ -16,10 +16,9 @@ class TokenBucketImpl : public TokenBucket { * @param max_tokens supplies the maximun number of tokens in the bucket. * @param fill_rate supplies the number of tokens that will return to the bucket on each second. * The default is 1. - * @param time_source supplies the time source. The default is ProdMonotonicTimeSource. + * @param time_source supplies the time source. */ - explicit TokenBucketImpl(uint64_t max_tokens, double fill_rate = 1, - MonotonicTimeSource& time_source = ProdMonotonicTimeSource::instance_); + explicit TokenBucketImpl(uint64_t max_tokens, TimeSource& time_source, double fill_rate = 1); bool consume(uint64_t tokens = 1) override; @@ -28,7 +27,7 @@ class TokenBucketImpl : public TokenBucket { const double fill_rate_; double tokens_; MonotonicTime last_fill_; - MonotonicTimeSource& time_source_; + TimeSource& time_source_; }; } // namespace Envoy diff --git a/source/common/common/utility.cc b/source/common/common/utility.cc index 35e3d4b579e98..33d1ac04c6c21 100644 --- a/source/common/common/utility.cc +++ b/source/common/common/utility.cc @@ -201,9 +201,6 @@ std::string DateFormatter::now() { return fromTime(current_time_t); } -ProdSystemTimeSource ProdSystemTimeSource::instance_; -ProdMonotonicTimeSource ProdMonotonicTimeSource::instance_; - ConstMemoryStreamBuffer::ConstMemoryStreamBuffer(const char* data, size_t size) { // std::streambuf won't modify `data`, but the interface still requires a char* for convenience, // so we need to const_cast. diff --git a/source/common/common/utility.h b/source/common/common/utility.h index 452d80192fca8..18c71c1eb1d00 100644 --- a/source/common/common/utility.h +++ b/source/common/common/utility.h @@ -101,9 +101,7 @@ class AccessLogDateTimeFormatter { class ProdSystemTimeSource : public SystemTimeSource { public: // SystemTimeSource - SystemTime currentTime() override { return std::chrono::system_clock::now(); } - - static ProdSystemTimeSource instance_; + SystemTime currentTime() const override { return std::chrono::system_clock::now(); } }; /** @@ -112,9 +110,7 @@ class ProdSystemTimeSource : public SystemTimeSource { class ProdMonotonicTimeSource : public MonotonicTimeSource { public: // MonotonicTimeSource - MonotonicTime currentTime() override { return std::chrono::steady_clock::now(); } - - static ProdMonotonicTimeSource instance_; + MonotonicTime currentTime() const override { return std::chrono::steady_clock::now(); } }; /** diff --git a/source/common/config/grpc_mux_impl.cc b/source/common/config/grpc_mux_impl.cc index 77b9fc84dc345..fd2d4c1c5c80a 100644 --- a/source/common/config/grpc_mux_impl.cc +++ b/source/common/config/grpc_mux_impl.cc @@ -12,9 +12,9 @@ namespace Config { GrpcMuxImpl::GrpcMuxImpl(const envoy::api::v2::core::Node& node, Grpc::AsyncClientPtr async_client, Event::Dispatcher& dispatcher, const Protobuf::MethodDescriptor& service_method, - Runtime::RandomGenerator& random, MonotonicTimeSource& time_source) + Runtime::RandomGenerator& random) : node_(node), async_client_(std::move(async_client)), service_method_(service_method), - random_(random), time_source_(time_source) { + random_(random), time_source_(dispatcher.timeSource()) { retry_timer_ = dispatcher.createTimer([this]() -> void { establishNewStream(); }); backoff_strategy_ = std::make_unique(RETRY_INITIAL_DELAY_MS, RETRY_MAX_DELAY_MS, random_); @@ -110,9 +110,9 @@ GrpcMuxWatchPtr GrpcMuxImpl::subscribe(const std::string& type_url, // TODO(gsagula): move TokenBucketImpl params to a config. if (!api_state_[type_url].subscribed_) { // Bucket contains 100 tokens maximum and refills at 5 tokens/sec. - api_state_[type_url].limit_request_ = std::make_unique(100, 5, time_source_); + api_state_[type_url].limit_request_ = std::make_unique(100, time_source_, 5); // Bucket contains 1 token maximum and refills 1 token on every ~5 seconds. - api_state_[type_url].limit_log_ = std::make_unique(1, 0.2, time_source_); + api_state_[type_url].limit_log_ = std::make_unique(1, time_source_, 0.2); api_state_[type_url].request_.set_type_url(type_url); api_state_[type_url].request_.mutable_node()->MergeFrom(node_); api_state_[type_url].subscribed_ = true; diff --git a/source/common/config/grpc_mux_impl.h b/source/common/config/grpc_mux_impl.h index 5f2c99c2e6168..8985cbbafc7a0 100644 --- a/source/common/config/grpc_mux_impl.h +++ b/source/common/config/grpc_mux_impl.h @@ -26,8 +26,7 @@ class GrpcMuxImpl : public GrpcMux, public: GrpcMuxImpl(const envoy::api::v2::core::Node& node, Grpc::AsyncClientPtr async_client, Event::Dispatcher& dispatcher, const Protobuf::MethodDescriptor& service_method, - Runtime::RandomGenerator& random, - MonotonicTimeSource& time_source = ProdMonotonicTimeSource::instance_); + Runtime::RandomGenerator& random); ~GrpcMuxImpl(); void start() override; @@ -104,7 +103,7 @@ class GrpcMuxImpl : public GrpcMux, std::list subscriptions_; Event::TimerPtr retry_timer_; Runtime::RandomGenerator& random_; - MonotonicTimeSource& time_source_; + TimeSource& time_source_; BackOffStrategyPtr backoff_strategy_; }; diff --git a/source/common/event/dispatched_thread.h b/source/common/event/dispatched_thread.h index 600e5906d8ae5..e5cd327f72a97 100644 --- a/source/common/event/dispatched_thread.h +++ b/source/common/event/dispatched_thread.h @@ -38,7 +38,7 @@ namespace Event { */ class DispatchedThreadImpl : Logger::Loggable { public: - DispatchedThreadImpl() : dispatcher_(new DispatcherImpl()) {} + DispatchedThreadImpl(TimeSource& time_source) : dispatcher_(new DispatcherImpl(time_source)) {} /** * Start the thread. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index ff8c3a1c76b2a..af409f8cb40a7 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -24,14 +24,14 @@ namespace Envoy { namespace Event { -DispatcherImpl::DispatcherImpl() - : DispatcherImpl(Buffer::WatermarkFactoryPtr{new Buffer::WatermarkBufferFactory}) { +DispatcherImpl::DispatcherImpl(TimeSource& time_source) + : DispatcherImpl(time_source, Buffer::WatermarkFactoryPtr{new Buffer::WatermarkBufferFactory}) { // The dispatcher won't work as expected if libevent hasn't been configured to use threads. RELEASE_ASSERT(Libevent::Global::initialized(), ""); } -DispatcherImpl::DispatcherImpl(Buffer::WatermarkFactoryPtr&& factory) - : buffer_factory_(std::move(factory)), base_(event_base_new()), +DispatcherImpl::DispatcherImpl(TimeSource& time_source, Buffer::WatermarkFactoryPtr&& factory) + : time_source_(time_source), buffer_factory_(std::move(factory)), base_(event_base_new()), deferred_delete_timer_(createTimer([this]() -> void { clearDeferredDeleteList(); })), post_timer_(createTimer([this]() -> void { runPostCallbacks(); })), current_to_delete_(&to_delete_1_) { diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index e1ab0c47e76b9..ffc136e2f8f54 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -5,6 +5,7 @@ #include #include +#include "envoy/common/time.h" #include "envoy/event/deferred_deletable.h" #include "envoy/event/dispatcher.h" #include "envoy/network/connection_handler.h" @@ -21,8 +22,8 @@ namespace Event { */ class DispatcherImpl : Logger::Loggable, public Dispatcher { public: - DispatcherImpl(); - DispatcherImpl(Buffer::WatermarkFactoryPtr&& factory); + explicit DispatcherImpl(TimeSource& time_source); + DispatcherImpl(TimeSource& time_source, Buffer::WatermarkFactoryPtr&& factory); ~DispatcherImpl(); /** @@ -31,6 +32,7 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { event_base& base() { return *base_; } // Event::Dispatcher + TimeSource& timeSource() override { return time_source_; } void clearDeferredDeleteList() override; Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, @@ -66,6 +68,7 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { return run_tid_ == 0 || run_tid_ == Thread::Thread::currentThreadId(); } + TimeSource time_source_; Thread::ThreadId run_tid_{}; Buffer::WatermarkFactoryPtr buffer_factory_; Libevent::BasePtr base_; diff --git a/source/common/grpc/async_client_impl.cc b/source/common/grpc/async_client_impl.cc index 8d6f15c765a40..852270d25110e 100644 --- a/source/common/grpc/async_client_impl.cc +++ b/source/common/grpc/async_client_impl.cc @@ -207,7 +207,7 @@ AsyncRequestImpl::AsyncRequestImpl(AsyncClientImpl& parent, current_span_ = parent_span.spawnChild(Tracing::EgressConfig::get(), "async " + parent.remote_cluster_name_ + " egress", - ProdSystemTimeSource::instance_.currentTime()); + parent.timeSource().systemTime()); current_span_->setTag(Tracing::Tags::get().UPSTREAM_CLUSTER, parent.remote_cluster_name_); current_span_->setTag(Tracing::Tags::get().COMPONENT, Tracing::Tags::get().PROXY); } diff --git a/source/common/grpc/async_client_impl.h b/source/common/grpc/async_client_impl.h index 06d8d173dc737..3841a911be113 100644 --- a/source/common/grpc/async_client_impl.h +++ b/source/common/grpc/async_client_impl.h @@ -25,6 +25,8 @@ class AsyncClientImpl final : public AsyncClient { AsyncStream* start(const Protobuf::MethodDescriptor& service_method, AsyncStreamCallbacks& callbacks) override; + TimeSource& timeSource() { return cm_.timeSource(); } + private: Upstream::ClusterManager& cm_; const std::string remote_cluster_name_; diff --git a/source/common/grpc/google_async_client_impl.cc b/source/common/grpc/google_async_client_impl.cc index 48ea1a16e5272..7fdc57768d6c5 100644 --- a/source/common/grpc/google_async_client_impl.cc +++ b/source/common/grpc/google_async_client_impl.cc @@ -387,7 +387,7 @@ GoogleAsyncRequestImpl::GoogleAsyncRequestImpl( callbacks_(callbacks) { current_span_ = parent_span.spawnChild(Tracing::EgressConfig::get(), "async " + parent.stat_prefix_ + " egress", - ProdSystemTimeSource::instance_.currentTime()); + parent.timeSource().systemTime()); current_span_->setTag(Tracing::Tags::get().UPSTREAM_CLUSTER, parent.stat_prefix_); current_span_->setTag(Tracing::Tags::get().COMPONENT, Tracing::Tags::get().PROXY); } diff --git a/source/common/grpc/google_async_client_impl.h b/source/common/grpc/google_async_client_impl.h index 72b7c95d82b46..1c91801c60612 100644 --- a/source/common/grpc/google_async_client_impl.h +++ b/source/common/grpc/google_async_client_impl.h @@ -165,6 +165,8 @@ class GoogleAsyncClientImpl final : public AsyncClient, Logger::Loggable createChannel(const envoy::api::v2::core::GrpcService::GoogleGrpc& config); diff --git a/source/common/http/async_client_impl.cc b/source/common/http/async_client_impl.cc index e9e435cd7121b..3f458595fa738 100644 --- a/source/common/http/async_client_impl.cc +++ b/source/common/http/async_client_impl.cc @@ -35,8 +35,9 @@ AsyncClientImpl::AsyncClientImpl(const Upstream::ClusterInfo& cluster, Stats::St Upstream::ClusterManager& cm, Runtime::Loader& runtime, Runtime::RandomGenerator& random, Router::ShadowWriterPtr&& shadow_writer) - : cluster_(cluster), config_("http.async-client.", local_info, stats_store, cm, runtime, random, - std::move(shadow_writer), true, false, false), + : cluster_(cluster), + config_("http.async-client.", local_info, stats_store, cm, runtime, random, + std::move(shadow_writer), true, false, false, dispatcher.timeSource()), dispatcher_(dispatcher) {} AsyncClientImpl::~AsyncClientImpl() { diff --git a/source/common/router/rds_impl.cc b/source/common/router/rds_impl.cc index 6a3e8c545cae5..7f3aa8c223824 100644 --- a/source/common/router/rds_impl.cc +++ b/source/common/router/rds_impl.cc @@ -44,7 +44,7 @@ StaticRouteConfigProviderImpl::StaticRouteConfigProviderImpl( Server::Configuration::FactoryContext& factory_context, RouteConfigProviderManagerImpl& route_config_provider_manager) : config_(new ConfigImpl(config, factory_context, true)), route_config_proto_{config}, - last_updated_(factory_context.systemTimeSource().currentTime()), + last_updated_(factory_context.timeSource().systemTime()), route_config_provider_manager_(route_config_provider_manager) { route_config_provider_manager_.static_route_config_providers_.insert(this); } @@ -64,8 +64,8 @@ RdsRouteConfigSubscription::RdsRouteConfigSubscription( scope_(factory_context.scope().createScope(stat_prefix + "rds." + route_config_name_ + ".")), stats_({ALL_RDS_STATS(POOL_COUNTER(*scope_))}), route_config_provider_manager_(route_config_provider_manager), - manager_identifier_(manager_identifier), time_source_(factory_context.systemTimeSource()), - last_updated_(factory_context.systemTimeSource().currentTime()) { + manager_identifier_(manager_identifier), time_source_(factory_context.timeSource().system()), + last_updated_(factory_context.timeSource().systemTime()) { ::Envoy::Config::Utility::checkLocalInfo("rds", factory_context.localInfo()); subscription_ = Envoy::Config::SubscriptionFactory::subscriptionFromConfigSource< diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 838d937454c75..a8ba44b05415e 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -779,7 +779,7 @@ Filter::UpstreamRequest::UpstreamRequest(Filter& parent, Http::ConnectionPool::I if (parent_.config_.start_child_span_) { span_ = parent_.callbacks_->activeSpan().spawnChild( parent_.callbacks_->tracingConfig(), "router " + parent.cluster_->name() + " egress", - ProdSystemTimeSource::instance_.currentTime()); + parent.timeSource().systemTime()); span_->setTag(Tracing::Tags::get().COMPONENT, Tracing::Tags::get().PROXY); } diff --git a/source/common/router/router.h b/source/common/router/router.h index 53ce571032886..5ad9f6ceea820 100644 --- a/source/common/router/router.h +++ b/source/common/router/router.h @@ -96,11 +96,13 @@ class FilterConfig { FilterConfig(const std::string& stat_prefix, const LocalInfo::LocalInfo& local_info, Stats::Scope& scope, Upstream::ClusterManager& cm, Runtime::Loader& runtime, Runtime::RandomGenerator& random, ShadowWriterPtr&& shadow_writer, - bool emit_dynamic_stats, bool start_child_span, bool suppress_envoy_headers) + bool emit_dynamic_stats, bool start_child_span, bool suppress_envoy_headers, + TimeSource& time_source) : scope_(scope), local_info_(local_info), cm_(cm), runtime_(runtime), random_(random), stats_{ALL_ROUTER_STATS(POOL_COUNTER_PREFIX(scope, stat_prefix))}, emit_dynamic_stats_(emit_dynamic_stats), start_child_span_(start_child_span), - suppress_envoy_headers_(suppress_envoy_headers), shadow_writer_(std::move(shadow_writer)) {} + suppress_envoy_headers_(suppress_envoy_headers), time_source_(time_source), + shadow_writer_(std::move(shadow_writer)) {} FilterConfig(const std::string& stat_prefix, Server::Configuration::FactoryContext& context, ShadowWriterPtr&& shadow_writer, @@ -108,7 +110,8 @@ class FilterConfig { : FilterConfig(stat_prefix, context.localInfo(), context.scope(), context.clusterManager(), context.runtime(), context.random(), std::move(shadow_writer), PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, dynamic_stats, true), - config.start_child_span(), config.suppress_envoy_headers()) { + config.start_child_span(), config.suppress_envoy_headers(), + context.timeSource()) { for (const auto& upstream_log : config.upstream_log()) { upstream_logs_.push_back(AccessLog::AccessLogFactory::fromProto(upstream_log, context)); } @@ -125,6 +128,7 @@ class FilterConfig { const bool emit_dynamic_stats_; const bool start_child_span_; const bool suppress_envoy_headers_; + TimeSource& time_source_; std::list upstream_logs_; private: @@ -345,6 +349,7 @@ class Filter : Logger::Loggable, // Called immediately after a non-5xx header is received from upstream, performs stats accounting // and handle difference between gRPC and non-gRPC requests. void handleNon5xxResponseHeaders(const Http::HeaderMap& headers, bool end_stream); + TimeSource& timeSource() { return config_.time_source_; } FilterConfig& config_; Http::StreamDecoderFilterCallbacks* callbacks_{}; diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index b77d7007567e6..96b540b07c232 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -172,8 +172,7 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, - Server::Admin& admin, SystemTimeSource& system_time_source, - MonotonicTimeSource& monotonic_time_source) + Server::Admin& admin) : factory_(factory), runtime_(runtime), stats_(stats), tls_(tls.allocateSlot()), random_(random), log_manager_(log_manager), bind_config_(bootstrap.cluster_manager().upstream_bind_config()), local_info_(local_info), @@ -181,14 +180,14 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots init_helper_([this](Cluster& cluster) { onClusterInit(cluster); }), config_tracker_entry_( admin.getConfigTracker().add("clusters", [this] { return dumpClusterConfigs(); })), - system_time_source_(system_time_source), dispatcher_(main_thread_dispatcher) { + time_source_(main_thread_dispatcher.timeSource()), dispatcher_(main_thread_dispatcher) { async_client_manager_ = std::make_unique(*this, tls); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { const std::string event_log_file_path = cm_config.outlier_detection().event_log_path(); if (!event_log_file_path.empty()) { outlier_event_logger_.reset(new Outlier::EventLoggerImpl( - log_manager, event_log_file_path, system_time_source, monotonic_time_source)); + log_manager, event_log_file_path, time_source_.system(), time_source_.monotonic())); } } @@ -305,7 +304,7 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots Config::Utility::factoryForGrpcApiConfigSource( *async_client_manager_, load_stats_config, stats) ->create(), - main_thread_dispatcher, ProdMonotonicTimeSource::instance_)); + main_thread_dispatcher, timeSource().monotonic())); } } @@ -619,7 +618,7 @@ void ClusterManagerImpl::loadCluster(const envoy::api::v2::Cluster& cluster, } cluster_map[cluster_reference.info()->name()] = std::make_unique( - cluster, version_info, added_via_api, std::move(new_cluster), system_time_source_); + cluster, version_info, added_via_api, std::move(new_cluster), time_source_.system()); const auto cluster_entry_it = cluster_map.find(cluster_reference.info()->name()); // If an LB is thread aware, create it here. The LB is not initialized until cluster pre-init @@ -1178,8 +1177,7 @@ ClusterManagerPtr ProdClusterManagerFactory::clusterManagerFromProto( Server::Admin& admin) { return ClusterManagerPtr{new ClusterManagerImpl(bootstrap, *this, stats, tls, runtime, random, local_info, log_manager, main_thread_dispatcher_, - admin, ProdSystemTimeSource::instance_, - ProdMonotonicTimeSource::instance_)}; + admin)}; } Http::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateConnPool( diff --git a/source/common/upstream/cluster_manager_impl.h b/source/common/upstream/cluster_manager_impl.h index 426d4fac292dc..0de5f17f12925 100644 --- a/source/common/upstream/cluster_manager_impl.h +++ b/source/common/upstream/cluster_manager_impl.h @@ -165,9 +165,7 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggable(options_.statsOptions(), restarter_->statsAllocator()); + server_ = std::make_unique( - options_, local_address, default_test_hooks_, *restarter_, *stats_store_, access_log_lock, - component_factory_, std::make_unique(), *tls_); + options_, time_source_, local_address, default_test_hooks_, *restarter_, *stats_store_, + access_log_lock, component_factory_, std::make_unique(), + *tls_); break; } case Server::Mode::Validate: diff --git a/source/exe/main_common.h b/source/exe/main_common.h index 040041dd366c6..5355bc2a4f3c6 100644 --- a/source/exe/main_common.h +++ b/source/exe/main_common.h @@ -49,6 +49,9 @@ class MainCommonBase { protected: Envoy::OptionsImpl& options_; ProdComponentFactory component_factory_; + ProdSystemTimeSource system_time_source_; + ProdMonotonicTimeSource monotonic_time_source_; + TimeSource time_source_; DefaultTestHooks default_test_hooks_; std::unique_ptr tls_; std::unique_ptr restarter_; diff --git a/source/extensions/tracers/zipkin/tracer.cc b/source/extensions/tracers/zipkin/tracer.cc index a3bc9072d302e..e95719262fc6e 100644 --- a/source/extensions/tracers/zipkin/tracer.cc +++ b/source/extensions/tracers/zipkin/tracer.cc @@ -28,7 +28,7 @@ SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span } // Create an all-new span, with no parent id - SpanPtr span_ptr(new Span()); + SpanPtr span_ptr(new Span(time_source_)); span_ptr->setName(span_name); uint64_t random_number = random_generator_.random(); span_ptr->setId(random_number); @@ -36,10 +36,9 @@ SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span if (trace_id_128bit_) { span_ptr->setTraceIdHigh(random_generator_.random()); } - int64_t start_time_micro = - std::chrono::duration_cast( - ProdMonotonicTimeSource::instance_.currentTime().time_since_epoch()) - .count(); + int64_t start_time_micro = std::chrono::duration_cast( + time_source_.monotonicTime().time_since_epoch()) + .count(); span_ptr->setStartTime(start_time_micro); // Set the timestamp globally for the span and also for the CS annotation @@ -58,7 +57,7 @@ SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span_name, SystemTime timestamp, SpanContext& previous_context) { - SpanPtr span_ptr(new Span()); + SpanPtr span_ptr(new Span(time_source_)); Annotation annotation; uint64_t timestamp_micro; @@ -114,10 +113,9 @@ SpanPtr Tracer::startSpan(const Tracing::Config& config, const std::string& span // Keep the same sampled flag span_ptr->setSampled(previous_context.sampled()); - int64_t start_time_micro = - std::chrono::duration_cast( - ProdMonotonicTimeSource::instance_.currentTime().time_since_epoch()) - .count(); + int64_t start_time_micro = std::chrono::duration_cast( + time_source_.monotonicTime().time_since_epoch()) + .count(); span_ptr->setStartTime(start_time_micro); span_ptr->setTracer(this); diff --git a/source/extensions/tracers/zipkin/tracer.h b/source/extensions/tracers/zipkin/tracer.h index d74606a3bff49..ab68286b1cbf2 100644 --- a/source/extensions/tracers/zipkin/tracer.h +++ b/source/extensions/tracers/zipkin/tracer.h @@ -59,9 +59,11 @@ class Tracer : public TracerInterface { * @param trace_id_128bit Whether 128bit ids should be used. */ Tracer(const std::string& service_name, Network::Address::InstanceConstSharedPtr address, - Runtime::RandomGenerator& random_generator, const bool trace_id_128bit) + Runtime::RandomGenerator& random_generator, const bool trace_id_128bit, + TimeSource& time_source) : service_name_(service_name), address_(address), reporter_(nullptr), - random_generator_(random_generator), trace_id_128bit_(trace_id_128bit) {} + random_generator_(random_generator), trace_id_128bit_(trace_id_128bit), + time_source_(time_source) {} /** * Creates a "root" Zipkin span. @@ -114,6 +116,7 @@ class Tracer : public TracerInterface { ReporterPtr reporter_; Runtime::RandomGenerator& random_generator_; const bool trace_id_128bit_; + TimeSource& time_source_; }; typedef std::unique_ptr TracerPtr; diff --git a/source/extensions/tracers/zipkin/util.cc b/source/extensions/tracers/zipkin/util.cc index 9ea8091a68e6a..447621f0a59de 100644 --- a/source/extensions/tracers/zipkin/util.cc +++ b/source/extensions/tracers/zipkin/util.cc @@ -47,9 +47,9 @@ void Util::addArrayToJson(std::string& target, const std::vector& j mergeJsons(target, stringified_json_array, field_name); } -uint64_t Util::generateRandom64() { +uint64_t Util::generateRandom64(TimeSource& time_source) { uint64_t seed = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + time_source.systemTime().time_since_epoch()) .count(); std::mt19937_64 rand_64(seed); return rand_64(); diff --git a/source/extensions/tracers/zipkin/util.h b/source/extensions/tracers/zipkin/util.h index cee928f8a9af1..ce86f73080e91 100644 --- a/source/extensions/tracers/zipkin/util.h +++ b/source/extensions/tracers/zipkin/util.h @@ -3,6 +3,8 @@ #include #include +#include "envoy/common/time.h" + namespace Envoy { namespace Extensions { namespace Tracers { @@ -45,7 +47,7 @@ class Util { /** * Returns a randomly-generated 64-bit integer number. */ - static uint64_t generateRandom64(); + static uint64_t generateRandom64(TimeSource& time_source); }; } // namespace Zipkin diff --git a/source/extensions/tracers/zipkin/zipkin_core_types.cc b/source/extensions/tracers/zipkin/zipkin_core_types.cc index ca0870744f88f..028ec2afada48 100644 --- a/source/extensions/tracers/zipkin/zipkin_core_types.cc +++ b/source/extensions/tracers/zipkin/zipkin_core_types.cc @@ -141,7 +141,7 @@ const std::string BinaryAnnotation::toJson() { const std::string Span::EMPTY_HEX_STRING_ = "0000000000000000"; -Span::Span(const Span& span) { +Span::Span(const Span& span) : time_source_(span.time_source_) { trace_id_ = span.traceId(); if (span.isSetTraceIdHigh()) { trace_id_high_ = span.traceIdHigh(); @@ -227,25 +227,23 @@ void Span::finish() { Annotation ss; ss.setEndpoint(annotations_[0].endpoint()); ss.setTimestamp(std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + time_source_.systemTime().time_since_epoch()) .count()); ss.setValue(ZipkinCoreConstants::get().SERVER_SEND); annotations_.push_back(std::move(ss)); } else if (annotations_[0].value() == ZipkinCoreConstants::get().CLIENT_SEND) { // Need to set the CR annotation Annotation cr; - const uint64_t stop_timestamp = - std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) - .count(); + const uint64_t stop_timestamp = std::chrono::duration_cast( + time_source_.systemTime().time_since_epoch()) + .count(); cr.setEndpoint(annotations_[0].endpoint()); cr.setTimestamp(stop_timestamp); cr.setValue(ZipkinCoreConstants::get().CLIENT_RECV); annotations_.push_back(std::move(cr)); - const int64_t monotonic_stop_time = - std::chrono::duration_cast( - ProdMonotonicTimeSource::instance_.currentTime().time_since_epoch()) - .count(); + const int64_t monotonic_stop_time = std::chrono::duration_cast( + time_source_.monotonicTime().time_since_epoch()) + .count(); setDuration(monotonic_stop_time - monotonic_start_time_); } diff --git a/source/extensions/tracers/zipkin/zipkin_core_types.h b/source/extensions/tracers/zipkin/zipkin_core_types.h index 5eeccef9f2e1c..059191245abc9 100644 --- a/source/extensions/tracers/zipkin/zipkin_core_types.h +++ b/source/extensions/tracers/zipkin/zipkin_core_types.h @@ -3,6 +3,7 @@ #include #include "envoy/common/pure.h" +#include "envoy/common/time.h" #include "envoy/network/address.h" #include "common/common/hex.h" @@ -304,9 +305,9 @@ class Span : public ZipkinBase { /** * Default constructor. Creates an empty span. */ - Span() + explicit Span(TimeSource& time_source) : trace_id_(0), name_(), id_(0), debug_(false), sampled_(false), monotonic_start_time_(0), - tracer_(nullptr) {} + tracer_(nullptr), time_source_(time_source) {} /** * Sets the span's trace id attribute. @@ -561,6 +562,7 @@ class Span : public ZipkinBase { absl::optional trace_id_high_; int64_t monotonic_start_time_; TracerInterface* tracer_; + TimeSource& time_source_; }; } // namespace Zipkin diff --git a/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc b/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc index 5d892f883bb4f..e122d7fface20 100644 --- a/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc +++ b/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc @@ -76,7 +76,7 @@ Driver::Driver(const Json::Object& config, Upstream::ClusterManager& cluster_man tls_->set([this, collector_endpoint, &random_generator, trace_id_128bit]( Event::Dispatcher& dispatcher) -> ThreadLocal::ThreadLocalObjectSharedPtr { TracerPtr tracer(new Tracer(local_info_.clusterName(), local_info_.address(), random_generator, - trace_id_128bit)); + trace_id_128bit, cm_.timeSource())); tracer->setReporter( ReporterImpl::NewInstance(std::ref(*this), std::ref(dispatcher), collector_endpoint)); return ThreadLocal::ThreadLocalObjectSharedPtr{new TlsTracer(std::move(tracer), *this)}; diff --git a/source/server/config_validation/api.cc b/source/server/config_validation/api.cc index f83d46a984105..293a3161c7f17 100644 --- a/source/server/config_validation/api.cc +++ b/source/server/config_validation/api.cc @@ -8,8 +8,8 @@ namespace Api { ValidationImpl::ValidationImpl(std::chrono::milliseconds file_flush_interval_msec) : Impl(file_flush_interval_msec) {} -Event::DispatcherPtr ValidationImpl::allocateDispatcher() { - return Event::DispatcherPtr{new Event::ValidationDispatcher()}; +Event::DispatcherPtr ValidationImpl::allocateDispatcher(TimeSource& time_source) { + return Event::DispatcherPtr{new Event::ValidationDispatcher(time_source)}; } } // namespace Api diff --git a/source/server/config_validation/api.h b/source/server/config_validation/api.h index 710b775e16ae0..2c568ab4c665e 100644 --- a/source/server/config_validation/api.h +++ b/source/server/config_validation/api.h @@ -16,7 +16,7 @@ class ValidationImpl : public Impl { public: ValidationImpl(std::chrono::milliseconds file_flush_interval_msec); - Event::DispatcherPtr allocateDispatcher() override; + Event::DispatcherPtr allocateDispatcher(TimeSource&) override; }; } // namespace Api diff --git a/source/server/config_validation/async_client.cc b/source/server/config_validation/async_client.cc index d29fcefa2d32c..991bbcc44e624 100644 --- a/source/server/config_validation/async_client.cc +++ b/source/server/config_validation/async_client.cc @@ -3,6 +3,8 @@ namespace Envoy { namespace Http { +ValidationAsyncClient::ValidationAsyncClient(TimeSource& time_source) : dispatcher_(time_source) {} + AsyncClient::Request* ValidationAsyncClient::send(MessagePtr&&, Callbacks&, const absl::optional&) { diff --git a/source/server/config_validation/async_client.h b/source/server/config_validation/async_client.h index a5050b2acef7e..fa1f768115611 100644 --- a/source/server/config_validation/async_client.h +++ b/source/server/config_validation/async_client.h @@ -19,6 +19,8 @@ namespace Http { */ class ValidationAsyncClient : public AsyncClient { public: + ValidationAsyncClient(TimeSource& time_source); + // Http::AsyncClient AsyncClient::Request* send(MessagePtr&& request, Callbacks& callbacks, const absl::optional& timeout) override; diff --git a/source/server/config_validation/cluster_manager.cc b/source/server/config_validation/cluster_manager.cc index e2d98f74c03d9..f90877ed4d761 100644 --- a/source/server/config_validation/cluster_manager.cc +++ b/source/server/config_validation/cluster_manager.cc @@ -39,8 +39,8 @@ ValidationClusterManager::ValidationClusterManager( AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, Server::Admin& admin) : ClusterManagerImpl(bootstrap, factory, stats, tls, runtime, random, local_info, log_manager, - main_thread_dispatcher, admin, ProdSystemTimeSource::instance_, - ProdMonotonicTimeSource::instance_) {} + main_thread_dispatcher, admin), + async_client_(main_thread_dispatcher.timeSource()) {} Http::ConnectionPool::Instance* ValidationClusterManager::httpConnPoolForCluster(const std::string&, ResourcePriority, diff --git a/source/server/config_validation/dispatcher.h b/source/server/config_validation/dispatcher.h index ec9c1fac8213b..bb1e4d34fc96d 100644 --- a/source/server/config_validation/dispatcher.h +++ b/source/server/config_validation/dispatcher.h @@ -16,6 +16,8 @@ namespace Event { */ class ValidationDispatcher : public DispatcherImpl { public: + ValidationDispatcher(TimeSource& time_source) : DispatcherImpl(time_source) {} + Network::ClientConnectionPtr createClientConnection(Network::Address::InstanceConstSharedPtr, Network::Address::InstanceConstSharedPtr, Network::TransportSocketPtr&&, diff --git a/source/server/config_validation/server.cc b/source/server/config_validation/server.cc index 8dc49dc87edcd..90b57e8f26228 100644 --- a/source/server/config_validation/server.cc +++ b/source/server/config_validation/server.cc @@ -22,7 +22,10 @@ bool validateConfig(Options& options, Network::Address::InstanceConstSharedPtr l Stats::IsolatedStoreImpl stats_store; try { - ValidationInstance server(options, local_address, stats_store, access_log_lock, + ProdSystemTimeSource system_time_source; + ProdMonotonicTimeSource monotonic_time_source; + TimeSource time_source(system_time_source, monotonic_time_source); + ValidationInstance server(options, time_source, local_address, stats_store, access_log_lock, component_factory); std::cout << "configuration '" << options.configPath() << "' OK" << std::endl; server.shutdown(); @@ -32,16 +35,17 @@ bool validateConfig(Options& options, Network::Address::InstanceConstSharedPtr l } } -ValidationInstance::ValidationInstance(Options& options, +ValidationInstance::ValidationInstance(Options& options, TimeSource& time_source, Network::Address::InstanceConstSharedPtr local_address, Stats::IsolatedStoreImpl& store, Thread::BasicLockable& access_log_lock, ComponentFactory& component_factory) - : options_(options), stats_store_(store), + : options_(options), time_source_(time_source), stats_store_(store), api_(new Api::ValidationImpl(options.fileFlushIntervalMsec())), - dispatcher_(api_->allocateDispatcher()), singleton_manager_(new Singleton::ManagerImpl()), + dispatcher_(api_->allocateDispatcher(time_source)), + singleton_manager_(new Singleton::ManagerImpl()), access_log_manager_(*api_, *dispatcher_, access_log_lock, store), - listener_manager_(*this, *this, *this, ProdSystemTimeSource::instance_) { + listener_manager_(*this, *this, *this, time_source) { try { initialize(options, local_address, component_factory); } catch (const EnvoyException& e) { diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index 95d89d0025043..65c45ae215ba8 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -52,7 +52,8 @@ class ValidationInstance : Logger::Loggable, public ListenerComponentFactory, public WorkerFactory { public: - ValidationInstance(Options& options, Network::Address::InstanceConstSharedPtr local_address, + ValidationInstance(Options& options, TimeSource& time_source, + Network::Address::InstanceConstSharedPtr local_address, Stats::IsolatedStoreImpl& store, Thread::BasicLockable& access_log_lock, ComponentFactory& component_factory); @@ -92,6 +93,7 @@ class ValidationInstance : Logger::Loggable, Tracing::HttpTracer& httpTracer() override { return config_->httpTracer(); } ThreadLocal::Instance& threadLocal() override { return thread_local_; } const LocalInfo::LocalInfo& localInfo() override { return *local_info_; } + TimeSource& timeSource() override { return time_source_; } std::chrono::milliseconds statsFlushInterval() const override { return config_->statsFlushInterval(); @@ -125,7 +127,7 @@ class ValidationInstance : Logger::Loggable, uint64_t nextListenerTag() override { return 0; } // Server::WorkerFactory - WorkerPtr createWorker() override { + WorkerPtr createWorker(TimeSource&) override { // Returned workers are not currently used so we can return nothing here safely vs. a // validation mock. return nullptr; @@ -136,6 +138,7 @@ class ValidationInstance : Logger::Loggable, ComponentFactory& component_factory); Options& options_; + TimeSource& time_source_; Stats::IsolatedStoreImpl& stats_store_; ThreadLocal::InstanceImpl thread_local_; Api::ApiPtr api_; diff --git a/source/server/guarddog_impl.cc b/source/server/guarddog_impl.cc index e6ea334bbf502..2449bcd85ffa9 100644 --- a/source/server/guarddog_impl.cc +++ b/source/server/guarddog_impl.cc @@ -14,7 +14,7 @@ namespace Envoy { namespace Server { GuardDogImpl::GuardDogImpl(Stats::Scope& stats_scope, const Server::Configuration::Main& config, - MonotonicTimeSource& tsource) + TimeSource& tsource) : time_source_(tsource), miss_timeout_(config.wdMissTimeout()), megamiss_timeout_(config.wdMegaMissTimeout()), kill_timeout_(config.wdKillTimeout()), multi_kill_timeout_(config.wdMultiKillTimeout()), @@ -37,7 +37,7 @@ GuardDogImpl::~GuardDogImpl() { stop(); } void GuardDogImpl::threadRoutine() { do { - const auto now = time_source_.currentTime(); + const auto now = time_source_.monotonicTime(); bool seen_one_multi_timeout(false); Thread::LockGuard guard(wd_lock_); for (auto& watched_dog : watched_dogs_) { diff --git a/source/server/guarddog_impl.h b/source/server/guarddog_impl.h index 31b161e725ec2..95aebf775c8b6 100644 --- a/source/server/guarddog_impl.h +++ b/source/server/guarddog_impl.h @@ -38,7 +38,7 @@ class GuardDogImpl : public GuardDog { * See the configuration documentation for details on the timeout settings. */ GuardDogImpl(Stats::Scope& stats_scope, const Server::Configuration::Main& config, - MonotonicTimeSource& tsource); + TimeSource& tsource); ~GuardDogImpl(); /** @@ -75,7 +75,7 @@ class GuardDogImpl : public GuardDog { bool megamiss_alerted_{}; }; - MonotonicTimeSource& time_source_; + TimeSource& time_source_; const std::chrono::milliseconds miss_timeout_; const std::chrono::milliseconds megamiss_timeout_; const std::chrono::milliseconds kill_timeout_; diff --git a/source/server/http/admin.cc b/source/server/http/admin.cc index 3e074e109d102..4343caf613d86 100644 --- a/source/server/http/admin.cc +++ b/source/server/http/admin.cc @@ -855,8 +855,8 @@ void AdminFilter::onComplete() { } } -AdminImpl::NullRouteConfigProvider::NullRouteConfigProvider() - : config_(new Router::NullConfigImpl()) {} +AdminImpl::NullRouteConfigProvider::NullRouteConfigProvider(TimeSource& time_source) + : config_(new Router::NullConfigImpl()), time_source_(time_source) {} AdminImpl::AdminImpl(const std::string& access_log_path, const std::string& profile_path, const std::string& address_out_path, @@ -867,6 +867,7 @@ AdminImpl::AdminImpl(const std::string& access_log_path, const std::string& prof stats_(Http::ConnectionManagerImpl::generateStats("http.admin.", server_.stats())), tracing_stats_( Http::ConnectionManagerImpl::generateTracingStats("http.admin.", no_op_store_)), + route_config_provider_(server.timeSource()), handlers_{ {"/", "Admin home page", MAKE_ADMIN_HANDLER(handlerAdminHome), false, false}, {"/certs", "print certs on machine", MAKE_ADMIN_HANDLER(handlerCerts), false, false}, diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 45ebeb391df3c..18203e8c5d6a3 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -133,16 +133,15 @@ class AdminImpl : public Admin, * Implementation of RouteConfigProvider that returns a static null route config. */ struct NullRouteConfigProvider : public Router::RouteConfigProvider { - NullRouteConfigProvider(); + NullRouteConfigProvider(TimeSource& time_source); // Router::RouteConfigProvider Router::ConfigConstSharedPtr config() override { return config_; } absl::optional configInfo() const override { return {}; } - SystemTime lastUpdated() const override { - return ProdSystemTimeSource::instance_.currentTime(); - } + SystemTime lastUpdated() const override { return time_source_.systemTime(); } Router::ConfigConstSharedPtr config_; + TimeSource time_source_; }; friend class AdminStatsTest; diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index 03afc4c08e1ed..a5bd2bc264de2 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -525,7 +525,7 @@ void ListenerImpl::debugLog(const std::string& message) { } void ListenerImpl::initialize() { - last_updated_ = systemTimeSource().currentTime(); + last_updated_ = timeSource().systemTime(); // If workers have already started, we shift from using the global init manager to using a local // per listener init manager. See ~ListenerImpl() for why we gate the onListenerWarmed() call // with initialize_canceled_. @@ -572,14 +572,13 @@ void ListenerImpl::setSocket(const Network::SocketSharedPtr& socket) { ListenerManagerImpl::ListenerManagerImpl(Instance& server, ListenerComponentFactory& listener_factory, - WorkerFactory& worker_factory, - SystemTimeSource& system_time_source) - : server_(server), system_time_source_(system_time_source), factory_(listener_factory), + WorkerFactory& worker_factory, TimeSource& time_source) + : server_(server), time_source_(time_source), factory_(listener_factory), stats_(generateStats(server.stats())), config_tracker_entry_(server.admin().getConfigTracker().add( "listeners", [this] { return dumpListenerConfigs(); })) { for (uint32_t i = 0; i < std::max(1U, server.options().concurrency()); i++) { - workers_.emplace_back(worker_factory.createWorker()); + workers_.emplace_back(worker_factory.createWorker(time_source_)); } } diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index acfe249b906d3..772ba5e2bc9f9 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -102,7 +102,7 @@ struct ListenerManagerStats { class ListenerManagerImpl : public ListenerManager, Logger::Loggable { public: ListenerManagerImpl(Instance& server, ListenerComponentFactory& listener_factory, - WorkerFactory& worker_factory, SystemTimeSource& system_time_source); + WorkerFactory& worker_factory, TimeSource& time_source); void onListenerWarmed(ListenerImpl& listener); @@ -121,7 +121,7 @@ class ListenerManagerImpl : public ListenerManager, Logger::LoggableallocateDispatcher()), + : options_(options), time_source_(time_source), restarter_(restarter), + start_time_(time(nullptr)), original_start_time_(start_time_), stats_store_(store), + thread_local_(tls), api_(new Api::Impl(options.fileFlushIntervalMsec())), + dispatcher_(api_->allocateDispatcher(time_source)), singleton_manager_(new Singleton::ManagerImpl()), handler_(new ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), random_generator_(std::move(random_generator)), listener_component_factory_(*this), @@ -207,7 +209,7 @@ void InstanceImpl::initialize(Options& options, // Handle configuration that needs to take place prior to the main configuration load. InstanceUtil::loadBootstrapConfig(bootstrap_, options); - bootstrap_config_update_time_ = ProdSystemTimeSource::instance_.currentTime(); + bootstrap_config_update_time_ = time_source_.systemTime(); // Needs to happen as early as possible in the instantiation to preempt the objects that require // stats. @@ -248,8 +250,8 @@ void InstanceImpl::initialize(Options& options, loadServerFlags(initial_config.flagsPath()); // Workers get created first so they register for thread local updates. - listener_manager_.reset(new ListenerManagerImpl( - *this, listener_component_factory_, worker_factory_, ProdSystemTimeSource::instance_)); + listener_manager_.reset( + new ListenerManagerImpl(*this, listener_component_factory_, worker_factory_, time_source_)); // The main thread is also registered for thread local updates so that code that does not care // whether it runs on the main thread or on workers can still use TLS. @@ -308,8 +310,7 @@ void InstanceImpl::initialize(Options& options, // GuardDog (deadlock detection) object and thread setup before workers are // started and before our own run() loop runs. - guard_dog_.reset( - new Server::GuardDogImpl(stats_store_, *config_, ProdMonotonicTimeSource::instance_)); + guard_dog_.reset(new Server::GuardDogImpl(stats_store_, *config_, time_source_)); } void InstanceImpl::startWorkers() { diff --git a/source/server/server.h b/source/server/server.h index 40cb5001539e0..0d8c7c1dbae8c 100644 --- a/source/server/server.h +++ b/source/server/server.h @@ -134,8 +134,9 @@ class InstanceImpl : Logger::Loggable, public Instance { /** * @throw EnvoyException if initialization fails. */ - InstanceImpl(Options& options, Network::Address::InstanceConstSharedPtr local_address, - TestHooks& hooks, HotRestart& restarter, Stats::StoreRoot& store, + InstanceImpl(Options& options, TimeSource& time_source, + Network::Address::InstanceConstSharedPtr local_address, TestHooks& hooks, + HotRestart& restarter, Stats::StoreRoot& store, Thread::BasicLockable& access_log_lock, ComponentFactory& component_factory, Runtime::RandomGeneratorPtr&& random_generator, ThreadLocal::Instance& tls); @@ -177,6 +178,7 @@ class InstanceImpl : Logger::Loggable, public Instance { Tracing::HttpTracer& httpTracer() override; ThreadLocal::Instance& threadLocal() override { return thread_local_; } const LocalInfo::LocalInfo& localInfo() override { return *local_info_; } + TimeSource& timeSource() override { return time_source_; } std::chrono::milliseconds statsFlushInterval() const override { return config_->statsFlushInterval(); @@ -193,6 +195,7 @@ class InstanceImpl : Logger::Loggable, public Instance { void terminate(); Options& options_; + TimeSource time_source_; HotRestart& restarter_; const time_t start_time_; time_t original_start_time_; diff --git a/source/server/watchdog_impl.h b/source/server/watchdog_impl.h index 68d06690eb005..dd0bd7fe580f7 100644 --- a/source/server/watchdog_impl.h +++ b/source/server/watchdog_impl.h @@ -20,9 +20,9 @@ class WatchDogImpl : public WatchDog { * @param thread_id A system thread ID (such as from Thread::currentThreadId()) * @param interval WatchDog timer interval (used after startWatchdog()) */ - WatchDogImpl(int32_t thread_id, MonotonicTimeSource& tsource, std::chrono::milliseconds interval) + WatchDogImpl(int32_t thread_id, TimeSource& tsource, std::chrono::milliseconds interval) : thread_id_(thread_id), time_source_(tsource), - latest_touch_time_since_epoch_(tsource.currentTime().time_since_epoch()), + latest_touch_time_since_epoch_(tsource.monotonicTime().time_since_epoch()), timer_interval_(interval) {} int32_t threadId() const override { return thread_id_; } @@ -33,12 +33,12 @@ class WatchDogImpl : public WatchDog { // Server::WatchDog void startWatchdog(Event::Dispatcher& dispatcher) override; void touch() override { - latest_touch_time_since_epoch_.store(time_source_.currentTime().time_since_epoch()); + latest_touch_time_since_epoch_.store(time_source_.monotonicTime().time_since_epoch()); } private: const int32_t thread_id_; - MonotonicTimeSource& time_source_; + TimeSource& time_source_; std::atomic latest_touch_time_since_epoch_; Event::TimerPtr timer_; const std::chrono::milliseconds timer_interval_; diff --git a/source/server/worker_impl.cc b/source/server/worker_impl.cc index 6c18db816944d..2ddd6d78b7bd1 100644 --- a/source/server/worker_impl.cc +++ b/source/server/worker_impl.cc @@ -14,8 +14,8 @@ namespace Envoy { namespace Server { -WorkerPtr ProdWorkerFactory::createWorker() { - Event::DispatcherPtr dispatcher(api_.allocateDispatcher()); +WorkerPtr ProdWorkerFactory::createWorker(TimeSource& time_source) { + Event::DispatcherPtr dispatcher(api_.allocateDispatcher(time_source)); return WorkerPtr{new WorkerImpl( tls_, hooks_, std::move(dispatcher), Network::ConnectionHandlerPtr{new ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher)})}; diff --git a/source/server/worker_impl.h b/source/server/worker_impl.h index ea018c3b73d59..98d6c6640546a 100644 --- a/source/server/worker_impl.h +++ b/source/server/worker_impl.h @@ -24,7 +24,7 @@ class ProdWorkerFactory : public WorkerFactory, Logger::Loggable time_source_; + NiceMock mock_system_time_; // not actually used in the test. + NiceMock mock_monotonic_time_; + TimeSource time_source_; }; // Verifies TokenBucket initialization. TEST_F(TokenBucketImplTest, Initialization) { - TokenBucketImpl token_bucket{1, -1.0, time_source_}; + TokenBucketImpl token_bucket{1, time_source_, -1.0}; EXPECT_TRUE(token_bucket.consume()); - EXPECT_CALL(time_source_, currentTime()).WillOnce(Return(time_point{})); + EXPECT_CALL(mock_monotonic_time_, currentTime()).WillOnce(Return(time_point{})); EXPECT_FALSE(token_bucket.consume()); } // Verifies TokenBucket's maximum capacity. TEST_F(TokenBucketImplTest, MaxBucketSize) { - TokenBucketImpl token_bucket{3, 1, time_source_}; + TokenBucketImpl token_bucket{3, time_source_, 1}; EXPECT_TRUE(token_bucket.consume(3)); - EXPECT_CALL(time_source_, currentTime()).WillOnce(Return(time_point(std::chrono::seconds(10)))); + EXPECT_CALL(mock_monotonic_time_, currentTime()) + .WillOnce(Return(time_point(std::chrono::seconds(10)))); EXPECT_FALSE(token_bucket.consume(4)); EXPECT_TRUE(token_bucket.consume(3)); @@ -44,36 +48,35 @@ TEST_F(TokenBucketImplTest, MaxBucketSize) { // Verifies that TokenBucket can consume and refill tokens. TEST_F(TokenBucketImplTest, ConsumeAndRefill) { { - TokenBucketImpl token_bucket{10, 1, time_source_}; + TokenBucketImpl token_bucket{10, time_source_, 1}; EXPECT_FALSE(token_bucket.consume(20)); EXPECT_TRUE(token_bucket.consume(9)); - EXPECT_CALL(time_source_, currentTime()).WillOnce(Return(time_point{})); + EXPECT_CALL(mock_monotonic_time_, currentTime()).WillOnce(Return(time_point{})); EXPECT_TRUE(token_bucket.consume()); - EXPECT_CALL(time_source_, currentTime()) + EXPECT_CALL(mock_monotonic_time_, currentTime()) .WillOnce(Return(time_point(std::chrono::milliseconds(999)))); EXPECT_FALSE(token_bucket.consume()); - EXPECT_CALL(time_source_, currentTime()) + EXPECT_CALL(mock_monotonic_time_, currentTime()) .WillOnce(Return(time_point(std::chrono::milliseconds(5999)))); EXPECT_FALSE(token_bucket.consume(6)); - EXPECT_CALL(time_source_, currentTime()) + EXPECT_CALL(mock_monotonic_time_, currentTime()) .WillRepeatedly(Return(time_point(std::chrono::milliseconds(6000)))); EXPECT_TRUE(token_bucket.consume(6)); EXPECT_FALSE(token_bucket.consume()); } - ASSERT_TRUE(Mock::VerifyAndClear(&time_source_)); + ASSERT_TRUE(Mock::VerifyAndClear(&mock_monotonic_time_)); { - TokenBucketImpl token_bucket{1, 0.5, time_source_}; - + TokenBucketImpl token_bucket{1, time_source_, 0.5}; EXPECT_TRUE(token_bucket.consume()); - EXPECT_CALL(time_source_, currentTime()) + EXPECT_CALL(mock_monotonic_time_, currentTime()) .Times(3) .WillOnce(Return(time_point(std::chrono::milliseconds(500)))) .WillOnce(Return(time_point(std::chrono::milliseconds(1500)))) @@ -83,7 +86,7 @@ TEST_F(TokenBucketImplTest, ConsumeAndRefill) { EXPECT_FALSE(token_bucket.consume()); EXPECT_TRUE(token_bucket.consume()); - ASSERT_TRUE(Mock::VerifyAndClear(&time_source_)); + ASSERT_TRUE(Mock::VerifyAndClear(&mock_monotonic_time_)); } } diff --git a/test/common/config/BUILD b/test/common/config/BUILD index 555bc63f7ec76..fb063659e5791 100644 --- a/test/common/config/BUILD +++ b/test/common/config/BUILD @@ -30,6 +30,7 @@ envoy_cc_test_library( "//source/common/event:dispatcher_lib", "//test/mocks/config:config_mocks", "//test/test_common:environment_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", "@envoy_api//envoy/api/v2:eds_cc", ], diff --git a/test/common/config/filesystem_subscription_test_harness.h b/test/common/config/filesystem_subscription_test_harness.h index 16a42f0543801..2104b447ab37f 100644 --- a/test/common/config/filesystem_subscription_test_harness.h +++ b/test/common/config/filesystem_subscription_test_harness.h @@ -9,6 +9,7 @@ #include "test/common/config/subscription_test_harness.h" #include "test/mocks/config/mocks.h" #include "test/test_common/environment.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -27,7 +28,7 @@ typedef FilesystemSubscriptionImpl class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { public: FilesystemSubscriptionTestHarness() - : path_(TestEnvironment::temporaryPath("eds.json")), + : path_(TestEnvironment::temporaryPath("eds.json")), dispatcher_(test_time_.timeSource()), subscription_(dispatcher_, path_, stats_) {} ~FilesystemSubscriptionTestHarness() { EXPECT_EQ(0, ::unlink(path_.c_str())); } @@ -94,6 +95,7 @@ class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { const std::string path_; std::string version_; + TestTime test_time_; Event::DispatcherImpl dispatcher_; NiceMock> callbacks_; FilesystemEdsSubscriptionImpl subscription_; diff --git a/test/common/config/grpc_mux_impl_test.cc b/test/common/config/grpc_mux_impl_test.cc index d0a1be52d76e3..02eebe2671b63 100644 --- a/test/common/config/grpc_mux_impl_test.cc +++ b/test/common/config/grpc_mux_impl_test.cc @@ -45,7 +45,7 @@ class GrpcMuxImplTest : public testing::Test { dispatcher_, *Protobuf::DescriptorPool::generated_pool()->FindMethodByName( "envoy.service.discovery.v2.AggregatedDiscoveryService.StreamAggregatedResources"), - random_, time_source_)); + random_)); } void expectSendMessage(const std::string& type_url, diff --git a/test/common/event/BUILD b/test/common/event/BUILD index 575787b6c01f6..b1aaef6114079 100644 --- a/test/common/event/BUILD +++ b/test/common/event/BUILD @@ -15,6 +15,7 @@ envoy_cc_test( "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", "//test/mocks:common_lib", + "//test/test_common:test_time_lib", ], ) @@ -27,6 +28,7 @@ envoy_cc_test( "//source/common/event:dispatcher_lib", "//test/mocks:common_lib", "//test/test_common:environment_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) @@ -41,5 +43,6 @@ envoy_cc_test( "//test/mocks:common_lib", "//test/mocks/server:server_mocks", "//test/mocks/stats:stats_mocks", + "//test/test_common:test_time_lib", ], ) diff --git a/test/common/event/dispatched_thread_impl_test.cc b/test/common/event/dispatched_thread_impl_test.cc index a177dcb6bd796..9f88e8b65d112 100644 --- a/test/common/event/dispatched_thread_impl_test.cc +++ b/test/common/event/dispatched_thread_impl_test.cc @@ -8,6 +8,7 @@ #include "test/mocks/common.h" #include "test/mocks/server/mocks.h" #include "test/mocks/stats/mocks.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -21,12 +22,13 @@ namespace Event { class DispatchedThreadTest : public testing::Test { protected: DispatchedThreadTest() - : config_(1000, 1000, 1000, 1000), guard_dog_(fakestats_, config_, time_source_) {} + : config_(1000, 1000, 1000, 1000), guard_dog_(fakestats_, config_, test_time_.timeSource()), + thread_(time_source_) {} void SetUp() { thread_.start(guard_dog_); } NiceMock config_; NiceMock fakestats_; - ProdMonotonicTimeSource time_source_; + TestTime test_time_; Envoy::Server::GuardDogImpl guard_dog_; DispatchedThreadImpl thread_; }; diff --git a/test/common/event/dispatcher_impl_test.cc b/test/common/event/dispatcher_impl_test.cc index 4b2abbf2e7e3d..c623d605b4af0 100644 --- a/test/common/event/dispatcher_impl_test.cc +++ b/test/common/event/dispatcher_impl_test.cc @@ -5,6 +5,7 @@ #include "common/event/dispatcher_impl.h" #include "test/mocks/common.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -25,7 +26,8 @@ class TestDeferredDeletable : public DeferredDeletable { TEST(DeferredDeleteTest, DeferredDelete) { InSequence s; - DispatcherImpl dispatcher; + TestTime test_time; + DispatcherImpl dispatcher(test_time.timeSource()); ReadyWatcher watcher1; dispatcher.deferredDelete( @@ -55,7 +57,9 @@ TEST(DeferredDeleteTest, DeferredDelete) { class DispatcherImplTest : public ::testing::Test { protected: - DispatcherImplTest() : dispatcher_(std::make_unique()), work_finished_(false) { + DispatcherImplTest() + : dispatcher_(std::make_unique(test_time_.timeSource())), + work_finished_(false) { dispatcher_thread_ = std::make_unique([this]() { // Must create a keepalive timer to keep the dispatcher from exiting. std::chrono::milliseconds time_interval(500); @@ -72,6 +76,8 @@ class DispatcherImplTest : public ::testing::Test { dispatcher_thread_->join(); } + TestTime test_time_; + std::unique_ptr dispatcher_thread_; DispatcherPtr dispatcher_; Thread::MutexBasicLockable mu_; diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index c2b7dd70e867e..9563b3dbbb011 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -6,6 +6,7 @@ #include "test/mocks/common.h" #include "test/test_common/environment.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gtest/gtest.h" @@ -15,6 +16,8 @@ namespace Event { class FileEventImplTest : public testing::Test { public: + FileEventImplTest() : dispatcher_(test_time_.timeSource()) {} + void SetUp() override { int rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds_); ASSERT_EQ(0, rc); @@ -30,6 +33,8 @@ class FileEventImplTest : public testing::Test { protected: int fds_[2]; + TestTime test_time_; + DispatcherImpl dispatcher_; }; class FileEventImplActivateTest : public testing::TestWithParam {}; @@ -47,7 +52,8 @@ TEST_P(FileEventImplActivateTest, Activate) { } ASSERT_NE(-1, fd); - DispatcherImpl dispatcher; + TestTime test_time; + DispatcherImpl dispatcher(test_time.timeSource()); ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(1); ReadyWatcher write_event; @@ -79,41 +85,39 @@ TEST_P(FileEventImplActivateTest, Activate) { } TEST_F(FileEventImplTest, EdgeTrigger) { - DispatcherImpl dispatcher; ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(1); ReadyWatcher write_event; EXPECT_CALL(write_event, ready()).Times(1); - Event::FileEventPtr file_event = - dispatcher.createFileEvent(fds_[0], - [&](uint32_t events) -> void { - if (events & FileReadyType::Read) { - read_event.ready(); - } + Event::FileEventPtr file_event = dispatcher_.createFileEvent( + fds_[0], + [&](uint32_t events) -> void { + if (events & FileReadyType::Read) { + read_event.ready(); + } - if (events & FileReadyType::Write) { - write_event.ready(); - } - }, - FileTriggerType::Edge, FileReadyType::Read | FileReadyType::Write); + if (events & FileReadyType::Write) { + write_event.ready(); + } + }, + FileTriggerType::Edge, FileReadyType::Read | FileReadyType::Write); - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } TEST_F(FileEventImplTest, LevelTrigger) { - DispatcherImpl dispatcher; ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(2); ReadyWatcher write_event; EXPECT_CALL(write_event, ready()).Times(2); int count = 2; - Event::FileEventPtr file_event = dispatcher.createFileEvent( + Event::FileEventPtr file_event = dispatcher_.createFileEvent( fds_[0], [&](uint32_t events) -> void { if (count-- == 0) { - dispatcher.exit(); + dispatcher_.exit(); return; } if (events & FileReadyType::Read) { @@ -126,40 +130,39 @@ TEST_F(FileEventImplTest, LevelTrigger) { }, FileTriggerType::Level, FileReadyType::Read | FileReadyType::Write); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } TEST_F(FileEventImplTest, SetEnabled) { - DispatcherImpl dispatcher; ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(2); ReadyWatcher write_event; EXPECT_CALL(write_event, ready()).Times(2); - Event::FileEventPtr file_event = - dispatcher.createFileEvent(fds_[0], - [&](uint32_t events) -> void { - if (events & FileReadyType::Read) { - read_event.ready(); - } + Event::FileEventPtr file_event = dispatcher_.createFileEvent( + fds_[0], + [&](uint32_t events) -> void { + if (events & FileReadyType::Read) { + read_event.ready(); + } - if (events & FileReadyType::Write) { - write_event.ready(); - } - }, - FileTriggerType::Edge, FileReadyType::Read | FileReadyType::Write); + if (events & FileReadyType::Write) { + write_event.ready(); + } + }, + FileTriggerType::Edge, FileReadyType::Read | FileReadyType::Write); file_event->setEnabled(FileReadyType::Read); - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); file_event->setEnabled(FileReadyType::Write); - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); file_event->setEnabled(0); - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); file_event->setEnabled(FileReadyType::Read | FileReadyType::Write); - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } } // namespace Event diff --git a/test/common/filesystem/BUILD b/test/common/filesystem/BUILD index 8ae711154adbf..c7ba54253d90e 100644 --- a/test/common/filesystem/BUILD +++ b/test/common/filesystem/BUILD @@ -36,5 +36,6 @@ envoy_cc_test( "//source/common/event:dispatcher_lib", "//source/common/filesystem:watcher_lib", "//test/test_common:environment_lib", + "//test/test_common:test_time_lib", ], ) diff --git a/test/common/filesystem/watcher_impl_test.cc b/test/common/filesystem/watcher_impl_test.cc index 5f78c0ecd17f7..02eee16321338 100644 --- a/test/common/filesystem/watcher_impl_test.cc +++ b/test/common/filesystem/watcher_impl_test.cc @@ -6,6 +6,7 @@ #include "common/filesystem/watcher_impl.h" #include "test/test_common/environment.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -13,14 +14,21 @@ namespace Envoy { namespace Filesystem { +class WatcherImplTest : public testing::Test { +protected: + WatcherImplTest() : dispatcher_(test_time_.timeSource()) {} + + TestTime test_time_; + Event::DispatcherImpl dispatcher_; +}; + class WatchCallback { public: MOCK_METHOD1(called, void(uint32_t)); }; -TEST(WatcherImplTest, All) { - Event::DispatcherImpl dispatcher; - Filesystem::WatcherPtr watcher = dispatcher.createFilesystemWatcher(); +TEST_F(WatcherImplTest, All) { + Filesystem::WatcherPtr watcher = dispatcher_.createFilesystemWatcher(); unlink(TestEnvironment::temporaryPath("envoy_test/watcher_target").c_str()); unlink(TestEnvironment::temporaryPath("envoy_test/watcher_link").c_str()); @@ -43,24 +51,23 @@ TEST(WatcherImplTest, All) { watcher->addWatch(TestEnvironment::temporaryPath("envoy_test/watcher_link"), Watcher::Events::MovedTo, [&](uint32_t events) -> void { callback.called(events); - dispatcher.exit(); + dispatcher_.exit(); }); rename(TestEnvironment::temporaryPath("envoy_test/watcher_new_link").c_str(), TestEnvironment::temporaryPath("envoy_test/watcher_link").c_str()); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); rc = symlink(TestEnvironment::temporaryPath("envoy_test/watcher_new_target").c_str(), TestEnvironment::temporaryPath("envoy_test/watcher_new_link").c_str()); EXPECT_EQ(0, rc); rename(TestEnvironment::temporaryPath("envoy_test/watcher_new_link").c_str(), TestEnvironment::temporaryPath("envoy_test/watcher_link").c_str()); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } -TEST(WatcherImplTest, Create) { - Event::DispatcherImpl dispatcher; - Filesystem::WatcherPtr watcher = dispatcher.createFilesystemWatcher(); +TEST_F(WatcherImplTest, Create) { + Filesystem::WatcherPtr watcher = dispatcher_.createFilesystemWatcher(); unlink(TestEnvironment::temporaryPath("envoy_test/watcher_target").c_str()); unlink(TestEnvironment::temporaryPath("envoy_test/watcher_link").c_str()); @@ -75,11 +82,11 @@ TEST(WatcherImplTest, Create) { watcher->addWatch(TestEnvironment::temporaryPath("envoy_test/watcher_link"), Watcher::Events::MovedTo, [&](uint32_t events) -> void { callback.called(events); - dispatcher.exit(); + dispatcher_.exit(); }); { std::ofstream file(TestEnvironment::temporaryPath("envoy_test/other_file")); } - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); int rc = symlink(TestEnvironment::temporaryPath("envoy_test/watcher_target").c_str(), TestEnvironment::temporaryPath("envoy_test/watcher_new_link").c_str()); @@ -89,12 +96,11 @@ TEST(WatcherImplTest, Create) { TestEnvironment::temporaryPath("envoy_test/watcher_link").c_str()); EXPECT_EQ(0, rc); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } -TEST(WatcherImplTest, BadPath) { - Event::DispatcherImpl dispatcher; - Filesystem::WatcherPtr watcher = dispatcher.createFilesystemWatcher(); +TEST_F(WatcherImplTest, BadPath) { + Filesystem::WatcherPtr watcher = dispatcher_.createFilesystemWatcher(); EXPECT_THROW( watcher->addWatch("this_is_not_a_file", Watcher::Events::MovedTo, [&](uint32_t) -> void {}), @@ -105,9 +111,8 @@ TEST(WatcherImplTest, BadPath) { EnvoyException); } -TEST(WatcherImplTest, ParentDirectoryRemoved) { - Event::DispatcherImpl dispatcher; - Filesystem::WatcherPtr watcher = dispatcher.createFilesystemWatcher(); +TEST_F(WatcherImplTest, ParentDirectoryRemoved) { + Filesystem::WatcherPtr watcher = dispatcher_.createFilesystemWatcher(); mkdir(TestEnvironment::temporaryPath("envoy_test_empty").c_str(), S_IRWXU); @@ -121,12 +126,11 @@ TEST(WatcherImplTest, ParentDirectoryRemoved) { int rc = rmdir(TestEnvironment::temporaryPath("envoy_test_empty").c_str()); EXPECT_EQ(0, rc); - dispatcher.run(Event::Dispatcher::RunType::NonBlock); + dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } -TEST(WatcherImplTest, RootDirectoryPath) { - Event::DispatcherImpl dispatcher; - Filesystem::WatcherPtr watcher = dispatcher.createFilesystemWatcher(); +TEST_F(WatcherImplTest, RootDirectoryPath) { + Filesystem::WatcherPtr watcher = dispatcher_.createFilesystemWatcher(); EXPECT_NO_THROW(watcher->addWatch("/", Watcher::Events::MovedTo, [&](uint32_t) -> void {})); } diff --git a/test/common/grpc/BUILD b/test/common/grpc/BUILD index 3294b133c88aa..c606429af441d 100644 --- a/test/common/grpc/BUILD +++ b/test/common/grpc/BUILD @@ -67,6 +67,7 @@ envoy_cc_test( "//test/mocks/grpc:grpc_mocks", "//test/mocks/tracing:tracing_mocks", "//test/proto:helloworld_proto", + "//test/test_common:test_time_lib", ] + envoy_select_google_grpc(["//source/common/grpc:google_async_client_lib"]), ) diff --git a/test/common/grpc/google_async_client_impl_test.cc b/test/common/grpc/google_async_client_impl_test.cc index 01a03a21850df..f4d73ab3a5d5a 100644 --- a/test/common/grpc/google_async_client_impl_test.cc +++ b/test/common/grpc/google_async_client_impl_test.cc @@ -7,6 +7,7 @@ #include "test/mocks/grpc/mocks.h" #include "test/mocks/tracing/mocks.h" #include "test/proto/helloworld.pb.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -44,7 +45,8 @@ class MockStubFactory : public GoogleStubFactory { class EnvoyGoogleAsyncClientImplTest : public testing::Test { public: EnvoyGoogleAsyncClientImplTest() - : method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")) { + : dispatcher_(test_time_.timeSource()), + method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")) { envoy::api::v2::core::GrpcService config; auto* google_grpc = config.mutable_google_grpc(); google_grpc->set_target_uri("fake_address"); @@ -54,6 +56,7 @@ class EnvoyGoogleAsyncClientImplTest : public testing::Test { stats_store_, config); } + TestTime test_time_; Event::DispatcherImpl dispatcher_; std::unique_ptr tls_; MockStubFactory stub_factory_; diff --git a/test/common/http/BUILD b/test/common/http/BUILD index 13c84e925b469..c34295d1e6568 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -28,6 +28,7 @@ envoy_cc_test( "//test/mocks/runtime:runtime_mocks", "//test/mocks/stats:stats_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", ], ) @@ -51,6 +52,7 @@ envoy_cc_test( "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) @@ -121,6 +123,7 @@ envoy_cc_fuzz_test( "//test/mocks/ssl:ssl_mocks", "//test/mocks/tracing:tracing_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", "@envoy_api//envoy/config/filter/network/http_connection_manager/v2:http_connection_manager_cc", ], ) @@ -160,6 +163,7 @@ envoy_cc_test( "//test/mocks/ssl:ssl_mocks", "//test/mocks/tracing:tracing_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", ], ) diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index e902232c7705a..9909e4b879b1d 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -18,6 +18,7 @@ #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -59,6 +60,7 @@ class CodecClientTest : public testing::Test { ~CodecClientTest() { EXPECT_EQ(0U, client_->numActiveRequests()); } + TestTime test_time_; Event::MockDispatcher dispatcher_; Network::MockClientConnection* connection_; Http::MockClientConnection* codec_; @@ -260,7 +262,7 @@ TEST_F(CodecClientTest, WatermarkPassthrough) { class CodecNetworkTest : public testing::TestWithParam { public: CodecNetworkTest() { - dispatcher_.reset(new Event::DispatcherImpl); + dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); upstream_listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket(), nullptr); @@ -326,6 +328,7 @@ class CodecNetworkTest : public testing::TestWithParam configInfo() const override { return {}; } - SystemTime lastUpdated() const override { - return ProdSystemTimeSource::instance_.currentTime(); - } + SystemTime lastUpdated() const override { return time_source_.systemTime(); } + TimeSource& time_source_; std::shared_ptr route_config_{new NiceMock()}; }; FuzzConfig() - : stats_{{ALL_HTTP_CONN_MAN_STATS(POOL_COUNTER(fake_stats_), POOL_GAUGE(fake_stats_), + : route_config_provider_(test_time_.timeSource()), + stats_{{ALL_HTTP_CONN_MAN_STATS(POOL_COUNTER(fake_stats_), POOL_GAUGE(fake_stats_), POOL_HISTOGRAM(fake_stats_))}, "", fake_stats_}, @@ -114,6 +117,7 @@ class FuzzConfig : public ConnectionManagerConfig { MockStreamEncoderFilter* encoder_filter_{}; NiceMock filter_factory_; absl::optional idle_timeout_; + TestTime test_time_; RouteConfigProvider route_config_provider_; std::string server_name_; Stats::IsolatedStoreImpl fake_stats_; diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index 013385aab6272..abf498ea095f3 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -38,6 +38,7 @@ #include "test/mocks/tracing/mocks.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -62,18 +63,19 @@ namespace Http { class HttpConnectionManagerImplTest : public Test, public ConnectionManagerConfig { public: struct RouteConfigProvider : public Router::RouteConfigProvider { + RouteConfigProvider(TimeSource& time_source) : time_source_(time_source) {} + // Router::RouteConfigProvider Router::ConfigConstSharedPtr config() override { return route_config_; } absl::optional configInfo() const override { return {}; } - SystemTime lastUpdated() const override { - return ProdSystemTimeSource::instance_.currentTime(); - } + SystemTime lastUpdated() const override { return time_source_.systemTime(); } + TimeSource& time_source_; std::shared_ptr route_config_{new NiceMock()}; }; HttpConnectionManagerImplTest() - : access_log_path_("dummy_path"), + : route_config_provider_(test_time_.timeSource()), access_log_path_("dummy_path"), access_logs_{ AccessLog::InstanceSharedPtr{new Extensions::AccessLoggers::File::FileAccessLog( access_log_path_, {}, AccessLog::AccessLogFormatUtils::defaultAccessLogFormatter(), @@ -274,6 +276,8 @@ class HttpConnectionManagerImplTest : public Test, public ConnectionManagerConfi bool proxy100Continue() const override { return proxy_100_continue_; } const Http::Http1Settings& http1Settings() const override { return http1_settings_; } + TestTime test_time_; + RouteConfigProvider route_config_provider_; NiceMock tracer_; NiceMock runtime_; NiceMock log_manager_; @@ -299,7 +303,6 @@ class HttpConnectionManagerImplTest : public Test, public ConnectionManagerConfi NiceMock local_info_; NiceMock factory_context_; std::unique_ptr ssl_connection_; - RouteConfigProvider route_config_provider_; TracingConnectionManagerConfigPtr tracing_config_; SlowDateProviderImpl date_provider_; MockStream stream_; diff --git a/test/common/http/http1/BUILD b/test/common/http/http1/BUILD index e685bff6f3288..66da7a23b6e86 100644 --- a/test/common/http/http1/BUILD +++ b/test/common/http/http1/BUILD @@ -45,6 +45,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/mocks/runtime:runtime_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index 0c396d8818fd6..1fa4c31310bf0 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -17,6 +17,7 @@ #include "test/mocks/runtime/mocks.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -79,7 +80,7 @@ class ConnPoolImplForTest : public ConnPoolImpl { test_client.codec_ = new NiceMock(); test_client.connect_timer_ = new NiceMock(&mock_dispatcher_); std::shared_ptr cluster{new NiceMock()}; - test_client.client_dispatcher_.reset(new Event::DispatcherImpl); + test_client.client_dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); Network::ClientConnectionPtr connection{test_client.connection_}; test_client.codec_client_ = new CodecClientForTest( std::move(connection), test_client.codec_, @@ -110,6 +111,7 @@ class ConnPoolImplForTest : public ConnPoolImpl { EXPECT_FALSE(upstream_ready_enabled_); } + TestTime test_time_; Event::MockDispatcher& mock_dispatcher_; NiceMock* mock_upstream_ready_timer_; std::vector test_clients_; diff --git a/test/common/http/http2/BUILD b/test/common/http/http2/BUILD index b9f7908934b73..f08f4f6237984 100644 --- a/test/common/http/http2/BUILD +++ b/test/common/http/http2/BUILD @@ -65,5 +65,6 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/mocks/runtime:runtime_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", ], ) diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 659676f8b8b13..2893d15aa0df4 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -15,6 +15,7 @@ #include "test/mocks/runtime/mocks.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -77,7 +78,7 @@ class Http2ConnPoolImplTest : public testing::Test { test_client.connection_ = new NiceMock(); test_client.codec_ = new NiceMock(); test_client.connect_timer_ = new NiceMock(&dispatcher_); - test_client.client_dispatcher_.reset(new Event::DispatcherImpl); + test_client.client_dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); std::shared_ptr cluster{new NiceMock()}; Network::ClientConnectionPtr connection{test_client.connection_}; @@ -101,6 +102,7 @@ class Http2ConnPoolImplTest : public testing::Test { MOCK_METHOD0(onClientDestroy, void()); + TestTime test_time_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; Upstream::HostSharedPtr host_{Upstream::makeTestHost(cluster_, "tcp://127.0.0.1:80")}; diff --git a/test/common/network/BUILD b/test/common/network/BUILD index fe0fdd4198c8d..ba4eadec52082 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -51,6 +51,7 @@ envoy_cc_test( "//test/mocks/stats:stats_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", + "//test/test_common:test_time_lib", ], ) @@ -72,6 +73,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) @@ -139,6 +141,7 @@ envoy_cc_test( "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index abb352e02f06a..0aa1ea1e84887 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -20,6 +20,7 @@ #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -76,7 +77,8 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ConnectionImplDeathTest, TestUtility::ipTestParamsToString); TEST_P(ConnectionImplDeathTest, BadFd) { - Event::DispatcherImpl dispatcher; + TestTime test_time; + Event::DispatcherImpl dispatcher(test_time.timeSource()); EXPECT_DEATH_LOG_TO_STDERR( ConnectionImpl(dispatcher, std::make_unique(-1, nullptr, nullptr), Network::Test::createRawBufferSocket(), false), @@ -87,7 +89,7 @@ class ConnectionImplTest : public testing::TestWithParam { public: void setUpBasicConnection() { if (dispatcher_.get() == nullptr) { - dispatcher_.reset(new Event::DispatcherImpl); + dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); } listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); @@ -149,7 +151,8 @@ class ConnectionImplTest : public testing::TestWithParam { ASSERT(dispatcher_.get() == nullptr); MockBufferFactory* factory = new StrictMock; - dispatcher_.reset(new Event::DispatcherImpl(Buffer::WatermarkFactoryPtr{factory})); + dispatcher_.reset( + new Event::DispatcherImpl(test_time_.timeSource(), Buffer::WatermarkFactoryPtr{factory})); // The first call to create a client session will get a MockBuffer. // Other calls for server sessions will by default get a normal OwnedImpl. EXPECT_CALL(*factory, create_(_, _)) @@ -166,6 +169,7 @@ class ConnectionImplTest : public testing::TestWithParam { } protected: + TestTime test_time_; Event::DispatcherPtr dispatcher_; Stats::IsolatedStoreImpl stats_store_; Network::TcpListenSocket socket_{Network::Test::getAnyAddress(GetParam()), nullptr, true}; @@ -229,7 +233,7 @@ TEST_P(ConnectionImplTest, CloseDuringConnectCallback) { } TEST_P(ConnectionImplTest, ImmediateConnectError) { - dispatcher_.reset(new Event::DispatcherImpl); + dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); // Using a broadcast/multicast address as the connection destiantion address causes an // immediate error return from connect(). @@ -801,7 +805,7 @@ TEST_P(ConnectionImplTest, BindFailureTest) { source_address_ = Network::Address::InstanceConstSharedPtr{ new Network::Address::Ipv6Instance(address_string, 0)}; } - dispatcher_.reset(new Event::DispatcherImpl); + dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); client_connection_ = dispatcher_->createClientConnection( @@ -1195,7 +1199,7 @@ class ReadBufferLimitTest : public ConnectionImplTest { public: void readBufferLimitTest(uint32_t read_buffer_limit, uint32_t expected_chunk_size) { const uint32_t buffer_size = 256 * 1024; - dispatcher_.reset(new Event::DispatcherImpl); + dispatcher_.reset(new Event::DispatcherImpl(test_time_.timeSource())); listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); client_connection_ = dispatcher_->createClientConnection( @@ -1264,13 +1268,17 @@ TEST_P(ReadBufferLimitTest, SomeLimit) { readBufferLimitTest(read_buffer_limit, read_buffer_limit - 1 + 16384); } -class TcpClientConnectionImplTest : public testing::TestWithParam {}; +class TcpClientConnectionImplTest : public testing::TestWithParam { +protected: + TcpClientConnectionImplTest() : dispatcher_(test_time_.timeSource()) {} + TestTime test_time_; + Event::DispatcherImpl dispatcher_; +}; INSTANTIATE_TEST_CASE_P(IpVersions, TcpClientConnectionImplTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), TestUtility::ipTestParamsToString); TEST_P(TcpClientConnectionImplTest, BadConnectNotConnRefused) { - Event::DispatcherImpl dispatcher; Address::InstanceConstSharedPtr address; if (GetParam() == Network::Address::IpVersion::v4) { // Connecting to 255.255.255.255 will cause a perm error and not ECONNREFUSED which is a @@ -1281,25 +1289,24 @@ TEST_P(TcpClientConnectionImplTest, BadConnectNotConnRefused) { address = Utility::resolveUrl("tcp://[ff00::]:1"); } ClientConnectionPtr connection = - dispatcher.createClientConnection(address, Network::Address::InstanceConstSharedPtr(), - Network::Test::createRawBufferSocket(), nullptr); + dispatcher_.createClientConnection(address, Network::Address::InstanceConstSharedPtr(), + Network::Test::createRawBufferSocket(), nullptr); connection->connect(); connection->noDelay(true); connection->close(ConnectionCloseType::NoFlush); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } TEST_P(TcpClientConnectionImplTest, BadConnectConnRefused) { - Event::DispatcherImpl dispatcher; // Connecting to an invalid port on localhost will cause ECONNREFUSED which is a different code // path from other errors. Test this also. - ClientConnectionPtr connection = dispatcher.createClientConnection( + ClientConnectionPtr connection = dispatcher_.createClientConnection( Utility::resolveUrl( fmt::format("tcp://{}:1", Network::Test::getLoopbackAddressUrlString(GetParam()))), Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr); connection->connect(); connection->noDelay(true); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } } // namespace Network diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 026cfa58bc9c6..a5a5c1bb3f956 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -25,6 +25,7 @@ #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "ares.h" @@ -319,15 +320,21 @@ class DnsResolverImplPeer { DnsResolverImpl* resolver_; }; -TEST(DnsImplConstructor, SupportsCustomResolvers) { - Event::DispatcherImpl dispatcher; +class DnsImplConstructor : public testing::Test { +protected: + DnsImplConstructor() : dispatcher_(test_time_.timeSource()) {} + TestTime test_time_; + Event::DispatcherImpl dispatcher_; +}; + +TEST_F(DnsImplConstructor, SupportsCustomResolvers) { char addr4str[INET_ADDRSTRLEN]; // we pick a port that isn't 53 as the default resolve.conf might be // set to point to localhost. auto addr4 = Network::Utility::parseInternetAddressAndPort("127.0.0.1:54"); char addr6str[INET6_ADDRSTRLEN]; auto addr6 = Network::Utility::parseInternetAddressAndPort("[::1]:54"); - auto resolver = dispatcher.createDnsResolver({addr4, addr6}); + auto resolver = dispatcher_.createDnsResolver({addr4, addr6}); auto peer = std::unique_ptr{ new DnsResolverImplPeer(dynamic_cast(resolver.get()))}; ares_addr_port_node* resolvers; @@ -369,11 +376,10 @@ class CustomInstance : public Address::Instance { Address::Ipv4Instance instance_; }; -TEST(DnsImplConstructor, SupportCustomAddressInstances) { - Event::DispatcherImpl dispatcher; +TEST_F(DnsImplConstructor, SupportCustomAddressInstances) { auto test_instance(std::make_shared("127.0.0.1", 45)); EXPECT_EQ(test_instance->asString(), "127.0.0.1:borked_port_45"); - auto resolver = dispatcher.createDnsResolver({test_instance}); + auto resolver = dispatcher_.createDnsResolver({test_instance}); auto peer = std::unique_ptr{ new DnsResolverImplPeer(dynamic_cast(resolver.get()))}; ares_addr_port_node* resolvers; @@ -386,17 +392,18 @@ TEST(DnsImplConstructor, SupportCustomAddressInstances) { ares_free_data(resolvers); } -TEST(DnsImplConstructor, BadCustomResolvers) { - Event::DispatcherImpl dispatcher; +TEST_F(DnsImplConstructor, BadCustomResolvers) { envoy::api::v2::core::Address pipe_address; pipe_address.mutable_pipe()->set_path("foo"); auto pipe_instance = Network::Utility::protobufAddressToAddress(pipe_address); - EXPECT_THROW_WITH_MESSAGE(dispatcher.createDnsResolver({pipe_instance}), EnvoyException, + EXPECT_THROW_WITH_MESSAGE(dispatcher_.createDnsResolver({pipe_instance}), EnvoyException, "DNS resolver 'foo' is not an IP address"); } class DnsImplTest : public testing::TestWithParam { public: + DnsImplTest() : dispatcher_(test_time_.timeSource()) {} + void SetUp() override { resolver_ = dispatcher_.createDnsResolver({}); @@ -427,6 +434,7 @@ class DnsImplTest : public testing::TestWithParam { Network::TcpListenSocketPtr socket_; Stats::IsolatedStoreImpl stats_store_; std::unique_ptr listener_; + TestTime test_time_; Event::DispatcherImpl dispatcher_; DnsResolverSharedPtr resolver_; }; diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index 76b4bfc1345c3..7e180a9c51058 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -6,6 +6,7 @@ #include "test/mocks/server/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -22,7 +23,8 @@ static void errorCallbackTest(Address::IpVersion version) { // Force the error callback to fire by closing the socket under the listener. We run this entire // test in the forked process to avoid confusion when the fork happens. Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; + TestTime test_time; + Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); @@ -76,10 +78,13 @@ class ListenerImplTest : public testing::TestWithParam { ListenerImplTest() : version_(GetParam()), alt_address_(Network::Test::findOrCheckFreePort( - Network::Test::getCanonicalLoopbackAddress(version_), Address::SocketType::Stream)) {} + Network::Test::getCanonicalLoopbackAddress(version_), Address::SocketType::Stream)), + dispatcher_(test_time_.timeSource()) {} const Address::IpVersion version_; const Address::InstanceConstSharedPtr alt_address_; + TestTime test_time_; + Event::DispatcherImpl dispatcher_; }; INSTANTIATE_TEST_CASE_P(IpVersions, ListenerImplTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), @@ -87,7 +92,6 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ListenerImplTest, // Test that socket options are set after the listener is setup. TEST_P(ListenerImplTest, SetListeningSocketOptionsSuccess) { - Event::DispatcherImpl dispatcher; Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; @@ -97,12 +101,11 @@ TEST_P(ListenerImplTest, SetListeningSocketOptionsSuccess) { socket.addOption(option); EXPECT_CALL(*option, setOption(_, envoy::api::v2::core::SocketOption::STATE_LISTENING)) .WillOnce(Return(true)); - TestListenerImpl listener(dispatcher, socket, listener_callbacks, true, false); + TestListenerImpl listener(dispatcher_, socket, listener_callbacks, true, false); } // Test that an exception is thrown if there is an error setting socket options. TEST_P(ListenerImplTest, SetListeningSocketOptionsError) { - Event::DispatcherImpl dispatcher; Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; @@ -112,7 +115,7 @@ TEST_P(ListenerImplTest, SetListeningSocketOptionsError) { socket.addOption(option); EXPECT_CALL(*option, setOption(_, envoy::api::v2::core::SocketOption::STATE_LISTENING)) .WillOnce(Return(false)); - EXPECT_THROW_WITH_MESSAGE(TestListenerImpl(dispatcher, socket, listener_callbacks, true, false), + EXPECT_THROW_WITH_MESSAGE(TestListenerImpl(dispatcher_, socket, listener_callbacks, true, false), CreateListenerException, fmt::format("cannot set post-listen socket option on socket: {}", socket.localAddress()->asString())); @@ -120,18 +123,17 @@ TEST_P(ListenerImplTest, SetListeningSocketOptionsError) { TEST_P(ListenerImplTest, UseActualDst) { Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version_), nullptr, true); Network::TcpListenSocket socketDst(alt_address_, nullptr, false); Network::MockListenerCallbacks listener_callbacks1; Network::MockConnectionHandler connection_handler; // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks1, true, true); + Network::TestListenerImpl listener(dispatcher_, socket, listener_callbacks1, true, true); Network::MockListenerCallbacks listener_callbacks2; - Network::TestListenerImpl listenerDst(dispatcher, socketDst, listener_callbacks2, false, false); + Network::TestListenerImpl listenerDst(dispatcher_, socketDst, listener_callbacks2, false, false); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr); client_connection->connect(); @@ -141,7 +143,7 @@ TEST_P(ListenerImplTest, UseActualDst) { EXPECT_CALL(listener_callbacks2, onAccept_(_, _)).Times(0); EXPECT_CALL(listener_callbacks1, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_.createServerConnection( std::move(socket), Network::Test::createRawBufferSocket()); listener_callbacks1.onNewConnection(std::move(new_connection)); })); @@ -150,24 +152,23 @@ TEST_P(ListenerImplTest, UseActualDst) { EXPECT_EQ(*conn->localAddress(), *socket.localAddress()); client_connection->close(ConnectionCloseType::NoFlush); conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); + dispatcher_.exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getAnyAddress(version_), nullptr, true); Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks, true, true); + Network::TestListenerImpl listener(dispatcher_, socket, listener_callbacks, true, true); auto local_dst_address = Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(version_), socket.localAddress()->ip()->port()); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_.createClientConnection( local_dst_address, Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr); client_connection->connect(); @@ -176,7 +177,7 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { EXPECT_CALL(listener_callbacks, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_.createServerConnection( std::move(socket), Network::Test::createRawBufferSocket()); listener_callbacks.onNewConnection(std::move(new_connection)); })); @@ -185,10 +186,10 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { EXPECT_EQ(*conn->localAddress(), *local_dst_address); client_connection->close(ConnectionCloseType::NoFlush); conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); + dispatcher_.exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } // Test for the correct behavior when a listener is configured with an ANY address that allows @@ -197,7 +198,6 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { // is an IPv4 connection. TEST_P(ListenerImplTest, WildcardListenerIpv4Compat) { Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; auto option = std::make_unique(); auto options = std::make_shared>(); EXPECT_CALL(*option, setOption(_, envoy::api::v2::core::SocketOption::STATE_PREBIND)) @@ -211,13 +211,13 @@ TEST_P(ListenerImplTest, WildcardListenerIpv4Compat) { ASSERT_TRUE(socket.localAddress()->ip()->isAnyAddress()); // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks, true, true); + Network::TestListenerImpl listener(dispatcher_, socket, listener_callbacks, true, true); auto listener_address = Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(version_), socket.localAddress()->ip()->port()); auto local_dst_address = Network::Utility::getAddressWithPort( *Network::Utility::getCanonicalIpv4LoopbackAddress(), socket.localAddress()->ip()->port()); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_.createClientConnection( local_dst_address, Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr); client_connection->connect(); @@ -228,7 +228,7 @@ TEST_P(ListenerImplTest, WildcardListenerIpv4Compat) { EXPECT_CALL(listener_callbacks, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_.createServerConnection( std::move(socket), Network::Test::createRawBufferSocket()); listener_callbacks.onNewConnection(std::move(new_connection)); })); @@ -238,10 +238,10 @@ TEST_P(ListenerImplTest, WildcardListenerIpv4Compat) { EXPECT_EQ(*conn->localAddress(), *local_dst_address); client_connection->close(ConnectionCloseType::NoFlush); conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); + dispatcher_.exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_.run(Event::Dispatcher::RunType::Block); } } // namespace Network diff --git a/test/common/ssl/BUILD b/test/common/ssl/BUILD index 70a45354264f9..91c5364d7fd82 100644 --- a/test/common/ssl/BUILD +++ b/test/common/ssl/BUILD @@ -41,6 +41,7 @@ envoy_cc_test( "//test/mocks/stats:stats_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 219de0e829551..960ddccb1f621 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -24,7 +24,7 @@ #include "test/mocks/stats/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" -#include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -59,7 +59,8 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - Event::DispatcherImpl dispatcher; + TestTime test_time; + Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); Network::MockListenerCallbacks callbacks; @@ -162,7 +163,8 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, server_names); - Event::DispatcherImpl dispatcher; + TestTime test_time; + Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); NiceMock callbacks; @@ -294,7 +296,13 @@ void configureServerAndExpiredClientCertificate(envoy::api::v2::Listener& listen } // namespace class SslSocketTest : public SslCertsTest, - public testing::WithParamInterface {}; + public testing::WithParamInterface { +protected: + SslSocketTest() : dispatcher_(std::make_unique(test_time_.timeSource())) {} + + TestTime test_time_; + std::unique_ptr dispatcher_; +}; INSTANTIATE_TEST_CASE_P(IpVersions, SslSocketTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), @@ -1541,14 +1549,13 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); + Network::ListenerPtr listener = dispatcher_->createListener(socket, callbacks, true, false); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr); client_connection->connect(); @@ -1559,7 +1566,7 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_->createServerConnection( std::move(socket), server_ssl_socket_factory.createTransportSocket()); callbacks.onNewConnection(std::move(new_connection)); })); @@ -1575,9 +1582,9 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { EXPECT_CALL(server_connection_callbacks, onEvent(Network::ConnectionEvent::LocalClose)); EXPECT_CALL(client_connection_callbacks, onEvent(Network::ConnectionEvent::Connected)); EXPECT_CALL(client_connection_callbacks, onEvent(Network::ConnectionEvent::RemoteClose)) - .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher.exit(); })); + .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_->run(Event::Dispatcher::RunType::Block); } // Test that half-close is sent and received correctly @@ -1599,13 +1606,12 @@ TEST_P(SslSocketTest, HalfClose) { Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; Network::ListenerPtr listener = - dispatcher.createListener(socket, listener_callbacks, true, false); + dispatcher_->createListener(socket, listener_callbacks, true, false); std::shared_ptr server_read_filter(new Network::MockReadFilter()); std::shared_ptr client_read_filter(new Network::MockReadFilter()); @@ -1617,7 +1623,7 @@ TEST_P(SslSocketTest, HalfClose) { Json::ObjectSharedPtr client_ctx_loader = TestEnvironment::jsonLoadFromString(client_ctx_json); auto client_cfg = std::make_unique(*client_ctx_loader, secret_manager_); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, stats_store); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), client_ssl_socket_factory.createTransportSocket(), nullptr); client_connection->enableHalfClose(true); @@ -1630,7 +1636,7 @@ TEST_P(SslSocketTest, HalfClose) { Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(listener_callbacks, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_->createServerConnection( std::move(socket), server_ssl_socket_factory.createTransportSocket()); listener_callbacks.onNewConnection(std::move(new_connection)); })); @@ -1659,9 +1665,9 @@ TEST_P(SslSocketTest, HalfClose) { EXPECT_CALL(client_connection_callbacks, onEvent(Network::ConnectionEvent::LocalClose)); EXPECT_CALL(*server_read_filter, onData(BufferStringEqual("world"), true)); EXPECT_CALL(server_connection_callbacks, onEvent(Network::ConnectionEvent::RemoteClose)) - .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher.exit(); })); + .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_->run(Event::Dispatcher::RunType::Block); } TEST_P(SslSocketTest, ClientAuthMultipleCAs) { @@ -1683,12 +1689,11 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); + Network::ListenerPtr listener = dispatcher_->createListener(socket, callbacks, true, false); std::string client_ctx_json = R"EOF( { @@ -1700,7 +1705,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Json::ObjectSharedPtr client_ctx_loader = TestEnvironment::jsonLoadFromString(client_ctx_json); auto client_cfg = std::make_unique(*client_ctx_loader, secret_manager); ClientSslSocketFactory ssl_socket_factory(std::move(client_cfg), manager, stats_store); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), ssl_socket_factory.createTransportSocket(), nullptr); @@ -1721,7 +1726,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_->createServerConnection( std::move(socket), server_ssl_socket_factory.createTransportSocket()); callbacks.onNewConnection(std::move(new_connection)); })); @@ -1735,11 +1740,11 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { server_connection->close(Network::ConnectionCloseType::NoFlush); client_connection->close(Network::ConnectionCloseType::NoFlush); - dispatcher.exit(); + dispatcher_->exit(); })); EXPECT_CALL(server_connection_callbacks, onEvent(Network::ConnectionEvent::LocalClose)); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_->run(Event::Dispatcher::RunType::Block); EXPECT_EQ(1UL, stats_store.counter("ssl.handshake").value()); } @@ -1767,13 +1772,14 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, Ssl::ServerSslSocketFactory server_ssl_socket_factory2(std::move(server_cfg2), manager, stats_store, server_names2); - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket1(Network::Test::getCanonicalLoopbackAddress(ip_version), nullptr, true); Network::TcpListenSocket socket2(Network::Test::getCanonicalLoopbackAddress(ip_version), nullptr, true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; + TestTime test_time; + Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true, false); Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); @@ -2128,15 +2134,14 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { Ssl::ServerSslSocketFactory server2_ssl_socket_factory(std::move(server2_cfg), manager, stats_store, std::vector{}); - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); Network::TcpListenSocket socket2(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); - Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); + Network::ListenerPtr listener = dispatcher_->createListener(socket, callbacks, true, false); + Network::ListenerPtr listener2 = dispatcher_->createListener(socket2, callbacks, true, false); std::string client_ctx_json = R"EOF( { @@ -2148,7 +2153,7 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { Json::ObjectSharedPtr client_ctx_loader = TestEnvironment::jsonLoadFromString(client_ctx_json); auto client_cfg = std::make_unique(*client_ctx_loader, secret_manager_); ClientSslSocketFactory ssl_socket_factory(std::move(client_cfg), manager, stats_store); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), ssl_socket_factory.createTransportSocket(), nullptr); @@ -2165,7 +2170,7 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { accepted_socket->localAddress() == socket.localAddress() ? server_ssl_socket_factory : server2_ssl_socket_factory; - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_->createServerConnection( std::move(accepted_socket), tsf.createTransportSocket()); callbacks.onNewConnection(std::move(new_connection)); })); @@ -2184,16 +2189,16 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { EXPECT_TRUE(SSL_SESSION_is_resumable(ssl_session)); server_connection->close(Network::ConnectionCloseType::NoFlush); client_connection->close(Network::ConnectionCloseType::NoFlush); - dispatcher.exit(); + dispatcher_->exit(); })); EXPECT_CALL(client_connection_callbacks, onEvent(Network::ConnectionEvent::LocalClose)); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_->run(Event::Dispatcher::RunType::Block); // 1 for client, 1 for server EXPECT_EQ(2UL, stats_store.counter("ssl.handshake").value()); - client_connection = dispatcher.createClientConnection( + client_connection = dispatcher_->createClientConnection( socket2.localAddress(), Network::Address::InstanceConstSharedPtr(), ssl_socket_factory.createTransportSocket(), nullptr); client_connection->addConnectionCallbacks(client_connection_callbacks); @@ -2210,9 +2215,9 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { })); EXPECT_CALL(server_connection_callbacks, onEvent(Network::ConnectionEvent::RemoteClose)); EXPECT_CALL(client_connection_callbacks, onEvent(Network::ConnectionEvent::RemoteClose)) - .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher.exit(); })); + .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_->run(Event::Dispatcher::RunType::Block); EXPECT_EQ(1UL, stats_store.counter("ssl.connection_error").value()); EXPECT_EQ(0UL, stats_store.counter("ssl.session_reused").value()); @@ -2237,14 +2242,13 @@ TEST_P(SslSocketTest, SslError) { Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - Event::DispatcherImpl dispatcher; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); + Network::ListenerPtr listener = dispatcher_->createListener(socket, callbacks, true, false); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( + Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr); client_connection->connect(); @@ -2255,7 +2259,7 @@ TEST_P(SslSocketTest, SslError) { Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { - Network::ConnectionPtr new_connection = dispatcher.createServerConnection( + Network::ConnectionPtr new_connection = dispatcher_->createServerConnection( std::move(socket), server_ssl_socket_factory.createTransportSocket()); callbacks.onNewConnection(std::move(new_connection)); })); @@ -2268,10 +2272,10 @@ TEST_P(SslSocketTest, SslError) { EXPECT_CALL(server_connection_callbacks, onEvent(Network::ConnectionEvent::RemoteClose)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { client_connection->close(Network::ConnectionCloseType::NoFlush); - dispatcher.exit(); + dispatcher_->exit(); })); - dispatcher.run(Event::Dispatcher::RunType::Block); + dispatcher_->run(Event::Dispatcher::RunType::Block); EXPECT_EQ(1UL, stats_store.counter("ssl.connection_error").value()); } @@ -2570,8 +2574,7 @@ TEST_P(SslSocketTest, GetRequestedServerName) { GetParam()); } -class SslReadBufferLimitTest : public SslCertsTest, - public testing::WithParamInterface { +class SslReadBufferLimitTest : public SslSocketTest { public: void initialize() { server_ctx_loader_ = TestEnvironment::jsonLoadFromString(server_ctx_json_); @@ -2664,7 +2667,8 @@ class SslReadBufferLimitTest : public SslCertsTest, void singleWriteTest(uint32_t read_buffer_limit, uint32_t bytes_to_write) { MockWatermarkBuffer* client_write_buffer = nullptr; MockBufferFactory* factory = new StrictMock; - dispatcher_.reset(new Event::DispatcherImpl(Buffer::WatermarkFactoryPtr{factory})); + dispatcher_.reset( + new Event::DispatcherImpl(test_time_.timeSource(), Buffer::WatermarkFactoryPtr{factory})); // By default, expect 4 buffers to be created - the client and server read and write buffers. EXPECT_CALL(*factory, create_(_, _)) @@ -2732,7 +2736,6 @@ class SslReadBufferLimitTest : public SslCertsTest, } Stats::IsolatedStoreImpl stats_store_; - Event::DispatcherPtr dispatcher_{new Event::DispatcherImpl}; Network::TcpListenSocket socket_{Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true}; Network::MockListenerCallbacks listener_callbacks_; diff --git a/test/common/thread_local/BUILD b/test/common/thread_local/BUILD index f731091ec6896..26049fc8c07c9 100644 --- a/test/common/thread_local/BUILD +++ b/test/common/thread_local/BUILD @@ -15,5 +15,6 @@ envoy_cc_test( "//source/common/event:dispatcher_lib", "//source/common/thread_local:thread_local_lib", "//test/mocks/event:event_mocks", + "//test/test_common:test_time_lib", ], ) diff --git a/test/common/thread_local/thread_local_impl_test.cc b/test/common/thread_local/thread_local_impl_test.cc index 5726f41658955..d6cd08e96ae43 100644 --- a/test/common/thread_local/thread_local_impl_test.cc +++ b/test/common/thread_local/thread_local_impl_test.cc @@ -2,6 +2,7 @@ #include "common/thread_local/thread_local_impl.h" #include "test/mocks/event/mocks.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" @@ -113,8 +114,10 @@ TEST_F(ThreadLocalInstanceImplTest, RunOnAllThreads) { // Validate ThreadLocal::InstanceImpl's dispatcher() behavior. TEST(ThreadLocalInstanceImplDispatcherTest, Dispatcher) { InstanceImpl tls; - Event::DispatcherImpl main_dispatcher; - Event::DispatcherImpl thread_dispatcher; + + TestTime test_time; + Event::DispatcherImpl main_dispatcher(test_time.timeSource()); + Event::DispatcherImpl thread_dispatcher(test_time.timeSource()); tls.registerThread(main_dispatcher, true); tls.registerThread(thread_dispatcher, false); diff --git a/test/extensions/tracers/zipkin/BUILD b/test/extensions/tracers/zipkin/BUILD index e6d81b9e8dee4..61220ae4e468e 100644 --- a/test/extensions/tracers/zipkin/BUILD +++ b/test/extensions/tracers/zipkin/BUILD @@ -39,6 +39,7 @@ envoy_extension_cc_test( "//test/mocks/thread_local:thread_local_mocks", "//test/mocks/tracing:tracing_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/extensions/tracers/zipkin/util_test.cc b/test/extensions/tracers/zipkin/util_test.cc index 0b27f554b2dfa..ac99224bd4984 100644 --- a/test/extensions/tracers/zipkin/util_test.cc +++ b/test/extensions/tracers/zipkin/util_test.cc @@ -1,5 +1,7 @@ #include "extensions/tracers/zipkin/util.h" +#include "test/test_common/test_time.h" + #include "gtest/gtest.h" namespace Envoy { @@ -8,7 +10,8 @@ namespace Tracers { namespace Zipkin { TEST(ZipkinUtilTest, utilTests) { - EXPECT_EQ(typeid(uint64_t).name(), typeid(Util::generateRandom64()).name()); + TestTime time; + EXPECT_EQ(typeid(uint64_t).name(), typeid(Util::generateRandom64(time.timeSource())).name()); // Test JSON merging diff --git a/test/integration/BUILD b/test/integration/BUILD index 002c019fbb019..d51da268ef29d 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -300,6 +300,7 @@ envoy_cc_test_library( "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", "//test/test_common:printers_lib", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 29f2289a5ce98..02677e1aacbec 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -1,4 +1,4 @@ -#include "fake_upstream.h" +#include "test/integration/fake_upstream.h" #include #include @@ -19,6 +19,7 @@ #include "server/connection_handler_impl.h" +#include "test/integration/utility.h" #include "test/test_common/network_utility.h" #include "test/test_common/printers.h" #include "test/test_common/utility.h" @@ -356,7 +357,7 @@ FakeUpstream::FakeUpstream(Network::TransportSocketFactoryPtr&& transport_socket Network::SocketPtr&& listen_socket, FakeHttpConnection::Type type, bool enable_half_close) : http_type_(type), socket_(std::move(listen_socket)), api_(new Api::Impl(milliseconds(10000))), - dispatcher_(api_->allocateDispatcher()), + dispatcher_(api_->allocateDispatcher(test_time_.timeSource())), handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), allow_unexpected_disconnects_(false), enable_half_close_(enable_half_close), listener_(*this), filter_chain_(Network::Test::createEmptyFilterChain(std::move(transport_socket_factory))) { diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index 052ac04e60df3..aa8dbc7bcbfce 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -28,6 +28,7 @@ #include "common/stats/isolated_store_impl.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" namespace Envoy { @@ -580,6 +581,7 @@ class FakeUpstream : Logger::Loggable, Thread::ThreadPtr thread_; Thread::CondVar new_connection_event_; Api::ApiPtr api_; + TestTime test_time_; Event::DispatcherPtr dispatcher_; Network::ConnectionHandlerPtr handler_; std::list new_connections_ GUARDED_BY(lock_); diff --git a/test/integration/integration.cc b/test/integration/integration.cc index b91be75da80d3..ba10deab6ab38 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -214,8 +214,8 @@ BaseIntegrationTest::BaseIntegrationTest(Network::Address::IpVersion version, const std::string& config) : api_(new Api::Impl(std::chrono::milliseconds(10000))), mock_buffer_factory_(new NiceMock), - dispatcher_(new Event::DispatcherImpl(Buffer::WatermarkFactoryPtr{mock_buffer_factory_})), - version_(version), config_helper_(version, config), + dispatcher_(new Event::DispatcherImpl(test_time_.timeSource())), version_(version), + config_helper_(version, config), default_log_level_(TestEnvironment::getOptions().logLevel()) { // This is a hack, but there are situations where we disconnect fake upstream connections and // then we expect the server connection pool to get the disconnect before the next test starts. diff --git a/test/integration/integration.h b/test/integration/integration.h index e558362850188..0d53cbe517d1c 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -14,6 +14,7 @@ #include "test/mocks/buffer/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "spdlog/spdlog.h" @@ -160,6 +161,8 @@ class BaseIntegrationTest : Logger::Loggable { const std::vector& port_names); Api::ApiPtr api_; + TestTime test_time_; + MockBufferFactory* mock_buffer_factory_; // Will point to the dispatcher's factory. Event::DispatcherPtr dispatcher_; diff --git a/test/integration/utility.cc b/test/integration/utility.cc index ffae1f6701516..fee1011e4ad74 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -53,13 +53,16 @@ void BufferingStreamDecoder::onComplete() { void BufferingStreamDecoder::onResetStream(Http::StreamResetReason) { ADD_FAILURE(); } +TestTime IntegrationUtil::evil_singleton_test_time_; + BufferingStreamDecoderPtr IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPtr& addr, const std::string& method, const std::string& url, const std::string& body, Http::CodecClient::Type type, const std::string& host, const std::string& content_type) { + Api::Impl api(std::chrono::milliseconds(9000)); - Event::DispatcherPtr dispatcher(api.allocateDispatcher()); + Event::DispatcherPtr dispatcher(api.allocateDispatcher(evil_singleton_test_time_.timeSource())); std::shared_ptr cluster{new NiceMock()}; Upstream::HostDescriptionConstSharedPtr host_description{ Upstream::makeTestHostDescription(cluster, "tcp://127.0.0.1:80")}; @@ -107,7 +110,7 @@ RawConnectionDriver::RawConnectionDriver(uint32_t port, Buffer::Instance& initia ReadCallback data_callback, Network::Address::IpVersion version) { api_.reset(new Api::Impl(std::chrono::milliseconds(10000))); - dispatcher_ = api_->allocateDispatcher(); + dispatcher_ = api_->allocateDispatcher(IntegrationUtil::evil_singleton_test_time_.timeSource()); client_ = dispatcher_->createClientConnection( Network::Utility::resolveUrl( fmt::format("tcp://{}:{}", Network::Test::getLoopbackAddressUrlString(version), port)), diff --git a/test/integration/utility.h b/test/integration/utility.h index a4b4c5d99c394..59f85feb4b728 100644 --- a/test/integration/utility.h +++ b/test/integration/utility.h @@ -11,9 +11,11 @@ #include "envoy/network/filter.h" #include "common/common/assert.h" +#include "common/common/utility.h" #include "common/http/codec_client.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" namespace Envoy { /** @@ -123,6 +125,9 @@ class IntegrationUtil { const std::string& body, Http::CodecClient::Type type, Network::Address::IpVersion ip_version, const std::string& host = "host", const std::string& content_type = ""); + + // TODO(jmarantz): this should be injectable. + static TestTime evil_singleton_test_time_; }; // A set of connection callbacks which tracks connection state. diff --git a/test/mocks/api/mocks.h b/test/mocks/api/mocks.h index 66898518b17a1..82a2eaf7412a3 100644 --- a/test/mocks/api/mocks.h +++ b/test/mocks/api/mocks.h @@ -23,11 +23,11 @@ class MockApi : public Api { ~MockApi(); // Api::Api - Event::DispatcherPtr allocateDispatcher() override { - return Event::DispatcherPtr{allocateDispatcher_()}; + Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) override { + return Event::DispatcherPtr{allocateDispatcher_(time_source)}; } - MOCK_METHOD0(allocateDispatcher_, Event::Dispatcher*()); + MOCK_METHOD1(allocateDispatcher_, Event::Dispatcher*(TimeSource&)); MOCK_METHOD4(createFile, Filesystem::FileSharedPtr(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, Stats::Store& stats_store)); diff --git a/test/mocks/common.h b/test/mocks/common.h index 70f6bb6f569d1..0dbdd828c4efc 100644 --- a/test/mocks/common.h +++ b/test/mocks/common.h @@ -40,7 +40,7 @@ class MockSystemTimeSource : public SystemTimeSource { MockSystemTimeSource(); ~MockSystemTimeSource(); - MOCK_METHOD0(currentTime, SystemTime()); + MOCK_CONST_METHOD0(currentTime, SystemTime()); }; class MockMonotonicTimeSource : public MonotonicTimeSource { @@ -48,7 +48,7 @@ class MockMonotonicTimeSource : public MonotonicTimeSource { MockMonotonicTimeSource(); ~MockMonotonicTimeSource(); - MOCK_METHOD0(currentTime, MonotonicTime()); + MOCK_CONST_METHOD0(currentTime, MonotonicTime()); }; class MockTokenBucket : public TokenBucket { diff --git a/test/mocks/event/mocks.cc b/test/mocks/event/mocks.cc index 402d25b17a879..8baf6741ee576 100644 --- a/test/mocks/event/mocks.cc +++ b/test/mocks/event/mocks.cc @@ -13,7 +13,7 @@ using testing::_; namespace Envoy { namespace Event { -MockDispatcher::MockDispatcher() { +MockDispatcher::MockDispatcher() : time_source_(system_time_, monotonic_time_) { ON_CALL(*this, clearDeferredDeleteList()).WillByDefault(Invoke([this]() -> void { to_delete_.clear(); })); diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 643bb7120faf1..3485aedfe8471 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -29,6 +29,7 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); + TimeSource& timeSource() override { return time_source_; } Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, Network::TransportSocketPtr&& transport_socket) override { @@ -102,6 +103,11 @@ class MockDispatcher : public Dispatcher { MOCK_METHOD1(run, void(RunType type)); Buffer::WatermarkFactory& getWatermarkFactory() override { return buffer_factory_; } + // TODO(jmarantz): Switch these to using mock-time. + ProdSystemTimeSource system_time_; + ProdMonotonicTimeSource monotonic_time_; + TimeSource time_source_; + std::list to_delete_; MockBufferFactory buffer_factory_; }; diff --git a/test/mocks/server/mocks.cc b/test/mocks/server/mocks.cc index 4905f3bbdad4a..f945607cee7f2 100644 --- a/test/mocks/server/mocks.cc +++ b/test/mocks/server/mocks.cc @@ -143,7 +143,9 @@ MockMain::MockMain(int wd_miss, int wd_megamiss, int wd_kill, int wd_multikill) ON_CALL(*this, wdMultiKillTimeout()).WillByDefault(Return(wd_multikill_)); } -MockFactoryContext::MockFactoryContext() : singleton_manager_(new Singleton::ManagerImpl()) { +MockFactoryContext::MockFactoryContext() + : singleton_manager_(new Singleton::ManagerImpl()), + time_source_(system_time_source_, monotonic_time_source_) { ON_CALL(*this, accessLogManager()).WillByDefault(ReturnRef(access_log_manager_)); ON_CALL(*this, clusterManager()).WillByDefault(ReturnRef(cluster_manager_)); ON_CALL(*this, dispatcher()).WillByDefault(ReturnRef(dispatcher_)); @@ -159,6 +161,7 @@ MockFactoryContext::MockFactoryContext() : singleton_manager_(new Singleton::Man ON_CALL(*this, admin()).WillByDefault(ReturnRef(admin_)); ON_CALL(*this, listenerScope()).WillByDefault(ReturnRef(listener_scope_)); ON_CALL(*this, systemTimeSource()).WillByDefault(ReturnRef(system_time_source_)); + ON_CALL(*this, monotonicTimeSource()).WillByDefault(ReturnRef(monotonic_time_source_)); } MockFactoryContext::~MockFactoryContext() {} diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index b43691cbd2b1d..9d2daffc2212d 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -234,9 +234,11 @@ class MockWorkerFactory : public WorkerFactory { ~MockWorkerFactory(); // Server::WorkerFactory - WorkerPtr createWorker() override { return WorkerPtr{createWorker_()}; } + WorkerPtr createWorker(TimeSource& time_source) override { + return WorkerPtr{createWorker_(time_source)}; + } - MOCK_METHOD0(createWorker_, Worker*()); + MOCK_METHOD1(createWorker_, Worker*(TimeSource&)); }; class MockWorker : public Worker { @@ -401,6 +403,8 @@ class MockFactoryContext : public FactoryContext { MOCK_CONST_METHOD0(localInfo, const LocalInfo::LocalInfo&()); MOCK_CONST_METHOD0(listenerMetadata, const envoy::api::v2::core::Metadata&()); MOCK_METHOD0(systemTimeSource, SystemTimeSource&()); + MOCK_METHOD0(monotonicTimeSource, MonotonicTimeSource&()); + MOCK_METHOD0(timeSource, TimeSource&()); testing::NiceMock access_log_manager_; testing::NiceMock cluster_manager_; @@ -417,6 +421,8 @@ class MockFactoryContext : public FactoryContext { testing::NiceMock admin_; Stats::IsolatedStoreImpl listener_scope_; testing::NiceMock system_time_source_; + testing::NiceMock monotonic_time_source_; + TimeSource time_source_; }; class MockTransportSocketFactoryContext : public TransportSocketFactoryContext { diff --git a/test/mocks/upstream/mocks.cc b/test/mocks/upstream/mocks.cc index f4f1bbc1a8e2c..541867cb45995 100644 --- a/test/mocks/upstream/mocks.cc +++ b/test/mocks/upstream/mocks.cc @@ -86,7 +86,7 @@ MockThreadLocalCluster::MockThreadLocalCluster() { MockThreadLocalCluster::~MockThreadLocalCluster() {} -MockClusterManager::MockClusterManager() { +MockClusterManager::MockClusterManager() : time_source_(system_time_, monotonic_time_) { ON_CALL(*this, httpConnPoolForCluster(_, _, _, _)).WillByDefault(Return(&conn_pool_)); ON_CALL(*this, tcpConnPoolForCluster(_, _, _)).WillByDefault(Return(&tcp_conn_pool_)); ON_CALL(*this, httpAsyncClientForCluster(_)).WillByDefault(ReturnRef(async_client_)); diff --git a/test/mocks/upstream/mocks.h b/test/mocks/upstream/mocks.h index 5ad05945a5826..33ad3c6cb1fb4 100644 --- a/test/mocks/upstream/mocks.h +++ b/test/mocks/upstream/mocks.h @@ -190,6 +190,7 @@ class MockClusterManager : public ClusterManager { ClusterManagerFactory& clusterManagerFactory() override { return cluster_manager_factory_; } // Upstream::ClusterManager + MOCK_METHOD0(timeSource, TimeSource&()); MOCK_METHOD2(addOrUpdateCluster, bool(const envoy::api::v2::Cluster& cluster, const std::string& version_info)); MOCK_METHOD1(setInitializedCb, void(std::function)); @@ -216,6 +217,11 @@ class MockClusterManager : public ClusterManager { MOCK_METHOD1(addThreadLocalClusterUpdateCallbacks, std::unique_ptr(ClusterUpdateCallbacks& callbacks)); + // TODO(jmarantz): Switch these to using mock-time. + ProdSystemTimeSource system_time_; + ProdMonotonicTimeSource monotonic_time_; + TimeSource time_source_; + NiceMock conn_pool_; NiceMock async_client_; NiceMock tcp_conn_pool_; diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index aa38340100fcc..46f0a4679295d 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -7,6 +7,7 @@ #include "server/config_validation/api.h" +//#include "test/mocks/common.h" #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/utility.h" @@ -22,9 +23,10 @@ class ConfigValidation : public ::testing::TestWithParam(std::chrono::milliseconds(1000)); - dispatcher_ = validation_->allocateDispatcher(); + dispatcher_ = validation_->allocateDispatcher(test_time_.timeSource()); } + TestTime test_time_; Event::DispatcherPtr dispatcher_; private: diff --git a/test/test_common/BUILD b/test/test_common/BUILD index d861e0b99ec73..0d7db72237ce0 100644 --- a/test/test_common/BUILD +++ b/test/test_common/BUILD @@ -110,6 +110,15 @@ envoy_cc_library( ], ) +envoy_cc_test_library( + name = "test_time_lib", + srcs = ["test_time.cc"], + hdrs = ["test_time.h"], + deps = [ + "//source/common/common:utility_lib", + ], +) + envoy_cc_library( name = "tls_utility_lib", srcs = ["tls_utility.cc"], diff --git a/test/test_common/test_time.cc b/test/test_common/test_time.cc new file mode 100644 index 0000000000000..da3eb4f5414d2 --- /dev/null +++ b/test/test_common/test_time.cc @@ -0,0 +1,9 @@ +#include "test/test_common/test_time.h" + +#include "common/common/utility.h" + +namespace Envoy { + +TestTime::TestTime() : time_source_(system_time_, monotonic_time_) {} + +} // namespace Envoy diff --git a/test/test_common/test_time.h b/test/test_common/test_time.h new file mode 100644 index 0000000000000..16873d9f36b94 --- /dev/null +++ b/test/test_common/test_time.h @@ -0,0 +1,19 @@ +#pragma once + +#include "common/common/utility.h" + +namespace Envoy { + +class TestTime { +public: + TestTime(); + + TimeSource& timeSource() { return time_source_; } + + // TODO(jmarantz): Switch these to using mock-time. + ProdSystemTimeSource system_time_; + ProdMonotonicTimeSource monotonic_time_; + TimeSource time_source_; +}; + +} // namespace Envoy From 7d59de4884f913eded6622bb9c28516618207875 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 16 Aug 2018 11:06:40 -0400 Subject: [PATCH 02/22] checkpoint with more stuff compiling, a few tests still fail due to changed mocks. Signed-off-by: Joshua Marantz --- source/common/http/async_client_impl.cc | 2 +- source/common/router/router.h | 13 +++++-------- source/common/upstream/cluster_manager_impl.h | 7 ++++++- test/common/config/grpc_mux_impl_test.cc | 12 ++++++++---- test/common/event/dispatched_thread_impl_test.cc | 2 +- test/common/grpc/BUILD | 1 + .../grpc/grpc_client_integration_test_harness.h | 5 ++++- test/integration/server.cc | 3 ++- test/integration/server.h | 2 ++ test/mocks/event/BUILD | 1 + test/mocks/event/mocks.cc | 2 +- test/mocks/event/mocks.h | 11 +++++++---- test/mocks/server/mocks.cc | 5 +++-- test/mocks/server/mocks.h | 4 +++- 14 files changed, 45 insertions(+), 25 deletions(-) diff --git a/source/common/http/async_client_impl.cc b/source/common/http/async_client_impl.cc index 3f458595fa738..ad9671cbf0ffd 100644 --- a/source/common/http/async_client_impl.cc +++ b/source/common/http/async_client_impl.cc @@ -37,7 +37,7 @@ AsyncClientImpl::AsyncClientImpl(const Upstream::ClusterInfo& cluster, Stats::St Router::ShadowWriterPtr&& shadow_writer) : cluster_(cluster), config_("http.async-client.", local_info, stats_store, cm, runtime, random, - std::move(shadow_writer), true, false, false, dispatcher.timeSource()), + std::move(shadow_writer), true, false, false), dispatcher_(dispatcher) {} AsyncClientImpl::~AsyncClientImpl() { diff --git a/source/common/router/router.h b/source/common/router/router.h index 5ad9f6ceea820..79684fd1df936 100644 --- a/source/common/router/router.h +++ b/source/common/router/router.h @@ -96,13 +96,11 @@ class FilterConfig { FilterConfig(const std::string& stat_prefix, const LocalInfo::LocalInfo& local_info, Stats::Scope& scope, Upstream::ClusterManager& cm, Runtime::Loader& runtime, Runtime::RandomGenerator& random, ShadowWriterPtr&& shadow_writer, - bool emit_dynamic_stats, bool start_child_span, bool suppress_envoy_headers, - TimeSource& time_source) + bool emit_dynamic_stats, bool start_child_span, bool suppress_envoy_headers) : scope_(scope), local_info_(local_info), cm_(cm), runtime_(runtime), random_(random), stats_{ALL_ROUTER_STATS(POOL_COUNTER_PREFIX(scope, stat_prefix))}, emit_dynamic_stats_(emit_dynamic_stats), start_child_span_(start_child_span), - suppress_envoy_headers_(suppress_envoy_headers), time_source_(time_source), - shadow_writer_(std::move(shadow_writer)) {} + suppress_envoy_headers_(suppress_envoy_headers), shadow_writer_(std::move(shadow_writer)) {} FilterConfig(const std::string& stat_prefix, Server::Configuration::FactoryContext& context, ShadowWriterPtr&& shadow_writer, @@ -110,14 +108,14 @@ class FilterConfig { : FilterConfig(stat_prefix, context.localInfo(), context.scope(), context.clusterManager(), context.runtime(), context.random(), std::move(shadow_writer), PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, dynamic_stats, true), - config.start_child_span(), config.suppress_envoy_headers(), - context.timeSource()) { + config.start_child_span(), config.suppress_envoy_headers()) { for (const auto& upstream_log : config.upstream_log()) { upstream_logs_.push_back(AccessLog::AccessLogFactory::fromProto(upstream_log, context)); } } ShadowWriter& shadowWriter() { return *shadow_writer_; } + TimeSource& timeSource() { return cm_.timeSource(); } Stats::Scope& scope_; const LocalInfo::LocalInfo& local_info_; @@ -128,7 +126,6 @@ class FilterConfig { const bool emit_dynamic_stats_; const bool start_child_span_; const bool suppress_envoy_headers_; - TimeSource& time_source_; std::list upstream_logs_; private: @@ -349,7 +346,7 @@ class Filter : Logger::Loggable, // Called immediately after a non-5xx header is received from upstream, performs stats accounting // and handle difference between gRPC and non-gRPC requests. void handleNon5xxResponseHeaders(const Http::HeaderMap& headers, bool end_stream); - TimeSource& timeSource() { return config_.time_source_; } + TimeSource& timeSource() { return config_.timeSource(); } FilterConfig& config_; Http::StreamDecoderFilterCallbacks* callbacks_{}; diff --git a/source/common/upstream/cluster_manager_impl.h b/source/common/upstream/cluster_manager_impl.h index 0de5f17f12925..30cd9c05239a4 100644 --- a/source/common/upstream/cluster_manager_impl.h +++ b/source/common/upstream/cluster_manager_impl.h @@ -165,7 +165,9 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggable grpc_mux_; NiceMock callbacks_; - NiceMock time_source_; + NiceMock mock_system_time_; + NiceMock mock_monotonic_time_; + TimeSource mock_time_source_; }; // Validate behavior when multiple type URL watches are maintained, watches are created/destroyed @@ -298,7 +302,7 @@ TEST_F(GrpcMuxImplTest, WatchDemux) { TEST_F(GrpcMuxImplTest, TooManyRequests) { EXPECT_CALL(async_stream_, sendMessage(_, false)).Times(AtLeast(100)); EXPECT_CALL(*async_client_, start(_, _)).WillOnce(Return(&async_stream_)); - EXPECT_CALL(time_source_, currentTime()) + EXPECT_CALL(mock_monotonic_time_, currentTime()) .WillRepeatedly(Return(std::chrono::steady_clock::time_point{})); const auto onReceiveMessage = [&](uint64_t burst) { @@ -324,7 +328,7 @@ TEST_F(GrpcMuxImplTest, TooManyRequests) { onReceiveMessage(1)); // Logging limiter waits for 5s, so a second warning message is expected. - EXPECT_CALL(time_source_, currentTime()) + EXPECT_CALL(mock_monotonic_time_, currentTime()) .Times(4) .WillOnce(Return(std::chrono::steady_clock::time_point{})) .WillOnce(Return(std::chrono::steady_clock::time_point{std::chrono::seconds(5)})) diff --git a/test/common/event/dispatched_thread_impl_test.cc b/test/common/event/dispatched_thread_impl_test.cc index 9f88e8b65d112..079b94f0751c0 100644 --- a/test/common/event/dispatched_thread_impl_test.cc +++ b/test/common/event/dispatched_thread_impl_test.cc @@ -23,7 +23,7 @@ class DispatchedThreadTest : public testing::Test { protected: DispatchedThreadTest() : config_(1000, 1000, 1000, 1000), guard_dog_(fakestats_, config_, test_time_.timeSource()), - thread_(time_source_) {} + thread_(test_time_.timeSource()) {} void SetUp() { thread_.start(guard_dog_); } NiceMock config_; diff --git a/test/common/grpc/BUILD b/test/common/grpc/BUILD index c606429af441d..b9c1e88b8fbc4 100644 --- a/test/common/grpc/BUILD +++ b/test/common/grpc/BUILD @@ -100,6 +100,7 @@ envoy_cc_test_library( "//test/integration:integration_lib", "//test/mocks/local_info:local_info_mocks", "//test/proto:helloworld_proto", + "//test/test_common:test_time_lib", ], ) diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 2c3dfcf89026b..0ed1ee3aa0711 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -18,6 +18,7 @@ #include "test/mocks/upstream/mocks.h" #include "test/proto/helloworld.pb.h" #include "test/test_common/environment.h" +#include "test/test_common/test_time.h" using testing::Invoke; using testing::InvokeWithoutArgs; @@ -202,7 +203,8 @@ class HelloworldRequest : public MockAsyncRequestCallbacksFindMethodByName("SayHello")) {} + : method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")), + dispatcher_(test_time_.timeSource()) {} virtual void initialize() { if (fake_upstream_ == nullptr) { @@ -393,6 +395,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { FakeHttpConnectionPtr fake_connection_; std::vector fake_streams_; const Protobuf::MethodDescriptor* method_descriptor_; + TestTime test_time_; Event::DispatcherImpl dispatcher_; DispatcherHelper dispatcher_helper_{dispatcher_}; Stats::IsolatedStoreImpl* stats_store_ = new Stats::IsolatedStoreImpl(); diff --git a/test/integration/server.cc b/test/integration/server.cc index eb84cfe8ad911..71d99fe472f58 100644 --- a/test/integration/server.cc +++ b/test/integration/server.cc @@ -102,7 +102,8 @@ void IntegrationTestServer::threadRoutine(const Network::Address::IpVersion vers } else { random_generator = std::make_unique(); } - server_.reset(new Server::InstanceImpl(options, Network::Utility::getLocalAddress(version), *this, + server_.reset(new Server::InstanceImpl(options, test_time_.timeSource(), + Network::Utility::getLocalAddress(version), *this, restarter, stats_store, lock, *this, std::move(random_generator), tls)); pending_listeners_ = server_->listenerManager().listeners().size(); diff --git a/test/integration/server.h b/test/integration/server.h index 3c1e65b9b1f6c..da3d106f99945 100644 --- a/test/integration/server.h +++ b/test/integration/server.h @@ -19,6 +19,7 @@ #include "server/test_hooks.h" #include "test/integration/server_stats.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" namespace Envoy { @@ -301,6 +302,7 @@ class IntegrationTestServer : Logger::Loggable, Thread::CondVar listeners_cv_; Thread::MutexBasicLockable listeners_mutex_; uint64_t pending_listeners_; + TestTime test_time_; ConditionalInitializer server_set_; std::unique_ptr server_; Server::TestDrainManager* drain_manager_{}; diff --git a/test/mocks/event/BUILD b/test/mocks/event/BUILD index 448c025043bfb..c807c41d0b6ad 100644 --- a/test/mocks/event/BUILD +++ b/test/mocks/event/BUILD @@ -24,5 +24,6 @@ envoy_cc_mock( "//include/envoy/network:listener_interface", "//include/envoy/ssl:context_interface", "//test/mocks/buffer:buffer_mocks", + "//test/test_common:test_time_lib", ], ) diff --git a/test/mocks/event/mocks.cc b/test/mocks/event/mocks.cc index 8baf6741ee576..231121c6c51b4 100644 --- a/test/mocks/event/mocks.cc +++ b/test/mocks/event/mocks.cc @@ -13,7 +13,7 @@ using testing::_; namespace Envoy { namespace Event { -MockDispatcher::MockDispatcher() : time_source_(system_time_, monotonic_time_) { +MockDispatcher::MockDispatcher() : time_source_(&test_time_.timeSource()) { ON_CALL(*this, clearDeferredDeleteList()).WillByDefault(Invoke([this]() -> void { to_delete_.clear(); })); diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 3485aedfe8471..b137a575c1c1b 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -18,6 +18,7 @@ #include "envoy/ssl/context.h" #include "test/mocks/buffer/mocks.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" @@ -29,7 +30,10 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); - TimeSource& timeSource() override { return time_source_; } + void setTimeSource(TimeSource& time_source) { time_source_ = &time_source; } + + // Dispatcher + TimeSource& timeSource() override { return *time_source_; } Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, Network::TransportSocketPtr&& transport_socket) override { @@ -104,9 +108,8 @@ class MockDispatcher : public Dispatcher { Buffer::WatermarkFactory& getWatermarkFactory() override { return buffer_factory_; } // TODO(jmarantz): Switch these to using mock-time. - ProdSystemTimeSource system_time_; - ProdMonotonicTimeSource monotonic_time_; - TimeSource time_source_; + TestTime test_time_; + TimeSource* time_source_; std::list to_delete_; MockBufferFactory buffer_factory_; diff --git a/test/mocks/server/mocks.cc b/test/mocks/server/mocks.cc index f945607cee7f2..ee2ff89b4c226 100644 --- a/test/mocks/server/mocks.cc +++ b/test/mocks/server/mocks.cc @@ -129,6 +129,7 @@ MockInstance::MockInstance() ON_CALL(*this, listenerManager()).WillByDefault(ReturnRef(listener_manager_)); ON_CALL(*this, singletonManager()).WillByDefault(ReturnRef(*singleton_manager_)); ON_CALL(*this, overloadManager()).WillByDefault(ReturnRef(overload_manager_)); + ON_CALL(*this, timeSource()).WillByDefault(ReturnRef(test_time_.timeSource())); } MockInstance::~MockInstance() {} @@ -144,8 +145,7 @@ MockMain::MockMain(int wd_miss, int wd_megamiss, int wd_kill, int wd_multikill) } MockFactoryContext::MockFactoryContext() - : singleton_manager_(new Singleton::ManagerImpl()), - time_source_(system_time_source_, monotonic_time_source_) { + : singleton_manager_(new Singleton::ManagerImpl()) { ON_CALL(*this, accessLogManager()).WillByDefault(ReturnRef(access_log_manager_)); ON_CALL(*this, clusterManager()).WillByDefault(ReturnRef(cluster_manager_)); ON_CALL(*this, dispatcher()).WillByDefault(ReturnRef(dispatcher_)); @@ -162,6 +162,7 @@ MockFactoryContext::MockFactoryContext() ON_CALL(*this, listenerScope()).WillByDefault(ReturnRef(listener_scope_)); ON_CALL(*this, systemTimeSource()).WillByDefault(ReturnRef(system_time_source_)); ON_CALL(*this, monotonicTimeSource()).WillByDefault(ReturnRef(monotonic_time_source_)); + ON_CALL(*this, timeSource()).WillByDefault(ReturnRef(test_time_.timeSource())); } MockFactoryContext::~MockFactoryContext() {} diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 9d2daffc2212d..6a2fb6397a5e8 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -326,6 +326,7 @@ class MockInstance : public Instance { MOCK_METHOD0(httpTracer, Tracing::HttpTracer&()); MOCK_METHOD0(threadLocal, ThreadLocal::Instance&()); MOCK_METHOD0(localInfo, const LocalInfo::LocalInfo&()); + MOCK_METHOD0(timeSource, TimeSource&()); MOCK_CONST_METHOD0(statsFlushInterval, std::chrono::milliseconds()); std::unique_ptr secret_manager_; @@ -350,6 +351,7 @@ class MockInstance : public Instance { testing::NiceMock init_manager_; testing::NiceMock listener_manager_; testing::NiceMock overload_manager_; + TestTime test_time_; Singleton::ManagerPtr singleton_manager_; }; @@ -422,7 +424,7 @@ class MockFactoryContext : public FactoryContext { Stats::IsolatedStoreImpl listener_scope_; testing::NiceMock system_time_source_; testing::NiceMock monotonic_time_source_; - TimeSource time_source_; + TestTime test_time_; }; class MockTransportSocketFactoryContext : public TransportSocketFactoryContext { From 10422d4a2e80bb92c2f62ebf3aef5c05c4c51ae1 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 16 Aug 2018 13:55:27 -0400 Subject: [PATCH 03/22] checkpoinging: all of //test/common/... compiles, 4 tests still fail (at least one with my own new assert). Signed-off-by: Joshua Marantz --- include/envoy/server/filter_config.h | 5 +++++ source/common/router/rds_impl.cc | 6 +++--- source/common/upstream/cluster_manager_impl.cc | 14 ++++++++++---- source/common/upstream/cluster_manager_impl.h | 5 +---- source/server/listener_manager_impl.h | 1 + test/mocks/server/mocks.cc | 6 +++--- test/mocks/server/mocks.h | 2 +- 7 files changed, 24 insertions(+), 15 deletions(-) diff --git a/include/envoy/server/filter_config.h b/include/envoy/server/filter_config.h index 14fff6902733e..32429f752f259 100644 --- a/include/envoy/server/filter_config.h +++ b/include/envoy/server/filter_config.h @@ -130,6 +130,11 @@ class FactoryContext { */ virtual const envoy::api::v2::core::Metadata& listenerMetadata() const PURE; + /** + * @return SystemTimeSource& a reference to the system time source. + */ + virtual SystemTimeSource& systemTimeSource() PURE; + /** * @return TimeSource& a reference to the time source. */ diff --git a/source/common/router/rds_impl.cc b/source/common/router/rds_impl.cc index 7f3aa8c223824..6a3e8c545cae5 100644 --- a/source/common/router/rds_impl.cc +++ b/source/common/router/rds_impl.cc @@ -44,7 +44,7 @@ StaticRouteConfigProviderImpl::StaticRouteConfigProviderImpl( Server::Configuration::FactoryContext& factory_context, RouteConfigProviderManagerImpl& route_config_provider_manager) : config_(new ConfigImpl(config, factory_context, true)), route_config_proto_{config}, - last_updated_(factory_context.timeSource().systemTime()), + last_updated_(factory_context.systemTimeSource().currentTime()), route_config_provider_manager_(route_config_provider_manager) { route_config_provider_manager_.static_route_config_providers_.insert(this); } @@ -64,8 +64,8 @@ RdsRouteConfigSubscription::RdsRouteConfigSubscription( scope_(factory_context.scope().createScope(stat_prefix + "rds." + route_config_name_ + ".")), stats_({ALL_RDS_STATS(POOL_COUNTER(*scope_))}), route_config_provider_manager_(route_config_provider_manager), - manager_identifier_(manager_identifier), time_source_(factory_context.timeSource().system()), - last_updated_(factory_context.timeSource().systemTime()) { + manager_identifier_(manager_identifier), time_source_(factory_context.systemTimeSource()), + last_updated_(factory_context.systemTimeSource().currentTime()) { ::Envoy::Config::Utility::checkLocalInfo("rds", factory_context.localInfo()); subscription_ = Envoy::Config::SubscriptionFactory::subscriptionFromConfigSource< diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index 96b540b07c232..9d1e0d11e3e39 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -172,7 +172,8 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, - Server::Admin& admin) + Server::Admin& admin, SystemTimeSource& system_time_source, + MonotonicTimeSource& monotonic_time_source) : factory_(factory), runtime_(runtime), stats_(stats), tls_(tls.allocateSlot()), random_(random), log_manager_(log_manager), bind_config_(bootstrap.cluster_manager().upstream_bind_config()), local_info_(local_info), @@ -180,14 +181,17 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots init_helper_([this](Cluster& cluster) { onClusterInit(cluster); }), config_tracker_entry_( admin.getConfigTracker().add("clusters", [this] { return dumpClusterConfigs(); })), - time_source_(main_thread_dispatcher.timeSource()), dispatcher_(main_thread_dispatcher) { + time_source_(system_time_source, monotonic_time_source), + dispatcher_(main_thread_dispatcher) { + ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); + ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); async_client_manager_ = std::make_unique(*this, tls); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { const std::string event_log_file_path = cm_config.outlier_detection().event_log_path(); if (!event_log_file_path.empty()) { outlier_event_logger_.reset(new Outlier::EventLoggerImpl( - log_manager, event_log_file_path, time_source_.system(), time_source_.monotonic())); + log_manager, event_log_file_path, system_time_source, monotonic_time_source)); } } @@ -1175,9 +1179,11 @@ ClusterManagerPtr ProdClusterManagerFactory::clusterManagerFromProto( ThreadLocal::Instance& tls, Runtime::Loader& runtime, Runtime::RandomGenerator& random, const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Server::Admin& admin) { + TimeSource& time_source = main_thread_dispatcher_.timeSource(); return ClusterManagerPtr{new ClusterManagerImpl(bootstrap, *this, stats, tls, runtime, random, local_info, log_manager, main_thread_dispatcher_, - admin)}; + admin, time_source.system(), + time_source.monotonic())}; } Http::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateConnPool( diff --git a/source/common/upstream/cluster_manager_impl.h b/source/common/upstream/cluster_manager_impl.h index 30cd9c05239a4..3cc2cc88bf22c 100644 --- a/source/common/upstream/cluster_manager_impl.h +++ b/source/common/upstream/cluster_manager_impl.h @@ -438,10 +438,7 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggable system_time_source_; testing::NiceMock monotonic_time_source_; - TestTime test_time_; + TimeSource time_source_; }; class MockTransportSocketFactoryContext : public TransportSocketFactoryContext { From 282307fa32086a6000e4d6a74bc9fe51c9cf20e8 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 16 Aug 2018 15:20:40 -0400 Subject: [PATCH 04/22] //test/common/... all pass. Signed-off-by: Joshua Marantz --- source/common/upstream/cluster_manager_impl.cc | 4 ++-- test/mocks/upstream/mocks.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index 9d1e0d11e3e39..b037b7a0fa7dd 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -183,8 +183,8 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots admin.getConfigTracker().add("clusters", [this] { return dumpClusterConfigs(); })), time_source_(system_time_source, monotonic_time_source), dispatcher_(main_thread_dispatcher) { - ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); - ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); + //ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); + //ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); async_client_manager_ = std::make_unique(*this, tls); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { diff --git a/test/mocks/upstream/mocks.h b/test/mocks/upstream/mocks.h index 33ad3c6cb1fb4..ee6a81ecec22f 100644 --- a/test/mocks/upstream/mocks.h +++ b/test/mocks/upstream/mocks.h @@ -188,9 +188,9 @@ class MockClusterManager : public ClusterManager { } ClusterManagerFactory& clusterManagerFactory() override { return cluster_manager_factory_; } + TimeSource& timeSource() override { return time_source_; } // Upstream::ClusterManager - MOCK_METHOD0(timeSource, TimeSource&()); MOCK_METHOD2(addOrUpdateCluster, bool(const envoy::api::v2::Cluster& cluster, const std::string& version_info)); MOCK_METHOD1(setInitializedCb, void(std::function)); From fa5c8c810420198e305c129699666e50bf8935d7 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 08:29:32 -0400 Subject: [PATCH 05/22] More of //test/... builds, some of it works. Signed-off-by: Joshua Marantz --- include/envoy/common/time.h | 4 ++ .../config_validation/cluster_manager.cc | 4 +- test/config_test/config_test.cc | 2 +- .../proxy_protocol/proxy_protocol_test.cc | 7 ++- .../tracers/zipkin/span_buffer_test.cc | 18 +++++--- .../tracers/zipkin/zipkin_core_types_test.cc | 6 ++- test/integration/integration.cc | 4 +- test/server/BUILD | 3 ++ test/server/config_validation/BUILD | 2 + .../config_validation/async_client_test.cc | 4 +- .../config_validation/dispatcher_test.cc | 1 + test/server/guarddog_impl_test.cc | 45 ++++++++++--------- test/server/listener_manager_impl_test.cc | 8 ++-- test/server/server_fuzz_test.cc | 5 ++- test/server/server_test.cc | 8 ++-- test/server/worker_impl_test.cc | 4 +- 16 files changed, 82 insertions(+), 43 deletions(-) diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index 7380f383cddb1..3f7d1388be283 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -55,6 +55,10 @@ class TimeSource { */ MonotonicTime monotonicTime() const { return monotonic_.currentTime(); } + bool operator==(const TimeSource& ts) const { + return &system_ == &ts.system_ && &monotonic_ == &ts.monotonic_; + } + // TODO(jmarantz): Eliminate these methods and the SystemTimeSource and MonotonicTimeSource // classes, and change method calls to work directly off of TimeSource. SystemTimeSource& system() { return system_; } diff --git a/source/server/config_validation/cluster_manager.cc b/source/server/config_validation/cluster_manager.cc index f90877ed4d761..a5621227f876d 100644 --- a/source/server/config_validation/cluster_manager.cc +++ b/source/server/config_validation/cluster_manager.cc @@ -39,7 +39,9 @@ ValidationClusterManager::ValidationClusterManager( AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, Server::Admin& admin) : ClusterManagerImpl(bootstrap, factory, stats, tls, runtime, random, local_info, log_manager, - main_thread_dispatcher, admin), + main_thread_dispatcher, admin, + main_thread_dispatcher.timeSource().system(), + main_thread_dispatcher.timeSource().monotonic()), async_client_(main_thread_dispatcher.timeSource()) {} Http::ConnectionPool::Instance* diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index 98a0576b957b2..55a7d01494b3e 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -84,7 +84,7 @@ class ConfigTest { NiceMock component_factory_; NiceMock worker_factory_; Server::ListenerManagerImpl listener_manager_{server_, component_factory_, worker_factory_, - ProdSystemTimeSource::instance_}; + server_.timeSource()}; Runtime::RandomGeneratorImpl random_; NiceMock os_sys_calls_; TestThreadsafeSingletonInjector os_calls{&os_sys_calls_}; diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index 57916b0bb4938..2bf469a1f791a 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -22,6 +22,7 @@ #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/printers.h" +#include "test/test_common/test_time.h" #include "test/test_common/threadsafe_singleton_injector.h" #include "test/test_common/utility.h" @@ -50,6 +51,7 @@ class ProxyProtocolTest : public testing::TestWithParam { public: WildcardProxyProtocolTest() - : socket_(Network::Test::getAnyAddress(GetParam()), nullptr, true), + : dispatcher_(test_time_.timeSource()), + socket_(Network::Test::getAnyAddress(GetParam()), nullptr, true), local_dst_address_(Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(GetParam()), socket_.localAddress()->ip()->port())), @@ -939,6 +943,7 @@ class WildcardProxyProtocolTest : public testing::TestWithParam( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) - .count(); + TestTime.timeSource().systemTime().time_since_epoch()).count(); ann.setTimestamp(timestamp); EXPECT_EQ(timestamp, ann.timestamp()); diff --git a/test/integration/integration.cc b/test/integration/integration.cc index ba10deab6ab38..2f85a687a2e9b 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -214,7 +214,9 @@ BaseIntegrationTest::BaseIntegrationTest(Network::Address::IpVersion version, const std::string& config) : api_(new Api::Impl(std::chrono::milliseconds(10000))), mock_buffer_factory_(new NiceMock), - dispatcher_(new Event::DispatcherImpl(test_time_.timeSource())), version_(version), + dispatcher_(new Event::DispatcherImpl(test_time_.timeSource(), + Buffer::WatermarkFactoryPtr{mock_buffer_factory_})), + version_(version), config_helper_(version, config), default_log_level_(TestEnvironment::getOptions().logLevel()) { // This is a hack, but there are situations where we disconnect fake upstream connections and diff --git a/test/server/BUILD b/test/server/BUILD index 064fe8fa72eff..4721ba2712b0e 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -183,6 +183,7 @@ envoy_cc_fuzz_test( "//test/mocks/server:server_mocks", "//test/mocks/stats:stats_mocks", "//test/test_common:environment_lib", + "//test/test_common:test_time_lib", ] + envoy_all_extensions(), ) @@ -213,6 +214,7 @@ envoy_cc_test( "//test/integration:integration_lib", "//test/mocks/server:server_mocks", "//test/mocks/stats:stats_mocks", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) @@ -235,6 +237,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", "//test/mocks/thread_local:thread_local_mocks", + "//test/test_common:test_time_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/server/config_validation/BUILD b/test/server/config_validation/BUILD index c57990c451c21..34bc8413b3215 100644 --- a/test/server/config_validation/BUILD +++ b/test/server/config_validation/BUILD @@ -18,6 +18,7 @@ envoy_cc_test( "//source/server/config_validation:dns_lib", "//test/mocks/http:http_mocks", "//test/mocks/upstream:upstream_mocks", + "//test/test_common:test_time_lib", ], ) @@ -74,6 +75,7 @@ envoy_cc_test( "//source/server/config_validation:dns_lib", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", + "//test/test_common:test_time_lib", ], ) diff --git a/test/server/config_validation/async_client_test.cc b/test/server/config_validation/async_client_test.cc index 200e8afb6c206..19a1ae1902a60 100644 --- a/test/server/config_validation/async_client_test.cc +++ b/test/server/config_validation/async_client_test.cc @@ -6,6 +6,7 @@ #include "test/mocks/http/mocks.h" #include "test/mocks/upstream/mocks.h" +#include "test/test_common/test_time.h" namespace Envoy { namespace Http { @@ -15,7 +16,8 @@ TEST(ValidationAsyncClientTest, MockedMethods) { MockAsyncClientCallbacks callbacks; MockAsyncClientStreamCallbacks stream_callbacks; - ValidationAsyncClient client; + TestTime test_time; + ValidationAsyncClient client(test_time.timeSource()); EXPECT_EQ(nullptr, client.send(std::move(message), callbacks, absl::optional())); EXPECT_EQ(nullptr, diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index 46f0a4679295d..557e72625bb2a 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -10,6 +10,7 @@ //#include "test/mocks/common.h" #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" diff --git a/test/server/guarddog_impl_test.cc b/test/server/guarddog_impl_test.cc index 632caae9ab0d2..d073877fd97c5 100644 --- a/test/server/guarddog_impl_test.cc +++ b/test/server/guarddog_impl_test.cc @@ -21,6 +21,15 @@ using testing::NiceMock; namespace Envoy { namespace Server { +class GuardDogTestBase : public testing::Test { + protected: + GuardDogTestBase() : time_source_(system_time_source_, monotonic_time_source_) {} + + NiceMock monotonic_time_source_; + ProdSystemTimeSource system_time_source_; + TimeSource time_source_; +}; + /** * Death test caveat: Because of the way we die gcov doesn't receive coverage * information from the forked process that is checked for succesful death. @@ -28,12 +37,12 @@ namespace Server { * green in the coverage report. However, rest assured from the results of the * test: these lines are in fact covered. */ -class GuardDogDeathTest : public testing::Test { +class GuardDogDeathTest : public GuardDogTestBase { protected: GuardDogDeathTest() : config_kill_(1000, 1000, 100, 1000), config_multikill_(1000, 1000, 1000, 500), mock_time_(0) { - ON_CALL(time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { + ON_CALL(monotonic_time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { return std::chrono::steady_clock::time_point(std::chrono::milliseconds(mock_time_)); })); } @@ -67,7 +76,6 @@ class GuardDogDeathTest : public testing::Test { NiceMock config_kill_; NiceMock config_multikill_; NiceMock fakestats_; - NiceMock time_source_; std::atomic mock_time_; std::unique_ptr guard_dog_; WatchDogSharedPtr unpet_dog_; @@ -129,10 +137,10 @@ TEST_F(GuardDogAlmostDeadTest, NearDeathTest) { } } -class GuardDogMissTest : public testing::Test { +class GuardDogMissTest : public GuardDogTestBase { protected: GuardDogMissTest() : config_miss_(500, 1000, 0, 0), config_mega_(1000, 500, 0, 0), mock_time_(0) { - ON_CALL(time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { + ON_CALL(monotonic_time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { return std::chrono::steady_clock::time_point(std::chrono::milliseconds(mock_time_)); })); } @@ -140,7 +148,6 @@ class GuardDogMissTest : public testing::Test { NiceMock config_miss_; NiceMock config_mega_; Stats::IsolatedStoreImpl stats_store_; - NiceMock time_source_; std::atomic mock_time_; }; @@ -166,7 +173,7 @@ TEST_F(GuardDogMissTest, MissTest) { TEST_F(GuardDogMissTest, MegaMissTest) { // This test checks the actual collected statistics after doing some timer // advances that should and shouldn't increment the counters. - ON_CALL(time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { + ON_CALL(monotonic_time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { return std::chrono::steady_clock::time_point(std::chrono::milliseconds(mock_time_)); })); GuardDogImpl gd(stats_store_, config_mega_, time_source_); @@ -189,7 +196,7 @@ TEST_F(GuardDogMissTest, MissCountTest) { // This tests a flake discovered in the MissTest where real timeout or // spurious condition_variable wakeup causes the counter to get incremented // more than it should be. - ON_CALL(time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { + ON_CALL(monotonic_time_source_, currentTime()).WillByDefault(testing::Invoke([this]() { return std::chrono::steady_clock::time_point(std::chrono::milliseconds(mock_time_)); })); GuardDogImpl gd(stats_store_, config_miss_, time_source_); @@ -229,34 +236,30 @@ TEST_F(GuardDogMissTest, MissCountTest) { sometimes_pet_dog = nullptr; } -TEST(GuardDogBasicTest, StartStopTest) { +TEST_F(GuardDogTestBase, StartStopTest) { NiceMock stats; NiceMock config(0, 0, 0, 0); - NiceMock time_source; - GuardDogImpl gd(stats, config, time_source); + GuardDogImpl gd(stats, config, time_source_); } -TEST(GuardDogBasicTest, LoopIntervalNoKillTest) { +TEST_F(GuardDogTestBase, LoopIntervalNoKillTest) { NiceMock stats; NiceMock config(40, 50, 0, 0); - NiceMock time_source; - GuardDogImpl gd(stats, config, time_source); + GuardDogImpl gd(stats, config, time_source_); EXPECT_EQ(gd.loopIntervalForTest(), 40); } -TEST(GuardDogBasicTest, LoopIntervalTest) { +TEST_F(GuardDogTestBase, LoopIntervalTest) { NiceMock stats; NiceMock config(100, 90, 1000, 500); - NiceMock time_source; - GuardDogImpl gd(stats, config, time_source); + GuardDogImpl gd(stats, config, time_source_); EXPECT_EQ(gd.loopIntervalForTest(), 90); } -TEST(WatchDogBasicTest, ThreadIdTest) { +TEST_F(GuardDogTestBase, WatchDogThreadIdTest) { NiceMock stats; NiceMock config(100, 90, 1000, 500); - NiceMock time_source; - GuardDogImpl gd(stats, config, time_source); + GuardDogImpl gd(stats, config, time_source_); auto watched_dog = gd.createWatchDog(123); EXPECT_EQ(watched_dog->threadId(), 123); gd.stopWatching(watched_dog); @@ -268,7 +271,7 @@ TEST(WatchDogBasicTest, ThreadIdTest) { // // The WatchDog/GuardDog relies on this being a lock free atomic for perf reasons so some workaround // will be required if this test starts failing. -TEST(WatchDogTimeTest, AtomicIsAtomicTest) { +TEST_F(GuardDogTestBase, AtomicIsAtomicTest) { ProdMonotonicTimeSource time_source; std::atomic atomic_time; ASSERT_EQ(atomic_time.is_lock_free(), true); diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 4c113784eddf6..94f2dffa01d79 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -51,10 +51,10 @@ class ListenerHandle { class ListenerManagerImplTest : public testing::Test { public: - ListenerManagerImplTest() { - EXPECT_CALL(worker_factory_, createWorker_()).WillOnce(Return(worker_)); + ListenerManagerImplTest() : time_source_(system_time_source_, monotonic_time_source_) { + EXPECT_CALL(worker_factory_, createWorker_(time_source_)).WillOnce(Return(worker_)); manager_.reset( - new ListenerManagerImpl(server_, listener_factory_, worker_factory_, system_time_source_)); + new ListenerManagerImpl(server_, listener_factory_, worker_factory_, time_source_)); } /** @@ -116,6 +116,8 @@ class ListenerManagerImplTest : public testing::Test { std::unique_ptr manager_; NiceMock guard_dog_; NiceMock system_time_source_; + ProdMonotonicTimeSource monotonic_time_source_; + TimeSource time_source_; }; class ListenerManagerImplWithRealFiltersTest : public ListenerManagerImplTest { diff --git a/test/server/server_fuzz_test.cc b/test/server/server_fuzz_test.cc index 6b8d057ce682a..7f1c231a825b8 100644 --- a/test/server/server_fuzz_test.cc +++ b/test/server/server_fuzz_test.cc @@ -12,6 +12,7 @@ #include "test/mocks/server/mocks.h" #include "test/mocks/stats/mocks.h" #include "test/test_common/environment.h" +#include "test/test_common/test_time.h" namespace Envoy { namespace Server { @@ -24,6 +25,7 @@ DEFINE_PROTO_FUZZER(const envoy::config::bootstrap::v2::Bootstrap& input) { Thread::MutexBasicLockable fakelock; TestComponentFactory component_factory; ThreadLocal::InstanceImpl thread_local_instance; + TestTime test_time; RELEASE_ASSERT(Envoy::Server::validateProtoDescriptors(), ""); @@ -37,7 +39,8 @@ DEFINE_PROTO_FUZZER(const envoy::config::bootstrap::v2::Bootstrap& input) { try { auto server = std::make_unique( - options, std::make_shared("127.0.0.1"), hooks, restart, + options, test_time.timeSource(), + std::make_shared("127.0.0.1"), hooks, restart, stats_store, fakelock, component_factory, std::make_unique(), thread_local_instance); } catch (const EnvoyException& ex) { diff --git a/test/server/server_test.cc b/test/server/server_test.cc index 56cdbac0d5620..5f3319b5a5a39 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -8,6 +8,7 @@ #include "test/mocks/server/mocks.h" #include "test/mocks/stats/mocks.h" #include "test/test_common/environment.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gtest/gtest.h" @@ -111,7 +112,7 @@ class ServerInstanceImplTest : public testing::TestWithParam>(), thread_local_)); @@ -127,7 +128,7 @@ class ServerInstanceImplTest : public testing::TestWithParam>(), thread_local_)); @@ -144,6 +145,7 @@ class ServerInstanceImplTest : public testing::TestWithParam server_; + TestTime test_time_; }; INSTANTIATE_TEST_CASE_P(IpVersions, ServerInstanceImplTest, @@ -292,7 +294,7 @@ TEST_P(ServerInstanceImplTest, LogToFileError) { TEST_P(ServerInstanceImplTest, NoOptionsPassed) { EXPECT_THROW_WITH_MESSAGE( server_.reset(new InstanceImpl( - options_, + options_, test_time_.timeSource(), Network::Address::InstanceConstSharedPtr(new Network::Address::Ipv4Instance("127.0.0.1")), hooks_, restart_, stats_store_, fakelock_, component_factory_, std::make_unique>(), thread_local_)), diff --git a/test/server/worker_impl_test.cc b/test/server/worker_impl_test.cc index 6a73bf302cfff..8dcc2cde0e790 100644 --- a/test/server/worker_impl_test.cc +++ b/test/server/worker_impl_test.cc @@ -5,6 +5,7 @@ #include "test/mocks/network/mocks.h" #include "test/mocks/server/mocks.h" #include "test/mocks/thread_local/mocks.h" +#include "test/test_common/test_time.h" #include "test/test_common/utility.h" #include "gtest/gtest.h" @@ -29,7 +30,8 @@ class WorkerImplTest : public testing::Test { } NiceMock tls_; - Event::DispatcherImpl* dispatcher_ = new Event::DispatcherImpl(); + TestTime test_time; + Event::DispatcherImpl* dispatcher_ = new Event::DispatcherImpl(test_time.timeSource()); Network::MockConnectionHandler* handler_ = new Network::MockConnectionHandler(); NiceMock guard_dog_; DefaultTestHooks hooks_; From 8d67f55eba782e90e3ccae685e2ba4dc446e9ed6 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 08:52:35 -0400 Subject: [PATCH 06/22] All tests compiling and working. Signed-off-by: Joshua Marantz --- source/common/http/async_client_impl.cc | 5 +- .../common/upstream/cluster_manager_impl.cc | 14 +++--- .../proxy_protocol/proxy_protocol_test.cc | 4 +- .../tracers/zipkin/span_buffer_test.cc | 2 +- test/extensions/tracers/zipkin/tracer_test.cc | 31 ++++++++---- .../tracers/zipkin/zipkin_core_types_test.cc | 44 +++++++++------- .../tracers/zipkin/zipkin_tracer_impl_test.cc | 50 +++++++++++-------- test/integration/integration.cc | 3 +- test/integration/server.cc | 7 ++- test/server/guarddog_impl_test.cc | 2 +- test/server/server_fuzz_test.cc | 4 +- 11 files changed, 92 insertions(+), 74 deletions(-) diff --git a/source/common/http/async_client_impl.cc b/source/common/http/async_client_impl.cc index ad9671cbf0ffd..e9e435cd7121b 100644 --- a/source/common/http/async_client_impl.cc +++ b/source/common/http/async_client_impl.cc @@ -35,9 +35,8 @@ AsyncClientImpl::AsyncClientImpl(const Upstream::ClusterInfo& cluster, Stats::St Upstream::ClusterManager& cm, Runtime::Loader& runtime, Runtime::RandomGenerator& random, Router::ShadowWriterPtr&& shadow_writer) - : cluster_(cluster), - config_("http.async-client.", local_info, stats_store, cm, runtime, random, - std::move(shadow_writer), true, false, false), + : cluster_(cluster), config_("http.async-client.", local_info, stats_store, cm, runtime, random, + std::move(shadow_writer), true, false, false), dispatcher_(dispatcher) {} AsyncClientImpl::~AsyncClientImpl() { diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index b037b7a0fa7dd..6a56988d899f7 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -181,10 +181,9 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots init_helper_([this](Cluster& cluster) { onClusterInit(cluster); }), config_tracker_entry_( admin.getConfigTracker().add("clusters", [this] { return dumpClusterConfigs(); })), - time_source_(system_time_source, monotonic_time_source), - dispatcher_(main_thread_dispatcher) { - //ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); - //ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); + time_source_(system_time_source, monotonic_time_source), dispatcher_(main_thread_dispatcher) { + // ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); + // ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); async_client_manager_ = std::make_unique(*this, tls); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { @@ -1180,10 +1179,9 @@ ClusterManagerPtr ProdClusterManagerFactory::clusterManagerFromProto( const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Server::Admin& admin) { TimeSource& time_source = main_thread_dispatcher_.timeSource(); - return ClusterManagerPtr{new ClusterManagerImpl(bootstrap, *this, stats, tls, runtime, random, - local_info, log_manager, main_thread_dispatcher_, - admin, time_source.system(), - time_source.monotonic())}; + return ClusterManagerPtr{new ClusterManagerImpl( + bootstrap, *this, stats, tls, runtime, random, local_info, log_manager, + main_thread_dispatcher_, admin, time_source.system(), time_source.monotonic())}; } Http::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateConnPool( diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index 2bf469a1f791a..61c0ad389000c 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -50,8 +50,8 @@ class ProxyProtocolTest : public testing::TestWithParam { public: ProxyProtocolTest() - : socket_(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true), - dispatcher_(test_time_.timeSource()), + : dispatcher_(test_time_.timeSource()), + socket_(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true), connection_handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)), name_("proxy"), filter_chain_(Network::Test::createEmptyFilterChainWithRawBufferSockets()) { diff --git a/test/extensions/tracers/zipkin/span_buffer_test.cc b/test/extensions/tracers/zipkin/span_buffer_test.cc index 7665a4cf7be90..69ba7cea73b32 100644 --- a/test/extensions/tracers/zipkin/span_buffer_test.cc +++ b/test/extensions/tracers/zipkin/span_buffer_test.cc @@ -15,7 +15,7 @@ TEST(ZipkinSpanBufferTest, defaultConstructorEndToEnd) { EXPECT_EQ(0ULL, buffer.pendingSpans()); EXPECT_EQ("[]", buffer.toStringifiedJsonArray()); - EXPECT_FALSE(buffer.addSpan(Span(test_time.timesource()))); + EXPECT_FALSE(buffer.addSpan(Span(test_time.timeSource()))); buffer.allocateBuffer(2); EXPECT_EQ(0ULL, buffer.pendingSpans()); diff --git a/test/extensions/tracers/zipkin/tracer_test.cc b/test/extensions/tracers/zipkin/tracer_test.cc index 740b4370b45c8..fae1f58488302 100644 --- a/test/extensions/tracers/zipkin/tracer_test.cc +++ b/test/extensions/tracers/zipkin/tracer_test.cc @@ -10,6 +10,7 @@ #include "test/mocks/common.h" #include "test/mocks/runtime/mocks.h" #include "test/mocks/tracing/mocks.h" +#include "test/test_common/test_time.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -34,11 +35,19 @@ class TestReporterImpl : public Reporter { std::vector reported_spans_; }; -TEST(ZipkinTracerTest, spanCreation) { +class ZipkinTracerTest : public testing::Test { +protected: + ZipkinTracerTest() : time_source_(test_time_.timeSource()) {} + + TestTime test_time_; + TimeSource time_source_; +}; + +TEST_F(ZipkinTracerTest, spanCreation) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:9000"); NiceMock random_generator; - Tracer tracer("my_service_name", addr, random_generator, false); + Tracer tracer("my_service_name", addr, random_generator, false, time_source_); NiceMock mock_start_time; SystemTime timestamp = mock_start_time.currentTime(); @@ -175,7 +184,7 @@ TEST(ZipkinTracerTest, spanCreation) { // ============== ON_CALL(config, operationName()).WillByDefault(Return(Tracing::OperationName::Ingress)); - const uint generated_parent_id = Util::generateRandom64(); + const uint generated_parent_id = Util::generateRandom64(test_time_.timeSource()); SpanContext modified_root_span_context(root_span_context.trace_id_high(), root_span_context.trace_id(), root_span_context.id(), generated_parent_id, root_span_context.sampled()); @@ -217,11 +226,11 @@ TEST(ZipkinTracerTest, spanCreation) { EXPECT_FALSE(new_shared_context_span->isSetDuration()); } -TEST(ZipkinTracerTest, finishSpan) { +TEST_F(ZipkinTracerTest, finishSpan) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:9000"); NiceMock random_generator; - Tracer tracer("my_service_name", addr, random_generator, false); + Tracer tracer("my_service_name", addr, random_generator, false, test_time_.timeSource()); NiceMock mock_start_time; SystemTime timestamp = mock_start_time.currentTime(); @@ -301,11 +310,11 @@ TEST(ZipkinTracerTest, finishSpan) { EXPECT_EQ("my_service_name", endpoint.serviceName()); } -TEST(ZipkinTracerTest, finishNotSampledSpan) { +TEST_F(ZipkinTracerTest, finishNotSampledSpan) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:9000"); NiceMock random_generator; - Tracer tracer("my_service_name", addr, random_generator, false); + Tracer tracer("my_service_name", addr, random_generator, false, time_source_); NiceMock mock_start_time; SystemTime timestamp = mock_start_time.currentTime(); @@ -330,11 +339,11 @@ TEST(ZipkinTracerTest, finishNotSampledSpan) { EXPECT_EQ(0ULL, reporter_object->reportedSpans().size()); } -TEST(ZipkinTracerTest, SpanSampledPropagatedToChild) { +TEST_F(ZipkinTracerTest, SpanSampledPropagatedToChild) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:9000"); NiceMock random_generator; - Tracer tracer("my_service_name", addr, random_generator, false); + Tracer tracer("my_service_name", addr, random_generator, false, time_source_); NiceMock mock_start_time; SystemTime timestamp = mock_start_time.currentTime(); @@ -359,11 +368,11 @@ TEST(ZipkinTracerTest, SpanSampledPropagatedToChild) { EXPECT_FALSE(child_span2->sampled()); } -TEST(ZipkinTracerTest, RootSpan128bitTraceId) { +TEST_F(ZipkinTracerTest, RootSpan128bitTraceId) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:9000"); NiceMock random_generator; - Tracer tracer("my_service_name", addr, random_generator, true); + Tracer tracer("my_service_name", addr, random_generator, true, time_source_); NiceMock mock_start_time; SystemTime timestamp = mock_start_time.currentTime(); diff --git a/test/extensions/tracers/zipkin/zipkin_core_types_test.cc b/test/extensions/tracers/zipkin/zipkin_core_types_test.cc index db551c40e25a7..f2d34e6ecae84 100644 --- a/test/extensions/tracers/zipkin/zipkin_core_types_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_core_types_test.cc @@ -90,7 +90,8 @@ TEST(ZipkinCoreTypesAnnotationTest, defaultConstructor) { TestTime test_time; uint64_t timestamp = std::chrono::duration_cast( - TestTime.timeSource().systemTime().time_since_epoch()).count(); + test_time.timeSource().systemTime().time_since_epoch()) + .count(); ann.setTimestamp(timestamp); EXPECT_EQ(timestamp, ann.timestamp()); @@ -146,8 +147,9 @@ TEST(ZipkinCoreTypesAnnotationTest, customConstructor) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); + TestTime test_time; uint64_t timestamp = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().systemTime().time_since_epoch()) .count(); Annotation ann(timestamp, ZipkinCoreConstants::get().CLIENT_SEND, ep); @@ -170,8 +172,9 @@ TEST(ZipkinCoreTypesAnnotationTest, copyConstructor) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); + TestTime test_time; uint64_t timestamp = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().systemTime().time_since_epoch()) .count(); Annotation ann(timestamp, ZipkinCoreConstants::get().CLIENT_SEND, ep); Annotation ann2(ann); @@ -187,8 +190,9 @@ TEST(ZipkinCoreTypesAnnotationTest, assignmentOperator) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); + TestTime test_time; uint64_t timestamp = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().systemTime().time_since_epoch()) .count(); Annotation ann(timestamp, ZipkinCoreConstants::get().CLIENT_SEND, ep); Annotation ann2 = ann; @@ -285,7 +289,8 @@ TEST(ZipkinCoreTypesBinaryAnnotationTest, assignmentOperator) { } TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { - Span span; + TestTime test_time; + Span span(test_time.timeSource()); EXPECT_EQ(0ULL, span.id()); EXPECT_EQ(0ULL, span.traceId()); @@ -305,40 +310,40 @@ TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { R"("annotations":[],"binaryAnnotations":[]})", span.toJson()); - uint64_t id = Util::generateRandom64(); + uint64_t id = Util::generateRandom64(test_time.timeSource()); std::string id_hex = Hex::uint64ToHex(id); span.setId(id); EXPECT_EQ(id, span.id()); EXPECT_EQ(id_hex, span.idAsHexString()); - id = Util::generateRandom64(); + id = Util::generateRandom64(test_time.timeSource()); id_hex = Hex::uint64ToHex(id); span.setParentId(id); EXPECT_EQ(id, span.parentId()); EXPECT_EQ(id_hex, span.parentIdAsHexString()); EXPECT_TRUE(span.isSetParentId()); - id = Util::generateRandom64(); + id = Util::generateRandom64(test_time.timeSource()); id_hex = Hex::uint64ToHex(id); span.setTraceId(id); EXPECT_EQ(id, span.traceId()); EXPECT_EQ(id_hex, span.traceIdAsHexString()); - id = Util::generateRandom64(); + id = Util::generateRandom64(test_time.timeSource()); id_hex = Hex::uint64ToHex(id); span.setTraceIdHigh(id); EXPECT_EQ(id, span.traceIdHigh()); EXPECT_TRUE(span.isSetTraceIdHigh()); int64_t timestamp = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().systemTime().time_since_epoch()) .count(); span.setTimestamp(timestamp); EXPECT_EQ(timestamp, span.timestamp()); EXPECT_TRUE(span.isSetTimestamp()); int64_t start_time = std::chrono::duration_cast( - ProdMonotonicTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().monotonicTime().time_since_epoch()) .count(); span.setStartTime(start_time); EXPECT_EQ(start_time, span.startTime()); @@ -485,15 +490,16 @@ TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { } TEST(ZipkinCoreTypesSpanTest, copyConstructor) { - Span span; + TestTime test_time; + Span span(test_time.timeSource()); - uint64_t id = Util::generateRandom64(); + uint64_t id = Util::generateRandom64(test_time.timeSource()); std::string id_hex = Hex::uint64ToHex(id); span.setId(id); span.setParentId(id); span.setTraceId(id); int64_t timestamp = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().systemTime().time_since_epoch()) .count(); span.setTimestamp(timestamp); span.setDuration(3000LL); @@ -521,15 +527,16 @@ TEST(ZipkinCoreTypesSpanTest, copyConstructor) { } TEST(ZipkinCoreTypesSpanTest, assignmentOperator) { - Span span; + TestTime test_time; + Span span(test_time.timeSource()); - uint64_t id = Util::generateRandom64(); + uint64_t id = Util::generateRandom64(test_time.timeSource()); std::string id_hex = Hex::uint64ToHex(id); span.setId(id); span.setParentId(id); span.setTraceId(id); int64_t timestamp = std::chrono::duration_cast( - ProdSystemTimeSource::instance_.currentTime().time_since_epoch()) + test_time.timeSource().systemTime().time_since_epoch()) .count(); span.setTimestamp(timestamp); span.setDuration(3000LL); @@ -557,7 +564,8 @@ TEST(ZipkinCoreTypesSpanTest, assignmentOperator) { } TEST(ZipkinCoreTypesSpanTest, setTag) { - Span span; + TestTime test_time; + Span span(test_time.timeSource()); span.setTag("key1", "value1"); span.setTag("key2", "value2"); diff --git a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc index a52333cf848b3..bd18cdde3c4ee 100644 --- a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc @@ -38,6 +38,8 @@ namespace Zipkin { class ZipkinDriverTest : public Test { public: + ZipkinDriverTest() : time_source_(test_time_.timeSource()) {} + void setup(Json::Object& config, bool init_timer) { ON_CALL(cm_, httpAsyncClientForCluster("fake_cluster")) .WillByDefault(ReturnRef(cm_.async_client_)); @@ -64,6 +66,8 @@ class ZipkinDriverTest : public Test { setup(*loader, true); } + uint64_t generateRandom64() { return Util::generateRandom64(time_source_); } + const std::string operation_name_{"test"}; Http::TestHeaderMapImpl request_headers_{ {":authority", "api.lyft.com"}, {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; @@ -80,6 +84,8 @@ class ZipkinDriverTest : public Test { NiceMock random_; NiceMock config_; + TestTime test_time_; + TimeSource& time_source_; }; TEST_F(ZipkinDriverTest, InitializeDriver) { @@ -277,8 +283,8 @@ TEST_F(ZipkinDriverTest, NoB3ContextSampledFalse) { TEST_F(ZipkinDriverTest, PropagateB3NoSampleDecisionSampleTrue) { setupValidDriver(); - request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(Util::generateRandom64())); - request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(generateRandom64())); + request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(generateRandom64())); EXPECT_EQ(nullptr, request_headers_.XB3Sampled()); Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, @@ -291,8 +297,8 @@ TEST_F(ZipkinDriverTest, PropagateB3NoSampleDecisionSampleTrue) { TEST_F(ZipkinDriverTest, PropagateB3NoSampleDecisionSampleFalse) { setupValidDriver(); - request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(Util::generateRandom64())); - request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(generateRandom64())); + request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(generateRandom64())); EXPECT_EQ(nullptr, request_headers_.XB3Sampled()); Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, @@ -369,8 +375,8 @@ TEST_F(ZipkinDriverTest, PropagateB3SampledWithTrue) { TEST_F(ZipkinDriverTest, PropagateB3SampleFalse) { setupValidDriver(); - request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(Util::generateRandom64())); - request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(generateRandom64())); + request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(generateRandom64())); request_headers_.insertXB3Sampled().value(ZipkinCoreConstants::get().NOT_SAMPLED); Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, @@ -405,9 +411,9 @@ TEST_F(ZipkinDriverTest, ZipkinSpanTest) { // Test setTag() with SR annotated span // ==== - const std::string trace_id = Hex::uint64ToHex(Util::generateRandom64()); - const std::string span_id = Hex::uint64ToHex(Util::generateRandom64()); - const std::string parent_id = Hex::uint64ToHex(Util::generateRandom64()); + const std::string trace_id = Hex::uint64ToHex(generateRandom64()); + const std::string span_id = Hex::uint64ToHex(generateRandom64()); + const std::string parent_id = Hex::uint64ToHex(generateRandom64()); const std::string context = trace_id + ";" + span_id + ";" + parent_id + ";" + ZipkinCoreConstants::get().CLIENT_SEND; @@ -445,9 +451,9 @@ TEST_F(ZipkinDriverTest, ZipkinSpanTest) { TEST_F(ZipkinDriverTest, ZipkinSpanContextFromB3HeadersTest) { setupValidDriver(); - const std::string trace_id = Hex::uint64ToHex(Util::generateRandom64()); - const std::string span_id = Hex::uint64ToHex(Util::generateRandom64()); - const std::string parent_id = Hex::uint64ToHex(Util::generateRandom64()); + const std::string trace_id = Hex::uint64ToHex(generateRandom64()); + const std::string span_id = Hex::uint64ToHex(generateRandom64()); + const std::string parent_id = Hex::uint64ToHex(generateRandom64()); request_headers_.insertXB3TraceId().value(trace_id); request_headers_.insertXB3SpanId().value(span_id); @@ -469,11 +475,11 @@ TEST_F(ZipkinDriverTest, ZipkinSpanContextFromB3HeadersTest) { TEST_F(ZipkinDriverTest, ZipkinSpanContextFromB3Headers128TraceIdTest) { setupValidDriver(); - const uint64_t trace_id_high = Util::generateRandom64(); - const uint64_t trace_id_low = Util::generateRandom64(); + const uint64_t trace_id_high = generateRandom64(); + const uint64_t trace_id_low = generateRandom64(); const std::string trace_id = Hex::uint64ToHex(trace_id_high) + Hex::uint64ToHex(trace_id_low); - const std::string span_id = Hex::uint64ToHex(Util::generateRandom64()); - const std::string parent_id = Hex::uint64ToHex(Util::generateRandom64()); + const std::string span_id = Hex::uint64ToHex(generateRandom64()); + const std::string parent_id = Hex::uint64ToHex(generateRandom64()); request_headers_.insertXB3TraceId().value(trace_id); request_headers_.insertXB3SpanId().value(span_id); @@ -498,8 +504,8 @@ TEST_F(ZipkinDriverTest, ZipkinSpanContextFromInvalidTraceIdB3HeadersTest) { setupValidDriver(); request_headers_.insertXB3TraceId().value(std::string("xyz")); - request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(Util::generateRandom64())); - request_headers_.insertXB3ParentSpanId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(generateRandom64())); + request_headers_.insertXB3ParentSpanId().value(Hex::uint64ToHex(generateRandom64())); Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, start_time_, {Tracing::Reason::Sampling, true}); @@ -509,9 +515,9 @@ TEST_F(ZipkinDriverTest, ZipkinSpanContextFromInvalidTraceIdB3HeadersTest) { TEST_F(ZipkinDriverTest, ZipkinSpanContextFromInvalidSpanIdB3HeadersTest) { setupValidDriver(); - request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(generateRandom64())); request_headers_.insertXB3SpanId().value(std::string("xyz")); - request_headers_.insertXB3ParentSpanId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3ParentSpanId().value(Hex::uint64ToHex(generateRandom64())); Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, start_time_, {Tracing::Reason::Sampling, true}); @@ -521,8 +527,8 @@ TEST_F(ZipkinDriverTest, ZipkinSpanContextFromInvalidSpanIdB3HeadersTest) { TEST_F(ZipkinDriverTest, ZipkinSpanContextFromInvalidParentIdB3HeadersTest) { setupValidDriver(); - request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(Util::generateRandom64())); - request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(Util::generateRandom64())); + request_headers_.insertXB3TraceId().value(Hex::uint64ToHex(generateRandom64())); + request_headers_.insertXB3SpanId().value(Hex::uint64ToHex(generateRandom64())); request_headers_.insertXB3ParentSpanId().value(std::string("xyz")); Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, diff --git a/test/integration/integration.cc b/test/integration/integration.cc index 2f85a687a2e9b..c5c6f7e6822ad 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -216,8 +216,7 @@ BaseIntegrationTest::BaseIntegrationTest(Network::Address::IpVersion version, mock_buffer_factory_(new NiceMock), dispatcher_(new Event::DispatcherImpl(test_time_.timeSource(), Buffer::WatermarkFactoryPtr{mock_buffer_factory_})), - version_(version), - config_helper_(version, config), + version_(version), config_helper_(version, config), default_log_level_(TestEnvironment::getOptions().logLevel()) { // This is a hack, but there are situations where we disconnect fake upstream connections and // then we expect the server connection pool to get the disconnect before the next test starts. diff --git a/test/integration/server.cc b/test/integration/server.cc index 71d99fe472f58..956cb4381e422 100644 --- a/test/integration/server.cc +++ b/test/integration/server.cc @@ -102,10 +102,9 @@ void IntegrationTestServer::threadRoutine(const Network::Address::IpVersion vers } else { random_generator = std::make_unique(); } - server_.reset(new Server::InstanceImpl(options, test_time_.timeSource(), - Network::Utility::getLocalAddress(version), *this, - restarter, stats_store, lock, *this, - std::move(random_generator), tls)); + server_.reset(new Server::InstanceImpl( + options, test_time_.timeSource(), Network::Utility::getLocalAddress(version), *this, + restarter, stats_store, lock, *this, std::move(random_generator), tls)); pending_listeners_ = server_->listenerManager().listeners().size(); ENVOY_LOG(info, "waiting for {} test server listeners", pending_listeners_); server_set_.setReady(); diff --git a/test/server/guarddog_impl_test.cc b/test/server/guarddog_impl_test.cc index d073877fd97c5..84562189ab2df 100644 --- a/test/server/guarddog_impl_test.cc +++ b/test/server/guarddog_impl_test.cc @@ -22,7 +22,7 @@ namespace Envoy { namespace Server { class GuardDogTestBase : public testing::Test { - protected: +protected: GuardDogTestBase() : time_source_(system_time_source_, monotonic_time_source_) {} NiceMock monotonic_time_source_; diff --git a/test/server/server_fuzz_test.cc b/test/server/server_fuzz_test.cc index 7f1c231a825b8..7dd17db0b047e 100644 --- a/test/server/server_fuzz_test.cc +++ b/test/server/server_fuzz_test.cc @@ -40,8 +40,8 @@ DEFINE_PROTO_FUZZER(const envoy::config::bootstrap::v2::Bootstrap& input) { try { auto server = std::make_unique( options, test_time.timeSource(), - std::make_shared("127.0.0.1"), hooks, restart, - stats_store, fakelock, component_factory, std::make_unique(), + std::make_shared("127.0.0.1"), hooks, restart, stats_store, + fakelock, component_factory, std::make_unique(), thread_local_instance); } catch (const EnvoyException& ex) { ENVOY_LOG_MISC(debug, "Controlled EnvoyException exit: {}", ex.what()); From c9a7d62c0b8238300db28275f6925eb7b0b299a0 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 10:12:13 -0400 Subject: [PATCH 07/22] More comments and TODOs. Signed-off-by: Joshua Marantz --- include/envoy/common/time.h | 18 +++++++++++++++++- include/envoy/event/dispatcher.h | 5 +++++ include/envoy/server/filter_config.h | 2 ++ include/envoy/server/worker.h | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index 3f7d1388be283..b4adb3960083b 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -16,6 +16,8 @@ typedef std::chrono::time_point MonotonicTime; /** * Abstraction for getting the current system time. Useful for testing. + * + * TODO(#4160): eliminate this class and pass TimeSource everywhere. */ class SystemTimeSource { public: @@ -28,7 +30,10 @@ class SystemTimeSource { }; /** - * Abstraction for getting the current monotonically increasing time. Useful for testing. + * Abstraction for getting the current monotonically increasing time. Useful for + * testing. + * + * TODO(#4160): eliminate this class and pass TimeSource everywhere. */ class MonotonicTimeSource { public: @@ -40,6 +45,14 @@ class MonotonicTimeSource { virtual MonotonicTime currentTime() const PURE; }; +/** + * Captures a system-time source, capable of computing both monotonically increasing + * and real time. + * + * TODO(#4160): currently this is just a container for SystemTimeSource and + * MonotonicTimeSource but we should clean that up and just have this as the + * base class. + */ class TimeSource { public: TimeSource(SystemTimeSource& system, MonotonicTimeSource& monotonic) @@ -55,6 +68,9 @@ class TimeSource { */ MonotonicTime monotonicTime() const { return monotonic_.currentTime(); } + /** + * Compares two time-sources for equality; this is needed for mocks. + */ bool operator==(const TimeSource& ts) const { return &system_ == &ts.system_ && &monotonic_ == &ts.monotonic_; } diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index b2b91c6beef48..05da014c06a78 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -34,6 +34,11 @@ class Dispatcher { /** * Returns a time-source to use with this dispatcher. + * + * TODO(#4160) the implementations currently manage timer events that + * ignore the time-source, and thus can't be mocked or faked. So it's + * difficult to mock time in an integration test without mocking out + * the dispatcher. */ virtual TimeSource& timeSource() PURE; diff --git a/include/envoy/server/filter_config.h b/include/envoy/server/filter_config.h index 32429f752f259..be290216385f0 100644 --- a/include/envoy/server/filter_config.h +++ b/include/envoy/server/filter_config.h @@ -132,6 +132,8 @@ class FactoryContext { /** * @return SystemTimeSource& a reference to the system time source. + * TODO(#4160): This method should be eliminated, and call-sites and mocks should + * be converted to work with timeSource() below. */ virtual SystemTimeSource& systemTimeSource() PURE; diff --git a/include/envoy/server/worker.h b/include/envoy/server/worker.h index b68fa75183a62..2189a7c3e2b4c 100644 --- a/include/envoy/server/worker.h +++ b/include/envoy/server/worker.h @@ -83,6 +83,7 @@ class WorkerFactory { /** * @return WorkerPtr a new worker. + * TODO(jmarantz): consider having the factory own the TimeSource */ virtual WorkerPtr createWorker(TimeSource&) PURE; }; From 2d9f2aaa12633e11aaba3a9feb16a2107786b89b Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 10:48:40 -0400 Subject: [PATCH 08/22] Pass the TimeSource into the WorkerFactory's ctor rather than into WorkerFactory::createWorker, Signed-off-by: Joshua Marantz --- include/envoy/server/worker.h | 3 +-- include/envoy/upstream/cluster_manager.h | 3 +++ source/server/config_validation/server.h | 2 +- source/server/listener_manager_impl.cc | 2 +- source/server/server.cc | 2 +- source/server/worker_impl.cc | 4 ++-- source/server/worker_impl.h | 8 +++++--- test/mocks/server/mocks.cc | 1 + test/mocks/server/mocks.h | 6 ++---- test/server/listener_manager_impl_test.cc | 2 +- 10 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/envoy/server/worker.h b/include/envoy/server/worker.h index 2189a7c3e2b4c..9f69a7163e739 100644 --- a/include/envoy/server/worker.h +++ b/include/envoy/server/worker.h @@ -83,9 +83,8 @@ class WorkerFactory { /** * @return WorkerPtr a new worker. - * TODO(jmarantz): consider having the factory own the TimeSource */ - virtual WorkerPtr createWorker(TimeSource&) PURE; + virtual WorkerPtr createWorker() PURE; }; } // namespace Server diff --git a/include/envoy/upstream/cluster_manager.h b/include/envoy/upstream/cluster_manager.h index bd93555669886..ae9d5b767d23c 100644 --- a/include/envoy/upstream/cluster_manager.h +++ b/include/envoy/upstream/cluster_manager.h @@ -210,6 +210,9 @@ class ClusterManager { virtual ClusterManagerFactory& clusterManagerFactory() PURE; + /** + * @return TimeSource& the time-source used with the cluster manager. + */ virtual TimeSource& timeSource() PURE; }; diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index 65c45ae215ba8..072e4fb6ea857 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -127,7 +127,7 @@ class ValidationInstance : Logger::Loggable, uint64_t nextListenerTag() override { return 0; } // Server::WorkerFactory - WorkerPtr createWorker(TimeSource&) override { + WorkerPtr createWorker() override { // Returned workers are not currently used so we can return nothing here safely vs. a // validation mock. return nullptr; diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index a5bd2bc264de2..102d1a8708e0d 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -578,7 +578,7 @@ ListenerManagerImpl::ListenerManagerImpl(Instance& server, config_tracker_entry_(server.admin().getConfigTracker().add( "listeners", [this] { return dumpListenerConfigs(); })) { for (uint32_t i = 0; i < std::max(1U, server.options().concurrency()); i++) { - workers_.emplace_back(worker_factory.createWorker(time_source_)); + workers_.emplace_back(worker_factory.createWorker()); } } diff --git a/source/server/server.cc b/source/server/server.cc index 8cc229e752e18..413736d840bd2 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -56,7 +56,7 @@ InstanceImpl::InstanceImpl(Options& options, TimeSource& time_source, singleton_manager_(new Singleton::ManagerImpl()), handler_(new ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), random_generator_(std::move(random_generator)), listener_component_factory_(*this), - worker_factory_(thread_local_, *api_, hooks), + worker_factory_(thread_local_, *api_, hooks, time_source), secret_manager_(new Secret::SecretManagerImpl()), dns_resolver_(dispatcher_->createDnsResolver({})), access_log_manager_(*api_, *dispatcher_, access_log_lock, store), terminated_(false) { diff --git a/source/server/worker_impl.cc b/source/server/worker_impl.cc index 2ddd6d78b7bd1..0e1e55e72dcad 100644 --- a/source/server/worker_impl.cc +++ b/source/server/worker_impl.cc @@ -14,8 +14,8 @@ namespace Envoy { namespace Server { -WorkerPtr ProdWorkerFactory::createWorker(TimeSource& time_source) { - Event::DispatcherPtr dispatcher(api_.allocateDispatcher(time_source)); +WorkerPtr ProdWorkerFactory::createWorker() { + Event::DispatcherPtr dispatcher(api_.allocateDispatcher(time_source_)); return WorkerPtr{new WorkerImpl( tls_, hooks_, std::move(dispatcher), Network::ConnectionHandlerPtr{new ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher)})}; diff --git a/source/server/worker_impl.h b/source/server/worker_impl.h index 98d6c6640546a..abf52da554df9 100644 --- a/source/server/worker_impl.h +++ b/source/server/worker_impl.h @@ -20,16 +20,18 @@ namespace Server { class ProdWorkerFactory : public WorkerFactory, Logger::Loggable { public: - ProdWorkerFactory(ThreadLocal::Instance& tls, Api::Api& api, TestHooks& hooks) - : tls_(tls), api_(api), hooks_(hooks) {} + ProdWorkerFactory(ThreadLocal::Instance& tls, Api::Api& api, TestHooks& hooks, + TimeSource& time_source) + : tls_(tls), api_(api), hooks_(hooks), time_source_(time_source) {} // Server::WorkerFactory - WorkerPtr createWorker(TimeSource&) override; + WorkerPtr createWorker() override; private: ThreadLocal::Instance& tls_; Api::Api& api_; TestHooks& hooks_; + TimeSource& time_source_; }; /** diff --git a/test/mocks/server/mocks.cc b/test/mocks/server/mocks.cc index 63146d05c8132..1325d2571df14 100644 --- a/test/mocks/server/mocks.cc +++ b/test/mocks/server/mocks.cc @@ -87,6 +87,7 @@ MockListenerManager::MockListenerManager() {} MockListenerManager::~MockListenerManager() {} MockWorkerFactory::MockWorkerFactory() {} + MockWorkerFactory::~MockWorkerFactory() {} MockWorker::MockWorker() { diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 445f92ef7886a..f315297b60476 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -234,11 +234,9 @@ class MockWorkerFactory : public WorkerFactory { ~MockWorkerFactory(); // Server::WorkerFactory - WorkerPtr createWorker(TimeSource& time_source) override { - return WorkerPtr{createWorker_(time_source)}; - } + WorkerPtr createWorker() override { return WorkerPtr{createWorker_()}; } - MOCK_METHOD1(createWorker_, Worker*(TimeSource&)); + MOCK_METHOD0(createWorker_, Worker*()); }; class MockWorker : public Worker { diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 94f2dffa01d79..6b435eefc068c 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -52,7 +52,7 @@ class ListenerHandle { class ListenerManagerImplTest : public testing::Test { public: ListenerManagerImplTest() : time_source_(system_time_source_, monotonic_time_source_) { - EXPECT_CALL(worker_factory_, createWorker_(time_source_)).WillOnce(Return(worker_)); + EXPECT_CALL(worker_factory_, createWorker_()).WillOnce(Return(worker_)); manager_.reset( new ListenerManagerImpl(server_, listener_factory_, worker_factory_, time_source_)); } From 1a84061a2c71ace0761772f1fa95f23bda3d5541 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 16:31:14 -0400 Subject: [PATCH 09/22] Fix race found in coverage tests due to order of destruction. Uncomment an assert and made it not fire. Signed-off-by: Joshua Marantz --- include/envoy/common/time.h | 24 ++++++++++++------- source/common/common/token_bucket_impl.h | 2 +- source/common/config/grpc_mux_impl.h | 2 +- .../common/upstream/cluster_manager_impl.cc | 4 ++-- source/extensions/tracers/zipkin/tracer.h | 2 +- .../tracers/zipkin/zipkin_core_types.h | 2 +- source/server/config_validation/server.h | 2 +- source/server/guarddog_impl.h | 2 +- source/server/listener_manager_impl.h | 2 +- source/server/watchdog_impl.h | 2 +- source/server/worker_impl.h | 2 +- .../upstream/cluster_manager_impl_test.cc | 5 ++++ test/mocks/event/mocks.cc | 2 +- test/mocks/event/mocks.h | 6 ++--- test/server/server_test.cc | 2 +- 15 files changed, 37 insertions(+), 24 deletions(-) diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index b4adb3960083b..eb9c1c960e3b4 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -56,33 +56,41 @@ class MonotonicTimeSource { class TimeSource { public: TimeSource(SystemTimeSource& system, MonotonicTimeSource& monotonic) - : system_(system), monotonic_(monotonic) {} + : system_(&system), monotonic_(&monotonic) {} + TimeSource(const TimeSource& src) : system_(src.system_), monotonic_(src.monotonic_) {} + TimeSource& operator=(const TimeSource& src) { + if (&src != this) { + system_ = src.system_; + monotonic_ = src.monotonic_; + } + return *this; + } /** * @return the current system time; not guaranteed to be monotonically increasing. */ - SystemTime systemTime() const { return system_.currentTime(); } + SystemTime systemTime() const { return system_->currentTime(); } /** * @return the current monotonic time. */ - MonotonicTime monotonicTime() const { return monotonic_.currentTime(); } + MonotonicTime monotonicTime() const { return monotonic_->currentTime(); } /** * Compares two time-sources for equality; this is needed for mocks. */ bool operator==(const TimeSource& ts) const { - return &system_ == &ts.system_ && &monotonic_ == &ts.monotonic_; + return system_ == ts.system_ && monotonic_ == ts.monotonic_; } // TODO(jmarantz): Eliminate these methods and the SystemTimeSource and MonotonicTimeSource // classes, and change method calls to work directly off of TimeSource. - SystemTimeSource& system() { return system_; } - MonotonicTimeSource& monotonic() { return monotonic_; } + SystemTimeSource& system() { return *system_; } + MonotonicTimeSource& monotonic() { return *monotonic_; } private: - SystemTimeSource& system_; - MonotonicTimeSource& monotonic_; + SystemTimeSource* system_; + MonotonicTimeSource* monotonic_; }; } // namespace Envoy diff --git a/source/common/common/token_bucket_impl.h b/source/common/common/token_bucket_impl.h index 13bf14435f509..49abae39af9b2 100644 --- a/source/common/common/token_bucket_impl.h +++ b/source/common/common/token_bucket_impl.h @@ -27,7 +27,7 @@ class TokenBucketImpl : public TokenBucket { const double fill_rate_; double tokens_; MonotonicTime last_fill_; - TimeSource& time_source_; + TimeSource time_source_; }; } // namespace Envoy diff --git a/source/common/config/grpc_mux_impl.h b/source/common/config/grpc_mux_impl.h index 8985cbbafc7a0..ad82356d1af71 100644 --- a/source/common/config/grpc_mux_impl.h +++ b/source/common/config/grpc_mux_impl.h @@ -103,7 +103,7 @@ class GrpcMuxImpl : public GrpcMux, std::list subscriptions_; Event::TimerPtr retry_timer_; Runtime::RandomGenerator& random_; - TimeSource& time_source_; + TimeSource time_source_; BackOffStrategyPtr backoff_strategy_; }; diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index 6a56988d899f7..a09c2675a410b 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -182,8 +182,8 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots config_tracker_entry_( admin.getConfigTracker().add("clusters", [this] { return dumpClusterConfigs(); })), time_source_(system_time_source, monotonic_time_source), dispatcher_(main_thread_dispatcher) { - // ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); - // ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); + ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); + ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); async_client_manager_ = std::make_unique(*this, tls); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { diff --git a/source/extensions/tracers/zipkin/tracer.h b/source/extensions/tracers/zipkin/tracer.h index ab68286b1cbf2..f177da30a7b12 100644 --- a/source/extensions/tracers/zipkin/tracer.h +++ b/source/extensions/tracers/zipkin/tracer.h @@ -116,7 +116,7 @@ class Tracer : public TracerInterface { ReporterPtr reporter_; Runtime::RandomGenerator& random_generator_; const bool trace_id_128bit_; - TimeSource& time_source_; + TimeSource time_source_; }; typedef std::unique_ptr TracerPtr; diff --git a/source/extensions/tracers/zipkin/zipkin_core_types.h b/source/extensions/tracers/zipkin/zipkin_core_types.h index 059191245abc9..bd83a1fa86074 100644 --- a/source/extensions/tracers/zipkin/zipkin_core_types.h +++ b/source/extensions/tracers/zipkin/zipkin_core_types.h @@ -562,7 +562,7 @@ class Span : public ZipkinBase { absl::optional trace_id_high_; int64_t monotonic_start_time_; TracerInterface* tracer_; - TimeSource& time_source_; + TimeSource time_source_; }; } // namespace Zipkin diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index 072e4fb6ea857..b985dd4955c6f 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -138,7 +138,7 @@ class ValidationInstance : Logger::Loggable, ComponentFactory& component_factory); Options& options_; - TimeSource& time_source_; + TimeSource time_source_; Stats::IsolatedStoreImpl& stats_store_; ThreadLocal::InstanceImpl thread_local_; Api::ApiPtr api_; diff --git a/source/server/guarddog_impl.h b/source/server/guarddog_impl.h index 95aebf775c8b6..543f7de8e1880 100644 --- a/source/server/guarddog_impl.h +++ b/source/server/guarddog_impl.h @@ -75,7 +75,7 @@ class GuardDogImpl : public GuardDog { bool megamiss_alerted_{}; }; - TimeSource& time_source_; + TimeSource time_source_; const std::chrono::milliseconds miss_timeout_; const std::chrono::milliseconds megamiss_timeout_; const std::chrono::milliseconds kill_timeout_; diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index a989cdd134f6a..84ae38aaae206 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -121,7 +121,7 @@ class ListenerManagerImpl : public ListenerManager, Logger::Loggable latest_touch_time_since_epoch_; Event::TimerPtr timer_; const std::chrono::milliseconds timer_interval_; diff --git a/source/server/worker_impl.h b/source/server/worker_impl.h index abf52da554df9..3ef7075ee806d 100644 --- a/source/server/worker_impl.h +++ b/source/server/worker_impl.h @@ -31,7 +31,7 @@ class ProdWorkerFactory : public WorkerFactory, Logger::Loggable system_time_source_; NiceMock monotonic_time_source_; MockLocalClusterUpdate local_cluster_update_; + TimeSource time_source_; }; envoy::config::bootstrap::v2::Bootstrap parseBootstrapFromJson(const std::string& json_string) { diff --git a/test/mocks/event/mocks.cc b/test/mocks/event/mocks.cc index 231121c6c51b4..94b5e88602fa0 100644 --- a/test/mocks/event/mocks.cc +++ b/test/mocks/event/mocks.cc @@ -13,7 +13,7 @@ using testing::_; namespace Envoy { namespace Event { -MockDispatcher::MockDispatcher() : time_source_(&test_time_.timeSource()) { +MockDispatcher::MockDispatcher() : time_source_(test_time_.timeSource()) { ON_CALL(*this, clearDeferredDeleteList()).WillByDefault(Invoke([this]() -> void { to_delete_.clear(); })); diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index b137a575c1c1b..c5f6bb5586b6d 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -30,10 +30,10 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); - void setTimeSource(TimeSource& time_source) { time_source_ = &time_source; } + void setTimeSource(const TimeSource& time_source) { time_source_ = time_source; } // Dispatcher - TimeSource& timeSource() override { return *time_source_; } + TimeSource& timeSource() override { return time_source_; } Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, Network::TransportSocketPtr&& transport_socket) override { @@ -109,7 +109,7 @@ class MockDispatcher : public Dispatcher { // TODO(jmarantz): Switch these to using mock-time. TestTime test_time_; - TimeSource* time_source_; + TimeSource time_source_; std::list to_delete_; MockBufferFactory buffer_factory_; diff --git a/test/server/server_test.cc b/test/server/server_test.cc index 5f3319b5a5a39..a7b828afa207e 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -144,8 +144,8 @@ class ServerInstanceImplTest : public testing::TestWithParam server_; TestTime test_time_; + std::unique_ptr server_; }; INSTANTIATE_TEST_CASE_P(IpVersions, ServerInstanceImplTest, From eb2347ed45ae77e375069c3a44f35c326b427021 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 16:54:11 -0400 Subject: [PATCH 10/22] Don't bother using a whole TimeSource for TokenBucketImpl -- all it needs is a MonotonicTimeSource, so no need for the added test complexity. Signed-off-by: Joshua Marantz --- source/common/common/token_bucket_impl.cc | 8 +++-- source/common/common/token_bucket_impl.h | 5 ++-- source/common/config/grpc_mux_impl.cc | 6 ++-- test/common/common/token_bucket_impl_test.cc | 31 +++++++++----------- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/source/common/common/token_bucket_impl.cc b/source/common/common/token_bucket_impl.cc index 07cf3a83c3e59..a46848ad34ff3 100644 --- a/source/common/common/token_bucket_impl.cc +++ b/source/common/common/token_bucket_impl.cc @@ -4,13 +4,15 @@ namespace Envoy { -TokenBucketImpl::TokenBucketImpl(uint64_t max_tokens, TimeSource& time_source, double fill_rate) +TokenBucketImpl::TokenBucketImpl(uint64_t max_tokens, MonotonicTimeSource& monotonic_time_source, + double fill_rate) : max_tokens_(max_tokens), fill_rate_(std::abs(fill_rate)), tokens_(max_tokens), - last_fill_(time_source.monotonicTime()), time_source_(time_source) {} + last_fill_(monotonic_time_source.currentTime()), + monotonic_time_source_(monotonic_time_source) {} bool TokenBucketImpl::consume(uint64_t tokens) { if (tokens_ < max_tokens_) { - const auto time_now = time_source_.monotonicTime(); + const auto time_now = monotonic_time_source_.currentTime(); tokens_ = std::min((std::chrono::duration(time_now - last_fill_).count() * fill_rate_) + tokens_, max_tokens_); diff --git a/source/common/common/token_bucket_impl.h b/source/common/common/token_bucket_impl.h index 49abae39af9b2..f652caeb54cf5 100644 --- a/source/common/common/token_bucket_impl.h +++ b/source/common/common/token_bucket_impl.h @@ -18,7 +18,8 @@ class TokenBucketImpl : public TokenBucket { * The default is 1. * @param time_source supplies the time source. */ - explicit TokenBucketImpl(uint64_t max_tokens, TimeSource& time_source, double fill_rate = 1); + explicit TokenBucketImpl(uint64_t max_tokens, MonotonicTimeSource& time_source, + double fill_rate = 1); bool consume(uint64_t tokens = 1) override; @@ -27,7 +28,7 @@ class TokenBucketImpl : public TokenBucket { const double fill_rate_; double tokens_; MonotonicTime last_fill_; - TimeSource time_source_; + MonotonicTimeSource& monotonic_time_source_; }; } // namespace Envoy diff --git a/source/common/config/grpc_mux_impl.cc b/source/common/config/grpc_mux_impl.cc index fd2d4c1c5c80a..480c8225ad43d 100644 --- a/source/common/config/grpc_mux_impl.cc +++ b/source/common/config/grpc_mux_impl.cc @@ -110,9 +110,11 @@ GrpcMuxWatchPtr GrpcMuxImpl::subscribe(const std::string& type_url, // TODO(gsagula): move TokenBucketImpl params to a config. if (!api_state_[type_url].subscribed_) { // Bucket contains 100 tokens maximum and refills at 5 tokens/sec. - api_state_[type_url].limit_request_ = std::make_unique(100, time_source_, 5); + api_state_[type_url].limit_request_ = + std::make_unique(100, time_source_.monotonic(), 5); // Bucket contains 1 token maximum and refills 1 token on every ~5 seconds. - api_state_[type_url].limit_log_ = std::make_unique(1, time_source_, 0.2); + api_state_[type_url].limit_log_ = + std::make_unique(1, time_source_.monotonic(), 0.2); api_state_[type_url].request_.set_type_url(type_url); api_state_[type_url].request_.mutable_node()->MergeFrom(node_); api_state_[type_url].subscribed_ = true; diff --git a/test/common/common/token_bucket_impl_test.cc b/test/common/common/token_bucket_impl_test.cc index fdc15475ac292..f6d0a9044e9cc 100644 --- a/test/common/common/token_bucket_impl_test.cc +++ b/test/common/common/token_bucket_impl_test.cc @@ -15,30 +15,27 @@ namespace Envoy { class TokenBucketImplTest : public testing::Test { public: - TokenBucketImplTest() : time_source_(mock_system_time_, mock_monotonic_time_) {} using time_point = std::chrono::steady_clock::time_point; protected: - NiceMock mock_system_time_; // not actually used in the test. - NiceMock mock_monotonic_time_; - TimeSource time_source_; + NiceMock mock_monotonic_time_source_; }; // Verifies TokenBucket initialization. TEST_F(TokenBucketImplTest, Initialization) { - TokenBucketImpl token_bucket{1, time_source_, -1.0}; + TokenBucketImpl token_bucket{1, mock_monotonic_time_source_, -1.0}; EXPECT_TRUE(token_bucket.consume()); - EXPECT_CALL(mock_monotonic_time_, currentTime()).WillOnce(Return(time_point{})); + EXPECT_CALL(mock_monotonic_time_source_, currentTime()).WillOnce(Return(time_point{})); EXPECT_FALSE(token_bucket.consume()); } // Verifies TokenBucket's maximum capacity. TEST_F(TokenBucketImplTest, MaxBucketSize) { - TokenBucketImpl token_bucket{3, time_source_, 1}; + TokenBucketImpl token_bucket{3, mock_monotonic_time_source_, 1}; EXPECT_TRUE(token_bucket.consume(3)); - EXPECT_CALL(mock_monotonic_time_, currentTime()) + EXPECT_CALL(mock_monotonic_time_source_, currentTime()) .WillOnce(Return(time_point(std::chrono::seconds(10)))); EXPECT_FALSE(token_bucket.consume(4)); @@ -48,35 +45,35 @@ TEST_F(TokenBucketImplTest, MaxBucketSize) { // Verifies that TokenBucket can consume and refill tokens. TEST_F(TokenBucketImplTest, ConsumeAndRefill) { { - TokenBucketImpl token_bucket{10, time_source_, 1}; + TokenBucketImpl token_bucket{10, mock_monotonic_time_source_, 1}; EXPECT_FALSE(token_bucket.consume(20)); EXPECT_TRUE(token_bucket.consume(9)); - EXPECT_CALL(mock_monotonic_time_, currentTime()).WillOnce(Return(time_point{})); + EXPECT_CALL(mock_monotonic_time_source_, currentTime()).WillOnce(Return(time_point{})); EXPECT_TRUE(token_bucket.consume()); - EXPECT_CALL(mock_monotonic_time_, currentTime()) + EXPECT_CALL(mock_monotonic_time_source_, currentTime()) .WillOnce(Return(time_point(std::chrono::milliseconds(999)))); EXPECT_FALSE(token_bucket.consume()); - EXPECT_CALL(mock_monotonic_time_, currentTime()) + EXPECT_CALL(mock_monotonic_time_source_, currentTime()) .WillOnce(Return(time_point(std::chrono::milliseconds(5999)))); EXPECT_FALSE(token_bucket.consume(6)); - EXPECT_CALL(mock_monotonic_time_, currentTime()) + EXPECT_CALL(mock_monotonic_time_source_, currentTime()) .WillRepeatedly(Return(time_point(std::chrono::milliseconds(6000)))); EXPECT_TRUE(token_bucket.consume(6)); EXPECT_FALSE(token_bucket.consume()); } - ASSERT_TRUE(Mock::VerifyAndClear(&mock_monotonic_time_)); + ASSERT_TRUE(Mock::VerifyAndClear(&mock_monotonic_time_source_)); { - TokenBucketImpl token_bucket{1, time_source_, 0.5}; + TokenBucketImpl token_bucket{1, mock_monotonic_time_source_, 0.5}; EXPECT_TRUE(token_bucket.consume()); - EXPECT_CALL(mock_monotonic_time_, currentTime()) + EXPECT_CALL(mock_monotonic_time_source_, currentTime()) .Times(3) .WillOnce(Return(time_point(std::chrono::milliseconds(500)))) .WillOnce(Return(time_point(std::chrono::milliseconds(1500)))) @@ -86,7 +83,7 @@ TEST_F(TokenBucketImplTest, ConsumeAndRefill) { EXPECT_FALSE(token_bucket.consume()); EXPECT_TRUE(token_bucket.consume()); - ASSERT_TRUE(Mock::VerifyAndClear(&mock_monotonic_time_)); + ASSERT_TRUE(Mock::VerifyAndClear(&mock_monotonic_time_source_)); } } From 21ac418e54a3d1a20ed8a53c427feaa3df483e42 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 17 Aug 2018 17:21:51 -0400 Subject: [PATCH 11/22] More API cleanups and TODOs. Signed-off-by: Joshua Marantz --- source/common/upstream/cluster_manager_impl.cc | 17 +++++++---------- source/common/upstream/cluster_manager_impl.h | 4 +--- .../server/config_validation/cluster_manager.cc | 4 +--- .../upstream/cluster_manager_impl_test.cc | 11 +++-------- .../server/config_validation/dispatcher_test.cc | 1 - test/test_common/test_time.h | 5 ++++- 6 files changed, 16 insertions(+), 26 deletions(-) diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index a09c2675a410b..1c50e7ca7c3fe 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -172,8 +172,7 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, - Server::Admin& admin, SystemTimeSource& system_time_source, - MonotonicTimeSource& monotonic_time_source) + Server::Admin& admin) : factory_(factory), runtime_(runtime), stats_(stats), tls_(tls.allocateSlot()), random_(random), log_manager_(log_manager), bind_config_(bootstrap.cluster_manager().upstream_bind_config()), local_info_(local_info), @@ -181,16 +180,15 @@ ClusterManagerImpl::ClusterManagerImpl(const envoy::config::bootstrap::v2::Boots init_helper_([this](Cluster& cluster) { onClusterInit(cluster); }), config_tracker_entry_( admin.getConfigTracker().add("clusters", [this] { return dumpClusterConfigs(); })), - time_source_(system_time_source, monotonic_time_source), dispatcher_(main_thread_dispatcher) { - ASSERT(&system_time_source == &main_thread_dispatcher.timeSource().system()); - ASSERT(&monotonic_time_source == &main_thread_dispatcher.timeSource().monotonic()); + time_source_(main_thread_dispatcher.timeSource()), dispatcher_(main_thread_dispatcher) { async_client_manager_ = std::make_unique(*this, tls); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { const std::string event_log_file_path = cm_config.outlier_detection().event_log_path(); if (!event_log_file_path.empty()) { outlier_event_logger_.reset(new Outlier::EventLoggerImpl( - log_manager, event_log_file_path, system_time_source, monotonic_time_source)); + log_manager, event_log_file_path, dispatcher_.timeSource().system(), + dispatcher_.timeSource().monotonic())); } } @@ -1178,10 +1176,9 @@ ClusterManagerPtr ProdClusterManagerFactory::clusterManagerFromProto( ThreadLocal::Instance& tls, Runtime::Loader& runtime, Runtime::RandomGenerator& random, const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Server::Admin& admin) { - TimeSource& time_source = main_thread_dispatcher_.timeSource(); - return ClusterManagerPtr{new ClusterManagerImpl( - bootstrap, *this, stats, tls, runtime, random, local_info, log_manager, - main_thread_dispatcher_, admin, time_source.system(), time_source.monotonic())}; + return ClusterManagerPtr{new ClusterManagerImpl(bootstrap, *this, stats, tls, runtime, random, + local_info, log_manager, main_thread_dispatcher_, + admin)}; } Http::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateConnPool( diff --git a/source/common/upstream/cluster_manager_impl.h b/source/common/upstream/cluster_manager_impl.h index 3cc2cc88bf22c..45fa479e7b94f 100644 --- a/source/common/upstream/cluster_manager_impl.h +++ b/source/common/upstream/cluster_manager_impl.h @@ -165,9 +165,7 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggable Date: Fri, 17 Aug 2018 19:26:51 -0400 Subject: [PATCH 12/22] Kick CI Signed-off-by: Joshua Marantz From 646a500cfaf2027f6a3c204a75f8fc1a2d417137 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Wed, 22 Aug 2018 12:36:10 -0400 Subject: [PATCH 13/22] formatting. Signed-off-by: Joshua Marantz --- test/common/config/grpc_mux_impl_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/common/config/grpc_mux_impl_test.cc b/test/common/config/grpc_mux_impl_test.cc index afe9a0bdd1ad2..3fd518ecd2f62 100644 --- a/test/common/config/grpc_mux_impl_test.cc +++ b/test/common/config/grpc_mux_impl_test.cc @@ -74,8 +74,8 @@ class GrpcMuxImplTest : public testing::Test { NiceMock dispatcher_; Runtime::MockRandomGenerator random_; Grpc::MockAsyncClient* async_client_; - Event::MockTimer* timer_; // Only used by ResetStream - Event::TimerCb timer_cb_; // Only used by ResetStream + Event::MockTimer* timer_; // Only used by ResetStream + Event::TimerCb timer_cb_; // Only used by ResetStream Grpc::MockAsyncStream async_stream_; std::unique_ptr grpc_mux_; NiceMock callbacks_; @@ -124,7 +124,7 @@ TEST_F(GrpcMuxImplTest, ResetStream) { grpc_mux_->start(); EXPECT_CALL(random_, random()); - ASSERT_TRUE(timer_ != nullptr); // timer_ initialized from dispatcher mock. + ASSERT_TRUE(timer_ != nullptr); // timer_ initialized from dispatcher mock. EXPECT_CALL(*timer_, enableTimer(_)); grpc_mux_->onRemoteClose(Grpc::Status::GrpcStatus::Canceled, ""); EXPECT_CALL(*async_client_, start(_, _)).WillOnce(Return(&async_stream_)); From e65a754c88737ca4551c8edd71396328a4835f39 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Wed, 22 Aug 2018 13:08:50 -0400 Subject: [PATCH 14/22] Add comment about preserving entropy in the future, when we move to mock-time. Signed-off-by: Joshua Marantz --- test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc index b15c25feba220..e148c56125b99 100644 --- a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc @@ -66,6 +66,9 @@ class ZipkinDriverTest : public Test { setup(*loader, true); } + // TODO(#4160): Currently time_source_ is initialized from TestTime, which uses real time, + // not mock-time. When that is switched to use mock-time intead, I think generateRandom64() + // may not be as random as we want, and we'll need to inject entropy appropriate for the test. uint64_t generateRandom64() { return Util::generateRandom64(time_source_); } const std::string operation_name_{"test"}; From c1f0dba7452306932f0054a7a30f29d6abc3966a Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Wed, 22 Aug 2018 16:55:22 -0400 Subject: [PATCH 15/22] Add check_format for instantiating time-sources in a new source file (tests excluded). Signed-off-by: Joshua Marantz --- tools/check_format.py | 18 ++++++++++++++++++ tools/check_format_test_helper.py | 8 ++++++++ .../check_format/prod_monotonic_time.cc | 4 ++++ .../testdata/check_format/prod_system_time.cc | 3 +++ 4 files changed, 33 insertions(+) create mode 100644 tools/testdata/check_format/prod_monotonic_time.cc create mode 100644 tools/testdata/check_format/prod_system_time.cc diff --git a/tools/check_format.py b/tools/check_format.py index c9e8fc2435359..6f643cd6b7f9c 100755 --- a/tools/check_format.py +++ b/tools/check_format.py @@ -23,6 +23,15 @@ GOOGLE_PROTOBUF_WHITELIST = ("ci/prebuilt", "source/common/protobuf", "api/test") REPOSITORIES_BZL = "bazel/repositories.bzl" +# Files matching these exact names can reference prod time. These include the class +# definitions for prod time, the construction of them in main(), and perf annotation. +# For now it includes the validation server but that really should be injected too. +PROD_TIME_WHITELIST = ('./source/common/common/utility.h', + './source/exe/main_common.cc', + './source/exe/main_common.h', + './source/server/config_validation/server.cc', + './source/common/common/perf_annotation.h') + CLANG_FORMAT_PATH = os.getenv("CLANG_FORMAT", "clang-format-6.0") BUILDIFIER_PATH = os.getenv("BUILDIFIER_BIN", "$GOPATH/bin/buildifier") ENVOY_BUILD_FIXER_PATH = os.path.join( @@ -65,6 +74,12 @@ def whitelistedForProtobufDeps(file_path): return (file_path.endswith(PROTO_SUFFIX) or file_path.endswith(REPOSITORIES_BZL) or \ any(path_segment in file_path for path_segment in GOOGLE_PROTOBUF_WHITELIST)) +# Production time sources should not be instantiated in the source, except for a few +# specific cases. They should be passed down from where they are instantied to where +# they need to be used, e.g. through the ServerInstance, Dispatcher, or ClusterManager. +def whitelistedForProdTime(file_path): + return file_path in PROD_TIME_WHITELIST or file_path.startswith('./test/') + def findSubstringAndReturnError(pattern, file_path, error_message): with open(file_path) as f: text = f.read() @@ -145,6 +160,9 @@ def checkSourceLine(line, file_path, reportError): # comments, for example this one. reportError("Don't use or , switch to " "Thread::MutexBasicLockable in source/common/common/thread.h") + if not whitelistedForProdTime(file_path): + if 'ProdSystemTimeSource' in line or 'ProdMonotonicTimeSource' in line: + reportError("Don't reference real-time sources from production code; use injection") def checkBuildLine(line, file_path, reportError): if not whitelistedForProtobufDeps(file_path) and '"protobuf"' in line: diff --git a/tools/check_format_test_helper.py b/tools/check_format_test_helper.py index 17ad7edf9f583..2d7b02081a34b 100755 --- a/tools/check_format_test_helper.py +++ b/tools/check_format_test_helper.py @@ -143,6 +143,10 @@ def checkFileExpectingOK(filename): "Don't use or ") errors += fixFileExpectingFailure("condition_variable_any.cc", "Don't use or ") + errors += fixFileExpectingFailure( + "prod_system_time.cc", "Don't reference real-time sources from production code; use injection") + errors += fixFileExpectingFailure( + "prod_monotonic_time.cc", "Don't reference real-time sources from production code; use injection") errors += fixFileExpectingNoChange("ok_file.cc") @@ -163,6 +167,10 @@ def checkFileExpectingOK(filename): errors += checkFileExpectingError("bad_envoy_build_sys_ref.BUILD", "Superfluous '@envoy//' prefix") errors += checkFileExpectingError("proto_format.proto", "clang-format check failed") + errors += checkFileExpectingError( + "prod_system_time.cc", "Don't reference real-time sources from production code; use injection") + errors += checkFileExpectingError( + "prod_monotonic_time.cc", "Don't reference real-time sources from production code; use injection") errors += checkFileExpectingOK("ok_file.cc") diff --git a/tools/testdata/check_format/prod_monotonic_time.cc b/tools/testdata/check_format/prod_monotonic_time.cc new file mode 100644 index 0000000000000..10bcfc7c5d3e1 --- /dev/null +++ b/tools/testdata/check_format/prod_monotonic_time.cc @@ -0,0 +1,4 @@ +int foo() { + ProdSystemTimeSource system_time; + ProdMonotonicTimeSource monotonic_time; +} diff --git a/tools/testdata/check_format/prod_system_time.cc b/tools/testdata/check_format/prod_system_time.cc new file mode 100644 index 0000000000000..a533661b9805e --- /dev/null +++ b/tools/testdata/check_format/prod_system_time.cc @@ -0,0 +1,3 @@ +int foo() { + ProdMonotonicTimeSource monotonic_time; +} From 5338985e49a14496ad20bc8114d8e9287ea9d2b1 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 23 Aug 2018 08:51:30 -0400 Subject: [PATCH 16/22] Address review comments. Signed-off-by: Joshua Marantz --- include/envoy/api/api.h | 1 + include/envoy/common/time.h | 11 ++++++----- source/common/common/utility.h | 4 ++-- source/server/http/admin.h | 2 +- test/common/config/grpc_mux_impl_test.cc | 21 +++++++++++---------- test/mocks/common.h | 4 ++-- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/envoy/api/api.h b/include/envoy/api/api.h index 6ab400cd197ff..39b4981635686 100644 --- a/include/envoy/api/api.h +++ b/include/envoy/api/api.h @@ -21,6 +21,7 @@ class Api { /** * Allocate a dispatcher. + * @param time_source the time source. * @return Event::DispatcherPtr which is owned by the caller. */ virtual Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) PURE; diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index eb9c1c960e3b4..52a876c599329 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -26,7 +26,7 @@ class SystemTimeSource { /** * @return the current system time. */ - virtual SystemTime currentTime() const PURE; + virtual SystemTime currentTime() PURE; }; /** @@ -42,7 +42,7 @@ class MonotonicTimeSource { /** * @return the current monotonic time. */ - virtual MonotonicTime currentTime() const PURE; + virtual MonotonicTime currentTime() PURE; }; /** @@ -51,7 +51,7 @@ class MonotonicTimeSource { * * TODO(#4160): currently this is just a container for SystemTimeSource and * MonotonicTimeSource but we should clean that up and just have this as the - * base class. + * base class. Once that's done, TimeSource will be a pure interface. */ class TimeSource { public: @@ -69,12 +69,12 @@ class TimeSource { /** * @return the current system time; not guaranteed to be monotonically increasing. */ - SystemTime systemTime() const { return system_->currentTime(); } + SystemTime systemTime() { return system_->currentTime(); } /** * @return the current monotonic time. */ - MonotonicTime monotonicTime() const { return monotonic_->currentTime(); } + MonotonicTime monotonicTime() { return monotonic_->currentTime(); } /** * Compares two time-sources for equality; this is needed for mocks. @@ -89,6 +89,7 @@ class TimeSource { MonotonicTimeSource& monotonic() { return *monotonic_; } private: + // These are pointers rather than references in order to support assignment. SystemTimeSource* system_; MonotonicTimeSource* monotonic_; }; diff --git a/source/common/common/utility.h b/source/common/common/utility.h index 18c71c1eb1d00..0373b4b36c864 100644 --- a/source/common/common/utility.h +++ b/source/common/common/utility.h @@ -101,7 +101,7 @@ class AccessLogDateTimeFormatter { class ProdSystemTimeSource : public SystemTimeSource { public: // SystemTimeSource - SystemTime currentTime() const override { return std::chrono::system_clock::now(); } + SystemTime currentTime() override { return std::chrono::system_clock::now(); } }; /** @@ -110,7 +110,7 @@ class ProdSystemTimeSource : public SystemTimeSource { class ProdMonotonicTimeSource : public MonotonicTimeSource { public: // MonotonicTimeSource - MonotonicTime currentTime() const override { return std::chrono::steady_clock::now(); } + MonotonicTime currentTime() override { return std::chrono::steady_clock::now(); } }; /** diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 18203e8c5d6a3..78957e06dc804 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -141,7 +141,7 @@ class AdminImpl : public Admin, SystemTime lastUpdated() const override { return time_source_.systemTime(); } Router::ConfigConstSharedPtr config_; - TimeSource time_source_; + TimeSource& time_source_; }; friend class AdminStatsTest; diff --git a/test/common/config/grpc_mux_impl_test.cc b/test/common/config/grpc_mux_impl_test.cc index 3fd518ecd2f62..cd2293c5d0e56 100644 --- a/test/common/config/grpc_mux_impl_test.cc +++ b/test/common/config/grpc_mux_impl_test.cc @@ -35,7 +35,7 @@ namespace { class GrpcMuxImplTest : public testing::Test { public: GrpcMuxImplTest() - : async_client_(new Grpc::MockAsyncClient()), timer_(nullptr), + : async_client_(new Grpc::MockAsyncClient()), mock_time_source_(mock_system_time_, mock_monotonic_time_) { dispatcher_.setTimeSource(mock_time_source_); } @@ -74,8 +74,6 @@ class GrpcMuxImplTest : public testing::Test { NiceMock dispatcher_; Runtime::MockRandomGenerator random_; Grpc::MockAsyncClient* async_client_; - Event::MockTimer* timer_; // Only used by ResetStream - Event::TimerCb timer_cb_; // Only used by ResetStream Grpc::MockAsyncStream async_stream_; std::unique_ptr grpc_mux_; NiceMock callbacks_; @@ -107,10 +105,13 @@ TEST_F(GrpcMuxImplTest, MultipleTypeUrlStreams) { // Validate behavior when multiple type URL watches are maintained and the stream is reset. TEST_F(GrpcMuxImplTest, ResetStream) { - EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([this](Event::TimerCb timer_cb) { - timer_cb_ = timer_cb; - timer_ = new Event::MockTimer(); - return timer_; + Event::MockTimer* timer = nullptr; + Event::TimerCb timer_cb; + EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([&timer, &timer_cb](Event::TimerCb cb) { + timer_cb = cb; + EXPECT_EQ(nullptr, timer); + timer = new Event::MockTimer(); + return timer; })); setup(); InSequence s; @@ -124,14 +125,14 @@ TEST_F(GrpcMuxImplTest, ResetStream) { grpc_mux_->start(); EXPECT_CALL(random_, random()); - ASSERT_TRUE(timer_ != nullptr); // timer_ initialized from dispatcher mock. - EXPECT_CALL(*timer_, enableTimer(_)); + ASSERT_TRUE(timer != nullptr); // initialized from dispatcher mock. + EXPECT_CALL(*timer, enableTimer(_)); grpc_mux_->onRemoteClose(Grpc::Status::GrpcStatus::Canceled, ""); EXPECT_CALL(*async_client_, start(_, _)).WillOnce(Return(&async_stream_)); expectSendMessage("foo", {"x", "y"}, ""); expectSendMessage("bar", {}, ""); expectSendMessage("baz", {"z"}, ""); - timer_cb_(); + timer_cb(); expectSendMessage("baz", {}, ""); expectSendMessage("foo", {}, ""); diff --git a/test/mocks/common.h b/test/mocks/common.h index 0dbdd828c4efc..70f6bb6f569d1 100644 --- a/test/mocks/common.h +++ b/test/mocks/common.h @@ -40,7 +40,7 @@ class MockSystemTimeSource : public SystemTimeSource { MockSystemTimeSource(); ~MockSystemTimeSource(); - MOCK_CONST_METHOD0(currentTime, SystemTime()); + MOCK_METHOD0(currentTime, SystemTime()); }; class MockMonotonicTimeSource : public MonotonicTimeSource { @@ -48,7 +48,7 @@ class MockMonotonicTimeSource : public MonotonicTimeSource { MockMonotonicTimeSource(); ~MockMonotonicTimeSource(); - MOCK_CONST_METHOD0(currentTime, MonotonicTime()); + MOCK_METHOD0(currentTime, MonotonicTime()); }; class MockTokenBucket : public TokenBucket { From edba78042aa7751f1aa836238b60d7daff348494 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 23 Aug 2018 09:08:29 -0400 Subject: [PATCH 17/22] Revert "Address review comments." This reverts commit 5338985e49a14496ad20bc8114d8e9287ea9d2b1. Signed-off-by: Joshua Marantz --- include/envoy/api/api.h | 1 - include/envoy/common/time.h | 11 +++++------ source/common/common/utility.h | 4 ++-- source/server/http/admin.h | 2 +- test/common/config/grpc_mux_impl_test.cc | 21 ++++++++++----------- test/mocks/common.h | 4 ++-- 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/include/envoy/api/api.h b/include/envoy/api/api.h index 39b4981635686..6ab400cd197ff 100644 --- a/include/envoy/api/api.h +++ b/include/envoy/api/api.h @@ -21,7 +21,6 @@ class Api { /** * Allocate a dispatcher. - * @param time_source the time source. * @return Event::DispatcherPtr which is owned by the caller. */ virtual Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) PURE; diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index 52a876c599329..eb9c1c960e3b4 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -26,7 +26,7 @@ class SystemTimeSource { /** * @return the current system time. */ - virtual SystemTime currentTime() PURE; + virtual SystemTime currentTime() const PURE; }; /** @@ -42,7 +42,7 @@ class MonotonicTimeSource { /** * @return the current monotonic time. */ - virtual MonotonicTime currentTime() PURE; + virtual MonotonicTime currentTime() const PURE; }; /** @@ -51,7 +51,7 @@ class MonotonicTimeSource { * * TODO(#4160): currently this is just a container for SystemTimeSource and * MonotonicTimeSource but we should clean that up and just have this as the - * base class. Once that's done, TimeSource will be a pure interface. + * base class. */ class TimeSource { public: @@ -69,12 +69,12 @@ class TimeSource { /** * @return the current system time; not guaranteed to be monotonically increasing. */ - SystemTime systemTime() { return system_->currentTime(); } + SystemTime systemTime() const { return system_->currentTime(); } /** * @return the current monotonic time. */ - MonotonicTime monotonicTime() { return monotonic_->currentTime(); } + MonotonicTime monotonicTime() const { return monotonic_->currentTime(); } /** * Compares two time-sources for equality; this is needed for mocks. @@ -89,7 +89,6 @@ class TimeSource { MonotonicTimeSource& monotonic() { return *monotonic_; } private: - // These are pointers rather than references in order to support assignment. SystemTimeSource* system_; MonotonicTimeSource* monotonic_; }; diff --git a/source/common/common/utility.h b/source/common/common/utility.h index 0373b4b36c864..18c71c1eb1d00 100644 --- a/source/common/common/utility.h +++ b/source/common/common/utility.h @@ -101,7 +101,7 @@ class AccessLogDateTimeFormatter { class ProdSystemTimeSource : public SystemTimeSource { public: // SystemTimeSource - SystemTime currentTime() override { return std::chrono::system_clock::now(); } + SystemTime currentTime() const override { return std::chrono::system_clock::now(); } }; /** @@ -110,7 +110,7 @@ class ProdSystemTimeSource : public SystemTimeSource { class ProdMonotonicTimeSource : public MonotonicTimeSource { public: // MonotonicTimeSource - MonotonicTime currentTime() override { return std::chrono::steady_clock::now(); } + MonotonicTime currentTime() const override { return std::chrono::steady_clock::now(); } }; /** diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 78957e06dc804..18203e8c5d6a3 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -141,7 +141,7 @@ class AdminImpl : public Admin, SystemTime lastUpdated() const override { return time_source_.systemTime(); } Router::ConfigConstSharedPtr config_; - TimeSource& time_source_; + TimeSource time_source_; }; friend class AdminStatsTest; diff --git a/test/common/config/grpc_mux_impl_test.cc b/test/common/config/grpc_mux_impl_test.cc index cd2293c5d0e56..3fd518ecd2f62 100644 --- a/test/common/config/grpc_mux_impl_test.cc +++ b/test/common/config/grpc_mux_impl_test.cc @@ -35,7 +35,7 @@ namespace { class GrpcMuxImplTest : public testing::Test { public: GrpcMuxImplTest() - : async_client_(new Grpc::MockAsyncClient()), + : async_client_(new Grpc::MockAsyncClient()), timer_(nullptr), mock_time_source_(mock_system_time_, mock_monotonic_time_) { dispatcher_.setTimeSource(mock_time_source_); } @@ -74,6 +74,8 @@ class GrpcMuxImplTest : public testing::Test { NiceMock dispatcher_; Runtime::MockRandomGenerator random_; Grpc::MockAsyncClient* async_client_; + Event::MockTimer* timer_; // Only used by ResetStream + Event::TimerCb timer_cb_; // Only used by ResetStream Grpc::MockAsyncStream async_stream_; std::unique_ptr grpc_mux_; NiceMock callbacks_; @@ -105,13 +107,10 @@ TEST_F(GrpcMuxImplTest, MultipleTypeUrlStreams) { // Validate behavior when multiple type URL watches are maintained and the stream is reset. TEST_F(GrpcMuxImplTest, ResetStream) { - Event::MockTimer* timer = nullptr; - Event::TimerCb timer_cb; - EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([&timer, &timer_cb](Event::TimerCb cb) { - timer_cb = cb; - EXPECT_EQ(nullptr, timer); - timer = new Event::MockTimer(); - return timer; + EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([this](Event::TimerCb timer_cb) { + timer_cb_ = timer_cb; + timer_ = new Event::MockTimer(); + return timer_; })); setup(); InSequence s; @@ -125,14 +124,14 @@ TEST_F(GrpcMuxImplTest, ResetStream) { grpc_mux_->start(); EXPECT_CALL(random_, random()); - ASSERT_TRUE(timer != nullptr); // initialized from dispatcher mock. - EXPECT_CALL(*timer, enableTimer(_)); + ASSERT_TRUE(timer_ != nullptr); // timer_ initialized from dispatcher mock. + EXPECT_CALL(*timer_, enableTimer(_)); grpc_mux_->onRemoteClose(Grpc::Status::GrpcStatus::Canceled, ""); EXPECT_CALL(*async_client_, start(_, _)).WillOnce(Return(&async_stream_)); expectSendMessage("foo", {"x", "y"}, ""); expectSendMessage("bar", {}, ""); expectSendMessage("baz", {"z"}, ""); - timer_cb(); + timer_cb_(); expectSendMessage("baz", {}, ""); expectSendMessage("foo", {}, ""); diff --git a/test/mocks/common.h b/test/mocks/common.h index 70f6bb6f569d1..0dbdd828c4efc 100644 --- a/test/mocks/common.h +++ b/test/mocks/common.h @@ -40,7 +40,7 @@ class MockSystemTimeSource : public SystemTimeSource { MockSystemTimeSource(); ~MockSystemTimeSource(); - MOCK_METHOD0(currentTime, SystemTime()); + MOCK_CONST_METHOD0(currentTime, SystemTime()); }; class MockMonotonicTimeSource : public MonotonicTimeSource { @@ -48,7 +48,7 @@ class MockMonotonicTimeSource : public MonotonicTimeSource { MockMonotonicTimeSource(); ~MockMonotonicTimeSource(); - MOCK_METHOD0(currentTime, MonotonicTime()); + MOCK_CONST_METHOD0(currentTime, MonotonicTime()); }; class MockTokenBucket : public TokenBucket { From be44f2d2a6b221a3802f9c65cc8bbcf06df430f8 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 23 Aug 2018 08:51:30 -0400 Subject: [PATCH 18/22] Address review comments. Signed-off-by: Joshua Marantz --- include/envoy/api/api.h | 1 + include/envoy/common/time.h | 11 ++++++----- source/common/common/utility.h | 4 ++-- source/server/http/admin.h | 2 +- test/common/config/grpc_mux_impl_test.cc | 21 +++++++++++---------- test/mocks/common.h | 4 ++-- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/envoy/api/api.h b/include/envoy/api/api.h index 6ab400cd197ff..39b4981635686 100644 --- a/include/envoy/api/api.h +++ b/include/envoy/api/api.h @@ -21,6 +21,7 @@ class Api { /** * Allocate a dispatcher. + * @param time_source the time source. * @return Event::DispatcherPtr which is owned by the caller. */ virtual Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) PURE; diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index eb9c1c960e3b4..52a876c599329 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -26,7 +26,7 @@ class SystemTimeSource { /** * @return the current system time. */ - virtual SystemTime currentTime() const PURE; + virtual SystemTime currentTime() PURE; }; /** @@ -42,7 +42,7 @@ class MonotonicTimeSource { /** * @return the current monotonic time. */ - virtual MonotonicTime currentTime() const PURE; + virtual MonotonicTime currentTime() PURE; }; /** @@ -51,7 +51,7 @@ class MonotonicTimeSource { * * TODO(#4160): currently this is just a container for SystemTimeSource and * MonotonicTimeSource but we should clean that up and just have this as the - * base class. + * base class. Once that's done, TimeSource will be a pure interface. */ class TimeSource { public: @@ -69,12 +69,12 @@ class TimeSource { /** * @return the current system time; not guaranteed to be monotonically increasing. */ - SystemTime systemTime() const { return system_->currentTime(); } + SystemTime systemTime() { return system_->currentTime(); } /** * @return the current monotonic time. */ - MonotonicTime monotonicTime() const { return monotonic_->currentTime(); } + MonotonicTime monotonicTime() { return monotonic_->currentTime(); } /** * Compares two time-sources for equality; this is needed for mocks. @@ -89,6 +89,7 @@ class TimeSource { MonotonicTimeSource& monotonic() { return *monotonic_; } private: + // These are pointers rather than references in order to support assignment. SystemTimeSource* system_; MonotonicTimeSource* monotonic_; }; diff --git a/source/common/common/utility.h b/source/common/common/utility.h index 18c71c1eb1d00..0373b4b36c864 100644 --- a/source/common/common/utility.h +++ b/source/common/common/utility.h @@ -101,7 +101,7 @@ class AccessLogDateTimeFormatter { class ProdSystemTimeSource : public SystemTimeSource { public: // SystemTimeSource - SystemTime currentTime() const override { return std::chrono::system_clock::now(); } + SystemTime currentTime() override { return std::chrono::system_clock::now(); } }; /** @@ -110,7 +110,7 @@ class ProdSystemTimeSource : public SystemTimeSource { class ProdMonotonicTimeSource : public MonotonicTimeSource { public: // MonotonicTimeSource - MonotonicTime currentTime() const override { return std::chrono::steady_clock::now(); } + MonotonicTime currentTime() override { return std::chrono::steady_clock::now(); } }; /** diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 18203e8c5d6a3..78957e06dc804 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -141,7 +141,7 @@ class AdminImpl : public Admin, SystemTime lastUpdated() const override { return time_source_.systemTime(); } Router::ConfigConstSharedPtr config_; - TimeSource time_source_; + TimeSource& time_source_; }; friend class AdminStatsTest; diff --git a/test/common/config/grpc_mux_impl_test.cc b/test/common/config/grpc_mux_impl_test.cc index 3fd518ecd2f62..cd2293c5d0e56 100644 --- a/test/common/config/grpc_mux_impl_test.cc +++ b/test/common/config/grpc_mux_impl_test.cc @@ -35,7 +35,7 @@ namespace { class GrpcMuxImplTest : public testing::Test { public: GrpcMuxImplTest() - : async_client_(new Grpc::MockAsyncClient()), timer_(nullptr), + : async_client_(new Grpc::MockAsyncClient()), mock_time_source_(mock_system_time_, mock_monotonic_time_) { dispatcher_.setTimeSource(mock_time_source_); } @@ -74,8 +74,6 @@ class GrpcMuxImplTest : public testing::Test { NiceMock dispatcher_; Runtime::MockRandomGenerator random_; Grpc::MockAsyncClient* async_client_; - Event::MockTimer* timer_; // Only used by ResetStream - Event::TimerCb timer_cb_; // Only used by ResetStream Grpc::MockAsyncStream async_stream_; std::unique_ptr grpc_mux_; NiceMock callbacks_; @@ -107,10 +105,13 @@ TEST_F(GrpcMuxImplTest, MultipleTypeUrlStreams) { // Validate behavior when multiple type URL watches are maintained and the stream is reset. TEST_F(GrpcMuxImplTest, ResetStream) { - EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([this](Event::TimerCb timer_cb) { - timer_cb_ = timer_cb; - timer_ = new Event::MockTimer(); - return timer_; + Event::MockTimer* timer = nullptr; + Event::TimerCb timer_cb; + EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([&timer, &timer_cb](Event::TimerCb cb) { + timer_cb = cb; + EXPECT_EQ(nullptr, timer); + timer = new Event::MockTimer(); + return timer; })); setup(); InSequence s; @@ -124,14 +125,14 @@ TEST_F(GrpcMuxImplTest, ResetStream) { grpc_mux_->start(); EXPECT_CALL(random_, random()); - ASSERT_TRUE(timer_ != nullptr); // timer_ initialized from dispatcher mock. - EXPECT_CALL(*timer_, enableTimer(_)); + ASSERT_TRUE(timer != nullptr); // initialized from dispatcher mock. + EXPECT_CALL(*timer, enableTimer(_)); grpc_mux_->onRemoteClose(Grpc::Status::GrpcStatus::Canceled, ""); EXPECT_CALL(*async_client_, start(_, _)).WillOnce(Return(&async_stream_)); expectSendMessage("foo", {"x", "y"}, ""); expectSendMessage("bar", {}, ""); expectSendMessage("baz", {"z"}, ""); - timer_cb_(); + timer_cb(); expectSendMessage("baz", {}, ""); expectSendMessage("foo", {}, ""); diff --git a/test/mocks/common.h b/test/mocks/common.h index 0dbdd828c4efc..70f6bb6f569d1 100644 --- a/test/mocks/common.h +++ b/test/mocks/common.h @@ -40,7 +40,7 @@ class MockSystemTimeSource : public SystemTimeSource { MockSystemTimeSource(); ~MockSystemTimeSource(); - MOCK_CONST_METHOD0(currentTime, SystemTime()); + MOCK_METHOD0(currentTime, SystemTime()); }; class MockMonotonicTimeSource : public MonotonicTimeSource { @@ -48,7 +48,7 @@ class MockMonotonicTimeSource : public MonotonicTimeSource { MockMonotonicTimeSource(); ~MockMonotonicTimeSource(); - MOCK_CONST_METHOD0(currentTime, MonotonicTime()); + MOCK_METHOD0(currentTime, MonotonicTime()); }; class MockTokenBucket : public TokenBucket { From 1488d58efb8a9d9ca3241909cc1c7ef219db3870 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 23 Aug 2018 11:26:17 -0400 Subject: [PATCH 19/22] Kick CI Signed-off-by: Joshua Marantz From 416917f5e4fdfa2653d684700fc77cf153a0cd32 Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 23 Aug 2018 08:51:30 -0400 Subject: [PATCH 20/22] Address review comments. Signed-off-by: Joshua Marantz --- include/envoy/api/api.h | 1 + include/envoy/common/time.h | 11 ++++++----- source/common/common/utility.h | 4 ++-- source/server/http/admin.h | 2 +- test/common/config/grpc_mux_impl_test.cc | 21 +++++++++++---------- test/mocks/common.h | 4 ++-- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/envoy/api/api.h b/include/envoy/api/api.h index 6ab400cd197ff..39b4981635686 100644 --- a/include/envoy/api/api.h +++ b/include/envoy/api/api.h @@ -21,6 +21,7 @@ class Api { /** * Allocate a dispatcher. + * @param time_source the time source. * @return Event::DispatcherPtr which is owned by the caller. */ virtual Event::DispatcherPtr allocateDispatcher(TimeSource& time_source) PURE; diff --git a/include/envoy/common/time.h b/include/envoy/common/time.h index eb9c1c960e3b4..52a876c599329 100644 --- a/include/envoy/common/time.h +++ b/include/envoy/common/time.h @@ -26,7 +26,7 @@ class SystemTimeSource { /** * @return the current system time. */ - virtual SystemTime currentTime() const PURE; + virtual SystemTime currentTime() PURE; }; /** @@ -42,7 +42,7 @@ class MonotonicTimeSource { /** * @return the current monotonic time. */ - virtual MonotonicTime currentTime() const PURE; + virtual MonotonicTime currentTime() PURE; }; /** @@ -51,7 +51,7 @@ class MonotonicTimeSource { * * TODO(#4160): currently this is just a container for SystemTimeSource and * MonotonicTimeSource but we should clean that up and just have this as the - * base class. + * base class. Once that's done, TimeSource will be a pure interface. */ class TimeSource { public: @@ -69,12 +69,12 @@ class TimeSource { /** * @return the current system time; not guaranteed to be monotonically increasing. */ - SystemTime systemTime() const { return system_->currentTime(); } + SystemTime systemTime() { return system_->currentTime(); } /** * @return the current monotonic time. */ - MonotonicTime monotonicTime() const { return monotonic_->currentTime(); } + MonotonicTime monotonicTime() { return monotonic_->currentTime(); } /** * Compares two time-sources for equality; this is needed for mocks. @@ -89,6 +89,7 @@ class TimeSource { MonotonicTimeSource& monotonic() { return *monotonic_; } private: + // These are pointers rather than references in order to support assignment. SystemTimeSource* system_; MonotonicTimeSource* monotonic_; }; diff --git a/source/common/common/utility.h b/source/common/common/utility.h index 18c71c1eb1d00..0373b4b36c864 100644 --- a/source/common/common/utility.h +++ b/source/common/common/utility.h @@ -101,7 +101,7 @@ class AccessLogDateTimeFormatter { class ProdSystemTimeSource : public SystemTimeSource { public: // SystemTimeSource - SystemTime currentTime() const override { return std::chrono::system_clock::now(); } + SystemTime currentTime() override { return std::chrono::system_clock::now(); } }; /** @@ -110,7 +110,7 @@ class ProdSystemTimeSource : public SystemTimeSource { class ProdMonotonicTimeSource : public MonotonicTimeSource { public: // MonotonicTimeSource - MonotonicTime currentTime() const override { return std::chrono::steady_clock::now(); } + MonotonicTime currentTime() override { return std::chrono::steady_clock::now(); } }; /** diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 18203e8c5d6a3..78957e06dc804 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -141,7 +141,7 @@ class AdminImpl : public Admin, SystemTime lastUpdated() const override { return time_source_.systemTime(); } Router::ConfigConstSharedPtr config_; - TimeSource time_source_; + TimeSource& time_source_; }; friend class AdminStatsTest; diff --git a/test/common/config/grpc_mux_impl_test.cc b/test/common/config/grpc_mux_impl_test.cc index 3fd518ecd2f62..cd2293c5d0e56 100644 --- a/test/common/config/grpc_mux_impl_test.cc +++ b/test/common/config/grpc_mux_impl_test.cc @@ -35,7 +35,7 @@ namespace { class GrpcMuxImplTest : public testing::Test { public: GrpcMuxImplTest() - : async_client_(new Grpc::MockAsyncClient()), timer_(nullptr), + : async_client_(new Grpc::MockAsyncClient()), mock_time_source_(mock_system_time_, mock_monotonic_time_) { dispatcher_.setTimeSource(mock_time_source_); } @@ -74,8 +74,6 @@ class GrpcMuxImplTest : public testing::Test { NiceMock dispatcher_; Runtime::MockRandomGenerator random_; Grpc::MockAsyncClient* async_client_; - Event::MockTimer* timer_; // Only used by ResetStream - Event::TimerCb timer_cb_; // Only used by ResetStream Grpc::MockAsyncStream async_stream_; std::unique_ptr grpc_mux_; NiceMock callbacks_; @@ -107,10 +105,13 @@ TEST_F(GrpcMuxImplTest, MultipleTypeUrlStreams) { // Validate behavior when multiple type URL watches are maintained and the stream is reset. TEST_F(GrpcMuxImplTest, ResetStream) { - EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([this](Event::TimerCb timer_cb) { - timer_cb_ = timer_cb; - timer_ = new Event::MockTimer(); - return timer_; + Event::MockTimer* timer = nullptr; + Event::TimerCb timer_cb; + EXPECT_CALL(dispatcher_, createTimer_(_)).WillOnce(Invoke([&timer, &timer_cb](Event::TimerCb cb) { + timer_cb = cb; + EXPECT_EQ(nullptr, timer); + timer = new Event::MockTimer(); + return timer; })); setup(); InSequence s; @@ -124,14 +125,14 @@ TEST_F(GrpcMuxImplTest, ResetStream) { grpc_mux_->start(); EXPECT_CALL(random_, random()); - ASSERT_TRUE(timer_ != nullptr); // timer_ initialized from dispatcher mock. - EXPECT_CALL(*timer_, enableTimer(_)); + ASSERT_TRUE(timer != nullptr); // initialized from dispatcher mock. + EXPECT_CALL(*timer, enableTimer(_)); grpc_mux_->onRemoteClose(Grpc::Status::GrpcStatus::Canceled, ""); EXPECT_CALL(*async_client_, start(_, _)).WillOnce(Return(&async_stream_)); expectSendMessage("foo", {"x", "y"}, ""); expectSendMessage("bar", {}, ""); expectSendMessage("baz", {"z"}, ""); - timer_cb_(); + timer_cb(); expectSendMessage("baz", {}, ""); expectSendMessage("foo", {}, ""); diff --git a/test/mocks/common.h b/test/mocks/common.h index 0dbdd828c4efc..70f6bb6f569d1 100644 --- a/test/mocks/common.h +++ b/test/mocks/common.h @@ -40,7 +40,7 @@ class MockSystemTimeSource : public SystemTimeSource { MockSystemTimeSource(); ~MockSystemTimeSource(); - MOCK_CONST_METHOD0(currentTime, SystemTime()); + MOCK_METHOD0(currentTime, SystemTime()); }; class MockMonotonicTimeSource : public MonotonicTimeSource { @@ -48,7 +48,7 @@ class MockMonotonicTimeSource : public MonotonicTimeSource { MockMonotonicTimeSource(); ~MockMonotonicTimeSource(); - MOCK_CONST_METHOD0(currentTime, MonotonicTime()); + MOCK_METHOD0(currentTime, MonotonicTime()); }; class MockTokenBucket : public TokenBucket { From 6d9fac6dc854a6d691c338dd05777e196de7f83f Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Thu, 23 Aug 2018 18:41:25 -0400 Subject: [PATCH 21/22] Rename 'TestTime' to 'RealTestTime' and add TODO to change all tests to use 'SimulatedTestTime' which hasn't been built yet. Signed-off-by: Joshua Marantz --- .../filesystem_subscription_test_harness.h | 2 +- test/common/event/dispatched_thread_impl_test.cc | 2 +- test/common/event/dispatcher_impl_test.cc | 4 ++-- test/common/event/file_event_impl_test.cc | 4 ++-- test/common/filesystem/watcher_impl_test.cc | 2 +- .../common/grpc/google_async_client_impl_test.cc | 2 +- .../grpc/grpc_client_integration_test_harness.h | 2 +- test/common/http/codec_client_test.cc | 4 ++-- test/common/http/conn_manager_impl_fuzz_test.cc | 2 +- test/common/http/conn_manager_impl_test.cc | 2 +- test/common/http/http1/conn_pool_test.cc | 2 +- test/common/http/http2/conn_pool_test.cc | 2 +- test/common/network/connection_impl_test.cc | 6 +++--- test/common/network/dns_impl_test.cc | 4 ++-- test/common/network/listener_impl_test.cc | 4 ++-- test/common/ssl/ssl_socket_test.cc | 8 ++++---- .../thread_local/thread_local_impl_test.cc | 2 +- .../proxy_protocol/proxy_protocol_test.cc | 4 ++-- .../tracers/zipkin/span_buffer_test.cc | 4 ++-- test/extensions/tracers/zipkin/tracer_test.cc | 2 +- test/extensions/tracers/zipkin/util_test.cc | 2 +- .../tracers/zipkin/zipkin_core_types_test.cc | 16 ++++++++-------- .../tracers/zipkin/zipkin_tracer_impl_test.cc | 4 ++-- test/integration/fake_upstream.h | 2 +- test/integration/integration.h | 2 +- test/integration/server.h | 2 +- test/integration/utility.cc | 2 +- test/integration/utility.h | 2 +- test/mocks/event/mocks.h | 2 +- test/mocks/server/mocks.h | 2 +- .../config_validation/async_client_test.cc | 2 +- test/server/config_validation/dispatcher_test.cc | 2 +- test/server/server_fuzz_test.cc | 2 +- test/server/server_test.cc | 2 +- test/server/worker_impl_test.cc | 2 +- test/test_common/test_time.cc | 2 +- test/test_common/test_time.h | 10 ++++++++-- 37 files changed, 64 insertions(+), 58 deletions(-) diff --git a/test/common/config/filesystem_subscription_test_harness.h b/test/common/config/filesystem_subscription_test_harness.h index 8a6da107ea77c..4aa1968dad167 100644 --- a/test/common/config/filesystem_subscription_test_harness.h +++ b/test/common/config/filesystem_subscription_test_harness.h @@ -95,7 +95,7 @@ class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { const std::string path_; std::string version_; - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; NiceMock> callbacks_; FilesystemEdsSubscriptionImpl subscription_; diff --git a/test/common/event/dispatched_thread_impl_test.cc b/test/common/event/dispatched_thread_impl_test.cc index 079b94f0751c0..1c215bbd67ecb 100644 --- a/test/common/event/dispatched_thread_impl_test.cc +++ b/test/common/event/dispatched_thread_impl_test.cc @@ -28,7 +28,7 @@ class DispatchedThreadTest : public testing::Test { void SetUp() { thread_.start(guard_dog_); } NiceMock config_; NiceMock fakestats_; - TestTime test_time_; + RealTestTime test_time_; Envoy::Server::GuardDogImpl guard_dog_; DispatchedThreadImpl thread_; }; diff --git a/test/common/event/dispatcher_impl_test.cc b/test/common/event/dispatcher_impl_test.cc index c623d605b4af0..35885ad7ee2a8 100644 --- a/test/common/event/dispatcher_impl_test.cc +++ b/test/common/event/dispatcher_impl_test.cc @@ -26,7 +26,7 @@ class TestDeferredDeletable : public DeferredDeletable { TEST(DeferredDeleteTest, DeferredDelete) { InSequence s; - TestTime test_time; + RealTestTime test_time; DispatcherImpl dispatcher(test_time.timeSource()); ReadyWatcher watcher1; @@ -76,7 +76,7 @@ class DispatcherImplTest : public ::testing::Test { dispatcher_thread_->join(); } - TestTime test_time_; + RealTestTime test_time_; std::unique_ptr dispatcher_thread_; DispatcherPtr dispatcher_; diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index 9563b3dbbb011..803b0676b2a94 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -33,7 +33,7 @@ class FileEventImplTest : public testing::Test { protected: int fds_[2]; - TestTime test_time_; + RealTestTime test_time_; DispatcherImpl dispatcher_; }; @@ -52,7 +52,7 @@ TEST_P(FileEventImplActivateTest, Activate) { } ASSERT_NE(-1, fd); - TestTime test_time; + RealTestTime test_time; DispatcherImpl dispatcher(test_time.timeSource()); ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(1); diff --git a/test/common/filesystem/watcher_impl_test.cc b/test/common/filesystem/watcher_impl_test.cc index 02eee16321338..070850413f4d9 100644 --- a/test/common/filesystem/watcher_impl_test.cc +++ b/test/common/filesystem/watcher_impl_test.cc @@ -18,7 +18,7 @@ class WatcherImplTest : public testing::Test { protected: WatcherImplTest() : dispatcher_(test_time_.timeSource()) {} - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; }; diff --git a/test/common/grpc/google_async_client_impl_test.cc b/test/common/grpc/google_async_client_impl_test.cc index 82c644ed6ae72..cd4c17b82968c 100644 --- a/test/common/grpc/google_async_client_impl_test.cc +++ b/test/common/grpc/google_async_client_impl_test.cc @@ -56,7 +56,7 @@ class EnvoyGoogleAsyncClientImplTest : public testing::Test { stats_store_, config); } - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; std::unique_ptr tls_; MockStubFactory stub_factory_; diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index f65ffa6b2edd8..905a5bb5e3f0b 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -395,7 +395,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { FakeHttpConnectionPtr fake_connection_; std::vector fake_streams_; const Protobuf::MethodDescriptor* method_descriptor_; - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; DispatcherHelper dispatcher_helper_{dispatcher_}; Stats::IsolatedStoreImpl* stats_store_ = new Stats::IsolatedStoreImpl(); diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 5652ecd0d880c..fafaa1fab0547 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -60,7 +60,7 @@ class CodecClientTest : public testing::Test { ~CodecClientTest() { EXPECT_EQ(0U, client_->numActiveRequests()); } - TestTime test_time_; + RealTestTime test_time_; Event::MockDispatcher dispatcher_; Network::MockClientConnection* connection_; Http::MockClientConnection* codec_; @@ -328,7 +328,7 @@ class CodecNetworkTest : public testing::TestWithParam filter_factory_; absl::optional idle_timeout_; - TestTime test_time_; + RealTestTime test_time_; RouteConfigProvider route_config_provider_; std::string server_name_; Stats::IsolatedStoreImpl fake_stats_; diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index 28a5d76590530..f0c515885fc14 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -277,7 +277,7 @@ class HttpConnectionManagerImplTest : public Test, public ConnectionManagerConfi bool proxy100Continue() const override { return proxy_100_continue_; } const Http::Http1Settings& http1Settings() const override { return http1_settings_; } - TestTime test_time_; + RealTestTime test_time_; RouteConfigProvider route_config_provider_; NiceMock tracer_; NiceMock runtime_; diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index c3b87e6cc9b29..9c1115dcfe183 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -111,7 +111,7 @@ class ConnPoolImplForTest : public ConnPoolImpl { EXPECT_FALSE(upstream_ready_enabled_); } - TestTime test_time_; + RealTestTime test_time_; Event::MockDispatcher& mock_dispatcher_; NiceMock* mock_upstream_ready_timer_; std::vector test_clients_; diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index ca3382d916933..3df8240d7124f 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -102,7 +102,7 @@ class Http2ConnPoolImplTest : public testing::Test { MOCK_METHOD0(onClientDestroy, void()); - TestTime test_time_; + RealTestTime test_time_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; Upstream::HostSharedPtr host_{Upstream::makeTestHost(cluster_, "tcp://127.0.0.1:80")}; diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index a019b7493704f..4d77fea8bdf19 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -77,7 +77,7 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ConnectionImplDeathTest, TestUtility::ipTestParamsToString); TEST_P(ConnectionImplDeathTest, BadFd) { - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); EXPECT_DEATH_LOG_TO_STDERR( ConnectionImpl(dispatcher, std::make_unique(-1, nullptr, nullptr), @@ -169,7 +169,7 @@ class ConnectionImplTest : public testing::TestWithParam { } protected: - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherPtr dispatcher_; Stats::IsolatedStoreImpl stats_store_; Network::TcpListenSocket socket_{Network::Test::getAnyAddress(GetParam()), nullptr, true}; @@ -1271,7 +1271,7 @@ TEST_P(ReadBufferLimitTest, SomeLimit) { class TcpClientConnectionImplTest : public testing::TestWithParam { protected: TcpClientConnectionImplTest() : dispatcher_(test_time_.timeSource()) {} - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; }; INSTANTIATE_TEST_CASE_P(IpVersions, TcpClientConnectionImplTest, diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 7bf4533b6897e..8b70a7b3ada9a 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -323,7 +323,7 @@ class DnsResolverImplPeer { class DnsImplConstructor : public testing::Test { protected: DnsImplConstructor() : dispatcher_(test_time_.timeSource()) {} - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; }; @@ -434,7 +434,7 @@ class DnsImplTest : public testing::TestWithParam { Network::TcpListenSocketPtr socket_; Stats::IsolatedStoreImpl stats_store_; std::unique_ptr listener_; - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; DnsResolverSharedPtr resolver_; }; diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index a703df0e661b3..e20898aa8130d 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -23,7 +23,7 @@ static void errorCallbackTest(Address::IpVersion version) { // Force the error callback to fire by closing the socket under the listener. We run this entire // test in the forked process to avoid confusion when the fork happens. Stats::IsolatedStoreImpl stats_store; - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, @@ -83,7 +83,7 @@ class ListenerImplTest : public testing::TestWithParam { const Address::IpVersion version_; const Address::InstanceConstSharedPtr alt_address_; - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherImpl dispatcher_; }; INSTANTIATE_TEST_CASE_P(IpVersions, ListenerImplTest, diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 63b9911c064b4..f8c542723d0b9 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -59,7 +59,7 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); @@ -163,7 +163,7 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, server_names); - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); @@ -302,7 +302,7 @@ class SslSocketTest : public SslCertsTest, protected: SslSocketTest() : dispatcher_(std::make_unique(test_time_.timeSource())) {} - TestTime test_time_; + RealTestTime test_time_; std::unique_ptr dispatcher_; }; @@ -1780,7 +1780,7 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true, false); Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); diff --git a/test/common/thread_local/thread_local_impl_test.cc b/test/common/thread_local/thread_local_impl_test.cc index cbba76979fee8..3f780d0e61f21 100644 --- a/test/common/thread_local/thread_local_impl_test.cc +++ b/test/common/thread_local/thread_local_impl_test.cc @@ -115,7 +115,7 @@ TEST_F(ThreadLocalInstanceImplTest, RunOnAllThreads) { TEST(ThreadLocalInstanceImplDispatcherTest, Dispatcher) { InstanceImpl tls; - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl main_dispatcher(test_time.timeSource()); Event::DispatcherImpl thread_dispatcher(test_time.timeSource()); diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index 36c68c37e6dcf..f48acd63159ba 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -144,7 +144,7 @@ class ProxyProtocolTest : public testing::TestWithParam( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -147,7 +147,7 @@ TEST(ZipkinCoreTypesAnnotationTest, customConstructor) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); - TestTime test_time; + RealTestTime test_time; uint64_t timestamp = std::chrono::duration_cast( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -172,7 +172,7 @@ TEST(ZipkinCoreTypesAnnotationTest, copyConstructor) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); - TestTime test_time; + RealTestTime test_time; uint64_t timestamp = std::chrono::duration_cast( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -190,7 +190,7 @@ TEST(ZipkinCoreTypesAnnotationTest, assignmentOperator) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); - TestTime test_time; + RealTestTime test_time; uint64_t timestamp = std::chrono::duration_cast( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -289,7 +289,7 @@ TEST(ZipkinCoreTypesBinaryAnnotationTest, assignmentOperator) { } TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { - TestTime test_time; + RealTestTime test_time; Span span(test_time.timeSource()); EXPECT_EQ(0ULL, span.id()); @@ -490,7 +490,7 @@ TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { } TEST(ZipkinCoreTypesSpanTest, copyConstructor) { - TestTime test_time; + RealTestTime test_time; Span span(test_time.timeSource()); uint64_t id = Util::generateRandom64(test_time.timeSource()); @@ -527,7 +527,7 @@ TEST(ZipkinCoreTypesSpanTest, copyConstructor) { } TEST(ZipkinCoreTypesSpanTest, assignmentOperator) { - TestTime test_time; + RealTestTime test_time; Span span(test_time.timeSource()); uint64_t id = Util::generateRandom64(test_time.timeSource()); @@ -564,7 +564,7 @@ TEST(ZipkinCoreTypesSpanTest, assignmentOperator) { } TEST(ZipkinCoreTypesSpanTest, setTag) { - TestTime test_time; + RealTestTime test_time; Span span(test_time.timeSource()); span.setTag("key1", "value1"); diff --git a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc index e148c56125b99..2b98c9c47fd5e 100644 --- a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc @@ -66,7 +66,7 @@ class ZipkinDriverTest : public Test { setup(*loader, true); } - // TODO(#4160): Currently time_source_ is initialized from TestTime, which uses real time, + // TODO(#4160): Currently time_source_ is initialized from RealTestTime, which uses real time, // not mock-time. When that is switched to use mock-time intead, I think generateRandom64() // may not be as random as we want, and we'll need to inject entropy appropriate for the test. uint64_t generateRandom64() { return Util::generateRandom64(time_source_); } @@ -87,7 +87,7 @@ class ZipkinDriverTest : public Test { NiceMock random_; NiceMock config_; - TestTime test_time_; + RealTestTime test_time_; TimeSource& time_source_; }; diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index aa8dbc7bcbfce..f46472b6ce4e0 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -581,7 +581,7 @@ class FakeUpstream : Logger::Loggable, Thread::ThreadPtr thread_; Thread::CondVar new_connection_event_; Api::ApiPtr api_; - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherPtr dispatcher_; Network::ConnectionHandlerPtr handler_; std::list new_connections_ GUARDED_BY(lock_); diff --git a/test/integration/integration.h b/test/integration/integration.h index 0d53cbe517d1c..7ccbe94d2bc46 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -161,7 +161,7 @@ class BaseIntegrationTest : Logger::Loggable { const std::vector& port_names); Api::ApiPtr api_; - TestTime test_time_; + RealTestTime test_time_; MockBufferFactory* mock_buffer_factory_; // Will point to the dispatcher's factory. Event::DispatcherPtr dispatcher_; diff --git a/test/integration/server.h b/test/integration/server.h index da3d106f99945..97ee245bf390a 100644 --- a/test/integration/server.h +++ b/test/integration/server.h @@ -302,7 +302,7 @@ class IntegrationTestServer : Logger::Loggable, Thread::CondVar listeners_cv_; Thread::MutexBasicLockable listeners_mutex_; uint64_t pending_listeners_; - TestTime test_time_; + RealTestTime test_time_; ConditionalInitializer server_set_; std::unique_ptr server_; Server::TestDrainManager* drain_manager_{}; diff --git a/test/integration/utility.cc b/test/integration/utility.cc index fee1011e4ad74..2429cda9f9669 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -53,7 +53,7 @@ void BufferingStreamDecoder::onComplete() { void BufferingStreamDecoder::onResetStream(Http::StreamResetReason) { ADD_FAILURE(); } -TestTime IntegrationUtil::evil_singleton_test_time_; +RealTestTime IntegrationUtil::evil_singleton_test_time_; BufferingStreamDecoderPtr IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPtr& addr, diff --git a/test/integration/utility.h b/test/integration/utility.h index 59f85feb4b728..9a9e38d5fab79 100644 --- a/test/integration/utility.h +++ b/test/integration/utility.h @@ -127,7 +127,7 @@ class IntegrationUtil { const std::string& content_type = ""); // TODO(jmarantz): this should be injectable. - static TestTime evil_singleton_test_time_; + static RealTestTime evil_singleton_test_time_; }; // A set of connection callbacks which tracks connection state. diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index c5f6bb5586b6d..a98e97809a68b 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -108,7 +108,7 @@ class MockDispatcher : public Dispatcher { Buffer::WatermarkFactory& getWatermarkFactory() override { return buffer_factory_; } // TODO(jmarantz): Switch these to using mock-time. - TestTime test_time_; + RealTestTime test_time_; TimeSource time_source_; std::list to_delete_; diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 73fd38fbcb4e0..8a7441057dbe8 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -352,7 +352,7 @@ class MockInstance : public Instance { testing::NiceMock init_manager_; testing::NiceMock listener_manager_; testing::NiceMock overload_manager_; - TestTime test_time_; + RealTestTime test_time_; Singleton::ManagerPtr singleton_manager_; }; diff --git a/test/server/config_validation/async_client_test.cc b/test/server/config_validation/async_client_test.cc index 19a1ae1902a60..acaca577eb375 100644 --- a/test/server/config_validation/async_client_test.cc +++ b/test/server/config_validation/async_client_test.cc @@ -16,7 +16,7 @@ TEST(ValidationAsyncClientTest, MockedMethods) { MockAsyncClientCallbacks callbacks; MockAsyncClientStreamCallbacks stream_callbacks; - TestTime test_time; + RealTestTime test_time; ValidationAsyncClient client(test_time.timeSource()); EXPECT_EQ(nullptr, client.send(std::move(message), callbacks, absl::optional())); diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index 4fc3b3f09ca3e..abfa99f9f6a03 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -26,7 +26,7 @@ class ConfigValidation : public ::testing::TestWithParamallocateDispatcher(test_time_.timeSource()); } - TestTime test_time_; + RealTestTime test_time_; Event::DispatcherPtr dispatcher_; private: diff --git a/test/server/server_fuzz_test.cc b/test/server/server_fuzz_test.cc index 8580954fba00e..14f31904e567b 100644 --- a/test/server/server_fuzz_test.cc +++ b/test/server/server_fuzz_test.cc @@ -57,7 +57,7 @@ DEFINE_PROTO_FUZZER(const envoy::config::bootstrap::v2::Bootstrap& input) { Thread::MutexBasicLockable fakelock; TestComponentFactory component_factory; ThreadLocal::InstanceImpl thread_local_instance; - TestTime test_time; + RealTestTime test_time; Fuzz::PerTestEnvironment test_env; RELEASE_ASSERT(Envoy::Server::validateProtoDescriptors(), ""); diff --git a/test/server/server_test.cc b/test/server/server_test.cc index 750df63fc2ad5..dc04e6c7237d3 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -145,7 +145,7 @@ class ServerInstanceImplTest : public testing::TestWithParam server_; }; diff --git a/test/server/worker_impl_test.cc b/test/server/worker_impl_test.cc index 55a9543c7f855..fe4ab01d69722 100644 --- a/test/server/worker_impl_test.cc +++ b/test/server/worker_impl_test.cc @@ -30,7 +30,7 @@ class WorkerImplTest : public testing::Test { } NiceMock tls_; - TestTime test_time; + RealTestTime test_time; Event::DispatcherImpl* dispatcher_ = new Event::DispatcherImpl(test_time.timeSource()); Network::MockConnectionHandler* handler_ = new Network::MockConnectionHandler(); NiceMock guard_dog_; diff --git a/test/test_common/test_time.cc b/test/test_common/test_time.cc index da3eb4f5414d2..caf973de25fbb 100644 --- a/test/test_common/test_time.cc +++ b/test/test_common/test_time.cc @@ -4,6 +4,6 @@ namespace Envoy { -TestTime::TestTime() : time_source_(system_time_, monotonic_time_) {} +RealTestTime::RealTestTime() : time_source_(system_time_, monotonic_time_) {} } // namespace Envoy diff --git a/test/test_common/test_time.h b/test/test_common/test_time.h index 2b49f05bd8bd3..9fa7ee7cb83cc 100644 --- a/test/test_common/test_time.h +++ b/test/test_common/test_time.h @@ -4,12 +4,18 @@ namespace Envoy { -class TestTime { +// Instantiates real-time sources for testing purposes. In general, this is a +// bad idea, and tests should use simulated or mock time. +// +// TODO(#4160): change all references to this class to instantiate instead to +// some kind of mock or simulated-time source. +class RealTestTime { public: - TestTime(); + RealTestTime(); TimeSource& timeSource() { return time_source_; } +private: // TODO(#4160): Add a 'mode' enum arg to the constructor, which // instantiates mock or perhaps fake time here rather than real-time, which is // makes testing non-deterministic and hard to debug. It should be easy, on From 46ad91d2e3b3e80ca4ffcd0810dd70874e28a8ab Mon Sep 17 00:00:00 2001 From: Joshua Marantz Date: Fri, 24 Aug 2018 15:10:41 -0400 Subject: [PATCH 22/22] replace RealTestTime with DangerousDeprecatedTestTime Signed-off-by: Joshua Marantz --- .../filesystem_subscription_test_harness.h | 2 +- test/common/event/dispatched_thread_impl_test.cc | 2 +- test/common/event/dispatcher_impl_test.cc | 4 ++-- test/common/event/file_event_impl_test.cc | 4 ++-- test/common/filesystem/watcher_impl_test.cc | 2 +- .../common/grpc/google_async_client_impl_test.cc | 2 +- .../grpc/grpc_client_integration_test_harness.h | 2 +- test/common/http/codec_client_test.cc | 4 ++-- test/common/http/conn_manager_impl_fuzz_test.cc | 2 +- test/common/http/conn_manager_impl_test.cc | 2 +- test/common/http/http1/conn_pool_test.cc | 2 +- test/common/http/http2/conn_pool_test.cc | 2 +- test/common/network/connection_impl_test.cc | 6 +++--- test/common/network/dns_impl_test.cc | 4 ++-- test/common/network/listener_impl_test.cc | 4 ++-- test/common/ssl/ssl_socket_test.cc | 8 ++++---- .../thread_local/thread_local_impl_test.cc | 2 +- .../proxy_protocol/proxy_protocol_test.cc | 4 ++-- .../tracers/zipkin/span_buffer_test.cc | 4 ++-- test/extensions/tracers/zipkin/tracer_test.cc | 2 +- test/extensions/tracers/zipkin/util_test.cc | 2 +- .../tracers/zipkin/zipkin_core_types_test.cc | 16 ++++++++-------- .../tracers/zipkin/zipkin_tracer_impl_test.cc | 4 ++-- test/integration/fake_upstream.h | 2 +- test/integration/integration.h | 2 +- test/integration/server.h | 2 +- test/integration/utility.cc | 2 +- test/integration/utility.h | 2 +- test/mocks/event/mocks.h | 2 +- test/mocks/server/mocks.h | 2 +- .../config_validation/async_client_test.cc | 2 +- test/server/config_validation/dispatcher_test.cc | 2 +- test/server/server_fuzz_test.cc | 2 +- test/server/server_test.cc | 2 +- test/server/worker_impl_test.cc | 2 +- test/test_common/test_time.cc | 2 +- test/test_common/test_time.h | 4 ++-- 37 files changed, 58 insertions(+), 58 deletions(-) diff --git a/test/common/config/filesystem_subscription_test_harness.h b/test/common/config/filesystem_subscription_test_harness.h index 4aa1968dad167..155cabb0c8acc 100644 --- a/test/common/config/filesystem_subscription_test_harness.h +++ b/test/common/config/filesystem_subscription_test_harness.h @@ -95,7 +95,7 @@ class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { const std::string path_; std::string version_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; NiceMock> callbacks_; FilesystemEdsSubscriptionImpl subscription_; diff --git a/test/common/event/dispatched_thread_impl_test.cc b/test/common/event/dispatched_thread_impl_test.cc index 1c215bbd67ecb..915dc9bee5028 100644 --- a/test/common/event/dispatched_thread_impl_test.cc +++ b/test/common/event/dispatched_thread_impl_test.cc @@ -28,7 +28,7 @@ class DispatchedThreadTest : public testing::Test { void SetUp() { thread_.start(guard_dog_); } NiceMock config_; NiceMock fakestats_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Envoy::Server::GuardDogImpl guard_dog_; DispatchedThreadImpl thread_; }; diff --git a/test/common/event/dispatcher_impl_test.cc b/test/common/event/dispatcher_impl_test.cc index 35885ad7ee2a8..5a8ed141b26e5 100644 --- a/test/common/event/dispatcher_impl_test.cc +++ b/test/common/event/dispatcher_impl_test.cc @@ -26,7 +26,7 @@ class TestDeferredDeletable : public DeferredDeletable { TEST(DeferredDeleteTest, DeferredDelete) { InSequence s; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; DispatcherImpl dispatcher(test_time.timeSource()); ReadyWatcher watcher1; @@ -76,7 +76,7 @@ class DispatcherImplTest : public ::testing::Test { dispatcher_thread_->join(); } - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; std::unique_ptr dispatcher_thread_; DispatcherPtr dispatcher_; diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index 803b0676b2a94..888247a006b21 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -33,7 +33,7 @@ class FileEventImplTest : public testing::Test { protected: int fds_[2]; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; DispatcherImpl dispatcher_; }; @@ -52,7 +52,7 @@ TEST_P(FileEventImplActivateTest, Activate) { } ASSERT_NE(-1, fd); - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; DispatcherImpl dispatcher(test_time.timeSource()); ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(1); diff --git a/test/common/filesystem/watcher_impl_test.cc b/test/common/filesystem/watcher_impl_test.cc index 070850413f4d9..4ddb442beced4 100644 --- a/test/common/filesystem/watcher_impl_test.cc +++ b/test/common/filesystem/watcher_impl_test.cc @@ -18,7 +18,7 @@ class WatcherImplTest : public testing::Test { protected: WatcherImplTest() : dispatcher_(test_time_.timeSource()) {} - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; }; diff --git a/test/common/grpc/google_async_client_impl_test.cc b/test/common/grpc/google_async_client_impl_test.cc index cd4c17b82968c..8f0e85d77bf04 100644 --- a/test/common/grpc/google_async_client_impl_test.cc +++ b/test/common/grpc/google_async_client_impl_test.cc @@ -56,7 +56,7 @@ class EnvoyGoogleAsyncClientImplTest : public testing::Test { stats_store_, config); } - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; std::unique_ptr tls_; MockStubFactory stub_factory_; diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 905a5bb5e3f0b..0f0861e5f7cd8 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -395,7 +395,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { FakeHttpConnectionPtr fake_connection_; std::vector fake_streams_; const Protobuf::MethodDescriptor* method_descriptor_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; DispatcherHelper dispatcher_helper_{dispatcher_}; Stats::IsolatedStoreImpl* stats_store_ = new Stats::IsolatedStoreImpl(); diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index fafaa1fab0547..b2175f45fc454 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -60,7 +60,7 @@ class CodecClientTest : public testing::Test { ~CodecClientTest() { EXPECT_EQ(0U, client_->numActiveRequests()); } - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::MockDispatcher dispatcher_; Network::MockClientConnection* connection_; Http::MockClientConnection* codec_; @@ -328,7 +328,7 @@ class CodecNetworkTest : public testing::TestWithParam filter_factory_; absl::optional idle_timeout_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; RouteConfigProvider route_config_provider_; std::string server_name_; Stats::IsolatedStoreImpl fake_stats_; diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index f0c515885fc14..90e6e21f45a30 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -277,7 +277,7 @@ class HttpConnectionManagerImplTest : public Test, public ConnectionManagerConfi bool proxy100Continue() const override { return proxy_100_continue_; } const Http::Http1Settings& http1Settings() const override { return http1_settings_; } - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; RouteConfigProvider route_config_provider_; NiceMock tracer_; NiceMock runtime_; diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index 9c1115dcfe183..cf7ffb2eb4f27 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -111,7 +111,7 @@ class ConnPoolImplForTest : public ConnPoolImpl { EXPECT_FALSE(upstream_ready_enabled_); } - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::MockDispatcher& mock_dispatcher_; NiceMock* mock_upstream_ready_timer_; std::vector test_clients_; diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 3df8240d7124f..40e98992c2d3e 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -102,7 +102,7 @@ class Http2ConnPoolImplTest : public testing::Test { MOCK_METHOD0(onClientDestroy, void()); - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; Upstream::HostSharedPtr host_{Upstream::makeTestHost(cluster_, "tcp://127.0.0.1:80")}; diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index 4d77fea8bdf19..8ae698340f0d2 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -77,7 +77,7 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ConnectionImplDeathTest, TestUtility::ipTestParamsToString); TEST_P(ConnectionImplDeathTest, BadFd) { - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); EXPECT_DEATH_LOG_TO_STDERR( ConnectionImpl(dispatcher, std::make_unique(-1, nullptr, nullptr), @@ -169,7 +169,7 @@ class ConnectionImplTest : public testing::TestWithParam { } protected: - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherPtr dispatcher_; Stats::IsolatedStoreImpl stats_store_; Network::TcpListenSocket socket_{Network::Test::getAnyAddress(GetParam()), nullptr, true}; @@ -1271,7 +1271,7 @@ TEST_P(ReadBufferLimitTest, SomeLimit) { class TcpClientConnectionImplTest : public testing::TestWithParam { protected: TcpClientConnectionImplTest() : dispatcher_(test_time_.timeSource()) {} - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; }; INSTANTIATE_TEST_CASE_P(IpVersions, TcpClientConnectionImplTest, diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 8b70a7b3ada9a..136c686a6348a 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -323,7 +323,7 @@ class DnsResolverImplPeer { class DnsImplConstructor : public testing::Test { protected: DnsImplConstructor() : dispatcher_(test_time_.timeSource()) {} - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; }; @@ -434,7 +434,7 @@ class DnsImplTest : public testing::TestWithParam { Network::TcpListenSocketPtr socket_; Stats::IsolatedStoreImpl stats_store_; std::unique_ptr listener_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; DnsResolverSharedPtr resolver_; }; diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index e20898aa8130d..b674b2a02ce9e 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -23,7 +23,7 @@ static void errorCallbackTest(Address::IpVersion version) { // Force the error callback to fire by closing the socket under the listener. We run this entire // test in the forked process to avoid confusion when the fork happens. Stats::IsolatedStoreImpl stats_store; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, @@ -83,7 +83,7 @@ class ListenerImplTest : public testing::TestWithParam { const Address::IpVersion version_; const Address::InstanceConstSharedPtr alt_address_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; }; INSTANTIATE_TEST_CASE_P(IpVersions, ListenerImplTest, diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index f8c542723d0b9..5d00bf3356584 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -59,7 +59,7 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, std::vector{}); - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); @@ -163,7 +163,7 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Ssl::ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, stats_store, server_names); - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, true); @@ -302,7 +302,7 @@ class SslSocketTest : public SslCertsTest, protected: SslSocketTest() : dispatcher_(std::make_unique(test_time_.timeSource())) {} - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; std::unique_ptr dispatcher_; }; @@ -1780,7 +1780,7 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl dispatcher(test_time.timeSource()); Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true, false); Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); diff --git a/test/common/thread_local/thread_local_impl_test.cc b/test/common/thread_local/thread_local_impl_test.cc index 3f780d0e61f21..cc523d79b2e63 100644 --- a/test/common/thread_local/thread_local_impl_test.cc +++ b/test/common/thread_local/thread_local_impl_test.cc @@ -115,7 +115,7 @@ TEST_F(ThreadLocalInstanceImplTest, RunOnAllThreads) { TEST(ThreadLocalInstanceImplDispatcherTest, Dispatcher) { InstanceImpl tls; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl main_dispatcher(test_time.timeSource()); Event::DispatcherImpl thread_dispatcher(test_time.timeSource()); diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index f48acd63159ba..362a2e9c1d6c9 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -144,7 +144,7 @@ class ProxyProtocolTest : public testing::TestWithParam( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -147,7 +147,7 @@ TEST(ZipkinCoreTypesAnnotationTest, customConstructor) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; uint64_t timestamp = std::chrono::duration_cast( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -172,7 +172,7 @@ TEST(ZipkinCoreTypesAnnotationTest, copyConstructor) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; uint64_t timestamp = std::chrono::duration_cast( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -190,7 +190,7 @@ TEST(ZipkinCoreTypesAnnotationTest, assignmentOperator) { Network::Address::InstanceConstSharedPtr addr = Network::Utility::parseInternetAddressAndPort("127.0.0.1:3306"); Endpoint ep(std::string("my_service"), addr); - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; uint64_t timestamp = std::chrono::duration_cast( test_time.timeSource().systemTime().time_since_epoch()) .count(); @@ -289,7 +289,7 @@ TEST(ZipkinCoreTypesBinaryAnnotationTest, assignmentOperator) { } TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Span span(test_time.timeSource()); EXPECT_EQ(0ULL, span.id()); @@ -490,7 +490,7 @@ TEST(ZipkinCoreTypesSpanTest, defaultConstructor) { } TEST(ZipkinCoreTypesSpanTest, copyConstructor) { - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Span span(test_time.timeSource()); uint64_t id = Util::generateRandom64(test_time.timeSource()); @@ -527,7 +527,7 @@ TEST(ZipkinCoreTypesSpanTest, copyConstructor) { } TEST(ZipkinCoreTypesSpanTest, assignmentOperator) { - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Span span(test_time.timeSource()); uint64_t id = Util::generateRandom64(test_time.timeSource()); @@ -564,7 +564,7 @@ TEST(ZipkinCoreTypesSpanTest, assignmentOperator) { } TEST(ZipkinCoreTypesSpanTest, setTag) { - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Span span(test_time.timeSource()); span.setTag("key1", "value1"); diff --git a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc index 2b98c9c47fd5e..88d52b153e780 100644 --- a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc @@ -66,7 +66,7 @@ class ZipkinDriverTest : public Test { setup(*loader, true); } - // TODO(#4160): Currently time_source_ is initialized from RealTestTime, which uses real time, + // TODO(#4160): Currently time_source_ is initialized from DangerousDeprecatedTestTime, which uses real time, // not mock-time. When that is switched to use mock-time intead, I think generateRandom64() // may not be as random as we want, and we'll need to inject entropy appropriate for the test. uint64_t generateRandom64() { return Util::generateRandom64(time_source_); } @@ -87,7 +87,7 @@ class ZipkinDriverTest : public Test { NiceMock random_; NiceMock config_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; TimeSource& time_source_; }; diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index f46472b6ce4e0..4e9271cd7d6e1 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -581,7 +581,7 @@ class FakeUpstream : Logger::Loggable, Thread::ThreadPtr thread_; Thread::CondVar new_connection_event_; Api::ApiPtr api_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherPtr dispatcher_; Network::ConnectionHandlerPtr handler_; std::list new_connections_ GUARDED_BY(lock_); diff --git a/test/integration/integration.h b/test/integration/integration.h index 7ccbe94d2bc46..0e126243022e3 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -161,7 +161,7 @@ class BaseIntegrationTest : Logger::Loggable { const std::vector& port_names); Api::ApiPtr api_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; MockBufferFactory* mock_buffer_factory_; // Will point to the dispatcher's factory. Event::DispatcherPtr dispatcher_; diff --git a/test/integration/server.h b/test/integration/server.h index 97ee245bf390a..0cc04041ceab0 100644 --- a/test/integration/server.h +++ b/test/integration/server.h @@ -302,7 +302,7 @@ class IntegrationTestServer : Logger::Loggable, Thread::CondVar listeners_cv_; Thread::MutexBasicLockable listeners_mutex_; uint64_t pending_listeners_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; ConditionalInitializer server_set_; std::unique_ptr server_; Server::TestDrainManager* drain_manager_{}; diff --git a/test/integration/utility.cc b/test/integration/utility.cc index 2429cda9f9669..f2440ff0893e8 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -53,7 +53,7 @@ void BufferingStreamDecoder::onComplete() { void BufferingStreamDecoder::onResetStream(Http::StreamResetReason) { ADD_FAILURE(); } -RealTestTime IntegrationUtil::evil_singleton_test_time_; +DangerousDeprecatedTestTime IntegrationUtil::evil_singleton_test_time_; BufferingStreamDecoderPtr IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPtr& addr, diff --git a/test/integration/utility.h b/test/integration/utility.h index 9a9e38d5fab79..a1e1d7c9e4492 100644 --- a/test/integration/utility.h +++ b/test/integration/utility.h @@ -127,7 +127,7 @@ class IntegrationUtil { const std::string& content_type = ""); // TODO(jmarantz): this should be injectable. - static RealTestTime evil_singleton_test_time_; + static DangerousDeprecatedTestTime evil_singleton_test_time_; }; // A set of connection callbacks which tracks connection state. diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index a98e97809a68b..4eba22e93542d 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -108,7 +108,7 @@ class MockDispatcher : public Dispatcher { Buffer::WatermarkFactory& getWatermarkFactory() override { return buffer_factory_; } // TODO(jmarantz): Switch these to using mock-time. - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; TimeSource time_source_; std::list to_delete_; diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 8a7441057dbe8..e0deddecfc33a 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -352,7 +352,7 @@ class MockInstance : public Instance { testing::NiceMock init_manager_; testing::NiceMock listener_manager_; testing::NiceMock overload_manager_; - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Singleton::ManagerPtr singleton_manager_; }; diff --git a/test/server/config_validation/async_client_test.cc b/test/server/config_validation/async_client_test.cc index acaca577eb375..53a172c3394ea 100644 --- a/test/server/config_validation/async_client_test.cc +++ b/test/server/config_validation/async_client_test.cc @@ -16,7 +16,7 @@ TEST(ValidationAsyncClientTest, MockedMethods) { MockAsyncClientCallbacks callbacks; MockAsyncClientStreamCallbacks stream_callbacks; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; ValidationAsyncClient client(test_time.timeSource()); EXPECT_EQ(nullptr, client.send(std::move(message), callbacks, absl::optional())); diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index abfa99f9f6a03..3476ea525668a 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -26,7 +26,7 @@ class ConfigValidation : public ::testing::TestWithParamallocateDispatcher(test_time_.timeSource()); } - RealTestTime test_time_; + DangerousDeprecatedTestTime test_time_; Event::DispatcherPtr dispatcher_; private: diff --git a/test/server/server_fuzz_test.cc b/test/server/server_fuzz_test.cc index 14f31904e567b..ff68f39a18145 100644 --- a/test/server/server_fuzz_test.cc +++ b/test/server/server_fuzz_test.cc @@ -57,7 +57,7 @@ DEFINE_PROTO_FUZZER(const envoy::config::bootstrap::v2::Bootstrap& input) { Thread::MutexBasicLockable fakelock; TestComponentFactory component_factory; ThreadLocal::InstanceImpl thread_local_instance; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Fuzz::PerTestEnvironment test_env; RELEASE_ASSERT(Envoy::Server::validateProtoDescriptors(), ""); diff --git a/test/server/server_test.cc b/test/server/server_test.cc index dc04e6c7237d3..89607ff98edba 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -145,7 +145,7 @@ class ServerInstanceImplTest : public testing::TestWithParam server_; }; diff --git a/test/server/worker_impl_test.cc b/test/server/worker_impl_test.cc index fe4ab01d69722..af730229348f6 100644 --- a/test/server/worker_impl_test.cc +++ b/test/server/worker_impl_test.cc @@ -30,7 +30,7 @@ class WorkerImplTest : public testing::Test { } NiceMock tls_; - RealTestTime test_time; + DangerousDeprecatedTestTime test_time; Event::DispatcherImpl* dispatcher_ = new Event::DispatcherImpl(test_time.timeSource()); Network::MockConnectionHandler* handler_ = new Network::MockConnectionHandler(); NiceMock guard_dog_; diff --git a/test/test_common/test_time.cc b/test/test_common/test_time.cc index caf973de25fbb..668e3de60a725 100644 --- a/test/test_common/test_time.cc +++ b/test/test_common/test_time.cc @@ -4,6 +4,6 @@ namespace Envoy { -RealTestTime::RealTestTime() : time_source_(system_time_, monotonic_time_) {} +DangerousDeprecatedTestTime::DangerousDeprecatedTestTime() : time_source_(system_time_, monotonic_time_) {} } // namespace Envoy diff --git a/test/test_common/test_time.h b/test/test_common/test_time.h index 9fa7ee7cb83cc..d57fda8761438 100644 --- a/test/test_common/test_time.h +++ b/test/test_common/test_time.h @@ -9,9 +9,9 @@ namespace Envoy { // // TODO(#4160): change all references to this class to instantiate instead to // some kind of mock or simulated-time source. -class RealTestTime { +class DangerousDeprecatedTestTime { public: - RealTestTime(); + DangerousDeprecatedTestTime(); TimeSource& timeSource() { return time_source_; }