Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions test/integration/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ envoy_cc_test_library(
"//test/integration/filters:random_pause_filter_lib",
"//test/integration/filters:remove_response_headers_lib",
"//test/test_common:logging_lib",
"//test/test_common:threadsafe_singleton_injector_lib",
"//test/test_common:utility_lib",
"@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto",
"@envoy_api//envoy/config/route/v3:pkg_cc_proto",
Expand Down
30 changes: 15 additions & 15 deletions test/integration/buffer_accounting_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ TEST_P(Http2BufferWatermarksTest, ShouldTrackAllocatedBytesToUpstream) {
buffer_factory_->setExpectedAccountBalance(request_body_size, num_requests);

// Makes us have Envoy's writes to upstream return EAGAIN
writev_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
write_matcher_->setWriteReturnsEgain();

codec_client_ = makeHttpConnection(lookupPort("http"));

Expand All @@ -228,7 +228,7 @@ TEST_P(Http2BufferWatermarksTest, ShouldTrackAllocatedBytesToUpstream) {
<< " buffer max: " << buffer_factory_->maxBufferSize() << printAccounts();
}

writev_matcher_->setResumeWrites();
write_matcher_->setResumeWrites();

for (auto& response : responses) {
ASSERT_TRUE(response->waitForEndStream());
Expand All @@ -246,12 +246,12 @@ TEST_P(Http2BufferWatermarksTest, ShouldTrackAllocatedBytesToDownstream) {
initialize();

buffer_factory_->setExpectedAccountBalance(response_body_size, num_requests);
writev_matcher_->setSourcePort(lookupPort("http"));
write_matcher_->setSourcePort(lookupPort("http"));
codec_client_ = makeHttpConnection(lookupPort("http"));

// Simulate TCP push back on the Envoy's downstream network socket, so that outbound frames
// start to accumulate in the transport socket buffer.
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

auto responses = sendRequests(num_requests, request_body_size, response_body_size);

Expand All @@ -263,7 +263,7 @@ TEST_P(Http2BufferWatermarksTest, ShouldTrackAllocatedBytesToDownstream) {
<< " buffer max: " << buffer_factory_->maxBufferSize() << printAccounts();
}

writev_matcher_->setResumeWrites();
write_matcher_->setResumeWrites();

// Wait for streams to terminate.
for (auto& response : responses) {
Expand Down Expand Up @@ -454,8 +454,8 @@ TEST_P(Http2OverloadManagerIntegrationTest,
initialize();

// Makes us have Envoy's writes to upstream return EAGAIN
writev_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
write_matcher_->setWriteReturnsEgain();

codec_client_ = makeHttpConnection(lookupPort("http"));
auto smallest_request_response = std::move(sendRequests(1, 4096, 4096)[0]);
Expand Down Expand Up @@ -500,7 +500,7 @@ TEST_P(Http2OverloadManagerIntegrationTest,
"overload.envoy.overload_actions.reset_high_memory_stream.scale_percent", 0);

// Resume writes to upstream, any request streams that survive can go through.
writev_matcher_->setResumeWrites();
write_matcher_->setResumeWrites();

if (!streamBufferAccounting()) {
// If we're not doing the accounting, we didn't end up resetting these
Expand Down Expand Up @@ -533,9 +533,9 @@ TEST_P(Http2OverloadManagerIntegrationTest,
initialize();

// Makes us have Envoy's writes to downstream return EAGAIN
writev_matcher_->setSourcePort(lookupPort("http"));
write_matcher_->setSourcePort(lookupPort("http"));
codec_client_ = makeHttpConnection(lookupPort("http"));
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

auto smallest_response = std::move(sendRequests(1, 10, 4096)[0]);
waitForNextUpstreamRequest();
Expand Down Expand Up @@ -589,7 +589,7 @@ TEST_P(Http2OverloadManagerIntegrationTest,
"overload.envoy.overload_actions.reset_high_memory_stream.scale_percent", 0);

// Resume writes to downstream, any responses that survive can go through.
writev_matcher_->setResumeWrites();
write_matcher_->setResumeWrites();

if (streamBufferAccounting()) {
EXPECT_TRUE(largest_response->waitForReset());
Expand Down Expand Up @@ -642,8 +642,8 @@ TEST_P(Http2OverloadManagerIntegrationTest, CanResetStreamIfEnvoyLevelStreamEnde
codec_client_ = makeRawHttpConnection(makeClientConnection(lookupPort("http")), http2_options);

// Makes us have Envoy's writes to downstream return EAGAIN
writev_matcher_->setSourcePort(lookupPort("http"));
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setSourcePort(lookupPort("http"));
write_matcher_->setWriteReturnsEgain();

// Send a request
auto encoder_decoder = codec_client_->startRequest(Http::TestRequestHeaderMapImpl{
Expand Down Expand Up @@ -690,7 +690,7 @@ TEST_P(Http2OverloadManagerIntegrationTest, CanResetStreamIfEnvoyLevelStreamEnde
"overload.envoy.overload_actions.reset_high_memory_stream.scale_percent", 0);

// Resume writes to downstream.
writev_matcher_->setResumeWrites();
write_matcher_->setResumeWrites();

if (streamBufferAccounting()) {
EXPECT_TRUE(response->waitForReset());
Expand Down
26 changes: 19 additions & 7 deletions test/integration/filters/test_socket_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,22 @@
namespace Envoy {
namespace Network {

Api::IoCallUint64Result TestIoSocketHandle::sendmsg(const Buffer::RawSlice* slices,
uint64_t num_slice, int flags,
const Address::Ip* self_ip,
const Address::Instance& peer_address) {
if (write_override_) {
auto result = write_override_(this, slices, num_slice);
if (result.has_value()) {
return std::move(result).value();
}
}
return Test::IoSocketHandlePlatformImpl::sendmsg(slices, num_slice, flags, self_ip, peer_address);
}
Api::IoCallUint64Result TestIoSocketHandle::writev(const Buffer::RawSlice* slices,
uint64_t num_slice) {
if (writev_override_) {
auto result = writev_override_(this, slices, num_slice);
if (write_override_) {
auto result = write_override_(this, slices, num_slice);
if (result.has_value()) {
return std::move(result).value();
}
Expand All @@ -30,8 +42,8 @@ IoHandlePtr TestIoSocketHandle::accept(struct sockaddr* addr, socklen_t* addrlen
return nullptr;
}

return std::make_unique<TestIoSocketHandle>(writev_override_, result.return_value_,
socket_v6only_, domain_);
return std::make_unique<TestIoSocketHandle>(write_override_, result.return_value_, socket_v6only_,
domain_);
}

IoHandlePtr TestIoSocketHandle::duplicate() {
Expand All @@ -40,13 +52,13 @@ IoHandlePtr TestIoSocketHandle::duplicate() {
throw EnvoyException(fmt::format("duplicate failed for '{}': ({}) {}", fd_, result.errno_,
errorDetails(result.errno_)));
}
return std::make_unique<TestIoSocketHandle>(writev_override_, result.return_value_,
socket_v6only_, domain_);
return std::make_unique<TestIoSocketHandle>(write_override_, result.return_value_, socket_v6only_,
domain_);
}

IoHandlePtr TestSocketInterface::makeSocket(int socket_fd, bool socket_v6only,
absl::optional<int> domain) const {
return std::make_unique<TestIoSocketHandle>(writev_override_proc_, socket_fd, socket_v6only,
return std::make_unique<TestIoSocketHandle>(write_override_proc_, socket_fd, socket_v6only,
domain);
}

Expand Down
32 changes: 18 additions & 14 deletions test/integration/filters/test_socket_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ namespace Network {

class TestIoSocketHandle : public Test::IoSocketHandlePlatformImpl {
public:
using WritevOverrideType = absl::optional<Api::IoCallUint64Result>(TestIoSocketHandle* io_handle,
const Buffer::RawSlice* slices,
uint64_t num_slice);
using WritevOverrideProc = std::function<WritevOverrideType>;
using WriteOverrideType = absl::optional<Api::IoCallUint64Result>(TestIoSocketHandle* io_handle,
const Buffer::RawSlice* slices,
uint64_t num_slice);
using WriteOverrideProc = std::function<WriteOverrideType>;

TestIoSocketHandle(WritevOverrideProc writev_override_proc, os_fd_t fd = INVALID_SOCKET,
TestIoSocketHandle(WriteOverrideProc write_override_proc, os_fd_t fd = INVALID_SOCKET,
bool socket_v6only = false, absl::optional<int> domain = absl::nullopt)
: Test::IoSocketHandlePlatformImpl(fd, socket_v6only, domain),
writev_override_(writev_override_proc) {}
write_override_(write_override_proc) {}

void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb,
Event::FileTriggerType trigger, uint32_t events) override {
Expand All @@ -50,9 +50,13 @@ class TestIoSocketHandle : public Test::IoSocketHandlePlatformImpl {
private:
IoHandlePtr accept(struct sockaddr* addr, socklen_t* addrlen) override;
Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) override;
Api::IoCallUint64Result sendmsg(const Buffer::RawSlice* slices, uint64_t num_slice, int flags,
const Address::Ip* self_ip,
const Address::Instance& peer_address) override;

IoHandlePtr duplicate() override;

const WritevOverrideProc writev_override_;
const WriteOverrideProc write_override_;
absl::Mutex mutex_;
Event::Dispatcher* dispatcher_ ABSL_GUARDED_BY(mutex_) = nullptr;
};
Expand All @@ -68,22 +72,22 @@ class TestIoSocketHandle : public Test::IoSocketHandlePlatformImpl {
class TestSocketInterface : public SocketInterfaceImpl {
public:
/**
* Override the behavior of the IoSocketHandleImpl::writev() method.
* The supplied callback is invoked with the arguments of the writev method and the index
* Override the behavior of the IoSocketHandleImpl::writev() and
* IoSocketHandleImpl::sendmsg() methods.
* The supplied callback is invoked with the slices arguments of the write method and the index
* of the accepted socket.
* Returning absl::nullopt from the callback continues normal execution of the
* IoSocketHandleImpl::writev() method. Returning a Api::IoCallUint64Result from callback skips
* the IoSocketHandleImpl::writev() with the returned result value.
* write methods. Returning a Api::IoCallUint64Result from callback skips
* the write methods with the returned result value.
*/
TestSocketInterface(TestIoSocketHandle::WritevOverrideProc writev)
: writev_override_proc_(writev) {}
TestSocketInterface(TestIoSocketHandle::WriteOverrideProc write) : write_override_proc_(write) {}

private:
// SocketInterfaceImpl
IoHandlePtr makeSocket(int socket_fd, bool socket_v6only,
absl::optional<int> domain) const override;

const TestIoSocketHandle::WritevOverrideProc writev_override_proc_;
const TestIoSocketHandle::WriteOverrideProc write_override_proc_;
};

} // namespace Network
Expand Down
32 changes: 16 additions & 16 deletions test/integration/http2_flood_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void Http2FloodMitigationTest::beginSession() {
options->emplace_back(std::make_shared<Network::SocketOptionImpl>(
envoy::config::core::v3::SocketOption::STATE_PREBIND,
ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_RCVBUF), 1024));
writev_matcher_->setSourcePort(lookupPort("http"));
write_matcher_->setSourcePort(lookupPort("http"));
tcp_client_ = makeTcpConnection(lookupPort("http"), options);
startHttp2Session();
}
Expand Down Expand Up @@ -156,11 +156,11 @@ void Http2FloodMitigationTest::floodClient(const Http2Frame& frame, uint32_t num
waitForNextUpstreamRequest();

// Make Envoy's writes into the upstream connection to return EAGAIN
writev_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
write_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());

auto buf = serializeFrames(frame, num_frames);

writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();
auto* upstream = fake_upstreams_.front().get();
ASSERT_TRUE(upstream->rawWriteConnection(0, std::string(buf.begin(), buf.end())));

Expand All @@ -184,7 +184,7 @@ void Http2FloodMitigationTest::floodServer(absl::string_view host, absl::string_
auto frame = readFrame();
EXPECT_EQ(Http2Frame::Type::Headers, frame.type());
EXPECT_EQ(expected_http_status, frame.responseStatus());
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();
for (uint32_t frame = 0; frame < num_frames; ++frame) {
request = Http2Frame::makeRequest(Http2Frame::makeClientStreamId(++request_idx), host, path);
sendFrame(request);
Expand All @@ -210,7 +210,7 @@ void Http2FloodMitigationTest::prefillOutboundDownstreamQueue(uint32_t data_fram
// such the next response triggers flood protection.
// Simulate TCP push back on the Envoy's downstream network socket, so that outbound frames
// start to accumulate in the transport socket buffer.
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

const auto request = Http2Frame::makeRequest(
Http2Frame::makeClientStreamId(0), "host", "/test/long/url",
Expand Down Expand Up @@ -258,11 +258,11 @@ Http2FloodMitigationTest::prefillOutboundUpstreamQueue(uint32_t frame_count) {
EXPECT_TRUE(upstream_request_->waitForData(*dispatcher_, 1));

// Make Envoy's writes into the upstream connection to return EAGAIN
writev_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
write_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());

auto buf = serializeFrames(Http2Frame::makePingFrame(), frame_count);

writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();
auto* upstream = fake_upstreams_.front().get();
EXPECT_TRUE(upstream->rawWriteConnection(0, std::string(buf.begin(), buf.end())));
// Wait for pre-fill data to arrive to Envoy
Expand All @@ -284,15 +284,15 @@ void Http2FloodMitigationTest::triggerListenerDrain() {
TEST_P(Http2FloodMitigationTest, Ping) {
setNetworkConnectionBufferSize();
beginSession();
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();
floodServer(Http2Frame::makePingFrame(), "http2.outbound_control_flood",
ControlFrameFloodLimit + 1);
}

TEST_P(Http2FloodMitigationTest, Settings) {
setNetworkConnectionBufferSize();
beginSession();
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();
floodServer(Http2Frame::makeEmptySettingsFrame(), "http2.outbound_control_flood",
ControlFrameFloodLimit + 1);
}
Expand Down Expand Up @@ -325,7 +325,7 @@ TEST_P(Http2FloodMitigationTest, Data) {
// 1000 DATA frames should trigger flood protection.
// Simulate TCP push back on the Envoy's downstream network socket, so that outbound frames start
// to accumulate in the transport socket buffer.
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

const auto request = Http2Frame::makeRequest(1, "host", "/test/long/url",
{Http2Frame::Header("response_data_blocks", "1000"),
Expand Down Expand Up @@ -565,7 +565,7 @@ TEST_P(Http2FloodMitigationTest, Trailers) {
// 999 DATA frames and trailers should trigger flood protection.
// Simulate TCP push back on the Envoy's downstream network socket, so that outbound frames start
// to accumulate in the transport socket buffer.
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

static_cast<AutonomousUpstream*>(fake_upstreams_.front().get())
->setResponseTrailers(std::make_unique<Http::TestResponseTrailerMapImpl>(
Expand Down Expand Up @@ -608,7 +608,7 @@ TEST_P(Http2FloodMitigationTest, WindowUpdateOnLowWatermarkFlood) {
autonomous_allow_incomplete_streams_ = true;
beginSession();

writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

// pre-fill two away from overflow
const auto request = Http2Frame::makePostRequest(
Expand Down Expand Up @@ -673,7 +673,7 @@ TEST_P(Http2FloodMitigationTest, RST_STREAM) {

// Simulate TCP push back on the Envoy's downstream network socket, so that outbound frames start
// to accumulate in the transport socket buffer.
writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

for (++stream_index; stream_index < ControlFrameFloodLimit + 2; ++stream_index) {
request =
Expand Down Expand Up @@ -949,7 +949,7 @@ TEST_P(Http2FloodMitigationTest, TooManyStreams) {
// writing by the upstream server. In this case Envoy will not see upstream responses and will
// keep client streams open, eventually maxing them out and causing client connection to be
// closed.
writev_matcher_->setSourcePort(fake_upstreams_[0]->localAddress()->ip()->port());
write_matcher_->setSourcePort(fake_upstreams_[0]->localAddress()->ip()->port());

// Exceed the number of streams allowed by the server. The server should stop reading from the
// client.
Expand Down Expand Up @@ -1446,9 +1446,9 @@ TEST_P(Http2FloodMitigationTest, RequestMetadata) {

// Make Envoy's writes into the upstream connection to return EAGAIN, preventing proxying of the
// METADATA frames
writev_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());
write_matcher_->setDestinationPort(fake_upstreams_[0]->localAddress()->ip()->port());

writev_matcher_->setWritevReturnsEgain();
write_matcher_->setWriteReturnsEgain();

// Send AllFrameFloodLimit + 1 number of METADATA frames from the downstream client to trigger the
// outbound upstream flood when they are proxied.
Expand Down
Loading