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

Cli change for file based request source #563

Merged
Merged
Show file tree
Hide file tree
Changes from 186 commits
Commits
Show all changes
187 commits
Select commit Hold shift + click to select a range
99f45d1
Adding a multiple path test to confirm that expected paths are hit
wjuan-AFK Jul 15, 2020
075a4cf
fixing asan problems
wjuan-AFK Jul 17, 2020
ecbf407
Fix Format
wjuan-AFK Jul 17, 2020
8fb11b6
Removeing unused comments
wjuan-AFK Jul 17, 2020
032dbba
Removing unnecessary invoke calls for cleanliness
wjuan-AFK Jul 17, 2020
953e953
Merge branch 'master' into RequestSourceUnitTestBenchmarkMultiplePath
wjuan-AFK Jul 17, 2020
6185edb
Refactoring test to take in request generator parameter instead of using
wjuan-AFK Jul 20, 2020
cded6ad
Changing to pass by reference.
wjuan-AFK Jul 20, 2020
fbfe523
Merge branch 'master' into RequestSourceUnitTestBenchmarkMultiplePath
wjuan-AFK Jul 20, 2020
0d70179
Merge branch 'master' into RequestSourceUnitTestBenchmarkMultiplePath
wjuan-AFK Jul 21, 2020
cdb7efe
Refactoring per comments in PR. Moving helpers, renaming functions.
wjuan-AFK Jul 21, 2020
f15bb47
Adding comments and renaming testbasicfunctionality for clarity
wjuan-AFK Jul 21, 2020
59359a2
Consistent unit test naming convention using should. Clarifying comments
wjuan-AFK Jul 21, 2020
f63df91
Fix format
wjuan-AFK Jul 21, 2020
406bd6b
Adding a clarifying comment for helper function.
wjuan-AFK Jul 22, 2020
f0b697b
Fixing typo and other nits
wjuan-AFK Jul 23, 2020
8425e48
Renaming testBenchmarkClient for clarity
wjuan-AFK Jul 23, 2020
fb4f372
Replacing Flat hash map with flat hash set for simplicity.
wjuan-AFK Jul 24, 2020
c6eae6c
Comment clarification.
wjuan-AFK Jul 24, 2020
96ae38b
Small refactor for factory method for more dependency injection.
wjuan-AFK Jul 27, 2020
b17240f
Fix format.
wjuan-AFK Jul 27, 2020
5c5a146
Refactor to inject the requestsourceconstructor.
wjuan-AFK Jul 27, 2020
29591ff
Moving helper functions.
wjuan-AFK Jul 27, 2020
7d928a9
Merge branch 'RequestSourceUnitTestBenchmarkMultiplePath' into Adding…
wjuan-AFK Jul 27, 2020
ff82d95
Fix format.
wjuan-AFK Jul 27, 2020
98381a4
Adding test using the new mock requestsourceconstructor to get remote
wjuan-AFK Jul 28, 2020
83ac556
Fix format.
wjuan-AFK Jul 28, 2020
38c5084
Adding missing request source constructor files.
wjuan-AFK Jul 28, 2020
fa4e285
Changing helper functions to anonymous namespace.
wjuan-AFK Jul 28, 2020
8551c76
Changing to use a nullable pointer instead of reference for clarity.
wjuan-AFK Jul 28, 2020
437de5e
Formatting fixes per PR.
wjuan-AFK Jul 28, 2020
6cef87e
Fix format.
wjuan-AFK Jul 28, 2020
c84ba4d
Merge branch 'master' into RequestSourceUnitTestBenchmarkMultiplePath
wjuan-AFK Jul 28, 2020
77d33f9
Fix format after merge.
wjuan-AFK Jul 29, 2020
73aa686
Testing a theory.
wjuan-AFK Jul 29, 2020
ef77d65
Fix format.
wjuan-AFK Jul 29, 2020
b9182a0
Merge branch 'RequestSourceUnitTestBenchmarkMultiplePath' into Adding…
wjuan-AFK Jul 29, 2020
e38dd80
Merge branch 'master' into RequestSourceUnitTestBenchmarkMultiplePath
wjuan-AFK Jul 29, 2020
21734e4
Merge branch 'RequestSourceUnitTestBenchmarkMultiplePath' into Adding…
wjuan-AFK Jul 29, 2020
7cda9d2
Merge branch 'master' into AddingTestForRequestSourceFactory
wjuan-AFK Aug 17, 2020
f827aca
Adding initial protos and stubs.
wjuan-AFK Aug 19, 2020
d194736
Adding impl for Dummy request source plugin.
wjuan-AFK Aug 19, 2020
7820cf9
Adding test for request source factory creation.
wjuan-AFK Aug 19, 2020
bee7805
Adding some more protos.
wjuan-AFK Aug 19, 2020
3db68ce
Merge branch 'master' into AddingTestForRequestSourceFactory
wjuan-AFK Aug 19, 2020
c0ec4dd
Merge branch 'AddingTestForRequestSourceFactory' into AddingConfigFac…
wjuan-AFK Aug 19, 2020
a1dd3f2
Fixing mockrequestsourcefactory impacted by the refactor.
wjuan-AFK Aug 20, 2020
0b25261
Adding more factories to the impl.h
wjuan-AFK Aug 20, 2020
c3fa23c
Fixing clang tidy.
wjuan-AFK Aug 20, 2020
547977e
Updating the impl.cc with a stub for the new factories.
wjuan-AFK Aug 20, 2020
c300203
Adding test for file based request source plugin
wjuan-AFK Aug 26, 2020
8f4d4d9
Adding test yaml file.
wjuan-AFK Aug 26, 2020
5ae2d51
Merge branch 'AddingTestForRequestSourceFactory' into AddingConfigFac…
wjuan-AFK Aug 26, 2020
fe74b6d
First try getting requests working.
wjuan-AFK Aug 27, 2020
6d87aea
Switching to using multiple requestOptions instead of one.
wjuan-AFK Sep 1, 2020
ca7a0c2
Removing unused comments.
wjuan-AFK Sep 2, 2020
967e3f8
Adding api dependency injection.
wjuan-AFK Sep 2, 2020
14b7d79
Getting the multiple paths parsing into the test.
wjuan-AFK Sep 3, 2020
c4985bb
Comment clean up and using loadfromfile instead of reading the file and
wjuan-AFK Sep 3, 2020
922639a
Switching to using iterators in a vector instead of a smart pointer.
wjuan-AFK Sep 9, 2020
81dfece
Removing unused comments.
wjuan-AFK Sep 9, 2020
bf08661
Small cleanup.
wjuan-AFK Sep 10, 2020
34900c5
Merge branch 'master' into AddingTestForRequestSourceFactory
wjuan-AFK Sep 10, 2020
768fa81
Merge branch 'AddingTestForRequestSourceFactory' into AddingConfigFac…
wjuan-AFK Sep 10, 2020
e93bb58
Reverting changes to RequestSourceConstructor.
wjuan-AFK Sep 10, 2020
f47cbd4
Removing RPCRequestSourcePlugin
wjuan-AFK Sep 10, 2020
7c5c6b2
Fix format.
wjuan-AFK Sep 10, 2020
1b02cec
Fix format.
wjuan-AFK Sep 10, 2020
4d75602
Fixing clang problems.
wjuan-AFK Sep 11, 2020
c74f535
Fixing clang.
wjuan-AFK Sep 11, 2020
9949fb8
Fix format.
wjuan-AFK Sep 11, 2020
fcf10d3
Fixing clang tidy.
wjuan-AFK Sep 11, 2020
fd9744d
Fix Format
wjuan-AFK Sep 11, 2020
68c1037
Rename requestOptionses to requestOptionsList.
wjuan-AFK Sep 14, 2020
883ee30
Renaming proto.
wjuan-AFK Sep 15, 2020
8c34b25
Updating to take a number of requests.
wjuan-AFK Sep 16, 2020
6ce7e74
Clean up tests.
wjuan-AFK Sep 16, 2020
92927e5
Changing visibility of RequestSourcePlugin's inheritance.
wjuan-AFK Sep 16, 2020
a62f2d5
Switching to using lock_guard.
wjuan-AFK Sep 16, 2020
16f89c6
Clean up.
wjuan-AFK Sep 16, 2020
f4257e3
Fix Format.
wjuan-AFK Sep 16, 2020
d075588
Addressing comments on PR. Cleaning up formatting.
wjuan-AFK Sep 17, 2020
eb10a3b
Getting rid of RequestSourcePluginPtr, and adding comments.
wjuan-AFK Sep 17, 2020
cdbd6bf
Removing unnecessary RequestSourcePlugin interface for improved testa…
wjuan-AFK Sep 17, 2020
17acc5f
Fix format
wjuan-AFK Sep 17, 2020
55a0e62
Cleanup unintentional whitespace.
wjuan-AFK Sep 18, 2020
fa23aad
Swapping to exception instead of Release_assert.
wjuan-AFK Sep 18, 2020
b8e2447
Renaming the request_source_plugin to request_source_plugin_config_fa…
wjuan-AFK Sep 18, 2020
248f439
Using a context struct for extensability.
wjuan-AFK Sep 22, 2020
91703b5
Spacing and comments.
wjuan-AFK Sep 22, 2020
bbc0c2a
Fix format.
wjuan-AFK Sep 22, 2020
517c83d
Adding test for multiple request sources thread lock.
wjuan-AFK Sep 22, 2020
c1d0428
Additional comment
wjuan-AFK Sep 22, 2020
bc86c09
Getting rid of context object because the Register Factory mechanism …
wjuan-AFK Sep 22, 2020
33e3564
Adding option to circumvent file reading.
wjuan-AFK Sep 23, 2020
338a874
Merge branch 'master' into AddingConfigFactory
wjuan-AFK Sep 23, 2020
402ada2
Fix format.
wjuan-AFK Sep 23, 2020
017481f
Getting rid of default constructors.
wjuan-AFK Sep 23, 2020
3ed43fc
Renames for clarity.
wjuan-AFK Sep 23, 2020
247b71b
Fix format.
wjuan-AFK Sep 23, 2020
718e4cd
Adding initial CLI code for requestSourceplugin.
wjuan-AFK Sep 24, 2020
50c0c07
Fixing build.
wjuan-AFK Sep 24, 2020
171fb2e
Splitting factory off into a separate pr.
wjuan-AFK Sep 24, 2020
5df83ed
Proto cleanup/rename
wjuan-AFK Sep 24, 2020
0af3ffd
Comment cleanup.
wjuan-AFK Sep 24, 2020
ff90e59
Proto comments and dummy -> stub clean up.
wjuan-AFK Sep 24, 2020
e57c05f
Cleaning up comments
wjuan-AFK Sep 28, 2020
55244b0
Updating class comments.
wjuan-AFK Sep 28, 2020
3d0b1a2
Merge pull request #3 from wjuan-AFK/AddingConfigFactory
wjuan-AFK Sep 28, 2020
c710d37
Refactor to move RequestSourcePlugins to a top level RequestSource fo…
wjuan-AFK Sep 28, 2020
fbb2fdc
Refactor plugins into separate files.
wjuan-AFK Sep 28, 2020
ae0f4a8
Fix format.
wjuan-AFK Sep 28, 2020
e092de0
Merge branch 'master' into AddingConfigFactory
wjuan-AFK Sep 28, 2020
1b87b71
Merge branch 'AddingConfigFactory' into CLIChangeForFileBasedRequestS…
wjuan-AFK Sep 28, 2020
6a72987
Merge branch 'CLIChangeForFileBasedRequestSource' of github.com:wjuan…
wjuan-AFK Sep 28, 2020
a080eec
Clean up after refactor moving plugins.
wjuan-AFK Sep 28, 2020
19b7aa0
Adding gmock and gtest to check_format so it stops complaining at me.
wjuan-AFK Sep 28, 2020
dae3098
Updating to prefix increment, and removing auto.
wjuan-AFK Sep 29, 2020
a4b6fb1
Removing gmock and gtest from script to avoid conflict. Add Request_s…
wjuan-AFK Sep 29, 2020
55f685e
Fixing clang-tidy
wjuan-AFK Sep 30, 2020
59c5b94
Using the test value in the stub for better testing.
wjuan-AFK Sep 30, 2020
2ea0c5e
Getting rid of auto. And updating stubplugintest.
wjuan-AFK Sep 30, 2020
d40a073
Further renaming.
wjuan-AFK Sep 30, 2020
7146079
Refactor to move plugins into their own libraries and separate files.
wjuan-AFK Sep 30, 2020
7ab1132
Moving request_source_plugin_config_factory into its own folder.
wjuan-AFK Sep 30, 2020
72c23d0
Refactor to make it testonly.
wjuan-AFK Sep 30, 2020
2b1170c
Using references instead of making a copy of the option list.
wjuan-AFK Oct 1, 2020
9dc3c4b
Passing in a reference to api instead of apiptr.
wjuan-AFK Oct 1, 2020
b555a71
Renaming request_max to total_requests
wjuan-AFK Oct 1, 2020
3924eee
Updating comments and removing explicit.
wjuan-AFK Oct 1, 2020
75eca07
Fix format.
wjuan-AFK Oct 1, 2020
9c93ff9
Merge branch 'master' into AddingConfigFactory
wjuan-AFK Oct 1, 2020
0040b33
Merge branch 'AddingConfigFactory' into CLIChangeForFileBasedRequestS…
wjuan-AFK Oct 1, 2020
e2af886
Clean up.
wjuan-AFK Oct 1, 2020
edae9be
Rename FilebasedConfigFactory to OptionListFromFileFactory
wjuan-AFK Oct 1, 2020
949d731
Improving Comments.
wjuan-AFK Oct 2, 2020
59d490f
Fix format.
wjuan-AFK Oct 2, 2020
078329a
More comment cleanup.
wjuan-AFK Oct 2, 2020
63e5d2b
Merge branch 'AddingConfigFactory' into CLIChangeForFileBasedRequestS…
wjuan-AFK Oct 2, 2020
530cc9c
Adding proto request source factory.
wjuan-AFK Oct 7, 2020
22cc3f8
Merge branch 'master' into AddingProtoOnlyFactory
wjuan-AFK Oct 7, 2020
32489d0
Fix format.
wjuan-AFK Oct 7, 2020
324bb23
Fixing Clang tidy.
wjuan-AFK Oct 7, 2020
5d6bb26
Clarifying proto comments.
wjuan-AFK Oct 8, 2020
32ae13d
Rename, using optional, and moving functions in test.
wjuan-AFK Oct 8, 2020
12708ac
Need to stop forggetting to add blank lines or update the fix format …
wjuan-AFK Oct 8, 2020
eff2f4e
Replacing request with request1
wjuan-AFK Oct 8, 2020
b890df4
Renaming tests for clarity
wjuan-AFK Oct 8, 2020
a907913
Adding assertions for safety.
wjuan-AFK Oct 8, 2020
49a47a4
Clarifying comments on parameters
wjuan-AFK Oct 8, 2020
b711028
Fix format.
wjuan-AFK Oct 8, 2020
8a2d792
Renames based on feedback, and swapping to using uint32 instead of ui…
wjuan-AFK Oct 9, 2020
22b93aa
Fix format.
wjuan-AFK Oct 9, 2020
7b9c175
Cleaning up comments per feedback.
wjuan-AFK Oct 21, 2020
bab49fc
Clarifying comments.
wjuan-AFK Oct 21, 2020
7184695
Adding test for CLI changes.
wjuan-AFK Oct 21, 2020
fc7eda6
Removing implementation detail from comment.
wjuan-AFK Oct 22, 2020
49e6eec
Fix Format.
wjuan-AFK Oct 22, 2020
43de3d8
Merge branch 'master' into AddingProtoOnlyFactory
wjuan-AFK Oct 22, 2020
fef08dd
Merge branch 'AddingProtoOnlyFactory' into CLIChangeForFileBasedReque…
wjuan-AFK Oct 22, 2020
264355c
Fixing merge.
wjuan-AFK Oct 22, 2020
fa4d4c9
Adding inlineoptionslist test.
wjuan-AFK Oct 22, 2020
546449a
Formatting.
wjuan-AFK Oct 22, 2020
1a28a30
Cleaning up.
wjuan-AFK Oct 22, 2020
fa2adc5
Fix format.
wjuan-AFK Oct 22, 2020
01959ea
Additional cleanup.
wjuan-AFK Oct 22, 2020
6696b5e
Merge branch 'master' into CLIChangeForFileBasedRequestSource
wjuan-AFK Oct 22, 2020
6168223
Fixing build.
wjuan-AFK Oct 22, 2020
3043405
Fix format.
wjuan-AFK Oct 22, 2020
309f75b
Updating ReadMe via updateReadme command.
wjuan-AFK Oct 22, 2020
4a63c18
Lowering threshold for CI integration test coverage so the PR can be …
wjuan-AFK Oct 26, 2020
55a7460
Comment cleanup. Signed-off-by: William Juan <66322422+wjuan-AFK@user…
wjuan-AFK Oct 26, 2020
fdb84d2
Enforcing mutual exclusivity.
wjuan-AFK Oct 28, 2020
592345a
Adding decimal point to clarify the precision.
wjuan-AFK Oct 28, 2020
e98211f
Adding coverage for initOnThread.
wjuan-AFK Oct 29, 2020
436f952
Adding maxFileSize test, fixing bug.
wjuan-AFK Oct 29, 2020
fee4328
fix format.
wjuan-AFK Nov 2, 2020
c37cde2
Adding bad json test.
wjuan-AFK Nov 2, 2020
8e56850
Adding TODO.
wjuan-AFK Nov 2, 2020
ac18ebb
Clarifying comments.
wjuan-AFK Nov 2, 2020
66cd5ed
Replacing string comparison with empty check per style.
wjuan-AFK Nov 2, 2020
fc254f0
Switching to parametrized test.
wjuan-AFK Nov 2, 2020
9a409dd
Small cleanup for stylistic reasons.
wjuan-AFK Nov 2, 2020
314f924
Comment clean up.
wjuan-AFK Nov 3, 2020
587cf3c
Adding back additional comparison to avoid edge cases missed.
wjuan-AFK Nov 3, 2020
8401dd5
Fix format
wjuan-AFK Nov 3, 2020
8ee66df
Formatting and commenting changes for cl feedback. Using raw string.
wjuan-AFK Nov 5, 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
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ bazel-bin/nighthawk_client [--latency-response-header-name <string>]
[--stats-flush-interval <uint32_t>]
[--stats-sinks <string>] ...
[--no-duration] [--simple-warmup]
[--request-source-plugin-config <string>]
[--request-source <uri format>] [--label
<string>] ... [--multi-target-use-https]
[--multi-target-path <string>]
Expand Down Expand Up @@ -109,10 +110,20 @@ Perform a simple single warmup request (per worker) before starting
execution. Note that this will be reflected in the counters that
Nighthawk writes to the output. Default is false.

--request-source-plugin-config <string>
[Request
Source](https://github.com/envoyproxy/nighthawk/blob/master/docs/root/
overview.md#requestsource) plugin configuration in json or compact
yaml. Mutually exclusive with --request-source. Example (json):
{name:"nighthawk.stub-request-source-plugin"
,typed_config:{"@type":"type.googleapis.com/nighthawk.request_source.S
tubPluginConfig",test_value:"3"}}

--request-source <uri format>
Remote gRPC source that will deliver to-be-replayed traffic. Each
worker will separately connect to this source. For example
grpc://127.0.0.1:8443/.
grpc://127.0.0.1:8443/. Mutually exclusive with
--request_source_plugin_config.

--label <string> (accepted multiple times)
Label. Allows specifying multiple labels which will be persisted in
Expand Down
5 changes: 5 additions & 0 deletions api/client/options.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "google/protobuf/wrappers.proto";
import "envoy/config/core/v3/base.proto";
import "envoy/config/metrics/v3/stats.proto";
import "envoy/extensions/transport_sockets/tls/v3/cert.proto";
import "envoy/config/core/v3/extension.proto";
import "validate/validate.proto";

// Allows for static configuration of requests that should be send by the load generator.
Expand Down Expand Up @@ -104,6 +105,7 @@ message H1ConnectionReuseStrategy {

// TODO(oschaaf): Ultimately this will be a load test specification. The fact that it
// can arrive via CLI is just a concrete detail. Change this to reflect that.
// highest unused number is 38
dubious90 marked this conversation as resolved.
Show resolved Hide resolved
message CommandLineOptions {
// The target requests-per-second rate. Default: 5.
google.protobuf.UInt32Value requests_per_second = 1
Expand Down Expand Up @@ -148,6 +150,9 @@ message CommandLineOptions {
// Remote gRPC source that will deliver to-be-replayed traffic. Each worker will separately
// connect to this source.
RequestSource request_source = 26;
// A plugin config that is to be parsed by a RequestSourcePluginConfigFactory and used to create
// an in memory request source.
envoy.config.core.v3.TypedExtensionConfig request_source_plugin_config = 37;
}
// DEPRECATED, use --transport-socket instead. Tls context configuration in json or compact yaml.
// Mutually exclusive with --transport-socket.
Expand Down
3 changes: 2 additions & 1 deletion ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ function do_unit_test_coverage() {

function do_integration_test_coverage() {
export TEST_TARGETS="//test:python_test"
export COVERAGE_THRESHOLD=78.6
#TODO(#564): Revert this to 78.6
export COVERAGE_THRESHOLD=75.0
echo "bazel coverage build with tests ${TEST_TARGETS}"
test/run_nighthawk_bazel_coverage.sh ${TEST_TARGETS}
exit 0
Expand Down
2 changes: 2 additions & 0 deletions include/nighthawk/client/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class Options {
virtual nighthawk::client::SequencerIdleStrategy::SequencerIdleStrategyOptions
sequencerIdleStrategy() const PURE;
virtual std::string requestSource() const PURE;
virtual const absl::optional<envoy::config::core::v3::TypedExtensionConfig>&
requestSourcePluginConfig() const PURE;
virtual std::string trace() const PURE;
virtual nighthawk::client::H1ConnectionReuseStrategy::H1ConnectionReuseStrategyOptions
h1ConnectionReuseStrategy() const PURE;
Expand Down
2 changes: 2 additions & 0 deletions source/client/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ envoy_cc_library(
"//source/common:request_source_impl_lib",
"//source/common:nighthawk_common_lib",
"//source/common:nighthawk_service_client_impl",
"//source/request_source:request_options_list_plugin_impl",
"@envoy//source/common/common:random_generator_lib_with_external_headers",
"@envoy//source/common/access_log:access_log_manager_lib_with_external_headers",
"@envoy//source/common/api:api_lib_with_external_headers",
Expand Down Expand Up @@ -90,6 +91,7 @@ envoy_cc_library(
"@envoy//source/server:server_lib_with_external_headers",
"@envoy//source/server/config_validation:admin_lib_with_external_headers",
"@envoy//include/envoy/http:protocol_interface_with_external_headers",
"@envoy//source/common/common:statusor_lib_with_external_headers",
] + select({
"//bazel:zipkin_disabled": [],
"//conditions:default": [
Expand Down
6 changes: 3 additions & 3 deletions source/client/factories_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,15 @@ RequestSourceFactoryImpl::create(const Envoy::Upstream::ClusterManagerPtr& clust
setRequestHeader(*header, option_header.header().key(), option_header.header().value());
}

if (options_.requestSource() == "") {
return std::make_unique<StaticRequestSourceImpl>(std::move(header));
} else {
if (!options_.requestSource().empty()) {
RELEASE_ASSERT(!service_cluster_name.empty(), "expected cluster name to be set");
// We pass in options_.requestsPerSecond() as the header buffer length so the grpc client
// will shoot for maintaining an amount of headers of at least one second.
return std::make_unique<RemoteRequestSourceImpl>(cluster_manager, dispatcher, scope,
service_cluster_name, std::move(header),
options_.requestsPerSecond());
} else {
return std::make_unique<StaticRequestSourceImpl>(std::move(header));
}
}

Expand Down
35 changes: 33 additions & 2 deletions source/client/options_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,19 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
TCLAP::ValueArg<std::string> request_source(
"", "request-source",
"Remote gRPC source that will deliver to-be-replayed traffic. Each worker will separately "
"connect to this source. For example grpc://127.0.0.1:8443/.",
"connect to this source. For example grpc://127.0.0.1:8443/. "
"Mutually exclusive with --request_source_plugin_config.",
false, "", "uri format", cmd);

TCLAP::ValueArg<std::string> request_source_plugin_config(
"", "request-source-plugin-config",
"[Request "
"Source](https://github.com/envoyproxy/nighthawk/blob/master/docs/root/"
"overview.md#requestsource) plugin configuration in json or compact yaml. "
"Mutually exclusive with --request-source. Example (json): "
oschaaf marked this conversation as resolved.
Show resolved Hide resolved
"{name:\"nighthawk.stub-request-source-plugin\",typed_config:{"
"\"@type\":\"type.googleapis.com/nighthawk.request_source.StubPluginConfig\","
"test_value:\"3\"}}",
false, "", "string", cmd);
TCLAP::SwitchArg simple_warmup(
"", "simple-warmup",
"Perform a simple single warmup request (per worker) before starting execution. Note that "
Expand Down Expand Up @@ -496,6 +506,21 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
throw MalformedArgvException(e.what());
}
}
if (!request_source.getValue().empty() && !request_source_plugin_config.getValue().empty()) {
throw MalformedArgvException(
"--request-source and --request_source_plugin_config cannot both be set.");
}
if (!request_source_plugin_config.getValue().empty()) {
try {
request_source_plugin_config_.emplace(envoy::config::core::v3::TypedExtensionConfig());
dubious90 marked this conversation as resolved.
Show resolved Hide resolved
Envoy::MessageUtil::loadFromJson(request_source_plugin_config.getValue(),
request_source_plugin_config_.value(),
Envoy::ProtobufMessage::getStrictValidationVisitor());
} catch (const Envoy::EnvoyException& e) {
throw MalformedArgvException(e.what());
}
}

validate();
}

Expand Down Expand Up @@ -570,6 +595,9 @@ OptionsImpl::OptionsImpl(const nighthawk::client::CommandLineOptions& options) {
} else if (options.has_request_source()) {
const auto& request_source_options = options.request_source();
request_source_ = request_source_options.uri();
} else if (options.has_request_source_plugin_config()) {
request_source_plugin_config_.emplace(envoy::config::core::v3::TypedExtensionConfig());
request_source_plugin_config_.value().MergeFrom(options.request_source_plugin_config());
}

max_pending_requests_ =
Expand Down Expand Up @@ -730,6 +758,9 @@ CommandLineOptionsPtr OptionsImpl::toCommandLineOptionsInternal() const {
if (requestSource() != "") {
auto request_source = command_line_options->mutable_request_source();
*request_source->mutable_uri() = request_source_;
} else if (request_source_plugin_config_.has_value()) {
*(command_line_options->mutable_request_source_plugin_config()) =
request_source_plugin_config_.value();
} else {
auto request_options = command_line_options->mutable_request_options();
request_options->set_request_method(request_method_);
Expand Down
7 changes: 7 additions & 0 deletions source/client/options_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class OptionsImpl : public Options, public Envoy::Logger::Loggable<Envoy::Logger
return sequencer_idle_strategy_;
}
std::string requestSource() const override { return request_source_; }
const absl::optional<envoy::config::core::v3::TypedExtensionConfig>&
requestSourcePluginConfig() const override {
return request_source_plugin_config_;
}

std::string trace() const override { return trace_; }
nighthawk::client::H1ConnectionReuseStrategy::H1ConnectionReuseStrategyOptions
h1ConnectionReuseStrategy() const override {
Expand Down Expand Up @@ -116,6 +121,8 @@ class OptionsImpl : public Options, public Envoy::Logger::Loggable<Envoy::Logger
uint32_t request_body_size_{0};
envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_context_;
absl::optional<envoy::config::core::v3::TransportSocket> transport_socket_;
absl::optional<envoy::config::core::v3::TypedExtensionConfig> request_source_plugin_config_;

uint32_t max_pending_requests_{0};
// This default is based the minimum recommendation for SETTINGS_MAX_CONCURRENT_STREAMS over at
// https://tools.ietf.org/html/rfc7540#section-6.5.2
Expand Down
2 changes: 1 addition & 1 deletion source/request_source/request_options_list_plugin_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ RequestSourcePtr FileBasedOptionsListRequestSourceFactory::createRequestSourcePl
const auto& any = dynamic_cast<const Envoy::ProtobufWkt::Any&>(message);
nighthawk::request_source::FileBasedOptionsListRequestSourceConfig config;
Envoy::MessageUtil util;
uint32_t max_file_size = config.has_max_file_size() ? config.max_file_size().value() : 1000000;
util.unpackTo(any, config);
uint32_t max_file_size = config.has_max_file_size() ? config.max_file_size().value() : 1000000;
if (api.fileSystem().fileSize(config.file_path()) > max_file_size) {
throw NighthawkException("file size must be less than max_file_size");
}
Expand Down
2 changes: 2 additions & 0 deletions test/mocks/client/mock_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class MockOptions : public Options {
MOCK_CONST_METHOD0(sequencerIdleStrategy,
nighthawk::client::SequencerIdleStrategy::SequencerIdleStrategyOptions());
MOCK_CONST_METHOD0(requestSource, std::string());
MOCK_CONST_METHOD0(requestSourcePluginConfig,
absl::optional<envoy::config::core::v3::TypedExtensionConfig>&());
MOCK_CONST_METHOD0(trace, std::string());
MOCK_CONST_METHOD0(
h1ConnectionReuseStrategy,
Expand Down
113 changes: 110 additions & 3 deletions test/options_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "client/options_impl.h"

#include "test/client/utility.h"
#include "test/test_common/environment.h"

#include "gtest/gtest.h"

Expand Down Expand Up @@ -249,7 +250,7 @@ TEST_F(OptionsImplTest, AlmostAll) {
EXPECT_TRUE(util(cmd->stats_sinks(0), options->statsSinks()[0]));
EXPECT_TRUE(util(cmd->stats_sinks(1), options->statsSinks()[1]));
EXPECT_EQ(cmd->latency_response_header_name().value(), options->responseHeaderWithLatencyInput());

// TODO(#433)
Copy link
Contributor

Choose a reason for hiding this comment

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

Two nit asks on this set of TODOs:

  1. Can we add a oneliner, explaining what the action to do here specifically is
  2. Rather than repeating it on every test here, we could have in the comment something like "Here and below". Then we only need to include the TODO once per relevant file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. sounds good to me. I feel like tagging the comparisons which need to be replaced is helpful, but I can remove the other ones if you insist.

OptionsImpl options_from_proto(*cmd);
std::string s1 = Envoy::MessageUtil::getYamlStringFromMessage(
*(options_from_proto.toCommandLineOptions()), true, true);
Expand All @@ -272,10 +273,115 @@ TEST_F(OptionsImplTest, RequestSource) {
// Check that our conversion to CommandLineOptionsPtr makes sense.
CommandLineOptionsPtr cmd = options->toCommandLineOptions();
EXPECT_EQ(cmd->request_source().uri(), request_source);
// TODO(#433)
OptionsImpl options_from_proto(*cmd);
EXPECT_TRUE(util(*(options_from_proto.toCommandLineOptions()), *cmd));
}

class RequestSourcePluginTestFixture : public OptionsImplTest,
public WithParamInterface<std::string> {};

TEST_P(RequestSourcePluginTestFixture, CreatesOptionsImplWithRequestSourceConfig) {
Envoy::MessageUtil util;
const std::string request_source_config = GetParam();
std::unique_ptr<OptionsImpl> options = TestUtility::createOptionsImpl(
fmt::format("{} --request-source-plugin-config {} {}", client_name_, request_source_config,
good_test_uri_));

CommandLineOptionsPtr command = options->toCommandLineOptions();
EXPECT_TRUE(
util(command->request_source_plugin_config(), options->requestSourcePluginConfig().value()));
// Now we construct a new options from the proto we created above. This should result in an
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you're overdescribing here. It's also particularly confusing because the code you're describing also doesn't appear to be the code that it immediately follows this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I found this comment helpful to me, so I thought it made sense to keep it. I think I would have found these lines odd if I didn't have them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry -- my previous code comment wasn't particularly helpful/directive. I agree that comments here would be helpful, but I'm not finding this comment to clarify the code for me, so let me re-explain better:
In general, comments are most helpful when we explain the why, rather than the what. This comment is actually doing a little bit of both. One of the reasons why I think you're finding the need to explain "what" is that the comments aren't actually positionally with the code that they're explaining.

Rather than explaining a whole series of actions in one comment, can we split up the comments to be directly tied to their code sections?

// OptionsImpl instance equivalent to options. We test that by converting both to yaml strings,
// expecting them to be equal. This should provide helpful output when the test fails by showing
// the unexpected (yaml) diff.

// The predicates are defined as proto maps, and these seem to re-serialize into a different
// order. Hence we trim the maps to contain a single entry so they don't thwart our textual
// comparison below.
EXPECT_EQ(1, command->mutable_failure_predicates()->erase("benchmark.http_4xx"));
EXPECT_EQ(1, command->mutable_failure_predicates()->erase("benchmark.http_5xx"));
EXPECT_EQ(1, command->mutable_failure_predicates()->erase("requestsource.upstream_rq_5xx"));
// TODO(#433)
OptionsImpl options_from_proto(*command);
std::string s1 = Envoy::MessageUtil::getYamlStringFromMessage(
*(options_from_proto.toCommandLineOptions()), true, true);
std::string s2 = Envoy::MessageUtil::getYamlStringFromMessage(*command, true, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

One thing that might make this easier to parse is if we use more descriptive names, rather than s1 and s2. Maybe expected_options_yaml and actual_options_yaml? Or whatever names you think would be accurate/helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For sure.

EXPECT_EQ(s1, s2);
Copy link
Member

Choose a reason for hiding this comment

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

Consider also adding the following comparison, as I suspect the yaml/text based comparison may miss edge cases.

  EXPECT_TRUE(util(*(options_from_proto.toCommandLineOptions()), *command));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. Understood. That makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dubious90 Wanted to let you know that I was adding this back in since this reasoning makes sense to me.

// Additional comparison to avoid edge cases missed.
EXPECT_TRUE(util(*(options_from_proto.toCommandLineOptions()), *command));
}

INSTANTIATE_TEST_SUITE_P(
HappyPathRequestSourceConfigJsonSuccessfullyTranslatesIntoOptions,
RequestSourcePluginTestFixture,
::testing::ValuesIn(std::vector<std::string>{
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm having a really hard time parsing this. There are two things that might help here:

  1. C++ has a formatted string option that will make this much easier to read, rather than using " so much. You can do R"( string that contains " with no problems)". https://abseil.io/tips/64
  2. (optional) I think this is just one string, but it's difficult to tell. Can we abstract the actual textprotos into variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure that 1 works for me here. I might be missing something, but it seems like there are issues with the newlines. At least it seems like using R"( makes you keep the newlines if you space them into separate lines. I can make each line a separate raw string though, I'm not sure that this makes it more readable, but maybe you'll find this preferable?
2. I've kind of tried to do this. Hope that this approach looks ok.

"{"
"name:\"nighthawk.in-line-options-list-request-source-plugin\","
"typed_config:{"
"\"@type\":\"type.googleapis.com/"
"nighthawk.request_source.InLineOptionsListRequestSourceConfig\","
"options_list:{"
"options:[{request_method:\"1\",request_headers:[{header:{key:\"key\",value:\"value\"}}]}]"
"},"
"}"
"}",
"{"
"name:\"nighthawk.file-based-request-source-plugin\","
"typed_config:{"
"\"@type\":\"type.googleapis.com/"
"nighthawk.request_source.FileBasedOptionsListRequestSourceConfig\","
"file_path:\"" +
TestEnvironment::runfilesPath("test/request_source/test_data/test-config.yaml") +
"\","
"}"
"}",
"{"
"name:\"nighthawk.stub-request-source-plugin\","
"typed_config:{"
"\"@type\":\"type.googleapis.com/nighthawk.request_source.StubPluginConfig\","
"test_value:\"3\","
"}"
"}",
}));

// This test covers --RequestSourcePlugin, which can't be tested at the same time as --RequestSource
// and some other options. This is the test for the inlineoptionslistplugin.
TEST_F(OptionsImplTest, InLineOptionsListRequestSourcePluginIsMutuallyExclusiveWithRequestSource) {
const std::string request_source = "127.9.9.4:32323";
const std::string request_source_config =
"{"
"name:\"nighthawk.in-line-options-list-request-source-plugin\","
"typed_config:{"
"\"@type\":\"type.googleapis.com/"
"nighthawk.request_source.InLineOptionsListRequestSourceConfig\","
"options_list:{"
"options:[{request_method:\"1\",request_headers:[{header:{key:\"key\",value:\"value\"}}]}]"
"},"
"}"
"}";
EXPECT_THROW_WITH_REGEX(
TestUtility::createOptionsImpl(
fmt::format("{} --request-source-plugin-config {} --request-source {} {}", client_name_,
request_source_config, request_source, good_test_uri_)),
MalformedArgvException,
"--request-source and --request_source_plugin_config cannot both be set.");
}

TEST_F(OptionsImplTest, BadRequestSourcePluginSpecification) {
// Bad JSON
EXPECT_THROW_WITH_REGEX(
TestUtility::createOptionsImpl(fmt::format("{} --request-source-plugin-config {} {}",
client_name_, "{broken_json:", good_test_uri_)),
MalformedArgvException, "Unable to parse JSON as proto");
// Correct JSON, but contents not according to spec.
EXPECT_THROW_WITH_REGEX(TestUtility::createOptionsImpl(
fmt::format("{} --request-source-plugin-config {} {}", client_name_,
"{misspelled_field:{}}", good_test_uri_)),
MalformedArgvException,
"envoy.config.core.v3.TypedExtensionConfig reason INVALID_ARGUMENT");
}

// We test --no-duration here and not in All above because it is exclusive to --duration.
TEST_F(OptionsImplTest, NoDuration) {
Envoy::MessageUtil util;
Expand All @@ -284,6 +390,7 @@ TEST_F(OptionsImplTest, NoDuration) {
EXPECT_TRUE(options->noDuration());
// Check that our conversion to CommandLineOptionsPtr makes sense.
CommandLineOptionsPtr cmd = options->toCommandLineOptions();
// TODO(#433)
OptionsImpl options_from_proto(*cmd);
EXPECT_TRUE(util(*(options_from_proto.toCommandLineOptions()), *cmd));
}
Expand Down Expand Up @@ -324,7 +431,7 @@ TEST_F(OptionsImplTest, TlsContext) {
EXPECT_EQ(1, cmd->mutable_failure_predicates()->erase("benchmark.http_4xx"));
EXPECT_EQ(1, cmd->mutable_failure_predicates()->erase("benchmark.http_5xx"));
EXPECT_EQ(1, cmd->mutable_failure_predicates()->erase("requestsource.upstream_rq_5xx"));

// TODO(#433)
OptionsImpl options_from_proto(*cmd);
std::string s1 = Envoy::MessageUtil::getYamlStringFromMessage(
*(options_from_proto.toCommandLineOptions()), true, true);
Expand Down Expand Up @@ -386,7 +493,7 @@ TEST_F(OptionsImplTest, MultiTarget) {
EXPECT_EQ(1, cmd->mutable_failure_predicates()->erase("benchmark.http_4xx"));
EXPECT_EQ(1, cmd->mutable_failure_predicates()->erase("benchmark.http_5xx"));
EXPECT_EQ(1, cmd->mutable_failure_predicates()->erase("requestsource.upstream_rq_5xx"));

// TODO(#433)
OptionsImpl options_from_proto(*cmd);
std::string s1 = Envoy::MessageUtil::getYamlStringFromMessage(
*(options_from_proto.toCommandLineOptions()), true, true);
Expand Down
Loading