diff --git a/docs/configuration/cluster_manager/cluster.rst b/docs/configuration/cluster_manager/cluster.rst index b8c35fa51896..4cdcb41b7d70 100644 --- a/docs/configuration/cluster_manager/cluster.rst +++ b/docs/configuration/cluster_manager/cluster.rst @@ -21,6 +21,8 @@ Cluster "alt_stat_name": "..." } +.. _config_cluster_manager_cluster_name: + name *(required, string)* Supplies the name of the cluster which must be unique across all clusters. The cluster name is used when emitting :ref:`statistics `. diff --git a/docs/configuration/cluster_manager/cluster_circuit_breakers.rst b/docs/configuration/cluster_manager/cluster_circuit_breakers.rst index 81463d3305d9..c573d21f7101 100644 --- a/docs/configuration/cluster_manager/cluster_circuit_breakers.rst +++ b/docs/configuration/cluster_manager/cluster_circuit_breakers.rst @@ -42,17 +42,32 @@ max_connections cluster. If not specified, the default is 1024. See the :ref:`circuit breaking overview ` for more information. +.. _config_cluster_manager_cluster_circuit_breakers_max_pending_requests: + max_pending_requests *(optional, integer)* The maximum number of pending requests that Envoy will allow to the upstream cluster. If not specified, the default is 1024. See the :ref:`circuit breaking overview ` for more information. +.. _config_cluster_manager_cluster_circuit_breakers_max_requests: + max_requests *(optional, integer)* The maximum number of parallel requests that Envoy will make to the upstream cluster. If not specified, the default is 1024. See the :ref:`circuit breaking overview ` for more information. +.. _config_cluster_manager_cluster_circuit_breakers_max_retries: + max_retries *(optional, integer)* The maximum number of parallel retries that Envoy will allow to the upstream cluster. If not specified, the default is 3. See the :ref:`circuit breaking overview ` for more information. + +Runtime +------- + +All four circuit breaking settings are runtime configurable for all defined priorities based on cluster +name. They follow the following naming scheme ``circuit_breakers...``. +``cluster_name`` is the name field in each cluster's configuration, which is set in the envoy +:ref:`config file `. Available runtime settings will override +settings set in the envoy config file. diff --git a/docs/configuration/cluster_manager/cluster_runtime.rst b/docs/configuration/cluster_manager/cluster_runtime.rst index ab3d069caf63..d03cd512893b 100644 --- a/docs/configuration/cluster_manager/cluster_runtime.rst +++ b/docs/configuration/cluster_manager/cluster_runtime.rst @@ -44,3 +44,15 @@ upstream.zone_routing.healthy_panic_threshold Defines the :ref:`zone healthy panic threshold ` percentage. Defaults to 80%. If the % of healthy hosts in the current zone falls below this % all healthy hosts will be used for routing. + +circuit_breakers...max_connections + :ref:`Max connections circuit breaker setting ` + +circuit_breakers...max_pending_requests + :ref:`Max pending requests circuit breaker setting ` + +circuit_breakers...max_requests + :ref:`Max requests circuit breaker setting ` + +circuit_breakers...max_retries + :ref:`Max retries circuit breaker setting ` diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index ac5c866b406d..a5284080c6d4 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -69,18 +69,19 @@ void ClusterManagerImpl::loadCluster(const Json::Object& cluster, Stats::Store& std::string string_type = cluster.getString("type"); ClusterImplBasePtr new_cluster; if (string_type == "static") { - new_cluster.reset(new StaticClusterImpl(cluster, stats, ssl_context_manager)); + new_cluster.reset(new StaticClusterImpl(cluster, runtime, stats, ssl_context_manager)); } else if (string_type == "strict_dns") { - new_cluster.reset(new StrictDnsClusterImpl(cluster, stats, ssl_context_manager, dns_resolver)); + new_cluster.reset( + new StrictDnsClusterImpl(cluster, runtime, stats, ssl_context_manager, dns_resolver)); } else if (string_type == "logical_dns") { new_cluster.reset( - new LogicalDnsCluster(cluster, stats, ssl_context_manager, dns_resolver, tls_)); + new LogicalDnsCluster(cluster, runtime, stats, ssl_context_manager, dns_resolver, tls_)); } else if (string_type == "sds") { if (!sds_config_.valid()) { throw EnvoyException("cannot create an sds cluster without an sds config"); } - sds_clusters_.push_back(new SdsClusterImpl(cluster, stats, ssl_context_manager, + sds_clusters_.push_back(new SdsClusterImpl(cluster, runtime, stats, ssl_context_manager, sds_config_.value(), *this, dns_resolver.dispatcher(), random)); new_cluster.reset(sds_clusters_.back()); diff --git a/source/common/upstream/logical_dns_cluster.cc b/source/common/upstream/logical_dns_cluster.cc index 206872993ca1..8ac64dacfbe9 100644 --- a/source/common/upstream/logical_dns_cluster.cc +++ b/source/common/upstream/logical_dns_cluster.cc @@ -4,11 +4,11 @@ namespace Upstream { -LogicalDnsCluster::LogicalDnsCluster(const Json::Object& config, Stats::Store& stats, - Ssl::ContextManager& ssl_context_manager, +LogicalDnsCluster::LogicalDnsCluster(const Json::Object& config, Runtime::Loader& runtime, + Stats::Store& stats, Ssl::ContextManager& ssl_context_manager, Network::DnsResolver& dns_resolver, ThreadLocal::Instance& tls) - : ClusterImplBase(config, stats, ssl_context_manager), dns_resolver_(dns_resolver), tls_(tls), - tls_slot_(tls.allocateSlot()), + : ClusterImplBase(config, runtime, stats, ssl_context_manager), dns_resolver_(dns_resolver), + tls_(tls), tls_slot_(tls.allocateSlot()), resolve_timer_(dns_resolver.dispatcher().createTimer([this]() -> void { startResolve(); })) { std::vector hosts_json = config.getObjectArray("hosts"); diff --git a/source/common/upstream/logical_dns_cluster.h b/source/common/upstream/logical_dns_cluster.h index 1b2e60072be1..f650bb8b4ec7 100644 --- a/source/common/upstream/logical_dns_cluster.h +++ b/source/common/upstream/logical_dns_cluster.h @@ -23,7 +23,7 @@ namespace Upstream { */ class LogicalDnsCluster : public ClusterImplBase { public: - LogicalDnsCluster(const Json::Object& config, Stats::Store& stats, + LogicalDnsCluster(const Json::Object& config, Runtime::Loader& runtime, Stats::Store& stats, Ssl::ContextManager& ssl_context_manager, Network::DnsResolver& dns_resolver, ThreadLocal::Instance& tls); diff --git a/source/common/upstream/resource_manager_impl.h b/source/common/upstream/resource_manager_impl.h index ae1bbf845e18..0fde747c69ff 100644 --- a/source/common/upstream/resource_manager_impl.h +++ b/source/common/upstream/resource_manager_impl.h @@ -1,5 +1,6 @@ #pragma once +#include "envoy/runtime/runtime.h" #include "envoy/upstream/resource_manager.h" #include "common/common/assert.h" @@ -17,10 +18,13 @@ namespace Upstream { */ class ResourceManagerImpl : public ResourceManager { public: - ResourceManagerImpl(uint64_t max_connections, uint64_t max_pending_requests, + ResourceManagerImpl(Runtime::Loader& runtime, const std::string& runtime_key, + uint64_t max_connections, uint64_t max_pending_requests, uint64_t max_requests, uint64_t max_retries) - : connections_(max_connections), pending_requests_(max_pending_requests), - requests_(max_requests), retries_(max_retries) {} + : connections_(max_connections, runtime, runtime_key + "max_connections"), + pending_requests_(max_pending_requests, runtime, runtime_key + "max_pending_requests"), + requests_(max_requests, runtime, runtime_key + "max_requests"), + retries_(max_retries, runtime, runtime_key + "max_retries") {} // Upstream::ResourceManager Resource& connections() override { return connections_; } @@ -30,20 +34,23 @@ class ResourceManagerImpl : public ResourceManager { private: struct ResourceImpl : public Resource { - ResourceImpl(uint64_t max) : max_(max) {} + ResourceImpl(uint64_t max, Runtime::Loader& runtime, const std::string& runtime_key) + : max_(max), runtime_(runtime), runtime_key_(runtime_key) {} ~ResourceImpl() { ASSERT(current_ == 0); } // Upstream::Resource - bool canCreate() override { return current_ < max_; } + bool canCreate() override { return current_ < max(); } void inc() override { current_++; } void dec() override { ASSERT(current_ > 0); current_--; } - uint64_t max() override { return max_; } + uint64_t max() override { return runtime_.snapshot().getInteger(runtime_key_, max_); } const uint64_t max_; std::atomic current_{}; + Runtime::Loader& runtime_; + std::string runtime_key_; }; ResourceImpl connections_; diff --git a/source/common/upstream/sds.cc b/source/common/upstream/sds.cc index ba4dd83d017d..44f3baa57e5d 100644 --- a/source/common/upstream/sds.cc +++ b/source/common/upstream/sds.cc @@ -15,12 +15,12 @@ namespace Upstream { -SdsClusterImpl::SdsClusterImpl(const Json::Object& config, Stats::Store& stats, - Ssl::ContextManager& ssl_context_manager, +SdsClusterImpl::SdsClusterImpl(const Json::Object& config, Runtime::Loader& runtime, + Stats::Store& stats, Ssl::ContextManager& ssl_context_manager, const SdsConfig& sds_config, ClusterManager& cm, Event::Dispatcher& dispatcher, Runtime::RandomGenerator& random) - : BaseDynamicClusterImpl(config, stats, ssl_context_manager), cm_(cm), sds_config_(sds_config), - service_name_(config.getString("service_name")), random_(random), + : BaseDynamicClusterImpl(config, runtime, stats, ssl_context_manager), cm_(cm), + sds_config_(sds_config), service_name_(config.getString("service_name")), random_(random), refresh_timer_(dispatcher.createTimer([this]() -> void { refreshHosts(); })) {} SdsClusterImpl::~SdsClusterImpl() {} diff --git a/source/common/upstream/sds.h b/source/common/upstream/sds.h index e465dec280e4..b44fd58883e6 100644 --- a/source/common/upstream/sds.h +++ b/source/common/upstream/sds.h @@ -22,7 +22,7 @@ struct SdsConfig { */ class SdsClusterImpl : public BaseDynamicClusterImpl, public Http::AsyncClient::Callbacks { public: - SdsClusterImpl(const Json::Object& config, Stats::Store& stats, + SdsClusterImpl(const Json::Object& config, Runtime::Loader& runtime, Stats::Store& stats, Ssl::ContextManager& ssl_context_manager, const SdsConfig& sds_config, ClusterManager& cm, Event::Dispatcher& dispatcher, Runtime::RandomGenerator& random); diff --git a/source/common/upstream/upstream_impl.cc b/source/common/upstream/upstream_impl.cc index 549376349d49..001f98896430 100644 --- a/source/common/upstream/upstream_impl.cc +++ b/source/common/upstream/upstream_impl.cc @@ -52,14 +52,15 @@ void HostSetImpl::runUpdateCallbacks(const std::vector& hosts_added, const ConstHostVectorPtr ClusterImplBase::empty_host_list_{new std::vector{}}; -ClusterImplBase::ClusterImplBase(const Json::Object& config, Stats::Store& stats, - Ssl::ContextManager& ssl_context_manager) +ClusterImplBase::ClusterImplBase(const Json::Object& config, Runtime::Loader& runtime, + Stats::Store& stats, Ssl::ContextManager& ssl_context_manager) : name_(config.getString("name")), max_requests_per_connection_(config.getInteger("max_requests_per_connection", 0)), connect_timeout_(std::chrono::milliseconds(config.getInteger("connect_timeout_ms"))), stats_(generateStats(name_, stats)), alt_stat_name_(config.getString("alt_stat_name", "")), features_(parseFeatures(config)), - http_codec_options_(Http::Utility::parseCodecOptions(config)), resource_managers_(config) { + http_codec_options_(Http::Utility::parseCodecOptions(config)), + resource_managers_(config, runtime, name_) { std::string string_lb_type = config.getString("lb_type"); if (string_lb_type == "round_robin") { @@ -133,17 +134,22 @@ void ClusterImplBase::setHealthChecker(HealthCheckerPtr&& health_checker) { }); } -ClusterImplBase::ResourceManagers::ResourceManagers(const Json::Object& config) { - managers_[enumToInt(ResourcePriority::Default)] = load(config, "default"); - managers_[enumToInt(ResourcePriority::High)] = load(config, "high"); +ClusterImplBase::ResourceManagers::ResourceManagers(const Json::Object& config, + Runtime::Loader& runtime, + const std::string& cluster_name) { + managers_[enumToInt(ResourcePriority::Default)] = load(config, runtime, cluster_name, "default"); + managers_[enumToInt(ResourcePriority::High)] = load(config, runtime, cluster_name, "high"); } ResourceManagerImplPtr ClusterImplBase::ResourceManagers::load(const Json::Object& config, + Runtime::Loader& runtime, + const std::string& cluster_name, const std::string& priority) { uint64_t max_connections = 1024; uint64_t max_pending_requests = 1024; uint64_t max_requests = 1024; uint64_t max_retries = 3; + std::string runtime_prefix = fmt::format("circuit_breakers.{}.{}.", cluster_name, priority); Json::Object settings = config.getObject("circuit_breakers", true).getObject(priority, true); max_connections = settings.getInteger("max_connections", max_connections); @@ -151,13 +157,13 @@ ResourceManagerImplPtr ClusterImplBase::ResourceManagers::load(const Json::Objec max_requests = settings.getInteger("max_requests", max_requests); max_retries = settings.getInteger("max_retries", max_retries); - return ResourceManagerImplPtr{ - new ResourceManagerImpl(max_connections, max_pending_requests, max_requests, max_retries)}; + return ResourceManagerImplPtr{new ResourceManagerImpl( + runtime, runtime_prefix, max_connections, max_pending_requests, max_requests, max_retries)}; } -StaticClusterImpl::StaticClusterImpl(const Json::Object& config, Stats::Store& stats, - Ssl::ContextManager& ssl_context_manager) - : ClusterImplBase(config, stats, ssl_context_manager) { +StaticClusterImpl::StaticClusterImpl(const Json::Object& config, Runtime::Loader& runtime, + Stats::Store& stats, Ssl::ContextManager& ssl_context_manager) + : ClusterImplBase(config, runtime, stats, ssl_context_manager) { std::vector hosts_json = config.getObjectArray("hosts"); HostVectorPtr new_hosts(new std::vector()); for (Json::Object& host : hosts_json) { @@ -249,10 +255,12 @@ bool BaseDynamicClusterImpl::updateDynamicHostList(const std::vector& n } } -StrictDnsClusterImpl::StrictDnsClusterImpl(const Json::Object& config, Stats::Store& stats, +StrictDnsClusterImpl::StrictDnsClusterImpl(const Json::Object& config, Runtime::Loader& runtime, + Stats::Store& stats, Ssl::ContextManager& ssl_context_manager, Network::DnsResolver& dns_resolver) - : BaseDynamicClusterImpl(config, stats, ssl_context_manager), dns_resolver_(dns_resolver) { + : BaseDynamicClusterImpl(config, runtime, stats, ssl_context_manager), + dns_resolver_(dns_resolver) { for (Json::Object& host : config.getObjectArray("hosts")) { resolve_targets_.emplace_back(new ResolveTarget(*this, host.getString("url"))); } diff --git a/source/common/upstream/upstream_impl.h b/source/common/upstream/upstream_impl.h index d1d219d17315..35df2d4b275e 100644 --- a/source/common/upstream/upstream_impl.h +++ b/source/common/upstream/upstream_impl.h @@ -4,6 +4,7 @@ #include "envoy/event/timer.h" #include "envoy/network/dns.h" +#include "envoy/runtime/runtime.h" #include "envoy/ssl/context_manager.h" #include "envoy/upstream/health_checker.h" #include "envoy/upstream/load_balancer.h" @@ -159,7 +160,7 @@ class ClusterImplBase : public Cluster, ClusterStats& stats() const override { return stats_; } protected: - ClusterImplBase(const Json::Object& config, Stats::Store& stats, + ClusterImplBase(const Json::Object& config, Runtime::Loader& runtime, Stats::Store& stats, Ssl::ContextManager& ssl_context_manager); static ConstHostVectorPtr createHealthyHostList(const std::vector& hosts); @@ -180,8 +181,10 @@ class ClusterImplBase : public Cluster, private: struct ResourceManagers { - ResourceManagers(const Json::Object& config); - ResourceManagerImplPtr load(const Json::Object& config, const std::string& priority); + ResourceManagers(const Json::Object& config, Runtime::Loader& runtime, + const std::string& cluster_name); + ResourceManagerImplPtr load(const Json::Object& config, Runtime::Loader& runtime, + const std::string& cluster_name, const std::string& priority); typedef std::array Managers; @@ -202,7 +205,7 @@ typedef std::shared_ptr ClusterImplBasePtr; */ class StaticClusterImpl : public ClusterImplBase { public: - StaticClusterImpl(const Json::Object& config, Stats::Store& stats, + StaticClusterImpl(const Json::Object& config, Runtime::Loader& runtime, Stats::Store& stats, Ssl::ContextManager& ssl_context_manager); // Upstream::Cluster @@ -236,7 +239,7 @@ class BaseDynamicClusterImpl : public ClusterImplBase { */ class StrictDnsClusterImpl : public BaseDynamicClusterImpl { public: - StrictDnsClusterImpl(const Json::Object& config, Stats::Store& stats, + StrictDnsClusterImpl(const Json::Object& config, Runtime::Loader& runtime, Stats::Store& stats, Ssl::ContextManager& ssl_context_manager, Network::DnsResolver& dns_resolver); ~StrictDnsClusterImpl(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 33d53d66f696..7c0b3bd741e2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -82,6 +82,7 @@ add_executable(envoy-test common/upstream/health_checker_impl_test.cc common/upstream/load_balancer_impl_test.cc common/upstream/logical_dns_cluster_test.cc + common/upstream/resource_manager_impl_test.cc common/upstream/sds_test.cc common/upstream/upstream_impl_test.cc example_configs_test.cc diff --git a/test/common/filter/tcp_proxy_test.cc b/test/common/filter/tcp_proxy_test.cc index 56f94fcc1e9b..2d87a2eff2d2 100644 --- a/test/common/filter/tcp_proxy_test.cc +++ b/test/common/filter/tcp_proxy_test.cc @@ -5,6 +5,7 @@ #include "test/mocks/buffer/mocks.h" #include "test/mocks/network/mocks.h" +#include "test/mocks/runtime/mocks.h" #include "test/mocks/upstream/host.h" #include "test/mocks/upstream/mocks.h" @@ -74,6 +75,7 @@ class TcpProxyTest : public testing::Test { Network::ReadFilterPtr upstream_read_filter_; NiceMock* connect_timer_{}; std::unique_ptr filter_; + NiceMock runtime_; }; TEST_F(TcpProxyTest, UpstreamDisconnect) { @@ -161,7 +163,8 @@ TEST_F(TcpProxyTest, UpstreamConnectionLimit) { // setup sets up expectation for tcpConnForCluster but this test is expected to NOT call that filter_.reset(new TcpProxy(config_, cluster_manager_)); filter_->initializeReadFilterCallbacks(filter_callbacks_); - cluster_manager_.cluster_.resource_manager_.reset(new Upstream::ResourceManagerImpl(0, 0, 0, 0)); + cluster_manager_.cluster_.resource_manager_.reset( + new Upstream::ResourceManagerImpl(runtime_, "fake_key", 0, 0, 0, 0)); Buffer::OwnedImpl buffer("hello"); // The downstream connection closes if the proxy can't make an upstream connection. diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index 0470a86d54ba..73f5d36bb140 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -8,6 +8,7 @@ #include "test/mocks/event/mocks.h" #include "test/mocks/http/mocks.h" #include "test/mocks/network/mocks.h" +#include "test/mocks/runtime/mocks.h" #include "test/mocks/upstream/mocks.h" using testing::_; @@ -103,6 +104,7 @@ class Http1ConnPoolImplTest : public testing::Test { NiceMock dispatcher_; NiceMock cluster_; ConnPoolImplForTest conn_pool_; + NiceMock runtime_; }; /** @@ -195,7 +197,8 @@ TEST_F(Http1ConnPoolImplTest, MultipleRequestAndResponse) { * Test when we overflow max pending requests. */ TEST_F(Http1ConnPoolImplTest, MaxPendingRequests) { - cluster_.resource_manager_.reset(new Upstream::ResourceManagerImpl(1, 1, 1024, 1)); + cluster_.resource_manager_.reset( + new Upstream::ResourceManagerImpl(runtime_, "fake_key", 1, 1, 1024, 1)); NiceMock outer_decoder; ConnPoolCallbacks callbacks; @@ -448,7 +451,8 @@ TEST_F(Http1ConnPoolImplTest, MaxRequestsPerConnection) { TEST_F(Http1ConnPoolImplTest, ConcurrentConnections) { InSequence s; - cluster_.resource_manager_.reset(new Upstream::ResourceManagerImpl(2, 1024, 1024, 1)); + cluster_.resource_manager_.reset( + new Upstream::ResourceManagerImpl(runtime_, "fake_key", 2, 1024, 1024, 1)); ActiveTestRequest r1(*this, 0, ActiveTestRequest::Type::CreateConnection); r1.startRequest(); diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 645fdcbd5044..27b5a2b0caeb 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -6,6 +6,7 @@ #include "test/mocks/event/mocks.h" #include "test/mocks/http/mocks.h" #include "test/mocks/network/mocks.h" +#include "test/mocks/runtime/mocks.h" #include "test/mocks/upstream/mocks.h" using testing::_; @@ -91,6 +92,7 @@ class Http2ConnPoolImplTest : public testing::Test { Upstream::HostPtr host_{new Upstream::HostImpl(cluster_, "tcp://127.0.0.1:80", false, 1, "")}; TestConnPoolImpl pool_; std::vector test_clients_; + NiceMock runtime_; }; class ActiveTestRequest { @@ -331,7 +333,8 @@ TEST_F(Http2ConnPoolImplTest, MaxRequests) { TEST_F(Http2ConnPoolImplTest, MaxGlobalRequests) { InSequence s; - cluster_.resource_manager_.reset(new Upstream::ResourceManagerImpl(1024, 1024, 1, 1)); + cluster_.resource_manager_.reset( + new Upstream::ResourceManagerImpl(runtime_, "fake_key", 1024, 1024, 1, 1)); expectClientCreate(); ActiveTestRequest r1(*this, 0); diff --git a/test/common/router/retry_state_impl_test.cc b/test/common/router/retry_state_impl_test.cc index d54080bee16e..e20af839a82e 100644 --- a/test/common/router/retry_state_impl_test.cc +++ b/test/common/router/retry_state_impl_test.cc @@ -175,7 +175,8 @@ TEST_F(RouterRetryStateImplTest, RouteConfigNoHeaderConfig) { } TEST_F(RouterRetryStateImplTest, NoAvailableRetries) { - cluster_.resource_manager_.reset(new Upstream::ResourceManagerImpl(0, 0, 0, 0)); + cluster_.resource_manager_.reset( + new Upstream::ResourceManagerImpl(runtime_, "fake_key", 0, 0, 0, 0)); Http::HeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); diff --git a/test/common/upstream/logical_dns_cluster_test.cc b/test/common/upstream/logical_dns_cluster_test.cc index 08fc8681c48c..5dabfeb2af0f 100644 --- a/test/common/upstream/logical_dns_cluster_test.cc +++ b/test/common/upstream/logical_dns_cluster_test.cc @@ -2,6 +2,7 @@ #include "test/mocks/common.h" #include "test/mocks/network/mocks.h" +#include "test/mocks/runtime/mocks.h" #include "test/mocks/ssl/mocks.h" #include "test/mocks/thread_local/mocks.h" @@ -16,8 +17,8 @@ class LogicalDnsClusterTest : public testing::Test { void setup(const std::string& json) { Json::StringLoader config(json); resolve_timer_ = new Event::MockTimer(&dns_resolver_.dispatcher_); - cluster_.reset( - new LogicalDnsCluster(config, stats_store_, ssl_context_manager_, dns_resolver_, tls_)); + cluster_.reset(new LogicalDnsCluster(config, runtime_, stats_store_, ssl_context_manager_, + dns_resolver_, tls_)); cluster_->addMemberUpdateCb([&](const std::vector&, const std::vector&) -> void { membership_updated_.ready(); }); cluster_->setInitializedCb([&]() -> void { initialized_.ready(); }); @@ -38,6 +39,7 @@ class LogicalDnsClusterTest : public testing::Test { std::unique_ptr cluster_; ReadyWatcher membership_updated_; ReadyWatcher initialized_; + NiceMock runtime_; }; TEST_F(LogicalDnsClusterTest, BadConfig) { diff --git a/test/common/upstream/resource_manager_impl_test.cc b/test/common/upstream/resource_manager_impl_test.cc new file mode 100644 index 000000000000..fdb399d16a9d --- /dev/null +++ b/test/common/upstream/resource_manager_impl_test.cc @@ -0,0 +1,37 @@ +#include "common/upstream/resource_manager_impl.h" + +#include "test/mocks/runtime/mocks.h" + +using testing::NiceMock; +using testing::Return; + +namespace Upstream { + +TEST(ResourceManagerImplTest, RuntimeResourceManager) { + NiceMock runtime; + ResourceManagerImpl resource_manager( + runtime, "circuit_breakers.runtime_resource_manager_test.default.", 0, 0, 0, 0); + + EXPECT_CALL(runtime.snapshot_, + getInteger("circuit_breakers.runtime_resource_manager_test.default.max_connections", + 0U)).WillOnce(Return(1U)); + EXPECT_EQ(1U, resource_manager.connections().max()); + + EXPECT_CALL( + runtime.snapshot_, + getInteger("circuit_breakers.runtime_resource_manager_test.default.max_pending_requests", 0U)) + .WillOnce(Return(2U)); + EXPECT_EQ(2U, resource_manager.pendingRequests().max()); + + EXPECT_CALL(runtime.snapshot_, + getInteger("circuit_breakers.runtime_resource_manager_test.default.max_requests", 0U)) + .WillOnce(Return(3U)); + EXPECT_EQ(3U, resource_manager.requests().max()); + + EXPECT_CALL(runtime.snapshot_, + getInteger("circuit_breakers.runtime_resource_manager_test.default.max_retries", 0U)) + .WillOnce(Return(4U)); + EXPECT_EQ(4U, resource_manager.retries().max()); +} + +} // Upstream diff --git a/test/common/upstream/sds_test.cc b/test/common/upstream/sds_test.cc index 8fe831ca096f..ee52e26f2bd8 100644 --- a/test/common/upstream/sds_test.cc +++ b/test/common/upstream/sds_test.cc @@ -35,8 +35,8 @@ class SdsTest : public testing::Test { Json::StringLoader config(raw_config); timer_ = new Event::MockTimer(&dispatcher_); - cluster_.reset(new SdsClusterImpl(config, stats_, ssl_context_manager_, sds_config_, cm_, - dispatcher_, random_)); + cluster_.reset(new SdsClusterImpl(config, runtime_, stats_, ssl_context_manager_, sds_config_, + cm_, dispatcher_, random_)); } HostPtr findHost(const std::string& address) { @@ -90,6 +90,7 @@ class SdsTest : public testing::Test { ReadyWatcher membership_updated_; NiceMock random_; Http::MockAsyncClientRequest request_; + NiceMock runtime_; }; TEST_F(SdsTest, Shutdown) { diff --git a/test/common/upstream/upstream_impl_test.cc b/test/common/upstream/upstream_impl_test.cc index 1569cf508beb..01c86610e744 100644 --- a/test/common/upstream/upstream_impl_test.cc +++ b/test/common/upstream/upstream_impl_test.cc @@ -6,6 +6,7 @@ #include "test/mocks/common.h" #include "test/mocks/network/mocks.h" +#include "test/mocks/runtime/mocks.h" #include "test/mocks/ssl/mocks.h" #include "test/mocks/upstream/mocks.h" @@ -46,6 +47,7 @@ TEST(StrictDnsClusterImplTest, Basic) { Stats::IsolatedStoreImpl stats; Ssl::MockContextManager ssl_context_manager; NiceMock dns_resolver; + NiceMock runtime; // gmock matches in LIFO order which is why these are swapped. ResolverData resolver2(dns_resolver); @@ -79,7 +81,7 @@ TEST(StrictDnsClusterImplTest, Basic) { )EOF"; Json::StringLoader loader(json); - StrictDnsClusterImpl cluster(loader, stats, ssl_context_manager, dns_resolver); + StrictDnsClusterImpl cluster(loader, runtime, stats, ssl_context_manager, dns_resolver); EXPECT_EQ(43U, cluster.resourceManager(ResourcePriority::Default).connections().max()); EXPECT_EQ(57U, cluster.resourceManager(ResourcePriority::Default).pendingRequests().max()); EXPECT_EQ(50U, cluster.resourceManager(ResourcePriority::Default).requests().max()); @@ -186,6 +188,7 @@ TEST(HostImplTest, MalformedUrl) { TEST(StaticClusterImplTest, UrlConfig) { Stats::IsolatedStoreImpl stats; Ssl::MockContextManager ssl_context_manager; + NiceMock runtime; std::string json = R"EOF( { "name": "addressportconfig", @@ -198,7 +201,7 @@ TEST(StaticClusterImplTest, UrlConfig) { )EOF"; Json::StringLoader config(json); - StaticClusterImpl cluster(config, stats, ssl_context_manager); + StaticClusterImpl cluster(config, runtime, stats, ssl_context_manager); EXPECT_EQ(1024U, cluster.resourceManager(ResourcePriority::Default).connections().max()); EXPECT_EQ(1024U, cluster.resourceManager(ResourcePriority::Default).pendingRequests().max()); EXPECT_EQ(1024U, cluster.resourceManager(ResourcePriority::Default).requests().max()); @@ -220,6 +223,7 @@ TEST(StaticClusterImplTest, UrlConfig) { TEST(StaticClusterImplTest, UnsupportedLBType) { Stats::IsolatedStoreImpl stats; Ssl::MockContextManager ssl_context_manager; + NiceMock runtime; std::string json = R"EOF( { "name": "addressportconfig", @@ -232,12 +236,13 @@ TEST(StaticClusterImplTest, UnsupportedLBType) { )EOF"; Json::StringLoader config(json); - EXPECT_THROW(StaticClusterImpl(config, stats, ssl_context_manager), EnvoyException); + EXPECT_THROW(StaticClusterImpl(config, runtime, stats, ssl_context_manager), EnvoyException); } TEST(StaticClusterImplTest, UnsupportedFeature) { Stats::IsolatedStoreImpl stats; Ssl::MockContextManager ssl_context_manager; + NiceMock runtime; std::string json = R"EOF( { "name": "addressportconfig", @@ -251,7 +256,7 @@ TEST(StaticClusterImplTest, UnsupportedFeature) { )EOF"; Json::StringLoader config(json); - EXPECT_THROW(StaticClusterImpl(config, stats, ssl_context_manager), EnvoyException); + EXPECT_THROW(StaticClusterImpl(config, runtime, stats, ssl_context_manager), EnvoyException); } } // Upstream diff --git a/test/mocks/upstream/mocks.cc b/test/mocks/upstream/mocks.cc index 5396113decb6..5700dc065c97 100644 --- a/test/mocks/upstream/mocks.cc +++ b/test/mocks/upstream/mocks.cc @@ -21,7 +21,7 @@ MockHost::~MockHost() {} MockCluster::MockCluster() : stats_(ClusterImplBase::generateStats(name_, stats_store_)), - resource_manager_(new Upstream::ResourceManagerImpl(1, 1024, 1024, 1)) { + resource_manager_(new Upstream::ResourceManagerImpl(runtime_, "fake_key", 1, 1024, 1024, 1)) { ON_CALL(*this, connectTimeout()).WillByDefault(Return(std::chrono::milliseconds(1))); ON_CALL(*this, hosts()).WillByDefault(ReturnRef(hosts_)); ON_CALL(*this, healthyHosts()).WillByDefault(ReturnRef(healthy_hosts_)); diff --git a/test/mocks/upstream/mocks.h b/test/mocks/upstream/mocks.h index 62cb1ac2525f..99de3d5ace57 100644 --- a/test/mocks/upstream/mocks.h +++ b/test/mocks/upstream/mocks.h @@ -8,6 +8,7 @@ #include "common/stats/stats_impl.h" #include "test/mocks/http/mocks.h" +#include "test/mocks/runtime/mocks.h" using testing::NiceMock; @@ -56,6 +57,7 @@ class MockCluster : public Cluster { Stats::IsolatedStoreImpl stats_store_; ClusterStats stats_; std::unique_ptr resource_manager_; + NiceMock runtime_; }; class MockClusterManager : public ClusterManager {