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

pull/1649/head
David Garcia Quintas 10 years ago
commit 7947f9caa7
  1. 3
      .travis.yml
  2. 61
      Makefile
  3. 12
      doc/interop-test-descriptions.md
  4. 76
      include/grpc/grpc.h
  5. 13
      src/core/surface/call.h
  6. 16
      src/core/surface/call_log_batch.c
  7. 12
      src/core/surface/server.c
  8. 2
      src/core/surface/server.h
  9. 3
      src/core/transport/chttp2/alpn.c
  10. 10
      src/core/tsi/ssl_transport_security.c
  11. 2
      src/node/package.json
  12. 4
      src/objective-c/ProtoRPC/ProtoRPC.m
  13. 119
      src/objective-c/README.md
  14. 2
      src/objective-c/examples/Sample/Sample/ViewController.m
  15. 2
      src/objective-c/examples/Sample/SampleTests/RemoteTests.m
  16. 2
      src/objective-c/examples/Sample/SampleTests/SampleTests.m
  17. 2
      src/python/src/setup.py
  18. 2
      templates/tools/doxygen/Doxyfile.c++.template
  19. 2
      templates/tools/doxygen/Doxyfile.core.template
  20. 2375
      templates/tools/doxygen/Doxyfile.include
  21. 136
      test/core/bad_client/bad_client.c
  22. 52
      test/core/bad_client/bad_client.h
  23. 79
      test/core/bad_client/gen_build_json.py
  24. 79
      test/core/bad_client/tests/connection_prefix.c
  25. 36
      test/cpp/end2end/server_crash_test.cc
  26. 4
      test/cpp/interop/interop_client.cc
  27. 2
      third_party/protobuf
  28. 1
      tools/buildgen/bunch.py
  29. 15
      tools/buildgen/generate_projects.sh
  30. 2365
      tools/doxygen/Doxyfile.c++
  31. 2365
      tools/doxygen/Doxyfile.core
  32. 41
      tools/doxygen/run_doxygen.sh
  33. 2
      tools/run_tests/run_sanity.sh
  34. 6
      tools/run_tests/run_tests.py
  35. 9
      tools/run_tests/tests.json
  36. 15
      vsprojects/Grpc.mak

@ -20,7 +20,8 @@ env:
- CONFIG=opt TEST=sanity JOBS=1
- CONFIG=gcov TEST=c JOBS=16
- CONFIG=gcov TEST=c++ JOBS=16
- CONFIG=opt TEST="c c++" JOBS=16
- CONFIG=opt TEST=c JOBS=16
- CONFIG=opt TEST=c++ JOBS=16
- CONFIG=opt TEST=node JOBS=16
- CONFIG=opt TEST=ruby JOBS=16
- CONFIG=opt TEST=python JOBS=1

File diff suppressed because one or more lines are too long

@ -558,20 +558,14 @@ pushback (i.e., attempts to send succeed only after appropriate delays).
Propagation of status code and message (yangg)
Cancel after sent headers (ctiller - done)
Cancel after received first message (ctiller - done)
Zero-message streams (ejona)
Multiple thousand simultaneous calls on same Channel (ctiller - done)
Multiple thousand simultaneous calls on same Channel (ctiller)
OAuth2 tokens + Service Credentials from GCE metadata server (GCE->prod only)
(abhishek)
OAuth2 tokens + JWT signing key (GCE->prod only) (abhishek)
Metadata: client headers, server headers + trailers, binary+ascii (chenw)
Metadata: client headers, server headers + trailers, binary+ascii
#### Normal priority:
@ -600,6 +594,8 @@ Multiple thousand simultaneous calls on different Channels (ctiller)
Failed TLS hostname verification (ejona?)
Large amount of headers to cause CONTINUATIONs; 63K of 'X's, all in one header.
#### To priorize:
Start streaming RPC but don't send any requests, server responds

@ -92,12 +92,13 @@ typedef struct {
} value;
} grpc_arg;
/* An array of arguments that can be passed around.
Used to set optional channel-level configuration.
These configuration options are modelled as key-value pairs as defined
by grpc_arg; keys are strings to allow easy backwards-compatible extension
by arbitrary parties.
All evaluation is performed at channel creation time. */
/** An array of arguments that can be passed around.
Used to set optional channel-level configuration.
These configuration options are modelled as key-value pairs as defined
by grpc_arg; keys are strings to allow easy backwards-compatible extension
by arbitrary parties.
All evaluation is performed at channel creation time. */
typedef struct {
size_t num_args;
grpc_arg *args;
@ -192,15 +193,27 @@ typedef struct grpc_metadata {
} internal_data;
} grpc_metadata;
/** The type of completion (for grpc_event) */
typedef enum grpc_completion_type {
GRPC_QUEUE_SHUTDOWN, /* Shutting down */
GRPC_QUEUE_TIMEOUT, /* No event before timeout */
GRPC_OP_COMPLETE /* operation completion */
/** Shutting down */
GRPC_QUEUE_SHUTDOWN,
/** No event before timeout */
GRPC_QUEUE_TIMEOUT,
/** Operation completion */
GRPC_OP_COMPLETE
} grpc_completion_type;
/** The result of an operation.
Returned by a completion queue when the operation started with tag. */
typedef struct grpc_event {
/** The type of the completion. */
grpc_completion_type type;
/** non-zero if the operation was successful, 0 upon failure.
Only GRPC_OP_COMPLETE can succeed or fail. */
int success;
/** The tag passed to grpc_call_start_batch etc to start this operation.
Only GRPC_OP_COMPLETE has a tag. */
void *tag;
} grpc_event;
@ -322,37 +335,42 @@ typedef struct grpc_op {
} data;
} grpc_op;
/* Initialize the grpc library.
It is not safe to call any other grpc functions before calling this.
(To avoid overhead, little checking is done, and some things may work. We
do not warrant that they will continue to do so in future revisions of this
library). */
/** Initialize the grpc library.
It is not safe to call any other grpc functions before calling this.
(To avoid overhead, little checking is done, and some things may work. We
do not warrant that they will continue to do so in future revisions of this
library). */
void grpc_init(void);
/* Shut down the grpc library.
No memory is used by grpc after this call returns, nor are any instructions
executing within the grpc library.
Prior to calling, all application owned grpc objects must have been
destroyed. */
/** Shut down the grpc library.
No memory is used by grpc after this call returns, nor are any instructions
executing within the grpc library.
Prior to calling, all application owned grpc objects must have been
destroyed. */
void grpc_shutdown(void);
/** Create a completion queue */
grpc_completion_queue *grpc_completion_queue_create(void);
/* Blocks until an event is available, the completion queue is being shut down,
or deadline is reached. Returns NULL on timeout, otherwise the event that
occurred.
/** Blocks until an event is available, the completion queue is being shut down,
or deadline is reached.
Returns NULL on timeout, otherwise the event that occurred.
Callers must not call grpc_completion_queue_next and
grpc_completion_queue_pluck simultaneously on the same completion queue. */
Callers must not call grpc_completion_queue_next and
grpc_completion_queue_pluck simultaneously on the same completion queue. */
grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
gpr_timespec deadline);
/* Blocks until an event with tag 'tag' is available, the completion queue is
being shutdown or deadline is reached. Returns NULL on timeout, or a pointer
to the event that occurred.
/** Blocks until an event with tag 'tag' is available, the completion queue is
being shutdown or deadline is reached.
Returns NULL on timeout, or a pointer to the event that occurred.
Callers must not call grpc_completion_queue_next and
grpc_completion_queue_pluck simultaneously on the same completion queue. */
Callers must not call grpc_completion_queue_next and
grpc_completion_queue_pluck simultaneously on the same completion queue. */
grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
gpr_timespec deadline);

@ -122,6 +122,16 @@ void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
grpc_call *call, const grpc_op *ops, size_t nops,
void *tag);
void grpc_server_log_request_call(char *file, int line,
gpr_log_severity severity,
grpc_server *server,
grpc_call **call,
grpc_call_details *details,
grpc_metadata_array *initial_metadata,
grpc_completion_queue *cq_bound_to_call,
grpc_completion_queue *cq_for_notification,
void *tag);
/* Set a context pointer.
No thread safety guarantees are made wrt this value. */
void grpc_call_context_set(grpc_call *call, grpc_context_index elem, void *value,
@ -132,6 +142,9 @@ void *grpc_call_context_get(grpc_call *call, grpc_context_index elem);
#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \
if (grpc_trace_batch) grpc_call_log_batch(sev, call, ops, nops, tag)
#define GRPC_SERVER_LOG_REQUEST_CALL(sev, server, call, details, initial_metadata, cq_bound_to_call, cq_for_notifications, tag) \
if (grpc_trace_batch) grpc_server_log_request_call(sev, server, call, details, initial_metadata, cq_bound_to_call, cq_for_notifications, tag)
gpr_uint8 grpc_call_is_client(grpc_call *call);
#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */

@ -119,3 +119,19 @@ void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
gpr_free(tmp);
}
}
void grpc_server_log_request_call(char *file, int line,
gpr_log_severity severity,
grpc_server *server,
grpc_call **call,
grpc_call_details *details,
grpc_metadata_array *initial_metadata,
grpc_completion_queue *cq_bound_to_call,
grpc_completion_queue *cq_for_notification,
void *tag) {
gpr_log(file, line, severity,
"grpc_server_request_call(server=%p, call=%p, details=%p, "
"initial_metadata=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
"tag=%p)", server, call, details, initial_metadata,
cq_bound_to_call, cq_for_notification, tag);
}

@ -1010,6 +1010,9 @@ grpc_call_error grpc_server_request_call(
grpc_completion_queue *cq_bound_to_call,
grpc_completion_queue *cq_for_notification, void *tag) {
requested_call rc;
GRPC_SERVER_LOG_REQUEST_CALL(GPR_INFO, server, call, details,
initial_metadata, cq_bound_to_call,
cq_for_notification, tag);
grpc_cq_begin_op(cq_for_notification, NULL);
rc.type = BATCH_CALL;
rc.tag = tag;
@ -1128,3 +1131,12 @@ static void publish_registered_or_batch(grpc_call *call, int success,
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
return server->channel_args;
}
int grpc_server_has_open_connections(grpc_server *server) {
int r;
gpr_mu_lock(&server->mu);
r = server->root_channel_data.next != &server->root_channel_data;
gpr_mu_unlock(&server->mu);
return r;
}

@ -62,4 +62,6 @@ grpc_transport_setup_result grpc_server_setup_transport(
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
int grpc_server_has_open_connections(grpc_server *server);
#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */

@ -36,7 +36,8 @@
#include <grpc/support/useful.h>
/* in order of preference */
static const char *const supported_versions[] = {"h2-16", "h2-15", "h2-14"};
static const char *const supported_versions[] = {"h2", "h2-17", "h2-16",
"h2-15", "h2-14"};
int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size) {
size_t i;

@ -639,7 +639,7 @@ static tsi_result ssl_protector_protect(tsi_frame_protector* self,
tsi_result result = TSI_OK;
/* First see if we have some pending data in the SSL BIO. */
size_t pending_in_ssl = BIO_ctrl_pending(impl->from_ssl);
size_t pending_in_ssl = BIO_pending(impl->from_ssl);
if (pending_in_ssl > 0) {
*unprotected_bytes_size = 0;
read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
@ -694,7 +694,7 @@ static tsi_result ssl_protector_protect_flush(
impl->buffer_offset = 0;
}
*still_pending_size = BIO_ctrl_pending(impl->from_ssl);
*still_pending_size = BIO_pending(impl->from_ssl);
if (*still_pending_size == 0) return TSI_OK;
read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
@ -704,7 +704,7 @@ static tsi_result ssl_protector_protect_flush(
return TSI_INTERNAL_ERROR;
}
*protected_output_frames_size = read_from_ssl;
*still_pending_size = BIO_ctrl_pending(impl->from_ssl);
*still_pending_size = BIO_pending(impl->from_ssl);
return TSI_OK;
}
@ -782,7 +782,7 @@ static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
}
}
*bytes_size = (size_t)bytes_read_from_ssl;
return BIO_ctrl_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
}
static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) {
@ -818,7 +818,7 @@ static tsi_result ssl_handshaker_process_bytes_from_peer(
ssl_result = SSL_get_error(impl->ssl, ssl_result);
switch (ssl_result) {
case SSL_ERROR_WANT_READ:
if (BIO_ctrl_pending(impl->from_ssl) == 0) {
if (BIO_pending(impl->from_ssl) == 0) {
/* We need more data. */
return TSI_INCOMPLETE_DATA;
} else {

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

@ -59,7 +59,7 @@
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable {
// Because we can't tell the type system to constrain the class, we need to check at runtime:
if (![responseClass respondsToSelector:@selector(parseFromData:)]) {
if (![responseClass respondsToSelector:@selector(parseFromData:error:)]) {
[NSException raise:NSInvalidArgumentException
format:@"A protobuf class to parse the responses must be provided."];
}
@ -71,7 +71,7 @@
if ((self = [super initWithHost:host method:method requestsWriter:bytesWriter])) {
// A writeable that parses the proto messages received.
_responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
[responsesWriteable writeValue:[responseClass parseFromData:value]];
[responsesWriteable writeValue:[responseClass parseFromData:value error:NULL]];
} completionHandler:^(NSError *errorOrNil) {
[responsesWriteable writesFinishedWithError:errorOrNil];
}];

@ -1,43 +1,119 @@
# gRPC for Objective-C
## How to generate a client library from a Protocol Buffers definition
- [Install protoc with the gRPC plugin](#install)
- [Use protoc to generate a gRPC library](#protoc)
- [Integrate the generated gRPC library in your project](#cocoapods)
- [Use the generated library in your code](#use)
- [Alternative methods](#alternatives)
- [Install protoc and the gRPC plugin without using Homebrew](#nohomebrew)
- [Integrate the generated gRPC library without using Cocoapods](#nococoapods)
First install v3 of the Protocol Buffers compiler (_protoc_), by cloning [its Git repository](https://github.com/google/protobuf) and following these [installation instructions](https://github.com/google/protobuf#c-installation---unix) (the ones titled C++; don't miss the note for Mac users).
<a name="install"></a>
## Install protoc with the gRPC plugin
Then clone this repository and execute the following commands from the root directory where it was cloned.
On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][].
Compile the gRPC plugins for _protoc_:
Run the following command to install the Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin:
```sh
make plugins
$ curl -fsSL https://goo.gl/getgrpc | bash -
```
This will download and run the [gRPC install script][]. After the command completes, you're ready to proceed.
<a name="protoc"></a>
## Use protoc to generate a gRPC library
Run _protoc_ with the following flags to generate the client library for your `.proto` files:
Create a symbolic link to the compiled plugin binary somewhere in your `$PATH`:
```sh
ln -s `pwd`/bins/opt/grpc_objective_c_plugin /usr/local/bin/protoc-gen-objcgrpc
protoc --objc_out=. --objcgrpc_out=. *.proto
```
(Notice that the name of the created link must begin with "protoc-gen-" for _protoc_ to recognize it as a plugin).
If you don't want to create the symbolic link, you can alternatively copy the binary (with the appropriate name). Or you might prefer instead to specify the plugin's path as a flag when invoking _protoc_, in which case no system modification nor renaming is necessary.
This will generate a pair of `.pbobjc.h`/`.pbobjc.m` files for each `.proto` file, with the messages and enums defined in them. And a pair of `.pbrpc.h`/`.pbrpc.m` files for each `.proto` file with services defined. The latter contains the code to make remote calls to the specified API.
Finally, run _protoc_ with the following flags to generate the client library for your `.proto` files:
<a name="cocoapods"></a>
## Integrate the generated gRPC library in your project
Install [Cocoapods](https://cocoapods.org/#install).
You need to create a Podspec file for the generated library. You may simply copy the following example to the directory where the source files were generated, updating the name and other metadata of the Podspec as necessary:
```ruby
Pod::Spec.new do |s|
s.name = '<Podspec file name>'
s.version = '...'
s.summary = 'Client library to make RPCs to <my proto API>'
s.homepage = '...'
s.license = '...'
s.authors = { '<my name>' => '<my email>' }
s.ios.deployment_target = '6.0'
s.osx.deployment_target = '10.8'
s.subspec 'Messages' do |ms|
ms.source_files = '*.pbobjc.{h,m}'
ms.requires_arc = false
ms.dependency 'Protobuf', '~> 3.0'
end
s.subspec 'Services' do |ss|
ss.source_files = '*.pbrpc.{h,m}'
ss.requires_arc = true
ss.dependency 'gRPC', '~> 0.0'
ss.dependency '<Podspec file name>/Messages'
end
end
```
The file should be named `<Podspec file name>.podspec`. You can refer to this [example Podspec][]. Once your library has a Podspec, Cocoapods can install it into any XCode project. For that, go into your project's directory and create a Podfile by running:
```sh
protoc --objc_out=. --objcgrpc_out=. *.proto
pod init
```
This will generate a pair of `.pbobjc.h`/`.pbobjc.m` files for each `.proto` file, with the messages and enums defined in them. And a pair of `.pbrpc.h`/`.pbrpc.m` files for each `.proto` file with services defined. The latter contains the code to make remote calls to the specified API.
Next add a line to your Podfile to refer to your library's Podspec. Use `:path` as described [here](https://guides.cocoapods.org/using/the-podfile.html#using-the-files-from-a-folder-local-to-the-machine):
```ruby
pod '<Podspec file name>', :path => 'path/to/the/directory/of/your/podspec'
```
You can look at this [example Podfile][].
Finally, in your project's directory, run:
## How to integrate a generated gRPC library in your project
```sh
pod install
```
<a name="use"></a>
## Use the generated library in your code
Please check this [sample app][] for examples of how to use a generated gRPC library.
<a name="alternatives"></a>
## Alternative methods
### If you use Cocoapods
<a name="nohomebrew"></a>
### Install protoc and the gRPC plugin without using Homebrew
This is the recommended approach.
First install v3 of the Protocol Buffers compiler (_protoc_), by cloning [its Git repository](https://github.com/google/protobuf) and following these [installation instructions](https://github.com/google/protobuf#c-installation---unix) (the ones titled C++; don't miss the note for Mac users).
Then clone this repository and execute the following commands from the root directory where it was cloned.
Compile the gRPC plugins for _protoc_:
```sh
make plugins
```
You need to create a Podspec file for the generated library. This is simply a matter of copying an example like [this one](https://github.com/grpc/grpc/blob/master/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec) to the directory where the source files were generated. Update the name and other metadata of the Podspec as suitable.
Create a symbolic link to the compiled plugin binary somewhere in your `$PATH`:
```sh
ln -s `pwd`/bins/opt/grpc_objective_c_plugin /usr/local/bin/protoc-gen-objcgrpc
```
(Notice that the name of the created link must begin with "protoc-gen-" for _protoc_ to recognize it as a plugin).
Once your library has a Podspec, refer to it from your Podfile using `:path` as described [here](https://guides.cocoapods.org/using/the-podfile.html#using-the-files-from-a-folder-local-to-the-machine).
If you don't want to create the symbolic link, you can alternatively copy the binary (with the appropriate name). Or you might prefer instead to specify the plugin's path as a flag when invoking _protoc_, in which case no system modification nor renaming is necessary.
### If you don't use Cocoapods
<a name="nococoapods"></a>
### Integrate the generated gRPC library without using Cocoapods
You need to compile the generated `.pbpbjc.*` files (the enums and messages) without ARC support, and the generated `.pbrpc.*` files (the services) with ARC support. The generated code depends on v0.3+ of the Objective-C gRPC runtime library and v3.0+ of the Objective-C Protobuf runtime library.
@ -45,3 +121,10 @@ These libraries need to be integrated into your project as described in their re
* [Podspec](https://github.com/grpc/grpc/blob/master/gRPC.podspec) for the Objective-C gRPC runtime library. This can be tedious to configure manually.
* [Podspec](https://github.com/jcanizales/protobuf/blob/add-podspec/Protobuf.podspec) for the Objective-C Protobuf runtime library.
[homebrew]:http://brew.sh
[linuxbrew]:https://github.com/Homebrew/linuxbrew
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[example Podspec]:https://github.com/grpc/grpc/blob/master/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec
[example Podfile]:https://github.com/grpc/grpc/blob/master/src/objective-c/examples/Sample/Podfile
[sample app]: https://github.com/grpc/grpc/tree/master/src/objective-c/examples/Sample

@ -80,7 +80,7 @@
requestsWriter:requestsWriter];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value];
RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
NSLog(@"Received response:\n%@", response);
} completionHandler:^(NSError *errorOrNil) {
if (errorOrNil) {

@ -125,7 +125,7 @@
XCTAssertNotNil(value, @"nil value received as response.");
[response fulfill];
XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value];
RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
// We expect empty strings, not nil:
XCTAssertNotNil(response.username, @"Response's username is nil.");
XCTAssertNotNil(response.oauthScope, @"Response's OAuth scope is nil.");

@ -123,7 +123,7 @@
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
RGDFeature *feature = [RGDFeature parseFromData:value];
RGDFeature *feature = [RGDFeature parseFromData:value error:NULL];
XCTAssertEqualObjects(point, feature.location);
XCTAssertNotNil(feature.name, @"Response's name is nil.");
[response fulfill];

@ -86,7 +86,7 @@ _PACKAGE_DIRECTORIES = {
setuptools.setup(
name='grpcio',
version='0.5.0a2',
version='0.9.0a0',
ext_modules=[_EXTENSION_MODULE],
packages=list(_PACKAGES),
package_dir=_PACKAGE_DIRECTORIES,

@ -0,0 +1,2 @@
<%namespace file="Doxyfile.include" import="gen_doxyfile"/>\
${gen_doxyfile(['grpc++'], 'C++', libs)}

@ -0,0 +1,2 @@
<%namespace file="Doxyfile.include" import="gen_doxyfile"/>\
${gen_doxyfile(['grpc', 'gpr'], 'Core', libs)}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,136 @@
/*
*
* 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.
*
*/
#include "test/core/bad_client/bad_client.h"
#include "src/core/channel/channel_stack.h"
#include "src/core/channel/http_server_filter.h"
#include "src/core/iomgr/endpoint_pair.h"
#include "src/core/surface/completion_queue.h"
#include "src/core/surface/server.h"
#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
typedef struct {
grpc_server *server;
grpc_completion_queue *cq;
grpc_bad_client_server_side_validator validator;
gpr_event done_thd;
gpr_event done_write;
} thd_args;
static void thd_func(void *arg) {
thd_args *a = arg;
a->validator(a->server, a->cq);
gpr_event_set(&a->done_thd, (void *)1);
}
static void done_write(void *arg, grpc_endpoint_cb_status status) {
thd_args *a = arg;
gpr_event_set(&a->done_write, (void *)1);
}
static grpc_transport_setup_result server_setup_transport(
void *ts, grpc_transport *transport, grpc_mdctx *mdctx) {
thd_args *a = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
return grpc_server_setup_transport(a->server, transport, extra_filters,
GPR_ARRAY_SIZE(extra_filters), mdctx);
}
void grpc_run_bad_client_test(const char *name, const char *client_payload,
size_t client_payload_length,
grpc_bad_client_server_side_validator validator) {
grpc_endpoint_pair sfd;
thd_args a;
gpr_thd_id id;
gpr_slice slice =
gpr_slice_from_copied_buffer(client_payload, client_payload_length);
/* Add a debug log */
gpr_log(GPR_INFO, "TEST: %s", name);
/* Init grpc */
grpc_init();
/* Create endpoints */
sfd = grpc_iomgr_create_endpoint_pair(65536);
/* Create server, completion events */
a.server = grpc_server_create_from_filters(NULL, 0, NULL);
a.cq = grpc_completion_queue_create();
gpr_event_init(&a.done_thd);
gpr_event_init(&a.done_write);
a.validator = validator;
grpc_server_register_completion_queue(a.server, a.cq);
grpc_server_start(a.server);
grpc_create_chttp2_transport(server_setup_transport, &a, NULL, sfd.server,
NULL, 0, grpc_mdctx_create(), 0);
/* Bind everything into the same pollset */
grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq));
grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq));
/* Check a ground truth */
GPR_ASSERT(grpc_server_has_open_connections(a.server));
/* Start validator */
gpr_thd_new(&id, thd_func, &a, NULL);
/* Write data */
switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) {
case GRPC_ENDPOINT_WRITE_DONE:
done_write(&a, 1);
break;
case GRPC_ENDPOINT_WRITE_PENDING:
break;
case GRPC_ENDPOINT_WRITE_ERROR:
done_write(&a, 0);
break;
}
/* Await completion */
GPR_ASSERT(
gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
/* Shutdown */
grpc_endpoint_destroy(sfd.client);
grpc_server_destroy(a.server);
grpc_completion_queue_destroy(a.cq);
grpc_shutdown();
}

@ -0,0 +1,52 @@
/*
*
* 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.
*
*/
#ifndef GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H
#define GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H
#include <grpc/grpc.h>
#include "test/core/util/test_config.h"
typedef void (*grpc_bad_client_server_side_validator)(
grpc_server *server, grpc_completion_queue *cq);
/* Test runner.
Create a server, and send client_payload to it as bytes from a client.
Execute validator in a separate thread to assert that the bytes are
handled as expected. */
void grpc_run_bad_client_test(const char *name, const char *client_payload,
size_t client_payload_length,
grpc_bad_client_server_side_validator validator);
#endif /* GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H */

@ -0,0 +1,79 @@
#!/usr/bin/env python
# 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.
"""Generates the appropriate build.json data for all the end2end tests."""
import simplejson
import collections
TestOptions = collections.namedtuple('TestOptions', 'flaky')
default_test_options = TestOptions(False)
# maps test names to options
BAD_CLIENT_TESTS = {
'connection_prefix': default_test_options,
}
def main():
json = {
'#': 'generated with test/bad_client/gen_build_json.py',
'libs': [
{
'name': 'bad_client_test',
'build': 'private',
'language': 'c',
'src': [
'test/core/bad_client/bad_client.c'
]
}],
'targets': [
{
'name': '%s_bad_client_test' % t,
'build': 'test',
'language': 'c',
'secure': 'no',
'src': ['test/core/bad_client/tests/%s.c' % t],
'flaky': 'invoke_large_request' in t,
'deps': [
'bad_client_test',
'grpc_test_util_unsecure',
'grpc_unsecure',
'gpr_test_util',
'gpr'
]
}
for t in sorted(BAD_CLIENT_TESTS.keys())]}
print simplejson.dumps(json, sort_keys=True, indent=2 * ' ')
if __name__ == '__main__':
main()

@ -0,0 +1,79 @@
/*
*
* 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.
*
*/
#include "test/core/bad_client/bad_client.h"
#include "src/core/surface/server.h"
static void verifier(grpc_server *server, grpc_completion_queue *cq) {
while (grpc_server_has_open_connections(server)) {
GPR_ASSERT(grpc_completion_queue_next(
cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20)).type ==
GRPC_QUEUE_TIMEOUT);
}
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_run_bad_client_test("conpfx_1", "X", 1, verifier);
grpc_run_bad_client_test("conpfx_2", "PX", 2, verifier);
grpc_run_bad_client_test("conpfx_3", "PRX", 3, verifier);
grpc_run_bad_client_test("conpfx_4", "PRIX", 4, verifier);
grpc_run_bad_client_test("conpfx_5", "PRI X", 5, verifier);
grpc_run_bad_client_test("conpfx_6", "PRI *X", 6, verifier);
grpc_run_bad_client_test("conpfx_7", "PRI * X", 7, verifier);
grpc_run_bad_client_test("conpfx_8", "PRI * HX", 8, verifier);
grpc_run_bad_client_test("conpfx_9", "PRI * HTX", 9, verifier);
grpc_run_bad_client_test("conpfx_10", "PRI * HTTX", 10, verifier);
grpc_run_bad_client_test("conpfx_11", "PRI * HTTPX", 11, verifier);
grpc_run_bad_client_test("conpfx_12", "PRI * HTTP/X", 12, verifier);
grpc_run_bad_client_test("conpfx_13", "PRI * HTTP/2X", 13, verifier);
grpc_run_bad_client_test("conpfx_14", "PRI * HTTP/2.X", 14, verifier);
grpc_run_bad_client_test("conpfx_15", "PRI * HTTP/2.0X", 15, verifier);
grpc_run_bad_client_test("conpfx_16", "PRI * HTTP/2.0\rX", 16, verifier);
grpc_run_bad_client_test("conpfx_17", "PRI * HTTP/2.0\r\nX", 17, verifier);
grpc_run_bad_client_test("conpfx_18", "PRI * HTTP/2.0\r\n\rX", 18, verifier);
grpc_run_bad_client_test("conpfx_19", "PRI * HTTP/2.0\r\n\r\nX", 19,
verifier);
grpc_run_bad_client_test("conpfx_20", "PRI * HTTP/2.0\r\n\r\nSX", 20,
verifier);
grpc_run_bad_client_test("conpfx_21", "PRI * HTTP/2.0\r\n\r\nSMX", 21,
verifier);
grpc_run_bad_client_test("conpfx_22", "PRI * HTTP/2.0\r\n\r\nSM\rX", 22,
verifier);
grpc_run_bad_client_test("conpfx_23", "PRI * HTTP/2.0\r\n\r\nSM\r\nX", 23,
verifier);
grpc_run_bad_client_test("conpfx_24", "PRI * HTTP/2.0\r\n\r\nSM\r\n\rX", 24,
verifier);
return 0;
}

@ -69,10 +69,15 @@ namespace testing {
namespace {
class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Service {
class ServiceImpl GRPC_FINAL
: public ::grpc::cpp::test::util::TestService::Service {
public:
ServiceImpl() : bidi_stream_count_(0), response_stream_count_(0) {}
Status BidiStream(ServerContext* context,
ServerReaderWriter<EchoResponse, EchoRequest>* stream)
GRPC_OVERRIDE {
bidi_stream_count_++;
EchoRequest request;
EchoResponse response;
while (stream->Read(&request)) {
@ -87,6 +92,7 @@ class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Serv
Status ResponseStream(ServerContext* context, const EchoRequest* request,
ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
EchoResponse response;
response_stream_count_++;
for (int i = 0;; i++) {
std::ostringstream msg;
msg << "Hello " << i;
@ -96,23 +102,27 @@ class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Serv
}
return Status::OK;
}
int bidi_stream_count() { return bidi_stream_count_; }
int response_stream_count() { return response_stream_count_; }
private:
int bidi_stream_count_;
int response_stream_count_;
};
class CrashTest : public ::testing::Test {
protected:
CrashTest() {}
std::unique_ptr<Server>
CreateServerAndClient(const std::string& mode) {
std::unique_ptr<Server> CreateServerAndClient(const std::string& mode) {
auto port = grpc_pick_unused_port_or_die();
std::ostringstream addr_stream;
addr_stream << "localhost:" << port;
auto addr = addr_stream.str();
client_.reset(new SubProcess({
g_root + "/server_crash_test_client",
"--address=" + addr,
"--mode=" + mode
}));
client_.reset(new SubProcess({g_root + "/server_crash_test_client",
"--address=" + addr, "--mode=" + mode}));
GPR_ASSERT(client_);
ServerBuilder builder;
@ -121,9 +131,11 @@ class CrashTest : public ::testing::Test {
return builder.BuildAndStart();
}
void KillClient() {
client_.reset();
}
void KillClient() { client_.reset(); }
bool HadOneBidiStream() { return service_.bidi_stream_count() == 1; }
bool HadOneResponseStream() { return service_.response_stream_count() == 1; }
private:
std::unique_ptr<SubProcess> client_;
@ -136,6 +148,7 @@ TEST_F(CrashTest, ResponseStream) {
gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
KillClient();
server->Shutdown();
GPR_ASSERT(HadOneResponseStream());
}
TEST_F(CrashTest, BidiStream) {
@ -144,6 +157,7 @@ TEST_F(CrashTest, BidiStream) {
gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
KillClient();
server->Shutdown();
GPR_ASSERT(HadOneBidiStream());
}
} // namespace

@ -57,8 +57,8 @@ const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
const int kNumResponseMessages = 2000;
const int kResponseMessageSize = 1030;
const int kReceiveDelayMilliSeconds = 20;
const int kLargeRequestSize = 314159;
const int kLargeResponseSize = 271812;
const int kLargeRequestSize = 271828;
const int kLargeResponseSize = 314159;
} // namespace
InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel)

@ -1 +1 @@
Subproject commit a8b38c598d7f65b281a72809b28117afdb760931
Subproject commit 8908cf16fe81f42c766fdf067b1da4554f54ed87

@ -57,6 +57,7 @@ def merge_json(dst, add):
if isinstance(dst, dict) and isinstance(add, dict):
for k, v in add.items():
if k in dst:
if k == '#': continue
merge_json(dst[k], v)
else:
dst[k] = v

@ -38,14 +38,19 @@ fi
cd `dirname $0`/../..
mako_renderer=tools/buildgen/mako_renderer.py
gen_build_json=test/core/end2end/gen_build_json.py
gen_build_json_dirs="test/core/end2end test/core/bad_client"
if [ "x$TEST" != "x" ] ; then
tools/buildgen/build-cleaner.py build.json
fi
end2end_test_build=`mktemp /tmp/genXXXXXX`
$gen_build_json > $end2end_test_build
gen_build_files=""
for gen_build_json in $gen_build_json_dirs
do
output_file=`mktemp /tmp/genXXXXXX`
$gen_build_json/gen_build_json.py > $output_file
gen_build_files="$gen_build_files $output_file"
done
global_plugins=`find ./tools/buildgen/plugins -name '*.py' |
sort | grep -v __init__ | awk ' { printf "-p %s ", $0 } '`
@ -60,7 +65,7 @@ for dir in . ; do
out=${dir}/${file#$dir/templates/} # strip templates dir prefix
out=${out%.*} # strip template extension
echo "generating file: $out"
json_files="build.json $end2end_test_build"
json_files="build.json $gen_build_files"
data=`for i in $json_files ; do echo $i ; done | awk ' { printf "-d %s ", $0 } '`
if [ "x$TEST" = "xtrue" ] ; then
actual_out=$out
@ -75,4 +80,4 @@ for dir in . ; do
done
done
rm $end2end_test_build
rm $gen_build_files

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,41 @@
#!/bin/sh
# 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.
set -ex
# change to grpc repo root
cd $(dirname $0)/../..
for i in core c++
do
mkdir -p doc/ref/$i
doxygen tools/doxygen/Doxyfile.$i
done

@ -45,6 +45,6 @@ git submodule > $submodules
diff -u $submodules - << EOF
05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
3df69d3aefde7671053d4e3c242b228e5d79c83f third_party/openssl (OpenSSL_1_0_2a)
a8b38c598d7f65b281a72809b28117afdb760931 third_party/protobuf (v3.0.0-alpha-1-978-ga8b38c5)
8908cf16fe81f42c766fdf067b1da4554f54ed87 third_party/protobuf (v3.0.0-alpha-1-1044-g8908cf1)
50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
EOF

@ -57,7 +57,6 @@ class SimpleConfig(object):
if environ is None:
environ = {}
self.build_config = config
self.maxjobs = 2 * multiprocessing.cpu_count()
self.allow_hashing = (config != 'gcov')
self.environ = environ
self.environ['CONFIG'] = config
@ -93,7 +92,6 @@ class ValgrindConfig(object):
self.build_config = config
self.tool = tool
self.args = args
self.maxjobs = 2 * multiprocessing.cpu_count()
self.allow_hashing = False
def job_spec(self, cmdline, hash_targets):
@ -333,7 +331,7 @@ argp.add_argument('-c', '--config',
default=_DEFAULT)
argp.add_argument('-n', '--runs_per_test', default=1, type=int)
argp.add_argument('-r', '--regex', default='.*', type=str)
argp.add_argument('-j', '--jobs', default=1000, type=int)
argp.add_argument('-j', '--jobs', default=2 * multiprocessing.cpu_count(), type=int)
argp.add_argument('-s', '--slowdown', default=1.0, type=float)
argp.add_argument('-f', '--forever',
default=False,
@ -455,7 +453,7 @@ def _build_and_run(check_cancelled, newline_on_success, travis, cache):
itertools.repeat(one_run, runs_per_test))
if not jobset.run(all_runs, check_cancelled,
newline_on_success=newline_on_success, travis=travis,
maxjobs=min(args.jobs, min(c.maxjobs for c in run_configs)),
maxjobs=args.jobs,
cache=cache):
return 2
finally:

@ -4039,6 +4039,15 @@
"windows",
"posix"
]
},
{
"flaky": false,
"language": "c",
"name": "connection_prefix_bad_client_test",
"platforms": [
"windows",
"posix"
]
}
]

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save