• 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.Collections.Generic;
21 using System.Diagnostics;
22 using System.IO;
23 using System.Linq;
24 using System.Text.RegularExpressions;
25 using System.Threading;
26 using System.Threading.Tasks;
27 using Google.Protobuf;
28 using Grpc.Core;
29 using Grpc.Core.Logging;
30 using Grpc.Core.Utils;
31 using NUnit.Framework;
32 using Grpc.Testing;
33 
34 namespace Grpc.IntegrationTesting
35 {
36     /// <summary>
37     /// Helper methods to start server runners for performance testing.
38     /// </summary>
39     public class ServerRunners
40     {
41         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<ServerRunners>();
42 
43         /// <summary>
44         /// Creates a started server runner.
45         /// </summary>
CreateStarted(ServerConfig config)46         public static IServerRunner CreateStarted(ServerConfig config)
47         {
48             Logger.Debug("ServerConfig: {0}", config);
49             var credentials = config.SecurityParams != null ? TestCredentials.CreateSslServerCredentials() : ServerCredentials.Insecure;
50 
51             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 
64             ServerServiceDefinition service = null;
65             if (config.ServerType == ServerType.AsyncServer)
66             {
67                 GrpcPreconditions.CheckArgument(config.PayloadConfig == null,
68                     "ServerConfig.PayloadConfig shouldn't be set for BenchmarkService based server.");
69                 service = BenchmarkService.BindService(new BenchmarkServiceImpl());
70             }
71             else if (config.ServerType == ServerType.AsyncGenericServer)
72             {
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 
81             var channelOptions = new List<ChannelOption>(config.ChannelArgs.Select((arg) => arg.ToChannelOption()));
82             var server = new Server(channelOptions)
83             {
84                 Services = { service },
85                 Ports = { new ServerPort("[::]", config.Port, credentials) }
86             };
87 
88             server.Start();
89             return new ServerRunnerImpl(server);
90         }
91 
92         private class GenericServiceImpl
93         {
94             readonly byte[] response;
95 
GenericServiceImpl(int responseSize)96             public GenericServiceImpl(int responseSize)
97             {
98                 this.response = new byte[responseSize];
99             }
100 
101             /// <summary>
102             /// Generic streaming call handler.
103             /// </summary>
StreamingCall(IAsyncStreamReader<byte[]> requestStream, IServerStreamWriter<byte[]> responseStream, ServerCallContext context)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         }
112     }
113 
114     /// <summary>
115     /// Server runner.
116     /// </summary>
117     public class ServerRunnerImpl : IServerRunner
118     {
119         readonly Server server;
120         readonly TimeStats timeStats = new TimeStats();
121 
ServerRunnerImpl(Server server)122         public ServerRunnerImpl(Server server)
123         {
124             this.server = GrpcPreconditions.CheckNotNull(server);
125         }
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>
GetStats(bool reset)139         public ServerStats GetStats(bool reset)
140         {
141             var timeSnapshot = timeStats.GetSnapshot(reset);
142 
143             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), timeSnapshot.WallClockTime.TotalSeconds);
145 
146             return new ServerStats
147             {
148                 TimeElapsed = timeSnapshot.WallClockTime.TotalSeconds,
149                 TimeUser = timeSnapshot.UserProcessorTime.TotalSeconds,
150                 TimeSystem = timeSnapshot.PrivilegedProcessorTime.TotalSeconds
151             };
152         }
153 
154         /// <summary>
155         /// Asynchronously stops the server.
156         /// </summary>
157         /// <returns>Task that finishes when server has shutdown.</returns>
StopAsync()158         public Task StopAsync()
159         {
160             return server.ShutdownAsync();
161         }
162     }
163 }
164