blob: e1b47744d506ec55b33d9f4b48dbdf30de9998f3 [file] [log] [blame]
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -07001#region Copyright notice and license
2
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003// Copyright 2015 gRPC authors.
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -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 Tattermuschd0c1bfa2015-10-22 19:14:57 -07008//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009// http://www.apache.org/licenses/LICENSE-2.0
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -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 Tattermuschd0c1bfa2015-10-22 19:14:57 -070016
17#endregion
18
19using System;
20using System.Collections.Generic;
21using System.Diagnostics;
22using System.IO;
23using System.Linq;
24using System.Text.RegularExpressions;
25using System.Threading;
26using System.Threading.Tasks;
27using Google.Protobuf;
28using Grpc.Core;
Jan Tattermusch3d6644a2016-03-21 09:46:15 -070029using Grpc.Core.Logging;
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -070030using Grpc.Core.Utils;
31using NUnit.Framework;
32using Grpc.Testing;
33
34namespace Grpc.IntegrationTesting
35{
36 /// <summary>
37 /// Helper methods to start server runners for performance testing.
38 /// </summary>
Jan Tattermusch3d6644a2016-03-21 09:46:15 -070039 public class ServerRunners
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -070040 {
Jan Tattermusch3d6644a2016-03-21 09:46:15 -070041 static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<ServerRunners>();
42
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -070043 /// <summary>
44 /// Creates a started server runner.
45 /// </summary>
46 public static IServerRunner CreateStarted(ServerConfig config)
47 {
Jan Tattermusch3d6644a2016-03-21 09:46:15 -070048 Logger.Debug("ServerConfig: {0}", config);
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -070049 var credentials = config.SecurityParams != null ? TestCredentials.CreateSslServerCredentials() : ServerCredentials.Insecure;
50
Jan Tattermusch3d6644a2016-03-21 09:46:15 -070051 if (config.AsyncServerThreads != 0)
52 {
53 Logger.Warning("ServerConfig.AsyncServerThreads is not supported for C#. Ignoring the value");
54 }
55 if (config.CoreLimit != 0)
56 {
57 Logger.Warning("ServerConfig.CoreLimit is not supported for C#. Ignoring the value");
58 }
59 if (config.CoreList.Count > 0)
60 {
61 Logger.Warning("ServerConfig.CoreList is not supported for C#. Ignoring the value");
62 }
63
Jan Tattermusch253769e2016-03-21 16:25:59 -070064 ServerServiceDefinition service = null;
Jan Tattermusch87ba2942016-05-16 17:18:00 -070065 if (config.ServerType == ServerType.AsyncServer)
Jan Tattermusch253769e2016-03-21 16:25:59 -070066 {
67 GrpcPreconditions.CheckArgument(config.PayloadConfig == null,
68 "ServerConfig.PayloadConfig shouldn't be set for BenchmarkService based server.");
69 service = BenchmarkService.BindService(new BenchmarkServiceImpl());
70 }
Jan Tattermusch87ba2942016-05-16 17:18:00 -070071 else if (config.ServerType == ServerType.AsyncGenericServer)
Jan Tattermusch253769e2016-03-21 16:25:59 -070072 {
73 var genericService = new GenericServiceImpl(config.PayloadConfig.BytebufParams.RespSize);
74 service = GenericService.BindHandler(genericService.StreamingCall);
75 }
76 else
77 {
78 throw new ArgumentException("Unsupported ServerType");
79 }
80
Jan Tattermuschea6cc572017-11-16 18:04:37 +010081 var channelOptions = new List<ChannelOption>(config.ChannelArgs.Select((arg) => arg.ToChannelOption()));
82 var server = new Server(channelOptions)
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -070083 {
Jan Tattermusch253769e2016-03-21 16:25:59 -070084 Services = { service },
Jan Tattermusch1cbb5672016-02-18 14:27:28 -080085 Ports = { new ServerPort("[::]", config.Port, credentials) }
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -070086 };
87
88 server.Start();
89 return new ServerRunnerImpl(server);
90 }
Jan Tattermusch253769e2016-03-21 16:25:59 -070091
92 private class GenericServiceImpl
93 {
94 readonly byte[] response;
95
96 public GenericServiceImpl(int responseSize)
97 {
98 this.response = new byte[responseSize];
99 }
100
101 /// <summary>
102 /// Generic streaming call handler.
103 /// </summary>
104 public async Task StreamingCall(IAsyncStreamReader<byte[]> requestStream, IServerStreamWriter<byte[]> responseStream, ServerCallContext context)
105 {
106 await requestStream.ForEachAsync(async request =>
107 {
108 await responseStream.WriteAsync(response);
109 });
110 }
111 }
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -0700112 }
113
114 /// <summary>
115 /// Server runner.
116 /// </summary>
117 public class ServerRunnerImpl : IServerRunner
118 {
119 readonly Server server;
120 readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
121
122 public ServerRunnerImpl(Server server)
123 {
Jan Tattermusch7a3ee6a2016-02-18 10:36:02 -0800124 this.server = GrpcPreconditions.CheckNotNull(server);
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -0700125 }
126
127 public int BoundPort
128 {
129 get
130 {
131 return server.Ports.Single().BoundPort;
132 }
133 }
134
135 /// <summary>
136 /// Gets server stats.
137 /// </summary>
138 /// <returns>The stats.</returns>
139 public ServerStats GetStats(bool reset)
140 {
141 var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
142
Jan Tattermusch8251fdd2017-06-01 19:26:12 +0200143 GrpcEnvironment.Logger.Info("[ServerRunner.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, (seconds since last reset {3})",
144 GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), secondsElapsed);
Jan Tattermusch01ce2362017-04-25 20:53:51 +0200145
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -0700146 // TODO: populate user time and system time
147 return new ServerStats
148 {
149 TimeElapsed = secondsElapsed,
150 TimeUser = 0,
151 TimeSystem = 0
152 };
153 }
154
155 /// <summary>
156 /// Asynchronously stops the server.
157 /// </summary>
158 /// <returns>Task that finishes when server has shutdown.</returns>
159 public Task StopAsync()
160 {
161 return server.ShutdownAsync();
162 }
Jan Tattermusch253769e2016-03-21 16:25:59 -0700163 }
Jan Tattermuschd0c1bfa2015-10-22 19:14:57 -0700164}