aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile102
-rw-r--r--PYTHON-MANIFEST.in2
-rw-r--r--build.yaml33
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c57
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_data.c24
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_data.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_rst_stream.c8
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_rst_stream.h4
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_window_update.c12
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_window_update.h4
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.c6
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.c3
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h8
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.c34
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.c42
-rw-r--r--src/core/lib/surface/call.c5
-rw-r--r--src/core/lib/transport/transport.c19
-rw-r--r--src/core/lib/transport/transport.h20
-rw-r--r--src/python/grpcio/precompiled.py3
-rw-r--r--test/core/internal_api_canaries/iomgr.c115
-rw-r--r--test/core/internal_api_canaries/support.c58
-rw-r--r--test/core/internal_api_canaries/transport.c81
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.c7
-rwxr-xr-xtools/gce/create_interop_worker.sh64
-rwxr-xr-xtools/run_tests/build_python.sh1
-rwxr-xr-xtools/run_tests/jobset.py7
-rwxr-xr-xtools/run_tests/performance/build_performance.sh40
-rwxr-xr-xtools/run_tests/performance/remote_host_build.sh36
-rwxr-xr-xtools/run_tests/performance/remote_host_prepare.sh44
-rwxr-xr-xtools/run_tests/run_performance_tests.py353
-rwxr-xr-xtools/run_tests/run_python.sh1
-rwxr-xr-xtools/run_tests/run_tests.py39
-rw-r--r--tools/run_tests/sources_and_headers.json48
-rw-r--r--vsprojects/build_vs2010.bat2
-rw-r--r--vsprojects/build_vs2013.bat2
-rw-r--r--vsprojects/build_vs2015.bat2
-rw-r--r--vsprojects/buildtests_c.sln81
-rw-r--r--vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj199
-rw-r--r--vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj.filters21
-rw-r--r--vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj199
-rw-r--r--vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj.filters21
-rw-r--r--vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj199
-rw-r--r--vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj.filters21
44 files changed, 1959 insertions, 72 deletions
diff --git a/Makefile b/Makefile
index 99c91aa32e..175530cbd0 100644
--- a/Makefile
+++ b/Makefile
@@ -944,6 +944,9 @@ httpcli_format_request_test: $(BINDIR)/$(CONFIG)/httpcli_format_request_test
httpcli_test: $(BINDIR)/$(CONFIG)/httpcli_test
httpscli_test: $(BINDIR)/$(CONFIG)/httpscli_test
init_test: $(BINDIR)/$(CONFIG)/init_test
+internal_api_canary_iomgr_test: $(BINDIR)/$(CONFIG)/internal_api_canary_iomgr_test
+internal_api_canary_support_test: $(BINDIR)/$(CONFIG)/internal_api_canary_support_test
+internal_api_canary_transport_test: $(BINDIR)/$(CONFIG)/internal_api_canary_transport_test
invalid_call_argument_test: $(BINDIR)/$(CONFIG)/invalid_call_argument_test
json_fuzzer_test: $(BINDIR)/$(CONFIG)/json_fuzzer_test
json_rewrite: $(BINDIR)/$(CONFIG)/json_rewrite
@@ -1248,6 +1251,9 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/httpcli_test \
$(BINDIR)/$(CONFIG)/httpscli_test \
$(BINDIR)/$(CONFIG)/init_test \
+ $(BINDIR)/$(CONFIG)/internal_api_canary_iomgr_test \
+ $(BINDIR)/$(CONFIG)/internal_api_canary_support_test \
+ $(BINDIR)/$(CONFIG)/internal_api_canary_transport_test \
$(BINDIR)/$(CONFIG)/invalid_call_argument_test \
$(BINDIR)/$(CONFIG)/json_rewrite \
$(BINDIR)/$(CONFIG)/json_rewrite_test \
@@ -8068,6 +8074,102 @@ endif
endif
+INTERNAL_API_CANARY_IOMGR_TEST_SRC = \
+ test/core/internal_api_canaries/iomgr.c \
+
+INTERNAL_API_CANARY_IOMGR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTERNAL_API_CANARY_IOMGR_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/internal_api_canary_iomgr_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/internal_api_canary_iomgr_test: $(INTERNAL_API_CANARY_IOMGR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(INTERNAL_API_CANARY_IOMGR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/internal_api_canary_iomgr_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/internal_api_canaries/iomgr.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_internal_api_canary_iomgr_test: $(INTERNAL_API_CANARY_IOMGR_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(INTERNAL_API_CANARY_IOMGR_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+INTERNAL_API_CANARY_SUPPORT_TEST_SRC = \
+ test/core/internal_api_canaries/iomgr.c \
+
+INTERNAL_API_CANARY_SUPPORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTERNAL_API_CANARY_SUPPORT_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/internal_api_canary_support_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/internal_api_canary_support_test: $(INTERNAL_API_CANARY_SUPPORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(INTERNAL_API_CANARY_SUPPORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/internal_api_canary_support_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/internal_api_canaries/iomgr.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_internal_api_canary_support_test: $(INTERNAL_API_CANARY_SUPPORT_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(INTERNAL_API_CANARY_SUPPORT_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+INTERNAL_API_CANARY_TRANSPORT_TEST_SRC = \
+ test/core/internal_api_canaries/iomgr.c \
+
+INTERNAL_API_CANARY_TRANSPORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTERNAL_API_CANARY_TRANSPORT_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/internal_api_canary_transport_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/internal_api_canary_transport_test: $(INTERNAL_API_CANARY_TRANSPORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(INTERNAL_API_CANARY_TRANSPORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/internal_api_canary_transport_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/internal_api_canaries/iomgr.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_internal_api_canary_transport_test: $(INTERNAL_API_CANARY_TRANSPORT_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(INTERNAL_API_CANARY_TRANSPORT_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
INVALID_CALL_ARGUMENT_TEST_SRC = \
test/core/end2end/invalid_call_argument_test.c \
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index 25aba87c18..534f4c1251 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -2,8 +2,10 @@ recursive-include src/python/grpcio/grpc *.c *.h *.py *.pyx *.pxd *.pxi *.python
recursive-exclude src/python/grpcio/grpc/_cython *.so *.pyd
graft src/python/grpcio/tests
graft src/core
+graft src/boringssl
graft include/grpc
graft third_party/boringssl
+graft third_party/nanopb
graft third_party/zlib
include src/python/grpcio/commands.py
include src/python/grpcio/grpc_version.py
diff --git a/build.yaml b/build.yaml
index fd8acc3f9e..65ea6ff510 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1674,6 +1674,39 @@ targets:
- grpc
- gpr_test_util
- gpr
+- name: internal_api_canary_iomgr_test
+ build: test
+ run: false
+ language: c
+ src:
+ - test/core/internal_api_canaries/iomgr.c
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+- name: internal_api_canary_support_test
+ build: test
+ run: false
+ language: c
+ src:
+ - test/core/internal_api_canaries/iomgr.c
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+- name: internal_api_canary_transport_test
+ build: test
+ run: false
+ language: c
+ src:
+ - test/core/internal_api_canaries/iomgr.c
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
- name: invalid_call_argument_test
build: test
language: c
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 0a307a73a6..b835e74c56 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -758,23 +758,35 @@ static void maybe_start_some_streams(
}
}
+#define CLOSURE_BARRIER_STATS_BIT (1 << 0)
+#define CLOSURE_BARRIER_FAILURE_BIT (1 << 1)
+#define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16)
+
static grpc_closure *add_closure_barrier(grpc_closure *closure) {
- closure->final_data += 2;
+ closure->final_data += CLOSURE_BARRIER_FIRST_REF_BIT;
return closure;
}
void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_stream_global *stream_global,
grpc_closure **pclosure, int success) {
grpc_closure *closure = *pclosure;
if (closure == NULL) {
return;
}
- closure->final_data -= 2;
+ closure->final_data -= CLOSURE_BARRIER_FIRST_REF_BIT;
if (!success) {
- closure->final_data |= 1;
+ closure->final_data |= CLOSURE_BARRIER_FAILURE_BIT;
}
- if (closure->final_data < 2) {
- grpc_exec_ctx_enqueue(exec_ctx, closure, closure->final_data == 0, NULL);
+ if (closure->final_data < CLOSURE_BARRIER_FIRST_REF_BIT) {
+ if (closure->final_data & CLOSURE_BARRIER_STATS_BIT) {
+ grpc_transport_move_stats(&stream_global->stats,
+ stream_global->collecting_stats);
+ stream_global->collecting_stats = NULL;
+ }
+ grpc_exec_ctx_enqueue(
+ exec_ctx, closure,
+ (closure->final_data & CLOSURE_BARRIER_FAILURE_BIT) == 0, NULL);
}
*pclosure = NULL;
}
@@ -807,7 +819,13 @@ static void perform_stream_op_locked(
}
/* use final_data as a barrier until enqueue time; the inital counter is
dropped at the end of this function */
- on_complete->final_data = 2;
+ on_complete->final_data = CLOSURE_BARRIER_FIRST_REF_BIT;
+
+ if (op->collect_stats != NULL) {
+ GPR_ASSERT(stream_global->collecting_stats == NULL);
+ stream_global->collecting_stats = op->collect_stats;
+ on_complete->final_data |= CLOSURE_BARRIER_STATS_BIT;
+ }
if (op->cancel_with_status != GRPC_STATUS_OK) {
cancel_from_api(exec_ctx, transport_global, stream_global,
@@ -840,7 +858,8 @@ static void perform_stream_op_locked(
}
} else {
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_initial_metadata_finished, 0);
+ exec_ctx, stream_global,
+ &stream_global->send_initial_metadata_finished, 0);
}
}
@@ -850,7 +869,7 @@ static void perform_stream_op_locked(
stream_global->send_message_finished = add_closure_barrier(on_complete);
if (stream_global->write_closed) {
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_message_finished, 0);
+ exec_ctx, stream_global, &stream_global->send_message_finished, 0);
} else {
stream_global->send_message = op->send_message;
if (stream_global->id != 0) {
@@ -870,7 +889,8 @@ static void perform_stream_op_locked(
}
if (stream_global->write_closed) {
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_trailing_metadata_finished,
+ exec_ctx, stream_global,
+ &stream_global->send_trailing_metadata_finished,
grpc_metadata_batch_is_empty(op->send_trailing_metadata));
} else if (stream_global->id != 0) {
/* TODO(ctiller): check if there's flow control for any outstanding
@@ -909,7 +929,7 @@ static void perform_stream_op_locked(
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
}
- grpc_chttp2_complete_closure_step(exec_ctx, &on_complete, 1);
+ grpc_chttp2_complete_closure_step(exec_ctx, stream_global, &on_complete, 1);
GPR_TIMER_END("perform_stream_op_locked", 0);
}
@@ -1080,7 +1100,8 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
&stream_global->received_trailing_metadata,
stream_global->recv_trailing_metadata);
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->recv_trailing_metadata_finished, 1);
+ exec_ctx, stream_global,
+ &stream_global->recv_trailing_metadata_finished, 1);
}
}
}
@@ -1131,7 +1152,8 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx,
&transport_global->qbuf,
grpc_chttp2_rst_stream_create(
stream_global->id,
- (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status)));
+ (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status),
+ &stream_global->stats.outgoing));
}
grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
NULL);
@@ -1179,10 +1201,12 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream_global *stream_global) {
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_initial_metadata_finished, 0);
+ exec_ctx, stream_global, &stream_global->send_initial_metadata_finished,
+ 0);
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_trailing_metadata_finished, 0);
- grpc_chttp2_complete_closure_step(exec_ctx,
+ exec_ctx, stream_global, &stream_global->send_trailing_metadata_finished,
+ 0);
+ grpc_chttp2_complete_closure_step(exec_ctx, stream_global,
&stream_global->send_message_finished, 0);
}
@@ -1319,7 +1343,8 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_add(
&transport_global->qbuf,
- grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR));
+ grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR,
+ &stream_global->stats.outgoing));
if (optional_message) {
gpr_slice_ref(*optional_message);
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c
index cdd624647c..baa66e0008 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.c
+++ b/src/core/ext/transport/chttp2/transport/frame_data.c
@@ -113,11 +113,13 @@ grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop(
void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf,
uint32_t write_bytes, int is_eof,
+ grpc_transport_one_way_stats *stats,
gpr_slice_buffer *outbuf) {
gpr_slice hdr;
uint8_t *p;
+ static const size_t header_size = 9;
- hdr = gpr_slice_malloc(9);
+ hdr = gpr_slice_malloc(header_size);
p = GPR_SLICE_START_PTR(hdr);
GPR_ASSERT(write_bytes < (1 << 24));
*p++ = (uint8_t)(write_bytes >> 16);
@@ -132,6 +134,9 @@ void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf,
gpr_slice_buffer_add(outbuf, hdr);
gpr_slice_buffer_move_first(inbuf, write_bytes, outbuf);
+
+ stats->framing_bytes += header_size;
+ stats->data_bytes += write_bytes;
}
grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
@@ -156,6 +161,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
switch (p->state) {
fh_0:
case GRPC_CHTTP2_DATA_FH_0:
+ stream_parsing->stats.incoming.framing_bytes++;
p->frame_type = *cur;
switch (p->frame_type) {
case 0:
@@ -174,6 +180,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_1:
+ stream_parsing->stats.incoming.framing_bytes++;
p->frame_size = ((uint32_t)*cur) << 24;
if (++cur == end) {
p->state = GRPC_CHTTP2_DATA_FH_2;
@@ -181,6 +188,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_2:
+ stream_parsing->stats.incoming.framing_bytes++;
p->frame_size |= ((uint32_t)*cur) << 16;
if (++cur == end) {
p->state = GRPC_CHTTP2_DATA_FH_3;
@@ -188,6 +196,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_3:
+ stream_parsing->stats.incoming.framing_bytes++;
p->frame_size |= ((uint32_t)*cur) << 8;
if (++cur == end) {
p->state = GRPC_CHTTP2_DATA_FH_4;
@@ -195,6 +204,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_4:
+ stream_parsing->stats.incoming.framing_bytes++;
p->frame_size |= ((uint32_t)*cur);
p->state = GRPC_CHTTP2_DATA_FRAME;
++cur;
@@ -215,7 +225,9 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
}
grpc_chttp2_list_add_parsing_seen_stream(transport_parsing,
stream_parsing);
- if ((uint32_t)(end - cur) == p->frame_size) {
+ uint32_t remaining = (uint32_t)(end - cur);
+ if (remaining == p->frame_size) {
+ stream_parsing->stats.incoming.data_bytes += p->frame_size;
grpc_chttp2_incoming_byte_stream_push(
exec_ctx, p->parsing_frame,
gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)));
@@ -224,7 +236,8 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
p->parsing_frame = NULL;
p->state = GRPC_CHTTP2_DATA_FH_0;
return GRPC_CHTTP2_PARSE_OK;
- } else if ((uint32_t)(end - cur) > p->frame_size) {
+ } else if (remaining > p->frame_size) {
+ stream_parsing->stats.incoming.data_bytes += p->frame_size;
grpc_chttp2_incoming_byte_stream_push(
exec_ctx, p->parsing_frame,
gpr_slice_sub(slice, (size_t)(cur - beg),
@@ -235,11 +248,12 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
cur += p->frame_size;
goto fh_0; /* loop */
} else {
+ GPR_ASSERT(remaining <= p->frame_size);
grpc_chttp2_incoming_byte_stream_push(
exec_ctx, p->parsing_frame,
gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)));
- GPR_ASSERT((size_t)(end - cur) <= p->frame_size);
- p->frame_size -= (uint32_t)(end - cur);
+ p->frame_size -= remaining;
+ stream_parsing->stats.incoming.data_bytes += remaining;
return GRPC_CHTTP2_PARSE_OK;
}
}
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h
index f2762ed9de..8a073a9c11 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.h
+++ b/src/core/ext/transport/chttp2/transport/frame_data.h
@@ -41,6 +41,7 @@
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/byte_stream.h"
+#include "src/core/lib/transport/transport.h"
typedef enum {
GRPC_CHTTP2_DATA_FH_0,
@@ -96,6 +97,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf,
uint32_t write_bytes, int is_eof,
+ grpc_transport_one_way_stats *stats,
gpr_slice_buffer *outbuf);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_DATA_H */
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
index acfc3627e8..d9a04bbf3c 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
@@ -38,8 +38,11 @@
#include "src/core/ext/transport/chttp2/transport/frame.h"
-gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code) {
- gpr_slice slice = gpr_slice_malloc(13);
+gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code,
+ grpc_transport_one_way_stats *stats) {
+ static const size_t frame_size = 13;
+ gpr_slice slice = gpr_slice_malloc(frame_size);
+ stats->framing_bytes += frame_size;
uint8_t *p = GPR_SLICE_START_PTR(slice);
*p++ = 0;
@@ -84,6 +87,7 @@ grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse(
cur++;
p->byte++;
}
+ stream_parsing->stats.incoming.framing_bytes += (uint64_t)(end - cur);
if (p->byte == 4) {
GPR_ASSERT(is_last);
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h
index 134f1368a0..729274e9a2 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h
@@ -37,13 +37,15 @@
#include <grpc/support/slice.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/transport.h"
typedef struct {
uint8_t byte;
uint8_t reason_bytes[4];
} grpc_chttp2_rst_stream_parser;
-gpr_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code);
+gpr_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code,
+ grpc_transport_one_way_stats *stats);
grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame(
grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags);
diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.c b/src/core/ext/transport/chttp2/transport/frame_window_update.c
index 1a561cebaf..0baf6d2fdd 100644
--- a/src/core/ext/transport/chttp2/transport/frame_window_update.c
+++ b/src/core/ext/transport/chttp2/transport/frame_window_update.c
@@ -36,9 +36,11 @@
#include <grpc/support/log.h>
-gpr_slice grpc_chttp2_window_update_create(uint32_t id,
- uint32_t window_update) {
- gpr_slice slice = gpr_slice_malloc(13);
+gpr_slice grpc_chttp2_window_update_create(
+ uint32_t id, uint32_t window_update, grpc_transport_one_way_stats *stats) {
+ static const size_t frame_size = 13;
+ gpr_slice slice = gpr_slice_malloc(frame_size);
+ stats->header_bytes += frame_size;
uint8_t *p = GPR_SLICE_START_PTR(slice);
GPR_ASSERT(window_update);
@@ -87,6 +89,10 @@ grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
p->byte++;
}
+ if (stream_parsing != NULL) {
+ stream_parsing->stats.incoming.framing_bytes += (uint32_t)(end - cur);
+ }
+
if (p->byte == 4) {
uint32_t received_update = p->amount;
if (received_update == 0 || (received_update & 0x80000000u)) {
diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h
index f9f670b6f1..a1093a6041 100644
--- a/src/core/ext/transport/chttp2/transport/frame_window_update.h
+++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h
@@ -37,6 +37,7 @@
#include <grpc/support/slice.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/transport.h"
typedef struct {
uint8_t byte;
@@ -44,7 +45,8 @@ typedef struct {
uint32_t amount;
} grpc_chttp2_window_update_parser;
-gpr_slice grpc_chttp2_window_update_create(uint32_t id, uint32_t window_delta);
+gpr_slice grpc_chttp2_window_update_create(uint32_t id, uint32_t window_delta,
+ grpc_transport_one_way_stats *stats);
grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame(
grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index 819addd9e3..880305afdd 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -74,6 +74,7 @@ typedef struct {
/* output stream id */
uint32_t stream_id;
gpr_slice_buffer *output;
+ grpc_transport_one_way_stats *stats;
} framer_state;
/* fills p (which is expected to be 9 bytes long) with a data frame header */
@@ -102,6 +103,7 @@ static void finish_frame(framer_state *st, int is_header_boundary,
st->stream_id, st->output->length - st->output_length_at_start_of_frame,
(uint8_t)((is_last_in_stream ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0) |
(is_header_boundary ? GRPC_CHTTP2_DATA_FLAG_END_HEADERS : 0)));
+ st->stats->framing_bytes += 9;
st->is_first_frame = 0;
}
@@ -147,8 +149,10 @@ static void add_header_data(framer_state *st, gpr_slice slice) {
remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
st->output_length_at_start_of_frame - st->output->length;
if (len <= remaining) {
+ st->stats->header_bytes += len;
gpr_slice_buffer_add(st->output, slice);
} else {
+ st->stats->header_bytes += remaining;
gpr_slice_buffer_add(st->output, gpr_slice_split_head(&slice, remaining));
finish_frame(st, 0, 0);
begin_frame(st);
@@ -535,6 +539,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
uint32_t stream_id,
grpc_metadata_batch *metadata, int is_eof,
+ grpc_transport_one_way_stats *stats,
gpr_slice_buffer *outbuf) {
framer_state st;
grpc_linked_mdelem *l;
@@ -546,6 +551,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
st.stream_id = stream_id;
st.output = outbuf;
st.is_first_frame = 1;
+ st.stats = stats;
/* Encode a metadata batch; store the returned values, representing
a metadata element that needs to be unreffed back into the metadata
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index d79de35979..91c368fbe2 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -40,6 +40,7 @@
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
+#include "src/core/lib/transport/transport.h"
#define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256
#define GRPC_CHTTP2_HPACKC_NUM_VALUES 256
@@ -90,6 +91,7 @@ void grpc_chttp2_hpack_compressor_set_max_usable_size(
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id,
grpc_metadata_batch *metadata, int is_eof,
+ grpc_transport_one_way_stats *stats,
gpr_slice_buffer *outbuf);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index ec3387efb8..259452fa42 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -1426,6 +1426,9 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) {
grpc_chttp2_hpack_parser *parser = hpack_parser;
GPR_TIMER_BEGIN("grpc_chttp2_hpack_parser_parse", 0);
+ if (stream_parsing != NULL) {
+ stream_parsing->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice);
+ }
if (!grpc_chttp2_hpack_parser_parse(parser, GPR_SLICE_START_PTR(slice),
GPR_SLICE_END_PTR(slice))) {
GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 2fae653623..2c3c7a3820 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -394,6 +394,9 @@ typedef struct {
grpc_metadata_batch *recv_trailing_metadata;
grpc_closure *recv_trailing_metadata_finished;
+ grpc_transport_stream_stats *collecting_stats;
+ grpc_transport_stream_stats stats;
+
/** when the application requests writes be closed, the write_closed is
'queued'; when the close is flow controlled into the send path, we are
'sending' it; when the write has been performed it is 'sent' */
@@ -435,6 +438,8 @@ typedef struct {
gpr_slice fetching_slice;
size_t stream_fetched;
grpc_closure finished_fetch;
+ /** stats gathered during the write */
+ grpc_transport_one_way_stats stats;
} grpc_chttp2_stream_writing;
struct grpc_chttp2_stream_parsing {
@@ -460,6 +465,8 @@ struct grpc_chttp2_stream_parsing {
int64_t outgoing_window;
/** number of bytes received - reset at end of parse thread execution */
int64_t received_bytes;
+ /** stats gathered during the parse */
+ grpc_transport_stream_stats stats;
/** incoming metadata */
grpc_chttp2_incoming_metadata_buffer metadata_buffer[2];
@@ -635,6 +642,7 @@ void grpc_chttp2_parsing_become_skip_parser(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing);
void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_stream_global *stream_global,
grpc_closure **pclosure, int success);
#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index a9f043cee3..1e815e096b 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -171,6 +171,9 @@ void grpc_chttp2_publish_reads(
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
}
+ /* flush stats to global stream state */
+ grpc_transport_move_stats(&stream_parsing->stats, &stream_global->stats);
+
/* update outgoing flow control window */
was_zero = stream_global->outgoing_window <= 0;
GRPC_CHTTP2_FLOW_MOVE_STREAM("parsed", transport_global, stream_global,
@@ -544,8 +547,13 @@ static int init_data_frame_parser(
grpc_chttp2_parsing_lookup_stream(transport_parsing,
transport_parsing->incoming_stream_id);
grpc_chttp2_parse_error err = GRPC_CHTTP2_PARSE_OK;
- if (!stream_parsing || stream_parsing->received_close)
+ if (stream_parsing == NULL) {
+ return init_skip_frame_parser(exec_ctx, transport_parsing, 0);
+ }
+ stream_parsing->stats.incoming.framing_bytes += 9;
+ if (stream_parsing->received_close) {
return init_skip_frame_parser(exec_ctx, transport_parsing, 0);
+ }
if (err == GRPC_CHTTP2_PARSE_OK) {
err = update_incoming_window(exec_ctx, transport_parsing, stream_parsing);
}
@@ -566,7 +574,8 @@ static int init_data_frame_parser(
gpr_slice_buffer_add(
&transport_parsing->qbuf,
grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id,
- GRPC_CHTTP2_PROTOCOL_ERROR));
+ GRPC_CHTTP2_PROTOCOL_ERROR,
+ &stream_parsing->stats.outgoing));
return init_skip_frame_parser(exec_ctx, transport_parsing, 0);
case GRPC_CHTTP2_CONNECTION_ERROR:
return 0;
@@ -717,6 +726,7 @@ static int init_header_frame_parser(
transport_parsing->incoming_stream = stream_parsing;
}
GPR_ASSERT(stream_parsing != NULL && (via_accept == 0 || via_accept == 1));
+ stream_parsing->stats.incoming.framing_bytes += 9;
if (stream_parsing->received_close) {
gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header");
transport_parsing->incoming_stream = NULL;
@@ -752,9 +762,14 @@ static int init_window_update_frame_parser(
&transport_parsing->simple.window_update,
transport_parsing->incoming_frame_size,
transport_parsing->incoming_frame_flags);
- if (transport_parsing->incoming_stream_id) {
- transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream(
- transport_parsing, transport_parsing->incoming_stream_id);
+ if (transport_parsing->incoming_stream_id != 0) {
+ grpc_chttp2_stream_parsing *stream_parsing =
+ transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream(
+ transport_parsing, transport_parsing->incoming_stream_id);
+ if (stream_parsing == NULL) {
+ return init_skip_frame_parser(exec_ctx, transport_parsing, 0);
+ }
+ stream_parsing->stats.incoming.framing_bytes += 9;
}
transport_parsing->parser = grpc_chttp2_window_update_parser_parse;
transport_parsing->parser_data = &transport_parsing->simple.window_update;
@@ -778,11 +793,13 @@ static int init_rst_stream_parser(
&transport_parsing->simple.rst_stream,
transport_parsing->incoming_frame_size,
transport_parsing->incoming_frame_flags);
- transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream(
- transport_parsing, transport_parsing->incoming_stream_id);
+ grpc_chttp2_stream_parsing *stream_parsing =
+ transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream(
+ transport_parsing, transport_parsing->incoming_stream_id);
if (!transport_parsing->incoming_stream) {
return init_skip_frame_parser(exec_ctx, transport_parsing, 0);
}
+ stream_parsing->stats.incoming.framing_bytes += 9;
transport_parsing->parser = grpc_chttp2_rst_stream_parser_parse;
transport_parsing->parser_data = &transport_parsing->simple.rst_stream;
return ok;
@@ -856,7 +873,8 @@ static int parse_frame_slice(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_add(
&transport_parsing->qbuf,
grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id,
- GRPC_CHTTP2_PROTOCOL_ERROR));
+ GRPC_CHTTP2_PROTOCOL_ERROR,
+ &stream_parsing->stats.outgoing));
}
return 1;
case GRPC_CHTTP2_CONNECTION_ERROR:
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 8d5886f225..6bb188f1da 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -161,8 +161,10 @@ int grpc_chttp2_unlocking_check_writes(
transport_global->announce_incoming_window, UINT32_MAX);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global,
announce_incoming_window, announced);
- gpr_slice_buffer_add(&transport_writing->outbuf,
- grpc_chttp2_window_update_create(0, announced));
+ grpc_transport_one_way_stats throwaway_stats;
+ gpr_slice_buffer_add(
+ &transport_writing->outbuf,
+ grpc_chttp2_window_update_create(0, announced, &throwaway_stats));
}
GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0);
@@ -205,7 +207,8 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
if (stream_writing->send_initial_metadata != NULL) {
grpc_chttp2_encode_header(
&transport_writing->hpack_compressor, stream_writing->id,
- stream_writing->send_initial_metadata, 0, &transport_writing->outbuf);
+ stream_writing->send_initial_metadata, 0, &stream_writing->stats,
+ &transport_writing->outbuf);
stream_writing->send_initial_metadata = NULL;
stream_writing->sent_initial_metadata = 1;
}
@@ -216,7 +219,8 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_add(
&transport_writing->outbuf,
grpc_chttp2_window_update_create(stream_writing->id,
- stream_writing->announce_window));
+ stream_writing->announce_window,
+ &stream_writing->stats));
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, stream_writing,
announce_window, announce);
stream_writing->announce_window = 0;
@@ -255,7 +259,8 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
stream_writing->send_trailing_metadata);
grpc_chttp2_encode_data(
stream_writing->id, &stream_writing->flow_controlled_buffer,
- send_bytes, is_last_frame, &transport_writing->outbuf);
+ send_bytes, is_last_frame, &stream_writing->stats,
+ &transport_writing->outbuf);
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing,
stream_writing, outgoing_window,
send_bytes);
@@ -281,19 +286,20 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
stream_writing->send_trailing_metadata != NULL) {
if (grpc_metadata_batch_is_empty(
stream_writing->send_trailing_metadata)) {
- grpc_chttp2_encode_data(stream_writing->id,
- &stream_writing->flow_controlled_buffer, 0, 1,
- &transport_writing->outbuf);
+ grpc_chttp2_encode_data(
+ stream_writing->id, &stream_writing->flow_controlled_buffer, 0, 1,
+ &stream_writing->stats, &transport_writing->outbuf);
} else {
- grpc_chttp2_encode_header(&transport_writing->hpack_compressor,
- stream_writing->id,
- stream_writing->send_trailing_metadata, 1,
- &transport_writing->outbuf);
+ grpc_chttp2_encode_header(
+ &transport_writing->hpack_compressor, stream_writing->id,
+ stream_writing->send_trailing_metadata, 1, &stream_writing->stats,
+ &transport_writing->outbuf);
}
if (!transport_writing->is_client && !stream_writing->read_closed) {
gpr_slice_buffer_add(&transport_writing->outbuf,
grpc_chttp2_rst_stream_create(
- stream_writing->id, GRPC_CHTTP2_NO_ERROR));
+ stream_writing->id, GRPC_CHTTP2_NO_ERROR,
+ &stream_writing->stats));
}
stream_writing->send_trailing_metadata = NULL;
stream_writing->sent_trailing_metadata = 1;
@@ -328,17 +334,21 @@ void grpc_chttp2_cleanup_writing(
transport_global, transport_writing, &stream_global, &stream_writing)) {
if (stream_writing->sent_initial_metadata) {
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_initial_metadata_finished, 1);
+ exec_ctx, stream_global,
+ &stream_global->send_initial_metadata_finished, 1);
}
+ grpc_transport_move_one_way_stats(&stream_writing->stats,
+ &stream_global->stats.outgoing);
if (stream_writing->sent_message) {
GPR_ASSERT(stream_writing->send_message == NULL);
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_message_finished, 1);
+ exec_ctx, stream_global, &stream_global->send_message_finished, 1);
stream_writing->sent_message = 0;
}
if (stream_writing->sent_trailing_metadata) {
grpc_chttp2_complete_closure_step(
- exec_ctx, &stream_global->send_trailing_metadata_finished, 1);
+ exec_ctx, stream_global,
+ &stream_global->send_trailing_metadata_finished, 1);
}
if (stream_writing->sent_trailing_metadata) {
grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global,
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index d63a4a7401..0219d7e6d0 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -174,6 +174,9 @@ struct grpc_call {
/* Received call statuses from various sources */
received_status status[STATUS_SOURCE_COUNT];
+ /* Call stats: only valid after trailing metadata received */
+ grpc_transport_stream_stats stats;
+
/* Compression algorithm for the call */
grpc_compression_algorithm compression_algorithm;
/* Supported encodings (compression algorithms), a bitset */
@@ -1371,6 +1374,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
bctl->recv_final_op = 1;
stream_op.recv_trailing_metadata =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
+ stream_op.collect_stats = &call->stats;
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
/* Flag validation: currently allow no flags */
@@ -1392,6 +1396,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
bctl->recv_final_op = 1;
stream_op.recv_trailing_metadata =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
+ stream_op.collect_stats = &call->stats;
break;
}
}
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index 18256aae5e..411e4f140a 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -35,6 +35,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
#include "src/core/lib/transport/transport_impl.h"
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -76,6 +77,24 @@ void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
grpc_closure_init(&refcount->destroy, cb, cb_arg);
}
+static void move64(uint64_t *from, uint64_t *to) {
+ *to += *from;
+ *from = 0;
+}
+
+void grpc_transport_move_one_way_stats(grpc_transport_one_way_stats *from,
+ grpc_transport_one_way_stats *to) {
+ move64(&from->framing_bytes, &to->framing_bytes);
+ move64(&from->data_bytes, &to->data_bytes);
+ move64(&from->header_bytes, &to->header_bytes);
+}
+
+void grpc_transport_move_stats(grpc_transport_stream_stats *from,
+ grpc_transport_stream_stats *to) {
+ grpc_transport_move_one_way_stats(&from->incoming, &to->incoming);
+ grpc_transport_move_one_way_stats(&from->outgoing, &to->outgoing);
+}
+
size_t grpc_transport_stream_size(grpc_transport *transport) {
return transport->vtable->sizeof_stream;
}
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index e98cfe9515..c253b190e7 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -78,6 +78,23 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount);
grpc_stream_ref_init(rc, ir, cb, cb_arg)
#endif
+typedef struct {
+ uint64_t framing_bytes;
+ uint64_t data_bytes;
+ uint64_t header_bytes;
+} grpc_transport_one_way_stats;
+
+typedef struct grpc_transport_stream_stats {
+ grpc_transport_one_way_stats incoming;
+ grpc_transport_one_way_stats outgoing;
+} grpc_transport_stream_stats;
+
+void grpc_transport_move_one_way_stats(grpc_transport_one_way_stats *from,
+ grpc_transport_one_way_stats *to);
+
+void grpc_transport_move_stats(grpc_transport_stream_stats *from,
+ grpc_transport_stream_stats *to);
+
/* Transport stream op: a set of operations to perform on a transport
against a single stream */
typedef struct grpc_transport_stream_op {
@@ -104,6 +121,9 @@ typedef struct grpc_transport_stream_op {
*/
grpc_metadata_batch *recv_trailing_metadata;
+ /** Collect any stats into provided buffer, zero internal stat counters */
+ grpc_transport_stream_stats *collect_stats;
+
/** Should be enqueued when all requested operations (excluding recv_message
and recv_initial_metadata which have their own closures) in a given batch
have been completed. */
diff --git a/src/python/grpcio/precompiled.py b/src/python/grpcio/precompiled.py
index d34250b02c..aeeb2754ea 100644
--- a/src/python/grpcio/precompiled.py
+++ b/src/python/grpcio/precompiled.py
@@ -91,6 +91,9 @@ class BuildTaggedExt(setuptools.Command):
def update_setup_arguments(setup_arguments):
+ if not USE_PRECOMPILED_BINARIES:
+ sys.stderr.write('not using precompiled extension')
+ return
url = '{}/{}.so'.format(BINARIES_REPOSITORY, _tagged_ext_name('cygrpc'))
target_path = os.path.join(PYTHON_STEM, 'grpc/_cython/cygrpc.so')
try:
diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c
new file mode 100644
index 0000000000..04d66994cd
--- /dev/null
+++ b/test/core/internal_api_canaries/iomgr.c
@@ -0,0 +1,115 @@
+/*
+ *
+ * Copyright 2015-2016, 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 "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/executor.h"
+
+/*******************************************************************************
+ * NOTE: If this test fails to compile, then the api changes are likely to cause
+ * merge failures downstream. Please pay special attention to reviewing
+ * these changes, and solicit help as appropriate when merging downstream.
+ *
+ * This test is NOT expected to be run directly.
+ ******************************************************************************/
+
+static void test_code(void) {
+ /* iomgr.h */
+ grpc_iomgr_init();
+ grpc_iomgr_shutdown();
+
+ /* closure.h */
+ grpc_closure closure;
+ closure.cb = NULL;
+ closure.cb_arg = NULL;
+ closure.final_data = 0;
+
+ grpc_closure_list closure_list = GRPC_CLOSURE_LIST_INIT;
+ closure_list.head = NULL;
+ closure_list.tail = NULL;
+
+ grpc_closure_init(&closure, NULL, NULL);
+
+ grpc_closure_create(NULL, NULL);
+
+ grpc_closure_list_move(NULL, NULL);
+ grpc_closure_list_add(NULL, NULL, true);
+ bool x = grpc_closure_list_empty(closure_list);
+ grpc_closure_next(&closure);
+
+ /* exec_ctx.h */
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_exec_ctx_flush(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
+ grpc_exec_ctx_enqueue(&exec_ctx, &closure, x, NULL);
+ grpc_exec_ctx_enqueue_list(&exec_ctx, &closure_list, NULL);
+
+ /* endpoint.h */
+ grpc_endpoint endpoint;
+ grpc_endpoint_vtable vtable = {
+ grpc_endpoint_read, grpc_endpoint_write,
+ grpc_endpoint_add_to_pollset, grpc_endpoint_add_to_pollset_set,
+ grpc_endpoint_shutdown, grpc_endpoint_destroy,
+ grpc_endpoint_get_peer};
+ endpoint.vtable = &vtable;
+
+ grpc_endpoint_read(&exec_ctx, &endpoint, NULL, NULL);
+ grpc_endpoint_get_peer(&endpoint);
+ grpc_endpoint_write(&exec_ctx, &endpoint, NULL, NULL);
+ grpc_endpoint_shutdown(&exec_ctx, &endpoint);
+ grpc_endpoint_destroy(&exec_ctx, &endpoint);
+ grpc_endpoint_add_to_pollset(&exec_ctx, &endpoint, NULL);
+ grpc_endpoint_add_to_pollset_set(&exec_ctx, &endpoint, NULL);
+
+ /* executor.h */
+ grpc_executor_init();
+ grpc_executor_enqueue(&closure, x);
+ grpc_executor_shutdown();
+
+ /* pollset.h */
+ grpc_pollset_size();
+ grpc_pollset_init(NULL, NULL);
+ grpc_pollset_shutdown(NULL, NULL, NULL);
+ grpc_pollset_reset(NULL);
+ grpc_pollset_destroy(NULL);
+ grpc_pollset_work(NULL, NULL, NULL, gpr_now(GPR_CLOCK_REALTIME),
+ gpr_now(GPR_CLOCK_MONOTONIC));
+ grpc_pollset_kick(NULL, NULL);
+}
+
+int main(void) {
+ if (false) test_code();
+ return 0;
+}
diff --git a/test/core/internal_api_canaries/support.c b/test/core/internal_api_canaries/support.c
new file mode 100644
index 0000000000..7e00e0d2ff
--- /dev/null
+++ b/test/core/internal_api_canaries/support.c
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2015-2016, 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.
+ *
+ */
+
+/*******************************************************************************
+ * NOTE: If this test fails to compile, then the api changes are likely to cause
+ * merge failures downstream. Please pay special attention to reviewing
+ * these changes, and solicit help as appropriate when merging downstream.
+ *
+ * This test is NOT expected to be run directly.
+ ******************************************************************************/
+
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/load_file.h"
+#include "src/core/lib/support/tmpfile.h"
+
+static void test_code(void) {
+ /* env.h */
+ gpr_set_env("abc", gpr_getenv("xyz"));
+ /* load_file.h */
+ gpr_load_file("abc", 1, NULL);
+ /* tmpfile.h */
+ fclose(gpr_tmpfile("foo", NULL));
+}
+
+int main(void) {
+ if (false) test_code();
+ return 0;
+}
diff --git a/test/core/internal_api_canaries/transport.c b/test/core/internal_api_canaries/transport.c
new file mode 100644
index 0000000000..01daabaa56
--- /dev/null
+++ b/test/core/internal_api_canaries/transport.c
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2015-2016, 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.
+ *
+ */
+
+/*******************************************************************************
+ * NOTE: If this test fails to compile, then the api changes are likely to cause
+ * merge failures downstream. Please pay special attention to reviewing
+ * these changes, and solicit help as appropriate when merging downstream.
+ *
+ * This test is NOT expected to be run directly.
+ ******************************************************************************/
+
+#include "src/core/lib/transport/transport.h"
+#include "src/core/lib/transport/transport_impl.h"
+
+static void test_code(void) {
+ /* transport_impl.h */
+ grpc_transport transport;
+ grpc_transport_vtable vtable = {12345,
+ grpc_transport_init_stream,
+ grpc_transport_set_pollset,
+ grpc_transport_perform_stream_op,
+ grpc_transport_perform_op,
+ grpc_transport_destroy_stream,
+ grpc_transport_destroy,
+ grpc_transport_get_peer};
+ transport.vtable = &vtable;
+
+ /* transport.h */
+ GRPC_STREAM_REF_INIT(NULL, 0, NULL, NULL, "xyz");
+ GPR_ASSERT(0 == grpc_transport_stream_size(NULL));
+ GPR_ASSERT(grpc_transport_init_stream(&transport, NULL, NULL, NULL, NULL));
+ grpc_transport_set_pollset(&transport, NULL, NULL, NULL);
+ grpc_transport_destroy_stream(&transport, NULL, NULL);
+ grpc_transport_stream_op_finish_with_failure(NULL, NULL);
+ grpc_transport_stream_op_add_cancellation(NULL, GRPC_STATUS_UNAVAILABLE);
+ grpc_transport_stream_op_add_close(NULL, GRPC_STATUS_UNAVAILABLE,
+ grpc_transport_op_string(NULL));
+ grpc_transport_perform_stream_op(&transport, NULL, NULL, NULL);
+ grpc_transport_perform_op(&transport, NULL, NULL);
+ grpc_transport_ping(&transport, NULL);
+ grpc_transport_goaway(&transport, GRPC_STATUS_UNAVAILABLE,
+ gpr_slice_malloc(0));
+ grpc_transport_close(&transport);
+ grpc_transport_destroy(&transport, NULL);
+ GPR_ASSERT("xyz" == grpc_transport_get_peer(&transport, NULL));
+}
+
+int main(void) {
+ if (false) test_code();
+ return 0;
+}
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 818ce09a7c..464f0d93b0 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -34,10 +34,12 @@
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include <stdio.h>
+#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/metadata.h"
@@ -93,7 +95,10 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
gpr_slice_buffer_init(&output);
- grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, &output);
+ grpc_transport_one_way_stats stats;
+ memset(&stats, 0, sizeof(stats));
+ grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, &stats,
+ &output);
merged = grpc_slice_merge(output.slices, output.count);
gpr_slice_buffer_destroy(&output);
grpc_metadata_batch_destroy(&b);
diff --git a/tools/gce/create_interop_worker.sh b/tools/gce/create_interop_worker.sh
new file mode 100755
index 0000000000..3c49c6102a
--- /dev/null
+++ b/tools/gce/create_interop_worker.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# Copyright 2015-2016, 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.
+
+# Creates an interop worker on GCE.
+# IMPORTANT: After this script finishes, there are still some manual
+# steps needed there are hard to automatize.
+# See go/grpc-jenkins-setup for followup instructions.
+
+set -ex
+
+cd $(dirname $0)
+
+CLOUD_PROJECT=grpc-testing
+ZONE=us-east1-a # canary gateway is reachable from this zone
+
+INSTANCE_NAME="${1:-grpc-canary-interop2}"
+
+gcloud compute instances create $INSTANCE_NAME \
+ --project="$CLOUD_PROJECT" \
+ --zone "$ZONE" \
+ --machine-type n1-standard-16 \
+ --image ubuntu-15-10 \
+ --boot-disk-size 1000 \
+ --scopes https://www.googleapis.com/auth/xapi.zoo
+
+echo 'Created GCE instance, waiting 60 seconds for it to come online.'
+sleep 60
+
+gcloud compute copy-files \
+ --project="$CLOUD_PROJECT" \
+ --zone "$ZONE" \
+ jenkins_master.pub linux_worker_init.sh ${INSTANCE_NAME}:~
+
+gcloud compute ssh \
+ --project="$CLOUD_PROJECT" \
+ --zone "$ZONE" \
+ $INSTANCE_NAME --command "./linux_worker_init.sh"
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index 79a148faf1..fe84300c7b 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -40,6 +40,7 @@ export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
export CFLAGS="-I$ROOT/include -std=gnu99"
export LDFLAGS="-L$ROOT/libs/$CONFIG"
export GRPC_PYTHON_BUILD_WITH_CYTHON=1
+export GRPC_PYTHON_USE_PRECOMPILED_BINARIES=0
if [ "$CONFIG" = "gcov" ]
then
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index a3b246dc08..d1cfc5952f 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -151,7 +151,8 @@ class JobSpec(object):
def __init__(self, cmdline, shortname=None, environ=None, hash_targets=None,
cwd=None, shell=False, timeout_seconds=5*60, flake_retries=0,
- timeout_retries=0, kill_handler=None, cpu_cost=1.0):
+ timeout_retries=0, kill_handler=None, cpu_cost=1.0,
+ verbose_success=False):
"""
Arguments:
cmdline: a list of arguments to pass as the command line
@@ -176,6 +177,7 @@ class JobSpec(object):
self.timeout_retries = timeout_retries
self.kill_handler = kill_handler
self.cpu_cost = cpu_cost
+ self.verbose_success = verbose_success
def identity(self):
return '%r %r %r' % (self.cmdline, self.environ, self.hash_targets)
@@ -287,7 +289,8 @@ class Job(object):
cores = (user + sys) / real
measurement = '; cpu_cost=%.01f; estimated=%.01f' % (cores, self._spec.cpu_cost)
message('PASSED', '%s [time=%.1fsec; retries=%d:%d%s]' % (
- self._spec.shortname, elapsed, self._retries, self._timeout_retries, measurement),
+ self._spec.shortname, elapsed, self._retries, self._timeout_retries, measurement),
+ stdout() if self._spec.verbose_success else None,
do_newline=self._newline_on_success or self._travis)
self.result.state = 'PASSED'
if self._bin_hash:
diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh
new file mode 100755
index 0000000000..00cc41ec73
--- /dev/null
+++ b/tools/run_tests/performance/build_performance.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Copyright 2015-2016, 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.
+
+set -ex
+
+cd $(dirname $0)/../../..
+
+#TODO(jtattermusch): add support for more languages
+
+CONFIG=${CONFIG:-opt}
+
+# build C++ qps worker & driver
+make CONFIG=${CONFIG} qps_worker qps_driver -j8
diff --git a/tools/run_tests/performance/remote_host_build.sh b/tools/run_tests/performance/remote_host_build.sh
new file mode 100755
index 0000000000..f23ea921ce
--- /dev/null
+++ b/tools/run_tests/performance/remote_host_build.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Copyright 2015-2016, 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.
+
+set -ex
+
+cd $(dirname $0)/../../..
+
+# execute the build script remotely
+ssh "${USER_AT_HOST}" "CONFIG=${CONFIG} ~/performance_workspace/grpc/tools/run_tests/performance/build_performance.sh"
diff --git a/tools/run_tests/performance/remote_host_prepare.sh b/tools/run_tests/performance/remote_host_prepare.sh
new file mode 100755
index 0000000000..bad2424a6b
--- /dev/null
+++ b/tools/run_tests/performance/remote_host_prepare.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Copyright 2015-2016, 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.
+
+set -ex
+
+cd $(dirname $0)/../../..
+
+# cleanup after previous builds
+ssh "${USER_AT_HOST}" "rm -rf ~/performance_workspace && mkdir -p ~/performance_workspace"
+
+# TODO(jtattermusch): To be sure there are not running processes that would
+# mess with the results, be rough and reboot the slave here
+# and wait for it to come back online.
+
+# push the current sources to the slave and unpack it.
+scp ../grpc.tar "${USER_AT_HOST}:~/performance_workspace"
+ssh "${USER_AT_HOST}" "tar -xf ~/performance_workspace/grpc.tar -C ~/performance_workspace" \ No newline at end of file
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
new file mode 100755
index 0000000000..77c0addb42
--- /dev/null
+++ b/tools/run_tests/run_performance_tests.py
@@ -0,0 +1,353 @@
+#!/usr/bin/env python2.7
+# Copyright 2016, 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.
+
+"""Run performance tests locally or remotely."""
+
+import argparse
+import jobset
+import multiprocessing
+import os
+import subprocess
+import sys
+import tempfile
+import time
+import uuid
+
+
+_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
+os.chdir(_ROOT)
+
+
+_REMOTE_HOST_USERNAME = 'jenkins'
+
+
+class CXXLanguage:
+
+ def __init__(self):
+ self.safename = 'cxx'
+
+ def scenarios(self):
+ # TODO(jtattermusch): add more scenarios
+ return {
+ # Scenario 1: generic async streaming ping-pong (contentionless latency)
+ 'cpp_async_generic_streaming_ping_pong': [
+ '--rpc_type=STREAMING',
+ '--client_type=ASYNC_CLIENT',
+ '--server_type=ASYNC_GENERIC_SERVER',
+ '--outstanding_rpcs_per_channel=1',
+ '--client_channels=1',
+ '--bbuf_req_size=0',
+ '--bbuf_resp_size=0',
+ '--async_client_threads=1',
+ '--async_server_threads=1',
+ '--secure_test=true',
+ '--num_servers=1',
+ '--num_clients=1',
+ '--server_core_limit=0',
+ '--client_core_limit=0'],
+ # Scenario 5: Sync unary ping-pong with protobufs
+ 'cpp_sync_unary_ping_pong_protobuf': [
+ '--rpc_type=UNARY',
+ '--client_type=SYNC_CLIENT',
+ '--server_type=SYNC_SERVER',
+ '--outstanding_rpcs_per_channel=1',
+ '--client_channels=1',
+ '--simple_req_size=0',
+ '--simple_resp_size=0',
+ '--secure_test=true',
+ '--num_servers=1',
+ '--num_clients=1',
+ '--server_core_limit=0',
+ '--client_core_limit=0']}
+
+ def __str__(self):
+ return 'c++'
+
+
+class CSharpLanguage:
+
+ def __init__(self):
+ self.safename = str(self)
+
+ def __str__(self):
+ return 'csharp'
+
+
+class NodeLanguage:
+
+ def __init__(self):
+ pass
+ self.safename = str(self)
+
+ def __str__(self):
+ return 'node'
+
+
+_LANGUAGES = {
+ 'c++' : CXXLanguage(),
+ 'csharp' : CSharpLanguage(),
+ 'node' : NodeLanguage(),
+}
+
+
+class QpsWorkerJob:
+ """Encapsulates a qps worker server job."""
+
+ def __init__(self, spec, host_and_port):
+ self._spec = spec
+ self.host_and_port = host_and_port
+ self._job = jobset.Job(spec, bin_hash=None, newline_on_success=True, travis=True, add_env={})
+
+ def is_running(self):
+ """Polls a job and returns True if given job is still running."""
+ return self._job.state(jobset.NoCache()) == jobset._RUNNING
+
+ def kill(self):
+ return self._job.kill()
+
+
+def create_qpsworker_job(language, port=10000, remote_host=None):
+ # TODO: support more languages
+ cmd = 'bins/opt/qps_worker --driver_port=%s' % port
+ if remote_host:
+ user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
+ cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && %s"' % (user_at_host, cmd)
+ host_and_port='%s:%s' % (remote_host, port)
+ else:
+ host_and_port='localhost:%s' % port
+
+ jobspec = jobset.JobSpec(
+ cmdline=[cmd],
+ shortname='qps_worker',
+ timeout_seconds=15*60,
+ shell=True)
+ return QpsWorkerJob(jobspec, host_and_port)
+
+
+def create_scenario_jobspec(scenario_name, driver_args, workers, remote_host=None):
+ """Runs one scenario using QPS driver."""
+ # setting QPS_WORKERS env variable here makes sure it works with SSH too.
+ cmd = 'QPS_WORKERS="%s" bins/opt/qps_driver ' % ','.join(workers)
+ cmd += ' '.join(driver_args)
+ if remote_host:
+ user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
+ cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && %s"' % (user_at_host, cmd)
+
+ return jobset.JobSpec(
+ cmdline=[cmd],
+ shortname='qps_driver.%s' % scenario_name,
+ timeout_seconds=3*60,
+ shell=True,
+ verbose_success=True)
+
+
+def archive_repo():
+ """Archives local version of repo including submodules."""
+ # TODO: also archive grpc-go and grpc-java repos
+ archive_job = jobset.JobSpec(
+ cmdline=['tar', '-cf', '../grpc.tar', '../grpc/'],
+ shortname='archive_repo',
+ timeout_seconds=3*60)
+
+ jobset.message('START', 'Archiving local repository.', do_newline=True)
+ num_failures, _ = jobset.run(
+ [archive_job], newline_on_success=True, maxjobs=1)
+ if num_failures == 0:
+ jobset.message('SUCCESS',
+ 'Archive with local repository create successfully.',
+ do_newline=True)
+ else:
+ jobset.message('FAILED', 'Failed to archive local repository.',
+ do_newline=True)
+ sys.exit(1)
+
+
+def prepare_remote_hosts(hosts):
+ """Prepares remote hosts."""
+ prepare_jobs = []
+ for host in hosts:
+ user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, host)
+ prepare_jobs.append(
+ jobset.JobSpec(
+ cmdline=['tools/run_tests/performance/remote_host_prepare.sh'],
+ shortname='remote_host_prepare.%s' % host,
+ environ = {'USER_AT_HOST': user_at_host},
+ timeout_seconds=3*60))
+ jobset.message('START', 'Preparing remote hosts.', do_newline=True)
+ num_failures, _ = jobset.run(
+ prepare_jobs, newline_on_success=True, maxjobs=10)
+ if num_failures == 0:
+ jobset.message('SUCCESS',
+ 'Remote hosts ready to start build.',
+ do_newline=True)
+ else:
+ jobset.message('FAILED', 'Failed to prepare remote hosts.',
+ do_newline=True)
+ sys.exit(1)
+
+
+def build_on_remote_hosts(hosts, build_local=False):
+ """Builds performance worker on remote hosts."""
+ build_timeout = 15*60
+ build_jobs = []
+ for host in hosts:
+ user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, host)
+ build_jobs.append(
+ jobset.JobSpec(
+ cmdline=['tools/run_tests/performance/remote_host_build.sh'],
+ shortname='remote_host_build.%s' % host,
+ environ = {'USER_AT_HOST': user_at_host, 'CONFIG': 'opt'},
+ timeout_seconds=build_timeout))
+ if build_local:
+ # Build locally as well
+ build_jobs.append(
+ jobset.JobSpec(
+ cmdline=['tools/run_tests/performance/build_performance.sh'],
+ shortname='local_build',
+ environ = {'CONFIG': 'opt'},
+ timeout_seconds=build_timeout))
+ jobset.message('START', 'Building on remote hosts.', do_newline=True)
+ num_failures, _ = jobset.run(
+ build_jobs, newline_on_success=True, maxjobs=10)
+ if num_failures == 0:
+ jobset.message('SUCCESS',
+ 'Build on remote hosts was successful.',
+ do_newline=True)
+ else:
+ jobset.message('FAILED', 'Failed to build on remote hosts.',
+ do_newline=True)
+ sys.exit(1)
+
+
+def start_qpsworkers(worker_hosts):
+ """Starts QPS workers as background jobs."""
+ if not worker_hosts:
+ # run two workers locally
+ workers=[(None, 10000), (None, 10010)]
+ elif len(worker_hosts) == 1:
+ # run two workers on the remote host
+ workers=[(worker_hosts[0], 10000), (worker_hosts[0], 10010)]
+ else:
+ # run one worker per each remote host
+ workers=[(worker_host, 10000) for worker_host in worker_hosts]
+
+ return [create_qpsworker_job(CXXLanguage(),
+ port=worker[1],
+ remote_host=worker[0])
+ for worker in workers]
+
+
+def create_scenarios(languages, workers, remote_host=None):
+ """Create jobspecs for scenarios to run."""
+ scenarios = []
+ for language in languages:
+ for scenario_name, driver_args in language.scenarios().iteritems():
+ scenario = create_scenario_jobspec(scenario_name,
+ driver_args,
+ workers,
+ remote_host=remote_host)
+ scenarios.append(scenario)
+
+ # the very last scenario requests shutting down the workers.
+ scenarios.append(create_scenario_jobspec('quit_workers',
+ ['--quit=true'],
+ workers,
+ remote_host=remote_host))
+ return scenarios
+
+
+def finish_qps_workers(jobs):
+ """Waits for given jobs to finish and eventually kills them."""
+ retries = 0
+ while any(job.is_running() for job in jobs):
+ for job in qpsworker_jobs:
+ if job.is_running():
+ print 'QPS worker "%s" is still running.' % job.host_and_port
+ if retries > 10:
+ print 'Killing all QPS workers.'
+ for job in jobs:
+ job.kill()
+ retries += 1
+ time.sleep(3)
+ print 'All QPS workers finished.'
+
+
+argp = argparse.ArgumentParser(description='Run performance tests.')
+argp.add_argument('--remote_driver_host',
+ default=None,
+ help='Run QPS driver on given host. By default, QPS driver is run locally.')
+argp.add_argument('--remote_worker_host',
+ nargs='+',
+ default=[],
+ help='Worker hosts where to start QPS workers.')
+
+args = argp.parse_args()
+
+# Put together set of remote hosts where to run and build
+remote_hosts = set()
+if args.remote_worker_host:
+ for host in args.remote_worker_host:
+ remote_hosts.add(host)
+if args.remote_driver_host:
+ remote_hosts.add(args.remote_driver_host)
+
+if remote_hosts:
+ archive_repo()
+ prepare_remote_hosts(remote_hosts)
+
+build_local = False
+if not args.remote_driver_host:
+ build_local = True
+build_on_remote_hosts(remote_hosts, build_local=build_local)
+
+qpsworker_jobs = start_qpsworkers(args.remote_worker_host)
+
+worker_addresses = [job.host_and_port for job in qpsworker_jobs]
+
+try:
+ scenarios = create_scenarios(languages=[CXXLanguage()],
+ workers=worker_addresses,
+ remote_host=args.remote_driver_host)
+ if not scenarios:
+ raise Exception('No scenarios to run')
+
+ jobset.message('START', 'Running scenarios.', do_newline=True)
+ num_failures, _ = jobset.run(
+ scenarios, newline_on_success=True, maxjobs=1)
+ if num_failures == 0:
+ jobset.message('SUCCESS',
+ 'All scenarios finished successfully.',
+ do_newline=True)
+ else:
+ jobset.message('FAILED', 'Some of the scenarios failed.',
+ do_newline=True)
+ sys.exit(1)
+finally:
+ finish_qps_workers(qpsworker_jobs)
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index d4b7250cbb..e3be14e7c7 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -40,6 +40,7 @@ export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
export CFLAGS="-I$ROOT/include -std=c89"
export LDFLAGS="-L$ROOT/libs/$CONFIG"
export GRPC_PYTHON_BUILD_WITH_CYTHON=1
+export GRPC_PYTHON_USE_PRECOMPILED_BINARIES=0
if [ "$CONFIG" = "gcov" ]
then
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index a9438045aa..71bb7b12db 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -120,7 +120,12 @@ def get_c_tests(travis, test_lang) :
def _check_compiler(compiler, supported_compilers):
if compiler not in supported_compilers:
- raise Exception('Compiler %s not supported.' % compiler)
+ raise Exception('Compiler %s not supported (on this platform).' % compiler)
+
+
+def _check_arch(arch, supported_archs):
+ if arch not in supported_archs:
+ raise Exception('Architecture %s not supported.' % arch)
def _is_use_docker_child():
@@ -464,7 +469,20 @@ class CSharpLanguage(object):
def configure(self, config, args):
self.config = config
self.args = args
- _check_compiler(self.args.compiler, ['default'])
+ if self.platform == 'windows':
+ # Explicitly choosing between x86 and x64 arch doesn't work yet
+ _check_arch(self.args.arch, ['default'])
+ self._make_options = [_windows_toolset_option(self.args.compiler),
+ _windows_arch_option(self.args.arch)]
+ else:
+ _check_compiler(self.args.compiler, ['default'])
+ if self.platform == 'mac':
+ # On Mac, official distribution of mono is 32bit.
+ # TODO(jtattermusch): EMBED_ZLIB=true currently breaks the mac build
+ self._make_options = ['EMBED_OPENSSL=true',
+ 'CFLAGS=-m32', 'LDFLAGS=-m32']
+ else:
+ self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true']
def test_specs(self):
with open('src/csharp/tests.json') as f:
@@ -511,23 +529,16 @@ class CSharpLanguage(object):
return [['tools/run_tests/pre_build_csharp.sh']]
def make_targets(self):
- # For Windows, this target doesn't really build anything,
- # everything is build by buildall script later.
- if self.platform == 'windows':
- return []
- else:
- return ['grpc_csharp_ext']
+ return ['grpc_csharp_ext']
def make_options(self):
- if self.platform == 'mac':
- # On Mac, official distribution of mono is 32bit.
- return ['CFLAGS=-arch i386', 'LDFLAGS=-arch i386']
- else:
- return []
+ return self._make_options;
def build_steps(self):
if self.platform == 'windows':
- return [['src\\csharp\\buildall.bat']]
+ return [[_windows_build_bat(self.args.compiler),
+ 'src/csharp/Grpc.sln',
+ '/p:Configuration=%s' % _MSBUILD_CONFIG[self.config.build_config]]]
else:
return [['tools/run_tests/build_csharp.sh']]
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index d3e8a5dbbc..7e456d2816 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1035,6 +1035,54 @@
],
"headers": [],
"language": "c",
+ "name": "internal_api_canary_iomgr_test",
+ "src": [
+ "test/core/internal_api_canaries/iomgr.c"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "language": "c",
+ "name": "internal_api_canary_support_test",
+ "src": [
+ "test/core/internal_api_canaries/iomgr.c"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "language": "c",
+ "name": "internal_api_canary_transport_test",
+ "src": [
+ "test/core/internal_api_canaries/iomgr.c"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "language": "c",
"name": "invalid_call_argument_test",
"src": [
"test/core/end2end/invalid_call_argument_test.c"
diff --git a/vsprojects/build_vs2010.bat b/vsprojects/build_vs2010.bat
index 64b0ed5d3f..1bc3c86a92 100644
--- a/vsprojects/build_vs2010.bat
+++ b/vsprojects/build_vs2010.bat
@@ -1,5 +1,5 @@
@rem Convenience wrapper that runs specified gRPC target using msbuild
-@rem Usage: build.bat TARGET_NAME
+@rem Usage: build_vs2010.bat TARGET_NAME
setlocal
@rem Set VS variables (uses Visual Studio 2010)
diff --git a/vsprojects/build_vs2013.bat b/vsprojects/build_vs2013.bat
index be3caa9298..82c0a3ad82 100644
--- a/vsprojects/build_vs2013.bat
+++ b/vsprojects/build_vs2013.bat
@@ -1,5 +1,5 @@
@rem Convenience wrapper that runs specified gRPC target using msbuild
-@rem Usage: build.bat TARGET_NAME
+@rem Usage: build_vs2013.bat TARGET_NAME
setlocal
@rem Set VS variables (uses Visual Studio 2013)
diff --git a/vsprojects/build_vs2015.bat b/vsprojects/build_vs2015.bat
index 50485a30f3..c6e1b433a3 100644
--- a/vsprojects/build_vs2015.bat
+++ b/vsprojects/build_vs2015.bat
@@ -1,5 +1,5 @@
@rem Convenience wrapper that runs specified gRPC target using msbuild
-@rem Usage: build.bat TARGET_NAME
+@rem Usage: build_vs2015.bat TARGET_NAME
setlocal
@rem Set VS variables (uses Visual Studio 2015)
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index 96dc4eb107..f736c86739 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -696,6 +696,39 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "init_test", "vcxproj\test\i
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "internal_api_canary_iomgr_test", "vcxproj\test\internal_api_canary_iomgr_test\internal_api_canary_iomgr_test.vcxproj", "{28AE726B-1BFB-202B-48D2-41AF9D09B9EA}"
+ ProjectSection(myProperties) = preProject
+ lib = "False"
+ EndProjectSection
+ ProjectSection(ProjectDependencies) = postProject
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "internal_api_canary_support_test", "vcxproj\test\internal_api_canary_support_test\internal_api_canary_support_test.vcxproj", "{D53575C6-713C-E6E3-FD74-E65F20916498}"
+ ProjectSection(myProperties) = preProject
+ lib = "False"
+ EndProjectSection
+ ProjectSection(ProjectDependencies) = postProject
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "internal_api_canary_transport_test", "vcxproj\test\internal_api_canary_transport_test\internal_api_canary_transport_test.vcxproj", "{ED24E700-964E-B426-6A6A-1944E2EF7BCB}"
+ ProjectSection(myProperties) = preProject
+ lib = "False"
+ EndProjectSection
+ ProjectSection(ProjectDependencies) = postProject
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "invalid_call_argument_test", "vcxproj\test\invalid_call_argument_test\invalid_call_argument_test.vcxproj", "{C32CA8A3-58E6-8EB9-B72F-C295547D36A6}"
ProjectSection(myProperties) = preProject
lib = "False"
@@ -2453,6 +2486,54 @@ Global
{117CA7AD-C42B-9217-6C95-42A801777BC5}.Release-DLL|Win32.Build.0 = Release|Win32
{117CA7AD-C42B-9217-6C95-42A801777BC5}.Release-DLL|x64.ActiveCfg = Release|x64
{117CA7AD-C42B-9217-6C95-42A801777BC5}.Release-DLL|x64.Build.0 = Release|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug|x64.ActiveCfg = Debug|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release|Win32.ActiveCfg = Release|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release|x64.ActiveCfg = Release|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug|Win32.Build.0 = Debug|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug|x64.Build.0 = Debug|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release|Win32.Build.0 = Release|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release|x64.Build.0 = Release|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug-DLL|Win32.Build.0 = Debug|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug-DLL|x64.ActiveCfg = Debug|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug-DLL|x64.Build.0 = Debug|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release-DLL|Win32.ActiveCfg = Release|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release-DLL|Win32.Build.0 = Release|Win32
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release-DLL|x64.ActiveCfg = Release|x64
+ {28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release-DLL|x64.Build.0 = Release|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug|x64.ActiveCfg = Debug|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release|Win32.ActiveCfg = Release|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release|x64.ActiveCfg = Release|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug|Win32.Build.0 = Debug|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug|x64.Build.0 = Debug|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release|Win32.Build.0 = Release|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release|x64.Build.0 = Release|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug-DLL|Win32.Build.0 = Debug|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug-DLL|x64.ActiveCfg = Debug|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Debug-DLL|x64.Build.0 = Debug|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release-DLL|Win32.ActiveCfg = Release|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release-DLL|Win32.Build.0 = Release|Win32
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release-DLL|x64.ActiveCfg = Release|x64
+ {D53575C6-713C-E6E3-FD74-E65F20916498}.Release-DLL|x64.Build.0 = Release|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug|x64.ActiveCfg = Debug|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release|Win32.ActiveCfg = Release|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release|x64.ActiveCfg = Release|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug|Win32.Build.0 = Debug|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug|x64.Build.0 = Debug|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release|Win32.Build.0 = Release|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release|x64.Build.0 = Release|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug-DLL|Win32.Build.0 = Debug|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug-DLL|x64.ActiveCfg = Debug|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Debug-DLL|x64.Build.0 = Debug|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release-DLL|Win32.ActiveCfg = Release|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release-DLL|Win32.Build.0 = Release|Win32
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release-DLL|x64.ActiveCfg = Release|x64
+ {ED24E700-964E-B426-6A6A-1944E2EF7BCB}.Release-DLL|x64.Build.0 = Release|x64
{C32CA8A3-58E6-8EB9-B72F-C295547D36A6}.Debug|Win32.ActiveCfg = Debug|Win32
{C32CA8A3-58E6-8EB9-B72F-C295547D36A6}.Debug|x64.ActiveCfg = Debug|x64
{C32CA8A3-58E6-8EB9-B72F-C295547D36A6}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj b/vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj
new file mode 100644
index 0000000000..11d89a01c1
--- /dev/null
+++ b/vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{28AE726B-1BFB-202B-48D2-41AF9D09B9EA}</ProjectGuid>
+ <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+ <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+ <TargetName>internal_api_canary_iomgr_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'">
+ <TargetName>internal_api_canary_iomgr_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\core\internal_api_canaries\iomgr.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+ <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+ </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj.filters b/vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj.filters
new file mode 100644
index 0000000000..f1ee82d1f4
--- /dev/null
+++ b/vsprojects/vcxproj/test/internal_api_canary_iomgr_test/internal_api_canary_iomgr_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\core\internal_api_canaries\iomgr.c">
+ <Filter>test\core\internal_api_canaries</Filter>
+ </ClCompile>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="test">
+ <UniqueIdentifier>{881986d1-d1fe-b377-cf26-b3377af95009}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\core">
+ <UniqueIdentifier>{4f9a544e-5680-18ee-30d7-38179bf82cee}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\core\internal_api_canaries">
+ <UniqueIdentifier>{6ab29f78-ec9d-d63a-8e8f-0d7552b3edd4}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj b/vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj
new file mode 100644
index 0000000000..59092dc2b3
--- /dev/null
+++ b/vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D53575C6-713C-E6E3-FD74-E65F20916498}</ProjectGuid>
+ <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+ <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+ <TargetName>internal_api_canary_support_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'">
+ <TargetName>internal_api_canary_support_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\core\internal_api_canaries\iomgr.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+ <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+ </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj.filters b/vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj.filters
new file mode 100644
index 0000000000..f7f4e3200e
--- /dev/null
+++ b/vsprojects/vcxproj/test/internal_api_canary_support_test/internal_api_canary_support_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\core\internal_api_canaries\iomgr.c">
+ <Filter>test\core\internal_api_canaries</Filter>
+ </ClCompile>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="test">
+ <UniqueIdentifier>{a6c31cba-af9d-78ea-8980-8b77c9fc4485}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\core">
+ <UniqueIdentifier>{d84283b8-4529-6c09-18bf-20a69f14f7ab}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\core\internal_api_canaries">
+ <UniqueIdentifier>{ea379f93-9285-7180-0d69-24a56da2b201}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj b/vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj
new file mode 100644
index 0000000000..110f7e3b04
--- /dev/null
+++ b/vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{ED24E700-964E-B426-6A6A-1944E2EF7BCB}</ProjectGuid>
+ <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+ <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+ <TargetName>internal_api_canary_transport_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'">
+ <TargetName>internal_api_canary_transport_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\core\internal_api_canaries\iomgr.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+ <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+ </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj.filters b/vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj.filters
new file mode 100644
index 0000000000..1e0b4c5557
--- /dev/null
+++ b/vsprojects/vcxproj/test/internal_api_canary_transport_test/internal_api_canary_transport_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\core\internal_api_canaries\iomgr.c">
+ <Filter>test\core\internal_api_canaries</Filter>
+ </ClCompile>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="test">
+ <UniqueIdentifier>{38e59e26-aad9-60fd-a1a7-c8fd9b606e2f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\core">
+ <UniqueIdentifier>{79aad60f-59b8-09e2-2cad-5b5e083ac008}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\core\internal_api_canaries">
+ <UniqueIdentifier>{e4f0214e-e3ec-b5b8-c00b-2932b5ec2422}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+