Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
Signed-off-by: Kuat Yessenov <[email protected]>
  • Loading branch information
kyessenov committed Oct 3, 2023
1 parent 4430333 commit 8345165
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 10 deletions.
4 changes: 4 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ new_features:
- area: original_dst
change: |
added support for the internal listener address recovery using the original destination listener filter.
- area: filters
change: |
added filters to update the filter state for :ref:`the HTTP requests <config_http_filters_set_filter_state>` and
:ref:`the TCP connections <config_network_filters_set_filter_state>`.
deprecated:
Expand Down
15 changes: 5 additions & 10 deletions source/extensions/filters/http/set_filter_state/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,16 @@ Http::FilterHeadersStatus SetFilterState::decodeHeaders(Http::RequestHeaderMap&

Http::FilterFactoryCb SetFilterStateConfig::createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::set_filter_state::v3::Config& proto_config,
const std::string&, Server::Configuration::FactoryContext& context) {
auto filter_config(std::make_shared<Filters::Common::SetFilterState::Config>(
proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain, context));
return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamDecoderFilter(
Http::StreamDecoderFilterSharedPtr{new SetFilterState(filter_config)});
};
const std::string& stat_prefix, Server::Configuration::FactoryContext& context) {
return createFilterFactoryFromProtoWithServerContextTyped(proto_config, stat_prefix,
context.getServerFactoryContext());
}

Http::FilterFactoryCb SetFilterStateConfig::createFilterFactoryFromProtoWithServerContextTyped(
const envoy::extensions::filters::http::set_filter_state::v3::Config& proto_config,
const std::string&, Server::Configuration::ServerFactoryContext& context) {
auto filter_config(std::make_shared<Filters::Common::SetFilterState::Config>(
proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain, context));

const auto filter_config = std::make_shared<Filters::Common::SetFilterState::Config>(
proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain, context);
return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamDecoderFilter(
Http::StreamDecoderFilterSharedPtr{new SetFilterState(filter_config)});
Expand Down
28 changes: 28 additions & 0 deletions test/extensions/filters/http/set_filter_state/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_package",
)
load(
"//test/extensions:extensions_build_system.bzl",
"envoy_extension_cc_test",
)

licenses(["notice"]) # Apache 2

envoy_package()

envoy_extension_cc_test(
name = "integration_test",
srcs = [
"integration_test.cc",
],
extension_names = ["envoy.filters.http.set_filter_state"],
deps = [
"//source/common/router:string_accessor_lib",
"//source/extensions/filters/http/set_filter_state:config",
"//test/mocks/http:http_mocks",
"//test/mocks/server:factory_context_mocks",
"//test/mocks/stream_info:stream_info_mocks",
"//test/test_common:utility_lib",
],
)
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
@@ -0,0 +1,73 @@
#include <memory>

#include "source/common/protobuf/protobuf.h"
#include "source/common/router/string_accessor_impl.h"
#include "source/extensions/filters/http/set_filter_state/config.h"

#include "test/mocks/http/mocks.h"
#include "test/mocks/server/factory_context.h"
#include "test/mocks/stream_info/mocks.h"
#include "test/test_common/utility.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

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

namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace SetFilterState {

class ObjectFooFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return "foo"; }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
return std::make_unique<Router::StringAccessorImpl>(data);
}
};

REGISTER_FACTORY(ObjectFooFactory, StreamInfo::FilterState::ObjectFactory);

class SetMetadataIntegrationTest : public testing::Test {
public:
SetMetadataIntegrationTest() = default;

void runFilter(const std::string& yaml_config) {
envoy::extensions::filters::http::set_filter_state::v3::Config proto_config;
TestUtility::loadFromYaml(yaml_config, proto_config);
auto config = std::make_shared<Filters::Common::SetFilterState::Config>(
proto_config.on_request_headers(), StreamInfo::FilterState::LifeSpan::FilterChain,
context_);
auto filter = std::make_shared<SetFilterState>(config);
NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks;
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_;
};

TEST_F(SetMetadataIntegrationTest, FromHeader) {
const std::string yaml_config = R"EOF(
on_request_headers:
- object_key: foo
format_string:
text_format_source:
inline_string: "%REQ(test-header)%"
)EOF";
runFilter(yaml_config);
const auto* foo = info_.filterState()->getDataReadOnly<Router::StringAccessor>("foo");
ASSERT_NE(nullptr, foo);
EXPECT_EQ(foo->serializeAsString(), "test-value");
}

} // namespace SetFilterState
} // namespace HttpFilters
} // namespace Extensions
} // namespace Envoy
29 changes: 29 additions & 0 deletions test/extensions/filters/network/set_filter_state/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_package",
)
load(
"//test/extensions:extensions_build_system.bzl",
"envoy_extension_cc_test",
)

licenses(["notice"]) # Apache 2

envoy_package()

envoy_extension_cc_test(
name = "integration_test",
srcs = [
"integration_test.cc",
],
extension_names = ["envoy.filters.network.set_filter_state"],
deps = [
"//source/common/router:string_accessor_lib",
"//source/extensions/filters/network/set_filter_state:config",
"//test/mocks/network:network_mocks",
"//test/mocks/server:factory_context_mocks",
"//test/mocks/stream_info:stream_info_mocks",
"//test/test_common:utility_lib",
"@envoy_api//envoy/extensions/filters/network/set_filter_state/v3:pkg_cc_proto",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <memory>

#include "envoy/extensions/filters/network/set_filter_state/v3/set_filter_state.pb.h"
#include "envoy/extensions/filters/network/set_filter_state/v3/set_filter_state.pb.validate.h"

#include "source/common/protobuf/protobuf.h"
#include "source/common/router/string_accessor_impl.h"
#include "source/extensions/filters/network/set_filter_state/config.h"

#include "test/mocks/network/mocks.h"
#include "test/mocks/server/factory_context.h"
#include "test/mocks/stream_info/mocks.h"
#include "test/test_common/utility.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

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

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace SetFilterState {

class ObjectFooFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return "foo"; }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
return std::make_unique<Router::StringAccessorImpl>(data);
}
};

REGISTER_FACTORY(ObjectFooFactory, StreamInfo::FilterState::ObjectFactory);

class SetMetadataIntegrationTest : public testing::Test {
public:
SetMetadataIntegrationTest() = default;

void runFilter(const std::string& yaml_config) {
envoy::extensions::filters::network::set_filter_state::v3::Config proto_config;
TestUtility::loadFromYaml(yaml_config, proto_config);
auto config = std::make_shared<Filters::Common::SetFilterState::Config>(
proto_config.on_new_connection(), StreamInfo::FilterState::LifeSpan::Connection, context_);
auto filter = std::make_shared<SetFilterState>(config);
NiceMock<Network::MockReadFilterCallbacks> callbacks;
filter->initializeReadFilterCallbacks(callbacks);
EXPECT_CALL(callbacks.connection_, streamInfo()).WillRepeatedly(ReturnRef(info_));
EXPECT_EQ(Network::FilterStatus::Continue, filter->onNewConnection());
}

NiceMock<Server::Configuration::MockFactoryContext> context_;
NiceMock<StreamInfo::MockStreamInfo> info_;
};

TEST_F(SetMetadataIntegrationTest, FromHeader) {
const std::string yaml_config = R"EOF(
on_new_connection:
- object_key: foo
format_string:
text_format_source:
inline_string: "bar"
)EOF";
runFilter(yaml_config);
const auto* foo = info_.filterState()->getDataReadOnly<Router::StringAccessor>("foo");
ASSERT_NE(nullptr, foo);
EXPECT_EQ(foo->serializeAsString(), "bar");
}

} // namespace SetFilterState
} // namespace NetworkFilters
} // namespace Extensions
} // namespace Envoy

0 comments on commit 8345165

Please sign in to comment.