From c8d1d0182adc6a4f78156f35c356405806fbce6c Mon Sep 17 00:00:00 2001 From: Alyssa Wilk Date: Mon, 13 Aug 2018 11:54:18 -0400 Subject: [PATCH] test: moving redundant code in websocket_integration_test to utilities Signed-off-by: Alyssa Wilk --- .../integration/websocket_integration_test.cc | 313 +++++++----------- test/integration/websocket_integration_test.h | 33 +- 2 files changed, 156 insertions(+), 190 deletions(-) diff --git a/test/integration/websocket_integration_test.cc b/test/integration/websocket_integration_test.cc index a47c234804cd7..675faad05d03e 100644 --- a/test/integration/websocket_integration_test.cc +++ b/test/integration/websocket_integration_test.cc @@ -111,47 +111,62 @@ void WebsocketIntegrationTest::validateFinalUpstreamData(const std::string& rece EXPECT_EQ(expected_data, stripped_data); } -TEST_P(WebsocketIntegrationTest, WebSocketConnectionDownstreamDisconnect) { - config_helper_.addConfigModifier(setRouteUsingWebsocket(nullptr, old_style_websockets_)); - initialize(); +void WebsocketIntegrationTest::performWebSocketUpgrade(const std::string& upgrade_req_string, + const std::string& upgrade_resp_string) { + // Establish the initial connection. + tcp_client_ = makeTcpConnection(lookupPort("http")); - // WebSocket upgrade, send some data and disconnect downstream - IntegrationTcpClientPtr tcp_client; - FakeRawConnectionPtr fake_upstream_connection; - - tcp_client = makeTcpConnection(lookupPort("http")); - // Send websocket upgrade request - tcp_client->write(upgrade_req_str_); + // Send the websocket upgrade request. + tcp_client_->write(upgrade_req_string); if (old_style_websockets_) { test_server_->waitForCounterGe("tcp.websocket.downstream_cx_total", 1); } - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); + + // Verify the upgrade was received upstream. + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_tcp_upstream_connection_)); std::string data; - ASSERT_TRUE(fake_upstream_connection->waitForData(&headersRead, &data)); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData(&headersRead, &data)); validateInitialUpstreamData(data); - // Accept websocket upgrade request - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str_)); - tcp_client->waitForData("\r\n\r\n", false); - validateInitialDownstreamData(tcp_client->data(), downstreamRespStr()); + // Send the upgrade response + ASSERT_TRUE(fake_tcp_upstream_connection_->write(upgrade_resp_string)); - // Standard TCP proxy semantics post upgrade - tcp_client->write("hello"); + // Verify the upgrade response was received downstream. + tcp_client_->waitForData("\r\n\r\n", false); + validateInitialDownstreamData(tcp_client_->data(), downstreamRespStr()); +} +void WebsocketIntegrationTest::sendBidirectionalData() { + // Verify that the client can still send data upstream, and that upstream + // receives it. + tcp_client_->write("hello"); ASSERT_TRUE( - fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("hello"))); - ASSERT_TRUE(fake_upstream_connection->write("world")); - tcp_client->waitForData("world", false); - tcp_client->write("bye!"); + fake_tcp_upstream_connection_->waitForData(FakeRawConnection::waitForInexactMatch("hello"))); - // downstream disconnect - tcp_client->close(); + // Verify the upstream can send data to the client and that the client + // receives it. + ASSERT_TRUE(fake_tcp_upstream_connection_->write("world")); + tcp_client_->waitForData("world", false); +} + +TEST_P(WebsocketIntegrationTest, WebSocketConnectionDownstreamDisconnect) { + config_helper_.addConfigModifier(setRouteUsingWebsocket(nullptr, old_style_websockets_)); + initialize(); + + performWebSocketUpgrade(upgrade_req_str_, upgrade_resp_str_); + sendBidirectionalData(); + + // Send some final data from the client, and disconnect. + tcp_client_->write("bye!"); + tcp_client_->close(); + + // Verify the final data was received and that the connection is torn down. std::string final_data; - ASSERT_TRUE(fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("bye"), - &final_data)); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData( + FakeRawConnection::waitForInexactMatch("bye"), &final_data)); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); - validateFinalDownstreamData(tcp_client->data(), downstreamRespStr() + "world"); + validateFinalDownstreamData(tcp_client_->data(), downstreamRespStr() + "world"); if (old_style_websockets_) { return; @@ -172,37 +187,24 @@ TEST_P(WebsocketIntegrationTest, WebSocketConnectionUpstreamDisconnect) { config_helper_.addConfigModifier(setRouteUsingWebsocket(nullptr, old_style_websockets_)); initialize(); - // WebSocket upgrade, send some data and disconnect upstream - IntegrationTcpClientPtr tcp_client; - FakeRawConnectionPtr fake_upstream_connection; - tcp_client = makeTcpConnection(lookupPort("http")); - // Send websocket upgrade request - tcp_client->write(upgrade_req_str_); - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - std::string data; - ASSERT_TRUE(fake_upstream_connection->waitForData(&headersRead, &data)); - validateInitialUpstreamData(data); - - // Accept websocket upgrade request - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str_)); - tcp_client->waitForData("\r\n\r\n", false); - validateInitialDownstreamData(tcp_client->data(), downstreamRespStr()); + performWebSocketUpgrade(upgrade_req_str_, upgrade_resp_str_); // Standard TCP proxy semantics post upgrade - tcp_client->write("hello"); - + tcp_client_->write("hello"); ASSERT_TRUE( - fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("hello"))); + fake_tcp_upstream_connection_->waitForData(FakeRawConnection::waitForInexactMatch("hello"))); - ASSERT_TRUE(fake_upstream_connection->write("world")); - // upstream disconnect - ASSERT_TRUE(fake_upstream_connection->close()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); - tcp_client->waitForData("world", false); - tcp_client->waitForDisconnect(); - ASSERT(!fake_upstream_connection->connected()); + // Send data downstream and disconnect immediately. + ASSERT_TRUE(fake_tcp_upstream_connection_->write("world")); + ASSERT_TRUE(fake_tcp_upstream_connection_->close()); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); + + // Verify both the data and the disconnect went through. + tcp_client_->waitForData("world", false); + tcp_client_->waitForDisconnect(); + ASSERT(!fake_tcp_upstream_connection_->connected()); - validateFinalDownstreamData(tcp_client->data(), downstreamRespStr() + "world"); + validateFinalDownstreamData(tcp_client_->data(), downstreamRespStr() + "world"); } TEST_P(WebsocketIntegrationTest, EarlyData) { @@ -210,43 +212,38 @@ TEST_P(WebsocketIntegrationTest, EarlyData) { initialize(); // WebSocket upgrade with early data (HTTP body) - IntegrationTcpClientPtr tcp_client; - FakeRawConnectionPtr fake_upstream_connection; const std::string early_data_req_str = "hello"; const std::string early_data_resp_str = "world"; const std::string upgrade_req_str = - fmt::format("GET /websocket/test HTTP/1.1\r\nHost: host\r\nConnection: " - "keep-alive, Upgrade\r\nUpgrade: websocket\r\nContent-Length: {}\r\n\r\n", - early_data_req_str.length()); - tcp_client = makeTcpConnection(lookupPort("http")); + createUpgradeRequest("websocket", early_data_req_str.length()); + tcp_client_ = makeTcpConnection(lookupPort("http")); // Send early data alongside websocket upgrade request - tcp_client->write(upgrade_req_str + early_data_req_str); - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); + tcp_client_->write(upgrade_req_str + early_data_req_str); + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_tcp_upstream_connection_)); // Wait for both the upgrade, and the early data. std::string data; - ASSERT_TRUE(fake_upstream_connection->waitForData( + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData( FakeRawConnection::waitForInexactMatch(early_data_req_str.c_str()), &data)); // We expect to find the early data on the upstream side EXPECT_TRUE(StringUtil::endsWith(data, early_data_req_str)); // Accept websocket upgrade request - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str_)); + ASSERT_TRUE(fake_tcp_upstream_connection_->write(upgrade_resp_str_)); // Reply also with early data - ASSERT_TRUE(fake_upstream_connection->write(early_data_resp_str)); + ASSERT_TRUE(fake_tcp_upstream_connection_->write(early_data_resp_str)); // upstream disconnect - ASSERT_TRUE(fake_upstream_connection->close()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); - tcp_client->waitForData(early_data_resp_str, false); - tcp_client->waitForDisconnect(); + ASSERT_TRUE(fake_tcp_upstream_connection_->close()); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); + tcp_client_->waitForData(early_data_resp_str, false); + tcp_client_->waitForDisconnect(); - validateFinalDownstreamData(tcp_client->data(), downstreamRespStr() + "world"); + validateFinalDownstreamData(tcp_client_->data(), downstreamRespStr() + "world"); } TEST_P(WebsocketIntegrationTest, WebSocketConnectionIdleTimeout) { envoy::api::v2::route::RouteAction::WebSocketProxyConfig ws_config; ws_config.mutable_idle_timeout()->set_nanos( std::chrono::duration_cast(std::chrono::milliseconds(100)).count()); - *ws_config.mutable_stat_prefix() = "my-stat-prefix"; config_helper_.addConfigModifier(setRouteUsingWebsocket(&ws_config, old_style_websockets_)); if (!old_style_websockets_) { config_helper_.addConfigModifier( @@ -262,35 +259,16 @@ TEST_P(WebsocketIntegrationTest, WebSocketConnectionIdleTimeout) { initialize(); // WebSocket upgrade, send some data and disconnect downstream - IntegrationTcpClientPtr tcp_client; - FakeRawConnectionPtr fake_upstream_connection; - tcp_client = makeTcpConnection(lookupPort("http")); - // Send websocket upgrade request - // The request path gets rewritten from /websocket/test to /websocket. - // The size of headers received by the destination is 228 bytes. - tcp_client->write(upgrade_req_str_); - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - std::string data; - ASSERT_TRUE(fake_upstream_connection->waitForData(&headersRead, &data)); - validateInitialUpstreamData(data); - - // Accept websocket upgrade request - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str_)); - tcp_client->waitForData("\r\n\r\n", false); - validateInitialDownstreamData(tcp_client->data(), downstreamRespStr()); - // Standard TCP proxy semantics post upgrade - tcp_client->write("hello"); - tcp_client->write("hello"); - ASSERT_TRUE(fake_upstream_connection->write("world")); - tcp_client->waitForData("world", false); + performWebSocketUpgrade(upgrade_req_str_, upgrade_resp_str_); + sendBidirectionalData(); if (old_style_websockets_) { - test_server_->waitForCounterGe("tcp.my-stat-prefix.idle_timeout", 1); + test_server_->waitForCounterGe("tcp.websocket.idle_timeout", 1); } else { test_server_->waitForCounterGe("http.config_test.downstream_rq_idle_timeout", 1); } - tcp_client->waitForDisconnect(); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + tcp_client_->waitForDisconnect(); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); } TEST_P(WebsocketIntegrationTest, WebSocketLogging) { @@ -299,7 +277,6 @@ TEST_P(WebsocketIntegrationTest, WebSocketLogging) { envoy::api::v2::route::RouteAction::WebSocketProxyConfig ws_config; ws_config.mutable_idle_timeout()->set_nanos( std::chrono::duration_cast(std::chrono::milliseconds(100)).count()); - *ws_config.mutable_stat_prefix() = "my-stat-prefix"; config_helper_.addConfigModifier(setRouteUsingWebsocket(&ws_config, old_style_websockets_)); std::string expected_log_template = "bytes_sent={0} " @@ -333,33 +310,11 @@ TEST_P(WebsocketIntegrationTest, WebSocketLogging) { initialize(); - // WebSocket upgrade, send some data and disconnect downstream - IntegrationTcpClientPtr tcp_client; - FakeRawConnectionPtr fake_upstream_connection; + performWebSocketUpgrade(upgrade_req_str_, upgrade_resp_str_); + sendBidirectionalData(); - tcp_client = makeTcpConnection(lookupPort("http")); - // Send websocket upgrade request - // The request path gets rewritten from /websocket/test to /websocket. - // The size of headers received by the destination is 228 bytes. - tcp_client->write(upgrade_req_str_); - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - std::string data; - ASSERT_TRUE(fake_upstream_connection->waitForData(228, &data)); - // Accept websocket upgrade request - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str_)); - tcp_client->waitForData(upgrade_resp_str_); - // Standard TCP proxy semantics post upgrade - tcp_client->write("hello"); - // datalen = 228 + strlen(hello) - ASSERT_TRUE(fake_upstream_connection->waitForData(233)); - ASSERT_TRUE(fake_upstream_connection->write("world")); - tcp_client->waitForData(upgrade_resp_str_ + "world"); - - ASSERT_TRUE(fake_upstream_connection->close()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); - - tcp_client->waitForDisconnect(); - tcp_client->close(); + tcp_client_->close(); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); std::string log_result; do { @@ -392,54 +347,45 @@ TEST_P(WebsocketIntegrationTest, NonWebsocketUpgrade) { config_helper_.addConfigModifier(setRouteUsingWebsocket(nullptr, old_style_websockets_)); initialize(); - const std::string upgrade_req_str = "GET / HTTP/1.1\r\nHost: host\r\nConnection: " - "keep-alive, Upgrade\r\nUpgrade: foo\r\n\r\n"; - const std::string upgrade_resp_str = - "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: foo\r\n\r\n"; + const std::string upgrade_req_str = createUpgradeRequest("foo"); + const std::string upgrade_resp_str = createUpgradeResponse("foo"); // Upgrade, send some data and disconnect downstream - IntegrationTcpClientPtr tcp_client; - FakeRawConnectionPtr fake_upstream_connection; - tcp_client = makeTcpConnection(lookupPort("http")); + tcp_client_ = makeTcpConnection(lookupPort("http")); // Send websocket upgrade request // The size of headers received by the destination is 228 bytes. - tcp_client->write(upgrade_req_str); + tcp_client_->write(upgrade_req_str); if (old_style_websockets_) { test_server_->waitForCounterGe("tcp.websocket.downstream_cx_total", 1); } - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_tcp_upstream_connection_)); std::string data; - ASSERT_TRUE(fake_upstream_connection->waitForData(&headersRead, &data)); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData(&headersRead, &data)); validateInitialUpstreamData(data); // Accept websocket upgrade request - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str)); - tcp_client->waitForData("\r\n\r\n", false); + ASSERT_TRUE(fake_tcp_upstream_connection_->write(upgrade_resp_str)); + tcp_client_->waitForData("\r\n\r\n", false); if (old_style_websockets_) { - ASSERT_EQ(tcp_client->data(), upgrade_resp_str); + ASSERT_EQ(tcp_client_->data(), upgrade_resp_str); } - // Standard TCP proxy semantics post upgrade - tcp_client->write("hello"); - ASSERT_TRUE( - fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("hello"))); - ASSERT_TRUE(fake_upstream_connection->write("world")); - tcp_client->waitForData("world", false); - tcp_client->write("bye!"); + sendBidirectionalData(); // downstream disconnect - tcp_client->close(); + tcp_client_->write("bye!"); + tcp_client_->close(); std::string final_data; - ASSERT_TRUE(fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("bye"), - &final_data)); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData( + FakeRawConnection::waitForInexactMatch("bye"), &final_data)); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); const std::string modified_upgrade_resp_str = "HTTP/1.1 101 Switching Protocols\r\nconnection: " "Upgrade\r\nupgrade: foo\r\ncontent-length: " "0\r\n\r\n"; - validateFinalDownstreamData(tcp_client->data(), modified_upgrade_resp_str + "world"); - const std::string upstream_payload = "GET / HTTP/1.1\r\n" + validateFinalDownstreamData(tcp_client_->data(), modified_upgrade_resp_str + "world"); + const std::string upstream_payload = "GET /websocket/test HTTP/1.1\r\n" "host: host\r\n" "connection: keep-alive, Upgrade\r\n" "upgrade: foo\r\n" @@ -480,14 +426,12 @@ TEST_P(WebsocketIntegrationTest, WebsocketCustomFilterChain) { const std::string early_data_req_str(2048, 'a'); { const std::string upgrade_req_str = - fmt::format("GET /websocket/test HTTP/1.1\r\nHost: host\r\nConnection: " - "keep-alive, Upgrade\r\nUpgrade: websocket\r\nContent-Length: {}\r\n\r\n", - early_data_req_str.length()); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("http")); - tcp_client->write(upgrade_req_str + early_data_req_str); - tcp_client->waitForData("\r\n\r\n", false); - EXPECT_NE(tcp_client->data().find("413"), std::string::npos); - tcp_client->waitForDisconnect(true); + createUpgradeRequest("websocket", early_data_req_str.length()); + IntegrationTcpClientPtr tcp_client_ = makeTcpConnection(lookupPort("http")); + tcp_client_->write(upgrade_req_str + early_data_req_str); + tcp_client_->waitForData("\r\n\r\n", false); + EXPECT_NE(tcp_client_->data().find("413"), std::string::npos); + tcp_client_->waitForDisconnect(true); } // HTTP requests are configured to disallow large bodies. @@ -495,30 +439,27 @@ TEST_P(WebsocketIntegrationTest, WebsocketCustomFilterChain) { const std::string upgrade_req_str = fmt::format("GET / HTTP/1.1\r\nHost: host\r\nConnection: " "keep-alive\r\nContent-Length: {}\r\n\r\n", early_data_req_str.length()); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("http")); - tcp_client->write(upgrade_req_str + early_data_req_str); - tcp_client->waitForData("\r\n\r\n", false); - EXPECT_NE(tcp_client->data().find("413"), std::string::npos); - tcp_client->waitForDisconnect(true); + IntegrationTcpClientPtr tcp_client_ = makeTcpConnection(lookupPort("http")); + tcp_client_->write(upgrade_req_str + early_data_req_str); + tcp_client_->waitForData("\r\n\r\n", false); + EXPECT_NE(tcp_client_->data().find("413"), std::string::npos); + tcp_client_->waitForDisconnect(true); } // Foo upgrades are configured without the buffer filter, so should explicitly // allow large payload. { - const std::string upgrade_req_str = - fmt::format("GET /websocket/test HTTP/1.1\r\nHost: host\r\nConnection: " - "keep-alive, Upgrade\r\nUpgrade: foo\r\nContent-Length: {}\r\n\r\n", - early_data_req_str.length()); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("http")); - tcp_client->write(upgrade_req_str + early_data_req_str); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); + const std::string upgrade_req_str = createUpgradeRequest("foo", early_data_req_str.length()); + IntegrationTcpClientPtr tcp_client_ = makeTcpConnection(lookupPort("http")); + tcp_client_->write(upgrade_req_str + early_data_req_str); + FakeRawConnectionPtr fake_tcp_upstream_connection_; + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_tcp_upstream_connection_)); // Make sure the full payload arrives. - ASSERT_TRUE(fake_upstream_connection->waitForData( + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData( FakeRawConnection::waitForInexactMatch(early_data_req_str.c_str()))); // Tear down all the connections cleanly. - tcp_client->close(); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + tcp_client_->close(); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); } } @@ -532,11 +473,11 @@ TEST_P(WebsocketIntegrationTest, BidirectionalChunkedData) { "SomeWebSocketPayload"; // Upgrade, send initial data and wait for it to be received. - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("http")); - tcp_client->write(upgrade_req_str); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - ASSERT_TRUE(fake_upstream_connection->waitForData( + IntegrationTcpClientPtr tcp_client_ = makeTcpConnection(lookupPort("http")); + tcp_client_->write(upgrade_req_str); + FakeRawConnectionPtr fake_tcp_upstream_connection_; + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_tcp_upstream_connection_)); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData( FakeRawConnection::waitForInexactMatch("SomeWebSocketPayload"))); // Finish the upgrade. @@ -545,20 +486,20 @@ TEST_P(WebsocketIntegrationTest, BidirectionalChunkedData) { "transfer-encoding: chunked\r\n\r\n" "4\r\nabcd\r\n0\r\n\r\n" "SomeWebsocketResponsePayload"; - ASSERT_TRUE(fake_upstream_connection->write(upgrade_resp_str)); - tcp_client->waitForData("SomeWebsocketResponsePayload", false); + ASSERT_TRUE(fake_tcp_upstream_connection_->write(upgrade_resp_str)); + tcp_client_->waitForData("SomeWebsocketResponsePayload", false); // Verify bidirectional data still works. - tcp_client->write("FinalClientPayload"); + tcp_client_->write("FinalClientPayload"); std::string final_data; - ASSERT_TRUE(fake_upstream_connection->waitForData( + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForData( FakeRawConnection::waitForInexactMatch("FinalClientPayload"), &final_data)); - ASSERT_TRUE(fake_upstream_connection->write("FinalServerPayload")); - tcp_client->waitForData("FinalServerPayload", false); + ASSERT_TRUE(fake_tcp_upstream_connection_->write("FinalServerPayload")); + tcp_client_->waitForData("FinalServerPayload", false); // Clean up. - tcp_client->close(); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + tcp_client_->close(); + ASSERT_TRUE(fake_tcp_upstream_connection_->waitForDisconnect()); const std::string modified_upstream_payload = "GET /websocket/test HTTP/1.1\r\n" @@ -586,7 +527,7 @@ TEST_P(WebsocketIntegrationTest, BidirectionalChunkedData) { "transfer-encoding: chunked\r\n\r\n" "4\r\nabcd\r\n0\r\n\r\n" "SomeWebsocketResponsePayloadFinalServerPayload"; - validateFinalDownstreamData(tcp_client->data(), modified_downstream_payload); + validateFinalDownstreamData(tcp_client_->data(), modified_downstream_payload); } } // namespace Envoy diff --git a/test/integration/websocket_integration_test.h b/test/integration/websocket_integration_test.h index 3dd7a34b5039d..a728a7c87caec 100644 --- a/test/integration/websocket_integration_test.h +++ b/test/integration/websocket_integration_test.h @@ -14,8 +14,16 @@ class WebsocketIntegrationTest WebsocketIntegrationTest() : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, std::get<0>(GetParam())) {} bool old_style_websockets_{std::get<1>(GetParam())}; + void TearDown() override { + fake_tcp_upstream_connection_.reset(); + tcp_client_.reset(); + } protected: + void performWebSocketUpgrade(const std::string& upgrade_req_string, + const std::string& upgrade_resp_string); + void sendBidirectionalData(); + void validateInitialUpstreamData(const std::string& received_data); void validateInitialDownstreamData(const std::string& received_data, const std::string& expected_data); @@ -28,14 +36,31 @@ class WebsocketIntegrationTest return old_style_websockets_ ? upgrade_resp_str_ : modified_upgrade_resp_str_; } - const std::string upgrade_req_str_ = "GET /websocket/test HTTP/1.1\r\nHost: host\r\nConnection: " - "keep-alive, Upgrade\r\nUpgrade: websocket\r\n\r\n"; - const std::string upgrade_resp_str_ = - "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n"; + static std::string createUpgradeRequest(absl::string_view upgrade_type, + absl::optional content_length = absl::nullopt) { + std::string content_length_string = + content_length.has_value() ? fmt::format("Content-Length: {}\r\n", content_length.value()) + : ""; + return fmt::format("GET /websocket/test HTTP/1.1\r\nHost: host\r\nConnection: " + "keep-alive, Upgrade\r\nUpgrade: {}\r\n{}\r\n", + upgrade_type, content_length_string); + } + + static std::string createUpgradeResponse(absl::string_view upgrade_type) { + return fmt::format( + "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: {}\r\n\r\n", + upgrade_type); + } + + const std::string upgrade_req_str_ = createUpgradeRequest("websocket"); + const std::string upgrade_resp_str_ = createUpgradeResponse("websocket"); const std::string modified_upgrade_resp_str_ = "HTTP/1.1 101 Switching Protocols\r\nconnection: " "Upgrade\r\nupgrade: websocket\r\ncontent-length: " "0\r\n\r\n"; + + FakeRawConnectionPtr fake_tcp_upstream_connection_; + IntegrationTcpClientPtr tcp_client_; }; } // namespace Envoy