Merge github.com:grpc/grpc into we-dont-need-no-backup

pull/2105/head
Craig Tiller 10 years ago
commit d5d862df67
  1. 11
      src/compiler/cpp_generator.cc
  2. 2
      src/core/transport/stream_op.h
  3. 137
      src/php/README.md
  4. 4
      src/php/bin/run_gen_code_test.sh
  5. 7
      src/php/composer.json
  6. 2
      src/php/tests/generated_code/AbstractGeneratedCodeTest.php
  7. 2
      src/php/tests/interop/interop_client.php
  8. 6
      src/python/README.md
  9. 22
      src/python/src/README.rst
  10. 13
      src/python/src/grpc/_adapter/_c/utility.c
  11. 182
      test/compiler/python_plugin_test.py
  12. 2
      tools/run_tests/build_python.sh

@ -849,6 +849,9 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
"::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, " "::grpc::ServerContext* context, "
"const $Request$* request, $Response$* response) {\n"); "const $Request$* request, $Response$* response) {\n");
printer->Print(" (void) context;\n");
printer->Print(" (void) request;\n");
printer->Print(" (void) response;\n");
printer->Print( printer->Print(
" return ::grpc::Status(" " return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n"); "::grpc::StatusCode::UNIMPLEMENTED);\n");
@ -859,6 +862,9 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
"::grpc::ServerContext* context, " "::grpc::ServerContext* context, "
"::grpc::ServerReader< $Request$>* reader, " "::grpc::ServerReader< $Request$>* reader, "
"$Response$* response) {\n"); "$Response$* response) {\n");
printer->Print(" (void) context;\n");
printer->Print(" (void) reader;\n");
printer->Print(" (void) response;\n");
printer->Print( printer->Print(
" return ::grpc::Status(" " return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n"); "::grpc::StatusCode::UNIMPLEMENTED);\n");
@ -869,6 +875,9 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
"::grpc::ServerContext* context, " "::grpc::ServerContext* context, "
"const $Request$* request, " "const $Request$* request, "
"::grpc::ServerWriter< $Response$>* writer) {\n"); "::grpc::ServerWriter< $Response$>* writer) {\n");
printer->Print(" (void) context;\n");
printer->Print(" (void) request;\n");
printer->Print(" (void) writer;\n");
printer->Print( printer->Print(
" return ::grpc::Status(" " return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n"); "::grpc::StatusCode::UNIMPLEMENTED);\n");
@ -879,6 +888,8 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
"::grpc::ServerContext* context, " "::grpc::ServerContext* context, "
"::grpc::ServerReaderWriter< $Response$, $Request$>* " "::grpc::ServerReaderWriter< $Response$, $Request$>* "
"stream) {\n"); "stream) {\n");
printer->Print(" (void) context;\n");
printer->Print(" (void) stream;\n");
printer->Print( printer->Print(
" return ::grpc::Status(" " return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n"); "::grpc::StatusCode::UNIMPLEMENTED);\n");

@ -58,7 +58,7 @@ typedef enum grpc_stream_op_code {
GRPC_OP_SLICE GRPC_OP_SLICE
} grpc_stream_op_code; } grpc_stream_op_code;
/* Arguments for GRPC_OP_BEGIN */ /* Arguments for GRPC_OP_BEGIN_MESSAGE */
typedef struct grpc_begin_message { typedef struct grpc_begin_message {
/* How many bytes of data will this message contain */ /* How many bytes of data will this message contain */
gpr_uint32 length; gpr_uint32 length;

@ -7,51 +7,122 @@ This directory contains source code for PHP implementation of gRPC layered on sh
Pre-Alpha : This gRPC PHP implementation is work-in-progress and is not expected to work yet. Pre-Alpha : This gRPC PHP implementation is work-in-progress and is not expected to work yet.
## LAYOUT
Directory structure is as generated by the PHP utility
[ext_skel](http://php.net/manual/en/internals2.buildsys.skeleton.php)
## ENVIRONMENT ## ENVIRONMENT
Install `php5` and `php5-dev`. Install `php5` and `php5-dev`.
To run the tests, additionally install `php5-readline` and `phpunit`. To run the tests, additionally install `phpunit`.
Alternatively, build and install PHP 5.5 or later from source with standard Alternatively, build and install PHP 5.5 or later from source with standard
configuration options. configuration options.
To also download and install protoc and the PHP code generator. ## Build from Homebrew
On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to
install gRPC.
```sh
$ curl -fsSL https://goo.gl/getgrpc | bash -s php
```
This will download and run the [gRPC install script][] and compile the gRPC PHP extension.
## Build from Source
Clone this repository
```
$ git clone https://github.com/grpc/grpc.git
```
Build and install the Protocol Buffers compiler (protoc)
```
$ cd grpc
$ git pull --recurse-submodules && git submodule update --init --recursive
$ cd third_party/protobuf
$ ./autogen.sh
$ ./configure
$ make
$ make check
$ sudo make install
```
Build and install the gRPC C core
```sh
$ cd grpc
$ make
$ sudo make install
```
Build the gRPC PHP extension
```bash ```sh
apt-get install -y procps $ cd grpc/src/php/ext/grpc
curl -sSL https://get.rvm.io | sudo bash -s stable --ruby $ phpize
git clone git@github.com:google/protobuf.git $ ./configure
cd protobuf $ make
./configure $ sudo make install
make
make install
git clone git@github.com:murgatroid99/Protobuf-PHP.git
cd Protobuf-PHP
rake pear:package version=1.0
pear install Protobuf-1.0.tgz
``` ```
## BUILDING In your php.ini file, add the line `extension=grpc.so` to load the extension
at PHP startup.
1. In ./ext/grpc, run the command `phpize` (distributed with PHP) Install Composer
2. Run `./ext/grpc/configure`
3. In ./ext/grpc, run `make` and `sudo make install`
4. In your php.ini file, add the line `extension=grpc.so` to load the
extension at PHP startup.
## PHPUnit ```sh
$ cd grpc/src/php
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar install
```
## Unit Tests
Run unit tests
```sh
$ cd grpc/src/php
$ ./bin/run_tests.sh
```
## Generated Code Tests
Install `protoc-gen-php`
```sh
$ cd grpc/src/php/vendor/datto/protobuf-php
$ gem install rake ronn
$ rake pear:package version=1.0
$ sudo pear install Protobuf-1.0.tgz
```
Generate client stub code
```sh
$ cd grpc/src/php
$ ./bin/generate_proto_php.sh
```
Run a local server serving the math services
- Please see [Node][] on how to run an example server
```sh
$ cd grpc/src/node
$ npm install
$ nodejs examples/math_server.js
```
Run the generated code tests
```sh
$ cd grpc/src/php
$ ./bin/run_gen_code_test.sh
```
This repo now has PHPUnit tests, which can by run by executing [homebrew]:http://brew.sh
`./bin/run_tests.sh` after building. [linuxbrew]:https://github.com/Homebrew/linuxbrew#installation
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[Node]:https://github.com/grpc/grpc/tree/master/src/node/examples
There is also a generated code test (`./bin/run_gen_code_test.sh`), which tests
the stub `./tests/generated_code/math.php` against a running localhost server
serving the math service. That stub is generated from
`./tests/generated_code/math.proto`.

@ -30,8 +30,8 @@
cd $(dirname $0) cd $(dirname $0)
GRPC_TEST_HOST=localhost:50051 php -d extension_dir=../ext/grpc/modules/ \ GRPC_TEST_HOST=localhost:50051 php -d extension_dir=../ext/grpc/modules/ \
-d extension=grpc.so /usr/local/bin/phpunit -v --debug --strict \ -d extension=grpc.so `which phpunit` -v --debug --strict \
../tests/generated_code/GeneratedCodeTest.php ../tests/generated_code/GeneratedCodeTest.php
GRPC_TEST_HOST=localhost:50051 php -d extension_dir=../ext/grpc/modules/ \ GRPC_TEST_HOST=localhost:50051 php -d extension_dir=../ext/grpc/modules/ \
-d extension=grpc.so /usr/local/bin/phpunit -v --debug --strict \ -d extension=grpc.so `which phpunit` -v --debug --strict \
../tests/generated_code/GeneratedCodeWithCallbackTest.php ../tests/generated_code/GeneratedCodeWithCallbackTest.php

@ -4,8 +4,15 @@
"version": "0.5.0", "version": "0.5.0",
"homepage": "http://grpc.io", "homepage": "http://grpc.io",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/stanley-cheung/Protobuf-PHP"
}
],
"require": { "require": {
"php": ">=5.5.0", "php": ">=5.5.0",
"datto/protobuf-php": "dev-master",
"google/auth": "dev-master" "google/auth": "dev-master"
}, },
"autoload": { "autoload": {

@ -32,8 +32,6 @@
* *
*/ */
require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php'); require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php');
require 'DrSlump/Protobuf.php';
\DrSlump\Protobuf::autoload();
require 'math.php'; require 'math.php';
abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase { abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase {
/* These tests require that a server exporting the math service must be /* These tests require that a server exporting the math service must be

@ -32,8 +32,6 @@
* *
*/ */
require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php'); require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php');
require 'DrSlump/Protobuf.php';
\DrSlump\Protobuf::autoload();
require 'empty.php'; require 'empty.php';
require 'message_set.php'; require 'message_set.php';
require 'messages.php'; require 'messages.php';

@ -20,6 +20,10 @@ $ curl -fsSL https://goo.gl/getgrpc | bash -s python
``` ```
This will download and run the [gRPC install script][], then install the latest version of the gRPC Python package. It also installs the Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for python. This will download and run the [gRPC install script][], then install the latest version of the gRPC Python package. It also installs the Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for python.
EXAMPLES
--------
Please read our online documentation for a [Quick Start][] and a [detailed example][]
BUILDING FROM SOURCE BUILDING FROM SOURCE
--------------------- ---------------------
- Clone this repository - Clone this repository
@ -58,3 +62,5 @@ $ ../../tools/distrib/python/submit.py
[homebrew]:http://brew.sh [homebrew]:http://brew.sh
[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation [linuxbrew]:https://github.com/Homebrew/linuxbrew#installation
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install [gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[Quick Start]:http://www.grpc.io/docs/tutorials/basic/python.html
[detailed example]:http://www.grpc.io/docs/installation/python.html

@ -6,22 +6,18 @@ Package for GRPC Python.
Dependencies Dependencies
------------ ------------
Ensure that you have installed GRPC core. Ensure you have installed the gRPC core. On Mac OS X, install homebrew_. On Linux, install linuxbrew_.
Run the following command to install gRPC Python.
On debian linux systems, install from our released deb package:
:: ::
$ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc_0.5.0_amd64.deb $ curl -fsSL https://goo.gl/getgrpc | bash -s python
$ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc-dev_0.5.0_amd64.deb
$ sudo dpkg -i libgrpc_0.5.0_amd64.deb libgrpc-dev_0.5.0_amd64.deb
Otherwise, install from source:
:: This will download and run the [gRPC install script][] to install grpc core. The script then uses pip to install this package. It also installs the Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for python.
git clone https://github.com/grpc/grpc.git Otherwise, `install from source`_
cd grpc
./configure
make && make install
.. _`install from source`: https://github.com/grpc/grpc/blob/master/src/python/README.md#building-from-source
.. _homebrew: http://brew.sh
.. _linuxbrew: https://github.com/Homebrew/linuxbrew#installation
.. _`gRPC install script`: https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install

@ -40,6 +40,7 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
#include <grpc/support/time.h> #include <grpc/support/time.h>
#include <grpc/support/string_util.h>
#include "grpc/_adapter/_c/types.h" #include "grpc/_adapter/_c/types.h"
@ -156,9 +157,10 @@ int pygrpc_produce_op(PyObject *op, grpc_op *result) {
return 0; return 0;
} }
if (PyTuple_Size(op) != OP_TUPLE_SIZE) { if (PyTuple_Size(op) != OP_TUPLE_SIZE) {
char buf[64]; char *buf;
snprintf(buf, sizeof(buf), "expected tuple op of length %d", OP_TUPLE_SIZE); gpr_asprintf(&buf, "expected tuple op of length %d", OP_TUPLE_SIZE);
PyErr_SetString(PyExc_ValueError, buf); PyErr_SetString(PyExc_ValueError, buf);
gpr_free(buf);
return 0; return 0;
} }
type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX)); type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX));
@ -353,9 +355,14 @@ double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) {
return timespec.tv_sec + 1e-9*timespec.tv_nsec; return timespec.tv_sec + 1e-9*timespec.tv_nsec;
} }
/* Because C89 doesn't have a way to check for infinity... */
static int pygrpc_isinf(double x) {
return x * 0 != 0;
}
gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds) { gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds) {
gpr_timespec result; gpr_timespec result;
if isinf(seconds) { if (pygrpc_isinf(seconds)) {
result = seconds > 0.0 ? gpr_inf_future : gpr_inf_past; result = seconds > 0.0 ? gpr_inf_future : gpr_inf_past;
} else { } else {
result.tv_sec = (time_t)seconds; result.tv_sec = (time_t)seconds;

@ -66,8 +66,8 @@ class _ServicerMethods(object):
def __init__(self, test_pb2, delay): def __init__(self, test_pb2, delay):
self._paused = False self._paused = False
self._failed = False self._failed = False
self.test_pb2 = test_pb2 self._test_pb2 = test_pb2
self.delay = delay self._delay = delay
@contextlib.contextmanager @contextlib.contextmanager
def pause(self): # pylint: disable=invalid-name def pause(self): # pylint: disable=invalid-name
@ -84,27 +84,27 @@ class _ServicerMethods(object):
def _control(self): # pylint: disable=invalid-name def _control(self): # pylint: disable=invalid-name
if self._failed: if self._failed:
raise ValueError() raise ValueError()
time.sleep(self.delay) time.sleep(self._delay)
while self._paused: while self._paused:
time.sleep(0) time.sleep(0)
def UnaryCall(self, request, unused_context): def UnaryCall(self, request, unused_rpc_context):
response = self.test_pb2.SimpleResponse() response = self._test_pb2.SimpleResponse()
response.payload.payload_type = self.test_pb2.COMPRESSABLE response.payload.payload_type = self._test_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * request.response_size response.payload.payload_compressable = 'a' * request.response_size
self._control() self._control()
return response return response
def StreamingOutputCall(self, request, unused_context): def StreamingOutputCall(self, request, unused_rpc_context):
for parameter in request.response_parameters: for parameter in request.response_parameters:
response = self.test_pb2.StreamingOutputCallResponse() response = self._test_pb2.StreamingOutputCallResponse()
response.payload.payload_type = self.test_pb2.COMPRESSABLE response.payload.payload_type = self._test_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * parameter.size response.payload.payload_compressable = 'a' * parameter.size
self._control() self._control()
yield response yield response
def StreamingInputCall(self, request_iter, unused_context): def StreamingInputCall(self, request_iter, unused_rpc_context):
response = self.test_pb2.StreamingInputCallResponse() response = self._test_pb2.StreamingInputCallResponse()
aggregated_payload_size = 0 aggregated_payload_size = 0
for request in request_iter: for request in request_iter:
aggregated_payload_size += len(request.payload.payload_compressable) aggregated_payload_size += len(request.payload.payload_compressable)
@ -112,21 +112,21 @@ class _ServicerMethods(object):
self._control() self._control()
return response return response
def FullDuplexCall(self, request_iter, unused_context): def FullDuplexCall(self, request_iter, unused_rpc_context):
for request in request_iter: for request in request_iter:
for parameter in request.response_parameters: for parameter in request.response_parameters:
response = self.test_pb2.StreamingOutputCallResponse() response = self._test_pb2.StreamingOutputCallResponse()
response.payload.payload_type = self.test_pb2.COMPRESSABLE response.payload.payload_type = self._test_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * parameter.size response.payload.payload_compressable = 'a' * parameter.size
self._control() self._control()
yield response yield response
def HalfDuplexCall(self, request_iter, unused_context): def HalfDuplexCall(self, request_iter, unused_rpc_context):
responses = [] responses = []
for request in request_iter: for request in request_iter:
for parameter in request.response_parameters: for parameter in request.response_parameters:
response = self.test_pb2.StreamingOutputCallResponse() response = self._test_pb2.StreamingOutputCallResponse()
response.payload.payload_type = self.test_pb2.COMPRESSABLE response.payload.payload_type = self._test_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * parameter.size response.payload.payload_compressable = 'a' * parameter.size
self._control() self._control()
responses.append(response) responses.append(response)
@ -152,7 +152,7 @@ def _CreateService(test_pb2, delay):
timeout: how long the stub will wait for the servicer by default. timeout: how long the stub will wait for the servicer by default.
Yields: Yields:
A three-tuple (servicer_methods, servicer, stub), where the servicer is A (servicer_methods, servicer, stub) three-tuple where servicer_methods is
the back-end of the service bound to the stub and the server and stub the back-end of the service bound to the stub and the server and stub
are both activated and ready for use. are both activated and ready for use.
""" """
@ -185,7 +185,7 @@ def _CreateService(test_pb2, delay):
yield servicer_methods, stub, server yield servicer_methods, stub, server
def StreamingInputRequest(test_pb2): def _streaming_input_request_iterator(test_pb2):
for _ in range(3): for _ in range(3):
request = test_pb2.StreamingInputCallRequest() request = test_pb2.StreamingInputCallRequest()
request.payload.payload_type = test_pb2.COMPRESSABLE request.payload.payload_type = test_pb2.COMPRESSABLE
@ -193,7 +193,7 @@ def StreamingInputRequest(test_pb2):
yield request yield request
def StreamingOutputRequest(test_pb2): def _streaming_output_request(test_pb2):
request = test_pb2.StreamingOutputCallRequest() request = test_pb2.StreamingOutputCallRequest()
sizes = [1, 2, 3] sizes = [1, 2, 3]
request.response_parameters.add(size=sizes[0], interval_us=0) request.response_parameters.add(size=sizes[0], interval_us=0)
@ -202,7 +202,7 @@ def StreamingOutputRequest(test_pb2):
return request return request
def FullDuplexRequest(test_pb2): def _full_duplex_request_iterator(test_pb2):
request = test_pb2.StreamingOutputCallRequest() request = test_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=1, interval_us=0) request.response_parameters.add(size=1, interval_us=0)
yield request yield request
@ -270,32 +270,32 @@ class PythonPluginTest(unittest.TestCase):
def testUnaryCall(self): def testUnaryCall(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
request = test_pb2.SimpleRequest(response_size=13) request = test_pb2.SimpleRequest(response_size=13)
response = stub.UnaryCall(request, NORMAL_TIMEOUT) response = stub.UnaryCall(request, NORMAL_TIMEOUT)
expected_response = servicer.UnaryCall(request, None) expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
def testUnaryCallAsync(self): def testUnaryCallAsync(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = test_pb2.SimpleRequest(response_size=13) request = test_pb2.SimpleRequest(response_size=13)
with _CreateService(test_pb2, LONG_DELAY) as ( with _CreateService(test_pb2, LONG_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
start_time = time.clock() start_time = time.clock()
response_future = stub.UnaryCall.async(request, LONG_TIMEOUT) response_future = stub.UnaryCall.async(request, LONG_TIMEOUT)
# Check that we didn't block on the asynchronous call. # Check that we didn't block on the asynchronous call.
self.assertGreater(LONG_DELAY, time.clock() - start_time) self.assertGreater(LONG_DELAY, time.clock() - start_time)
response = response_future.result() response = response_future.result()
expected_response = servicer.UnaryCall(request, None) expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
def testUnaryCallAsyncExpired(self): def testUnaryCallAsyncExpired(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
# set the timeout super low... # set the timeout super low...
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
request = test_pb2.SimpleRequest(response_size=13) request = test_pb2.SimpleRequest(response_size=13)
with servicer.pause(): with methods.pause():
response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT) response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT)
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):
response_future.result() response_future.result()
@ -306,8 +306,8 @@ class PythonPluginTest(unittest.TestCase):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = test_pb2.SimpleRequest(response_size=13) request = test_pb2.SimpleRequest(response_size=13)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.pause(): with methods.pause():
response_future = stub.UnaryCall.async(request, 1) response_future = stub.UnaryCall.async(request, 1)
response_future.cancel() response_future.cancel()
self.assertTrue(response_future.cancelled()) self.assertTrue(response_future.cancelled())
@ -316,29 +316,30 @@ class PythonPluginTest(unittest.TestCase):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = test_pb2.SimpleRequest(response_size=13) request = test_pb2.SimpleRequest(response_size=13)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.fail(): with methods.fail():
response_future = stub.UnaryCall.async(request, NORMAL_TIMEOUT) response_future = stub.UnaryCall.async(request, NORMAL_TIMEOUT)
self.assertIsNotNone(response_future.exception()) self.assertIsNotNone(response_future.exception())
def testStreamingOutputCall(self): def testStreamingOutputCall(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = StreamingOutputRequest(test_pb2) request = _streaming_output_request(test_pb2)
with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
responses = stub.StreamingOutputCall(request, NORMAL_TIMEOUT) responses = stub.StreamingOutputCall(request, NORMAL_TIMEOUT)
expected_responses = servicer.StreamingOutputCall(request, None) expected_responses = methods.StreamingOutputCall(
for check in itertools.izip_longest(expected_responses, responses): request, 'not a real RpcContext!')
expected_response, response = check for expected_response, response in itertools.izip_longest(
expected_responses, responses):
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
@unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
'forever and fix.') 'forever and fix.')
def testStreamingOutputCallExpired(self): def testStreamingOutputCallExpired(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = StreamingOutputRequest(test_pb2) request = _streaming_output_request(test_pb2)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.pause(): with methods.pause():
responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT) responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):
list(responses) list(responses)
@ -347,9 +348,9 @@ class PythonPluginTest(unittest.TestCase):
'forever and fix.') 'forever and fix.')
def testStreamingOutputCallCancelled(self): def testStreamingOutputCallCancelled(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = StreamingOutputRequest(test_pb2) request = _streaming_output_request(test_pb2)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
unused_servicer, stub, unused_server): unused_methods, stub, unused_server):
responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT) responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
next(responses) next(responses)
responses.cancel() responses.cancel()
@ -360,10 +361,10 @@ class PythonPluginTest(unittest.TestCase):
'instead of raising the proper error.') 'instead of raising the proper error.')
def testStreamingOutputCallFailed(self): def testStreamingOutputCallFailed(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = StreamingOutputRequest(test_pb2) request = _streaming_output_request(test_pb2)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.fail(): with methods.fail():
responses = stub.StreamingOutputCall(request, 1) responses = stub.StreamingOutputCall(request, 1)
self.assertIsNotNone(responses) self.assertIsNotNone(responses)
with self.assertRaises(exceptions.ServicerError): with self.assertRaises(exceptions.ServicerError):
@ -373,34 +374,34 @@ class PythonPluginTest(unittest.TestCase):
'forever and fix.') 'forever and fix.')
def testStreamingInputCall(self): def testStreamingInputCall(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
response = stub.StreamingInputCall(StreamingInputRequest(test_pb2), response = stub.StreamingInputCall(StreamingInputRequest(test_pb2),
NORMAL_TIMEOUT) NORMAL_TIMEOUT)
expected_response = servicer.StreamingInputCall( expected_response = methods.StreamingInputCall(
StreamingInputRequest(test_pb2), None) _streaming_input_request_iterator(test_pb2), 'not a real RpcContext!')
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
def testStreamingInputCallAsync(self): def testStreamingInputCallAsync(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, LONG_DELAY) as ( with _CreateService(test_pb2, LONG_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
start_time = time.clock() start_time = time.clock()
response_future = stub.StreamingInputCall.async( response_future = stub.StreamingInputCall.async(
StreamingInputRequest(test_pb2), LONG_TIMEOUT) _streaming_input_request_iterator(test_pb2), LONG_TIMEOUT)
self.assertGreater(LONG_DELAY, time.clock() - start_time) self.assertGreater(LONG_DELAY, time.clock() - start_time)
response = response_future.result() response = response_future.result()
expected_response = servicer.StreamingInputCall( expected_response = methods.StreamingInputCall(
StreamingInputRequest(test_pb2), None) _streaming_input_request_iterator(test_pb2), 'not a real RpcContext!')
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
def testStreamingInputCallAsyncExpired(self): def testStreamingInputCallAsyncExpired(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
# set the timeout super low... # set the timeout super low...
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.pause(): with methods.pause():
response_future = stub.StreamingInputCall.async( response_future = stub.StreamingInputCall.async(
StreamingInputRequest(test_pb2), SHORT_TIMEOUT) _streaming_input_request_iterator(test_pb2), SHORT_TIMEOUT)
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):
response_future.result() response_future.result()
self.assertIsInstance( self.assertIsInstance(
@ -409,10 +410,10 @@ class PythonPluginTest(unittest.TestCase):
def testStreamingInputCallAsyncCancelled(self): def testStreamingInputCallAsyncCancelled(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.pause(): with methods.pause():
response_future = stub.StreamingInputCall.async( response_future = stub.StreamingInputCall.async(
StreamingInputRequest(test_pb2), NORMAL_TIMEOUT) _streaming_input_request_iterator(test_pb2), NORMAL_TIMEOUT)
response_future.cancel() response_future.cancel()
self.assertTrue(response_future.cancelled()) self.assertTrue(response_future.cancelled())
with self.assertRaises(future.CancelledError): with self.assertRaises(future.CancelledError):
@ -421,32 +422,32 @@ class PythonPluginTest(unittest.TestCase):
def testStreamingInputCallAsyncFailed(self): def testStreamingInputCallAsyncFailed(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.fail(): with methods.fail():
response_future = stub.StreamingInputCall.async( response_future = stub.StreamingInputCall.async(
StreamingInputRequest(test_pb2), SHORT_TIMEOUT) _streaming_input_request_iterator(test_pb2), SHORT_TIMEOUT)
self.assertIsNotNone(response_future.exception()) self.assertIsNotNone(response_future.exception())
def testFullDuplexCall(self): def testFullDuplexCall(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2), responses = stub.FullDuplexCall(
NORMAL_TIMEOUT) _full_duplex_request_iterator(test_pb2), NORMAL_TIMEOUT)
expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2), expected_responses = methods.FullDuplexCall(
None) _full_duplex_request_iterator(test_pb2), 'not a real RpcContext!')
for check in itertools.izip_longest(expected_responses, responses): for expected_response, response in itertools.izip_longest(
expected_response, response = check expected_responses, responses):
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
@unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs '
'forever and fix.') 'forever and fix.')
def testFullDuplexCallExpired(self): def testFullDuplexCallExpired(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = FullDuplexRequest(test_pb2) request_iterator = _full_duplex_request_iterator(test_pb2)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.pause(): with methods.pause():
responses = stub.FullDuplexCall(request, SHORT_TIMEOUT) responses = stub.FullDuplexCall(request_iterator, SHORT_TIMEOUT)
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):
list(responses) list(responses)
@ -454,9 +455,9 @@ class PythonPluginTest(unittest.TestCase):
'forever and fix.') 'forever and fix.')
def testFullDuplexCallCancelled(self): def testFullDuplexCallCancelled(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
request = FullDuplexRequest(test_pb2) request_iterator = _full_duplex_request_iterator(test_pb2)
responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT) responses = stub.FullDuplexCall(request_iterator, NORMAL_TIMEOUT)
next(responses) next(responses)
responses.cancel() responses.cancel()
with self.assertRaises(future.CancelledError): with self.assertRaises(future.CancelledError):
@ -466,11 +467,11 @@ class PythonPluginTest(unittest.TestCase):
'and fix.') 'and fix.')
def testFullDuplexCallFailed(self): def testFullDuplexCallFailed(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
request = FullDuplexRequest(test_pb2) request_iterator = _full_duplex_request_iterator(test_pb2)
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
with servicer.fail(): with methods.fail():
responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT) responses = stub.FullDuplexCall(request_iterator, NORMAL_TIMEOUT)
self.assertIsNotNone(responses) self.assertIsNotNone(responses)
with self.assertRaises(exceptions.ServicerError): with self.assertRaises(exceptions.ServicerError):
next(responses) next(responses)
@ -480,8 +481,8 @@ class PythonPluginTest(unittest.TestCase):
def testHalfDuplexCall(self): def testHalfDuplexCall(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
servicer, stub, unused_server): methods, stub, unused_server):
def HalfDuplexRequest(): def half_duplex_request_iterator():
request = test_pb2.StreamingOutputCallRequest() request = test_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=1, interval_us=0) request.response_parameters.add(size=1, interval_us=0)
yield request yield request
@ -489,30 +490,33 @@ class PythonPluginTest(unittest.TestCase):
request.response_parameters.add(size=2, interval_us=0) request.response_parameters.add(size=2, interval_us=0)
request.response_parameters.add(size=3, interval_us=0) request.response_parameters.add(size=3, interval_us=0)
yield request yield request
responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT) responses = stub.HalfDuplexCall(
expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest(), None) half_duplex_request_iterator(), NORMAL_TIMEOUT)
expected_responses = methods.HalfDuplexCall(
HalfDuplexRequest(), 'not a real RpcContext!')
for check in itertools.izip_longest(expected_responses, responses): for check in itertools.izip_longest(expected_responses, responses):
expected_response, response = check expected_response, response = check
self.assertEqual(expected_response, response) self.assertEqual(expected_response, response)
def testHalfDuplexCallWedged(self): def testHalfDuplexCallWedged(self):
import test_pb2 # pylint: disable=g-import-not-at-top import test_pb2 # pylint: disable=g-import-not-at-top
wait_flag = [False] wait_cell = [False]
@contextlib.contextmanager @contextlib.contextmanager
def wait(): # pylint: disable=invalid-name def wait(): # pylint: disable=invalid-name
# Where's Python 3's 'nonlocal' statement when you need it? # Where's Python 3's 'nonlocal' statement when you need it?
wait_flag[0] = True wait_cell[0] = True
yield yield
wait_flag[0] = False wait_cell[0] = False
def HalfDuplexRequest(): def half_duplex_request_iterator():
request = test_pb2.StreamingOutputCallRequest() request = test_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=1, interval_us=0) request.response_parameters.add(size=1, interval_us=0)
yield request yield request
while wait_flag[0]: while wait_cell[0]:
time.sleep(0.1) time.sleep(0.1)
with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): with _CreateService(test_pb2, NO_DELAY) as (methods, stub, unused_server):
with wait(): with wait():
responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT) responses = stub.HalfDuplexCall(
half_duplex_request_iterator(), NORMAL_TIMEOUT)
# half-duplex waits for the client to send all info # half-duplex waits for the client to send all info
with self.assertRaises(exceptions.ExpirationError): with self.assertRaises(exceptions.ExpirationError):
next(responses) next(responses)

@ -38,5 +38,5 @@ rm -rf python2.7_virtual_environment
virtualenv -p /usr/bin/python2.7 python2.7_virtual_environment virtualenv -p /usr/bin/python2.7 python2.7_virtual_environment
source python2.7_virtual_environment/bin/activate source python2.7_virtual_environment/bin/activate
pip install -r src/python/requirements.txt pip install -r src/python/requirements.txt
CFLAGS=-I$root/include LDFLAGS=-L$root/libs/$CONFIG pip install src/python/src CFLAGS="-I$root/include -std=c89" LDFLAGS=-L$root/libs/$CONFIG pip install src/python/src
pip install src/python/interop pip install src/python/interop

Loading…
Cancel
Save