Repository: envoyproxy/envoy
File: test/common/network/transport_socket_options_impl_test.cc (C++)

Code before:
                        StreamInfo::StreamSharingMayImpactPooling::SharedWithUpstreamConnection);

  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  ASSERT_NE(nullptr, transport_socket_options);

  auto objects = transport_socket_options->downstreamSharedFilterStateObjects();
  EXPECT_EQ(1, objects.size());
  EXPECT_EQ(DownstreamNetworkNamespace::key(), objects.at(0).name_);

  // Verify we can retrieve the network namespace from the filter state object.
  const auto* network_namespace_state =
      dynamic_cast<const DownstreamNetworkNamespace*>(objects.at(0).data_.get());
  ASSERT_NE(nullptr, network_namespace_state);
  EXPECT_EQ(network_namespace_filepath, network_namespace_state->value());
}

TEST_F(TransportSocketOptionsImplTest, NetworkNamespaceDynamicObject) {
  setFilterStateObject(DownstreamNetworkNamespace::key(), "/var/run/netns/development");

  // When network namespace is set alone without shared flag, it won't create transport socket
  // options.
  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  EXPECT_EQ(nullptr, transport_socket_options);
}

TEST_F(TransportSocketOptionsImplTest, Http11ProxyInfoFromWellKnownKey) {
  setFilterStateObject(Http11ProxyInfoFilterState::key(), "www.example.com:443,127.0.0.1:15002");

  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  ASSERT_NE(nullptr, transport_socket_options);
  ASSERT_TRUE(transport_socket_options->http11ProxyInfo().has_value());
  EXPECT_EQ("www.example.com:443", transport_socket_options->http11ProxyInfo()->hostname);
  EXPECT_EQ("127.0.0.1:15002",
            transport_socket_options->http11ProxyInfo()->proxy_address->asStringView());
}

} // namespace
} // namespace Network
} // namespace Envoy


Review comment (suggestion):
The test only covers the happy path. Consider adding negative test cases:
- Invalid format (no comma, empty parts)
- Invalid proxy address (e.g., "example.com:443,not-an-ip")
- IPv6 proxy address format

Code after:
                        StreamInfo::StreamSharingMayImpactPooling::SharedWithUpstreamConnection);

  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  ASSERT_NE(nullptr, transport_socket_options);

  auto objects = transport_socket_options->downstreamSharedFilterStateObjects();
  EXPECT_EQ(1, objects.size());
  EXPECT_EQ(DownstreamNetworkNamespace::key(), objects.at(0).name_);

  // Verify we can retrieve the network namespace from the filter state object.
  const auto* network_namespace_state =
      dynamic_cast<const DownstreamNetworkNamespace*>(objects.at(0).data_.get());
  ASSERT_NE(nullptr, network_namespace_state);
  EXPECT_EQ(network_namespace_filepath, network_namespace_state->value());
}

TEST_F(TransportSocketOptionsImplTest, NetworkNamespaceDynamicObject) {
  setFilterStateObject(DownstreamNetworkNamespace::key(), "/var/run/netns/development");

  // When network namespace is set alone without shared flag, it won't create transport socket
  // options.
  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  EXPECT_EQ(nullptr, transport_socket_options);
}

TEST_F(TransportSocketOptionsImplTest, Http11ProxyInfoFromWellKnownKey) {
  setFilterStateObject(Http11ProxyInfoFilterState::key(), "www.example.com:443,127.0.0.1:15002");

  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  ASSERT_NE(nullptr, transport_socket_options);
  ASSERT_TRUE(transport_socket_options->http11ProxyInfo().has_value());
  EXPECT_EQ("www.example.com:443", transport_socket_options->http11ProxyInfo()->hostname);
  EXPECT_EQ("127.0.0.1:15002",
            transport_socket_options->http11ProxyInfo()->proxy_address->asStringView());
}

TEST_F(TransportSocketOptionsImplTest, Http11ProxyInfoIpv6ProxyAddressBracketed) {
  setFilterStateObject(Http11ProxyInfoFilterState::key(), "www.example.com:443,[::1]:15002");

  auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
  ASSERT_NE(nullptr, transport_socket_options);
  ASSERT_TRUE(transport_socket_options->http11ProxyInfo().has_value());
  EXPECT_EQ("www.example.com:443", transport_socket_options->http11ProxyInfo()->hostname);
  EXPECT_EQ(Address::IpVersion::v6,
            transport_socket_options->http11ProxyInfo()->proxy_address->ip()->version());
  EXPECT_EQ("::1",
            transport_socket_options->http11ProxyInfo()->proxy_address->ip()->addressAsString());
  EXPECT_EQ(15002, transport_socket_options->http11ProxyInfo()->proxy_address->ip()->port());
}

TEST_F(TransportSocketOptionsImplTest, Http11ProxyInfoInvalidEncodingsAreRejected) {