diff options
-rw-r--r-- | include/grpc/support/slice_buffer.h | 3 | ||||
-rw-r--r-- | src/core/iomgr/iomgr.c | 7 | ||||
-rw-r--r-- | src/core/iomgr/pollset_multipoller_with_epoll.c | 25 | ||||
-rw-r--r-- | src/core/iomgr/pollset_multipoller_with_poll_posix.c | 22 | ||||
-rw-r--r-- | src/core/iomgr/pollset_posix.c | 50 | ||||
-rw-r--r-- | src/core/iomgr/pollset_posix.h | 1 | ||||
-rw-r--r-- | src/core/iomgr/pollset_windows.c | 4 | ||||
-rw-r--r-- | test/core/end2end/README | 2 | ||||
-rw-r--r-- | test/core/end2end/tests/channel_connectivity.c | 56 | ||||
-rw-r--r-- | test/core/util/test_config.c | 34 | ||||
-rw-r--r-- | test/cpp/end2end/end2end_test.cc | 834 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/README.md | 35 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/buildall.bat | 51 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/grpc.dependencies.zlib.autopkg | 102 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.props | 13 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.targets | 14 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/version.inc | 1 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/zlib.sln | 26 | ||||
-rw-r--r-- | vsprojects/coapp/zlib/zlib.vcxproj | 147 |
19 files changed, 977 insertions, 450 deletions
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h index f3f14a6aa0..e4f296c32a 100644 --- a/include/grpc/support/slice_buffer.h +++ b/include/grpc/support/slice_buffer.h @@ -87,7 +87,8 @@ void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b); /* move all of the elements of src into dst */ void gpr_slice_buffer_move_into(gpr_slice_buffer *src, gpr_slice_buffer *dst); /* remove n bytes from the end of a slice buffer */ -void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *garbage); +void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n, + gpr_slice_buffer *garbage); #ifdef __cplusplus } diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c index a10399311f..e61fc32925 100644 --- a/src/core/iomgr/iomgr.c +++ b/src/core/iomgr/iomgr.c @@ -51,13 +51,6 @@ static gpr_cv g_rcv; static int g_shutdown; static grpc_iomgr_object g_root_object; -void grpc_kick_poller(void) { - /* Empty. The background callback executor polls periodically. The activity - * the kicker is trying to draw the executor's attention to will be picked up - * either by one of the periodic wakeups or by one of the polling application - * threads. */ -} - void grpc_iomgr_init(void) { g_shutdown = 0; gpr_mu_init(&g_mu); diff --git a/src/core/iomgr/pollset_multipoller_with_epoll.c b/src/core/iomgr/pollset_multipoller_with_epoll.c index b22eaa6288..d26e60f665 100644 --- a/src/core/iomgr/pollset_multipoller_with_epoll.c +++ b/src/core/iomgr/pollset_multipoller_with_epoll.c @@ -213,11 +213,15 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock( int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP); int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI); int write_ev = ep_ev[i].events & EPOLLOUT; - if (read_ev || cancel) { - grpc_fd_become_readable(exec_ctx, fd); - } - if (write_ev || cancel) { - grpc_fd_become_writable(exec_ctx, fd); + if (fd == NULL) { + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); + } else { + if (read_ev || cancel) { + grpc_fd_become_readable(exec_ctx, fd); + } + if (write_ev || cancel) { + grpc_fd_become_writable(exec_ctx, fd); + } } } } @@ -246,6 +250,8 @@ static void epoll_become_multipoller(grpc_exec_ctx *exec_ctx, size_t nfds) { size_t i; pollset_hdr *h = gpr_malloc(sizeof(pollset_hdr)); + struct epoll_event ev; + int err; pollset->vtable = &multipoll_with_epoll_pollset; pollset->data.ptr = h; @@ -255,6 +261,15 @@ static void epoll_become_multipoller(grpc_exec_ctx *exec_ctx, gpr_log(GPR_ERROR, "epoll_create1 failed: %s", strerror(errno)); abort(); } + + ev.events = (uint32_t)(EPOLLIN | EPOLLET); + ev.data.ptr = NULL; + err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), &ev); + if (err < 0) { + gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), + strerror(errno)); + } + for (i = 0; i < nfds; i++) { multipoll_with_epoll_pollset_add_fd(exec_ctx, pollset, fds[i], 0); } diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c index 63e0b9edb9..1356ebe7a0 100644 --- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c +++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c @@ -114,13 +114,16 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock( h = pollset->data.ptr; timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); /* TODO(ctiller): perform just one malloc here if we exceed the inline case */ - pfds = gpr_malloc(sizeof(*pfds) * (h->fd_count + 1)); - watchers = gpr_malloc(sizeof(*watchers) * (h->fd_count + 1)); + pfds = gpr_malloc(sizeof(*pfds) * (h->fd_count + 2)); + watchers = gpr_malloc(sizeof(*watchers) * (h->fd_count + 2)); fd_count = 0; - pfd_count = 1; - pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd); + pfd_count = 2; + pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); pfds[0].events = POLLIN; - pfds[0].revents = POLLOUT; + pfds[0].revents = 0; + pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd); + pfds[1].events = POLLIN; + pfds[1].revents = 0; for (i = 0; i < h->fd_count; i++) { int remove = grpc_fd_is_orphaned(h->fds[i]); for (j = 0; !remove && j < h->del_count; j++) { @@ -143,7 +146,7 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock( h->fd_count = fd_count; gpr_mu_unlock(&pollset->mu); - for (i = 1; i < pfd_count; i++) { + for (i = 2; i < pfd_count; i++) { pfds[i].events = (short)grpc_fd_begin_poll(watchers[i].fd, pollset, POLLIN, POLLOUT, &watchers[i]); } @@ -154,7 +157,7 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock( r = grpc_poll_function(pfds, pfd_count, timeout); GRPC_SCHEDULING_END_BLOCKING_REGION; - for (i = 1; i < pfd_count; i++) { + for (i = 2; i < pfd_count; i++) { grpc_fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN, pfds[i].revents & POLLOUT); } @@ -167,9 +170,12 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock( /* do nothing */ } else { if (pfds[0].revents & POLLIN) { + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); + } + if (pfds[1].revents & POLLIN) { grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd); } - for (i = 1; i < pfd_count; i++) { + for (i = 2; i < pfd_count; i++) { if (watchers[i].fd == NULL) { continue; } diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c index f9d6aad651..82a82cc064 100644 --- a/src/core/iomgr/pollset_posix.c +++ b/src/core/iomgr/pollset_posix.c @@ -57,8 +57,16 @@ GPR_TLS_DECL(g_current_thread_poller); GPR_TLS_DECL(g_current_thread_worker); +/** Default poll() function - a pointer so that it can be overridden by some + * tests */ grpc_poll_function_type grpc_poll_function = poll; +/** The alarm system needs to be able to wakeup 'some poller' sometimes + * (specifically when a new alarm needs to be triggered earlier than the next + * alarm 'epoch'). + * This wakeup_fd gives us something to alert on when such a case occurs. */ +grpc_wakeup_fd grpc_global_wakeup_fd; + static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) { worker->prev->next = worker->next; worker->next->prev = worker->prev; @@ -121,12 +129,18 @@ void grpc_pollset_global_init(void) { gpr_tls_init(&g_current_thread_poller); gpr_tls_init(&g_current_thread_worker); grpc_wakeup_fd_global_init(); + grpc_wakeup_fd_init(&grpc_global_wakeup_fd); } void grpc_pollset_global_shutdown(void) { + grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd); + grpc_wakeup_fd_global_destroy(); gpr_tls_destroy(&g_current_thread_poller); gpr_tls_destroy(&g_current_thread_worker); - grpc_wakeup_fd_global_destroy(); +} + +void grpc_kick_poller(void) { + grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); } /* main interface */ @@ -193,6 +207,8 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, goto done; } if (grpc_alarm_check(exec_ctx, now, &deadline)) { + gpr_mu_unlock(&pollset->mu); + locked = 0; goto done; } if (pollset->shutting_down) { @@ -294,7 +310,7 @@ int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, } timeout = gpr_time_sub(deadline, now); return gpr_time_to_millis(gpr_time_add( - timeout, gpr_time_from_nanos(GPR_NS_PER_SEC - 1, GPR_TIMESPAN))); + timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN))); } /* @@ -439,7 +455,7 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, grpc_pollset_worker *worker, gpr_timespec deadline, gpr_timespec now) { - struct pollfd pfd[2]; + struct pollfd pfd[3]; grpc_fd *fd; grpc_fd_watcher fd_watcher; int timeout; @@ -452,17 +468,20 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, fd = pollset->data.ptr = NULL; } timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); - pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd); + pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); pfd[0].events = POLLIN; pfd[0].revents = 0; - nfds = 1; + pfd[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd); + pfd[1].events = POLLIN; + pfd[1].revents = 0; + nfds = 2; if (fd) { - pfd[1].fd = fd->fd; - pfd[1].revents = 0; + pfd[2].fd = fd->fd; + pfd[2].revents = 0; gpr_mu_unlock(&pollset->mu); - pfd[1].events = + pfd[2].events = (short)grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher); - if (pfd[1].events != 0) { + if (pfd[2].events != 0) { nfds++; } } else { @@ -479,8 +498,8 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, GRPC_TIMER_MARK(GRPC_PTAG_POLL_FINISHED, r); if (fd) { - grpc_fd_end_poll(exec_ctx, &fd_watcher, pfd[1].revents & POLLIN, - pfd[1].revents & POLLOUT); + grpc_fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN, + pfd[2].revents & POLLOUT); } if (r < 0) { @@ -491,13 +510,16 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, /* do nothing */ } else { if (pfd[0].revents & POLLIN) { + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); + } + if (pfd[1].revents & POLLIN) { grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd); } - if (nfds > 1) { - if (pfd[1].revents & (POLLIN | POLLHUP | POLLERR)) { + if (nfds > 2) { + if (pfd[2].revents & (POLLIN | POLLHUP | POLLERR)) { grpc_fd_become_readable(exec_ctx, fd); } - if (pfd[1].revents & (POLLOUT | POLLHUP | POLLERR)) { + if (pfd[2].revents & (POLLOUT | POLLHUP | POLLERR)) { grpc_fd_become_writable(exec_ctx, fd); } } diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h index f996dd1edf..83c5258539 100644 --- a/src/core/iomgr/pollset_posix.h +++ b/src/core/iomgr/pollset_posix.h @@ -129,5 +129,6 @@ int grpc_pollset_has_workers(grpc_pollset *pollset); /* override to allow tests to hook poll() usage */ typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int); extern grpc_poll_function_type grpc_poll_function; +extern grpc_wakeup_fd grpc_global_wakeup_fd; #endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H */ diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c index 798b637635..1b4935a841 100644 --- a/src/core/iomgr/pollset_windows.c +++ b/src/core/iomgr/pollset_windows.c @@ -230,4 +230,8 @@ void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) { } } +void grpc_kick_poller(void) { + grpc_iocp_kick(); +} + #endif /* GPR_WINSOCK_SOCKET */ diff --git a/test/core/end2end/README b/test/core/end2end/README index 59daec45d0..a18172a7a1 100644 --- a/test/core/end2end/README +++ b/test/core/end2end/README @@ -3,5 +3,5 @@ forms a complete end-to-end test. To add a new test or fixture: - add the code to the relevant directory -- update gen_build_json.py to reflect the change +- update gen_build_yaml.py to reflect the change - regenerate projects diff --git a/test/core/end2end/tests/channel_connectivity.c b/test/core/end2end/tests/channel_connectivity.c index 0b7a8a664b..be9b7fde1d 100644 --- a/test/core/end2end/tests/channel_connectivity.c +++ b/test/core/end2end/tests/channel_connectivity.c @@ -34,19 +34,49 @@ #include "test/core/end2end/end2end_tests.h" #include <grpc/support/log.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> #include <grpc/support/time.h> #include "test/core/end2end/cq_verifier.h" static void *tag(gpr_intptr t) { return (void *)t; } +typedef struct { + gpr_event started; + grpc_channel *channel; + grpc_completion_queue *cq; +} child_events; + +static void child_thread(void *arg) { + child_events *ce = arg; + grpc_event ev; + gpr_event_set(&ce->started, (void*)1); + gpr_log(GPR_DEBUG, "verifying"); + ev = grpc_completion_queue_next(ce->cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL); + GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); + GPR_ASSERT(ev.tag == tag(1)); + GPR_ASSERT(ev.success == 0); +} + static void test_connectivity(grpc_end2end_test_config config) { grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL); grpc_connectivity_state state; cq_verifier *cqv = cq_verifier_create(f.cq); + child_events ce; + gpr_thd_options thdopt = gpr_thd_options_default(); + gpr_thd_id thdid; config.init_client(&f, NULL); + ce.channel = f.client; + ce.cq = f.cq; + gpr_event_init(&ce.started); + gpr_thd_options_set_joinable(&thdopt); + GPR_ASSERT(gpr_thd_new(&thdid, child_thread, &ce, &thdopt)); + + gpr_event_wait(&ce.started, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + /* channels should start life in IDLE, and stay there */ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 0) == GRPC_CHANNEL_IDLE); @@ -55,18 +85,24 @@ static void test_connectivity(grpc_end2end_test_config config) { GRPC_CHANNEL_IDLE); /* start watching for a change */ + gpr_log(GPR_DEBUG, "watching"); grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_IDLE, - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), + gpr_now(GPR_CLOCK_MONOTONIC), f.cq, tag(1)); - /* nothing should happen */ - cq_verify_empty(cqv); + + /* eventually the child thread completion should trigger */ + gpr_thd_join(thdid); /* check that we're still in idle, and start connecting */ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) == GRPC_CHANNEL_IDLE); + /* start watching for a change */ + grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_IDLE, + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), + f.cq, tag(2)); /* and now the watch should trigger */ - cq_expect_completion(cqv, tag(1), 1); + cq_expect_completion(cqv, tag(2), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || @@ -75,8 +111,8 @@ static void test_connectivity(grpc_end2end_test_config config) { /* quickly followed by a transition to TRANSIENT_FAILURE */ grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_CONNECTING, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), - f.cq, tag(2)); - cq_expect_completion(cqv, tag(2), 1); + f.cq, tag(3)); + cq_expect_completion(cqv, tag(3), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || @@ -93,8 +129,8 @@ static void test_connectivity(grpc_end2end_test_config config) { READY is reached */ while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( - f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(3)); - cq_expect_completion(cqv, tag(3), 1); + f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(4)); + cq_expect_completion(cqv, tag(4), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -108,11 +144,11 @@ static void test_connectivity(grpc_end2end_test_config config) { grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_READY, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), - f.cq, tag(4)); + f.cq, tag(5)); grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); - cq_expect_completion(cqv, tag(4), 1); + cq_expect_completion(cqv, tag(5), 1); cq_expect_completion(cqv, tag(0xdead), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c index 30caf4b1ef..84b376ad3e 100644 --- a/test/core/util/test_config.c +++ b/test/core/util/test_config.c @@ -35,6 +35,7 @@ #include <grpc/support/port_platform.h> #include <grpc/support/log.h> +#include "src/core/support/string.h" #include <stdlib.h> #include <signal.h> @@ -88,25 +89,43 @@ static void install_crash_handler() { #include <stdio.h> #include <string.h> #include <grpc/support/useful.h> +#include <errno.h> static char g_alt_stack[MINSIGSTKSZ]; #define MAX_FRAMES 32 +/* signal safe output */ +static void output_string(const char *string) { + size_t len = strlen(string); + ssize_t r; + + do { + r = write(STDERR_FILENO, string, len); + } while (r == -1 && errno == EINTR); +} + +static void output_num(long num) { + char buf[GPR_LTOA_MIN_BUFSIZE]; + gpr_ltoa(num, buf); + output_string(buf); +} + static void crash_handler(int signum, siginfo_t *info, void *data) { void *addrlist[MAX_FRAMES + 1]; int addrlen; - int i; - char **symlist; - fprintf(stderr, "Caught signal %d\n", signum); + output_string("\n\n\n*******************************\nCaught signal "); + output_num(signum); + output_string("\n"); + addrlen = backtrace(addrlist, GPR_ARRAY_SIZE(addrlist)); - symlist = backtrace_symbols(addrlist, addrlen); - for (i = 0; i < addrlen; i++) { - fprintf(stderr, " %s\n", symlist[i]); + if (addrlen == 0) { + output_string(" no backtrace\n"); + } else { + backtrace_symbols_fd(addrlist, addrlen, STDERR_FILENO); } - free(symlist); raise(signum); } @@ -114,6 +133,7 @@ static void crash_handler(int signum, siginfo_t *info, void *data) { static void install_crash_handler() { stack_t ss; struct sigaction sa; + memset(&ss, 0, sizeof(ss)); memset(&sa, 0, sizeof(sa)); ss.ss_size = sizeof(g_alt_stack); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 2659b0e213..49a38ce544 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -62,7 +62,6 @@ using std::chrono::system_clock; namespace grpc { namespace testing { - namespace { const char* kServerCancelAfterReads = "cancel_after_reads"; @@ -195,8 +194,6 @@ const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll"; const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity"; -} // namespace - class Proxy : public ::grpc::cpp::test::util::TestService::Service { public: Proxy(std::shared_ptr<Channel> channel) @@ -353,14 +350,24 @@ class TestServiceImplDupPkg } }; -/* Param is whether or not to use a proxy -- some tests use TEST_F as they don't - need this functionality */ -class End2endTest : public ::testing::TestWithParam<bool> { +class TestScenario { + public: + TestScenario(bool proxy, bool tls) : use_proxy(proxy), use_tls(tls) {} + void Log() const { + gpr_log(GPR_INFO, "Scenario: proxy %d, tls %d", use_proxy, use_tls); + } + bool use_proxy; + bool use_tls; +}; + +class End2endTest : public ::testing::TestWithParam<TestScenario> { protected: End2endTest() : is_server_started_(false), kMaxMessageSize_(8192), - special_service_("special") {} + special_service_("special") { + GetParam().Log(); + } void TearDown() GRPC_OVERRIDE { if (is_server_started_) { @@ -374,13 +381,16 @@ class End2endTest : public ::testing::TestWithParam<bool> { server_address_ << "127.0.0.1:" << port; // Setup server ServerBuilder builder; - SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, - test_server1_cert}; - SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - auto server_creds = SslServerCredentials(ssl_opts); - server_creds->SetAuthMetadataProcessor(processor); + auto server_creds = InsecureServerCredentials(); + if (GetParam().use_tls) { + SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, + test_server1_cert}; + SslServerCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = ""; + ssl_opts.pem_key_cert_pairs.push_back(pkcp); + server_creds = SslServerCredentials(ssl_opts); + server_creds->SetAuthMetadataProcessor(processor); + } builder.AddListeningPort(server_address_.str(), server_creds); builder.RegisterService(&service_); builder.RegisterService("foo.test.youtube.com", &special_service_); @@ -396,17 +406,20 @@ class End2endTest : public ::testing::TestWithParam<bool> { StartServer(std::shared_ptr<AuthMetadataProcessor>()); } EXPECT_TRUE(is_server_started_); - SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; ChannelArguments args; - args.SetSslTargetNameOverride("foo.test.google.fr"); + auto channel_creds = InsecureCredentials(); + if (GetParam().use_tls) { + SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; + args.SetSslTargetNameOverride("foo.test.google.fr"); + channel_creds = SslCredentials(ssl_opts); + } args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test"); - channel_ = CreateCustomChannel(server_address_.str(), - SslCredentials(ssl_opts), args); + channel_ = CreateCustomChannel(server_address_.str(), channel_creds, args); } - void ResetStub(bool use_proxy) { + void ResetStub() { ResetChannel(); - if (use_proxy) { + if (GetParam().use_proxy) { proxy_service_.reset(new Proxy(channel_)); int port = grpc_pick_unused_port_or_die(); std::ostringstream proxyaddr; @@ -450,124 +463,8 @@ static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub, } } -TEST_F(End2endTest, SimpleRpcWithHost) { - ResetStub(false); - - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - context.set_authority("foo.test.youtube.com"); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(response.has_param()); - EXPECT_EQ("special", response.param().host()); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, SimpleRpc) { - ResetStub(GetParam()); - SendRpc(stub_.get(), 1); -} - -TEST_P(End2endTest, MultipleRpcs) { - ResetStub(GetParam()); - std::vector<std::thread*> threads; - for (int i = 0; i < 10; ++i) { - threads.push_back(new std::thread(SendRpc, stub_.get(), 10)); - } - for (int i = 0; i < 10; ++i) { - threads[i]->join(); - delete threads[i]; - } -} - -// Set a 10us deadline and make sure proper error is returned. -TEST_P(End2endTest, RpcDeadlineExpires) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::microseconds(10); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code()); -} - -// Set a long but finite deadline. -TEST_P(End2endTest, RpcLongDeadline) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::hours(1); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); -} - -// Ask server to echo back the deadline it sees. -TEST_P(End2endTest, EchoDeadline) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_echo_deadline(true); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::seconds(100); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - gpr_timespec sent_deadline; - Timepoint2Timespec(deadline, &sent_deadline); - // Allow 1 second error. - EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1); - EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1); -} - -// Ask server to echo back the deadline it sees. The rpc has no deadline. -TEST_P(End2endTest, EchoDeadlineForNoDeadlineRpc) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_echo_deadline(true); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(response.param().request_deadline(), - gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec); -} - -TEST_P(End2endTest, UnimplementedRpc) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - Status s = stub_->Unimplemented(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED); - EXPECT_EQ(s.error_message(), ""); - EXPECT_EQ(response.message(), ""); -} - -TEST_F(End2endTest, RequestStreamOneRequest) { - ResetStub(false); +TEST_P(End2endTest, RequestStreamOneRequest) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -581,8 +478,8 @@ TEST_F(End2endTest, RequestStreamOneRequest) { EXPECT_TRUE(s.ok()); } -TEST_F(End2endTest, RequestStreamTwoRequests) { - ResetStub(false); +TEST_P(End2endTest, RequestStreamTwoRequests) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -597,8 +494,8 @@ TEST_F(End2endTest, RequestStreamTwoRequests) { EXPECT_TRUE(s.ok()); } -TEST_F(End2endTest, ResponseStream) { - ResetStub(false); +TEST_P(End2endTest, ResponseStream) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -617,8 +514,8 @@ TEST_F(End2endTest, ResponseStream) { EXPECT_TRUE(s.ok()); } -TEST_F(End2endTest, BidiStream) { - ResetStub(false); +TEST_P(End2endTest, BidiStream) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -650,8 +547,8 @@ TEST_F(End2endTest, BidiStream) { // Talk to the two services with the same name but different package names. // The two stubs are created on the same channel. -TEST_F(End2endTest, DiffPackageServices) { - ResetStub(false); +TEST_P(End2endTest, DiffPackageServices) { + ResetStub(); EchoRequest request; EchoResponse response; request.set_message("Hello"); @@ -670,33 +567,6 @@ TEST_F(End2endTest, DiffPackageServices) { EXPECT_TRUE(s.ok()); } -// rpc and stream should fail on bad credentials. -TEST_F(End2endTest, BadCredentials) { - std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials(""); - EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get()); - std::shared_ptr<Channel> channel = - CreateChannel(server_address_.str(), bad_creds); - std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub( - grpc::cpp::test::util::TestService::NewStub(channel)); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("Hello"); - - Status s = stub->Echo(&context, request, &response); - EXPECT_EQ("", response.message()); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code()); - EXPECT_EQ("Invalid credentials.", s.error_message()); - - ClientContext context2; - auto stream = stub->BidiStream(&context2); - s = stream->Finish(); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code()); - EXPECT_EQ("Invalid credentials.", s.error_message()); -} - void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(delay_us, GPR_TIMESPAN))); @@ -705,40 +575,9 @@ void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { context->TryCancel(); } -// Client cancels rpc after 10ms -TEST_P(End2endTest, ClientCancelsRpc) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - const int kCancelDelayUs = 10 * 1000; - request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); - - ClientContext context; - std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_); - Status s = stub_->Echo(&context, request, &response); - cancel_thread.join(); - EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); - EXPECT_EQ(s.error_message(), "Cancelled"); -} - -// Server cancels rpc after 1ms -TEST_P(End2endTest, ServerCancelsRpc) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_server_cancel_after_us(1000); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); - EXPECT_TRUE(s.error_message().empty()); -} - // Client cancels request stream after sending two messages -TEST_F(End2endTest, ClientCancelsRequestStream) { - ResetStub(false); +TEST_P(End2endTest, ClientCancelsRequestStream) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -757,8 +596,8 @@ TEST_F(End2endTest, ClientCancelsRequestStream) { } // Client cancels server stream after sending some messages -TEST_F(End2endTest, ClientCancelsResponseStream) { - ResetStub(false); +TEST_P(End2endTest, ClientCancelsResponseStream) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -789,8 +628,8 @@ TEST_F(End2endTest, ClientCancelsResponseStream) { } // Client cancels bidi stream after sending some messages -TEST_F(End2endTest, ClientCancelsBidi) { - ResetStub(false); +TEST_P(End2endTest, ClientCancelsBidi) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -821,8 +660,8 @@ TEST_F(End2endTest, ClientCancelsBidi) { EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); } -TEST_F(End2endTest, RpcMaxMessageSize) { - ResetStub(false); +TEST_P(End2endTest, RpcMaxMessageSize) { + ResetStub(); EchoRequest request; EchoResponse response; request.set_message(string(kMaxMessageSize_ * 2, 'a')); @@ -832,6 +671,328 @@ TEST_F(End2endTest, RpcMaxMessageSize) { EXPECT_FALSE(s.ok()); } +// Client sends 20 requests and the server returns CANCELLED status after +// reading 10 requests. +TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) { + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + + context.AddMetadata(kServerCancelAfterReads, "10"); + auto stream = stub_->RequestStream(&context, &response); + request.set_message("hello"); + int send_messages = 20; + while (send_messages > 0) { + EXPECT_TRUE(stream->Write(request)); + send_messages--; + } + stream->WritesDone(); + Status s = stream->Finish(); + EXPECT_EQ(s.error_code(), StatusCode::CANCELLED); +} + +void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream, + gpr_event* ev) { + EchoResponse resp; + gpr_event_set(ev, (void*)1); + while (stream->Read(&resp)) { + gpr_log(GPR_INFO, "Read message"); + } +} + +// Run a Read and a WritesDone simultaneously. +TEST_P(End2endTest, SimultaneousReadWritesDone) { + ResetStub(); + ClientContext context; + gpr_event ev; + gpr_event_init(&ev); + auto stream = stub_->BidiStream(&context); + std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev); + gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME)); + stream->WritesDone(); + Status s = stream->Finish(); + EXPECT_TRUE(s.ok()); + reader_thread.join(); +} + +TEST_P(End2endTest, ChannelState) { + ResetStub(); + // Start IDLE + EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false)); + + // Did not ask to connect, no state change. + CompletionQueue cq; + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::milliseconds(10); + channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL); + void* tag; + bool ok = true; + cq.Next(&tag, &ok); + EXPECT_FALSE(ok); + + EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true)); + EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE, + gpr_inf_future(GPR_CLOCK_REALTIME))); + EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel_->GetState(false)); +} + +// Takes 10s. +TEST_P(End2endTest, ChannelStateTimeout) { + if (GetParam().use_tls) { + return; + } + int port = grpc_pick_unused_port_or_die(); + std::ostringstream server_address; + server_address << "127.0.0.1:" << port; + // Channel to non-existing server + auto channel = CreateChannel(server_address.str(), InsecureCredentials()); + // Start IDLE + EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); + + auto state = GRPC_CHANNEL_IDLE; + for (int i = 0; i < 10; i++) { + channel->WaitForStateChange( + state, std::chrono::system_clock::now() + std::chrono::seconds(1)); + state = channel->GetState(false); + } +} + +// Talking to a non-existing service. +TEST_P(End2endTest, NonExistingService) { + ResetChannel(); + std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub; + stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel_); + + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + Status s = stub->Unimplemented(&context, request, &response); + EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code()); + EXPECT_EQ("", s.error_message()); +} + +////////////////////////////////////////////////////////////////////////// +// Test with and without a proxy. +class ProxyEnd2endTest : public End2endTest { + protected: +}; + +TEST_P(ProxyEnd2endTest, SimpleRpc) { + ResetStub(); + SendRpc(stub_.get(), 1); +} + +TEST_P(ProxyEnd2endTest, MultipleRpcs) { + ResetStub(); + std::vector<std::thread*> threads; + for (int i = 0; i < 10; ++i) { + threads.push_back(new std::thread(SendRpc, stub_.get(), 10)); + } + for (int i = 0; i < 10; ++i) { + threads[i]->join(); + delete threads[i]; + } +} + +// Set a 10us deadline and make sure proper error is returned. +TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::microseconds(10); + context.set_deadline(deadline); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code()); +} + +// Set a long but finite deadline. +TEST_P(ProxyEnd2endTest, RpcLongDeadline) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::hours(1); + context.set_deadline(deadline); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); +} + +// Ask server to echo back the deadline it sees. +TEST_P(ProxyEnd2endTest, EchoDeadline) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_echo_deadline(true); + + ClientContext context; + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::seconds(100); + context.set_deadline(deadline); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); + gpr_timespec sent_deadline; + Timepoint2Timespec(deadline, &sent_deadline); + // Allow 1 second error. + EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1); + EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1); +} + +// Ask server to echo back the deadline it sees. The rpc has no deadline. +TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_echo_deadline(true); + + ClientContext context; + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response.param().request_deadline(), + gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec); +} + +TEST_P(ProxyEnd2endTest, UnimplementedRpc) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + Status s = stub_->Unimplemented(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED); + EXPECT_EQ(s.error_message(), ""); + EXPECT_EQ(response.message(), ""); +} + +// Client cancels rpc after 10ms +TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + const int kCancelDelayUs = 10 * 1000; + request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); + + ClientContext context; + std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_); + Status s = stub_->Echo(&context, request, &response); + cancel_thread.join(); + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(s.error_message(), "Cancelled"); +} + +// Server cancels rpc after 1ms +TEST_P(ProxyEnd2endTest, ServerCancelsRpc) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_server_cancel_after_us(1000); + + ClientContext context; + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); + EXPECT_TRUE(s.error_message().empty()); +} + +// Make the response larger than the flow control window. +TEST_P(ProxyEnd2endTest, HugeResponse) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("huge response"); + const size_t kResponseSize = 1024 * (1024 + 10); + request.mutable_param()->set_response_message_length(kResponseSize); + + ClientContext context; + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(kResponseSize, response.message().size()); + EXPECT_TRUE(s.ok()); +} + +TEST_P(ProxyEnd2endTest, Peer) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("hello"); + request.mutable_param()->set_echo_peer(true); + + ClientContext context; + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); + EXPECT_TRUE(CheckIsLocalhost(response.param().peer())); + EXPECT_TRUE(CheckIsLocalhost(context.peer())); +} + +////////////////////////////////////////////////////////////////////////// +class SecureEnd2endTest : public End2endTest { + protected: + SecureEnd2endTest() { + GPR_ASSERT(!GetParam().use_proxy); + GPR_ASSERT(GetParam().use_tls); + } +}; + +TEST_P(SecureEnd2endTest, SimpleRpcWithHost) { + ResetStub(); + + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + context.set_authority("foo.test.youtube.com"); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(response.has_param()); + EXPECT_EQ("special", response.param().host()); + EXPECT_TRUE(s.ok()); +} + +// rpc and stream should fail on bad credentials. +TEST_P(SecureEnd2endTest, BadCredentials) { + std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials(""); + EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get()); + std::shared_ptr<Channel> channel = + CreateChannel(server_address_.str(), bad_creds); + std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub( + grpc::cpp::test::util::TestService::NewStub(channel)); + EchoRequest request; + EchoResponse response; + ClientContext context; + request.set_message("Hello"); + + Status s = stub->Echo(&context, request, &response); + EXPECT_EQ("", response.message()); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code()); + EXPECT_EQ("Invalid credentials.", s.error_message()); + + ClientContext context2; + auto stream = stub->BidiStream(&context2); + s = stream->Finish(); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code()); + EXPECT_EQ("Invalid credentials.", s.error_message()); +} + bool MetadataContains( const std::multimap<grpc::string_ref, grpc::string_ref>& metadata, const grpc::string& key, const grpc::string& value) { @@ -847,8 +1008,45 @@ bool MetadataContains( return count == 1; } -TEST_F(End2endTest, SetPerCallCredentials) { - ResetStub(false); +TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { + auto* processor = new TestAuthMetadataProcessor(true); + StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials(processor->GetCompatibleClientCreds()); + request.set_message("Hello"); + request.mutable_param()->set_echo_metadata(true); + request.mutable_param()->set_expected_client_identity( + TestAuthMetadataProcessor::kGoodGuy); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(request.message(), response.message()); + EXPECT_TRUE(s.ok()); + + // Metadata should have been consumed by the processor. + EXPECT_FALSE(MetadataContains( + context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY, + grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); +} + +TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { + auto* processor = new TestAuthMetadataProcessor(true); + StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials(processor->GetIncompatibleClientCreds()); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); +} +TEST_P(SecureEnd2endTest, SetPerCallCredentials) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -869,8 +1067,8 @@ TEST_F(End2endTest, SetPerCallCredentials) { "fake_selector")); } -TEST_F(End2endTest, InsecurePerCallCredentials) { - ResetStub(false); +TEST_P(SecureEnd2endTest, InsecurePerCallCredentials) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -884,8 +1082,8 @@ TEST_F(End2endTest, InsecurePerCallCredentials) { EXPECT_EQ("Failed to set credentials to rpc.", s.error_message()); } -TEST_F(End2endTest, OverridePerCallCredentials) { - ResetStub(false); +TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -915,8 +1113,8 @@ TEST_F(End2endTest, OverridePerCallCredentials) { EXPECT_TRUE(s.ok()); } -TEST_F(End2endTest, NonBlockingAuthMetadataPluginFailure) { - ResetStub(false); +TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -932,10 +1130,10 @@ TEST_F(End2endTest, NonBlockingAuthMetadataPluginFailure) { EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); } -TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { +TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { auto* processor = new TestAuthMetadataProcessor(false); StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(false); + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -955,10 +1153,10 @@ TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); } -TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { +TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { auto* processor = new TestAuthMetadataProcessor(false); StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(false); + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -970,8 +1168,8 @@ TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); } -TEST_F(End2endTest, BlockingAuthMetadataPluginFailure) { - ResetStub(false); +TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { + ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; @@ -987,67 +1185,8 @@ TEST_F(End2endTest, BlockingAuthMetadataPluginFailure) { EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); } -TEST_F(End2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { - auto* processor = new TestAuthMetadataProcessor(true); - StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(false); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(processor->GetCompatibleClientCreds()); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - request.mutable_param()->set_expected_client_identity( - TestAuthMetadataProcessor::kGoodGuy); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - - // Metadata should have been consumed by the processor. - EXPECT_FALSE(MetadataContains( - context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY, - grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); -} - -TEST_F(End2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { - auto* processor = new TestAuthMetadataProcessor(true); - StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(false); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(processor->GetIncompatibleClientCreds()); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); -} - -// Client sends 20 requests and the server returns CANCELLED status after -// reading 10 requests. -TEST_F(End2endTest, RequestStreamServerEarlyCancelTest) { - ResetStub(false); - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.AddMetadata(kServerCancelAfterReads, "10"); - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - int send_messages = 20; - while (send_messages > 0) { - EXPECT_TRUE(stream->Write(request)); - send_messages--; - } - stream->WritesDone(); - Status s = stream->Finish(); - EXPECT_EQ(s.error_code(), StatusCode::CANCELLED); -} - -TEST_F(End2endTest, ClientAuthContext) { - ResetStub(false); +TEST_P(SecureEnd2endTest, ClientAuthContext) { + ResetStub(); EchoRequest request; EchoResponse response; request.set_message("Hello"); @@ -1072,119 +1211,20 @@ TEST_F(End2endTest, ClientAuthContext) { EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2])); } -// Make the response larger than the flow control window. -TEST_P(End2endTest, HugeResponse) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("huge response"); - const size_t kResponseSize = 1024 * (1024 + 10); - request.mutable_param()->set_response_message_length(kResponseSize); +INSTANTIATE_TEST_CASE_P(End2end, End2endTest, + ::testing::Values(TestScenario(false, true), + TestScenario(false, false))); - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(kResponseSize, response.message().size()); - EXPECT_TRUE(s.ok()); -} +INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest, + ::testing::Values(TestScenario(true, true), + TestScenario(true, false), + TestScenario(false, true), + TestScenario(false, false))); -namespace { -void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream, - gpr_event* ev) { - EchoResponse resp; - gpr_event_set(ev, (void*)1); - while (stream->Read(&resp)) { - gpr_log(GPR_INFO, "Read message"); - } -} -} // namespace - -// Run a Read and a WritesDone simultaneously. -TEST_F(End2endTest, SimultaneousReadWritesDone) { - ResetStub(false); - ClientContext context; - gpr_event ev; - gpr_event_init(&ev); - auto stream = stub_->BidiStream(&context); - std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev); - gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME)); - stream->WritesDone(); - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); - reader_thread.join(); -} - -TEST_P(End2endTest, Peer) { - ResetStub(GetParam()); - EchoRequest request; - EchoResponse response; - request.set_message("hello"); - request.mutable_param()->set_echo_peer(true); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(CheckIsLocalhost(response.param().peer())); - EXPECT_TRUE(CheckIsLocalhost(context.peer())); -} - -TEST_F(End2endTest, ChannelState) { - ResetStub(false); - // Start IDLE - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false)); - - // Did not ask to connect, no state change. - CompletionQueue cq; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::milliseconds(10); - channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL); - void* tag; - bool ok = true; - cq.Next(&tag, &ok); - EXPECT_FALSE(ok); - - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true)); - EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE, - gpr_inf_future(GPR_CLOCK_REALTIME))); - EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel_->GetState(false)); -} - -// Takes 10s. -TEST_F(End2endTest, ChannelStateTimeout) { - int port = grpc_pick_unused_port_or_die(); - std::ostringstream server_address; - server_address << "127.0.0.1:" << port; - // Channel to non-existing server - auto channel = CreateChannel(server_address.str(), InsecureCredentials()); - // Start IDLE - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); - - auto state = GRPC_CHANNEL_IDLE; - for (int i = 0; i < 10; i++) { - channel->WaitForStateChange( - state, std::chrono::system_clock::now() + std::chrono::seconds(1)); - state = channel->GetState(false); - } -} - -// Talking to a non-existing service. -TEST_F(End2endTest, NonExistingService) { - ResetChannel(); - std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub; - stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel_); - - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - Status s = stub->Unimplemented(&context, request, &response); - EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code()); - EXPECT_EQ("", s.error_message()); -} - -INSTANTIATE_TEST_CASE_P(End2end, End2endTest, ::testing::Values(false, true)); +INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest, + ::testing::Values(TestScenario(false, true))); +} // namespace } // namespace testing } // namespace grpc diff --git a/vsprojects/coapp/zlib/README.md b/vsprojects/coapp/zlib/README.md new file mode 100644 index 0000000000..c81a57a48b --- /dev/null +++ b/vsprojects/coapp/zlib/README.md @@ -0,0 +1,35 @@ +Zlib Native Nuget package +------------------------- + +Uses [CoApp](http://coapp.org/) project to build the zlib package. + +Prerequisites +------------- +Multiple versions of VS installed to be able to build all the targets: +* Visual Studio 2013 +* Visual Studio 2010 (you might need SP1 to prevent LNK1123 error) + +CoApp toolkit: http://downloads.coapp.org/files/CoApp.Tools.Powershell.msi + +More details on installation: http://coapp.org/tutorials/installation.html + +Building +-------- + +Build all flavors of zlib library using the provided batch file. +``` +buildall.bat +``` + +Then, create NuGet package using powershell (you'll need the CoApp toolkit installed): +``` +[THIS_DIRECTORY]> Write-NuGetPackage grpc.dependencies.zlib.autopkg +``` + +This will create three NuGet packages: +* the main dev package +* the redistributable package that contains just the binaries and no headers +* the symbols package (debug symbols) + +Later, you can push the package to NuGet.org repo. +Attention: before pusing the resulting nuget package to public nuget repo, you have to be 100% sure it works correctly - there’s no way how to delete or update an already existing package.
\ No newline at end of file diff --git a/vsprojects/coapp/zlib/buildall.bat b/vsprojects/coapp/zlib/buildall.bat new file mode 100644 index 0000000000..a71e56f4ae --- /dev/null +++ b/vsprojects/coapp/zlib/buildall.bat @@ -0,0 +1,51 @@ +@echo off +setlocal + +setlocal +call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64 +call :build x64 Release v120 || goto :eof +call :build x64 Debug v120 || goto :eof +endlocal + +setlocal +call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86 +call :build Win32 Release v120 || goto :eof +call :build Win32 Debug v120 || goto :eof +endlocal + +REM setlocal +REM call "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64 +REM call :build x64 Release v110 || goto :eof +REM call :build x64 Debug v110 || goto :eof +REM endlocal + +REM setlocal +REM call "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" x86 +REM call :build Win32 Release v110 || goto :eof +REM call :build Win32 Debug v110 || goto :eof +REM endlocal + +REM setlocal +REM call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64 +REM call :build x64 Release v100 || goto :eof +REM call :build x64 Debug v100 || goto :eof +REM endlocal + +setlocal +call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 +call :build Win32 Release v100 || goto :eof +call :build Win32 Debug v100 || goto :eof +endlocal + +goto :eof + +:build +msbuild /P:Platform=%1 /P:Configuration=%2 /P:PlatformToolset=%3 /P:UsesConfigurationType=Dynamic /P:CallingConvention=cdecl .\zlib.sln || goto :eof +msbuild /P:Platform=%1 /P:Configuration=%2 /P:PlatformToolset=%3 /P:UsesConfigurationType=Dynamic /P:CallingConvention=stdcall .\zlib.sln || goto :eof +msbuild /P:Platform=%1 /P:Configuration=%2 /P:PlatformToolset=%3 /P:UsesConfigurationType=Static /P:CallingConvention=cdecl .\zlib.sln || goto :eof +msbuild /P:Platform=%1 /P:Configuration=%2 /P:PlatformToolset=%3 /P:UsesConfigurationType=Static /P:CallingConvention=stdcall .\zlib.sln || goto :eof +msbuild /P:Platform=%1 /P:Configuration=%2 /P:PlatformToolset=%3 /P:UsesConfigurationType=ltcg /P:CallingConvention=cdecl .\zlib.sln || goto :eof +msbuild /P:Platform=%1 /P:Configuration=%2 /P:PlatformToolset=%3 /P:UsesConfigurationType=ltcg /P:CallingConvention=stdcall .\zlib.sln || goto :eof +goto :eof + + diff --git a/vsprojects/coapp/zlib/grpc.dependencies.zlib.autopkg b/vsprojects/coapp/zlib/grpc.dependencies.zlib.autopkg new file mode 100644 index 0000000000..01390b9434 --- /dev/null +++ b/vsprojects/coapp/zlib/grpc.dependencies.zlib.autopkg @@ -0,0 +1,102 @@ +@import @"version.inc"; + +configurations { +}; + +#define { + package-id = "grpc.dependencies.zlib"; +} + +nuget { + // the nuspec file metadata. Gets created/updated on build + nuspec { + id = ${package-id}; + version : ${package-version}; + title: gRPC Native Dependency: ZLib compression library; + authors: {Jean-loup Gailly, Mark Adler, Garrett Serack, Tim Rogers}; + owners: {Jan Tattermusch}; + licenseUrl: "http://zlib.net/zlib-license.html"; + projectUrl: "http://github.com/jtattermusch/zlib"; + iconUrl: "http://zlib.net/images/zlib3d-b1.png"; + requireLicenseAcceptance:false; + summary:A zlib library; + description: @"A native zlib library. + zlib homepage: http://zlib.net"; + releaseNotes: "Release of zlib 1.2.8 libraries."; + copyright: Copyright 2013; + tags: { zlib, native, CoApp }; + + }; + + // the files that go into the content folders + // (inserted into the nuspec file) + files { + // .targets file that are applied when redist package is installed from a managed project. + managed_build: { + #output { + package = redist; + }; + #destination = "\build\portable-net45"; + "managed_targets\${package-id}.redist.props"; + "managed_targets\${package-id}.redist.targets"; + }; + + include: { ..\..\..\third_party\zlib\zlib.h, ..\..\..\third_party\zlib\zconf.h }; + + docs: { ..\..\..\third_party\zlib\doc\**\* }; + + source += { + "..\..\..\third_party\zlib\adler32.c", + "..\..\..\third_party\zlib\compress.c", + "..\..\..\third_party\zlib\crc32.c", + "..\..\..\third_party\zlib\deflate.c", + "..\..\..\third_party\zlib\gzclose.c", + "..\..\..\third_party\zlib\gzlib.c", + "..\..\..\third_party\zlib\gzread.c", + "..\..\..\third_party\zlib\gzwrite.c", + "..\..\..\third_party\zlib\infback.c", + "..\..\..\third_party\zlib\inffast.c", + "..\..\..\third_party\zlib\inflate.c", + "..\..\..\third_party\zlib\inftrees.c", + "..\..\..\third_party\zlib\trees.c", + "..\..\..\third_party\zlib\uncompr.c", + "..\..\..\third_party\zlib\zutil.c", + "..\..\..\third_party\zlib\crc32.h", + "..\..\..\third_party\zlib\deflate.h", + "..\..\..\third_party\zlib\gzguts.h", + "..\..\..\third_party\zlib\inffast.h", + "..\..\..\third_party\zlib\inffixed.h", + "..\..\..\third_party\zlib\inflate.h", + "..\..\..\third_party\zlib\inftrees.h", + "..\..\..\third_party\zlib\trees.h", + "..\..\..\third_party\zlib\zconf.h", + "..\..\..\third_party\zlib\zlib.h", + "..\..\..\third_party\zlib\zutil.h", + "..\..\..\third_party\zlib\contrib\masmx64\inffas8664.c", + }; + ("v100,v120", "Win32,x64", "Release,Debug", "Dynamic", "cdecl,stdcall", "MultiByte") => { + [${0},${1},${2},${3},${4}] { + lib: { .\output\${0}\${1}\${2}\${3}\${4}\${5}\*.lib }; + bin: { .\output\${0}\${1}\${2}\${3}\${4}\${5}\*.dll }; + symbols: { .\output\${0}\${1}\${2}\${3}\${4}\${5}\*.pdb }; + }; + }; + ("v100,v120", "Win32,x64", "Release,Debug", "Static,ltcg", "cdecl,stdcall", "MultiByte") => { + [${0},${1},${2},${3},${4}] { + lib: { .\output\${0}\${1}\${2}\${3}\${4}\${5}\*.lib }; + }; + }; + + }; + + // the VC++ .targets file that gets generated and inserted into the ${d_content} folder + targets { + Defines += HAS_ZLIB; + [dynamic] + Defines += ZLIB_DLL; + [stdcall] + Defines += ZLIB_WINAPI; + + }; +} + diff --git a/vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.props b/vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.props new file mode 100644 index 0000000000..bcb37de0f7 --- /dev/null +++ b/vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.props @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <!-- Whether or not copy native dependencies to output directory after building --> + <CopyNativeDependencies Condition=" '$(CopyNativeDependencies)' == '' ">true</CopyNativeDependencies> + + <!-- Set defaults for native dependencies if not already set. Properties can be overriden in the project files. --> + <NativeDependenciesToolset Condition=" '$(NativeDependenciesToolset)' == '' ">v120</NativeDependenciesToolset> + <NativeDependenciesPlatform Condition=" '$(NativeDependenciesPlatform)' == '' ">Win32</NativeDependenciesPlatform> + <NativeDependenciesConfiguration Condition=" '$(NativeDependenciesConfiguration)' == '' ">Debug</NativeDependenciesConfiguration> + <ZlibCallingConvention Condition=" '$(ZlibCallingConvention)' == '' ">cdecl</ZlibCallingConvention> + </PropertyGroup> +</Project>
\ No newline at end of file diff --git a/vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.targets b/vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.targets new file mode 100644 index 0000000000..f00d97dc36 --- /dev/null +++ b/vsprojects/coapp/zlib/managed_targets/grpc.dependencies.zlib.redist.targets @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Choose> + <!-- Under older versions of Monodevelop, Choose is not supported and is just ignored, which gives us the desired effect. --> + <When Condition=" '$(OS)' != 'Unix' "> + <ItemGroup Condition=" '$(CopyNativeDependencies)' == 'true' "> + <Content Include="$(MSBuildThisFileDirectory)..\..\build\native\bin\$(NativeDependenciesToolset)\$(NativeDependenciesPlatform)\$(NativeDependenciesConfiguration)\dynamic\$(ZlibCallingConvention)\zlib.dll"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + </ItemGroup> + </When> + <Otherwise /> + </Choose> +</Project>
\ No newline at end of file diff --git a/vsprojects/coapp/zlib/version.inc b/vsprojects/coapp/zlib/version.inc new file mode 100644 index 0000000000..1f893a4951 --- /dev/null +++ b/vsprojects/coapp/zlib/version.inc @@ -0,0 +1 @@ +#define { package-version : 1.2.8.9; } diff --git a/vsprojects/coapp/zlib/zlib.sln b/vsprojects/coapp/zlib/zlib.sln new file mode 100644 index 0000000000..7c38e6e121 --- /dev/null +++ b/vsprojects/coapp/zlib/zlib.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib.vcxproj", "{63BED288-E8C3-4345-B84D-2E64598DCF3A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Debug|Win32.ActiveCfg = Debug|Win32 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Debug|Win32.Build.0 = Debug|Win32 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Release|Win32.ActiveCfg = Release|Win32 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Release|Win32.Build.0 = Release|Win32 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Debug|x64.ActiveCfg = Debug|x64 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Debug|x64.Build.0 = Debug|x64 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Release|x64.ActiveCfg = Release|x64 + {63BED288-E8C3-4345-B84D-2E64598DCF3A}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vsprojects/coapp/zlib/zlib.vcxproj b/vsprojects/coapp/zlib/zlib.vcxproj new file mode 100644 index 0000000000..56df39a248 --- /dev/null +++ b/vsprojects/coapp/zlib/zlib.vcxproj @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="PreBuildCmds;PreBuildTargets;Build;PostBuildCmds;PostBuildTargets" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="CoApp" > + <CoAppEtcDirectory>$(registry:HKEY_LOCAL_MACHINE\Software\Outercurve\CoApp.Powershell\etc)</CoAppEtcDirectory> + + <!-- Set to true to make visual studio use PTK when building.--> + <UsePTKFromVisualStudio>false</UsePTKFromVisualStudio> + </PropertyGroup> + + <PropertyGroup Label="Configuration" > + <!-- This lets Visual Studio see this as a VC12 project by default --> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v120</PlatformToolset> + </PropertyGroup> + + <Import Condition="Exists('$(CoAppEtcDirectory)\common-variables.vcxproj')" Project="$(CoAppEtcDirectory)\common-variables.vcxproj" /> + + <PropertyGroup Label="CustomSettings" /> + + <PropertyGroup Label="Globals"> + <ProjectGuid>{63BED288-E8C3-4345-B84D-2E64598DCF3A}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + + <OutNameSuffix Condition="$(IS_CDECL) AND $(IS_DYNAMIC)">1</OutNameSuffix> + + <!-- set to Application or DynamicLibrary (DynamicLibrary can get altered to StaticLibrary by PTK --> + <ConfigurationType>DynamicLibrary</ConfigurationType> + + <!-- Common Compiler Defines (semicolon delimited) --> + <Defines>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;</Defines> + <Defines Condition="$(IS_STDCALL)">$(Defines);ZLIB_WINAPI;</Defines> + <Defines Condition="$(IS_DYNAMIC)">$(Defines);ZLIB_DLL;</Defines> + <Defines Condition="'$(AppContainer)' == 'App'">$(Defines);IOWIN32_USING_WINRT_API=1;</Defines> + <Defines Condition="'$(AppContainer)' != 'App'">$(Defines);IOWIN32_USING_WINRT_API=0;</Defines> + <Defines Condition="'$(UseASM)' == 'ASM'">$(Defines);ASMV;ASMINF;</Defines> + <Defines Condition="$(IS_X64)">$(Defines);WIN64;</Defines> + + <!-- Additional Include folders (semicolon delimited) --> + <IncludeDirectories>..\..\..\third_party\zlib;</IncludeDirectories> + + <!-- Additional Library folders (semicolon delimited) --> + <LibraryDirectories></LibraryDirectories> + + <!-- Libraries to Link with --> + <Libraries></Libraries> + + <!-- Batch script to run before Build--> + <PreBuild></PreBuild> + + <!-- Batch script to run after Build--> + <PostBuild></PostBuild> + + <!-- Batch script to run before Link step--> + <PreLink></PreLink> + + <!-- Batch script to run after Link--> + <PostLink></PostLink> + + <!-- Batch script to run before Lib step--> + <PreLib></PreLib> + + <!-- Batch script to run after Lib--> + <PostLib></PostLib> + + <!-- Targets to run before Build (semcolon delimited)--> + <PreBuildTargets></PreBuildTargets> + + <!-- Targets to run before Build (semcolon delimited)--> + <PostBuildTargets></PostBuildTargets> + + <!-- for Dynamic libs, you can specify the Module .DEF file path --> + <ModuleDefinitionFile></ModuleDefinitionFile> + </PropertyGroup> + + <Import Condition="Exists('$(CoAppEtcDirectory)\common-header.vcxproj')" Project="$(CoAppEtcDirectory)\common-header.vcxproj" /> + <Import Condition="'$(UseASM)' == 'ASM'" Project="$(VCTargetsPath)\BuildCustomizations\masm.props" /> + + <PropertyGroup> + <OutDir>$(ProjectRootDir)Output/$(PlatformToolset)/$(Platform)/$(Configuration)/$(UsesConfigurationType)/$(CallingConvention)/$(CharacterSet)/$(AppContainer)/$(UseASM)/</OutDir> + <IntDir>$(ProjectRootDir)Intermediate/$(TargetName)/$(PlatformToolset)/$(Platform)/$(Configuration)/$(UsesConfigurationType)/$(CallingConvention)/$(CharacterSet)/$(AppContainer)/$(UseASM)/</IntDir> + </PropertyGroup> + + <ItemDefinitionGroup> + <ClCompile> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <BaseAddress>0x5A4C0000</BaseAddress> + </Link> + </ItemDefinitionGroup> + + <ItemGroup Condition="'$(UseASM)' == 'ASM'"> + <MASM Include="..\..\..\third_party\zlib\contrib\masmx64\gvmat64.asm" Condition="$(IS_X64)"> + <AssembledCodeListingFile>$(IntDir)gvmat64.lst</AssembledCodeListingFile> + <MASMBeforeTargets>Build</MASMBeforeTargets> + <ObjectFileName>$(IntDir)gvmat64.obj</ObjectFileName> + </MASM> + <MASM Include="..\..\..\third_party\zlib\contrib\masmx64\inffasx64.asm" Condition="$(IS_X64)"> + <AssembledCodeListingFile>$(IntDir)inffasx64.lst</AssembledCodeListingFile> + <MASMBeforeTargets>Build</MASMBeforeTargets> + <ObjectFileName>$(IntDir)inffasx64.obj</ObjectFileName> + </MASM> + <MASM Include="..\..\..\third_party\zlib\contrib\masmx86\inffas32.asm" Condition="$(IS_X86) AND $(IS_STDCALL)"> + <AssembledCodeListingFile>$(IntDir)inffas32.lst</AssembledCodeListingFile> + <MASMBeforeTargets>Build</MASMBeforeTargets> + <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers> + <AdditionalOptions>/coff %(AdditionalOptions)</AdditionalOptions> + <ObjectFileName>$(IntDir)inffas32.obj</ObjectFileName> + </MASM> + <MASM Include="..\..\..\third_party\zlib\contrib\masmx86\match686.asm" Condition="$(IS_X86) AND $(IS_STDCALL)"> + <AssembledCodeListingFile>$(IntDir)match686.lst</AssembledCodeListingFile> + <MASMBeforeTargets>Build</MASMBeforeTargets> + <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers> + <AdditionalOptions>/coff %(AdditionalOptions)</AdditionalOptions> + <ObjectFileName>$(IntDir)match686.obj</ObjectFileName> + </MASM> + </ItemGroup> + + <ItemGroup Label="C Source Files"> + <!-- Include the source files to compile here --> + <!-- <ClCompile Include="..\src\foo.c" /> --> + <ClCompile Include="..\..\..\third_party\zlib\adler32.c" /> + <ClCompile Include="..\..\..\third_party\zlib\compress.c" /> + <ClCompile Include="..\..\..\third_party\zlib\crc32.c" /> + <ClCompile Include="..\..\..\third_party\zlib\deflate.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzclose.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzlib.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzread.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzwrite.c" /> + <ClCompile Include="..\..\..\third_party\zlib\infback.c" /> + <ClCompile Include="..\..\..\third_party\zlib\contrib\masmx64\inffas8664.c" Condition="$(IS_X64)" /> + <ClCompile Include="..\..\..\third_party\zlib\inffast.c" /> + <ClCompile Include="..\..\..\third_party\zlib\inflate.c" /> + <ClCompile Include="..\..\..\third_party\zlib\inftrees.c" /> + <ClCompile Include="..\..\..\third_party\zlib\trees.c" /> + <ClCompile Include="..\..\..\third_party\zlib\uncompr.c" /> + <ClCompile Include="..\..\..\third_party\zlib\zutil.c" /> + </ItemGroup> + + <ItemGroup Label="Resource Files"> + <!-- Include the source files to compile here --> + <!-- <ResourceCompile Include="..\src\foo.rc" /> --> + <ResourceCompile Include="..\..\..\third_party\zlib\win32\zlib1.rc" /> + </ItemGroup> + + <Import Condition="'$(UseASM)' == 'ASM'" Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> + <Import Condition="Exists('$(CoAppEtcDirectory)\common-footer.vcxproj')" Project="$(CoAppEtcDirectory)\common-footer.vcxproj" /> +</Project> |