aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core
diff options
context:
space:
mode:
authorGravatar Yash Tibrewal <yashkt@google.com>2018-06-11 16:33:15 -0700
committerGravatar Yash Tibrewal <yashkt@google.com>2018-06-11 16:33:15 -0700
commitdddf20793269a7ba5f658ae5fdcde2c175cf196b (patch)
tree595d0fbc0c501132857b63f00f073ec6a0f54f58 /test/core
parent935ae7d01242c21f0230ead18927087a70c03e5b (diff)
parent37b292a0f7500e434c9ae41919248e2641ddc7f1 (diff)
Merge branch 'master' into epollerr
Diffstat (limited to 'test/core')
-rw-r--r--test/core/end2end/end2end_nosec_tests.cc8
-rw-r--r--test/core/end2end/end2end_tests.cc8
-rwxr-xr-xtest/core/end2end/gen_build_yaml.py1
-rwxr-xr-xtest/core/end2end/generate_tests.bzl1
-rw-r--r--test/core/end2end/tests/no_error_on_hotpath.cc246
-rw-r--r--test/core/end2end/tests/retry_server_pushback_delay.cc2
-rw-r--r--test/core/gpr/arena_test.cc2
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm201
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm344
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj338
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme56
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme61
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme78
-rw-r--r--test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme60
-rw-r--r--test/core/iomgr/ios/CFStreamTests/Info.plist22
-rw-r--r--test/core/iomgr/ios/CFStreamTests/Podfile50
-rwxr-xr-xtest/core/iomgr/ios/CFStreamTests/build_tests.sh39
-rwxr-xr-xtest/core/iomgr/ios/CFStreamTests/run_tests.sh67
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.cc23
19 files changed, 1591 insertions, 16 deletions
diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc
index 59eb643a93..a70128254a 100644
--- a/test/core/end2end/end2end_nosec_tests.cc
+++ b/test/core/end2end/end2end_nosec_tests.cc
@@ -100,6 +100,8 @@ extern void negative_deadline(grpc_end2end_test_config config);
extern void negative_deadline_pre_init(void);
extern void network_status_change(grpc_end2end_test_config config);
extern void network_status_change_pre_init(void);
+extern void no_error_on_hotpath(grpc_end2end_test_config config);
+extern void no_error_on_hotpath_pre_init(void);
extern void no_logging(grpc_end2end_test_config config);
extern void no_logging_pre_init(void);
extern void no_op(grpc_end2end_test_config config);
@@ -222,6 +224,7 @@ void grpc_end2end_tests_pre_init(void) {
max_message_length_pre_init();
negative_deadline_pre_init();
network_status_change_pre_init();
+ no_error_on_hotpath_pre_init();
no_logging_pre_init();
no_op_pre_init();
payload_pre_init();
@@ -307,6 +310,7 @@ void grpc_end2end_tests(int argc, char **argv,
max_message_length(config);
negative_deadline(config);
network_status_change(config);
+ no_error_on_hotpath(config);
no_logging(config);
no_op(config);
payload(config);
@@ -492,6 +496,10 @@ void grpc_end2end_tests(int argc, char **argv,
network_status_change(config);
continue;
}
+ if (0 == strcmp("no_error_on_hotpath", argv[i])) {
+ no_error_on_hotpath(config);
+ continue;
+ }
if (0 == strcmp("no_logging", argv[i])) {
no_logging(config);
continue;
diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc
index 9f164b4ead..bf75dd4579 100644
--- a/test/core/end2end/end2end_tests.cc
+++ b/test/core/end2end/end2end_tests.cc
@@ -102,6 +102,8 @@ extern void negative_deadline(grpc_end2end_test_config config);
extern void negative_deadline_pre_init(void);
extern void network_status_change(grpc_end2end_test_config config);
extern void network_status_change_pre_init(void);
+extern void no_error_on_hotpath(grpc_end2end_test_config config);
+extern void no_error_on_hotpath_pre_init(void);
extern void no_logging(grpc_end2end_test_config config);
extern void no_logging_pre_init(void);
extern void no_op(grpc_end2end_test_config config);
@@ -225,6 +227,7 @@ void grpc_end2end_tests_pre_init(void) {
max_message_length_pre_init();
negative_deadline_pre_init();
network_status_change_pre_init();
+ no_error_on_hotpath_pre_init();
no_logging_pre_init();
no_op_pre_init();
payload_pre_init();
@@ -311,6 +314,7 @@ void grpc_end2end_tests(int argc, char **argv,
max_message_length(config);
negative_deadline(config);
network_status_change(config);
+ no_error_on_hotpath(config);
no_logging(config);
no_op(config);
payload(config);
@@ -500,6 +504,10 @@ void grpc_end2end_tests(int argc, char **argv,
network_status_change(config);
continue;
}
+ if (0 == strcmp("no_error_on_hotpath", argv[i])) {
+ no_error_on_hotpath(config);
+ continue;
+ }
if (0 == strcmp("no_logging", argv[i])) {
no_logging(config);
continue;
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index c355fc24b5..1851214191 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -138,6 +138,7 @@ END2END_TESTS = {
'max_message_length': default_test_options._replace(cpu_cost=LOWCPU),
'negative_deadline': default_test_options,
'network_status_change': default_test_options._replace(cpu_cost=LOWCPU),
+ 'no_error_on_hotpath': default_test_options._replace(proxyable=False),
'no_logging': default_test_options._replace(traceable=False),
'no_op': default_test_options,
'payload': default_test_options,
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 11fc576165..706f4fa86d 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -134,6 +134,7 @@ END2END_TESTS = {
'max_message_length': test_options(),
'negative_deadline': test_options(),
'network_status_change': test_options(),
+ 'no_error_on_hotpath': test_options(proxyable=False),
'no_logging': test_options(traceable=False),
'no_op': test_options(),
'payload': test_options(),
diff --git a/test/core/end2end/tests/no_error_on_hotpath.cc b/test/core/end2end/tests/no_error_on_hotpath.cc
new file mode 100644
index 0000000000..7afadf7d3a
--- /dev/null
+++ b/test/core/end2end/tests/no_error_on_hotpath.cc
@@ -0,0 +1,246 @@
+/*
+ *
+ * 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 "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.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/gpr/string.h"
+#include "src/core/lib/iomgr/error.h"
+#include "test/core/end2end/cq_verifier.h"
+
+static void* tag(intptr_t 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, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+static void simple_request_body(grpc_end2end_test_config config,
+ grpc_end2end_test_fixture f) {
+ grpc_call* c;
+ grpc_call* s;
+ cq_verifier* cqv = cq_verifier_create(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 = five_seconds_from_now();
+ 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_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), 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, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ 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_OK;
+ op->data.send_status_from_server.status_details = nullptr;
+ 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), tag(102),
+ nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_OK);
+ GPR_ASSERT(GRPC_SLICE_LENGTH(details) == 0);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == call_details.flags);
+ 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);
+
+ cq_verifier_destroy(cqv);
+}
+
+static void test_no_error_on_hotpath_one_request(
+ grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f;
+
+ f = begin_test(config, "test_invoke_simple_request_with_no_error_logging",
+ nullptr, nullptr);
+ // First RPC is not considered the hotpath, since there are lots of things to
+ // set up.
+ simple_request_body(config, f);
+ grpc_disable_error_creation();
+ simple_request_body(config, f);
+ grpc_enable_error_creation();
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+static void test_no_error_on_hotpath_10_requests(
+ grpc_end2end_test_config config) {
+ int i;
+ grpc_end2end_test_fixture f = begin_test(
+ config, "test_no_error_on_hotpath_in_one_request", nullptr, nullptr);
+ // First RPC is not considered the hotpath, since there are lots of things to
+ // set up.
+ simple_request_body(config, f);
+ grpc_disable_error_creation();
+ for (i = 0; i < 10; i++) {
+ simple_request_body(config, f);
+ }
+ grpc_enable_error_creation();
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void no_error_on_hotpath(grpc_end2end_test_config config) {
+ test_no_error_on_hotpath_one_request(config);
+ test_no_error_on_hotpath_10_requests(config);
+}
+
+void no_error_on_hotpath_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_server_pushback_delay.cc b/test/core/end2end/tests/retry_server_pushback_delay.cc
index f6a979613d..221b416828 100644
--- a/test/core/end2end/tests/retry_server_pushback_delay.cc
+++ b/test/core/end2end/tests/retry_server_pushback_delay.cc
@@ -249,7 +249,7 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
retry_delay.tv_sec, retry_delay.tv_nsec);
GPR_ASSERT(retry_delay.tv_sec >= 1);
if (retry_delay.tv_sec == 1) {
- GPR_ASSERT(retry_delay.tv_nsec >= 900000000);
+ GPR_ASSERT(retry_delay.tv_nsec >= 800000000);
}
peer = grpc_call_get_peer(s);
diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc
index 111414ea3e..3e7c906591 100644
--- a/test/core/gpr/arena_test.cc
+++ b/test/core/gpr/arena_test.cc
@@ -71,7 +71,7 @@ static void test(const char* name, size_t init_size, const size_t* allocs,
static const size_t allocs_##name[] = {__VA_ARGS__}; \
test(#name, init_size, allocs_##name, GPR_ARRAY_SIZE(allocs_##name))
-#define CONCURRENT_TEST_THREADS 100
+#define CONCURRENT_TEST_THREADS 10
size_t concurrent_test_iterations() {
if (sizeof(void*) < 8) return 1000;
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm
new file mode 100644
index 0000000000..414b6c78c0
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm
@@ -0,0 +1,201 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#import <XCTest/XCTest.h>
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_CFSTREAM
+
+#include <netinet/in.h>
+
+#include <grpc/impl/codegen/sync.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/tcp_client.h"
+#include "test/core/util/test_config.h"
+
+// static int g_connections_complete = 0;
+static gpr_mu g_mu;
+static int g_connections_complete = 0;
+static grpc_endpoint* g_connecting = nullptr;
+
+static void finish_connection() {
+ gpr_mu_lock(&g_mu);
+ g_connections_complete++;
+ gpr_mu_unlock(&g_mu);
+}
+
+static void must_succeed(void* arg, grpc_error* error) {
+ GPR_ASSERT(g_connecting != nullptr);
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
+ grpc_endpoint_shutdown(g_connecting, GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called"));
+ grpc_endpoint_destroy(g_connecting);
+ g_connecting = nullptr;
+ finish_connection();
+}
+
+static void must_fail(void* arg, grpc_error* error) {
+ GPR_ASSERT(g_connecting == nullptr);
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
+ const char* error_str = grpc_error_string(error);
+ NSLog(@"%s", error_str);
+ finish_connection();
+}
+
+@interface CFStreamClientTests : XCTestCase
+
+@end
+
+@implementation CFStreamClientTests
+
++ (void)setUp {
+ grpc_init();
+ gpr_mu_init(&g_mu);
+}
+
++ (void)tearDown {
+ grpc_shutdown();
+}
+
+- (void)testSucceeds {
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr);
+ int svr_fd;
+ int r;
+ int connections_complete_before;
+ grpc_closure done;
+ grpc_core::ExecCtx exec_ctx;
+
+ gpr_log(GPR_DEBUG, "test_succeeds");
+
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+
+ /* create a dummy server */
+ svr_fd = socket(AF_INET, SOCK_STREAM, 0);
+ GPR_ASSERT(svr_fd >= 0);
+ GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr.len));
+ GPR_ASSERT(0 == listen(svr_fd, 1));
+
+ gpr_mu_lock(&g_mu);
+ connections_complete_before = g_connections_complete;
+ gpr_mu_unlock(&g_mu);
+
+ /* connect to it */
+ GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0);
+ GRPC_CLOSURE_INIT(&done, must_succeed, nullptr, grpc_schedule_on_exec_ctx);
+ grpc_tcp_client_connect(&done, &g_connecting, nullptr, nullptr, &resolved_addr,
+ GRPC_MILLIS_INF_FUTURE);
+
+ /* await the connection */
+ do {
+ resolved_addr.len = sizeof(addr);
+ r = accept(svr_fd, reinterpret_cast<struct sockaddr*>(addr),
+ reinterpret_cast<socklen_t*>(&resolved_addr.len));
+ } while (r == -1 && errno == EINTR);
+ GPR_ASSERT(r >= 0);
+ close(r);
+
+ grpc_core::ExecCtx::Get()->Flush();
+
+ /* wait for the connection callback to finish */
+ gpr_mu_lock(&g_mu);
+ NSDate* deadline = [NSDate dateWithTimeIntervalSinceNow:5];
+ while (connections_complete_before == g_connections_complete) {
+ gpr_mu_unlock(&g_mu);
+ [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:deadline];
+ gpr_mu_lock(&g_mu);
+ }
+ XCTAssertGreaterThan(g_connections_complete, connections_complete_before);
+
+ gpr_mu_unlock(&g_mu);
+}
+
+- (void)testFails {
+ grpc_core::ExecCtx exec_ctx;
+
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr);
+ int connections_complete_before;
+ grpc_closure done;
+ int svr_fd;
+
+ gpr_log(GPR_DEBUG, "test_fails");
+
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
+
+ svr_fd = socket(AF_INET, SOCK_STREAM, 0);
+ GPR_ASSERT(svr_fd >= 0);
+ GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr.len));
+ GPR_ASSERT(0 == listen(svr_fd, 1));
+ GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0);
+ close(svr_fd);
+
+ gpr_mu_lock(&g_mu);
+ connections_complete_before = g_connections_complete;
+ gpr_mu_unlock(&g_mu);
+
+ /* connect to a broken address */
+ GRPC_CLOSURE_INIT(&done, must_fail, nullptr, grpc_schedule_on_exec_ctx);
+ grpc_tcp_client_connect(&done, &g_connecting, nullptr, nullptr, &resolved_addr,
+ GRPC_MILLIS_INF_FUTURE);
+
+ grpc_core::ExecCtx::Get()->Flush();
+
+ /* wait for the connection callback to finish */
+ gpr_mu_lock(&g_mu);
+ NSDate* deadline = [NSDate dateWithTimeIntervalSinceNow:5];
+ while (g_connections_complete == connections_complete_before) {
+ gpr_mu_unlock(&g_mu);
+ [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:deadline];
+ gpr_mu_lock(&g_mu);
+ }
+
+ XCTAssertGreaterThan(g_connections_complete, connections_complete_before);
+
+ gpr_mu_unlock(&g_mu);
+}
+
+@end
+
+#else // GRPC_CFSTREAM
+
+// Dummy test suite
+@interface CFStreamClientTests : XCTestCase
+
+@end
+
+@implementation CFStreamClientTests
+
+- (void)setUp {
+ [super setUp];
+}
+
+- (void)tearDown {
+ [super tearDown];
+}
+
+@end
+
+#endif // GRPC_CFSTREAM
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm
new file mode 100644
index 0000000000..fbc34c74d6
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm
@@ -0,0 +1,344 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#import <XCTest/XCTest.h>
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_CFSTREAM
+
+#include <netinet/in.h>
+
+#include <grpc/impl/codegen/sync.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/tcp_client.h"
+#include "test/core/util/test_config.h"
+
+static const int kConnectTimeout = 5;
+static const int kWriteTimeout = 5;
+static const int kReadTimeout = 5;
+
+static const int kBufferSize = 10000;
+
+static const int kRunLoopTimeout = 1;
+
+static void set_atm(void *arg, grpc_error *error) {
+ gpr_atm *p = static_cast<gpr_atm *>(arg);
+ gpr_atm_full_cas(p, -1, reinterpret_cast<gpr_atm>(error));
+}
+
+static void init_event_closure(grpc_closure *closure, gpr_atm *atm) {
+ *atm = -1;
+ GRPC_CLOSURE_INIT(closure, set_atm, static_cast<void *>(atm), grpc_schedule_on_exec_ctx);
+}
+
+static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const char *buffer,
+ size_t buffer_len) {
+ if (slices->length != buffer_len) {
+ return false;
+ }
+
+ for (int i = 0; i < slices->count; i++) {
+ grpc_slice slice = slices->slices[i];
+ if (0 != memcmp(buffer, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice))) {
+ return false;
+ }
+ buffer += GRPC_SLICE_LENGTH(slice);
+ }
+
+ return true;
+}
+
+@interface CFStreamEndpointTests : XCTestCase
+
+@end
+
+@implementation CFStreamEndpointTests {
+ grpc_endpoint *ep_;
+ int svr_fd_;
+}
+
+- (BOOL)waitForEvent:(gpr_atm *)event timeout:(int)timeout {
+ grpc_core::ExecCtx::Get()->Flush();
+
+ NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:kConnectTimeout];
+ while (gpr_atm_acq_load(event) == -1 && [deadline timeIntervalSinceNow] > 0) {
+ NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:kRunLoopTimeout];
+ [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:deadline];
+ }
+
+ return (gpr_atm_acq_load(event) != -1);
+}
+
++ (void)setUp {
+ grpc_init();
+}
+
++ (void)tearDown {
+ grpc_shutdown();
+}
+
+- (void)setUp {
+ self.continueAfterFailure = NO;
+
+ // Set up CFStream connection before testing the endpoint
+
+ grpc_core::ExecCtx exec_ctx;
+
+ grpc_resolved_address resolved_addr;
+ struct sockaddr_in *addr = reinterpret_cast<struct sockaddr_in *>(resolved_addr.addr);
+ int svr_fd;
+ int r;
+ gpr_atm connected = -1;
+ grpc_closure done;
+
+ gpr_log(GPR_DEBUG, "test_succeeds");
+
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+
+ /* create a dummy server */
+ svr_fd = socket(AF_INET, SOCK_STREAM, 0);
+ XCTAssertGreaterThanOrEqual(svr_fd, 0);
+ XCTAssertEqual(bind(svr_fd, (struct sockaddr *)addr, (socklen_t)resolved_addr.len), 0);
+ XCTAssertEqual(listen(svr_fd, 1), 0);
+
+ /* connect to it */
+ XCTAssertEqual(getsockname(svr_fd, (struct sockaddr *)addr, (socklen_t *)&resolved_addr.len), 0);
+ init_event_closure(&done, &connected);
+ grpc_tcp_client_connect(&done, &ep_, nullptr, nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE);
+
+ /* await the connection */
+ do {
+ resolved_addr.len = sizeof(addr);
+ r = accept(svr_fd, reinterpret_cast<struct sockaddr *>(addr),
+ reinterpret_cast<socklen_t *>(&resolved_addr.len));
+ } while (r == -1 && errno == EINTR);
+ XCTAssertGreaterThanOrEqual(r, 0);
+ svr_fd_ = r;
+
+ /* wait for the connection callback to finish */
+ XCTAssertEqual([self waitForEvent:&connected timeout:kConnectTimeout], YES);
+ XCTAssertEqual(reinterpret_cast<grpc_error *>(connected), GRPC_ERROR_NONE);
+}
+
+- (void)tearDown {
+ grpc_core::ExecCtx exec_ctx;
+ close(svr_fd_);
+ grpc_endpoint_destroy(ep_);
+}
+
+- (void)testReadWrite {
+ grpc_core::ExecCtx exec_ctx;
+
+ gpr_atm read;
+ grpc_closure read_done;
+ grpc_slice_buffer read_slices;
+ grpc_slice_buffer read_one_slice;
+ gpr_atm write;
+ grpc_closure write_done;
+ grpc_slice_buffer write_slices;
+
+ grpc_slice slice;
+ char write_buffer[kBufferSize];
+ char read_buffer[kBufferSize];
+ size_t recv_size = 0;
+
+ grpc_slice_buffer_init(&write_slices);
+ slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize);
+ grpc_slice_buffer_add(&write_slices, slice);
+ init_event_closure(&write_done, &write);
+ grpc_endpoint_write(ep_, &write_slices, &write_done);
+
+ XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES);
+ XCTAssertEqual(reinterpret_cast<grpc_error *>(write), GRPC_ERROR_NONE);
+
+ while (recv_size < kBufferSize) {
+ ssize_t size = recv(svr_fd_, read_buffer, kBufferSize, 0);
+ XCTAssertGreaterThanOrEqual(size, 0);
+ recv_size += size;
+ }
+
+ XCTAssertEqual(recv_size, kBufferSize);
+ XCTAssertEqual(memcmp(read_buffer, write_buffer, kBufferSize), 0);
+ ssize_t send_size = send(svr_fd_, read_buffer, kBufferSize, 0);
+ XCTAssertGreaterThanOrEqual(send_size, 0);
+
+ grpc_slice_buffer_init(&read_slices);
+ grpc_slice_buffer_init(&read_one_slice);
+ while (read_slices.length < kBufferSize) {
+ init_event_closure(&read_done, &read);
+ grpc_endpoint_read(ep_, &read_one_slice, &read_done);
+ XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES);
+ XCTAssertEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE);
+ grpc_slice_buffer_move_into(&read_one_slice, &read_slices);
+ XCTAssertLessThanOrEqual(read_slices.length, kBufferSize);
+ }
+ XCTAssertTrue(compare_slice_buffer_with_buffer(&read_slices, read_buffer, kBufferSize));
+
+ grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE);
+ grpc_slice_buffer_reset_and_unref(&read_slices);
+ grpc_slice_buffer_reset_and_unref(&write_slices);
+ grpc_slice_buffer_reset_and_unref(&read_one_slice);
+}
+
+- (void)testShutdownBeforeRead {
+ grpc_core::ExecCtx exec_ctx;
+
+ gpr_atm read;
+ grpc_closure read_done;
+ grpc_slice_buffer read_slices;
+ gpr_atm write;
+ grpc_closure write_done;
+ grpc_slice_buffer write_slices;
+
+ grpc_slice slice;
+ char write_buffer[kBufferSize];
+ char read_buffer[kBufferSize];
+ size_t recv_size = 0;
+
+ grpc_slice_buffer_init(&read_slices);
+ init_event_closure(&read_done, &read);
+ grpc_endpoint_read(ep_, &read_slices, &read_done);
+
+ grpc_slice_buffer_init(&write_slices);
+ slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize);
+ grpc_slice_buffer_add(&write_slices, slice);
+ init_event_closure(&write_done, &write);
+ grpc_endpoint_write(ep_, &write_slices, &write_done);
+
+ XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES);
+ XCTAssertEqual(reinterpret_cast<grpc_error *>(write), GRPC_ERROR_NONE);
+
+ while (recv_size < kBufferSize) {
+ ssize_t size = recv(svr_fd_, read_buffer, kBufferSize, 0);
+ XCTAssertGreaterThanOrEqual(size, 0);
+ recv_size += size;
+ }
+
+ XCTAssertEqual(recv_size, kBufferSize);
+ XCTAssertEqual(memcmp(read_buffer, write_buffer, kBufferSize), 0);
+
+ XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], NO);
+
+ grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE);
+
+ grpc_core::ExecCtx::Get()->Flush();
+ XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES);
+ XCTAssertNotEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE);
+
+ grpc_slice_buffer_reset_and_unref(&read_slices);
+ grpc_slice_buffer_reset_and_unref(&write_slices);
+}
+
+- (void)testRemoteClosed {
+ grpc_core::ExecCtx exec_ctx;
+
+ gpr_atm read;
+ grpc_closure read_done;
+ grpc_slice_buffer read_slices;
+ gpr_atm write;
+ grpc_closure write_done;
+ grpc_slice_buffer write_slices;
+
+ grpc_slice slice;
+ char write_buffer[kBufferSize];
+ char read_buffer[kBufferSize];
+ size_t recv_size = 0;
+
+ init_event_closure(&read_done, &read);
+ grpc_slice_buffer_init(&read_slices);
+ grpc_endpoint_read(ep_, &read_slices, &read_done);
+
+ grpc_slice_buffer_init(&write_slices);
+ slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize);
+ grpc_slice_buffer_add(&write_slices, slice);
+ init_event_closure(&write_done, &write);
+ grpc_endpoint_write(ep_, &write_slices, &write_done);
+
+ XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES);
+ XCTAssertEqual(reinterpret_cast<grpc_error *>(write), GRPC_ERROR_NONE);
+
+ while (recv_size < kBufferSize) {
+ ssize_t size = recv(svr_fd_, read_buffer, kBufferSize, 0);
+ XCTAssertGreaterThanOrEqual(size, 0);
+ recv_size += size;
+ }
+
+ XCTAssertEqual(recv_size, kBufferSize);
+ XCTAssertEqual(memcmp(read_buffer, write_buffer, kBufferSize), 0);
+
+ close(svr_fd_);
+
+ XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES);
+ XCTAssertNotEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE);
+
+ grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE);
+ grpc_slice_buffer_reset_and_unref(&read_slices);
+ grpc_slice_buffer_reset_and_unref(&write_slices);
+}
+
+- (void)testRemoteReset {
+ grpc_core::ExecCtx exec_ctx;
+
+ gpr_atm read;
+ grpc_closure read_done;
+ grpc_slice_buffer read_slices;
+
+ init_event_closure(&read_done, &read);
+ grpc_slice_buffer_init(&read_slices);
+ grpc_endpoint_read(ep_, &read_slices, &read_done);
+
+ struct linger so_linger;
+ so_linger.l_onoff = 1;
+ so_linger.l_linger = 0;
+ setsockopt(svr_fd_, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
+
+ close(svr_fd_);
+
+ XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES);
+ XCTAssertNotEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE);
+
+ grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE);
+ grpc_slice_buffer_reset_and_unref(&read_slices);
+}
+
+@end
+
+#else // GRPC_CFSTREAM
+
+// Dummy test suite
+@interface CFStreamEndpointTests : XCTestCase
+@end
+
+@implementation CFStreamEndpointTests
+- (void)setUp {
+ [super setUp];
+}
+
+- (void)tearDown {
+ [super tearDown];
+}
+
+@end
+
+#endif // GRPC_CFSTREAM
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..2218f129ae
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj
@@ -0,0 +1,338 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 48;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 5E143B892069D72200715A6E /* CFStreamClientTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B882069D72200715A6E /* CFStreamClientTests.mm */; };
+ 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5E143B8A2069D72700715A6E /* Info.plist */; };
+ 5E143B8E206C5B9A00715A6E /* CFStreamEndpointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */; };
+ 604EA96D9CD477A8EA411BDF /* libPods-CFStreamTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 5E143B792069D67300715A6E /* CFStreamTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CFStreamTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5E143B882069D72200715A6E /* CFStreamClientTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CFStreamClientTests.mm; sourceTree = "<group>"; };
+ 5E143B8A2069D72700715A6E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CFStreamEndpointTests.mm; sourceTree = "<group>"; };
+ 8CB4409E07E180CCA59987DF /* Pods-CFStreamTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CFStreamTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CFStreamTests/Pods-CFStreamTests.release.xcconfig"; sourceTree = "<group>"; };
+ 9E3FAF9DA6B98ED4FE6D6848 /* Pods-CFStreamTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CFStreamTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CFStreamTests/Pods-CFStreamTests.debug.xcconfig"; sourceTree = "<group>"; };
+ AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CFStreamTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 5E143B762069D67300715A6E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 604EA96D9CD477A8EA411BDF /* libPods-CFStreamTests.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 5E143B582069D67300715A6E = {
+ isa = PBXGroup;
+ children = (
+ 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */,
+ 5E143B8A2069D72700715A6E /* Info.plist */,
+ 5E143B882069D72200715A6E /* CFStreamClientTests.mm */,
+ 5E143B622069D67300715A6E /* Products */,
+ A331D95F7F230B507FBF6D22 /* Pods */,
+ 6AC36F6C5DB5CA8F717D1B67 /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 5E143B622069D67300715A6E /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 5E143B792069D67300715A6E /* CFStreamTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 6AC36F6C5DB5CA8F717D1B67 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ A331D95F7F230B507FBF6D22 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 9E3FAF9DA6B98ED4FE6D6848 /* Pods-CFStreamTests.debug.xcconfig */,
+ 8CB4409E07E180CCA59987DF /* Pods-CFStreamTests.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 5E143B782069D67300715A6E /* CFStreamTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5E143B852069D67300715A6E /* Build configuration list for PBXNativeTarget "CFStreamTests" */;
+ buildPhases = (
+ 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */,
+ 5E143B752069D67300715A6E /* Sources */,
+ 5E143B762069D67300715A6E /* Frameworks */,
+ 5E143B772069D67300715A6E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CFStreamTests;
+ productName = CFStreamTestsTests;
+ productReference = 5E143B792069D67300715A6E /* CFStreamTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 5E143B592069D67300715A6E /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0920;
+ ORGANIZATIONNAME = gRPC;
+ TargetAttributes = {
+ 5E143B782069D67300715A6E = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = 5E143B5C2069D67300715A6E /* Build configuration list for PBXProject "CFStreamTests" */;
+ compatibilityVersion = "Xcode 8.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 5E143B582069D67300715A6E;
+ productRefGroup = 5E143B622069D67300715A6E /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 5E143B782069D67300715A6E /* CFStreamTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 5E143B772069D67300715A6E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-CFStreamTests-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 5E143B752069D67300715A6E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5E143B892069D72200715A6E /* CFStreamClientTests.mm in Sources */,
+ 5E143B8E206C5B9A00715A6E /* CFStreamEndpointTests.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 5E143B802069D67300715A6E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 5E143B812069D67300715A6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 5E143B862069D67300715A6E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9E3FAF9DA6B98ED4FE6D6848 /* Pods-CFStreamTests.debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(inherited)",
+ "COCOAPODS=1",
+ "$(inherited)",
+ "PB_FIELD_32BIT=1",
+ "PB_NO_PACKED_STRUCTS=1",
+ "GRPC_CFSTREAM=1",
+ );
+ INFOPLIST_FILE = Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CFStreamTestsTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ USER_HEADER_SEARCH_PATHS = ../../../../..;
+ };
+ name = Debug;
+ };
+ 5E143B872069D67300715A6E /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8CB4409E07E180CCA59987DF /* Pods-CFStreamTests.release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CFStreamTestsTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ USER_HEADER_SEARCH_PATHS = ../../../../..;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 5E143B5C2069D67300715A6E /* Build configuration list for PBXProject "CFStreamTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5E143B802069D67300715A6E /* Debug */,
+ 5E143B812069D67300715A6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5E143B852069D67300715A6E /* Build configuration list for PBXNativeTarget "CFStreamTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5E143B862069D67300715A6E /* Debug */,
+ 5E143B872069D67300715A6E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 5E143B592069D67300715A6E /* Project object */;
+}
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme
new file mode 100644
index 0000000000..25d6f780a1
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5E143B782069D67300715A6E"
+ BuildableName = "CFStreamTests.xctest"
+ BlueprintName = "CFStreamTests"
+ ReferencedContainer = "container:CFStreamTests.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme
new file mode 100644
index 0000000000..6c5c43aa72
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ enableAddressSanitizer = "YES"
+ enableASanStackUseAfterReturn = "YES"
+ language = ""
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5E143B782069D67300715A6E"
+ BuildableName = "CFStreamTests.xctest"
+ BlueprintName = "CFStreamTests"
+ ReferencedContainer = "container:CFStreamTests.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ enableASanStackUseAfterReturn = "YES"
+ language = ""
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme
new file mode 100644
index 0000000000..3e39ff84d0
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5E143B782069D67300715A6E"
+ BuildableName = "CFStreamTests.xctest"
+ BlueprintName = "CFStreamTests"
+ ReferencedContainer = "container:CFStreamTests.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ <AdditionalOption
+ key = "DYLD_INSERT_LIBRARIES"
+ value = "/usr/lib/libgmalloc.dylib"
+ isEnabled = "YES">
+ </AdditionalOption>
+ <AdditionalOption
+ key = "NSZombieEnabled"
+ value = "YES"
+ isEnabled = "YES">
+ </AdditionalOption>
+ <AdditionalOption
+ key = "MallocGuardEdges"
+ value = ""
+ isEnabled = "YES">
+ </AdditionalOption>
+ <AdditionalOption
+ key = "MallocScribble"
+ value = ""
+ isEnabled = "YES">
+ </AdditionalOption>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme
new file mode 100644
index 0000000000..f0bde837c5
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ enableThreadSanitizer = "YES"
+ language = ""
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5E143B782069D67300715A6E"
+ BuildableName = "CFStreamTests.xctest"
+ BlueprintName = "CFStreamTests"
+ ReferencedContainer = "container:CFStreamTests.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ stopOnEveryThreadSanitizerIssue = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/test/core/iomgr/ios/CFStreamTests/Info.plist b/test/core/iomgr/ios/CFStreamTests/Info.plist
new file mode 100644
index 0000000000..6c40a6cd0c
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/test/core/iomgr/ios/CFStreamTests/Podfile b/test/core/iomgr/ios/CFStreamTests/Podfile
new file mode 100644
index 0000000000..630168a363
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/Podfile
@@ -0,0 +1,50 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+# Location of gRPC's repo root relative to this file.
+GRPC_LOCAL_SRC = '../../../../..'
+
+# Install the dependencies in the main target plus all test targets.
+target 'CFStreamTests' do
+ pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC
+end
+
+pre_install do |installer|
+ # This is the gRPC-Core podspec object, as initialized by its podspec file.
+ grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec
+
+ # Copied from gRPC-Core.podspec, except for the adjusted src_root:
+ src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}"
+ grpc_core_spec.pod_target_xcconfig = {
+ 'GRPC_SRC_ROOT' => src_root,
+ 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
+ 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
+ # If we don't set these two settings, `include/grpc/support/time.h` and
+ # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+ # build.
+ 'USE_HEADERMAP' => 'NO',
+ 'ALWAYS_SEARCH_USER_PATHS' => 'NO',
+ }
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES'
+ end
+
+ # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include
+ # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core'
+ # and require the same error suppresion.
+ if target.name.start_with?('gRPC-Core')
+ target.build_configurations.each do |config|
+ # TODO(zyc): Remove this setting after the issue is resolved
+ # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void
+ # function" warning
+ config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO'
+ end
+ end
+ end
+end
diff --git a/test/core/iomgr/ios/CFStreamTests/build_tests.sh b/test/core/iomgr/ios/CFStreamTests/build_tests.sh
new file mode 100755
index 0000000000..d23f26f5db
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/build_tests.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# 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.
+
+# Don't run this script standalone. Instead, run from the repository root:
+# ./tools/run_tests/run_tests.py -l objc
+
+set -e
+
+# CocoaPods requires the terminal to be using UTF-8 encoding.
+export LANG=en_US.UTF-8
+
+cd "$(dirname "$0")"
+
+hash pod 2>/dev/null || { echo >&2 "Cocoapods needs to be installed."; exit 1; }
+hash xcodebuild 2>/dev/null || {
+ echo >&2 "XCode command-line tools need to be installed."
+ exit 1
+}
+
+# clean the directory
+rm -rf Pods
+rm -rf CFStreamTests.xcworkspace
+rm -f Podfile.lock
+
+echo "TIME: $(date)"
+pod install
+
diff --git a/test/core/iomgr/ios/CFStreamTests/run_tests.sh b/test/core/iomgr/ios/CFStreamTests/run_tests.sh
new file mode 100755
index 0000000000..1045ec10a8
--- /dev/null
+++ b/test/core/iomgr/ios/CFStreamTests/run_tests.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# 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.
+
+# Don't run this script standalone. Instead, run from the repository root:
+# ./tools/run_tests/run_tests.py -l objc
+
+set -ev
+
+cd "$(dirname "$0")"
+
+echo "TIME: $(date)"
+
+XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )'
+
+xcodebuild \
+ -workspace CFStreamTests.xcworkspace \
+ -scheme CFStreamTests \
+ -destination name="iPhone 8" \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
+
+echo "TIME: $(date)"
+
+xcodebuild \
+ -workspace CFStreamTests.xcworkspace \
+ -scheme CFStreamTests_Asan \
+ -destination name="iPhone 8" \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
+
+echo "TIME: $(date)"
+
+xcodebuild \
+ -workspace CFStreamTests.xcworkspace \
+ -scheme CFStreamTests_Tsan \
+ -destination name="iPhone 8" \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
+
+echo "TIME: $(date)"
+
+xcodebuild \
+ -workspace CFStreamTests.xcworkspace \
+ -scheme CFStreamTests_Msan \
+ -destination name="iPhone 8" \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc
index d3ba50a91c..2a57198ab6 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.cc
+++ b/test/core/transport/chttp2/hpack_encoder_test.cc
@@ -160,6 +160,8 @@ static void encode_int_to_str(int i, char* p) {
}
static void test_decode_table_overflow() {
+ // Decrease the default table size to make decode table overflow easier.
+ grpc_chttp2_hpack_compressor_set_max_table_size(&g_compressor, 1024);
int i;
char key[3], value[3];
char* expect;
@@ -170,27 +172,20 @@ static void test_decode_table_overflow() {
false,
};
- for (i = 0; i < 114; i++) {
+ for (i = 0; i < 29; i++) {
encode_int_to_str(i, key);
encode_int_to_str(i + 1, value);
-
- if (i + 61 >= 127) {
+ if (i == 0) {
+ // 3fe107 corresponds to the table size update.
gpr_asprintf(&expect,
- "000009 0104 deadbeef ff%02x 40 02%02x%02x 02%02x%02x",
- i + 61 - 127, key[0], key[1], value[0], value[1]);
- } else if (i > 0) {
+ "00000a 0104 deadbeef 3fe107 40 02%02x%02x 02%02x%02x",
+ key[0], key[1], value[0], value[1]);
+ verify(params, expect, 1, key, value);
+ } else {
gpr_asprintf(&expect,
"000008 0104 deadbeef %02x 40 02%02x%02x 02%02x%02x",
0x80 + 61 + i, key[0], key[1], value[0], value[1]);
- } else {
- gpr_asprintf(&expect, "000007 0104 deadbeef 40 02%02x%02x 02%02x%02x",
- key[0], key[1], value[0], value[1]);
- }
-
- if (i > 0) {
verify(params, expect, 2, "aa", "ba", key, value);
- } else {
- verify(params, expect, 1, key, value);
}
gpr_free(expect);
}