blob: a925f865ff327beef0631a87fa4c80c3739b30ae [file] [log] [blame]
Jan Tattermusch5b0b3922015-08-07 19:07:14 -07001#region Copyright notice and license
2
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003// Copyright 2015 gRPC authors.
Jan Tattermusch5b0b3922015-08-07 19:07:14 -07004//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005// 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
Jan Tattermusch5b0b3922015-08-07 19:07:14 -07008//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009// http://www.apache.org/licenses/LICENSE-2.0
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070010//
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011// 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.
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070016
17#endregion
18
19using System;
Jan Tattermusch7ebbc472015-12-08 22:39:02 -080020using System.Collections.Generic;
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070021using System.Diagnostics;
22using System.Linq;
23using System.Threading;
24using System.Threading.Tasks;
25using Grpc.Core;
26using Grpc.Core.Internal;
27using Grpc.Core.Utils;
28using NUnit.Framework;
29
30namespace Grpc.Core.Tests
31{
32 /// <summary>
33 /// Allows setting up a mock service in the client-server tests easily.
34 /// </summary>
35 public class MockServiceHelper
36 {
37 public const string ServiceName = "tests.Test";
38
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070039 readonly string host;
Jan Tattermusch7ebbc472015-12-08 22:39:02 -080040 readonly IEnumerable<ChannelOption> channelOptions;
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070041
Jan Tattermusch67c45872015-08-27 18:12:39 -070042 readonly Method<string, string> unaryMethod;
43 readonly Method<string, string> clientStreamingMethod;
44 readonly Method<string, string> serverStreamingMethod;
45 readonly Method<string, string> duplexStreamingMethod;
46
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070047 UnaryServerMethod<string, string> unaryHandler;
48 ClientStreamingServerMethod<string, string> clientStreamingHandler;
49 ServerStreamingServerMethod<string, string> serverStreamingHandler;
50 DuplexStreamingServerMethod<string, string> duplexStreamingHandler;
51
52 Server server;
53 Channel channel;
54
Jan Tattermusch7ebbc472015-12-08 22:39:02 -080055 public MockServiceHelper(string host = null, Marshaller<string> marshaller = null, IEnumerable<ChannelOption> channelOptions = null)
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070056 {
57 this.host = host ?? "localhost";
Jan Tattermusch7ebbc472015-12-08 22:39:02 -080058 this.channelOptions = channelOptions;
Jan Tattermusch67c45872015-08-27 18:12:39 -070059 marshaller = marshaller ?? Marshallers.StringMarshaller;
60
61 unaryMethod = new Method<string, string>(
62 MethodType.Unary,
63 ServiceName,
64 "Unary",
65 marshaller,
66 marshaller);
67
68 clientStreamingMethod = new Method<string, string>(
69 MethodType.ClientStreaming,
70 ServiceName,
71 "ClientStreaming",
72 marshaller,
73 marshaller);
74
75 serverStreamingMethod = new Method<string, string>(
76 MethodType.ServerStreaming,
77 ServiceName,
78 "ServerStreaming",
79 marshaller,
80 marshaller);
81
82 duplexStreamingMethod = new Method<string, string>(
83 MethodType.DuplexStreaming,
84 ServiceName,
85 "DuplexStreaming",
86 marshaller,
87 marshaller);
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070088
Mehrdad Afsharie954dff2018-02-11 20:11:28 -080089 ServiceDefinition = ServerServiceDefinition.CreateBuilder()
Jan Tattermusch67c45872015-08-27 18:12:39 -070090 .AddMethod(unaryMethod, (request, context) => unaryHandler(request, context))
91 .AddMethod(clientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context))
92 .AddMethod(serverStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context))
93 .AddMethod(duplexStreamingMethod, (requestStream, responseStream, context) => duplexStreamingHandler(requestStream, responseStream, context))
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070094 .Build();
95
96 var defaultStatus = new Status(StatusCode.Unknown, "Default mock implementation. Please provide your own.");
97
Jan Tattermusch2fb313c2017-08-09 09:41:25 +020098 unaryHandler = new UnaryServerMethod<string, string>((request, context) =>
Jan Tattermusch5b0b3922015-08-07 19:07:14 -070099 {
100 context.Status = defaultStatus;
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200101 return Task.FromResult("");
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700102 });
103
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200104 clientStreamingHandler = new ClientStreamingServerMethod<string, string>((requestStream, context) =>
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700105 {
106 context.Status = defaultStatus;
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200107 return Task.FromResult("");
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700108 });
109
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200110 serverStreamingHandler = new ServerStreamingServerMethod<string, string>((request, responseStream, context) =>
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700111 {
112 context.Status = defaultStatus;
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200113 return TaskUtils.CompletedTask;
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700114 });
115
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200116 duplexStreamingHandler = new DuplexStreamingServerMethod<string, string>((requestStream, responseStream, context) =>
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700117 {
118 context.Status = defaultStatus;
Jan Tattermusch2fb313c2017-08-09 09:41:25 +0200119 return TaskUtils.CompletedTask;
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700120 });
121 }
122
123 /// <summary>
124 /// Returns the default server for this service and creates one if not yet created.
125 /// </summary>
126 public Server GetServer()
127 {
128 if (server == null)
129 {
Jan Tattermusch09d2f552017-04-20 11:39:37 +0200130 // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
131 server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700132 {
Mehrdad Afsharie954dff2018-02-11 20:11:28 -0800133 Services = { ServiceDefinition },
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700134 Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
135 };
136 }
137 return server;
138 }
139
140 /// <summary>
141 /// Returns the default channel for this service and creates one if not yet created.
142 /// </summary>
143 public Channel GetChannel()
144 {
145 if (channel == null)
146 {
Jan Tattermusch7ebbc472015-12-08 22:39:02 -0800147 channel = new Channel(Host, GetServer().Ports.Single().BoundPort, ChannelCredentials.Insecure, channelOptions);
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700148 }
149 return channel;
150 }
151
Jan Tattermusch9698b5b2015-08-10 16:40:19 -0700152 public CallInvocationDetails<string, string> CreateUnaryCall(CallOptions options = default(CallOptions))
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700153 {
Jan Tattermusch67c45872015-08-27 18:12:39 -0700154 return new CallInvocationDetails<string, string>(channel, unaryMethod, options);
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700155 }
156
Jan Tattermusch9698b5b2015-08-10 16:40:19 -0700157 public CallInvocationDetails<string, string> CreateClientStreamingCall(CallOptions options = default(CallOptions))
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700158 {
Jan Tattermusch67c45872015-08-27 18:12:39 -0700159 return new CallInvocationDetails<string, string>(channel, clientStreamingMethod, options);
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700160 }
161
Jan Tattermusch9698b5b2015-08-10 16:40:19 -0700162 public CallInvocationDetails<string, string> CreateServerStreamingCall(CallOptions options = default(CallOptions))
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700163 {
Jan Tattermusch67c45872015-08-27 18:12:39 -0700164 return new CallInvocationDetails<string, string>(channel, serverStreamingMethod, options);
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700165 }
166
Jan Tattermusch9698b5b2015-08-10 16:40:19 -0700167 public CallInvocationDetails<string, string> CreateDuplexStreamingCall(CallOptions options = default(CallOptions))
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700168 {
Jan Tattermusch67c45872015-08-27 18:12:39 -0700169 return new CallInvocationDetails<string, string>(channel, duplexStreamingMethod, options);
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700170 }
171
172 public string Host
173 {
174 get
175 {
176 return this.host;
177 }
178 }
179
Mehrdad Afsharie954dff2018-02-11 20:11:28 -0800180 public ServerServiceDefinition ServiceDefinition { get; set; }
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700181
182 public UnaryServerMethod<string, string> UnaryHandler
183 {
184 get
185 {
186 return this.unaryHandler;
187 }
Jan Tattermuschc75c57c2015-08-07 22:07:40 -0700188
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700189 set
190 {
191 unaryHandler = value;
192 }
193 }
194
195 public ClientStreamingServerMethod<string, string> ClientStreamingHandler
196 {
197 get
198 {
199 return this.clientStreamingHandler;
200 }
Jan Tattermuschc75c57c2015-08-07 22:07:40 -0700201
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700202 set
203 {
204 clientStreamingHandler = value;
205 }
206 }
207
208 public ServerStreamingServerMethod<string, string> ServerStreamingHandler
209 {
210 get
211 {
212 return this.serverStreamingHandler;
213 }
Jan Tattermuschc75c57c2015-08-07 22:07:40 -0700214
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700215 set
216 {
217 serverStreamingHandler = value;
218 }
219 }
220
221 public DuplexStreamingServerMethod<string, string> DuplexStreamingHandler
222 {
223 get
224 {
225 return this.duplexStreamingHandler;
226 }
Jan Tattermuschc75c57c2015-08-07 22:07:40 -0700227
Jan Tattermusch5b0b3922015-08-07 19:07:14 -0700228 set
229 {
230 duplexStreamingHandler = value;
231 }
232 }
233 }
234}