Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions test/server/api_listener_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -240,5 +240,147 @@ name: test_api_listener
EXPECT_ENVOY_BUG(connection.isHalfCloseEnabled(), "Unexpected function call");
}

// Exercise SyntheticReadCallbacks unimplemented methods and PANIC behavior for socket().
TEST_F(ApiListenerTest, SyntheticReadCallbacksUnimplementedMethods) {
const std::string yaml = R"EOF(
name: test_api_listener
address:
socket_address:
address: 127.0.0.1
port_value: 1234
api_listener:
api_listener:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: hcm
route_config:
name: api_router
virtual_hosts:
- name: api
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: dynamic_forward_proxy_cluster
)EOF";

const envoy::config::listener::v3::Listener config = parseListenerFromV3Yaml(yaml);
server_.server_factory_context_->cluster_manager_.initializeClusters(
{"dynamic_forward_proxy_cluster"}, {});
HttpApiListenerFactory factory;
auto http_api_listener = factory.create(config, server_, config.name()).value();
auto api_listener = http_api_listener->createHttpApiListener(server_.dispatcher());
ASSERT_NE(api_listener, nullptr);

// Access SyntheticReadCallbacks through the wrapper.
auto* wrapper = dynamic_cast<HttpApiListener::ApiListenerWrapper*>(api_listener.get());
ASSERT_NE(wrapper, nullptr);
auto& read_callbacks = wrapper->readCallbacks();

Buffer::OwnedImpl dummy_buffer("x");
EXPECT_ENVOY_BUG(read_callbacks.continueReading(), "Unexpected call to continueReading");
EXPECT_ENVOY_BUG(read_callbacks.injectReadDataToFilterChain(dummy_buffer, false),
"Unexpected call to injectReadDataToFilterChain");
EXPECT_ENVOY_BUG(read_callbacks.disableClose(true), "Unexpected call to disableClose");
EXPECT_ENVOY_BUG(read_callbacks.startUpstreamSecureTransport(),
"Unexpected call to startUpstreamSecureTransport");
EXPECT_EQ(read_callbacks.upstreamHost(), nullptr);
EXPECT_ENVOY_BUG(read_callbacks.upstreamHost(nullptr), "Unexpected call to upstreamHost");
EXPECT_DEATH(read_callbacks.socket(), "not implemented");
}

// Verify base address access and drain decision behavior.
TEST_F(ApiListenerTest, NewStreamHandleReturnsDecoderHandle) {
const std::string yaml = R"EOF(
name: test_api_listener
address:
socket_address:
address: 127.0.0.1
port_value: 1234
api_listener:
api_listener:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: hcm
route_config:
name: api_router
virtual_hosts:
- name: api
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: dynamic_forward_proxy_cluster
)EOF";

const envoy::config::listener::v3::Listener config = parseListenerFromV3Yaml(yaml);
server_.server_factory_context_->cluster_manager_.initializeClusters(
{"dynamic_forward_proxy_cluster"}, {});

HttpApiListenerFactory factory;
auto http_api_listener = factory.create(config, server_, config.name()).value();
auto api_listener = http_api_listener->createHttpApiListener(server_.dispatcher());
ASSERT_NE(api_listener, nullptr);

testing::NiceMock<Envoy::Http::MockResponseEncoder> response_encoder;
ON_CALL(response_encoder, getStream())
.WillByDefault(testing::ReturnRef(response_encoder.stream_));
ON_CALL(response_encoder, setRequestDecoder(testing::_)).WillByDefault(testing::Return());

auto decoder_handle = api_listener->newStreamHandle(response_encoder);
ASSERT_NE(decoder_handle, nullptr);

// Tear down in safe order.
decoder_handle.reset();
api_listener.reset();
}

// Removing callbacks prevents receiving RemoteClose on ApiListenerWrapper destruction.
TEST_F(ApiListenerTest, NoEventAfterCallbackRemovalOnShutdown) {
const std::string yaml = R"EOF(
name: test_api_listener
address:
socket_address:
address: 127.0.0.1
port_value: 1234
api_listener:
api_listener:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: hcm
route_config:
name: api_router
virtual_hosts:
- name: api
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: dynamic_forward_proxy_cluster
)EOF";

const envoy::config::listener::v3::Listener config = parseListenerFromV3Yaml(yaml);
server_.server_factory_context_->cluster_manager_.initializeClusters(
{"dynamic_forward_proxy_cluster"}, {});

HttpApiListenerFactory factory;
auto http_api_listener = factory.create(config, server_, config.name()).value();
auto api_listener = http_api_listener->createHttpApiListener(server_.dispatcher());
ASSERT_NE(api_listener, nullptr);

Network::MockConnectionCallbacks network_connection_callbacks;
auto& connection = dynamic_cast<HttpApiListener::ApiListenerWrapper*>(api_listener.get())
->readCallbacks()
.connection();
connection.addConnectionCallbacks(network_connection_callbacks);
connection.removeConnectionCallbacks(network_connection_callbacks);

EXPECT_CALL(network_connection_callbacks, onEvent(testing::_)).Times(0);
api_listener.reset();
}

} // namespace Server
} // namespace Envoy