• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #endregion
18 
19 using System;
20 using System.Diagnostics;
21 using System.Linq;
22 using System.Threading;
23 using System.Threading.Tasks;
24 using Grpc.Core;
25 using Grpc.Core.Internal;
26 using Grpc.Core.Utils;
27 using NUnit.Framework;
28 
29 namespace Grpc.Core.Tests
30 {
31     /// <summary>
32     /// Tests for Deadline support.
33     /// </summary>
34     public class TimeoutsTest
35     {
36         MockServiceHelper helper;
37         Server server;
38         Channel channel;
39 
40         [SetUp]
Init()41         public void Init()
42         {
43             helper = new MockServiceHelper();
44 
45             server = helper.GetServer();
46             server.Start();
47             channel = helper.GetChannel();
48         }
49 
50         [TearDown]
Cleanup()51         public void Cleanup()
52         {
53             channel.ShutdownAsync().Wait();
54             server.ShutdownAsync().Wait();
55         }
56 
57         [Test]
InfiniteDeadline()58         public void InfiniteDeadline()
59         {
60             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
61             {
62                 Assert.AreEqual(DateTime.MaxValue, context.Deadline);
63                 return Task.FromResult("PASS");
64             });
65 
66             // no deadline specified, check server sees infinite deadline
67             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc"));
68 
69             // DateTime.MaxValue deadline specified, check server sees infinite deadline
70             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: DateTime.MaxValue)), "abc"));
71         }
72 
73         [Test]
DeadlineTransferredToServer()74         public void DeadlineTransferredToServer()
75         {
76             var clientDeadline = DateTime.UtcNow + TimeSpan.FromDays(7);
77 
78             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
79             {
80                 // A fairly relaxed check that the deadline set by client and deadline seen by server
81                 // are in agreement. C core takes care of the work with transferring deadline over the wire,
82                 // so we don't need an exact check here.
83                 Assert.IsTrue(Math.Abs((clientDeadline - context.Deadline).TotalHours) < 1);
84                 return Task.FromResult("PASS");
85             });
86             Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: clientDeadline)), "abc");
87         }
88 
89         [Test]
DeadlineInThePast()90         public void DeadlineInThePast()
91         {
92             helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
93             {
94                 await Task.Delay(60000);
95                 return "FAIL";
96             });
97 
98             var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: DateTime.MinValue)), "abc"));
99             Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
100         }
101 
102         [Test]
DeadlineExceededStatusOnTimeout()103         public void DeadlineExceededStatusOnTimeout()
104         {
105             helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
106             {
107                 await Task.Delay(60000);
108                 return "FAIL";
109             });
110 
111             var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: DateTime.UtcNow.Add(TimeSpan.FromSeconds(5)))), "abc"));
112             Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
113         }
114 
115         [Test]
ServerReceivesCancellationOnTimeout()116         public async Task ServerReceivesCancellationOnTimeout()
117         {
118             var serverReceivedCancellationTcs = new TaskCompletionSource<bool>();
119 
120             helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
121             {
122                 // wait until cancellation token is fired.
123                 var tcs = new TaskCompletionSource<object>();
124                 context.CancellationToken.Register(() => { tcs.SetResult(null); });
125                 await tcs.Task;
126                 serverReceivedCancellationTcs.SetResult(true);
127                 return "";
128             });
129 
130             var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: DateTime.UtcNow.Add(TimeSpan.FromSeconds(5)))), "abc"));
131             Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
132             Assert.IsTrue(await serverReceivedCancellationTcs.Task);
133         }
134     }
135 }
136