aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/csharp/Grpc.Core.Tests/ClientServerTest.cs3
-rw-r--r--src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj1
-rw-r--r--src/csharp/Grpc.Core.Tests/MockServiceHelper.cs4
-rw-r--r--src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs139
-rw-r--r--src/csharp/Grpc.Core.Tests/TimeoutsTest.cs15
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs3
-rw-r--r--src/csharp/Grpc.Core/WriteOptions.cs1
8 files changed, 159 insertions, 9 deletions
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index 08c80bbe53..f56fb744a6 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -217,7 +217,8 @@ namespace Grpc.Core.Tests
[Test]
public void UnaryCallPerformance()
{
- helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
return request;
});
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index 55d0c98d44..4692d958a0 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -78,6 +78,7 @@
<Compile Include="NUnitVersionTest.cs" />
<Compile Include="ChannelTest.cs" />
<Compile Include="MockServiceHelper.cs" />
+ <Compile Include="ResponseHeadersTest.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
index 25afa30bba..b642286b11 100644
--- a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
+++ b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
@@ -199,6 +199,7 @@ namespace Grpc.Core.Tests
{
return this.unaryHandler;
}
+
set
{
unaryHandler = value;
@@ -211,6 +212,7 @@ namespace Grpc.Core.Tests
{
return this.clientStreamingHandler;
}
+
set
{
clientStreamingHandler = value;
@@ -223,6 +225,7 @@ namespace Grpc.Core.Tests
{
return this.serverStreamingHandler;
}
+
set
{
serverStreamingHandler = value;
@@ -235,6 +238,7 @@ namespace Grpc.Core.Tests
{
return this.duplexStreamingHandler;
}
+
set
{
duplexStreamingHandler = value;
diff --git a/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs b/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
new file mode 100644
index 0000000000..b024488549
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
@@ -0,0 +1,139 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+ /// <summary>
+ /// Tests for response headers support.
+ /// </summary>
+ public class ResponseHeadersTest
+ {
+ MockServiceHelper helper;
+ Server server;
+ Channel channel;
+
+ Metadata headers;
+
+ [SetUp]
+ public void Init()
+ {
+ helper = new MockServiceHelper();
+
+ server = helper.GetServer();
+ server.Start();
+ channel = helper.GetChannel();
+
+ headers = new Metadata
+ {
+ new Metadata.Entry("ascii-header", "abcdefg"),
+ };
+ }
+
+ [TearDown]
+ public void Cleanup()
+ {
+ channel.Dispose();
+ server.ShutdownAsync().Wait();
+ }
+
+ [TestFixtureTearDown]
+ public void CleanupClass()
+ {
+ GrpcEnvironment.Shutdown();
+ }
+
+ [Test]
+ public void WriteResponseHeaders_NullNotAllowed()
+ {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
+ Assert.Throws(typeof(NullReferenceException), async () => await context.WriteResponseHeadersAsync(null));
+ return "PASS";
+ });
+
+ Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
+ }
+
+ [Test]
+ public void WriteResponseHeaders_AllowedOnlyOnce()
+ {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
+ await context.WriteResponseHeadersAsync(headers);
+ try
+ {
+ await context.WriteResponseHeadersAsync(headers);
+ Assert.Fail();
+ }
+ catch (InvalidOperationException expected)
+ {
+ }
+ return "PASS";
+ });
+
+ Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
+ }
+
+ [Test]
+ public async Task WriteResponseHeaders_NotAllowedAfterWrite()
+ {
+ helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>(async (request, responseStream, context) =>
+ {
+ await responseStream.WriteAsync("A");
+ try
+ {
+ await context.WriteResponseHeadersAsync(headers);
+ Assert.Fail();
+ }
+ catch (InvalidOperationException expected)
+ {
+ }
+ await responseStream.WriteAsync("B");
+ });
+
+ var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "");
+ var responses = await call.ResponseStream.ToList();
+ CollectionAssert.AreEqual(new[] { "A", "B" }, responses);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
index ead0b1854b..d875d601b9 100644
--- a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
+++ b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
@@ -78,7 +78,8 @@ namespace Grpc.Core.Tests
[Test]
public void InfiniteDeadline()
{
- helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
Assert.AreEqual(DateTime.MaxValue, context.Deadline);
return "PASS";
});
@@ -95,7 +96,8 @@ namespace Grpc.Core.Tests
{
var clientDeadline = DateTime.UtcNow + TimeSpan.FromDays(7);
- helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
// A fairly relaxed check that the deadline set by client and deadline seen by server
// are in agreement. C core takes care of the work with transferring deadline over the wire,
// so we don't need an exact check here.
@@ -108,7 +110,8 @@ namespace Grpc.Core.Tests
[Test]
public void DeadlineInThePast()
{
- helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
await Task.Delay(60000);
return "FAIL";
});
@@ -121,7 +124,8 @@ namespace Grpc.Core.Tests
[Test]
public void DeadlineExceededStatusOnTimeout()
{
- helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
await Task.Delay(60000);
return "FAIL";
});
@@ -136,7 +140,8 @@ namespace Grpc.Core.Tests
{
var serverReceivedCancellationTcs = new TaskCompletionSource<bool>();
- helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => {
+ helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+ {
// wait until cancellation token is fired.
var tcs = new TaskCompletionSource<object>();
context.CancellationToken.Register(() => { tcs.SetResult(null); });
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index c8c2449ee6..df5c07e4c4 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -279,7 +279,7 @@ namespace Grpc.Core.Internal
}
}
- public CallInvocationDetails<TRequest, TResponse> Details
+ public CallInvocationDetails<TRequest, TResponse> Details
{
get
{
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 9eac7f7b61..1704b9afbf 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -107,10 +107,11 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
+ Preconditions.CheckNotNull(headers, "metadata");
Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
Preconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call.");
- Preconditions.CheckState(streamingWritesCounter > 0, "Response headers can only be sent before the first write starts.");
+ Preconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts.");
CheckSendingAllowed();
Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
diff --git a/src/csharp/Grpc.Core/WriteOptions.cs b/src/csharp/Grpc.Core/WriteOptions.cs
index ec4a7dd8cd..7ef3189d76 100644
--- a/src/csharp/Grpc.Core/WriteOptions.cs
+++ b/src/csharp/Grpc.Core/WriteOptions.cs
@@ -54,7 +54,6 @@ namespace Grpc.Core
NoCompress = 0x2
}
-
/// <summary>
/// Options for write operations.
/// </summary>