[testing] Add a test of server handling of calls that expired in the request matcher (#34679)

Also expand core_end2end_test suite to allow testing of server
registered methods

---------

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/34691/head
Craig Tiller 1 year ago committed by GitHub
parent a54c7f7266
commit bfb98d89ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      CMakeLists.txt
  2. 36
      build_autogenerated.yaml
  3. 4
      test/core/end2end/BUILD
  4. 1
      test/core/end2end/end2end_test_corpus/timeout_before_request_call/empty
  5. 51
      test/core/end2end/end2end_test_suites.cc
  6. 34
      test/core/end2end/end2end_tests.cc
  7. 42
      test/core/end2end/end2end_tests.h
  8. 17
      test/core/end2end/fixtures/inproc_fixture.h
  9. 6
      test/core/end2end/fixtures/local_util.cc
  10. 7
      test/core/end2end/fixtures/local_util.h
  11. 8
      test/core/end2end/fixtures/secure_fixture.h
  12. 7
      test/core/end2end/fixtures/sockpair_fixture.h
  13. 5
      test/core/end2end/h2_ssl_cert_test.cc
  14. 173
      test/core/end2end/tests/timeout_before_request_call.cc
  15. 24
      tools/run_tests/generated/tests.json

45
CMakeLists.txt generated

@ -1403,6 +1403,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx time_jump_test)
endif()
add_dependencies(buildtests_cxx time_util_test)
add_dependencies(buildtests_cxx timeout_before_request_call_test)
add_dependencies(buildtests_cxx timeout_encoding_test)
add_dependencies(buildtests_cxx timer_manager_test)
add_dependencies(buildtests_cxx timer_test)
@ -24778,6 +24779,50 @@ target_link_libraries(time_util_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(timeout_before_request_call_test
test/core/end2end/cq_verifier.cc
test/core/end2end/end2end_test_main.cc
test/core/end2end/end2end_test_suites.cc
test/core/end2end/end2end_tests.cc
test/core/end2end/fixtures/http_proxy_fixture.cc
test/core/end2end/fixtures/local_util.cc
test/core/end2end/fixtures/proxy.cc
test/core/end2end/tests/timeout_before_request_call.cc
test/core/event_engine/event_engine_test_utils.cc
test/core/util/test_lb_policies.cc
)
target_compile_features(timeout_before_request_call_test PUBLIC cxx_std_14)
target_include_directories(timeout_before_request_call_test
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}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(timeout_before_request_call_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
grpc_authorization_provider
grpc_unsecure
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)

@ -16455,6 +16455,42 @@ targets:
- gtest
- grpc_test_util
uses_polling: false
- name: timeout_before_request_call_test
gtest: true
build: test
language: c++
headers:
- test/core/end2end/cq_verifier.h
- test/core/end2end/end2end_tests.h
- test/core/end2end/fixtures/h2_oauth2_common.h
- test/core/end2end/fixtures/h2_ssl_cred_reload_fixture.h
- test/core/end2end/fixtures/h2_ssl_tls_common.h
- test/core/end2end/fixtures/h2_tls_common.h
- test/core/end2end/fixtures/http_proxy_fixture.h
- test/core/end2end/fixtures/inproc_fixture.h
- test/core/end2end/fixtures/local_util.h
- test/core/end2end/fixtures/proxy.h
- test/core/end2end/fixtures/secure_fixture.h
- test/core/end2end/fixtures/sockpair_fixture.h
- test/core/end2end/tests/cancel_test_helpers.h
- test/core/event_engine/event_engine_test_utils.h
- test/core/util/test_lb_policies.h
src:
- test/core/end2end/cq_verifier.cc
- test/core/end2end/end2end_test_main.cc
- test/core/end2end/end2end_test_suites.cc
- test/core/end2end/end2end_tests.cc
- test/core/end2end/fixtures/http_proxy_fixture.cc
- test/core/end2end/fixtures/local_util.cc
- test/core/end2end/fixtures/proxy.cc
- test/core/end2end/tests/timeout_before_request_call.cc
- test/core/event_engine/event_engine_test_utils.cc
- test/core/util/test_lb_policies.cc
deps:
- gtest
- grpc_authorization_provider
- grpc_unsecure
- grpc_test_util
- name: timeout_encoding_test
gtest: true
build: test

@ -158,6 +158,7 @@ grpc_cc_library(
"tests/cancel_test_helpers.h",
],
external_deps = [
"absl/functional:any_invocable",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -196,6 +197,7 @@ grpc_cc_library(
],
external_deps = [
"absl/base:core_headers",
"absl/functional:any_invocable",
"absl/meta:type_traits",
"absl/random",
"absl/status",
@ -446,6 +448,8 @@ grpc_core_end2end_test(name = "simple_request")
grpc_core_end2end_test(name = "streaming_error_response")
grpc_core_end2end_test(name = "timeout_before_request_call")
grpc_core_end2end_test(name = "trailing_metadata")
grpc_core_end2end_test(name = "write_buffering")

@ -25,6 +25,7 @@
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/functional/any_invocable.h"
#include "absl/meta/type_traits.h"
#include "absl/random/random.h"
#include "absl/status/status.h"
@ -122,8 +123,9 @@ void AddFailAuthCheckIfNeeded(const ChannelArgs& args,
class CensusFixture : public CoreTestFixture {
private:
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
grpc_server_credentials* server_creds =
grpc_insecure_server_credentials_create();
auto* server = grpc_server_create(
@ -132,6 +134,7 @@ class CensusFixture : public CoreTestFixture {
GPR_ASSERT(
grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
grpc_server_credentials_release(server_creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}
@ -150,8 +153,9 @@ class CensusFixture : public CoreTestFixture {
class CompressionFixture : public CoreTestFixture {
private:
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
auto* server = grpc_server_create(
args.SetIfUnset(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
GRPC_COMPRESS_GZIP)
@ -164,6 +168,7 @@ class CompressionFixture : public CoreTestFixture {
GPR_ASSERT(
grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
grpc_server_credentials_release(server_creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}
@ -246,11 +251,13 @@ class FdFixture : public CoreTestFixture {
FdFixture() { create_sockets(fd_pair_); }
private:
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
ExecCtx exec_ctx;
auto* server = grpc_server_create(args.ToC().get(), nullptr);
grpc_server_register_completion_queue(server, cq, nullptr);
pre_server_start(server);
grpc_server_start(server);
grpc_server_credentials* creds = grpc_insecure_server_credentials_create();
grpc_server_add_channel_from_fd(server, fd_pair_[1], creds);
@ -298,8 +305,9 @@ class HttpProxyFilter : public CoreTestFixture {
~HttpProxyFilter() override { grpc_end2end_http_proxy_destroy(proxy_); }
private:
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
auto* server = grpc_server_create(args.ToC().get(), nullptr);
grpc_server_register_completion_queue(server, cq, nullptr);
grpc_server_credentials* server_creds =
@ -307,6 +315,7 @@ class HttpProxyFilter : public CoreTestFixture {
GPR_ASSERT(
grpc_server_add_http2_port(server, server_addr_.c_str(), server_creds));
grpc_server_credentials_release(server_creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}
@ -365,8 +374,9 @@ class ProxyFixture : public CoreTestFixture {
return channel;
}
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
auto* server = grpc_server_create(args.ToC().get(), nullptr);
grpc_server_register_completion_queue(server, cq, nullptr);
grpc_server_credentials* server_creds =
@ -374,6 +384,7 @@ class ProxyFixture : public CoreTestFixture {
GPR_ASSERT(grpc_server_add_http2_port(
server, grpc_end2end_proxy_get_server_port(proxy_), server_creds));
grpc_server_credentials_release(server_creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}
@ -443,8 +454,9 @@ class SslProxyFixture : public CoreTestFixture {
return channel;
}
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
grpc_slice cert_slice, key_slice;
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
@ -470,6 +482,7 @@ class SslProxyFixture : public CoreTestFixture {
GPR_ASSERT(grpc_server_add_http2_port(
server, grpc_end2end_proxy_get_server_port(proxy_), ssl_creds));
grpc_server_credentials_release(ssl_creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}
@ -506,9 +519,10 @@ class FixtureWithTracing final : public CoreTestFixture {
// g_fixture_slowdown_factor = 1;
}
grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) override {
return fixture_->MakeServer(args, cq);
grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
return fixture_->MakeServer(args, cq, pre_server_start);
}
grpc_channel* MakeClient(const ChannelArgs& args,
@ -1028,6 +1042,13 @@ CORE_END2END_TEST_SUITE(
CoreDeadlineTest,
ConfigQuery().ExcludeFeatures(FEATURE_MASK_IS_MINSTACK).Run());
CORE_END2END_TEST_SUITE(
CoreDeadlineSingleHopTest,
ConfigQuery()
.ExcludeFeatures(FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
FEATURE_MASK_IS_MINSTACK)
.Run());
CORE_END2END_TEST_SUITE(
CoreClientChannelTest,
ConfigQuery().EnforceFeatures(FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL).Run());

@ -319,12 +319,40 @@ CoreEnd2endTest::Call CoreEnd2endTest::ClientCallBuilder::Create() {
}
}
CoreEnd2endTest::ServerRegisteredMethod::ServerRegisteredMethod(
CoreEnd2endTest* test, absl::string_view name,
grpc_server_register_method_payload_handling payload_handling) {
GPR_ASSERT(test->server_ == nullptr);
test->pre_server_start_ = [old = std::move(test->pre_server_start_),
handle = handle_, name = std::string(name),
payload_handling](grpc_server* server) mutable {
*handle = grpc_server_register_method(server, name.c_str(), nullptr,
payload_handling, 0);
old(server);
};
}
CoreEnd2endTest::IncomingCall::IncomingCall(CoreEnd2endTest& test, int tag)
: impl_(std::make_unique<Impl>(&test)) {
test.ForceInitialized();
grpc_server_request_call(test.server(), impl_->call.call_ptr(),
&impl_->call_details, &impl_->request_metadata,
test.cq(), test.cq(), CqVerifier::tag(tag));
EXPECT_EQ(
grpc_server_request_call(test.server(), impl_->call.call_ptr(),
&impl_->call_details, &impl_->request_metadata,
test.cq(), test.cq(), CqVerifier::tag(tag)),
GRPC_CALL_OK);
}
CoreEnd2endTest::IncomingCall::IncomingCall(CoreEnd2endTest& test, void* method,
IncomingMessage* message, int tag)
: impl_(std::make_unique<Impl>(&test)) {
test.ForceInitialized();
impl_->call_details.method = grpc_empty_slice();
EXPECT_EQ(grpc_server_request_registered_call(
test.server(), method, impl_->call.call_ptr(),
&impl_->call_details.deadline, &impl_->request_metadata,
message == nullptr ? nullptr : &message->payload_, test.cq(),
test.cq(), CqVerifier::tag(tag)),
GRPC_CALL_OK);
}
absl::optional<std::string> CoreEnd2endTest::IncomingCall::GetInitialMetadata(

@ -95,8 +95,9 @@ class CoreTestFixture {
public:
virtual ~CoreTestFixture() = default;
virtual grpc_server* MakeServer(const ChannelArgs& args,
grpc_completion_queue* cq) = 0;
virtual grpc_server* MakeServer(
const ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) = 0;
virtual grpc_channel* MakeClient(const ChannelArgs& args,
grpc_completion_queue* cq) = 0;
};
@ -242,6 +243,8 @@ class CoreEnd2endTest : public ::testing::Test {
grpc_metadata_array{0, 0, nullptr});
};
class IncomingCall;
// Receiving container for one incoming message.
class IncomingMessage final : public CqVerifier::SuccessfulStateString {
public:
@ -270,6 +273,7 @@ class CoreEnd2endTest : public ::testing::Test {
grpc_op MakeOp();
private:
friend class IncomingCall;
grpc_byte_buffer* payload_ = nullptr;
};
@ -504,6 +508,8 @@ class CoreEnd2endTest : public ::testing::Test {
class IncomingCall {
public:
IncomingCall(CoreEnd2endTest& test, int tag);
IncomingCall(CoreEnd2endTest& test, void* method, IncomingMessage* message,
int tag);
IncomingCall(const IncomingCall&) = delete;
IncomingCall& operator=(const IncomingCall&) = delete;
IncomingCall(IncomingCall&&) noexcept = default;
@ -561,6 +567,24 @@ class CoreEnd2endTest : public ::testing::Test {
std::unique_ptr<Impl> impl_;
};
class ServerRegisteredMethod {
public:
ServerRegisteredMethod(
CoreEnd2endTest* test, absl::string_view name,
grpc_server_register_method_payload_handling payload_handling);
void* handle() { return *handle_; }
private:
std::shared_ptr<void*> handle_ = std::make_shared<void*>(nullptr);
};
ServerRegisteredMethod RegisterServerMethod(
absl::string_view name,
grpc_server_register_method_payload_handling payload_handling) {
return ServerRegisteredMethod(this, name, payload_handling);
}
// Begin construction of a client call.
ClientCallBuilder NewClientCall(std::string method) {
return ClientCallBuilder(*this, std::move(method));
@ -570,6 +594,14 @@ class CoreEnd2endTest : public ::testing::Test {
}
// Request a call on the server - notifies `tag` when complete.
IncomingCall RequestCall(int tag) { return IncomingCall(*this, tag); }
// Request a call on the server - notifies `tag` when complete.
IncomingCall RequestRegisteredCall(ServerRegisteredMethod method, int tag) {
return IncomingCall(*this, method.handle(), nullptr, tag);
}
IncomingCall RequestRegisteredCall(ServerRegisteredMethod method,
IncomingMessage* message, int tag) {
return IncomingCall(*this, method.handle(), message, tag);
}
// Pull in CqVerifier types for ergonomics
// TODO(ctiller): evaluate just dropping CqVerifier and folding it in here.
@ -616,7 +648,7 @@ class CoreEnd2endTest : public ::testing::Test {
initialized_ = true;
if (server_ != nullptr) ShutdownAndDestroyServer();
auto& f = fixture();
server_ = f.MakeServer(args, cq_);
server_ = f.MakeServer(args, cq_, pre_server_start_);
GPR_ASSERT(server_ != nullptr);
}
// Remove the client.
@ -730,6 +762,8 @@ class CoreEnd2endTest : public ::testing::Test {
grpc_server* server_ = nullptr;
grpc_channel* client_ = nullptr;
std::unique_ptr<CqVerifier> cq_verifier_;
absl::AnyInvocable<void(grpc_server*)> pre_server_start_ = [](grpc_server*) {
};
int expectations_ = 0;
bool initialized_ = false;
absl::AnyInvocable<void()> post_grpc_init_func_ = []() {};
@ -755,6 +789,8 @@ class CoreLargeSendTest : public CoreEnd2endTest {};
class CoreClientChannelTest : public CoreEnd2endTest {};
// Test suite for tests that require deadline handling
class CoreDeadlineTest : public CoreEnd2endTest {};
// Test suite for tests that require deadline handling
class CoreDeadlineSingleHopTest : public CoreEnd2endTest {};
// Test suite for http2 tests that only work over a single hop (unproxyable)
class Http2SingleHopTest : public CoreEnd2endTest {};
// Test suite for tests that require retry features

@ -15,6 +15,8 @@
#ifndef GRPC_TEST_CORE_END2END_FIXTURES_INPROC_FIXTURE_H
#define GRPC_TEST_CORE_END2END_FIXTURES_INPROC_FIXTURE_H
#include "absl/functional/any_invocable.h"
#include <grpc/grpc.h>
#include "src/core/ext/transport/inproc/inproc_transport.h"
@ -23,18 +25,25 @@
class InprocFixture : public grpc_core::CoreTestFixture {
private:
grpc_server* MakeServer(const grpc_core::ChannelArgs& args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const grpc_core::ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
if (made_server_ != nullptr) return made_server_;
made_server_ = grpc_server_create(args.ToC().get(), nullptr);
grpc_server_register_completion_queue(made_server_, cq, nullptr);
pre_server_start(made_server_);
grpc_server_start(made_server_);
return made_server_;
}
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args,
grpc_completion_queue* cq) override {
return grpc_inproc_channel_create(MakeServer(args, cq), args.ToC().get(),
nullptr);
// Registered method registration isn't going to work for tests that create
// the client first and use inproc transports.
absl::AnyInvocable<void(grpc_server*)>
not_sure_what_to_do_but_this_works_for_now = [](grpc_server*) {};
return grpc_inproc_channel_create(
MakeServer(args, cq, not_sure_what_to_do_but_this_works_for_now),
args.ToC().get(), nullptr);
}
grpc_server* made_server_ = nullptr;

@ -39,8 +39,9 @@ LocalTestFixture::LocalTestFixture(std::string localaddr,
grpc_local_connect_type type)
: localaddr_(std::move(localaddr)), type_(type) {}
grpc_server* LocalTestFixture::MakeServer(const grpc_core::ChannelArgs& args,
grpc_completion_queue* cq) {
grpc_server* LocalTestFixture::MakeServer(
const grpc_core::ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) {
grpc_server_credentials* server_creds =
grpc_local_server_credentials_create(type_);
auto* server = grpc_server_create(args.ToC().get(), nullptr);
@ -54,6 +55,7 @@ grpc_server* LocalTestFixture::MakeServer(const grpc_core::ChannelArgs& args,
GPR_ASSERT(
grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
grpc_server_credentials_release(server_creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}

@ -21,6 +21,8 @@
#include <string>
#include "absl/functional/any_invocable.h"
#include <grpc/grpc.h>
#include <grpc/grpc_security_constants.h>
@ -32,8 +34,9 @@ class LocalTestFixture final : public grpc_core::CoreTestFixture {
LocalTestFixture(std::string localaddr, grpc_local_connect_type type);
private:
grpc_server* MakeServer(const grpc_core::ChannelArgs& args,
grpc_completion_queue* cq) override;
grpc_server* MakeServer(
const grpc_core::ChannelArgs& args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override;
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args,
grpc_completion_queue* cq) override;

@ -18,6 +18,8 @@
#include <string>
#include <utility>
#include "absl/functional/any_invocable.h"
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
@ -49,14 +51,16 @@ class SecureFixture : public grpc_core::CoreTestFixture {
virtual grpc_core::ChannelArgs MutateServerArgs(grpc_core::ChannelArgs args) {
return args;
}
grpc_server* MakeServer(const grpc_core::ChannelArgs& in_args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const grpc_core::ChannelArgs& in_args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
auto args = MutateServerArgs(in_args);
auto* creds = MakeServerCreds(args);
auto* server = grpc_server_create(args.ToC().get(), nullptr);
grpc_server_register_completion_queue(server, cq, nullptr);
GPR_ASSERT(grpc_server_add_http2_port(server, localaddr_.c_str(), creds));
grpc_server_credentials_release(creds);
pre_server_start(server);
grpc_server_start(server);
return server;
}

@ -17,6 +17,7 @@
#include <utility>
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "gtest/gtest.h"
@ -66,13 +67,15 @@ class SockpairFixture : public CoreTestFixture {
private:
virtual ChannelArgs MutateClientArgs(ChannelArgs args) { return args; }
virtual ChannelArgs MutateServerArgs(ChannelArgs args) { return args; }
grpc_server* MakeServer(const ChannelArgs& in_args,
grpc_completion_queue* cq) override {
grpc_server* MakeServer(
const ChannelArgs& in_args, grpc_completion_queue* cq,
absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
auto args = MutateServerArgs(in_args);
ExecCtx exec_ctx;
grpc_transport* transport;
auto* server = grpc_server_create(args.ToC().get(), nullptr);
grpc_server_register_completion_queue(server, cq, nullptr);
pre_server_start(server);
grpc_server_start(server);
auto server_channel_args = CoreConfiguration::Get()
.channel_args_preconditioning()

@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include "absl/functional/any_invocable.h"
#include "absl/types/optional.h"
#include "gtest/gtest.h"
@ -203,7 +204,9 @@ static void simple_request_body(grpc_core::CoreTestFixture* f,
grpc_call_error error;
grpc_channel* client = f->MakeClient(grpc_core::ChannelArgs(), cq);
grpc_server* server = f->MakeServer(grpc_core::ChannelArgs(), cq);
absl::AnyInvocable<void(grpc_server*)> pre_start_server = [](grpc_server*) {};
grpc_server* server =
f->MakeServer(grpc_core::ChannelArgs(), cq, pre_start_server);
grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr:1234");
c = grpc_channel_create_call(client, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,

@ -0,0 +1,173 @@
// Copyright 2023 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 <string.h>
#include <memory>
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include <grpc/impl/channel_arg_names.h>
#include <grpc/status.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/slice/slice.h"
#include "test/core/end2end/end2end_tests.h"
namespace grpc_core {
namespace {
CORE_END2END_TEST(CoreDeadlineTest, TimeoutBeforeRequestCall) {
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(1)).Create();
CoreEnd2endTest::IncomingStatusOnClient server_status;
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
c.NewBatch(1)
.SendInitialMetadata({})
.SendCloseFromClient()
.RecvInitialMetadata(server_initial_metadata)
.RecvStatusOnClient(server_status);
Expect(1, true);
Step();
EXPECT_EQ(server_status.status(), GRPC_STATUS_DEADLINE_EXCEEDED);
auto s = RequestCall(2);
bool got_call = false;
std::unique_ptr<IncomingCloseOnServer> client_close;
Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) {
got_call = true;
if (ok) {
// If we successfully get a call, then we should additionally get a
// close tag.
client_close = std::make_unique<IncomingCloseOnServer>();
s.NewBatch(3).RecvCloseOnServer(*client_close);
Expect(3, true);
}
}});
Step();
if (client_close != nullptr) {
// If we got a close op then it should indicate cancelled.
EXPECT_TRUE(got_call);
EXPECT_TRUE(client_close->was_cancelled());
}
if (!got_call) {
// Maybe we didn't get a call (didn't reach the server pre-deadline).
// In that case we should get a failed call back on shutdown.
ShutdownServerAndNotify(4);
Expect(2, false);
Expect(4, true);
Step();
}
}
CORE_END2END_TEST(CoreDeadlineTest,
TimeoutBeforeRequestCallWithRegisteredMethod) {
auto method = RegisterServerMethod("/foo", GRPC_SRM_PAYLOAD_NONE);
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(1)).Create();
CoreEnd2endTest::IncomingStatusOnClient server_status;
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
c.NewBatch(1)
.SendInitialMetadata({})
.SendCloseFromClient()
.RecvInitialMetadata(server_initial_metadata)
.RecvStatusOnClient(server_status);
Expect(1, true);
Step();
EXPECT_EQ(server_status.status(), GRPC_STATUS_DEADLINE_EXCEEDED);
auto s = RequestRegisteredCall(method, 2);
bool got_call = false;
std::unique_ptr<IncomingCloseOnServer> client_close;
Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) {
got_call = true;
if (ok) {
// If we successfully get a call, then we should additionally get a
// close tag.
client_close = std::make_unique<IncomingCloseOnServer>();
s.NewBatch(3).RecvCloseOnServer(*client_close);
Expect(3, true);
}
}});
Step();
if (client_close != nullptr) {
// If we got a close op then it should indicate cancelled.
EXPECT_TRUE(got_call);
EXPECT_TRUE(client_close->was_cancelled());
}
if (!got_call) {
// Maybe we didn't get a call (didn't reach the server pre-deadline).
// In that case we should get a failed call back on shutdown.
ShutdownServerAndNotify(4);
Expect(2, false);
Expect(4, true);
Step();
}
}
CORE_END2END_TEST(CoreDeadlineSingleHopTest,
TimeoutBeforeRequestCallWithRegisteredMethodWithPayload) {
auto method =
RegisterServerMethod("/foo", GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER);
const size_t kMessageSize = 10 * 1024 * 1024;
auto send_from_client = RandomSlice(kMessageSize);
InitServer(
ChannelArgs().Set(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, kMessageSize));
InitClient(
ChannelArgs().Set(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, kMessageSize));
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(1)).Create();
CoreEnd2endTest::IncomingStatusOnClient server_status;
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
c.NewBatch(1)
.SendInitialMetadata({})
.SendCloseFromClient()
.SendMessage(send_from_client.Ref())
.RecvInitialMetadata(server_initial_metadata)
.RecvStatusOnClient(server_status);
Expect(1, true);
Step();
EXPECT_EQ(server_status.status(), GRPC_STATUS_DEADLINE_EXCEEDED);
IncomingMessage client_message;
auto s = RequestRegisteredCall(method, &client_message, 2);
bool got_call = false;
std::unique_ptr<IncomingCloseOnServer> client_close;
Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) {
got_call = true;
if (ok) {
// If we successfully get a call, then we should additionally get a
// close tag.
client_close = std::make_unique<IncomingCloseOnServer>();
s.NewBatch(3).RecvCloseOnServer(*client_close);
Expect(3, true);
}
}});
Step();
if (client_close != nullptr) {
// If we got a close op then it should indicate cancelled.
EXPECT_TRUE(got_call);
EXPECT_TRUE(client_close->was_cancelled());
}
if (!got_call) {
// Maybe we didn't get a call (didn't reach the server pre-deadline).
// In that case we should get a failed call back on shutdown.
ShutdownServerAndNotify(4);
Expect(2, false);
Expect(4, true);
Step();
}
}
} // namespace
} // namespace grpc_core

@ -10491,6 +10491,30 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "timeout_before_request_call_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save