Resolved merge conflicts

pull/3558/head
murgatroid99 9 years ago
commit 47f519ece2
  1. 0
      .istanbul.yml
  2. 95
      binding.gyp
  3. 2729
      build.json
  4. 2
      examples/node/greeter_client.js
  5. 2
      examples/node/greeter_server.js
  6. 10
      examples/node/package.json
  7. 4
      examples/node/route_guide/route_guide_client.js
  8. 4
      examples/node/route_guide/route_guide_server.js
  9. 55
      examples/python/README.md
  10. 202
      examples/python/helloworld/helloworld_pb2.py
  11. 12368
      grpc.gyp
  12. 39
      package.json
  13. 2
      src/core/channel/client_channel.c
  14. 47
      src/core/client_config/lb_policies/pick_first.c
  15. 24
      src/core/iomgr/closure.c
  16. 3
      src/core/iomgr/closure.h
  17. 2
      src/core/iomgr/tcp_server_windows.c
  18. 28
      src/node/LICENSE
  19. 36
      src/node/README.md
  20. 101
      src/node/binding.gyp
  21. 2
      src/node/ext/node_grpc.cc
  22. 3
      src/node/index.js
  23. 43
      src/node/interop/empty.proto
  24. 4
      src/node/interop/interop_client.js
  25. 4
      src/node/interop/interop_server.js
  26. 132
      src/node/interop/messages.proto
  27. 72
      src/node/interop/test.proto
  28. 4
      src/node/src/client.js
  29. 2
      src/node/src/credentials.js
  30. 2
      src/node/src/server.js
  31. 2
      src/node/test/call_test.js
  32. 2
      src/node/test/channel_test.js
  33. 2
      src/node/test/constant_test.js
  34. 2
      src/node/test/end_to_end_test.js
  35. 2
      src/node/test/server_test.js
  36. 2
      src/node/test/surface_test.js
  37. 29
      templates/grpc.gyp.template
  38. 7
      tools/jenkins/build_docker_and_run_tests.sh
  39. 4
      tools/jenkins/docker_run_tests.sh
  40. 5
      tools/jenkins/grpc_jenkins_slave/Dockerfile
  41. 5
      tools/run_tests/build_node.sh
  42. 49
      tools/run_tests/build_python.sh
  43. 19
      tools/run_tests/port_server.py
  44. 12
      tools/run_tests/run_node.sh
  45. 63
      tools/run_tests/run_tests.py

@ -0,0 +1,95 @@
# 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.
{
"variables" : {
'config': '<!(echo $CONFIG)'
},
"targets" : [
{
'include_dirs': [
"<!(node -e \"require('nan')\")"
],
'cflags': [
'-std=c++0x',
'-Wall',
'-pthread',
'-g',
'-zdefs',
'-Werror',
'-Wno-error=deprecated-declarations'
],
'ldflags': [
'-g'
],
"conditions": [
['OS != "win"', {
'conditions': [
['config=="gcov"', {
'cflags': [
'-ftest-coverage',
'-fprofile-arcs',
'-O0'
],
'ldflags': [
'-ftest-coverage',
'-fprofile-arcs'
]
}
]
]
}],
['OS == "mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.9',
'OTHER_CFLAGS': [
'-std=c++11',
'-stdlib=libc++'
]
}
}]
],
"target_name": "grpc_node",
"sources": [
"src/node/ext/byte_buffer.cc",
"src/node/ext/call.cc",
"src/node/ext/call_credentials.cc",
"src/node/ext/channel.cc",
"src/node/ext/channel_credentials.cc",
"src/node/ext/completion_queue_async_worker.cc",
"src/node/ext/node_grpc.cc",
"src/node/ext/server.cc",
"src/node/ext/server_credentials.cc",
"src/node/ext/timeval.cc"
],
"dependencies": [
"grpc.gyp:grpc"
]
}
]
}

File diff suppressed because it is too large Load Diff

@ -33,7 +33,7 @@
var PROTO_PATH = __dirname + '/helloworld.proto'; var PROTO_PATH = __dirname + '/helloworld.proto';
var grpc = require('grpc'); var grpc = require('../../');
var hello_proto = grpc.load(PROTO_PATH).helloworld; var hello_proto = grpc.load(PROTO_PATH).helloworld;
function main() { function main() {

@ -33,7 +33,7 @@
var PROTO_PATH = __dirname + '/helloworld.proto'; var PROTO_PATH = __dirname + '/helloworld.proto';
var grpc = require('grpc'); var grpc = require('../../');
var hello_proto = grpc.load(PROTO_PATH).helloworld; var hello_proto = grpc.load(PROTO_PATH).helloworld;
/** /**

@ -1,10 +0,0 @@
{
"name": "grpc-demo",
"version": "0.11.0",
"dependencies": {
"async": "^0.9.0",
"grpc": "~0.11.0",
"minimist": "^1.1.0",
"underscore": "^1.8.2"
}
}

@ -31,8 +31,8 @@ var async = require('async');
var fs = require('fs'); var fs = require('fs');
var parseArgs = require('minimist'); var parseArgs = require('minimist');
var path = require('path'); var path = require('path');
var _ = require('underscore'); var _ = require('lodash');
var grpc = require('grpc'); var grpc = require('../../../');
var routeguide = grpc.load(__dirname + '/route_guide.proto').routeguide; var routeguide = grpc.load(__dirname + '/route_guide.proto').routeguide;
var client = new routeguide.RouteGuide('localhost:50051', var client = new routeguide.RouteGuide('localhost:50051',
grpc.Credentials.createInsecure()); grpc.Credentials.createInsecure());

@ -30,8 +30,8 @@
var fs = require('fs'); var fs = require('fs');
var parseArgs = require('minimist'); var parseArgs = require('minimist');
var path = require('path'); var path = require('path');
var _ = require('underscore'); var _ = require('lodash');
var grpc = require('grpc'); var grpc = require('../../../');
var routeguide = grpc.load(__dirname + '/route_guide.proto').routeguide; var routeguide = grpc.load(__dirname + '/route_guide.proto').routeguide;
var COORD_FACTOR = 1e7; var COORD_FACTOR = 1e7;

@ -0,0 +1,55 @@
gRPC in 3 minutes (Python)
========================
Background
-------------
For this sample, we've already generated the server and client stubs from
[helloworld.proto][] and we'll be using a specific reference platform.
Prerequisites
-------------
- Debian 8.2 "Jessie" platform with `root` access
- `git`
- `python2.7`
- `pip`
- Python development headers
Set-up
-------
```sh
$ # install the gRPC Core:
$ sudo apt-get install libgrpc-dev
$ # install gRPC Python:
$ sudo pip install -U grpcio==0.11.0b1
$ # Since this "hello, world" example uses protocol buffers:
$ sudo pip install -U protobuf==3.0.0a3
$ # Clone the repository to get the example code:
$ git clone https://github.com/grpc/grpc
$ # Navigate to the "hello, world" Python example:
$ cd grpc/examples/python/helloworld
```
Try it!
-------
- Run the server
```sh
$ python2.7 greeter_server.py &
```
- Run the client
```sh
$ python2.7 greeter_client.py
```
Tutorial
--------
You can find a more detailed tutorial in [gRPC Basics: Python][]
[helloworld.proto]:../protos/helloworld.proto
[Install gRPC Python]:../../src/python#installation
[gRPC Basics: Python]:http://www.grpc.io/docs/tutorials/basic/python.html

@ -0,0 +1,202 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='helloworld.proto',
package='helloworld',
syntax='proto3',
serialized_pb=b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x18\n\x10io.grpc.examples\xa2\x02\x03HLWb\x06proto3'
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
_HELLOREQUEST = _descriptor.Descriptor(
name='HelloRequest',
full_name='helloworld.HelloRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='helloworld.HelloRequest.name', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=32,
serialized_end=60,
)
_HELLOREPLY = _descriptor.Descriptor(
name='HelloReply',
full_name='helloworld.HelloReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='message', full_name='helloworld.HelloReply.message', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=62,
serialized_end=91,
)
DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(
DESCRIPTOR = _HELLOREQUEST,
__module__ = 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:helloworld.HelloRequest)
))
_sym_db.RegisterMessage(HelloRequest)
HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict(
DESCRIPTOR = _HELLOREPLY,
__module__ = 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:helloworld.HelloReply)
))
_sym_db.RegisterMessage(HelloReply)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), b'\n\020io.grpc.examples\242\002\003HLW')
import abc
from grpc.beta import implementations as beta_implementations
from grpc.early_adopter import implementations as early_adopter_implementations
from grpc.framework.alpha import utilities as alpha_utilities
from grpc.framework.common import cardinality
from grpc.framework.interfaces.face import utilities as face_utilities
class EarlyAdopterGreeterServicer(object):
"""<fill me in later!>"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def SayHello(self, request, context):
raise NotImplementedError()
class EarlyAdopterGreeterServer(object):
"""<fill me in later!>"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def start(self):
raise NotImplementedError()
@abc.abstractmethod
def stop(self):
raise NotImplementedError()
class EarlyAdopterGreeterStub(object):
"""<fill me in later!>"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def SayHello(self, request):
raise NotImplementedError()
SayHello.async = None
def early_adopter_create_Greeter_server(servicer, port, private_key=None, certificate_chain=None):
import helloworld_pb2
import helloworld_pb2
method_service_descriptions = {
"SayHello": alpha_utilities.unary_unary_service_description(
servicer.SayHello,
helloworld_pb2.HelloRequest.FromString,
helloworld_pb2.HelloReply.SerializeToString,
),
}
return early_adopter_implementations.server("helloworld.Greeter", method_service_descriptions, port, private_key=private_key, certificate_chain=certificate_chain)
def early_adopter_create_Greeter_stub(host, port, metadata_transformer=None, secure=False, root_certificates=None, private_key=None, certificate_chain=None, server_host_override=None):
import helloworld_pb2
import helloworld_pb2
method_invocation_descriptions = {
"SayHello": alpha_utilities.unary_unary_invocation_description(
helloworld_pb2.HelloRequest.SerializeToString,
helloworld_pb2.HelloReply.FromString,
),
}
return early_adopter_implementations.stub("helloworld.Greeter", method_invocation_descriptions, host, port, metadata_transformer=metadata_transformer, secure=secure, root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain, server_host_override=server_host_override)
class BetaGreeterServicer(object):
"""<fill me in later!>"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def SayHello(self, request, context):
raise NotImplementedError()
class BetaGreeterStub(object):
"""The interface to which stubs will conform."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def SayHello(self, request, timeout):
raise NotImplementedError()
SayHello.future = None
def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
import helloworld_pb2
import helloworld_pb2
request_deserializers = {
('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloRequest.FromString,
}
response_serializers = {
('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloReply.SerializeToString,
}
method_implementations = {
('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
}
server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
return beta_implementations.server(method_implementations, options=server_options)
def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
import helloworld_pb2
import helloworld_pb2
request_serializers = {
('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloRequest.SerializeToString,
}
response_deserializers = {
('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloReply.FromString,
}
cardinalities = {
'SayHello': cardinality.Cardinality.UNARY_UNARY,
}
stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
# @@protoc_insertion_point(module_scope)

12368
grpc.gyp

File diff suppressed because it is too large Load Diff

@ -16,14 +16,13 @@
} }
], ],
"directories": { "directories": {
"lib": "src", "lib": "src/node/src"
"example": "examples"
}, },
"scripts": { "scripts": {
"lint": "node ./node_modules/jshint/bin/jshint src test examples interop index.js", "lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/examples src/node/interop src/node/index.js",
"test": "./node_modules/.bin/mocha && npm run-script lint", "test": "./node_modules/.bin/mocha src/node/test && npm run-script lint",
"gen_docs": "./node_modules/.bin/jsdoc -c jsdoc_conf.json", "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
"coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha" "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test"
}, },
"dependencies": { "dependencies": {
"bindings": "^1.2.0", "bindings": "^1.2.0",
@ -47,18 +46,22 @@
}, },
"files": [ "files": [
"LICENSE", "LICENSE",
"README.md", "src/node/README.md",
"index.js", "src/node/index.js",
"binding.gyp", "src/node/bin",
"bin", "src/node/cli",
"cli", "src/node/examples",
"examples", "src/node/ext",
"ext", "src/node/health_check",
"health_check", "src/node/interop",
"interop", "src/node/src",
"src", "src/node/test",
"test" "src/core",
"test/proto",
"include",
"grpc.gyp",
"binding.gyp"
], ],
"main": "index.js", "main": "src/node/index.js",
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
} }

@ -51,7 +51,7 @@
typedef struct call_data call_data; typedef struct call_data call_data;
typedef struct { typedef struct client_channel_channel_data {
/** metadata context for this channel */ /** metadata context for this channel */
grpc_mdctx *mdctx; grpc_mdctx *mdctx;
/** resolver for this channel */ /** resolver for this channel */

@ -101,6 +101,9 @@ void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
for (i = 0; i < p->num_subchannels; i++) { for (i = 0; i < p->num_subchannels; i++) {
GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i], "pick_first"); GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i], "pick_first");
} }
if (p->selected) {
GRPC_SUBCHANNEL_UNREF(exec_ctx, p->selected, "picked_first");
}
grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker); grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
gpr_free(p->subchannels); gpr_free(p->subchannels);
gpr_mu_destroy(&p->mu); gpr_mu_destroy(&p->mu);
@ -172,6 +175,35 @@ void pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
} }
} }
static void destroy_subchannels(grpc_exec_ctx *exec_ctx, void *arg,
int iomgr_success) {
pick_first_lb_policy *p = arg;
size_t i;
grpc_transport_op op;
size_t num_subchannels = p->num_subchannels;
grpc_subchannel **subchannels;
grpc_subchannel *exclude_subchannel;
gpr_mu_lock(&p->mu);
subchannels = p->subchannels;
p->num_subchannels = 0;
p->subchannels = NULL;
exclude_subchannel = p->selected;
gpr_mu_unlock(&p->mu);
GRPC_LB_POLICY_UNREF(exec_ctx, &p->base, "destroy_subchannels");
for (i = 0; i < num_subchannels; i++) {
if (subchannels[i] != exclude_subchannel) {
memset(&op, 0, sizeof(op));
op.disconnect = 1;
grpc_subchannel_process_transport_op(exec_ctx, subchannels[i], &op);
}
GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pick_first");
}
gpr_free(subchannels);
}
static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
int iomgr_success) { int iomgr_success) {
pick_first_lb_policy *p = arg; pick_first_lb_policy *p = arg;
@ -200,6 +232,11 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_READY, "connecting_ready"); GRPC_CHANNEL_READY, "connecting_ready");
p->selected = p->subchannels[p->checking_subchannel]; p->selected = p->subchannels[p->checking_subchannel];
GRPC_SUBCHANNEL_REF(p->selected, "picked_first");
/* drop the pick list: we are connected now */
GRPC_LB_POLICY_REF(&p->base, "destroy_subchannels");
grpc_exec_ctx_enqueue(exec_ctx, grpc_closure_create(destroy_subchannels, p), 1);
/* update any calls that were waiting for a pick */
while ((pp = p->pending_picks)) { while ((pp = p->pending_picks)) {
p->pending_picks = pp->next; p->pending_picks = pp->next;
*pp->target = p->selected; *pp->target = p->selected;
@ -279,10 +316,15 @@ static void pf_broadcast(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
size_t i; size_t i;
size_t n; size_t n;
grpc_subchannel **subchannels; grpc_subchannel **subchannels;
grpc_subchannel *selected;
gpr_mu_lock(&p->mu); gpr_mu_lock(&p->mu);
n = p->num_subchannels; n = p->num_subchannels;
subchannels = gpr_malloc(n * sizeof(*subchannels)); subchannels = gpr_malloc(n * sizeof(*subchannels));
selected = p->selected;
if (selected) {
GRPC_SUBCHANNEL_REF(selected, "pf_broadcast_to_selected");
}
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
subchannels[i] = p->subchannels[i]; subchannels[i] = p->subchannels[i];
GRPC_SUBCHANNEL_REF(subchannels[i], "pf_broadcast"); GRPC_SUBCHANNEL_REF(subchannels[i], "pf_broadcast");
@ -290,9 +332,14 @@ static void pf_broadcast(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
gpr_mu_unlock(&p->mu); gpr_mu_unlock(&p->mu);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (selected == subchannels[i]) continue;
grpc_subchannel_process_transport_op(exec_ctx, subchannels[i], op); grpc_subchannel_process_transport_op(exec_ctx, subchannels[i], op);
GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pf_broadcast"); GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pf_broadcast");
} }
if (p->selected) {
grpc_subchannel_process_transport_op(exec_ctx, selected, op);
GRPC_SUBCHANNEL_UNREF(exec_ctx, selected, "pf_broadcast_to_selected");
}
gpr_free(subchannels); gpr_free(subchannels);
} }

@ -33,6 +33,8 @@
#include "src/core/iomgr/closure.h" #include "src/core/iomgr/closure.h"
#include <grpc/support/alloc.h>
void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
void *cb_arg) { void *cb_arg) {
closure->cb = cb; closure->cb = cb;
@ -69,3 +71,25 @@ void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst) {
} }
src->head = src->tail = NULL; src->head = src->tail = NULL;
} }
typedef struct {
grpc_iomgr_cb_func cb;
void *cb_arg;
grpc_closure wrapper;
} wrapped_closure;
static void closure_wrapper(grpc_exec_ctx *exec_ctx, void *arg, int success) {
wrapped_closure *wc = arg;
grpc_iomgr_cb_func cb = wc->cb;
void *cb_arg = wc->cb_arg;
gpr_free(wc);
cb(exec_ctx, cb_arg, success);
}
grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) {
wrapped_closure *wc = gpr_malloc(sizeof(*wc));
wc->cb = cb;
wc->cb_arg = cb_arg;
grpc_closure_init(&wc->wrapper, closure_wrapper, wc);
return &wc->wrapper;
}

@ -77,6 +77,9 @@ struct grpc_closure {
void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
void *cb_arg); void *cb_arg);
/* Create a heap allocated closure: try to avoid except for very rare events */
grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg);
#define GRPC_CLOSURE_LIST_INIT \ #define GRPC_CLOSURE_LIST_INIT \
{ NULL, NULL } { NULL, NULL }

@ -336,6 +336,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, int from_iocp) {
peer_name_string); peer_name_string);
gpr_free(fd_name); gpr_free(fd_name);
gpr_free(peer_name_string); gpr_free(peer_name_string);
} else {
closesocket(sock);
} }
} }

@ -1,28 +0,0 @@
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.

@ -5,51 +5,19 @@ Beta
## PREREQUISITES ## PREREQUISITES
- `node`: This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package. - `node`: This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package.
- [homebrew][] on Mac OS X. These simplify the installation of the gRPC C core.
## INSTALLATION ## INSTALLATION
**Linux (Debian):**
Add [Debian jessie-backports][] to your `sources.list` file. Example:
```sh
echo "deb http://http.debian.net/debian jessie-backports main" | \
sudo tee -a /etc/apt/sources.list
```
Install the gRPC Debian package
```sh
sudo apt-get update
sudo apt-get install libgrpc-dev
```
Install the gRPC NPM package Install the gRPC NPM package
```sh ```sh
npm install grpc npm install grpc
``` ```
**Mac OS X**
Install [homebrew][]. Run the following command to install gRPC Node.js.
```sh
$ curl -fsSL https://goo.gl/getgrpc | bash -s nodejs
```
This will download and run the [gRPC install script][], then install the latest version of gRPC Nodejs npm package.
## BUILD FROM SOURCE ## BUILD FROM SOURCE
1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc).
2. Follow the instructions in the `INSTALL` file in the root of that repository to install the C core library that this package depends on.
3. Run `npm install`. 3. Run `npm install`.
If you install the gRPC C core library in a custom location, then you need to set some environment variables to install this library. The command will look like this:
```sh
CXXFLAGS=-I<custom location>/include LDFLAGS=-L<custom location>/lib npm install [grpc]
```
## TESTING ## TESTING
To run the test suite, simply run `npm test` in the install location. To run the test suite, simply run `npm test` in the install location.
@ -110,7 +78,3 @@ ServerCredentials
``` ```
An object with factory methods for creating credential objects for servers. An object with factory methods for creating credential objects for servers.
[homebrew]:http://brew.sh
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[Debian jessie-backports]:http://backports.debian.org/Instructions/

@ -1,101 +0,0 @@
{
"variables" : {
'config': '<!(echo $CONFIG)'
},
"targets" : [
{
'include_dirs': [
"<!(node -e \"require('nan')\")"
],
'cflags': [
'-std=c++0x',
'-Wall',
'-pthread',
'-g',
'-zdefs',
'-Werror',
'-Wno-error=deprecated-declarations'
],
'ldflags': [
'-g'
],
"conditions": [
['OS != "win"', {
'variables': {
'pkg_config_grpc': '<!(pkg-config --exists grpc >/dev/null 2>&1 && echo true || echo false)'
},
'conditions': [
['config=="gcov"', {
'cflags': [
'-ftest-coverage',
'-fprofile-arcs',
'-O0'
],
'ldflags': [
'-ftest-coverage',
'-fprofile-arcs'
]
}
],
['pkg_config_grpc == "true"', {
'link_settings': {
'libraries': [
'<!@(pkg-config --libs-only-l --static grpc)'
]
},
'cflags': [
'<!@(pkg-config --cflags grpc)'
],
'libraries': [
'<!@(pkg-config --libs-only-L --static grpc)'
],
'ldflags': [
'<!@(pkg-config --libs-only-other --static grpc)'
]
}, {
'link_settings': {
'libraries': [
'-lpthread',
'-lgrpc',
'-lgpr'
],
},
'conditions':[
['OS != "mac"', {
'link_settings': {
'libraries': [
'-lrt'
]
}
}]
]
}
]
]
}],
['OS == "mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.9',
'OTHER_CFLAGS': [
'-std=c++11',
'-stdlib=libc++'
]
}
}]
],
"target_name": "grpc",
"sources": [
"ext/byte_buffer.cc",
"ext/call.cc",
"ext/call_credentials.cc",
"ext/channel.cc",
"ext/channel_credentials.cc",
"ext/completion_queue_async_worker.cc",
"ext/node_grpc.cc",
"ext/server.cc",
"ext/server_credentials.cc",
"ext/timeval.cc"
]
}
]
}

@ -249,4 +249,4 @@ void init(Local<Object> exports) {
grpc::node::ServerCredentials::Init(exports); grpc::node::ServerCredentials::Init(exports);
} }
NODE_MODULE(grpc, init) NODE_MODULE(grpc_node, init)

@ -43,7 +43,7 @@ var server = require('./src/server.js');
var Metadata = require('./src/metadata.js'); var Metadata = require('./src/metadata.js');
var grpc = require('bindings')('grpc'); var grpc = require('bindings')('grpc_node');
/** /**
* Load a gRPC object from an existing ProtoBuf.Reflect object. * Load a gRPC object from an existing ProtoBuf.Reflect object.
@ -90,7 +90,6 @@ exports.load = function load(filename, format) {
default: default:
throw new Error('Unrecognized format "' + format + '"'); throw new Error('Unrecognized format "' + format + '"');
} }
return loadObject(builder.ns); return loadObject(builder.ns);
}; };

@ -1,43 +0,0 @@
// 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.
syntax = "proto3";
package grpc.testing;
// An empty message that you can re-use to avoid defining duplicated empty
// messages in your project. A typical example is to use it as argument or the
// return value of a service API. For instance:
//
// service Foo {
// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
// };
//
message Empty {}

@ -37,7 +37,9 @@ var fs = require('fs');
var path = require('path'); var path = require('path');
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('..'); var grpc = require('..');
var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; var testProto = grpc.load({
root: __dirname + '/../../..',
file: 'test/proto/test.proto'}).grpc.testing;
var GoogleAuth = require('google-auth-library'); var GoogleAuth = require('google-auth-library');
var assert = require('assert'); var assert = require('assert');

@ -37,7 +37,9 @@ var fs = require('fs');
var path = require('path'); var path = require('path');
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('..'); var grpc = require('..');
var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; var testProto = grpc.load({
root: __dirname + '/../../..',
file: 'test/proto/test.proto'}).grpc.testing;
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial'; var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin'; var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';

@ -1,132 +0,0 @@
// 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.
// Message definitions to be used by integration test service definitions.
syntax = "proto3";
package grpc.testing;
// The type of payload that should be returned.
enum PayloadType {
// Compressable text format.
COMPRESSABLE = 0;
// Uncompressable binary format.
UNCOMPRESSABLE = 1;
// Randomly chosen from all other formats defined in this enum.
RANDOM = 2;
}
// A block of data, to simply increase gRPC message size.
message Payload {
// The type of data in body.
PayloadType type = 1;
// Primary contents of payload.
bytes body = 2;
}
// Unary request.
message SimpleRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
PayloadType response_type = 1;
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
int32 response_size = 2;
// Optional input payload sent along with the request.
Payload payload = 3;
// Whether SimpleResponse should include username.
bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope.
bool fill_oauth_scope = 5;
}
// Unary response, as configured by the request.
message SimpleResponse {
// Payload to increase message size.
Payload payload = 1;
// The user the request came from, for verifying authentication was
// successful when the client expected it.
string username = 2;
// OAuth scope.
string oauth_scope = 3;
}
// Client-streaming request.
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
Payload payload = 1;
// Not expecting any payload from the response.
}
// Client-streaming response.
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
int32 aggregated_payload_size = 1;
}
// Configuration for a particular response.
message ResponseParameters {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
int32 interval_us = 2;
}
// Server-streaming request.
message StreamingOutputCallRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
PayloadType response_type = 1;
// Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
Payload payload = 3;
}
// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
// Payload to increase response size.
Payload payload = 1;
}

@ -1,72 +0,0 @@
// 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.
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto3";
import "empty.proto";
import "messages.proto";
package grpc.testing;
// A simple service to test the various types of RPCs and experiment with
// performance with various types of payload.
service TestService {
// One empty request followed by one empty response.
rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
// One request followed by one response.
rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
rpc StreamingOutputCall(StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
rpc StreamingInputCall(stream StreamingInputCallRequest)
returns (StreamingInputCallResponse);
// A sequence of requests with each request served by the server immediately.
// As one request could lead to multiple responses, this interface
// demonstrates the idea of full duplexing.
rpc FullDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by a sequence of responses.
// The server buffers all the client requests and then serves them in order. A
// stream of responses are returned to the client when the server starts with
// first request.
rpc HalfDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
}

@ -40,7 +40,7 @@
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
var common = require('./common'); var common = require('./common');
@ -54,7 +54,7 @@ var Readable = stream.Readable;
var Writable = stream.Writable; var Writable = stream.Writable;
var Duplex = stream.Duplex; var Duplex = stream.Duplex;
var util = require('util'); var util = require('util');
var version = require('../package.json').version; var version = require('../../../package.json').version;
util.inherits(ClientWritableStream, Writable); util.inherits(ClientWritableStream, Writable);

@ -38,7 +38,7 @@
'use strict'; 'use strict';
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node.node');
var CallCredentials = grpc.CallCredentials; var CallCredentials = grpc.CallCredentials;

@ -40,7 +40,7 @@
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
var common = require('./common'); var common = require('./common');

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* Helper function to return an absolute deadline given a relative timeout in * Helper function to return an absolute deadline given a relative timeout in

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* This is used for testing functions with multiple asynchronous calls that * This is used for testing functions with multiple asynchronous calls that

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* List of all status names * List of all status names

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* This is used for testing functions with multiple asynchronous calls that * This is used for testing functions with multiple asynchronous calls that

@ -36,7 +36,7 @@
var assert = require('assert'); var assert = require('assert');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
describe('server', function() { describe('server', function() {
describe('constructor', function() { describe('constructor', function() {

@ -356,7 +356,7 @@ describe('Echo metadata', function() {
call.end(); call.end();
}); });
it('shows the correct user-agent string', function(done) { it('shows the correct user-agent string', function(done) {
var version = require('../package.json').version; var version = require('../../../package.json').version;
var call = client.unary({}, function(err, data) { assert.ifError(err); }, var call = client.unary({}, function(err, data) { assert.ifError(err); },
metadata); metadata);
call.on('metadata', function(metadata) { call.on('metadata', function(metadata) {

@ -80,12 +80,17 @@
'-ldl', '-ldl',
'-lpthread', '-lpthread',
'-lz' '-lz'
] ],
'direct_dependent_settings': {
'include_dirs': [
'.',
'include'
],
}
}, },
'targets': [ 'targets': [
% for lib in libs: % for lib in libs:
# TODO: Add C++ targets % if lib.name == 'gpr' or lib.name == 'grpc':
% if lib.language == 'c':
{ {
'target_name': '${lib.name}', 'target_name': '${lib.name}',
'product_prefix': 'lib', 'product_prefix': 'lib',
@ -103,23 +108,5 @@
}, },
% endif % endif
% endfor % endfor
% for tgt in targets:
% if tgt.language == 'c':
{
'target_name': '${tgt.name}',
'type': 'executable',
'dependencies': [
% for dep in getattr(tgt, 'deps', []):
'${dep}',
% endfor
],
'sources': [
% for source in tgt.src:
'${source}',
% endfor
]
},
% endif
% endfor
] ]
} }

@ -37,8 +37,13 @@ cd `dirname $0`/../..
git_root=`pwd` git_root=`pwd`
cd - cd -
# Ensure existence of ccache directory
mkdir -p /tmp/ccache mkdir -p /tmp/ccache
# Ensure existence of the home directory for XDG caches (e.g. what pip uses for
# its cache location now that --download-cache is deprecated).
mkdir -p /tmp/xdg-cache-home
# Create a local branch so the child Docker script won't complain # Create a local branch so the child Docker script won't complain
git branch -f jenkins-docker git branch -f jenkins-docker
@ -57,9 +62,11 @@ docker run \
-e "config=$config" \ -e "config=$config" \
-e "arch=$arch" \ -e "arch=$arch" \
-e CCACHE_DIR=/tmp/ccache \ -e CCACHE_DIR=/tmp/ccache \
-e XDG_CACHE_HOME=/tmp/xdg-cache-home \
-i $TTY_FLAG \ -i $TTY_FLAG \
-v "$git_root:/var/local/jenkins/grpc" \ -v "$git_root:/var/local/jenkins/grpc" \
-v /tmp/ccache:/tmp/ccache \ -v /tmp/ccache:/tmp/ccache \
-v /tmp/xdg-cache-home:/tmp/xdg-cache-home \
-v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/bin/docker \ -v $(which docker):/bin/docker \
-w /var/local/git/grpc \ -w /var/local/git/grpc \

@ -36,6 +36,10 @@ set -e
export CONFIG=$config export CONFIG=$config
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.5 export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.5
# Ensure that programs depending on current-user-ownership of cache directories
# are satisfied (it's being mounted from outside the image).
chown `whoami` $XDG_CACHE_HOME
mkdir -p /var/local/git mkdir -p /var/local/git
git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc

@ -126,10 +126,11 @@ RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
python-all-dev \ python-all-dev \
python3-all-dev \ python3-all-dev \
python-pip \ python-pip
python-virtualenv
# Install Python packages from PyPI # Install Python packages from PyPI
RUN pip install pip --upgrade
RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2
# For sanity test # For sanity test

@ -36,9 +36,4 @@ CONFIG=${CONFIG:-opt}
# change to grpc repo root # change to grpc repo root
cd $(dirname $0)/../.. cd $(dirname $0)/../..
export CXXFLAGS=-I`pwd`/include
export LDFLAGS=-L`pwd`/libs/$CONFIG
cd src/node
npm install --unsafe-perm npm install --unsafe-perm

@ -39,6 +39,33 @@ GRPCIO=$ROOT/src/python/grpcio
GRPCIO_TEST=$ROOT/src/python/grpcio_test GRPCIO_TEST=$ROOT/src/python/grpcio_test
GRPCIO_HEALTH_CHECKING=$ROOT/src/python/grpcio_health_checking GRPCIO_HEALTH_CHECKING=$ROOT/src/python/grpcio_health_checking
install_grpcio_deps() {
cd $GRPCIO
pip install -r requirements.txt
}
install_grpcio_test_deps() {
cd $GRPCIO_TEST
pip install -r requirements.txt
}
install_grpcio() {
CFLAGS="-I$ROOT/include -std=c89" LDFLAGS=-L$ROOT/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install $GRPCIO
}
install_grpcio_test() {
pip install $GRPCIO_TEST
}
install_grpcio_health_checking() {
pip install $GRPCIO_HEALTH_CHECKING
}
# Cleans the environment of previous installations
clean_grpcio_all() {
(yes | pip uninstall grpcio) || true
(yes | pip uninstall grpcio_test) || true
(yes | pip uninstall grpcio_health_checking) || true
}
# Builds the testing environment.
make_virtualenv() { make_virtualenv() {
virtualenv_name="python"$1"_virtual_environment" virtualenv_name="python"$1"_virtual_environment"
if [ ! -d $virtualenv_name ] if [ ! -d $virtualenv_name ]
@ -48,33 +75,29 @@ make_virtualenv() {
source $virtualenv_name/bin/activate source $virtualenv_name/bin/activate
# Install grpcio # Install grpcio
cd $GRPCIO install_grpcio_deps
pip install -r requirements.txt install_grpcio
CFLAGS="-I$ROOT/include -std=c89" LDFLAGS=-L$ROOT/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install $GRPCIO
# Install grpcio_test # Install grpcio_test
cd $GRPCIO_TEST install_grpcio_test_deps
pip install -r requirements.txt install_grpcio_test
pip install $GRPCIO_TEST
# Install grpcio_health_checking # Install grpcio_health_checking
pip install $GRPCIO_HEALTH_CHECKING install_grpcio_health_checking
else else
source $virtualenv_name/bin/activate source $virtualenv_name/bin/activate
# Uninstall and re-install the packages we care about. Don't use # Uninstall and re-install the packages we care about. Don't use
# --force-reinstall or --ignore-installed to avoid propagating this # --force-reinstall or --ignore-installed to avoid propagating this
# unnecessarily to dependencies. Don't use --no-deps to avoid missing # unnecessarily to dependencies. Don't use --no-deps to avoid missing
# dependency upgrades. # dependency upgrades.
(yes | pip uninstall grpcio) || true clean_grpcio_all
(yes | pip uninstall grpcio_test) || true install_grpcio || (
(yes | pip uninstall grpcio_health_checking) || true
(CFLAGS="-I$ROOT/include -std=c89" LDFLAGS=-L$ROOT/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install $GRPCIO) || (
# Fall back to rebuilding the entire environment # Fall back to rebuilding the entire environment
rm -rf $virtualenv_name rm -rf $virtualenv_name
make_virtualenv $1 make_virtualenv $1
) )
pip install $GRPCIO_TEST install_grpcio_test
pip install $GRPCIO_HEALTH_CHECKING install_grpcio_health_checking
fi fi
} }

@ -38,6 +38,18 @@ import socket
import sys import sys
import time import time
# increment this number whenever making a change to ensure that
# the changes are picked up by running CI servers
# note that all changes must be backwards compatible
_MY_VERSION = 2
if len(sys.argv) == 2 and sys.argv[1] == 'dump_version':
print _MY_VERSION
sys.exit(0)
argp = argparse.ArgumentParser(description='Server for httpcli_test') argp = argparse.ArgumentParser(description='Server for httpcli_test')
argp.add_argument('-p', '--port', default=12345, type=int) argp.add_argument('-p', '--port', default=12345, type=int)
args = argp.parse_args() args = argp.parse_args()
@ -47,9 +59,6 @@ print 'port server running on port %d' % args.port
pool = [] pool = []
in_use = {} in_use = {}
with open(__file__) as f:
_MY_VERSION = hashlib.sha1(f.read()).hexdigest()
def refill_pool(max_timeout, req): def refill_pool(max_timeout, req):
"""Scan for ports not marked for being in use""" """Scan for ports not marked for being in use"""
@ -113,7 +122,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
del in_use[p] del in_use[p]
pool.append(p) pool.append(p)
self.log_message('drop port %d' % p) self.log_message('drop port %d' % p)
elif self.path == '/version': elif self.path == '/version_number':
# fetch a version string and the current process pid # fetch a version string and the current process pid
self.send_response(200) self.send_response(200)
self.send_header('Content-Type', 'text/plain') self.send_header('Content-Type', 'text/plain')
@ -128,7 +137,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
now = time.time() now = time.time()
self.wfile.write(yaml.dump({'pool': pool, 'in_use': dict((k, now - v) for k, v in in_use.iteritems())})) self.wfile.write(yaml.dump({'pool': pool, 'in_use': dict((k, now - v) for k, v in in_use.iteritems())}))
elif self.path == '/quit': elif self.path == '/quitquitquit':
self.send_response(200) self.send_response(200)
self.end_headers() self.end_headers()
keep_running = False keep_running = False

@ -37,19 +37,15 @@ cd $(dirname $0)/../..
root=`pwd` root=`pwd`
cd $root/src/node
export LD_LIBRARY_PATH=$root/libs/$CONFIG
if [ "$CONFIG" = "gcov" ] if [ "$CONFIG" = "gcov" ]
then then
./node_modules/.bin/istanbul cover --dir ../../reports/node_coverage \ ./node_modules/.bin/istanbul cover --dir reports/node_coverage \
./node_modules/.bin/_mocha -- --timeout 8000 ./node_modules/.bin/_mocha -- --timeout 8000 src/node/test
cd build cd build
gcov Release/obj.target/grpc/ext/*.o gcov Release/obj.target/grpc/ext/*.o
lcov --base-directory . --directory . -c -o coverage.info lcov --base-directory . --directory . -c -o coverage.info
genhtml -o ../../../reports/node_ext_coverage --num-spaces 2 \ genhtml -o ../reports/node_ext_coverage --num-spaces 2 \
-t 'Node gRPC test coverage' coverage.info -t 'Node gRPC test coverage' coverage.info
else else
./node_modules/mocha/bin/mocha --timeout 8000 ./node_modules/mocha/bin/mocha --timeout 8000 src/node/test
fi fi

@ -181,45 +181,6 @@ class CLanguage(object):
def __str__(self): def __str__(self):
return self.make_target return self.make_target
def gyp_test_paths(travis, config=None):
binaries = get_c_tests(travis, 'c')
out = []
for target in binaries:
if config is not None and config.build_config in target['exclude_configs']:
continue
binary = 'out/Debug/%s' % target['name']
out.append(binary)
return sorted(out)
class GYPCLanguage(object):
def test_specs(self, config, travis):
return [config.job_spec([binary], [binary])
for binary in gyp_test_paths(travis, config)]
def pre_build_steps(self):
return [['gyp', '--depth=.', '--suffix=-gyp', 'grpc.gyp']]
def make_targets(self):
# HACK(ctiller): force fling_client and fling_server to be built, as fling_test
# needs these
return gyp_test_paths(False) + ['fling_client', 'fling_server']
def build_steps(self):
return []
def makefile_name(self):
return 'Makefile-gyp'
def supports_multi_config(self):
return False
def __str__(self):
return 'gyp'
class NodeLanguage(object): class NodeLanguage(object):
def test_specs(self, config, travis): def test_specs(self, config, travis):
@ -230,7 +191,7 @@ class NodeLanguage(object):
return [] return []
def make_targets(self): def make_targets(self):
return ['static_c', 'shared_c'] return []
def build_steps(self): def build_steps(self):
return [['tools/run_tests/build_node.sh']] return [['tools/run_tests/build_node.sh']]
@ -483,7 +444,6 @@ _DEFAULT = ['opt']
_LANGUAGES = { _LANGUAGES = {
'c++': CLanguage('cxx', 'c++'), 'c++': CLanguage('cxx', 'c++'),
'c': CLanguage('c', 'c'), 'c': CLanguage('c', 'c'),
'gyp': GYPCLanguage(),
'node': NodeLanguage(), 'node': NodeLanguage(),
'php': PhpLanguage(), 'php': PhpLanguage(),
'python': PythonLanguage(), 'python': PythonLanguage(),
@ -713,20 +673,23 @@ def _start_port_server(port_server_port):
# if not running ==> start a new one # if not running ==> start a new one
# otherwise, leave it up # otherwise, leave it up
try: try:
version = urllib2.urlopen('http://localhost:%d/version' % port_server_port, version = int(urllib2.urlopen(
timeout=1).read() 'http://localhost:%d/version_number' % port_server_port,
print 'detected port server running' timeout=1).read())
print 'detected port server running version %d' % version
running = True running = True
except Exception: except Exception as e:
print 'failed to detect port server: %s' % sys.exc_info()[0] print 'failed to detect port server: %s' % sys.exc_info()[0]
print e.strerror
running = False running = False
if running: if running:
with open('tools/run_tests/port_server.py') as f: current_version = int(subprocess.check_output(
current_version = hashlib.sha1(f.read()).hexdigest() [sys.executable, 'tools/run_tests/port_server.py', 'dump_version']))
running = (version == current_version) print 'my port server is version %d' % current_version
running = (version >= current_version)
if not running: if not running:
print 'port_server version mismatch: killing the old one' print 'port_server version mismatch: killing the old one'
urllib2.urlopen('http://localhost:%d/quit' % port_server_port).read() urllib2.urlopen('http://localhost:%d/quitquitquit' % port_server_port).read()
time.sleep(1) time.sleep(1)
if not running: if not running:
print 'starting port_server' print 'starting port_server'
@ -773,7 +736,7 @@ def _build_and_run(
# start antagonists # start antagonists
antagonists = [subprocess.Popen(['tools/run_tests/antagonist.py']) antagonists = [subprocess.Popen(['tools/run_tests/antagonist.py'])
for _ in range(0, args.antagonists)] for _ in range(0, args.antagonists)]
port_server_port = 9999 port_server_port = 32767
_start_port_server(port_server_port) _start_port_server(port_server_port)
try: try:
infinite_runs = runs_per_test == 0 infinite_runs = runs_per_test == 0

Loading…
Cancel
Save