Skip to content

Commit 9dec4de

Browse files
authored
api_listener: improve test coverage (#40898)
1 parent f384ab2 commit 9dec4de

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

test/server/api_listener_test.cc

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,5 +240,147 @@ name: test_api_listener
240240
EXPECT_ENVOY_BUG(connection.isHalfCloseEnabled(), "Unexpected function call");
241241
}
242242

243+
// Exercise SyntheticReadCallbacks unimplemented methods and PANIC behavior for socket().
244+
TEST_F(ApiListenerTest, SyntheticReadCallbacksUnimplementedMethods) {
245+
const std::string yaml = R"EOF(
246+
name: test_api_listener
247+
address:
248+
socket_address:
249+
address: 127.0.0.1
250+
port_value: 1234
251+
api_listener:
252+
api_listener:
253+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
254+
stat_prefix: hcm
255+
route_config:
256+
name: api_router
257+
virtual_hosts:
258+
- name: api
259+
domains:
260+
- "*"
261+
routes:
262+
- match:
263+
prefix: "/"
264+
route:
265+
cluster: dynamic_forward_proxy_cluster
266+
)EOF";
267+
268+
const envoy::config::listener::v3::Listener config = parseListenerFromV3Yaml(yaml);
269+
server_.server_factory_context_->cluster_manager_.initializeClusters(
270+
{"dynamic_forward_proxy_cluster"}, {});
271+
HttpApiListenerFactory factory;
272+
auto http_api_listener = factory.create(config, server_, config.name()).value();
273+
auto api_listener = http_api_listener->createHttpApiListener(server_.dispatcher());
274+
ASSERT_NE(api_listener, nullptr);
275+
276+
// Access SyntheticReadCallbacks through the wrapper.
277+
auto* wrapper = dynamic_cast<HttpApiListener::ApiListenerWrapper*>(api_listener.get());
278+
ASSERT_NE(wrapper, nullptr);
279+
auto& read_callbacks = wrapper->readCallbacks();
280+
281+
Buffer::OwnedImpl dummy_buffer("x");
282+
EXPECT_ENVOY_BUG(read_callbacks.continueReading(), "Unexpected call to continueReading");
283+
EXPECT_ENVOY_BUG(read_callbacks.injectReadDataToFilterChain(dummy_buffer, false),
284+
"Unexpected call to injectReadDataToFilterChain");
285+
EXPECT_ENVOY_BUG(read_callbacks.disableClose(true), "Unexpected call to disableClose");
286+
EXPECT_ENVOY_BUG(read_callbacks.startUpstreamSecureTransport(),
287+
"Unexpected call to startUpstreamSecureTransport");
288+
EXPECT_EQ(read_callbacks.upstreamHost(), nullptr);
289+
EXPECT_ENVOY_BUG(read_callbacks.upstreamHost(nullptr), "Unexpected call to upstreamHost");
290+
EXPECT_DEATH(read_callbacks.socket(), "not implemented");
291+
}
292+
293+
// Verify base address access and drain decision behavior.
294+
TEST_F(ApiListenerTest, NewStreamHandleReturnsDecoderHandle) {
295+
const std::string yaml = R"EOF(
296+
name: test_api_listener
297+
address:
298+
socket_address:
299+
address: 127.0.0.1
300+
port_value: 1234
301+
api_listener:
302+
api_listener:
303+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
304+
stat_prefix: hcm
305+
route_config:
306+
name: api_router
307+
virtual_hosts:
308+
- name: api
309+
domains:
310+
- "*"
311+
routes:
312+
- match:
313+
prefix: "/"
314+
route:
315+
cluster: dynamic_forward_proxy_cluster
316+
)EOF";
317+
318+
const envoy::config::listener::v3::Listener config = parseListenerFromV3Yaml(yaml);
319+
server_.server_factory_context_->cluster_manager_.initializeClusters(
320+
{"dynamic_forward_proxy_cluster"}, {});
321+
322+
HttpApiListenerFactory factory;
323+
auto http_api_listener = factory.create(config, server_, config.name()).value();
324+
auto api_listener = http_api_listener->createHttpApiListener(server_.dispatcher());
325+
ASSERT_NE(api_listener, nullptr);
326+
327+
testing::NiceMock<Envoy::Http::MockResponseEncoder> response_encoder;
328+
ON_CALL(response_encoder, getStream())
329+
.WillByDefault(testing::ReturnRef(response_encoder.stream_));
330+
ON_CALL(response_encoder, setRequestDecoder(testing::_)).WillByDefault(testing::Return());
331+
332+
auto decoder_handle = api_listener->newStreamHandle(response_encoder);
333+
ASSERT_NE(decoder_handle, nullptr);
334+
335+
// Tear down in safe order.
336+
decoder_handle.reset();
337+
api_listener.reset();
338+
}
339+
340+
// Removing callbacks prevents receiving RemoteClose on ApiListenerWrapper destruction.
341+
TEST_F(ApiListenerTest, NoEventAfterCallbackRemovalOnShutdown) {
342+
const std::string yaml = R"EOF(
343+
name: test_api_listener
344+
address:
345+
socket_address:
346+
address: 127.0.0.1
347+
port_value: 1234
348+
api_listener:
349+
api_listener:
350+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
351+
stat_prefix: hcm
352+
route_config:
353+
name: api_router
354+
virtual_hosts:
355+
- name: api
356+
domains:
357+
- "*"
358+
routes:
359+
- match:
360+
prefix: "/"
361+
route:
362+
cluster: dynamic_forward_proxy_cluster
363+
)EOF";
364+
365+
const envoy::config::listener::v3::Listener config = parseListenerFromV3Yaml(yaml);
366+
server_.server_factory_context_->cluster_manager_.initializeClusters(
367+
{"dynamic_forward_proxy_cluster"}, {});
368+
369+
HttpApiListenerFactory factory;
370+
auto http_api_listener = factory.create(config, server_, config.name()).value();
371+
auto api_listener = http_api_listener->createHttpApiListener(server_.dispatcher());
372+
ASSERT_NE(api_listener, nullptr);
373+
374+
Network::MockConnectionCallbacks network_connection_callbacks;
375+
auto& connection = dynamic_cast<HttpApiListener::ApiListenerWrapper*>(api_listener.get())
376+
->readCallbacks()
377+
.connection();
378+
connection.addConnectionCallbacks(network_connection_callbacks);
379+
connection.removeConnectionCallbacks(network_connection_callbacks);
380+
381+
EXPECT_CALL(network_connection_callbacks, onEvent(testing::_)).Times(0);
382+
api_listener.reset();
383+
}
384+
243385
} // namespace Server
244386
} // namespace Envoy

0 commit comments

Comments
 (0)