From ff5c6355d7fd0c855bfebd21d7d740bca74761a7 Mon Sep 17 00:00:00 2001 From: giantcroc Date: Fri, 23 Sep 2022 11:17:16 +0800 Subject: [PATCH] add tests Signed-off-by: giantcroc --- .../filters/udp/udp_proxy/udp_proxy_filter.cc | 23 +++- .../filters/udp/udp_proxy/udp_proxy_filter.h | 8 +- .../udp/udp_proxy/udp_proxy_filter_test.cc | 111 +++++++++++++----- 3 files changed, 106 insertions(+), 36 deletions(-) diff --git a/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.cc b/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.cc index 171fe9f54724..e31418daf37d 100644 --- a/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.cc +++ b/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.cc @@ -22,12 +22,11 @@ UdpProxyFilter::UdpProxyFilter(Network::UdpReadFilterCallbacks& callbacks, } if (!config_->proxyAccessLogs().empty()) { - udp_proxy_stats_.emplace( - StreamInfo::StreamInfoImpl(config_->timeSource(), nullptr)); + udp_proxy_stats_.emplace(StreamInfo::StreamInfoImpl(config_->timeSource(), nullptr)); } } -UdpProxyFilter::~UdpProxyFilter(){ +UdpProxyFilter::~UdpProxyFilter() { if (!config_->proxyAccessLogs().empty()) { fillProxyStreamInfo(); for (const auto& access_log : config_->proxyAccessLogs()) { @@ -35,6 +34,7 @@ UdpProxyFilter::~UdpProxyFilter(){ } } } + void UdpProxyFilter::onClusterAddOrUpdate(Upstream::ThreadLocalCluster& cluster) { auto cluster_name = cluster.info()->name(); ENVOY_LOG(debug, "udp proxy: attaching to cluster {}", cluster_name); @@ -322,12 +322,23 @@ void UdpProxyFilter::ActiveSession::fillSessionStreamInfo() { void UdpProxyFilter::fillProxyStreamInfo() { ProtobufWkt::Struct stats_obj; auto& fields_map = *stats_obj.mutable_fields(); + fields_map["bytes_sent"] = + ValueUtil::numberValue(config_->stats().downstream_sess_tx_bytes_.value()); + fields_map["bytes_received"] = + ValueUtil::numberValue(config_->stats().downstream_sess_rx_bytes_.value()); + fields_map["errors_sent"] = + ValueUtil::numberValue(config_->stats().downstream_sess_tx_errors_.value()); + fields_map["errors_received"] = + ValueUtil::numberValue(config_->stats().downstream_sess_rx_errors_.value()); + fields_map["datagrams_sent"] = + ValueUtil::numberValue(config_->stats().downstream_sess_tx_datagrams_.value()); + fields_map["datagrams_received"] = + ValueUtil::numberValue(config_->stats().downstream_sess_rx_datagrams_.value()); fields_map["no_route"] = ValueUtil::numberValue(config_->stats().downstream_sess_no_route_.value()); fields_map["sess_total"] = - ValueUtil::numberValue(config_->stats().downstream_sess_total_.value()); - fields_map["idle_timeout"] = - ValueUtil::numberValue(config_->stats().idle_timeout_.value()); + ValueUtil::numberValue(config_->stats().downstream_sess_total_.value()); + fields_map["idle_timeout"] = ValueUtil::numberValue(config_->stats().idle_timeout_.value()); udp_proxy_stats_.value().setDynamicMetadata("udp.proxy.proxy", stats_obj); } diff --git a/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.h b/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.h index 17b07ce83e6d..407f339bd870 100644 --- a/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.h +++ b/source/extensions/filters/udp/udp_proxy/udp_proxy_filter.h @@ -121,8 +121,12 @@ class UdpProxyFilterConfig { const Network::ResolvedUdpSocketConfig& upstreamSocketConfig() const { return upstream_socket_config_; } - const std::vector& sessionAccessLogs() const { return sess_access_logs_; } - const std::vector& proxyAccessLogs() const { return proxy_access_logs_; } + const std::vector& sessionAccessLogs() const { + return sess_access_logs_; + } + const std::vector& proxyAccessLogs() const { + return proxy_access_logs_; + } private: static UdpProxyDownstreamStats generateStats(const std::string& stat_prefix, diff --git a/test/extensions/filters/udp/udp_proxy/udp_proxy_filter_test.cc b/test/extensions/filters/udp/udp_proxy/udp_proxy_filter_test.cc index 1865793854af..5f118c25db7d 100644 --- a/test/extensions/filters/udp/udp_proxy/udp_proxy_filter_test.cc +++ b/test/extensions/filters/udp/udp_proxy/udp_proxy_filter_test.cc @@ -167,7 +167,8 @@ class UdpProxyFilterTest : public testing::Test { peer_address_(std::move(peer_address)) { // Disable strict mock warnings. ON_CALL(*factory_context_.access_log_manager_.file_, write(_)) - .WillByDefault(SaveArg<0>(&access_log_data_)); + .WillByDefault( + Invoke([&](absl::string_view data) { output_.push_back(std::string(data)); })); ON_CALL(os_sys_calls_, supportsIpTransparent()).WillByDefault(Return(true)); EXPECT_CALL(os_sys_calls_, supportsUdpGro()).Times(AtLeast(0)).WillRepeatedly(Return(true)); EXPECT_CALL(callbacks_, udpListener()).Times(AtLeast(0)); @@ -275,16 +276,31 @@ use_original_src_ip: true // Return the config from yaml, plus one file access log with the specified format envoy::extensions::filters::udp::udp_proxy::v3::UdpProxyConfig - accessLogConfig(const std::string& yaml, const std::string& access_log_format) { + accessLogConfig(const std::string& yaml, const std::string& sess_access_log_format, + const std::string& proxy_access_log_format) { auto config = readConfig(yaml); - envoy::config::accesslog::v3::AccessLog* access_log = config.mutable_access_log()->Add(); - access_log->set_name("envoy.access_loggers.file"); - envoy::extensions::access_loggers::file::v3::FileAccessLog file_access_log; - file_access_log.set_path("unused"); - file_access_log.mutable_log_format()->mutable_text_format_source()->set_inline_string( - access_log_format); - access_log->mutable_typed_config()->PackFrom(file_access_log); + if (!sess_access_log_format.empty()) { + envoy::config::accesslog::v3::AccessLog* sess_access_log = + config.mutable_sess_access_log()->Add(); + sess_access_log->set_name("envoy.access_loggers.file"); + envoy::extensions::access_loggers::file::v3::FileAccessLog sess_file_access_log; + sess_file_access_log.set_path("unused"); + sess_file_access_log.mutable_log_format()->mutable_text_format_source()->set_inline_string( + sess_access_log_format); + sess_access_log->mutable_typed_config()->PackFrom(sess_file_access_log); + } + + if (!proxy_access_log_format.empty()) { + envoy::config::accesslog::v3::AccessLog* proxy_access_log = + config.mutable_proxy_access_log()->Add(); + proxy_access_log->set_name("envoy.access_loggers.file"); + envoy::extensions::access_loggers::file::v3::FileAccessLog proxy_file_access_log; + proxy_file_access_log.set_path("unused"); + proxy_file_access_log.mutable_log_format()->mutable_text_format_source()->set_inline_string( + proxy_access_log_format); + proxy_access_log->mutable_typed_config()->PackFrom(proxy_file_access_log); + } return config; } @@ -314,6 +330,7 @@ use_original_src_ip: true std::unique_ptr filter_; std::vector test_sessions_; StringViewSaver access_log_data_; + std::vector output_; bool expect_gro_{}; const Network::Address::InstanceConstSharedPtr upstream_address_; const Network::Address::InstanceConstSharedPtr peer_address_; @@ -368,10 +385,20 @@ class UdpProxyFilterIpv4Ipv6Test : public UdpProxyFilterIpv6Test { TEST_F(UdpProxyFilterTest, BasicFlow) { InSequence s; - const std::string access_log_format = "%DYNAMIC_METADATA(udp.proxy:bytes_received)% " - "%DYNAMIC_METADATA(udp.proxy:datagrams_received)% " - "%DYNAMIC_METADATA(udp.proxy:bytes_sent)% " - "%DYNAMIC_METADATA(udp.proxy:datagrams_sent)%"; + const std::string sess_access_log_format = + "%DYNAMIC_METADATA(udp.proxy.session:bytes_received)% " + "%DYNAMIC_METADATA(udp.proxy.session:datagrams_received)% " + "%DYNAMIC_METADATA(udp.proxy.session:bytes_sent)% " + "%DYNAMIC_METADATA(udp.proxy.session:datagrams_sent)%"; + + const std::string proxy_access_log_format = + "%DYNAMIC_METADATA(udp.proxy.proxy:bytes_received)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:datagrams_received)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:bytes_sent)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:datagrams_sent)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:no_route)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:sess_total)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:idle_timeout)%"; setup(accessLogConfig(R"EOF( stat_prefix: foo @@ -385,7 +412,7 @@ stat_prefix: foo upstream_socket_config: prefer_gro: false )EOF", - access_log_format), + sess_access_log_format, proxy_access_log_format), true, false); expectSessionCreate(upstream_address_); @@ -410,7 +437,9 @@ stat_prefix: foo checkTransferStats(17 /*rx_bytes*/, 3 /*rx_datagrams*/, 17 /*tx_bytes*/, 3 /*tx_datagrams*/); filter_.reset(); - EXPECT_EQ(access_log_data_.value(), "17 3 17 3"); + EXPECT_EQ(output_.size(), 2); + EXPECT_EQ(output_.front(), "17 3 17 3 0 1 0"); + EXPECT_EQ(output_.back(), "17 3 17 3"); } // Route with source IP. @@ -460,7 +489,12 @@ stat_prefix: foo TEST_F(UdpProxyFilterTest, IdleTimeout) { InSequence s; - setup(readConfig(R"EOF( + const std::string sess_access_log_format = ""; + + const std::string proxy_access_log_format = "%DYNAMIC_METADATA(udp.proxy.proxy:sess_total)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:idle_timeout)%"; + + setup(accessLogConfig(R"EOF( stat_prefix: foo matcher: on_no_match: @@ -469,7 +503,8 @@ stat_prefix: foo typed_config: '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route cluster: fake_cluster - )EOF")); + )EOF", + sess_access_log_format, proxy_access_log_format)); expectSessionCreate(upstream_address_); test_sessions_[0].expectWriteToUpstream("hello"); @@ -486,19 +521,28 @@ stat_prefix: foo recvDataFromDownstream("10.0.0.1:1000", "10.0.0.2:80", "hello"); EXPECT_EQ(2, config_->stats().downstream_sess_total_.value()); EXPECT_EQ(1, config_->stats().downstream_sess_active_.value()); + + filter_.reset(); + EXPECT_EQ(output_.size(), 1); + EXPECT_EQ(output_.front(), "2 1"); } // Verify downstream send and receive error handling. TEST_F(UdpProxyFilterTest, SendReceiveErrorHandling) { InSequence s; - const std::string access_log_format = "%DYNAMIC_METADATA(udp.proxy:cluster_name)% " - "%DYNAMIC_METADATA(udp.proxy:bytes_sent)% " - "%DYNAMIC_METADATA(udp.proxy:bytes_received)% " - "%DYNAMIC_METADATA(udp.proxy:errors_sent)% " - "%DYNAMIC_METADATA(udp.proxy:errors_received)% " - "%DYNAMIC_METADATA(udp.proxy:datagrams_sent)% " - "%DYNAMIC_METADATA(udp.proxy:datagrams_received)%"; + const std::string sess_access_log_format = + "%DYNAMIC_METADATA(udp.proxy.session:cluster_name)% " + "%DYNAMIC_METADATA(udp.proxy.session:bytes_sent)% " + "%DYNAMIC_METADATA(udp.proxy.session:bytes_received)% " + "%DYNAMIC_METADATA(udp.proxy.session:errors_sent)% " + "%DYNAMIC_METADATA(udp.proxy.session:errors_received)% " + "%DYNAMIC_METADATA(udp.proxy.session:datagrams_sent)% " + "%DYNAMIC_METADATA(udp.proxy.session:datagrams_received)%"; + + const std::string proxy_access_log_format = "%DYNAMIC_METADATA(udp.proxy.proxy:no_route)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:sess_total)% " + "%DYNAMIC_METADATA(udp.proxy.proxy:idle_timeout)%"; setup(accessLogConfig(R"EOF( stat_prefix: foo @@ -510,7 +554,7 @@ stat_prefix: foo '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route cluster: fake_cluster )EOF", - access_log_format)); + sess_access_log_format, proxy_access_log_format)); filter_->onReceiveError(Api::IoError::IoErrorCode::UnknownError); EXPECT_EQ(1, config_->stats().downstream_sess_rx_errors_.value()); @@ -550,7 +594,9 @@ stat_prefix: foo ->value()); filter_.reset(); - EXPECT_EQ(access_log_data_.value(), "fake_cluster 0 10 1 1 0 2"); + EXPECT_EQ(output_.size(), 2); + EXPECT_EQ(output_.front(), "0 1 0"); + EXPECT_EQ(output_.back(), "fake_cluster 0 10 1 1 0 2"); } // No upstream host handling. @@ -579,7 +625,11 @@ stat_prefix: foo TEST_F(UdpProxyFilterTest, NoUpstreamClusterAtCreation) { InSequence s; - setup(readConfig(R"EOF( + const std::string sess_access_log_format = ""; + + const std::string proxy_access_log_format = "%DYNAMIC_METADATA(udp.proxy.proxy:no_route)%"; + + setup(accessLogConfig(R"EOF( stat_prefix: foo matcher: on_no_match: @@ -588,11 +638,16 @@ stat_prefix: foo typed_config: '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route cluster: fake_cluster - )EOF"), + )EOF", + sess_access_log_format, proxy_access_log_format), false); recvDataFromDownstream("10.0.0.1:1000", "10.0.0.2:80", "hello"); EXPECT_EQ(1, config_->stats().downstream_sess_no_route_.value()); + + filter_.reset(); + EXPECT_EQ(output_.size(), 1); + EXPECT_EQ(output_.front(), "1"); } // Dynamic cluster addition and removal handling.