aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2015-10-09 17:10:03 -0700
committerGravatar Craig Tiller <ctiller@google.com>2015-10-09 17:10:03 -0700
commit2783ced6f48afa70d339172e1d5a6beca51957b2 (patch)
tree241654231decd617508fc28be76f544b53aa86cc /src
parentcde54ba69f013f1c1d970fd32afebc7ddddef0c9 (diff)
parent2b15f1e25ae4aec6ef0de92b7e99e50188eb6438 (diff)
Merge branch 'latent-see' into try-this-simple-trick-to-double-performance
Diffstat (limited to 'src')
-rw-r--r--src/core/channel/client_channel.c4
-rw-r--r--src/core/channel/compress_filter.c2
-rw-r--r--src/core/client_config/uri_parser.c4
-rw-r--r--src/core/httpcli/parser.c11
-rw-r--r--src/core/iomgr/tcp_client_posix.c2
-rw-r--r--src/core/iomgr/tcp_server_posix.c2
-rw-r--r--src/core/security/credentials.c42
-rw-r--r--src/core/security/credentials.h8
-rw-r--r--src/core/security/security_context.c26
-rw-r--r--src/core/security/security_context.h11
-rw-r--r--src/core/security/server_auth_filter.c36
-rw-r--r--src/core/security/server_secure_chttp2.c4
-rw-r--r--src/core/surface/byte_buffer.c8
-rw-r--r--src/core/surface/call.c29
-rw-r--r--src/core/surface/call.h11
-rw-r--r--src/core/surface/call_test_only.h65
-rw-r--r--src/core/surface/channel_connectivity.c8
-rw-r--r--src/core/surface/completion_queue.c3
-rw-r--r--src/core/transport/chttp2/frame_data.c4
-rw-r--r--src/core/transport/chttp2/frame_goaway.c4
-rw-r--r--src/core/transport/chttp2/hpack_parser.c8
-rw-r--r--src/core/transport/chttp2/parsing.c16
-rw-r--r--src/core/transport/chttp2/stream_encoder.c6
-rw-r--r--src/cpp/server/server.cc3
-rw-r--r--src/node/interop/interop_client.js188
-rw-r--r--src/node/interop/interop_server.js63
-rw-r--r--src/node/src/credentials.js2
-rw-r--r--src/node/src/server.js2
-rw-r--r--src/node/test/async_test.js2
-rw-r--r--src/node/test/channel_test.js2
-rw-r--r--src/node/test/credentials_test.js10
-rw-r--r--src/node/test/interop_sanity_test.js10
-rwxr-xr-xsrc/php/tests/interop/interop_client.php20
33 files changed, 398 insertions, 218 deletions
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 1bdba5b3c0..dfa71c9af5 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -654,9 +654,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
case CALL_WAITING_FOR_CONFIG:
case CALL_WAITING_FOR_CALL:
case CALL_WAITING_FOR_SEND:
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- break;
+ GPR_UNREACHABLE_CODE(return );
}
}
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c
index 477e607596..20b5084044 100644
--- a/src/core/channel/compress_filter.c
+++ b/src/core/channel/compress_filter.c
@@ -243,7 +243,7 @@ static void process_send_ops(grpc_call_element *elem,
GPR_ASSERT(calld->remaining_slice_bytes > 0);
/* Increase input ref count, gpr_slice_buffer_add takes ownership. */
gpr_slice_buffer_add(&calld->slices, gpr_slice_ref(sop->data.slice));
- GPR_ASSERT(GPR_SLICE_LENGTH(sop->data.slice) >=
+ GPR_ASSERT(GPR_SLICE_LENGTH(sop->data.slice) <=
calld->remaining_slice_bytes);
calld->remaining_slice_bytes -=
(gpr_uint32)GPR_SLICE_LENGTH(sop->data.slice);
diff --git a/src/core/client_config/uri_parser.c b/src/core/client_config/uri_parser.c
index df9f32d403..cbdfffcf8e 100644
--- a/src/core/client_config/uri_parser.c
+++ b/src/core/client_config/uri_parser.c
@@ -37,6 +37,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
/** a size_t default value... maps to all 1's */
@@ -120,8 +121,7 @@ static int parse_fragment_or_query(const char *uri_text, size_t *i) {
} else {
return 1;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return 0);
default:
(*i) += advance;
break;
diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c
index 404906d5ae..046770c094 100644
--- a/src/core/httpcli/parser.c
+++ b/src/core/httpcli/parser.c
@@ -139,8 +139,7 @@ static int finish_line(grpc_httpcli_parser *parser) {
}
break;
case GRPC_HTTPCLI_BODY:
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return 0);
}
parser->cur_line_length = 0;
@@ -165,8 +164,7 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) {
} else {
return 1;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return 0);
case GRPC_HTTPCLI_BODY:
if (parser->r.body_length == parser->body_capacity) {
parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2);
@@ -177,10 +175,7 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) {
parser->r.body_length++;
return 1;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
-
- return 0;
+ GPR_UNREACHABLE_CODE(return 0);
}
void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) {
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index aca2691c41..fe20039264 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -191,7 +191,7 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, int success) {
goto finish;
}
- abort();
+ GPR_UNREACHABLE_CODE(return );
finish:
if (fd != NULL) {
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 13bd67576f..99c76dcbe9 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -352,7 +352,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
gpr_free(addr_str);
}
- abort();
+ GPR_UNREACHABLE_CODE(return );
error:
gpr_mu_lock(&sp->server->mu);
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 398db20e8c..5e155d83b9 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -181,6 +181,48 @@ void grpc_server_credentials_set_auth_metadata_processor(
creds->processor = processor;
}
+static void server_credentials_pointer_arg_destroy(void *p) {
+ grpc_server_credentials_unref(p);
+}
+
+static void *server_credentials_pointer_arg_copy(void *p) {
+ return grpc_server_credentials_ref(p);
+}
+
+grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) {
+ grpc_arg arg;
+ memset(&arg, 0, sizeof(grpc_arg));
+ arg.type = GRPC_ARG_POINTER;
+ arg.key = GRPC_SERVER_CREDENTIALS_ARG;
+ arg.value.pointer.p = p;
+ arg.value.pointer.copy = server_credentials_pointer_arg_copy;
+ arg.value.pointer.destroy = server_credentials_pointer_arg_destroy;
+ return arg;
+}
+
+grpc_server_credentials *grpc_server_credentials_from_arg(
+ const grpc_arg *arg) {
+ if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL;
+ if (arg->type != GRPC_ARG_POINTER) {
+ gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
+ GRPC_SERVER_CREDENTIALS_ARG);
+ return NULL;
+ }
+ return arg->value.pointer.p;
+}
+
+grpc_server_credentials *grpc_find_server_credentials_in_args(
+ const grpc_channel_args *args) {
+ size_t i;
+ if (args == NULL) return NULL;
+ for (i = 0; i < args->num_args; i++) {
+ grpc_server_credentials *p =
+ grpc_server_credentials_from_arg(&args->args[i]);
+ if (p != NULL) return p;
+ }
+ return NULL;
+}
+
/* -- Ssl credentials. -- */
static void ssl_destruct(grpc_credentials *creds) {
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index b213e052d3..01203b08f1 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -215,7 +215,6 @@ typedef struct {
grpc_server_credentials *c, grpc_security_connector **sc);
} grpc_server_credentials_vtable;
-/* TODO(jboeuf): Add a refcount. */
struct grpc_server_credentials {
const grpc_server_credentials_vtable *vtable;
const char *type;
@@ -231,6 +230,13 @@ grpc_server_credentials *grpc_server_credentials_ref(
void grpc_server_credentials_unref(grpc_server_credentials *creds);
+#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
+
+grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *c);
+grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg);
+grpc_server_credentials *grpc_find_server_credentials_in_args(
+ const grpc_channel_args *args);
+
/* -- Ssl credentials. -- */
typedef struct {
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index fb905e0b22..f544c1d943 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -305,33 +305,43 @@ void grpc_auth_property_reset(grpc_auth_property *property) {
memset(property, 0, sizeof(grpc_auth_property));
}
-grpc_arg grpc_auth_metadata_processor_to_arg(grpc_auth_metadata_processor *p) {
+static void auth_context_pointer_arg_destroy(void *p) {
+ GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
+}
+
+static void *auth_context_pointer_arg_copy(void *p) {
+ return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg");
+}
+
+grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) {
grpc_arg arg;
memset(&arg, 0, sizeof(grpc_arg));
arg.type = GRPC_ARG_POINTER;
- arg.key = GRPC_AUTH_METADATA_PROCESSOR_ARG;
+ arg.key = GRPC_AUTH_CONTEXT_ARG;
arg.value.pointer.p = p;
+ arg.value.pointer.copy = auth_context_pointer_arg_copy;
+ arg.value.pointer.destroy = auth_context_pointer_arg_destroy;
return arg;
}
-grpc_auth_metadata_processor *grpc_auth_metadata_processor_from_arg(
+grpc_auth_context *grpc_auth_context_from_arg(
const grpc_arg *arg) {
- if (strcmp(arg->key, GRPC_AUTH_METADATA_PROCESSOR_ARG) != 0) return NULL;
+ if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
- GRPC_AUTH_METADATA_PROCESSOR_ARG);
+ GRPC_AUTH_CONTEXT_ARG);
return NULL;
}
return arg->value.pointer.p;
}
-grpc_auth_metadata_processor *grpc_find_auth_metadata_processor_in_args(
+grpc_auth_context *grpc_find_auth_context_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) {
- grpc_auth_metadata_processor *p =
- grpc_auth_metadata_processor_from_arg(&args->args[i]);
+ grpc_auth_context *p =
+ grpc_auth_context_from_arg(&args->args[i]);
if (p != NULL) return p;
}
return NULL;
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index a9a0306410..2bbdc4be97 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -103,13 +103,12 @@ typedef struct {
grpc_server_security_context *grpc_server_security_context_create(void);
void grpc_server_security_context_destroy(void *ctx);
-/* --- Auth metadata processing. --- */
-#define GRPC_AUTH_METADATA_PROCESSOR_ARG "grpc.auth_metadata_processor"
+/* --- Channel args for auth context --- */
+#define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context"
-grpc_arg grpc_auth_metadata_processor_to_arg(grpc_auth_metadata_processor *p);
-grpc_auth_metadata_processor *grpc_auth_metadata_processor_from_arg(
- const grpc_arg *arg);
-grpc_auth_metadata_processor *grpc_find_auth_metadata_processor_in_args(
+grpc_arg grpc_auth_context_to_arg(grpc_auth_context *c);
+grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg);
+grpc_auth_context *grpc_find_auth_context_in_args(
const grpc_channel_args *args);
#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */
diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c
index 30ca9f57a2..2e18369fe8 100644
--- a/src/core/security/server_auth_filter.c
+++ b/src/core/security/server_auth_filter.c
@@ -34,7 +34,7 @@
#include <string.h>
#include "src/core/security/auth_filters.h"
-#include "src/core/security/security_connector.h"
+#include "src/core/security/credentials.h"
#include "src/core/security/security_context.h"
#include <grpc/support/alloc.h>
@@ -58,8 +58,8 @@ typedef struct call_data {
} call_data;
typedef struct channel_data {
- grpc_security_connector *security_connector;
- grpc_auth_metadata_processor processor;
+ grpc_auth_context *auth_context;
+ grpc_server_credentials *creds;
grpc_mdctx *mdctx;
} channel_data;
@@ -160,12 +160,12 @@ static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_stream_op *op = &ops[i];
if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue;
calld->got_client_metadata = 1;
- if (chand->processor.process == NULL) continue;
+ if (chand->creds->processor.process == NULL) continue;
calld->md_op = op;
calld->md = metadata_batch_to_md_array(&op->data.metadata);
- chand->processor.process(chand->processor.state, calld->auth_context,
- calld->md.metadata, calld->md.count,
- on_md_processing_done, elem);
+ chand->creds->processor.process(
+ chand->creds->processor.state, calld->auth_context,
+ calld->md.metadata, calld->md.count, on_md_processing_done, elem);
return;
}
}
@@ -221,7 +221,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
}
server_ctx = grpc_server_security_context_create();
server_ctx->auth_context =
- grpc_auth_context_create(chand->security_connector->auth_context);
+ grpc_auth_context_create(chand->auth_context);
server_ctx->auth_context->pollset = initial_op->bind_pollset;
initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx;
initial_op->context[GRPC_CONTEXT_SECURITY].destroy =
@@ -241,9 +241,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem, grpc_channel *master,
const grpc_channel_args *args, grpc_mdctx *mdctx,
int is_first, int is_last) {
- grpc_security_connector *sc = grpc_find_security_connector_in_args(args);
- grpc_auth_metadata_processor *processor =
- grpc_find_auth_metadata_processor_in_args(args);
+ grpc_auth_context *auth_context = grpc_find_auth_context_in_args(args);
+ grpc_server_credentials *creds = grpc_find_server_credentials_in_args(args);
/* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data;
@@ -252,15 +251,14 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
path */
GPR_ASSERT(!is_first);
GPR_ASSERT(!is_last);
- GPR_ASSERT(sc != NULL);
- GPR_ASSERT(processor != NULL);
+ GPR_ASSERT(auth_context != NULL);
+ GPR_ASSERT(creds != NULL);
/* initialize members */
- GPR_ASSERT(!sc->is_client_side);
- chand->security_connector =
- GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter");
+ chand->auth_context =
+ GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
+ chand->creds = grpc_server_credentials_ref(creds);
chand->mdctx = mdctx;
- chand->processor = *processor;
}
/* Destructor for channel data */
@@ -268,8 +266,8 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data;
- GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector,
- "server_auth_filter");
+ GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
+ grpc_server_credentials_unref(chand->creds);
}
const grpc_channel_filter grpc_server_auth_filter = {
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 881e44a3fe..82c639e830 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -93,9 +93,9 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
grpc_server_secure_state *state = statep;
grpc_channel_args *args_copy;
grpc_arg args_to_add[2];
- args_to_add[0] = grpc_security_connector_to_arg(state->sc);
+ args_to_add[0] = grpc_server_credentials_to_arg(state->creds);
args_to_add[1] =
- grpc_auth_metadata_processor_to_arg(&state->creds->processor);
+ grpc_auth_context_to_arg(state->sc->auth_context);
args_copy = grpc_channel_args_copy_and_add(
grpc_server_get_channel_args(state->server), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
diff --git a/src/core/surface/byte_buffer.c b/src/core/surface/byte_buffer.c
index 295ef5ab0e..fb39c4531d 100644
--- a/src/core/surface/byte_buffer.c
+++ b/src/core/surface/byte_buffer.c
@@ -75,9 +75,7 @@ grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) {
return grpc_raw_byte_buffer_create(bb->data.raw.slice_buffer.slices,
bb->data.raw.slice_buffer.count);
}
- gpr_log(GPR_INFO, "should never get here");
- abort();
- return NULL;
+ GPR_UNREACHABLE_CODE(return NULL);
}
void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
@@ -95,7 +93,5 @@ size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
case GRPC_BB_RAW:
return bb->data.raw.slice_buffer.length;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- return 0;
+ GPR_UNREACHABLE_CODE(return 0);
}
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 9efcb90a56..b40e74d61b 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -436,8 +436,7 @@ static grpc_cq_completion *allocate_completion(grpc_call *call) {
gpr_mu_unlock(&call->completion_mu);
return &call->completions[i];
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return NULL);
return NULL;
}
@@ -531,9 +530,13 @@ static void set_compression_algorithm(grpc_call *call,
call->compression_algorithm = algo;
}
-grpc_compression_algorithm grpc_call_get_compression_algorithm(
- const grpc_call *call) {
- return call->compression_algorithm;
+grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
+ grpc_call *call) {
+ grpc_compression_algorithm algorithm;
+ gpr_mu_lock(&call->mu);
+ algorithm = call->compression_algorithm;
+ gpr_mu_unlock(&call->mu);
+ return algorithm;
}
static void set_encodings_accepted_by_peer(
@@ -567,12 +570,20 @@ static void set_encodings_accepted_by_peer(
}
}
-gpr_uint32 grpc_call_get_encodings_accepted_by_peer(grpc_call *call) {
- return call->encodings_accepted_by_peer;
+gpr_uint32 grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
+ gpr_uint32 encodings_accepted_by_peer;
+ gpr_mu_lock(&call->mu);
+ encodings_accepted_by_peer = call->encodings_accepted_by_peer;
+ gpr_mu_unlock(&call->mu);
+ return encodings_accepted_by_peer;
}
-gpr_uint32 grpc_call_get_message_flags(const grpc_call *call) {
- return call->incoming_message_flags;
+gpr_uint32 grpc_call_test_only_get_message_flags(grpc_call *call) {
+ gpr_uint32 flags;
+ gpr_mu_lock(&call->mu);
+ flags = call->incoming_message_flags;
+ gpr_mu_unlock(&call->mu);
+ return flags;
}
static void set_status_details(grpc_call *call, status_source source,
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index f421a81619..9b7c6f9bfb 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -169,17 +169,6 @@ void *grpc_call_context_get(grpc_call *call, grpc_context_index elem);
gpr_uint8 grpc_call_is_client(grpc_call *call);
-grpc_compression_algorithm grpc_call_get_compression_algorithm(
- const grpc_call *call);
-
-gpr_uint32 grpc_call_get_message_flags(const grpc_call *call);
-
-/** Returns a bitset for the encodings (compression algorithms) supported by \a
- * call's peer.
- *
- * To be indexed by grpc_compression_algorithm enum values. */
-gpr_uint32 grpc_call_get_encodings_accepted_by_peer(grpc_call *call);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/core/surface/call_test_only.h b/src/core/surface/call_test_only.h
new file mode 100644
index 0000000000..df4be3248b
--- /dev/null
+++ b/src/core/surface/call_test_only.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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_CORE_SURFACE_CALL_TEST_ONLY_H
+#define GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H
+
+#include <grpc/grpc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Return the compression algorithm from \a call.
+ *
+ * \warning This function should \b only be used in test code. */
+grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
+ grpc_call *call);
+
+/** Return the message flags from \a call.
+ *
+ * \warning This function should \b only be used in test code. */
+gpr_uint32 grpc_call_test_only_get_message_flags(grpc_call *call);
+
+/** Returns a bitset for the encodings (compression algorithms) supported by \a
+ * call's peer.
+ *
+ * To be indexed by grpc_compression_algorithm enum values. */
+gpr_uint32 grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H */
diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c
index f72fb04142..ca3c02c536 100644
--- a/src/core/surface/channel_connectivity.c
+++ b/src/core/surface/channel_connectivity.c
@@ -100,9 +100,7 @@ static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw,
switch (w->phase) {
case WAITING:
case CALLED_BACK:
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- break;
+ GPR_UNREACHABLE_CODE(return );
case CALLING_BACK:
w->phase = CALLED_BACK;
break;
@@ -149,9 +147,7 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
w->phase = CALLING_BACK_AND_FINISHED;
break;
case CALLING_BACK_AND_FINISHED:
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- break;
+ GPR_UNREACHABLE_CODE(return );
case CALLED_BACK:
delete = 1;
break;
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index bc32f55473..bcdb363873 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -264,8 +264,7 @@ static void del_plucker(grpc_completion_queue *cc, void *tag,
return;
}
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return );
}
grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
index acfa7c002e..07179a4571 100644
--- a/src/core/transport/chttp2/frame_data.c
+++ b/src/core/transport/chttp2/frame_data.c
@@ -168,7 +168,5 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
}
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- return GRPC_CHTTP2_CONNECTION_ERROR;
+ GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR);
}
diff --git a/src/core/transport/chttp2/frame_goaway.c b/src/core/transport/chttp2/frame_goaway.c
index 2ff1eda89b..c5758bcb71 100644
--- a/src/core/transport/chttp2/frame_goaway.c
+++ b/src/core/transport/chttp2/frame_goaway.c
@@ -152,9 +152,7 @@ grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse(
}
return GRPC_CHTTP2_PARSE_OK;
}
- gpr_log(GPR_ERROR, "Should never end up here");
- abort();
- return GRPC_CHTTP2_CONNECTION_ERROR;
+ GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR);
}
void grpc_chttp2_goaway_append(gpr_uint32 last_stream_id, gpr_uint32 error_code,
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index 20ea513375..20d8312d54 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -1166,9 +1166,7 @@ static int append_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
append_bytes(str, decoded, 3);
goto b64_byte0;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- return 1;
+ GPR_UNREACHABLE_CODE(return 1);
}
/* append a null terminator to a string */
@@ -1313,9 +1311,7 @@ static int parse_value_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
return 0;
}
/* Add code to prevent return without value error */
- gpr_log(GPR_ERROR, "Should never reach beyond switch in parse_value_string");
- abort();
- return 0;
+ GPR_UNREACHABLE_CODE(return 0);
}
static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p,
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 04e4803227..5d4d8e70c4 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -422,14 +422,10 @@ int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
transport_parsing->incoming_frame_size -= (gpr_uint32)(end - cur);
return 1;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return 0);
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
-
- return 0;
+ GPR_UNREACHABLE_CODE(return 0);
}
static int init_frame_parser(grpc_chttp2_transport_parsing *transport_parsing) {
@@ -585,9 +581,7 @@ static int init_data_frame_parser(
case GRPC_CHTTP2_CONNECTION_ERROR:
return 0;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- return 0;
+ GPR_UNREACHABLE_CODE(return 0);
}
static void free_timeout(void *p) { gpr_free(p); }
@@ -825,7 +819,5 @@ static int parse_frame_slice(grpc_exec_ctx *exec_ctx,
case GRPC_CHTTP2_CONNECTION_ERROR:
return 0;
}
- gpr_log(GPR_ERROR, "should never reach here");
- abort();
- return 0;
+ GPR_UNREACHABLE_CODE(return 0);
}
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 83227e677d..6c7f7a9ea7 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -428,7 +428,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
return elem;
}
- abort();
+ GPR_UNREACHABLE_CODE(return NULL);
}
indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)];
@@ -442,7 +442,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
return elem;
}
- abort();
+ GPR_UNREACHABLE_CODE(return NULL);
}
/* no elem, key in the table... fall back to literal emission */
@@ -454,7 +454,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
emit_lithdr_noidx_v(c, elem, st);
return elem;
}
- abort();
+ GPR_UNREACHABLE_CODE(return NULL);
}
#define STRLEN_LIT(x) (sizeof(x) - 1)
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index aacc5c7387..f5063a079e 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -153,8 +153,7 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
GPR_ASSERT((*req)->in_flight_);
return true;
}
- gpr_log(GPR_ERROR, "Should never reach here");
- abort();
+ GPR_UNREACHABLE_CODE(return false);
}
void SetupRequest() { cq_ = grpc_completion_queue_create(nullptr); }
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index 14cc6c0efe..cb55083d1a 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -44,12 +44,14 @@ var GoogleAuth = require('google-auth-library');
var assert = require('assert');
-var AUTH_SCOPE = 'https://www.googleapis.com/auth/xapi.zoo';
-var AUTH_SCOPE_RESPONSE = 'xapi.zoo';
-var AUTH_USER = ('155450119199-vefjjaekcc6cmsd5914v6lqufunmh9ue' +
- '@developer.gserviceaccount.com');
-var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' +
- '@developer.gserviceaccount.com');
+var SERVICE_ACCOUNT_EMAIL;
+try {
+ SERVICE_ACCOUNT_EMAIL = require(
+ process.env.GOOGLE_APPLICATION_CREDENTIALS).client_email;
+} catch (e) {
+ // This will cause the tests to fail if they need that string
+ SERVICE_ACCOUNT_EMAIL = null;
+}
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
@@ -345,6 +347,41 @@ function customMetadata(client, done) {
stream.end();
}
+function statusCodeAndMessage(client, done) {
+ done = multiDone(done, 2);
+ var arg = {
+ response_status: {
+ code: 2,
+ message: 'test status message'
+ }
+ };
+ client.unaryCall(arg, function(err, resp) {
+ assert(err);
+ assert.strictEqual(err.code, 2);
+ assert.strictEqual(err.message, 'test status message');
+ done();
+ });
+ var duplex = client.fullDuplexCall();
+ duplex.on('status', function(status) {
+ assert(status);
+ assert.strictEqual(status.code, 2);
+ assert.strictEqual(status.details, 'test status message');
+ done();
+ });
+ duplex.on('error', function(){});
+ duplex.write(arg);
+ duplex.end();
+}
+
+function unimplementedMethod(client, done) {
+ client.unimplementedCall({}, function(err, resp) {
+ assert(err);
+ assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
+ assert(!err.message);
+ done();
+ });
+}
+
/**
* Run one of the authentication tests.
* @param {string} expected_user The expected username in the response
@@ -369,7 +406,7 @@ function authTest(expected_user, scope, client, done) {
assert.strictEqual(resp.payload.body.length, 314159);
assert.strictEqual(resp.username, expected_user);
if (scope) {
- assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
+ assert(scope.indexOf(resp.oauth_scope) > -1);
}
if (done) {
done();
@@ -377,56 +414,49 @@ function authTest(expected_user, scope, client, done) {
});
}
-function oauth2Test(expected_user, scope, per_rpc, client, done) {
- (new GoogleAuth()).getApplicationDefault(function(err, credential) {
+function computeEngineCreds(client, done, extra) {
+ authTest(extra.service_account, null, client, done);
+}
+
+function serviceAccountCreds(client, done, extra) {
+ authTest(SERVICE_ACCOUNT_EMAIL, extra.oauth_scope, client, done);
+}
+
+function jwtTokenCreds(client, done, extra) {
+ authTest(SERVICE_ACCOUNT_EMAIL, null, client, done);
+}
+
+function oauth2Test(client, done, extra) {
+ var arg = {
+ fill_username: true,
+ fill_oauth_scope: true
+ };
+ client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
- var arg = {
- fill_username: true,
- fill_oauth_scope: true
- };
- credential = credential.createScoped(scope);
- credential.getAccessToken(function(err, token) {
- assert.ifError(err);
- var updateMetadata = function(authURI, metadata, callback) {
- metadata.add('authorization', 'Bearer ' + token);
- callback(null, metadata);
- };
- var makeTestCall = function(error, client_metadata) {
- assert.ifError(error);
- client.unaryCall(arg, function(err, resp) {
- assert.ifError(err);
- assert.strictEqual(resp.username, expected_user);
- assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
- if (done) {
- done();
- }
- }, client_metadata);
- };
- if (per_rpc) {
- updateMetadata('', new grpc.Metadata(), makeTestCall);
- } else {
- client.$updateMetadata = updateMetadata;
- makeTestCall(null, new grpc.Metadata());
- }
- });
+ assert.strictEqual(resp.username, SERVICE_ACCOUNT_EMAIL);
+ assert(extra.oauth_scope.indexOf(resp.oauth_scope) > -1);
+ if (done) {
+ done();
+ }
});
}
-function perRpcAuthTest(expected_user, scope, per_rpc, client, done) {
+function perRpcAuthTest(client, done, extra) {
(new GoogleAuth()).getApplicationDefault(function(err, credential) {
assert.ifError(err);
var arg = {
fill_username: true,
fill_oauth_scope: true
};
+ var scope = extra.oauth_scope;
if (credential.createScopedRequired() && scope) {
credential = credential.createScoped(scope);
}
var creds = grpc.credentials.createFromGoogleCredential(credential);
client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
- assert.strictEqual(resp.username, expected_user);
- assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
+ assert.strictEqual(resp.username, SERVICE_ACCOUNT_EMAIL);
+ assert(extra.oauth_scope.indexOf(resp.oauth_scope) > -1);
if (done) {
done();
}
@@ -473,25 +503,44 @@ function getOauth2Creds(scope, callback) {
* Map from test case names to test functions
*/
var test_cases = {
- empty_unary: {run: emptyUnary},
- large_unary: {run: largeUnary},
- client_streaming: {run: clientStreaming},
- server_streaming: {run: serverStreaming},
- ping_pong: {run: pingPong},
- empty_stream: {run: emptyStream},
- cancel_after_begin: {run: cancelAfterBegin},
- cancel_after_first_response: {run: cancelAfterFirstResponse},
- timeout_on_sleeping_server: {run: timeoutOnSleepingServer},
- custom_metadata: {run: customMetadata},
- compute_engine_creds: {run: _.partial(authTest, COMPUTE_ENGINE_USER, null),
- getCreds: _.partial(getApplicationCreds, null)},
- service_account_creds: {run: _.partial(authTest, AUTH_USER, AUTH_SCOPE),
- getCreds: _.partial(getApplicationCreds, AUTH_SCOPE)},
- jwt_token_creds: {run: _.partial(authTest, AUTH_USER, null),
- getCreds: _.partial(getApplicationCreds, null)},
- oauth2_auth_token: {run: _.partial(oauth2Test, AUTH_USER, AUTH_SCOPE, false),
- getCreds: _.partial(getOauth2Creds, AUTH_SCOPE)},
- per_rpc_creds: {run: _.partial(perRpcAuthTest, AUTH_USER, AUTH_SCOPE, true)}
+ empty_unary: {run: emptyUnary,
+ Client: testProto.TestService},
+ large_unary: {run: largeUnary,
+ Client: testProto.TestService},
+ client_streaming: {run: clientStreaming,
+ Client: testProto.TestService},
+ server_streaming: {run: serverStreaming,
+ Client: testProto.TestService},
+ ping_pong: {run: pingPong,
+ Client: testProto.TestService},
+ empty_stream: {run: emptyStream,
+ Client: testProto.TestService},
+ cancel_after_begin: {run: cancelAfterBegin,
+ Client: testProto.TestService},
+ cancel_after_first_response: {run: cancelAfterFirstResponse,
+ Client: testProto.TestService},
+ timeout_on_sleeping_server: {run: timeoutOnSleepingServer,
+ Client: testProto.TestService},
+ custom_metadata: {run: customMetadata,
+ Client: testProto.TestService},
+ status_code_and_message: {run: statusCodeAndMessage,
+ Client: testProto.TestService},
+ unimplemented_method: {run: unimplementedMethod,
+ Client: testProto.UnimplementedService},
+ compute_engine_creds: {run: computeEngineCreds,
+ Client: testProto.TestService,
+ getCreds: getApplicationCreds},
+ service_account_creds: {run: serviceAccountCreds,
+ Client: testProto.TestService,
+ getCreds: getApplicationCreds},
+ jwt_token_creds: {run: jwtTokenCreds,
+ Client: testProto.TestService,
+ getCreds: getApplicationCreds},
+ oauth2_auth_token: {run: oauth2Test,
+ Client: testProto.TestService,
+ getCreds: getOauth2Creds},
+ per_rpc_creds: {run: perRpcAuthTest,
+ Client: testProto.TestService}
};
/**
@@ -504,8 +553,9 @@ var test_cases = {
* @param {bool} tls Indicates that a secure channel should be used
* @param {function} done Callback to call when the test is completed. Included
* primarily for use with mocha
+ * @param {object=} extra Extra options for some tests
*/
-function runTest(address, host_override, test_case, tls, test_ca, done) {
+function runTest(address, host_override, test_case, tls, test_ca, done, extra) {
// TODO(mlumish): enable TLS functionality
var options = {};
var creds;
@@ -529,12 +579,13 @@ function runTest(address, host_override, test_case, tls, test_ca, done) {
var execute = function(err, creds) {
assert.ifError(err);
- var client = new testProto.TestService(address, creds, options);
- test.run(client, done);
+ var client = new test.Client(address, creds, options);
+ test.run(client, done, extra);
};
if (test.getCreds) {
- test.getCreds(function(err, new_creds) {
+ test.getCreds(extra.oauth_scope, function(err, new_creds) {
+ assert.ifError(err);
execute(err, grpc.credentials.combineChannelCredentials(
creds, new_creds));
});
@@ -547,13 +598,18 @@ if (require.main === module) {
var parseArgs = require('minimist');
var argv = parseArgs(process.argv, {
string: ['server_host', 'server_host_override', 'server_port', 'test_case',
- 'use_tls', 'use_test_ca']
+ 'use_tls', 'use_test_ca', 'default_service_account', 'oauth_scope',
+ 'service_account_key_file']
});
+ var extra_args = {
+ service_account: argv.default_service_account,
+ oauth_scope: argv.oauth_scope
+ };
runTest(argv.server_host + ':' + argv.server_port, argv.server_host_override,
argv.test_case, argv.use_tls === 'true', argv.use_test_ca === 'true',
function () {
console.log('OK:', argv.test_case);
- });
+ }, extra_args);
}
/**
diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js
index 3e83304faa..5321005c86 100644
--- a/src/node/interop/interop_server.js
+++ b/src/node/interop/interop_server.js
@@ -44,6 +44,9 @@ var testProto = grpc.load({
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
+var incompressible_data = fs.readFileSync(
+ __dirname + '/../../../test/cpp/interop/rnd.dat');
+
/**
* Create a buffer filled with size zeroes
* @param {number} size The length of the buffer
@@ -83,6 +86,19 @@ function getEchoTrailer(call) {
return response_trailer;
}
+function getPayload(payload_type, size) {
+ if (payload_type === 'RANDOM') {
+ payload_type = ['COMPRESSABLE',
+ 'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
+ }
+ var body;
+ switch (payload_type) {
+ case 'COMPRESSABLE': body = zeroBuffer(size); break;
+ case 'UNCOMPRESSABLE': incompressible_data.slice(size); break;
+ }
+ return {type: payload_type, body: body};
+}
+
/**
* Respond to an empty parameter with an empty response.
* NOTE: this currently does not work due to issue #137
@@ -104,13 +120,14 @@ function handleEmpty(call, callback) {
function handleUnary(call, callback) {
echoHeader(call);
var req = call.request;
- var zeros = zeroBuffer(req.response_size);
- var payload_type = req.response_type;
- if (payload_type === 'RANDOM') {
- payload_type = ['COMPRESSABLE',
- 'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
+ if (req.response_status) {
+ var status = req.response_status;
+ status.metadata = getEchoTrailer(call);
+ callback(status);
+ return;
}
- callback(null, {payload: {type: payload_type, body: zeros}},
+ var payload = getPayload(req.response_type, req.response_size);
+ callback(null, {payload: payload},
getEchoTrailer(call));
}
@@ -139,18 +156,14 @@ function handleStreamingInput(call, callback) {
function handleStreamingOutput(call) {
echoHeader(call);
var req = call.request;
- var payload_type = req.response_type;
- if (payload_type === 'RANDOM') {
- payload_type = ['COMPRESSABLE',
- 'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
+ if (req.response_status) {
+ var status = req.response_status;
+ status.metadata = getEchoTrailer(call);
+ call.emit('error', status);
+ return;
}
_.each(req.response_parameters, function(resp_param) {
- call.write({
- payload: {
- body: zeroBuffer(resp_param.size),
- type: payload_type
- }
- });
+ call.write({payload: getPayload(req.response_type, resp_param.size)});
});
call.end(getEchoTrailer(call));
}
@@ -163,18 +176,14 @@ function handleStreamingOutput(call) {
function handleFullDuplex(call) {
echoHeader(call);
call.on('data', function(value) {
- var payload_type = value.response_type;
- if (payload_type === 'RANDOM') {
- payload_type = ['COMPRESSABLE',
- 'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
+ if (value.response_status) {
+ var status = value.response_status;
+ status.metadata = getEchoTrailer(call);
+ call.emit('error', status);
+ return;
}
_.each(value.response_parameters, function(resp_param) {
- call.write({
- payload: {
- body: zeroBuffer(resp_param.size),
- type: payload_type
- }
- });
+ call.write({payload: getPayload(value.response_type, resp_param.size)});
});
});
call.on('end', function() {
@@ -188,7 +197,7 @@ function handleFullDuplex(call) {
* @param {Call} call Call to handle
*/
function handleHalfDuplex(call) {
- throw new Error('HalfDuplexCall not yet implemented');
+ call.emit('error', Error('HalfDuplexCall not yet implemented'));
}
/**
diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js
index 009ff63306..ddc094f896 100644
--- a/src/node/src/credentials.js
+++ b/src/node/src/credentials.js
@@ -153,7 +153,7 @@ exports.combineCallCredentials = function() {
current = current.compose(arguments[i]);
}
return current;
-}
+};
/**
* Create an insecure credentials object. This is used to create a channel that
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 87b5b7ad06..a974d593c9 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -629,7 +629,7 @@ function Server(options) {
(new Metadata())._getCoreRepresentation();
batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
code: grpc.status.UNIMPLEMENTED,
- details: 'This method is not available on this server.',
+ details: '',
metadata: {}
};
batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
diff --git a/src/node/test/async_test.js b/src/node/test/async_test.js
index ce3ce50a2d..6d71ea24f5 100644
--- a/src/node/test/async_test.js
+++ b/src/node/test/async_test.js
@@ -57,7 +57,7 @@ describe('Async functionality', function() {
grpc.ServerCredentials.createInsecure());
server.start();
math_client = new math.Math('localhost:' + port_num,
- grpc.Credentials.createInsecure());
+ grpc.credentials.createInsecure());
done();
});
after(function() {
diff --git a/src/node/test/channel_test.js b/src/node/test/channel_test.js
index b86f89b8a8..05269f7b6e 100644
--- a/src/node/test/channel_test.js
+++ b/src/node/test/channel_test.js
@@ -149,7 +149,7 @@ describe('channel', function() {
afterEach(function() {
channel.close();
});
- it.only('should time out if called alone', function(done) {
+ it('should time out if called alone', function(done) {
var old_state = channel.getConnectivityState();
var deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1);
diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js
index 8eb91ee69e..7fc311a888 100644
--- a/src/node/test/credentials_test.js
+++ b/src/node/test/credentials_test.js
@@ -130,8 +130,8 @@ describe('client credentials', function() {
callback(null, metadata);
};
var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater);
- var combined_creds = grpc.credentials.combineCredentials(client_ssl_creds,
- creds);
+ var combined_creds = grpc.credentials.combineChannelCredentials(
+ client_ssl_creds, creds);
var client = new Client('localhost:' + port, combined_creds,
client_options);
var call = client.unary({}, function(err, data) {
@@ -150,8 +150,8 @@ describe('client credentials', function() {
callback(null, metadata);
};
var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater);
- var combined_creds = grpc.credentials.combineCredentials(client_ssl_creds,
- creds);
+ var combined_creds = grpc.credentials.combineChannelCredentials(
+ client_ssl_creds, creds);
var client = new Client('localhost:' + port, combined_creds,
client_options);
var call = client.unary({}, function(err, data) {
@@ -231,7 +231,7 @@ describe('client credentials', function() {
updater_creds, alt_updater_creds);
var call = client.unary({}, function(err, data) {
assert.ifError(err);
- }, null, {credentials: updater_creds});
+ }, null, {credentials: combined_updater});
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
assert.deepEqual(metadata.get('other_plugin_key'),
diff --git a/src/node/test/interop_sanity_test.js b/src/node/test/interop_sanity_test.js
index 804c1d45e4..f8c0b14137 100644
--- a/src/node/test/interop_sanity_test.js
+++ b/src/node/test/interop_sanity_test.js
@@ -71,7 +71,7 @@ describe('Interop tests', function() {
interop_client.runTest(port, name_override, 'server_streaming', true, true,
done);
});
- it('should pass ping_pong', function(done) {
+ it.only('should pass ping_pong', function(done) {
interop_client.runTest(port, name_override, 'ping_pong', true, true, done);
});
it('should pass empty_stream', function(done) {
@@ -94,4 +94,12 @@ describe('Interop tests', function() {
interop_client.runTest(port, name_override, 'custom_metadata',
true, true, done);
});
+ it('should pass status_code_and_message', function(done) {
+ interop_client.runTest(port, name_override, 'status_code_and_message',
+ true, true, done);
+ });
+ it('should pass unimplemented_method', function(done) {
+ interop_client.runTest(port, name_override, 'unimplemented_method',
+ true, true, done);
+ });
});
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index d55d5629b7..0590264ef8 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -251,6 +251,23 @@ function pingPong($stub) {
}
/**
+ * Run the empty_stream test.
+ * Passes when run against the Node server as of 2015-10-09
+ * @param $stub Stub object that has service methods.
+ */
+function emptyStream($stub) {
+ // for the current PHP implementation, $call->read() will wait
+ // forever for a server response if the server is not sending any.
+ // so this test is imeplemented as a timeout to indicate the absence
+ // of receiving any response from the server
+ $call = $stub->FullDuplexCall(array('timeout' => 100000));
+ $call->writesDone();
+ hardAssert($call->read() === null, 'Server returned too many responses');
+ hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
+ 'Call did not complete successfully');
+}
+
+/**
* Run the cancel_after_begin test.
* Passes when run against the Node server as of 2015-08-28
* @param $stub Stub object that has service methods.
@@ -370,6 +387,9 @@ switch ($args['test_case']) {
case 'ping_pong':
pingPong($stub);
break;
+ case 'empty_stream':
+ emptyStream($stub);
+ break;
case 'cancel_after_begin':
cancelAfterBegin($stub);
break;