diff --git a/source/common/quic/client_connection_factory_impl.cc b/source/common/quic/client_connection_factory_impl.cc index b8c3c2bd9190..fcd8258c8b85 100644 --- a/source/common/quic/client_connection_factory_impl.cc +++ b/source/common/quic/client_connection_factory_impl.cc @@ -19,7 +19,6 @@ getContext(Network::TransportSocketFactory& transport_socket_factory) { auto* quic_socket_factory = dynamic_cast(&transport_socket_factory); ASSERT(quic_socket_factory != nullptr); - ASSERT(quic_socket_factory->sslCtx() != nullptr); return quic_socket_factory->sslCtx(); } diff --git a/source/common/quic/quic_filter_manager_connection_impl.h b/source/common/quic/quic_filter_manager_connection_impl.h index c33bc5959d7f..7922810e362c 100644 --- a/source/common/quic/quic_filter_manager_connection_impl.h +++ b/source/common/quic/quic_filter_manager_connection_impl.h @@ -77,7 +77,7 @@ class QuicFilterManagerConnectionImpl : public Network::ConnectionImplBase, absl::optional unixSocketPeerCredentials() const override { // Unix domain socket is not supported. - NOT_REACHED_GCOVR_EXCL_LINE; + return absl::nullopt; } void setConnectionStats(const Network::Connection::ConnectionStats& stats) override { // TODO(danzh): populate stats. @@ -113,6 +113,7 @@ class QuicFilterManagerConnectionImpl : public Network::ConnectionImplBase, const StreamInfo::StreamInfo& streamInfo() const override { return stream_info_; } absl::string_view transportFailureReason() const override { return transport_failure_reason_; } bool startSecureTransport() override { return false; } + // TODO(#2557) Implement this. absl::optional lastRoundTripTime() const override { return {}; } // Network::FilterManagerConnection diff --git a/source/common/quic/udp_gso_batch_writer.cc b/source/common/quic/udp_gso_batch_writer.cc index d54ceaf790a9..8f46df35f2ea 100644 --- a/source/common/quic/udp_gso_batch_writer.cc +++ b/source/common/quic/udp_gso_batch_writer.cc @@ -8,7 +8,7 @@ namespace Quic { namespace { Api::IoCallUint64Result convertQuicWriteResult(quic::WriteResult quic_result, size_t payload_len) { switch (quic_result.status) { - case quic::WRITE_STATUS_OK: { + case quic::WRITE_STATUS_OK: if (quic_result.bytes_written == 0) { ENVOY_LOG_MISC(trace, "sendmsg successful, message buffered to send"); } else { @@ -18,23 +18,20 @@ Api::IoCallUint64Result convertQuicWriteResult(quic::WriteResult quic_result, si return Api::IoCallUint64Result( /*rc=*/payload_len, /*err=*/Api::IoErrorPtr(nullptr, Network::IoSocketError::deleteIoError)); - } - case quic::WRITE_STATUS_BLOCKED_DATA_BUFFERED: { + case quic::WRITE_STATUS_BLOCKED_DATA_BUFFERED: // Data was buffered, Return payload_len as rc & nullptr as error ENVOY_LOG_MISC(trace, "sendmsg blocked, message buffered to send"); return Api::IoCallUint64Result( /*rc=*/payload_len, /*err=*/Api::IoErrorPtr(nullptr, Network::IoSocketError::deleteIoError)); - } - case quic::WRITE_STATUS_BLOCKED: { + case quic::WRITE_STATUS_BLOCKED: // Writer blocked, return error ENVOY_LOG_MISC(trace, "sendmsg blocked, message not buffered"); return Api::IoCallUint64Result( /*rc=*/0, /*err=*/Api::IoErrorPtr(Network::IoSocketError::getIoSocketEagainInstance(), Network::IoSocketError::deleteIoError)); - } - default: { + default: // Write Failed, return {0 and error_code} ENVOY_LOG_MISC(trace, "sendmsg failed with error code {}", static_cast(quic_result.error_code)); @@ -43,7 +40,6 @@ Api::IoCallUint64Result convertQuicWriteResult(quic::WriteResult quic_result, si /*err=*/Api::IoErrorPtr(new Network::IoSocketError(quic_result.error_code), Network::IoSocketError::deleteIoError)); } - } } } // namespace diff --git a/test/common/http/conn_pool_grid_test.cc b/test/common/http/conn_pool_grid_test.cc index 115009c37b56..e25551aaaf5d 100644 --- a/test/common/http/conn_pool_grid_test.cc +++ b/test/common/http/conn_pool_grid_test.cc @@ -610,6 +610,7 @@ TEST_F(ConnectivityGridTest, RealGrid) { Envoy::Ssl::ClientContextConfigPtr config(new NiceMock()); auto factory = std::make_unique(std::move(config)); factory->initialize(); + ASSERT_FALSE(factory->usesProxyProtocolOptions()); auto& matcher = static_cast(*cluster_->transport_socket_matcher_); EXPECT_CALL(matcher, resolve(_)) diff --git a/test/common/quic/BUILD b/test/common/quic/BUILD index f187dc762949..9f432b55c200 100644 --- a/test/common/quic/BUILD +++ b/test/common/quic/BUILD @@ -249,6 +249,29 @@ envoy_cc_test_library( ], ) +envoy_cc_test( + name = "client_connection_factory_impl_test", + srcs = ["client_connection_factory_impl_test.cc"], + tags = ["nofips"], + deps = [ + "//source/common/event:dispatcher_lib", + "//source/common/http/http3:conn_pool_lib", + "//source/common/network:utility_lib", + "//source/common/upstream:upstream_includes", + "//source/common/upstream:upstream_lib", + "//test/common/http:common_lib", + "//test/common/upstream:utility_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/network:network_mocks", + "//test/mocks/runtime:runtime_mocks", + "//test/mocks/server:transport_socket_factory_context_mocks", + "//test/mocks/upstream:cluster_info_mocks", + "//test/mocks/upstream:transport_socket_match_mocks", + "//test/test_common:test_runtime_lib", + ], +) + envoy_cc_test( name = "quic_io_handle_wrapper_test", srcs = ["quic_io_handle_wrapper_test.cc"], @@ -256,6 +279,7 @@ envoy_cc_test( deps = [ "//source/common/quic:quic_io_handle_wrapper_lib", "//test/mocks/api:api_mocks", + "//test/mocks/network:io_handle_mocks", "//test/mocks/network:network_mocks", "//test/test_common:threadsafe_singleton_injector_lib", ], diff --git a/test/common/quic/client_connection_factory_impl_test.cc b/test/common/quic/client_connection_factory_impl_test.cc new file mode 100644 index 000000000000..c919aa9165b0 --- /dev/null +++ b/test/common/quic/client_connection_factory_impl_test.cc @@ -0,0 +1,47 @@ +#include "common/quic/client_connection_factory_impl.h" +#include "common/quic/quic_transport_socket_factory.h" + +#include "test/common/upstream/utility.h" +#include "test/mocks/common.h" +#include "test/mocks/event/mocks.h" +#include "test/mocks/server/transport_socket_factory_context.h" +#include "test/mocks/ssl/mocks.h" +#include "test/mocks/upstream/cluster_info.h" +#include "test/mocks/upstream/host.h" +#include "test/test_common/simulated_time_system.h" + +namespace Envoy { +namespace Quic { + +class QuicNetworkConnectionTest : public Event::TestUsingSimulatedTime, public testing::Test { +protected: + NiceMock dispatcher_; + std::shared_ptr cluster_{new NiceMock()}; + Upstream::HostSharedPtr host_{new NiceMock}; + NiceMock random_; + Upstream::ClusterConnectivityState state_; + Network::Address::InstanceConstSharedPtr test_address_ = + Network::Utility::resolveUrl("tcp://127.0.0.1:3000"); + NiceMock context_; + Quic::QuicClientTransportSocketFactory factory_{ + std::unique_ptr(new NiceMock), + context_}; +}; + +TEST_F(QuicNetworkConnectionTest, BufferLimits) { + PersistentQuicInfoImpl info{dispatcher_, factory_, simTime(), test_address_}; + + std::unique_ptr client_connection = + createQuicNetworkConnection(info, dispatcher_, test_address_, test_address_); + EnvoyQuicClientSession* session = static_cast(client_connection.get()); + session->Initialize(); + client_connection->connect(); + EXPECT_TRUE(client_connection->connecting()); + ASSERT(session != nullptr); + EXPECT_EQ(absl::nullopt, session->unixSocketPeerCredentials()); + EXPECT_EQ(absl::nullopt, session->lastRoundTripTime()); + client_connection->close(Network::ConnectionCloseType::NoFlush); +} + +} // namespace Quic +} // namespace Envoy diff --git a/test/common/quic/quic_io_handle_wrapper_test.cc b/test/common/quic/quic_io_handle_wrapper_test.cc index d5ee4d081474..2ef58610f06f 100644 --- a/test/common/quic/quic_io_handle_wrapper_test.cc +++ b/test/common/quic/quic_io_handle_wrapper_test.cc @@ -7,12 +7,14 @@ #include "common/quic/quic_io_handle_wrapper.h" #include "test/mocks/api/mocks.h" +#include "test/mocks/network/io_handle.h" #include "test/mocks/network/mocks.h" #include "test/test_common/threadsafe_singleton_injector.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +using testing::ByMove; using testing::Return; namespace Envoy { @@ -119,5 +121,84 @@ TEST_F(QuicIoHandleWrapperTest, DelegateIoHandleCalls) { wrapper_->supportsMmsg(); } +TEST(QuicIoHandleWrapper, DelegateWithMocks) { + Network::MockIoHandle mock_io; + QuicIoHandleWrapper wrapper(mock_io); + Buffer::OwnedImpl buffer; + Event::MockDispatcher dispatcher; + Event::FileReadyCb cb; + Event::FileTriggerType trigger = Event::PlatformDefaultTriggerType; + + { + EXPECT_CALL(mock_io, fdDoNotUse()); + wrapper.fdDoNotUse(); + + EXPECT_CALL(mock_io, read(_, _)) + .WillOnce(testing::Return(ByMove(Api::ioCallUint64ResultNoError()))); + wrapper.read(buffer, 5); + + EXPECT_CALL(mock_io, write(_)).WillOnce(Return(ByMove(Api::ioCallUint64ResultNoError()))); + wrapper.write(buffer); + + EXPECT_CALL(mock_io, recv(_, _, _)).WillOnce(Return(ByMove(Api::ioCallUint64ResultNoError()))); + wrapper.recv(nullptr, 10, 0); + + EXPECT_CALL(mock_io, bind(_)).WillOnce(Return(Api::SysCallIntResult{0, 0})); + wrapper.bind(nullptr); + + EXPECT_CALL(mock_io, listen(_)).WillOnce(Return(Api::SysCallIntResult{0, 0})); + wrapper.listen(0); + + EXPECT_CALL(mock_io, accept(_, _)); + wrapper.accept(nullptr, nullptr); + + EXPECT_CALL(mock_io, connect(_)).WillOnce(Return(Api::SysCallIntResult{0, 0})); + wrapper.connect(nullptr); + + EXPECT_CALL(mock_io, setOption(_, _, _, _)).WillOnce(Return(Api::SysCallIntResult{0, 0})); + wrapper.setOption(0, 0, nullptr, 0); + + EXPECT_CALL(mock_io, ioctl(_, _, _, _, _, _)).WillOnce(Return(Api::SysCallIntResult{0, 0})); + wrapper.ioctl(0, nullptr, 0, nullptr, 0, nullptr); + + EXPECT_CALL(mock_io, setBlocking(_)).WillOnce(Return(Api::SysCallIntResult{0, 0})); + wrapper.setBlocking(false); + + EXPECT_CALL(mock_io, createFileEvent_(_, _, _, _)); + wrapper.initializeFileEvent(dispatcher, cb, trigger, 0); + + EXPECT_CALL(mock_io, duplicate); + wrapper.duplicate(); + + EXPECT_CALL(mock_io, activateFileEvents(_)); + wrapper.activateFileEvents(0); + + EXPECT_CALL(mock_io, enableFileEvents(_)); + wrapper.enableFileEvents(0); + + EXPECT_CALL(mock_io, resetFileEvents()); + wrapper.resetFileEvents(); + + EXPECT_CALL(mock_io, shutdown(_)); + wrapper.shutdown(0); + + EXPECT_CALL(mock_io, lastRoundTripTime()).Times(0); + wrapper.lastRoundTripTime(); + } + + wrapper.close(); + + { + EXPECT_CALL(mock_io, read(_, _)).Times(0); + wrapper.read(buffer, 5); + + EXPECT_CALL(mock_io, write(_)).Times(0); + wrapper.write(buffer); + + EXPECT_CALL(mock_io, recv(_, _, _)).Times(0); + ASSERT_DEBUG_DEATH(wrapper.recv(nullptr, 10, 0), "recv called after close"); + } +} + } // namespace Quic } // namespace Envoy