Merge github.com:grpc/grpc into latent-see

pull/36964/head
Craig Tiller 5 months ago
commit 251f2d885b
  1. 96
      CMakeLists.txt
  2. 2
      bazel/experiments.bzl
  3. 74
      build_autogenerated.yaml
  4. 1
      src/core/ext/transport/chaotic_good/client_transport.cc
  5. 4
      src/core/ext/transport/chaotic_good/server_transport.cc
  6. 4
      src/core/lib/debug/trace_impl.h
  7. 17
      src/core/lib/experiments/experiments.cc
  8. 1
      src/core/lib/experiments/rollouts.yaml
  9. 4
      test/core/call/client_call_test.cc
  10. 4
      test/core/call/corpus/client_call/clusterfuzz-testcase-minimized-client_call_fuzzer-4634405960482816
  11. 12
      test/core/test_util/BUILD
  12. 131
      test/core/test_util/passthrough_endpoint.cc
  13. 95
      test/core/test_util/passthrough_endpoint.h
  14. 48
      test/core/transport/benchmarks/BUILD
  15. 93
      test/core/transport/benchmarks/bm_chaotic_good.cc
  16. 83
      test/core/transport/benchmarks/bm_inproc.cc
  17. 83
      test/core/transport/call_spine_benchmarks.h
  18. 44
      tools/run_tests/generated/tests.json
  19. 15
      tools/run_tests/sanity/banned_functions.py

96
CMakeLists.txt generated

@ -889,6 +889,9 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_call_spine)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_chaotic_good)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_client_call)
endif()
@ -901,6 +904,9 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_http_client_filter)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_inproc)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_party)
endif()
@ -5872,6 +5878,51 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
)
endif()
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_executable(bm_chaotic_good
src/core/ext/transport/chaotic_good/client_transport.cc
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/ext/transport/chaotic_good/server_transport.cc
src/core/lib/transport/promise_endpoint.cc
test/core/test_util/passthrough_endpoint.cc
test/core/transport/benchmarks/bm_chaotic_good.cc
)
if(WIN32 AND MSVC)
if(BUILD_SHARED_LIBS)
target_compile_definitions(bm_chaotic_good
PRIVATE
"GPR_DLL_IMPORTS"
"GRPC_DLL_IMPORTS"
)
endif()
endif()
target_compile_features(bm_chaotic_good PUBLIC cxx_std_14)
target_include_directories(bm_chaotic_good
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(bm_chaotic_good
${_gRPC_ALLTARGETS_LIBRARIES}
${_gRPC_BENCHMARK_LIBRARIES}
grpc
)
endif()
endif()
if(gRPC_BUILD_TESTS)
@ -6028,6 +6079,51 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
)
endif()
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_executable(bm_inproc
src/core/ext/transport/chaotic_good/client_transport.cc
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/ext/transport/chaotic_good/server_transport.cc
src/core/lib/transport/promise_endpoint.cc
test/core/test_util/passthrough_endpoint.cc
test/core/transport/benchmarks/bm_inproc.cc
)
if(WIN32 AND MSVC)
if(BUILD_SHARED_LIBS)
target_compile_definitions(bm_inproc
PRIVATE
"GPR_DLL_IMPORTS"
"GRPC_DLL_IMPORTS"
)
endif()
endif()
target_compile_features(bm_inproc PUBLIC cxx_std_14)
target_include_directories(bm_inproc
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(bm_inproc
${_gRPC_ALLTARGETS_LIBRARIES}
${_gRPC_BENCHMARK_LIBRARIES}
grpc
)
endif()
endif()
if(gRPC_BUILD_TESTS)

@ -41,7 +41,7 @@ EXPERIMENT_ENABLES = {
"trace_record_callops": "trace_record_callops",
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
"work_serializer_dispatch": "event_engine_client,work_serializer_dispatch",
"work_serializer_dispatch": "work_serializer_dispatch",
}
EXPERIMENT_POLLERS = [

@ -5163,6 +5163,43 @@ targets:
- linux
- posix
uses_polling: false
- name: bm_chaotic_good
build: test
language: c
headers:
- src/core/ext/transport/chaotic_good/chaotic_good_transport.h
- src/core/ext/transport/chaotic_good/client_transport.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/ext/transport/chaotic_good/server_transport.h
- src/core/lib/promise/event_engine_wakeup_scheduler.h
- src/core/lib/promise/inter_activity_latch.h
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/mpsc.h
- src/core/lib/promise/switch.h
- src/core/lib/promise/wait_set.h
- src/core/lib/transport/promise_endpoint.h
- test/core/test_util/passthrough_endpoint.h
- test/core/transport/call_spine_benchmarks.h
src:
- src/core/ext/transport/chaotic_good/client_transport.cc
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/ext/transport/chaotic_good/server_transport.cc
- src/core/lib/transport/promise_endpoint.cc
- test/core/test_util/passthrough_endpoint.cc
- test/core/transport/benchmarks/bm_chaotic_good.cc
deps:
- benchmark
- grpc
args:
- --benchmark_min_time=0.001s
benchmark: true
defaults: benchmark
platforms:
- linux
- posix
uses_polling: false
- name: bm_client_call
build: test
language: c
@ -5233,6 +5270,43 @@ targets:
- linux
- posix
uses_polling: false
- name: bm_inproc
build: test
language: c
headers:
- src/core/ext/transport/chaotic_good/chaotic_good_transport.h
- src/core/ext/transport/chaotic_good/client_transport.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/ext/transport/chaotic_good/server_transport.h
- src/core/lib/promise/event_engine_wakeup_scheduler.h
- src/core/lib/promise/inter_activity_latch.h
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/mpsc.h
- src/core/lib/promise/switch.h
- src/core/lib/promise/wait_set.h
- src/core/lib/transport/promise_endpoint.h
- test/core/test_util/passthrough_endpoint.h
- test/core/transport/call_spine_benchmarks.h
src:
- src/core/ext/transport/chaotic_good/client_transport.cc
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/ext/transport/chaotic_good/server_transport.cc
- src/core/lib/transport/promise_endpoint.cc
- test/core/test_util/passthrough_endpoint.cc
- test/core/transport/benchmarks/bm_inproc.cc
deps:
- benchmark
- grpc
args:
- --benchmark_min_time=0.001s
benchmark: true
defaults: benchmark
platforms:
- linux
- posix
uses_polling: false
- name: bm_party
build: test
language: c

@ -58,7 +58,6 @@ namespace grpc_core {
namespace chaotic_good {
void ChaoticGoodClientTransport::Orphan() {
LOG(INFO) << "ChaoticGoodClientTransport::Orphan";
AbortWithError();
ActivityPtr writer;
ActivityPtr reader;

@ -323,9 +323,7 @@ auto ChaoticGoodServerTransport::ReadOneFrame(ChaoticGoodTransport& transport) {
return absl::OkStatus();
});
},
[]() -> absl::Status {
return absl::InternalError("Unexpected cancel frame");
});
[]() -> absl::Status { return absl::OkStatus(); });
}),
Default([frame_header]() {
return absl::InternalError(

@ -25,6 +25,10 @@
#include <grpc/support/port_platform.h>
#ifdef _WIN32
#undef ERROR
#endif
void grpc_tracer_init();
void grpc_tracer_shutdown(void);

@ -16,8 +16,6 @@
#include "src/core/lib/experiments/experiments.h"
#include <stdint.h>
#include <grpc/support/port_platform.h>
#ifndef GRPC_EXPERIMENTS_ARE_FINAL
@ -114,8 +112,6 @@ const char* const description_work_serializer_dispatch =
"callback, instead of running things inline in the first thread that "
"successfully enqueues work.";
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
} // namespace
namespace grpc_core {
@ -181,8 +177,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
true},
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
additional_constraints_work_serializer_dispatch, nullptr, 0, false, true},
};
} // namespace grpc_core
@ -279,8 +274,6 @@ const char* const description_work_serializer_dispatch =
"callback, instead of running things inline in the first thread that "
"successfully enqueues work.";
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
} // namespace
namespace grpc_core {
@ -346,8 +339,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
true},
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
additional_constraints_work_serializer_dispatch, nullptr, 0, false, true},
};
} // namespace grpc_core
@ -444,8 +436,6 @@ const char* const description_work_serializer_dispatch =
"callback, instead of running things inline in the first thread that "
"successfully enqueues work.";
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
} // namespace
namespace grpc_core {
@ -511,8 +501,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
true},
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, true, true},
additional_constraints_work_serializer_dispatch, nullptr, 0, true, true},
};
} // namespace grpc_core

@ -111,7 +111,6 @@
- name: work_serializer_clears_time_cache
default: true
- name: work_serializer_dispatch
requires: ["event_engine_client"]
default:
# TODO(ysseung): Not fully tested.
ios: broken

@ -217,7 +217,9 @@ CLIENT_CALL_TEST(SendInitialMetadataAndReceiveStatusAfterTimeout) {
ExecCtx::Get()->InvalidateNow();
auto now = Timestamp::Now();
EXPECT_GE(now - start, Duration::Seconds(1)) << GRPC_DUMP_ARGS(now, start);
EXPECT_LE(now - start, Duration::Seconds(5)) << GRPC_DUMP_ARGS(now, start);
EXPECT_LE(now - start,
g_yodel_fuzzing ? Duration::Minutes(10) : Duration::Seconds(5))
<< GRPC_DUMP_ARGS(now, start);
WaitForAllPendingWork();
}

@ -0,0 +1,4 @@
test_id: 178
event_engine_actions {
run_delay: 261993005056
}

@ -535,3 +535,15 @@ grpc_cc_library(
"//src/core:metrics",
],
)
grpc_cc_library(
name = "passthrough_endpoint",
testonly = True,
srcs = ["passthrough_endpoint.cc"],
hdrs = ["passthrough_endpoint.h"],
external_deps = [
],
deps = [
"//:grpc",
],
)

@ -0,0 +1,131 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/core/test_util/passthrough_endpoint.h"
namespace grpc_event_engine {
namespace experimental {
class PassthroughEndpoint::CallbackHelper {
public:
CallbackHelper(EventEngine* event_engine, bool allow_inline_callbacks)
: event_engine_(allow_inline_callbacks ? nullptr : event_engine) {}
template <typename F>
void AddCallback(F&& callback) {
if (event_engine_ != nullptr) {
event_engine_->Run(std::forward<F>(callback));
} else {
callbacks_.emplace_back(std::forward<F>(callback));
}
}
~CallbackHelper() {
for (auto& callback : callbacks_) {
callback();
}
}
private:
EventEngine* event_engine_;
absl::InlinedVector<absl::AnyInvocable<void()>, 4> callbacks_;
};
PassthroughEndpoint::PassthroughEndpointPair
PassthroughEndpoint::MakePassthroughEndpoint(int client_port, int server_port,
bool allow_inline_callbacks) {
auto send_middle =
grpc_core::MakeRefCounted<PassthroughEndpoint::Middle>(client_port);
auto recv_middle =
grpc_core::MakeRefCounted<PassthroughEndpoint::Middle>(server_port);
auto client = std::unique_ptr<PassthroughEndpoint>(new PassthroughEndpoint(
send_middle, recv_middle, allow_inline_callbacks));
auto server = std::unique_ptr<PassthroughEndpoint>(new PassthroughEndpoint(
recv_middle, send_middle, allow_inline_callbacks));
return {std::move(client), std::move(server)};
}
PassthroughEndpoint::~PassthroughEndpoint() {
CallbackHelper callback_helper(event_engine_.get(), allow_inline_callbacks_);
send_middle_->Close(callback_helper);
recv_middle_->Close(callback_helper);
}
bool PassthroughEndpoint::Read(absl::AnyInvocable<void(absl::Status)> on_read,
SliceBuffer* buffer, const ReadArgs*) {
CallbackHelper callback_helper(event_engine_.get(), allow_inline_callbacks_);
grpc_core::MutexLock lock(&recv_middle_->mu);
if (recv_middle_->closed) {
callback_helper.AddCallback([on_read = std::move(on_read)]() mutable {
on_read(absl::CancelledError());
});
return false;
}
if (recv_middle_->on_write != nullptr) {
*buffer = std::move(*recv_middle_->write_buffer);
callback_helper.AddCallback(
[on_write = std::move(recv_middle_->on_write)]() mutable {
on_write(absl::OkStatus());
});
recv_middle_->on_write = nullptr;
return true;
}
recv_middle_->read_buffer = buffer;
recv_middle_->on_read = std::move(on_read);
return false;
}
bool PassthroughEndpoint::Write(absl::AnyInvocable<void(absl::Status)> on_write,
SliceBuffer* buffer, const WriteArgs*) {
CallbackHelper callback_helper(event_engine_.get(), allow_inline_callbacks_);
grpc_core::MutexLock lock(&send_middle_->mu);
if (send_middle_->closed) {
callback_helper.AddCallback([on_write = std::move(on_write)]() mutable {
on_write(absl::CancelledError());
});
return false;
}
if (send_middle_->on_read != nullptr) {
*send_middle_->read_buffer = std::move(*buffer);
callback_helper.AddCallback(
[on_read = std::move(send_middle_->on_read)]() mutable {
on_read(absl::OkStatus());
});
send_middle_->on_read = nullptr;
return true;
}
send_middle_->write_buffer = buffer;
send_middle_->on_write = std::move(on_write);
return false;
}
void PassthroughEndpoint::Middle::Close(CallbackHelper& callback_helper) {
grpc_core::MutexLock lock(&mu);
closed = true;
if (on_read != nullptr) {
callback_helper.AddCallback([on_read = std::move(on_read)]() mutable {
on_read(absl::CancelledError());
});
on_read = nullptr;
}
if (on_write != nullptr) {
callback_helper.AddCallback([on_write = std::move(on_write)]() mutable {
on_write(absl::CancelledError());
});
on_write = nullptr;
}
}
} // namespace experimental
} // namespace grpc_event_engine

@ -0,0 +1,95 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_TEST_CORE_TEST_UTIL_PASSTHROUGH_ENDPOINT_H
#define GRPC_TEST_CORE_TEST_UTIL_PASSTHROUGH_ENDPOINT_H
#include <memory>
#include <grpc/event_engine/event_engine.h>
#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/event_engine/tcp_socket_utils.h"
#include "src/core/lib/gprpp/ref_counted.h"
namespace grpc_event_engine {
namespace experimental {
class PassthroughEndpoint final : public EventEngine::Endpoint {
public:
struct PassthroughEndpointPair {
std::unique_ptr<PassthroughEndpoint> client;
std::unique_ptr<PassthroughEndpoint> server;
};
// client_port, server_port are markers that are baked into the peer/local
// addresses for debug information.
// allow_inline_callbacks is a flag that allows the endpoint to call the
// on_read/on_write callbacks inline (but outside any PassthroughEndpoint
// locks)
static PassthroughEndpointPair MakePassthroughEndpoint(
int client_port, int server_port, bool allow_inline_callbacks);
~PassthroughEndpoint() override;
bool Read(absl::AnyInvocable<void(absl::Status)> on_read, SliceBuffer* buffer,
const ReadArgs* args) override;
bool Write(absl::AnyInvocable<void(absl::Status)> on_write,
SliceBuffer* buffer, const WriteArgs* args) override;
const EventEngine::ResolvedAddress& GetPeerAddress() const override {
return recv_middle_->address;
}
const EventEngine::ResolvedAddress& GetLocalAddress() const override {
return send_middle_->address;
}
private:
class CallbackHelper;
struct Middle : public grpc_core::RefCounted<Middle> {
explicit Middle(int port)
: address(URIToResolvedAddress(absl::StrCat("ipv4:127.0.0.1:", port))
.value()) {}
void Close(CallbackHelper& callback_helper);
grpc_core::Mutex mu;
bool closed ABSL_GUARDED_BY(mu) = false;
SliceBuffer* read_buffer ABSL_GUARDED_BY(mu) = nullptr;
absl::AnyInvocable<void(absl::Status)> on_read ABSL_GUARDED_BY(mu) =
nullptr;
SliceBuffer* write_buffer ABSL_GUARDED_BY(mu) = nullptr;
absl::AnyInvocable<void(absl::Status)> on_write ABSL_GUARDED_BY(mu) =
nullptr;
EventEngine::ResolvedAddress address;
};
PassthroughEndpoint(grpc_core::RefCountedPtr<Middle> send_middle,
grpc_core::RefCountedPtr<Middle> recv_middle,
bool allow_inline_callbacks)
: send_middle_(std::move(send_middle)),
recv_middle_(std::move(recv_middle)),
allow_inline_callbacks_(allow_inline_callbacks) {}
grpc_core::RefCountedPtr<Middle> send_middle_;
grpc_core::RefCountedPtr<Middle> recv_middle_;
std::shared_ptr<EventEngine> event_engine_ = GetDefaultEventEngine();
bool allow_inline_callbacks_;
};
} // namespace experimental
} // namespace grpc_event_engine
#endif // GRPC_TEST_CORE_TEST_UTIL_PASSTHROUGH_ENDPOINT_H

@ -0,0 +1,48 @@
# Copyright 2021 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("//bazel:grpc_build_system.bzl", "grpc_package")
load("//test/cpp/microbenchmarks:grpc_benchmark_config.bzl", "grpc_cc_benchmark")
licenses(["notice"])
grpc_package(
name = "test/core/transport/benchmarks",
)
grpc_cc_benchmark(
name = "bm_chaotic_good",
srcs = ["bm_chaotic_good.cc"],
deps = [
"//:grpc",
"//src/core:chaotic_good_client_transport",
"//src/core:chaotic_good_server_transport",
"//src/core:default_event_engine",
"//test/core/test_util:passthrough_endpoint",
"//test/core/transport:call_spine_benchmarks",
],
)
grpc_cc_benchmark(
name = "bm_inproc",
srcs = ["bm_inproc.cc"],
deps = [
"//:grpc",
"//src/core:chaotic_good_client_transport",
"//src/core:chaotic_good_server_transport",
"//src/core:default_event_engine",
"//test/core/test_util:passthrough_endpoint",
"//test/core/transport:call_spine_benchmarks",
],
)

@ -0,0 +1,93 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <benchmark/benchmark.h>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include <grpc/grpc.h>
#include "src/core/ext/transport/chaotic_good/client_transport.h"
#include "src/core/ext/transport/chaotic_good/server_transport.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "test/core/test_util/passthrough_endpoint.h"
#include "test/core/transport/call_spine_benchmarks.h"
namespace grpc_core {
namespace {
const Slice kTestPath = Slice::FromExternalString("/foo/bar");
class ChaoticGoodTraits {
public:
BenchmarkTransport MakeTransport() {
auto channel_args = CoreConfiguration::Get()
.channel_args_preconditioning()
.PreconditionChannelArgs(nullptr);
auto control = grpc_event_engine::experimental::PassthroughEndpoint::
MakePassthroughEndpoint(1, 2, true);
auto data = grpc_event_engine::experimental::PassthroughEndpoint::
MakePassthroughEndpoint(3, 4, true);
auto client = MakeOrphanable<chaotic_good::ChaoticGoodClientTransport>(
PromiseEndpoint(std::move(control.client), SliceBuffer()),
PromiseEndpoint(std::move(data.client), SliceBuffer()), channel_args,
grpc_event_engine::experimental::GetDefaultEventEngine(), HPackParser(),
HPackCompressor());
auto server = MakeOrphanable<chaotic_good::ChaoticGoodServerTransport>(
channel_args, PromiseEndpoint(std::move(control.server), SliceBuffer()),
PromiseEndpoint(std::move(data.server), SliceBuffer()),
grpc_event_engine::experimental::GetDefaultEventEngine(), HPackParser(),
HPackCompressor());
return {std::move(client), std::move(server)};
}
ClientMetadataHandle MakeClientInitialMetadata() {
auto md = Arena::MakePooled<ClientMetadata>();
md->Set(HttpPathMetadata(), kTestPath.Copy());
return md;
}
ServerMetadataHandle MakeServerInitialMetadata() {
return Arena::MakePooled<ServerMetadata>();
}
MessageHandle MakePayload() { return Arena::MakePooled<Message>(); }
ServerMetadataHandle MakeServerTrailingMetadata() {
auto md = Arena::MakePooled<ServerMetadata>();
return md;
}
};
GRPC_CALL_SPINE_BENCHMARK(TransportFixture<ChaoticGoodTraits>);
} // namespace
} // namespace grpc_core
// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
// and others do not. This allows us to support both modes.
namespace benchmark {
void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
} // namespace benchmark
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
grpc_init();
{
auto ee = grpc_event_engine::experimental::GetDefaultEventEngine();
benchmark::RunTheBenchmarksNamespaced();
}
grpc_shutdown();
return 0;
}

@ -0,0 +1,83 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <memory>
#include <benchmark/benchmark.h>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include <grpc/grpc.h>
#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "test/core/transport/call_spine_benchmarks.h"
namespace grpc_core {
namespace {
const Slice kTestPath = Slice::FromExternalString("/foo/bar");
class InprocTraits {
public:
BenchmarkTransport MakeTransport() {
auto channel_args = CoreConfiguration::Get()
.channel_args_preconditioning()
.PreconditionChannelArgs(nullptr);
auto t = MakeInProcessTransportPair(channel_args);
return {OrphanablePtr<ClientTransport>(
DownCast<ClientTransport*>(t.first.release())),
OrphanablePtr<ServerTransport>(
DownCast<ServerTransport*>(t.second.release()))};
}
ClientMetadataHandle MakeClientInitialMetadata() {
auto md = Arena::MakePooled<ClientMetadata>();
md->Set(HttpPathMetadata(), kTestPath.Copy());
return md;
}
ServerMetadataHandle MakeServerInitialMetadata() {
return Arena::MakePooled<ServerMetadata>();
}
MessageHandle MakePayload() { return Arena::MakePooled<Message>(); }
ServerMetadataHandle MakeServerTrailingMetadata() {
auto md = Arena::MakePooled<ServerMetadata>();
return md;
}
};
GRPC_CALL_SPINE_BENCHMARK(TransportFixture<InprocTraits>);
} // namespace
} // namespace grpc_core
// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
// and others do not. This allows us to support both modes.
namespace benchmark {
void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
} // namespace benchmark
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
grpc_init();
{
auto ee = grpc_event_engine::experimental::GetDefaultEventEngine();
benchmark::RunTheBenchmarksNamespaced();
}
grpc_shutdown();
return 0;
}

@ -27,6 +27,7 @@
#include "src/core/lib/promise/map.h"
#include "src/core/lib/resource_quota/resource_quota.h"
#include "src/core/lib/transport/call_spine.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
@ -361,6 +362,88 @@ class UnstartedCallDestinationFixture {
traits_->CreateCallDestination(bottom_destination_);
};
// Base class for transports
// Traits should have MakeClientInitialMetadata, MakeServerInitialMetadata,
// MakePayload, MakeServerTrailingMetadata.
// They should also have a MakeTransport returning a BenchmarkTransport.
struct BenchmarkTransport {
OrphanablePtr<ClientTransport> client;
OrphanablePtr<ServerTransport> server;
};
template <class Traits>
class TransportFixture {
public:
TransportFixture() { transport_.server->SetCallDestination(acceptor_); };
BenchmarkCall MakeCall() {
auto arena = arena_allocator_->MakeArena();
arena->SetContext<grpc_event_engine::experimental::EventEngine>(
event_engine_.get());
auto p =
MakeCallPair(traits_.MakeClientInitialMetadata(), std::move(arena));
transport_.client->StartCall(p.handler.StartCall());
auto handler = acceptor_->TakeHandler();
absl::optional<CallHandler> started_handler;
Notification started;
handler.SpawnInfallible("handler_setup", [&]() {
started_handler = handler.StartCall();
started.Notify();
return Empty{};
});
started.WaitForNotification();
CHECK(started_handler.has_value());
return {std::move(p.initiator), std::move(*started_handler)};
}
ServerMetadataHandle MakeServerInitialMetadata() {
return traits_.MakeServerInitialMetadata();
}
MessageHandle MakePayload() { return traits_.MakePayload(); }
ServerMetadataHandle MakeServerTrailingMetadata() {
return traits_.MakeServerTrailingMetadata();
}
private:
class Acceptor : public UnstartedCallDestination {
public:
void StartCall(UnstartedCallHandler handler) override {
MutexLock lock(&mu_);
handler_ = std::move(handler);
}
void Orphaned() override {}
UnstartedCallHandler TakeHandler() {
mu_.LockWhen(absl::Condition(
+[](Acceptor* dest) ABSL_EXCLUSIVE_LOCKS_REQUIRED(dest->mu_) {
return dest->handler_.has_value();
},
this));
auto h = std::move(*handler_);
handler_.reset();
mu_.Unlock();
return h;
}
absl::Mutex mu_;
absl::optional<UnstartedCallHandler> handler_ ABSL_GUARDED_BY(mu_);
};
Traits traits_;
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_ =
grpc_event_engine::experimental::GetDefaultEventEngine();
RefCountedPtr<CallArenaAllocator> arena_allocator_ =
MakeRefCounted<CallArenaAllocator>(
ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator(
"test-allocator"),
1024);
RefCountedPtr<Acceptor> acceptor_ = MakeRefCounted<Acceptor>();
BenchmarkTransport transport_ = traits_.MakeTransport();
};
} // namespace grpc_core
// Declare all relevant benchmarks for a given fixture

@ -23,6 +23,28 @@
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"
],
"benchmark": true,
"ci_platforms": [
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "bm_chaotic_good",
"platforms": [
"linux",
"posix"
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"
@ -111,6 +133,28 @@
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"
],
"benchmark": true,
"ci_platforms": [
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "bm_inproc",
"platforms": [
"linux",
"posix"
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"

@ -76,7 +76,6 @@ DEPRECATED_FUNCTION_TEMP_ALLOW_LIST = {
"./src/core/ext/transport/chaotic_good/server_transport.cc",
"./src/core/ext/transport/chttp2/client/chttp2_connector.cc",
"./src/core/ext/transport/chttp2/transport/bin_decoder.cc",
"./src/core/ext/transport/chttp2/transport/chttp2_transport.cc",
"./src/core/ext/transport/chttp2/transport/flow_control.cc",
"./src/core/ext/transport/chttp2/transport/frame_ping.cc",
"./src/core/ext/transport/chttp2/transport/frame_rst_stream.cc",
@ -123,8 +122,6 @@ DEPRECATED_FUNCTION_TEMP_ALLOW_LIST = {
"./src/core/lib/iomgr/socket_utils_common_posix.cc",
"./src/core/lib/iomgr/tcp_client_cfstream.cc",
"./src/core/lib/iomgr/tcp_client_posix.cc",
"./src/core/lib/iomgr/tcp_posix.cc",
"./src/core/lib/iomgr/tcp_server_posix.cc",
"./src/core/lib/iomgr/tcp_windows.cc",
"./src/core/lib/iomgr/timer_generic.cc",
"./src/core/lib/iomgr/timer_manager.cc",
@ -165,18 +162,6 @@ DEPRECATED_FUNCTION_TEMP_ALLOW_LIST = {
"./src/core/resolver/xds/xds_resolver.cc",
"./src/core/server/server.cc",
"./src/core/server/xds_server_config_fetcher.cc",
"./src/core/tsi/alts/frame_protector/frame_handler.cc",
"./src/core/tsi/alts/handshaker/alts_handshaker_client.cc",
"./src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc",
"./src/core/tsi/alts/handshaker/transport_security_common_api.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc",
"./src/core/tsi/fake_transport_security.cc",
"./src/core/tsi/ssl/key_logging/ssl_key_logging.cc",
"./src/core/tsi/ssl_transport_security.cc",
"./src/core/tsi/ssl_transport_security_utils.cc",
"./src/core/util/android/log.cc",
"./src/core/util/linux/log.cc",
"./src/core/util/posix/log.cc",

Loading…
Cancel
Save