mirror of https://github.com/grpc/grpc.git
commit
239d6d5341
148 changed files with 3652 additions and 2051 deletions
@ -1,217 +0,0 @@ |
|||||||
These instructions only cover building grpc C and C++ libraries under |
|
||||||
typical unix systems. If you need more information, please try grpc's |
|
||||||
wiki pages: |
|
||||||
|
|
||||||
https://github.com/google/grpc/wiki |
|
||||||
|
|
||||||
|
|
||||||
************************* |
|
||||||
* If you are in a hurry * |
|
||||||
************************* |
|
||||||
|
|
||||||
On Linux (Debian): |
|
||||||
|
|
||||||
Note: you will need to add the Debian 'jessie-backports' distribution to your sources |
|
||||||
file first. |
|
||||||
|
|
||||||
Add the following line to your `/etc/apt/sources.list` file: |
|
||||||
|
|
||||||
deb http://http.debian.net/debian jessie-backports main |
|
||||||
|
|
||||||
Install the gRPC library: |
|
||||||
|
|
||||||
$ [sudo] apt-get install libgrpc-dev |
|
||||||
|
|
||||||
OR |
|
||||||
|
|
||||||
$ git clone https://github.com/grpc/grpc.git |
|
||||||
$ cd grpc |
|
||||||
$ git submodule update --init |
|
||||||
$ make |
|
||||||
$ [sudo] make install |
|
||||||
|
|
||||||
You don't need anything else than GNU Make, gcc and autotools. Under a Debian |
|
||||||
or Ubuntu system, this should boil down to the following packages: |
|
||||||
|
|
||||||
$ [sudo] apt-get install build-essential autoconf libtool |
|
||||||
|
|
||||||
Building the python wrapper requires the following: |
|
||||||
|
|
||||||
$ [sudo] apt-get install python-all-dev python-virtualenv |
|
||||||
|
|
||||||
If you want to install in a different directory than the default /usr/lib, you can |
|
||||||
override it on the command line: |
|
||||||
|
|
||||||
$ [sudo] make install prefix=/opt |
|
||||||
|
|
||||||
|
|
||||||
******************************* |
|
||||||
* More detailled instructions * |
|
||||||
******************************* |
|
||||||
|
|
||||||
Setting up dependencies |
|
||||||
======================= |
|
||||||
|
|
||||||
Dependencies to compile the libraries |
|
||||||
------------------------------------- |
|
||||||
|
|
||||||
grpc libraries have few external dependencies. If you need to compile and |
|
||||||
install them, they are present in the third_party directory if you have |
|
||||||
cloned the github repository recursively. If you didn't clone recursively, |
|
||||||
you can still get them later by running the following command: |
|
||||||
|
|
||||||
$ git submodule update --init |
|
||||||
|
|
||||||
Note that the Makefile makes it much easier for you to compile from sources |
|
||||||
if you were to clone recursively our git repository: it will automatically |
|
||||||
compile zlib and OpenSSL, which are core requirements for grpc. Note this |
|
||||||
creates grpc libraries that will have zlib and OpenSSL built-in inside of them, |
|
||||||
which significantly increases the libraries' size. |
|
||||||
|
|
||||||
In order to decrease that size, you can manually install zlib and OpenSSL on |
|
||||||
your system, so that the Makefile can use them instead. |
|
||||||
|
|
||||||
Under a Debian or Ubuntu system, one can acquire the development package |
|
||||||
for zlib this way: |
|
||||||
|
|
||||||
# apt-get install zlib1g-dev |
|
||||||
|
|
||||||
To the best of our knowledge, no distribution has an OpenSSL package that |
|
||||||
supports ALPN yet, so you would still have to depend on installing from source |
|
||||||
for that particular dependency if you want to reduce the libraries' size. |
|
||||||
|
|
||||||
The recommended version of OpenSSL that provides ALPN support is available |
|
||||||
at this URL: |
|
||||||
|
|
||||||
https://www.openssl.org/source/openssl-1.0.2.tar.gz |
|
||||||
|
|
||||||
|
|
||||||
Dependencies to compile and run the tests |
|
||||||
----------------------------------------- |
|
||||||
|
|
||||||
Compiling and running grpc plain-C tests dont't require any more dependency. |
|
||||||
|
|
||||||
|
|
||||||
Compiling and running grpc C++ tests depend on protobuf 3.0.0, gtest and |
|
||||||
gflags. Although gflags is provided in third_party, you will need to manually |
|
||||||
install that dependency on your system to run these tests. |
|
||||||
|
|
||||||
Under a Debian or Ubuntu system, you can install the gtests and gflags packages |
|
||||||
using apt-get: |
|
||||||
|
|
||||||
# apt-get install libgflags-dev libgtest-dev |
|
||||||
|
|
||||||
However, protobuf 3.0.0 isn't in a debian package yet, but the Makefile will |
|
||||||
automatically try and compile the one present in third_party if you cloned the |
|
||||||
repository recursively, and that it detects your system is lacking it. |
|
||||||
|
|
||||||
Compiling and installing protobuf 3.0.0 requires a few more dependencies in |
|
||||||
itself, notably the autoconf suite. If you have apt-get, you can install |
|
||||||
these dependencies this way: |
|
||||||
|
|
||||||
# apt-get install autoconf libtool |
|
||||||
|
|
||||||
If you want to run the tests using one of the sanitized configurations, you |
|
||||||
will need clang and its instrumented libc++: |
|
||||||
|
|
||||||
# apt-get install clang libc++-dev |
|
||||||
|
|
||||||
Mac-specific notes: |
|
||||||
------------------- |
|
||||||
|
|
||||||
For a Mac system, git is not available by default. You will first need to |
|
||||||
install Xcode from the Mac AppStore and then run the following command from a |
|
||||||
terminal: |
|
||||||
|
|
||||||
$ sudo xcode-select --install |
|
||||||
|
|
||||||
You should also install "port" following the instructions at |
|
||||||
https://www.macports.org . This will reside in /opt/local/bin/port for |
|
||||||
most Mac installations. Do the "git submodule" command listed above. |
|
||||||
|
|
||||||
Then execute the following for all the needed build dependencies |
|
||||||
|
|
||||||
$ sudo /opt/local/bin/port install autoconf automake libtool gflags cmake |
|
||||||
$ mkdir ~/gtest-svn |
|
||||||
$ svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn |
|
||||||
$ mkdir mybuild |
|
||||||
$ cd mybuild |
|
||||||
$ cmake ../gtest-svn |
|
||||||
$ make |
|
||||||
$ make gtest.a gtest_main.a |
|
||||||
$ sudo cp libgtest.a libgtest_main.a /opt/local/lib |
|
||||||
$ sudo mkdir /opt/local/include/gtest |
|
||||||
$ sudo cp -pr ../gtest-svn/include/gtest /opt/local/include/gtest |
|
||||||
|
|
||||||
If you are going to make changes and need to regenerate the projects file, |
|
||||||
you will need to install certain modules for python. |
|
||||||
|
|
||||||
$ sudo easy_install simplejson mako |
|
||||||
|
|
||||||
Mingw-specific notes: |
|
||||||
--------------------- |
|
||||||
|
|
||||||
While gRPC compiles properly under mingw, some more preparation work is needed. |
|
||||||
The recommendation is to use msys2. The installation instructions are available |
|
||||||
at that address: http://msys2.github.io/ |
|
||||||
|
|
||||||
Once this is installed, make sure you are using the following: MinGW-w64 Win64. |
|
||||||
You'll be required to install a few more packages: |
|
||||||
|
|
||||||
$ pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-zlib autoconf automake libtool |
|
||||||
|
|
||||||
Please also install OpenSSL from that website: |
|
||||||
|
|
||||||
http://slproweb.com/products/Win32OpenSSL.html |
|
||||||
|
|
||||||
The package Win64 OpenSSL v1.0.2a should do. At that point you should be able |
|
||||||
to compile gRPC with the following: |
|
||||||
|
|
||||||
$ export LDFLAGS="-L/mingw64/lib -L/c/OpenSSL-Win64" |
|
||||||
$ export CPPFLAGS="-I/mingw64/include -I/c/OpenSSL-Win64/include" |
|
||||||
$ make |
|
||||||
|
|
||||||
A word on OpenSSL |
|
||||||
----------------- |
|
||||||
|
|
||||||
Secure HTTP2 requires the TLS extension ALPN (see rfc 7301 and |
|
||||||
http://http2.github.io/http2-spec/ section 3.3). Our HTTP2 implementation |
|
||||||
relies on OpenSSL's implementation. OpenSSL 1.0.2 is the first released version |
|
||||||
of OpenSSL that has ALPN support, and this explains our dependency on it. |
|
||||||
|
|
||||||
Note that the Makefile supports compiling only the unsecure elements of grpc, |
|
||||||
and if you do not have OpenSSL and do not want it, you can still proceed |
|
||||||
with installing only the elements you require. However, we strongly recommend |
|
||||||
the use of encryption for all network traffic, and discourage the use of grpc |
|
||||||
without TLS. |
|
||||||
|
|
||||||
|
|
||||||
Compiling |
|
||||||
========= |
|
||||||
|
|
||||||
If you have all the dependencies mentioned above, you should simply be able |
|
||||||
to go ahead and run "make" to compile grpc's C and C++ libraries: |
|
||||||
|
|
||||||
$ make |
|
||||||
|
|
||||||
|
|
||||||
Testing |
|
||||||
======= |
|
||||||
|
|
||||||
To build and run the tests, you can run the command: |
|
||||||
|
|
||||||
$ make test |
|
||||||
|
|
||||||
If you want to be able to run them in parallel, and get better output, you can |
|
||||||
also use the python tool we have written: |
|
||||||
|
|
||||||
$ ./tools/run_tests/run_tests.py |
|
||||||
|
|
||||||
|
|
||||||
Installing |
|
||||||
========== |
|
||||||
|
|
||||||
Once everything is compiled, you should be able to install grpc C and C++ |
|
||||||
libraries and headers: |
|
||||||
|
|
||||||
# make install |
|
@ -0,0 +1,57 @@ |
|||||||
|
#If you are in a hurry |
||||||
|
|
||||||
|
For language-specific installation instructions for gRPC runtime, please |
||||||
|
refer to these documents |
||||||
|
|
||||||
|
* [C++](examples/cpp): Currently to install gRPC for C++, you need to build from source as described below. |
||||||
|
* [C#](src/csharp): NuGet package `Grpc` |
||||||
|
* [Go](https://github.com/grpc/grpc-go): `go get google.golang.org/grpc` |
||||||
|
* [Java](https://github.com/grpc/grpc-java) |
||||||
|
* [Node](src/node): `npm install grpc` |
||||||
|
* [Objective-C](src/objective-c) |
||||||
|
* [PHP](src/php): `pecl install grpc-beta` |
||||||
|
* [Python](src/python/grpcio): `pip install grpcio` |
||||||
|
* [Ruby](src/ruby): `gem install grpc` |
||||||
|
|
||||||
|
|
||||||
|
#Pre-requisites |
||||||
|
|
||||||
|
##Linux |
||||||
|
|
||||||
|
```sh |
||||||
|
$ [sudo] apt-get install build-essential autoconf libtool |
||||||
|
``` |
||||||
|
|
||||||
|
##Mac OSX |
||||||
|
|
||||||
|
For a Mac system, git is not available by default. You will first need to |
||||||
|
install Xcode from the Mac AppStore and then run the following command from a |
||||||
|
terminal: |
||||||
|
|
||||||
|
```sh |
||||||
|
$ [sudo] xcode-select --install |
||||||
|
``` |
||||||
|
|
||||||
|
##Protoc |
||||||
|
|
||||||
|
By default gRPC uses [protocol buffers](https://github.com/google/protobuf), |
||||||
|
you will need the `protoc` compiler to generate stub server and client code. |
||||||
|
|
||||||
|
If you compile gRPC from source, as described below, the Makefile will |
||||||
|
automatically try and compile the `protoc` in third_party if you cloned the |
||||||
|
repository recursively and it detects that you don't already have it |
||||||
|
installed. |
||||||
|
|
||||||
|
|
||||||
|
#Build from Source |
||||||
|
|
||||||
|
For developers who are interested to contribute, here is how to compile the |
||||||
|
gRPC C Core library. |
||||||
|
|
||||||
|
```sh |
||||||
|
$ git clone https://github.com/grpc/grpc.git |
||||||
|
$ cd grpc |
||||||
|
$ git submodule update --init |
||||||
|
$ make |
||||||
|
$ [sudo] make install |
||||||
|
``` |
@ -1,17 +1,14 @@ |
|||||||
{ |
{ |
||||||
|
"name": "grpc/grpc-demo", |
||||||
|
"description": "gRPC example for PHP", |
||||||
|
"minimum-stability": "dev", |
||||||
"repositories": [ |
"repositories": [ |
||||||
{ |
{ |
||||||
"type": "vcs", |
"type": "vcs", |
||||||
"url": "https://github.com/stanley-cheung/Protobuf-PHP" |
"url": "https://github.com/stanley-cheung/Protobuf-PHP" |
||||||
} |
} |
||||||
], |
], |
||||||
"name": "grpc/grpc-demo", |
|
||||||
"description": "gRPC example for PHP", |
|
||||||
"minimum-stability": "dev", |
|
||||||
"require": { |
"require": { |
||||||
"php": ">=5.5.0", |
"grpc/grpc": "dev-release-0_13" |
||||||
"datto/protobuf-php": "dev-master", |
|
||||||
"google/auth": "dev-master", |
|
||||||
"grpc/grpc": "dev-release-0_11" |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,77 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016, 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 <SystemConfiguration/SystemConfiguration.h> |
||||||
|
|
||||||
|
@interface GRPCReachabilityFlags : NSObject |
||||||
|
|
||||||
|
+ (nonnull instancetype)flagsWithFlags:(SCNetworkReachabilityFlags)flags; |
||||||
|
|
||||||
|
/**
|
||||||
|
* One accessor method to query each of the different flags. Example: |
||||||
|
|
||||||
|
@property(nonatomic, readonly) BOOL isCell; |
||||||
|
|
||||||
|
*/ |
||||||
|
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ |
||||||
|
@property(nonatomic, readonly) BOOL methodName; |
||||||
|
|
||||||
|
#include "GRPCReachabilityFlagNames.xmacro.h" |
||||||
|
#undef GRPC_XMACRO_ITEM |
||||||
|
|
||||||
|
@property(nonatomic, readonly) BOOL isHostReachable; |
||||||
|
@end |
||||||
|
|
||||||
|
|
||||||
|
@interface GRPCConnectivityMonitor : NSObject |
||||||
|
|
||||||
|
+ (nullable instancetype)monitorWithHost:(nonnull NSString *)hostName; |
||||||
|
|
||||||
|
- (nonnull instancetype)init NS_UNAVAILABLE; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue on which callbacks will be dispatched. Default is the main queue. Set it before calling |
||||||
|
* handleLossWithHandler:. |
||||||
|
*/ |
||||||
|
// TODO(jcanizales): Default to a serial background queue instead.
|
||||||
|
@property(nonatomic, strong, null_resettable) dispatch_queue_t queue; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls handler every time the connectivity to this instance's host is lost. If this instance is |
||||||
|
* released before that happens, the handler won't be called. |
||||||
|
* Only one handler is active at a time, so if this method is called again before the previous |
||||||
|
* handler has been called, it might never be called at all (or yes, if it has already been queued). |
||||||
|
*/ |
||||||
|
- (void)handleLossWithHandler:(nonnull void (^)())handler; |
||||||
|
@end |
@ -0,0 +1,192 @@ |
|||||||
|
/* |
||||||
|
* |
||||||
|
* Copyright 2016, 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 "GRPCConnectivityMonitor.h" |
||||||
|
|
||||||
|
#pragma mark Flags |
||||||
|
|
||||||
|
@implementation GRPCReachabilityFlags { |
||||||
|
SCNetworkReachabilityFlags _flags; |
||||||
|
} |
||||||
|
|
||||||
|
+ (instancetype)flagsWithFlags:(SCNetworkReachabilityFlags)flags { |
||||||
|
return [[self alloc] initWithFlags:flags]; |
||||||
|
} |
||||||
|
|
||||||
|
- (instancetype)initWithFlags:(SCNetworkReachabilityFlags)flags { |
||||||
|
if ((self = [super init])) { |
||||||
|
_flags = flags; |
||||||
|
} |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* One accessor method implementation per flag. Example: |
||||||
|
|
||||||
|
- (BOOL)isCell { \ |
||||||
|
return !!(_flags & kSCNetworkReachabilityFlagsIsWWAN); \ |
||||||
|
} |
||||||
|
|
||||||
|
*/ |
||||||
|
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ |
||||||
|
- (BOOL)methodName { \ |
||||||
|
return !!(_flags & kSCNetworkReachabilityFlags ## FlagName); \ |
||||||
|
} |
||||||
|
#include "GRPCReachabilityFlagNames.xmacro.h" |
||||||
|
#undef GRPC_XMACRO_ITEM |
||||||
|
|
||||||
|
- (BOOL)isHostReachable { |
||||||
|
// Note: connectionOnDemand means it'll be reachable only if using the CFSocketStream API or APIs |
||||||
|
// on top of it. |
||||||
|
// connectionRequired means we can't tell until a connection is attempted (e.g. for VPN on |
||||||
|
// demand). |
||||||
|
return self.reachable && !self.interventionRequired && !self.connectionOnDemand; |
||||||
|
} |
||||||
|
|
||||||
|
- (NSString *)description { |
||||||
|
NSMutableArray *activeOptions = [NSMutableArray arrayWithCapacity:9]; |
||||||
|
|
||||||
|
/* |
||||||
|
* For each flag, add its name to the array if it's ON. Example: |
||||||
|
|
||||||
|
if (self.isCell) { |
||||||
|
[activeOptions addObject:@"isCell"]; |
||||||
|
} |
||||||
|
|
||||||
|
*/ |
||||||
|
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ |
||||||
|
if (self.methodName) { \ |
||||||
|
[activeOptions addObject:@#methodName]; \ |
||||||
|
} |
||||||
|
#include "GRPCReachabilityFlagNames.xmacro.h" |
||||||
|
#undef GRPC_XMACRO_ITEM |
||||||
|
|
||||||
|
return activeOptions.count == 0 ? @"(none)" : [activeOptions componentsJoinedByString:@", "]; |
||||||
|
} |
||||||
|
|
||||||
|
- (BOOL)isEqual:(id)object { |
||||||
|
return [object isKindOfClass:[GRPCReachabilityFlags class]] && |
||||||
|
_flags == ((GRPCReachabilityFlags *)object)->_flags; |
||||||
|
} |
||||||
|
|
||||||
|
- (NSUInteger)hash { |
||||||
|
return _flags; |
||||||
|
} |
||||||
|
@end |
||||||
|
|
||||||
|
#pragma mark Connectivity Monitor |
||||||
|
|
||||||
|
// Assumes the third argument is a block that accepts a GRPCReachabilityFlags object, and passes the |
||||||
|
// received ones to it. |
||||||
|
static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target, |
||||||
|
SCNetworkReachabilityFlags flags, |
||||||
|
void *info) { |
||||||
|
#pragma unused (target) |
||||||
|
// This can be called many times with the same info. The info is retained by SCNetworkReachability |
||||||
|
// while this function is being executed. |
||||||
|
void (^handler)(GRPCReachabilityFlags *) = (__bridge void (^)(GRPCReachabilityFlags *))info; |
||||||
|
handler([[GRPCReachabilityFlags alloc] initWithFlags:flags]); |
||||||
|
} |
||||||
|
|
||||||
|
@implementation GRPCConnectivityMonitor { |
||||||
|
SCNetworkReachabilityRef _reachabilityRef; |
||||||
|
} |
||||||
|
|
||||||
|
- (nullable instancetype)initWithReachability:(nullable SCNetworkReachabilityRef)reachability { |
||||||
|
if (!reachability) { |
||||||
|
return nil; |
||||||
|
} |
||||||
|
if ((self = [super init])) { |
||||||
|
_reachabilityRef = CFRetain(reachability); |
||||||
|
_queue = dispatch_get_main_queue(); |
||||||
|
} |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
+ (nullable instancetype)monitorWithHost:(nonnull NSString *)host { |
||||||
|
const char *hostName = host.UTF8String; |
||||||
|
if (!hostName) { |
||||||
|
[NSException raise:NSInvalidArgumentException |
||||||
|
format:@"host.UTF8String returns NULL for %@", host]; |
||||||
|
} |
||||||
|
SCNetworkReachabilityRef reachability = |
||||||
|
SCNetworkReachabilityCreateWithName(NULL, hostName); |
||||||
|
|
||||||
|
GRPCConnectivityMonitor *returnValue = [[self alloc] initWithReachability:reachability]; |
||||||
|
if (reachability) { |
||||||
|
CFRelease(reachability); |
||||||
|
} |
||||||
|
return returnValue; |
||||||
|
} |
||||||
|
|
||||||
|
- (void)handleLossWithHandler:(void (^)())handler { |
||||||
|
[self startListeningWithHandler:^(GRPCReachabilityFlags *flags) { |
||||||
|
if (!flags.isHostReachable) { |
||||||
|
handler(); |
||||||
|
} |
||||||
|
}]; |
||||||
|
} |
||||||
|
|
||||||
|
- (void)startListeningWithHandler:(void (^)(GRPCReachabilityFlags *))handler { |
||||||
|
// Copy to ensure the handler block is in the heap (and so can't be deallocated when this method |
||||||
|
// returns). |
||||||
|
void (^copiedHandler)(GRPCReachabilityFlags *) = [handler copy]; |
||||||
|
SCNetworkReachabilityContext context = { |
||||||
|
.version = 0, |
||||||
|
.info = (__bridge void *)copiedHandler, |
||||||
|
.retain = CFRetain, |
||||||
|
.release = CFRelease, |
||||||
|
}; |
||||||
|
// The following will retain context.info, and release it when the callback is set to NULL. |
||||||
|
SCNetworkReachabilitySetCallback(_reachabilityRef, PassFlagsToContextInfoBlock, &context); |
||||||
|
SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _queue); |
||||||
|
} |
||||||
|
|
||||||
|
- (void)stopListening { |
||||||
|
// This releases the block on context.info. |
||||||
|
SCNetworkReachabilitySetCallback(_reachabilityRef, NULL, NULL); |
||||||
|
SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
- (void)setQueue:(dispatch_queue_t)queue { |
||||||
|
_queue = queue ?: dispatch_get_main_queue(); |
||||||
|
} |
||||||
|
|
||||||
|
- (void)dealloc { |
||||||
|
if (_reachabilityRef) { |
||||||
|
[self stopListening]; |
||||||
|
CFRelease(_reachabilityRef); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@end |
@ -0,0 +1,65 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016, 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. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* "X-macro" file that lists the flags names of Apple's Network Reachability API, along with a nice |
||||||
|
* Objective-C method name used to query each of them. |
||||||
|
* |
||||||
|
* Example usage: To generate a dictionary from flag value to name, one can do: |
||||||
|
|
||||||
|
NSDictionary *flagNames = @{ |
||||||
|
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ |
||||||
|
@(kSCNetworkReachabilityFlags ## FlagName): @#methodName, |
||||||
|
#include "GRXReachabilityFlagNames.xmacro.h" |
||||||
|
#undef GRPC_XMACRO_ITEM |
||||||
|
}; |
||||||
|
|
||||||
|
XCTAssertEqualObjects(flagNames[@(kSCNetworkReachabilityFlagsIsWWAN)], @"isCell"); |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_XMACRO_ITEM |
||||||
|
#error This file is to be used with the "X-macro" pattern: Please #define \ |
||||||
|
GRPC_XMACRO_ITEM(methodName, FlagName), then #include this file, and then #undef \
|
||||||
|
GRPC_XMACRO_ITEM. |
||||||
|
#endif |
||||||
|
|
||||||
|
GRPC_XMACRO_ITEM(isCell, IsWWAN) |
||||||
|
GRPC_XMACRO_ITEM(reachable, Reachable) |
||||||
|
GRPC_XMACRO_ITEM(transientConnection, TransientConnection) |
||||||
|
GRPC_XMACRO_ITEM(connectionRequired, ConnectionRequired) |
||||||
|
GRPC_XMACRO_ITEM(connectionOnTraffic, ConnectionOnTraffic) |
||||||
|
GRPC_XMACRO_ITEM(interventionRequired, InterventionRequired) |
||||||
|
GRPC_XMACRO_ITEM(connectionOnDemand, ConnectionOnDemand) |
||||||
|
GRPC_XMACRO_ITEM(isLocalAddress, IsLocalAddress) |
||||||
|
GRPC_XMACRO_ITEM(isDirect, IsDirect) |
@ -1,67 +0,0 @@ |
|||||||
gRPC PHP Extension |
|
||||||
================== |
|
||||||
|
|
||||||
# Requirements |
|
||||||
|
|
||||||
* PHP 5.5+ |
|
||||||
* [gRPC core library](https://github.com/grpc/grpc) 0.11.0 |
|
||||||
|
|
||||||
# Installation |
|
||||||
|
|
||||||
## Install PHP 5 |
|
||||||
|
|
||||||
``` |
|
||||||
$ sudo apt-get install git php5 php5-dev php-pear unzip |
|
||||||
``` |
|
||||||
|
|
||||||
## Compile gRPC Core Library |
|
||||||
|
|
||||||
Clone the gRPC source code repository |
|
||||||
|
|
||||||
``` |
|
||||||
$ git clone https://github.com/grpc/grpc.git |
|
||||||
``` |
|
||||||
|
|
||||||
Build and install the gRPC C core libraries |
|
||||||
|
|
||||||
```sh |
|
||||||
$ cd grpc |
|
||||||
$ git checkout --track origin/release-0_11 |
|
||||||
$ git pull --recurse-submodules && git submodule update --init --recursive |
|
||||||
$ make |
|
||||||
$ sudo make install |
|
||||||
``` |
|
||||||
|
|
||||||
Note: you may encounter a warning about the Protobuf compiler `protoc` 3.0.0+ not being installed. The following might help, and will be useful later on when we need to compile the `protoc-gen-php` tool. |
|
||||||
|
|
||||||
```sh |
|
||||||
$ cd grpc/third_party/protobuf |
|
||||||
$ sudo make install # 'make' should have been run by core grpc |
|
||||||
``` |
|
||||||
|
|
||||||
## Install the gRPC PHP extension |
|
||||||
|
|
||||||
Quick install |
|
||||||
|
|
||||||
```sh |
|
||||||
$ sudo pecl install grpc |
|
||||||
``` |
|
||||||
|
|
||||||
Note: before a stable release, you may need to do |
|
||||||
|
|
||||||
```sh |
|
||||||
$ sudo pecl install grpc-beta |
|
||||||
``` |
|
||||||
|
|
||||||
OR |
|
||||||
|
|
||||||
Compile from source |
|
||||||
|
|
||||||
```sh |
|
||||||
$ # from grpc |
|
||||||
$ cd src/php/ext/grpc |
|
||||||
$ phpize |
|
||||||
$ ./configure |
|
||||||
$ make |
|
||||||
$ sudo make install |
|
||||||
``` |
|
@ -0,0 +1,53 @@ |
|||||||
|
[ |
||||||
|
"_base_interface_test.AsyncEasyTest", |
||||||
|
"_base_interface_test.AsyncPeasyTest", |
||||||
|
"_base_interface_test.SyncEasyTest", |
||||||
|
"_base_interface_test.SyncPeasyTest", |
||||||
|
"_beta_features_test.BetaFeaturesTest", |
||||||
|
"_beta_features_test.ContextManagementAndLifecycleTest", |
||||||
|
"_channel_test.ChannelTest", |
||||||
|
"_connectivity_channel_test.ChannelConnectivityTest", |
||||||
|
"_core_over_links_base_interface_test.AsyncEasyTest", |
||||||
|
"_core_over_links_base_interface_test.AsyncPeasyTest", |
||||||
|
"_core_over_links_base_interface_test.SyncEasyTest", |
||||||
|
"_core_over_links_base_interface_test.SyncPeasyTest", |
||||||
|
"_crust_over_core_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_crust_over_core_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_crust_over_core_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_crust_over_core_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_crust_over_core_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_crust_over_core_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_crust_over_core_over_links_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_crust_over_core_over_links_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_crust_over_core_over_links_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_crust_over_core_over_links_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_crust_over_core_over_links_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_crust_over_core_over_links_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", |
||||||
|
"_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest", |
||||||
|
"_implementations_test.ChannelCredentialsTest", |
||||||
|
"_insecure_interop_test.InsecureInteropTest", |
||||||
|
"_intermediary_low_test.CancellationTest", |
||||||
|
"_intermediary_low_test.EchoTest", |
||||||
|
"_intermediary_low_test.ExpirationTest", |
||||||
|
"_intermediary_low_test.LonelyClientTest", |
||||||
|
"_later_test.LaterTest", |
||||||
|
"_logging_pool_test.LoggingPoolTest", |
||||||
|
"_lonely_invocation_link_test.LonelyInvocationLinkTest", |
||||||
|
"_low_test.HangingServerShutdown", |
||||||
|
"_low_test.InsecureServerInsecureClient", |
||||||
|
"_not_found_test.NotFoundTest", |
||||||
|
"_sanity_test.Sanity", |
||||||
|
"_secure_interop_test.SecureInteropTest", |
||||||
|
"_transmission_test.RoundTripTest", |
||||||
|
"_transmission_test.TransmissionTest", |
||||||
|
"_utilities_test.ChannelConnectivityTest", |
||||||
|
"beta_python_plugin_test.PythonPluginTest", |
||||||
|
"cygrpc_test.InsecureServerInsecureClient", |
||||||
|
"cygrpc_test.SecureServerSecureClient", |
||||||
|
"cygrpc_test.TypeSmokeTest" |
||||||
|
] |
@ -0,0 +1,30 @@ |
|||||||
|
# Copyright 2016, 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. |
||||||
|
|
||||||
|
|
@ -0,0 +1,53 @@ |
|||||||
|
# Copyright 2016, 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 json |
||||||
|
import unittest |
||||||
|
|
||||||
|
import tests |
||||||
|
|
||||||
|
|
||||||
|
class Sanity(unittest.TestCase): |
||||||
|
|
||||||
|
def testTestsJsonUpToDate(self): |
||||||
|
"""Autodiscovers all test suites and checks that tests.json is up to date""" |
||||||
|
loader = tests.Loader() |
||||||
|
loader.loadTestsFromNames(['tests']) |
||||||
|
test_suite_names = [ |
||||||
|
test_case_class.id().rsplit('.', 1)[0] |
||||||
|
for test_case_class in tests._loader.iterate_suite_cases(loader.suite)] |
||||||
|
test_suite_names = sorted(set(test_suite_names)) |
||||||
|
|
||||||
|
with open('src/python/grpcio/tests/tests.json') as tests_json_file: |
||||||
|
tests_json = json.load(tests_json_file) |
||||||
|
self.assertListEqual(test_suite_names, tests_json) |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
unittest.main(verbosity=2) |
@ -1,381 +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. |
|
||||||
|
|
||||||
"""Test code for the Face layer of RPC Framework.""" |
|
||||||
|
|
||||||
import abc |
|
||||||
import unittest |
|
||||||
|
|
||||||
# test_interfaces is referenced from specification in this module. |
|
||||||
from grpc.framework.interfaces.face import face |
|
||||||
from tests.unit.framework.common import test_constants |
|
||||||
from tests.unit.framework.common import test_control |
|
||||||
from tests.unit.framework.common import test_coverage |
|
||||||
from tests.unit.framework.interfaces.face import _3069_test_constant |
|
||||||
from tests.unit.framework.interfaces.face import _digest |
|
||||||
from tests.unit.framework.interfaces.face import _receiver |
|
||||||
from tests.unit.framework.interfaces.face import _stock_service |
|
||||||
from tests.unit.framework.interfaces.face import test_interfaces # pylint: disable=unused-import |
|
||||||
|
|
||||||
|
|
||||||
class TestCase(test_coverage.Coverage, unittest.TestCase): |
|
||||||
"""A test of the Face layer of RPC Framework. |
|
||||||
|
|
||||||
Concrete subclasses must have an "implementation" attribute of type |
|
||||||
test_interfaces.Implementation and an "invoker_constructor" attribute of type |
|
||||||
_invocation.InvokerConstructor. |
|
||||||
""" |
|
||||||
__metaclass__ = abc.ABCMeta |
|
||||||
|
|
||||||
NAME = 'EventInvocationSynchronousEventServiceTest' |
|
||||||
|
|
||||||
def setUp(self): |
|
||||||
"""See unittest.TestCase.setUp for full specification. |
|
||||||
|
|
||||||
Overriding implementations must call this implementation. |
|
||||||
""" |
|
||||||
self._control = test_control.PauseFailControl() |
|
||||||
self._digest = _digest.digest( |
|
||||||
_stock_service.STOCK_TEST_SERVICE, self._control, None) |
|
||||||
|
|
||||||
generic_stub, dynamic_stubs, self._memo = self.implementation.instantiate( |
|
||||||
self._digest.methods, self._digest.event_method_implementations, None) |
|
||||||
self._invoker = self.invoker_constructor.construct_invoker( |
|
||||||
generic_stub, dynamic_stubs, self._digest.methods) |
|
||||||
|
|
||||||
def tearDown(self): |
|
||||||
"""See unittest.TestCase.tearDown for full specification. |
|
||||||
|
|
||||||
Overriding implementations must call this implementation. |
|
||||||
""" |
|
||||||
self._invoker = None |
|
||||||
self.implementation.destantiate(self._memo) |
|
||||||
|
|
||||||
def testSuccessfulUnaryRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
response = receiver.unary_response() |
|
||||||
|
|
||||||
test_messages.verify(request, response, self) |
|
||||||
|
|
||||||
def testSuccessfulUnaryRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
responses = receiver.stream_responses() |
|
||||||
|
|
||||||
test_messages.verify(request, responses, self) |
|
||||||
|
|
||||||
def testSuccessfulStreamRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
requests = test_messages.requests() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
for request in requests: |
|
||||||
call_consumer.consume(request) |
|
||||||
call_consumer.terminate() |
|
||||||
receiver.block_until_terminated() |
|
||||||
response = receiver.unary_response() |
|
||||||
|
|
||||||
test_messages.verify(requests, response, self) |
|
||||||
|
|
||||||
def testSuccessfulStreamRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
requests = test_messages.requests() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
for request in requests: |
|
||||||
call_consumer.consume(request) |
|
||||||
call_consumer.terminate() |
|
||||||
receiver.block_until_terminated() |
|
||||||
responses = receiver.stream_responses() |
|
||||||
|
|
||||||
test_messages.verify(requests, responses, self) |
|
||||||
|
|
||||||
def testSequentialInvocations(self): |
|
||||||
# pylint: disable=cell-var-from-loop |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
first_request = test_messages.request() |
|
||||||
second_request = test_messages.request() |
|
||||||
second_receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
def make_second_invocation(): |
|
||||||
self._invoker.event(group, method)( |
|
||||||
second_request, second_receiver, second_receiver.abort, |
|
||||||
test_constants.LONG_TIMEOUT) |
|
||||||
|
|
||||||
class FirstReceiver(_receiver.Receiver): |
|
||||||
|
|
||||||
def complete(self, terminal_metadata, code, details): |
|
||||||
super(FirstReceiver, self).complete( |
|
||||||
terminal_metadata, code, details) |
|
||||||
make_second_invocation() |
|
||||||
|
|
||||||
first_receiver = FirstReceiver() |
|
||||||
|
|
||||||
self._invoker.event(group, method)( |
|
||||||
first_request, first_receiver, first_receiver.abort, |
|
||||||
test_constants.LONG_TIMEOUT) |
|
||||||
second_receiver.block_until_terminated() |
|
||||||
|
|
||||||
first_response = first_receiver.unary_response() |
|
||||||
second_response = second_receiver.unary_response() |
|
||||||
test_messages.verify(first_request, first_response, self) |
|
||||||
test_messages.verify(second_request, second_response, self) |
|
||||||
|
|
||||||
def testParallelInvocations(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
first_request = test_messages.request() |
|
||||||
first_receiver = _receiver.Receiver() |
|
||||||
second_request = test_messages.request() |
|
||||||
second_receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
self._invoker.event(group, method)( |
|
||||||
first_request, first_receiver, first_receiver.abort, |
|
||||||
test_constants.LONG_TIMEOUT) |
|
||||||
self._invoker.event(group, method)( |
|
||||||
second_request, second_receiver, second_receiver.abort, |
|
||||||
test_constants.LONG_TIMEOUT) |
|
||||||
first_receiver.block_until_terminated() |
|
||||||
second_receiver.block_until_terminated() |
|
||||||
|
|
||||||
first_response = first_receiver.unary_response() |
|
||||||
second_response = second_receiver.unary_response() |
|
||||||
test_messages.verify(first_request, first_response, self) |
|
||||||
test_messages.verify(second_request, second_response, self) |
|
||||||
|
|
||||||
@unittest.skip('TODO(nathaniel): implement.') |
|
||||||
def testWaitingForSomeButNotAllParallelInvocations(self): |
|
||||||
raise NotImplementedError() |
|
||||||
|
|
||||||
def testCancelledUnaryRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.pause(): |
|
||||||
call = self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
call.cancel() |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.CANCELLED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testCancelledUnaryRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
call = self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
call.cancel() |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.CANCELLED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testCancelledStreamRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
requests = test_messages.requests() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
for request in requests: |
|
||||||
call_consumer.consume(request) |
|
||||||
call_consumer.cancel() |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.CANCELLED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testCancelledStreamRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_stream_messages_sequences.iteritems()): |
|
||||||
for unused_test_messages in test_messages_sequence: |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
call_consumer.cancel() |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.CANCELLED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testExpiredUnaryRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.pause(): |
|
||||||
self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, |
|
||||||
_3069_test_constant.REALLY_SHORT_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.EXPIRED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testExpiredUnaryRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.pause(): |
|
||||||
self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, |
|
||||||
_3069_test_constant.REALLY_SHORT_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.EXPIRED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testExpiredStreamRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_unary_messages_sequences.iteritems()): |
|
||||||
for unused_test_messages in test_messages_sequence: |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, _3069_test_constant.REALLY_SHORT_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.EXPIRED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testExpiredStreamRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
requests = test_messages.requests() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, _3069_test_constant.REALLY_SHORT_TIMEOUT) |
|
||||||
for request in requests: |
|
||||||
call_consumer.consume(request) |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs(face.Abortion.Kind.EXPIRED, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testFailedUnaryRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.fail(): |
|
||||||
self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs( |
|
||||||
face.Abortion.Kind.REMOTE_FAILURE, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testFailedUnaryRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.unary_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
request = test_messages.request() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.fail(): |
|
||||||
self._invoker.event(group, method)( |
|
||||||
request, receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs( |
|
||||||
face.Abortion.Kind.REMOTE_FAILURE, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testFailedStreamRequestUnaryResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_unary_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
requests = test_messages.requests() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.fail(): |
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
for request in requests: |
|
||||||
call_consumer.consume(request) |
|
||||||
call_consumer.terminate() |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs( |
|
||||||
face.Abortion.Kind.REMOTE_FAILURE, receiver.abortion().kind) |
|
||||||
|
|
||||||
def testFailedStreamRequestStreamResponse(self): |
|
||||||
for (group, method), test_messages_sequence in ( |
|
||||||
self._digest.stream_stream_messages_sequences.iteritems()): |
|
||||||
for test_messages in test_messages_sequence: |
|
||||||
requests = test_messages.requests() |
|
||||||
receiver = _receiver.Receiver() |
|
||||||
|
|
||||||
with self._control.fail(): |
|
||||||
call_consumer = self._invoker.event(group, method)( |
|
||||||
receiver, receiver.abort, test_constants.LONG_TIMEOUT) |
|
||||||
for request in requests: |
|
||||||
call_consumer.consume(request) |
|
||||||
call_consumer.terminate() |
|
||||||
receiver.block_until_terminated() |
|
||||||
|
|
||||||
self.assertIs( |
|
||||||
face.Abortion.Kind.REMOTE_FAILURE, receiver.abortion().kind) |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue