aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/core/end2end/end2end_tests.h1
-rw-r--r--test/core/end2end/fixtures/chttp2_fake_security.c4
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c (renamed from test/core/end2end/fixtures/chttp2_fullstack_uds.c)0
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c3
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c3
-rwxr-xr-xtest/core/end2end/gen_build_json.py93
-rw-r--r--test/core/end2end/tests/bad_hostname.c1
-rw-r--r--test/core/end2end/tests/cancel_after_accept.c1
-rw-r--r--test/core/end2end/tests/cancel_after_accept_and_writes_closed.c1
-rw-r--r--test/core/end2end/tests/cancel_after_invoke.c1
-rw-r--r--test/core/end2end/tests/cancel_before_invoke.c1
-rw-r--r--test/core/end2end/tests/cancel_in_a_vacuum.c1
-rw-r--r--test/core/end2end/tests/census_simple_request.c1
-rw-r--r--test/core/end2end/tests/disappearing_server.c1
-rw-r--r--test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c1
-rw-r--r--test/core/end2end/tests/early_server_shutdown_finishes_tags.c1
-rw-r--r--test/core/end2end/tests/empty_batch.c1
-rw-r--r--test/core/end2end/tests/graceful_server_shutdown.c1
-rw-r--r--test/core/end2end/tests/invoke_large_request.c1
-rw-r--r--test/core/end2end/tests/max_concurrent_streams.c1
-rw-r--r--test/core/end2end/tests/max_message_length.c1
-rw-r--r--test/core/end2end/tests/no_op.c1
-rw-r--r--test/core/end2end/tests/ping_pong_streaming.c1
-rw-r--r--test/core/end2end/tests/registered_call.c1
-rw-r--r--test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c1
-rw-r--r--test/core/end2end/tests/request_response_with_metadata_and_payload.c1
-rw-r--r--test/core/end2end/tests/request_response_with_payload.c1
-rw-r--r--test/core/end2end/tests/request_response_with_payload_and_call_creds.c337
-rw-r--r--test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c1
-rw-r--r--test/core/end2end/tests/request_with_large_metadata.c1
-rw-r--r--test/core/end2end/tests/request_with_payload.c1
-rw-r--r--test/core/end2end/tests/simple_delayed_request.c1
-rw-r--r--test/core/end2end/tests/simple_request.c1
-rw-r--r--test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c1
-rw-r--r--test/core/fling/server.c5
-rw-r--r--test/core/iomgr/sockaddr_utils_test.c1
-rw-r--r--test/core/security/secure_endpoint_test.c2
-rw-r--r--test/cpp/end2end/async_end2end_test.cc5
-rw-r--r--test/cpp/end2end/end2end_test.cc12
-rw-r--r--test/cpp/end2end/thread_stress_test.cc242
40 files changed, 647 insertions, 88 deletions
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index 41c6e2ee0c..a61c725aa2 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -41,6 +41,7 @@ typedef struct grpc_end2end_test_config grpc_end2end_test_config;
#define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1
#define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2
+#define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4
struct grpc_end2end_test_fixture {
grpc_completion_queue *server_cq;
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index 929f1f50db..c1ac9163ed 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -112,7 +112,9 @@ static void chttp2_init_server_fake_secure_fullstack(
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"chttp2/fake_secure_fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+ {"chttp2/fake_secure_fullstack",
+ FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
chttp2_create_fixture_secure_fullstack,
chttp2_init_client_fake_secure_fullstack,
chttp2_init_server_fake_secure_fullstack,
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_uds.c b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
index 53803b0f1d..53803b0f1d 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_uds.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 9c4086d79d..3d6c0cf3f0 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -124,7 +124,8 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
static grpc_end2end_test_config configs[] = {
{"chttp2/simple_ssl_fullstack",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
- FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION,
+ FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
chttp2_create_fixture_secure_fullstack,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index e9e1c5f838..b57872f4f0 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -129,7 +129,8 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
static grpc_end2end_test_config configs[] = {
{"chttp2/simple_ssl_with_oauth2_fullstack",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
- FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION,
+ FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
chttp2_create_fixture_secure_fullstack,
chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
diff --git a/test/core/end2end/gen_build_json.py b/test/core/end2end/gen_build_json.py
index dfe9c1d360..77b929ec18 100755
--- a/test/core/end2end/gen_build_json.py
+++ b/test/core/end2end/gen_build_json.py
@@ -33,48 +33,56 @@
import simplejson
+import collections
+FixtureOptions = collections.namedtuple('FixtureOptions', 'secure platforms')
+default_unsecure_fixture_options = FixtureOptions(False, ['windows', 'posix'])
+default_secure_fixture_options = FixtureOptions(True, ['windows', 'posix'])
+
# maps fixture name to whether it requires the security library
END2END_FIXTURES = {
- 'chttp2_fake_security': True,
- 'chttp2_fullstack': False,
- 'chttp2_fullstack_uds': False,
- 'chttp2_simple_ssl_fullstack': True,
- 'chttp2_simple_ssl_with_oauth2_fullstack': True,
- 'chttp2_socket_pair': False,
- 'chttp2_socket_pair_one_byte_at_a_time': False,
+ 'chttp2_fake_security': default_secure_fixture_options,
+ 'chttp2_fullstack': default_unsecure_fixture_options,
+ 'chttp2_fullstack_uds_posix': FixtureOptions(False, ['posix']),
+ 'chttp2_simple_ssl_fullstack': default_secure_fixture_options,
+ 'chttp2_simple_ssl_with_oauth2_fullstack': default_secure_fixture_options,
+ 'chttp2_socket_pair': default_unsecure_fixture_options,
+ 'chttp2_socket_pair_one_byte_at_a_time': default_unsecure_fixture_options,
}
-# maps tests names to whether they run fine or not (aka, not flaky)
+TestOptions = collections.namedtuple('TestOptions', 'flaky secure')
+default_test_options = TestOptions(False, False)
+
+# maps test names to options
END2END_TESTS = {
- 'bad_hostname': True,
- 'cancel_after_accept': False,
- 'cancel_after_accept_and_writes_closed': True,
- 'cancel_after_invoke': True,
- 'cancel_before_invoke': True,
- 'cancel_in_a_vacuum': True,
- 'census_simple_request': True,
- 'disappearing_server': True,
- 'early_server_shutdown_finishes_inflight_calls': True,
- 'early_server_shutdown_finishes_tags': True,
- 'empty_batch': True,
- 'graceful_server_shutdown': True,
- 'invoke_large_request': False,
- 'max_concurrent_streams': True,
- 'max_message_length': True,
- 'no_op': True,
- 'ping_pong_streaming': True,
- 'registered_call': True,
- 'request_response_with_binary_metadata_and_payload': True,
- 'request_response_with_metadata_and_payload': True,
- 'request_response_with_payload': True,
- 'request_response_with_trailing_metadata_and_payload': True,
- 'request_with_large_metadata': True,
- 'request_with_payload': True,
- 'simple_delayed_request': True,
- 'simple_request': True,
- 'simple_request_with_high_initial_sequence_number': True,
+ 'bad_hostname': default_test_options,
+ 'cancel_after_accept': TestOptions(flaky=True, secure=False),
+ 'cancel_after_accept_and_writes_closed': default_test_options,
+ 'cancel_after_invoke': default_test_options,
+ 'cancel_before_invoke': default_test_options,
+ 'cancel_in_a_vacuum': default_test_options,
+ 'census_simple_request': default_test_options,
+ 'disappearing_server': default_test_options,
+ 'early_server_shutdown_finishes_inflight_calls': default_test_options,
+ 'early_server_shutdown_finishes_tags': default_test_options,
+ 'empty_batch': default_test_options,
+ 'graceful_server_shutdown': default_test_options,
+ 'invoke_large_request': TestOptions(flaky=True, secure=False),
+ 'max_concurrent_streams': default_test_options,
+ 'max_message_length': default_test_options,
+ 'no_op': default_test_options,
+ 'ping_pong_streaming': default_test_options,
+ 'registered_call': default_test_options,
+ 'request_response_with_binary_metadata_and_payload': default_test_options,
+ 'request_response_with_metadata_and_payload': default_test_options,
+ 'request_response_with_payload': default_test_options,
+ 'request_response_with_payload_and_call_creds': TestOptions(flaky=False, secure=True),
+ 'request_with_large_metadata': default_test_options,
+ 'request_with_payload': default_test_options,
+ 'simple_delayed_request': default_test_options,
+ 'simple_request': default_test_options,
+ 'simple_request_with_high_initial_sequence_number': default_test_options,
}
@@ -86,15 +94,16 @@ def main():
'name': 'end2end_fixture_%s' % f,
'build': 'private',
'language': 'c',
- 'secure': 'check' if END2END_FIXTURES[f] else 'no',
- 'src': ['test/core/end2end/fixtures/%s.c' % f]
+ 'secure': 'check' if END2END_FIXTURES[f].secure else 'no',
+ 'src': ['test/core/end2end/fixtures/%s.c' % f],
+ 'platforms': [ 'posix' ] if f.endswith('_posix') else [ 'windows', 'posix' ],
}
for f in sorted(END2END_FIXTURES.keys())] + [
{
'name': 'end2end_test_%s' % t,
'build': 'private',
'language': 'c',
- 'secure': 'no',
+ 'secure': 'check' if END2END_TESTS[t].secure else 'no',
'src': ['test/core/end2end/tests/%s.c' % t],
'headers': ['test/core/end2end/tests/cancel_test_helpers.h']
}
@@ -116,7 +125,8 @@ def main():
'build': 'test',
'language': 'c',
'src': [],
- 'flaky': not END2END_TESTS[t],
+ 'flaky': END2END_TESTS[t].flaky,
+ 'platforms': END2END_FIXTURES[f].platforms,
'deps': [
'end2end_fixture_%s' % f,
'end2end_test_%s' % t,
@@ -136,6 +146,7 @@ def main():
'secure': 'no',
'src': [],
'flaky': 'invoke_large_request' in t,
+ 'platforms': END2END_FIXTURES[f].platforms,
'deps': [
'end2end_fixture_%s' % f,
'end2end_test_%s' % t,
@@ -145,8 +156,8 @@ def main():
'gpr'
]
}
- for f in sorted(END2END_FIXTURES.keys()) if not END2END_FIXTURES[f]
- for t in sorted(END2END_TESTS.keys())]}
+ for f in sorted(END2END_FIXTURES.keys()) if not END2END_FIXTURES[f].secure
+ for t in sorted(END2END_TESTS.keys()) if not END2END_TESTS[t].secure]}
print simplejson.dumps(json, sort_keys=True, indent=2 * ' ')
diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c
index 80922f3b6f..671f232ee3 100644
--- a/test/core/end2end/tests/bad_hostname.c
+++ b/test/core/end2end/tests/bad_hostname.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index 21057969d9..184434cc97 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
index f8733ef444..f84c3343be 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 592dfd415f..ce6dc72508 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 6e100db185..02c238221f 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index a88ca0b5b7..523091f5a1 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
index 67c769c08b..45406975db 100644
--- a/test/core/end2end/tests/census_simple_request.c
+++ b/test/core/end2end/tests/census_simple_request.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index c8e22ce11c..3e3ea3052b 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
index 2c2d2e895b..28ace256ef 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
index 96978a8cb9..c909e94ac2 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c
index 6237e29b12..19b017abcf 100644
--- a/test/core/end2end/tests/empty_batch.c
+++ b/test/core/end2end/tests/empty_batch.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index d084530a9c..17057c4ca7 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index d9d9e934cb..5aa378dd38 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 6e95a6c5f8..4640f3287c 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index 6291f773b3..40fcbfba8b 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c
index 497bdccdbd..0e52c4ec98 100644
--- a/test/core/end2end/tests/no_op.c
+++ b/test/core/end2end/tests/no_op.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index fe02f25875..caea950172 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index 05b7a1dad0..0fe21a86c9 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
index 8a6391b7f0..6edc641a54 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
index 79ba6fdce8..9f3c1242a3 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c
index 4d050833d8..e40d6c723b 100644
--- a/test/core/end2end/tests/request_response_with_payload.c
+++ b/test/core/end2end/tests/request_response_with_payload.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
new file mode 100644
index 0000000000..0339d5ab99
--- /dev/null
+++ b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
@@ -0,0 +1,337 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/grpc_security.h>
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "test/core/end2end/cq_verifier.h"
+#include "src/core/security/credentials.h"
+#include "src/core/support/string.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";
+
+typedef enum {
+ NONE,
+ OVERRIDE,
+ DESTROY
+} override_mode;
+
+enum { TIMEOUT = 200000 };
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char *test_name,
+ grpc_channel_args *client_args,
+ grpc_channel_args *server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_client(&f, client_args);
+ config.init_server(&f, server_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_time(int n) {
+ return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
+}
+
+static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+
+static void drain_cq(grpc_completion_queue *cq) {
+ grpc_event *ev;
+ grpc_completion_type type;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_time());
+ GPR_ASSERT(ev);
+ type = ev->type;
+ grpc_event_finish(ev);
+ } while (type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+ if (!f->server) return;
+ grpc_server_shutdown(f->server);
+ grpc_server_destroy(f->server);
+ f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->server_cq);
+ drain_cq(f->server_cq);
+ grpc_completion_queue_destroy(f->server_cq);
+ grpc_completion_queue_shutdown(f->client_cq);
+ drain_cq(f->client_cq);
+ grpc_completion_queue_destroy(f->client_cq);
+}
+
+static void test_call_creds_failure(grpc_end2end_test_config config) {
+ grpc_call *c;
+ grpc_credentials *creds = NULL;
+ grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
+ gpr_timespec deadline = five_seconds_time();
+ c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+ "foo.test.google.fr", deadline);
+ GPR_ASSERT(c);
+
+ /* Try with credentials unfit to be set on a call (channel creds). */
+ creds = grpc_fake_transport_security_credentials_create();
+ GPR_ASSERT(grpc_call_set_credentials(c, creds) != GRPC_CALL_OK);
+ grpc_credentials_release(creds);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+static void request_response_with_payload_and_call_creds(
+ const char *test_name, grpc_end2end_test_config config,
+ override_mode mode) {
+ grpc_call *c;
+ grpc_call *s;
+ gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
+ gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you");
+ grpc_byte_buffer *request_payload =
+ grpc_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer *response_payload =
+ grpc_byte_buffer_create(&response_payload_slice, 1);
+ gpr_timespec deadline = five_seconds_time();
+
+ grpc_end2end_test_fixture f = begin_test(config, test_name, NULL, NULL);
+ cq_verifier *v_client = cq_verifier_create(f.client_cq);
+ cq_verifier *v_server = cq_verifier_create(f.server_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 = NULL;
+ grpc_byte_buffer *response_payload_recv = NULL;
+ grpc_call_details call_details;
+ grpc_status_code status;
+ char *details = NULL;
+ size_t details_capacity = 0;
+ int was_cancelled = 2;
+ grpc_credentials *creds = NULL;
+
+ c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+ "foo.test.google.fr", deadline);
+ GPR_ASSERT(c);
+ creds = grpc_iam_credentials_create(iam_token, iam_selector);
+ GPR_ASSERT(creds != NULL);
+ GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
+ switch (mode) {
+ case NONE:
+ break;
+ case OVERRIDE:
+ grpc_credentials_release(creds);
+ creds = grpc_iam_credentials_create(overridden_iam_token,
+ overridden_iam_selector);
+ GPR_ASSERT(creds != NULL);
+ GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
+ break;
+ case DESTROY:
+ GPR_ASSERT(grpc_call_set_credentials(c, NULL) == GRPC_CALL_OK);
+ break;
+ }
+ grpc_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);
+
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &response_payload_recv;
+ 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.status_details_capacity = &details_capacity;
+ op++;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
+
+ GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
+ &call_details,
+ &request_metadata_recv,
+ f.server_cq, tag(101)));
+ cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
+ cq_verify(v_server);
+
+ /* Cannot set creds on the server call object. */
+ GPR_ASSERT(grpc_call_set_credentials(s, NULL) != GRPC_CALL_OK);
+
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message = response_payload;
+ 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;
+ op->data.send_status_from_server.status_details = "xyz";
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &request_payload_recv;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
+
+ cq_expect_completion(v_server, tag(102), GRPC_OP_OK);
+ cq_verify(v_server);
+
+ cq_expect_completion(v_client, tag(1), GRPC_OP_OK);
+ cq_verify(v_client);
+
+ GPR_ASSERT(status == GRPC_STATUS_OK);
+ GPR_ASSERT(0 == strcmp(details, "xyz"));
+ GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
+ 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:
+ 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));
+ break;
+ case OVERRIDE:
+ 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));
+ 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));
+ break;
+ }
+
+ gpr_free(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_destroy(c);
+ grpc_call_destroy(s);
+
+ cq_verifier_destroy(v_client);
+ cq_verifier_destroy(v_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);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void test_request_response_with_payload_and_call_creds(
+ grpc_end2end_test_config config) {
+ request_response_with_payload_and_call_creds(__FUNCTION__, config, NONE);
+}
+
+void test_request_response_with_payload_and_overridden_call_creds(
+ grpc_end2end_test_config config) {
+ request_response_with_payload_and_call_creds(__FUNCTION__, config, OVERRIDE);
+}
+
+void test_request_response_with_payload_and_deleted_call_creds(
+ grpc_end2end_test_config config) {
+ request_response_with_payload_and_call_creds(__FUNCTION__, config, DESTROY);
+}
+
+void grpc_end2end_tests(grpc_end2end_test_config config) {
+ if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS) {
+ test_call_creds_failure(config);
+ test_request_response_with_payload_and_call_creds(config);
+ test_request_response_with_payload_and_overridden_call_creds(config);
+ test_request_response_with_payload_and_deleted_call_creds(config);
+ }
+}
+
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
index 652a155b73..04306df074 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c
index 302d2e0586..506766a73f 100644
--- a/test/core/end2end/tests/request_with_large_metadata.c
+++ b/test/core/end2end/tests/request_with_large_metadata.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index 5b92780f0e..fea71b4193 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index 0dbb35d454..231e260227 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 4d4d48a211..e6fe2b3435 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
diff --git a/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c b/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c
index 538291a5f2..0105d00c5d 100644
--- a/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c
+++ b/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 63c7bd7f88..a35afa1077 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -39,7 +39,10 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#ifndef _WIN32
+/* This is for _exit() below, which is temporary. */
#include <unistd.h>
+#endif
#include "test/core/util/grpc_profiler.h"
#include "test/core/util/test_config.h"
@@ -166,6 +169,8 @@ static void start_send_status(void) {
tag(FLING_SERVER_SEND_STATUS_FOR_STREAMING)));
}
+/* We have some sort of deadlock, so let's not exit gracefully for now.
+ When that is resolved, please remove the #include <unistd.h> above. */
static void sigint_handler(int x) { _exit(0); }
int main(int argc, char **argv) {
diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c
index 9f5e954b9d..9212f01c3f 100644
--- a/test/core/iomgr/sockaddr_utils_test.c
+++ b/test/core/iomgr/sockaddr_utils_test.c
@@ -34,7 +34,6 @@
#include "src/core/iomgr/sockaddr_utils.h"
#include <errno.h>
-#include <netinet/in.h>
#include <string.h>
#include <grpc/support/alloc.h>
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index f7bd3cb4ae..6477454e8a 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -35,8 +35,6 @@
#include <fcntl.h>
#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
#include "src/core/security/secure_endpoint.h"
#include "src/core/iomgr/endpoint_pair.h"
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 949a2ffa12..bf5540f706 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -197,8 +197,9 @@ TEST_F(AsyncEnd2endTest, AsyncNextRpc) {
stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_));
std::chrono::system_clock::time_point time_now(
- std::chrono::system_clock::now()),
- time_limit(std::chrono::system_clock::now() + std::chrono::seconds(5));
+ std::chrono::system_clock::now());
+ std::chrono::system_clock::time_point time_limit(
+ std::chrono::system_clock::now() + std::chrono::seconds(10));
verify_timed_ok(&srv_cq_, -1, true, time_now, CompletionQueue::TIMEOUT);
verify_timed_ok(&cli_cq_, -1, true, time_now, CompletionQueue::TIMEOUT);
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 0945ed269d..f35b16fe55 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -577,18 +577,6 @@ TEST_F(End2endTest, ClientCancelsBidi) {
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.code());
}
-TEST_F(End2endTest, ThreadStress) {
- ResetStub();
- std::vector<std::thread*> threads;
- for (int i = 0; i < 100; ++i) {
- threads.push_back(new std::thread(SendRpc, stub_.get(), 1000));
- }
- for (int i = 0; i < 100; ++i) {
- threads[i]->join();
- delete threads[i];
- }
-}
-
TEST_F(End2endTest, RpcMaxMessageSize) {
ResetStub();
EchoRequest request;
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
new file mode 100644
index 0000000000..12656128c0
--- /dev/null
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -0,0 +1,242 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <thread>
+
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/util/echo_duplicate.grpc.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
+#include "src/cpp/server/thread_pool.h"
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+#include <grpc++/time.h>
+#include <gtest/gtest.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+using grpc::cpp::test::util::EchoRequest;
+using grpc::cpp::test::util::EchoResponse;
+using std::chrono::system_clock;
+
+namespace grpc {
+namespace testing {
+
+namespace {
+
+// When echo_deadline is requested, deadline seen in the ServerContext is set in
+// the response in seconds.
+void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) {
+ if (request->has_param() && request->param().echo_deadline()) {
+ gpr_timespec deadline = gpr_inf_future;
+ if (context->deadline() != system_clock::time_point::max()) {
+ Timepoint2Timespec(context->deadline(), &deadline);
+ }
+ response->mutable_param()->set_request_deadline(deadline.tv_sec);
+ }
+}
+
+} // namespace
+
+class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
+ public:
+ TestServiceImpl() : signal_client_(false) {}
+
+ Status Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ response->set_message(request->message());
+ MaybeEchoDeadline(context, request, response);
+ if (request->has_param() && request->param().client_cancel_after_us()) {
+ {
+ std::unique_lock<std::mutex> lock(mu_);
+ signal_client_ = true;
+ }
+ while (!context->IsCancelled()) {
+ std::this_thread::sleep_for(std::chrono::microseconds(
+ request->param().client_cancel_after_us()));
+ }
+ return Status::Cancelled;
+ } else if (request->has_param() &&
+ request->param().server_cancel_after_us()) {
+ std::this_thread::sleep_for(
+ std::chrono::microseconds(request->param().server_cancel_after_us()));
+ return Status::Cancelled;
+ } else {
+ EXPECT_FALSE(context->IsCancelled());
+ }
+ return Status::OK;
+ }
+
+ // Unimplemented is left unimplemented to test the returned error.
+
+ Status RequestStream(ServerContext* context,
+ ServerReader<EchoRequest>* reader,
+ EchoResponse* response) GRPC_OVERRIDE {
+ EchoRequest request;
+ response->set_message("");
+ while (reader->Read(&request)) {
+ response->mutable_message()->append(request.message());
+ }
+ return Status::OK;
+ }
+
+ // Return 3 messages.
+ // TODO(yangg) make it generic by adding a parameter into EchoRequest
+ Status ResponseStream(ServerContext* context, const EchoRequest* request,
+ ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
+ EchoResponse response;
+ response.set_message(request->message() + "0");
+ writer->Write(response);
+ response.set_message(request->message() + "1");
+ writer->Write(response);
+ response.set_message(request->message() + "2");
+ writer->Write(response);
+
+ return Status::OK;
+ }
+
+ Status BidiStream(ServerContext* context,
+ ServerReaderWriter<EchoResponse, EchoRequest>* stream)
+ GRPC_OVERRIDE {
+ EchoRequest request;
+ EchoResponse response;
+ while (stream->Read(&request)) {
+ gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
+ response.set_message(request.message());
+ stream->Write(response);
+ }
+ return Status::OK;
+ }
+
+ bool signal_client() {
+ std::unique_lock<std::mutex> lock(mu_);
+ return signal_client_;
+ }
+
+ private:
+ bool signal_client_;
+ std::mutex mu_;
+};
+
+class TestServiceImplDupPkg
+ : public ::grpc::cpp::test::util::duplicate::TestService::Service {
+ public:
+ Status Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ response->set_message("no package");
+ return Status::OK;
+ }
+};
+
+class End2endTest : public ::testing::Test {
+ protected:
+ End2endTest() : kMaxMessageSize_(8192), thread_pool_(2) {}
+
+ void SetUp() GRPC_OVERRIDE {
+ int port = grpc_pick_unused_port_or_die();
+ server_address_ << "localhost:" << port;
+ // Setup server
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address_.str(),
+ InsecureServerCredentials());
+ builder.RegisterService(&service_);
+ builder.SetMaxMessageSize(
+ kMaxMessageSize_); // For testing max message size.
+ builder.RegisterService(&dup_pkg_service_);
+ builder.SetThreadPool(&thread_pool_);
+ server_ = builder.BuildAndStart();
+ }
+
+ void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
+
+ void ResetStub() {
+ std::shared_ptr<ChannelInterface> channel = CreateChannel(
+ server_address_.str(), InsecureCredentials(), ChannelArguments());
+ stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
+ }
+
+ std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
+ std::unique_ptr<Server> server_;
+ std::ostringstream server_address_;
+ const int kMaxMessageSize_;
+ TestServiceImpl service_;
+ TestServiceImplDupPkg dup_pkg_service_;
+ ThreadPool thread_pool_;
+};
+
+static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
+ int num_rpcs) {
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ for (int i = 0; i < num_rpcs; ++i) {
+ ClientContext context;
+ Status s = stub->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.IsOk());
+ }
+}
+
+TEST_F(End2endTest, ThreadStress) {
+ ResetStub();
+ std::vector<std::thread*> threads;
+ for (int i = 0; i < 100; ++i) {
+ threads.push_back(new std::thread(SendRpc, stub_.get(), 1000));
+ }
+ for (int i = 0; i < 100; ++i) {
+ threads[i]->join();
+ delete threads[i];
+ }
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}