diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/csharp/Grpc.Core.Tests/ClientServerTest.cs | 3 | ||||
-rw-r--r-- | src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 1 | ||||
-rw-r--r-- | src/csharp/Grpc.Core.Tests/MockServiceHelper.cs | 4 | ||||
-rw-r--r-- | src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs | 139 | ||||
-rw-r--r-- | src/csharp/Grpc.Core.Tests/TimeoutsTest.cs | 15 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/AsyncCall.cs | 2 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/AsyncCallServer.cs | 3 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/WriteOptions.cs | 1 |
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> |