[tests] Convert core e2e tests to gtest (#32603)
Notes: - `+trace` fixtures haven't run since 2016, so they're disabled for now (7ad2d0b463 (diff-780fce7267c34170c1d0ea15cc9f65a7f4b79fefe955d185c44e8b3251cf9e38R76)) - all current fixtures define `FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER` and hence `authority_not_supported` has not been run in years - deleted - bad_hostname similarly hasn't been triggered in a long while, so deleted - load_reporting_hook has never been enabled, so deleted (f23fb4cf31/test/core/end2end/generate_tests.bzl (L145-L148)) - filter_latency & filter_status_code rely on global variables and so don't convert particularly cleanly - and their value seems marginal, so deleted --------- Co-authored-by: ctiller <ctiller@users.noreply.github.com>
This commit is contained in:
parent
d551a512c8
commit
724441d85b
|
|
@ -19,7 +19,6 @@ binding.gyp linguist-generated=true
|
|||
src/python/grpcio/grpc_core_dependencies.py linguist-generated=true
|
||||
src/ruby/ext/grpc/rb_grpc_imports.generated.h linguist-generated=true
|
||||
src/ruby/ext/grpc/rb_grpc_imports.generated.c linguist-generated=true
|
||||
test/core/end2end/end2end_tests.cc linguist-generated=true
|
||||
test/core/security/grpc_tls_credentials_options_comparator_test.cc linguist-generated=true
|
||||
test/core/surface/public_headers_must_be_c89.c linguist-generated=true
|
||||
tools/doxygen/Doxyfile.c++.internal linguist-generated=true
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -12,134 +12,6 @@ libs:
|
|||
- third_party/address_sorting/address_sorting_posix.c
|
||||
- third_party/address_sorting/address_sorting_windows.c
|
||||
deps: []
|
||||
- name: end2end_tests
|
||||
build: private
|
||||
language: c
|
||||
public_headers: []
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
- test/core/end2end/data/ssl_test_data.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/util/test_lb_policies.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/data/client_certs.cc
|
||||
- test/core/end2end/data/server1_cert.cc
|
||||
- test/core/end2end/data/server1_key.cc
|
||||
- test/core/end2end/data/test_root_cert.cc
|
||||
- test/core/end2end/end2end_test_utils.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/authority_not_supported.cc
|
||||
- test/core/end2end/tests/bad_hostname.cc
|
||||
- test/core/end2end/tests/bad_ping.cc
|
||||
- test/core/end2end/tests/binary_metadata.cc
|
||||
- test/core/end2end/tests/call_creds.cc
|
||||
- test/core/end2end/tests/call_host_override.cc
|
||||
- test/core/end2end/tests/cancel_after_accept.cc
|
||||
- test/core/end2end/tests/cancel_after_client_done.cc
|
||||
- test/core/end2end/tests/cancel_after_invoke.cc
|
||||
- test/core/end2end/tests/cancel_after_round_trip.cc
|
||||
- test/core/end2end/tests/cancel_before_invoke.cc
|
||||
- test/core/end2end/tests/cancel_in_a_vacuum.cc
|
||||
- test/core/end2end/tests/cancel_with_status.cc
|
||||
- test/core/end2end/tests/channelz.cc
|
||||
- test/core/end2end/tests/client_streaming.cc
|
||||
- test/core/end2end/tests/compressed_payload.cc
|
||||
- test/core/end2end/tests/connectivity.cc
|
||||
- test/core/end2end/tests/default_host.cc
|
||||
- test/core/end2end/tests/disappearing_server.cc
|
||||
- test/core/end2end/tests/empty_batch.cc
|
||||
- test/core/end2end/tests/filter_causes_close.cc
|
||||
- test/core/end2end/tests/filter_context.cc
|
||||
- test/core/end2end/tests/filter_init_fails.cc
|
||||
- test/core/end2end/tests/filter_latency.cc
|
||||
- test/core/end2end/tests/filter_status_code.cc
|
||||
- test/core/end2end/tests/filtered_metadata.cc
|
||||
- test/core/end2end/tests/graceful_server_shutdown.cc
|
||||
- test/core/end2end/tests/grpc_authz.cc
|
||||
- test/core/end2end/tests/high_initial_seqno.cc
|
||||
- test/core/end2end/tests/hpack_size.cc
|
||||
- test/core/end2end/tests/invoke_large_request.cc
|
||||
- test/core/end2end/tests/keepalive_timeout.cc
|
||||
- test/core/end2end/tests/large_metadata.cc
|
||||
- test/core/end2end/tests/max_concurrent_streams.cc
|
||||
- test/core/end2end/tests/max_connection_age.cc
|
||||
- test/core/end2end/tests/max_connection_idle.cc
|
||||
- test/core/end2end/tests/max_message_length.cc
|
||||
- test/core/end2end/tests/negative_deadline.cc
|
||||
- test/core/end2end/tests/no_logging.cc
|
||||
- test/core/end2end/tests/no_op.cc
|
||||
- test/core/end2end/tests/payload.cc
|
||||
- test/core/end2end/tests/ping.cc
|
||||
- test/core/end2end/tests/ping_pong_streaming.cc
|
||||
- test/core/end2end/tests/proxy_auth.cc
|
||||
- test/core/end2end/tests/registered_call.cc
|
||||
- test/core/end2end/tests/request_with_flags.cc
|
||||
- test/core/end2end/tests/request_with_payload.cc
|
||||
- test/core/end2end/tests/resource_quota_server.cc
|
||||
- test/core/end2end/tests/retry.cc
|
||||
- test/core/end2end/tests/retry_cancel_after_first_attempt_starts.cc
|
||||
- test/core/end2end/tests/retry_cancel_during_delay.cc
|
||||
- test/core/end2end/tests/retry_cancel_with_multiple_send_batches.cc
|
||||
- test/core/end2end/tests/retry_cancellation.cc
|
||||
- test/core/end2end/tests/retry_disabled.cc
|
||||
- test/core/end2end/tests/retry_exceeds_buffer_size_in_delay.cc
|
||||
- test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
|
||||
- test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
|
||||
- test/core/end2end/tests/retry_lb_drop.cc
|
||||
- test/core/end2end/tests/retry_lb_fail.cc
|
||||
- test/core/end2end/tests/retry_non_retriable_status.cc
|
||||
- test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
|
||||
- test/core/end2end/tests/retry_per_attempt_recv_timeout.cc
|
||||
- test/core/end2end/tests/retry_per_attempt_recv_timeout_on_last_attempt.cc
|
||||
- test/core/end2end/tests/retry_recv_initial_metadata.cc
|
||||
- test/core/end2end/tests/retry_recv_message.cc
|
||||
- test/core/end2end/tests/retry_recv_message_replay.cc
|
||||
- test/core/end2end/tests/retry_recv_trailing_metadata_error.cc
|
||||
- test/core/end2end/tests/retry_send_initial_metadata_refs.cc
|
||||
- test/core/end2end/tests/retry_send_op_fails.cc
|
||||
- test/core/end2end/tests/retry_send_recv_batch.cc
|
||||
- test/core/end2end/tests/retry_server_pushback_delay.cc
|
||||
- test/core/end2end/tests/retry_server_pushback_disabled.cc
|
||||
- test/core/end2end/tests/retry_streaming.cc
|
||||
- test/core/end2end/tests/retry_streaming_after_commit.cc
|
||||
- test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
|
||||
- test/core/end2end/tests/retry_throttled.cc
|
||||
- test/core/end2end/tests/retry_too_many_attempts.cc
|
||||
- test/core/end2end/tests/retry_transparent_goaway.cc
|
||||
- test/core/end2end/tests/retry_transparent_max_concurrent_streams.cc
|
||||
- test/core/end2end/tests/retry_transparent_not_sent_on_wire.cc
|
||||
- test/core/end2end/tests/retry_unref_before_finish.cc
|
||||
- test/core/end2end/tests/retry_unref_before_recv.cc
|
||||
- test/core/end2end/tests/server_finishes_request.cc
|
||||
- test/core/end2end/tests/server_streaming.cc
|
||||
- test/core/end2end/tests/shutdown_finishes_calls.cc
|
||||
- test/core/end2end/tests/shutdown_finishes_tags.cc
|
||||
- test/core/end2end/tests/simple_delayed_request.cc
|
||||
- test/core/end2end/tests/simple_metadata.cc
|
||||
- test/core/end2end/tests/simple_request.cc
|
||||
- test/core/end2end/tests/streaming_error_response.cc
|
||||
- test/core/end2end/tests/trailing_metadata.cc
|
||||
- test/core/end2end/tests/write_buffering.cc
|
||||
- test/core/end2end/tests/write_buffering_at_end.cc
|
||||
- test/core/util/test_lb_policies.cc
|
||||
deps:
|
||||
- grpc_authorization_provider
|
||||
- grpc_test_util
|
||||
- name: gpr
|
||||
build: all
|
||||
language: c
|
||||
|
|
@ -4185,118 +4057,6 @@ libs:
|
|||
deps:
|
||||
- grpc++
|
||||
targets:
|
||||
- name: bad_server_response_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/bad_server_response_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: bad_ssl_alpn_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
- test/core/util/cmdline.h
|
||||
- test/core/util/evaluate_args_test_util.h
|
||||
- test/core/util/fuzzer_util.h
|
||||
- test/core/util/grpc_profiler.h
|
||||
- test/core/util/histogram.h
|
||||
- test/core/util/mock_authorization_endpoint.h
|
||||
- test/core/util/mock_endpoint.h
|
||||
- test/core/util/parse_hexstring.h
|
||||
- test/core/util/passthru_endpoint.h
|
||||
- test/core/util/resolve_localhost_ip46.h
|
||||
- test/core/util/slice_splitter.h
|
||||
- test/core/util/subprocess.h
|
||||
- test/core/util/tracer_util.h
|
||||
src:
|
||||
- test/core/bad_ssl/bad_ssl_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/util/cmdline.cc
|
||||
- test/core/util/fuzzer_util.cc
|
||||
- test/core/util/grpc_profiler.cc
|
||||
- test/core/util/histogram.cc
|
||||
- test/core/util/mock_endpoint.cc
|
||||
- test/core/util/parse_hexstring.cc
|
||||
- test/core/util/passthru_endpoint.cc
|
||||
- test/core/util/resolve_localhost_ip46.cc
|
||||
- test/core/util/slice_splitter.cc
|
||||
- test/core/util/subprocess_posix.cc
|
||||
- test/core/util/subprocess_windows.cc
|
||||
- test/core/util/tracer_util.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
platforms:
|
||||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: bad_ssl_cert_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
- test/core/util/cmdline.h
|
||||
- test/core/util/evaluate_args_test_util.h
|
||||
- test/core/util/fuzzer_util.h
|
||||
- test/core/util/grpc_profiler.h
|
||||
- test/core/util/histogram.h
|
||||
- test/core/util/mock_authorization_endpoint.h
|
||||
- test/core/util/mock_endpoint.h
|
||||
- test/core/util/parse_hexstring.h
|
||||
- test/core/util/passthru_endpoint.h
|
||||
- test/core/util/resolve_localhost_ip46.h
|
||||
- test/core/util/slice_splitter.h
|
||||
- test/core/util/subprocess.h
|
||||
- test/core/util/tracer_util.h
|
||||
src:
|
||||
- test/core/bad_ssl/bad_ssl_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/util/cmdline.cc
|
||||
- test/core/util/fuzzer_util.cc
|
||||
- test/core/util/grpc_profiler.cc
|
||||
- test/core/util/histogram.cc
|
||||
- test/core/util/mock_endpoint.cc
|
||||
- test/core/util/parse_hexstring.cc
|
||||
- test/core/util/passthru_endpoint.cc
|
||||
- test/core/util/resolve_localhost_ip46.cc
|
||||
- test/core/util/slice_splitter.cc
|
||||
- test/core/util/subprocess_posix.cc
|
||||
- test/core/util/subprocess_windows.cc
|
||||
- test/core/util/tracer_util.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
platforms:
|
||||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: connection_refused_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/connection_refused_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: dualstack_socket_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/dualstack_socket_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
platforms:
|
||||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: fd_conservation_posix_test
|
||||
build: test
|
||||
language: c
|
||||
|
|
@ -4334,26 +4094,6 @@ targets:
|
|||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: goaway_server_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/goaway_server_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: invalid_call_argument_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/invalid_call_argument_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: multiple_server_queues_test
|
||||
build: test
|
||||
language: c
|
||||
|
|
@ -4362,16 +4102,6 @@ targets:
|
|||
- test/core/end2end/multiple_server_queues_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: no_server_test
|
||||
build: test
|
||||
language: c
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/no_server_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: pollset_windows_starvation_test
|
||||
build: test
|
||||
language: c
|
||||
|
|
@ -5028,6 +4758,97 @@ targets:
|
|||
deps:
|
||||
- grpc_test_util
|
||||
uses_polling: false
|
||||
- name: bad_server_response_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/bad_server_response_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: bad_ssl_alpn_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
- test/core/util/cmdline.h
|
||||
- test/core/util/evaluate_args_test_util.h
|
||||
- test/core/util/fuzzer_util.h
|
||||
- test/core/util/grpc_profiler.h
|
||||
- test/core/util/histogram.h
|
||||
- test/core/util/mock_authorization_endpoint.h
|
||||
- test/core/util/mock_endpoint.h
|
||||
- test/core/util/parse_hexstring.h
|
||||
- test/core/util/passthru_endpoint.h
|
||||
- test/core/util/resolve_localhost_ip46.h
|
||||
- test/core/util/slice_splitter.h
|
||||
- test/core/util/subprocess.h
|
||||
- test/core/util/tracer_util.h
|
||||
src:
|
||||
- test/core/bad_ssl/bad_ssl_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/util/cmdline.cc
|
||||
- test/core/util/fuzzer_util.cc
|
||||
- test/core/util/grpc_profiler.cc
|
||||
- test/core/util/histogram.cc
|
||||
- test/core/util/mock_endpoint.cc
|
||||
- test/core/util/parse_hexstring.cc
|
||||
- test/core/util/passthru_endpoint.cc
|
||||
- test/core/util/resolve_localhost_ip46.cc
|
||||
- test/core/util/slice_splitter.cc
|
||||
- test/core/util/subprocess_posix.cc
|
||||
- test/core/util/subprocess_windows.cc
|
||||
- test/core/util/tracer_util.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
platforms:
|
||||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: bad_ssl_cert_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
- test/core/util/cmdline.h
|
||||
- test/core/util/evaluate_args_test_util.h
|
||||
- test/core/util/fuzzer_util.h
|
||||
- test/core/util/grpc_profiler.h
|
||||
- test/core/util/histogram.h
|
||||
- test/core/util/mock_authorization_endpoint.h
|
||||
- test/core/util/mock_endpoint.h
|
||||
- test/core/util/parse_hexstring.h
|
||||
- test/core/util/passthru_endpoint.h
|
||||
- test/core/util/resolve_localhost_ip46.h
|
||||
- test/core/util/slice_splitter.h
|
||||
- test/core/util/subprocess.h
|
||||
- test/core/util/tracer_util.h
|
||||
src:
|
||||
- test/core/bad_ssl/bad_ssl_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/util/cmdline.cc
|
||||
- test/core/util/fuzzer_util.cc
|
||||
- test/core/util/grpc_profiler.cc
|
||||
- test/core/util/histogram.cc
|
||||
- test/core/util/mock_endpoint.cc
|
||||
- test/core/util/parse_hexstring.cc
|
||||
- test/core/util/passthru_endpoint.cc
|
||||
- test/core/util/resolve_localhost_ip46.cc
|
||||
- test/core/util/slice_splitter.cc
|
||||
- test/core/util/subprocess_posix.cc
|
||||
- test/core/util/subprocess_windows.cc
|
||||
- test/core/util/tracer_util.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
platforms:
|
||||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: bad_streaming_id_bad_client_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -6225,6 +6046,17 @@ targets:
|
|||
- test/core/end2end/cq_verifier.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: connection_refused_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/connection_refused_test.cc
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: connectivity_state_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -6330,6 +6162,126 @@ targets:
|
|||
deps:
|
||||
- grpc
|
||||
uses_polling: false
|
||||
- name: core_end2end_tests
|
||||
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/util/test_lb_policies.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/end2end_test_main.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/bad_ping.cc
|
||||
- test/core/end2end/tests/binary_metadata.cc
|
||||
- test/core/end2end/tests/call_creds.cc
|
||||
- test/core/end2end/tests/call_host_override.cc
|
||||
- test/core/end2end/tests/cancel_after_accept.cc
|
||||
- test/core/end2end/tests/cancel_after_client_done.cc
|
||||
- test/core/end2end/tests/cancel_after_invoke.cc
|
||||
- test/core/end2end/tests/cancel_after_round_trip.cc
|
||||
- test/core/end2end/tests/cancel_before_invoke.cc
|
||||
- test/core/end2end/tests/cancel_in_a_vacuum.cc
|
||||
- test/core/end2end/tests/cancel_with_status.cc
|
||||
- test/core/end2end/tests/channelz.cc
|
||||
- test/core/end2end/tests/client_streaming.cc
|
||||
- test/core/end2end/tests/compressed_payload.cc
|
||||
- test/core/end2end/tests/connectivity.cc
|
||||
- test/core/end2end/tests/default_host.cc
|
||||
- test/core/end2end/tests/disappearing_server.cc
|
||||
- test/core/end2end/tests/empty_batch.cc
|
||||
- test/core/end2end/tests/filter_causes_close.cc
|
||||
- test/core/end2end/tests/filter_context.cc
|
||||
- test/core/end2end/tests/filter_init_fails.cc
|
||||
- test/core/end2end/tests/filtered_metadata.cc
|
||||
- test/core/end2end/tests/graceful_server_shutdown.cc
|
||||
- test/core/end2end/tests/grpc_authz.cc
|
||||
- test/core/end2end/tests/high_initial_seqno.cc
|
||||
- test/core/end2end/tests/hpack_size.cc
|
||||
- test/core/end2end/tests/invoke_large_request.cc
|
||||
- test/core/end2end/tests/keepalive_timeout.cc
|
||||
- test/core/end2end/tests/large_metadata.cc
|
||||
- test/core/end2end/tests/max_concurrent_streams.cc
|
||||
- test/core/end2end/tests/max_connection_age.cc
|
||||
- test/core/end2end/tests/max_connection_idle.cc
|
||||
- test/core/end2end/tests/max_message_length.cc
|
||||
- test/core/end2end/tests/negative_deadline.cc
|
||||
- test/core/end2end/tests/no_logging.cc
|
||||
- test/core/end2end/tests/no_op.cc
|
||||
- test/core/end2end/tests/payload.cc
|
||||
- test/core/end2end/tests/ping.cc
|
||||
- test/core/end2end/tests/ping_pong_streaming.cc
|
||||
- test/core/end2end/tests/proxy_auth.cc
|
||||
- test/core/end2end/tests/registered_call.cc
|
||||
- test/core/end2end/tests/request_with_flags.cc
|
||||
- test/core/end2end/tests/request_with_payload.cc
|
||||
- test/core/end2end/tests/resource_quota_server.cc
|
||||
- test/core/end2end/tests/retry.cc
|
||||
- test/core/end2end/tests/retry_cancel_after_first_attempt_starts.cc
|
||||
- test/core/end2end/tests/retry_cancel_during_delay.cc
|
||||
- test/core/end2end/tests/retry_cancel_with_multiple_send_batches.cc
|
||||
- test/core/end2end/tests/retry_cancellation.cc
|
||||
- test/core/end2end/tests/retry_disabled.cc
|
||||
- test/core/end2end/tests/retry_exceeds_buffer_size_in_delay.cc
|
||||
- test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
|
||||
- test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
|
||||
- test/core/end2end/tests/retry_lb_drop.cc
|
||||
- test/core/end2end/tests/retry_lb_fail.cc
|
||||
- test/core/end2end/tests/retry_non_retriable_status.cc
|
||||
- test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
|
||||
- test/core/end2end/tests/retry_per_attempt_recv_timeout.cc
|
||||
- test/core/end2end/tests/retry_per_attempt_recv_timeout_on_last_attempt.cc
|
||||
- test/core/end2end/tests/retry_recv_initial_metadata.cc
|
||||
- test/core/end2end/tests/retry_recv_message.cc
|
||||
- test/core/end2end/tests/retry_recv_message_replay.cc
|
||||
- test/core/end2end/tests/retry_recv_trailing_metadata_error.cc
|
||||
- test/core/end2end/tests/retry_send_initial_metadata_refs.cc
|
||||
- test/core/end2end/tests/retry_send_op_fails.cc
|
||||
- test/core/end2end/tests/retry_send_recv_batch.cc
|
||||
- test/core/end2end/tests/retry_server_pushback_delay.cc
|
||||
- test/core/end2end/tests/retry_server_pushback_disabled.cc
|
||||
- test/core/end2end/tests/retry_streaming.cc
|
||||
- test/core/end2end/tests/retry_streaming_after_commit.cc
|
||||
- test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
|
||||
- test/core/end2end/tests/retry_throttled.cc
|
||||
- test/core/end2end/tests/retry_too_many_attempts.cc
|
||||
- test/core/end2end/tests/retry_transparent_goaway.cc
|
||||
- test/core/end2end/tests/retry_transparent_max_concurrent_streams.cc
|
||||
- test/core/end2end/tests/retry_transparent_not_sent_on_wire.cc
|
||||
- test/core/end2end/tests/retry_unref_before_finish.cc
|
||||
- test/core/end2end/tests/retry_unref_before_recv.cc
|
||||
- test/core/end2end/tests/server_finishes_request.cc
|
||||
- test/core/end2end/tests/server_streaming.cc
|
||||
- test/core/end2end/tests/shutdown_finishes_calls.cc
|
||||
- test/core/end2end/tests/shutdown_finishes_tags.cc
|
||||
- test/core/end2end/tests/simple_delayed_request.cc
|
||||
- test/core/end2end/tests/simple_metadata.cc
|
||||
- test/core/end2end/tests/simple_request.cc
|
||||
- test/core/end2end/tests/streaming_error_response.cc
|
||||
- test/core/end2end/tests/trailing_metadata.cc
|
||||
- test/core/end2end/tests/write_buffering.cc
|
||||
- test/core/end2end/tests/write_buffering_at_end.cc
|
||||
- test/core/util/test_lb_policies.cc
|
||||
deps:
|
||||
- grpc_authorization_provider
|
||||
- grpc_unsecure
|
||||
- grpc_test_util
|
||||
- name: cpp_impl_of_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -6425,6 +6377,21 @@ targets:
|
|||
- test/core/gprpp/dual_ref_counted_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: dualstack_socket_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/dualstack_socket_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
platforms:
|
||||
- linux
|
||||
- posix
|
||||
- mac
|
||||
- name: duplicate_header_bad_client_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -7968,6 +7935,17 @@ targets:
|
|||
- test/cpp/end2end/generic_end2end_test.cc
|
||||
deps:
|
||||
- grpc++_test_util
|
||||
- name: goaway_server_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/goaway_server_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: google_c2p_resolver_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -8505,12 +8483,14 @@ targets:
|
|||
- test/core/end2end/fixtures/local_util.h
|
||||
- test/core/end2end/fixtures/secure_fixture.h
|
||||
- test/core/end2end/fixtures/sockpair_fixture.h
|
||||
- test/core/end2end/tests/cancel_test_helpers.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/data/client_certs.cc
|
||||
- test/core/end2end/data/server1_cert.cc
|
||||
- test/core/end2end/data/server1_key.cc
|
||||
- test/core/end2end/data/test_root_cert.cc
|
||||
- test/core/end2end/end2end_tests.cc
|
||||
- test/core/end2end/fixtures/local_util.cc
|
||||
- test/core/end2end/h2_ssl_cert_test.cc
|
||||
deps:
|
||||
|
|
@ -9043,6 +9023,17 @@ targets:
|
|||
deps:
|
||||
- grpc++_test_config
|
||||
- grpc++_test_util
|
||||
- name: invalid_call_argument_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/invalid_call_argument_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: iocp_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
@ -9676,6 +9667,17 @@ targets:
|
|||
- test/core/gprpp/no_destruct_test.cc
|
||||
deps: []
|
||||
uses_polling: false
|
||||
- name: no_server_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- test/core/end2end/cq_verifier.h
|
||||
src:
|
||||
- test/core/end2end/cq_verifier.cc
|
||||
- test/core/end2end/no_server_test.cc
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- name: nonblocking_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
|
|||
|
|
@ -2799,159 +2799,6 @@ Pod::Spec.new do |s|
|
|||
'third_party/objective_c/Cronet/bidirectional_stream_c.h'
|
||||
end
|
||||
|
||||
s.subspec 'Tests' do |ss|
|
||||
ss.header_mappings_dir = '.'
|
||||
|
||||
ss.dependency "#{s.name}/Interface", version
|
||||
ss.dependency "#{s.name}/Implementation", version
|
||||
ss.dependency 'abseil/debugging/failure_signal_handler', abseil_version
|
||||
ss.dependency 'abseil/debugging/stacktrace', abseil_version
|
||||
ss.dependency 'abseil/debugging/symbolize', abseil_version
|
||||
|
||||
ss.source_files = 'src/core/lib/security/authorization/grpc_authorization_policy_provider.cc',
|
||||
'src/core/lib/security/authorization/grpc_authorization_policy_provider.h',
|
||||
'src/core/lib/security/authorization/rbac_translator.cc',
|
||||
'src/core/lib/security/authorization/rbac_translator.h',
|
||||
'test/core/end2end/cq_verifier.cc',
|
||||
'test/core/end2end/cq_verifier.h',
|
||||
'test/core/end2end/data/client_certs.cc',
|
||||
'test/core/end2end/data/server1_cert.cc',
|
||||
'test/core/end2end/data/server1_key.cc',
|
||||
'test/core/end2end/data/ssl_test_data.h',
|
||||
'test/core/end2end/data/test_root_cert.cc',
|
||||
'test/core/end2end/end2end_test_utils.cc',
|
||||
'test/core/end2end/end2end_tests.cc',
|
||||
'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.cc',
|
||||
'test/core/end2end/fixtures/http_proxy_fixture.h',
|
||||
'test/core/end2end/fixtures/inproc_fixture.h',
|
||||
'test/core/end2end/fixtures/local_util.cc',
|
||||
'test/core/end2end/fixtures/local_util.h',
|
||||
'test/core/end2end/fixtures/proxy.cc',
|
||||
'test/core/end2end/fixtures/proxy.h',
|
||||
'test/core/end2end/fixtures/secure_fixture.h',
|
||||
'test/core/end2end/fixtures/sockpair_fixture.h',
|
||||
'test/core/end2end/tests/authority_not_supported.cc',
|
||||
'test/core/end2end/tests/bad_hostname.cc',
|
||||
'test/core/end2end/tests/bad_ping.cc',
|
||||
'test/core/end2end/tests/binary_metadata.cc',
|
||||
'test/core/end2end/tests/call_creds.cc',
|
||||
'test/core/end2end/tests/call_host_override.cc',
|
||||
'test/core/end2end/tests/cancel_after_accept.cc',
|
||||
'test/core/end2end/tests/cancel_after_client_done.cc',
|
||||
'test/core/end2end/tests/cancel_after_invoke.cc',
|
||||
'test/core/end2end/tests/cancel_after_round_trip.cc',
|
||||
'test/core/end2end/tests/cancel_before_invoke.cc',
|
||||
'test/core/end2end/tests/cancel_in_a_vacuum.cc',
|
||||
'test/core/end2end/tests/cancel_test_helpers.h',
|
||||
'test/core/end2end/tests/cancel_with_status.cc',
|
||||
'test/core/end2end/tests/channelz.cc',
|
||||
'test/core/end2end/tests/client_streaming.cc',
|
||||
'test/core/end2end/tests/compressed_payload.cc',
|
||||
'test/core/end2end/tests/connectivity.cc',
|
||||
'test/core/end2end/tests/default_host.cc',
|
||||
'test/core/end2end/tests/disappearing_server.cc',
|
||||
'test/core/end2end/tests/empty_batch.cc',
|
||||
'test/core/end2end/tests/filter_causes_close.cc',
|
||||
'test/core/end2end/tests/filter_context.cc',
|
||||
'test/core/end2end/tests/filter_init_fails.cc',
|
||||
'test/core/end2end/tests/filter_latency.cc',
|
||||
'test/core/end2end/tests/filter_status_code.cc',
|
||||
'test/core/end2end/tests/filtered_metadata.cc',
|
||||
'test/core/end2end/tests/graceful_server_shutdown.cc',
|
||||
'test/core/end2end/tests/grpc_authz.cc',
|
||||
'test/core/end2end/tests/high_initial_seqno.cc',
|
||||
'test/core/end2end/tests/hpack_size.cc',
|
||||
'test/core/end2end/tests/invoke_large_request.cc',
|
||||
'test/core/end2end/tests/keepalive_timeout.cc',
|
||||
'test/core/end2end/tests/large_metadata.cc',
|
||||
'test/core/end2end/tests/max_concurrent_streams.cc',
|
||||
'test/core/end2end/tests/max_connection_age.cc',
|
||||
'test/core/end2end/tests/max_connection_idle.cc',
|
||||
'test/core/end2end/tests/max_message_length.cc',
|
||||
'test/core/end2end/tests/negative_deadline.cc',
|
||||
'test/core/end2end/tests/no_logging.cc',
|
||||
'test/core/end2end/tests/no_op.cc',
|
||||
'test/core/end2end/tests/payload.cc',
|
||||
'test/core/end2end/tests/ping.cc',
|
||||
'test/core/end2end/tests/ping_pong_streaming.cc',
|
||||
'test/core/end2end/tests/proxy_auth.cc',
|
||||
'test/core/end2end/tests/registered_call.cc',
|
||||
'test/core/end2end/tests/request_with_flags.cc',
|
||||
'test/core/end2end/tests/request_with_payload.cc',
|
||||
'test/core/end2end/tests/resource_quota_server.cc',
|
||||
'test/core/end2end/tests/retry.cc',
|
||||
'test/core/end2end/tests/retry_cancel_after_first_attempt_starts.cc',
|
||||
'test/core/end2end/tests/retry_cancel_during_delay.cc',
|
||||
'test/core/end2end/tests/retry_cancel_with_multiple_send_batches.cc',
|
||||
'test/core/end2end/tests/retry_cancellation.cc',
|
||||
'test/core/end2end/tests/retry_disabled.cc',
|
||||
'test/core/end2end/tests/retry_exceeds_buffer_size_in_delay.cc',
|
||||
'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
|
||||
'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
|
||||
'test/core/end2end/tests/retry_lb_drop.cc',
|
||||
'test/core/end2end/tests/retry_lb_fail.cc',
|
||||
'test/core/end2end/tests/retry_non_retriable_status.cc',
|
||||
'test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc',
|
||||
'test/core/end2end/tests/retry_per_attempt_recv_timeout.cc',
|
||||
'test/core/end2end/tests/retry_per_attempt_recv_timeout_on_last_attempt.cc',
|
||||
'test/core/end2end/tests/retry_recv_initial_metadata.cc',
|
||||
'test/core/end2end/tests/retry_recv_message.cc',
|
||||
'test/core/end2end/tests/retry_recv_message_replay.cc',
|
||||
'test/core/end2end/tests/retry_recv_trailing_metadata_error.cc',
|
||||
'test/core/end2end/tests/retry_send_initial_metadata_refs.cc',
|
||||
'test/core/end2end/tests/retry_send_op_fails.cc',
|
||||
'test/core/end2end/tests/retry_send_recv_batch.cc',
|
||||
'test/core/end2end/tests/retry_server_pushback_delay.cc',
|
||||
'test/core/end2end/tests/retry_server_pushback_disabled.cc',
|
||||
'test/core/end2end/tests/retry_streaming.cc',
|
||||
'test/core/end2end/tests/retry_streaming_after_commit.cc',
|
||||
'test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc',
|
||||
'test/core/end2end/tests/retry_throttled.cc',
|
||||
'test/core/end2end/tests/retry_too_many_attempts.cc',
|
||||
'test/core/end2end/tests/retry_transparent_goaway.cc',
|
||||
'test/core/end2end/tests/retry_transparent_max_concurrent_streams.cc',
|
||||
'test/core/end2end/tests/retry_transparent_not_sent_on_wire.cc',
|
||||
'test/core/end2end/tests/retry_unref_before_finish.cc',
|
||||
'test/core/end2end/tests/retry_unref_before_recv.cc',
|
||||
'test/core/end2end/tests/server_finishes_request.cc',
|
||||
'test/core/end2end/tests/server_streaming.cc',
|
||||
'test/core/end2end/tests/shutdown_finishes_calls.cc',
|
||||
'test/core/end2end/tests/shutdown_finishes_tags.cc',
|
||||
'test/core/end2end/tests/simple_delayed_request.cc',
|
||||
'test/core/end2end/tests/simple_metadata.cc',
|
||||
'test/core/end2end/tests/simple_request.cc',
|
||||
'test/core/end2end/tests/streaming_error_response.cc',
|
||||
'test/core/end2end/tests/trailing_metadata.cc',
|
||||
'test/core/end2end/tests/write_buffering.cc',
|
||||
'test/core/end2end/tests/write_buffering_at_end.cc',
|
||||
'test/core/event_engine/test_init.cc',
|
||||
'test/core/event_engine/test_init.h',
|
||||
'test/core/util/build.cc',
|
||||
'test/core/util/build.h',
|
||||
'test/core/util/port.cc',
|
||||
'test/core/util/port.h',
|
||||
'test/core/util/port_isolated_runtime_environment.cc',
|
||||
'test/core/util/port_server_client.cc',
|
||||
'test/core/util/port_server_client.h',
|
||||
'test/core/util/reconnect_server.cc',
|
||||
'test/core/util/reconnect_server.h',
|
||||
'test/core/util/stack_tracer.cc',
|
||||
'test/core/util/stack_tracer.h',
|
||||
'test/core/util/test_config.cc',
|
||||
'test/core/util/test_config.h',
|
||||
'test/core/util/test_lb_policies.cc',
|
||||
'test/core/util/test_lb_policies.h',
|
||||
'test/core/util/test_tcp_server.cc',
|
||||
'test/core/util/test_tcp_server.h',
|
||||
'test/core/util/tls_utils.cc',
|
||||
'test/core/util/tls_utils.h'
|
||||
end
|
||||
|
||||
# patch include of openssl to openssl_grpc
|
||||
s.prepare_command = <<-END_OF_COMMAND
|
||||
set -e
|
||||
|
|
|
|||
|
|
@ -173,120 +173,6 @@
|
|||
'third_party/address_sorting/address_sorting_windows.c',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'end2end_tests',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'grpc_authorization_provider',
|
||||
'grpc_test_util',
|
||||
],
|
||||
'sources': [
|
||||
'test/core/end2end/cq_verifier.cc',
|
||||
'test/core/end2end/data/client_certs.cc',
|
||||
'test/core/end2end/data/server1_cert.cc',
|
||||
'test/core/end2end/data/server1_key.cc',
|
||||
'test/core/end2end/data/test_root_cert.cc',
|
||||
'test/core/end2end/end2end_test_utils.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/authority_not_supported.cc',
|
||||
'test/core/end2end/tests/bad_hostname.cc',
|
||||
'test/core/end2end/tests/bad_ping.cc',
|
||||
'test/core/end2end/tests/binary_metadata.cc',
|
||||
'test/core/end2end/tests/call_creds.cc',
|
||||
'test/core/end2end/tests/call_host_override.cc',
|
||||
'test/core/end2end/tests/cancel_after_accept.cc',
|
||||
'test/core/end2end/tests/cancel_after_client_done.cc',
|
||||
'test/core/end2end/tests/cancel_after_invoke.cc',
|
||||
'test/core/end2end/tests/cancel_after_round_trip.cc',
|
||||
'test/core/end2end/tests/cancel_before_invoke.cc',
|
||||
'test/core/end2end/tests/cancel_in_a_vacuum.cc',
|
||||
'test/core/end2end/tests/cancel_with_status.cc',
|
||||
'test/core/end2end/tests/channelz.cc',
|
||||
'test/core/end2end/tests/client_streaming.cc',
|
||||
'test/core/end2end/tests/compressed_payload.cc',
|
||||
'test/core/end2end/tests/connectivity.cc',
|
||||
'test/core/end2end/tests/default_host.cc',
|
||||
'test/core/end2end/tests/disappearing_server.cc',
|
||||
'test/core/end2end/tests/empty_batch.cc',
|
||||
'test/core/end2end/tests/filter_causes_close.cc',
|
||||
'test/core/end2end/tests/filter_context.cc',
|
||||
'test/core/end2end/tests/filter_init_fails.cc',
|
||||
'test/core/end2end/tests/filter_latency.cc',
|
||||
'test/core/end2end/tests/filter_status_code.cc',
|
||||
'test/core/end2end/tests/filtered_metadata.cc',
|
||||
'test/core/end2end/tests/graceful_server_shutdown.cc',
|
||||
'test/core/end2end/tests/grpc_authz.cc',
|
||||
'test/core/end2end/tests/high_initial_seqno.cc',
|
||||
'test/core/end2end/tests/hpack_size.cc',
|
||||
'test/core/end2end/tests/invoke_large_request.cc',
|
||||
'test/core/end2end/tests/keepalive_timeout.cc',
|
||||
'test/core/end2end/tests/large_metadata.cc',
|
||||
'test/core/end2end/tests/max_concurrent_streams.cc',
|
||||
'test/core/end2end/tests/max_connection_age.cc',
|
||||
'test/core/end2end/tests/max_connection_idle.cc',
|
||||
'test/core/end2end/tests/max_message_length.cc',
|
||||
'test/core/end2end/tests/negative_deadline.cc',
|
||||
'test/core/end2end/tests/no_logging.cc',
|
||||
'test/core/end2end/tests/no_op.cc',
|
||||
'test/core/end2end/tests/payload.cc',
|
||||
'test/core/end2end/tests/ping.cc',
|
||||
'test/core/end2end/tests/ping_pong_streaming.cc',
|
||||
'test/core/end2end/tests/proxy_auth.cc',
|
||||
'test/core/end2end/tests/registered_call.cc',
|
||||
'test/core/end2end/tests/request_with_flags.cc',
|
||||
'test/core/end2end/tests/request_with_payload.cc',
|
||||
'test/core/end2end/tests/resource_quota_server.cc',
|
||||
'test/core/end2end/tests/retry.cc',
|
||||
'test/core/end2end/tests/retry_cancel_after_first_attempt_starts.cc',
|
||||
'test/core/end2end/tests/retry_cancel_during_delay.cc',
|
||||
'test/core/end2end/tests/retry_cancel_with_multiple_send_batches.cc',
|
||||
'test/core/end2end/tests/retry_cancellation.cc',
|
||||
'test/core/end2end/tests/retry_disabled.cc',
|
||||
'test/core/end2end/tests/retry_exceeds_buffer_size_in_delay.cc',
|
||||
'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
|
||||
'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
|
||||
'test/core/end2end/tests/retry_lb_drop.cc',
|
||||
'test/core/end2end/tests/retry_lb_fail.cc',
|
||||
'test/core/end2end/tests/retry_non_retriable_status.cc',
|
||||
'test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc',
|
||||
'test/core/end2end/tests/retry_per_attempt_recv_timeout.cc',
|
||||
'test/core/end2end/tests/retry_per_attempt_recv_timeout_on_last_attempt.cc',
|
||||
'test/core/end2end/tests/retry_recv_initial_metadata.cc',
|
||||
'test/core/end2end/tests/retry_recv_message.cc',
|
||||
'test/core/end2end/tests/retry_recv_message_replay.cc',
|
||||
'test/core/end2end/tests/retry_recv_trailing_metadata_error.cc',
|
||||
'test/core/end2end/tests/retry_send_initial_metadata_refs.cc',
|
||||
'test/core/end2end/tests/retry_send_op_fails.cc',
|
||||
'test/core/end2end/tests/retry_send_recv_batch.cc',
|
||||
'test/core/end2end/tests/retry_server_pushback_delay.cc',
|
||||
'test/core/end2end/tests/retry_server_pushback_disabled.cc',
|
||||
'test/core/end2end/tests/retry_streaming.cc',
|
||||
'test/core/end2end/tests/retry_streaming_after_commit.cc',
|
||||
'test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc',
|
||||
'test/core/end2end/tests/retry_throttled.cc',
|
||||
'test/core/end2end/tests/retry_too_many_attempts.cc',
|
||||
'test/core/end2end/tests/retry_transparent_goaway.cc',
|
||||
'test/core/end2end/tests/retry_transparent_max_concurrent_streams.cc',
|
||||
'test/core/end2end/tests/retry_transparent_not_sent_on_wire.cc',
|
||||
'test/core/end2end/tests/retry_unref_before_finish.cc',
|
||||
'test/core/end2end/tests/retry_unref_before_recv.cc',
|
||||
'test/core/end2end/tests/server_finishes_request.cc',
|
||||
'test/core/end2end/tests/server_streaming.cc',
|
||||
'test/core/end2end/tests/shutdown_finishes_calls.cc',
|
||||
'test/core/end2end/tests/shutdown_finishes_tags.cc',
|
||||
'test/core/end2end/tests/simple_delayed_request.cc',
|
||||
'test/core/end2end/tests/simple_metadata.cc',
|
||||
'test/core/end2end/tests/simple_request.cc',
|
||||
'test/core/end2end/tests/streaming_error_response.cc',
|
||||
'test/core/end2end/tests/trailing_metadata.cc',
|
||||
'test/core/end2end/tests/write_buffering.cc',
|
||||
'test/core/end2end/tests/write_buffering_at_end.cc',
|
||||
'test/core/util/test_lb_policies.cc',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'gpr',
|
||||
'type': 'static_library',
|
||||
|
|
|
|||
|
|
@ -369,6 +369,8 @@ static void read_channel_args(grpc_chttp2_transport* t,
|
|||
.GetObjectRef<grpc_core::channelz::SocketNode::Security>());
|
||||
}
|
||||
|
||||
t->ack_pings = channel_args.GetBool("grpc.http2.ack_pings").value_or(true);
|
||||
|
||||
const int soft_limit =
|
||||
channel_args.GetInt(GRPC_ARG_MAX_METADATA_SIZE).value_or(-1);
|
||||
if (soft_limit < 0) {
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@
|
|||
#include "src/core/ext/transport/chttp2/transport/stream_map.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
|
||||
static bool g_disable_ping_ack = false;
|
||||
|
||||
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes) {
|
||||
grpc_slice slice = GRPC_SLICE_MALLOC(9 + 8);
|
||||
uint8_t* p = GRPC_SLICE_START_PTR(slice);
|
||||
|
|
@ -116,7 +114,7 @@ grpc_error_handle grpc_chttp2_ping_parser_parse(void* parser,
|
|||
|
||||
t->ping_recv_state.last_ping_recv_time = now;
|
||||
}
|
||||
if (!g_disable_ping_ack) {
|
||||
if (t->ack_pings) {
|
||||
if (t->ping_ack_count == t->ping_ack_capacity) {
|
||||
t->ping_ack_capacity =
|
||||
std::max(t->ping_ack_capacity * 3 / 2, size_t{3});
|
||||
|
|
@ -132,7 +130,3 @@ grpc_error_handle grpc_chttp2_ping_parser_parse(void* parser,
|
|||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void grpc_set_disable_ping_ack(bool disable_ping_ack) {
|
||||
g_disable_ping_ack = disable_ping_ack;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,4 @@ grpc_error_handle grpc_chttp2_ping_parser_parse(void* parser,
|
|||
const grpc_slice& slice,
|
||||
int is_last);
|
||||
|
||||
// Test-only function for disabling ping ack
|
||||
void grpc_set_disable_ping_ack(bool disable_ping_ack);
|
||||
|
||||
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_PING_H
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ auto HPackTable::MementoRingBuffer::Lookup(uint32_t index) const
|
|||
|
||||
void HPackTable::MementoRingBuffer::Rebuild(uint32_t max_entries) {
|
||||
if (max_entries == max_entries_) return;
|
||||
max_entries_ = max_entries;
|
||||
std::vector<Memento> entries;
|
||||
entries.reserve(num_entries_);
|
||||
for (size_t i = 0; i < num_entries_; i++) {
|
||||
|
|
|
|||
|
|
@ -436,6 +436,8 @@ struct grpc_chttp2_transport
|
|||
|
||||
/// If start_bdp_ping_locked has been called
|
||||
bool bdp_ping_started = false;
|
||||
// True if pings should be acked
|
||||
bool ack_pings = true;
|
||||
// next bdp ping timer handle
|
||||
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
|
||||
next_bdp_ping_timer_handle;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
|
|
@ -77,12 +78,17 @@ void TraceFlagList::Add(TraceFlag* flag) {
|
|||
|
||||
void TraceFlagList::LogAllTracers() {
|
||||
gpr_log(GPR_DEBUG, "available tracers:");
|
||||
TraceFlag* t;
|
||||
for (t = root_tracer_; t != nullptr; t = t->next_tracer_) {
|
||||
for (TraceFlag* t = root_tracer_; t != nullptr; t = t->next_tracer_) {
|
||||
gpr_log(GPR_DEBUG, "\t%s", t->name_);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceFlagList::SaveTo(std::map<std::string, bool>& values) {
|
||||
for (TraceFlag* t = root_tracer_; t != nullptr; t = t->next_tracer_) {
|
||||
values[t->name_] = t->enabled();
|
||||
}
|
||||
}
|
||||
|
||||
// Flags register themselves on the list during construction
|
||||
TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) {
|
||||
static_assert(std::is_trivially_destructible<TraceFlag>::value,
|
||||
|
|
@ -91,6 +97,14 @@ TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) {
|
|||
TraceFlagList::Add(this);
|
||||
}
|
||||
|
||||
SavedTraceFlags::SavedTraceFlags() { TraceFlagList::SaveTo(values_); }
|
||||
|
||||
void SavedTraceFlags::Restore() {
|
||||
for (const auto& flag : values_) {
|
||||
TraceFlagList::Set(flag.first.c_str(), flag.second);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
static void add(const char* beg, const char* end, char*** ss, size_t* ns) {
|
||||
|
|
@ -138,11 +152,6 @@ static void parse(const char* s) {
|
|||
gpr_free(strings);
|
||||
}
|
||||
|
||||
void grpc_tracer_init(const char* env_var_name) {
|
||||
(void)env_var_name; // suppress unused variable error
|
||||
grpc_tracer_init();
|
||||
}
|
||||
|
||||
void grpc_tracer_init() {
|
||||
parse(std::string(grpc_core::ConfigVars::Get().Trace()).c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,8 @@
|
|||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
// TODO(veblush): Remove this deprecated function once codes depending on this
|
||||
// function are updated in the internal repo.
|
||||
void grpc_tracer_init(const char* env_var_name);
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
void grpc_tracer_init();
|
||||
void grpc_tracer_shutdown(void);
|
||||
|
|
@ -37,6 +35,7 @@ class TraceFlagList {
|
|||
public:
|
||||
static bool Set(const char* name, bool enabled);
|
||||
static void Add(TraceFlag* flag);
|
||||
static void SaveTo(std::map<std::string, bool>& values);
|
||||
|
||||
private:
|
||||
static void LogAllTracers();
|
||||
|
|
@ -101,6 +100,15 @@ class DebugOnlyTraceFlag {
|
|||
};
|
||||
#endif
|
||||
|
||||
class SavedTraceFlags {
|
||||
public:
|
||||
SavedTraceFlags();
|
||||
void Restore();
|
||||
|
||||
private:
|
||||
std::map<std::string, bool> values_;
|
||||
};
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_DEBUG_TRACE_H
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ static void timer_init(grpc_timer* timer, grpc_core::Timestamp deadline,
|
|||
#endif
|
||||
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) {
|
||||
gpr_log(GPR_INFO, "TIMER %p: SET %" PRId64 " now %" PRId64 " call %p[%p]",
|
||||
gpr_log(GPR_DEBUG, "TIMER %p: SET %" PRId64 " now %" PRId64 " call %p[%p]",
|
||||
timer, deadline.milliseconds_after_process_epoch(),
|
||||
grpc_core::Timestamp::Now().milliseconds_after_process_epoch(),
|
||||
closure, closure->cb);
|
||||
|
|
@ -374,7 +374,7 @@ static void timer_init(grpc_timer* timer, grpc_core::Timestamp deadline,
|
|||
list_join(&shard->list, timer);
|
||||
}
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) {
|
||||
gpr_log(GPR_INFO,
|
||||
gpr_log(GPR_DEBUG,
|
||||
" .. add to shard %d with queue_deadline_cap=%" PRId64
|
||||
" => is_first_timer=%s",
|
||||
static_cast<int>(shard - g_shards),
|
||||
|
|
@ -397,7 +397,7 @@ static void timer_init(grpc_timer* timer, grpc_core::Timestamp deadline,
|
|||
if (is_first_timer) {
|
||||
gpr_mu_lock(&g_shared_mutables.mu);
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) {
|
||||
gpr_log(GPR_INFO, " .. old shard min_deadline=%" PRId64,
|
||||
gpr_log(GPR_DEBUG, " .. old shard min_deadline=%" PRId64,
|
||||
shard->min_deadline.milliseconds_after_process_epoch());
|
||||
}
|
||||
if (deadline < shard->min_deadline) {
|
||||
|
|
@ -439,7 +439,7 @@ static void timer_cancel(grpc_timer* timer) {
|
|||
timer_shard* shard = &g_shards[grpc_core::HashPointer(timer, g_num_shards)];
|
||||
gpr_mu_lock(&shard->mu);
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) {
|
||||
gpr_log(GPR_INFO, "TIMER %p: CANCEL pending=%s", timer,
|
||||
gpr_log(GPR_DEBUG, "TIMER %p: CANCEL pending=%s", timer,
|
||||
timer->pending ? "true" : "false");
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +480,7 @@ static bool refill_heap(timer_shard* shard, grpc_core::Timestamp now) {
|
|||
grpc_core::Duration::FromSecondsAsDouble(deadline_delta);
|
||||
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(GPR_INFO, " .. shard[%d]->queue_deadline_cap --> %" PRId64,
|
||||
gpr_log(GPR_DEBUG, " .. shard[%d]->queue_deadline_cap --> %" PRId64,
|
||||
static_cast<int>(shard - g_shards),
|
||||
shard->queue_deadline_cap.milliseconds_after_process_epoch());
|
||||
}
|
||||
|
|
@ -492,7 +492,7 @@ static bool refill_heap(timer_shard* shard, grpc_core::Timestamp now) {
|
|||
|
||||
if (timer_deadline < shard->queue_deadline_cap) {
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(GPR_INFO, " .. add timer with deadline %" PRId64 " to heap",
|
||||
gpr_log(GPR_DEBUG, " .. add timer with deadline %" PRId64 " to heap",
|
||||
timer_deadline.milliseconds_after_process_epoch());
|
||||
}
|
||||
list_remove(timer);
|
||||
|
|
@ -509,7 +509,7 @@ static grpc_timer* pop_one(timer_shard* shard, grpc_core::Timestamp now) {
|
|||
grpc_timer* timer;
|
||||
for (;;) {
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(GPR_INFO, " .. shard[%d]: heap_empty=%s",
|
||||
gpr_log(GPR_DEBUG, " .. shard[%d]: heap_empty=%s",
|
||||
static_cast<int>(shard - g_shards),
|
||||
grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false");
|
||||
}
|
||||
|
|
@ -522,14 +522,14 @@ static grpc_timer* pop_one(timer_shard* shard, grpc_core::Timestamp now) {
|
|||
grpc_core::Timestamp::FromMillisecondsAfterProcessEpoch(
|
||||
timer->deadline);
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(GPR_INFO,
|
||||
gpr_log(GPR_DEBUG,
|
||||
" .. check top timer deadline=%" PRId64 " now=%" PRId64,
|
||||
timer_deadline.milliseconds_after_process_epoch(),
|
||||
now.milliseconds_after_process_epoch());
|
||||
}
|
||||
if (timer_deadline > now) return nullptr;
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) {
|
||||
gpr_log(GPR_INFO, "TIMER %p: FIRE %" PRId64 "ms late", timer,
|
||||
gpr_log(GPR_DEBUG, "TIMER %p: FIRE %" PRId64 "ms late", timer,
|
||||
(now - timer_deadline).millis());
|
||||
}
|
||||
timer->pending = false;
|
||||
|
|
@ -553,7 +553,7 @@ static size_t pop_timers(timer_shard* shard, grpc_core::Timestamp now,
|
|||
*new_min_deadline = compute_min_deadline(shard);
|
||||
gpr_mu_unlock(&shard->mu);
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(GPR_INFO, " .. shard[%d] popped %" PRIdPTR,
|
||||
gpr_log(GPR_DEBUG, " .. shard[%d] popped %" PRIdPTR,
|
||||
static_cast<int>(shard - g_shards), n);
|
||||
}
|
||||
return n;
|
||||
|
|
@ -593,7 +593,7 @@ static grpc_timer_check_result run_some_expired_timers(
|
|||
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(
|
||||
GPR_INFO, " .. shard[%d]->min_deadline = %" PRId64,
|
||||
GPR_DEBUG, " .. shard[%d]->min_deadline = %" PRId64,
|
||||
static_cast<int>(g_shard_queue[0] - g_shards),
|
||||
g_shard_queue[0]->min_deadline.milliseconds_after_process_epoch());
|
||||
}
|
||||
|
|
@ -612,7 +612,7 @@ static grpc_timer_check_result run_some_expired_timers(
|
|||
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(
|
||||
GPR_INFO,
|
||||
GPR_DEBUG,
|
||||
" .. result --> %d"
|
||||
", shard[%d]->min_deadline %" PRId64 " --> %" PRId64
|
||||
", now=%" PRId64,
|
||||
|
|
@ -671,7 +671,7 @@ static grpc_timer_check_result timer_check(grpc_core::Timestamp* next) {
|
|||
*next = std::min(*next, min_timer);
|
||||
}
|
||||
if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) {
|
||||
gpr_log(GPR_INFO, "TIMER CHECK SKIP: now=%" PRId64 " min_timer=%" PRId64,
|
||||
gpr_log(GPR_DEBUG, "TIMER CHECK SKIP: now=%" PRId64 " min_timer=%" PRId64,
|
||||
now.milliseconds_after_process_epoch(),
|
||||
min_timer.milliseconds_after_process_epoch());
|
||||
}
|
||||
|
|
@ -693,7 +693,7 @@ static grpc_timer_check_result timer_check(grpc_core::Timestamp* next) {
|
|||
}
|
||||
#if GPR_ARCH_64
|
||||
gpr_log(
|
||||
GPR_INFO,
|
||||
GPR_DEBUG,
|
||||
"TIMER CHECK BEGIN: now=%" PRId64 " next=%s tls_min=%" PRId64
|
||||
" glob_min=%" PRId64,
|
||||
now.milliseconds_after_process_epoch(), next_str.c_str(),
|
||||
|
|
@ -702,7 +702,8 @@ static grpc_timer_check_result timer_check(grpc_core::Timestamp* next) {
|
|||
gpr_atm_no_barrier_load((gpr_atm*)(&g_shared_mutables.min_timer)))
|
||||
.milliseconds_after_process_epoch());
|
||||
#else
|
||||
gpr_log(GPR_INFO, "TIMER CHECK BEGIN: now=%" PRId64 " next=%s min=%" PRId64,
|
||||
gpr_log(GPR_DEBUG,
|
||||
"TIMER CHECK BEGIN: now=%" PRId64 " next=%s min=%" PRId64,
|
||||
now.milliseconds_after_process_epoch(), next_str.c_str(),
|
||||
min_timer.milliseconds_after_process_epoch());
|
||||
#endif
|
||||
|
|
@ -718,7 +719,7 @@ static grpc_timer_check_result timer_check(grpc_core::Timestamp* next) {
|
|||
} else {
|
||||
next_str = absl::StrCat(next->milliseconds_after_process_epoch());
|
||||
}
|
||||
gpr_log(GPR_INFO, "TIMER CHECK END: r=%d; next=%s", r, next_str.c_str());
|
||||
gpr_log(GPR_DEBUG, "TIMER CHECK END: r=%d; next=%s", r, next_str.c_str());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -298,6 +298,8 @@ class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND MutableSlice
|
|||
|
||||
// Array access
|
||||
uint8_t& operator[](size_t i) { return mutable_data()[i]; }
|
||||
|
||||
using slice_detail::BaseSlice::c_slice_ptr;
|
||||
};
|
||||
|
||||
class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND Slice
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ load(
|
|||
"local_objc_grpc_library",
|
||||
"proto_library_objc_wrapper",
|
||||
)
|
||||
load("//test/core/end2end:generate_tests.bzl", "grpc_end2end_tests")
|
||||
load("@build_bazel_rules_apple//apple:resources.bzl", "apple_resource_bundle")
|
||||
load("@build_bazel_rules_apple//apple:macos.bzl", "macos_unit_test")
|
||||
load("@build_bazel_rules_apple//apple:tvos.bzl", "tvos_application", "tvos_unit_test")
|
||||
|
|
@ -33,8 +32,6 @@ package(default_visibility = ["//visibility:public"])
|
|||
|
||||
exports_files(["LICENSE"])
|
||||
|
||||
grpc_end2end_tests()
|
||||
|
||||
proto_library_objc_wrapper(
|
||||
name = "messages_proto",
|
||||
srcs = ["RemoteTestClient/messages.proto"],
|
||||
|
|
@ -188,7 +185,8 @@ grpc_objc_testing_library(
|
|||
deps = [
|
||||
"InteropTests-lib",
|
||||
"//src/objective-c:grpc_objc_client_core_cronet_testing",
|
||||
"//test/core/end2end:end2end_tests",
|
||||
"//test/core/end2end:cq_verifier",
|
||||
"//test/core/end2end:ssl_test_data",
|
||||
"//third_party/objective_c/Cronet:cronet_c_for_grpc",
|
||||
],
|
||||
)
|
||||
|
|
@ -206,7 +204,7 @@ grpc_objc_testing_library(
|
|||
"//:grpc++_cronet_credentials",
|
||||
"//src/objective-c:grpc_objc_client_core_cronet_testing",
|
||||
"//src/proto/grpc/testing:echo_proto",
|
||||
"//test/core/end2end:end2end_tests",
|
||||
"//test/core/end2end:ssl_test_data",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,330 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test file is derived from fixture h2_ssl.c in core end2end test
|
||||
* (test/core/end2end/fixture/h2_ssl.c). The structure of the fixture is
|
||||
* preserved as much as possible
|
||||
*
|
||||
* This fixture creates a server full stack using chttp2 and a client
|
||||
* full stack using Cronet. End-to-end tests are run against this
|
||||
* configuration
|
||||
*
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include "src/core/lib/gprpp/crash.h"
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "src/core/lib/gpr/string.h"
|
||||
#include "src/core/lib/gpr/tmpfile.h"
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "src/core/lib/security/credentials/credentials.h"
|
||||
|
||||
#include "test/core/end2end/data/ssl_test_data.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
#import <Cronet/Cronet.h>
|
||||
#include <grpc/grpc_cronet.h>
|
||||
|
||||
#import "../ConfigureCronet.h"
|
||||
|
||||
static void process_auth_failure(void *state, grpc_auth_context *ctx, const grpc_metadata *md,
|
||||
size_t md_count, grpc_process_auth_metadata_done_cb cb,
|
||||
void *user_data) {
|
||||
GPR_ASSERT(state == nullptr);
|
||||
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
|
||||
}
|
||||
|
||||
class CronetFixture final : public SecureFixture {
|
||||
private:
|
||||
grpc_channel_credentials *MakeClientCreds(const grpc_core::ChannelArgs &args) override {
|
||||
grpc_core::Crash("unreachable");
|
||||
}
|
||||
grpc_server_credentials *MakeServerCreds(const grpc_core::ChannelArgs &args) override {
|
||||
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert};
|
||||
grpc_server_credentials *ssl_creds =
|
||||
grpc_ssl_server_credentials_create(nullptr, &pem_cert_key_pair, 1, 0, nullptr);
|
||||
if (args.Contains(FAIL_AUTH_CHECK_SERVER_ARG_NAME)) {
|
||||
grpc_auth_metadata_processor processor = {process_auth_failure, nullptr, nullptr};
|
||||
grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
|
||||
}
|
||||
return ssl_creds;
|
||||
}
|
||||
grpc_channel *MakeClient(const grpc_core::ChannelArgs &args) override {
|
||||
stream_engine *cronetEngine = [Cronet getGlobalEngine];
|
||||
return grpc_cronet_secure_channel_create(cronetEngine, localaddr().c_str(), args.ToC().get(),
|
||||
nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
/* All test configurations */
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, nullptr,
|
||||
[](const grpc_core::ChannelArgs & /*client_args*/,
|
||||
const grpc_core::ChannelArgs & /*server_args*/) {
|
||||
return std::make_unique<CronetFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
static char *roots_filename;
|
||||
|
||||
@interface CoreCronetEnd2EndTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation CoreCronetEnd2EndTests
|
||||
|
||||
// The setUp() function is run before the test cases run and only run once
|
||||
+ (void)setUp {
|
||||
[super setUp];
|
||||
|
||||
FILE *roots_file;
|
||||
size_t roots_size = strlen(test_root_cert);
|
||||
|
||||
char *argv[] = {(char *)"CoreCronetEnd2EndTests"};
|
||||
int argc = 1;
|
||||
grpc_test_init(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
|
||||
/* Set the SSL roots env var. */
|
||||
roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename);
|
||||
GPR_ASSERT(roots_filename != nullptr);
|
||||
GPR_ASSERT(roots_file != nullptr);
|
||||
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
|
||||
fclose(roots_file);
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = roots_filename;
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
grpc_init();
|
||||
|
||||
configureCronet(/*enable_netlog=*/false);
|
||||
}
|
||||
|
||||
// The tearDown() function is run after all test cases finish running
|
||||
+ (void)tearDown {
|
||||
grpc_shutdown();
|
||||
|
||||
/* Cleanup. */
|
||||
remove(roots_filename);
|
||||
gpr_free(roots_filename);
|
||||
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testIndividualCase:(char *)test_case {
|
||||
char *argv[] = {(char *)"h2_ssl", test_case};
|
||||
for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(2, argv, configs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the
|
||||
// test case method name, so that bodies of test cases can stay identical
|
||||
- (void)testAuthorityNotSupported {
|
||||
[self testIndividualCase:(char *)"authority_not_supported"];
|
||||
}
|
||||
|
||||
- (void)testBadHostname {
|
||||
[self testIndividualCase:(char *)"bad_hostname"];
|
||||
}
|
||||
|
||||
- (void)testBinaryMetadata {
|
||||
[self testIndividualCase:(char *)"binary_metadata"];
|
||||
}
|
||||
|
||||
- (void)testCallCreds {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"call_creds"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterAccept {
|
||||
[self testIndividualCase:(char *)"cancel_after_accept"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterClientDone {
|
||||
[self testIndividualCase:(char *)"cancel_after_client_done"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterInvoke {
|
||||
[self testIndividualCase:(char *)"cancel_after_invoke"];
|
||||
}
|
||||
|
||||
- (void)testCancelAfterRoundTrip {
|
||||
[self testIndividualCase:(char *)"cancel_after_round_trip"];
|
||||
}
|
||||
|
||||
- (void)testCancelBeforeInvoke {
|
||||
[self testIndividualCase:(char *)"cancel_before_invoke"];
|
||||
}
|
||||
|
||||
- (void)testCancelInAVacuum {
|
||||
[self testIndividualCase:(char *)"cancel_in_a_vacuum"];
|
||||
}
|
||||
|
||||
- (void)testCancelWithStatus {
|
||||
[self testIndividualCase:(char *)"cancel_with_status"];
|
||||
}
|
||||
|
||||
- (void)testCompressedPayload {
|
||||
[self testIndividualCase:(char *)"compressed_payload"];
|
||||
}
|
||||
|
||||
- (void)testConnectivity {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"connectivity"];
|
||||
}
|
||||
|
||||
- (void)testDefaultHost {
|
||||
[self testIndividualCase:(char *)"default_host"];
|
||||
}
|
||||
|
||||
- (void)testDisappearingServer {
|
||||
[self testIndividualCase:(char *)"disappearing_server"];
|
||||
}
|
||||
|
||||
- (void)testEmptyBatch {
|
||||
[self testIndividualCase:(char *)"empty_batch"];
|
||||
}
|
||||
|
||||
- (void)testFilterCausesClose {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"filter_causes_close"];
|
||||
}
|
||||
|
||||
- (void)testGracefulServerShutdown {
|
||||
[self testIndividualCase:(char *)"graceful_server_shutdown"];
|
||||
}
|
||||
|
||||
- (void)testHighInitialSeqno {
|
||||
[self testIndividualCase:(char *)"high_initial_seqno"];
|
||||
}
|
||||
|
||||
- (void)testHpackSize {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"hpack_size"];
|
||||
}
|
||||
|
||||
- (void)testIdempotentRequest {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"idempotent_request"];
|
||||
}
|
||||
|
||||
- (void)testInvokeLargeRequest {
|
||||
// NOT SUPPORTED (frame size)
|
||||
// [self testIndividualCase:(char *)"invoke_large_request"];
|
||||
}
|
||||
|
||||
- (void)testLargeMetadata {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"large_metadata"];
|
||||
}
|
||||
|
||||
- (void)testMaxConcurrentStreams {
|
||||
[self testIndividualCase:(char *)"max_concurrent_streams"];
|
||||
}
|
||||
|
||||
- (void)testMaxMessageLength {
|
||||
// NOT SUPPORTED (close_error)
|
||||
// [self testIndividualCase:(char *)"max_message_length"];
|
||||
}
|
||||
|
||||
- (void)testNegativeDeadline {
|
||||
[self testIndividualCase:(char *)"negative_deadline"];
|
||||
}
|
||||
|
||||
- (void)testNoOp {
|
||||
[self testIndividualCase:(char *)"no_op"];
|
||||
}
|
||||
|
||||
- (void)testPayload {
|
||||
[self testIndividualCase:(char *)"payload"];
|
||||
}
|
||||
|
||||
- (void)testPing {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"ping"];
|
||||
}
|
||||
|
||||
- (void)testPingPongStreaming {
|
||||
[self testIndividualCase:(char *)"ping_pong_streaming"];
|
||||
}
|
||||
|
||||
- (void)testRegisteredCall {
|
||||
[self testIndividualCase:(char *)"registered_call"];
|
||||
}
|
||||
|
||||
- (void)testRequestWithFlags {
|
||||
// NOT SUPPORTED
|
||||
// [self testIndividualCase:(char *)"request_with_flags"];
|
||||
}
|
||||
|
||||
- (void)testRequestWithPayload {
|
||||
[self testIndividualCase:(char *)"request_with_payload"];
|
||||
}
|
||||
|
||||
- (void)testServerFinishesRequest {
|
||||
[self testIndividualCase:(char *)"server_finishes_request"];
|
||||
}
|
||||
|
||||
- (void)testServerStreaming {
|
||||
[self testIndividualCase:(char *)"server_streaming"];
|
||||
}
|
||||
|
||||
- (void)testShutdownFinishesCalls {
|
||||
[self testIndividualCase:(char *)"shutdown_finishes_calls"];
|
||||
}
|
||||
|
||||
- (void)testShutdownFinishesTags {
|
||||
[self testIndividualCase:(char *)"shutdown_finishes_tags"];
|
||||
}
|
||||
|
||||
- (void)testSimpleDelayedRequest {
|
||||
[self testIndividualCase:(char *)"simple_delayed_request"];
|
||||
}
|
||||
|
||||
- (void)testSimpleMetadata {
|
||||
[self testIndividualCase:(char *)"simple_metadata"];
|
||||
}
|
||||
|
||||
- (void)testSimpleRequest {
|
||||
[self testIndividualCase:(char *)"simple_request"];
|
||||
}
|
||||
|
||||
- (void)testStreamingErrorResponse {
|
||||
[self testIndividualCase:(char *)"streaming_error_response"];
|
||||
}
|
||||
|
||||
- (void)testTrailingMetadata {
|
||||
[self testIndividualCase:(char *)"trailing_metadata"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -47,7 +47,6 @@ target 'CronetTests' do
|
|||
|
||||
pod 'gRPC/GRPCCoreCronet', :path => GRPC_LOCAL_SRC
|
||||
pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
|
||||
pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true
|
||||
end
|
||||
|
||||
target 'PerfTests' do
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@
|
|||
set(address_sorting_unwanted_files))
|
||||
| set(list_lib_files("re2", ("headers", )))))
|
||||
grpc_abseil_specs = list_abseil_specs("grpc")
|
||||
grpc_tests_abseil_specs = list(sorted(set(list_abseil_specs("end2end_tests")) - set(grpc_abseil_specs)))
|
||||
|
||||
# TODO(jtattermusch): build.yaml is now generated from bazel build
|
||||
# which doesn't have an explicit "grpc_cronet" target. Until it exists
|
||||
|
|
@ -95,15 +94,6 @@
|
|||
|
||||
grpc_cronet_files = list(sorted(grpc_cronet_extra_impl_files))
|
||||
grpc_cronet_public_headers = list(sorted(grpc_cronet_extra_public_headers))
|
||||
|
||||
grpc_test_util_files = list(sorted(
|
||||
set(list_lib_files("end2end_tests", ("src", "headers")))
|
||||
- set(grpc_private_files)
|
||||
- set(address_sorting_unwanted_files)
|
||||
- set([
|
||||
# Subprocess is not supported in tvOS and not needed by our tests.
|
||||
"test/core/util/subprocess_posix.cc",
|
||||
])))
|
||||
%>
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'gRPC-Core'
|
||||
|
|
@ -228,18 +218,6 @@
|
|||
ss.source_files = ${ruby_multiline_list(grpc_cronet_files, 22)}
|
||||
end
|
||||
|
||||
s.subspec 'Tests' do |ss|
|
||||
ss.header_mappings_dir = '.'
|
||||
|
||||
ss.dependency "#{s.name}/Interface", version
|
||||
ss.dependency "#{s.name}/Implementation", version
|
||||
% for abseil_spec in grpc_tests_abseil_specs:
|
||||
ss.dependency '${abseil_spec}', abseil_version
|
||||
% endfor
|
||||
|
||||
ss.source_files = ${ruby_multiline_list(grpc_test_util_files, 22)}
|
||||
end
|
||||
|
||||
# patch include of openssl to openssl_grpc
|
||||
s.prepare_command = <<-END_OF_COMMAND
|
||||
set -e
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
<%def name="end2end_selector(tests)">
|
||||
//
|
||||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
//
|
||||
|
||||
<% tests = sorted(tests) %>\
|
||||
// This file is auto-generated
|
||||
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/gprpp/crash.h"
|
||||
|
||||
static bool g_pre_init_called = false;
|
||||
|
||||
% for test in tests:
|
||||
extern void ${test}(const CoreTestConfiguration& config);
|
||||
extern void ${test}_pre_init(void);
|
||||
% endfor
|
||||
|
||||
void grpc_end2end_tests_pre_init(void) {
|
||||
GPR_ASSERT(!g_pre_init_called);
|
||||
g_pre_init_called = true;
|
||||
% for test in tests:
|
||||
${test}_pre_init();
|
||||
% endfor
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-size)
|
||||
void grpc_end2end_tests(int argc, char **argv,
|
||||
const CoreTestConfiguration& config) {
|
||||
int i;
|
||||
|
||||
GPR_ASSERT(g_pre_init_called);
|
||||
|
||||
if (argc <= 1) {
|
||||
% for test in tests:
|
||||
${test}(config);
|
||||
% endfor
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
% for test in tests:
|
||||
if (0 == strcmp("${test}", argv[i])) {
|
||||
${test}(config);
|
||||
continue;
|
||||
}
|
||||
% endfor
|
||||
grpc_core::Crash(absl::StrFormat( "not a test: '%s'", argv[i]));
|
||||
}
|
||||
}</%def>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
%YAML 1.2
|
||||
--- |
|
||||
<%namespace file="end2end_defs.include" import="*"/>\
|
||||
${end2end_selector(core_end2end_tests.keys())}
|
||||
|
|
@ -43,6 +43,7 @@ def grpc_bad_client_tests():
|
|||
srcs = ["bad_client.cc"],
|
||||
hdrs = ["bad_client.h"],
|
||||
language = "C++",
|
||||
testonly = 1,
|
||||
deps = [
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//:grpc",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
# limitations under the License.
|
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package")
|
||||
load(":generate_tests.bzl", "grpc_end2end_tests")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
|
|
@ -21,15 +20,18 @@ grpc_package(name = "test/core/end2end")
|
|||
|
||||
grpc_cc_library(
|
||||
name = "cq_verifier",
|
||||
testonly = 1,
|
||||
srcs = ["cq_verifier.cc"],
|
||||
hdrs = ["cq_verifier.h"],
|
||||
external_deps = [
|
||||
"absl/functional:any_invocable",
|
||||
"absl/strings",
|
||||
"absl/strings:str_format",
|
||||
"absl/types:variant",
|
||||
"gtest",
|
||||
],
|
||||
language = "C++",
|
||||
visibility = ["//test:__subpackages__"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//:debug_location",
|
||||
"//:gpr",
|
||||
|
|
@ -50,7 +52,7 @@ grpc_cc_library(
|
|||
],
|
||||
hdrs = ["data/ssl_test_data.h"],
|
||||
language = "C++",
|
||||
visibility = ["//test:__subpackages__"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
|
|
@ -100,10 +102,43 @@ grpc_cc_library(
|
|||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "fixture_support",
|
||||
srcs = ["fixtures/local_util.cc"],
|
||||
name = "end2end_test_lib",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"end2end_tests.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"end2end_tests.h",
|
||||
],
|
||||
external_deps = [
|
||||
"absl/memory",
|
||||
"absl/random",
|
||||
"absl/strings",
|
||||
"absl/types:optional",
|
||||
"absl/types:variant",
|
||||
"gtest",
|
||||
],
|
||||
deps = [
|
||||
"cq_verifier",
|
||||
"//:config",
|
||||
"//:debug_location",
|
||||
"//:gpr",
|
||||
"//:grpc",
|
||||
"//:grpc_public_hdrs",
|
||||
"//src/core:bitset",
|
||||
"//src/core:channel_args",
|
||||
"//src/core:no_destruct",
|
||||
"//src/core:slice",
|
||||
"//src/core:time",
|
||||
"//test/core/util:grpc_test_util",
|
||||
],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "fixture_support",
|
||||
testonly = 1,
|
||||
srcs = ["fixtures/local_util.cc"],
|
||||
hdrs = [
|
||||
"fixtures/h2_oauth2_common.h",
|
||||
"fixtures/h2_ssl_cred_reload_fixture.h",
|
||||
"fixtures/h2_ssl_tls_common.h",
|
||||
|
|
@ -112,14 +147,17 @@ grpc_cc_library(
|
|||
"fixtures/local_util.h",
|
||||
"fixtures/secure_fixture.h",
|
||||
"fixtures/sockpair_fixture.h",
|
||||
"tests/cancel_test_helpers.h",
|
||||
],
|
||||
external_deps = [
|
||||
"absl/status",
|
||||
"absl/status:statusor",
|
||||
"absl/strings",
|
||||
"gtest",
|
||||
],
|
||||
language = "C++",
|
||||
deps = [
|
||||
"end2end_test_lib",
|
||||
"//:config",
|
||||
"//:exec_ctx",
|
||||
"//:gpr",
|
||||
|
|
@ -141,6 +179,162 @@ grpc_cc_library(
|
|||
],
|
||||
)
|
||||
|
||||
grpc_cc_test(
|
||||
name = "core_end2end_tests",
|
||||
timeout = "long",
|
||||
srcs = [
|
||||
"end2end_test_main.cc",
|
||||
"tests/bad_ping.cc",
|
||||
"tests/binary_metadata.cc",
|
||||
"tests/call_creds.cc",
|
||||
"tests/call_host_override.cc",
|
||||
"tests/cancel_after_accept.cc",
|
||||
"tests/cancel_after_client_done.cc",
|
||||
"tests/cancel_after_invoke.cc",
|
||||
"tests/cancel_after_round_trip.cc",
|
||||
"tests/cancel_before_invoke.cc",
|
||||
"tests/cancel_in_a_vacuum.cc",
|
||||
"tests/cancel_with_status.cc",
|
||||
"tests/channelz.cc",
|
||||
"tests/client_streaming.cc",
|
||||
"tests/compressed_payload.cc",
|
||||
"tests/connectivity.cc",
|
||||
"tests/default_host.cc",
|
||||
"tests/disappearing_server.cc",
|
||||
"tests/empty_batch.cc",
|
||||
"tests/filter_causes_close.cc",
|
||||
"tests/filter_context.cc",
|
||||
"tests/filter_init_fails.cc",
|
||||
"tests/filtered_metadata.cc",
|
||||
"tests/graceful_server_shutdown.cc",
|
||||
"tests/grpc_authz.cc",
|
||||
"tests/high_initial_seqno.cc",
|
||||
"tests/hpack_size.cc",
|
||||
"tests/invoke_large_request.cc",
|
||||
"tests/keepalive_timeout.cc",
|
||||
"tests/large_metadata.cc",
|
||||
"tests/max_concurrent_streams.cc",
|
||||
"tests/max_connection_age.cc",
|
||||
"tests/max_connection_idle.cc",
|
||||
"tests/max_message_length.cc",
|
||||
"tests/negative_deadline.cc",
|
||||
"tests/no_logging.cc",
|
||||
"tests/no_op.cc",
|
||||
"tests/payload.cc",
|
||||
"tests/ping.cc",
|
||||
"tests/ping_pong_streaming.cc",
|
||||
"tests/proxy_auth.cc",
|
||||
"tests/registered_call.cc",
|
||||
"tests/request_with_flags.cc",
|
||||
"tests/request_with_payload.cc",
|
||||
"tests/resource_quota_server.cc",
|
||||
"tests/retry.cc",
|
||||
"tests/retry_cancel_after_first_attempt_starts.cc",
|
||||
"tests/retry_cancel_during_delay.cc",
|
||||
"tests/retry_cancel_with_multiple_send_batches.cc",
|
||||
"tests/retry_cancellation.cc",
|
||||
"tests/retry_disabled.cc",
|
||||
"tests/retry_exceeds_buffer_size_in_delay.cc",
|
||||
"tests/retry_exceeds_buffer_size_in_initial_batch.cc",
|
||||
"tests/retry_exceeds_buffer_size_in_subsequent_batch.cc",
|
||||
"tests/retry_lb_drop.cc",
|
||||
"tests/retry_lb_fail.cc",
|
||||
"tests/retry_non_retriable_status.cc",
|
||||
"tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc",
|
||||
"tests/retry_per_attempt_recv_timeout.cc",
|
||||
"tests/retry_per_attempt_recv_timeout_on_last_attempt.cc",
|
||||
"tests/retry_recv_initial_metadata.cc",
|
||||
"tests/retry_recv_message.cc",
|
||||
"tests/retry_recv_message_replay.cc",
|
||||
"tests/retry_recv_trailing_metadata_error.cc",
|
||||
"tests/retry_send_initial_metadata_refs.cc",
|
||||
"tests/retry_send_op_fails.cc",
|
||||
"tests/retry_send_recv_batch.cc",
|
||||
"tests/retry_server_pushback_delay.cc",
|
||||
"tests/retry_server_pushback_disabled.cc",
|
||||
"tests/retry_streaming.cc",
|
||||
"tests/retry_streaming_after_commit.cc",
|
||||
"tests/retry_streaming_succeeds_before_replay_finished.cc",
|
||||
"tests/retry_throttled.cc",
|
||||
"tests/retry_too_many_attempts.cc",
|
||||
"tests/retry_transparent_goaway.cc",
|
||||
"tests/retry_transparent_max_concurrent_streams.cc",
|
||||
"tests/retry_transparent_not_sent_on_wire.cc",
|
||||
"tests/retry_unref_before_finish.cc",
|
||||
"tests/retry_unref_before_recv.cc",
|
||||
"tests/server_finishes_request.cc",
|
||||
"tests/server_streaming.cc",
|
||||
"tests/shutdown_finishes_calls.cc",
|
||||
"tests/shutdown_finishes_tags.cc",
|
||||
"tests/simple_delayed_request.cc",
|
||||
"tests/simple_metadata.cc",
|
||||
"tests/simple_request.cc",
|
||||
"tests/streaming_error_response.cc",
|
||||
"tests/trailing_metadata.cc",
|
||||
"tests/write_buffering.cc",
|
||||
"tests/write_buffering_at_end.cc",
|
||||
],
|
||||
data = [
|
||||
"//src/core/tsi/test_creds:ca.pem",
|
||||
"//src/core/tsi/test_creds:server1.key",
|
||||
"//src/core/tsi/test_creds:server1.pem",
|
||||
],
|
||||
external_deps = [
|
||||
"absl/status",
|
||||
"absl/status:statusor",
|
||||
"absl/strings",
|
||||
"absl/strings:str_format",
|
||||
"absl/types:optional",
|
||||
"gtest",
|
||||
],
|
||||
shard_count = 50,
|
||||
tags = ["core_end2end_test"],
|
||||
deps = [
|
||||
"cq_verifier",
|
||||
"end2end_test_lib",
|
||||
"fixture_support",
|
||||
"http_proxy",
|
||||
"proxy",
|
||||
"//:channel_stack_builder",
|
||||
"//:config",
|
||||
"//:config_vars",
|
||||
"//:debug_location",
|
||||
"//:exec_ctx",
|
||||
"//:gpr",
|
||||
"//:grpc_authorization_provider",
|
||||
"//:grpc_public_hdrs",
|
||||
"//:grpc_security_base",
|
||||
"//:grpc_trace",
|
||||
"//:grpc_unsecure",
|
||||
"//:orphanable",
|
||||
"//:promise",
|
||||
"//:ref_counted_ptr",
|
||||
"//:stats",
|
||||
"//src/core:arena_promise",
|
||||
"//src/core:bitset",
|
||||
"//src/core:channel_args",
|
||||
"//src/core:channel_fwd",
|
||||
"//src/core:channel_init",
|
||||
"//src/core:channel_stack_type",
|
||||
"//src/core:closure",
|
||||
"//src/core:error",
|
||||
"//src/core:grpc_authorization_base",
|
||||
"//src/core:grpc_fake_credentials",
|
||||
"//src/core:iomgr_port",
|
||||
"//src/core:json",
|
||||
"//src/core:lb_policy",
|
||||
"//src/core:lb_policy_factory",
|
||||
"//src/core:no_destruct",
|
||||
"//src/core:notification",
|
||||
"//src/core:slice",
|
||||
"//src/core:stats_data",
|
||||
"//src/core:status_helper",
|
||||
"//src/core:time",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//test/core/util:test_lb_policies",
|
||||
],
|
||||
)
|
||||
|
||||
grpc_cc_test(
|
||||
name = "bad_server_response_test",
|
||||
srcs = ["bad_server_response_test.cc"],
|
||||
|
|
@ -267,8 +461,6 @@ grpc_cc_test(
|
|||
],
|
||||
)
|
||||
|
||||
grpc_end2end_tests()
|
||||
|
||||
grpc_cc_test(
|
||||
name = "h2_ssl_cert_test",
|
||||
srcs = [
|
||||
|
|
@ -276,21 +468,29 @@ grpc_cc_test(
|
|||
"h2_ssl_cert_test.cc",
|
||||
],
|
||||
external_deps = [
|
||||
"absl/memory",
|
||||
"absl/strings",
|
||||
"absl/types:optional",
|
||||
"absl/types:variant",
|
||||
"gtest",
|
||||
"libcrypto",
|
||||
],
|
||||
language = "C++",
|
||||
deps = [
|
||||
"cq_verifier",
|
||||
"end2end_test_lib",
|
||||
"fixture_support",
|
||||
"ssl_test_data",
|
||||
"//:config_vars",
|
||||
"//:debug_location",
|
||||
"//:gpr",
|
||||
"//:grpc",
|
||||
"//:grpc_public_hdrs",
|
||||
"//:grpc_security_base",
|
||||
"//src/core:bitset",
|
||||
"//src/core:channel_args",
|
||||
"//src/core:slice",
|
||||
"//src/core:time",
|
||||
"//test/core/util:grpc_test_util",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
Each fixture (under fixtures/) is paired with each test (under tests/) and
|
||||
forms a complete end-to-end test.
|
||||
|
||||
To add a new test or fixture:
|
||||
- add the code to the relevant directory
|
||||
- update generate_tests.bzl to reflect the change
|
||||
- regenerate projects
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/compression.h>
|
||||
|
|
@ -196,7 +197,9 @@ std::string TagStr(void* tag) {
|
|||
|
||||
namespace grpc_core {
|
||||
|
||||
CqVerifier::CqVerifier(grpc_completion_queue* cq) : cq_(cq) {}
|
||||
CqVerifier::CqVerifier(grpc_completion_queue* cq,
|
||||
absl::AnyInvocable<void(Failure)> fail)
|
||||
: cq_(cq), fail_(std::move(fail)) {}
|
||||
|
||||
CqVerifier::~CqVerifier() { Verify(); }
|
||||
|
||||
|
|
@ -209,30 +212,66 @@ std::string CqVerifier::Expectation::ToString() const {
|
|||
return absl::StrCat("success=", success ? "true" : "false");
|
||||
},
|
||||
[](Maybe) { return std::string("maybe"); },
|
||||
[](AnyStatus) { return std::string("any success value"); }));
|
||||
[](AnyStatus) { return std::string("any success value"); },
|
||||
[](PerformAction) { return std::string("perform some action"); },
|
||||
[](MaybePerformAction) {
|
||||
return std::string("maybe perform action");
|
||||
}));
|
||||
}
|
||||
|
||||
std::string CqVerifier::ToString() const {
|
||||
std::vector<std::string> CqVerifier::ToStrings() const {
|
||||
std::vector<std::string> expectations;
|
||||
expectations.reserve(expectations_.size());
|
||||
for (const auto& e : expectations_) {
|
||||
expectations.push_back(e.ToString());
|
||||
}
|
||||
return absl::StrJoin(expectations, "\n");
|
||||
return expectations;
|
||||
}
|
||||
|
||||
std::string CqVerifier::ToString() const {
|
||||
return absl::StrJoin(ToStrings(), "\n");
|
||||
}
|
||||
|
||||
void CqVerifier::FailNoEventReceived(const SourceLocation& location) const {
|
||||
Crash(absl::StrFormat("[%s:%d] no event received, but expected:%s",
|
||||
location.file(), location.line(), ToString().c_str()));
|
||||
fail_(Failure{location, "No event received", ToStrings()});
|
||||
}
|
||||
|
||||
void CqVerifier::FailUnexpectedEvent(grpc_event* ev,
|
||||
const SourceLocation& location) const {
|
||||
gpr_log(GPR_ERROR, "[%s:%d] cq returned unexpected event: %s",
|
||||
location.file(), location.line(), grpc_event_string(ev).c_str());
|
||||
Crash(absl::StrFormat("expected tags:\n%s", ToString().c_str()));
|
||||
fail_(Failure{location,
|
||||
absl::StrCat("Unexpected event: ", grpc_event_string(ev)),
|
||||
ToStrings()});
|
||||
}
|
||||
|
||||
void CqVerifier::FailUsingGprCrash(const Failure& failure) {
|
||||
Crash(absl::StrCat("[", failure.location.file(), ":", failure.location.line(),
|
||||
"] ", failure.message, "\nexpected:\n",
|
||||
absl::StrJoin(failure.expected, "\n")));
|
||||
}
|
||||
|
||||
void CqVerifier::FailUsingGtestFail(const Failure& failure) {
|
||||
std::string message = absl::StrCat(" ", failure.message);
|
||||
if (!failure.expected.empty()) {
|
||||
absl::StrAppend(&message, "\n expected:\n");
|
||||
for (const auto& line : failure.expected) {
|
||||
absl::StrAppend(&message, " ", line, "\n");
|
||||
}
|
||||
} else {
|
||||
absl::StrAppend(&message, "\n expected nothing");
|
||||
}
|
||||
ADD_FAILURE_AT(failure.location.file(), failure.location.line()) << message;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool IsMaybe(const CqVerifier::ExpectedResult& r) {
|
||||
return Match(
|
||||
r, [](bool) { return false; }, [](CqVerifier::Maybe) { return true; },
|
||||
[](CqVerifier::AnyStatus) { return false; },
|
||||
[](const CqVerifier::PerformAction&) { return false; },
|
||||
[](const CqVerifier::MaybePerformAction&) { return true; });
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void CqVerifier::Verify(Duration timeout, SourceLocation location) {
|
||||
const gpr_timespec deadline =
|
||||
grpc_timeout_milliseconds_to_deadline(timeout.millis());
|
||||
|
|
@ -254,6 +293,14 @@ void CqVerifier::Verify(Duration timeout, SourceLocation location) {
|
|||
[ev](AnyStatus a) {
|
||||
if (a.result != nullptr) *a.result = ev.success;
|
||||
return true;
|
||||
},
|
||||
[ev](const PerformAction& action) {
|
||||
action.action(ev.success);
|
||||
return true;
|
||||
},
|
||||
[ev](const MaybePerformAction& action) {
|
||||
action.action(ev.success);
|
||||
return true;
|
||||
});
|
||||
if (!expected) {
|
||||
FailUnexpectedEvent(&ev, location);
|
||||
|
|
@ -267,16 +314,14 @@ void CqVerifier::Verify(Duration timeout, SourceLocation location) {
|
|||
}
|
||||
expectations_.erase(
|
||||
std::remove_if(expectations_.begin(), expectations_.end(),
|
||||
[](const Expectation& e) {
|
||||
return absl::holds_alternative<Maybe>(e.result);
|
||||
}),
|
||||
[](const Expectation& e) { return IsMaybe(e.result); }),
|
||||
expectations_.end());
|
||||
if (!expectations_.empty()) FailNoEventReceived(location);
|
||||
}
|
||||
|
||||
bool CqVerifier::AllMaybes() const {
|
||||
for (const auto& e : expectations_) {
|
||||
if (!absl::holds_alternative<Maybe>(e.result)) return false;
|
||||
if (!IsMaybe(e.result)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -293,7 +338,7 @@ void CqVerifier::VerifyEmpty(Duration timeout, SourceLocation location) {
|
|||
|
||||
void CqVerifier::Expect(void* tag, ExpectedResult result,
|
||||
SourceLocation location) {
|
||||
expectations_.push_back(Expectation{location, tag, result});
|
||||
expectations_.push_back(Expectation{location, tag, std::move(result)});
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/types/variant.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
|
@ -48,10 +50,34 @@ class CqVerifier {
|
|||
struct AnyStatus {
|
||||
bool* result = nullptr;
|
||||
};
|
||||
// PerformAction - expect the tag, and run a function based on the result
|
||||
struct PerformAction {
|
||||
std::function<void(bool success)> action;
|
||||
};
|
||||
// MaybePerformAction - run a function if a tag is seen
|
||||
struct MaybePerformAction {
|
||||
std::function<void(bool success)> action;
|
||||
};
|
||||
|
||||
using ExpectedResult = absl::variant<bool, Maybe, AnyStatus>;
|
||||
using ExpectedResult =
|
||||
absl::variant<bool, Maybe, AnyStatus, PerformAction, MaybePerformAction>;
|
||||
|
||||
explicit CqVerifier(grpc_completion_queue* cq);
|
||||
struct Failure {
|
||||
SourceLocation location;
|
||||
std::string message;
|
||||
std::vector<std::string> expected;
|
||||
};
|
||||
|
||||
static void FailUsingGprCrash(const Failure& failure);
|
||||
static void FailUsingGtestFail(const Failure& failure);
|
||||
|
||||
// Allow customizing the failure handler
|
||||
// For legacy tests we should use FailUsingGprCrash (the default)
|
||||
// For gtest based tests we should start migrating to FailUsingGtestFail which
|
||||
// will produce nicer failure messages.
|
||||
explicit CqVerifier(
|
||||
grpc_completion_queue* cq,
|
||||
absl::AnyInvocable<void(Failure)> fail = FailUsingGprCrash);
|
||||
~CqVerifier();
|
||||
|
||||
CqVerifier(const CqVerifier&) = delete;
|
||||
|
|
@ -74,6 +100,7 @@ class CqVerifier {
|
|||
SourceLocation location = SourceLocation());
|
||||
|
||||
std::string ToString() const;
|
||||
std::vector<std::string> ToStrings() const;
|
||||
|
||||
static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
|
||||
|
||||
|
|
@ -93,6 +120,7 @@ class CqVerifier {
|
|||
|
||||
grpc_completion_queue* const cq_;
|
||||
std::vector<Expectation> expectations_;
|
||||
mutable absl::AnyInvocable<void(Failure)> fail_;
|
||||
};
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <grpc/slice.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
const char* get_host_override_string(const char* str,
|
||||
const CoreTestConfiguration& config) {
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER) {
|
||||
return str;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const grpc_slice* get_host_override_slice(const char* str,
|
||||
const CoreTestConfiguration& config) {
|
||||
const char* r = get_host_override_string(str, config);
|
||||
if (r != nullptr) {
|
||||
static grpc_slice ret;
|
||||
ret = grpc_slice_from_static_string(r);
|
||||
return &ret;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void validate_host_override_string(const char* pattern, grpc_slice str,
|
||||
const CoreTestConfiguration& config) {
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER) {
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(str, pattern));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -19,20 +19,46 @@
|
|||
#ifndef GRPC_TEST_CORE_END2END_END2END_TESTS_H
|
||||
#define GRPC_TEST_CORE_END2END_END2END_TESTS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "absl/types/variant.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/compression.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/bitset.h"
|
||||
#include "src/core/lib/gprpp/debug_location.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/slice/slice.h"
|
||||
#include "src/core/lib/slice/slice_internal.h"
|
||||
#include "src/core/lib/surface/call_test_only.h"
|
||||
#include "src/core/lib/surface/channel.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// Test feature flags.
|
||||
#define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1
|
||||
#define FEATURE_MASK_DOES_NOT_SUPPORT_RETRY 1
|
||||
#define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2
|
||||
// Feature mask supports call credentials with a minimum security level of
|
||||
// GRPC_PRIVACY_AND_INTEGRITY.
|
||||
|
|
@ -42,12 +68,17 @@
|
|||
#define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE 8
|
||||
#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 16
|
||||
#define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 32
|
||||
#define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 64
|
||||
#define FEATURE_MASK_IS_HTTP2 64
|
||||
#define FEATURE_MASK_ENABLES_TRACES 128
|
||||
#define FEATURE_MASK_1BYTE_AT_A_TIME 256
|
||||
#define FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING 512
|
||||
#define FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST 1024
|
||||
#define FEATURE_MASK_DOES_NOT_SUPPORT_DEADLINES 2048
|
||||
#define FEATURE_MASK_IS_MINSTACK 2048
|
||||
#define FEATURE_MASK_IS_SECURE 4096
|
||||
|
||||
#define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"
|
||||
|
||||
namespace grpc_core {
|
||||
class CoreTestFixture {
|
||||
public:
|
||||
virtual ~CoreTestFixture() {
|
||||
|
|
@ -62,12 +93,12 @@ class CoreTestFixture {
|
|||
grpc_server* server() { return server_; }
|
||||
grpc_channel* client() { return client_; }
|
||||
|
||||
void InitServer(const grpc_core::ChannelArgs& args) {
|
||||
void InitServer(const ChannelArgs& args) {
|
||||
if (server_ != nullptr) ShutdownServer();
|
||||
server_ = MakeServer(args);
|
||||
GPR_ASSERT(server_ != nullptr);
|
||||
}
|
||||
void InitClient(const grpc_core::ChannelArgs& args) {
|
||||
void InitClient(const ChannelArgs& args) {
|
||||
if (client_ != nullptr) ShutdownClient();
|
||||
client_ = MakeClient(args);
|
||||
GPR_ASSERT(client_ != nullptr);
|
||||
|
|
@ -96,14 +127,14 @@ class CoreTestFixture {
|
|||
client_ = nullptr;
|
||||
}
|
||||
|
||||
virtual grpc_server* MakeServer(const ChannelArgs& args) = 0;
|
||||
virtual grpc_channel* MakeClient(const ChannelArgs& args) = 0;
|
||||
|
||||
protected:
|
||||
void SetServer(grpc_server* server);
|
||||
void SetClient(grpc_channel* client);
|
||||
|
||||
private:
|
||||
virtual grpc_server* MakeServer(const grpc_core::ChannelArgs& args) = 0;
|
||||
virtual grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) = 0;
|
||||
|
||||
void DrainCq() {
|
||||
grpc_event ev;
|
||||
do {
|
||||
|
|
@ -117,6 +148,12 @@ class CoreTestFixture {
|
|||
grpc_channel* client_ = nullptr;
|
||||
};
|
||||
|
||||
Slice RandomSlice(size_t length);
|
||||
Slice RandomBinarySlice(size_t length);
|
||||
using ByteBufferUniquePtr =
|
||||
std::unique_ptr<grpc_byte_buffer, void (*)(grpc_byte_buffer*)>;
|
||||
ByteBufferUniquePtr ByteBufferFromSlice(Slice slice);
|
||||
|
||||
struct CoreTestConfiguration {
|
||||
// A descriptive name for this test fixture.
|
||||
const char* name;
|
||||
|
|
@ -130,23 +167,584 @@ struct CoreTestConfiguration {
|
|||
const char* overridden_call_host;
|
||||
|
||||
std::function<std::unique_ptr<CoreTestFixture>(
|
||||
const grpc_core::ChannelArgs& client_args,
|
||||
const grpc_core::ChannelArgs& server_args)>
|
||||
const ChannelArgs& client_args, const ChannelArgs& server_args)>
|
||||
create_fixture;
|
||||
};
|
||||
|
||||
void grpc_end2end_tests_pre_init(void);
|
||||
void grpc_end2end_tests(int argc, char** argv,
|
||||
const CoreTestConfiguration& config);
|
||||
// Base class for e2e tests.
|
||||
//
|
||||
// Initialization:
|
||||
//
|
||||
// At the start of a test, nothing is initialized. CoreConfiguration is reset,
|
||||
// and there's certainly no server nor client.
|
||||
// A test can then register whatever builders it wants into the
|
||||
// CoreConfiguration and have them picked up. If it does not, it will get the
|
||||
// default CoreConfiguration.
|
||||
//
|
||||
// The test may choose to then create a client and server with InitClient() and
|
||||
// InitServer(). It does not matter which order they are called, nor whether one
|
||||
// or both are called. It's necessary to call these if the test demands that
|
||||
// non-empty channel args should be passed to either the client or server.
|
||||
//
|
||||
// If a test does not call InitClient() or InitServer(), then upon the first
|
||||
// call to either NewClientCall() or NewServerCall(), the client and server will
|
||||
// be instantiated - this saves substantial boilerplate in the most common case
|
||||
// for our tests.
|
||||
//
|
||||
// Notes:
|
||||
// - older compilers fail matching absl::string_view with some gmock matchers on
|
||||
// older compilers, and it's tremendously convenient to be able to do so. So
|
||||
// we use std::string for return types here - performance isn't particularly
|
||||
// important, so an extra copy is fine.
|
||||
class CoreEnd2endTest
|
||||
: public ::testing::TestWithParam<const CoreTestConfiguration*> {
|
||||
public:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
const char* get_host_override_string(const char* str,
|
||||
const CoreTestConfiguration& config);
|
||||
// Returns a pointer to a statically allocated slice: future invocations
|
||||
// overwrite past invocations, not threadsafe, etc...
|
||||
const grpc_slice* get_host_override_slice(const char* str,
|
||||
const CoreTestConfiguration& config);
|
||||
class Call;
|
||||
struct RegisteredCall {
|
||||
void* p;
|
||||
};
|
||||
|
||||
void validate_host_override_string(const char* pattern, grpc_slice str,
|
||||
const CoreTestConfiguration& config);
|
||||
// CallBuilder - results in a call to either grpc_channel_create_call or
|
||||
// grpc_channel_create_registered_call.
|
||||
// Affords a fluent interface to specify optional arguments.
|
||||
class ClientCallBuilder {
|
||||
public:
|
||||
ClientCallBuilder(CoreEnd2endTest& test, std::string method)
|
||||
: test_(test),
|
||||
call_selector_(UnregisteredCall{std::move(method), absl::nullopt}) {}
|
||||
ClientCallBuilder(CoreEnd2endTest& test, RegisteredCall registered_call)
|
||||
: test_(test), call_selector_(registered_call.p) {}
|
||||
|
||||
// Specify the host (otherwise nullptr is passed)
|
||||
ClientCallBuilder& Host(std::string host) {
|
||||
absl::get<UnregisteredCall>(call_selector_).host = std::move(host);
|
||||
return *this;
|
||||
}
|
||||
// Specify the timeout (otherwise gpr_inf_future is passed) - this time is
|
||||
// scaled according to the test environment.
|
||||
ClientCallBuilder& Timeout(Duration timeout) {
|
||||
if (timeout == Duration::Infinity()) {
|
||||
deadline_ = gpr_inf_future(GPR_CLOCK_REALTIME);
|
||||
return *this;
|
||||
}
|
||||
deadline_ = grpc_timeout_milliseconds_to_deadline(timeout.millis());
|
||||
return *this;
|
||||
}
|
||||
// Finally create the call.
|
||||
Call Create();
|
||||
|
||||
private:
|
||||
CoreEnd2endTest& test_;
|
||||
struct UnregisteredCall {
|
||||
std::string method;
|
||||
absl::optional<std::string> host;
|
||||
};
|
||||
absl::variant<void*, UnregisteredCall> call_selector_;
|
||||
grpc_call* parent_call_ = nullptr;
|
||||
uint32_t propagation_mask_ = GRPC_PROPAGATE_DEFAULTS;
|
||||
gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_REALTIME);
|
||||
};
|
||||
|
||||
// Receiving container for incoming metadata.
|
||||
class IncomingMetadata {
|
||||
public:
|
||||
IncomingMetadata() = default;
|
||||
~IncomingMetadata() {
|
||||
if (metadata_ != nullptr) grpc_metadata_array_destroy(metadata_.get());
|
||||
}
|
||||
|
||||
// Lookup a metadata value by key.
|
||||
absl::optional<std::string> Get(absl::string_view key) const;
|
||||
|
||||
// Make a GRPC_RECV_INITIAL_METADATA op - intended for the framework, not
|
||||
// for tests.
|
||||
grpc_op MakeOp();
|
||||
|
||||
private:
|
||||
std::unique_ptr<grpc_metadata_array> metadata_ =
|
||||
std::make_unique<grpc_metadata_array>(
|
||||
grpc_metadata_array{0, 0, nullptr});
|
||||
};
|
||||
|
||||
// Receiving container for one incoming message.
|
||||
class IncomingMessage {
|
||||
public:
|
||||
IncomingMessage() = default;
|
||||
IncomingMessage(const IncomingMessage&) = delete;
|
||||
IncomingMessage& operator=(const IncomingMessage&) = delete;
|
||||
~IncomingMessage() {
|
||||
if (payload_ != nullptr) grpc_byte_buffer_destroy(payload_);
|
||||
}
|
||||
|
||||
// Get the payload of the message - concatenated together into a string for
|
||||
// easy verification.
|
||||
std::string payload() const;
|
||||
// Check if the message is the end of the stream.
|
||||
bool is_end_of_stream() const { return payload_ == nullptr; }
|
||||
// Get the type of the message.
|
||||
grpc_byte_buffer_type byte_buffer_type() const { return payload_->type; }
|
||||
// Get the compression algorithm used for the message.
|
||||
grpc_compression_algorithm compression() const {
|
||||
return payload_->data.raw.compression;
|
||||
}
|
||||
|
||||
// Make a GRPC_OP_RECV_MESSAGE op - intended for the framework, not for
|
||||
// tests.
|
||||
grpc_op MakeOp();
|
||||
|
||||
private:
|
||||
grpc_byte_buffer* payload_ = nullptr;
|
||||
};
|
||||
|
||||
// Receiving container for incoming status on the client from the server.
|
||||
class IncomingStatusOnClient {
|
||||
public:
|
||||
IncomingStatusOnClient() = default;
|
||||
IncomingStatusOnClient(const IncomingStatusOnClient&) = delete;
|
||||
IncomingStatusOnClient& operator=(const IncomingStatusOnClient&) = delete;
|
||||
IncomingStatusOnClient(IncomingStatusOnClient&& other) noexcept = default;
|
||||
IncomingStatusOnClient& operator=(IncomingStatusOnClient&& other) noexcept =
|
||||
default;
|
||||
~IncomingStatusOnClient() {
|
||||
if (data_ != nullptr) {
|
||||
grpc_metadata_array_destroy(&data_->trailing_metadata);
|
||||
gpr_free(const_cast<char*>(data_->error_string));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the status code.
|
||||
grpc_status_code status() const { return data_->status; }
|
||||
// Get the status details.
|
||||
std::string message() const {
|
||||
return std::string(data_->status_details.as_string_view());
|
||||
}
|
||||
// Get the error string.
|
||||
std::string error_string() const {
|
||||
return data_->error_string == nullptr ? "" : data_->error_string;
|
||||
}
|
||||
// Get a trailing metadata value by key.
|
||||
absl::optional<std::string> GetTrailingMetadata(
|
||||
absl::string_view key) const;
|
||||
|
||||
// Make a GRPC_OP_RECV_STATUS_ON_CLIENT op - intended for the framework, not
|
||||
// for tests.
|
||||
grpc_op MakeOp();
|
||||
|
||||
private:
|
||||
struct Data {
|
||||
grpc_metadata_array trailing_metadata{0, 0, nullptr};
|
||||
grpc_status_code status;
|
||||
Slice status_details;
|
||||
const char* error_string = nullptr;
|
||||
};
|
||||
std::unique_ptr<Data> data_ = std::make_unique<Data>();
|
||||
};
|
||||
|
||||
// Receiving container for incoming status on the server from the client.
|
||||
class IncomingCloseOnServer {
|
||||
public:
|
||||
IncomingCloseOnServer() = default;
|
||||
IncomingCloseOnServer(const IncomingCloseOnServer&) = delete;
|
||||
IncomingCloseOnServer& operator=(const IncomingCloseOnServer&) = delete;
|
||||
|
||||
// Get the cancellation bit.
|
||||
bool was_cancelled() const { return cancelled_ != 0; }
|
||||
|
||||
// Make a GRPC_OP_RECV_CLOSE_ON_SERVER op - intended for the framework, not
|
||||
// for tests.
|
||||
grpc_op MakeOp();
|
||||
|
||||
private:
|
||||
int cancelled_;
|
||||
};
|
||||
|
||||
// Build one batch. Returned from NewBatch (use that to instantiate this!)
|
||||
// Upon destruction of the BatchBuilder, the batch will be executed with any
|
||||
// added batches.
|
||||
class BatchBuilder {
|
||||
public:
|
||||
BatchBuilder(grpc_call* call, int tag) : call_(call), tag_(tag) {}
|
||||
~BatchBuilder();
|
||||
|
||||
BatchBuilder(const BatchBuilder&) = delete;
|
||||
BatchBuilder& operator=(const BatchBuilder&) = delete;
|
||||
BatchBuilder(BatchBuilder&&) noexcept = default;
|
||||
|
||||
// Add a GRPC_OP_SEND_INITIAL_METADATA op.
|
||||
// Optionally specify flags, compression level.
|
||||
BatchBuilder& SendInitialMetadata(
|
||||
std::initializer_list<std::pair<absl::string_view, absl::string_view>>
|
||||
md,
|
||||
uint32_t flags = 0,
|
||||
absl::optional<grpc_compression_level> compression_level =
|
||||
absl::nullopt);
|
||||
|
||||
// Add a GRPC_OP_SEND_MESSAGE op.
|
||||
BatchBuilder& SendMessage(Slice payload, uint32_t flags = 0);
|
||||
BatchBuilder& SendMessage(absl::string_view payload, uint32_t flags = 0) {
|
||||
return SendMessage(Slice::FromCopiedString(payload), flags);
|
||||
}
|
||||
|
||||
// Add a GRPC_OP_SEND_CLOSE_FROM_CLIENT op.
|
||||
BatchBuilder& SendCloseFromClient();
|
||||
|
||||
// Add a GRPC_OP_SEND_STATUS_FROM_SERVER op.
|
||||
BatchBuilder& SendStatusFromServer(
|
||||
grpc_status_code status, absl::string_view message,
|
||||
std::initializer_list<std::pair<absl::string_view, absl::string_view>>
|
||||
md);
|
||||
|
||||
// Add a GRPC_OP_RECV_INITIAL_METADATA op.
|
||||
BatchBuilder& RecvInitialMetadata(IncomingMetadata& md) {
|
||||
ops_.emplace_back(md.MakeOp());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add a GRPC_OP_RECV_MESSAGE op.
|
||||
BatchBuilder& RecvMessage(IncomingMessage& msg) {
|
||||
ops_.emplace_back(msg.MakeOp());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add a GRPC_OP_RECV_STATUS_ON_CLIENT op.
|
||||
BatchBuilder& RecvStatusOnClient(IncomingStatusOnClient& status) {
|
||||
ops_.emplace_back(status.MakeOp());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add a GRPC_OP_RECV_CLOSE_ON_SERVER op.
|
||||
BatchBuilder& RecvCloseOnServer(IncomingCloseOnServer& close) {
|
||||
ops_.emplace_back(close.MakeOp());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// We need to track little bits of memory up until the batch is executed.
|
||||
// One Thing is one such block of memory.
|
||||
// We specialize it with SpecificThing to track a specific type of memory.
|
||||
// These get placed on things_ and deleted when the batch is executed.
|
||||
class Thing {
|
||||
public:
|
||||
virtual ~Thing() = default;
|
||||
};
|
||||
template <typename T>
|
||||
class SpecificThing final : public Thing {
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit SpecificThing(Args&&... args)
|
||||
: t_(std::forward<Args>(args)...) {}
|
||||
SpecificThing() = default;
|
||||
|
||||
T& get() { return t_; }
|
||||
|
||||
private:
|
||||
T t_;
|
||||
};
|
||||
|
||||
// Make a thing of type T, and return a reference to it.
|
||||
template <typename T, typename... Args>
|
||||
T& Make(Args&&... args) {
|
||||
things_.emplace_back(new SpecificThing<T>(std::forward<Args>(args)...));
|
||||
return static_cast<SpecificThing<T>*>(things_.back().get())->get();
|
||||
}
|
||||
|
||||
grpc_call* call_;
|
||||
const int tag_;
|
||||
std::vector<grpc_op> ops_;
|
||||
std::vector<std::unique_ptr<Thing>> things_;
|
||||
};
|
||||
|
||||
// Wrapper around a grpc_call.
|
||||
// Instantiated by ClientCallBuilder via NewClientCall for client calls.
|
||||
// Wrapped by IncomingCall for server calls.
|
||||
class Call {
|
||||
public:
|
||||
explicit Call(grpc_call* call) : call_(call) {}
|
||||
Call(const Call&) = delete;
|
||||
Call& operator=(const Call&) = delete;
|
||||
Call(Call&& other) noexcept : call_(std::exchange(other.call_, nullptr)) {}
|
||||
~Call() {
|
||||
if (call_ != nullptr) grpc_call_unref(call_);
|
||||
}
|
||||
// Construct a batch with a tag - upon destruction of the BatchBuilder the
|
||||
// operation will occur.
|
||||
BatchBuilder NewBatch(int tag) { return BatchBuilder(call_, tag); }
|
||||
// Cancel the call
|
||||
void Cancel() { grpc_call_cancel(call_, nullptr); }
|
||||
void CancelWithStatus(grpc_status_code status, const char* message) {
|
||||
grpc_call_cancel_with_status(call_, status, message, nullptr);
|
||||
}
|
||||
// Access the peer structure (returns a string that can be matched, etc) -
|
||||
// or nullopt if grpc_call_get_peer returns nullptr.
|
||||
absl::optional<std::string> GetPeer() {
|
||||
char* peer = grpc_call_get_peer(call_);
|
||||
if (peer == nullptr) return absl::nullopt;
|
||||
std::string result(peer);
|
||||
gpr_free(peer);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Set call credentials.
|
||||
// Takes ownership of creds.
|
||||
void SetCredentials(grpc_call_credentials* creds) {
|
||||
EXPECT_EQ(grpc_call_set_credentials(call_, creds), GRPC_CALL_OK);
|
||||
grpc_call_credentials_release(creds);
|
||||
}
|
||||
|
||||
// Retrieve the auth context.
|
||||
std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>
|
||||
GetAuthContext() {
|
||||
return std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>(
|
||||
grpc_call_auth_context(call_), grpc_auth_context_release);
|
||||
}
|
||||
|
||||
grpc_call** call_ptr() { return &call_; }
|
||||
grpc_call* c_call() const { return call_; }
|
||||
|
||||
private:
|
||||
grpc_call* call_ = nullptr;
|
||||
};
|
||||
|
||||
// Wrapper around a server call.
|
||||
class IncomingCall {
|
||||
public:
|
||||
IncomingCall(CoreEnd2endTest& test, int tag);
|
||||
IncomingCall(const IncomingCall&) = delete;
|
||||
IncomingCall& operator=(const IncomingCall&) = delete;
|
||||
IncomingCall(IncomingCall&&) noexcept = default;
|
||||
|
||||
// Construct a batch with a tag - upon destruction of the BatchBuilder the
|
||||
// operation will occur. Must have received the call first!
|
||||
BatchBuilder NewBatch(int tag) { return impl_->call.NewBatch(tag); }
|
||||
void Cancel() { impl_->call.Cancel(); }
|
||||
|
||||
// Return the method being called.
|
||||
std::string method() const {
|
||||
return std::string(StringViewFromSlice(impl_->call_details.method));
|
||||
}
|
||||
|
||||
// Return the host being called.
|
||||
std::string host() const {
|
||||
return std::string(StringViewFromSlice(impl_->call_details.host));
|
||||
}
|
||||
|
||||
// Return some initial metadata.
|
||||
absl::optional<std::string> GetInitialMetadata(absl::string_view key) const;
|
||||
|
||||
// Return the peer address.
|
||||
absl::optional<std::string> GetPeer() { return impl_->call.GetPeer(); }
|
||||
|
||||
// Return the auth context.
|
||||
std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>
|
||||
GetAuthContext() {
|
||||
return impl_->call.GetAuthContext();
|
||||
}
|
||||
|
||||
// Return the underlying C call object
|
||||
grpc_call* c_call() { return impl_->call.c_call(); }
|
||||
|
||||
// Return the encodings accepted by the peer.
|
||||
BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT> GetEncodingsAcceptedByPeer() {
|
||||
return BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT>::FromInt(
|
||||
grpc_call_test_only_get_encodings_accepted_by_peer(c_call()));
|
||||
}
|
||||
|
||||
private:
|
||||
struct Impl {
|
||||
Impl() {
|
||||
grpc_call_details_init(&call_details);
|
||||
grpc_metadata_array_init(&request_metadata);
|
||||
}
|
||||
~Impl() {
|
||||
grpc_call_details_destroy(&call_details);
|
||||
grpc_metadata_array_destroy(&request_metadata);
|
||||
}
|
||||
Call call{nullptr};
|
||||
grpc_call_details call_details;
|
||||
grpc_metadata_array request_metadata;
|
||||
};
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
// Begin construction of a client call.
|
||||
ClientCallBuilder NewClientCall(std::string method) {
|
||||
return ClientCallBuilder(*this, std::move(method));
|
||||
}
|
||||
ClientCallBuilder NewClientCall(RegisteredCall registered_method) {
|
||||
return ClientCallBuilder(*this, registered_method);
|
||||
}
|
||||
// Request a call on the server - notifies `tag` when complete.
|
||||
IncomingCall RequestCall(int tag) { return IncomingCall(*this, tag); }
|
||||
|
||||
// Pull in CqVerifier types for ergonomics
|
||||
// TODO(ctiller): evaluate just dropping CqVerifier and folding it in here.
|
||||
using ExpectedResult = CqVerifier::ExpectedResult;
|
||||
using Maybe = CqVerifier::Maybe;
|
||||
using PerformAction = CqVerifier::PerformAction;
|
||||
using MaybePerformAction = CqVerifier::MaybePerformAction;
|
||||
using AnyStatus = CqVerifier::AnyStatus;
|
||||
// Expect a tag with some result.
|
||||
void Expect(int tag, ExpectedResult result, SourceLocation whence = {}) {
|
||||
expectations_++;
|
||||
cq_verifier().Expect(CqVerifier::tag(tag), result, whence);
|
||||
}
|
||||
// Step the system until expectations are met or until timeout is reached.
|
||||
// If there are no expectations logged, then step for 1 second and verify that
|
||||
// no events occur.
|
||||
void Step(absl::optional<Duration> timeout = absl::nullopt,
|
||||
SourceLocation whence = {}) {
|
||||
if (expectations_ == 0) {
|
||||
cq_verifier().VerifyEmpty(timeout.value_or(Duration::Seconds(1)), whence);
|
||||
return;
|
||||
}
|
||||
expectations_ = 0;
|
||||
cq_verifier().Verify(timeout.value_or(Duration::Seconds(10)), whence);
|
||||
}
|
||||
|
||||
// Initialize the client.
|
||||
// If called, then InitServer must be called to create a server (otherwise one
|
||||
// will be provided).
|
||||
void InitClient(const ChannelArgs& args) {
|
||||
initialized_ = true;
|
||||
fixture().InitClient(args);
|
||||
}
|
||||
// Initialize the server.
|
||||
// If called, then InitClient must be called to create a client (otherwise one
|
||||
// will be provided).
|
||||
void InitServer(const ChannelArgs& args) {
|
||||
initialized_ = true;
|
||||
fixture().InitServer(args);
|
||||
}
|
||||
// Remove the client.
|
||||
void ShutdownAndDestroyClient() { fixture().ShutdownClient(); }
|
||||
// Shutdown the server; notify tag on completion.
|
||||
void ShutdownServerAndNotify(int tag) {
|
||||
grpc_server_shutdown_and_notify(fixture().server(), fixture().cq(),
|
||||
CqVerifier::tag(tag));
|
||||
}
|
||||
// Destroy the server.
|
||||
void DestroyServer() { fixture().DestroyServer(); }
|
||||
// Shutdown then destroy the server.
|
||||
void ShutdownAndDestroyServer() { fixture().ShutdownServer(); }
|
||||
// Cancel any calls on the server.
|
||||
void CancelAllCallsOnServer() {
|
||||
grpc_server_cancel_all_calls(fixture().server());
|
||||
}
|
||||
// Ping the server from the client
|
||||
void PingServerFromClient(int tag) {
|
||||
grpc_channel_ping(fixture().client(), fixture().cq(), CqVerifier::tag(tag),
|
||||
nullptr);
|
||||
}
|
||||
// Register a call on the client, return its handle.
|
||||
RegisteredCall RegisterCallOnClient(const char* method, const char* host) {
|
||||
ForceInitialized();
|
||||
return RegisteredCall{
|
||||
grpc_channel_register_call(fixture().client(), method, host, nullptr)};
|
||||
}
|
||||
|
||||
// Return the current connectivity state of the client.
|
||||
grpc_connectivity_state CheckConnectivityState(bool try_to_connect) {
|
||||
return grpc_channel_check_connectivity_state(fixture().client(),
|
||||
try_to_connect);
|
||||
}
|
||||
|
||||
// Watch the connectivity state of the client.
|
||||
void WatchConnectivityState(grpc_connectivity_state last_observed_state,
|
||||
Duration deadline, int tag) {
|
||||
grpc_channel_watch_connectivity_state(
|
||||
fixture().client(), last_observed_state,
|
||||
grpc_timeout_milliseconds_to_deadline(deadline.millis()),
|
||||
fixture().cq(), CqVerifier::tag(tag));
|
||||
}
|
||||
|
||||
// Return the client channel.
|
||||
grpc_channel* client() {
|
||||
ForceInitialized();
|
||||
return fixture().client();
|
||||
}
|
||||
|
||||
// Return the server channel.
|
||||
grpc_server* server() {
|
||||
ForceInitialized();
|
||||
return fixture().server();
|
||||
}
|
||||
|
||||
// Given a duration, return a timestamp that is that duration in the future -
|
||||
// with dilation according to test environment (eg sanitizers)
|
||||
Timestamp TimestampAfterDuration(Duration duration) {
|
||||
return Timestamp::FromTimespecRoundUp(
|
||||
grpc_timeout_milliseconds_to_deadline(duration.millis()));
|
||||
}
|
||||
|
||||
private:
|
||||
void ForceInitialized();
|
||||
|
||||
CoreTestFixture& fixture() {
|
||||
if (fixture_ == nullptr) {
|
||||
grpc_init();
|
||||
fixture_ = GetParam()->create_fixture(ChannelArgs(), ChannelArgs());
|
||||
}
|
||||
return *fixture_;
|
||||
}
|
||||
|
||||
CqVerifier& cq_verifier() {
|
||||
if (cq_verifier_ == nullptr) {
|
||||
cq_verifier_ = absl::make_unique<CqVerifier>(
|
||||
fixture().cq(), CqVerifier::FailUsingGtestFail);
|
||||
}
|
||||
return *cq_verifier_;
|
||||
}
|
||||
|
||||
std::unique_ptr<CoreTestFixture> fixture_;
|
||||
std::unique_ptr<CqVerifier> cq_verifier_;
|
||||
int expectations_ = 0;
|
||||
bool initialized_ = false;
|
||||
};
|
||||
|
||||
// Define names for additional test suites.
|
||||
// These make no changes to the actual class, but define new names to register
|
||||
// tests against. Each new name gets a differing set of configurations in
|
||||
// end2end_test_main.cc to customize the set of fixtures the tests run against.
|
||||
|
||||
// Test suite for tests that rely on a secure transport
|
||||
class SecureEnd2endTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that send rather large messages/metadata
|
||||
class CoreLargeSendTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that need a client channel
|
||||
class CoreClientChannelTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that require deadline handling
|
||||
class CoreDeadlineTest : 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
|
||||
class RetryTest : public CoreEnd2endTest {};
|
||||
// Test suite for write buffering
|
||||
class WriteBufferingTest : public CoreEnd2endTest {};
|
||||
// Test suite for http2 tests
|
||||
class Http2Test : public CoreEnd2endTest {};
|
||||
// Test suite for http2 tests that require retry features
|
||||
class RetryHttp2Test : public CoreEnd2endTest {};
|
||||
// Test suite for tests that require resource quota
|
||||
class ResourceQuotaTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that require a transport that supports secure call
|
||||
// credentials
|
||||
class PerCallCredsTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that require a transport that supports insecure call
|
||||
// credentials
|
||||
class PerCallCredsOnInsecureTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that verify lack of logging in particular situations
|
||||
class NoLoggingTest : public CoreEnd2endTest {};
|
||||
// Test suite for tests that verify proxy authentication
|
||||
class ProxyAuthTest : public CoreEnd2endTest {};
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
// If this test fixture is being run under minstack, skip the test.
|
||||
#define SKIP_IF_MINSTACK() \
|
||||
if (GetParam()->feature_mask & FEATURE_MASK_IS_MINSTACK) \
|
||||
GTEST_SKIP() << "Skipping test for minstack"
|
||||
|
||||
#endif // GRPC_TEST_CORE_END2END_END2END_TESTS_H
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
class CensusFixture : public CoreTestFixture {
|
||||
private:
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_server_credentials* server_creds =
|
||||
grpc_insecure_server_credentials_create();
|
||||
auto* server = grpc_server_create(
|
||||
args.Set(GRPC_ARG_ENABLE_CENSUS, true).ToC().get(), nullptr);
|
||||
grpc_server_register_completion_queue(server, cq(), nullptr);
|
||||
GPR_ASSERT(
|
||||
grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
|
||||
grpc_server_credentials_release(server_creds);
|
||||
grpc_server_start(server);
|
||||
return server;
|
||||
}
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) override {
|
||||
auto* creds = grpc_insecure_credentials_create();
|
||||
auto* client =
|
||||
grpc_channel_create(localaddr_.c_str(), creds,
|
||||
args.Set(GRPC_ARG_ENABLE_CENSUS, true).ToC().get());
|
||||
grpc_channel_credentials_release(creds);
|
||||
return client;
|
||||
}
|
||||
const std::string localaddr_ =
|
||||
grpc_core::JoinHostPort("localhost", grpc_pick_unused_port_or_die());
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack+census",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<CensusFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <grpc/compression.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
class CompressionFixture : public CoreTestFixture {
|
||||
private:
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
auto* server = grpc_server_create(
|
||||
args.SetIfUnset(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
|
||||
GRPC_COMPRESS_GZIP)
|
||||
.ToC()
|
||||
.get(),
|
||||
nullptr);
|
||||
grpc_server_register_completion_queue(server, cq(), nullptr);
|
||||
grpc_server_credentials* server_creds =
|
||||
grpc_insecure_server_credentials_create();
|
||||
GPR_ASSERT(
|
||||
grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
|
||||
grpc_server_credentials_release(server_creds);
|
||||
grpc_server_start(server);
|
||||
return server;
|
||||
}
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
|
||||
auto* client = grpc_channel_create(
|
||||
localaddr_.c_str(), creds,
|
||||
args.SetIfUnset(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
|
||||
GRPC_COMPRESS_GZIP)
|
||||
.ToC()
|
||||
.get());
|
||||
grpc_channel_credentials_release(creds);
|
||||
return client;
|
||||
}
|
||||
|
||||
std::string localaddr_ =
|
||||
grpc_core::JoinHostPort("localhost", grpc_pick_unused_port_or_die());
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_compression",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<CompressionFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
|
||||
const grpc_metadata* /*md*/,
|
||||
size_t /*md_count*/,
|
||||
grpc_process_auth_metadata_done_cb cb,
|
||||
void* user_data) {
|
||||
GPR_ASSERT(state == nullptr);
|
||||
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
|
||||
}
|
||||
|
||||
class FakesecFixture : public SecureFixture {
|
||||
private:
|
||||
grpc_channel_credentials* MakeClientCreds(
|
||||
const grpc_core::ChannelArgs&) override {
|
||||
return grpc_fake_transport_security_credentials_create();
|
||||
}
|
||||
grpc_server_credentials* MakeServerCreds(
|
||||
const grpc_core::ChannelArgs& args) override {
|
||||
grpc_server_credentials* fake_ts_creds =
|
||||
grpc_fake_transport_security_server_credentials_create();
|
||||
if (args.Contains(FAIL_AUTH_CHECK_SERVER_ARG_NAME)) {
|
||||
grpc_auth_metadata_processor processor = {process_auth_failure, nullptr,
|
||||
nullptr};
|
||||
grpc_server_credentials_set_auth_metadata_processor(fake_ts_creds,
|
||||
processor);
|
||||
}
|
||||
return fake_ts_creds;
|
||||
}
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fake_secure_fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE,
|
||||
nullptr, [](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<FakesecFixture>();
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/iomgr/port.h"
|
||||
|
||||
// This test won't work except with posix sockets enabled
|
||||
#ifdef GRPC_POSIX_SOCKET
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_posix.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/iomgr/exec_ctx.h"
|
||||
#include "src/core/lib/iomgr/socket_utils_posix.h"
|
||||
#include "src/core/lib/iomgr/unix_sockets_posix.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static void create_sockets(int sv[2]) {
|
||||
int flags;
|
||||
grpc_create_socketpair_if_unix(sv);
|
||||
flags = fcntl(sv[0], F_GETFL, 0);
|
||||
GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0);
|
||||
flags = fcntl(sv[1], F_GETFL, 0);
|
||||
GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0);
|
||||
GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[0]) == absl::OkStatus());
|
||||
GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1]) == absl::OkStatus());
|
||||
}
|
||||
|
||||
class FdFixture : public CoreTestFixture {
|
||||
public:
|
||||
FdFixture() { create_sockets(fd_pair_); }
|
||||
|
||||
private:
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
auto* server = grpc_server_create(args.ToC().get(), nullptr);
|
||||
grpc_server_register_completion_queue(server, cq(), nullptr);
|
||||
grpc_server_start(server);
|
||||
grpc_server_credentials* creds = grpc_insecure_server_credentials_create();
|
||||
grpc_server_add_channel_from_fd(server, fd_pair_[1], creds);
|
||||
grpc_server_credentials_release(creds);
|
||||
return server;
|
||||
}
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
|
||||
auto* client = grpc_channel_create_from_fd("fixture_client", fd_pair_[0],
|
||||
creds, args.ToC().get());
|
||||
grpc_channel_credentials_release(creds);
|
||||
return client;
|
||||
}
|
||||
|
||||
int fd_pair_[2];
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fd", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<FdFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // GRPC_POSIX_SOCKET
|
||||
|
||||
int main(int /* argc */, char** /* argv */) { return 1; }
|
||||
|
||||
#endif // GRPC_POSIX_SOCKET
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/iomgr/port.h"
|
||||
|
||||
// This test requires posix wakeup fds
|
||||
#ifdef GRPC_POSIX_WAKEUP_FD
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
return std::make_unique<InsecureFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc_allow_specialized_wakeup_fd = 0;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // GRPC_POSIX_WAKEUP_FD
|
||||
|
||||
int main(int argc, char** argv) { return 1; }
|
||||
|
||||
#endif // GRPC_POSIX_WAKEUP_FD
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <grpc/support/port_platform.h>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/iomgr/port.h" // IWYU pragma: keep
|
||||
|
||||
#ifdef GRPC_POSIX_SOCKET
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
return std::make_unique<InsecureFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
// force tracing on, with a value to force many
|
||||
// code paths in trace.c to be taken
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.trace = "doesnt-exist,http,all";
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
#ifdef GRPC_POSIX_SOCKET
|
||||
g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1;
|
||||
#else
|
||||
g_fixture_slowdown_factor = 10;
|
||||
#endif
|
||||
|
||||
#ifdef GPR_WINDOWS
|
||||
// on Windows, writing logs to stderr is very slow
|
||||
// when stderr is redirected to a disk file.
|
||||
// The "trace" tests fixtures generates large amount
|
||||
// of logs, so setting a buffer for stderr prevents certain
|
||||
// test cases from timing out.
|
||||
setvbuf(stderr, NULL, _IOLBF, 1024);
|
||||
#endif
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
GPR_ASSERT(0 == grpc_tracer_set_enabled("also-doesnt-exist", 0));
|
||||
GPR_ASSERT(1 == grpc_tracer_set_enabled("http", 1));
|
||||
GPR_ASSERT(1 == grpc_tracer_set_enabled("all", 1));
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
return std::make_unique<InsecureFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
class NoRetryFixture : public InsecureFixture {
|
||||
private:
|
||||
grpc_core::ChannelArgs MutateClientArgs(
|
||||
grpc_core::ChannelArgs args) override {
|
||||
return args.Set(GRPC_ARG_ENABLE_RETRIES, false);
|
||||
}
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
return std::make_unique<NoRetryFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2016 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 <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/http_proxy_fixture.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
class HttpProxyFilter : public CoreTestFixture {
|
||||
public:
|
||||
explicit HttpProxyFilter(const grpc_core::ChannelArgs& client_args)
|
||||
: proxy_(grpc_end2end_http_proxy_create(client_args.ToC().get())) {}
|
||||
~HttpProxyFilter() override {
|
||||
// Need to shut down the proxy users before closing the proxy (otherwise we
|
||||
// become stuck).
|
||||
ShutdownClient();
|
||||
ShutdownServer();
|
||||
grpc_end2end_http_proxy_destroy(proxy_);
|
||||
}
|
||||
|
||||
private:
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
auto* server = grpc_server_create(args.ToC().get(), nullptr);
|
||||
grpc_server_register_completion_queue(server, cq(), nullptr);
|
||||
grpc_server_credentials* server_creds =
|
||||
grpc_insecure_server_credentials_create();
|
||||
GPR_ASSERT(
|
||||
grpc_server_add_http2_port(server, server_addr_.c_str(), server_creds));
|
||||
grpc_server_credentials_release(server_creds);
|
||||
grpc_server_start(server);
|
||||
return server;
|
||||
}
|
||||
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) override {
|
||||
// If testing for proxy auth, add credentials to proxy uri
|
||||
absl::optional<std::string> proxy_auth_str =
|
||||
args.GetOwnedString(GRPC_ARG_HTTP_PROXY_AUTH_CREDS);
|
||||
std::string proxy_uri;
|
||||
if (!proxy_auth_str.has_value()) {
|
||||
proxy_uri = absl::StrFormat(
|
||||
"http://%s", grpc_end2end_http_proxy_get_proxy_name(proxy_));
|
||||
} else {
|
||||
proxy_uri =
|
||||
absl::StrFormat("http://%s@%s", proxy_auth_str->c_str(),
|
||||
grpc_end2end_http_proxy_get_proxy_name(proxy_));
|
||||
}
|
||||
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
|
||||
auto* client = grpc_channel_create(
|
||||
server_addr_.c_str(), creds,
|
||||
args.Set(GRPC_ARG_HTTP_PROXY, proxy_uri).ToC().get());
|
||||
grpc_channel_credentials_release(creds);
|
||||
GPR_ASSERT(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
std::string server_addr_ =
|
||||
grpc_core::JoinHostPort("localhost", grpc_pick_unused_port_or_die());
|
||||
grpc_end2end_http_proxy* proxy_;
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& client_args,
|
||||
const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<HttpProxyFilter>(client_args);
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2020 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void ProcessAuthFailure(void* state, grpc_auth_context* /*ctx*/,
|
||||
const grpc_metadata* /*md*/, size_t /*md_count*/,
|
||||
grpc_process_auth_metadata_done_cb cb,
|
||||
void* user_data) {
|
||||
GPR_ASSERT(state == nullptr);
|
||||
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
|
||||
}
|
||||
|
||||
class InsecureCredsFixture : public InsecureFixture {
|
||||
private:
|
||||
grpc_server_credentials* MakeServerCreds(
|
||||
const grpc_core::ChannelArgs& args) override {
|
||||
auto* creds = grpc_insecure_server_credentials_create();
|
||||
if (args.Contains(FAIL_AUTH_CHECK_SERVER_ARG_NAME)) {
|
||||
grpc_auth_metadata_processor processor = {ProcessAuthFailure, nullptr,
|
||||
nullptr};
|
||||
grpc_server_credentials_set_auth_metadata_processor(creds, processor);
|
||||
}
|
||||
return creds;
|
||||
}
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
CoreTestConfiguration configs[] = {
|
||||
{"chttp2/insecure_fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<InsecureCredsFixture>();
|
||||
}},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/local_util.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::atomic<int> unique{0};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_local_abstract_uds_percent_encoded",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
|
||||
return std::make_unique<LocalTestFixture>(
|
||||
absl::StrFormat("unix-abstract:grpc_fullstack_test.%%00.%d.%" PRId64
|
||||
".%" PRId32 ".%d",
|
||||
getpid(), now.tv_sec, now.tv_nsec,
|
||||
unique.fetch_add(1, std::memory_order_relaxed)),
|
||||
UDS);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2018 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 <unistd.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/local_util.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_local_ipv4",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
return std::make_unique<LocalTestFixture>(
|
||||
grpc_core::JoinHostPort("127.0.0.1", port), LOCAL_TCP);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2018 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 <unistd.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/host_port.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/local_util.h"
|
||||
#include "test/core/util/port.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_local_ipv6",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
int port = grpc_pick_unused_port_or_die();
|
||||
return std::make_unique<LocalTestFixture>(
|
||||
grpc_core::JoinHostPort("[::1]", port), LOCAL_TCP);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/local_util.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::atomic<int> unique{1};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_local_uds",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
|
||||
return std::make_unique<LocalTestFixture>(
|
||||
absl::StrFormat("unix:/tmp/grpc_fullstack_test.%d.%" PRId64
|
||||
".%" PRId32 ".%d",
|
||||
getpid(), now.tv_sec, now.tv_nsec,
|
||||
unique.fetch_add(1, std::memory_order_relaxed)),
|
||||
UDS);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/local_util.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::atomic<int> unique{1};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_local_uds_percent_encoded",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& /*client_args*/,
|
||||
const grpc_core::ChannelArgs& /*server_args*/) {
|
||||
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
|
||||
return std::make_unique<LocalTestFixture>(
|
||||
absl::StrFormat("unix:/tmp/grpc_fullstack_test.%%25.%d.%" PRId64
|
||||
".%" PRId32 ".%d",
|
||||
getpid(), now.tv_sec, now.tv_nsec,
|
||||
unique.fetch_add(1, std::memory_order_relaxed)),
|
||||
UDS);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <stdio.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_oauth2_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_with_oauth2_fullstack_tls1_2",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<Oauth2Fixture>(grpc_tls_version::TLS1_2);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <stdio.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_oauth2_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_with_oauth2_fullstack_tls1_3",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<Oauth2Fixture>(grpc_tls_version::TLS1_3);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/proxy.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
class ProxyFixture : public CoreTestFixture {
|
||||
public:
|
||||
ProxyFixture(const grpc_core::ChannelArgs& client_args,
|
||||
const grpc_core::ChannelArgs& server_args)
|
||||
: proxy_(grpc_end2end_proxy_create(&proxy_def_, client_args.ToC().get(),
|
||||
server_args.ToC().get())) {}
|
||||
~ProxyFixture() override { grpc_end2end_proxy_destroy(proxy_); }
|
||||
|
||||
private:
|
||||
static grpc_server* CreateProxyServer(const char* port,
|
||||
const grpc_channel_args* server_args) {
|
||||
grpc_server* s = grpc_server_create(server_args, nullptr);
|
||||
grpc_server_credentials* server_creds =
|
||||
grpc_insecure_server_credentials_create();
|
||||
GPR_ASSERT(grpc_server_add_http2_port(s, port, server_creds));
|
||||
grpc_server_credentials_release(server_creds);
|
||||
return s;
|
||||
}
|
||||
|
||||
static grpc_channel* CreateProxyClient(const char* target,
|
||||
const grpc_channel_args* client_args) {
|
||||
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
|
||||
grpc_channel* channel = grpc_channel_create(target, creds, client_args);
|
||||
grpc_channel_credentials_release(creds);
|
||||
return channel;
|
||||
}
|
||||
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
auto* server = grpc_server_create(args.ToC().get(), nullptr);
|
||||
grpc_server_register_completion_queue(server, cq(), nullptr);
|
||||
grpc_server_credentials* server_creds =
|
||||
grpc_insecure_server_credentials_create();
|
||||
GPR_ASSERT(grpc_server_add_http2_port(
|
||||
server, grpc_end2end_proxy_get_server_port(proxy_), server_creds));
|
||||
grpc_server_credentials_release(server_creds);
|
||||
grpc_server_start(server);
|
||||
return server;
|
||||
}
|
||||
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
|
||||
auto* client = grpc_channel_create(
|
||||
grpc_end2end_proxy_get_client_target(proxy_), creds, args.ToC().get());
|
||||
grpc_channel_credentials_release(creds);
|
||||
GPR_ASSERT(client);
|
||||
return client;
|
||||
}
|
||||
const grpc_end2end_proxy_def proxy_def_ = {CreateProxyServer,
|
||||
CreateProxyClient};
|
||||
grpc_end2end_proxy* proxy_;
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack+proxy",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs& client_args,
|
||||
const grpc_core::ChannelArgs& server_args) {
|
||||
return std::make_unique<ProxyFixture>(client_args, server_args);
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "src/core/lib/iomgr/port.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/sockpair_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
#ifdef GRPC_POSIX_SOCKET
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SockpairFixture>(grpc_core::ChannelArgs());
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
// force tracing on, with a value to force many
|
||||
// code paths in trace.cc to be taken
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.trace = "doesnt-exist,http,all";
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
#ifdef GRPC_POSIX_SOCKET
|
||||
g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1;
|
||||
#else
|
||||
g_fixture_slowdown_factor = 10;
|
||||
#endif
|
||||
|
||||
#ifdef GPR_WINDOWS
|
||||
// on Windows, writing logs to stderr is very slow
|
||||
// when stderr is redirected to a disk file.
|
||||
// The "trace" tests fixtures generates large amount
|
||||
// of logs, so setting a buffer for stderr prevents certain
|
||||
// test cases from timing out.
|
||||
setvbuf(stderr, NULL, _IOLBF, 1024);
|
||||
#endif
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
GPR_ASSERT(0 == grpc_tracer_set_enabled("also-doesnt-exist", 0));
|
||||
GPR_ASSERT(1 == grpc_tracer_set_enabled("http", 1));
|
||||
GPR_ASSERT(1 == grpc_tracer_set_enabled("all", 1));
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/sockpair_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SockpairFixture>(grpc_core::ChannelArgs());
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/sockpair_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SockpairFixture>(
|
||||
grpc_core::ChannelArgs()
|
||||
.Set(GRPC_ARG_TCP_READ_CHUNK_SIZE, 1)
|
||||
.Set(GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE, 1)
|
||||
.Set(GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE, 1));
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
g_fixture_slowdown_factor = 2;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/sockpair_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
class SockpairWithMinstackFixture : public SockpairFixture {
|
||||
public:
|
||||
using SockpairFixture::SockpairFixture;
|
||||
|
||||
private:
|
||||
grpc_core::ChannelArgs MutateClientArgs(
|
||||
grpc_core::ChannelArgs args) override {
|
||||
return args.Set(GRPC_ARG_MINIMAL_STACK, true);
|
||||
}
|
||||
grpc_core::ChannelArgs MutateServerArgs(
|
||||
grpc_core::ChannelArgs args) override {
|
||||
return args.Set(GRPC_ARG_MINIMAL_STACK, true);
|
||||
}
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/socketpair+minstack",
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_DOES_NOT_SUPPORT_DEADLINES,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SockpairWithMinstackFixture>(
|
||||
grpc_core::ChannelArgs());
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_ssl_cred_reload_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack_tls1_2",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SslCredReloadFixture>(TLS1_2);
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = SslCredReloadFixture::CaCertPath();
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_ssl_cred_reload_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack_tls1_3",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SslCredReloadFixture>(TLS1_3);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = SslCredReloadFixture::CaCertPath();
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/iomgr/exec_ctx.h"
|
||||
#include "src/core/lib/iomgr/load_file.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/proxy.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
|
||||
#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
|
||||
#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
|
||||
|
||||
static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
|
||||
const grpc_metadata* /*md*/,
|
||||
size_t /*md_count*/,
|
||||
grpc_process_auth_metadata_done_cb cb,
|
||||
void* user_data) {
|
||||
GPR_ASSERT(state == nullptr);
|
||||
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
|
||||
}
|
||||
|
||||
class SslProxyFixture : public CoreTestFixture {
|
||||
public:
|
||||
SslProxyFixture(const grpc_core::ChannelArgs& client_args,
|
||||
const grpc_core::ChannelArgs& server_args)
|
||||
: proxy_(grpc_end2end_proxy_create(&proxy_def_, client_args.ToC().get(),
|
||||
server_args.ToC().get())) {}
|
||||
~SslProxyFixture() override { grpc_end2end_proxy_destroy(proxy_); }
|
||||
|
||||
private:
|
||||
static grpc_server* CreateProxyServer(const char* port,
|
||||
const grpc_channel_args* server_args) {
|
||||
grpc_server* s = grpc_server_create(server_args, nullptr);
|
||||
grpc_slice cert_slice, key_slice;
|
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR(
|
||||
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
|
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR(
|
||||
"load_file", grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
|
||||
const char* server_cert =
|
||||
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
|
||||
const char* server_key =
|
||||
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
|
||||
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
|
||||
grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
|
||||
nullptr, &pem_key_cert_pair, 1, 0, nullptr);
|
||||
grpc_slice_unref(cert_slice);
|
||||
grpc_slice_unref(key_slice);
|
||||
GPR_ASSERT(grpc_server_add_http2_port(s, port, ssl_creds));
|
||||
grpc_server_credentials_release(ssl_creds);
|
||||
return s;
|
||||
}
|
||||
|
||||
static grpc_channel* CreateProxyClient(const char* target,
|
||||
const grpc_channel_args* client_args) {
|
||||
grpc_channel* channel;
|
||||
grpc_channel_credentials* ssl_creds =
|
||||
grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
|
||||
grpc_arg ssl_name_override = {
|
||||
GRPC_ARG_STRING,
|
||||
const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
|
||||
{const_cast<char*>("foo.test.google.fr")}};
|
||||
const grpc_channel_args* new_client_args =
|
||||
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
|
||||
channel = grpc_channel_create(target, ssl_creds, new_client_args);
|
||||
grpc_channel_credentials_release(ssl_creds);
|
||||
{
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_channel_args_destroy(new_client_args);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_slice cert_slice, key_slice;
|
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR(
|
||||
"load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
|
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR(
|
||||
"load_file", grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
|
||||
const char* server_cert =
|
||||
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
|
||||
const char* server_key =
|
||||
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
|
||||
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key, server_cert};
|
||||
grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
|
||||
nullptr, &pem_key_cert_pair, 1, 0, nullptr);
|
||||
grpc_slice_unref(cert_slice);
|
||||
grpc_slice_unref(key_slice);
|
||||
if (args.Contains(FAIL_AUTH_CHECK_SERVER_ARG_NAME)) {
|
||||
grpc_auth_metadata_processor processor = {process_auth_failure, nullptr,
|
||||
nullptr};
|
||||
grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
|
||||
}
|
||||
|
||||
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, grpc_end2end_proxy_get_server_port(proxy_), ssl_creds));
|
||||
grpc_server_credentials_release(ssl_creds);
|
||||
grpc_server_start(server);
|
||||
return server;
|
||||
}
|
||||
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& args) override {
|
||||
grpc_channel_credentials* ssl_creds =
|
||||
grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
|
||||
auto* client = grpc_channel_create(
|
||||
grpc_end2end_proxy_get_client_target(proxy_), ssl_creds,
|
||||
args.Set(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, "foo.test.google.fr")
|
||||
.ToC()
|
||||
.get());
|
||||
GPR_ASSERT(client != nullptr);
|
||||
grpc_channel_credentials_release(ssl_creds);
|
||||
return client;
|
||||
}
|
||||
const grpc_end2end_proxy_def proxy_def_ = {CreateProxyServer,
|
||||
CreateProxyClient};
|
||||
grpc_end2end_proxy* proxy_;
|
||||
};
|
||||
|
||||
// All test configurations
|
||||
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs& client_args,
|
||||
const grpc_core::ChannelArgs& server_args) {
|
||||
return std::make_unique<SslProxyFixture>(client_args, server_args);
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = CA_CERT_PATH;
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_ssl_tls_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack_tls1_2",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SslTlsFixture>(grpc_tls_version::TLS1_2);
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = SslTlsFixture::CaCertPath();
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security_constants.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_ssl_tls_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/simple_ssl_fullstack_tls1_3",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
|
||||
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<SslTlsFixture>(grpc_tls_version::TLS1_3);
|
||||
}}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = SslTlsFixture::CaCertPath();
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2018 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_tls_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static CoreTestConfiguration config = {
|
||||
// client: certificate watcher provider + async external verifier
|
||||
// server: certificate watcher provider + async external verifier
|
||||
// extra: TLS 1.3
|
||||
"chttp2/cert_watcher_provider_async_verifier_tls1_3",
|
||||
kH2TLSFeatureMask,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<TlsFixture>(
|
||||
SecurityPrimitives::TlsVersion::V_13,
|
||||
SecurityPrimitives::ProviderType::FILE_PROVIDER,
|
||||
SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER);
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = CA_CERT_PATH;
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
grpc_init();
|
||||
grpc_end2end_tests(argc, argv, config);
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2018 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_tls_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static CoreTestConfiguration config = {
|
||||
// client: certificate watcher provider + hostname verifier
|
||||
// server: certificate watcher provider + sync external verifier
|
||||
// extra: TLS 1.2
|
||||
"chttp2/cert_watcher_provider_sync_verifier_tls1_2",
|
||||
kH2TLSFeatureMask,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<TlsFixture>(
|
||||
SecurityPrimitives::TlsVersion::V_12,
|
||||
SecurityPrimitives::ProviderType::FILE_PROVIDER,
|
||||
SecurityPrimitives::VerifierType::HOSTNAME_VERIFIER);
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = CA_CERT_PATH;
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
grpc_init();
|
||||
grpc_end2end_tests(argc, argv, config);
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -229,9 +229,7 @@ class TlsFixture : public SecureFixture {
|
|||
};
|
||||
|
||||
static const uint32_t kH2TLSFeatureMask =
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER;
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2;
|
||||
|
||||
#endif // GRPC_TEST_CORE_END2END_FIXTURES_H2_TLS_COMMON_H
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2018 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_tls_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static CoreTestConfiguration config = {
|
||||
// client: static data provider + sync external verifier
|
||||
// server: static data provider + sync external verifier
|
||||
// extra: TLS 1.2
|
||||
"chttp2/simple_ssl_fullstack",
|
||||
kH2TLSFeatureMask,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<TlsFixture>(
|
||||
SecurityPrimitives::TlsVersion::V_12,
|
||||
SecurityPrimitives::ProviderType::STATIC_PROVIDER,
|
||||
SecurityPrimitives::VerifierType::EXTERNAL_SYNC_VERIFIER);
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = CA_CERT_PATH;
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
grpc_init();
|
||||
grpc_end2end_tests(argc, argv, config);
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2018 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 <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/config_vars.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/h2_tls_common.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static CoreTestConfiguration config = {
|
||||
// client: static data provider + async external verifier
|
||||
// server: static data provider + async external verifier
|
||||
// extra: TLS 1.3
|
||||
"chttp2/static_provider_async_verifier_tls1_3",
|
||||
kH2TLSFeatureMask,
|
||||
"foo.test.google.fr",
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<TlsFixture>(
|
||||
SecurityPrimitives::TlsVersion::V_13,
|
||||
SecurityPrimitives::ProviderType::STATIC_PROVIDER,
|
||||
SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER);
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_core::ConfigVars::Overrides overrides;
|
||||
overrides.default_ssl_roots_file_path = CA_CERT_PATH;
|
||||
grpc_core::ConfigVars::SetOverrides(overrides);
|
||||
grpc_init();
|
||||
grpc_end2end_tests(argc, argv, config);
|
||||
grpc_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::atomic<int> unique{1};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_uds",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
|
||||
return std::make_unique<InsecureFixture>(absl::StrFormat(
|
||||
"unix:/tmp/grpc_fullstack_test.%d.%" PRId64 ".%" PRId32 ".%d",
|
||||
getpid(), now.tv_sec, now.tv_nsec,
|
||||
unique.fetch_add(1, std::memory_order_relaxed)));
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/secure_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::atomic<int> unique{1};
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {
|
||||
{"chttp2/fullstack_uds_abstract_namespace",
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
|
||||
return std::make_unique<InsecureFixture>(absl::StrFormat(
|
||||
"unix-abstract:grpc_fullstack_test.%d.%" PRId64 ".%" PRId32 ".%d",
|
||||
getpid(), now.tv_sec, now.tv_nsec,
|
||||
unique.fetch_add(1, std::memory_order_relaxed)));
|
||||
}},
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2017 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/fixtures/inproc_fixture.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
// All test configurations
|
||||
static CoreTestConfiguration configs[] = {{
|
||||
"inproc",
|
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
|
||||
nullptr,
|
||||
[](const grpc_core::ChannelArgs&, const grpc_core::ChannelArgs&) {
|
||||
return std::make_unique<InprocFixture>();
|
||||
},
|
||||
}};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
size_t i;
|
||||
|
||||
grpc::testing::TestEnvironment env(&argc, argv);
|
||||
grpc_end2end_tests_pre_init();
|
||||
grpc_init();
|
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
|
||||
grpc_end2end_tests(argc, argv, configs[i]);
|
||||
}
|
||||
|
||||
grpc_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
class InprocFixture : public CoreTestFixture {
|
||||
class InprocFixture : public grpc_core::CoreTestFixture {
|
||||
private:
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& args) override {
|
||||
auto* server = grpc_server_create(args.ToC().get(), nullptr);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
class LocalTestFixture final : public CoreTestFixture {
|
||||
class LocalTestFixture final : public grpc_core::CoreTestFixture {
|
||||
public:
|
||||
LocalTestFixture(std::string localaddr, grpc_local_connect_type type);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
// Base class for a fixture that just needs to select cred types (or mutate
|
||||
// client/server channel args).
|
||||
class SecureFixture : public CoreTestFixture {
|
||||
class SecureFixture : public grpc_core::CoreTestFixture {
|
||||
public:
|
||||
explicit SecureFixture(std::string localaddr = grpc_core::JoinHostPort(
|
||||
"localhost", grpc_pick_unused_port_or_die()))
|
||||
|
|
|
|||
|
|
@ -15,8 +15,11 @@
|
|||
#ifndef GRPC_TEST_CORE_END2END_FIXTURES_SOCKPAIR_FIXTURE_H
|
||||
#define GRPC_TEST_CORE_END2END_FIXTURES_SOCKPAIR_FIXTURE_H
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/status.h>
|
||||
|
|
@ -40,32 +43,44 @@
|
|||
#include "src/core/lib/transport/transport_fwd.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
class SockpairFixture : public CoreTestFixture {
|
||||
public:
|
||||
explicit SockpairFixture(const grpc_core::ChannelArgs& ep_args)
|
||||
explicit SockpairFixture(const ChannelArgs& ep_args)
|
||||
: ep_(grpc_iomgr_create_endpoint_pair("fixture", ep_args.ToC().get())) {}
|
||||
|
||||
~SockpairFixture() override {
|
||||
ExecCtx exec_ctx;
|
||||
if (ep_.client != nullptr) {
|
||||
grpc_endpoint_shutdown(ep_.client, absl::InternalError("done"));
|
||||
grpc_endpoint_destroy(ep_.client);
|
||||
}
|
||||
if (ep_.server != nullptr) {
|
||||
grpc_endpoint_shutdown(ep_.server, absl::InternalError("done"));
|
||||
grpc_endpoint_destroy(ep_.server);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
virtual grpc_core::ChannelArgs MutateClientArgs(grpc_core::ChannelArgs args) {
|
||||
return args;
|
||||
}
|
||||
virtual grpc_core::ChannelArgs MutateServerArgs(grpc_core::ChannelArgs args) {
|
||||
return args;
|
||||
}
|
||||
grpc_server* MakeServer(const grpc_core::ChannelArgs& in_args) override {
|
||||
virtual ChannelArgs MutateClientArgs(ChannelArgs args) { return args; }
|
||||
virtual ChannelArgs MutateServerArgs(ChannelArgs args) { return args; }
|
||||
grpc_server* MakeServer(const ChannelArgs& in_args) override {
|
||||
auto args = MutateServerArgs(in_args);
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
ExecCtx exec_ctx;
|
||||
grpc_transport* transport;
|
||||
auto* server = grpc_server_create(args.ToC().get(), nullptr);
|
||||
grpc_server_register_completion_queue(server, cq(), nullptr);
|
||||
grpc_server_start(server);
|
||||
auto server_channel_args = grpc_core::CoreConfiguration::Get()
|
||||
auto server_channel_args = CoreConfiguration::Get()
|
||||
.channel_args_preconditioning()
|
||||
.PreconditionChannelArgs(args.ToC().get());
|
||||
transport =
|
||||
grpc_create_chttp2_transport(server_channel_args, ep_.server, false);
|
||||
grpc_endpoint_add_to_pollset(ep_.server, grpc_cq_pollset(cq()));
|
||||
grpc_core::Server* core_server = grpc_core::Server::FromC(server);
|
||||
auto* server_endpoint = std::exchange(ep_.server, nullptr);
|
||||
EXPECT_NE(server_endpoint, nullptr);
|
||||
transport = grpc_create_chttp2_transport(server_channel_args,
|
||||
server_endpoint, false);
|
||||
grpc_endpoint_add_to_pollset(server_endpoint, grpc_cq_pollset(cq()));
|
||||
Server* core_server = Server::FromC(server);
|
||||
grpc_error_handle error = core_server->SetupTransport(
|
||||
transport, nullptr, core_server->channel_args(), nullptr);
|
||||
if (error.ok()) {
|
||||
|
|
@ -75,9 +90,9 @@ class SockpairFixture : public CoreTestFixture {
|
|||
}
|
||||
return server;
|
||||
}
|
||||
grpc_channel* MakeClient(const grpc_core::ChannelArgs& in_args) override {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
auto args = grpc_core::CoreConfiguration::Get()
|
||||
grpc_channel* MakeClient(const ChannelArgs& in_args) override {
|
||||
ExecCtx exec_ctx;
|
||||
auto args = CoreConfiguration::Get()
|
||||
.channel_args_preconditioning()
|
||||
.PreconditionChannelArgs(
|
||||
MutateClientArgs(in_args)
|
||||
|
|
@ -85,9 +100,11 @@ class SockpairFixture : public CoreTestFixture {
|
|||
.ToC()
|
||||
.get());
|
||||
grpc_transport* transport;
|
||||
transport = grpc_create_chttp2_transport(args, ep_.client, true);
|
||||
auto channel = grpc_core::Channel::Create(
|
||||
"socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
|
||||
auto* client_endpoint = std::exchange(ep_.client, nullptr);
|
||||
EXPECT_NE(client_endpoint, nullptr);
|
||||
transport = grpc_create_chttp2_transport(args, client_endpoint, true);
|
||||
auto channel = Channel::Create("socketpair-target", args,
|
||||
GRPC_CLIENT_DIRECT_CHANNEL, transport);
|
||||
grpc_channel* client;
|
||||
if (channel.ok()) {
|
||||
client = channel->release()->c_ptr();
|
||||
|
|
@ -104,5 +121,6 @@ class SockpairFixture : public CoreTestFixture {
|
|||
|
||||
grpc_endpoint_pair ep_;
|
||||
};
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_TEST_CORE_END2END_FIXTURES_SOCKPAIR_FIXTURE_H
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
# Copyright 2015 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.
|
||||
"""Generates the list of end2end test cases from generate_tests.bzl"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
|
||||
os.chdir(_ROOT)
|
||||
|
||||
|
||||
def load(*args):
|
||||
"""Replacement of bazel's load() function"""
|
||||
pass
|
||||
|
||||
|
||||
def struct(**kwargs):
|
||||
return kwargs # all the args as a dict
|
||||
|
||||
|
||||
# generate_tests.bzl is now the source of truth for end2end tests.
|
||||
# The .bzl file is basically a python file and we can "execute" it
|
||||
# to get access to the variables it defines.
|
||||
exec(
|
||||
compile(
|
||||
open('test/core/end2end/generate_tests.bzl', "rb").read(),
|
||||
'test/core/end2end/generate_tests.bzl', 'exec'))
|
||||
|
||||
|
||||
def main():
|
||||
json = {
|
||||
# needed by end2end_tests.cc.template
|
||||
'core_end2end_tests':
|
||||
dict((t, END2END_TESTS[t]['secure']) for t in END2END_TESTS.keys())
|
||||
}
|
||||
print(yaml.dump(json))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -1,499 +0,0 @@
|
|||
#!/usr/bin/env python2.7
|
||||
# Copyright 2015 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.
|
||||
"""Generates the appropriate build.json data for all the end2end tests."""
|
||||
|
||||
load(
|
||||
"//bazel:grpc_build_system.bzl",
|
||||
"grpc_cc_binary",
|
||||
"grpc_cc_library",
|
||||
"grpc_sh_test",
|
||||
)
|
||||
load("flaky.bzl", "FLAKY_TESTS")
|
||||
|
||||
def _fixture_options(
|
||||
fullstack = True,
|
||||
includes_proxy = False,
|
||||
dns_resolver = True,
|
||||
name_resolution = True,
|
||||
secure = True,
|
||||
tracing = False,
|
||||
_platforms = ["windows", "linux", "mac", "posix"],
|
||||
is_inproc = False,
|
||||
is_1byte = False,
|
||||
is_http2 = True,
|
||||
is_minstack = False,
|
||||
supports_proxy_auth = False,
|
||||
supports_write_buffering = True,
|
||||
client_channel = True,
|
||||
supports_msvc = True,
|
||||
supports_retry = None,
|
||||
tags = []):
|
||||
if supports_retry == None:
|
||||
supports_retry = client_channel
|
||||
return struct(
|
||||
fullstack = fullstack,
|
||||
includes_proxy = includes_proxy,
|
||||
dns_resolver = dns_resolver,
|
||||
name_resolution = name_resolution,
|
||||
secure = secure,
|
||||
tracing = tracing,
|
||||
is_inproc = is_inproc,
|
||||
is_1byte = is_1byte,
|
||||
is_http2 = is_http2,
|
||||
is_minstack = is_minstack,
|
||||
supports_proxy_auth = supports_proxy_auth,
|
||||
supports_write_buffering = supports_write_buffering,
|
||||
client_channel = client_channel,
|
||||
supports_msvc = supports_msvc,
|
||||
_platforms = _platforms,
|
||||
supports_retry = supports_retry,
|
||||
tags = tags,
|
||||
)
|
||||
|
||||
# maps fixture name to whether it requires the security library
|
||||
END2END_FIXTURES = {
|
||||
"h2_compress": _fixture_options(),
|
||||
"h2_census": _fixture_options(),
|
||||
# TODO(juanlishen): This is disabled for now, but should be considered to re-enable once we have
|
||||
# decided how the load reporting service should be enabled.
|
||||
#'h2_load_reporting': _fixture_options(),
|
||||
"h2_fakesec": _fixture_options(),
|
||||
"h2_fd": _fixture_options(
|
||||
dns_resolver = False,
|
||||
fullstack = False,
|
||||
client_channel = False,
|
||||
_platforms = ["linux", "mac", "posix"],
|
||||
tags = ["no_test_ios"],
|
||||
),
|
||||
"h2_full": _fixture_options(
|
||||
tags = ["event_engine_client_test"],
|
||||
),
|
||||
"h2_full_no_retry": _fixture_options(supports_retry = False),
|
||||
"h2_full+pipe": _fixture_options(_platforms = ["linux"]),
|
||||
"h2_full+trace": _fixture_options(tracing = True),
|
||||
"h2_http_proxy": _fixture_options(supports_proxy_auth = True),
|
||||
"h2_insecure": _fixture_options(secure = True),
|
||||
"h2_oauth2_tls12": _fixture_options(),
|
||||
"h2_oauth2_tls13": _fixture_options(),
|
||||
"h2_proxy": _fixture_options(includes_proxy = True),
|
||||
"h2_sockpair_1byte": _fixture_options(
|
||||
fullstack = False,
|
||||
dns_resolver = False,
|
||||
client_channel = False,
|
||||
is_1byte = True,
|
||||
),
|
||||
"h2_sockpair": _fixture_options(
|
||||
fullstack = False,
|
||||
dns_resolver = False,
|
||||
client_channel = False,
|
||||
),
|
||||
"h2_sockpair_with_minstack": _fixture_options(
|
||||
fullstack = False,
|
||||
dns_resolver = False,
|
||||
client_channel = False,
|
||||
is_minstack = True,
|
||||
),
|
||||
"h2_sockpair+trace": _fixture_options(
|
||||
fullstack = False,
|
||||
dns_resolver = False,
|
||||
tracing = True,
|
||||
client_channel = False,
|
||||
),
|
||||
"h2_ssl_tls12": _fixture_options(secure = True),
|
||||
"h2_ssl_tls13": _fixture_options(secure = True),
|
||||
"h2_ssl_cred_reload_tls12": _fixture_options(secure = True),
|
||||
"h2_ssl_cred_reload_tls13": _fixture_options(secure = True),
|
||||
"h2_tls_simple": _fixture_options(secure = True),
|
||||
"h2_tls_static_async_tls1_3": _fixture_options(secure = True),
|
||||
"h2_tls_certwatch_sync_tls1_2": _fixture_options(secure = True),
|
||||
"h2_tls_certwatch_async_tls1_3": _fixture_options(secure = True),
|
||||
"h2_local_abstract_uds_percent_encoded": _fixture_options(
|
||||
secure = True,
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "posix"],
|
||||
),
|
||||
"h2_local_uds": _fixture_options(
|
||||
secure = True,
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "mac", "posix"],
|
||||
),
|
||||
"h2_local_uds_percent_encoded": _fixture_options(
|
||||
secure = True,
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "mac", "posix"],
|
||||
),
|
||||
"h2_local_ipv4": _fixture_options(
|
||||
secure = True,
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "mac", "posix"],
|
||||
tags = ["requires-net:ipv4", "requires-net:loopback", "event_engine_client"],
|
||||
),
|
||||
"h2_local_ipv6": _fixture_options(
|
||||
secure = True,
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "mac", "posix"],
|
||||
),
|
||||
"h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True),
|
||||
"h2_uds": _fixture_options(
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "mac", "posix"],
|
||||
),
|
||||
"h2_uds_abstract": _fixture_options(
|
||||
dns_resolver = False,
|
||||
_platforms = ["linux", "posix"],
|
||||
),
|
||||
"inproc": _fixture_options(
|
||||
secure = True,
|
||||
fullstack = False,
|
||||
dns_resolver = False,
|
||||
name_resolution = False,
|
||||
is_inproc = True,
|
||||
is_http2 = False,
|
||||
supports_write_buffering = False,
|
||||
client_channel = False,
|
||||
),
|
||||
}
|
||||
|
||||
def _test_options(
|
||||
needs_fullstack = False,
|
||||
needs_dns = False,
|
||||
needs_names = False,
|
||||
proxyable = True,
|
||||
secure = False,
|
||||
traceable = False,
|
||||
exclude_inproc = False,
|
||||
exclude_1byte = False,
|
||||
exclude_minstack = False,
|
||||
needs_http2 = False,
|
||||
needs_proxy_auth = False,
|
||||
needs_write_buffering = False,
|
||||
needs_client_channel = False,
|
||||
needs_retry = False,
|
||||
short_name = None,
|
||||
tags = [],
|
||||
exclude_pollers = []):
|
||||
return struct(
|
||||
needs_fullstack = needs_fullstack,
|
||||
needs_dns = needs_dns,
|
||||
needs_names = needs_names,
|
||||
proxyable = proxyable,
|
||||
secure = secure,
|
||||
traceable = traceable,
|
||||
exclude_inproc = exclude_inproc,
|
||||
exclude_1byte = exclude_1byte,
|
||||
exclude_minstack = exclude_minstack,
|
||||
needs_http2 = needs_http2,
|
||||
needs_proxy_auth = needs_proxy_auth,
|
||||
needs_write_buffering = needs_write_buffering,
|
||||
needs_client_channel = needs_client_channel,
|
||||
needs_retry = needs_retry,
|
||||
short_name = short_name,
|
||||
tags = tags,
|
||||
exclude_pollers = exclude_pollers,
|
||||
)
|
||||
|
||||
# maps test names to options
|
||||
END2END_TESTS = {
|
||||
"bad_hostname": _test_options(needs_names = True),
|
||||
"bad_ping": _test_options(needs_fullstack = True, proxyable = False),
|
||||
"binary_metadata": _test_options(),
|
||||
"resource_quota_server": _test_options(
|
||||
proxyable = False,
|
||||
# TODO(b/151212019): Test case known to be flaky under epoll1.
|
||||
exclude_pollers = ["epoll1"],
|
||||
exclude_1byte = True,
|
||||
),
|
||||
"call_creds": _test_options(secure = True),
|
||||
"call_host_override": _test_options(
|
||||
needs_fullstack = True,
|
||||
needs_dns = True,
|
||||
needs_names = True,
|
||||
),
|
||||
"cancel_after_accept": _test_options(),
|
||||
"cancel_after_client_done": _test_options(),
|
||||
"cancel_after_invoke": _test_options(),
|
||||
"cancel_after_round_trip": _test_options(),
|
||||
"cancel_before_invoke": _test_options(),
|
||||
"cancel_in_a_vacuum": _test_options(),
|
||||
"cancel_with_status": _test_options(),
|
||||
"client_streaming": _test_options(),
|
||||
"compressed_payload": _test_options(proxyable = False, exclude_inproc = True, exclude_minstack = True),
|
||||
"connectivity": _test_options(
|
||||
needs_fullstack = True,
|
||||
needs_names = True,
|
||||
proxyable = False,
|
||||
),
|
||||
"channelz": _test_options(),
|
||||
"default_host": _test_options(
|
||||
needs_fullstack = True,
|
||||
needs_dns = True,
|
||||
needs_names = True,
|
||||
),
|
||||
"disappearing_server": _test_options(needs_fullstack = True, needs_names = True),
|
||||
"empty_batch": _test_options(),
|
||||
"filter_causes_close": _test_options(),
|
||||
"filter_init_fails": _test_options(),
|
||||
"filter_context": _test_options(),
|
||||
"filtered_metadata": _test_options(),
|
||||
"graceful_server_shutdown": _test_options(exclude_inproc = True),
|
||||
"grpc_authz": _test_options(secure = True),
|
||||
"hpack_size": _test_options(
|
||||
proxyable = False,
|
||||
traceable = False,
|
||||
exclude_inproc = True,
|
||||
),
|
||||
"high_initial_seqno": _test_options(),
|
||||
"invoke_large_request": _test_options(exclude_1byte = True, tags = ["flow_control_test"]),
|
||||
"keepalive_timeout": _test_options(proxyable = False, needs_http2 = True),
|
||||
"large_metadata": _test_options(exclude_1byte = True),
|
||||
"max_concurrent_streams": _test_options(
|
||||
proxyable = False,
|
||||
exclude_inproc = True,
|
||||
exclude_minstack = True,
|
||||
),
|
||||
"max_connection_age": _test_options(exclude_minstack = True, exclude_inproc = True),
|
||||
"max_connection_idle": _test_options(needs_fullstack = True, proxyable = False),
|
||||
"max_message_length": _test_options(exclude_minstack = True),
|
||||
"negative_deadline": _test_options(exclude_minstack = True),
|
||||
"no_logging": _test_options(traceable = False),
|
||||
"no_op": _test_options(),
|
||||
"payload": _test_options(exclude_1byte = True),
|
||||
# TODO(juanlishen): This is disabled for now because it depends on some generated functions in
|
||||
# end2end_tests.cc, which are not generated because they would depend on OpenCensus while
|
||||
# OpenCensus can only be built via Bazel so far.
|
||||
# 'load_reporting_hook': _test_options(),
|
||||
"ping_pong_streaming": _test_options(tags = ["flow_control_test"]),
|
||||
"ping": _test_options(needs_fullstack = True, proxyable = False),
|
||||
"proxy_auth": _test_options(needs_proxy_auth = True),
|
||||
"registered_call": _test_options(),
|
||||
"request_with_flags": _test_options(proxyable = False),
|
||||
"request_with_payload": _test_options(),
|
||||
"retry": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_cancellation": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_cancel_during_delay": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_cancel_with_multiple_send_batches": _test_options(
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_cancel3",
|
||||
needs_client_channel = True,
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_cancel_after_first_attempt_starts": _test_options(
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_cancel4",
|
||||
needs_client_channel = True,
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_disabled": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_exceeds_buffer_size_in_delay": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_exceeds_buffer_size_in_initial_batch": _test_options(
|
||||
needs_client_channel = True,
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_exceeds_buffer_size_in_init",
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_exceeds_buffer_size_in_subsequent_batch": _test_options(
|
||||
needs_client_channel = True,
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_exceeds_buffer_size_in_subseq",
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_lb_drop": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_lb_fail": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_non_retriable_status": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_non_retriable_status_before_recv_trailing_metadata_started": _test_options(
|
||||
needs_client_channel = True,
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_non_retriable_status2",
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_per_attempt_recv_timeout": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_per_attempt_recv_timeout_on_last_attempt": _test_options(
|
||||
needs_client_channel = True,
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_per_attempt_recv_timeout2",
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_recv_initial_metadata": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_recv_message": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_recv_message_replay": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_recv_trailing_metadata_error": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_send_initial_metadata_refs": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_send_op_fails": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_send_recv_batch": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_server_pushback_delay": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_server_pushback_disabled": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_streaming": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_streaming_after_commit": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_streaming_succeeds_before_replay_finished": _test_options(
|
||||
needs_client_channel = True,
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_streaming2",
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_throttled": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_too_many_attempts": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_transparent_goaway": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_transparent_not_sent_on_wire": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_transparent_max_concurrent_streams": _test_options(
|
||||
needs_client_channel = True,
|
||||
proxyable = False,
|
||||
# TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE
|
||||
# See b/151617965
|
||||
short_name = "retry_transparent_mcs",
|
||||
needs_retry = True,
|
||||
),
|
||||
"retry_unref_before_finish": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"retry_unref_before_recv": _test_options(needs_client_channel = True, needs_retry = True),
|
||||
"server_finishes_request": _test_options(),
|
||||
"server_streaming": _test_options(needs_http2 = True),
|
||||
"shutdown_finishes_calls": _test_options(),
|
||||
"shutdown_finishes_tags": _test_options(),
|
||||
"simple_delayed_request": _test_options(needs_fullstack = True),
|
||||
"simple_metadata": _test_options(),
|
||||
"simple_request": _test_options(),
|
||||
"streaming_error_response": _test_options(),
|
||||
"trailing_metadata": _test_options(),
|
||||
"authority_not_supported": _test_options(),
|
||||
"filter_latency": _test_options(),
|
||||
"filter_status_code": _test_options(),
|
||||
"write_buffering": _test_options(needs_write_buffering = True),
|
||||
"write_buffering_at_end": _test_options(needs_write_buffering = True),
|
||||
}
|
||||
|
||||
def _compatible(fopt, topt):
|
||||
if topt.needs_fullstack:
|
||||
if not fopt.fullstack:
|
||||
return False
|
||||
if topt.needs_dns:
|
||||
if not fopt.dns_resolver:
|
||||
return False
|
||||
if topt.needs_names:
|
||||
if not fopt.name_resolution:
|
||||
return False
|
||||
if not topt.proxyable:
|
||||
if fopt.includes_proxy:
|
||||
return False
|
||||
if not topt.traceable:
|
||||
if fopt.tracing:
|
||||
return False
|
||||
if topt.exclude_inproc:
|
||||
if fopt.is_inproc:
|
||||
return False
|
||||
if topt.exclude_1byte:
|
||||
if fopt.is_1byte:
|
||||
return False
|
||||
if topt.exclude_minstack:
|
||||
if fopt.is_minstack:
|
||||
return False
|
||||
if topt.needs_http2:
|
||||
if not fopt.is_http2:
|
||||
return False
|
||||
if topt.needs_proxy_auth:
|
||||
if not fopt.supports_proxy_auth:
|
||||
return False
|
||||
if topt.needs_write_buffering:
|
||||
if not fopt.supports_write_buffering:
|
||||
return False
|
||||
if topt.needs_client_channel:
|
||||
if not fopt.client_channel:
|
||||
return False
|
||||
if topt.needs_retry:
|
||||
if not fopt.supports_retry:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _platform_support_tags(fopt):
|
||||
result = []
|
||||
if not "windows" in fopt._platforms:
|
||||
result.append("no_windows")
|
||||
if not "mac" in fopt._platforms:
|
||||
result.append("no_mac")
|
||||
if not "linux" in fopt._platforms:
|
||||
result.append("no_linux")
|
||||
return result
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
def grpc_end2end_tests():
|
||||
"""Instantiates the gRPC end2end tests."""
|
||||
grpc_cc_library(
|
||||
name = "end2end_tests",
|
||||
srcs = ["end2end_tests.cc", "end2end_test_utils.cc"] +
|
||||
["tests/%s.cc" % t for t in sorted(END2END_TESTS.keys())],
|
||||
hdrs = [
|
||||
"tests/cancel_test_helpers.h",
|
||||
"end2end_tests.h",
|
||||
],
|
||||
language = "C++",
|
||||
testonly = 1,
|
||||
deps = [
|
||||
":cq_verifier",
|
||||
":ssl_test_data",
|
||||
":http_proxy",
|
||||
":proxy",
|
||||
":fixture_support",
|
||||
"//test/core/util:test_lb_policies",
|
||||
"//:grpc_authorization_provider",
|
||||
"//:grpc_http_filters",
|
||||
"//src/core:event_log",
|
||||
],
|
||||
visibility = [
|
||||
"//src/objective-c/tests:__subpackages__",
|
||||
],
|
||||
)
|
||||
for f, fopt in END2END_FIXTURES.items():
|
||||
bin_name = "%s_test" % f
|
||||
grpc_cc_binary(
|
||||
name = bin_name,
|
||||
srcs = ["fixtures/%s.cc" % f, "fixtures/h2_tls_common.h"],
|
||||
language = "C++",
|
||||
testonly = 1,
|
||||
data = [
|
||||
"//src/core/tsi/test_creds:ca.pem",
|
||||
"//src/core/tsi/test_creds:server1.key",
|
||||
"//src/core/tsi/test_creds:server1.pem",
|
||||
],
|
||||
deps = [
|
||||
":end2end_tests",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//:grpc",
|
||||
"//:gpr",
|
||||
"//:grpc_http_filters",
|
||||
],
|
||||
tags = _platform_support_tags(fopt) + fopt.tags,
|
||||
)
|
||||
for t, topt in END2END_TESTS.items():
|
||||
if not _compatible(fopt, topt):
|
||||
continue
|
||||
test_short_name = str(t) if not topt.short_name else topt.short_name
|
||||
name = "%s_test@%s" % (f, test_short_name)
|
||||
grpc_sh_test(
|
||||
name = name,
|
||||
srcs = ["run.sh"],
|
||||
data = [":" + bin_name],
|
||||
args = ["$(location %s)" % bin_name, t],
|
||||
tags = _platform_support_tags(fopt) + fopt.tags + topt.tags + [
|
||||
"no_test_ios",
|
||||
"core_end2end_test",
|
||||
],
|
||||
flaky = name in FLAKY_TESTS,
|
||||
exclude_pollers = topt.exclude_pollers,
|
||||
)
|
||||
|
|
@ -141,8 +141,7 @@ typedef enum { SUCCESS, FAIL } test_result;
|
|||
#define SSL_TEST(request_type, cert_type, result) \
|
||||
{ \
|
||||
{TEST_NAME(request_type, cert_type, result), \
|
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | \
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | \
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | \
|
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL, \
|
||||
"foo.test.google.fr", TestFixture::MakeFactory(request_type, cert_type)}, \
|
||||
result \
|
||||
|
|
@ -150,7 +149,7 @@ typedef enum { SUCCESS, FAIL } test_result;
|
|||
|
||||
// All test configurations
|
||||
struct CoreTestConfigWrapper {
|
||||
CoreTestConfiguration config;
|
||||
grpc_core::CoreTestConfiguration config;
|
||||
test_result result;
|
||||
};
|
||||
|
||||
|
|
@ -194,7 +193,7 @@ static CoreTestConfigWrapper configs[] = {
|
|||
BAD_CERT_PAIR, FAIL),
|
||||
};
|
||||
|
||||
static void simple_request_body(CoreTestFixture* f,
|
||||
static void simple_request_body(grpc_core::CoreTestFixture* f,
|
||||
test_result expected_result) {
|
||||
grpc_call* c;
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
|
|
@ -239,7 +238,7 @@ class H2SslCertTest : public ::testing::TestWithParam<CoreTestConfigWrapper> {
|
|||
}
|
||||
void TearDown() override { fixture_.reset(); }
|
||||
|
||||
std::unique_ptr<CoreTestFixture> fixture_;
|
||||
std::unique_ptr<grpc_core::CoreTestFixture> fixture_;
|
||||
};
|
||||
|
||||
TEST_P(H2SslCertTest, SimpleRequestBody) {
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Arbitrary shell script runner
|
||||
# Copyright 2017 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.
|
||||
set -ex
|
||||
"$@"
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
// Request/response with metadata and payload.
|
||||
static void test_with_authority_header(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
|
||||
grpc_slice_from_static_string("val1"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}},
|
||||
{grpc_slice_from_static_string("key2"),
|
||||
grpc_slice_from_static_string("val2"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}}};
|
||||
auto f = begin_test(config, "test_with_authority_header", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
&host, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 2;
|
||||
op->data.send_initial_metadata.metadata = meta_c;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_CANCELLED);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
}
|
||||
|
||||
void authority_not_supported(const CoreTestConfiguration& config) {
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER) {
|
||||
return;
|
||||
}
|
||||
test_with_authority_header(config);
|
||||
}
|
||||
|
||||
void authority_not_supported_pre_init(void) {}
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
static void simple_request_body(CoreTestFixture* f) {
|
||||
grpc_call* c;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
grpc_slice host = grpc_slice_from_static_string("slartibartfast.local");
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
&host, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_INTERNAL);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
}
|
||||
|
||||
static void test_invoke_simple_request(const CoreTestConfiguration& config) {
|
||||
auto f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
|
||||
simple_request_body(f.get());
|
||||
}
|
||||
|
||||
void bad_hostname(const CoreTestConfiguration& config) {
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION) {
|
||||
test_invoke_simple_request(config);
|
||||
}
|
||||
}
|
||||
|
||||
void bad_hostname_pre_init(void) {}
|
||||
|
|
@ -16,104 +16,41 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/surface/channel.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
#define MAX_PING_STRIKES 2
|
||||
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
// Send more pings than server allows to trigger server's GOAWAY.
|
||||
static void test_bad_ping(const CoreTestConfiguration& config) {
|
||||
auto f =
|
||||
config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs());
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
auto client_args = grpc_core::ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0);
|
||||
auto server_args =
|
||||
grpc_core::ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
|
||||
grpc_core::Duration::Minutes(5).millis())
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, MAX_PING_STRIKES)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0);
|
||||
|
||||
f->InitClient(client_args);
|
||||
f->InitServer(server_args);
|
||||
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
TEST_P(RetryHttp2Test, BadPing) {
|
||||
InitClient(ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
|
||||
InitServer(ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
|
||||
Duration::Minutes(5).millis())
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, MAX_PING_STRIKES)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(10)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(101, true);
|
||||
Step();
|
||||
// Send too many pings to the server to trigger the punishment:
|
||||
// The first ping will let server mark its last_recv time. Afterwards, each
|
||||
// ping will trigger a ping strike, and we need at least MAX_PING_STRIKES
|
||||
|
|
@ -121,214 +58,84 @@ static void test_bad_ping(const CoreTestConfiguration& config) {
|
|||
// needed here.
|
||||
int i;
|
||||
for (i = 1; i <= MAX_PING_STRIKES + 2; i++) {
|
||||
grpc_channel_ping(f->client(), f->cq(), grpc_core::CqVerifier::tag(200 + i),
|
||||
nullptr);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(200 + i), true);
|
||||
PingServerFromClient(200 + i);
|
||||
Expect(200 + i, true);
|
||||
if (i == MAX_PING_STRIKES + 2) {
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
Expect(1, true);
|
||||
}
|
||||
cqv.Verify();
|
||||
Step();
|
||||
}
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Verify();
|
||||
|
||||
grpc_server_shutdown_and_notify(f->server(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(0xdead));
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(0xdead), true);
|
||||
cqv.Verify();
|
||||
|
||||
grpc_call_unref(s);
|
||||
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
Expect(102, true);
|
||||
Step();
|
||||
ShutdownServerAndNotify(103);
|
||||
Expect(103, true);
|
||||
Step();
|
||||
// The connection should be closed immediately after the misbehaved pings,
|
||||
// the in-progress RPC should fail.
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 1);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
grpc_call_unref(c);
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAVAILABLE);
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_TRUE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
// Try sending more pings than server allows, but server should be fine because
|
||||
// max_pings_without_data should limit pings sent out on wire.
|
||||
static void test_pings_without_data(const CoreTestConfiguration& config) {
|
||||
auto f =
|
||||
config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs());
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
TEST_P(RetryHttp2Test, PingsWithoutData) {
|
||||
// Only allow MAX_PING_STRIKES pings without data (DATA/HEADERS/WINDOW_UPDATE)
|
||||
// so that the transport will throttle the excess pings.
|
||||
auto client_args =
|
||||
grpc_core::ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, MAX_PING_STRIKES)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0);
|
||||
auto server_args =
|
||||
grpc_core::ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
|
||||
grpc_core::Duration::Minutes(5).millis())
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, MAX_PING_STRIKES)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0);
|
||||
|
||||
f->InitClient(client_args);
|
||||
f->InitServer(server_args);
|
||||
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
InitClient(ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, MAX_PING_STRIKES)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
|
||||
InitServer(ChannelArgs()
|
||||
.Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
|
||||
Duration::Minutes(5).millis())
|
||||
.Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, MAX_PING_STRIKES)
|
||||
.Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(10)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(101, true);
|
||||
Step();
|
||||
// Send too many pings to the server similar to the previous test case.
|
||||
// However, since we set the MAX_PINGS_WITHOUT_DATA at the client side, only
|
||||
// MAX_PING_STRIKES will actually be sent and the rpc will still succeed.
|
||||
int i;
|
||||
for (i = 1; i <= MAX_PING_STRIKES + 2; i++) {
|
||||
grpc_channel_ping(f->client(), f->cq(), grpc_core::CqVerifier::tag(200 + i),
|
||||
nullptr);
|
||||
PingServerFromClient(200 + i);
|
||||
if (i <= MAX_PING_STRIKES) {
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(200 + i), true);
|
||||
Expect(200 + i, true);
|
||||
}
|
||||
cqv.Verify();
|
||||
Step();
|
||||
}
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
Expect(102, true);
|
||||
// Client call should return.
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
grpc_server_shutdown_and_notify(f->server(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(0xdead));
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(0xdead), true);
|
||||
|
||||
Expect(1, true);
|
||||
Step();
|
||||
ShutdownServerAndNotify(103);
|
||||
Expect(103, true);
|
||||
// Also expect the previously blocked pings to complete with an error
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(200 + MAX_PING_STRIKES + 1), false);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(200 + MAX_PING_STRIKES + 2), false);
|
||||
|
||||
cqv.Verify();
|
||||
|
||||
grpc_call_unref(s);
|
||||
|
||||
Expect(200 + MAX_PING_STRIKES + 1, false);
|
||||
Expect(200 + MAX_PING_STRIKES + 2, false);
|
||||
Step();
|
||||
// The rpc should be successful.
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
grpc_call_unref(c);
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
}
|
||||
|
||||
void bad_ping(const CoreTestConfiguration& config) {
|
||||
GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
|
||||
test_bad_ping(config);
|
||||
test_pings_without_data(config);
|
||||
}
|
||||
|
||||
void bad_ping_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,272 +16,104 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_args_preconditioning.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/slice/slice.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
client_args =
|
||||
const_cast<grpc_channel_args*>(grpc_core::CoreConfiguration::Get()
|
||||
.channel_args_preconditioning()
|
||||
.PreconditionChannelArgs(client_args)
|
||||
.ToC()
|
||||
.release());
|
||||
server_args =
|
||||
const_cast<grpc_channel_args*>(grpc_core::CoreConfiguration::Get()
|
||||
.channel_args_preconditioning()
|
||||
.PreconditionChannelArgs(server_args)
|
||||
.ToC()
|
||||
.release());
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
grpc_channel_args_destroy(client_args);
|
||||
grpc_channel_args_destroy(server_args);
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
|
||||
static void BinaryMetadata(CoreEnd2endTest& test, bool server_true_binary,
|
||||
bool client_true_binary) {
|
||||
test.InitServer(
|
||||
ChannelArgs().Set(GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY, server_true_binary));
|
||||
test.InitClient(
|
||||
ChannelArgs().Set(GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY, client_true_binary));
|
||||
|
||||
auto key1_payload = RandomBinarySlice(32);
|
||||
auto key2_payload = RandomBinarySlice(18);
|
||||
auto key3_payload = RandomBinarySlice(17);
|
||||
auto key4_payload = RandomBinarySlice(68);
|
||||
auto key5_payload = RandomBinarySlice(33);
|
||||
auto key6_payload = RandomBinarySlice(2);
|
||||
auto request_payload = RandomBinarySlice(7);
|
||||
auto response_payload = RandomBinarySlice(9);
|
||||
auto status_string = RandomBinarySlice(256);
|
||||
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_md;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({
|
||||
{"key1-bin", key1_payload.as_string_view()},
|
||||
{"key2-bin", key2_payload.as_string_view()},
|
||||
})
|
||||
.SendMessage(request_payload.Ref())
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_md)
|
||||
.RecvMessage(server_message)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({
|
||||
{"key3-bin", key3_payload.as_string_view()},
|
||||
{"key4-bin", key4_payload.as_string_view()},
|
||||
})
|
||||
.RecvMessage(client_message);
|
||||
test.Expect(102, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(103)
|
||||
.RecvCloseOnServer(client_close)
|
||||
.SendMessage(response_payload.Ref())
|
||||
.SendStatusFromServer(GRPC_STATUS_OK, status_string.as_string_view(),
|
||||
{
|
||||
{"key5-bin", key5_payload.as_string_view()},
|
||||
{"key6-bin", key6_payload.as_string_view()},
|
||||
});
|
||||
test.Expect(103, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), status_string.as_string_view());
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
EXPECT_EQ(client_message.payload(), request_payload);
|
||||
EXPECT_EQ(server_message.payload(), response_payload);
|
||||
EXPECT_EQ(s.GetInitialMetadata("key1-bin"), key1_payload.as_string_view());
|
||||
EXPECT_EQ(s.GetInitialMetadata("key2-bin"), key2_payload.as_string_view());
|
||||
EXPECT_EQ(server_initial_md.Get("key3-bin"), key3_payload.as_string_view());
|
||||
EXPECT_EQ(server_initial_md.Get("key4-bin"), key4_payload.as_string_view());
|
||||
EXPECT_EQ(server_status.GetTrailingMetadata("key5-bin"),
|
||||
key5_payload.as_string_view());
|
||||
EXPECT_EQ(server_status.GetTrailingMetadata("key6-bin"),
|
||||
key6_payload.as_string_view());
|
||||
}
|
||||
|
||||
// Request/response with metadata and payload.
|
||||
static void test_request_response_with_metadata_and_payload(
|
||||
const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_slice response_payload_slice =
|
||||
grpc_slice_from_copied_string("hello you");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
grpc_byte_buffer* response_payload =
|
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
grpc_metadata meta_c[2] = {
|
||||
{grpc_slice_from_static_string("key1-bin"),
|
||||
grpc_slice_from_static_string(
|
||||
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}},
|
||||
{grpc_slice_from_static_string("key2-bin"),
|
||||
grpc_slice_from_static_string(
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}}};
|
||||
grpc_metadata meta_s[2] = {
|
||||
{grpc_slice_from_static_string("key3-bin"),
|
||||
grpc_slice_from_static_string(
|
||||
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}},
|
||||
{grpc_slice_from_static_string("key4-bin"),
|
||||
grpc_slice_from_static_string(
|
||||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}}};
|
||||
auto f = begin_test(config, "test_request_response_with_metadata_and_payload",
|
||||
nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 2;
|
||||
op->data.send_initial_metadata.metadata = meta_c;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 2;
|
||||
op->data.send_initial_metadata.metadata = meta_s;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_OK;
|
||||
grpc_slice status_string = grpc_slice_from_static_string(
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12"
|
||||
"\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24"
|
||||
"\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36"
|
||||
"\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48"
|
||||
"\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a"
|
||||
"\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c"
|
||||
"\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e"
|
||||
"\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
|
||||
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2"
|
||||
"\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4"
|
||||
"\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"
|
||||
"\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
|
||||
"\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea"
|
||||
"\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc"
|
||||
"\xfd\xfe\xff");
|
||||
op->data.send_status_from_server.status_details = &status_string;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_OK);
|
||||
GPR_ASSERT(
|
||||
0 ==
|
||||
grpc_slice_str_cmp(
|
||||
details,
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
|
||||
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
|
||||
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
|
||||
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
|
||||
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
|
||||
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
|
||||
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
|
||||
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
|
||||
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
|
||||
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
|
||||
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
|
||||
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
|
||||
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
|
||||
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
|
||||
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
|
||||
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
|
||||
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
|
||||
GPR_ASSERT(contains_metadata(
|
||||
&request_metadata_recv, "key1-bin",
|
||||
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"));
|
||||
GPR_ASSERT(contains_metadata(
|
||||
&request_metadata_recv, "key2-bin",
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"));
|
||||
GPR_ASSERT(contains_metadata(
|
||||
&initial_metadata_recv, "key3-bin",
|
||||
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"));
|
||||
GPR_ASSERT(contains_metadata(
|
||||
&initial_metadata_recv, "key4-bin",
|
||||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
TEST_P(CoreEnd2endTest, BinaryMetadataServerTrueBinaryClientHttp2Fallback) {
|
||||
BinaryMetadata(*this, true, false);
|
||||
}
|
||||
|
||||
void binary_metadata(const CoreTestConfiguration& config) {
|
||||
test_request_response_with_metadata_and_payload(config);
|
||||
TEST_P(CoreEnd2endTest, BinaryMetadataServerHttp2FallbackClientTrueBinary) {
|
||||
BinaryMetadata(*this, false, true);
|
||||
}
|
||||
|
||||
void binary_metadata_pre_init(void) {}
|
||||
TEST_P(CoreEnd2endTest, BinaryMetadataServerTrueBinaryClientTrueBinary) {
|
||||
BinaryMetadata(*this, true, true);
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, BinaryMetadataServerHttp2FallbackClientHttp2Fallback) {
|
||||
BinaryMetadata(*this, false, false);
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,56 +16,34 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include "absl/types/optional.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/security/credentials/credentials.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static const char iam_token[] = "token";
|
||||
static const char iam_selector[] = "selector";
|
||||
static const char overridden_iam_token[] = "overridden_token";
|
||||
static const char overridden_iam_selector[] = "overridden_selector";
|
||||
static const char fake_md_key[] = "fake_key";
|
||||
static const char fake_md_value[] = "fake_value";
|
||||
static const char overridden_fake_md_key[] = "overridden_fake_key";
|
||||
static const char overridden_fake_md_value[] = "overridden_fake_value";
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
typedef enum { NONE, OVERRIDE, DESTROY, FAIL } override_mode;
|
||||
const char iam_token[] = "token";
|
||||
const char iam_selector[] = "selector";
|
||||
const char overridden_iam_token[] = "overridden_token";
|
||||
const char overridden_iam_selector[] = "overridden_selector";
|
||||
const char fake_md_key[] = "fake_key";
|
||||
const char fake_md_value[] = "fake_value";
|
||||
const char overridden_fake_md_key[] = "overridden_fake_key";
|
||||
const char overridden_fake_md_value[] = "overridden_fake_value";
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
bool use_secure_call_creds, int fail_server_auth_check) {
|
||||
gpr_log(GPR_INFO, "Running test: %s%s/%s", test_name,
|
||||
use_secure_call_creds ? "_with_secure_call_creds"
|
||||
: "_with_insecure_call_creds",
|
||||
config.name);
|
||||
auto f =
|
||||
config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs());
|
||||
f->InitClient(grpc_core::ChannelArgs());
|
||||
grpc_core::ChannelArgs server_args;
|
||||
if (fail_server_auth_check) {
|
||||
server_args = server_args.Set(FAIL_AUTH_CHECK_SERVER_ARG_NAME, true);
|
||||
}
|
||||
f->InitServer(server_args);
|
||||
return f;
|
||||
}
|
||||
|
||||
static void print_auth_context(int is_client, const grpc_auth_context* ctx) {
|
||||
void PrintAuthContext(bool is_client, const grpc_auth_context* ctx) {
|
||||
const grpc_auth_property* p;
|
||||
grpc_auth_property_iterator it;
|
||||
gpr_log(GPR_INFO, "%s peer:", is_client ? "client" : "server");
|
||||
|
|
@ -82,412 +60,270 @@ static void print_auth_context(int is_client, const grpc_auth_context* ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
static void request_response_with_payload_and_call_creds(
|
||||
const char* test_name, const CoreTestConfiguration& config,
|
||||
override_mode mode, bool use_secure_call_creds) {
|
||||
grpc_call* c = nullptr;
|
||||
grpc_call* s = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_slice response_payload_slice =
|
||||
grpc_slice_from_copied_string("hello you");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
grpc_byte_buffer* response_payload =
|
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
grpc_call_credentials* creds = nullptr;
|
||||
grpc_auth_context* server_auth_context = nullptr;
|
||||
grpc_auth_context* client_auth_context = nullptr;
|
||||
|
||||
auto f = begin_test(config, test_name, use_secure_call_creds, 0);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
void TestRequestResponseWithPayloadAndCallCreds(CoreEnd2endTest& test,
|
||||
bool use_secure_call_creds) {
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
grpc_call_credentials* creds;
|
||||
if (use_secure_call_creds) {
|
||||
creds =
|
||||
grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
|
||||
} else {
|
||||
creds = grpc_md_only_test_credentials_create(fake_md_key, fake_md_value);
|
||||
}
|
||||
GPR_ASSERT(creds != nullptr);
|
||||
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
|
||||
switch (mode) {
|
||||
case NONE:
|
||||
break;
|
||||
case OVERRIDE:
|
||||
grpc_call_credentials_release(creds);
|
||||
if (use_secure_call_creds) {
|
||||
creds = grpc_google_iam_credentials_create(
|
||||
overridden_iam_token, overridden_iam_selector, nullptr);
|
||||
} else {
|
||||
creds = grpc_md_only_test_credentials_create(overridden_fake_md_key,
|
||||
overridden_fake_md_value);
|
||||
}
|
||||
GPR_ASSERT(creds != nullptr);
|
||||
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
|
||||
break;
|
||||
case DESTROY:
|
||||
GPR_ASSERT(grpc_call_set_credentials(c, nullptr) == GRPC_CALL_OK);
|
||||
break;
|
||||
case FAIL:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
grpc_call_credentials_release(creds);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
if (mode == FAIL) {
|
||||
// Expect the call to fail since the channel credentials did not satisfy the
|
||||
// minimum security level requirements.
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNAUTHENTICATED);
|
||||
EXPECT_NE(creds, nullptr);
|
||||
c.SetCredentials(creds);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello world")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
PrintAuthContext(false, s.GetAuthContext().get());
|
||||
PrintAuthContext(true, c.GetAuthContext().get());
|
||||
// Cannot set creds on the server call object.
|
||||
EXPECT_NE(grpc_call_set_credentials(s.c_call(), nullptr), GRPC_CALL_OK);
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).SendInitialMetadata({}).RecvMessage(client_message);
|
||||
test.Expect(102, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(103)
|
||||
.RecvCloseOnServer(client_close)
|
||||
.SendMessage("hello you")
|
||||
.SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test.Expect(103, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
EXPECT_EQ(client_message.payload(), "hello world");
|
||||
EXPECT_EQ(server_message.payload(), "hello you");
|
||||
if (use_secure_call_creds) {
|
||||
EXPECT_EQ(s.GetInitialMetadata(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY),
|
||||
iam_token);
|
||||
EXPECT_EQ(s.GetInitialMetadata(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY),
|
||||
iam_selector);
|
||||
} else {
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
server_auth_context = grpc_call_auth_context(s);
|
||||
GPR_ASSERT(server_auth_context != nullptr);
|
||||
print_auth_context(0, server_auth_context);
|
||||
grpc_auth_context_release(server_auth_context);
|
||||
|
||||
client_auth_context = grpc_call_auth_context(c);
|
||||
GPR_ASSERT(client_auth_context != nullptr);
|
||||
print_auth_context(1, client_auth_context);
|
||||
grpc_auth_context_release(client_auth_context);
|
||||
|
||||
// Cannot set creds on the server call object.
|
||||
GPR_ASSERT(grpc_call_set_credentials(s, nullptr) != GRPC_CALL_OK);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_OK;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_OK);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
|
||||
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
|
||||
|
||||
switch (mode) {
|
||||
case NONE:
|
||||
if (use_secure_call_creds) {
|
||||
GPR_ASSERT(contains_metadata(
|
||||
&request_metadata_recv, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
|
||||
iam_token));
|
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv,
|
||||
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
|
||||
iam_selector));
|
||||
} else {
|
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv, fake_md_key,
|
||||
fake_md_value));
|
||||
}
|
||||
break;
|
||||
case OVERRIDE:
|
||||
if (use_secure_call_creds) {
|
||||
GPR_ASSERT(contains_metadata(
|
||||
&request_metadata_recv, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
|
||||
overridden_iam_token));
|
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv,
|
||||
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
|
||||
overridden_iam_selector));
|
||||
} else {
|
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv,
|
||||
overridden_fake_md_key,
|
||||
overridden_fake_md_value));
|
||||
}
|
||||
break;
|
||||
case DESTROY:
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
|
||||
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
|
||||
iam_token));
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
|
||||
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
|
||||
iam_selector));
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
|
||||
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
|
||||
overridden_iam_token));
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
|
||||
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
|
||||
overridden_iam_selector));
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv, fake_md_key,
|
||||
fake_md_value));
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
|
||||
overridden_fake_md_key,
|
||||
overridden_fake_md_value));
|
||||
break;
|
||||
case FAIL:
|
||||
GPR_ASSERT(0);
|
||||
}
|
||||
grpc_call_unref(s);
|
||||
EXPECT_EQ(s.GetInitialMetadata(fake_md_key), fake_md_value);
|
||||
}
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
}
|
||||
|
||||
static void test_request_response_with_payload_and_call_creds(
|
||||
const CoreTestConfiguration& config, bool use_secure_call_creds) {
|
||||
request_response_with_payload_and_call_creds(
|
||||
"test_request_response_with_payload_and_call_creds", config, NONE,
|
||||
use_secure_call_creds);
|
||||
}
|
||||
|
||||
static void test_request_response_with_payload_and_overridden_call_creds(
|
||||
const CoreTestConfiguration& config, bool use_secure_call_creds) {
|
||||
request_response_with_payload_and_call_creds(
|
||||
"test_request_response_with_payload_and_overridden_call_creds", config,
|
||||
OVERRIDE, use_secure_call_creds);
|
||||
}
|
||||
|
||||
static void test_request_response_with_payload_and_deleted_call_creds(
|
||||
const CoreTestConfiguration& config, bool use_secure_call_creds) {
|
||||
request_response_with_payload_and_call_creds(
|
||||
"test_request_response_with_payload_and_deleted_call_creds", config,
|
||||
DESTROY, use_secure_call_creds);
|
||||
}
|
||||
|
||||
static void test_request_response_with_payload_fail_to_send_call_creds(
|
||||
const CoreTestConfiguration& config, bool use_secure_call_creds) {
|
||||
request_response_with_payload_and_call_creds(
|
||||
"test_request_response_with_payload_fail_to_send_call_creds", config,
|
||||
FAIL, use_secure_call_creds);
|
||||
}
|
||||
|
||||
static void test_request_with_server_rejecting_client_creds(
|
||||
const CoreTestConfiguration& config) {
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_call* c;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
void TestRequestResponseWithPayloadAndOverriddenCallCreds(
|
||||
CoreEnd2endTest& test, bool use_secure_call_creds) {
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
grpc_call_credentials* creds;
|
||||
|
||||
auto f = begin_test(config, "test_request_with_server_rejecting_client_creds",
|
||||
false, 1);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
creds = grpc_md_only_test_credentials_create(fake_md_key, fake_md_value);
|
||||
GPR_ASSERT(creds != nullptr);
|
||||
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
|
||||
grpc_call_credentials_release(creds);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNAUTHENTICATED);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
grpc_slice_unref(details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
}
|
||||
|
||||
void call_creds(const CoreTestConfiguration& config) {
|
||||
// Test fixtures that support call credentials with a minimum security level
|
||||
// of GRPC_PRIVACY_AND_INTEGRITY
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS) {
|
||||
test_request_response_with_payload_and_call_creds(config, true);
|
||||
test_request_response_with_payload_and_overridden_call_creds(config, true);
|
||||
test_request_response_with_payload_and_deleted_call_creds(config, true);
|
||||
if (use_secure_call_creds) {
|
||||
creds =
|
||||
grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
|
||||
} else {
|
||||
creds = grpc_md_only_test_credentials_create(fake_md_key, fake_md_value);
|
||||
}
|
||||
// Test that fixtures that support call credentials with a minimum security
|
||||
// level of GRPC_SECURITY_NONE cannot send call credentials that require
|
||||
// higher security level
|
||||
if (config.feature_mask &
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE) {
|
||||
test_request_response_with_payload_fail_to_send_call_creds(config, true);
|
||||
EXPECT_NE(creds, nullptr);
|
||||
c.SetCredentials(creds);
|
||||
if (use_secure_call_creds) {
|
||||
creds = grpc_google_iam_credentials_create(
|
||||
overridden_iam_token, overridden_iam_selector, nullptr);
|
||||
} else {
|
||||
creds = grpc_md_only_test_credentials_create(overridden_fake_md_key,
|
||||
overridden_fake_md_value);
|
||||
}
|
||||
// Fixtures that support sending call credentials should be able to send call
|
||||
// credentials of security level GRPC_SECURITY_NONE.
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS ||
|
||||
config.feature_mask &
|
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE) {
|
||||
test_request_response_with_payload_and_call_creds(config, false);
|
||||
test_request_response_with_payload_and_overridden_call_creds(config, false);
|
||||
test_request_response_with_payload_and_deleted_call_creds(config, false);
|
||||
test_request_with_server_rejecting_client_creds(config);
|
||||
c.SetCredentials(creds);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello world")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
PrintAuthContext(false, s.GetAuthContext().get());
|
||||
PrintAuthContext(true, c.GetAuthContext().get());
|
||||
// Cannot set creds on the server call object.
|
||||
EXPECT_NE(grpc_call_set_credentials(s.c_call(), nullptr), GRPC_CALL_OK);
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).SendInitialMetadata({}).RecvMessage(client_message);
|
||||
test.Expect(102, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(103)
|
||||
.RecvCloseOnServer(client_close)
|
||||
.SendMessage("hello you")
|
||||
.SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test.Expect(103, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
EXPECT_EQ(client_message.payload(), "hello world");
|
||||
EXPECT_EQ(server_message.payload(), "hello you");
|
||||
if (use_secure_call_creds) {
|
||||
EXPECT_EQ(s.GetInitialMetadata(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY),
|
||||
overridden_iam_token);
|
||||
EXPECT_EQ(s.GetInitialMetadata(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY),
|
||||
overridden_iam_selector);
|
||||
} else {
|
||||
EXPECT_EQ(s.GetInitialMetadata(overridden_fake_md_key),
|
||||
overridden_fake_md_value);
|
||||
}
|
||||
}
|
||||
|
||||
void call_creds_pre_init(void) {}
|
||||
void TestRequestResponseWithPayloadAndDeletedCallCreds(
|
||||
CoreEnd2endTest& test, bool use_secure_call_creds) {
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
grpc_call_credentials* creds;
|
||||
if (use_secure_call_creds) {
|
||||
creds =
|
||||
grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
|
||||
} else {
|
||||
creds = grpc_md_only_test_credentials_create(fake_md_key, fake_md_value);
|
||||
}
|
||||
EXPECT_NE(creds, nullptr);
|
||||
c.SetCredentials(creds);
|
||||
c.SetCredentials(nullptr);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello world")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
PrintAuthContext(false, s.GetAuthContext().get());
|
||||
PrintAuthContext(true, c.GetAuthContext().get());
|
||||
// Cannot set creds on the server call object.
|
||||
EXPECT_NE(grpc_call_set_credentials(s.c_call(), nullptr), GRPC_CALL_OK);
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).SendInitialMetadata({}).RecvMessage(client_message);
|
||||
test.Expect(102, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(103)
|
||||
.RecvCloseOnServer(client_close)
|
||||
.SendMessage("hello you")
|
||||
.SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test.Expect(103, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
EXPECT_EQ(client_message.payload(), "hello world");
|
||||
EXPECT_EQ(server_message.payload(), "hello you");
|
||||
EXPECT_EQ(s.GetInitialMetadata(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY),
|
||||
absl::nullopt);
|
||||
EXPECT_EQ(s.GetInitialMetadata(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY),
|
||||
absl::nullopt);
|
||||
EXPECT_EQ(s.GetInitialMetadata(fake_md_key), absl::nullopt);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsOnInsecureTest, RequestWithServerRejectingClientCreds) {
|
||||
InitClient(ChannelArgs());
|
||||
InitServer(ChannelArgs().Set(FAIL_AUTH_CHECK_SERVER_ARG_NAME, true));
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(10)).Create();
|
||||
auto* creds =
|
||||
grpc_md_only_test_credentials_create(fake_md_key, fake_md_value);
|
||||
EXPECT_NE(creds, nullptr);
|
||||
c.SetCredentials(creds);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello world")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message)
|
||||
.RecvStatusOnClient(server_status);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAUTHENTICATED);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsTest, RequestResponseWithPayloadAndCallCreds) {
|
||||
TestRequestResponseWithPayloadAndCallCreds(*this, true);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsTest, RequestResponseWithPayloadAndOverriddenCallCreds) {
|
||||
TestRequestResponseWithPayloadAndOverriddenCallCreds(*this, true);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsTest, RequestResponseWithPayloadAndDeletedCallCreds) {
|
||||
TestRequestResponseWithPayloadAndDeletedCallCreds(*this, true);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsTest, RequestResponseWithPayloadAndInsecureCallCreds) {
|
||||
TestRequestResponseWithPayloadAndCallCreds(*this, false);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsTest,
|
||||
RequestResponseWithPayloadAndOverriddenInsecureCallCreds) {
|
||||
TestRequestResponseWithPayloadAndOverriddenCallCreds(*this, false);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsTest,
|
||||
RequestResponseWithPayloadAndDeletedInsecureCallCreds) {
|
||||
TestRequestResponseWithPayloadAndDeletedCallCreds(*this, false);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsOnInsecureTest,
|
||||
RequestResponseWithPayloadAndInsecureCallCreds) {
|
||||
TestRequestResponseWithPayloadAndCallCreds(*this, false);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsOnInsecureTest,
|
||||
RequestResponseWithPayloadAndOverriddenInsecureCallCreds) {
|
||||
TestRequestResponseWithPayloadAndOverriddenCallCreds(*this, false);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsOnInsecureTest,
|
||||
RequestResponseWithPayloadAndDeletedInsecureCallCreds) {
|
||||
TestRequestResponseWithPayloadAndDeletedCallCreds(*this, false);
|
||||
}
|
||||
|
||||
TEST_P(PerCallCredsOnInsecureTest, FailToSendCallCreds) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
grpc_call_credentials* creds;
|
||||
creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
|
||||
EXPECT_NE(creds, nullptr);
|
||||
c.SetCredentials(creds);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello world")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message)
|
||||
.RecvStatusOnClient(server_status);
|
||||
// Expect the call to fail since the channel credentials did not satisfy the
|
||||
// minimum security level requirements.
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAUTHENTICATED);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,162 +16,54 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "absl/types/optional.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(
|
||||
grpc_core::ChannelArgs::FromC(client_args)
|
||||
.Set(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, "foo.test.google.fr:1234"));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
TEST_P(CoreClientChannelTest, CallHostOverride) {
|
||||
InitClient(ChannelArgs().Set(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
|
||||
"foo.test.google.fr:1234"));
|
||||
InitServer(ChannelArgs());
|
||||
auto c = NewClientCall("/foo")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Host("foo.test.google.fr:1234")
|
||||
.Create();
|
||||
EXPECT_NE(c.GetPeer(), absl::nullopt);
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(101, true);
|
||||
Step();
|
||||
EXPECT_NE(s.GetPeer(), absl::nullopt);
|
||||
EXPECT_NE(c.GetPeer(), absl::nullopt);
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
Expect(102, true);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_EQ(s.host(), "foo.test.google.fr:1234");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
static void test_invoke_simple_request(const CoreTestConfiguration& config) {
|
||||
auto f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
char* peer;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(
|
||||
f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq(),
|
||||
grpc_slice_from_static_string("/foo"),
|
||||
get_host_override_slice("foo.test.google.fr:1234", config), deadline,
|
||||
nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
peer = grpc_call_get_peer(c);
|
||||
GPR_ASSERT(peer != nullptr);
|
||||
gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
|
||||
gpr_free(peer);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
peer = grpc_call_get_peer(s);
|
||||
GPR_ASSERT(peer != nullptr);
|
||||
gpr_log(GPR_DEBUG, "server_peer=%s", peer);
|
||||
gpr_free(peer);
|
||||
peer = grpc_call_get_peer(c);
|
||||
GPR_ASSERT(peer != nullptr);
|
||||
gpr_log(GPR_DEBUG, "client_peer=%s", peer);
|
||||
gpr_free(peer);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
|
||||
config);
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
}
|
||||
|
||||
void call_host_override(const CoreTestConfiguration& config) {
|
||||
test_invoke_simple_request(config);
|
||||
}
|
||||
|
||||
void call_host_override_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,216 +16,80 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "src/core/lib/iomgr/exec_ctx.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/tests/cancel_test_helpers.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
cancellation_mode mode, bool use_service_config,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "%s", std::string(80, '*').c_str());
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s/%s/%s", test_name, config.name,
|
||||
mode.name, use_service_config ? "service_config" : "client_api");
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
namespace grpc_core {
|
||||
|
||||
// Cancel after accept, no payload
|
||||
static void test_cancel_after_accept(const CoreTestConfiguration& config,
|
||||
cancellation_mode mode,
|
||||
bool use_service_config) {
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_slice response_payload_slice =
|
||||
grpc_slice_from_copied_string("hello you");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
grpc_byte_buffer* response_payload =
|
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
int was_cancelled = 2;
|
||||
|
||||
grpc_channel_args* args = nullptr;
|
||||
if (use_service_config) {
|
||||
grpc_arg arg;
|
||||
arg.type = GRPC_ARG_STRING;
|
||||
arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
|
||||
arg.value.string = const_cast<char*>(
|
||||
"{\n"
|
||||
" \"methodConfig\": [ {\n"
|
||||
" \"name\": [\n"
|
||||
" { \"service\": \"service\", \"method\": \"method\" },\n"
|
||||
" { \"service\": \"unused\" }\n"
|
||||
" ],\n"
|
||||
" \"timeout\": \"5s\"\n"
|
||||
" } ]\n"
|
||||
"}");
|
||||
args = grpc_channel_args_copy_and_add(args, &arg, 1);
|
||||
}
|
||||
|
||||
auto f = begin_test(config, "cancel_after_accept", mode, use_service_config,
|
||||
args, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
gpr_timespec deadline = use_service_config
|
||||
? gpr_inf_future(GPR_CLOCK_MONOTONIC)
|
||||
: grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(),
|
||||
grpc_slice_from_static_string("/service/method"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(2));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(3), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(3), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL);
|
||||
GPR_ASSERT(was_cancelled == 1);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
grpc_slice_unref(details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
|
||||
if (args != nullptr) {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_channel_args_destroy(args);
|
||||
}
|
||||
void CancelAfterAccept(CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> cancellation_mode,
|
||||
Duration timeout) {
|
||||
auto c = test.NewClientCall("/service/method").Timeout(timeout).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message);
|
||||
auto s = test.RequestCall(2);
|
||||
test.Expect(2, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(3)
|
||||
.RecvMessage(client_message)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.RecvCloseOnServer(client_close);
|
||||
cancellation_mode->Apply(c);
|
||||
test.Expect(1, true);
|
||||
test.Expect(3, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(cancellation_mode->ExpectedStatus(),
|
||||
GRPC_STATUS_INTERNAL));
|
||||
EXPECT_TRUE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
void cancel_after_accept(const CoreTestConfiguration& config) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
|
||||
if (config.feature_mask & FEATURE_MASK_DOES_NOT_SUPPORT_DEADLINES &&
|
||||
cancellation_modes[i].expect_status == GRPC_STATUS_DEADLINE_EXCEEDED) {
|
||||
continue;
|
||||
}
|
||||
test_cancel_after_accept(config, cancellation_modes[i],
|
||||
false /* use_service_config */);
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL &&
|
||||
cancellation_modes[i].expect_status == GRPC_STATUS_DEADLINE_EXCEEDED) {
|
||||
test_cancel_after_accept(config, cancellation_modes[i],
|
||||
true /* use_service_config */);
|
||||
}
|
||||
}
|
||||
TEST_P(CoreEnd2endTest, CancelAfterAccept) {
|
||||
CancelAfterAccept(*this, std::make_unique<CancelCancellationMode>(),
|
||||
Duration::Seconds(5));
|
||||
}
|
||||
|
||||
void cancel_after_accept_pre_init(void) {}
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterAccept) {
|
||||
CancelAfterAccept(*this, std::make_unique<DeadlineCancellationMode>(),
|
||||
Duration::Seconds(5));
|
||||
}
|
||||
|
||||
TEST_P(CoreClientChannelTest, DeadlineAfterAcceptWithServiceConfig) {
|
||||
InitServer(ChannelArgs());
|
||||
InitClient(ChannelArgs().Set(
|
||||
GRPC_ARG_SERVICE_CONFIG,
|
||||
"{\n"
|
||||
" \"methodConfig\": [ {\n"
|
||||
" \"name\": [\n"
|
||||
" { \"service\": \"service\", \"method\": \"method\" },\n"
|
||||
" { \"service\": \"unused\" }\n"
|
||||
" ],\n"
|
||||
" \"timeout\": \"5s\"\n"
|
||||
" } ]\n"
|
||||
"}"));
|
||||
CancelAfterAccept(*this, std::make_unique<DeadlineCancellationMode>(),
|
||||
Duration::Infinity());
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,183 +16,62 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include <grpc/status.h>
|
||||
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/tests/cancel_test_helpers.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
cancellation_mode mode, grpc_channel_args* client_args,
|
||||
grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s/%s", test_name, config.name,
|
||||
mode.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
namespace grpc_core {
|
||||
|
||||
// Cancel after accept with a writes closed, no payload
|
||||
static void test_cancel_after_accept_and_writes_closed(
|
||||
const CoreTestConfiguration& config, cancellation_mode mode) {
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
auto f = begin_test(config, "test_cancel_after_accept_and_writes_closed",
|
||||
mode, nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_slice response_payload_slice =
|
||||
grpc_slice_from_copied_string("hello you");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
grpc_byte_buffer* response_payload =
|
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
int was_cancelled = 2;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(2));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(3), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(3), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL);
|
||||
GPR_ASSERT(was_cancelled == 1);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
grpc_slice_unref(details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
void CancelAfterClientDone(
|
||||
CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> cancellation_mode) {
|
||||
auto c = test.NewClientCall("/service/method")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message)
|
||||
.SendCloseFromClient();
|
||||
auto s = test.RequestCall(2);
|
||||
test.Expect(2, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(3)
|
||||
.RecvMessage(client_message)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.RecvCloseOnServer(client_close);
|
||||
cancellation_mode->Apply(c);
|
||||
test.Expect(1, true);
|
||||
test.Expect(3, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(cancellation_mode->ExpectedStatus(),
|
||||
GRPC_STATUS_INTERNAL));
|
||||
EXPECT_TRUE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
void cancel_after_client_done(const CoreTestConfiguration& config) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
|
||||
if (config.feature_mask & FEATURE_MASK_DOES_NOT_SUPPORT_DEADLINES &&
|
||||
cancellation_modes[i].expect_status == GRPC_STATUS_DEADLINE_EXCEEDED) {
|
||||
continue;
|
||||
}
|
||||
test_cancel_after_accept_and_writes_closed(config, cancellation_modes[i]);
|
||||
}
|
||||
TEST_P(CoreEnd2endTest, CancelAfterClientDone) {
|
||||
CancelAfterClientDone(*this, std::make_unique<CancelCancellationMode>());
|
||||
}
|
||||
|
||||
void cancel_after_client_done_pre_init(void) {}
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterClientDone) {
|
||||
CancelAfterClientDone(*this, std::make_unique<DeadlineCancellationMode>());
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,143 +16,128 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include <grpc/status.h>
|
||||
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/tests/cancel_test_helpers.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
cancellation_mode mode, size_t test_ops, grpc_channel_args* client_args,
|
||||
grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s/%s [%" PRIdPTR " ops]", test_name,
|
||||
config.name, mode.name, test_ops);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
|
||||
void CancelAfterInvoke6(CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> mode) {
|
||||
auto c = test.NewClientCall("/service/method")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.SendCloseFromClient()
|
||||
.RecvMessage(server_message);
|
||||
mode->Apply(c);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(mode->ExpectedStatus(), GRPC_STATUS_INTERNAL));
|
||||
}
|
||||
|
||||
// Cancel after invoke, no payload
|
||||
static void test_cancel_after_invoke(const CoreTestConfiguration& config,
|
||||
cancellation_mode mode, size_t test_ops) {
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_call* c;
|
||||
auto f = begin_test(config, "test_cancel_after_invoke", mode, test_ops,
|
||||
nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, test_ops, grpc_core::CqVerifier::tag(1),
|
||||
nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
grpc_slice_unref(details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
void CancelAfterInvoke5(CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> mode) {
|
||||
auto c = test.NewClientCall("/service/method")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.SendCloseFromClient();
|
||||
mode->Apply(c);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(mode->ExpectedStatus(), GRPC_STATUS_INTERNAL));
|
||||
}
|
||||
|
||||
void cancel_after_invoke(const CoreTestConfiguration& config) {
|
||||
unsigned i, j;
|
||||
|
||||
for (j = 3; j < 6; j++) {
|
||||
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
|
||||
if (config.feature_mask & FEATURE_MASK_DOES_NOT_SUPPORT_DEADLINES &&
|
||||
cancellation_modes[i].expect_status ==
|
||||
GRPC_STATUS_DEADLINE_EXCEEDED) {
|
||||
continue;
|
||||
}
|
||||
test_cancel_after_invoke(config, cancellation_modes[i], j);
|
||||
}
|
||||
}
|
||||
void CancelAfterInvoke4(CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> mode) {
|
||||
auto c = test.NewClientCall("/service/method")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024));
|
||||
mode->Apply(c);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(mode->ExpectedStatus(), GRPC_STATUS_INTERNAL));
|
||||
}
|
||||
|
||||
void cancel_after_invoke_pre_init(void) {}
|
||||
void CancelAfterInvoke3(CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> mode) {
|
||||
auto c = test.NewClientCall("/service/method")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.SendInitialMetadata({});
|
||||
mode->Apply(c);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(mode->ExpectedStatus(), GRPC_STATUS_INTERNAL));
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelAfterInvoke6) {
|
||||
CancelAfterInvoke6(*this, std::make_unique<CancelCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelAfterInvoke5) {
|
||||
CancelAfterInvoke5(*this, std::make_unique<CancelCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelAfterInvoke4) {
|
||||
CancelAfterInvoke4(*this, std::make_unique<CancelCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelAfterInvoke3) {
|
||||
CancelAfterInvoke3(*this, std::make_unique<CancelCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterInvoke6) {
|
||||
CancelAfterInvoke6(*this, std::make_unique<DeadlineCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterInvoke5) {
|
||||
CancelAfterInvoke5(*this, std::make_unique<DeadlineCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterInvoke4) {
|
||||
CancelAfterInvoke4(*this, std::make_unique<DeadlineCancellationMode>());
|
||||
}
|
||||
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterInvoke3) {
|
||||
CancelAfterInvoke3(*this, std::make_unique<DeadlineCancellationMode>());
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,247 +16,83 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "src/core/lib/iomgr/exec_ctx.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/tests/cancel_test_helpers.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
cancellation_mode mode, bool use_service_config,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s/%s/%s", test_name, config.name,
|
||||
mode.name, use_service_config ? "service_config" : "client_api");
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
void CancelAfterRoundTrip(CoreEnd2endTest& test,
|
||||
std::unique_ptr<CancellationMode> mode,
|
||||
Duration timeout) {
|
||||
auto c = test.NewClientCall("/service/method").Timeout(timeout).Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(100))
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102)
|
||||
.RecvMessage(client_message)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(100));
|
||||
test.Expect(102, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingMessage server_message_2;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(2).RecvMessage(server_message_2).RecvStatusOnClient(server_status);
|
||||
mode->Apply(c);
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(103).RecvCloseOnServer(client_close).SendMessage(RandomSlice(100));
|
||||
test.Expect(2, true);
|
||||
test.Expect(103, true);
|
||||
test.Step();
|
||||
EXPECT_THAT(server_status.status(),
|
||||
::testing::AnyOf(mode->ExpectedStatus(), GRPC_STATUS_INTERNAL));
|
||||
EXPECT_TRUE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
// Cancel after accept, no payload
|
||||
static void test_cancel_after_round_trip(const CoreTestConfiguration& config,
|
||||
cancellation_mode mode,
|
||||
bool use_service_config) {
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_slice response_payload_slice =
|
||||
grpc_slice_from_copied_string("hello you");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
grpc_byte_buffer* response_payload1 =
|
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
grpc_byte_buffer* response_payload2 =
|
||||
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
int was_cancelled = 2;
|
||||
|
||||
grpc_channel_args* args = nullptr;
|
||||
if (use_service_config) {
|
||||
grpc_arg arg;
|
||||
arg.type = GRPC_ARG_STRING;
|
||||
arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
|
||||
arg.value.string = const_cast<char*>(
|
||||
"{\n"
|
||||
" \"methodConfig\": [ {\n"
|
||||
" \"name\": [\n"
|
||||
" { \"service\": \"service\", \"method\": \"method\" }\n"
|
||||
" ],\n"
|
||||
" \"timeout\": \"5s\"\n"
|
||||
" } ]\n"
|
||||
"}");
|
||||
args = grpc_channel_args_copy_and_add(args, &arg, 1);
|
||||
}
|
||||
|
||||
auto f = begin_test(config, "cancel_after_round_trip", mode,
|
||||
use_service_config, args, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
gpr_timespec deadline = use_service_config
|
||||
? gpr_inf_future(GPR_CLOCK_MONOTONIC)
|
||||
: grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(),
|
||||
grpc_slice_from_static_string("/service/method"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload1;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
request_payload_recv = nullptr;
|
||||
response_payload_recv = nullptr;
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(2), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload2;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL);
|
||||
GPR_ASSERT(was_cancelled == 1);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload1);
|
||||
grpc_byte_buffer_destroy(response_payload2);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
grpc_slice_unref(details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
|
||||
if (args != nullptr) {
|
||||
grpc_core::ExecCtx exec_ctx;
|
||||
grpc_channel_args_destroy(args);
|
||||
}
|
||||
TEST_P(CoreEnd2endTest, CancelAfterRoundTrip) {
|
||||
CancelAfterRoundTrip(*this, std::make_unique<CancelCancellationMode>(),
|
||||
Duration::Seconds(5));
|
||||
}
|
||||
|
||||
void cancel_after_round_trip(const CoreTestConfiguration& config) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
|
||||
if (config.feature_mask & FEATURE_MASK_DOES_NOT_SUPPORT_DEADLINES &&
|
||||
cancellation_modes[i].expect_status == GRPC_STATUS_DEADLINE_EXCEEDED) {
|
||||
continue;
|
||||
}
|
||||
test_cancel_after_round_trip(config, cancellation_modes[i],
|
||||
false /* use_service_config */);
|
||||
if (config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL &&
|
||||
cancellation_modes[i].expect_status == GRPC_STATUS_DEADLINE_EXCEEDED) {
|
||||
test_cancel_after_round_trip(config, cancellation_modes[i],
|
||||
true /* use_service_config */);
|
||||
}
|
||||
}
|
||||
TEST_P(CoreDeadlineTest, DeadlineAfterRoundTrip) {
|
||||
CancelAfterRoundTrip(*this, std::make_unique<DeadlineCancellationMode>(),
|
||||
Duration::Seconds(5));
|
||||
}
|
||||
|
||||
void cancel_after_round_trip_pre_init(void) {}
|
||||
TEST_P(CoreClientChannelTest, DeadlineAfterAcceptWithServiceConfig) {
|
||||
InitServer(ChannelArgs());
|
||||
InitClient(ChannelArgs().Set(
|
||||
GRPC_ARG_SERVICE_CONFIG,
|
||||
"{\n"
|
||||
" \"methodConfig\": [ {\n"
|
||||
" \"name\": [\n"
|
||||
" { \"service\": \"service\", \"method\": \"method\" }\n"
|
||||
" ],\n"
|
||||
" \"timeout\": \"5s\"\n"
|
||||
" } ]\n"
|
||||
"}"));
|
||||
CancelAfterRoundTrip(*this, std::make_unique<DeadlineCancellationMode>(),
|
||||
Duration::Infinity());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,136 +16,93 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name, size_t num_ops,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s [%" PRIdPTR " ops]", test_name,
|
||||
config.name, num_ops);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelBeforeInvoke6) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.Cancel();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvMessage(server_message);
|
||||
Expect(1, AnyStatus());
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
// Cancel before invoke
|
||||
static void test_cancel_before_invoke(const CoreTestConfiguration& config,
|
||||
size_t test_ops) {
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_call* c;
|
||||
auto f =
|
||||
begin_test(config, "cancel_before_invoke", test_ops, nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* response_payload_recv = nullptr;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c, nullptr));
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, test_ops, grpc_core::CqVerifier::tag(1),
|
||||
nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
// Filter based stack tracks this as a failed op, promise based stack tracks
|
||||
// it as a successful one with a failed request. The latter probably makes
|
||||
// more sense, but since we can't tell from outside which case we have we
|
||||
// accept either.
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), grpc_core::CqVerifier::AnyStatus());
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_CANCELLED);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
grpc_slice_unref(details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
TEST_P(CoreEnd2endTest, CancelBeforeInvoke5) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.Cancel();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata);
|
||||
Expect(1, AnyStatus());
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
void cancel_before_invoke(const CoreTestConfiguration& config) {
|
||||
size_t i;
|
||||
for (i = 1; i <= 6; i++) {
|
||||
test_cancel_before_invoke(config, i);
|
||||
}
|
||||
TEST_P(CoreEnd2endTest, CancelBeforeInvoke4) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.Cancel();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024))
|
||||
.SendCloseFromClient();
|
||||
Expect(1, AnyStatus());
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
void cancel_before_invoke_pre_init(void) {}
|
||||
TEST_P(CoreEnd2endTest, CancelBeforeInvoke3) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.Cancel();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(RandomSlice(1024));
|
||||
Expect(1, AnyStatus());
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelBeforeInvoke2) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.Cancel();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1).RecvStatusOnClient(server_status).SendInitialMetadata({});
|
||||
Expect(1, AnyStatus());
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelBeforeInvoke1) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.Cancel();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1).RecvStatusOnClient(server_status);
|
||||
Expect(1, AnyStatus());
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,58 +16,18 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/end2end/tests/cancel_test_helpers.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
cancellation_mode mode, grpc_channel_args* client_args,
|
||||
grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s/%s", test_name, config.name,
|
||||
mode.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelInAVacuum) {
|
||||
NewClientCall("/service/method").Create().Cancel();
|
||||
}
|
||||
|
||||
// Cancel and do nothing
|
||||
static void test_cancel_in_a_vacuum(const CoreTestConfiguration& config,
|
||||
cancellation_mode mode) {
|
||||
grpc_call* c;
|
||||
auto f =
|
||||
begin_test(config, "test_cancel_in_a_vacuum", mode, nullptr, nullptr);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
|
||||
|
||||
grpc_call_unref(c);
|
||||
TEST_P(CoreDeadlineTest, DeadlineInAVacuum) {
|
||||
NewClientCall("/service/method").Create();
|
||||
}
|
||||
|
||||
void cancel_in_a_vacuum(const CoreTestConfiguration& config) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); i++) {
|
||||
test_cancel_in_a_vacuum(config, cancellation_modes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void cancel_in_a_vacuum_pre_init(void) {}
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -19,25 +19,31 @@
|
|||
#ifndef GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
|
||||
#define GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/status.h>
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
grpc_call_error (*initiate_cancel)(grpc_call* call, void* reserved);
|
||||
grpc_status_code expect_status;
|
||||
const char* expect_details;
|
||||
} cancellation_mode;
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
|
||||
static grpc_call_error wait_for_deadline(grpc_call* /*call*/, void* reserved) {
|
||||
(void)reserved;
|
||||
return GRPC_CALL_OK;
|
||||
}
|
||||
|
||||
static const cancellation_mode cancellation_modes[] = {
|
||||
{"cancel", grpc_call_cancel, GRPC_STATUS_CANCELLED, "CANCELLED"},
|
||||
{"deadline", wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED,
|
||||
"Deadline Exceeded"},
|
||||
namespace grpc_core {
|
||||
class CancellationMode {
|
||||
public:
|
||||
virtual void Apply(CoreEnd2endTest::Call& call) = 0;
|
||||
virtual grpc_status_code ExpectedStatus() = 0;
|
||||
virtual ~CancellationMode() = default;
|
||||
};
|
||||
|
||||
class CancelCancellationMode : public CancellationMode {
|
||||
public:
|
||||
void Apply(CoreEnd2endTest::Call& call) override { call.Cancel(); }
|
||||
grpc_status_code ExpectedStatus() override { return GRPC_STATUS_CANCELLED; }
|
||||
};
|
||||
|
||||
class DeadlineCancellationMode : public CancellationMode {
|
||||
public:
|
||||
void Apply(CoreEnd2endTest::Call&) override {}
|
||||
grpc_status_code ExpectedStatus() override {
|
||||
return GRPC_STATUS_DEADLINE_EXCEEDED;
|
||||
}
|
||||
};
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
|
||||
|
|
|
|||
|
|
@ -16,122 +16,89 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/string_util.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name, size_t num_ops,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s [%" PRIdPTR " ops]", test_name,
|
||||
config.name, num_ops);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
static void simple_request_body(const CoreTestConfiguration& /*config*/,
|
||||
CoreTestFixture* f, size_t num_ops) {
|
||||
grpc_call* c;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
GPR_ASSERT(num_ops <= (size_t)(op - ops));
|
||||
error = grpc_call_start_batch(c, ops, num_ops, grpc_core::CqVerifier::tag(1),
|
||||
nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
TEST_P(CoreEnd2endTest, CancelWithStatus1) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1).RecvStatusOnClient(server_status);
|
||||
char* dynamic_string = gpr_strdup("xyz");
|
||||
grpc_call_cancel_with_status(c, GRPC_STATUS_UNIMPLEMENTED, dynamic_string,
|
||||
nullptr);
|
||||
c.CancelWithStatus(GRPC_STATUS_UNIMPLEMENTED, dynamic_string);
|
||||
// The API of \a description allows for it to be a dynamic/non-const
|
||||
// string, test this guarantee.
|
||||
gpr_free(dynamic_string);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
|
||||
grpc_call_unref(c);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
}
|
||||
|
||||
static void test_invoke_simple_request(const CoreTestConfiguration& config,
|
||||
size_t num_ops) {
|
||||
auto f = begin_test(config, "test_invoke_simple_request", num_ops, nullptr,
|
||||
nullptr);
|
||||
simple_request_body(config, f.get(), num_ops);
|
||||
TEST_P(CoreEnd2endTest, CancelWithStatus2) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata);
|
||||
char* dynamic_string = gpr_strdup("xyz");
|
||||
c.CancelWithStatus(GRPC_STATUS_UNIMPLEMENTED, dynamic_string);
|
||||
// The API of \a description allows for it to be a dynamic/non-const
|
||||
// string, test this guarantee.
|
||||
gpr_free(dynamic_string);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
}
|
||||
|
||||
void cancel_with_status(const CoreTestConfiguration& config) {
|
||||
size_t i;
|
||||
for (i = 1; i <= 4; i++) {
|
||||
test_invoke_simple_request(config, i);
|
||||
}
|
||||
TEST_P(CoreEnd2endTest, CancelWithStatus3) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.SendInitialMetadata({});
|
||||
char* dynamic_string = gpr_strdup("xyz");
|
||||
c.CancelWithStatus(GRPC_STATUS_UNIMPLEMENTED, dynamic_string);
|
||||
// The API of \a description allows for it to be a dynamic/non-const
|
||||
// string, test this guarantee.
|
||||
gpr_free(dynamic_string);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
}
|
||||
|
||||
void cancel_with_status_pre_init(void) {}
|
||||
TEST_P(CoreEnd2endTest, CancelWithStatus4) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.RecvStatusOnClient(server_status)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient();
|
||||
char* dynamic_string = gpr_strdup("xyz");
|
||||
c.CancelWithStatus(GRPC_STATUS_UNIMPLEMENTED, dynamic_string);
|
||||
// The API of \a description allows for it to be a dynamic/non-const
|
||||
// string, test this guarantee.
|
||||
gpr_free(dynamic_string);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -18,252 +18,145 @@
|
|||
|
||||
#include "src/core/lib/channel/channelz.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/surface/channel.h"
|
||||
#include "src/core/lib/surface/server.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
using testing::HasSubstr;
|
||||
using testing::Not;
|
||||
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
void RunOneRequest(CoreEnd2endTest& test, bool request_is_success) {
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(
|
||||
request_is_success ? GRPC_STATUS_OK : GRPC_STATUS_UNIMPLEMENTED,
|
||||
"xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
test.Expect(102, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
}
|
||||
|
||||
static void run_one_request(const CoreTestConfiguration& /*config*/,
|
||||
CoreTestFixture* f, bool request_is_success) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
TEST_P(CoreEnd2endTest, Channelz) {
|
||||
auto args = ChannelArgs()
|
||||
.Set(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 0)
|
||||
.Set(GRPC_ARG_ENABLE_CHANNELZ, true);
|
||||
InitServer(args);
|
||||
InitClient(args);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
channelz::ChannelNode* channelz_channel =
|
||||
grpc_channel_get_channelz_node(client());
|
||||
ASSERT_NE(channelz_channel, nullptr);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->data.recv_status_on_client.error_string = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status =
|
||||
request_is_success ? GRPC_STATUS_OK : GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
}
|
||||
|
||||
static void test_channelz(const CoreTestConfiguration& config) {
|
||||
grpc_arg arg[] = {
|
||||
grpc_channel_arg_integer_create(
|
||||
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
|
||||
0),
|
||||
grpc_channel_arg_integer_create(
|
||||
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true)};
|
||||
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
|
||||
|
||||
auto f = begin_test(config, "test_channelz", &args, &args);
|
||||
grpc_core::channelz::ChannelNode* channelz_channel =
|
||||
grpc_channel_get_channelz_node(f->client());
|
||||
GPR_ASSERT(channelz_channel != nullptr);
|
||||
|
||||
grpc_core::channelz::ServerNode* channelz_server =
|
||||
grpc_core::Server::FromC(f->server())->channelz_node();
|
||||
GPR_ASSERT(channelz_server != nullptr);
|
||||
channelz::ServerNode* channelz_server =
|
||||
Server::FromC(server())->channelz_node();
|
||||
ASSERT_NE(channelz_server, nullptr);
|
||||
|
||||
std::string json = channelz_channel->RenderJsonString();
|
||||
// nothing is present yet
|
||||
GPR_ASSERT(json.find("\"callsStarted\"") == json.npos);
|
||||
GPR_ASSERT(json.find("\"callsFailed\"") == json.npos);
|
||||
GPR_ASSERT(json.find("\"callsSucceeded\"") == json.npos);
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"callsStarted\"")));
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"callsFailed\"")));
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"callsSucceeded\"")));
|
||||
|
||||
// one successful request
|
||||
run_one_request(config, f.get(), true);
|
||||
RunOneRequest(*this, true);
|
||||
|
||||
json = channelz_channel->RenderJsonString();
|
||||
GPR_ASSERT(json.find("\"callsStarted\":\"1\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"callsSucceeded\":\"1\"") != json.npos);
|
||||
EXPECT_THAT(json, HasSubstr("\"callsStarted\":\"1\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"callsSucceeded\":\"1\""));
|
||||
|
||||
// one failed request
|
||||
run_one_request(config, f.get(), false);
|
||||
RunOneRequest(*this, false);
|
||||
|
||||
json = channelz_channel->RenderJsonString();
|
||||
GPR_ASSERT(json.find("\"callsStarted\":\"2\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"callsFailed\":\"1\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"callsSucceeded\":\"1\"") != json.npos);
|
||||
EXPECT_THAT(json, HasSubstr("\"callsStarted\":\"2\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"callsFailed\":\"1\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"callsSucceeded\":\"1\""));
|
||||
// channel tracing is not enabled, so these should not be preset.
|
||||
GPR_ASSERT(json.find("\"trace\"") == json.npos);
|
||||
GPR_ASSERT(json.find("\"description\":\"Channel created\"") == json.npos);
|
||||
GPR_ASSERT(json.find("\"severity\":\"CT_INFO\"") == json.npos);
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"trace\"")));
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"description\":\"Channel created\"")));
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"severity\":\"CT_INFO\"")));
|
||||
|
||||
json = channelz_server->RenderJsonString();
|
||||
GPR_ASSERT(json.find("\"callsStarted\":\"2\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"callsFailed\":\"1\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"callsSucceeded\":\"1\"") != json.npos);
|
||||
EXPECT_THAT(json, HasSubstr("\"callsStarted\":\"2\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"callsFailed\":\"1\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"callsSucceeded\":\"1\""));
|
||||
// channel tracing is not enabled, so these should not be preset.
|
||||
GPR_ASSERT(json.find("\"trace\"") == json.npos);
|
||||
GPR_ASSERT(json.find("\"description\":\"Channel created\"") == json.npos);
|
||||
GPR_ASSERT(json.find("\"severity\":\"CT_INFO\"") == json.npos);
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"trace\"")));
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"description\":\"Channel created\"")));
|
||||
EXPECT_THAT(json, Not(HasSubstr("\"severity\":\"CT_INFO\"")));
|
||||
|
||||
json = channelz_server->RenderServerSockets(0, 100);
|
||||
GPR_ASSERT(json.find("\"end\":true") != json.npos);
|
||||
EXPECT_THAT(json, HasSubstr("\"end\":true"));
|
||||
}
|
||||
|
||||
static void test_channelz_with_channel_trace(
|
||||
const CoreTestConfiguration& config) {
|
||||
grpc_arg arg[] = {
|
||||
grpc_channel_arg_integer_create(
|
||||
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
|
||||
1024 * 1024),
|
||||
grpc_channel_arg_integer_create(
|
||||
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true)};
|
||||
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
|
||||
TEST_P(CoreEnd2endTest, ChannelzWithChannelTrace) {
|
||||
auto args =
|
||||
ChannelArgs()
|
||||
.Set(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024 * 1024)
|
||||
.Set(GRPC_ARG_ENABLE_CHANNELZ, true);
|
||||
InitServer(args);
|
||||
InitClient(args);
|
||||
|
||||
auto f = begin_test(config, "test_channelz_with_channel_trace", &args, &args);
|
||||
grpc_core::channelz::ChannelNode* channelz_channel =
|
||||
grpc_channel_get_channelz_node(f->client());
|
||||
GPR_ASSERT(channelz_channel != nullptr);
|
||||
channelz::ChannelNode* channelz_channel =
|
||||
grpc_channel_get_channelz_node(client());
|
||||
ASSERT_NE(channelz_channel, nullptr);
|
||||
|
||||
grpc_core::channelz::ServerNode* channelz_server =
|
||||
grpc_core::Server::FromC(f->server())->channelz_node();
|
||||
GPR_ASSERT(channelz_server != nullptr);
|
||||
channelz::ServerNode* channelz_server =
|
||||
Server::FromC(server())->channelz_node();
|
||||
ASSERT_NE(channelz_server, nullptr);
|
||||
|
||||
run_one_request(config, f.get(), true);
|
||||
RunOneRequest(*this, true);
|
||||
|
||||
std::string json = channelz_channel->RenderJsonString();
|
||||
GPR_ASSERT(json.find("\"trace\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"description\":\"Channel created\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"severity\":\"CT_INFO\"") != json.npos);
|
||||
EXPECT_THAT(json, HasSubstr("\"trace\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"description\":\"Channel created\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"severity\":\"CT_INFO\""));
|
||||
|
||||
json = channelz_server->RenderJsonString();
|
||||
GPR_ASSERT(json.find("\"trace\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"description\":\"Server created\"") != json.npos);
|
||||
GPR_ASSERT(json.find("\"severity\":\"CT_INFO\"") != json.npos);
|
||||
EXPECT_THAT(json, HasSubstr("\"trace\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"description\":\"Server created\""));
|
||||
EXPECT_THAT(json, HasSubstr("\"severity\":\"CT_INFO\""));
|
||||
}
|
||||
|
||||
static void test_channelz_disabled(const CoreTestConfiguration& config) {
|
||||
grpc_arg arg[] = {
|
||||
grpc_channel_arg_integer_create(
|
||||
const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
|
||||
0),
|
||||
grpc_channel_arg_integer_create(
|
||||
const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), false)};
|
||||
grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg};
|
||||
|
||||
auto f = begin_test(config, "test_channelz_disabled", &args, &args);
|
||||
grpc_core::channelz::ChannelNode* channelz_channel =
|
||||
grpc_channel_get_channelz_node(f->client());
|
||||
GPR_ASSERT(channelz_channel == nullptr);
|
||||
// one successful request
|
||||
run_one_request(config, f.get(), true);
|
||||
GPR_ASSERT(channelz_channel == nullptr);
|
||||
TEST_P(CoreEnd2endTest, ChannelzDisabled) {
|
||||
auto args = ChannelArgs()
|
||||
.Set(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 0)
|
||||
.Set(GRPC_ARG_ENABLE_CHANNELZ, false);
|
||||
InitServer(args);
|
||||
InitClient(args);
|
||||
channelz::ChannelNode* channelz_channel =
|
||||
grpc_channel_get_channelz_node(client());
|
||||
EXPECT_EQ(channelz_channel, nullptr);
|
||||
RunOneRequest(*this, true);
|
||||
}
|
||||
|
||||
void channelz(const CoreTestConfiguration& config) {
|
||||
test_channelz(config);
|
||||
test_channelz_with_channel_trace(config);
|
||||
test_channelz_disabled(config);
|
||||
}
|
||||
|
||||
void channelz_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,214 +16,70 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
// Client streaming test where the client sends a bunch of messages and the
|
||||
// server reads them. After reading some messages, the server sends the status.
|
||||
// Client writes fail after that due to the end of stream and the client
|
||||
// subsequently requests and receives the status.
|
||||
static void test_client_streaming(const CoreTestConfiguration& config,
|
||||
int messages) {
|
||||
auto f = begin_test(config, "test_client_streaming", nullptr, nullptr);
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* request_payload = nullptr;
|
||||
int i;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(100));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(100), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(101), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
void ClientStreaming(CoreEnd2endTest& test, int messages) {
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1).SendInitialMetadata({}).RecvInitialMetadata(
|
||||
server_initial_metadata);
|
||||
auto s = test.RequestCall(100);
|
||||
test.Expect(100, true);
|
||||
test.Step();
|
||||
s.NewBatch(101).SendInitialMetadata({});
|
||||
test.Expect(101, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
// Client writes bunch of messages and server reads them
|
||||
for (i = 0; i < messages; i++) {
|
||||
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Verify();
|
||||
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
for (int i = 0; i < messages; i++) {
|
||||
c.NewBatch(2).SendMessage("hello world");
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).RecvMessage(client_message);
|
||||
test.Expect(2, true);
|
||||
test.Expect(102, true);
|
||||
test.Step();
|
||||
EXPECT_EQ(client_message.payload(), "hello world");
|
||||
}
|
||||
|
||||
// Server sends status denoting end of stream
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(104), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(104), true);
|
||||
cqv.Verify();
|
||||
s.NewBatch(103).SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {});
|
||||
test.Expect(103, true);
|
||||
test.Step();
|
||||
// Do an empty verify to make sure that the client receives the status
|
||||
cqv.VerifyEmpty();
|
||||
test.Step();
|
||||
|
||||
// Client tries sending another message which should fail
|
||||
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), false);
|
||||
cqv.Verify();
|
||||
c.NewBatch(3).SendMessage("hello world");
|
||||
test.Expect(3, false);
|
||||
test.Step();
|
||||
|
||||
// Client sends close and requests status
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(3), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(3), true);
|
||||
cqv.Verify();
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
|
||||
grpc_slice_unref(request_payload_slice);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
grpc_slice_unref(details);
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(4).SendCloseFromClient().RecvStatusOnClient(server_status);
|
||||
test.Expect(4, true);
|
||||
test.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
}
|
||||
|
||||
void client_streaming(const CoreTestConfiguration& config) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
test_client_streaming(config, i);
|
||||
}
|
||||
}
|
||||
TEST_P(CoreEnd2endTest, ClientStreaming0) { ClientStreaming(*this, 0); }
|
||||
TEST_P(CoreEnd2endTest, ClientStreaming1) { ClientStreaming(*this, 1); }
|
||||
TEST_P(CoreEnd2endTest, ClientStreaming3) { ClientStreaming(*this, 3); }
|
||||
TEST_P(CoreEnd2endTest, ClientStreaming10) { ClientStreaming(*this, 10); }
|
||||
TEST_P(CoreEnd2endTest, ClientStreaming30) { ClientStreaming(*this, 30); }
|
||||
|
||||
void client_streaming_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -17,627 +17,414 @@
|
|||
//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/compression.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gpr/useful.h"
|
||||
#include "src/core/lib/gprpp/bitset.h"
|
||||
#include "src/core/lib/surface/call.h"
|
||||
#include "src/core/lib/surface/call_test_only.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
const grpc_channel_args* client_args, const grpc_channel_args* server_args,
|
||||
bool decompress_in_core) {
|
||||
gpr_log(GPR_INFO, "Running test: %s%s/%s", test_name,
|
||||
decompress_in_core ? "" : "_with_decompression_disabled",
|
||||
config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
static void request_for_disabled_algorithm(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
uint32_t send_flags_bitmask,
|
||||
grpc_compression_algorithm algorithm_to_disable,
|
||||
grpc_compression_algorithm requested_client_compression_algorithm,
|
||||
grpc_status_code expected_error, grpc_metadata* client_metadata,
|
||||
bool decompress_in_core) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice;
|
||||
grpc_byte_buffer* request_payload;
|
||||
grpc_core::ChannelArgs client_args;
|
||||
grpc_core::ChannelArgs server_args;
|
||||
class TestConfigurator {
|
||||
public:
|
||||
explicit TestConfigurator(CoreEnd2endTest& test) : test_(test) {}
|
||||
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
char str[1024];
|
||||
|
||||
memset(str, 'x', 1023);
|
||||
str[1023] = '\0';
|
||||
request_payload_slice = grpc_slice_from_copied_string(str);
|
||||
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
|
||||
client_args =
|
||||
grpc_core::ChannelArgs().Set(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
|
||||
requested_client_compression_algorithm);
|
||||
server_args =
|
||||
grpc_core::ChannelArgs()
|
||||
.Set(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, GRPC_COMPRESS_NONE)
|
||||
.Set(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
|
||||
grpc_core::BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT>()
|
||||
.SetAll(true)
|
||||
.Set(algorithm_to_disable, false)
|
||||
.ToInt<uint32_t>());
|
||||
if (!decompress_in_core) {
|
||||
client_args =
|
||||
client_args.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
|
||||
server_args =
|
||||
server_args.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
|
||||
TestConfigurator& DisableAlgorithmAtServer(
|
||||
grpc_compression_algorithm algorithm) {
|
||||
server_args_ =
|
||||
server_args_.Set(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
|
||||
BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT>()
|
||||
.SetAll(true)
|
||||
.Set(algorithm, false)
|
||||
.ToInt<uint32_t>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto f = begin_test(config, test_name, client_args.ToC().get(),
|
||||
server_args.ToC().get(), decompress_in_core);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
if (client_metadata != nullptr) {
|
||||
op->data.send_initial_metadata.count = 1;
|
||||
op->data.send_initial_metadata.metadata = client_metadata;
|
||||
} else {
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
TestConfigurator& ClientDefaultAlgorithm(
|
||||
grpc_compression_algorithm algorithm) {
|
||||
client_args_ =
|
||||
client_args_.Set(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, algorithm);
|
||||
return *this;
|
||||
}
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = send_flags_bitmask;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), false);
|
||||
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Verify();
|
||||
|
||||
// call was cancelled (closed) ...
|
||||
GPR_ASSERT(was_cancelled != 0);
|
||||
// with a certain error
|
||||
GPR_ASSERT(status == expected_error);
|
||||
|
||||
const char* algo_name = nullptr;
|
||||
GPR_ASSERT(grpc_compression_algorithm_name(algorithm_to_disable, &algo_name));
|
||||
std::string expected_details =
|
||||
absl::StrFormat("Compression algorithm '%s' is disabled.", algo_name);
|
||||
// and we expect a specific reason for it
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details.c_str()));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
|
||||
grpc_slice_unref(request_payload_slice);
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
}
|
||||
|
||||
static void request_with_payload_template_inner(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
uint32_t client_send_flags_bitmask,
|
||||
grpc_compression_algorithm default_client_channel_compression_algorithm,
|
||||
grpc_compression_algorithm default_server_channel_compression_algorithm,
|
||||
grpc_compression_algorithm expected_algorithm_from_client,
|
||||
grpc_compression_algorithm expected_algorithm_from_server,
|
||||
grpc_metadata* client_init_metadata, bool set_server_level,
|
||||
grpc_compression_level server_compression_level,
|
||||
bool send_message_before_initial_metadata, bool decompress_in_core) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice;
|
||||
grpc_byte_buffer* request_payload = nullptr;
|
||||
grpc_core::ChannelArgs client_args;
|
||||
grpc_core::ChannelArgs server_args;
|
||||
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_byte_buffer* response_payload;
|
||||
grpc_byte_buffer* response_payload_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
char request_str[1024];
|
||||
char response_str[1024];
|
||||
|
||||
memset(request_str, 'x', 1023);
|
||||
request_str[1023] = '\0';
|
||||
|
||||
memset(response_str, 'y', 1023);
|
||||
response_str[1023] = '\0';
|
||||
|
||||
request_payload_slice = grpc_slice_from_copied_string(request_str);
|
||||
grpc_slice response_payload_slice =
|
||||
grpc_slice_from_copied_string(response_str);
|
||||
|
||||
client_args = grpc_core::ChannelArgs().Set(
|
||||
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
|
||||
default_client_channel_compression_algorithm);
|
||||
server_args = grpc_core::ChannelArgs().Set(
|
||||
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
|
||||
default_server_channel_compression_algorithm);
|
||||
if (!decompress_in_core) {
|
||||
client_args =
|
||||
client_args.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
|
||||
server_args =
|
||||
server_args.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
|
||||
TestConfigurator& ServerDefaultAlgorithm(
|
||||
grpc_compression_algorithm algorithm) {
|
||||
server_args_ =
|
||||
server_args_.Set(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, algorithm);
|
||||
return *this;
|
||||
}
|
||||
auto f = begin_test(config, test_name, client_args.ToC().get(),
|
||||
server_args.ToC().get(), decompress_in_core);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
if (send_message_before_initial_metadata) {
|
||||
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = client_send_flags_bitmask;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(2), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
TestConfigurator& DecompressInApp() {
|
||||
client_args_ =
|
||||
client_args_.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
|
||||
server_args_ =
|
||||
server_args_.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
|
||||
return *this;
|
||||
}
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
if (client_init_metadata != nullptr) {
|
||||
op->data.send_initial_metadata.count = 1;
|
||||
op->data.send_initial_metadata.metadata = client_init_metadata;
|
||||
} else {
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
|
||||
TestConfigurator& ExpectedAlgorithmFromClient(
|
||||
grpc_compression_algorithm algorithm) {
|
||||
expected_algorithm_from_client_ = algorithm;
|
||||
return *this;
|
||||
}
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(100));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(100), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(grpc_core::BitCount(
|
||||
grpc_call_test_only_get_encodings_accepted_by_peer(s)) ==
|
||||
GRPC_COMPRESS_ALGORITHMS_COUNT);
|
||||
GPR_ASSERT(
|
||||
grpc_core::GetBit(grpc_call_test_only_get_encodings_accepted_by_peer(s),
|
||||
GRPC_COMPRESS_NONE) != 0);
|
||||
GPR_ASSERT(
|
||||
grpc_core::GetBit(grpc_call_test_only_get_encodings_accepted_by_peer(s),
|
||||
GRPC_COMPRESS_DEFLATE) != 0);
|
||||
GPR_ASSERT(
|
||||
grpc_core::GetBit(grpc_call_test_only_get_encodings_accepted_by_peer(s),
|
||||
GRPC_COMPRESS_GZIP) != 0);
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
if (set_server_level) {
|
||||
op->data.send_initial_metadata.maybe_compression_level.is_set = true;
|
||||
op->data.send_initial_metadata.maybe_compression_level.level =
|
||||
server_compression_level;
|
||||
TestConfigurator& ExpectedAlgorithmFromServer(
|
||||
grpc_compression_algorithm algorithm) {
|
||||
expected_algorithm_from_server_ = algorithm;
|
||||
return *this;
|
||||
}
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(101), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
|
||||
|
||||
if (i > 0 || !send_message_before_initial_metadata) {
|
||||
request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = client_send_flags_bitmask;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(2), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
void DisabledAlgorithmTest() {
|
||||
Init();
|
||||
auto c = test_.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
auto s = test_.RequestCall(101);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage(std::string(1024, 'x'))
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
test_.Expect(101, true);
|
||||
test_.Expect(1, true);
|
||||
test_.Step();
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).SendInitialMetadata({}).RecvMessage(client_message);
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
test_.Expect(102, false);
|
||||
s.NewBatch(103).RecvCloseOnServer(client_close);
|
||||
test_.Expect(103, true);
|
||||
test_.Step();
|
||||
// call was cancelled (closed) ...
|
||||
EXPECT_NE(client_close.was_cancelled(), 0);
|
||||
// with a certain error
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
// and we expect a specific reason for it
|
||||
EXPECT_EQ(server_status.message(),
|
||||
"Compression algorithm 'gzip' is disabled.");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
}
|
||||
|
||||
void RequestWithPayload(
|
||||
uint32_t client_send_flags_bitmask,
|
||||
std::initializer_list<std::pair<absl::string_view, absl::string_view>>
|
||||
client_init_metadata) {
|
||||
Init();
|
||||
auto c = test_.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata(client_init_metadata)
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test_.RequestCall(100);
|
||||
test_.Expect(100, true);
|
||||
test_.Step();
|
||||
EXPECT_TRUE(s.GetEncodingsAcceptedByPeer().all());
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(101).SendInitialMetadata({}).RecvCloseOnServer(client_close);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
c.NewBatch(2).SendMessage(std::string(1024, 'x'),
|
||||
client_send_flags_bitmask);
|
||||
test_.Expect(2, true);
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).RecvMessage(client_message);
|
||||
test_.Expect(102, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(client_message.byte_buffer_type(), GRPC_BB_RAW);
|
||||
EXPECT_EQ(client_message.payload(), std::string(1024, 'x'));
|
||||
EXPECT_EQ(client_message.compression(), expected_algorithm_from_client_);
|
||||
s.NewBatch(103).SendMessage(std::string(1024, 'y'));
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(3).RecvMessage(server_message);
|
||||
test_.Expect(103, true);
|
||||
test_.Expect(3, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(server_message.byte_buffer_type(), GRPC_BB_RAW);
|
||||
EXPECT_EQ(server_message.payload(), std::string(1024, 'y'));
|
||||
EXPECT_EQ(server_message.compression(), expected_algorithm_from_server_);
|
||||
}
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &request_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
|
||||
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, request_str));
|
||||
GPR_ASSERT(request_payload_recv->data.raw.compression ==
|
||||
(decompress_in_core ? GRPC_COMPRESS_NONE
|
||||
: expected_algorithm_from_client));
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = response_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message.recv_message = &response_payload_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(3), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(3), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW);
|
||||
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, response_str));
|
||||
if (server_compression_level > GRPC_COMPRESS_LEVEL_NONE) {
|
||||
const grpc_compression_algorithm algo_for_server_level =
|
||||
grpc_call_compression_for_level(s, server_compression_level);
|
||||
GPR_ASSERT(
|
||||
response_payload_recv->data.raw.compression ==
|
||||
(decompress_in_core ? GRPC_COMPRESS_NONE : algo_for_server_level));
|
||||
} else {
|
||||
GPR_ASSERT(response_payload_recv->data.raw.compression ==
|
||||
(decompress_in_core ? GRPC_COMPRESS_NONE
|
||||
: expected_algorithm_from_server));
|
||||
}
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(response_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
grpc_byte_buffer_destroy(response_payload_recv);
|
||||
c.NewBatch(4).SendCloseFromClient();
|
||||
s.NewBatch(104).SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test_.Expect(1, true);
|
||||
test_.Expect(4, true);
|
||||
test_.Expect(101, true);
|
||||
test_.Expect(104, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
}
|
||||
grpc_slice_unref(request_payload_slice);
|
||||
grpc_slice_unref(response_payload_slice);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(4), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
void RequestWithSendMessageBeforeInitialMetadata() {
|
||||
Init();
|
||||
auto c = test_.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
c.NewBatch(2).SendMessage(std::string(1024, 'x'));
|
||||
test_.Expect(2, true);
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test_.RequestCall(100);
|
||||
test_.Expect(100, true);
|
||||
test_.Step();
|
||||
EXPECT_TRUE(s.GetEncodingsAcceptedByPeer().all());
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(101).SendInitialMetadata({}).RecvCloseOnServer(client_close);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (i > 0) {
|
||||
c.NewBatch(2).SendMessage(std::string(1024, 'x'));
|
||||
test_.Expect(2, true);
|
||||
}
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).RecvMessage(client_message);
|
||||
test_.Expect(102, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(client_message.byte_buffer_type(), GRPC_BB_RAW);
|
||||
EXPECT_EQ(client_message.payload(), std::string(1024, 'x'));
|
||||
EXPECT_EQ(client_message.compression(), expected_algorithm_from_client_);
|
||||
s.NewBatch(103).SendMessage(std::string(1024, 'y'));
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(3).RecvMessage(server_message);
|
||||
test_.Expect(103, true);
|
||||
test_.Expect(3, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(server_message.byte_buffer_type(), GRPC_BB_RAW);
|
||||
EXPECT_EQ(server_message.payload(), std::string(1024, 'y'));
|
||||
EXPECT_EQ(server_message.compression(), expected_algorithm_from_server_);
|
||||
}
|
||||
c.NewBatch(4).SendCloseFromClient();
|
||||
s.NewBatch(104).SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test_.Expect(1, true);
|
||||
test_.Expect(4, true);
|
||||
test_.Expect(101, true);
|
||||
test_.Expect(104, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_OK;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(104), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
void RequestWithServerLevel(grpc_compression_level server_compression_level) {
|
||||
Init();
|
||||
auto c = test_.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test_.RequestCall(100);
|
||||
test_.Expect(100, true);
|
||||
test_.Step();
|
||||
EXPECT_TRUE(s.GetEncodingsAcceptedByPeer().all());
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(101)
|
||||
.SendInitialMetadata({}, 0, server_compression_level)
|
||||
.RecvCloseOnServer(client_close);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
c.NewBatch(2).SendMessage(std::string(1024, 'x'));
|
||||
test_.Expect(2, true);
|
||||
CoreEnd2endTest::IncomingMessage client_message;
|
||||
s.NewBatch(102).RecvMessage(client_message);
|
||||
test_.Expect(102, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(client_message.byte_buffer_type(), GRPC_BB_RAW);
|
||||
EXPECT_EQ(client_message.payload(), std::string(1024, 'x'));
|
||||
EXPECT_EQ(client_message.compression(), expected_algorithm_from_client_);
|
||||
s.NewBatch(103).SendMessage(std::string(1024, 'y'));
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(3).RecvMessage(server_message);
|
||||
test_.Expect(103, true);
|
||||
test_.Expect(3, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(server_message.byte_buffer_type(), GRPC_BB_RAW);
|
||||
EXPECT_EQ(server_message.payload(), std::string(1024, 'y'));
|
||||
EXPECT_EQ(server_message.compression(), expected_algorithm_from_server_);
|
||||
}
|
||||
c.NewBatch(4).SendCloseFromClient();
|
||||
s.NewBatch(104).SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test_.Expect(1, true);
|
||||
test_.Expect(4, true);
|
||||
test_.Expect(101, true);
|
||||
test_.Expect(104, true);
|
||||
test_.Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(4), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(104), true);
|
||||
cqv.Verify();
|
||||
private:
|
||||
void Init() {
|
||||
test_.InitClient(client_args_);
|
||||
test_.InitServer(server_args_);
|
||||
}
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_OK);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
CoreEnd2endTest& test_;
|
||||
ChannelArgs client_args_ = ChannelArgs().Set(
|
||||
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, GRPC_COMPRESS_NONE);
|
||||
ChannelArgs server_args_ = ChannelArgs().Set(
|
||||
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, GRPC_COMPRESS_NONE);
|
||||
grpc_compression_algorithm expected_algorithm_from_client_ =
|
||||
GRPC_COMPRESS_NONE;
|
||||
grpc_compression_algorithm expected_algorithm_from_server_ =
|
||||
GRPC_COMPRESS_NONE;
|
||||
};
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
TEST_P(Http2SingleHopTest, DisabledAlgorithmDecompressInCore) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.DisableAlgorithmAtServer(GRPC_COMPRESS_GZIP)
|
||||
.DisabledAlgorithmTest();
|
||||
}
|
||||
|
||||
static void request_with_payload_template(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
uint32_t client_send_flags_bitmask,
|
||||
grpc_compression_algorithm default_client_channel_compression_algorithm,
|
||||
grpc_compression_algorithm default_server_channel_compression_algorithm,
|
||||
grpc_compression_algorithm expected_algorithm_from_client,
|
||||
grpc_compression_algorithm expected_algorithm_from_server,
|
||||
grpc_metadata* client_init_metadata, bool set_server_level,
|
||||
grpc_compression_level server_compression_level,
|
||||
bool send_message_before_initial_metadata) {
|
||||
request_with_payload_template_inner(
|
||||
config, test_name, client_send_flags_bitmask,
|
||||
default_client_channel_compression_algorithm,
|
||||
default_server_channel_compression_algorithm,
|
||||
expected_algorithm_from_client, expected_algorithm_from_server,
|
||||
client_init_metadata, set_server_level, server_compression_level,
|
||||
send_message_before_initial_metadata, false);
|
||||
request_with_payload_template_inner(
|
||||
config, test_name, client_send_flags_bitmask,
|
||||
default_client_channel_compression_algorithm,
|
||||
default_server_channel_compression_algorithm,
|
||||
expected_algorithm_from_client, expected_algorithm_from_server,
|
||||
client_init_metadata, set_server_level, server_compression_level,
|
||||
send_message_before_initial_metadata, true);
|
||||
TEST_P(Http2SingleHopTest, DisabledAlgorithmDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.DisableAlgorithmAtServer(GRPC_COMPRESS_GZIP)
|
||||
.DecompressInApp()
|
||||
.DisabledAlgorithmTest();
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_exceptionally_uncompressed_payload(
|
||||
const CoreTestConfiguration& config) {
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_exceptionally_uncompressed_payload",
|
||||
GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
|
||||
GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, nullptr, false,
|
||||
/* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
|
||||
TEST_P(Http2SingleHopTest,
|
||||
RequestWithExceptionallyUncompressedPayloadDecompressInCore) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithPayload(GRPC_WRITE_NO_COMPRESS, {});
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_uncompressed_payload(
|
||||
const CoreTestConfiguration& config) {
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_uncompressed_payload", 0,
|
||||
GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
|
||||
GRPC_COMPRESS_NONE, nullptr, false,
|
||||
/* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
|
||||
TEST_P(Http2SingleHopTest,
|
||||
RequestWithExceptionallyUncompressedPayloadDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.DecompressInApp()
|
||||
.ExpectedAlgorithmFromServer(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithPayload(GRPC_WRITE_NO_COMPRESS, {});
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_compressed_payload(
|
||||
const CoreTestConfiguration& config) {
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_compressed_payload", 0,
|
||||
GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
|
||||
GRPC_COMPRESS_GZIP, nullptr, false,
|
||||
/* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
|
||||
TEST_P(Http2SingleHopTest, RequestWithUncompressedPayloadDecompressInCore) {
|
||||
TestConfigurator(*this).RequestWithPayload(0, {});
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_send_message_before_initial_metadata(
|
||||
const CoreTestConfiguration& config) {
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_compressed_payload", 0,
|
||||
GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
|
||||
GRPC_COMPRESS_GZIP, nullptr, false,
|
||||
/* ignored */ GRPC_COMPRESS_LEVEL_NONE, true);
|
||||
TEST_P(Http2SingleHopTest, RequestWithUncompressedPayloadDecompressInApp) {
|
||||
TestConfigurator(*this).DecompressInApp().RequestWithPayload(0, {});
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_server_level(
|
||||
const CoreTestConfiguration& config) {
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
|
||||
GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
|
||||
nullptr, true, GRPC_COMPRESS_LEVEL_HIGH, false);
|
||||
TEST_P(Http2SingleHopTest, RequestWithCompressedPayloadDecompressInCore) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithPayload(0, {});
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_compressed_payload_md_override(
|
||||
const CoreTestConfiguration& config) {
|
||||
grpc_metadata gzip_compression_override;
|
||||
grpc_metadata identity_compression_override;
|
||||
|
||||
gzip_compression_override.key =
|
||||
grpc_slice_from_static_string("grpc-internal-encoding-request");
|
||||
gzip_compression_override.value = grpc_slice_from_static_string("gzip");
|
||||
memset(&gzip_compression_override.internal_data, 0,
|
||||
sizeof(gzip_compression_override.internal_data));
|
||||
|
||||
identity_compression_override.key =
|
||||
grpc_slice_from_static_string("grpc-internal-encoding-request");
|
||||
identity_compression_override.value =
|
||||
grpc_slice_from_static_string("identity");
|
||||
memset(&identity_compression_override.internal_data, 0,
|
||||
sizeof(identity_compression_override.internal_data));
|
||||
|
||||
// Channel default NONE (aka IDENTITY), call override to GZIP
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
|
||||
GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
|
||||
GRPC_COMPRESS_NONE, &gzip_compression_override, false,
|
||||
/*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
|
||||
|
||||
// Channel default DEFLATE, call override to GZIP
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_compressed_payload_md_override_2", 0,
|
||||
GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
|
||||
GRPC_COMPRESS_NONE, &gzip_compression_override, false,
|
||||
/*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
|
||||
|
||||
// Channel default DEFLATE, call override to NONE (aka IDENTITY)
|
||||
request_with_payload_template(
|
||||
config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
|
||||
GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
|
||||
GRPC_COMPRESS_NONE, &identity_compression_override, false,
|
||||
/*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
|
||||
TEST_P(Http2SingleHopTest, RequestWithCompressedPayloadDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.DecompressInApp()
|
||||
.ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
|
||||
.ExpectedAlgorithmFromServer(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithPayload(0, {});
|
||||
}
|
||||
|
||||
static void test_invoke_request_with_disabled_algorithm(
|
||||
const CoreTestConfiguration& config) {
|
||||
request_for_disabled_algorithm(config,
|
||||
"test_invoke_request_with_disabled_algorithm",
|
||||
0, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
|
||||
GRPC_STATUS_UNIMPLEMENTED, nullptr, false);
|
||||
request_for_disabled_algorithm(config,
|
||||
"test_invoke_request_with_disabled_algorithm",
|
||||
0, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
|
||||
GRPC_STATUS_UNIMPLEMENTED, nullptr, true);
|
||||
TEST_P(Http2SingleHopTest,
|
||||
RequestWithSendMessageBeforeInitialMetadataDecompressInCore) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithSendMessageBeforeInitialMetadata();
|
||||
}
|
||||
|
||||
void compressed_payload(const CoreTestConfiguration& config) {
|
||||
test_invoke_request_with_exceptionally_uncompressed_payload(config);
|
||||
test_invoke_request_with_uncompressed_payload(config);
|
||||
test_invoke_request_with_compressed_payload(config);
|
||||
test_invoke_request_with_send_message_before_initial_metadata(config);
|
||||
test_invoke_request_with_server_level(config);
|
||||
test_invoke_request_with_compressed_payload_md_override(config);
|
||||
test_invoke_request_with_disabled_algorithm(config);
|
||||
TEST_P(Http2SingleHopTest,
|
||||
RequestWithSendMessageBeforeInitialMetadataDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
|
||||
.DecompressInApp()
|
||||
.ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
|
||||
.ExpectedAlgorithmFromServer(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithSendMessageBeforeInitialMetadata();
|
||||
}
|
||||
|
||||
void compressed_payload_pre_init(void) {}
|
||||
TEST_P(Http2SingleHopTest, RequestWithServerLevelDecompressInCore) {
|
||||
TestConfigurator(*this).RequestWithServerLevel(GRPC_COMPRESS_LEVEL_HIGH);
|
||||
}
|
||||
|
||||
TEST_P(Http2SingleHopTest, RequestWithServerLevelDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.DecompressInApp()
|
||||
.ExpectedAlgorithmFromServer(GRPC_COMPRESS_DEFLATE)
|
||||
.RequestWithServerLevel(GRPC_COMPRESS_LEVEL_HIGH);
|
||||
}
|
||||
|
||||
TEST_P(Http2SingleHopTest,
|
||||
RequestWithCompressedPayloadMetadataOverrideNoneToGzipDecompressInCore) {
|
||||
TestConfigurator(*this).RequestWithPayload(
|
||||
0, {{"grpc-internal-encoding-request", "gzip"}});
|
||||
}
|
||||
|
||||
TEST_P(Http2SingleHopTest,
|
||||
RequestWithCompressedPayloadMetadataOverrideNoneToGzipDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.DecompressInApp()
|
||||
.ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithPayload(0, {{"grpc-internal-encoding-request", "gzip"}});
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
Http2SingleHopTest,
|
||||
RequestWithCompressedPayloadMetadataOverrideDeflateToGzipDecompressInCore) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
|
||||
.RequestWithPayload(0, {{"grpc-internal-encoding-request", "gzip"}});
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
Http2SingleHopTest,
|
||||
RequestWithCompressedPayloadMetadataOverrideDeflateToGzipDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
|
||||
.DecompressInApp()
|
||||
.ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
|
||||
.RequestWithPayload(0, {{"grpc-internal-encoding-request", "gzip"}});
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
Http2SingleHopTest,
|
||||
RequestWithCompressedPayloadMetadataOverrideDeflateToIdentityDecompressInCore) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
|
||||
.RequestWithPayload(0, {{"grpc-internal-encoding-request", "identity"}});
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
Http2SingleHopTest,
|
||||
RequestWithCompressedPayloadMetadataOverrideDeflateToIdentityDecompressInApp) {
|
||||
TestConfigurator(*this)
|
||||
.ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
|
||||
.DecompressInApp()
|
||||
.RequestWithPayload(0, {{"grpc-internal-encoding-request", "identity"}});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,213 +16,73 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/sync.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/gprpp/thd.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
typedef struct {
|
||||
gpr_event started;
|
||||
grpc_channel* channel;
|
||||
grpc_completion_queue* cq;
|
||||
} child_events;
|
||||
|
||||
struct CallbackContext {
|
||||
grpc_completion_queue_functor functor;
|
||||
gpr_event finished;
|
||||
explicit CallbackContext(void (*cb)(grpc_completion_queue_functor* functor,
|
||||
int success)) {
|
||||
functor.functor_run = cb;
|
||||
functor.inlineable = false;
|
||||
gpr_event_init(&finished);
|
||||
}
|
||||
};
|
||||
|
||||
static void child_thread(void* arg) {
|
||||
child_events* ce = static_cast<child_events*>(arg);
|
||||
grpc_event ev;
|
||||
gpr_event_set(&ce->started, reinterpret_cast<void*>(1));
|
||||
gpr_log(GPR_DEBUG, "verifying");
|
||||
ev = grpc_completion_queue_next(ce->cq, gpr_inf_future(GPR_CLOCK_MONOTONIC),
|
||||
nullptr);
|
||||
GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
|
||||
GPR_ASSERT(ev.tag == grpc_core::CqVerifier::tag(1));
|
||||
GPR_ASSERT(ev.success == 0);
|
||||
}
|
||||
|
||||
static void test_connectivity(const CoreTestConfiguration& config) {
|
||||
auto f =
|
||||
config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs());
|
||||
grpc_connectivity_state state;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
child_events ce;
|
||||
|
||||
auto client_args = grpc_core::ChannelArgs()
|
||||
.Set(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000)
|
||||
.Set(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 1000)
|
||||
.Set(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 5000);
|
||||
|
||||
f->InitClient(client_args);
|
||||
|
||||
ce.channel = f->client();
|
||||
ce.cq = f->cq();
|
||||
gpr_event_init(&ce.started);
|
||||
grpc_core::Thread thd("grpc_connectivity", child_thread, &ce);
|
||||
thd.Start();
|
||||
|
||||
gpr_event_wait(&ce.started, gpr_inf_future(GPR_CLOCK_MONOTONIC));
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
TEST_P(RetryHttp2Test, ConnectivityWatch) {
|
||||
InitClient(ChannelArgs()
|
||||
.Set(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000)
|
||||
.Set(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 1000)
|
||||
.Set(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 5000));
|
||||
// channels should start life in IDLE, and stay there
|
||||
GPR_ASSERT(grpc_channel_check_connectivity_state(f->client(), 0) ==
|
||||
GRPC_CHANNEL_IDLE);
|
||||
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
|
||||
GPR_ASSERT(grpc_channel_check_connectivity_state(f->client(), 0) ==
|
||||
GRPC_CHANNEL_IDLE);
|
||||
|
||||
EXPECT_EQ(CheckConnectivityState(false), GRPC_CHANNEL_IDLE);
|
||||
Step(Duration::Milliseconds(100));
|
||||
EXPECT_EQ(CheckConnectivityState(false), GRPC_CHANNEL_IDLE);
|
||||
// start watching for a change
|
||||
gpr_log(GPR_DEBUG, "watching");
|
||||
grpc_channel_watch_connectivity_state(f->client(), GRPC_CHANNEL_IDLE,
|
||||
gpr_now(GPR_CLOCK_MONOTONIC), f->cq(),
|
||||
grpc_core::CqVerifier::tag(1));
|
||||
|
||||
// eventually the child thread completion should trigger
|
||||
thd.Join();
|
||||
|
||||
WatchConnectivityState(GRPC_CHANNEL_IDLE, Duration::Milliseconds(500), 1);
|
||||
Expect(1, false);
|
||||
Step(Duration::Minutes(1));
|
||||
// check that we're still in idle, and start connecting
|
||||
GPR_ASSERT(grpc_channel_check_connectivity_state(f->client(), 1) ==
|
||||
GRPC_CHANNEL_IDLE);
|
||||
EXPECT_EQ(CheckConnectivityState(true), GRPC_CHANNEL_IDLE);
|
||||
// start watching for a change
|
||||
grpc_channel_watch_connectivity_state(f->client(), GRPC_CHANNEL_IDLE,
|
||||
grpc_timeout_seconds_to_deadline(10),
|
||||
f->cq(), grpc_core::CqVerifier::tag(2));
|
||||
|
||||
WatchConnectivityState(GRPC_CHANNEL_IDLE, Duration::Seconds(10), 2);
|
||||
// and now the watch should trigger
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
cqv.Verify();
|
||||
state = grpc_channel_check_connectivity_state(f->client(), 0);
|
||||
GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
|
||||
state == GRPC_CHANNEL_CONNECTING);
|
||||
|
||||
Expect(2, true);
|
||||
Step();
|
||||
grpc_connectivity_state state = CheckConnectivityState(false);
|
||||
EXPECT_THAT(state, ::testing::AnyOf(GRPC_CHANNEL_TRANSIENT_FAILURE,
|
||||
GRPC_CHANNEL_CONNECTING));
|
||||
// quickly followed by a transition to TRANSIENT_FAILURE
|
||||
grpc_channel_watch_connectivity_state(f->client(), GRPC_CHANNEL_CONNECTING,
|
||||
grpc_timeout_seconds_to_deadline(10),
|
||||
f->cq(), grpc_core::CqVerifier::tag(3));
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(3), true);
|
||||
cqv.Verify();
|
||||
state = grpc_channel_check_connectivity_state(f->client(), 0);
|
||||
GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
|
||||
state == GRPC_CHANNEL_CONNECTING);
|
||||
|
||||
gpr_log(GPR_DEBUG, "*** STARTING SERVER ***");
|
||||
|
||||
WatchConnectivityState(GRPC_CHANNEL_CONNECTING, Duration::Seconds(10), 3);
|
||||
Expect(3, true);
|
||||
Step();
|
||||
state = CheckConnectivityState(false);
|
||||
EXPECT_THAT(state, ::testing::AnyOf(GRPC_CHANNEL_TRANSIENT_FAILURE,
|
||||
GRPC_CHANNEL_CONNECTING));
|
||||
// now let's bring up a server to connect to
|
||||
f->InitServer(grpc_core::ChannelArgs());
|
||||
|
||||
gpr_log(GPR_DEBUG, "*** STARTED SERVER ***");
|
||||
|
||||
InitServer(ChannelArgs());
|
||||
// we'll go through some set of transitions (some might be missed), until
|
||||
// READY is reached
|
||||
while (state != GRPC_CHANNEL_READY) {
|
||||
grpc_channel_watch_connectivity_state(
|
||||
f->client(), state, grpc_timeout_seconds_to_deadline(10), f->cq(),
|
||||
grpc_core::CqVerifier::tag(4));
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(4), true);
|
||||
cqv.Verify(grpc_core::Duration::Seconds(20));
|
||||
state = grpc_channel_check_connectivity_state(f->client(), 0);
|
||||
GPR_ASSERT(state == GRPC_CHANNEL_READY ||
|
||||
state == GRPC_CHANNEL_CONNECTING ||
|
||||
state == GRPC_CHANNEL_TRANSIENT_FAILURE);
|
||||
WatchConnectivityState(state, Duration::Seconds(10), 4);
|
||||
Expect(4, true);
|
||||
Step(Duration::Seconds(20));
|
||||
state = CheckConnectivityState(false);
|
||||
EXPECT_THAT(state,
|
||||
::testing::AnyOf(GRPC_CHANNEL_TRANSIENT_FAILURE,
|
||||
GRPC_CHANNEL_CONNECTING, GRPC_CHANNEL_READY));
|
||||
}
|
||||
|
||||
// bring down the server again
|
||||
// we should go immediately to TRANSIENT_FAILURE
|
||||
gpr_log(GPR_DEBUG, "*** SHUTTING DOWN SERVER ***");
|
||||
|
||||
grpc_channel_watch_connectivity_state(f->client(), GRPC_CHANNEL_READY,
|
||||
grpc_timeout_seconds_to_deadline(10),
|
||||
f->cq(), grpc_core::CqVerifier::tag(5));
|
||||
|
||||
grpc_server_shutdown_and_notify(f->server(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(0xdead));
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(5), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(0xdead), true);
|
||||
cqv.Verify();
|
||||
state = grpc_channel_check_connectivity_state(f->client(), 0);
|
||||
GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
|
||||
state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_IDLE);
|
||||
WatchConnectivityState(GRPC_CHANNEL_READY, Duration::Seconds(10), 5);
|
||||
ShutdownServerAndNotify(1000);
|
||||
Expect(5, true);
|
||||
Expect(1000, true);
|
||||
Step();
|
||||
state = CheckConnectivityState(false);
|
||||
EXPECT_THAT(state,
|
||||
::testing::AnyOf(GRPC_CHANNEL_TRANSIENT_FAILURE,
|
||||
GRPC_CHANNEL_CONNECTING, GRPC_CHANNEL_IDLE));
|
||||
}
|
||||
|
||||
static void cb_watch_connectivity(grpc_completion_queue_functor* functor,
|
||||
int success) {
|
||||
CallbackContext* cb_ctx = reinterpret_cast<CallbackContext*>(functor);
|
||||
|
||||
gpr_log(GPR_DEBUG, "cb_watch_connectivity called, verifying");
|
||||
|
||||
// callback must not have errors
|
||||
GPR_ASSERT(success != 0);
|
||||
|
||||
gpr_event_set(&cb_ctx->finished, reinterpret_cast<void*>(1));
|
||||
}
|
||||
|
||||
static void cb_shutdown(grpc_completion_queue_functor* functor,
|
||||
int /*success*/) {
|
||||
CallbackContext* cb_ctx = reinterpret_cast<CallbackContext*>(functor);
|
||||
|
||||
gpr_log(GPR_DEBUG, "cb_shutdown called, nothing to do");
|
||||
gpr_event_set(&cb_ctx->finished, reinterpret_cast<void*>(1));
|
||||
}
|
||||
|
||||
static void test_watch_connectivity_cq_callback(
|
||||
const CoreTestConfiguration& config) {
|
||||
CallbackContext cb_ctx(cb_watch_connectivity);
|
||||
CallbackContext cb_shutdown_ctx(cb_shutdown);
|
||||
grpc_completion_queue* cq;
|
||||
auto f =
|
||||
config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs());
|
||||
|
||||
f->InitClient(grpc_core::ChannelArgs());
|
||||
|
||||
// start connecting
|
||||
grpc_channel_check_connectivity_state(f->client(), 1);
|
||||
|
||||
// create the cq callback
|
||||
cq = grpc_completion_queue_create_for_callback(&cb_shutdown_ctx.functor,
|
||||
nullptr);
|
||||
|
||||
// start watching for any change, cb is immediately called
|
||||
// and no dead lock should be raised
|
||||
grpc_channel_watch_connectivity_state(f->client(), GRPC_CHANNEL_IDLE,
|
||||
grpc_timeout_seconds_to_deadline(3), cq,
|
||||
&cb_ctx.functor);
|
||||
|
||||
// we just check that the callback was executed once notifying a connection
|
||||
// transition
|
||||
GPR_ASSERT(gpr_event_wait(&cb_ctx.finished,
|
||||
gpr_inf_future(GPR_CLOCK_MONOTONIC)) != nullptr);
|
||||
|
||||
// shutdown, since shutdown cb might be executed in a background thread
|
||||
// we actively wait till is executed.
|
||||
grpc_completion_queue_shutdown(cq);
|
||||
gpr_event_wait(&cb_shutdown_ctx.finished,
|
||||
gpr_inf_future(GPR_CLOCK_MONOTONIC));
|
||||
grpc_completion_queue_destroy(cq);
|
||||
}
|
||||
|
||||
void connectivity(const CoreTestConfiguration& config) {
|
||||
GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
|
||||
test_connectivity(config);
|
||||
test_watch_connectivity_cq_callback(config);
|
||||
}
|
||||
|
||||
void connectivity_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,164 +16,55 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "absl/types/optional.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
return f;
|
||||
}
|
||||
using testing::AnyOf;
|
||||
using testing::StartsWith;
|
||||
|
||||
static void test_invoke_simple_request(const CoreTestConfiguration& config) {
|
||||
auto f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
char* peer;
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
peer = grpc_call_get_peer(c);
|
||||
GPR_ASSERT(peer != nullptr);
|
||||
gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
|
||||
gpr_free(peer);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
peer = grpc_call_get_peer(s);
|
||||
GPR_ASSERT(peer != nullptr);
|
||||
gpr_log(GPR_DEBUG, "server_peer=%s", peer);
|
||||
gpr_free(peer);
|
||||
peer = grpc_call_get_peer(c);
|
||||
GPR_ASSERT(peer != nullptr);
|
||||
gpr_log(GPR_DEBUG, "client_peer=%s", peer);
|
||||
gpr_free(peer);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(error == GRPC_CALL_OK);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
|
||||
if (config.overridden_call_host != nullptr) {
|
||||
validate_host_override_string(config.overridden_call_host,
|
||||
call_details.host, config);
|
||||
TEST_P(CoreClientChannelTest, DefaultHost) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
EXPECT_NE(c.GetPeer(), absl::nullopt);
|
||||
IncomingStatusOnClient server_status;
|
||||
IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(101, true);
|
||||
Step();
|
||||
EXPECT_NE(s.GetPeer(), absl::nullopt);
|
||||
EXPECT_NE(c.GetPeer(), absl::nullopt);
|
||||
IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
Expect(102, true);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
if (GetParam()->overridden_call_host != nullptr) {
|
||||
EXPECT_EQ(GetParam()->overridden_call_host, s.host());
|
||||
} else {
|
||||
GPR_ASSERT(grpc_slice_buf_start_eq(call_details.host, "localhost", 9) ||
|
||||
grpc_slice_buf_start_eq(call_details.host, "127.0.0.1", 9));
|
||||
EXPECT_THAT(s.host(), AnyOf(StartsWith("localhost"),
|
||||
StartsWith("127.0.0.1"), StartsWith("[::1]")));
|
||||
}
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
void default_host(const CoreTestConfiguration& config) {
|
||||
test_invoke_simple_request(config);
|
||||
}
|
||||
|
||||
void default_host_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,117 +16,41 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static void do_request_and_shutdown_server(
|
||||
const CoreTestConfiguration& /*config*/, CoreTestFixture* f,
|
||||
grpc_core::CqVerifier& cqv) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
#ifndef GPR_WINDOWS // b/148110727 for more details
|
||||
namespace grpc_core {
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
// should be able to shut down the server early
|
||||
// - and still complete the request
|
||||
grpc_server_shutdown_and_notify(f->server(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(1000));
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1000), true);
|
||||
cqv.Verify();
|
||||
static void OneRequestAndShutdownServer(CoreEnd2endTest& test) {
|
||||
auto c = test.NewClientCall("/service/method")
|
||||
.Timeout(Duration::Seconds(5))
|
||||
.Create();
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_md;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_md)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = test.RequestCall(101);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
test.ShutdownServerAndNotify(1000);
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_closed;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_closed);
|
||||
test.Expect(102, true);
|
||||
test.Expect(1, true);
|
||||
test.Expect(1000, true);
|
||||
test.Step();
|
||||
// Please refer https://github.com/grpc/grpc/issues/21221 for additional
|
||||
// details.
|
||||
// TODO(yashykt@) - The following line should be removeable after C-Core
|
||||
|
|
@ -134,47 +58,19 @@ static void do_request_and_shutdown_server(
|
|||
// test remains flaky even after this, an alternative fix would be to send a
|
||||
// request when the server is in the shut down state.
|
||||
//
|
||||
cqv.VerifyEmpty();
|
||||
test.Step();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/service/method");
|
||||
EXPECT_FALSE(client_closed.was_cancelled());
|
||||
}
|
||||
|
||||
static void disappearing_server_test(const CoreTestConfiguration& config) {
|
||||
auto f =
|
||||
config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs());
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", "disappearing_server_test",
|
||||
config.name);
|
||||
|
||||
f->InitClient(grpc_core::ChannelArgs());
|
||||
f->InitServer(grpc_core::ChannelArgs());
|
||||
|
||||
do_request_and_shutdown_server(config, f.get(), cqv);
|
||||
|
||||
// now destroy and recreate the server
|
||||
f->InitServer(grpc_core::ChannelArgs());
|
||||
|
||||
do_request_and_shutdown_server(config, f.get(), cqv);
|
||||
TEST_P(CoreClientChannelTest, DisappearingServer) {
|
||||
OneRequestAndShutdownServer(*this);
|
||||
InitServer(ChannelArgs());
|
||||
OneRequestAndShutdownServer(*this);
|
||||
}
|
||||
|
||||
void disappearing_server(const CoreTestConfiguration& config) {
|
||||
GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
|
||||
#ifndef GPR_WINDOWS // b/148110727 for more details
|
||||
disappearing_server_test(config);
|
||||
} // namespace grpc_core
|
||||
#endif // GPR_WINDOWS
|
||||
}
|
||||
|
||||
void disappearing_server_pre_init(void) {}
|
||||
|
|
|
|||
|
|
@ -16,60 +16,17 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
namespace grpc_core {
|
||||
|
||||
TEST_P(CoreEnd2endTest, EmptyBatch) {
|
||||
auto c = NewClientCall("/service/method").Create();
|
||||
c.NewBatch(1);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
}
|
||||
|
||||
static void empty_batch_body(const CoreTestConfiguration& /*config*/,
|
||||
CoreTestFixture* f) {
|
||||
grpc_call* c;
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_call_error error;
|
||||
grpc_op* op = nullptr;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
error =
|
||||
grpc_call_start_batch(c, op, 0, grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
grpc_call_unref(c);
|
||||
}
|
||||
|
||||
static void test_invoke_empty_body(const CoreTestConfiguration& config) {
|
||||
auto f = begin_test(config, "test_invoke_empty_body", nullptr, nullptr);
|
||||
empty_batch_body(config, f.get());
|
||||
}
|
||||
|
||||
void empty_batch(const CoreTestConfiguration& config) {
|
||||
test_invoke_empty_body(config);
|
||||
}
|
||||
|
||||
void empty_batch_pre_init(void) {}
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -17,137 +17,27 @@
|
|||
//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/channel_stack_builder.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/gprpp/debug_location.h"
|
||||
#include "src/core/lib/gprpp/status_helper.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/iomgr/closure.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
// Simple request via a server filter that always closes the stream.
|
||||
static void test_request(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
auto f = begin_test(config, "filter_causes_close", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
|
||||
GPR_ASSERT(0 ==
|
||||
grpc_slice_str_cmp(details, "Failure that's not preventable."));
|
||||
|
||||
f->ShutdownServer();
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
}
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
//******************************************************************************
|
||||
// Test filter - always closes incoming requests
|
||||
|
|
@ -161,19 +51,19 @@ typedef struct {
|
|||
uint8_t unused;
|
||||
} channel_data;
|
||||
|
||||
static void recv_im_ready(void* arg, grpc_error_handle error) {
|
||||
void recv_im_ready(void* arg, grpc_error_handle error) {
|
||||
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
|
||||
call_data* calld = static_cast<call_data*>(elem->call_data);
|
||||
grpc_core::Closure::Run(
|
||||
Closure::Run(
|
||||
DEBUG_LOCATION, calld->recv_im_ready,
|
||||
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING(
|
||||
"Failure that's not preventable.", &error, 1),
|
||||
grpc_core::StatusIntProperty::kRpcStatus,
|
||||
StatusIntProperty::kRpcStatus,
|
||||
GRPC_STATUS_PERMISSION_DENIED));
|
||||
}
|
||||
|
||||
static void start_transport_stream_op_batch(
|
||||
grpc_call_element* elem, grpc_transport_stream_op_batch* op) {
|
||||
void start_transport_stream_op_batch(grpc_call_element* elem,
|
||||
grpc_transport_stream_op_batch* op) {
|
||||
call_data* calld = static_cast<call_data*>(elem->call_data);
|
||||
if (op->recv_initial_metadata) {
|
||||
calld->recv_im_ready =
|
||||
|
|
@ -184,23 +74,23 @@ static void start_transport_stream_op_batch(
|
|||
grpc_call_next_op(elem, op);
|
||||
}
|
||||
|
||||
static grpc_error_handle init_call_elem(
|
||||
grpc_call_element* /*elem*/, const grpc_call_element_args* /*args*/) {
|
||||
grpc_error_handle init_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_element_args* /*args*/) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* /*final_info*/,
|
||||
grpc_closure* /*ignored*/) {}
|
||||
void destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* /*final_info*/,
|
||||
grpc_closure* /*ignored*/) {}
|
||||
|
||||
static grpc_error_handle init_channel_elem(
|
||||
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
|
||||
grpc_error_handle init_channel_elem(grpc_channel_element* /*elem*/,
|
||||
grpc_channel_element_args* /*args*/) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
|
||||
static const grpc_channel_filter test_filter = {
|
||||
const grpc_channel_filter test_filter = {
|
||||
start_transport_stream_op_batch,
|
||||
nullptr,
|
||||
grpc_channel_next_op,
|
||||
|
|
@ -215,22 +105,29 @@ static const grpc_channel_filter test_filter = {
|
|||
grpc_channel_next_get_info,
|
||||
"filter_causes_close"};
|
||||
|
||||
//******************************************************************************
|
||||
// Registration
|
||||
//
|
||||
TEST_P(CoreEnd2endTest, FilterCausesClose) {
|
||||
CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
GRPC_SERVER_CHANNEL, 0, [](ChannelStackBuilder* builder) {
|
||||
builder->PrependFilter(&test_filter);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("foo")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
|
||||
void filter_causes_close(const CoreTestConfiguration& config) {
|
||||
grpc_core::CoreConfiguration::RunWithSpecialConfiguration(
|
||||
[](grpc_core::CoreConfiguration::Builder* builder) {
|
||||
grpc_core::BuildCoreConfiguration(builder);
|
||||
builder->channel_init()->RegisterStage(
|
||||
GRPC_SERVER_CHANNEL, 0,
|
||||
[](grpc_core::ChannelStackBuilder* builder) {
|
||||
builder->PrependFilter(&test_filter);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
[config] { test_request(config); });
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_PERMISSION_DENIED);
|
||||
EXPECT_EQ(server_status.message(), "Failure that's not preventable.");
|
||||
}
|
||||
|
||||
void filter_causes_close_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -17,169 +17,31 @@
|
|||
//
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/channel_stack_builder.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/iomgr/closure.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
enum { TIMEOUT = 200000 };
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
// Simple request to test that filters see a consistent view of the
|
||||
// call context.
|
||||
static void test_request(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
auto f = begin_test(config, "filter_context", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_string = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_string;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(s);
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
}
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
//******************************************************************************
|
||||
// Test context filter
|
||||
|
|
@ -189,16 +51,16 @@ struct call_data {
|
|||
grpc_call_context_element* context;
|
||||
};
|
||||
|
||||
static grpc_error_handle init_call_elem(grpc_call_element* elem,
|
||||
const grpc_call_element_args* args) {
|
||||
grpc_error_handle init_call_elem(grpc_call_element* elem,
|
||||
const grpc_call_element_args* args) {
|
||||
call_data* calld = static_cast<call_data*>(elem->call_data);
|
||||
calld->context = args->context;
|
||||
gpr_log(GPR_INFO, "init_call_elem(): context=%p", args->context);
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void start_transport_stream_op_batch(
|
||||
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
|
||||
void start_transport_stream_op_batch(grpc_call_element* elem,
|
||||
grpc_transport_stream_op_batch* batch) {
|
||||
call_data* calld = static_cast<call_data*>(elem->call_data);
|
||||
// If batch payload context is not null (which will happen in some
|
||||
// cancellation cases), make sure we get the same context here that we
|
||||
|
|
@ -211,18 +73,18 @@ static void start_transport_stream_op_batch(
|
|||
grpc_call_next_op(elem, batch);
|
||||
}
|
||||
|
||||
static void destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* /*final_info*/,
|
||||
grpc_closure* /*ignored*/) {}
|
||||
void destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* /*final_info*/,
|
||||
grpc_closure* /*ignored*/) {}
|
||||
|
||||
static grpc_error_handle init_channel_elem(
|
||||
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
|
||||
grpc_error_handle init_channel_elem(grpc_channel_element* /*elem*/,
|
||||
grpc_channel_element_args* /*args*/) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
|
||||
static const grpc_channel_filter test_filter = {
|
||||
const grpc_channel_filter test_filter = {
|
||||
start_transport_stream_op_batch,
|
||||
nullptr,
|
||||
grpc_channel_next_op,
|
||||
|
|
@ -237,31 +99,49 @@ static const grpc_channel_filter test_filter = {
|
|||
grpc_channel_next_get_info,
|
||||
"filter_context"};
|
||||
|
||||
//******************************************************************************
|
||||
// Registration
|
||||
//
|
||||
|
||||
void filter_context(const CoreTestConfiguration& config) {
|
||||
grpc_core::CoreConfiguration::RunWithSpecialConfiguration(
|
||||
[](grpc_core::CoreConfiguration::Builder* builder) {
|
||||
grpc_core::BuildCoreConfiguration(builder);
|
||||
for (auto type : {GRPC_CLIENT_CHANNEL, GRPC_CLIENT_SUBCHANNEL,
|
||||
GRPC_CLIENT_DIRECT_CHANNEL, GRPC_SERVER_CHANNEL}) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
type, INT_MAX, [](grpc_core::ChannelStackBuilder* builder) {
|
||||
// Want to add the filter as close to the end as possible, to
|
||||
// make sure that all of the filters work well together.
|
||||
// However, we can't add it at the very end, because the
|
||||
// connected channel filter must be the last one. So we add it
|
||||
// right before the last one.
|
||||
auto it = builder->mutable_stack()->end();
|
||||
--it;
|
||||
builder->mutable_stack()->insert(it, &test_filter);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
},
|
||||
[config] { test_request(config); });
|
||||
// Simple request to test that filters see a consistent view of the
|
||||
// call context.
|
||||
TEST_P(CoreEnd2endTest, FilterContext) {
|
||||
CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) {
|
||||
for (auto type : {GRPC_CLIENT_CHANNEL, GRPC_CLIENT_SUBCHANNEL,
|
||||
GRPC_CLIENT_DIRECT_CHANNEL, GRPC_SERVER_CHANNEL}) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
type, INT_MAX, [](ChannelStackBuilder* builder) {
|
||||
// Want to add the filter as close to the end as possible, to
|
||||
// make sure that all of the filters work well together.
|
||||
// However, we can't add it at the very end, because the
|
||||
// connected channel filter must be the last one. So we add it
|
||||
// right before the last one.
|
||||
auto it = builder->mutable_stack()->end();
|
||||
--it;
|
||||
builder->mutable_stack()->insert(it, &test_filter);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
});
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello world")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(101, true);
|
||||
Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
Expect(102, true);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
}
|
||||
|
||||
void filter_context_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -17,22 +17,17 @@
|
|||
//
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
|
|
@ -40,371 +35,52 @@
|
|||
#include "src/core/lib/channel/channel_stack_builder.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/gprpp/status_helper.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/iomgr/closure.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/promise/arena_promise.h"
|
||||
#include "src/core/lib/promise/promise.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
enum { TIMEOUT = 200000 };
|
||||
using ::testing::AnyOf;
|
||||
|
||||
static bool g_enable_server_channel_filter = false;
|
||||
static bool g_enable_client_channel_filter = false;
|
||||
static bool g_enable_client_subchannel_filter = false;
|
||||
static bool g_channel_filter_init_failure = false;
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
// Simple request via a SERVER_CHANNEL filter that always fails to
|
||||
// initialize the call.
|
||||
static void test_server_channel_filter(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
auto f = begin_test(config, "filter_init_fails", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
if (g_channel_filter_init_failure) {
|
||||
// Inproc channel returns invalid_argument and other clients return
|
||||
// unavailable.
|
||||
// Windows with sockpair returns unknown.
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNKNOWN ||
|
||||
status == GRPC_STATUS_UNAVAILABLE ||
|
||||
status == GRPC_STATUS_INVALID_ARGUMENT);
|
||||
} else {
|
||||
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
|
||||
}
|
||||
|
||||
f->ShutdownServer();
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
}
|
||||
|
||||
// Simple request via a CLIENT_CHANNEL or CLIENT_DIRECT_CHANNEL filter
|
||||
// that always fails to initialize the call.
|
||||
static void test_client_channel_filter(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
auto f = begin_test(config, "filter_init_fails", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
if (g_channel_filter_init_failure) {
|
||||
GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
|
||||
} else {
|
||||
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
|
||||
}
|
||||
|
||||
f->ShutdownServer();
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
}
|
||||
|
||||
// Simple request via a CLIENT_SUBCHANNEL filter that always fails to
|
||||
// initialize the call.
|
||||
static void test_client_subchannel_filter(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
auto f = begin_test(config, "filter_init_fails", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
if (g_channel_filter_init_failure) {
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
|
||||
} else {
|
||||
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
|
||||
}
|
||||
|
||||
// Reset and create a new call. (The first call uses a different code
|
||||
// path in client_channel.c than subsequent calls on the same channel,
|
||||
// and we need to test both.)
|
||||
grpc_call_unref(c);
|
||||
status = GRPC_STATUS_OK;
|
||||
grpc_slice_unref(details);
|
||||
details = grpc_empty_slice();
|
||||
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(2), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(2), true);
|
||||
cqv.Verify();
|
||||
|
||||
if (g_channel_filter_init_failure) {
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
|
||||
} else {
|
||||
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
|
||||
}
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
//
|
||||
// Test filter - always fails to initialize a call
|
||||
//
|
||||
|
||||
static grpc_error_handle init_call_elem(
|
||||
grpc_call_element* /*elem*/, const grpc_call_element_args* /*args*/) {
|
||||
grpc_error_handle init_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_element_args* /*args*/) {
|
||||
return grpc_error_set_int(GRPC_ERROR_CREATE("access denied"),
|
||||
grpc_core::StatusIntProperty::kRpcStatus,
|
||||
StatusIntProperty::kRpcStatus,
|
||||
GRPC_STATUS_PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
static void destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* /*final_info*/,
|
||||
grpc_closure* /*ignored*/) {}
|
||||
void destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* /*final_info*/,
|
||||
grpc_closure* /*ignored*/) {}
|
||||
|
||||
static grpc_error_handle init_channel_elem(
|
||||
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
|
||||
if (g_channel_filter_init_failure) {
|
||||
grpc_error_handle init_channel_elem(grpc_channel_element* /*elem*/,
|
||||
grpc_channel_element_args* args) {
|
||||
if (args->channel_args.GetBool("channel_init_fails").value_or(false)) {
|
||||
return grpc_error_set_int(
|
||||
GRPC_ERROR_CREATE("Test channel filter init error"),
|
||||
grpc_core::StatusIntProperty::kRpcStatus, GRPC_STATUS_INVALID_ARGUMENT);
|
||||
StatusIntProperty::kRpcStatus, GRPC_STATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
|
||||
static const grpc_channel_filter test_filter = {
|
||||
const grpc_channel_filter test_filter = {
|
||||
grpc_call_next_op,
|
||||
[](grpc_channel_element*, grpc_core::CallArgs,
|
||||
grpc_core::NextPromiseFactory)
|
||||
-> grpc_core::ArenaPromise<grpc_core::ServerMetadataHandle> {
|
||||
return grpc_core::Immediate(grpc_core::ServerMetadataFromStatus(
|
||||
[](grpc_channel_element*, CallArgs,
|
||||
NextPromiseFactory) -> ArenaPromise<ServerMetadataHandle> {
|
||||
return Immediate(ServerMetadataFromStatus(
|
||||
absl::PermissionDeniedError("access denied")));
|
||||
},
|
||||
grpc_channel_next_op,
|
||||
|
|
@ -419,63 +95,175 @@ static const grpc_channel_filter test_filter = {
|
|||
grpc_channel_next_get_info,
|
||||
"filter_init_fails"};
|
||||
|
||||
//******************************************************************************
|
||||
// Registration
|
||||
//
|
||||
|
||||
static void filter_init_fails_internal(const CoreTestConfiguration& config) {
|
||||
gpr_log(GPR_INFO, "Testing SERVER_CHANNEL filter.");
|
||||
g_enable_server_channel_filter = true;
|
||||
test_server_channel_filter(config);
|
||||
g_enable_server_channel_filter = false;
|
||||
gpr_log(GPR_INFO, "Testing CLIENT_CHANNEL / CLIENT_DIRECT_CHANNEL filter.");
|
||||
g_enable_client_channel_filter = true;
|
||||
test_client_channel_filter(config);
|
||||
g_enable_client_channel_filter = false;
|
||||
// If the client handshake completes before the server handshake and the
|
||||
// client is able to send application data before the server handshake
|
||||
// completes, then testing the CLIENT_SUBCHANNEL filter will cause the server
|
||||
// to freeze waiting for the final handshake message from the client. This
|
||||
// handshake message will never arrive because it would have been sent with
|
||||
// the first application data message, which failed because of the filter.
|
||||
if ((config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) &&
|
||||
!(config.feature_mask &
|
||||
FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST)) {
|
||||
gpr_log(GPR_INFO, "Testing CLIENT_SUBCHANNEL filter.");
|
||||
g_enable_client_subchannel_filter = true;
|
||||
test_client_subchannel_filter(config);
|
||||
g_enable_client_subchannel_filter = false;
|
||||
}
|
||||
void RegisterFilter(grpc_channel_stack_type type) {
|
||||
CoreConfiguration::RegisterBuilder(
|
||||
[type](CoreConfiguration::Builder* builder) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
type, INT_MAX, [](ChannelStackBuilder* builder) {
|
||||
// Want to add the filter as close to the end as possible,
|
||||
// to make sure that all of the filters work well together.
|
||||
// However, we can't add it at the very end, because either the
|
||||
// client_channel filter or connected_channel filter must be the
|
||||
// last one. So we add it right before the last one.
|
||||
auto it = builder->mutable_stack()->end();
|
||||
--it;
|
||||
builder->mutable_stack()->insert(it, &test_filter);
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void filter_init_fails(const CoreTestConfiguration& config) {
|
||||
grpc_core::CoreConfiguration::RunWithSpecialConfiguration(
|
||||
[](grpc_core::CoreConfiguration::Builder* builder) {
|
||||
grpc_core::BuildCoreConfiguration(builder);
|
||||
auto register_stage = [builder](grpc_channel_stack_type type,
|
||||
bool* enable) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
type, INT_MAX, [enable](grpc_core::ChannelStackBuilder* builder) {
|
||||
if (!*enable) return true;
|
||||
// Want to add the filter as close to the end as possible,
|
||||
// to make sure that all of the filters work well together.
|
||||
// However, we can't add it at the very end, because either the
|
||||
// client_channel filter or connected_channel filter must be the
|
||||
// last one. So we add it right before the last one.
|
||||
auto it = builder->mutable_stack()->end();
|
||||
--it;
|
||||
builder->mutable_stack()->insert(it, &test_filter);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
register_stage(GRPC_SERVER_CHANNEL, &g_enable_server_channel_filter);
|
||||
register_stage(GRPC_CLIENT_CHANNEL, &g_enable_client_channel_filter);
|
||||
register_stage(GRPC_CLIENT_SUBCHANNEL,
|
||||
&g_enable_client_subchannel_filter);
|
||||
register_stage(GRPC_CLIENT_DIRECT_CHANNEL,
|
||||
&g_enable_client_channel_filter);
|
||||
},
|
||||
[&config] { filter_init_fails_internal(config); });
|
||||
TEST_P(CoreEnd2endTest, DISABLED_ServerFilterChannelInitFails) {
|
||||
RegisterFilter(GRPC_SERVER_CHANNEL);
|
||||
InitClient(ChannelArgs());
|
||||
InitServer(ChannelArgs().Set("channel_init_fails", true));
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
// Inproc channel returns invalid_argument and other clients return
|
||||
// unavailable.
|
||||
// Windows with sockpair returns unknown.
|
||||
EXPECT_THAT(server_status.status(),
|
||||
AnyOf(GRPC_STATUS_UNKNOWN, GRPC_STATUS_UNAVAILABLE,
|
||||
GRPC_STATUS_INVALID_ARGUMENT));
|
||||
ShutdownAndDestroyServer();
|
||||
};
|
||||
|
||||
TEST_P(CoreEnd2endTest, ServerFilterCallInitFails) {
|
||||
RegisterFilter(GRPC_SERVER_CHANNEL);
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_PERMISSION_DENIED);
|
||||
EXPECT_EQ(server_status.message(), "access denied");
|
||||
ShutdownAndDestroyServer();
|
||||
};
|
||||
|
||||
TEST_P(CoreEnd2endTest, DISABLED_ClientFilterChannelInitFails) {
|
||||
RegisterFilter(GRPC_CLIENT_CHANNEL);
|
||||
RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL);
|
||||
InitServer(ChannelArgs());
|
||||
InitClient(ChannelArgs().Set("channel_init_fails", true));
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
void filter_init_fails_pre_init(void) {}
|
||||
TEST_P(CoreEnd2endTest, ClientFilterCallInitFails) {
|
||||
RegisterFilter(GRPC_CLIENT_CHANNEL);
|
||||
RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL);
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_PERMISSION_DENIED);
|
||||
EXPECT_EQ(server_status.message(), "access denied");
|
||||
}
|
||||
|
||||
TEST_P(CoreClientChannelTest, DISABLED_SubchannelFilterChannelInitFails) {
|
||||
RegisterFilter(GRPC_CLIENT_SUBCHANNEL);
|
||||
InitServer(ChannelArgs());
|
||||
InitClient(ChannelArgs().Set("channel_init_fails", true));
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAVAILABLE);
|
||||
// Create a new call. (The first call uses a different code path in
|
||||
// client_channel.c than subsequent calls on the same channel, and we need to
|
||||
// test both.)
|
||||
auto c2 = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status2;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata2;
|
||||
CoreEnd2endTest::IncomingMessage server_message2;
|
||||
c2.NewBatch(2)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hi again")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata2)
|
||||
.RecvStatusOnClient(server_status2);
|
||||
Expect(2, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status2.status(), GRPC_STATUS_UNAVAILABLE);
|
||||
}
|
||||
|
||||
TEST_P(CoreClientChannelTest, SubchannelFilterCallInitFails) {
|
||||
RegisterFilter(GRPC_CLIENT_SUBCHANNEL);
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingMessage server_message;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hello")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_PERMISSION_DENIED);
|
||||
EXPECT_EQ(server_status.message(), "access denied");
|
||||
// Create a new call. (The first call uses a different code path in
|
||||
// client_channel.c than subsequent calls on the same channel, and we need to
|
||||
// test both.)
|
||||
auto c2 = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status2;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata2;
|
||||
CoreEnd2endTest::IncomingMessage server_message2;
|
||||
c2.NewBatch(2)
|
||||
.SendInitialMetadata({})
|
||||
.SendMessage("hi again")
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata2)
|
||||
.RecvStatusOnClient(server_status2);
|
||||
Expect(2, true);
|
||||
Step();
|
||||
EXPECT_EQ(server_status2.status(), GRPC_STATUS_PERMISSION_DENIED);
|
||||
EXPECT_EQ(server_status2.message(), "access denied");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -1,289 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2016 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 <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
#include <grpc/byte_buffer.h>
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/sync.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/channel_stack_builder.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/iomgr/closure.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
enum { TIMEOUT = 200000 };
|
||||
|
||||
static gpr_mu g_mu;
|
||||
static gpr_timespec g_client_latency;
|
||||
static gpr_timespec g_server_latency;
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
// Simple request via a server filter that saves the reported latency value.
|
||||
static void test_request(const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_slice request_payload_slice =
|
||||
grpc_slice_from_copied_string("hello world");
|
||||
grpc_byte_buffer* request_payload =
|
||||
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
|
||||
auto f = begin_test(config, "filter_latency", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_byte_buffer* request_payload_recv = nullptr;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
gpr_mu_lock(&g_mu);
|
||||
g_client_latency = gpr_time_0(GPR_TIMESPAN);
|
||||
g_server_latency = gpr_time_0(GPR_TIMESPAN);
|
||||
gpr_mu_unlock(&g_mu);
|
||||
const gpr_timespec start_time = gpr_now(GPR_CLOCK_REALTIME);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_MESSAGE;
|
||||
op->data.send_message.send_message = request_payload;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_string = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_string;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(s);
|
||||
grpc_call_unref(c);
|
||||
|
||||
grpc_byte_buffer_destroy(request_payload);
|
||||
grpc_byte_buffer_destroy(request_payload_recv);
|
||||
|
||||
const gpr_timespec end_time = gpr_now(GPR_CLOCK_REALTIME);
|
||||
const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
|
||||
|
||||
// Perform checks after test tear-down
|
||||
// Guards against the case that there's outstanding channel-related work on a
|
||||
// call prior to verification
|
||||
gpr_mu_lock(&g_mu);
|
||||
GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
|
||||
GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) <= 0);
|
||||
GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
|
||||
GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) <= 0);
|
||||
// Server latency should always be smaller than client latency, however since
|
||||
// we only calculate latency at destruction time, and that might mean that we
|
||||
// need to wait for outstanding channel-related work, this isn't verifiable
|
||||
// right now (the server MAY hold on to the call for longer than the client).
|
||||
// GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
|
||||
gpr_mu_unlock(&g_mu);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
// Test latency filter
|
||||
//
|
||||
|
||||
static grpc_error_handle init_call_elem(
|
||||
grpc_call_element* /*elem*/, const grpc_call_element_args* /*args*/) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void client_destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* final_info,
|
||||
grpc_closure* /*ignored*/) {
|
||||
gpr_mu_lock(&g_mu);
|
||||
g_client_latency = final_info->stats.latency;
|
||||
gpr_mu_unlock(&g_mu);
|
||||
}
|
||||
|
||||
static void server_destroy_call_elem(grpc_call_element* /*elem*/,
|
||||
const grpc_call_final_info* final_info,
|
||||
grpc_closure* /*ignored*/) {
|
||||
gpr_mu_lock(&g_mu);
|
||||
g_server_latency = final_info->stats.latency;
|
||||
gpr_mu_unlock(&g_mu);
|
||||
}
|
||||
|
||||
static grpc_error_handle init_channel_elem(
|
||||
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
|
||||
static const grpc_channel_filter test_client_filter = {
|
||||
grpc_call_next_op, nullptr,
|
||||
grpc_channel_next_op, 0,
|
||||
init_call_elem, grpc_call_stack_ignore_set_pollset_or_pollset_set,
|
||||
client_destroy_call_elem, 0,
|
||||
init_channel_elem, grpc_channel_stack_no_post_init,
|
||||
destroy_channel_elem, grpc_channel_next_get_info,
|
||||
"client_filter_latency"};
|
||||
|
||||
static const grpc_channel_filter test_server_filter = {
|
||||
grpc_call_next_op, nullptr,
|
||||
grpc_channel_next_op, 0,
|
||||
init_call_elem, grpc_call_stack_ignore_set_pollset_or_pollset_set,
|
||||
server_destroy_call_elem, 0,
|
||||
init_channel_elem, grpc_channel_stack_no_post_init,
|
||||
destroy_channel_elem, grpc_channel_next_get_info,
|
||||
"server_filter_latency"};
|
||||
|
||||
//******************************************************************************
|
||||
// Registration
|
||||
//
|
||||
|
||||
void filter_latency(const CoreTestConfiguration& config) {
|
||||
grpc_core::CoreConfiguration::RunWithSpecialConfiguration(
|
||||
[](grpc_core::CoreConfiguration::Builder* builder) {
|
||||
grpc_core::BuildCoreConfiguration(builder);
|
||||
auto register_stage = [builder](grpc_channel_stack_type type,
|
||||
const grpc_channel_filter* filter) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
type, INT_MAX, [filter](grpc_core::ChannelStackBuilder* builder) {
|
||||
// Want to add the filter as close to the end as possible, to
|
||||
// make sure that all of the filters work well together.
|
||||
// However, we can't add it at the very end, because the
|
||||
// connected channel filter must be the last one. So we add it
|
||||
// right before the last one.
|
||||
auto it = builder->mutable_stack()->end();
|
||||
--it;
|
||||
builder->mutable_stack()->insert(it, filter);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
register_stage(GRPC_CLIENT_CHANNEL, &test_client_filter);
|
||||
register_stage(GRPC_CLIENT_DIRECT_CHANNEL, &test_client_filter);
|
||||
register_stage(GRPC_SERVER_CHANNEL, &test_server_filter);
|
||||
},
|
||||
[config] { test_request(config); });
|
||||
}
|
||||
|
||||
void filter_latency_pre_init(void) { gpr_mu_init(&g_mu); }
|
||||
|
|
@ -1,353 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
//
|
||||
|
||||
// This test verifies -
|
||||
// 1) grpc_call_final_info passed to the filters on destroying a call contains
|
||||
// the proper status.
|
||||
// 2) If the response has both an HTTP status code and a gRPC status code, then
|
||||
// we should prefer the gRPC status code as mentioned in
|
||||
// https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md
|
||||
//
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/sync.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/channel_stack_builder.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/iomgr/closure.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/surface/call.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static gpr_mu g_mu;
|
||||
static grpc_call_stack* g_client_call_stack;
|
||||
static grpc_call_stack* g_server_call_stack;
|
||||
static bool g_client_code_recv;
|
||||
static bool g_server_code_recv;
|
||||
static gpr_cv g_client_code_cv;
|
||||
static gpr_cv g_server_code_cv;
|
||||
static grpc_status_code g_client_status_code;
|
||||
static grpc_status_code g_server_status_code;
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
// Simple request via a server filter that saves the reported status code.
|
||||
static void test_request(const CoreTestConfiguration& config) {
|
||||
g_client_code_recv = false;
|
||||
g_server_code_recv = false;
|
||||
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
auto f = begin_test(config, "filter_status_code", nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
gpr_mu_lock(&g_mu);
|
||||
g_client_call_stack = nullptr;
|
||||
g_server_call_stack = nullptr;
|
||||
g_client_status_code = GRPC_STATUS_OK;
|
||||
g_server_status_code = GRPC_STATUS_OK;
|
||||
gpr_mu_unlock(&g_mu);
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
gpr_mu_lock(&g_mu);
|
||||
g_client_call_stack = grpc_call_get_call_stack(c);
|
||||
gpr_mu_unlock(&g_mu);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
|
||||
gpr_mu_lock(&g_mu);
|
||||
g_server_call_stack = grpc_call_get_call_stack(s);
|
||||
gpr_mu_unlock(&g_mu);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_string = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_string;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(s);
|
||||
grpc_call_unref(c);
|
||||
|
||||
// Perform checks after test tear-down
|
||||
// Guards against the case that there's outstanding channel-related work on a
|
||||
// call prior to verification
|
||||
gpr_mu_lock(&g_mu);
|
||||
if (!g_client_code_recv) {
|
||||
GPR_ASSERT(gpr_cv_wait(&g_client_code_cv, &g_mu,
|
||||
grpc_timeout_seconds_to_deadline(3)) == 0);
|
||||
}
|
||||
if (!g_server_code_recv) {
|
||||
GPR_ASSERT(gpr_cv_wait(&g_server_code_cv, &g_mu,
|
||||
grpc_timeout_seconds_to_deadline(3)) == 0);
|
||||
}
|
||||
GPR_ASSERT(g_client_status_code == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(g_server_status_code == GRPC_STATUS_UNIMPLEMENTED);
|
||||
gpr_mu_unlock(&g_mu);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
// Test status_code filter
|
||||
//
|
||||
|
||||
typedef struct final_status_data {
|
||||
grpc_call_stack* call;
|
||||
} final_status_data;
|
||||
|
||||
static void server_start_transport_stream_op_batch(
|
||||
grpc_call_element* elem, grpc_transport_stream_op_batch* op) {
|
||||
auto* data = static_cast<final_status_data*>(elem->call_data);
|
||||
gpr_mu_lock(&g_mu);
|
||||
if (data->call == g_server_call_stack) {
|
||||
if (op->send_initial_metadata) {
|
||||
auto* batch = op->payload->send_initial_metadata.send_initial_metadata;
|
||||
auto* status = batch->get_pointer(grpc_core::HttpStatusMetadata());
|
||||
if (status != nullptr) {
|
||||
// Replace the HTTP status with 404
|
||||
*status = 404;
|
||||
}
|
||||
}
|
||||
}
|
||||
gpr_mu_unlock(&g_mu);
|
||||
grpc_call_next_op(elem, op);
|
||||
}
|
||||
|
||||
static grpc_error_handle init_call_elem(grpc_call_element* elem,
|
||||
const grpc_call_element_args* args) {
|
||||
final_status_data* data = static_cast<final_status_data*>(elem->call_data);
|
||||
data->call = args->call_stack;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void client_destroy_call_elem(grpc_call_element* elem,
|
||||
const grpc_call_final_info* final_info,
|
||||
grpc_closure* /*ignored*/) {
|
||||
final_status_data* data = static_cast<final_status_data*>(elem->call_data);
|
||||
gpr_mu_lock(&g_mu);
|
||||
// Some fixtures, like proxies, will spawn intermidiate calls
|
||||
// We only want the results from our explicit calls
|
||||
if (data->call == g_client_call_stack) {
|
||||
g_client_status_code = final_info->final_status;
|
||||
g_client_code_recv = true;
|
||||
gpr_cv_signal(&g_client_code_cv);
|
||||
}
|
||||
gpr_mu_unlock(&g_mu);
|
||||
}
|
||||
|
||||
static void server_destroy_call_elem(grpc_call_element* elem,
|
||||
const grpc_call_final_info* final_info,
|
||||
grpc_closure* /*ignored*/) {
|
||||
final_status_data* data = static_cast<final_status_data*>(elem->call_data);
|
||||
gpr_mu_lock(&g_mu);
|
||||
// Some fixtures, like proxies, will spawn intermidiate calls
|
||||
// We only want the results from our explicit calls
|
||||
if (data->call == g_server_call_stack) {
|
||||
g_server_status_code = final_info->final_status;
|
||||
g_server_code_recv = true;
|
||||
gpr_cv_signal(&g_server_code_cv);
|
||||
}
|
||||
gpr_mu_unlock(&g_mu);
|
||||
}
|
||||
|
||||
static grpc_error_handle init_channel_elem(
|
||||
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
|
||||
|
||||
static const grpc_channel_filter test_client_filter = {
|
||||
grpc_call_next_op,
|
||||
nullptr,
|
||||
grpc_channel_next_op,
|
||||
sizeof(final_status_data),
|
||||
init_call_elem,
|
||||
grpc_call_stack_ignore_set_pollset_or_pollset_set,
|
||||
client_destroy_call_elem,
|
||||
0,
|
||||
init_channel_elem,
|
||||
grpc_channel_stack_no_post_init,
|
||||
destroy_channel_elem,
|
||||
grpc_channel_next_get_info,
|
||||
"client_filter_status_code"};
|
||||
|
||||
static const grpc_channel_filter test_server_filter = {
|
||||
server_start_transport_stream_op_batch,
|
||||
nullptr,
|
||||
grpc_channel_next_op,
|
||||
sizeof(final_status_data),
|
||||
init_call_elem,
|
||||
grpc_call_stack_ignore_set_pollset_or_pollset_set,
|
||||
server_destroy_call_elem,
|
||||
0,
|
||||
init_channel_elem,
|
||||
grpc_channel_stack_no_post_init,
|
||||
destroy_channel_elem,
|
||||
grpc_channel_next_get_info,
|
||||
"server_filter_status_code"};
|
||||
|
||||
//******************************************************************************
|
||||
// Registration
|
||||
//
|
||||
|
||||
void filter_status_code(const CoreTestConfiguration& config) {
|
||||
grpc_core::CoreConfiguration::RunWithSpecialConfiguration(
|
||||
[](grpc_core::CoreConfiguration::Builder* builder) {
|
||||
grpc_core::BuildCoreConfiguration(builder);
|
||||
auto register_stage = [builder](grpc_channel_stack_type type,
|
||||
const grpc_channel_filter* filter) {
|
||||
builder->channel_init()->RegisterStage(
|
||||
type, INT_MAX, [filter](grpc_core::ChannelStackBuilder* builder) {
|
||||
// Want to add the filter as close to the end as possible, to
|
||||
// make sure that all of the filters work well together.
|
||||
// However, we can't add it at the very end, because the
|
||||
// connected_channel/client_channel filter must be the last one.
|
||||
// So we add it right before the last one.
|
||||
auto it = builder->mutable_stack()->end();
|
||||
--it;
|
||||
builder->mutable_stack()->insert(it, filter);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
register_stage(GRPC_CLIENT_CHANNEL, &test_client_filter);
|
||||
register_stage(GRPC_CLIENT_DIRECT_CHANNEL, &test_client_filter);
|
||||
register_stage(GRPC_SERVER_CHANNEL, &test_server_filter);
|
||||
},
|
||||
[&config] { test_request(config); });
|
||||
}
|
||||
|
||||
void filter_status_code_pre_init(void) {
|
||||
gpr_mu_init(&g_mu);
|
||||
gpr_cv_init(&g_client_code_cv);
|
||||
gpr_cv_init(&g_server_code_cv);
|
||||
}
|
||||
|
|
@ -16,175 +16,64 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
// Request/response with metadata which should be filtered
|
||||
static void test_request_response_with_metadata_to_be_filtered(
|
||||
const CoreTestConfiguration& config, const char* filtered_md_key,
|
||||
const char* filter_md_value) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
|
||||
grpc_slice_from_static_string("val1"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}},
|
||||
{grpc_slice_from_static_string(filtered_md_key),
|
||||
grpc_slice_from_static_string(filter_md_value),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}}};
|
||||
grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key2"),
|
||||
grpc_slice_from_static_string("val2"),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}},
|
||||
{grpc_slice_from_static_string(filtered_md_key),
|
||||
grpc_slice_from_static_string(filter_md_value),
|
||||
{{nullptr, nullptr, nullptr, nullptr}}}};
|
||||
auto f =
|
||||
begin_test(config, "test_request_response_with_metadata_to_be_filtered",
|
||||
nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
void TestRequestResponseWithMetadataToBeFiltered(
|
||||
CoreEnd2endTest& test, absl::string_view filtered_md_key,
|
||||
absl::string_view filter_md_value) {
|
||||
auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata(
|
||||
{{"key1", "val1"}, {filtered_md_key, filter_md_value}})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
auto s = test.RequestCall(101);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 2;
|
||||
op->data.send_initial_metadata.metadata = meta_c;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
test.Expect(101, true);
|
||||
test.Step();
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
s.NewBatch(102).SendInitialMetadata(
|
||||
{{"key2", "val2"}, {filtered_md_key, filter_md_value}});
|
||||
test.Expect(102, true);
|
||||
test.Step();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 2;
|
||||
op->data.send_initial_metadata.metadata = meta_s;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(103)
|
||||
.RecvCloseOnServer(client_close)
|
||||
.SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
|
||||
test.Expect(103, true);
|
||||
test.Expect(1, true);
|
||||
test.Step();
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Verify();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_OK;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(103), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(103), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_OK);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1"));
|
||||
GPR_ASSERT(!contains_metadata(&request_metadata_recv, filtered_md_key,
|
||||
filter_md_value));
|
||||
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key2", "val2"));
|
||||
GPR_ASSERT(!contains_metadata(&initial_metadata_recv, filtered_md_key,
|
||||
filter_md_value));
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
grpc_call_unref(s);
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
|
||||
EXPECT_EQ(server_status.message(), "xyz");
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
EXPECT_EQ(s.GetInitialMetadata("key1"), "val1");
|
||||
EXPECT_EQ(s.GetInitialMetadata(filtered_md_key), absl::nullopt);
|
||||
EXPECT_EQ(server_initial_metadata.Get("key2"), "val2");
|
||||
EXPECT_EQ(server_initial_metadata.Get(filtered_md_key), absl::nullopt);
|
||||
}
|
||||
|
||||
void filtered_metadata(const CoreTestConfiguration& config) {
|
||||
test_request_response_with_metadata_to_be_filtered(config, "content-length",
|
||||
"45");
|
||||
TEST_P(CoreEnd2endTest, ContentLengthIsFiltered) {
|
||||
TestRequestResponseWithMetadataToBeFiltered(*this, "content-length", "45");
|
||||
}
|
||||
|
||||
void filtered_metadata_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
|
|
@ -16,150 +16,45 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/impl/propagation_bits.h>
|
||||
#include <grpc/slice.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
|
||||
static std::unique_ptr<CoreTestFixture> begin_test(
|
||||
const CoreTestConfiguration& config, const char* test_name,
|
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) {
|
||||
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
|
||||
auto f = config.create_fixture(grpc_core::ChannelArgs::FromC(client_args),
|
||||
grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitServer(grpc_core::ChannelArgs::FromC(server_args));
|
||||
f->InitClient(grpc_core::ChannelArgs::FromC(client_args));
|
||||
return f;
|
||||
}
|
||||
|
||||
static void test_early_server_shutdown_finishes_inflight_calls(
|
||||
const CoreTestConfiguration& config) {
|
||||
grpc_call* c;
|
||||
grpc_call* s;
|
||||
auto f =
|
||||
begin_test(config, "test_early_server_shutdown_finishes_inflight_calls",
|
||||
nullptr, nullptr);
|
||||
grpc_core::CqVerifier cqv(f->cq());
|
||||
grpc_op ops[6];
|
||||
grpc_op* op;
|
||||
grpc_metadata_array initial_metadata_recv;
|
||||
grpc_metadata_array trailing_metadata_recv;
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
grpc_call_details call_details;
|
||||
grpc_status_code status;
|
||||
grpc_call_error error;
|
||||
grpc_slice details;
|
||||
int was_cancelled = 2;
|
||||
|
||||
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
|
||||
c = grpc_channel_create_call(f->client(), nullptr, GRPC_PROPAGATE_DEFAULTS,
|
||||
f->cq(), grpc_slice_from_static_string("/foo"),
|
||||
nullptr, deadline, nullptr);
|
||||
GPR_ASSERT(c);
|
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv);
|
||||
grpc_metadata_array_init(&trailing_metadata_recv);
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
grpc_call_details_init(&call_details);
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->data.send_initial_metadata.metadata = nullptr;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA;
|
||||
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
|
||||
op->data.recv_status_on_client.status = &status;
|
||||
op->data.recv_status_on_client.status_details = &details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(1), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
error = grpc_server_request_call(f->server(), &s, &call_details,
|
||||
&request_metadata_recv, f->cq(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(101), true);
|
||||
cqv.Verify();
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
TEST_P(Http2Test, GracefulServerShutdown) {
|
||||
auto c = NewClientCall("/foo").Timeout(Duration::Seconds(10)).Create();
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
CoreEnd2endTest::IncomingMetadata server_initial_metadata;
|
||||
c.NewBatch(1)
|
||||
.SendInitialMetadata({})
|
||||
.SendCloseFromClient()
|
||||
.RecvInitialMetadata(server_initial_metadata)
|
||||
.RecvStatusOnClient(server_status);
|
||||
auto s = RequestCall(101);
|
||||
Expect(101, true);
|
||||
Step();
|
||||
// shutdown and destroy the server
|
||||
grpc_server_shutdown_and_notify(f->server(), f->cq(),
|
||||
grpc_core::CqVerifier::tag(0xdead));
|
||||
cqv.VerifyEmpty();
|
||||
ShutdownServerAndNotify(200);
|
||||
Step();
|
||||
CoreEnd2endTest::IncomingCloseOnServer client_close;
|
||||
s.NewBatch(102)
|
||||
.SendInitialMetadata({})
|
||||
.SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
|
||||
.RecvCloseOnServer(client_close);
|
||||
Expect(102, true);
|
||||
Expect(200, true);
|
||||
Expect(1, true);
|
||||
Step();
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
|
||||
op->data.send_status_from_server.trailing_metadata_count = 0;
|
||||
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
|
||||
grpc_slice status_details = grpc_slice_from_static_string("xyz");
|
||||
op->data.send_status_from_server.status_details = &status_details;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
|
||||
op->data.recv_close_on_server.cancelled = &was_cancelled;
|
||||
op->flags = 0;
|
||||
op->reserved = nullptr;
|
||||
op++;
|
||||
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
|
||||
grpc_core::CqVerifier::tag(102), nullptr);
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(102), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(0xdead), true);
|
||||
cqv.Expect(grpc_core::CqVerifier::tag(1), true);
|
||||
cqv.Verify();
|
||||
|
||||
grpc_call_unref(s);
|
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
|
||||
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
|
||||
GPR_ASSERT(was_cancelled == 0);
|
||||
|
||||
grpc_slice_unref(details);
|
||||
grpc_metadata_array_destroy(&initial_metadata_recv);
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv);
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_details_destroy(&call_details);
|
||||
|
||||
grpc_call_unref(c);
|
||||
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
|
||||
EXPECT_EQ(s.method(), "/foo");
|
||||
EXPECT_FALSE(client_close.was_cancelled());
|
||||
}
|
||||
|
||||
void graceful_server_shutdown(const CoreTestConfiguration& config) {
|
||||
test_early_server_shutdown_finishes_inflight_calls(config);
|
||||
}
|
||||
|
||||
void graceful_server_shutdown_pre_init(void) {}
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue