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

pull/1649/head
David Garcia Quintas 10 years ago
commit f526bd487a
  1. 3
      include/grpc++/config.h
  2. 7
      src/core/iomgr/pollset_posix.c
  3. 1
      src/core/surface/call.c
  4. 4
      src/core/surface/completion_queue.c
  5. 1
      src/csharp/Grpc.Auth/Grpc.Auth.csproj
  6. 3
      src/csharp/Grpc.Auth/Grpc.Auth.nuspec
  7. 17
      src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
  8. 17
      src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
  9. 17
      src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
  10. 6
      src/csharp/Grpc.Core/Calls.cs
  11. 1
      src/csharp/Grpc.Core/Grpc.Core.csproj
  12. 5
      src/csharp/Grpc.Core/Grpc.Core.nuspec
  13. 1
      src/csharp/Grpc.Core/IAsyncStreamReader.cs
  14. 2
      src/csharp/Grpc.Core/IAsyncStreamWriter.cs
  15. 2
      src/csharp/Grpc.Core/IClientStreamWriter.cs
  16. 2
      src/csharp/Grpc.Core/IServerStreamWriter.cs
  17. 4
      src/csharp/Grpc.Core/Internal/ClientRequestStream.cs
  18. 14
      src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
  19. 4
      src/csharp/Grpc.Core/Internal/ServerResponseStream.cs
  20. 6
      src/csharp/Grpc.Core/Utils/AsyncStreamExtensions.cs
  21. 51
      src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
  22. 40
      src/csharp/Grpc.Examples/MathExamples.cs
  23. 4
      src/csharp/Grpc.Examples/MathServiceImpl.cs
  24. 163
      src/csharp/Grpc.IntegrationTesting/InteropClient.cs
  25. 4
      src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
  26. 4
      src/csharp/build_packages.bat
  27. 16
      src/node/bin/README.md
  28. 2
      src/node/bin/service_packager
  29. 142
      src/node/cli/service_packager.js
  30. 36
      src/node/cli/service_packager/index.js
  31. 17
      src/node/cli/service_packager/package.json.template
  32. 3
      src/node/package.json
  33. 2
      src/objective-c/examples/Sample/Podfile
  34. 29
      templates/vsprojects/generate_debug_projects.sh
  35. 4
      test/cpp/qps/async_streaming_ping_pong_test.cc
  36. 4
      test/cpp/qps/async_unary_ping_pong_test.cc
  37. 30
      test/cpp/qps/driver.cc
  38. 15
      test/cpp/qps/driver.h
  39. 29
      test/cpp/qps/qps-sweep.sh
  40. 8
      test/cpp/qps/qps_driver.cc
  41. 4
      test/cpp/qps/qps_test.cc
  42. 2
      test/cpp/qps/qpstest.proto
  43. 28
      test/cpp/qps/single_run_localhost.sh
  44. 4
      test/cpp/qps/sync_streaming_ping_pong_test.cc
  45. 4
      test/cpp/qps/sync_unary_ping_pong_test.cc
  46. 28
      tools/distrib/python/submit.py
  47. 28
      tools/dockerfile/grpc_cxx/build.sh
  48. 28
      tools/dockerfile/grpc_java/build.sh
  49. 28
      tools/dockerfile/grpc_node/build.sh
  50. 28
      tools/dockerfile/grpc_ruby/build.sh
  51. 28
      tools/gce_setup/private_build_and_test.sh
  52. 28
      tools/run_tests/prepare_travis.sh
  53. 31
      tools/run_tests/run_tests.py
  54. 4
      vsprojects/nuget_package/grpc.native.csharp_ext.nuspec

@ -112,6 +112,9 @@ public:
template <class T> operator std::unique_ptr<T>() const {
return std::unique_ptr<T>(static_cast<T *>(0));
}
template <class T> operator std::shared_ptr<T>() const {
return std::shared_ptr<T>(static_cast<T *>(0));
}
operator bool() const {return false;}
private:
void operator&() const = delete;

@ -258,7 +258,6 @@ static void unary_poll_do_promote(void *args, int success) {
grpc_pollset *pollset = up_args->pollset;
grpc_fd *fd = up_args->fd;
int do_shutdown_cb = 0;
gpr_free(up_args);
/*
* This is quite tricky. There are a number of cases to keep in mind here:
@ -273,8 +272,12 @@ static void unary_poll_do_promote(void *args, int success) {
/* First we need to ensure that nobody is polling concurrently */
while (pollset->counter != 0) {
grpc_pollset_kick(pollset);
gpr_cv_wait(&pollset->cv, &pollset->mu, gpr_inf_future);
grpc_iomgr_add_callback(unary_poll_do_promote, up_args);
gpr_mu_unlock(&pollset->mu);
return;
}
gpr_free(up_args);
/* At this point the pollset may no longer be a unary poller. In that case
* we should just call the right add function and be done. */
/* TODO(klempner): If we're not careful this could cause infinite recursion.

@ -597,6 +597,7 @@ static void call_on_done_send(void *pc, int success) {
finish_ioreq_op(call, GRPC_IOREQ_SEND_STATUS, success);
finish_ioreq_op(call, GRPC_IOREQ_SEND_CLOSE, 1);
}
call->send_ops.nops = 0;
call->last_send_contains = 0;
call->sending = 0;
unlock(call);

@ -275,14 +275,14 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
memset(&ret, 0, sizeof(ret));
ret.type = GRPC_QUEUE_TIMEOUT;
GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ev->base);
GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
return ret;
}
}
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
ret = ev->base;
gpr_free(ev);
GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ev->base);
GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
return ret;
}

@ -10,6 +10,7 @@
<RootNamespace>Grpc.Auth</RootNamespace>
<AssemblyName>Grpc.Auth</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<DocumentationFile>bin\$(Configuration)\Grpc.Auth.Xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

@ -22,5 +22,8 @@
</metadata>
<files>
<file src="bin/Release/Grpc.Auth.dll" target="lib/net45" />
<file src="bin/Release/Grpc.Auth.pdb" target="lib/net45" />
<file src="bin/Release/Grpc.Auth.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
</files>
</package>

@ -40,15 +40,17 @@ namespace Grpc.Core
/// <summary>
/// Return type for client streaming calls.
/// </summary>
public sealed class AsyncClientStreamingCall<TRequest, TResponse>
public sealed class AsyncClientStreamingCall<TRequest, TResponse> : IDisposable
{
readonly IClientStreamWriter<TRequest> requestStream;
readonly Task<TResponse> result;
readonly Action disposeAction;
public AsyncClientStreamingCall(IClientStreamWriter<TRequest> requestStream, Task<TResponse> result)
public AsyncClientStreamingCall(IClientStreamWriter<TRequest> requestStream, Task<TResponse> result, Action disposeAction)
{
this.requestStream = requestStream;
this.result = result;
this.disposeAction = disposeAction;
}
/// <summary>
@ -81,5 +83,16 @@ namespace Grpc.Core
{
return result.GetAwaiter();
}
/// <summary>
/// Provides means to provide after the call.
/// If the call has already finished normally (request stream has been completed and call result has been received), doesn't do anything.
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
/// As a result, all resources being used by the call should be released eventually.
/// </summary>
public void Dispose()
{
disposeAction.Invoke();
}
}
}

@ -40,15 +40,17 @@ namespace Grpc.Core
/// <summary>
/// Return type for bidirectional streaming calls.
/// </summary>
public sealed class AsyncDuplexStreamingCall<TRequest, TResponse>
public sealed class AsyncDuplexStreamingCall<TRequest, TResponse> : IDisposable
{
readonly IClientStreamWriter<TRequest> requestStream;
readonly IAsyncStreamReader<TResponse> responseStream;
readonly Action disposeAction;
public AsyncDuplexStreamingCall(IClientStreamWriter<TRequest> requestStream, IAsyncStreamReader<TResponse> responseStream)
public AsyncDuplexStreamingCall(IClientStreamWriter<TRequest> requestStream, IAsyncStreamReader<TResponse> responseStream, Action disposeAction)
{
this.requestStream = requestStream;
this.responseStream = responseStream;
this.disposeAction = disposeAction;
}
/// <summary>
@ -72,5 +74,16 @@ namespace Grpc.Core
return requestStream;
}
}
/// <summary>
/// Provides means to cleanup after the call.
/// If the call has already finished normally (request stream has been completed and response stream has been fully read), doesn't do anything.
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
/// As a result, all resources being used by the call should be released eventually.
/// </summary>
public void Dispose()
{
disposeAction.Invoke();
}
}
}

@ -40,13 +40,15 @@ namespace Grpc.Core
/// <summary>
/// Return type for server streaming calls.
/// </summary>
public sealed class AsyncServerStreamingCall<TResponse>
public sealed class AsyncServerStreamingCall<TResponse> : IDisposable
{
readonly IAsyncStreamReader<TResponse> responseStream;
readonly Action disposeAction;
public AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream)
public AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, Action disposeAction)
{
this.responseStream = responseStream;
this.disposeAction = disposeAction;
}
/// <summary>
@ -59,5 +61,16 @@ namespace Grpc.Core
return responseStream;
}
}
/// <summary>
/// Provides means to cleanup after the call.
/// If the call has already finished normally (response stream has been fully read), doesn't do anything.
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
/// As a result, all resources being used by the call should be released eventually.
/// </summary>
public void Dispose()
{
disposeAction.Invoke();
}
}
}

@ -73,7 +73,7 @@ namespace Grpc.Core
asyncCall.StartServerStreamingCall(req, call.Headers);
RegisterCancellationCallback(asyncCall, token);
var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
return new AsyncServerStreamingCall<TResponse>(responseStream);
return new AsyncServerStreamingCall<TResponse>(responseStream, asyncCall.Cancel);
}
public static AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
@ -85,7 +85,7 @@ namespace Grpc.Core
var resultTask = asyncCall.ClientStreamingCallAsync(call.Headers);
RegisterCancellationCallback(asyncCall, token);
var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask);
return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask, asyncCall.Cancel);
}
public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
@ -98,7 +98,7 @@ namespace Grpc.Core
RegisterCancellationCallback(asyncCall, token);
var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
return new AsyncDuplexStreamingCall<TRequest, TResponse>(requestStream, responseStream);
return new AsyncDuplexStreamingCall<TRequest, TResponse>(requestStream, responseStream, asyncCall.Cancel);
}
private static void RegisterCancellationCallback<TRequest, TResponse>(AsyncCall<TRequest, TResponse> asyncCall, CancellationToken token)

@ -13,6 +13,7 @@
<AssemblyName>Grpc.Core</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<NuGetPackageImportStamp>8bb563fb</NuGetPackageImportStamp>
<DocumentationFile>bin\$(Configuration)\Grpc.Core.Xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

@ -17,10 +17,13 @@
<dependencies>
<dependency id="Microsoft.Bcl.Immutable" version="1.0.34" />
<dependency id="Ix-Async" version="1.2.3" />
<dependency id="grpc.native.csharp_ext" version="0.8.0.0" />
<dependency id="grpc.native.csharp_ext" version="0.9.0.0" />
</dependencies>
</metadata>
<files>
<file src="bin/Release/Grpc.Core.dll" target="lib/net45" />
<file src="bin/Release/Grpc.Core.pdb" target="lib/net45" />
<file src="bin/Release/Grpc.Core.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
</files>
</package>

@ -45,5 +45,6 @@ namespace Grpc.Core
/// <typeparam name="T"></typeparam>
public interface IAsyncStreamReader<TResponse> : IAsyncEnumerator<TResponse>
{
// TODO(jtattermusch): consider just using IAsyncEnumerator instead of this interface.
}
}

@ -49,6 +49,6 @@ namespace Grpc.Core
/// Writes a single asynchronously. Only one write can be pending at a time.
/// </summary>
/// <param name="message">the message to be written. Cannot be null.</param>
Task Write(T message);
Task WriteAsync(T message);
}
}

@ -48,6 +48,6 @@ namespace Grpc.Core
/// <summary>
/// Completes/closes the stream. Can only be called once there is no pending write. No writes should follow calling this.
/// </summary>
Task Complete();
Task CompleteAsync();
}
}

@ -43,7 +43,7 @@ namespace Grpc.Core
/// A writable stream of messages that is used in server-side handlers.
/// </summary>
public interface IServerStreamWriter<T> : IAsyncStreamWriter<T>
where T : class
{
// TODO(jtattermusch): consider just using IAsyncStreamWriter instead of this interface.
}
}

@ -46,14 +46,14 @@ namespace Grpc.Core.Internal
this.call = call;
}
public Task Write(TRequest message)
public Task WriteAsync(TRequest message)
{
var taskSource = new AsyncCompletionTaskSource<object>();
call.StartSendMessage(message, taskSource.CompletionDelegate);
return taskSource.Task;
}
public Task Complete()
public Task CompleteAsync()
{
var taskSource = new AsyncCompletionTaskSource<object>();
call.StartSendCloseFromClient(taskSource.CompletionDelegate);

@ -78,7 +78,7 @@ namespace Grpc.Core.Internal
Preconditions.CheckArgument(!await requestStream.MoveNext());
var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context
var result = await handler(context, request);
await responseStream.Write(result);
await responseStream.WriteAsync(result);
}
catch (Exception e)
{
@ -87,7 +87,7 @@ namespace Grpc.Core.Internal
}
try
{
await responseStream.WriteStatus(status);
await responseStream.WriteStatusAsync(status);
}
catch (OperationCanceledException)
{
@ -140,7 +140,7 @@ namespace Grpc.Core.Internal
try
{
await responseStream.WriteStatus(status);
await responseStream.WriteStatusAsync(status);
}
catch (OperationCanceledException)
{
@ -181,7 +181,7 @@ namespace Grpc.Core.Internal
var result = await handler(context, requestStream);
try
{
await responseStream.Write(result);
await responseStream.WriteAsync(result);
}
catch (OperationCanceledException)
{
@ -196,7 +196,7 @@ namespace Grpc.Core.Internal
try
{
await responseStream.WriteStatus(status);
await responseStream.WriteStatusAsync(status);
}
catch (OperationCanceledException)
{
@ -243,7 +243,7 @@ namespace Grpc.Core.Internal
}
try
{
await responseStream.WriteStatus(status);
await responseStream.WriteStatusAsync(status);
}
catch (OperationCanceledException)
{
@ -266,7 +266,7 @@ namespace Grpc.Core.Internal
var requestStream = new ServerRequestStream<byte[], byte[]>(asyncCall);
var responseStream = new ServerResponseStream<byte[], byte[]>(asyncCall);
await responseStream.WriteStatus(new Status(StatusCode.Unimplemented, "No such method."));
await responseStream.WriteStatusAsync(new Status(StatusCode.Unimplemented, "No such method."));
// TODO(jtattermusch): if we don't read what client has sent, the server call never gets disposed.
await requestStream.ToList();
await finishedTask;

@ -49,14 +49,14 @@ namespace Grpc.Core.Internal
this.call = call;
}
public Task Write(TResponse message)
public Task WriteAsync(TResponse message)
{
var taskSource = new AsyncCompletionTaskSource<object>();
call.StartSendMessage(message, taskSource.CompletionDelegate);
return taskSource.Task;
}
public Task WriteStatus(Status status)
public Task WriteStatusAsync(Status status)
{
var taskSource = new AsyncCompletionTaskSource<object>();
call.StartSendStatusFromServer(status, taskSource.CompletionDelegate);

@ -78,11 +78,11 @@ namespace Grpc.Core.Utils
{
foreach (var element in elements)
{
await streamWriter.Write(element);
await streamWriter.WriteAsync(element);
}
if (complete)
{
await streamWriter.Complete();
await streamWriter.CompleteAsync();
}
}
@ -94,7 +94,7 @@ namespace Grpc.Core.Utils
{
foreach (var element in elements)
{
await streamWriter.Write(element);
await streamWriter.WriteAsync(element);
}
}
}

@ -96,7 +96,19 @@ namespace math.Tests
Assert.AreEqual(0, response.Remainder);
}
// TODO(jtattermusch): test division by zero
[Test]
public void DivByZero()
{
try
{
DivReply response = client.Div(new DivArgs.Builder { Dividend = 0, Divisor = 0 }.Build());
Assert.Fail();
}
catch (RpcException e)
{
Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
}
}
[Test]
public void DivAsync()
@ -114,11 +126,12 @@ namespace math.Tests
{
Task.Run(async () =>
{
var call = client.Fib(new FibArgs.Builder { Limit = 6 }.Build());
var responses = await call.ResponseStream.ToList();
CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
responses.ConvertAll((n) => n.Num_));
using (var call = client.Fib(new FibArgs.Builder { Limit = 6 }.Build()))
{
var responses = await call.ResponseStream.ToList();
CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
responses.ConvertAll((n) => n.Num_));
}
}).Wait();
}
@ -128,13 +141,15 @@ namespace math.Tests
{
Task.Run(async () =>
{
var call = client.Sum();
var numbers = new List<long> { 10, 20, 30 }.ConvertAll(
n => Num.CreateBuilder().SetNum_(n).Build());
using (var call = client.Sum())
{
var numbers = new List<long> { 10, 20, 30 }.ConvertAll(
n => Num.CreateBuilder().SetNum_(n).Build());
await call.RequestStream.WriteAll(numbers);
var result = await call.Result;
Assert.AreEqual(60, result.Num_);
await call.RequestStream.WriteAll(numbers);
var result = await call.Result;
Assert.AreEqual(60, result.Num_);
}
}).Wait();
}
@ -150,12 +165,14 @@ namespace math.Tests
new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
};
var call = client.DivMany();
await call.RequestStream.WriteAll(divArgsList);
var result = await call.ResponseStream.ToList();
using (var call = client.DivMany())
{
await call.RequestStream.WriteAll(divArgsList);
var result = await call.ResponseStream.ToList();
CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient));
CollectionAssert.AreEqual(new long[] { 1, 16, 1 }, result.ConvertAll((divReply) => divReply.Remainder));
CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient));
CollectionAssert.AreEqual(new long[] { 1, 16, 1 }, result.ConvertAll((divReply) => divReply.Remainder));
}
}).Wait();
}
}

@ -51,18 +51,13 @@ namespace math
Console.WriteLine("DivAsync Result: " + result);
}
public static async Task DivAsyncWithCancellationExample(Math.IMathClient stub)
{
Task<DivReply> resultTask = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build());
DivReply result = await resultTask;
Console.WriteLine(result);
}
public static async Task FibExample(Math.IMathClient stub)
{
var call = stub.Fib(new FibArgs.Builder { Limit = 5 }.Build());
List<Num> result = await call.ResponseStream.ToList();
Console.WriteLine("Fib Result: " + string.Join("|", result));
using (var call = stub.Fib(new FibArgs.Builder { Limit = 5 }.Build()))
{
List<Num> result = await call.ResponseStream.ToList();
Console.WriteLine("Fib Result: " + string.Join("|", result));
}
}
public static async Task SumExample(Math.IMathClient stub)
@ -74,9 +69,11 @@ namespace math
new Num.Builder { Num_ = 3 }.Build()
};
var call = stub.Sum();
await call.RequestStream.WriteAll(numbers);
Console.WriteLine("Sum Result: " + await call.Result);
using (var call = stub.Sum())
{
await call.RequestStream.WriteAll(numbers);
Console.WriteLine("Sum Result: " + await call.Result);
}
}
public static async Task DivManyExample(Math.IMathClient stub)
@ -87,9 +84,11 @@ namespace math
new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
};
var call = stub.DivMany();
await call.RequestStream.WriteAll(divArgsList);
Console.WriteLine("DivMany Result: " + string.Join("|", await call.ResponseStream.ToList()));
using (var call = stub.DivMany())
{
await call.RequestStream.WriteAll(divArgsList);
Console.WriteLine("DivMany Result: " + string.Join("|", await call.ResponseStream.ToList()));
}
}
public static async Task DependendRequestsExample(Math.IMathClient stub)
@ -101,9 +100,12 @@ namespace math
new Num.Builder { Num_ = 3 }.Build()
};
var sumCall = stub.Sum();
await sumCall.RequestStream.WriteAll(numbers);
Num sum = await sumCall.Result;
Num sum;
using (var sumCall = stub.Sum())
{
await sumCall.RequestStream.WriteAll(numbers);
sum = await sumCall.Result;
}
DivReply result = await stub.DivAsync(new DivArgs.Builder { Dividend = sum.Num_, Divisor = numbers.Count }.Build());
Console.WriteLine("Avg Result: " + result);

@ -62,7 +62,7 @@ namespace math
{
foreach (var num in FibInternal(request.Limit))
{
await responseStream.Write(num);
await responseStream.WriteAsync(num);
}
}
}
@ -81,7 +81,7 @@ namespace math
{
await requestStream.ForEach(async divArgs =>
{
await responseStream.Write(DivInternal(divArgs));
await responseStream.WriteAsync(DivInternal(divArgs));
});
}

@ -213,11 +213,13 @@ namespace Grpc.IntegrationTesting
var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => StreamingInputCallRequest.CreateBuilder().SetPayload(CreateZerosPayload(size)).Build());
var call = client.StreamingInputCall();
await call.RequestStream.WriteAll(bodySizes);
using (var call = client.StreamingInputCall())
{
await call.RequestStream.WriteAll(bodySizes);
var response = await call.Result;
Assert.AreEqual(74922, response.AggregatedPayloadSize);
var response = await call.Result;
Assert.AreEqual(74922, response.AggregatedPayloadSize);
}
Console.WriteLine("Passed!");
}).Wait();
}
@ -236,14 +238,15 @@ namespace Grpc.IntegrationTesting
(size) => ResponseParameters.CreateBuilder().SetSize(size).Build()))
.Build();
var call = client.StreamingOutputCall(request);
var responseList = await call.ResponseStream.ToList();
foreach (var res in responseList)
using (var call = client.StreamingOutputCall(request))
{
Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
var responseList = await call.ResponseStream.ToList();
foreach (var res in responseList)
{
Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
}
CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
}
CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
Console.WriteLine("Passed!");
}).Wait();
}
@ -254,48 +257,48 @@ namespace Grpc.IntegrationTesting
{
Console.WriteLine("running ping_pong");
var call = client.FullDuplexCall();
await call.RequestStream.Write(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
.SetPayload(CreateZerosPayload(27182)).Build());
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
using (var call = client.FullDuplexCall())
{
await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
.SetPayload(CreateZerosPayload(27182)).Build());
await call.RequestStream.Write(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
.SetPayload(CreateZerosPayload(8)).Build());
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
.SetPayload(CreateZerosPayload(8)).Build());
await call.RequestStream.Write(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653))
.SetPayload(CreateZerosPayload(1828)).Build());
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653))
.SetPayload(CreateZerosPayload(1828)).Build());
await call.RequestStream.Write(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
.SetPayload(CreateZerosPayload(45904)).Build());
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
.SetPayload(CreateZerosPayload(45904)).Build());
await call.RequestStream.Complete();
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
Assert.IsFalse(await call.ResponseStream.MoveNext());
await call.RequestStream.CompleteAsync();
Assert.IsFalse(await call.ResponseStream.MoveNext());
}
Console.WriteLine("Passed!");
}).Wait();
}
@ -305,12 +308,13 @@ namespace Grpc.IntegrationTesting
Task.Run(async () =>
{
Console.WriteLine("running empty_stream");
var call = client.FullDuplexCall();
await call.RequestStream.Complete();
var responseList = await call.ResponseStream.ToList();
Assert.AreEqual(0, responseList.Count);
using (var call = client.FullDuplexCall())
{
await call.RequestStream.CompleteAsync();
var responseList = await call.ResponseStream.ToList();
Assert.AreEqual(0, responseList.Count);
}
Console.WriteLine("Passed!");
}).Wait();
}
@ -362,19 +366,21 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("running cancel_after_begin");
var cts = new CancellationTokenSource();
var call = client.StreamingInputCall(cts.Token);
// TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
await Task.Delay(1000);
cts.Cancel();
try
using (var call = client.StreamingInputCall(cts.Token))
{
var response = await call.Result;
Assert.Fail();
}
catch (RpcException e)
{
Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
// TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
await Task.Delay(1000);
cts.Cancel();
try
{
var response = await call.Result;
Assert.Fail();
}
catch (RpcException e)
{
Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
}
}
Console.WriteLine("Passed!");
}).Wait();
@ -387,27 +393,28 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("running cancel_after_first_response");
var cts = new CancellationTokenSource();
var call = client.FullDuplexCall(cts.Token);
await call.RequestStream.Write(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
.SetPayload(CreateZerosPayload(27182)).Build());
using (var call = client.FullDuplexCall(cts.Token))
{
await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
.SetPayload(CreateZerosPayload(27182)).Build());
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
Assert.IsTrue(await call.ResponseStream.MoveNext());
Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
cts.Cancel();
cts.Cancel();
try
{
await call.ResponseStream.MoveNext();
Assert.Fail();
}
catch (RpcException e)
{
Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
try
{
await call.ResponseStream.MoveNext();
Assert.Fail();
}
catch (RpcException e)
{
Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
}
}
Console.WriteLine("Passed!");
}).Wait();

@ -64,7 +64,7 @@ namespace grpc.testing
{
var response = StreamingOutputCallResponse.CreateBuilder()
.SetPayload(CreateZerosPayload(responseParam.Size)).Build();
await responseStream.Write(response);
await responseStream.WriteAsync(response);
}
}
@ -86,7 +86,7 @@ namespace grpc.testing
{
var response = StreamingOutputCallResponse.CreateBuilder()
.SetPayload(CreateZerosPayload(responseParam.Size)).Build();
await responseStream.Write(response);
await responseStream.WriteAsync(response);
}
});
}

@ -11,8 +11,8 @@ endlocal
@call buildall.bat || goto :error
%NUGET% pack ..\..\vsprojects\nuget_package\grpc.native.csharp_ext.nuspec || goto :error
%NUGET% pack Grpc.Core\Grpc.Core.nuspec || goto :error
%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec || goto :error
%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols || goto :error
%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols || goto :error
%NUGET% pack Grpc.nuspec || goto :error
goto :EOF

@ -0,0 +1,16 @@
# Command Line Tools
# Service Packager
The command line tool `bin/service_packager`, when called with the following command line:
```bash
service_packager proto_file -o output_path -n name -v version [-i input_path...]
```
Populates `output_path` with a node package consisting of a `package.json` populated with `name` and `version`, an `index.js`, a `LICENSE` file copied from gRPC, and a `service.json`, which is compiled from `proto_file` and the given `input_path`s. `require('output_path')` returns an object that is equivalent to
```js
{ client: require('grpc').load('service.json'),
auth: require('google-auth-library') }
```

@ -0,0 +1,2 @@
#!/usr/bin/env node
require(__dirname+'/../cli/service_packager.js').main(process.argv.slice(2));

@ -0,0 +1,142 @@
/*
*
* 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.
*
*/
'use strict';
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var async = require('async');
var pbjs = require('protobufjs/cli/pbjs');
var parseArgs = require('minimist');
var Mustache = require('mustache');
var package_json = require('../package.json');
var template_path = path.resolve(__dirname, 'service_packager');
var package_tpl_path = path.join(template_path, 'package.json.template');
var arg_format = {
string: ['include', 'out', 'name', 'version'],
alias: {
include: 'i',
out: 'o',
name: 'n',
version: 'v'
}
};
// TODO(mlumish): autogenerate README.md from proto file
/**
* Render package.json file from template using provided parameters.
* @param {Object} params Map of parameter names to values
* @param {function(Error, string)} callback Callback to pass rendered template
* text to
*/
function generatePackage(params, callback) {
fs.readFile(package_tpl_path, {encoding: 'utf-8'}, function(err, template) {
if (err) {
callback(err);
} else {
var rendered = Mustache.render(template, params);
callback(null, rendered);
}
});
}
/**
* Copy a file
* @param {string} src_path The filepath to copy from
* @param {string} dest_path The filepath to copy to
*/
function copyFile(src_path, dest_path) {
fs.createReadStream(src_path).pipe(fs.createWriteStream(dest_path));
}
/**
* Run the script. Copies the index.js and LICENSE files to the output path,
* renders the package.json template to the output path, and generates a
* service.json file from the input proto files using pbjs. The arguments are
* taken directly from the command line, and handled as follows:
* -i (--include) : An include path for pbjs (can be dpulicated)
* -o (--output): The output path
* -n (--name): The name of the package
* -v (--version): The package version
* @param {Array} argv The argument vector
*/
function main(argv) {
var args = parseArgs(argv, arg_format);
var out_path = path.resolve(args.out);
var include_dirs = [];
if (args.include) {
include_dirs = _.map(_.flatten([args.include]), function(p) {
return path.resolve(p);
});
}
args.grpc_version = package_json.version;
generatePackage(args, function(err, rendered) {
if (err) throw err;
fs.writeFile(path.join(out_path, 'package.json'), rendered, function(err) {
if (err) throw err;
});
});
copyFile(path.join(template_path, 'index.js'),
path.join(out_path, 'index.js'));
copyFile(path.join(__dirname, '..', 'LICENSE'),
path.join(out_path, 'LICENSE'));
var service_stream = fs.createWriteStream(path.join(out_path,
'service.json'));
var pbjs_args = _.flatten(['node', 'pbjs',
args._[0],
'-legacy',
_.map(include_dirs, function(dir) {
return "-path=" + dir;
})]);
var old_stdout = process.stdout;
process.__defineGetter__('stdout', function() {
return service_stream;
});
var pbjs_status = pbjs.main(pbjs_args);
process.__defineGetter__('stdout', function() {
return old_stdout;
});
if (pbjs_status !== pbjs.STATUS_OK) {
throw new Error('pbjs failed with status code ' + pbjs_status);
}
}
exports.main = main;

@ -0,0 +1,36 @@
/*
*
* 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.
*
*/
var grpc = require('grpc');
exports.client = grpc.load(__dirname + '/service.json', 'json');
exports.auth = require('google-auth-library');

@ -0,0 +1,17 @@
{
"name": "{{{name}}}",
"version": "{{{version}}}",
"author": "Google Inc.",
"description": "Client library for {{{name}}} built on gRPC",
"license": "Apache-2.0",
"dependencies": {
"grpc": "{{{grpc_version}}}",
"google-auth-library": "^0.9.2"
},
"main": "index.js",
"files": [
"LICENSE",
"index.js",
"service.json"
]
}

@ -36,6 +36,7 @@
"jshint": "^2.5.0",
"minimist": "^1.1.0",
"mocha": "~1.21.0",
"mustache": "^2.0.0",
"strftime": "^0.8.2"
},
"engines": {
@ -46,6 +47,8 @@
"README.md",
"index.js",
"binding.gyp",
"bin",
"cli",
"examples",
"ext",
"interop",

@ -2,7 +2,7 @@ source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'gRPC', :path => "../../../.."
pod 'Protobuf', :git => 'https://github.com/jcanizales/protobuf.git', :branch => 'add-podspec'
pod 'Protobuf', :git => 'https://github.com/google/protobuf.git'
pod 'Route_guide', :path => "RouteGuideClient"
pod 'RemoteTest', :path => "RemoteTestClient"

@ -1,5 +1,34 @@
#!/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.
# To properly use this, you'll need to add:
#
# "debug": true

@ -67,8 +67,8 @@ static void RunAsyncStreamingPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPS(result);
GetReporter()->ReportLatency(result);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
}
} // namespace testing

@ -67,8 +67,8 @@ static void RunAsyncUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPS(result);
GetReporter()->ReportLatency(result);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc

@ -77,13 +77,10 @@ static deque<string> get_hosts(const string& name) {
}
}
ScenarioResult RunScenario(const ClientConfig& initial_client_config,
size_t num_clients,
const ServerConfig& server_config,
size_t num_servers,
int warmup_seconds,
int benchmark_seconds,
int spawn_local_worker_count) {
std::unique_ptr<ScenarioResult> RunScenario(
const ClientConfig& initial_client_config, size_t num_clients,
const ServerConfig& server_config, size_t num_servers, int warmup_seconds,
int benchmark_seconds, int spawn_local_worker_count) {
// ClientContext allocator (all are destroyed at scope exit)
list<ClientContext> contexts;
auto alloc_context = [&contexts]() {
@ -91,6 +88,11 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
return &contexts.back();
};
// To be added to the result, containing the final configuration used for
// client and config (incluiding host, etc.)
ClientConfig result_client_config;
ServerConfig result_server_config;
// Get client, server lists
auto workers = get_hosts("QPS_WORKERS");
ClientConfig client_config = initial_client_config;
@ -139,6 +141,8 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
sd.stub = std::move(Worker::NewStub(
CreateChannel(workers[i], InsecureCredentials(), ChannelArguments())));
ServerArgs args;
result_server_config = server_config;
result_server_config.set_host(workers[i]);
*args.mutable_setup() = server_config;
sd.stream = std::move(sd.stub->RunServer(alloc_context()));
GPR_ASSERT(sd.stream->Write(args));
@ -168,6 +172,8 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
cd.stub = std::move(Worker::NewStub(CreateChannel(
workers[i + num_servers], InsecureCredentials(), ChannelArguments())));
ClientArgs args;
result_client_config = client_config;
result_client_config.set_host(workers[i + num_servers]);
*args.mutable_setup() = client_config;
cd.stream = std::move(cd.stub->RunTest(alloc_context()));
GPR_ASSERT(cd.stream->Write(args));
@ -208,7 +214,9 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds)));
// Finish a run
ScenarioResult result;
std::unique_ptr<ScenarioResult> result(new ScenarioResult);
result->client_config = result_client_config;
result->server_config = result_server_config;
gpr_log(GPR_INFO, "Finishing");
for (auto server = servers.begin(); server != servers.end(); server++) {
GPR_ASSERT(server->stream->Write(server_mark));
@ -219,14 +227,14 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
for (auto server = servers.begin(); server != servers.end(); server++) {
GPR_ASSERT(server->stream->Read(&server_status));
const auto& stats = server_status.stats();
result.server_resources.push_back(ResourceUsage{
result->server_resources.push_back(ResourceUsage{
stats.time_elapsed(), stats.time_user(), stats.time_system()});
}
for (auto client = clients.begin(); client != clients.end(); client++) {
GPR_ASSERT(client->stream->Read(&client_status));
const auto& stats = client_status.stats();
result.latencies.MergeProto(stats.latencies());
result.client_resources.push_back(ResourceUsage{
result->latencies.MergeProto(stats.latencies());
result->client_resources.push_back(ResourceUsage{
stats.time_elapsed(), stats.time_user(), stats.time_system()});
}

@ -34,6 +34,8 @@
#ifndef TEST_QPS_DRIVER_H
#define TEST_QPS_DRIVER_H
#include <memory>
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/qpstest.grpc.pb.h"
@ -49,15 +51,14 @@ struct ScenarioResult {
Histogram latencies;
std::vector<ResourceUsage> client_resources;
std::vector<ResourceUsage> server_resources;
ClientConfig client_config;
ServerConfig server_config;
};
ScenarioResult RunScenario(const grpc::testing::ClientConfig& client_config,
size_t num_clients,
const grpc::testing::ServerConfig& server_config,
size_t num_servers,
int warmup_seconds,
int benchmark_seconds,
int spawn_local_worker_count);
std::unique_ptr<ScenarioResult> RunScenario(
const grpc::testing::ClientConfig& client_config, size_t num_clients,
const grpc::testing::ServerConfig& server_config, size_t num_servers,
int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count);
} // namespace testing
} // namespace grpc

@ -1,5 +1,34 @@
#!/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.
if [ x"$QPS_WORKERS" == x ]; then
echo Error: Must set QPS_WORKERS variable in form \
"host:port,host:port,..." 1>&2

@ -111,10 +111,10 @@ static void QpsDriver() {
client_config, FLAGS_num_clients, server_config, FLAGS_num_servers,
FLAGS_warmup_seconds, FLAGS_benchmark_seconds, FLAGS_local_workers);
GetReporter()->ReportQPS(result);
GetReporter()->ReportQPSPerCore(result, server_config);
GetReporter()->ReportLatency(result);
GetReporter()->ReportTimes(result);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportQPSPerCore(*result, server_config);
GetReporter()->ReportLatency(*result);
GetReporter()->ReportTimes(*result);
}
} // namespace testing

@ -67,8 +67,8 @@ static void RunQPS() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPSPerCore(result, server_config);
GetReporter()->ReportLatency(result);
GetReporter()->ReportQPSPerCore(*result, server_config);
GetReporter()->ReportLatency(*result);
}
} // namespace testing

@ -102,6 +102,7 @@ message ClientConfig {
// only for async client:
optional int32 async_client_threads = 7;
optional RpcType rpc_type = 8 [default=UNARY];
optional string host = 9;
}
// Request current stats
@ -129,6 +130,7 @@ message ServerConfig {
required ServerType server_type = 1;
optional int32 threads = 2 [default=1];
optional bool enable_ssl = 3 [default=false];
optional string host = 4;
}
message ServerArgs {

@ -1,4 +1,32 @@
#!/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.
# performs a single qps run with one client and one server

@ -66,8 +66,8 @@ static void RunSynchronousStreamingPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPS(result);
GetReporter()->ReportLatency(result);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc

@ -66,8 +66,8 @@ static void RunSynchronousUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPS(result);
GetReporter()->ReportLatency(result);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
}
} // namespace testing

@ -1,4 +1,32 @@
#!/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.
import argparse
import os

@ -1,4 +1,32 @@
#!/bin/bash
# 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.
rm -rf /var/local/git
cp -R /var/local/git-clone /var/local/git

@ -1,4 +1,32 @@
#!/bin/bash
# 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.
rm -rf /var/local/git
cp -R /var/local/git-clone /var/local/git
cd /var/local/git/grpc-java/lib/netty && \

@ -1,4 +1,32 @@
#!/bin/bash
# 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.
cp -R /var/local/git-clone/grpc /var/local/git
make clean -C /var/local/git/grpc

@ -1,4 +1,32 @@
#!/bin/bash
# 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.
cp -R /var/local/git-clone/grpc /var/local/git
make clean -C /var/local/git/grpc

@ -1,4 +1,32 @@
#!/bin/bash
# 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.
# This script has to be run from the same directory as grpc_docker.sh and after grpc_docker.sh is sourced
#

@ -1,4 +1,32 @@
#!/bin/bash
# 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.
cd `dirname $0`/../..
grpc_dir=`pwd`

@ -61,7 +61,7 @@ class SimpleConfig(object):
self.environ = environ
self.environ['CONFIG'] = config
def job_spec(self, cmdline, hash_targets, shortname=None):
def job_spec(self, cmdline, hash_targets, shortname=None, environ={}):
"""Construct a jobset.JobSpec for a test under this config
Args:
@ -73,9 +73,12 @@ class SimpleConfig(object):
-- if used, all artifacts needed to run the test must
be listed
"""
actual_environ = self.environ.copy()
for k, v in environ.iteritems():
actual_environ[k] = v
return jobset.JobSpec(cmdline=cmdline,
shortname=shortname,
environ=self.environ,
environ=actual_environ,
hash_targets=hash_targets
if self.allow_hashing else None)
@ -143,7 +146,8 @@ class CLanguage(object):
class NodeLanguage(object):
def test_specs(self, config, travis):
return [config.job_spec(['tools/run_tests/run_node.sh'], None)]
return [config.job_spec(['tools/run_tests/run_node.sh'], None,
environ={'GRPC_TRACE': 'surface,batch'})]
def make_targets(self):
return ['static_c']
@ -161,7 +165,8 @@ class NodeLanguage(object):
class PhpLanguage(object):
def test_specs(self, config, travis):
return [config.job_spec(['src/php/bin/run_tests.sh'], None)]
return [config.job_spec(['src/php/bin/run_tests.sh'], None,
environ={'GRPC_TRACE': 'surface,batch'})]
def make_targets(self):
return ['static_c']
@ -184,15 +189,17 @@ class PythonLanguage(object):
def test_specs(self, config, travis):
modules = [config.job_spec(['tools/run_tests/run_python.sh', '-m',
test['module']],
None,
test['module']],
None,
environ={'GRPC_TRACE': 'surface,batch'},
shortname=test['module'])
for test in self._tests if 'module' in test]
files = [config.job_spec(['tools/run_tests/run_python.sh',
test['file']],
None,
test['file']],
None,
environ={'GRPC_TRACE': 'surface,batch'},
shortname=test['file'])
for test in self._tests if 'file' in test]
for test in self._tests if 'file' in test]
return files + modules
def make_targets(self):
@ -211,7 +218,8 @@ class PythonLanguage(object):
class RubyLanguage(object):
def test_specs(self, config, travis):
return [config.job_spec(['tools/run_tests/run_ruby.sh'], None)]
return [config.job_spec(['tools/run_tests/run_ruby.sh'], None,
environ={'GRPC_TRACE': 'surface,batch'})]
def make_targets(self):
return ['run_dep_checks']
@ -232,7 +240,8 @@ class CSharpLanguage(object):
'Grpc.Examples.Tests',
'Grpc.IntegrationTesting']
return [config.job_spec(['tools/run_tests/run_csharp.sh', assembly],
None, shortname=assembly)
None, shortname=assembly,
environ={'GRPC_TRACE': 'surface,batch'})
for assembly in assemblies ]
def make_targets(self):

@ -2,14 +2,14 @@
<package>
<metadata>
<id>grpc.native.csharp_ext</id>
<version>0.8.0.0</version>
<version>0.9.0.0</version>
<authors>Google Inc.</authors>
<owners>Jan Tattermusch</owners>
<licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
<projectUrl>http://github.com/grpc/grpc</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Native extension needed by gRPC C# library. This is not the package you are looking for, it is only meant to be used as a dependency.</description>
<releaseNotes>Release of gRPC C core 0.8.0 libraries.</releaseNotes>
<releaseNotes>Release of gRPC C core 0.9.0 libraries.</releaseNotes>
<copyright>Copyright 2015</copyright>
<title>gRPC C# Native Extension</title>
<summary>Native library required by gRPC C#</summary>

Loading…
Cancel
Save