Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config switch to turn on/off Quic processing #9679

Merged
merged 67 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
b526e9f
[WIP] Config switch to turn on/off Quic/Udp processing
Jan 14, 2020
fbbef39
apply review comments
Jan 31, 2020
6a8a161
Merge remote-tracking branch 'origin/master'
Jan 31, 2020
1377cd5
use runtime flag instead
Feb 3, 2020
ed1a399
more wip
Feb 3, 2020
98148f1
more wip
Feb 4, 2020
43905d8
more wip
Feb 4, 2020
b64e40b
remove dummy changes
Feb 4, 2020
6d3eaf8
fix default
Feb 4, 2020
4c0c2fa
more wip
Feb 5, 2020
f9cdb78
more tests
Feb 11, 2020
3e47943
Merge remote-tracking branch 'origin/master'
Mar 5, 2020
9502c3e
fix format
Mar 5, 2020
6940388
clean up
Mar 5, 2020
2f8e4de
Fix test
Mar 5, 2020
ccf4bb1
fix test
Mar 6, 2020
68c8702
Merge remote-tracking branch 'origin/master'
Mar 9, 2020
cef470d
apply review comments
Mar 18, 2020
80556e1
apply review comments
Mar 18, 2020
d77c6a1
remove unused var
Mar 18, 2020
132cce0
remove unused var
Mar 18, 2020
e3ac7b0
remove invalid test
Mar 19, 2020
0091d58
Check if flag is enabled by default
Mar 20, 2020
fd9adb0
Remove temp check
Mar 20, 2020
d70fb7d
apply review comments
Mar 30, 2020
ed64f3a
make clang happy, not creating temp copy
Apr 3, 2020
d914ed0
Not call virtual func from desctructor
Apr 3, 2020
dd5b6ed
fix naming for clang_tidy
Apr 3, 2020
3b595da
Merge remote-tracking branch 'origin/master'
Apr 6, 2020
60b7034
fix api shadow
Apr 6, 2020
d27bc45
fix namings in test
Apr 6, 2020
e98f673
apply review comments
Apr 13, 2020
97691af
Merge remote-tracking branch 'origin/master'
Apr 13, 2020
019dc49
remove changes for v2
Apr 13, 2020
740d3d2
remove changes to v2
Apr 13, 2020
1b7a7f5
fix format
Apr 13, 2020
9ae7c42
align shadow api
Apr 14, 2020
b25447e
remove unused var
Apr 14, 2020
7be1fd4
fix merge conflict
Apr 15, 2020
f6960de
Merge remote-tracking branch 'origin/master'
Apr 15, 2020
471a56f
Remove test that does not make sense
Apr 17, 2020
5f1e4ad
Merge remote-tracking branch 'origin/master'
Apr 17, 2020
598082c
correct merge issue
Apr 17, 2020
1828540
cleanup
Apr 20, 2020
5e0fc6c
cleanup
Apr 20, 2020
b865e60
Use real loader in tests
Apr 25, 2020
2a0e388
cleanup
Apr 30, 2020
0bd459c
fix spelling
Apr 30, 2020
ae894d9
Apply review comments
May 4, 2020
8c1a26a
clean up
May 6, 2020
76bdeed
Clean up
May 6, 2020
c52961e
ammend formatting of new lines
May 6, 2020
af9a8aa
fix format
May 6, 2020
6c8176e
Merge remote-tracking branch 'origin/master'
May 6, 2020
8ab8576
fix proto v4
May 6, 2020
e4393dd
fix v4 protos
May 6, 2020
de45a8d
fix api change
May 7, 2020
bb53249
fix clang
May 7, 2020
198c267
fix v4 protos
May 7, 2020
8ad4ae6
fix generated api shadow
May 7, 2020
99d1e92
fix proto again
May 7, 2020
a328c6b
more clang tidy
May 7, 2020
5c76b99
Merge remote-tracking branch 'origin/master'
May 8, 2020
e055f8a
apply review comments
May 14, 2020
0737550
nits in test
May 14, 2020
a507b8b
dummy to retrigger ci
May 15, 2020
6ce2379
remove unused import
May 15, 2020
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
8 changes: 7 additions & 1 deletion api/envoy/config/listener/v3/quic_config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ syntax = "proto3";

package envoy.config.listener.v3;

import "envoy/config/core/v3/base.proto";

import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";

Expand All @@ -16,7 +18,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: QUIC listener Config]

// Configuration specific to the QUIC protocol.
// Next id: 4
// Next id: 5
message QuicProtocolOptions {
option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.listener.QuicProtocolOptions";
Expand All @@ -32,4 +34,8 @@ message QuicProtocolOptions {
// Connection timeout in milliseconds before the crypto handshake is finished.
// 20000ms if not specified.
google.protobuf.Duration crypto_handshake_timeout = 3;

// Runtime flag that controls whether the listener is enabled or not. If not specified, defaults
// to enabled.
core.v3.RuntimeFeatureFlag enabled = 4;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions source/extensions/quic_listeners/quiche/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ envoy_cc_library(
"//include/envoy/network:listener_interface",
"//source/common/network:listener_lib",
"//source/common/protobuf:utility_lib",
"//source/common/runtime:runtime_lib",
"//source/server:connection_handler_lib",
"@envoy_api//envoy/config/listener/v3:pkg_cc_proto",
],
Expand Down
18 changes: 12 additions & 6 deletions source/extensions/quic_listeners/quiche/active_quic_listener.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@ ActiveQuicListener::ActiveQuicListener(Event::Dispatcher& dispatcher,
Network::ConnectionHandler& parent,
Network::ListenerConfig& listener_config,
const quic::QuicConfig& quic_config,
Network::Socket::OptionsSharedPtr options)
Network::Socket::OptionsSharedPtr options,
const envoy::config::core::v3::RuntimeFeatureFlag enabled)
: ActiveQuicListener(dispatcher, parent,
listener_config.listenSocketFactory().getListenSocket(), listener_config,
quic_config, std::move(options)) {}
quic_config, std::move(options), enabled) {}

ActiveQuicListener::ActiveQuicListener(Event::Dispatcher& dispatcher,
Network::ConnectionHandler& parent,
Network::SocketSharedPtr listen_socket,
Network::ListenerConfig& listener_config,
const quic::QuicConfig& quic_config,
Network::Socket::OptionsSharedPtr options)
Network::Socket::OptionsSharedPtr options,
const envoy::config::core::v3::RuntimeFeatureFlag enabled)
: Server::ConnectionHandlerImpl::ActiveListenerImplBase(parent, &listener_config),
dispatcher_(dispatcher), version_manager_(quic::CurrentSupportedVersions()),
listen_socket_(*listen_socket) {
listen_socket_(*listen_socket), enabled_(enabled, Runtime::LoaderSingleton::get()) {
if (options != nullptr) {
const bool ok = Network::Socket::applyOptions(
options, listen_socket_, envoy::config::core::v3::SocketOption::STATE_BOUND);
Expand Down Expand Up @@ -93,6 +95,10 @@ void ActiveQuicListener::onData(Network::UdpRecvData& data) {
}

void ActiveQuicListener::onReadReady() {
if (!enabled()) {
ENVOY_LOG(trace, "Quic listener {}: runtime disabled", config_->name());
return;
}
quic_dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerLoop);
}

Expand All @@ -112,7 +118,7 @@ void ActiveQuicListener::shutdownListener() {

ActiveQuicListenerFactory::ActiveQuicListenerFactory(
const envoy::config::listener::v3::QuicProtocolOptions& config, uint32_t concurrency)
: concurrency_(concurrency) {
: concurrency_(concurrency), enabled_(config.enabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if config.has_enabled() == false?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just verified the implementation, has_enabled() checks if field is not (either nullptr or is set to default value), but enabled instead always provides value to the caller:

inline const ::envoy::config::core::v3::RuntimeFeatureFlag& QuicProtocolOptions::_internal_enabled() const {
  const ::envoy::config::core::v3::RuntimeFeatureFlag* p = enabled_;
  return p != nullptr ? *p : *reinterpret_cast<const ::envoy::config::core::v3::RuntimeFeatureFlag*>(
      &::envoy::config::core::v3::_RuntimeFeatureFlag_default_instance_);
}

If config is empty, enabled field is set to default instance.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this!

uint64_t idle_network_timeout_ms =
config.has_idle_timeout() ? DurationUtil::durationToMilliseconds(config.idle_timeout())
: 300000;
Expand Down Expand Up @@ -192,7 +198,7 @@ ActiveQuicListenerFactory::createActiveUdpListener(Network::ConnectionHandler& p
}
#endif
return std::make_unique<ActiveQuicListener>(disptacher, parent, config, quic_config_,
std::move(options));
std::move(options), enabled_);
}

} // namespace Quic
Expand Down
12 changes: 10 additions & 2 deletions source/extensions/quic_listeners/quiche/active_quic_listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#include "envoy/config/listener/v3/quic_config.pb.h"
#include "envoy/network/connection_handler.h"
#include "envoy/network/listener.h"
#include "envoy/runtime/runtime.h"

#include "common/network/socket_option_impl.h"
#include "common/protobuf/utility.h"
#include "common/runtime/runtime_protos.h"

#include "server/connection_handler_impl.h"

Expand All @@ -25,12 +27,14 @@ class ActiveQuicListener : public Network::UdpListenerCallbacks,

ActiveQuicListener(Event::Dispatcher& dispatcher, Network::ConnectionHandler& parent,
Network::ListenerConfig& listener_config, const quic::QuicConfig& quic_config,
Network::Socket::OptionsSharedPtr options);
Network::Socket::OptionsSharedPtr options,
const envoy::config::core::v3::RuntimeFeatureFlag enabled);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: pass by const ref here and below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


ActiveQuicListener(Event::Dispatcher& dispatcher, Network::ConnectionHandler& parent,
Network::SocketSharedPtr listen_socket,
Network::ListenerConfig& listener_config, const quic::QuicConfig& quic_config,
Network::Socket::OptionsSharedPtr options);
Network::Socket::OptionsSharedPtr options,
const envoy::config::core::v3::RuntimeFeatureFlag enabled);

~ActiveQuicListener() override;

Expand All @@ -50,6 +54,8 @@ class ActiveQuicListener : public Network::UdpListenerCallbacks,
void resumeListening() override;
void shutdownListener() override;

bool enabled() { return enabled_.enabled(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't strongly feel this interface is needed. Can you inline it at call site? If it's only used in test, accessing via a peer class is better.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danzh2010 alright, just looked up that method in other envoy modules and followed by example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the only definition of quic listener being enabled. I would prefer not to add this interface.


private:
friend class ActiveQuicListenerPeer;

Expand All @@ -60,6 +66,7 @@ class ActiveQuicListener : public Network::UdpListenerCallbacks,
quic::QuicVersionManager version_manager_;
std::unique_ptr<EnvoyQuicDispatcher> quic_dispatcher_;
Network::Socket& listen_socket_;
Runtime::FeatureFlag enabled_;
};

using ActiveQuicListenerPtr = std::unique_ptr<ActiveQuicListener>;
Expand All @@ -83,6 +90,7 @@ class ActiveQuicListenerFactory : public Network::ActiveUdpListenerFactory,
quic::QuicConfig quic_config_;
const uint32_t concurrency_;
absl::once_flag install_bpf_once_;
envoy::config::core::v3::RuntimeFeatureFlag enabled_;
};

} // namespace Quic
Expand Down
1 change: 1 addition & 0 deletions test/extensions/quic_listeners/quiche/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ envoy_cc_test(
"//test/test_common:environment_lib",
"//test/test_common:network_utility_lib",
"//test/test_common:simulated_time_system_lib",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class ActiveQuicListenerFactoryPeer {
static quic::QuicConfig& quicConfig(ActiveQuicListenerFactory& factory) {
return factory.quic_config_;
}
static envoy::config::core::v3::RuntimeFeatureFlag&
runtimeEnabled(ActiveQuicListenerFactory& factory) {
return factory.enabled_;
}
};

TEST(ActiveQuicListenerConfigTest, CreateActiveQuicListenerFactory) {
Expand All @@ -29,6 +33,9 @@ TEST(ActiveQuicListenerConfigTest, CreateActiveQuicListenerFactory) {
idle_timeout: {
seconds: 2
}
enabled:
default_value: true
runtime_key: foo_key
nezdolik marked this conversation as resolved.
Show resolved Hide resolved
)EOF";
TestUtility::loadFromYaml(yaml, *config);
Network::ActiveUdpListenerFactoryPtr listener_factory =
Expand All @@ -41,6 +48,35 @@ TEST(ActiveQuicListenerConfigTest, CreateActiveQuicListenerFactory) {
EXPECT_EQ(2000u, quic_config.IdleNetworkTimeout().ToMilliseconds());
// Default value if not present in config.
EXPECT_EQ(20000u, quic_config.max_time_before_crypto_handshake().ToMilliseconds());
envoy::config::core::v3::RuntimeFeatureFlag& runtime_enabled =
ActiveQuicListenerFactoryPeer::runtimeEnabled(
dynamic_cast<ActiveQuicListenerFactory&>(*listener_factory));
EXPECT_EQ(true, runtime_enabled.default_value().value());
EXPECT_EQ("foo_key", runtime_enabled.runtime_key());
}

TEST(ActiveQuicListenerConfigTest, QuicListenerFlagNotConfigured) {
nezdolik marked this conversation as resolved.
Show resolved Hide resolved
std::string listener_name = QuicListenerName;
auto& config_factory =
Config::Utility::getAndCheckFactoryByName<Server::ActiveUdpListenerConfigFactory>(
listener_name);
ProtobufTypes::MessagePtr config = config_factory.createEmptyConfigProto();

std::string yaml = R"EOF(
max_concurrent_streams: 10
idle_timeout: {
seconds: 2
}
)EOF";
TestUtility::loadFromYaml(yaml, *config);
nezdolik marked this conversation as resolved.
Show resolved Hide resolved
Network::ActiveUdpListenerFactoryPtr listener_factory =
config_factory.createActiveUdpListenerFactory(*config, /*concurrency=*/1);
EXPECT_NE(nullptr, listener_factory);
envoy::config::core::v3::RuntimeFeatureFlag& runtime_enabled =
ActiveQuicListenerFactoryPeer::runtimeEnabled(
dynamic_cast<ActiveQuicListenerFactory&>(*listener_factory));
EXPECT_EQ(false, runtime_enabled.default_value().value());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check runtime_enabled.has_default_value() here instead? If it's false, we know that FeatureFlags will be instantiated with default value true.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

EXPECT_EQ("", runtime_enabled.runtime_key());
}

} // namespace Quic
Expand Down
69 changes: 54 additions & 15 deletions test/extensions/quic_listeners/quiche/active_quic_listener_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

#include <memory>

#include "envoy/config/core/v3/base.pb.h"
#include "envoy/config/core/v3/base.pb.validate.h"

#include "quiche/quic/core/crypto/crypto_protocol.h"
#include "quiche/quic/test_tools/crypto_test_utils.h"
#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
Expand All @@ -23,6 +26,7 @@
#include "test/test_common/simulated_time_system.h"
#include "test/test_common/environment.h"
#include "test/mocks/network/mocks.h"
#include "test/mocks/runtime/mocks.h"
#include "test/test_common/utility.h"
#include "test/test_common/network_utility.h"
#include "absl/time/time.h"
Expand Down Expand Up @@ -57,19 +61,28 @@ class ActiveQuicListenerTest : public testing::TestWithParam<Network::Address::I
: version_(GetParam()), api_(Api::createApiForTest(simulated_time_system_)),
dispatcher_(api_->allocateDispatcher("test_thread")), clock_(*dispatcher_),
local_address_(Network::Test::getCanonicalLoopbackAddress(version_)),
connection_handler_(*dispatcher_) {}
connection_handler_(*dispatcher_) {
Runtime::LoaderSingleton::initialize(&runtime_);
}

void SetUp() override {
listen_socket_ =
std::make_shared<Network::UdpListenSocket>(local_address_, nullptr, /*bind*/ true);
listen_socket_->addOptions(Network::SocketOptionFactory::buildIpPacketInfoOptions());
listen_socket_->addOptions(Network::SocketOptionFactory::buildRxQueueOverFlowOptions());

quic_listener_ = std::make_unique<ActiveQuicListener>(
*dispatcher_, connection_handler_, listen_socket_, listener_config_, quic_config_, nullptr);
quic_listener_ = std::make_unique<ActiveQuicListener>(*dispatcher_, connection_handler_,
listen_socket_, listener_config_,
quic_config_, nullptr, enabledFlag());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overriding enabledFlag() is a bit indirect. Can you add two methods like below:

std::make_unique<ActiveQuicListener> createQuicListenerFactory(const std::string& yaml) {
std::string listener_name = QuicListenerName;
    auto& config_factory =
        Config::Utility::getAndCheckFactoryByName<Server::ActiveUdpListenerConfigFactory>(
            listener_name);
    ProtobufTypes::MessagePtr config = config_factory.createEmptyConfigProto();
    TestUtility::loadFromYaml(yaml, *config);
    return config_factory.createActiveUdpListenerFactory(*config, /*concurrency=*/1);

virtual std::string yamlForQuicConfig() {
  return  R"EOF(
runtime_key: "quic.enabled"
default_value: true
)EOF";
}

And use them here:

EXPECT_CALL(listener_config_, listenSocketFactory());
EXPECT_CALL(listener_config_. socket_factory_, getListenSocket).WillOnce(Return(listen_socket_));
quic_listener_ = createQuicListenerFactory(yamlForQuicConfig())->createActiveUdpListener(*dispatcher_, connection_handler_, ...);

In ActiveQuicListenerEmptyFlagConfigTest,

std::string yamlForQuicConfig() override {
 return R"EOF(
    max_concurrent_streams: 10
  )EOF";
}

quic_dispatcher_ = ActiveQuicListenerPeer::quic_dispatcher(*quic_listener_);
simulated_time_system_.advanceTimeWait(std::chrono::milliseconds(100));
}

void configureQuicRuntimeFlag(bool runtime_enabled) {
EXPECT_CALL(runtime_.snapshot_, getBoolean("quic.enabled", true))
.WillRepeatedly(Return(runtime_enabled));
}

void configureMocks(int connection_count) {
EXPECT_CALL(listener_config_, filterChainManager())
.Times(connection_count)
Expand Down Expand Up @@ -116,7 +129,7 @@ class ActiveQuicListenerTest : public testing::TestWithParam<Network::Address::I

// TODO(bencebeky): Factor out parts common with
// EnvoyQuicDispatcherTest::createFullChloPacket() to test_utils.
void SendFullCHLO(quic::QuicConnectionId connection_id) {
void sendFullCHLO(quic::QuicConnectionId connection_id) {
client_sockets_.push_back(std::make_unique<Socket>(local_address_, nullptr, /*bind*/ false));
quic::CryptoHandshakeMessage chlo = quic::test::crypto_test_utils::GenerateDefaultInchoateCHLO(
&clock_, quic::AllSupportedVersions()[0].transport_version,
Expand Down Expand Up @@ -185,6 +198,18 @@ class ActiveQuicListenerTest : public testing::TestWithParam<Network::Address::I
quic_listener_->onListenerShutdown();
// Trigger alarm to fire before listener destruction.
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);
Runtime::LoaderSingleton::clear();
}

protected:
envoy::config::core::v3::RuntimeFeatureFlag enabledFlag() const {
envoy::config::core::v3::RuntimeFeatureFlag enabled_proto;
std::string yaml(R"EOF(
runtime_key: "quic.enabled"
default_value: true
)EOF");
TestUtility::loadFromYamlAndValidate(yaml, enabled_proto);
return enabled_proto;
}

Network::Address::IpVersion version_;
Expand All @@ -201,6 +226,8 @@ class ActiveQuicListenerTest : public testing::TestWithParam<Network::Address::I
quic::QuicConfig quic_config_;
Server::ConnectionHandlerImpl connection_handler_;
std::unique_ptr<ActiveQuicListener> quic_listener_;
EnvoyQuicDispatcher* quic_dispatcher_;
NiceMock<Runtime::MockLoader> runtime_;

std::list<std::unique_ptr<Socket>> client_sockets_;
std::list<std::shared_ptr<Network::MockReadFilter>> read_filters_;
Expand All @@ -221,30 +248,33 @@ TEST_P(ActiveQuicListenerTest, FailSocketOptionUponCreation) {
.WillOnce(Return(false));
auto options = std::make_shared<std::vector<Network::Socket::OptionConstSharedPtr>>();
options->emplace_back(std::move(option));
EXPECT_THROW_WITH_REGEX(std::make_unique<ActiveQuicListener>(*dispatcher_, connection_handler_,
listen_socket_, listener_config_,
quic_config_, options),
EnvoyException, "Failed to apply socket options.");
EXPECT_THROW_WITH_REGEX(
std::make_unique<ActiveQuicListener>(*dispatcher_, connection_handler_, listen_socket_,
listener_config_, quic_config_, options, enabledFlag()),
EnvoyException, "Failed to apply socket options.");
}

TEST_P(ActiveQuicListenerTest, ReceiveFullQuicCHLO) {
quic::QuicBufferedPacketStore* const buffered_packets =
quic::test::QuicDispatcherPeer::GetBufferedPackets(quic_dispatcher_);
configureQuicRuntimeFlag(/* runtime_enabled = */ true);
configureMocks(/* connection_count = */ 1);
SendFullCHLO(quic::test::TestConnectionId(1));
sendFullCHLO(quic::test::TestConnectionId(1));
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);
EXPECT_FALSE(buffered_packets->HasChlosBuffered());
EXPECT_FALSE(quic_dispatcher_->session_map().empty());
ReadFromClientSockets();
}

TEST_P(ActiveQuicListenerTest, ProcessBufferedChlos) {
EnvoyQuicDispatcher* const envoy_quic_dispatcher =
ActiveQuicListenerPeer::quic_dispatcher(*quic_listener_);
quic::QuicBufferedPacketStore* const buffered_packets =
quic::test::QuicDispatcherPeer::GetBufferedPackets(envoy_quic_dispatcher);

quic::test::QuicDispatcherPeer::GetBufferedPackets(quic_dispatcher_);
configureQuicRuntimeFlag(/* runtime_enabled = */ true);
configureMocks(ActiveQuicListener::kNumSessionsToCreatePerLoop + 2);

// Generate one more CHLO than can be processed immediately.
for (size_t i = 1; i <= ActiveQuicListener::kNumSessionsToCreatePerLoop + 1; ++i) {
SendFullCHLO(quic::test::TestConnectionId(i));
sendFullCHLO(quic::test::TestConnectionId(i));
}
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);

Expand All @@ -256,9 +286,10 @@ TEST_P(ActiveQuicListenerTest, ProcessBufferedChlos) {
EXPECT_TRUE(buffered_packets->HasBufferedPackets(
quic::test::TestConnectionId(ActiveQuicListener::kNumSessionsToCreatePerLoop + 1)));
EXPECT_TRUE(buffered_packets->HasChlosBuffered());
EXPECT_FALSE(quic_dispatcher_->session_map().empty());

// Generate more data to trigger a socket read during the next event loop.
SendFullCHLO(quic::test::TestConnectionId(ActiveQuicListener::kNumSessionsToCreatePerLoop + 2));
sendFullCHLO(quic::test::TestConnectionId(ActiveQuicListener::kNumSessionsToCreatePerLoop + 2));
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);

// The socket read results in processing all CHLOs.
Expand All @@ -270,5 +301,13 @@ TEST_P(ActiveQuicListenerTest, ProcessBufferedChlos) {
ReadFromClientSockets();
}

TEST_P(ActiveQuicListenerTest, QuicProcessingDisabled) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is already tested in QuicProcessingDisabledAndEnabled, right? Maybe remove it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

configureQuicRuntimeFlag(/* runtime_enabled = */ false);
sendFullCHLO(quic::test::TestConnectionId(1));
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);
// If listener was enabled, there should have been session created for active connection.
EXPECT_TRUE(quic_dispatcher_->session_map().empty());
}

} // namespace Quic
} // namespace Envoy