Merge branch 'vjpai-timers' into timers

pull/1267/head
Vijay Pai 10 years ago
commit caec4bfa56
  1. 1291
      BUILD
  2. 328
      Makefile
  3. 67
      build.json
  4. 2
      examples/pubsub/publisher.h
  5. 2
      examples/pubsub/subscriber.h
  6. 153
      src/compiler/cpp_generator.cc
  7. 19
      src/compiler/cpp_generator.h
  8. 36
      src/compiler/cpp_plugin.cc
  9. 4
      src/core/iomgr/pollset_multipoller_with_poll_posix.c
  10. 4
      src/core/iomgr/pollset_posix.c
  11. 6
      src/core/iomgr/tcp_server.h
  12. 60
      src/core/iomgr/tcp_server_posix.c
  13. 36
      src/core/iomgr/tcp_server_windows.c
  14. 19
      src/core/security/server_secure_chttp2.c
  15. 8
      src/core/surface/completion_queue.c
  16. 4
      src/core/surface/completion_queue.h
  17. 55
      src/core/surface/server.c
  18. 7
      src/core/surface/server.h
  19. 7
      src/core/surface/server_chttp2.c
  20. 35
      src/cpp/client/secure_credentials.cc
  21. 61
      src/cpp/client/secure_credentials.h
  22. 31
      src/cpp/server/secure_server_credentials.cc
  23. 60
      src/cpp/server/secure_server_credentials.h
  24. 40
      src/php/bin/generate_proto_php.sh
  25. 11
      src/php/ext/grpc/call.c
  26. 1
      src/php/ext/grpc/channel.c
  27. 10
      src/python/interop/interop/_interop_test_case.py
  28. 24
      src/python/interop/interop/client.py
  29. 60
      src/python/interop/interop/methods.py
  30. 2
      src/python/interop/setup.py
  31. 79
      templates/BUILD.template
  32. 17
      templates/Makefile.template
  33. 6
      test/core/end2end/tests/cancel_after_invoke.c
  34. 9
      test/core/end2end/tests/cancel_test_helpers.h
  35. 10
      test/core/iomgr/tcp_server_posix_test.c
  36. 4
      test/cpp/end2end/async_end2end_test.cc
  37. 4
      test/cpp/end2end/end2end_test.cc
  38. 2
      test/cpp/end2end/generic_end2end_test.cc
  39. 394
      test/cpp/interop/client.cc
  40. 119
      test/cpp/interop/client_helper.cc
  41. 53
      test/cpp/interop/client_helper.h
  42. 311
      test/cpp/interop/interop_client.cc
  43. 79
      test/cpp/interop/interop_client.h
  44. 19
      test/cpp/interop/server.cc
  45. 69
      test/cpp/interop/server_helper.cc
  46. 49
      test/cpp/interop/server_helper.h
  47. 34
      test/cpp/qps/client.h
  48. 38
      test/cpp/qps/client_async.cc
  49. 15
      test/cpp/qps/client_sync.cc
  50. 2
      test/cpp/qps/driver.h
  51. 6
      test/cpp/qps/histogram.h
  52. 37
      test/cpp/qps/qps_driver.cc
  53. 94
      test/cpp/qps/report.cc
  54. 57
      test/cpp/qps/report.h
  55. 2
      test/cpp/qps/server.h
  56. 22
      test/cpp/qps/server_async.cc
  57. 2
      test/cpp/qps/server_sync.cc
  58. 149
      test/cpp/qps/smoke_test.cc
  59. 28
      test/cpp/qps/smoke_test.sh
  60. 2
      test/cpp/qps/worker.cc
  61. 2
      test/cpp/util/cli_call_test.cc
  62. 8
      tools/distpackages/build_deb_packages.sh
  63. 29
      tools/gce_setup/grpc_docker.sh
  64. 2
      tools/gce_setup/interop_test_runner.sh
  65. 8
      vsprojects/vs2010/grpc++.vcxproj
  66. 24
      vsprojects/vs2010/grpc++.vcxproj.filters
  67. 8
      vsprojects/vs2013/grpc++.vcxproj
  68. 24
      vsprojects/vs2013/grpc++.vcxproj.filters

1291
BUILD

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -29,6 +29,12 @@
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",
"include/grpc++/impl/sync_no_cxx11.h",
"include/grpc++/impl/thd.h",
"include/grpc++/impl/thd_cxx11.h",
"include/grpc++/impl/thd_no_cxx11.h",
"include/grpc++/server.h",
"include/grpc++/server_builder.h",
"include/grpc++/server_context.h",
@ -466,6 +472,10 @@
"name": "grpc++",
"build": "all",
"language": "c++",
"headers": [
"src/cpp/client/secure_credentials.h",
"src/cpp/server/secure_server_credentials.h"
],
"src": [
"src/cpp/client/secure_credentials.cc",
"src/cpp/server/secure_server_credentials.cc"
@ -533,6 +543,38 @@
"deps": [],
"secure": "no"
},
{
"name": "interop_client_lib",
"build": "private",
"language": "c++",
"src": [
"test/cpp/interop/empty.proto",
"test/cpp/interop/messages.proto",
"test/cpp/interop/test.proto",
"test/cpp/interop/client_helper.cc",
"test/cpp/interop/interop_client.cc"
],
"deps": [
"grpc++_test_util",
"grpc++",
"grpc",
"gpr"
]
},
{
"name": "interop_server_lib",
"build": "private",
"language": "c++",
"src": [
"test/cpp/interop/server_helper.cc"
],
"deps": [
"grpc_test_util",
"grpc++",
"grpc",
"gpr"
]
},
{
"name": "pubsub_client_lib",
"build": "private",
@ -556,11 +598,13 @@
"language": "c++",
"headers": [
"test/cpp/qps/driver.h",
"test/cpp/qps/report.h",
"test/cpp/qps/timer.h"
],
"src": [
"test/cpp/qps/qpstest.proto",
"test/cpp/qps/driver.cc",
"test/cpp/qps/report.cc",
"test/cpp/qps/timer.cc"
]
},
@ -1878,12 +1922,10 @@
"run": false,
"language": "c++",
"src": [
"test/cpp/interop/empty.proto",
"test/cpp/interop/messages.proto",
"test/cpp/interop/test.proto",
"test/cpp/interop/client.cc"
],
"deps": [
"interop_client_lib",
"grpc++_test_util",
"grpc_test_util",
"grpc++",
@ -1904,6 +1946,7 @@
"test/cpp/interop/server.cc"
],
"deps": [
"interop_server_lib",
"grpc++_test_util",
"grpc_test_util",
"grpc++",
@ -1995,6 +2038,24 @@
"gpr"
]
},
{
"name": "qps_smoke_test",
"build": "test",
"run": false,
"language": "c++",
"src": [
"test/cpp/qps/smoke_test.cc"
],
"deps": [
"qps",
"grpc++_test_util",
"grpc_test_util",
"grpc++",
"grpc",
"gpr_test_util",
"gpr"
]
},
{
"name": "qps_worker",
"build": "test",

@ -37,7 +37,7 @@
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
#include "examples/pubsub/pubsub.pb.h"
#include "examples/pubsub/pubsub.grpc.pb.h"
namespace grpc {
namespace examples {

@ -37,7 +37,7 @@
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
#include "examples/pubsub/pubsub.pb.h"
#include "examples/pubsub/pubsub.grpc.pb.h"
namespace grpc {
namespace examples {

@ -109,8 +109,47 @@ bool HasBidiStreaming(const grpc::protobuf::FileDescriptor *file) {
}
return false;
}
grpc::string FilenameIdentifier(const grpc::string& filename) {
grpc::string result;
for (unsigned i = 0; i < filename.size(); i++) {
char c = filename[i];
if (isalnum(c)) {
result.push_back(c);
} else {
static char hex[] = "0123456789abcdef";
result.push_back('_');
result.push_back(hex[(c >> 4) & 0xf]);
result.push_back(hex[c & 0xf]);
}
}
return result;
}
} // namespace
grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
vars["filename"] = file->name();
vars["filename_identifier"] = FilenameIdentifier(file->name());
vars["filename_base"] = grpc_generator::StripProto(file->name());
printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
printer.Print(vars, "// If you make any local change, they will be lost.\n");
printer.Print(vars, "// source: $filename$\n");
printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
printer.Print(vars, "\n");
printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
printer.Print(vars, "\n");
return output;
}
grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string temp =
@ -156,17 +195,21 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
"class ServerAsyncReaderWriter;\n");
}
temp.append("} // namespace grpc\n");
return temp;
}
grpc::string GetSourceIncludes(const Parameters &param) {
return "#include <grpc++/async_unary_call.h>\n"
"#include <grpc++/channel_interface.h>\n"
"#include <grpc++/impl/client_unary_call.h>\n"
"#include <grpc++/impl/rpc_method.h>\n"
"#include <grpc++/impl/rpc_service_method.h>\n"
"#include <grpc++/impl/service_type.h>\n"
"#include <grpc++/stream.h>\n";
temp.append("\n");
std::vector<grpc::string> parts =
grpc_generator::tokenize(file->package(), ".");
for (auto part = parts.begin(); part != parts.end(); part++) {
temp.append("namespace ");
temp.append(*part);
temp.append(" {\n");
}
temp.append("\n");
return temp;
}
void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
@ -378,6 +421,78 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
return output;
}
grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
vars["filename"] = file->name();
vars["filename_identifier"] = FilenameIdentifier(file->name());
std::vector<grpc::string> parts =
grpc_generator::tokenize(file->package(), ".");
for (auto part = parts.rbegin(); part != parts.rend(); part++) {
vars["part"] = *part;
printer.Print(vars, "} // namespace $part$\n");
}
printer.Print(vars, "\n\n");
printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
return output;
}
grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
vars["filename"] = file->name();
vars["filename_base"] = grpc_generator::StripProto(file->name());
printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
printer.Print(vars, "// If you make any local change, they will be lost.\n");
printer.Print(vars, "// source: $filename$\n\n");
printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
printer.Print(vars, "\n");
return output;
}
grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &param) {
grpc::string output;
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n");
printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
printer.Print(vars, "#include <grpc++/stream.h>\n");
std::vector<grpc::string> parts =
grpc_generator::tokenize(file->package(), ".");
for (auto part = parts.begin(); part != parts.end(); part++) {
vars["part"] = *part;
printer.Print(vars, "namespace $part$ {\n");
}
printer.Print(vars, "\n");
return output;
}
void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
const grpc::protobuf::MethodDescriptor *method,
std::map<grpc::string, grpc::string> *vars) {
@ -741,4 +856,22 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
return output;
}
grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string temp;
std::vector<grpc::string> parts =
grpc_generator::tokenize(file->package(), ".");
for (auto part = parts.begin(); part != parts.end(); part++) {
temp.append("} // namespace ");
temp.append(*part);
temp.append("\n");
}
temp.append("\n");
return temp;
}
} // namespace grpc_cpp_generator

@ -44,12 +44,25 @@ struct Parameters {
grpc::string services_namespace;
};
// Return the prologue of the generated header file.
grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the includes needed for generated header file.
grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the includes needed for generated source file.
grpc::string GetSourceIncludes(const Parameters &params);
grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the epilogue of the generated header file.
grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the prologue of the generated source file.
grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the services for generated header file.
grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
@ -59,6 +72,10 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the epilogue of the generated source file.
grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
} // namespace grpc_cpp_generator
#endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H

@ -58,11 +58,6 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
return false;
}
if (file->service_count() == 0) {
// No services. Do nothing.
return true;
}
grpc_cpp_generator::Parameters generator_parameters;
if (!parameter.empty()) {
@ -84,16 +79,27 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc::string file_name = grpc_generator::StripProto(file->name());
// Generate .pb.h
Insert(context, file_name + ".pb.h", "includes",
grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters));
Insert(context, file_name + ".pb.h", "namespace_scope",
grpc_cpp_generator::GetHeaderServices(file, generator_parameters));
// Generate .pb.cc
Insert(context, file_name + ".pb.cc", "includes",
grpc_cpp_generator::GetSourceIncludes(generator_parameters));
Insert(context, file_name + ".pb.cc", "namespace_scope",
grpc_cpp_generator::GetSourceServices(file, generator_parameters));
grpc::string header_code =
grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) +
grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) +
grpc_cpp_generator::GetHeaderServices(file, generator_parameters) +
grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
context->Open(file_name + ".grpc.pb.h"));
grpc::protobuf::io::CodedOutputStream header_coded_out(
header_output.get());
header_coded_out.WriteRaw(header_code.data(), header_code.size());
grpc::string source_code =
grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) +
grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) +
grpc_cpp_generator::GetSourceServices(file, generator_parameters) +
grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
context->Open(file_name + ".grpc.pb.cc"));
grpc::protobuf::io::CodedOutputStream source_coded_out(
source_output.get());
source_coded_out.WriteRaw(source_code.data(), source_code.size());
return true;
}

@ -172,6 +172,9 @@ static int multipoll_with_poll_pollset_maybe_work(
}
r = poll(h->pfds, h->pfd_count, timeout);
end_polling(pollset);
if (r < 0) {
if (errno != EINTR) {
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
@ -192,7 +195,6 @@ static int multipoll_with_poll_pollset_maybe_work(
}
}
grpc_pollset_kick_post_poll(&pollset->kick_state);
end_polling(pollset);
gpr_mu_lock(&pollset->mu);
pollset->counter = 0;

@ -396,6 +396,9 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
pfd[1].events = grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher);
r = poll(pfd, GPR_ARRAY_SIZE(pfd), timeout);
grpc_fd_end_poll(&fd_watcher);
if (r < 0) {
if (errno != EINTR) {
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
@ -415,7 +418,6 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
}
grpc_pollset_kick_post_poll(&pollset->kick_state);
grpc_fd_end_poll(&fd_watcher);
gpr_mu_lock(&pollset->mu);
pollset->counter = 0;

@ -71,6 +71,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
up when grpc_tcp_server_destroy is called. */
int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index);
void grpc_tcp_server_destroy(grpc_tcp_server *server);
void grpc_tcp_server_destroy(grpc_tcp_server *server,
void (*shutdown_done)(void *shutdown_done_arg),
void *shutdown_done_arg);
#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */

@ -102,12 +102,18 @@ struct grpc_tcp_server {
gpr_cv cv;
/* active port count: how many ports are actually still listening */
int active_ports;
size_t active_ports;
/* destroyed port count: how many ports are completely destroyed */
size_t destroyed_ports;
/* all listening ports */
server_port *ports;
size_t nports;
size_t port_capacity;
/* shutdown callback */
void (*shutdown_complete)(void *);
void *shutdown_complete_arg;
};
grpc_tcp_server *grpc_tcp_server_create(void) {
@ -115,6 +121,7 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
gpr_mu_init(&s->mu);
gpr_cv_init(&s->cv);
s->active_ports = 0;
s->destroyed_ports = 0;
s->cb = NULL;
s->cb_arg = NULL;
s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
@ -123,29 +130,64 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
return s;
}
void grpc_tcp_server_destroy(grpc_tcp_server *s) {
static void finish_shutdown(grpc_tcp_server *s) {
s->shutdown_complete(s->shutdown_complete_arg);
gpr_mu_destroy(&s->mu);
gpr_cv_destroy(&s->cv);
gpr_free(s->ports);
gpr_free(s);
}
static void destroyed_port(void *server, int success) {
grpc_tcp_server *s = server;
gpr_mu_lock(&s->mu);
s->destroyed_ports++;
if (s->destroyed_ports == s->nports) {
gpr_mu_unlock(&s->mu);
finish_shutdown(s);
} else {
gpr_mu_unlock(&s->mu);
}
}
static void dont_care_about_shutdown_completion(void *ignored) {}
void grpc_tcp_server_destroy(
grpc_tcp_server *s, void (*shutdown_complete)(void *shutdown_complete_arg),
void *shutdown_complete_arg) {
size_t i;
gpr_mu_lock(&s->mu);
s->shutdown_complete = shutdown_complete
? shutdown_complete
: dont_care_about_shutdown_completion;
s->shutdown_complete_arg = shutdown_complete_arg;
/* shutdown all fd's */
for (i = 0; i < s->nports; i++) {
grpc_fd_shutdown(s->ports[i].emfd);
}
/* wait while that happens */
/* TODO(ctiller): make this asynchronous also */
while (s->active_ports) {
gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
}
gpr_mu_unlock(&s->mu);
/* delete ALL the things */
for (i = 0; i < s->nports; i++) {
server_port *sp = &s->ports[i];
if (sp->addr.sockaddr.sa_family == AF_UNIX) {
unlink_if_unix_domain_socket(&sp->addr.un);
if (s->nports) {
for (i = 0; i < s->nports; i++) {
server_port *sp = &s->ports[i];
if (sp->addr.sockaddr.sa_family == AF_UNIX) {
unlink_if_unix_domain_socket(&sp->addr.un);
}
grpc_fd_orphan(sp->emfd, destroyed_port, s);
}
grpc_fd_orphan(sp->emfd, NULL, NULL);
} else {
finish_shutdown(s);
}
gpr_free(s->ports);
gpr_free(s);
}
/* get max listen queue size on linux */

@ -92,7 +92,9 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
return s;
}
void grpc_tcp_server_destroy(grpc_tcp_server *s) {
void grpc_tcp_server_destroy(grpc_tcp_server *s,
void (*shutdown_done)(void *shutdown_done_arg),
void *shutdown_done_arg) {
size_t i;
gpr_mu_lock(&s->mu);
/* shutdown all fd's */
@ -112,11 +114,15 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s) {
}
gpr_free(s->ports);
gpr_free(s);
if (shutdown_done) {
shutdown_done(shutdown_done_arg);
}
}
/* Prepare a recently-created socket for listening. */
static int prepare_socket(SOCKET sock,
const struct sockaddr *addr, int addr_len) {
static int prepare_socket(SOCKET sock, const struct sockaddr *addr,
int addr_len) {
struct sockaddr_storage sockname_temp;
socklen_t sockname_len;
@ -147,15 +153,15 @@ static int prepare_socket(SOCKET sock,
}
sockname_len = sizeof(sockname_temp);
if (getsockname(sock, (struct sockaddr *) &sockname_temp, &sockname_len)
== SOCKET_ERROR) {
if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) ==
SOCKET_ERROR) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "getsockname: %s", utf8_message);
gpr_free(utf8_message);
goto error;
}
return grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
error:
if (sock != INVALID_SOCKET) closesocket(sock);
@ -221,8 +227,7 @@ static void on_accept(void *arg, int success) {
DWORD transfered_bytes = 0;
DWORD flags;
BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
&transfered_bytes, FALSE,
&flags);
&transfered_bytes, FALSE, &flags);
if (!wsa_success) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
@ -257,9 +262,9 @@ static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
if (sock == INVALID_SOCKET) return -1;
status = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
&guid, sizeof(guid), &AcceptEx, sizeof(AcceptEx),
&ioctl_num_bytes, NULL, NULL);
status =
WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&AcceptEx, sizeof(AcceptEx), &ioctl_num_bytes, NULL, NULL);
if (status != 0) {
char *utf8_message = gpr_format_message(WSAGetLastError());
@ -307,9 +312,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
for (i = 0; i < s->nports; i++) {
sockname_len = sizeof(sockname_temp);
if (0 == getsockname(s->ports[i].socket->socket,
(struct sockaddr *) &sockname_temp,
&sockname_len)) {
port = grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
(struct sockaddr *)&sockname_temp, &sockname_len)) {
port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
if (port > 0) {
allocated_addr = malloc(addr_len);
memcpy(allocated_addr, addr, addr_len);
@ -330,7 +334,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
if (grpc_sockaddr_is_wildcard(addr, &port)) {
grpc_sockaddr_make_wildcard6(port, &wildcard);
addr = (struct sockaddr *) &wildcard;
addr = (struct sockaddr *)&wildcard;
addr_len = sizeof(wildcard);
}
@ -369,4 +373,4 @@ void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset **pollset,
gpr_mu_unlock(&s->mu);
}
#endif /* GPR_WINSOCK_SOCKET */
#endif /* GPR_WINSOCK_SOCKET */

@ -85,10 +85,10 @@ static void on_secure_transport_setup_done(void *statep,
if (status == GRPC_SECURITY_OK) {
gpr_mu_lock(&state->mu);
if (!state->is_shutdown) {
grpc_create_chttp2_transport(
setup_transport, state->server,
grpc_server_get_channel_args(state->server),
secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
grpc_create_chttp2_transport(setup_transport, state->server,
grpc_server_get_channel_args(state->server),
secure_endpoint, NULL, 0,
grpc_mdctx_create(), 0);
} else {
/* We need to consume this here, because the server may already have gone
* away. */
@ -104,7 +104,8 @@ static void on_secure_transport_setup_done(void *statep,
static void on_accept(void *statep, grpc_endpoint *tcp) {
grpc_server_secure_state *state = statep;
state_ref(state);
grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state);
grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done,
state);
}
/* Server callback: start listening on our ports */
@ -120,12 +121,14 @@ static void destroy(grpc_server *server, void *statep) {
grpc_server_secure_state *state = statep;
gpr_mu_lock(&state->mu);
state->is_shutdown = 1;
grpc_tcp_server_destroy(state->tcp);
grpc_tcp_server_destroy(state->tcp, grpc_server_listener_destroy_done,
server);
gpr_mu_unlock(&state->mu);
state_unref(state);
}
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) {
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
grpc_server_credentials *creds) {
grpc_resolved_addresses *resolved = NULL;
grpc_tcp_server *tcp = NULL;
grpc_server_secure_state *state = NULL;
@ -213,7 +216,7 @@ error:
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
grpc_tcp_server_destroy(tcp);
grpc_tcp_server_destroy(tcp, NULL, NULL);
}
if (state) {
gpr_free(state);

@ -432,3 +432,11 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc) {
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
return &cc->pollset;
}
void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc) {
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
grpc_pollset_kick(&cc->pollset);
grpc_pollset_work(&cc->pollset,
gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}

@ -114,4 +114,6 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc);
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc);
#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */

@ -137,6 +137,7 @@ struct grpc_server {
size_t cq_count;
gpr_mu mu;
gpr_cv cv;
registered_method *registered_methods;
requested_call_array requested_calls;
@ -149,6 +150,7 @@ struct grpc_server {
channel_data root_channel_data;
listener *listeners;
int listeners_destroyed;
gpr_refcount internal_refcount;
};
@ -263,6 +265,7 @@ static void server_unref(grpc_server *server) {
if (gpr_unref(&server->internal_refcount)) {
grpc_channel_args_destroy(server->channel_args);
gpr_mu_destroy(&server->mu);
gpr_cv_destroy(&server->cv);
gpr_free(server->channel_filters);
requested_call_array_destroy(&server->requested_calls);
while ((rm = server->registered_methods) != NULL) {
@ -589,9 +592,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
static const grpc_channel_filter server_surface_filter = {
call_op, channel_op, sizeof(call_data),
init_call_elem, destroy_call_elem, sizeof(channel_data),
init_channel_elem, destroy_channel_elem, "server",
call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem, "server",
};
static void addcq(grpc_server *server, grpc_completion_queue *cq) {
@ -620,6 +622,7 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
if (cq) addcq(server, cq);
gpr_mu_init(&server->mu);
gpr_cv_init(&server->cv);
server->unregistered_cq = cq;
/* decremented by grpc_server_destroy */
@ -733,7 +736,8 @@ grpc_transport_setup_result grpc_server_setup_transport(
channel = grpc_channel_create_from_filters(filters, num_filters,
s->channel_args, mdctx, 0);
chand = (channel_data *)grpc_channel_stack_element(
grpc_channel_get_channel_stack(channel), 0)->channel_data;
grpc_channel_get_channel_stack(channel), 0)
->channel_data;
chand->server = s;
server_ref(s);
chand->channel = channel;
@ -754,7 +758,7 @@ grpc_transport_setup_result grpc_server_setup_transport(
method = grpc_mdstr_from_string(mdctx, rm->method);
hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
.server_registered_method != NULL;
.server_registered_method != NULL;
probes++)
;
if (probes > max_probes) max_probes = probes;
@ -781,6 +785,15 @@ grpc_transport_setup_result grpc_server_setup_transport(
return result;
}
static int num_listeners(grpc_server *server) {
listener *l;
int n = 0;
for (l = server->listeners; l; l = l->next) {
n++;
}
return n;
}
static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
void *shutdown_tag) {
listener *l;
@ -878,11 +891,6 @@ static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
for (l = server->listeners; l; l = l->next) {
l->destroy(server, l->arg);
}
while (server->listeners) {
l = server->listeners;
server->listeners = l->next;
gpr_free(l);
}
}
void grpc_server_shutdown(grpc_server *server) {
@ -893,8 +901,18 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *tag) {
shutdown_internal(server, 1, tag);
}
void grpc_server_listener_destroy_done(void *s) {
grpc_server *server = s;
gpr_mu_lock(&server->mu);
server->listeners_destroyed++;
gpr_cv_signal(&server->cv);
gpr_mu_unlock(&server->mu);
}
void grpc_server_destroy(grpc_server *server) {
channel_data *c;
listener *l;
size_t i;
gpr_mu_lock(&server->mu);
if (!server->shutdown) {
gpr_mu_unlock(&server->mu);
@ -902,6 +920,23 @@ void grpc_server_destroy(grpc_server *server) {
gpr_mu_lock(&server->mu);
}
while (server->listeners_destroyed != num_listeners(server)) {
for (i = 0; i < server->cq_count; i++) {
gpr_mu_unlock(&server->mu);
grpc_cq_hack_spin_pollset(server->cqs[i]);
gpr_mu_lock(&server->mu);
}
gpr_cv_wait(&server->cv, &server->mu,
gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
}
while (server->listeners) {
l = server->listeners;
server->listeners = l->next;
gpr_free(l);
}
for (c = server->root_channel_data.next; c != &server->root_channel_data;
c = c->next) {
shutdown_channel(c);

@ -48,9 +48,12 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
and when it shuts down, it will call destroy */
void grpc_server_add_listener(grpc_server *server, void *listener,
void (*start)(grpc_server *server, void *arg,
grpc_pollset **pollsets, size_t npollsets),
grpc_pollset **pollsets,
size_t npollsets),
void (*destroy)(grpc_server *server, void *arg));
void grpc_server_listener_destroy_done(void *server);
/* Setup a transport - creates a channel stack, binds the transport to the
server */
grpc_transport_setup_result grpc_server_setup_transport(
@ -60,4 +63,4 @@ grpc_transport_setup_result grpc_server_setup_transport(
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */

@ -66,7 +66,8 @@ static void new_transport(void *server, grpc_endpoint *tcp) {
}
/* Server callback: start listening on our ports */
static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) {
static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets,
size_t pollset_count) {
grpc_tcp_server *tcp = tcpp;
grpc_tcp_server_start(tcp, pollsets, pollset_count, new_transport, server);
}
@ -75,7 +76,7 @@ static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size
callbacks) */
static void destroy(grpc_server *server, void *tcpp) {
grpc_tcp_server *tcp = tcpp;
grpc_tcp_server_destroy(tcp);
grpc_tcp_server_destroy(tcp, grpc_server_listener_destroy_done, server);
}
int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
@ -131,7 +132,7 @@ error:
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
grpc_tcp_server_destroy(tcp);
grpc_tcp_server_destroy(tcp, NULL, NULL);
}
return 0;
}

@ -31,38 +31,23 @@
*
*/
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc++/channel_arguments.h>
#include <grpc++/config.h>
#include <grpc++/credentials.h>
#include "src/cpp/client/channel.h"
#include "src/cpp/client/secure_credentials.h"
namespace grpc {
class SecureCredentials GRPC_FINAL : public Credentials {
public:
explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
grpc_credentials* GetRawCreds() { return c_creds_; }
std::shared_ptr<grpc::ChannelInterface> CreateChannel(
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return std::shared_ptr<ChannelInterface>(new Channel(
args.GetSslTargetNameOverride().empty()
? target
: args.GetSslTargetNameOverride(),
grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
}
SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
private:
grpc_credentials* const c_creds_;
};
std::shared_ptr<grpc::ChannelInterface> SecureCredentials::CreateChannel(
const string& target, const grpc::ChannelArguments& args) {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return std::shared_ptr<ChannelInterface>(new Channel(
args.GetSslTargetNameOverride().empty() ? target
: args.GetSslTargetNameOverride(),
grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
}
namespace {
std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {

@ -0,0 +1,61 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
#define GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
#include <grpc/grpc_security.h>
#include <grpc++/config.h>
#include <grpc++/credentials.h>
namespace grpc {
class SecureCredentials GRPC_FINAL : public Credentials {
public:
explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
grpc_credentials* GetRawCreds() { return c_creds_; }
std::shared_ptr<grpc::ChannelInterface> CreateChannel(
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE;
SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
private:
grpc_credentials* const c_creds_;
};
} // namespace grpc
#endif // GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H

@ -31,39 +31,22 @@
*
*/
#include <grpc/grpc_security.h>
#include <grpc++/server_credentials.h>
#include "src/cpp/server/secure_server_credentials.h"
namespace grpc {
namespace {
class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
public:
explicit SecureServerCredentials(grpc_server_credentials* creds)
: creds_(creds) {}
~SecureServerCredentials() GRPC_OVERRIDE {
grpc_server_credentials_release(creds_);
}
int AddPortToServer(const grpc::string& addr,
grpc_server* server) GRPC_OVERRIDE {
return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
}
private:
grpc_server_credentials* const creds_;
};
} // namespace
int SecureServerCredentials::AddPortToServer(
const grpc::string& addr, grpc_server* server) {
return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
}
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options) {
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
for (auto key_cert_pair = options.pem_key_cert_pairs.begin();
key_cert_pair != options.pem_key_cert_pairs.end();
key_cert_pair++) {
key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) {
grpc_ssl_pem_key_cert_pair p = {key_cert_pair->private_key.c_str(),
key_cert_pair->cert_chain.c_str()};
key_cert_pair->cert_chain.c_str()};
pem_key_cert_pairs.push_back(p);
}
grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(

@ -0,0 +1,60 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
#define GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
#include <grpc/grpc_security.h>
#include <grpc++/server_credentials.h>
namespace grpc {
class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
public:
explicit SecureServerCredentials(grpc_server_credentials* creds)
: creds_(creds) {}
~SecureServerCredentials() GRPC_OVERRIDE {
grpc_server_credentials_release(creds_);
}
int AddPortToServer(const grpc::string& addr,
grpc_server* server) GRPC_OVERRIDE;
private:
grpc_server_credentials* const creds_;
};
} // namespace grpc
#endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H

@ -0,0 +1,40 @@
#!/bin/sh
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set +e
cd $(dirname $0)
gen_code='../tests/generated_code'
interop='../tests/interop'
protoc-gen-php -i $gen_code -o $gen_code $gen_code/math.proto
protoc-gen-php -i $interop -o $interop $interop/test.proto

@ -443,8 +443,9 @@ PHP_METHOD(Call, startBatch) {
add_property_bool(result, "send_status", true);
break;
case GRPC_OP_RECV_INITIAL_METADATA:
add_property_zval(result, "metadata",
grpc_parse_metadata_array(&recv_metadata));
array = grpc_parse_metadata_array(&recv_metadata);
add_property_zval(result, "metadata", array);
Z_DELREF_P(array);
break;
case GRPC_OP_RECV_MESSAGE:
byte_buffer_to_string(message, &message_str, &message_len);
@ -458,11 +459,13 @@ PHP_METHOD(Call, startBatch) {
case GRPC_OP_RECV_STATUS_ON_CLIENT:
MAKE_STD_ZVAL(recv_status);
object_init(recv_status);
add_property_zval(recv_status, "metadata",
grpc_parse_metadata_array(&recv_trailing_metadata));
array = grpc_parse_metadata_array(&recv_trailing_metadata);
add_property_zval(recv_status, "metadata", array);
Z_DELREF_P(array);
add_property_long(recv_status, "code", status);
add_property_string(recv_status, "details", status_details, true);
add_property_zval(result, "status", recv_status);
Z_DELREF_P(recv_status);
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
add_property_bool(result, "cancelled", cancelled);

@ -62,6 +62,7 @@ void free_wrapped_grpc_channel(void *object TSRMLS_DC) {
if (channel->wrapped != NULL) {
grpc_channel_destroy(channel->wrapped);
}
efree(channel->target);
efree(channel);
}

@ -40,16 +40,16 @@ class InteropTestCase(object):
"""
def testEmptyUnary(self):
methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub)
methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None)
def testLargeUnary(self):
methods.TestCase.LARGE_UNARY.test_interoperability(self.stub)
methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None)
def testServerStreaming(self):
methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub)
methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None)
def testClientStreaming(self):
methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub)
methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None)
def testPingPong(self):
methods.TestCase.PING_PONG.test_interoperability(self.stub)
methods.TestCase.PING_PONG.test_interoperability(self.stub, None)

@ -30,6 +30,7 @@
"""The Python implementation of the GRPC interoperability test client."""
import argparse
from oauth2client import client as oauth2client_client
from grpc.early_adopter import implementations
@ -43,9 +44,6 @@ def _args():
parser = argparse.ArgumentParser()
parser.add_argument(
'--server_host', help='the host to which to connect', type=str)
parser.add_argument(
'--server_host_override',
help='the server host to which to claim to connect', type=str)
parser.add_argument(
'--server_port', help='the port to which to connect', type=int)
parser.add_argument(
@ -56,10 +54,25 @@ def _args():
parser.add_argument(
'--use_test_ca', help='replace platform root CAs with ca.pem',
action='store_true')
parser.add_argument(
'--server_host_override',
help='the server host to which to claim to connect', type=str)
parser.add_argument('--oauth_scope', help='scope for OAuth tokens', type=str)
parser.add_argument(
'--default_service_account',
help='email address of the default service account', type=str)
return parser.parse_args()
def _oauth_access_token(args):
credentials = client.GoogleCredentials.get_application_default()
scoped_credentials = credentials.create_scoped([args.oauth_scope])
return scoped_credentials.get_access_token().access_token
def _stub(args):
if args.oauth_scope:
metadata_transformer = lambda x: [('Authorization', 'Bearer %s' % _oauth_access_token(args))]
else:
metadata_transformer = lambda x: []
if args.use_tls:
if args.use_test_ca:
root_certificates = resources.test_root_certificates()
@ -68,7 +81,8 @@ def _stub(args):
stub = implementations.stub(
methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host,
args.server_port, secure=True, root_certificates=root_certificates,
args.server_port, metadata_transformer=metadata_transformer,
secure=True, root_certificates=root_certificates,
server_host_override=args.server_host_override)
else:
stub = implementations.stub(
@ -89,7 +103,7 @@ def _test_interoperability():
args = _args()
stub = _stub(args)
test_case = _test_case_from_arg(args.test_case)
test_case.test_interoperability(stub)
test_case.test_interoperability(stub, args)
if __name__ == '__main__':

@ -30,8 +30,12 @@
"""Implementations of interoperability test methods."""
import enum
import json
import os
import threading
from oauth2client import client as oauth2client_client
from grpc.framework.alpha import utilities
from interop import empty_pb2
@ -150,19 +154,12 @@ SERVER_METHODS = {
}
def _empty_unary(stub):
with stub:
response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
if not isinstance(response, empty_pb2.Empty):
raise TypeError(
'response is of type "%s", not empty_pb2.Empty!', type(response))
def _large_unary(stub):
def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope):
with stub:
request = messages_pb2.SimpleRequest(
response_type=messages_pb2.COMPRESSABLE, response_size=314159,
payload=messages_pb2.Payload(body=b'\x00' * 271828))
payload=messages_pb2.Payload(body=b'\x00' * 271828),
fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
response_future = stub.UnaryCall.async(request, _TIMEOUT)
response = response_future.result()
if response.payload.type is not messages_pb2.COMPRESSABLE:
@ -171,6 +168,19 @@ def _large_unary(stub):
if len(response.payload.body) != 314159:
raise ValueError(
'response body of incorrect size %d!' % len(response.payload.body))
return response
def _empty_unary(stub):
with stub:
response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
if not isinstance(response, empty_pb2.Empty):
raise TypeError(
'response is of type "%s", not empty_pb2.Empty!', type(response))
def _large_unary(stub):
_large_unary_common_behavior(stub, False, False)
def _client_streaming(stub):
@ -266,6 +276,28 @@ def _ping_pong(stub):
pipe.close()
def _compute_engine_creds(stub, args):
response = _large_unary_common_behavior(stub, True, True)
if args.default_service_account != response.username:
raise ValueError(
'expected username %s, got %s' % (args.default_service_account,
response.username))
def _service_account_creds(stub, args):
json_key_filename = os.environ[
oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
response = _large_unary_common_behavior(stub, True, True)
if wanted_email != response.username:
raise ValueError(
'expected username %s, got %s' % (wanted_email, response.username))
if response.oauth_scope in args.oauth_scope:
raise ValueError(
'expected to find oauth scope "%s" in received "%s"' %
(response.oauth_scope, args.oauth_scope))
@enum.unique
class TestCase(enum.Enum):
EMPTY_UNARY = 'empty_unary'
@ -273,8 +305,10 @@ class TestCase(enum.Enum):
SERVER_STREAMING = 'server_streaming'
CLIENT_STREAMING = 'client_streaming'
PING_PONG = 'ping_pong'
COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
SERVICE_ACCOUNT_CREDS = 'service_account_creds'
def test_interoperability(self, stub):
def test_interoperability(self, stub, args):
if self is TestCase.EMPTY_UNARY:
_empty_unary(stub)
elif self is TestCase.LARGE_UNARY:
@ -285,5 +319,9 @@ class TestCase(enum.Enum):
_client_streaming(stub)
elif self is TestCase.PING_PONG:
_ping_pong(stub)
elif self is TestCase.COMPUTE_ENGINE_CREDS:
_compute_engine_creds(stub, args)
elif self is TestCase.SERVICE_ACCOUNT_CREDS:
_service_account_creds(stub, args)
else:
raise NotImplementedError('Test case "%s" not implemented!' % self.name)

@ -45,7 +45,7 @@ _PACKAGE_DATA = {
'credentials/server1.pem',]
}
_INSTALL_REQUIRES = ['grpcio>=0.4.0a4']
_INSTALL_REQUIRES = ['oauth2client>=1.4.7', 'grpcio>=0.4.0a4']
setuptools.setup(
name='interop',

@ -32,38 +32,79 @@
licenses(["notice"]) # 3-clause BSD
package(default_visibility = ["//visibility:public"])
<%!
def get_deps(target_dict):
deps = []
if target_dict.get('secure', 'no') == 'yes':
deps = [
"//external:libssl",
]
if target_dict.get('build', None) == 'protoc':
deps.append("//external:protobuf_compiler")
if target_dict['name'] == 'grpc++_unsecure' or target_dict['name'] == 'grpc++':
deps.append("//external:protobuf_clib")
for d in target_dict.get('deps', []):
if d.find('//') == 0 or d[0] == ':':
deps.append(d)
else:
deps.append(':%s' % (d))
return deps
%>
% for lib in libs:
% if lib.build == "all" and lib.language == 'c':
${makelib(lib)}
% if lib.build != "private":
${cc_library(lib)}
% endif
% endfor
<%def name="makelib(lib)">
% for tgt in targets:
% if tgt.build == 'protoc':
${cc_binary(tgt)}
% endif
% endfor
<%def name="cc_library(lib)">
cc_library(
name = "${lib.name}",
srcs = [
name = "${lib.name}",
srcs = [
% for hdr in lib.get("headers", []):
"${hdr}",
"${hdr}",
% endfor
% for src in lib.src:
"${src}",
"${src}",
% endfor
],
hdrs = [
],
hdrs = [
% for hdr in lib.get("public_headers", []):
"${hdr}",
"${hdr}",
% endfor
],
includes = [
"include",
".",
],
deps = [
% for dep in lib.get("deps", []):
":${dep}",
],
includes = [
"include",
".",
],
deps = [
% for dep in get_deps(lib):
"${dep}",
% endfor
],
],
)
</%def>
<%def name="cc_binary(tgt)">
cc_binary(
name = "${tgt.name}",
srcs = [
% for src in tgt.src:
"${src}",
% endfor
],
deps = [
% for dep in get_deps(tgt):
"${dep}",
% endfor
],
)
</%def>

@ -35,17 +35,11 @@
proto_re = re.compile('(.*)\\.proto')
def excluded(filename, exclude_res):
for r in exclude_res:
if r.match(filename):
return True
return False
def proto_to_cc(filename):
m = proto_re.match(filename)
if not m:
return filename
return '$(GENDIR)/' + m.group(1) + '.pb.cc'
return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc'
%>
@ -840,11 +834,17 @@ endif
% for p in protos:
ifeq ($(NO_PROTOC),true)
$(GENDIR)/${p}.pb.cc: protoc_dep_error
$(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
$(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
% endfor
@ -930,6 +930,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so.${settings.version.major}
$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so
endif
endif

@ -51,10 +51,11 @@ static void *tag(gpr_intptr t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
cancellation_mode mode,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
gpr_log(GPR_INFO, "%s/%s/%s", test_name, config.name, mode.name);
f = config.create_fixture(client_args, server_args);
config.init_client(&f, client_args);
config.init_server(&f, server_args);
@ -109,7 +110,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
grpc_end2end_test_fixture f =
begin_test(config, __FUNCTION__, mode, NULL, NULL);
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
grpc_metadata_array initial_metadata_recv;

@ -35,6 +35,7 @@
#define GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
typedef struct {
const char *name;
grpc_call_error (*initiate_cancel)(grpc_call *call);
grpc_status_code expect_status;
const char *expect_details;
@ -45,7 +46,9 @@ static grpc_call_error wait_for_deadline(grpc_call *call) {
}
static const cancellation_mode cancellation_modes[] = {
{grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
{wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"}, };
{"cancel", grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
{"deadline", wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED,
"Deadline Exceeded"},
};
#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */
#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */

@ -60,14 +60,14 @@ static void on_connect(void *arg, grpc_endpoint *tcp) {
static void test_no_op(void) {
grpc_tcp_server *s = grpc_tcp_server_create();
grpc_tcp_server_destroy(s);
grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_start(void) {
grpc_tcp_server *s = grpc_tcp_server_create();
LOG_TEST();
grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
grpc_tcp_server_destroy(s);
grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_port(void) {
@ -80,7 +80,7 @@ static void test_no_op_with_port(void) {
GPR_ASSERT(
grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
grpc_tcp_server_destroy(s);
grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_port_and_start(void) {
@ -95,7 +95,7 @@ static void test_no_op_with_port_and_start(void) {
grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
grpc_tcp_server_destroy(s);
grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_connect(int n) {
@ -144,7 +144,7 @@ static void test_connect(int n) {
gpr_mu_unlock(&mu);
grpc_tcp_server_destroy(s);
grpc_tcp_server_destroy(s, NULL, NULL);
}
int main(int argc, char **argv) {

@ -35,8 +35,8 @@
#include <memory>
#include "test/core/util/test_config.h"
#include "test/cpp/util/echo_duplicate.pb.h"
#include "test/cpp/util/echo.pb.h"
#include "test/cpp/util/echo_duplicate.grpc.pb.h"
#include "test/cpp/util/echo.grpc.pb.h"
#include "src/cpp/util/time.h"
#include <grpc++/async_unary_call.h>
#include <grpc++/channel_arguments.h>

@ -35,8 +35,8 @@
#include <thread>
#include "test/core/util/test_config.h"
#include "test/cpp/util/echo_duplicate.pb.h"
#include "test/cpp/util/echo.pb.h"
#include "test/cpp/util/echo_duplicate.grpc.pb.h"
#include "test/cpp/util/echo.grpc.pb.h"
#include "src/cpp/util/time.h"
#include "src/cpp/server/thread_pool.h"
#include <grpc++/channel_arguments.h>

@ -38,7 +38,7 @@
#include "src/cpp/util/time.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/util/echo.pb.h"
#include "test/cpp/util/echo.grpc.pb.h"
#include <grpc++/async_generic_service.h>
#include <grpc++/async_unary_call.h>
#include <grpc++/byte_buffer.h>

@ -31,29 +31,19 @@
*
*/
#include <chrono>
#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <thread>
#include <unistd.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <gflags/gflags.h>
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/interop/test.pb.h"
#include "test/cpp/interop/empty.pb.h"
#include "test/cpp/interop/messages.pb.h"
#include "test/cpp/interop/client_helper.h"
#include "test/cpp/interop/interop_client.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google");
@ -81,21 +71,8 @@ DEFINE_string(service_account_key_file, "",
"Path to service account json key file.");
DEFINE_string(oauth_scope, "", "Scope for OAuth tokens.");
using grpc::ChannelInterface;
using grpc::ClientContext;
using grpc::ComputeEngineCredentials;
using grpc::CreateTestChannel;
using grpc::Credentials;
using grpc::JWTCredentials;
using grpc::ServiceAccountCredentials;
using grpc::testing::ResponseParameters;
using grpc::testing::SimpleRequest;
using grpc::testing::SimpleResponse;
using grpc::testing::StreamingInputCallRequest;
using grpc::testing::StreamingInputCallResponse;
using grpc::testing::StreamingOutputCallRequest;
using grpc::testing::StreamingOutputCallResponse;
using grpc::testing::TestService;
using grpc::testing::CreateChannelForTestCase;
using grpc::testing::GetServiceAccountJsonKey;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
@ -104,362 +81,48 @@ namespace gflags {}
using namespace google;
using namespace gflags;
namespace {
// The same value is defined by the Java client.
const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
const int kNumResponseMessages = 2000;
const int kResponseMessageSize = 1030;
const int kReceiveDelayMilliSeconds = 20;
const int kLargeRequestSize = 314159;
const int kLargeResponseSize = 271812;
} // namespace
grpc::string GetServiceAccountJsonKey() {
static grpc::string json_key;
if (json_key.empty()) {
std::ifstream json_key_file(FLAGS_service_account_key_file);
std::stringstream key_stream;
key_stream << json_key_file.rdbuf();
json_key = key_stream.str();
}
return json_key;
}
std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
const grpc::string& test_case) {
GPR_ASSERT(FLAGS_server_port);
const int host_port_buf_size = 1024;
char host_port[host_port_buf_size];
snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
FLAGS_server_port);
if (test_case == "service_account_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope,
std::chrono::hours(1));
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "compute_engine_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
creds = ComputeEngineCredentials();
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "jwt_token_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
creds = JWTCredentials(json_key, std::chrono::hours(1));
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else {
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots);
}
}
void AssertOkOrPrintErrorStatus(const grpc::Status& s) {
if (s.IsOk()) {
return;
}
gpr_log(GPR_INFO, "Error status code: %d, message: %s", s.code(),
s.details().c_str());
GPR_ASSERT(0);
}
void DoEmpty() {
gpr_log(GPR_INFO, "Sending an empty rpc...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("empty_unary");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
grpc::testing::Empty request = grpc::testing::Empty::default_instance();
grpc::testing::Empty response = grpc::testing::Empty::default_instance();
ClientContext context;
grpc::Status s = stub->EmptyCall(&context, request, &response);
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Empty rpc done.");
}
// Shared code to set large payload, make rpc and check response payload.
void PerformLargeUnary(std::shared_ptr<ChannelInterface> channel,
SimpleRequest* request, SimpleResponse* response) {
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
ClientContext context;
request->set_response_type(grpc::testing::PayloadType::COMPRESSABLE);
request->set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
grpc::Status s = stub->UnaryCall(&context, *request, response);
AssertOkOrPrintErrorStatus(s);
GPR_ASSERT(response->payload().type() ==
grpc::testing::PayloadType::COMPRESSABLE);
GPR_ASSERT(response->payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
}
void DoComputeEngineCreds() {
gpr_log(GPR_INFO,
"Sending a large unary rpc with compute engine credentials ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("compute_engine_creds");
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
request.set_fill_oauth_scope(true);
PerformLargeUnary(channel, &request, &response);
gpr_log(GPR_INFO, "Got username %s", response.username().c_str());
gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str());
GPR_ASSERT(!response.username().empty());
GPR_ASSERT(response.username().c_str() == FLAGS_default_service_account);
GPR_ASSERT(!response.oauth_scope().empty());
const char* oauth_scope_str = response.oauth_scope().c_str();
GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
}
void DoServiceAccountCreds() {
gpr_log(GPR_INFO,
"Sending a large unary rpc with service account credentials ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("service_account_creds");
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
request.set_fill_oauth_scope(true);
PerformLargeUnary(channel, &request, &response);
GPR_ASSERT(!response.username().empty());
GPR_ASSERT(!response.oauth_scope().empty());
grpc::string json_key = GetServiceAccountJsonKey();
GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos);
const char* oauth_scope_str = response.oauth_scope().c_str();
GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with service account creds done.");
}
void DoJwtTokenCreds() {
gpr_log(GPR_INFO, "Sending a large unary rpc with JWT token credentials ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("jwt_token_creds");
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
PerformLargeUnary(channel, &request, &response);
GPR_ASSERT(!response.username().empty());
grpc::string json_key = GetServiceAccountJsonKey();
GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with JWT token creds done.");
}
void DoLargeUnary() {
gpr_log(GPR_INFO, "Sending a large unary rpc...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("large_unary");
SimpleRequest request;
SimpleResponse response;
PerformLargeUnary(channel, &request, &response);
gpr_log(GPR_INFO, "Large unary done.");
}
void DoRequestStreaming() {
gpr_log(GPR_INFO, "Sending request steaming rpc ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("client_streaming");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
grpc::ClientContext context;
StreamingInputCallRequest request;
StreamingInputCallResponse response;
std::unique_ptr<grpc::ClientWriter<StreamingInputCallRequest>> stream(
stub->StreamingInputCall(&context, &response));
int aggregated_payload_size = 0;
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
grpc::testing::Payload* payload = request.mutable_payload();
payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
GPR_ASSERT(stream->Write(request));
aggregated_payload_size += request_stream_sizes[i];
}
stream->WritesDone();
grpc::Status s = stream->Finish();
GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Request streaming done.");
}
void DoResponseStreaming() {
gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("server_streaming");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
grpc::ClientContext context;
StreamingOutputCallRequest request;
for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
ResponseParameters* response_parameter = request.add_response_parameters();
response_parameter->set_size(response_stream_sizes[i]);
}
StreamingOutputCallResponse response;
std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
unsigned int i = 0;
while (stream->Read(&response)) {
GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0'));
++i;
}
GPR_ASSERT(response_stream_sizes.size() == i);
grpc::Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Response streaming done.");
}
void DoResponseStreamingWithSlowConsumer() {
gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("slow_consumer");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
grpc::ClientContext context;
StreamingOutputCallRequest request;
for (int i = 0; i < kNumResponseMessages; ++i) {
ResponseParameters* response_parameter = request.add_response_parameters();
response_parameter->set_size(kResponseMessageSize);
}
StreamingOutputCallResponse response;
std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
int i = 0;
while (stream->Read(&response)) {
GPR_ASSERT(response.payload().body() ==
grpc::string(kResponseMessageSize, '\0'));
gpr_log(GPR_INFO, "received message %d", i);
usleep(kReceiveDelayMilliSeconds * 1000);
++i;
}
GPR_ASSERT(kNumResponseMessages == i);
grpc::Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Response streaming done.");
}
void DoHalfDuplex() {
gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("half_duplex");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
grpc::ClientContext context;
std::unique_ptr<grpc::ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->HalfDuplexCall(&context));
StreamingOutputCallRequest request;
ResponseParameters* response_parameter = request.add_response_parameters();
for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
response_parameter->set_size(response_stream_sizes[i]);
GPR_ASSERT(stream->Write(request));
}
stream->WritesDone();
unsigned int i = 0;
StreamingOutputCallResponse response;
while (stream->Read(&response)) {
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0'));
++i;
}
GPR_ASSERT(response_stream_sizes.size() == i);
grpc::Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
}
void DoPingPong() {
gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
std::shared_ptr<ChannelInterface> channel =
CreateChannelForTestCase("ping_pong");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
grpc::ClientContext context;
std::unique_ptr<grpc::ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->FullDuplexCall(&context));
StreamingOutputCallRequest request;
request.set_response_type(grpc::testing::PayloadType::COMPRESSABLE);
ResponseParameters* response_parameter = request.add_response_parameters();
grpc::testing::Payload* payload = request.mutable_payload();
StreamingOutputCallResponse response;
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
response_parameter->set_size(response_stream_sizes[i]);
payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
GPR_ASSERT(stream->Write(request));
GPR_ASSERT(stream->Read(&response));
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0'));
}
stream->WritesDone();
GPR_ASSERT(!stream->Read(&response));
grpc::Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Ping pong streaming done.");
}
int main(int argc, char** argv) {
grpc_init();
ParseCommandLineFlags(&argc, &argv, true);
grpc::testing::InteropClient client(
CreateChannelForTestCase(FLAGS_test_case));
if (FLAGS_test_case == "empty_unary") {
DoEmpty();
client.DoEmpty();
} else if (FLAGS_test_case == "large_unary") {
DoLargeUnary();
client.DoLargeUnary();
} else if (FLAGS_test_case == "client_streaming") {
DoRequestStreaming();
client.DoRequestStreaming();
} else if (FLAGS_test_case == "server_streaming") {
DoResponseStreaming();
client.DoResponseStreaming();
} else if (FLAGS_test_case == "slow_consumer") {
DoResponseStreamingWithSlowConsumer();
client.DoResponseStreamingWithSlowConsumer();
} else if (FLAGS_test_case == "half_duplex") {
DoHalfDuplex();
client.DoHalfDuplex();
} else if (FLAGS_test_case == "ping_pong") {
DoPingPong();
client.DoPingPong();
} else if (FLAGS_test_case == "service_account_creds") {
DoServiceAccountCreds();
grpc::string json_key = GetServiceAccountJsonKey();
client.DoServiceAccountCreds(json_key, FLAGS_oauth_scope);
} else if (FLAGS_test_case == "compute_engine_creds") {
DoComputeEngineCreds();
client.DoComputeEngineCreds(FLAGS_default_service_account,
FLAGS_oauth_scope);
} else if (FLAGS_test_case == "jwt_token_creds") {
DoJwtTokenCreds();
grpc::string json_key = GetServiceAccountJsonKey();
client.DoJwtTokenCreds(json_key);
} else if (FLAGS_test_case == "all") {
DoEmpty();
DoLargeUnary();
DoRequestStreaming();
DoResponseStreaming();
DoHalfDuplex();
DoPingPong();
client.DoEmpty();
client.DoLargeUnary();
client.DoRequestStreaming();
client.DoResponseStreaming();
client.DoHalfDuplex();
client.DoPingPong();
// service_account_creds and jwt_token_creds can only run with ssl.
if (FLAGS_enable_ssl) {
DoServiceAccountCreds();
DoJwtTokenCreds();
grpc::string json_key = GetServiceAccountJsonKey();
client.DoServiceAccountCreds(json_key, FLAGS_oauth_scope);
client.DoJwtTokenCreds(json_key);
}
// compute_engine_creds only runs in GCE.
} else {
@ -470,6 +133,7 @@ int main(int argc, char** argv) {
"service_account_creds|compute_engine_creds|jwt_token_creds",
FLAGS_test_case.c_str());
}
client.Reset(nullptr);
grpc_shutdown();
return 0;

@ -0,0 +1,119 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/cpp/interop/client_helper.h"
#include <fstream>
#include <memory>
#include <sstream>
#include <unistd.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <gflags/gflags.h>
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
#include <grpc++/stream.h>
#include "test/cpp/util/create_test_channel.h"
DECLARE_bool(enable_ssl);
DECLARE_bool(use_prod_roots);
DECLARE_int32(server_port);
DECLARE_string(server_host);
DECLARE_string(server_host_override);
DECLARE_string(test_case);
DECLARE_string(default_service_account);
DECLARE_string(service_account_key_file);
DECLARE_string(oauth_scope);
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
namespace google {}
namespace gflags {}
using namespace google;
using namespace gflags;
namespace grpc {
namespace testing {
grpc::string GetServiceAccountJsonKey() {
static grpc::string json_key;
if (json_key.empty()) {
std::ifstream json_key_file(FLAGS_service_account_key_file);
std::stringstream key_stream;
key_stream << json_key_file.rdbuf();
json_key = key_stream.str();
}
return json_key;
}
std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
const grpc::string& test_case) {
GPR_ASSERT(FLAGS_server_port);
const int host_port_buf_size = 1024;
char host_port[host_port_buf_size];
snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
FLAGS_server_port);
if (test_case == "service_account_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope,
std::chrono::hours(1));
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "compute_engine_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
creds = ComputeEngineCredentials();
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "jwt_token_creds") {
std::unique_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
creds = JWTCredentials(json_key, std::chrono::hours(1));
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else {
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots);
}
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,53 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
#define GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
#include <memory>
#include <grpc++/config.h>
#include <grpc++/channel_interface.h>
namespace grpc {
namespace testing {
grpc::string GetServiceAccountJsonKey();
std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
const grpc::string& test_case);
} // namespace testing
} // namespace grpc
#endif // GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H

@ -0,0 +1,311 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/cpp/interop/interop_client.h"
#include <memory>
#include <unistd.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "test/cpp/interop/test.grpc.pb.h"
#include "test/cpp/interop/empty.grpc.pb.h"
#include "test/cpp/interop/messages.grpc.pb.h"
namespace grpc {
namespace testing {
namespace {
// The same value is defined by the Java client.
const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
const int kNumResponseMessages = 2000;
const int kResponseMessageSize = 1030;
const int kReceiveDelayMilliSeconds = 20;
const int kLargeRequestSize = 314159;
const int kLargeResponseSize = 271812;
} // namespace
InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel)
: channel_(channel) {}
void InteropClient::AssertOkOrPrintErrorStatus(const Status& s) {
if (s.IsOk()) {
return;
}
gpr_log(GPR_INFO, "Error status code: %d, message: %s", s.code(),
s.details().c_str());
GPR_ASSERT(0);
}
void InteropClient::DoEmpty() {
gpr_log(GPR_INFO, "Sending an empty rpc...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
Empty request = Empty::default_instance();
Empty response = Empty::default_instance();
ClientContext context;
Status s = stub->EmptyCall(&context, request, &response);
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Empty rpc done.");
}
// Shared code to set large payload, make rpc and check response payload.
void InteropClient::PerformLargeUnary(SimpleRequest* request,
SimpleResponse* response) {
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
request->set_response_type(PayloadType::COMPRESSABLE);
request->set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = stub->UnaryCall(&context, *request, response);
AssertOkOrPrintErrorStatus(s);
GPR_ASSERT(response->payload().type() == PayloadType::COMPRESSABLE);
GPR_ASSERT(response->payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
}
void InteropClient::DoComputeEngineCreds(
const grpc::string& default_service_account,
const grpc::string& oauth_scope) {
gpr_log(GPR_INFO,
"Sending a large unary rpc with compute engine credentials ...");
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
request.set_fill_oauth_scope(true);
PerformLargeUnary(&request, &response);
gpr_log(GPR_INFO, "Got username %s", response.username().c_str());
gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str());
GPR_ASSERT(!response.username().empty());
GPR_ASSERT(response.username().c_str() == default_service_account);
GPR_ASSERT(!response.oauth_scope().empty());
const char* oauth_scope_str = response.oauth_scope().c_str();
GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
}
void InteropClient::DoServiceAccountCreds(const grpc::string& username,
const grpc::string& oauth_scope) {
gpr_log(GPR_INFO,
"Sending a large unary rpc with service account credentials ...");
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
request.set_fill_oauth_scope(true);
PerformLargeUnary(&request, &response);
GPR_ASSERT(!response.username().empty());
GPR_ASSERT(!response.oauth_scope().empty());
GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
const char* oauth_scope_str = response.oauth_scope().c_str();
GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with service account creds done.");
}
void InteropClient::DoJwtTokenCreds(const grpc::string& username) {
gpr_log(GPR_INFO, "Sending a large unary rpc with JWT token credentials ...");
SimpleRequest request;
SimpleResponse response;
request.set_fill_username(true);
PerformLargeUnary(&request, &response);
GPR_ASSERT(!response.username().empty());
GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
gpr_log(GPR_INFO, "Large unary with JWT token creds done.");
}
void InteropClient::DoLargeUnary() {
gpr_log(GPR_INFO, "Sending a large unary rpc...");
SimpleRequest request;
SimpleResponse response;
PerformLargeUnary(&request, &response);
gpr_log(GPR_INFO, "Large unary done.");
}
void InteropClient::DoRequestStreaming() {
gpr_log(GPR_INFO, "Sending request steaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingInputCallRequest request;
StreamingInputCallResponse response;
std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
stub->StreamingInputCall(&context, &response));
int aggregated_payload_size = 0;
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
Payload* payload = request.mutable_payload();
payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
GPR_ASSERT(stream->Write(request));
aggregated_payload_size += request_stream_sizes[i];
}
stream->WritesDone();
Status s = stream->Finish();
GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Request streaming done.");
}
void InteropClient::DoResponseStreaming() {
gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingOutputCallRequest request;
for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
ResponseParameters* response_parameter = request.add_response_parameters();
response_parameter->set_size(response_stream_sizes[i]);
}
StreamingOutputCallResponse response;
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
unsigned int i = 0;
while (stream->Read(&response)) {
GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0'));
++i;
}
GPR_ASSERT(response_stream_sizes.size() == i);
Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Response streaming done.");
}
void InteropClient::DoResponseStreamingWithSlowConsumer() {
gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
StreamingOutputCallRequest request;
for (int i = 0; i < kNumResponseMessages; ++i) {
ResponseParameters* response_parameter = request.add_response_parameters();
response_parameter->set_size(kResponseMessageSize);
}
StreamingOutputCallResponse response;
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
stub->StreamingOutputCall(&context, request));
int i = 0;
while (stream->Read(&response)) {
GPR_ASSERT(response.payload().body() ==
grpc::string(kResponseMessageSize, '\0'));
gpr_log(GPR_INFO, "received message %d", i);
usleep(kReceiveDelayMilliSeconds * 1000);
++i;
}
GPR_ASSERT(kNumResponseMessages == i);
Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Response streaming done.");
}
void InteropClient::DoHalfDuplex() {
gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->HalfDuplexCall(&context));
StreamingOutputCallRequest request;
ResponseParameters* response_parameter = request.add_response_parameters();
for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
response_parameter->set_size(response_stream_sizes[i]);
GPR_ASSERT(stream->Write(request));
}
stream->WritesDone();
unsigned int i = 0;
StreamingOutputCallResponse response;
while (stream->Read(&response)) {
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0'));
++i;
}
GPR_ASSERT(response_stream_sizes.size() == i);
Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
}
void InteropClient::DoPingPong() {
gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
ClientContext context;
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
StreamingOutputCallResponse>>
stream(stub->FullDuplexCall(&context));
StreamingOutputCallRequest request;
request.set_response_type(PayloadType::COMPRESSABLE);
ResponseParameters* response_parameter = request.add_response_parameters();
Payload* payload = request.mutable_payload();
StreamingOutputCallResponse response;
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
response_parameter->set_size(response_stream_sizes[i]);
payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
GPR_ASSERT(stream->Write(request));
GPR_ASSERT(stream->Read(&response));
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0'));
}
stream->WritesDone();
GPR_ASSERT(!stream->Read(&response));
Status s = stream->Finish();
AssertOkOrPrintErrorStatus(s);
gpr_log(GPR_INFO, "Ping pong streaming done.");
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,79 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H
#define GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H
#include <memory>
#include <grpc/grpc.h>
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
#include "test/cpp/interop/messages.grpc.pb.h"
namespace grpc {
namespace testing {
class InteropClient {
public:
explicit InteropClient(std::shared_ptr<ChannelInterface> channel);
~InteropClient() {}
void Reset(std::shared_ptr<ChannelInterface> channel) { channel_ = channel; }
void DoEmpty();
void DoLargeUnary();
void DoPingPong();
void DoHalfDuplex();
void DoRequestStreaming();
void DoResponseStreaming();
void DoResponseStreamingWithSlowConsumer();
// Auth tests.
// username is a string containing the user email
void DoJwtTokenCreds(const grpc::string& username);
void DoComputeEngineCreds(const grpc::string& default_service_account,
const grpc::string& oauth_scope);
// username is a string containing the user email
void DoServiceAccountCreds(const grpc::string& username,
const grpc::string& oauth_scope);
private:
void PerformLargeUnary(SimpleRequest* request, SimpleResponse* response);
void AssertOkOrPrintErrorStatus(const Status& s);
std::shared_ptr<ChannelInterface> channel_;
};
} // namespace testing
} // namespace grpc
#endif // GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H

@ -41,7 +41,6 @@
#include <gflags/gflags.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "test/core/end2end/data/ssl_test_data.h"
#include <grpc++/config.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
@ -49,9 +48,10 @@
#include <grpc++/server_credentials.h>
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "test/cpp/interop/test.pb.h"
#include "test/cpp/interop/empty.pb.h"
#include "test/cpp/interop/messages.pb.h"
#include "test/cpp/interop/test.grpc.pb.h"
#include "test/cpp/interop/empty.grpc.pb.h"
#include "test/cpp/interop/messages.grpc.pb.h"
#include "test/cpp/interop/server_helper.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_int32(port, 0, "Server port.");
@ -211,15 +211,8 @@ void RunServer() {
ServerBuilder builder;
builder.RegisterService(&service);
std::shared_ptr<ServerCredentials> creds = grpc::InsecureServerCredentials();
if (FLAGS_enable_ssl) {
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);
creds = grpc::SslServerCredentials(ssl_opts);
}
std::shared_ptr<ServerCredentials> creds =
grpc::testing::CreateInteropServerCredentials();
builder.AddListeningPort(server_address.str(), creds);
std::unique_ptr<Server> server(builder.BuildAndStart());
gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());

@ -0,0 +1,69 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/cpp/interop/server_helper.h"
#include <memory>
#include <gflags/gflags.h>
#include "test/core/end2end/data/ssl_test_data.h"
#include <grpc++/config.h>
#include <grpc++/server_credentials.h>
DECLARE_bool(enable_ssl);
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
namespace google {}
namespace gflags {}
using namespace google;
using namespace gflags;
namespace grpc {
namespace testing {
std::shared_ptr<ServerCredentials> CreateInteropServerCredentials() {
if (FLAGS_enable_ssl) {
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);
return SslServerCredentials(ssl_opts);
} else {
return InsecureServerCredentials();
}
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,49 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H
#define GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H
#include <memory>
#include <grpc++/server_credentials.h>
namespace grpc {
namespace testing {
std::shared_ptr<ServerCredentials> CreateInteropServerCredentials();
} // namespace testing
} // namespace grpc
#endif // GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H

@ -36,7 +36,7 @@
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/timer.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
#include <condition_variable>
#include <mutex>
@ -104,7 +104,7 @@ class Client {
void EndThreads() { threads_.clear(); }
virtual void ThreadFunc(Histogram* histogram, size_t thread_idx) = 0;
virtual bool ThreadFunc(Histogram* histogram, size_t thread_idx) = 0;
private:
class Thread {
@ -113,20 +113,24 @@ class Client {
: done_(false),
new_(nullptr),
impl_([this, idx, client]() {
for (;;) {
// run the loop body
client->ThreadFunc(&histogram_, idx);
// lock, see if we're done
std::lock_guard<std::mutex> g(mu_);
if (done_) {return;}
// check if we're marking, swap out the histogram if so
if (new_) {
new_->Swap(&histogram_);
new_ = nullptr;
cv_.notify_one();
for (;;) {
// run the loop body
bool thread_still_ok = client->ThreadFunc(&histogram_, idx);
// lock, see if we're done
std::lock_guard<std::mutex> g(mu_);
if (!thread_still_ok) {
gpr_log(GPR_ERROR, "Finishing client thread due to RPC error");
done_ = true;
}
if (done_) {return;}
// check if we're marking, swap out the histogram if so
if (new_) {
new_->Swap(&histogram_);
new_ = nullptr;
cv_.notify_one();
}
}
}
}) {}
}) {}
~Thread() {
{

@ -48,7 +48,7 @@
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/timer.h"
#include "test/cpp/qps/client.h"
@ -137,13 +137,7 @@ class AsyncUnaryClient GRPC_FINAL : public Client {
cli_cqs_.emplace_back(new CompletionQueue);
}
auto payload_size = config.payload_size();
auto check_done = [payload_size](grpc::Status s, SimpleResponse* response) {
GPR_ASSERT(s.IsOk() && (response->payload().type() ==
grpc::testing::PayloadType::COMPRESSABLE) &&
(response->payload().body().length() ==
static_cast<size_t>(payload_size)));
};
auto check_done = [](grpc::Status s, SimpleResponse* response) {};
int t = 0;
for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
@ -179,10 +173,14 @@ class AsyncUnaryClient GRPC_FINAL : public Client {
}
}
void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
void* got_tag;
bool ok;
cli_cqs_[thread_idx]->Next(&got_tag, &ok);
switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) {
case CompletionQueue::SHUTDOWN: return false;
case CompletionQueue::TIMEOUT: return true;
case CompletionQueue::GOT_EVENT: break;
}
ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
if (ctx->RunNextState(ok, histogram) == false) {
@ -191,6 +189,8 @@ class AsyncUnaryClient GRPC_FINAL : public Client {
ctx->StartNewClone();
delete ctx;
}
return true;
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
@ -270,13 +270,7 @@ class AsyncStreamingClient GRPC_FINAL : public Client {
cli_cqs_.emplace_back(new CompletionQueue);
}
auto payload_size = config.payload_size();
auto check_done = [payload_size](grpc::Status s, SimpleResponse *response) {
GPR_ASSERT(s.IsOk() && (response->payload().type() ==
grpc::testing::PayloadType::COMPRESSABLE) &&
(response->payload().body().length() ==
static_cast<size_t>(payload_size)));
};
auto check_done = [](grpc::Status s, SimpleResponse* response) {};
int t = 0;
for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
@ -313,10 +307,14 @@ class AsyncStreamingClient GRPC_FINAL : public Client {
}
}
void ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE {
bool ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE {
void *got_tag;
bool ok;
cli_cqs_[thread_idx]->Next(&got_tag, &ok);
switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) {
case CompletionQueue::SHUTDOWN: return false;
case CompletionQueue::TIMEOUT: return true;
case CompletionQueue::GOT_EVENT: break;
}
ClientRpcContext *ctx = ClientRpcContext::detag(got_tag);
if (ctx->RunNextState(ok, histogram) == false) {
@ -325,6 +323,8 @@ class AsyncStreamingClient GRPC_FINAL : public Client {
ctx->StartNewClone();
delete ctx;
}
return true;
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;

@ -55,7 +55,7 @@
#include <gtest/gtest.h>
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/qps/client.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/timer.h"
@ -83,13 +83,14 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient {
SynchronousClient(config) {StartThreads(num_threads_);}
~SynchronousUnaryClient() {}
void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
auto* stub = channels_[thread_idx % channels_.size()].get_stub();
double start = Timer::Now();
grpc::ClientContext context;
grpc::Status s =
stub->UnaryCall(&context, request_, &responses_[thread_idx]);
histogram->Add((Timer::Now() - start) * 1e9);
return s.IsOk();
}
};
@ -111,11 +112,13 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient {
}
}
void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
double start = Timer::Now();
EXPECT_TRUE(stream_->Write(request_));
EXPECT_TRUE(stream_->Read(&responses_[thread_idx]));
histogram->Add((Timer::Now() - start) * 1e9);
if (stream_->Write(request_) && stream_->Read(&responses_[thread_idx])) {
histogram->Add((Timer::Now() - start) * 1e9);
return true;
}
return false;
}
private:
grpc::ClientContext context_;

@ -35,7 +35,7 @@
#define TEST_QPS_DRIVER_H
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {

@ -35,7 +35,7 @@
#define TEST_QPS_HISTOGRAM_H
#include <grpc/support/histogram.h>
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {
@ -50,10 +50,10 @@ class Histogram {
void Merge(Histogram* h) { gpr_histogram_merge(impl_, h->impl_); }
void Add(double value) { gpr_histogram_add(impl_, value); }
double Percentile(double pctile) {
double Percentile(double pctile) const {
return gpr_histogram_percentile(impl_, pctile);
}
double Count() { return gpr_histogram_count(impl_); }
double Count() const { return gpr_histogram_count(impl_); }
void Swap(Histogram* other) { std::swap(impl_, other->impl_); }
void FillProto(HistogramData* p) {
size_t n;

@ -35,7 +35,7 @@
#include <grpc/support/log.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/stats.h"
#include "test/cpp/qps/report.h"
DEFINE_int32(num_clients, 1, "Number of client binaries");
DEFINE_int32(num_servers, 1, "Number of server binaries");
@ -65,7 +65,6 @@ using grpc::testing::ClientType;
using grpc::testing::ServerType;
using grpc::testing::RpcType;
using grpc::testing::ResourceUsage;
using grpc::testing::sum;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
@ -105,37 +104,9 @@ int main(int argc, char** argv) {
server_config, FLAGS_num_servers,
FLAGS_warmup_seconds, FLAGS_benchmark_seconds);
gpr_log(GPR_INFO, "QPS: %.1f",
result.latencies.Count() /
average(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Latencies (50/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f us",
result.latencies.Percentile(50) / 1000,
result.latencies.Percentile(95) / 1000,
result.latencies.Percentile(99) / 1000,
result.latencies.Percentile(99.9) / 1000);
gpr_log(GPR_INFO, "Server system time: %.2f%%",
100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.system_time; }) /
sum(result.server_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Server user time: %.2f%%",
100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.user_time; }) /
sum(result.server_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Client system time: %.2f%%",
100.0 * sum(result.client_resources,
[](ResourceUsage u) { return u.system_time; }) /
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Client user time: %.2f%%",
100.0 * sum(result.client_resources,
[](ResourceUsage u) { return u.user_time; }) /
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
ReportQPSPerCore(result, server_config);
ReportLatency(result);
ReportTimes(result);
grpc_shutdown();
return 0;

@ -0,0 +1,94 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/cpp/qps/report.h"
#include <grpc/support/log.h>
#include "test/cpp/qps/stats.h"
namespace grpc {
namespace testing {
// QPS: XXX
void ReportQPS(const ScenarioResult& result) {
gpr_log(GPR_INFO, "QPS: %.1f",
result.latencies.Count() /
average(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
}
// QPS: XXX (YYY/server core)
void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& server_config) {
auto qps =
result.latencies.Count() /
average(result.client_resources,
[](ResourceUsage u) { return u.wall_time; });
gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, qps/server_config.threads());
}
// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
void ReportLatency(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
result.latencies.Percentile(50) / 1000,
result.latencies.Percentile(90) / 1000,
result.latencies.Percentile(95) / 1000,
result.latencies.Percentile(99) / 1000,
result.latencies.Percentile(99.9) / 1000);
}
void ReportTimes(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Server system time: %.2f%%",
100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.system_time; }) /
sum(result.server_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Server user time: %.2f%%",
100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.user_time; }) /
sum(result.server_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Client system time: %.2f%%",
100.0 * sum(result.client_resources,
[](ResourceUsage u) { return u.system_time; }) /
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
gpr_log(GPR_INFO, "Client user time: %.2f%%",
100.0 * sum(result.client_resources,
[](ResourceUsage u) { return u.user_time; }) /
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,57 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef TEST_QPS_REPORT_H
#define TEST_QPS_REPORT_H
#include "test/cpp/qps/driver.h"
namespace grpc {
namespace testing {
// QPS: XXX
void ReportQPS(const ScenarioResult& result);
// QPS: XXX (YYY/server core)
void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config);
// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
void ReportLatency(const ScenarioResult& result);
// Server system time: XX%
// Server user time: XX%
// Client system time: XX%
// Client user time: XX%
void ReportTimes(const ScenarioResult& result);
} // namespace testing
} // namespace grpc
#endif

@ -35,7 +35,7 @@
#define TEST_QPS_SERVER_H
#include "test/cpp/qps/timer.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {

@ -52,7 +52,7 @@
#include <grpc++/stream.h>
#include <gtest/gtest.h>
#include "src/cpp/server/thread_pool.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/server.h"
#include <grpc/grpc.h>
@ -97,15 +97,15 @@ class AsyncQpsServerTest : public Server {
bool ok;
void* got_tag;
while (srv_cq_.Next(&got_tag, &ok)) {
ServerRpcContext* ctx = detag(got_tag);
// The tag is a pointer to an RPC context to invoke
if (ctx->RunNextState(ok) == false) {
// this RPC context is done, so refresh it
ServerRpcContext* ctx = detag(got_tag);
// The tag is a pointer to an RPC context to invoke
if (ctx->RunNextState(ok) == false) {
// this RPC context is done, so refresh it
std::lock_guard<std::mutex> g(shutdown_mutex_);
if (!shutdown_) {
ctx->Reset();
}
}
}
}
return;
}));
@ -175,8 +175,9 @@ class AsyncQpsServerTest : public Server {
private:
bool finisher(bool) { return false; }
bool invoker(bool ok) {
if (!ok)
return false;
if (!ok) {
return false;
}
ResponseType response;
@ -230,8 +231,9 @@ class AsyncQpsServerTest : public Server {
private:
bool request_done(bool ok) {
if (!ok)
return false;
if (!ok) {
return false;
}
stream_.Read(&req_, AsyncQpsServerTest::tag(this));
next_state_ = &ServerRpcContextStreamingImpl::read_done;
return true;

@ -47,7 +47,7 @@
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "src/cpp/server/thread_pool.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/server.h"
#include "test/cpp/qps/timer.h"

@ -0,0 +1,149 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/log.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
namespace grpc {
namespace testing {
static const int WARMUP = 5;
static const int BENCHMARK = 10;
static void RunSynchronousUnaryPingPong() {
gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong");
ClientConfig client_config;
client_config.set_client_type(SYNCHRONOUS_CLIENT);
client_config.set_enable_ssl(false);
client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1);
client_config.set_payload_size(1);
client_config.set_rpc_type(UNARY);
ServerConfig server_config;
server_config.set_server_type(SYNCHRONOUS_SERVER);
server_config.set_enable_ssl(false);
server_config.set_threads(1);
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
ReportQPS(result);
ReportLatency(result);
}
static void RunSynchronousStreamingPingPong() {
gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong");
ClientConfig client_config;
client_config.set_client_type(SYNCHRONOUS_CLIENT);
client_config.set_enable_ssl(false);
client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1);
client_config.set_payload_size(1);
client_config.set_rpc_type(STREAMING);
ServerConfig server_config;
server_config.set_server_type(SYNCHRONOUS_SERVER);
server_config.set_enable_ssl(false);
server_config.set_threads(1);
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
ReportQPS(result);
ReportLatency(result);
}
static void RunAsyncUnaryPingPong() {
gpr_log(GPR_INFO, "Running Async Unary Ping Pong");
ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false);
client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1);
client_config.set_payload_size(1);
client_config.set_async_client_threads(1);
client_config.set_rpc_type(UNARY);
ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false);
server_config.set_threads(1);
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
ReportQPS(result);
ReportLatency(result);
}
static void RunQPS() {
gpr_log(GPR_INFO, "Running QPS test");
ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false);
client_config.set_outstanding_rpcs_per_channel(1000);
client_config.set_client_channels(8);
client_config.set_payload_size(1);
client_config.set_async_client_threads(8);
client_config.set_rpc_type(UNARY);
ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER);
server_config.set_enable_ssl(false);
server_config.set_threads(4);
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
ReportQPSPerCore(result, server_config);
ReportLatency(result);
}
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc_init();
using namespace grpc::testing;
RunSynchronousStreamingPingPong();
RunSynchronousUnaryPingPong();
RunAsyncUnaryPingPong();
RunQPS();
grpc_shutdown();
return 0;
}

@ -0,0 +1,28 @@
#!/bin/sh
# performs a single qps run with one client and one server
set -ex
cd $(dirname $0)/../../..
killall qps_worker || true
config=opt
NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
make CONFIG=$config qps_worker qps_smoke_test -j$NUMCPUS
bins/$config/qps_worker -driver_port 10000 -server_port 10001 &
PID1=$!
bins/$config/qps_worker -driver_port 10010 -server_port 10011 &
PID2=$!
export QPS_WORKERS="localhost:10000,localhost:10010"
bins/$config/qps_smoke_test $*
kill -2 $PID1 $PID2
wait

@ -55,7 +55,7 @@
#include <grpc++/stream.h>
#include "test/core/util/grpc_profiler.h"
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/qps/qpstest.pb.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/client.h"
#include "test/cpp/qps/server.h"

@ -33,7 +33,7 @@
#include "test/core/util/test_config.h"
#include "test/cpp/util/cli_call.h"
#include "test/cpp/util/echo.pb.h"
#include "test/cpp/util/echo.grpc.pb.h"
#include "src/cpp/server/thread_pool.h"
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>

@ -45,7 +45,13 @@ if [ -f /version.txt ]; then
pkg_version=$(cat /version.txt)
fi
version="${pkg_version}.0"
echo "Target release => $pkg_version"
release_tag="release-${pkg_version//./_}"
echo "Target release => $pkg_version, will checkout tag $release_tag"
# Switch grpc_root to the release tag
pushd $grpc_root
git checkout $release_tag || { echo "bad release tag ${release_tag}"; exit 1; }
popd
if [ -f /.dockerinit ]; then
# We're in Docker where uname -p returns "unknown".

@ -1041,6 +1041,35 @@ grpc_interop_gen_python_cmd() {
echo $the_cmd
}
# constructs the full dockerized python service_account auth interop test cmd.
#
# call-seq:
# flags= .... # generic flags to include the command
# cmd=$($grpc_gen_test_cmd $flags)
grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() {
local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
local gfe_flags=$(_grpc_prod_gfe_flags)
local added_gfe_flags=$(_grpc_default_creds_test_flags)
local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'"
echo $the_cmd
}
# constructs the full dockerized python gce auth interop test cmd.
#
# call-seq:
# flags= .... # generic flags to include the command
# cmd=$($grpc_gen_test_cmd $flags)
grpc_cloud_prod_auth_compute_engine_creds_gen_python_cmd() {
local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
local gfe_flags=$(_grpc_prod_gfe_flags)
local added_gfe_flags=$(_grpc_gce_test_flags)
local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'"
echo $the_cmd
}
# constructs the full dockerized java interop test cmd.
#
# call-seq:

@ -36,7 +36,7 @@ echo $result_file_name
main() {
source grpc_docker.sh
test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
clients=(cxx java go ruby node python csharp_mono)
clients=(cxx java go ruby node python csharp_mono php)
servers=(cxx java go ruby node python csharp_mono)
for test_case in "${test_cases[@]}"
do

@ -93,6 +93,12 @@
<ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\service_type.h" />
<ClInclude Include="..\..\include\grpc++\impl\sync.h" />
<ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\impl\thd.h" />
<ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\server.h" />
<ClInclude Include="..\..\include\grpc++\server_builder.h" />
<ClInclude Include="..\..\include\grpc++\server_context.h" />
@ -104,6 +110,8 @@
<ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\cpp\client\secure_credentials.h" />
<ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="..\..\src\cpp\client\channel.h" />
<ClInclude Include="..\..\src\cpp\proto\proto_utils.h" />
<ClInclude Include="..\..\src\cpp\server\thread_pool.h" />

@ -132,6 +132,24 @@
<ClInclude Include="..\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\sync.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\thd.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\server.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@ -161,6 +179,12 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\cpp\client\secure_credentials.h">
<Filter>src\cpp\client</Filter>
</ClInclude>
<ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h">
<Filter>src\cpp\server</Filter>
</ClInclude>
<ClInclude Include="..\..\src\cpp\client\channel.h">
<Filter>src\cpp\client</Filter>
</ClInclude>

@ -95,6 +95,12 @@
<ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\service_type.h" />
<ClInclude Include="..\..\include\grpc++\impl\sync.h" />
<ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\impl\thd.h" />
<ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\server.h" />
<ClInclude Include="..\..\include\grpc++\server_builder.h" />
<ClInclude Include="..\..\include\grpc++\server_context.h" />
@ -106,6 +112,8 @@
<ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\cpp\client\secure_credentials.h" />
<ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="..\..\src\cpp\client\channel.h" />
<ClInclude Include="..\..\src\cpp\proto\proto_utils.h" />
<ClInclude Include="..\..\src\cpp\server\thread_pool.h" />

@ -132,6 +132,24 @@
<ClInclude Include="..\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\sync.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\thd.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc++\server.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@ -161,6 +179,12 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\cpp\client\secure_credentials.h">
<Filter>src\cpp\client</Filter>
</ClInclude>
<ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h">
<Filter>src\cpp\server</Filter>
</ClInclude>
<ClInclude Include="..\..\src\cpp\client\channel.h">
<Filter>src\cpp\client</Filter>
</ClInclude>

Loading…
Cancel
Save