Completes merge

pull/227/head
Tim Emiola 10 years ago
commit 2b90e305ec
  1. 5
      examples/tips/client.h
  2. 17
      examples/tips/client_main.cc
  3. 96
      src/core/channel/call_op_string.c
  4. 1
      src/core/channel/connected_channel.c
  5. 82
      src/core/httpcli/format_request.c
  6. 48
      src/core/support/string.c
  7. 21
      src/core/support/string.h
  8. 80
      src/core/surface/event_string.c
  9. 14
      src/node/client.js
  10. 7
      src/node/examples/math_server.js
  11. 2
      src/node/interop/interop_client.js
  12. 5
      src/node/server.js
  13. 132
      src/node/surface_client.js
  14. 145
      src/node/surface_server.js
  15. 28
      src/node/test/client_server_test.js
  16. 5
      src/node/test/interop_sanity_test.js
  17. 53
      src/node/test/surface_test.js
  18. 27
      src/ruby/README.md
  19. 96
      src/ruby/spec/client_server_spec.rb
  20. 9
      test/core/channel/metadata_buffer_test.c
  21. 126
      test/core/end2end/cq_verifier.c
  22. 6
      test/core/end2end/tests/census_simple_request.c
  23. 6
      test/core/end2end/tests/simple_request.c
  24. 6
      test/core/security/credentials_test.c
  25. 7
      test/core/statistics/hash_table_test.c
  26. 21
      test/core/transport/chttp2/hpack_table_test.c
  27. 17
      test/core/transport/chttp2/stream_encoder_test.c
  28. 19
      test/core/transport/chttp2/timeout_encoding_test.c
  29. 19
      test/core/transport/metadata_test.c
  30. 9
      tools/clang-format/clang-format-all.sh
  31. 11
      tools/clang-format/config.sh
  32. 5
      tools/dockerfile/grpc_java/Dockerfile
  33. 18
      tools/dockerfile/grpc_java_base/Dockerfile
  34. 4
      tools/gce_setup/grpc_docker.sh
  35. 7
      tools/run_tests/build_node.sh
  36. 8
      tools/run_tests/build_php.sh
  37. 10
      tools/run_tests/run_node.sh
  38. 24
      tools/run_tests/run_tests.py

@ -31,6 +31,9 @@
*
*/
#ifndef __GRPCPP_EXAMPLES_TIPS_CLIENT_H_
#define __GRPCPP_EXAMPLES_TIPS_CLIENT_H_
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
@ -52,3 +55,5 @@ class Client {
} // namespace tips
} // namespace examples
} // namespace grpc
#endif // __GRPCPP_EXAMPLES_TIPS_CLIENT_H_

@ -41,30 +41,29 @@
#include "examples/tips/client.h"
#include "test/cpp/util/create_test_channel.h"
DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls.");
DEFINE_bool(use_prod_roots, true, "True to use SSL roots for production GFE");
DEFINE_int32(server_port, 0, "Server port.");
DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
DEFINE_string(server_host_override, "foo.test.google.com",
"Override the server host which is sent in HTTP header");
DEFINE_int32(server_port, 443, "Server port.");
DEFINE_string(server_host,
"pubsub-staging.googleapis.com", "Server host to connect to");
int main(int argc, char** argv) {
grpc_init();
google::ParseCommandLineFlags(&argc, &argv, true);
gpr_log(GPR_INFO, "Start TIPS client");
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);
std::shared_ptr<grpc::ChannelInterface> channel(
grpc::CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots));
grpc::CreateTestChannel(host_port,
FLAGS_server_host,
true, // enable SSL
true)); // use prod roots
grpc::examples::tips::Client client(channel);
grpc::Status s = client.CreateTopic("test");
gpr_log(GPR_INFO, "return code %d", s.code());
GPR_ASSERT(s.IsOk());
channel.reset();

@ -41,110 +41,86 @@
#include <grpc/support/alloc.h>
#include <grpc/support/useful.h>
#define MAX_APPEND 1024
static void put_metadata(gpr_strvec *b, grpc_mdelem *md) {
gpr_strvec_add(b, gpr_strdup(" key="));
gpr_strvec_add(b, gpr_hexdump((char *)GPR_SLICE_START_PTR(md->key->slice),
GPR_SLICE_LENGTH(md->key->slice), GPR_HEXDUMP_PLAINTEXT));
typedef struct {
size_t cap;
size_t len;
char *buffer;
} buf;
static void bprintf(buf *b, const char *fmt, ...) {
va_list arg;
if (b->len + MAX_APPEND > b->cap) {
b->cap = GPR_MAX(b->len + MAX_APPEND, b->cap * 3 / 2);
b->buffer = gpr_realloc(b->buffer, b->cap);
}
va_start(arg, fmt);
b->len += vsprintf(b->buffer + b->len, fmt, arg);
va_end(arg);
}
static void bputs(buf *b, const char *s) {
size_t slen = strlen(s);
if (b->len + slen + 1 > b->cap) {
b->cap = GPR_MAX(b->len + slen + 1, b->cap * 3 / 2);
b->buffer = gpr_realloc(b->buffer, b->cap);
}
strcat(b->buffer, s);
b->len += slen;
}
static void put_metadata(buf *b, grpc_mdelem *md) {
char *txt;
txt = gpr_hexdump((char *)GPR_SLICE_START_PTR(md->key->slice),
GPR_SLICE_LENGTH(md->key->slice), GPR_HEXDUMP_PLAINTEXT);
bputs(b, " key=");
bputs(b, txt);
gpr_free(txt);
txt = gpr_hexdump((char *)GPR_SLICE_START_PTR(md->value->slice),
GPR_SLICE_LENGTH(md->value->slice), GPR_HEXDUMP_PLAINTEXT);
bputs(b, " value=");
bputs(b, txt);
gpr_free(txt);
gpr_strvec_add(b, gpr_strdup(" value="));
gpr_strvec_add(b, gpr_hexdump((char *)GPR_SLICE_START_PTR(md->value->slice),
GPR_SLICE_LENGTH(md->value->slice), GPR_HEXDUMP_PLAINTEXT));
}
char *grpc_call_op_string(grpc_call_op *op) {
buf b = {0, 0, 0};
char *tmp;
char *out;
gpr_strvec b;
gpr_strvec_init(&b);
switch (op->dir) {
case GRPC_CALL_DOWN:
bprintf(&b, ">");
gpr_strvec_add(&b, gpr_strdup(">"));
break;
case GRPC_CALL_UP:
bprintf(&b, "<");
gpr_strvec_add(&b, gpr_strdup("<"));
break;
}
switch (op->type) {
case GRPC_SEND_METADATA:
bprintf(&b, "SEND_METADATA");
gpr_strvec_add(&b, gpr_strdup("SEND_METADATA"));
put_metadata(&b, op->data.metadata);
break;
case GRPC_SEND_DEADLINE:
bprintf(&b, "SEND_DEADLINE %d.%09d", op->data.deadline.tv_sec,
gpr_asprintf(&tmp, "SEND_DEADLINE %d.%09d", op->data.deadline.tv_sec,
op->data.deadline.tv_nsec);
gpr_strvec_add(&b, tmp);
break;
case GRPC_SEND_START:
bprintf(&b, "SEND_START pollset=%p", op->data.start.pollset);
gpr_asprintf(&tmp, "SEND_START pollset=%p", op->data.start.pollset);
gpr_strvec_add(&b, tmp);
break;
case GRPC_SEND_MESSAGE:
bprintf(&b, "SEND_MESSAGE");
gpr_strvec_add(&b, gpr_strdup("SEND_MESSAGE"));
break;
case GRPC_SEND_FINISH:
bprintf(&b, "SEND_FINISH");
gpr_strvec_add(&b, gpr_strdup("SEND_FINISH"));
break;
case GRPC_REQUEST_DATA:
bprintf(&b, "REQUEST_DATA");
gpr_strvec_add(&b, gpr_strdup("REQUEST_DATA"));
break;
case GRPC_RECV_METADATA:
bprintf(&b, "RECV_METADATA");
gpr_strvec_add(&b, gpr_strdup("RECV_METADATA"));
put_metadata(&b, op->data.metadata);
break;
case GRPC_RECV_DEADLINE:
bprintf(&b, "RECV_DEADLINE %d.%09d", op->data.deadline.tv_sec,
gpr_asprintf(&tmp, "RECV_DEADLINE %d.%09d", op->data.deadline.tv_sec,
op->data.deadline.tv_nsec);
gpr_strvec_add(&b, tmp);
break;
case GRPC_RECV_END_OF_INITIAL_METADATA:
bprintf(&b, "RECV_END_OF_INITIAL_METADATA");
gpr_strvec_add(&b, gpr_strdup("RECV_END_OF_INITIAL_METADATA"));
break;
case GRPC_RECV_MESSAGE:
bprintf(&b, "RECV_MESSAGE");
gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE"));
break;
case GRPC_RECV_HALF_CLOSE:
bprintf(&b, "RECV_HALF_CLOSE");
gpr_strvec_add(&b, gpr_strdup("RECV_HALF_CLOSE"));
break;
case GRPC_RECV_FINISH:
bprintf(&b, "RECV_FINISH");
gpr_strvec_add(&b, gpr_strdup("RECV_FINISH"));
break;
case GRPC_CANCEL_OP:
bprintf(&b, "CANCEL_OP");
gpr_strvec_add(&b, gpr_strdup("CANCEL_OP"));
break;
}
bprintf(&b, " flags=0x%08x", op->flags);
gpr_asprintf(&tmp, " flags=0x%08x", op->flags);
gpr_strvec_add(&b, tmp);
out = gpr_strvec_flatten(&b, NULL);
gpr_strvec_destroy(&b);
return b.buffer;
return out;
}
void grpc_call_log_op(char *file, int line, gpr_log_severity severity,

@ -450,6 +450,7 @@ static void recv_batch(void *user_data, grpc_transport *transport,
(int)calld->incoming_message.length,
(int)calld->incoming_message_length);
recv_error(chand, calld, __LINE__, message);
gpr_free(message);
}
call_op.type = GRPC_RECV_HALF_CLOSE;
call_op.dir = GRPC_CALL_UP;

@ -37,67 +37,57 @@
#include <stdio.h>
#include <string.h>
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/slice.h>
#include <grpc/support/useful.h>
typedef struct {
size_t length;
size_t capacity;
char *data;
} sbuf;
static void sbuf_append(sbuf *buf, const char *bytes, size_t len) {
if (buf->length + len > buf->capacity) {
buf->capacity = GPR_MAX(buf->length + len, buf->capacity * 3 / 2);
buf->data = gpr_realloc(buf->data, buf->capacity);
}
memcpy(buf->data + buf->length, bytes, len);
buf->length += len;
}
static void sbprintf(sbuf *buf, const char *fmt, ...) {
char temp[GRPC_HTTPCLI_MAX_HEADER_LENGTH];
size_t len;
va_list args;
va_start(args, fmt);
len = vsprintf(temp, fmt, args);
va_end(args);
sbuf_append(buf, temp, len);
}
static void fill_common_header(const grpc_httpcli_request *request, sbuf *buf) {
static void fill_common_header(const grpc_httpcli_request *request, gpr_strvec *buf) {
size_t i;
sbprintf(buf, "%s HTTP/1.0\r\n", request->path);
gpr_strvec_add(buf, gpr_strdup(request->path));
gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n"));
/* just in case some crazy server really expects HTTP/1.1 */
sbprintf(buf, "Host: %s\r\n", request->host);
sbprintf(buf, "Connection: close\r\n");
sbprintf(buf, "User-Agent: %s\r\n", GRPC_HTTPCLI_USER_AGENT);
gpr_strvec_add(buf, gpr_strdup("Host: "));
gpr_strvec_add(buf, gpr_strdup(request->host));
gpr_strvec_add(buf, gpr_strdup("\r\n"));
gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n"));
gpr_strvec_add(buf, gpr_strdup("User-Agent: "GRPC_HTTPCLI_USER_AGENT"\r\n"));
/* user supplied headers */
for (i = 0; i < request->hdr_count; i++) {
sbprintf(buf, "%s: %s\r\n", request->hdrs[i].key, request->hdrs[i].value);
gpr_strvec_add(buf, gpr_strdup(request->hdrs[i].key));
gpr_strvec_add(buf, gpr_strdup(": "));
gpr_strvec_add(buf, gpr_strdup(request->hdrs[i].value));
gpr_strvec_add(buf, gpr_strdup("\r\n"));
}
}
gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) {
sbuf out = {0, 0, NULL};
gpr_strvec out;
char *flat;
size_t flat_len;
sbprintf(&out, "GET ");
gpr_strvec_init(&out);
gpr_strvec_add(&out, gpr_strdup("GET "));
fill_common_header(request, &out);
sbprintf(&out, "\r\n");
gpr_strvec_add(&out, gpr_strdup("\r\n"));
return gpr_slice_new(out.data, out.length, gpr_free);
flat = gpr_strvec_flatten(&out, &flat_len);
gpr_strvec_destroy(&out);
return gpr_slice_new(flat, flat_len, gpr_free);
}
gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
const char *body_bytes,
size_t body_size) {
sbuf out = {0, 0, NULL};
gpr_strvec out;
char *tmp;
size_t out_len;
size_t i;
sbprintf(&out, "POST ");
gpr_strvec_init(&out);
gpr_strvec_add(&out, gpr_strdup("POST "));
fill_common_header(request, &out);
if (body_bytes) {
gpr_uint8 has_content_type = 0;
@ -108,14 +98,18 @@ gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
}
}
if (!has_content_type) {
sbprintf(&out, "Content-Type: text/plain\r\n");
gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n"));
}
sbprintf(&out, "Content-Length: %lu\r\n", (unsigned long)body_size);
gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size);
gpr_strvec_add(&out, tmp);
}
sbprintf(&out, "\r\n");
gpr_strvec_add(&out, gpr_strdup("\r\n"));
tmp = gpr_strvec_flatten(&out, &out_len);
if (body_bytes) {
sbuf_append(&out, body_bytes, body_size);
tmp = gpr_realloc(tmp, out_len + body_size);
memcpy(tmp + out_len, body_bytes, body_size);
out_len += body_size;
}
return gpr_slice_new(out.data, out.length, gpr_free);
return gpr_slice_new(tmp, out_len, gpr_free);
}

@ -14,7 +14,7 @@
* 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
* 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
@ -152,3 +152,49 @@ int gpr_ltoa(long value, char *string) {
string[i] = 0;
return i;
}
char *gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length) {
size_t out_length = 0;
size_t i;
char *out;
for (i = 0; i < nstrs; i++) {
out_length += strlen(strs[i]);
}
out_length += 1; /* null terminator */
out = gpr_malloc(out_length);
out_length = 0;
for (i = 0; i < nstrs; i++) {
size_t slen = strlen(strs[i]);
memcpy(out + out_length, strs[i], slen);
out_length += slen;
}
out[out_length] = 0;
if (final_length != NULL) {
*final_length = out_length;
}
return out;
}
void gpr_strvec_init(gpr_strvec *sv) {
memset(sv, 0, sizeof(*sv));
}
void gpr_strvec_destroy(gpr_strvec *sv) {
size_t i;
for (i = 0; i < sv->count; i++) {
gpr_free(sv->strs[i]);
}
gpr_free(sv->strs);
}
void gpr_strvec_add(gpr_strvec *sv, char *str) {
if (sv->count == sv->capacity) {
sv->capacity = GPR_MAX(sv->capacity + 8, sv->capacity * 2);
sv->strs = gpr_realloc(sv->strs, sizeof(char*) * sv->capacity);
}
sv->strs[sv->count++] = str;
}
char *gpr_strvec_flatten(gpr_strvec *sv, size_t *final_length) {
return gpr_strjoin((const char**)sv->strs, sv->count, final_length);
}

@ -81,6 +81,27 @@ void gpr_reverse_bytes(char *str, int len);
the result is undefined. */
int gpr_asprintf(char **strp, const char *format, ...);
/* Join a set of strings, returning the resulting string.
Total combined length (excluding null terminator) is returned in total_length
if it is non-null. */
char *gpr_strjoin(const char **strs, size_t nstrs, size_t *total_length);
/* A vector of strings... for building up a final string one piece at a time */
typedef struct {
char **strs;
size_t count;
size_t capacity;
} gpr_strvec;
/* Initialize/destroy */
void gpr_strvec_init(gpr_strvec *strs);
void gpr_strvec_destroy(gpr_strvec *strs);
/* Add a string to a strvec, takes ownership of the string */
void gpr_strvec_add(gpr_strvec *strs, char *add);
/* Return a joined string with all added substrings, optionally setting
total_length as per gpr_strjoin */
char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length);
#ifdef __cplusplus
}
#endif

@ -38,8 +38,10 @@
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
static size_t addhdr(char *p, grpc_event *ev) {
return sprintf(p, "tag:%p call:%p", ev->tag, (void *)ev->call);
static void addhdr(gpr_strvec *buf, grpc_event *ev) {
char *tmp;
gpr_asprintf(&tmp, "tag:%p call:%p", ev->tag, (void *)ev->call);
gpr_strvec_add(buf, tmp);
}
static const char *errstr(grpc_op_error err) {
@ -52,72 +54,84 @@ static const char *errstr(grpc_op_error err) {
return "UNKNOWN_UNKNOWN";
}
static size_t adderr(char *p, grpc_op_error err) {
return sprintf(p, " err=%s", errstr(err));
static void adderr(gpr_strvec *buf, grpc_op_error err) {
char *tmp;
gpr_asprintf(&tmp, " err=%s", errstr(err));
gpr_strvec_add(buf, tmp);
}
char *grpc_event_string(grpc_event *ev) {
char buffer[1024];
char *p = buffer;
char *out;
char *tmp;
gpr_strvec buf;
if (ev == NULL) return gpr_strdup("null");
gpr_strvec_init(&buf);
switch (ev->type) {
case GRPC_SERVER_SHUTDOWN:
p += sprintf(p, "SERVER_SHUTDOWN");
gpr_strvec_add(&buf, gpr_strdup("SERVER_SHUTDOWN"));
break;
case GRPC_QUEUE_SHUTDOWN:
p += sprintf(p, "QUEUE_SHUTDOWN");
gpr_strvec_add(&buf, gpr_strdup("QUEUE_SHUTDOWN"));
break;
case GRPC_READ:
p += sprintf(p, "READ: ");
p += addhdr(p, ev);
gpr_strvec_add(&buf, gpr_strdup("READ: "));
addhdr(&buf, ev);
if (ev->data.read) {
p += sprintf(p, " %d bytes",
gpr_asprintf(&tmp, " %d bytes",
(int)grpc_byte_buffer_length(ev->data.read));
gpr_strvec_add(&buf, tmp);
} else {
p += sprintf(p, " end-of-stream");
gpr_strvec_add(&buf, gpr_strdup(" end-of-stream"));
}
break;
case GRPC_INVOKE_ACCEPTED:
p += sprintf(p, "INVOKE_ACCEPTED: ");
p += addhdr(p, ev);
p += adderr(p, ev->data.invoke_accepted);
gpr_strvec_add(&buf, gpr_strdup("INVOKE_ACCEPTED: "));
addhdr(&buf, ev);
adderr(&buf, ev->data.invoke_accepted);
break;
case GRPC_WRITE_ACCEPTED:
p += sprintf(p, "WRITE_ACCEPTED: ");
p += addhdr(p, ev);
p += adderr(p, ev->data.write_accepted);
gpr_strvec_add(&buf, gpr_strdup("WRITE_ACCEPTED: "));
addhdr(&buf, ev);
adderr(&buf, ev->data.write_accepted);
break;
case GRPC_FINISH_ACCEPTED:
p += sprintf(p, "FINISH_ACCEPTED: ");
p += addhdr(p, ev);
p += adderr(p, ev->data.write_accepted);
gpr_strvec_add(&buf, gpr_strdup("FINISH_ACCEPTED: "));
addhdr(&buf, ev);
adderr(&buf, ev->data.write_accepted);
break;
case GRPC_CLIENT_METADATA_READ:
p += sprintf(p, "CLIENT_METADATA_READ: ");
p += addhdr(p, ev);
p += sprintf(p, " %d elements", (int)ev->data.client_metadata_read.count);
gpr_strvec_add(&buf, gpr_strdup("CLIENT_METADATA_READ: "));
addhdr(&buf, ev);
gpr_asprintf(&tmp, " %d elements",
(int)ev->data.client_metadata_read.count);
gpr_strvec_add(&buf, tmp);
break;
case GRPC_FINISHED:
p += sprintf(p, "FINISHED: ");
p += addhdr(p, ev);
p += sprintf(p, " status=%d details='%s' %d metadata elements",
gpr_strvec_add(&buf, gpr_strdup("FINISHED: "));
addhdr(&buf, ev);
gpr_asprintf(&tmp, " status=%d details='%s' %d metadata elements",
ev->data.finished.status, ev->data.finished.details,
(int)ev->data.finished.metadata_count);
gpr_strvec_add(&buf, tmp);
break;
case GRPC_SERVER_RPC_NEW:
p += sprintf(p, "SERVER_RPC_NEW: ");
p += addhdr(p, ev);
p += sprintf(p, " method='%s' host='%s' %d metadata elements",
gpr_strvec_add(&buf, gpr_strdup("SERVER_RPC_NEW: "));
addhdr(&buf, ev);
gpr_asprintf(&tmp, " method='%s' host='%s' %d metadata elements",
ev->data.server_rpc_new.method, ev->data.server_rpc_new.host,
(int)ev->data.server_rpc_new.metadata_count);
gpr_strvec_add(&buf, tmp);
break;
case GRPC_COMPLETION_DO_NOT_USE:
p += sprintf(p, "DO_NOT_USE (this is a bug)");
p += addhdr(p, ev);
gpr_strvec_add(&buf, gpr_strdup("DO_NOT_USE (this is a bug)"));
addhdr(&buf, ev);
break;
}
return gpr_strdup(buffer);
out = gpr_strvec_flatten(&buf, NULL);
gpr_strvec_destroy(&buf);
return out;
}

@ -105,7 +105,7 @@ function GrpcClientStream(call, serialize, deserialize) {
return;
}
var data = event.data;
if (self.push(data) && data != null) {
if (self.push(self.deserialize(data)) && data != null) {
self._call.startRead(readCallback);
} else {
reading = false;
@ -155,11 +155,19 @@ GrpcClientStream.prototype._read = function(size) {
*/
GrpcClientStream.prototype._write = function(chunk, encoding, callback) {
var self = this;
self._call.startWrite(chunk, function(event) {
self._call.startWrite(self.serialize(chunk), function(event) {
callback();
}, 0);
};
/**
* Cancel the ongoing call. If the call has not already finished, it will finish
* with status CANCELLED.
*/
GrpcClientStream.prototype.cancel = function() {
this._call.cancel();
};
/**
* Make a request on the channel to the given method with the given arguments
* @param {grpc.Channel} channel The channel on which to make the request
@ -185,7 +193,7 @@ function makeRequest(channel,
if (metadata) {
call.addMetadata(metadata);
}
return new GrpcClientStream(call);
return new GrpcClientStream(call, serialize, deserialize);
}
/**

@ -52,7 +52,8 @@ var Server = grpc.buildServer([math.Math.service]);
*/
function mathDiv(call, cb) {
var req = call.request;
if (req.divisor == 0) {
// Unary + is explicit coersion to integer
if (+req.divisor === 0) {
cb(new Error('cannot divide by zero'));
}
cb(null, {
@ -89,7 +90,7 @@ function mathSum(call, cb) {
// Here, call is a standard readable Node object Stream
var sum = 0;
call.on('data', function(data) {
sum += data.num | 0;
sum += (+data.num);
});
call.on('end', function() {
cb(null, {num: sum});
@ -104,7 +105,7 @@ function mathDivMany(stream) {
Transform.call(this, options);
}
DivTransform.prototype._transform = function(div_args, encoding, callback) {
if (div_args.divisor == 0) {
if (+div_args.divisor === 0) {
callback(new Error('cannot divide by zero'));
}
callback(null, {

@ -183,7 +183,7 @@ function pingPong(client, done) {
assert.equal(response.payload.body.limit - response.payload.body.offset,
response_sizes[index]);
index += 1;
if (index == 4) {
if (index === 4) {
call.end();
} else {
call.write({

@ -151,7 +151,7 @@ function GrpcServerStream(call, serialize, deserialize) {
return;
}
var data = event.data;
if (self.push(deserialize(data)) && data != null) {
if (self.push(self.deserialize(data)) && data != null) {
self._call.startRead(readCallback);
} else {
reading = false;
@ -233,7 +233,7 @@ function Server(options) {
function handleNewCall(event) {
var call = event.call;
var data = event.data;
if (data == null) {
if (data === null) {
return;
}
server.requestCall(handleNewCall);
@ -246,6 +246,7 @@ function Server(options) {
call.serverAccept(function(event) {
if (event.data.code === grpc.status.CANCELLED) {
cancelled = true;
stream.emit('cancelled');
}
}, 0);
call.serverEndInitialMetadata(0);

@ -63,114 +63,80 @@ util.inherits(ClientReadableObjectStream, Readable);
* client side. Extends from stream.Readable.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
* @param {function(Buffer)} deserialize Function for deserializing binary data
* @param {object} options Stream options
*/
function ClientReadableObjectStream(stream, deserialize, options) {
options = _.extend(options, {objectMode: true});
function ClientReadableObjectStream(stream) {
var options = {objectMode: true};
Readable.call(this, options);
this._stream = stream;
var self = this;
forwardEvent(stream, this, 'status');
forwardEvent(stream, this, 'metadata');
this._stream.on('data', function forwardData(chunk) {
if (!self.push(deserialize(chunk))) {
if (!self.push(chunk)) {
self._stream.pause();
}
});
this._stream.pause();
}
util.inherits(ClientWritableObjectStream, Writable);
/**
* Class for representing a gRPC client streaming call as a Node stream on the
* client side. Extends from stream.Writable.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
* @param {function(*):Buffer} serialize Function for serializing objects
* @param {object} options Stream options
* _read implementation for both types of streams that allow reading.
* @this {ClientReadableObjectStream}
* @param {number} size Ignored
*/
function ClientWritableObjectStream(stream, serialize, options) {
options = _.extend(options, {objectMode: true});
Writable.call(this, options);
this._stream = stream;
this._serialize = serialize;
forwardEvent(stream, this, 'status');
forwardEvent(stream, this, 'metadata');
this.on('finish', function() {
this._stream.end();
});
function _read(size) {
this._stream.resume();
}
/**
* See docs for _read
*/
ClientReadableObjectStream.prototype._read = _read;
util.inherits(ClientBidiObjectStream, Duplex);
util.inherits(ClientWritableObjectStream, Writable);
/**
* Class for representing a gRPC bidi streaming call as a Node stream on the
* client side. Extends from stream.Duplex.
* Class for representing a gRPC client streaming call as a Node stream on the
* client side. Extends from stream.Writable.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
* @param {function(*):Buffer} serialize Function for serializing objects
* @param {function(Buffer)} deserialize Function for deserializing binary data
* @param {object} options Stream options
*/
function ClientBidiObjectStream(stream, serialize, deserialize, options) {
options = _.extend(options, {objectMode: true});
Duplex.call(this, options);
function ClientWritableObjectStream(stream) {
var options = {objectMode: true};
Writable.call(this, options);
this._stream = stream;
this._serialize = serialize;
var self = this;
forwardEvent(stream, this, 'status');
forwardEvent(stream, this, 'metadata');
this._stream.on('data', function forwardData(chunk) {
if (!self.push(deserialize(chunk))) {
self._stream.pause();
}
});
this._stream.pause();
this.on('finish', function() {
this._stream.end();
});
}
/**
* _read implementation for both types of streams that allow reading.
* @this {ClientReadableObjectStream|ClientBidiObjectStream}
* @param {number} size Ignored
*/
function _read(size) {
this._stream.resume();
}
/**
* See docs for _read
*/
ClientReadableObjectStream.prototype._read = _read;
/**
* See docs for _read
*/
ClientBidiObjectStream.prototype._read = _read;
/**
* _write implementation for both types of streams that allow writing
* @this {ClientWritableObjectStream|ClientBidiObjectStream}
* @this {ClientWritableObjectStream}
* @param {*} chunk The value to write to the stream
* @param {string} encoding Ignored
* @param {function(Error)} callback Callback to call when finished writing
*/
function _write(chunk, encoding, callback) {
this._stream.write(this._serialize(chunk), encoding, callback);
this._stream.write(chunk, encoding, callback);
}
/**
* See docs for _write
*/
ClientWritableObjectStream.prototype._write = _write;
/**
* See docs for _write
* Cancel the underlying call
*/
ClientBidiObjectStream.prototype._write = _write;
function cancel() {
this._stream.cancel();
}
ClientReadableObjectStream.prototype.cancel = cancel;
ClientWritableObjectStream.prototype.cancel = cancel;
/**
* Get a function that can make unary requests to the specified method.
@ -196,19 +162,28 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
* @return {EventEmitter} An event emitter for stream related events
*/
function makeUnaryRequest(argument, callback, metadata, deadline) {
var stream = client.makeRequest(this.channel, method, metadata, deadline);
var stream = client.makeRequest(this.channel, method, serialize,
deserialize, metadata, deadline);
var emitter = new EventEmitter();
emitter.cancel = function cancel() {
stream.cancel();
};
forwardEvent(stream, emitter, 'status');
forwardEvent(stream, emitter, 'metadata');
stream.write(serialize(argument));
stream.write(argument);
stream.end();
stream.on('data', function forwardData(chunk) {
try {
callback(null, deserialize(chunk));
callback(null, chunk);
} catch (e) {
callback(e);
}
});
stream.on('status', function forwardStatus(status) {
if (status.code !== client.status.OK) {
callback(status);
}
});
return emitter;
}
return makeUnaryRequest;
@ -236,15 +211,21 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
* @return {EventEmitter} An event emitter for stream related events
*/
function makeClientStreamRequest(callback, metadata, deadline) {
var stream = client.makeRequest(this.channel, method, metadata, deadline);
var obj_stream = new ClientWritableObjectStream(stream, serialize, {});
var stream = client.makeRequest(this.channel, method, serialize,
deserialize, metadata, deadline);
var obj_stream = new ClientWritableObjectStream(stream);
stream.on('data', function forwardData(chunk) {
try {
callback(null, deserialize(chunk));
callback(null, chunk);
} catch (e) {
callback(e);
}
});
stream.on('status', function forwardStatus(status) {
if (status.code !== client.status.OK) {
callback(status);
}
});
return obj_stream;
}
return makeClientStreamRequest;
@ -272,9 +253,10 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
* @return {EventEmitter} An event emitter for stream related events
*/
function makeServerStreamRequest(argument, metadata, deadline) {
var stream = client.makeRequest(this.channel, method, metadata, deadline);
var obj_stream = new ClientReadableObjectStream(stream, deserialize, {});
stream.write(serialize(argument));
var stream = client.makeRequest(this.channel, method, serialize,
deserialize, metadata, deadline);
var obj_stream = new ClientReadableObjectStream(stream);
stream.write(argument);
stream.end();
return obj_stream;
}
@ -301,12 +283,8 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
* @return {EventEmitter} An event emitter for stream related events
*/
function makeBidiStreamRequest(metadata, deadline) {
var stream = client.makeRequest(this.channel, method, metadata, deadline);
var obj_stream = new ClientBidiObjectStream(stream,
serialize,
deserialize,
{});
return obj_stream;
return client.makeRequest(this.channel, method, serialize,
deserialize, metadata, deadline);
}
return makeBidiStreamRequest;
}

@ -54,67 +54,20 @@ util.inherits(ServerReadableObjectStream, Readable);
* server side. Extends from stream.Readable.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
* @param {function(Buffer)} deserialize Function for deserializing binary data
* @param {object} options Stream options
*/
function ServerReadableObjectStream(stream, deserialize, options) {
options = _.extend(options, {objectMode: true});
function ServerReadableObjectStream(stream) {
var options = {objectMode: true};
Readable.call(this, options);
this._stream = stream;
Object.defineProperty(this, 'cancelled', {
get: function() { return stream.cancelled; }
});
var self = this;
this._stream.on('data', function forwardData(chunk) {
if (!self.push(deserialize(chunk))) {
self._stream.pause();
}
});
this._stream.on('end', function forwardEnd() {
self.push(null);
this._stream.on('cancelled', function() {
self.emit('cancelled');
});
this._stream.pause();
}
util.inherits(ServerWritableObjectStream, Writable);
/**
* Class for representing a gRPC server streaming call as a Node stream on the
* server side. Extends from stream.Writable.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
* @param {function(*):Buffer} serialize Function for serializing objects
* @param {object} options Stream options
*/
function ServerWritableObjectStream(stream, serialize, options) {
options = _.extend(options, {objectMode: true});
Writable.call(this, options);
this._stream = stream;
this._serialize = serialize;
this.on('finish', function() {
this._stream.end();
});
}
util.inherits(ServerBidiObjectStream, Duplex);
/**
* Class for representing a gRPC bidi streaming call as a Node stream on the
* server side. Extends from stream.Duplex.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
* @param {function(*):Buffer} serialize Function for serializing objects
* @param {function(Buffer)} deserialize Function for deserializing binary data
* @param {object} options Stream options
*/
function ServerBidiObjectStream(stream, serialize, deserialize, options) {
options = _.extend(options, {objectMode: true});
Duplex.call(this, options);
this._stream = stream;
this._serialize = serialize;
var self = this;
this._stream.on('data', function forwardData(chunk) {
if (!self.push(deserialize(chunk))) {
if (!self.push(chunk)) {
self._stream.pause();
}
});
@ -122,9 +75,6 @@ function ServerBidiObjectStream(stream, serialize, deserialize, options) {
self.push(null);
});
this._stream.pause();
this.on('finish', function() {
this._stream.end();
});
}
/**
@ -140,39 +90,49 @@ function _read(size) {
* See docs for _read
*/
ServerReadableObjectStream.prototype._read = _read;
util.inherits(ServerWritableObjectStream, Writable);
/**
* See docs for _read
* Class for representing a gRPC server streaming call as a Node stream on the
* server side. Extends from stream.Writable.
* @constructor
* @param {stream} stream Underlying binary Duplex stream for the call
*/
ServerBidiObjectStream.prototype._read = _read;
function ServerWritableObjectStream(stream) {
var options = {objectMode: true};
Writable.call(this, options);
this._stream = stream;
this._stream.on('cancelled', function() {
self.emit('cancelled');
});
this.on('finish', function() {
this._stream.end();
});
}
/**
* _write implementation for both types of streams that allow writing
* @this {ServerWritableObjectStream|ServerBidiObjectStream}
* @this {ServerWritableObjectStream}
* @param {*} chunk The value to write to the stream
* @param {string} encoding Ignored
* @param {function(Error)} callback Callback to call when finished writing
*/
function _write(chunk, encoding, callback) {
this._stream.write(this._serialize(chunk), encoding, callback);
this._stream.write(chunk, encoding, callback);
}
/**
* See docs for _write
*/
ServerWritableObjectStream.prototype._write = _write;
/**
* See docs for _write
*/
ServerBidiObjectStream.prototype._write = _write;
/**
* Creates a binary stream handler function from a unary handler function
* @param {function(Object, function(Error, *))} handler Unary call handler
* @param {function(*):Buffer} serialize Serialization function
* @param {function(Buffer):*} deserialize Deserialization function
* @return {function(stream)} Binary stream handler
*/
function makeUnaryHandler(handler, serialize, deserialize) {
function makeUnaryHandler(handler) {
/**
* Handles a stream by reading a single data value, passing it to the handler,
* and writing the response back to the stream.
@ -180,15 +140,18 @@ function makeUnaryHandler(handler, serialize, deserialize) {
*/
return function handleUnaryCall(stream) {
stream.on('data', function handleUnaryData(value) {
var call = {request: deserialize(value)};
var call = {request: value};
Object.defineProperty(call, 'cancelled', {
get: function() { return stream.cancelled;}
});
stream.on('cancelled', function() {
call.emit('cancelled');
});
handler(call, function sendUnaryData(err, value) {
if (err) {
stream.emit('error', err);
} else {
stream.write(serialize(value));
stream.write(value);
stream.end();
}
});
@ -201,23 +164,21 @@ function makeUnaryHandler(handler, serialize, deserialize) {
* function
* @param {function(Readable, function(Error, *))} handler Client stream call
* handler
* @param {function(*):Buffer} serialize Serialization function
* @param {function(Buffer):*} deserialize Deserialization function
* @return {function(stream)} Binary stream handler
*/
function makeClientStreamHandler(handler, serialize, deserialize) {
function makeClientStreamHandler(handler) {
/**
* Handles a stream by passing a deserializing stream to the handler and
* writing the response back to the stream.
* @param {stream} stream Binary data stream
*/
return function handleClientStreamCall(stream) {
var object_stream = new ServerReadableObjectStream(stream, deserialize, {});
var object_stream = new ServerReadableObjectStream(stream);
handler(object_stream, function sendClientStreamData(err, value) {
if (err) {
stream.emit('error', err);
} else {
stream.write(serialize(value));
stream.write(value);
stream.end();
}
});
@ -228,11 +189,9 @@ function makeClientStreamHandler(handler, serialize, deserialize) {
* Creates a binary stream handler function from a server stream handler
* function
* @param {function(Writable)} handler Server stream call handler
* @param {function(*):Buffer} serialize Serialization function
* @param {function(Buffer):*} deserialize Deserialization function
* @return {function(stream)} Binary stream handler
*/
function makeServerStreamHandler(handler, serialize, deserialize) {
function makeServerStreamHandler(handler) {
/**
* Handles a stream by attaching it to a serializing stream, and passing it to
* the handler.
@ -240,10 +199,8 @@ function makeServerStreamHandler(handler, serialize, deserialize) {
*/
return function handleServerStreamCall(stream) {
stream.on('data', function handleClientData(value) {
var object_stream = new ServerWritableObjectStream(stream,
serialize,
{});
object_stream.request = deserialize(value);
var object_stream = new ServerWritableObjectStream(stream);
object_stream.request = value;
handler(object_stream);
});
};
@ -252,23 +209,10 @@ function makeServerStreamHandler(handler, serialize, deserialize) {
/**
* Creates a binary stream handler function from a bidi stream handler function
* @param {function(Duplex)} handler Unary call handler
* @param {function(*):Buffer} serialize Serialization function
* @param {function(Buffer):*} deserialize Deserialization function
* @return {function(stream)} Binary stream handler
*/
function makeBidiStreamHandler(handler, serialize, deserialize) {
/**
* Handles a stream by wrapping it in a serializing and deserializing object
* stream, and passing it to the handler.
* @param {stream} stream Binary data stream
*/
return function handleBidiStreamCall(stream) {
var object_stream = new ServerBidiObjectStream(stream,
serialize,
deserialize,
{});
handler(object_stream);
};
function makeBidiStreamHandler(handler) {
return handler;
}
/**
@ -341,10 +285,13 @@ function makeServerConstructor(services) {
common.fullyQualifiedName(method) + ' not provided.');
}
var binary_handler = handler_makers[method_type](
service_handlers[service_name][decapitalize(method.name)],
common.serializeCls(method.resolvedResponseType.build()),
common.deserializeCls(method.resolvedRequestType.build()));
server.register(prefix + capitalize(method.name), binary_handler);
service_handlers[service_name][decapitalize(method.name)]);
var serialize = common.serializeCls(
method.resolvedResponseType.build());
var deserialize = common.deserializeCls(
method.resolvedRequestType.build());
server.register(prefix + capitalize(method.name), binary_handler,
serialize, deserialize);
});
}, this);
}

@ -77,6 +77,14 @@ function errorHandler(stream) {
};
}
/**
* Wait for a cancellation instead of responding
* @param {Stream} stream
*/
function cancelHandler(stream) {
// do nothing
}
describe('echo client', function() {
it('should receive echo responses', function(done) {
var server = new Server();
@ -125,6 +133,26 @@ describe('echo client', function() {
done();
});
});
it('should be able to cancel a call', function(done) {
var server = new Server();
var port_num = server.bind('0.0.0.0:0');
server.register('cancellation', cancelHandler);
server.start();
var channel = new grpc.Channel('localhost:' + port_num);
var stream = client.makeRequest(
channel,
'cancellation',
null,
getDeadline(1));
stream.cancel();
stream.on('status', function(status) {
assert.equal(status.code, grpc.status.CANCELLED);
server.shutdown();
done();
});
});
});
/* TODO(mlumish): explore options for reducing duplication between this test
* and the insecure echo client test */

@ -48,6 +48,9 @@ describe('Interop tests', function() {
port = 'localhost:' + server_obj.port;
done();
});
after(function() {
server.shutdown();
});
// This depends on not using a binary stream
it('should pass empty_unary', function(done) {
interop_client.runTest(port, name_override, 'empty_unary', true, done);
@ -65,7 +68,7 @@ describe('Interop tests', function() {
it('should pass ping_pong', function(done) {
interop_client.runTest(port, name_override, 'ping_pong', true, done);
});
it.skip('should pass empty_stream', function(done) {
it('should pass empty_stream', function(done) {
interop_client.runTest(port, name_override, 'empty_stream', true, done);
});
});

@ -35,6 +35,8 @@ var assert = require('assert');
var surface_server = require('../surface_server.js');
var surface_client = require('../surface_client.js');
var ProtoBuf = require('protobufjs');
var grpc = require('..');
@ -73,3 +75,54 @@ describe('Surface server constructor', function() {
}, /math.Math/);
});
});
describe('Surface client', function() {
var client;
var server;
before(function() {
var Server = grpc.buildServer([mathService]);
server = new Server({
'math.Math': {
'div': function(stream) {},
'divMany': function(stream) {},
'fib': function(stream) {},
'sum': function(stream) {}
}
});
var port = server.bind('localhost:0');
var Client = surface_client.makeClientConstructor(mathService);
client = new Client('localhost:' + port);
});
after(function() {
server.shutdown();
});
it('Should correctly cancel a unary call', function(done) {
var call = client.div({'divisor': 0, 'dividend': 0}, function(err, resp) {
assert.strictEqual(err.code, surface_client.status.CANCELLED);
done();
});
call.cancel();
});
it('Should correctly cancel a client stream call', function(done) {
var call = client.sum(function(err, resp) {
assert.strictEqual(err.code, surface_client.status.CANCELLED);
done();
});
call.cancel();
});
it('Should correctly cancel a server stream call', function(done) {
var call = client.fib({'limit': 5});
call.on('status', function(status) {
assert.strictEqual(status.code, surface_client.status.CANCELLED);
done();
});
call.cancel();
});
it('Should correctly cancel a bidi stream call', function(done) {
var call = client.divMany();
call.on('status', function(status) {
assert.strictEqual(status.code, surface_client.status.CANCELLED);
done();
});
call.cancel();
});
});

@ -14,9 +14,10 @@ INSTALLING
----------
- Install the gRPC core library
TODO: describe this, once the core distribution mechanism is defined.
TODO: describe this, once the core distribution mechanism is defined.
```
$ gem install grpc
```
Installing from source
@ -24,37 +25,47 @@ Installing from source
- Build or Install the gRPC core
E.g, from the root of the grpc [git repo](https://github.com/google/grpc)
```
$ cd ../..
$ make && sudo make install
```
- Install Ruby 2.x. Consider doing this with [RVM](http://rvm.io), it's a nice way of controlling
the exact ruby version that's used.
```
$ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby
$
$ # follow the instructions to ensure that your're using the latest stable version of Ruby
$ # and that the rvm command is installed
```
- Install [bundler](http://bundler.io/)
```
$ gem install bundler
```
- Finally, install grpc ruby locally.
```
$ cd <install_dir>
$ bundle install
$ rake # compiles the extension, runs the unit tests, see rake -T for other options
```
CONTENTS
--------
Directory structure is the layout for [ruby extensions](http://guides.rubygems.org/gems-with-extensions/)
* ext: the extension code
* lib: the entrypoint grpc ruby library to be used in a 'require' statement
* spec: tests
* bin: example gRPC clients and servers, e.g,
- ext:
the gRPC ruby extension
- lib:
the entrypoint grpc ruby library to be used in a 'require' statement
- spec:
Rspec unittest
- bin:
example gRPC clients and servers, e.g,
```ruby
# client
stub = Math::Math::Stub.new('my.test.math.server.com:8080')
req = Math::DivArgs.new(dividend: 7, divisor: 3)
logger.info("div(7/3): req=#{req.inspect}")

@ -44,12 +44,13 @@ shared_context 'setup: tags' do
before(:example) do
@server_finished_tag = Object.new
@client_finished_tag = Object.new
@client_metadata_tag = Object.new
@server_tag = Object.new
@tag = Object.new
end
def deadline
Time.now + 0.05
Time.now + 2
end
def expect_next_event_on(queue, type, tag)
@ -63,27 +64,30 @@ shared_context 'setup: tags' do
ev
end
def server_receives_and_responds_with(reply_text)
reply = ByteBuffer.new(reply_text)
def server_allows_client_to_proceed
@server.request_call(@server_tag)
ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
ev = @server_queue.pluck(@server_tag, deadline)
expect(ev).not_to be_nil
expect(ev.type).to be(SERVER_RPC_NEW)
ev.call.server_accept(@server_queue, @server_finished_tag)
ev.call.server_end_initial_metadata
ev.call.start_read(@server_tag)
server_call = ev.call
server_call.server_accept(@server_queue, @server_finished_tag)
server_call.server_end_initial_metadata
server_call
end
def server_responds_with(server_call, reply_text)
reply = ByteBuffer.new(reply_text)
server_call.start_read(@server_tag)
ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
expect(ev.type).to be(READ)
ev.call.start_write(reply, @server_tag)
server_call.start_write(reply, @server_tag)
ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
expect(ev).not_to be_nil
expect(ev.type).to be(WRITE_ACCEPTED)
ev.call
end
def client_sends(call, sent = 'a message')
req = ByteBuffer.new(sent)
call.invoke(@client_queue, @tag, @client_finished_tag)
call.start_write(req, @tag)
ev = @client_queue.pluck(@tag, TimeConsts::INFINITE_FUTURE)
expect(ev).not_to be_nil
@ -102,16 +106,20 @@ shared_examples 'basic GRPC message delivery is OK' do
it 'servers receive requests from clients and start responding' do
reply = ByteBuffer.new('the server payload')
call = new_client_call
msg = client_sends(call)
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
# check the server rpc new was received
@server.request_call(@server_tag)
ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
# @server.request_call(@server_tag)
# ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
# accept the call
server_call = ev.call
server_call.server_accept(@server_queue, @server_finished_tag)
server_call.server_end_initial_metadata
# server_call = ev.call
# server_call.server_accept(@server_queue, @server_finished_tag)
# server_call.server_end_initial_metadata
server_call = server_allows_client_to_proceed
# client sends a message
msg = client_sends(call)
# confirm the server can read the inbound message
server_call.start_read(@server_tag)
@ -125,18 +133,19 @@ shared_examples 'basic GRPC message delivery is OK' do
it 'responses written by servers are received by the client' do
call = new_client_call
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
server_call = server_allows_client_to_proceed
client_sends(call)
server_receives_and_responds_with('server_response')
server_responds_with(server_call, 'server_response')
call.start_read(@tag)
expect_next_event_on(@client_queue, CLIENT_METADATA_READ, @tag)
ev = expect_next_event_on(@client_queue, READ, @tag)
expect(ev.result.to_s).to eq('server_response')
end
it 'servers can ignore a client write and send a status' do
call = new_client_call
client_sends(call)
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
# check the server rpc new was received
@server.request_call(@server_tag)
@ -150,9 +159,13 @@ shared_examples 'basic GRPC message delivery is OK' do
server_call.start_write_status(StatusCodes::NOT_FOUND, 'not found',
@server_tag)
# Client sends some data
client_sends(call)
# client gets an empty response for the read, preceeded by some metadata.
call.start_read(@tag)
expect_next_event_on(@client_queue, CLIENT_METADATA_READ, @tag)
expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
@client_metadata_tag)
ev = expect_next_event_on(@client_queue, READ, @tag)
expect(ev.tag).to be(@tag)
expect(ev.result.to_s).to eq('')
@ -166,13 +179,14 @@ shared_examples 'basic GRPC message delivery is OK' do
it 'completes calls by sending status to client and server' do
call = new_client_call
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
server_call = server_allows_client_to_proceed
client_sends(call)
server_call = server_receives_and_responds_with('server_response')
server_responds_with(server_call, 'server_response')
server_call.start_write_status(10_101, 'status code is 10101', @server_tag)
# first the client says writes are done
call.start_read(@tag)
expect_next_event_on(@client_queue, CLIENT_METADATA_READ, @tag)
expect_next_event_on(@client_queue, READ, @tag)
call.writes_done(@tag)
@ -215,22 +229,13 @@ shared_examples 'GRPC metadata delivery works OK' do
end
end
it 'sends an empty hash when no metadata is added' do
call = new_client_call
client_sends(call)
# Server gets a response
@server.request_call(@server_tag)
expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
end
it 'sends all the metadata pairs when keys and values are valid' do
@valid_metadata.each do |md|
call = new_client_call
call.add_metadata(md)
# Client begins a call OK
call.invoke(@client_queue, @tag, @client_finished_tag)
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
# ... server has all metadata available even though the client did not
# send a write
@ -262,7 +267,7 @@ shared_examples 'GRPC metadata delivery works OK' do
it 'raises an exception if a metadata key is invalid' do
@bad_keys.each do |md|
call = new_client_call
client_sends(call)
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
# server gets the invocation
@server.request_call(@server_tag)
@ -273,7 +278,7 @@ shared_examples 'GRPC metadata delivery works OK' do
it 'sends a hash that contains the status when no metadata is added' do
call = new_client_call
client_sends(call)
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
# server gets the invocation
@server.request_call(@server_tag)
@ -284,21 +289,17 @@ shared_examples 'GRPC metadata delivery works OK' do
server_call.server_accept(@server_queue, @server_finished_tag)
server_call.server_end_initial_metadata
# ... these server sends some data, allowing the metadata read
server_call.start_write(ByteBuffer.new('reply with metadata'),
@server_tag)
expect_next_event_on(@server_queue, WRITE_ACCEPTED, @server_tag)
# there is the HTTP status metadata, though there should not be any
# TODO: update this with the bug number to be resolved
ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ, @tag)
ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
@client_metadata_tag)
expect(ev.result).to eq(':status' => '200')
end
it 'sends all the pairs and status:200 when keys and values are valid' do
@valid_metadata.each do |md|
call = new_client_call
client_sends(call)
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
# server gets the invocation
@server.request_call(@server_tag)
@ -311,7 +312,8 @@ shared_examples 'GRPC metadata delivery works OK' do
server_call.server_end_initial_metadata
# Now the client can read the metadata
ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ, @tag)
ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
@client_metadata_tag)
replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
replace_symbols[':status'] = '200'
expect(ev.result).to eq(replace_symbols)
@ -322,16 +324,17 @@ end
describe 'the http client/server' do
before(:example) do
server_host = 'localhost:0'
server_host = '0.0.0.0:0'
@client_queue = GRPC::Core::CompletionQueue.new
@server_queue = GRPC::Core::CompletionQueue.new
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(server_host)
@server.start
@ch = Channel.new("localhost:#{server_port}", nil)
@ch = Channel.new("0.0.0.0:#{server_port}", nil)
end
after(:example) do
@ch.close
@server.close
end
@ -345,16 +348,15 @@ end
describe 'the secure http client/server' do
before(:example) do
certs = load_test_certs
port = find_unused_tcp_port
server_host = 'localhost:0'
@client_queue = GRPC::Core::CompletionQueue.new
@server_queue = GRPC::Core::CompletionQueue.new
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
@server = GRPC::Core::Server.new(@server_queue, nil, server_creds)
server_port = @server.add_http2_port(host, true)
server_port = @server.add_http2_port(server_host, true)
@server.start
args = { Channel::SSL_TARGET => 'foo.test.google.com' }
@ch = Channel.new("localhost:#{server_port}", args,
@ch = Channel.new("0.0.0.0:#{server_port}", args,
GRPC::Core::Credentials.new(certs[0], nil, nil))
end

@ -32,6 +32,7 @@
*/
#include "src/core/channel/metadata_buffer.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "test/core/util/test_config.h"
@ -42,12 +43,12 @@
/* construct a buffer with some prefix followed by an integer converted to
a string */
static gpr_slice construct_buffer(size_t prefix_length, size_t index) {
gpr_slice buffer = gpr_slice_malloc(prefix_length + 32);
gpr_slice buffer = gpr_slice_malloc(prefix_length + GPR_LTOA_MIN_BUFSIZE);
memset(GPR_SLICE_START_PTR(buffer), 'a', prefix_length);
GPR_SLICE_SET_LENGTH(
buffer, prefix_length +
sprintf((char *)GPR_SLICE_START_PTR(buffer) + prefix_length,
"%d", (int)index));
buffer,
prefix_length +
gpr_ltoa(index, (char *)GPR_SLICE_START_PTR(buffer) + prefix_length));
return buffer;
}

@ -231,100 +231,91 @@ static void verify_matches(expectation *e, grpc_event *ev) {
}
}
static char *metadata_expectation_string(metadata *md) {
size_t len;
static void metadata_expectation(gpr_strvec *buf, metadata *md) {
size_t i;
char *out;
char *p;
if (!md) return gpr_strdup("nil");
for (len = 0, i = 0; i < md->count; i++) {
len += strlen(md->keys[i]);
len += strlen(md->values[i]);
}
len += 3 + md->count;
p = out = gpr_malloc(len);
*p++ = '{';
for (i = 0; i < md->count; i++) {
if (i) *p++ = ',';
p += sprintf(p, "%s:%s", md->keys[i], md->values[i]);
char *tmp;
if (!md) {
gpr_strvec_add(buf, gpr_strdup("nil"));
} else {
for (i = 0; i < md->count; i++) {
gpr_asprintf(&tmp, "%c%s:%s", i ? ',' : '{', md->keys[i], md->values[i]);
gpr_strvec_add(buf, tmp);
}
gpr_strvec_add(buf, gpr_strdup("}"));
}
*p++ = '}';
*p++ = 0;
return out;
}
static size_t expectation_to_string(char *out, expectation *e) {
static void expectation_to_strvec(gpr_strvec *buf, expectation *e) {
gpr_timespec timeout;
char *str = NULL;
size_t len;
char *tmp;
switch (e->type) {
case GRPC_FINISH_ACCEPTED:
return sprintf(out, "GRPC_FINISH_ACCEPTED result=%d",
gpr_asprintf(&tmp, "GRPC_FINISH_ACCEPTED result=%d",
e->data.finish_accepted);
gpr_strvec_add(buf, tmp);
break;
case GRPC_WRITE_ACCEPTED:
return sprintf(out, "GRPC_WRITE_ACCEPTED result=%d",
gpr_asprintf(&tmp, "GRPC_WRITE_ACCEPTED result=%d",
e->data.write_accepted);
gpr_strvec_add(buf, tmp);
break;
case GRPC_INVOKE_ACCEPTED:
return sprintf(out, "GRPC_INVOKE_ACCEPTED");
gpr_strvec_add(buf, gpr_strdup("GRPC_INVOKE_ACCEPTED"));
break;
case GRPC_SERVER_RPC_NEW:
timeout = gpr_time_sub(e->data.server_rpc_new.deadline, gpr_now());
return sprintf(out, "GRPC_SERVER_RPC_NEW method=%s host=%s timeout=%fsec",
gpr_asprintf(&tmp, "GRPC_SERVER_RPC_NEW method=%s host=%s timeout=%fsec",
e->data.server_rpc_new.method, e->data.server_rpc_new.host,
timeout.tv_sec + 1e-9 * timeout.tv_nsec);
gpr_strvec_add(buf, tmp);
break;
case GRPC_CLIENT_METADATA_READ:
str = metadata_expectation_string(e->data.client_metadata_read);
len = sprintf(out, "GRPC_CLIENT_METADATA_READ %s", str);
gpr_free(str);
return len;
gpr_strvec_add(buf, gpr_strdup("GRPC_CLIENT_METADATA_READ "));
metadata_expectation(buf, e->data.client_metadata_read);
break;
case GRPC_FINISHED:
str = metadata_expectation_string(e->data.finished.metadata);
len = sprintf(out, "GRPC_FINISHED status=%d details=%s %s",
e->data.finished.status, e->data.finished.details, str);
gpr_free(str);
return len;
gpr_asprintf(&tmp, "GRPC_FINISHED status=%d details=%s ",
e->data.finished.status, e->data.finished.details);
gpr_strvec_add(buf, tmp);
metadata_expectation(buf, e->data.finished.metadata);
break;
case GRPC_READ:
if (e->data.read) {
str =
gpr_hexdump((char *)GPR_SLICE_START_PTR(*e->data.read),
GPR_SLICE_LENGTH(*e->data.read), GPR_HEXDUMP_PLAINTEXT);
}
len = sprintf(out, "GRPC_READ data=%s", str);
gpr_free(str);
return len;
gpr_strvec_add(buf, gpr_strdup("GRPC_READ data="));
gpr_strvec_add(buf, gpr_hexdump((char *)GPR_SLICE_START_PTR(*e->data.read),
GPR_SLICE_LENGTH(*e->data.read), GPR_HEXDUMP_PLAINTEXT));
break;
case GRPC_SERVER_SHUTDOWN:
return sprintf(out, "GRPC_SERVER_SHUTDOWN");
gpr_strvec_add(buf, gpr_strdup("GRPC_SERVER_SHUTDOWN"));
break;
case GRPC_COMPLETION_DO_NOT_USE:
case GRPC_QUEUE_SHUTDOWN:
gpr_log(GPR_ERROR, "not implemented");
abort();
break;
}
return 0;
}
static char *expectations_to_string(cq_verifier *v) {
/* allocate a large buffer: we're about to crash anyway */
char *buffer = gpr_malloc(32 * 1024 * 1024);
char *p = buffer;
static void expectations_to_strvec(gpr_strvec *buf, cq_verifier *v) {
expectation *e;
for (e = v->expect.next; e != &v->expect; e = e->next) {
p += expectation_to_string(p, e);
*p++ = '\n';
expectation_to_strvec(buf, e);
gpr_strvec_add(buf, gpr_strdup("\n"));
}
*p = 0;
return buffer;
}
static void fail_no_event_received(cq_verifier *v) {
char *expectations = expectations_to_string(v);
gpr_log(GPR_ERROR, "no event received, but expected:\n%s", expectations);
gpr_free(expectations);
gpr_strvec buf;
char *msg;
gpr_strvec_init(&buf);
gpr_strvec_add(&buf, gpr_strdup("no event received, but expected:\n"));
expectations_to_strvec(&buf, v);
msg = gpr_strvec_flatten(&buf, NULL);
gpr_log(GPR_ERROR, "%s", msg);
gpr_strvec_destroy(&buf);
gpr_free(msg);
abort();
}
@ -333,9 +324,10 @@ void cq_verify(cq_verifier *v) {
gpr_time_add(gpr_now(), gpr_time_from_micros(10 * GPR_US_PER_SEC));
grpc_event *ev;
expectation *e;
char *s;
gpr_strvec have_tags;
char have_tags[512] = {0};
char *phave = have_tags;
gpr_strvec_init(&have_tags);
while (v->expect.next != &v->expect) {
ev = grpc_completion_queue_next(v->cq, deadline);
@ -344,7 +336,8 @@ void cq_verify(cq_verifier *v) {
}
for (e = v->expect.next; e != &v->expect; e = e->next) {
phave += sprintf(phave, " %p", e->tag);
gpr_asprintf(&s, " %p", e->tag);
gpr_strvec_add(&have_tags, s);
if (e->tag == ev->tag) {
verify_matches(e, ev);
e->next->prev = e->prev;
@ -354,15 +347,20 @@ void cq_verify(cq_verifier *v) {
}
}
if (e == &v->expect) {
char *s = grpc_event_string(ev);
s = grpc_event_string(ev);
gpr_log(GPR_ERROR, "event not found: %s", s);
gpr_log(GPR_ERROR, "have tags:%s", have_tags);
gpr_free(s);
s = gpr_strvec_flatten(&have_tags, NULL);
gpr_log(GPR_ERROR, "have tags:%s", s);
gpr_free(s);
gpr_strvec_destroy(&have_tags);
abort();
}
grpc_event_finish(ev);
}
gpr_strvec_destroy(&have_tags);
}
void cq_verify_empty(cq_verifier *v) {

@ -37,6 +37,7 @@
#include <string.h>
#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -145,7 +146,7 @@ static void test_body(grpc_end2end_test_fixture f) {
static void test_invoke_request_with_census(
grpc_end2end_test_config config, const char *name,
void (*body)(grpc_end2end_test_fixture f)) {
char fullname[64];
char *fullname;
grpc_end2end_test_fixture f;
grpc_arg client_arg, server_arg;
grpc_channel_args client_args, server_args;
@ -163,11 +164,12 @@ static void test_invoke_request_with_census(
server_args.num_args = 1;
server_args.args = &server_arg;
sprintf(fullname, "%s/%s", __FUNCTION__, name);
gpr_asprintf(&fullname, "%s/%s", __FUNCTION__, name);
f = begin_test(config, fullname, &client_args, &server_args);
body(f);
end_test(&f);
config.tear_down_data(&f);
gpr_free(fullname);
}
void grpc_end2end_tests(grpc_end2end_test_config config) {

@ -37,6 +37,7 @@
#include <string.h>
#include <unistd.h>
#include "src/core/support/string.h"
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -198,15 +199,16 @@ static void simple_request_body2(grpc_end2end_test_fixture f) {
static void test_invoke_simple_request(
grpc_end2end_test_config config, const char *name,
void (*body)(grpc_end2end_test_fixture f)) {
char fullname[64];
char *fullname;
grpc_end2end_test_fixture f;
sprintf(fullname, "%s/%s", __FUNCTION__, name);
gpr_asprintf(&fullname, "%s/%s", __FUNCTION__, name);
f = begin_test(config, fullname, NULL, NULL);
body(f);
end_test(&f);
config.tear_down_data(&f);
gpr_free(fullname);
}
static void test_invoke_10_simple_requests(grpc_end2end_test_config config) {

@ -498,10 +498,8 @@ static void validate_service_account_http_request(
char *expected_body = NULL;
GPR_ASSERT(body != NULL);
GPR_ASSERT(body_size != 0);
expected_body = gpr_malloc(strlen(expected_service_account_http_body_prefix) +
strlen(test_signed_jwt) + 1);
sprintf(expected_body, "%s%s", expected_service_account_http_body_prefix,
test_signed_jwt);
gpr_asprintf(&expected_body, "%s%s",
expected_service_account_http_body_prefix, test_signed_jwt);
GPR_ASSERT(strlen(expected_body) == body_size);
GPR_ASSERT(!memcmp(expected_body, body, body_size));
gpr_free(expected_body);

@ -38,6 +38,7 @@
#include "src/core/statistics/hash_table.h"
#include "src/core/support/murmur_hash.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
@ -187,15 +188,15 @@ static void test_insertion_and_deletion_with_high_collision_rate(void) {
census_ht_option opt = {CENSUS_HT_POINTER, 13, &force_collision,
&cmp_str_keys, NULL, NULL};
census_ht* ht = census_ht_create(&opt);
char key_str[1000][10];
char key_str[1000][GPR_LTOA_MIN_BUFSIZE];
gpr_uint64 val = 0;
int i = 0;
for (i = 0; i < 1000; i++) {
census_ht_key key;
key.ptr = key_str[i];
sprintf(key_str[i], "%d", i);
gpr_ltoa(i, key_str[i]);
census_ht_insert(ht, key, (void*)(&val));
printf("%d\n", i);
gpr_log(GPR_INFO, "%d\n", i);
GPR_ASSERT(census_ht_get_size(ht) == (i + 1));
}
for (i = 0; i < 1000; i++) {

@ -36,6 +36,7 @@
#include <string.h>
#include <stdio.h>
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "test/core/util/test_config.h"
@ -131,8 +132,8 @@ static void test_static_lookup(void) {
static void test_many_additions(void) {
grpc_chttp2_hptbl tbl;
int i;
char key[32];
char value[32];
char *key;
char *value;
grpc_mdctx *mdctx;
LOG_TEST();
@ -141,14 +142,18 @@ static void test_many_additions(void) {
grpc_chttp2_hptbl_init(&tbl, mdctx);
for (i = 0; i < 1000000; i++) {
sprintf(key, "K:%d", i);
sprintf(value, "VALUE:%d", i);
gpr_asprintf(&key, "K:%d", i);
gpr_asprintf(&value, "VALUE:%d", i);
grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, key, value));
assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
gpr_free(key);
gpr_free(value);
if (i) {
sprintf(key, "K:%d", i - 1);
sprintf(value, "VALUE:%d", i - 1);
gpr_asprintf(&key, "K:%d", i - 1);
gpr_asprintf(&value, "VALUE:%d", i - 1);
assert_index(&tbl, 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
gpr_free(key);
gpr_free(value);
}
}
@ -226,7 +231,7 @@ static void test_find(void) {
/* overflow the string buffer, check find still works */
for (i = 0; i < 10000; i++) {
sprintf(buffer, "%d", i);
gpr_ltoa(i, buffer);
grpc_chttp2_hptbl_add(&tbl,
grpc_mdelem_from_strings(mdctx, "test", buffer));
}
@ -245,7 +250,7 @@ static void test_find(void) {
for (i = 0; i < tbl.num_ents; i++) {
int expect = 9999 - i;
sprintf(buffer, "%d", expect);
gpr_ltoa(expect, buffer);
r = find_simple(&tbl, "test", buffer);
GPR_ASSERT(r.index == i + 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY);

@ -186,7 +186,7 @@ static void encode_int_to_str(int i, char *p) {
static void test_decode_table_overflow(void) {
int i;
char key[3], value[3];
char expect[128];
char *expect;
for (i = 0; i < 114; i++) {
if (i > 0) {
@ -197,18 +197,21 @@ static void test_decode_table_overflow(void) {
encode_int_to_str(i + 1, value);
if (i + 61 >= 127) {
sprintf(expect, "000009 0104 deadbeef ff%02x 40 02%02x%02x 02%02x%02x",
i + 61 - 127, key[0], key[1], value[0], value[1]);
gpr_asprintf(&expect,
"000009 0104 deadbeef ff%02x 40 02%02x%02x 02%02x%02x",
i + 61 - 127, key[0], key[1], value[0], value[1]);
} else if (i > 0) {
sprintf(expect, "000008 0104 deadbeef %02x 40 02%02x%02x 02%02x%02x",
0x80 + 61 + i, key[0], key[1], value[0], value[1]);
gpr_asprintf(&expect,
"000008 0104 deadbeef %02x 40 02%02x%02x 02%02x%02x",
0x80 + 61 + i, key[0], key[1], value[0], value[1]);
} else {
sprintf(expect, "000007 0104 deadbeef 40 02%02x%02x 02%02x%02x", key[0],
key[1], value[0], value[1]);
gpr_asprintf(&expect, "000007 0104 deadbeef 40 02%02x%02x 02%02x%02x",
key[0], key[1], value[0], value[1]);
}
add_sopb_header(key, value);
verify_sopb(0, 0, 0, expect);
gpr_free(expect);
}
/* if the above passes, then we must have just knocked this pair out of the

@ -36,6 +36,8 @@
#include <stdio.h>
#include <string.h>
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
#include "test/core/util/test_config.h"
@ -93,16 +95,23 @@ void decode_suite(char ext, gpr_timespec (*answer)(long x)) {
1234567, 12345678, 123456789, 98765432, 9876543, 987654,
98765, 9876, 987, 98, 9};
int i;
char input[32];
char *input;
for (i = 0; i < GPR_ARRAY_SIZE(test_vals); i++) {
sprintf(input, "%ld%c", test_vals[i], ext);
gpr_asprintf(&input, "%ld%c", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i]));
sprintf(input, " %ld%c", test_vals[i], ext);
gpr_free(input);
gpr_asprintf(&input, " %ld%c", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i]));
sprintf(input, "%ld %c", test_vals[i], ext);
gpr_free(input);
gpr_asprintf(&input, "%ld %c", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i]));
sprintf(input, "%ld %c ", test_vals[i], ext);
gpr_free(input);
gpr_asprintf(&input, "%ld %c ", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i]));
gpr_free(input);
}
}

@ -35,6 +35,7 @@
#include <stdio.h>
#include "src/core/support/string.h"
#include "src/core/transport/chttp2/bin_encoder.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -99,7 +100,7 @@ static void test_create_metadata(void) {
static void test_create_many_ephemeral_metadata(void) {
grpc_mdctx *ctx;
char buffer[256];
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
size_t mdtab_capacity_before;
@ -109,7 +110,7 @@ static void test_create_many_ephemeral_metadata(void) {
mdtab_capacity_before = grpc_mdctx_get_mdtab_capacity_test_only(ctx);
/* add, and immediately delete a bunch of different elements */
for (i = 0; i < MANY; i++) {
sprintf(buffer, "%ld", i);
gpr_ltoa(i, buffer);
grpc_mdelem_unref(grpc_mdelem_from_strings(ctx, "a", buffer));
}
/* capacity should not grow */
@ -120,7 +121,7 @@ static void test_create_many_ephemeral_metadata(void) {
static void test_create_many_persistant_metadata(void) {
grpc_mdctx *ctx;
char buffer[256];
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
grpc_mdelem **created = gpr_malloc(sizeof(grpc_mdelem *) * MANY);
grpc_mdelem *md;
@ -130,12 +131,12 @@ static void test_create_many_persistant_metadata(void) {
ctx = grpc_mdctx_create();
/* add phase */
for (i = 0; i < MANY; i++) {
sprintf(buffer, "%ld", i);
gpr_ltoa(i, buffer);
created[i] = grpc_mdelem_from_strings(ctx, "a", buffer);
}
/* verify phase */
for (i = 0; i < MANY; i++) {
sprintf(buffer, "%ld", i);
gpr_ltoa(i, buffer);
md = grpc_mdelem_from_strings(ctx, "a", buffer);
GPR_ASSERT(md == created[i]);
grpc_mdelem_unref(md);
@ -176,7 +177,7 @@ static void test_spin_creating_the_same_thing(void) {
static void test_things_stick_around(void) {
grpc_mdctx *ctx;
int i, j;
char buffer[64];
char *buffer;
int nstrs = 10000;
grpc_mdstr **strs = gpr_malloc(sizeof(grpc_mdstr *) * nstrs);
int *shuf = gpr_malloc(sizeof(int) * nstrs);
@ -187,9 +188,10 @@ static void test_things_stick_around(void) {
ctx = grpc_mdctx_create();
for (i = 0; i < nstrs; i++) {
sprintf(buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
strs[i] = grpc_mdstr_from_string(ctx, buffer);
shuf[i] = i;
gpr_free(buffer);
}
for (i = 0; i < nstrs; i++) {
@ -208,10 +210,11 @@ static void test_things_stick_around(void) {
for (i = 0; i < nstrs; i++) {
grpc_mdstr_unref(strs[shuf[i]]);
for (j = i + 1; j < nstrs; j++) {
sprintf(buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
test = grpc_mdstr_from_string(ctx, buffer);
GPR_ASSERT(test == strs[shuf[j]]);
grpc_mdstr_unref(test);
gpr_free(buffer);
}
}

@ -1,9 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/config.sh
cd $(dirname $0)/../..
for dir in src test include
do
find $dir -name '*.c' -or -name '*.cc' -or -name '*.h' | xargs $CLANG_FORMAT -i
done

@ -1,11 +0,0 @@
CLANG_FORMAT=clang-format-3.5
set -ex
if not hash $CLANG_FORMAT 2>/dev/null; then
echo "$CLANG_FORMAT is needed but not installed"
echo "perhaps try:"
echo " sudo apt-get install $CLANG_FORMAT"
exit 1
fi

@ -1,9 +1,6 @@
# Dockerfile for the gRPC Java dev image
FROM grpc/java_base
# Start the daemon that allows access to private git-on-borg repos
RUN /var/local/git/gcompute-tools/git-cookie-authdaemon
RUN cd /var/local/git/grpc-java/lib/okhttp && \
mvn -pl okhttp -am install
RUN cd /var/local/git/grpc-java/lib/netty && \
@ -13,4 +10,4 @@ RUN cd /var/local/git/grpc-java && \
mvn install
# Specify the default command such that the interop server runs on its known testing port
CMD ["/var/local/git/grpc-java/run-test-server.sh", "--transport=HTTP2_NETTY_TLS", "--grpc_version=2", "--port=8030"]
CMD ["/var/local/git/grpc-java/run-test-server.sh", "--use_tls=true", "--port=8030"]

@ -20,14 +20,24 @@ ENV M2_HOME /var/local/apache-maven-3.2.1
ENV PATH $PATH:$JAVA_HOME/bin:$M2_HOME/bin
ENV LD_LIBRARY_PATH /usr/local/lib
# Start the daemon that allows access to the protected git-on-borg repos
RUN /var/local/git/gcompute-tools/git-cookie-authdaemon
# Install a GitHub SSH service credential that gives access to the GitHub repo while it's private
# TODO: remove this once the repo is public
ADD .ssh .ssh
RUN chmod 600 .ssh/github.rsa
RUN mkdir -p $HOME/.ssh && echo 'Host github.com' > $HOME/.ssh/config
RUN echo " IdentityFile /.ssh/github.rsa" >> $HOME/.ssh/config
RUN echo 'StrictHostKeyChecking no' >> $HOME/.ssh/config
RUN git clone --recursive https://team.googlesource.com/one-platform-grpc-team/grpc-java /var/local/git/grpc-java
# Get the protobuf source from GitHub and install it
RUN git clone --recursive --branch v2.6.1 git@github.com:google/protobuf.git /var/local/git/protobuf
RUN cd /var/local/git/protobuf && \
./autogen.sh && \
./configure --prefix=/usr && \
make -j12 && make check && make install && make clean
RUN cd /var/local/git/grpc-java/lib/okhttp && \
mvn -pl okhttp -am validate
RUN cd /var/local/git/grpc-java/lib/netty && \
mvn -pl codec-http2 -am validate
RUN cd /var/local/git/grpc-java && \
mvn validate
mvn validate

@ -655,7 +655,7 @@ grpc_interop_gen_go_cmd() {
grpc_interop_gen_java_cmd() {
local cmd_prefix="sudo docker run grpc/java";
local test_script="/var/local/git/grpc-java/run-test-client.sh";
local test_script+=" --transport=NETTY_TLS --grpc_version=2"
local test_script+=" --server_host_override=foo.test.google.com --use_test_ca=true --use_tls=true"
local the_cmd="$cmd_prefix $test_script $@";
echo $the_cmd
}
@ -683,7 +683,7 @@ grpc_interop_gen_php_cmd() {
# flags= .... # generic flags to include the command
# cmd=$($grpc_gen_test_cmd $flags)
grpc_interop_gen_cxx_cmd() {
local cmd_prefix="sudo docker run grpc/cxx";
local cmd_prefix="sudo docker run grpc/cxx";
local test_script="/var/local/git/grpc/bins/opt/interop_client --enable_ssl";
local the_cmd="$cmd_prefix $test_script $@";
echo $the_cmd

@ -2,19 +2,18 @@
set -ex
CONFIG=${CONFIG:-opt}
# change to grpc repo root
cd $(dirname $0)/../..
# tells npm install to look for files in that directory
export GRPC_ROOT=`pwd`
# tells npm install the subdirectory with library files
export GRPC_LIB_SUBDIR=libs/opt
export GRPC_LIB_SUBDIR=libs/$CONFIG
# tells npm install not to use default locations
export GRPC_NO_INSTALL=yes
# build the c libraries
make -j static_c
cd src/node
npm install

@ -2,14 +2,13 @@
set -ex
CONFIG=${CONFIG:-opt}
# change to grpc repo root
cd $(dirname $0)/../..
root=`pwd`
export GRPC_LIB_SUBDIR=libs/opt
# make the libraries
make -j static_c
export GRPC_LIB_SUBDIR=libs/$CONFIG
# build php
cd src/php
@ -18,4 +17,3 @@ cd ext/grpc
phpize
./configure --enable-grpc=$root
make

@ -0,0 +1,10 @@
#!/bin/bash
set -ex
# change to grpc repo root
cd $(dirname $0)/../..
root=`pwd`
$root/src/node/node_modules/mocha/bin/mocha $root/src/node/test

@ -46,8 +46,8 @@ class CLanguage(object):
self.make_target = make_target
with open('tools/run_tests/tests.json') as f:
js = json.load(f)
self.binaries = [tgt['name']
for tgt in js
self.binaries = [tgt['name']
for tgt in js
if tgt['language'] == test_lang]
def test_binaries(self, config):
@ -59,6 +59,19 @@ class CLanguage(object):
def build_steps(self):
return []
class NodeLanguage(object):
def __init__(self):
self.allow_hashing = False
def test_binaries(self, config):
return ['tools/run_tests/run_node.sh']
def make_targets(self):
return ['static_c']
def build_steps(self):
return [['tools/run_tests/build_node.sh']]
class PhpLanguage(object):
@ -69,7 +82,7 @@ class PhpLanguage(object):
return ['src/php/bin/run_tests.sh']
def make_targets(self):
return []
return ['static_c']
def build_steps(self):
return [['tools/run_tests/build_php.sh']]
@ -107,6 +120,7 @@ _DEFAULT = ['dbg', 'opt']
_LANGUAGES = {
'c++': CLanguage('cxx', 'c++'),
'c': CLanguage('c', 'c'),
'node': NodeLanguage(),
'php': PhpLanguage(),
'python': PythonLanguage(),
}
@ -190,8 +204,8 @@ class TestCache(object):
def _build_and_run(check_cancelled, newline_on_success, cache):
"""Do one pass of building & running tests."""
# build latest, sharing cpu between the various makes
if not jobset.run(build_steps):
# build latest sequentially
if not jobset.run(build_steps, maxjobs=1):
return 1
# run all the tests

Loading…
Cancel
Save