Skip to content

Commit

Permalink
Add integration test
Browse files Browse the repository at this point in the history
Signed-off-by: John Howard <[email protected]>
  • Loading branch information
howardjohn committed Dec 11, 2024
1 parent 71ce473 commit 5c8a97f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
5 changes: 2 additions & 3 deletions source/extensions/filters/http/set_filter_state/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,16 @@ Http::FilterFactoryCb SetFilterStateConfig::createFilterFactoryFromProtoTyped(
};
}

Router::RouteSpecificFilterConfigConstSharedPtr
absl::StatusOr<Router::RouteSpecificFilterConfigConstSharedPtr>
SetFilterStateConfig::createRouteSpecificFilterConfigTyped(
const envoy::extensions::filters::http::set_filter_state::v3::Config& proto_config,
Server::Configuration::ServerFactoryContext& context, ProtobufMessage::ValidationVisitor&) {

Server::GenericFactoryContextImpl generic_context(context, context.messageValidationVisitor());

const auto filter_config = std::make_shared<Filters::Common::SetFilterState::Config>(
return std::make_shared<const Filters::Common::SetFilterState::Config>(
proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain,
generic_context);
return filter_config;
}

Http::FilterFactoryCb SetFilterStateConfig::createFilterFactoryFromProtoWithServerContextTyped(
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/filters/http/set_filter_state/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SetFilterStateConfig
const envoy::extensions::filters::http::set_filter_state::v3::Config& proto_config,
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) override;

Router::RouteSpecificFilterConfigConstSharedPtr createRouteSpecificFilterConfigTyped(
absl::StatusOr<Router::RouteSpecificFilterConfigConstSharedPtr> createRouteSpecificFilterConfigTyped(
const envoy::extensions::filters::http::set_filter_state::v3::Config& proto_config,
Server::Configuration::ServerFactoryContext&, ProtobufMessage::ValidationVisitor&) override;

Expand Down
73 changes: 73 additions & 0 deletions test/extensions/filters/http/set_filter_state/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "gtest/gtest.h"

using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;

namespace Envoy {
Expand Down Expand Up @@ -66,6 +67,32 @@ class SetMetadataIntegrationTest : public testing::Test {
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter->decodeHeaders(headers_, true));
}

void runPerRouteFilter(const std::string& listener_yaml_config,
const std::string& per_route_yaml_config) {
Server::GenericFactoryContextImpl generic_context(context_);

envoy::extensions::filters::http::set_filter_state::v3::Config listener_proto_config;
TestUtility::loadFromYaml(listener_yaml_config, listener_proto_config);
auto listener_config = std::make_shared<Filters::Common::SetFilterState::Config>(
listener_proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain,
generic_context);

envoy::extensions::filters::http::set_filter_state::v3::Config route_proto_config;
TestUtility::loadFromYaml(per_route_yaml_config, route_proto_config);
Filters::Common::SetFilterState::Config route_config(
route_proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain,
generic_context);

NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks;
EXPECT_CALL(*decoder_callbacks.route_, mostSpecificPerFilterConfig(_))
.WillOnce(Return(&route_config));

auto filter = std::make_shared<SetFilterState>(listener_config);
filter->setDecoderFilterCallbacks(decoder_callbacks);
EXPECT_CALL(decoder_callbacks, streamInfo()).WillRepeatedly(ReturnRef(info_));
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter->decodeHeaders(headers_, true));
}

NiceMock<Server::Configuration::MockFactoryContext> context_;
Http::TestRequestHeaderMapImpl headers_{{"test-header", "test-value"}};
NiceMock<StreamInfo::MockStreamInfo> info_;
Expand All @@ -85,6 +112,52 @@ TEST_F(SetMetadataIntegrationTest, FromHeader) {
EXPECT_EQ(foo->serializeAsString(), "test-value");
}

TEST_F(SetMetadataIntegrationTest, RouteLevel) {
const std::string listener_config = R"EOF(
on_request_headers:
- object_key: both
factory_key: envoy.string
format_string:
text_format_source:
inline_string: "listener-%REQ(test-header)%"
- object_key: listener-only
factory_key: envoy.string
format_string:
text_format_source:
inline_string: "listener"
)EOF";
const std::string route_config = R"EOF(
on_request_headers:
- object_key: both
factory_key: envoy.string
format_string:
text_format_source:
inline_string: "route-%REQ(test-header)%"
- object_key: route-only
factory_key: envoy.string
format_string:
text_format_source:
inline_string: "route"
)EOF";
runPerRouteFilter(listener_config, route_config);

const auto* both = info_.filterState()->getDataReadOnly<Router::StringAccessor>("both");
ASSERT_NE(nullptr, both);
// Route takes precedence
EXPECT_EQ(both->serializeAsString(), "route-test-value");

const auto* listener =
info_.filterState()->getDataReadOnly<Router::StringAccessor>("listener-only");
ASSERT_NE(nullptr, listener);
// Only set on listener
EXPECT_EQ(listener->serializeAsString(), "listener");

const auto* route = info_.filterState()->getDataReadOnly<Router::StringAccessor>("route-only");
ASSERT_NE(nullptr, route);
// Only set on route
EXPECT_EQ(route->serializeAsString(), "route");
}

} // namespace SetFilterState
} // namespace HttpFilters
} // namespace Extensions
Expand Down

0 comments on commit 5c8a97f

Please sign in to comment.