Merge branch 'master' of github.com:grpc/grpc into flakes

pull/1360/head
Nicolas "Pixel" Noble 10 years ago
commit fdcd07bf2b
  1. 1276
      Makefile
  2. 42
      build.json
  3. 79
      gRPC.podspec
  4. 2
      src/core/support/histogram.c
  5. 6
      src/node/README.md
  6. 22
      src/node/ext/completion_queue_async_worker.cc
  7. 5
      src/node/ext/completion_queue_async_worker.h
  8. 2
      src/node/package.json
  9. 3
      src/objective-c/GRPCClient/GRPCMethodName.h
  10. 46
      src/objective-c/ProtoRPC/ProtoRPC.h
  11. 91
      src/objective-c/ProtoRPC/ProtoRPC.m
  12. 49
      src/objective-c/ProtoRPC/ProtoService.h
  13. 81
      src/objective-c/ProtoRPC/ProtoService.m
  14. 6
      src/objective-c/RxLibrary/GRXWriteable.h
  15. 24
      src/objective-c/RxLibrary/GRXWriteable.m
  16. 1
      src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec
  17. 86
      src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h
  18. 136
      src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m
  19. 12
      src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
  20. 90
      src/objective-c/examples/Sample/SampleTests/RemoteProtoTests.m
  21. 4
      src/ruby/bin/interop/interop_client.rb
  22. 29
      templates/Makefile.template
  23. 4
      test/core/end2end/gen_build_json.py
  24. 66
      test/cpp/end2end/end2end_test.cc
  25. 2
      tools/dockerfile/grpc_ruby/Dockerfile
  26. 1
      tools/gce_setup/grpc_docker.sh
  27. 2
      tools/run_tests/run_tests.py
  28. 11
      vsprojects/grpc.sln
  29. 4
      vsprojects/grpc_test_util/grpc_test_util.vcxproj
  30. 117
      vsprojects/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj

1276
Makefile

File diff suppressed because it is too large Load Diff

@ -279,6 +279,19 @@
"src/core/transport/stream_op.c",
"src/core/transport/transport.c"
]
},
{
"name": "grpc_test_util_base",
"src": [
"test/core/end2end/cq_verifier.c",
"test/core/iomgr/endpoint_tests.c",
"test/core/statistics/census_log_tests.c",
"test/core/util/grpc_profiler.c",
"test/core/util/parse_hexstring.c",
"test/core/util/port_posix.c",
"test/core/util/port_windows.c",
"test/core/util/slice_splitter.c"
]
}
],
"libs": [
@ -375,6 +388,7 @@
"deps": [
"gpr"
],
"secure": "no",
"vs_project_guid": "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}"
},
{
@ -438,25 +452,35 @@
"build": "private",
"language": "c",
"src": [
"test/core/end2end/cq_verifier.c",
"test/core/end2end/data/server1_cert.c",
"test/core/end2end/data/server1_key.c",
"test/core/end2end/data/test_root_cert.c",
"test/core/iomgr/endpoint_tests.c",
"test/core/statistics/census_log_tests.c",
"test/core/util/grpc_profiler.c",
"test/core/util/parse_hexstring.c",
"test/core/util/port_posix.c",
"test/core/util/port_windows.c",
"test/core/util/slice_splitter.c"
"test/core/end2end/data/test_root_cert.c"
],
"deps": [
"gpr",
"gpr_test_util",
"grpc"
],
"filegroups": [
"grpc_test_util_base"
],
"vs_project_guid": "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
},
{
"name": "grpc_test_util_unsecure",
"build": "private",
"language": "c",
"deps": [
"gpr",
"gpr_test_util",
"grpc"
],
"filegroups": [
"grpc_test_util_base"
],
"secure": "no",
"vs_project_guid": "{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}"
},
{
"name": "grpc_unsecure",
"build": "all",

@ -7,15 +7,13 @@ Pod::Spec.new do |s|
s.authors = { 'Jorge Canizales' => 'jcanizales@google.com' }
# s.source = { :git => 'https://github.com/grpc/grpc.git', :tag => 'release-0_5_0' }
s.source_files = 'src/objective-c/GRPCClient/*.{h,m}', 'src/objective-c/GRPCClient/private/*.{h,m}'
s.private_header_files = 'src/objective-c/GRPCClient/private/*.h'
s.platform = :ios
s.ios.deployment_target = '6.0'
s.requires_arc = true
s.subspec 'RxLibrary' do |rs|
rs.summary = 'Reactive Extensions library for iOS'
rs.summary = 'Reactive Extensions library for iOS.'
rs.authors = { 'Jorge Canizales' => 'jcanizales@google.com' }
rs.source_files = 'src/objective-c/RxLibrary/*.{h,m}', 'src/objective-c/RxLibrary/transformations/*.{h,m}', 'src/objective-c/RxLibrary/private/*.{h,m}'
@ -23,7 +21,7 @@ Pod::Spec.new do |s|
end
s.subspec 'C-Core' do |cs|
cs.summary = 'Core gRPC library, written in C'
cs.summary = 'Core cross-platform gRPC library, written in C.'
cs.authors = { 'Craig Tiller' => 'ctiller@google.com',
'David Klempner' => 'klempner@google.com',
'Nicolas Noble' => 'nnoble@google.com',
@ -38,32 +36,53 @@ Pod::Spec.new do |s|
cs.requires_arc = false
cs.libraries = 'z'
cs.dependency 'OpenSSL', '~> 1.0.200'
# This is a workaround for Cocoapods Issue #1437.
# It renames time.h and string.h to grpc_time.h and grpc_string.h.
cs.prepare_command = <<-CMD
DIR_TIME="grpc/support"
BAD_TIME="$DIR_TIME/time.h"
GOOD_TIME="$DIR_TIME/grpc_time.h"
if [ -f "include/$BAD_TIME" ];
then
grep -rl "$BAD_TIME" include/grpc src/core | xargs sed -i '' -e s@$BAD_TIME@$GOOD_TIME@g
mv "include/$BAD_TIME" "include/$GOOD_TIME"
fi
DIR_STRING="src/core/support"
BAD_STRING="$DIR_STRING/string.h"
GOOD_STRING="$DIR_STRING/grpc_string.h"
if [ -f "$BAD_STRING" ];
then
grep -rl "$BAD_STRING" include/grpc src/core | xargs sed -i '' -e s@$BAD_STRING@$GOOD_STRING@g
mv "$BAD_STRING" "$GOOD_STRING"
fi
CMD
end
s.subspec 'GRPCClient' do |gs|
gs.summary = 'Objective-C wrapper around the core gRPC library.'
gs.authors = { 'Jorge Canizales' => 'jcanizales@google.com' }
gs.source_files = 'src/objective-c/GRPCClient/*.{h,m}', 'src/objective-c/GRPCClient/private/*.{h,m}'
gs.private_header_files = 'src/objective-c/GRPCClient/private/*.h'
gs.dependency 'gRPC/C-Core'
# Is this needed in all dependents?
gs.xcconfig = { 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers/Public/gRPC/include"' }
gs.dependency 'gRPC/RxLibrary'
# Certificates, to be able to establish TLS connections:
gs.resource_bundles = { 'gRPC' => ['etc/roots.pem'] }
end
# This is a workaround for Cocoapods Issue #1437.
# It renames time.h and string.h to grpc_time.h and grpc_string.h.
s.prepare_command = <<-CMD
DIR_TIME="grpc/support"
BAD_TIME="$DIR_TIME/time.h"
GOOD_TIME="$DIR_TIME/grpc_time.h"
if [ -f "include/$BAD_TIME" ];
then
grep -rl "$BAD_TIME" include/grpc src/core | xargs sed -i '' -e s@$BAD_TIME@$GOOD_TIME@g
mv "include/$BAD_TIME" "include/$GOOD_TIME"
fi
DIR_STRING="src/core/support"
BAD_STRING="$DIR_STRING/string.h"
GOOD_STRING="$DIR_STRING/grpc_string.h"
if [ -f "$BAD_STRING" ];
then
grep -rl "$BAD_STRING" include/grpc src/core | xargs sed -i '' -e s@$BAD_STRING@$GOOD_STRING@g
mv "$BAD_STRING" "$GOOD_STRING"
fi
CMD
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers/Public/gRPC/include"' }
# Certificates, to be able to establish TLS connections:
s.resource_bundles = { 'gRPC' => ['etc/roots.pem'] }
s.subspec 'ProtoRPC' do |ps|
ps.summary = 'RPC library for ProtocolBuffers, based on gRPC'
ps.authors = { 'Jorge Canizales' => 'jcanizales@google.com' }
ps.source_files = 'src/objective-c/ProtoRPC/*.{h,m}'
ps.dependency 'gRPC/GRPCClient'
ps.dependency 'gRPC/RxLibrary'
end
end

@ -76,7 +76,7 @@ static size_t bucket_for_unchecked(gpr_histogram *h, double x) {
/* bounds checked version of the above */
static size_t bucket_for(gpr_histogram *h, double x) {
size_t bucket = bucket_for_unchecked(h, GPR_CLAMP(x, 0, h->max_possible));
size_t bucket = bucket_for_unchecked(h, GPR_CLAMP(x, 1.0, h->max_possible));
GPR_ASSERT(bucket < h->num_buckets);
return bucket;
}

@ -14,6 +14,12 @@ This requires `node` to be installed. If you instead have the `nodejs` executabl
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`.
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]
```
## Tests
To run the test suite, simply run `npm test` in the install location.

@ -43,6 +43,8 @@
namespace grpc {
namespace node {
const int max_queue_threads = 2;
using v8::Function;
using v8::Handle;
using v8::Object;
@ -51,6 +53,9 @@ using v8::Value;
grpc_completion_queue *CompletionQueueAsyncWorker::queue;
int CompletionQueueAsyncWorker::current_threads;
int CompletionQueueAsyncWorker::waiting_next_calls;
CompletionQueueAsyncWorker::CompletionQueueAsyncWorker()
: NanAsyncWorker(NULL) {}
@ -67,17 +72,30 @@ grpc_completion_queue *CompletionQueueAsyncWorker::GetQueue() { return queue; }
void CompletionQueueAsyncWorker::Next() {
NanScope();
CompletionQueueAsyncWorker *worker = new CompletionQueueAsyncWorker();
NanAsyncQueueWorker(worker);
if (current_threads < max_queue_threads) {
CompletionQueueAsyncWorker *worker = new CompletionQueueAsyncWorker();
NanAsyncQueueWorker(worker);
} else {
waiting_next_calls += 1;
}
}
void CompletionQueueAsyncWorker::Init(Handle<Object> exports) {
NanScope();
current_threads = 0;
waiting_next_calls = 0;
queue = grpc_completion_queue_create();
}
void CompletionQueueAsyncWorker::HandleOKCallback() {
NanScope();
if (waiting_next_calls > 0) {
waiting_next_calls -= 1;
CompletionQueueAsyncWorker *worker = new CompletionQueueAsyncWorker();
NanAsyncQueueWorker(worker);
} else {
current_threads -= 1;
}
NanCallback *callback = GetTagCallback(result->tag);
Handle<Value> argv[] = {NanNull(), GetTagNodeValue(result->tag)};
callback->Call(2, argv);

@ -73,6 +73,11 @@ class CompletionQueueAsyncWorker : public NanAsyncWorker {
grpc_event *result;
static grpc_completion_queue *queue;
// Number of grpc_completion_queue_next calls in the thread pool
static int current_threads;
// Number of grpc_completion_queue_next calls waiting to enter the thread pool
static int waiting_next_calls;
};
} // namespace node

@ -1,6 +1,6 @@
{
"name": "grpc",
"version": "0.6.1",
"version": "0.6.2",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",

@ -37,7 +37,8 @@
// A fully-qualified gRPC method name. Full qualification is needed because a gRPC endpoint can
// implement multiple interfaces.
// TODO(jcanizales): Is this proto-specific, or actual part of gRPC? If the former, move one layer up.
// TODO(jcanizales): Move to ProtoRPC package.
// TODO(jcanizales): Rename interface -> service.
@interface GRPCMethodName : NSObject
@property(nonatomic, readonly) NSString *package;
@property(nonatomic, readonly) NSString *interface;

@ -0,0 +1,46 @@
/*
*
* 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.
*
*/
#import <Foundation/Foundation.h>
#import <gRPC/GRPCCall.h>
@interface ProtoRPC : GRPCCall
- (instancetype)initWithHost:(NSString *)host
method:(GRPCMethodName *)method
requestsWriter:(id<GRXWriter>)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
- (void)start;
@end

@ -0,0 +1,91 @@
/*
*
* 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.
*
*/
#import "ProtoRPC.h"
#import <gRPC/GRXWriteable.h>
#import <gRPC/GRXWriter.h>
#import <gRPC/GRXWriter+Transformations.h>
#import <ProtocolBuffers/ProtocolBuffers.h>
@implementation ProtoRPC {
id<GRXWriteable> _responseWriteable;
}
- (instancetype)initWithHost:(NSString *)host
method:(GRPCMethodName *)method
requestsWriter:(id<GRXWriter>)requestsWriter {
return [self initWithHost:host
method:method
requestsWriter:requestsWriter
responseClass:nil
responsesWriteable:nil];
}
// Designated initializer
- (instancetype)initWithHost:(NSString *)host
method:(GRPCMethodName *)method
requestsWriter:(id<GRXWriter>)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable {
// Because we can't tell the type system to constrain the class, we need to check at runtime:
if (![responseClass respondsToSelector:@selector(parseFromData:)]) {
[NSException raise:NSInvalidArgumentException
format:@"A protobuf class to parse the responses must be provided."];
}
// A writer that serializes the proto messages to send.
id<GRXWriter> bytesWriter =
[[[GRXWriter alloc] initWithWriter:requestsWriter] map:^id(PBGeneratedMessage *proto) {
return [proto data];
}];
if ((self = [super initWithHost:host method:method requestsWriter:bytesWriter])) {
// A writeable that parses the proto messages received.
_responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
[responsesWriteable didReceiveValue:[responseClass parseFromData:value]];
} completionHandler:^(NSError *errorOrNil) {
[responsesWriteable didFinishWithError:errorOrNil];
}];
}
return self;
}
- (void)start {
[self startWithWriteable:_responseWriteable];
}
- (void)startWithWriteable:(id<GRXWriteable>)writeable {
[super startWithWriteable:writeable];
// Break retain cycles.
_responseWriteable = nil;
}
@end

@ -0,0 +1,49 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#import <Foundation/Foundation.h>
@class ProtoRPC;
@protocol GRXWriteable;
@protocol GRXWriter;
@interface ProtoService : NSObject
- (instancetype)initWithHost:(NSString *)host
packageName:(NSString *)packageName
serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER;
- (ProtoRPC *)RPCToMethod:(NSString *)method
requestsWriter:(id<GRXWriter>)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable;
@end

@ -0,0 +1,81 @@
/*
*
* 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.
*
*/
#import "ProtoService.h"
#import <gRPC/GRPCMethodName.h>
#import <gRPC/GRXWriteable.h>
#import <gRPC/GRXWriter.h>
#import "ProtoRPC.h"
@implementation ProtoService {
NSString *_host;
NSString *_packageName;
NSString *_serviceName;
}
- (instancetype)init {
return [self initWithHost:nil packageName:nil serviceName:nil];
}
// Designated initializer
- (instancetype)initWithHost:(NSString *)host
packageName:(NSString *)packageName
serviceName:(NSString *)serviceName {
if (!host || !serviceName) {
[NSException raise:NSInvalidArgumentException
format:@"Neither host nor serviceName can be nil."];
}
if ((self = [super init])) {
_host = [host copy];
_packageName = [packageName copy];
_serviceName = [serviceName copy];
}
return self;
}
- (ProtoRPC *)RPCToMethod:(NSString *)method
requestsWriter:(id<GRXWriter>)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable {
GRPCMethodName *methodName = [[GRPCMethodName alloc] initWithPackage:_packageName
interface:_serviceName
method:method];
return [[ProtoRPC alloc] initWithHost:_host
method:methodName
requestsWriter:requestsWriter
responseClass:responseClass
responsesWriteable:responsesWriteable];
}
@end

@ -50,10 +50,16 @@
typedef void (^GRXValueHandler)(id value);
typedef void (^GRXCompletionHandler)(NSError *errorOrNil);
typedef void (^GRXSingleValueHandler)(id value, NSError *errorOrNil);
typedef void (^GRXStreamHandler)(BOOL done, id value, NSError *error);
// Utility to create objects that conform to the GRXWriteable protocol, from
// blocks that handle each of the two methods of the protocol.
@interface GRXWriteable : NSObject<GRXWriteable>
+ (instancetype)writeableWithSingleValueHandler:(GRXSingleValueHandler)handler;
+ (instancetype)writeableWithStreamHandler:(GRXStreamHandler)handler;
- (instancetype)initWithValueHandler:(GRXValueHandler)valueHandler
completionHandler:(GRXCompletionHandler)completionHandler
NS_DESIGNATED_INITIALIZER;

@ -38,6 +38,30 @@
GRXCompletionHandler _completionHandler;
}
+ (instancetype)writeableWithSingleValueHandler:(GRXSingleValueHandler)handler {
if (!handler) {
return [[self alloc] init];
}
return [[self alloc] initWithValueHandler:^(id value) {
handler(value, nil);
} completionHandler:^(NSError *errorOrNil) {
if (errorOrNil) {
handler(nil, errorOrNil);
}
}];
}
+ (instancetype)writeableWithStreamHandler:(GRXStreamHandler)handler {
if (!handler) {
return [[self alloc] init];
}
return [[self alloc] initWithValueHandler:^(id value) {
handler(NO, value, nil);
} completionHandler:^(NSError *errorOrNil) {
handler(YES, nil, errorOrNil);
}];
}
- (instancetype)init {
return [self initWithValueHandler:nil completionHandler:nil];
}

@ -14,4 +14,5 @@ Pod::Spec.new do |s|
s.requires_arc = true
s.dependency 'ProtocolBuffers', '~> 1.9'
s.dependency 'gRPC', '~> 0.0'
end

@ -4,6 +4,7 @@
#import "Empty.pb.h"
#import "Messages.pb.h"
#import <gRPC/ProtoService.h>
// @@protoc_insertion_point(imports)
@class ObjectiveCFileOptions;
@ -78,4 +79,89 @@
@end
@protocol GRXWriteable;
@protocol GRXWriter;
@protocol RMTTestService <NSObject>
#pragma mark EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty)
// One empty request followed by one empty response.
- (void)emptyCallWithRequest:(RMTEmpty *)request
handler:(void(^)(RMTEmpty *response, NSError *error))handler;
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToEmptyCallWithRequest:(RMTEmpty *)request
handler:(void(^)(RMTEmpty *response, NSError *error))handler;
#pragma mark UnaryCall(SimpleRequest) returns (SimpleResponse)
// One request followed by one response.
- (void)unaryCallWithRequest:(RMTSimpleRequest *)request
handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler;
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToUnaryCallWithRequest:(RMTSimpleRequest *)request
handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler;
#pragma mark StreamingOutputCall(StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse)
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
- (void)streamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler;
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToStreamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler;
#pragma mark StreamingInputCall(stream StreamingInputCallRequest) returns (StreamingInputCallResponse)
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
- (void)streamingInputCallWithRequestsWriter:(id<GRXWriter>)request
handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler;
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToStreamingInputCallWithRequestsWriter:(id<GRXWriter>)request
handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler;
#pragma mark FullDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse)
// 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.
- (void)fullDuplexCallWithRequestsWriter:(id<GRXWriter>)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler;
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToFullDuplexCallWithRequestsWriter:(id<GRXWriter>)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler;
#pragma mark HalfDuplexCall(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.
- (void)halfDuplexCallWithRequestsWriter:(id<GRXWriter>)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler;
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToHalfDuplexCallWithRequestsWriter:(id<GRXWriter>)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler;
@end
// Basic service implementation, over gRPC, that only does marshalling and parsing.
@interface RMTTestService : ProtoService<RMTTestService>
- (instancetype)initWithHost:(NSString *)host NS_DESIGNATED_INITIALIZER;
@end
// @@protoc_insertion_point(global_scope)

@ -1,6 +1,10 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
#import "Test.pb.h"
#import <gRPC/GRXWriteable.h>
#import <gRPC/GRXWriter+Immediate.h>
#import <gRPC/ProtoRPC.h>
// @@protoc_insertion_point(imports)
@implementation RMTTestRoot
@ -24,4 +28,136 @@ static PBExtensionRegistry* extensionRegistry = nil;
@end
static NSString *const kPackageName = @"grpc.testing";
static NSString *const kServiceName = @"TestService";
@implementation RMTTestService
// Designated initializer
- (instancetype)initWithHost:(NSString *)host {
return (self = [super initWithHost:host packageName:kPackageName serviceName:kServiceName]);
}
- (instancetype)initWithHost:(NSString *)host
packageName:(NSString *)packageName
serviceName:(NSString *)serviceName {
return [self initWithHost:host];
}
#pragma mark EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty)
// One empty request followed by one empty response.
- (void)emptyCallWithRequest:(RMTEmpty *)request
handler:(void(^)(RMTEmpty *response, NSError *error))handler {
[[self RPCToEmptyCallWithRequest:request handler:handler] start];
}
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToEmptyCallWithRequest:(RMTEmpty *)request
handler:(void(^)(RMTEmpty *response, NSError *error))handler {
return [self RPCToMethod:@"EmptyCall"
requestsWriter:[GRXWriter writerWithValue:request]
responseClass:[RMTEmpty class]
responsesWriteable:[GRXWriteable writeableWithSingleValueHandler:handler]];
}
#pragma mark UnaryCall(SimpleRequest) returns (SimpleResponse)
// One request followed by one response.
- (void)unaryCallWithRequest:(RMTSimpleRequest *)request
handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler {
[[self RPCToUnaryCallWithRequest:request handler:handler] start];
}
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToUnaryCallWithRequest:(RMTSimpleRequest *)request
handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler {
return [self RPCToMethod:@"UnaryCall"
requestsWriter:[GRXWriter writerWithValue:request]
responseClass:[RMTSimpleResponse class]
responsesWriteable:[GRXWriteable writeableWithSingleValueHandler:handler]];
}
#pragma mark StreamingOutputCall(StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse)
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
- (void)streamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler {
[[self RPCToStreamingOutputCallWithRequest:request handler:handler] start];
}
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToStreamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler {
return [self RPCToMethod:@"StreamingOutputCall"
requestsWriter:[GRXWriter writerWithValue:request]
responseClass:[RMTStreamingOutputCallResponse class]
responsesWriteable:[GRXWriteable writeableWithStreamHandler:handler]];
}
#pragma mark StreamingInputCall(stream StreamingInputCallRequest) returns (StreamingInputCallResponse)
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
- (void)streamingInputCallWithRequestsWriter:(id<GRXWriter>)requestsWriter
handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler {
[[self RPCToStreamingInputCallWithRequestsWriter:requestsWriter handler:handler] start];
}
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToStreamingInputCallWithRequestsWriter:(id<GRXWriter>)requestsWriter
handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler {
return [self RPCToMethod:@"StreamingInputCall"
requestsWriter:requestsWriter
responseClass:[RMTStreamingInputCallResponse class]
responsesWriteable:[GRXWriteable writeableWithSingleValueHandler:handler]];
}
#pragma mark FullDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse)
// 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.
- (void)fullDuplexCallWithRequestsWriter:(id<GRXWriter>)requestsWriter
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler {
[[self RPCToFullDuplexCallWithRequestsWriter:requestsWriter handler:handler] start];
}
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToFullDuplexCallWithRequestsWriter:(id<GRXWriter>)requestsWriter
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler {
return [self RPCToMethod:@"FullDuplexCall"
requestsWriter:requestsWriter
responseClass:[RMTStreamingOutputCallResponse class]
responsesWriteable:[GRXWriteable writeableWithStreamHandler:handler]];
}
#pragma mark HalfDuplexCall(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.
- (void)halfDuplexCallWithRequestsWriter:(id<GRXWriter>)requestsWriter
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler {
[[self RPCToHalfDuplexCallWithRequestsWriter:requestsWriter handler:handler] start];
}
// Returns a not-yet-started RPC object.
- (ProtoRPC *)RPCToHalfDuplexCallWithRequestsWriter:(id<GRXWriter>)requestsWriter
handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler {
return [self RPCToMethod:@"HalfDuplexCall"
requestsWriter:requestsWriter
responseClass:[RMTStreamingOutputCallResponse class]
responsesWriteable:[GRXWriteable writeableWithStreamHandler:handler]];
}
@end
// @@protoc_insertion_point(global_scope)

@ -8,6 +8,8 @@
/* Begin PBXBuildFile section */
60BBBBB15823BBF7639D7AA9 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC7B7C4C0410F43B9621631 /* libPods.a */; };
6340F0491AE66E3300FB6A3D /* RemoteProtoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6340F0481AE66E3300FB6A3D /* RemoteProtoTests.m */; };
6356D1DE1AC11FE00075FBBC /* RemoteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6356D1DD1AC11FE00075FBBC /* RemoteTests.m */; };
6369A2701A9322E20015FC5C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A26F1A9322E20015FC5C /* main.m */; };
6369A2731A9322E20015FC5C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2721A9322E20015FC5C /* AppDelegate.m */; };
6369A2761A9322E20015FC5C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2751A9322E20015FC5C /* ViewController.m */; };
@ -15,7 +17,6 @@
6369A27B1A9322E20015FC5C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6369A27A1A9322E20015FC5C /* Images.xcassets */; };
6369A27E1A9322E20015FC5C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6369A27C1A9322E20015FC5C /* LaunchScreen.xib */; };
6369A28A1A9322E20015FC5C /* SampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2891A9322E20015FC5C /* SampleTests.m */; };
63D886A71AE73797000580D7 /* RemoteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D886A61AE73797000580D7 /* RemoteTests.m */; };
FC81FE63CA655031F3524EC0 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC7B7C4C0410F43B9621631 /* libPods.a */; };
/* End PBXBuildFile section */
@ -31,6 +32,8 @@
/* Begin PBXFileReference section */
2DC7B7C4C0410F43B9621631 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
6340F0481AE66E3300FB6A3D /* RemoteProtoTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteProtoTests.m; sourceTree = "<group>"; };
6356D1DD1AC11FE00075FBBC /* RemoteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteTests.m; sourceTree = "<group>"; };
6369A26A1A9322E20015FC5C /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; };
6369A26E1A9322E20015FC5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6369A26F1A9322E20015FC5C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
@ -44,7 +47,6 @@
6369A2831A9322E20015FC5C /* SampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
6369A2881A9322E20015FC5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6369A2891A9322E20015FC5C /* SampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleTests.m; sourceTree = "<group>"; };
63D886A61AE73797000580D7 /* RemoteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteTests.m; sourceTree = "<group>"; };
AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -116,9 +118,10 @@
6369A2861A9322E20015FC5C /* SampleTests */ = {
isa = PBXGroup;
children = (
63D886A61AE73797000580D7 /* RemoteTests.m */,
6340F0481AE66E3300FB6A3D /* RemoteProtoTests.m */,
6369A2891A9322E20015FC5C /* SampleTests.m */,
6369A2871A9322E20015FC5C /* Supporting Files */,
6356D1DD1AC11FE00075FBBC /* RemoteTests.m */,
);
path = SampleTests;
sourceTree = "<group>";
@ -326,7 +329,8 @@
buildActionMask = 2147483647;
files = (
6369A28A1A9322E20015FC5C /* SampleTests.m in Sources */,
63D886A71AE73797000580D7 /* RemoteTests.m in Sources */,
6340F0491AE66E3300FB6A3D /* RemoteProtoTests.m in Sources */,
6356D1DE1AC11FE00075FBBC /* RemoteTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -0,0 +1,90 @@
/*
*
* 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.
*
*/
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import <RemoteTest/Messages.pb.h>
#import <RemoteTest/Test.pb.h>
@interface RemoteProtoTests : XCTestCase
@end
@implementation RemoteProtoTests {
RMTTestService *_service;
}
- (void)setUp {
_service = [[RMTTestService alloc] initWithHost:@"grpc-test.sandbox.google.com"];
}
- (void)testEmptyRPC {
__weak XCTestExpectation *noRPCError = [self expectationWithDescription:@"RPC succeeded."];
__weak XCTestExpectation *responded = [self expectationWithDescription:@"Response received."];
[_service emptyCallWithRequest:[RMTEmpty defaultInstance]
handler:^(RMTEmpty *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
[noRPCError fulfill];
XCTAssertNotNil(response, @"nil response received.");
[responded fulfill];
}];
[self waitForExpectationsWithTimeout:2. handler:nil];
}
- (void)testSimpleProtoRPC {
__weak XCTestExpectation *noRPCError = [self expectationWithDescription:@"RPC succeeded."];
__weak XCTestExpectation *responded = [self expectationWithDescription:@"Response received."];
__weak XCTestExpectation *validResponse = [self expectationWithDescription:@"Valid response."];
RMTSimpleRequest *request = [[[[[[RMTSimpleRequestBuilder alloc] init]
setResponseSize:100]
setFillUsername:YES]
setFillOauthScope:YES]
build];
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
[noRPCError fulfill];
XCTAssertNotNil(response, @"nil response received.");
[responded fulfill];
// We expect empty strings, not nil:
XCTAssertNotNil(response.username, @"Response's username is nil.");
XCTAssertNotNil(response.oauthScope, @"Response's OAuth scope is nil.");
[validResponse fulfill];
}];
[self waitForExpectationsWithTimeout:2. handler:nil];
}
@end

@ -277,13 +277,13 @@ class NamedTests
p 'OK: cancel_after_begin'
end
def cancel_after_first
def cancel_after_first_response
msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
ppp = PingPongPlayer.new(msg_sizes)
op = @stub.full_duplex_call(ppp.each_item, return_op: true)
ppp.canceller_op = op # causes ppp to cancel after the 1st message
assert_raises(GRPC::Cancelled) { op.execute.each { |r| ppp.queue.push(r) } }
p 'OK: cancel_after_first'
p 'OK: cancel_after_first_response'
end
def all

@ -42,6 +42,9 @@
if not m:
return filename
return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc'
sources_that_need_openssl = set()
sources_that_don_t_need_openssl = set()
%>
@ -1080,15 +1083,6 @@ endif
else
% endif
ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this
# otherwise parallel compilation will fail if a source is compiled first.
% for src in lib.src:
${src}: $(OPENSSL_DEP)
% endfor
endif
$(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP)\
## The else here corresponds to the if secure earlier.
% else:
@ -1136,6 +1130,7 @@ ifeq ($(SYSTEM),Darwin)
endif
<%
if lib.language == 'c++':
ld = '$(LDXX)'
else:
@ -1158,6 +1153,11 @@ endif
if lib.get('secure', 'check') == 'yes':
common = common + ' $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS)'
for src in lib.src:
sources_that_need_openssl.add(src)
else:
for src in lib.src:
sources_that_don_t_need_openssl.add(src)
if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
lib_deps = lib_deps + ' $(OPENSSL_DEP)'
@ -1340,6 +1340,17 @@ endif
% endif
</%def>
ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this
# otherwise parallel compilation will fail if a source is compiled first.
% for src in sorted(sources_that_need_openssl):
% if src not in sources_that_don_t_need_openssl:
${src}: $(OPENSSL_DEP)
% endif
% endfor
endif
.PHONY: all strip tools \
dep_error openssl_dep_error openssl_dep_message git_update stop \
buildtests buildtests_c buildtests_cxx \

@ -110,7 +110,7 @@ def main():
'name': 'end2end_fixture_%s' % f,
'build': 'private',
'language': 'c',
'secure': 'check',
'secure': 'check' if END2END_FIXTURES[f] else 'no',
'src': ['test/core/end2end/fixtures/%s.c' % f]
}
for f in sorted(END2END_FIXTURES.keys())] + [
@ -163,7 +163,7 @@ def main():
'deps': [
'end2end_fixture_%s' % f,
'end2end_test_%s' % t,
'grpc_test_util',
'grpc_test_util_unsecure',
'grpc_unsecure',
'gpr_test_util',
'gpr'

@ -491,6 +491,72 @@ TEST_F(End2endTest, ServerCancelsRpc) {
EXPECT_TRUE(s.details().empty());
}
// Client cancels server stream after sending some messages
TEST_F(End2endTest, ClientCancelsResponseStream) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
request.set_message("hello");
auto stream = stub_->ResponseStream(&context, request);
EXPECT_TRUE(stream->Read(&response));
EXPECT_EQ(response.message(), request.message() + "0");
EXPECT_TRUE(stream->Read(&response));
EXPECT_EQ(response.message(), request.message() + "1");
context.TryCancel();
// The cancellation races with responses, so there might be zero or
// one responses pending, read till failure
if (stream->Read(&response)) {
EXPECT_EQ(response.message(), request.message() + "2");
// Since we have cancelled, we expect the next attempt to read to fail
EXPECT_FALSE(stream->Read(&response));
}
Status s = stream->Finish();
// The final status could be either of CANCELLED or OK depending on
// who won the race.
EXPECT_GE(grpc::StatusCode::CANCELLED, s.code());
}
// Client cancels bidi stream after sending some messages
TEST_F(End2endTest, ClientCancelsBidi) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
grpc::string msg("hello");
auto stream = stub_->BidiStream(&context);
request.set_message(msg + "0");
EXPECT_TRUE(stream->Write(request));
EXPECT_TRUE(stream->Read(&response));
EXPECT_EQ(response.message(), request.message());
request.set_message(msg + "1");
EXPECT_TRUE(stream->Write(request));
context.TryCancel();
// The cancellation races with responses, so there might be zero or
// one responses pending, read till failure
if (stream->Read(&response)) {
EXPECT_EQ(response.message(), request.message());
// Since we have cancelled, we expect the next attempt to read to fail
EXPECT_FALSE(stream->Read(&response));
}
Status s = stream->Finish();
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.code());
}
} // namespace testing
} // namespace grpc

@ -42,7 +42,7 @@ RUN make clean -C /var/local/git/grpc
RUN make install_c -j12 -C /var/local/git/grpc
# Build ruby gRPC and run its tests
RUN /bin/bash -l -c 'cd /var/local/git/grpc/src/ruby && bundle && rake'
RUN /bin/bash -l -c 'cd /var/local/git/grpc/src/ruby && gem update bundler && bundle && rake'
# Add a cacerts directory containing the Google root pem file, allowing the
# ruby client to access the production test instance

@ -1173,7 +1173,6 @@ grpc_cloud_prod_auth_jwt_token_creds_gen_ruby_cmd() {
local test_script="/var/local/git/grpc/src/ruby/bin/interop/interop_client.rb"
local test_script+=" --use_tls"
local gfe_flags=$(_grpc_prod_gfe_flags)
local added_gfe_flags=$(_grpc_jwt_token_test_flags)
local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'"

@ -259,7 +259,7 @@ class Build(object):
return []
def make_targets(self):
return ['all']
return ['static']
def build_steps(self):
return []

@ -22,6 +22,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "grpc_test
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util_unsecure", "grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj", "{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}"
ProjectSection(ProjectDependencies) = postProject
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "grpc_unsecure\grpc_unsecure.vcxproj", "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
ProjectSection(ProjectDependencies) = postProject
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
@ -61,6 +68,10 @@ Global
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.Build.0 = Debug|Win32
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.Build.0 = Release|Win32
{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|Win32.ActiveCfg = Debug|Win32
{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|Win32.Build.0 = Debug|Win32
{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|Win32.ActiveCfg = Release|Win32
{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|Win32.Build.0 = Release|Win32
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.ActiveCfg = Debug|Win32
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug|Win32
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release|Win32

@ -83,14 +83,14 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\test\core\end2end\cq_verifier.c">
</ClCompile>
<ClCompile Include="..\..\test\core\end2end\data\server1_cert.c">
</ClCompile>
<ClCompile Include="..\..\test\core\end2end\data\server1_key.c">
</ClCompile>
<ClCompile Include="..\..\test\core\end2end\data\test_root_cert.c">
</ClCompile>
<ClCompile Include="..\..\test\core\end2end\cq_verifier.c">
</ClCompile>
<ClCompile Include="..\..\test\core\iomgr\endpoint_tests.c">
</ClCompile>
<ClCompile Include="..\..\test\core\statistics\census_log_tests.c">

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\global.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\global.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>grpc_test_util_unsecure</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>grpc_test_util_unsecure</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\test\core\end2end\cq_verifier.c">
</ClCompile>
<ClCompile Include="..\..\test\core\iomgr\endpoint_tests.c">
</ClCompile>
<ClCompile Include="..\..\test\core\statistics\census_log_tests.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\grpc_profiler.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\parse_hexstring.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\port_posix.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\port_windows.c">
</ClCompile>
<ClCompile Include="..\..\test\core\util\slice_splitter.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\gpr\gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
<ProjectReference Include="..\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="..\grpc\grpc.vcxproj">
<Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Loading…
Cancel
Save