• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 
3 // Copyright 2018 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.Collections.Generic;
21 using System.Linq;
22 using System.Text;
23 using System.Threading;
24 using System.Threading.Tasks;
25 using Grpc.Core;
26 using Grpc.Core.Interceptors;
27 using Grpc.Core.Internal;
28 using Grpc.Core.Tests;
29 using Grpc.Core.Utils;
30 using NUnit.Framework;
31 
32 namespace Grpc.Core.Interceptors.Tests
33 {
34     public class ServerInterceptorTest
35     {
36         const string Host = "127.0.0.1";
37 
38         [Test]
AddRequestHeaderInServerInterceptor()39         public void AddRequestHeaderInServerInterceptor()
40         {
41             var helper = new MockServiceHelper(Host);
42             const string MetadataKey = "x-interceptor";
43             const string MetadataValue = "hello world";
44             var interceptor = new ServerCallContextInterceptor(ctx => ctx.RequestHeaders.Add(new Metadata.Entry(MetadataKey, MetadataValue)));
45             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
46             {
47                 var interceptorHeader = context.RequestHeaders.Last(m => (m.Key == MetadataKey)).Value;
48                 Assert.AreEqual(interceptorHeader, MetadataValue);
49                 return Task.FromResult("PASS");
50             });
51             helper.ServiceDefinition = helper.ServiceDefinition.Intercept(interceptor);
52             var server = helper.GetServer();
53             server.Start();
54             var channel = helper.GetChannel();
55             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
56         }
57 
58         [Test]
VerifyInterceptorOrdering()59         public void VerifyInterceptorOrdering()
60         {
61             var helper = new MockServiceHelper(Host);
62             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
63             {
64                 return Task.FromResult("PASS");
65             });
66             var stringBuilder = new StringBuilder();
67             helper.ServiceDefinition = helper.ServiceDefinition
68                 .Intercept(new ServerCallContextInterceptor(ctx => stringBuilder.Append("A")))
69                 .Intercept(new ServerCallContextInterceptor(ctx => stringBuilder.Append("B1")),
70                     new ServerCallContextInterceptor(ctx => stringBuilder.Append("B2")),
71                     new ServerCallContextInterceptor(ctx => stringBuilder.Append("B3")))
72                 .Intercept(new ServerCallContextInterceptor(ctx => stringBuilder.Append("C")));
73             var server = helper.GetServer();
74             server.Start();
75             var channel = helper.GetChannel();
76             Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
77             Assert.AreEqual("CB1B2B3A", stringBuilder.ToString());
78         }
79 
80         [Test]
CheckNullInterceptorRegistrationFails()81         public void CheckNullInterceptorRegistrationFails()
82         {
83             var helper = new MockServiceHelper(Host);
84             var sd = helper.ServiceDefinition;
85             Assert.Throws<ArgumentNullException>(() => sd.Intercept(default(Interceptor)));
86             Assert.Throws<ArgumentNullException>(() => sd.Intercept(new[]{default(Interceptor)}));
87             Assert.Throws<ArgumentNullException>(() => sd.Intercept(new[]{new ServerCallContextInterceptor(ctx=>{}), null}));
88             Assert.Throws<ArgumentNullException>(() => sd.Intercept(default(Interceptor[])));
89         }
90 
91         private class ServerCallContextInterceptor : Interceptor
92         {
93             readonly Action<ServerCallContext> interceptor;
94 
ServerCallContextInterceptor(Action<ServerCallContext> interceptor)95             public ServerCallContextInterceptor(Action<ServerCallContext> interceptor)
96             {
97                 GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor));
98                 this.interceptor = interceptor;
99             }
100 
UnaryServerHandler(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)101             public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
102             {
103                 interceptor(context);
104                 return continuation(request, context);
105             }
106 
ClientStreamingServerHandler(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)107             public override Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)
108             {
109                 interceptor(context);
110                 return continuation(requestStream, context);
111             }
112 
ServerStreamingServerHandler(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)113             public override Task ServerStreamingServerHandler<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)
114             {
115                 interceptor(context);
116                 return continuation(request, responseStream, context);
117             }
118 
DuplexStreamingServerHandler(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)119             public override Task DuplexStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)
120             {
121                 interceptor(context);
122                 return continuation(requestStream, responseStream, context);
123             }
124         }
125     }
126 }
127