1 //
2 //
3 // Copyright 2024 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 // Benchmark gRPC end2end in various configurations for chaotic good
20 // TODO(ctiller): fold back into bm_fullstack_unary_ping_pong.cc once chaotic
21 // good can run without custom experiment configuration.
22
23 #include "src/cpp/ext/chaotic_good.h"
24 #include "test/core/util/test_config.h"
25 #include "test/cpp/microbenchmarks/fullstack_unary_ping_pong.h"
26 #include "test/cpp/util/test_config.h"
27
28 namespace grpc {
29 namespace testing {
30
31 class ChaoticGoodFixture : public BaseFixture {
32 public:
ChaoticGoodFixture(Service * service,const FixtureConfiguration & config=FixtureConfiguration ())33 explicit ChaoticGoodFixture(
34 Service* service,
35 const FixtureConfiguration& config = FixtureConfiguration()) {
36 auto address = MakeAddress(&port_);
37 ServerBuilder b;
38 if (address.length() > 0) {
39 b.AddListeningPort(address, ChaoticGoodInsecureServerCredentials());
40 }
41 cq_ = b.AddCompletionQueue(true);
42 b.RegisterService(service);
43 config.ApplyCommonServerBuilderConfig(&b);
44 server_ = b.BuildAndStart();
45 ChannelArguments args;
46 config.ApplyCommonChannelArguments(&args);
47 if (address.length() > 0) {
48 channel_ = grpc::CreateCustomChannel(
49 address, ChaoticGoodInsecureChannelCredentials(), args);
50 } else {
51 channel_ = server_->InProcessChannel(args);
52 }
53 }
54
~ChaoticGoodFixture()55 ~ChaoticGoodFixture() override {
56 server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
57 cq_->Shutdown();
58 void* tag;
59 bool ok;
60 while (cq_->Next(&tag, &ok)) {
61 }
62 grpc_recycle_unused_port(port_);
63 }
64
cq()65 ServerCompletionQueue* cq() { return cq_.get(); }
channel()66 std::shared_ptr<Channel> channel() { return channel_; }
67
68 private:
MakeAddress(int * port)69 static std::string MakeAddress(int* port) {
70 *port = grpc_pick_unused_port_or_die();
71 std::stringstream addr;
72 addr << "localhost:" << *port;
73 return addr.str();
74 }
75
76 std::unique_ptr<Server> server_;
77 std::unique_ptr<ServerCompletionQueue> cq_;
78 std::shared_ptr<Channel> channel_;
79 int port_;
80 };
81
82 //******************************************************************************
83 // CONFIGURATIONS
84 //
85
86 // Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use
87 // internal microbenchmarking tooling
SweepSizesArgs(benchmark::internal::Benchmark * b)88 static void SweepSizesArgs(benchmark::internal::Benchmark* b) {
89 b->Args({0, 0});
90 for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) {
91 b->Args({i, 0});
92 b->Args({0, i});
93 b->Args({i, i});
94 }
95 }
96
97 BENCHMARK_TEMPLATE(BM_UnaryPingPong, ChaoticGoodFixture, NoOpMutator,
98 NoOpMutator)
99 ->Apply(SweepSizesArgs);
100
101 } // namespace testing
102 } // namespace grpc
103
104 // Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
105 // and others do not. This allows us to support both modes.
106 namespace benchmark {
RunTheBenchmarksNamespaced()107 void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
108 } // namespace benchmark
109
main(int argc,char ** argv)110 int main(int argc, char** argv) {
111 grpc_core::ForceEnableExperiment("event_engine_client", true);
112 grpc_core::ForceEnableExperiment("event_engine_listener", true);
113 grpc_core::ForceEnableExperiment("promise_based_client_call", true);
114 grpc_core::ForceEnableExperiment("promise_based_server_call", true);
115 grpc_core::ForceEnableExperiment("chaotic_good", true);
116 grpc::testing::TestEnvironment env(&argc, argv);
117 LibraryInitializer libInit;
118 ::benchmark::Initialize(&argc, argv);
119 grpc::testing::InitTest(&argc, &argv, false);
120 benchmark::RunTheBenchmarksNamespaced();
121 return 0;
122 }
123