Skip to content

Commit 49ae44d

Browse files
committed
Add perf testing and service develop with corewcf
1 parent 0ec7243 commit 49ae44d

File tree

10 files changed

+965
-0
lines changed

10 files changed

+965
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.3.32714.290
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WCFCorePerfService", "WCFCorePerfService\WCFCorePerfService.csproj", "{35B05C6A-9FF0-4A9C-9BBE-E88963416022}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WCFCorePerfClient", "WCFCorePerfClient\WCFCorePerfClient.csproj", "{D9001454-F77C-4053-B4AE-34342351FD49}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{D9001454-F77C-4053-B4AE-34342351FD49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{D9001454-F77C-4053-B4AE-34342351FD49}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{D9001454-F77C-4053-B4AE-34342351FD49}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{D9001454-F77C-4053-B4AE-34342351FD49}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {BD5D3AEC-A9AB-412C-A41B-A410030B454A}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.ServiceModel;
2+
using System.Threading.Tasks;
3+
4+
namespace WCFCorePerfClient
5+
{
6+
[ServiceContract]
7+
public interface ISayHello
8+
{
9+
[OperationContract]
10+
Task<string> HelloAsync(string name);
11+
}
12+
}
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
using Microsoft.Crank.EventSources;
2+
using System;
3+
using System.Diagnostics;
4+
using System.Security.Cryptography.X509Certificates;
5+
using System.ServiceModel;
6+
using System.ServiceModel.Security;
7+
8+
namespace WCFCorePerfClient
9+
{
10+
public class Parameters
11+
{
12+
public const string Binding = "binding";
13+
public const string ServiceUrl = "serviceurl";
14+
public const string TransferMode = "transfermode";
15+
public const string ReportingUrl = "reportingurl";
16+
public const string PerfMeasurementDuration = "perfmeasurementduration";
17+
}
18+
19+
public enum TestBinding { BasicHttp, WSHttp, NetTcp }
20+
21+
class Program
22+
{
23+
private TestBinding _paramBinding = TestBinding.BasicHttp;
24+
private TimeSpan _paramPerfMeasurementDuration = s_defaultPerfMeasurementDuration;
25+
private string _paramServiceUrl = "";
26+
private readonly static TimeSpan s_defaultPerfMeasurementDuration = TimeSpan.FromSeconds(10);
27+
private string _paramTransferMode = "Buffered";
28+
29+
static void Main(string[] args)
30+
{
31+
Console.WriteLine("WCFCorePerf Client.");
32+
33+
Program test = new Program();
34+
35+
if (test.ProcessRunOptions(args))
36+
{
37+
var startTime = DateTime.Now;
38+
int request = 0;
39+
40+
BenchmarksEventSource.Register("wcfcoreperf/channelopen", Operations.Max, Operations.Max, "Channel Open Time (ms)", "Time to Open Channel in ms", "n0");
41+
BenchmarksEventSource.Register("wcfcoreperf/firstrequest", Operations.Max, Operations.Max, "First Request (ms)", "Time to first request in ms", "n0");
42+
BenchmarksEventSource.Register("wcfcoreperf/requests", Operations.Max, Operations.Sum, "Requests (" + test._paramPerfMeasurementDuration.TotalMilliseconds + " ms)", "Total number of requests", "n0");
43+
BenchmarksEventSource.Register("wcfcoreperf/rps/max", Operations.Max, Operations.Sum, "Requests/sec (max)", "Max requests per second", "n0");
44+
45+
switch (test._paramBinding)
46+
{
47+
case TestBinding.BasicHttp:
48+
BasicHttpBinding binding = new BasicHttpBinding();
49+
switch (test._paramTransferMode.ToLower())
50+
{
51+
case "buffered":
52+
binding.TransferMode = TransferMode.Buffered;
53+
break;
54+
case "streamed":
55+
binding.TransferMode = TransferMode.Streamed;
56+
break;
57+
case "streamedrequest":
58+
binding.TransferMode = TransferMode.StreamedRequest;
59+
break;
60+
case "streamedresponse":
61+
binding.TransferMode = TransferMode.StreamedResponse;
62+
break;
63+
default:
64+
break;
65+
}
66+
67+
Console.WriteLine($"Testing TransferMode: {binding.TransferMode}");
68+
ChannelFactory<ISayHello> factory = new ChannelFactory<ISayHello>(binding, new EndpointAddress(test._paramServiceUrl));
69+
var stopwatchChannelOpen = new Stopwatch();
70+
stopwatchChannelOpen.Start();
71+
factory.Open();
72+
BenchmarksEventSource.Measure("wcfcoreperf/channelopen", stopwatchChannelOpen.ElapsedMilliseconds);
73+
74+
var client = factory.CreateChannel();
75+
var stopwatchFirstReq = new Stopwatch();
76+
stopwatchFirstReq.Start();
77+
var result = client.HelloAsync("helloworld").Result;
78+
BenchmarksEventSource.Measure("wcfcoreperf/firstrequest", stopwatchFirstReq.ElapsedMilliseconds);
79+
80+
while (DateTime.Now <= startTime.Add(test._paramPerfMeasurementDuration))
81+
{
82+
var rtnResult = client.HelloAsync("helloworld").Result;
83+
request++;
84+
}
85+
86+
BenchmarksEventSource.Measure("wcfcoreperf/requests", request);
87+
BenchmarksEventSource.Measure("wcfcoreperf/rps/max", request / test._paramPerfMeasurementDuration.TotalSeconds);
88+
break;
89+
case TestBinding.WSHttp:
90+
WSHttpBinding wsHttpBinding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
91+
wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
92+
ChannelFactory<ISayHello> wsHttpFactory = new ChannelFactory<ISayHello>(wsHttpBinding, new EndpointAddress(test._paramServiceUrl));
93+
wsHttpFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
94+
{
95+
CertificateValidationMode = X509CertificateValidationMode.None,
96+
RevocationMode = X509RevocationMode.NoCheck
97+
};
98+
wsHttpFactory.Credentials.UserName.UserName = "abc";
99+
wsHttpFactory.Credentials.UserName.Password = "[PLACEHOLDER]";
100+
101+
var stopwatchWSHttpChannelOpen = new Stopwatch();
102+
stopwatchWSHttpChannelOpen.Start();
103+
wsHttpFactory.Open();
104+
BenchmarksEventSource.Measure("wcfcoreperf/channelopen", stopwatchWSHttpChannelOpen.ElapsedMilliseconds);
105+
106+
var clientWSHttp = wsHttpFactory.CreateChannel();
107+
var stopwatchWSHttpFirstReq = new Stopwatch();
108+
stopwatchWSHttpFirstReq.Start();
109+
Console.WriteLine(clientWSHttp.HelloAsync("helloworld").Result);
110+
BenchmarksEventSource.Measure("wcfcoreperf/firstrequest", stopwatchWSHttpFirstReq.ElapsedMilliseconds);
111+
112+
while (DateTime.Now <= startTime.Add(test._paramPerfMeasurementDuration))
113+
{
114+
var rtnResult = clientWSHttp.HelloAsync("helloworld").Result;
115+
request++;
116+
}
117+
118+
BenchmarksEventSource.Measure("wcfcoreperf/requests", request);
119+
BenchmarksEventSource.Measure("wcfcoreperf/rps/max", request / test._paramPerfMeasurementDuration.TotalSeconds);
120+
break;
121+
case TestBinding.NetTcp:
122+
NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None);
123+
ChannelFactory<ISayHello> netTcpFactory = new ChannelFactory<ISayHello>(netTcpBinding, new EndpointAddress(test._paramServiceUrl));
124+
125+
var stopwatchNetTcpChannelOpen = new Stopwatch();
126+
stopwatchNetTcpChannelOpen.Start();
127+
netTcpFactory.Open();
128+
BenchmarksEventSource.Measure("wcfcoreperf/channelopen", stopwatchNetTcpChannelOpen.ElapsedMilliseconds);
129+
130+
var clientNetTcp = netTcpFactory.CreateChannel();
131+
var stopwatchNetTcpFirstReq = new Stopwatch();
132+
stopwatchNetTcpFirstReq.Start();
133+
var netTcpResult = clientNetTcp.HelloAsync("helloworld").Result;
134+
BenchmarksEventSource.Measure("wcfcoreperf/firstrequest", stopwatchNetTcpFirstReq.ElapsedMilliseconds);
135+
136+
while (DateTime.Now <= startTime.Add(test._paramPerfMeasurementDuration))
137+
{
138+
var rtnResult = clientNetTcp.HelloAsync("helloworld").Result;
139+
request++;
140+
}
141+
142+
BenchmarksEventSource.Measure("wcfcoreperf/requests", request);
143+
BenchmarksEventSource.Measure("wcfcoreperf/rps/max", request / test._paramPerfMeasurementDuration.TotalSeconds);
144+
break;
145+
}
146+
}
147+
}
148+
149+
private bool ProcessRunOptions(string[] args)
150+
{
151+
foreach (string s in args)
152+
{
153+
Console.WriteLine(s);
154+
string[] p = s.Split(new char[] { ':' }, count: 2);
155+
if (p.Length != 2)
156+
{
157+
continue;
158+
}
159+
160+
switch (p[0].ToLower())
161+
{
162+
case Parameters.Binding:
163+
if (!Enum.TryParse<TestBinding>(p[1], ignoreCase: true, result: out _paramBinding))
164+
{
165+
return ReportWrongArgument(s);
166+
}
167+
break;
168+
169+
case Parameters.PerfMeasurementDuration:
170+
int perfPerfMeasurementDurationSeconds = 0;
171+
if (!Int32.TryParse(p[1], out perfPerfMeasurementDurationSeconds))
172+
{
173+
return ReportWrongArgument(s);
174+
}
175+
_paramPerfMeasurementDuration = TimeSpan.FromSeconds(perfPerfMeasurementDurationSeconds);
176+
break;
177+
178+
case Parameters.ServiceUrl:
179+
_paramServiceUrl = p[1];
180+
break;
181+
182+
case Parameters.TransferMode:
183+
_paramTransferMode = p[1];
184+
break;
185+
default:
186+
Console.WriteLine("unknown argument: " + s);
187+
continue;
188+
}
189+
}
190+
191+
return true;
192+
}
193+
194+
private bool ReportWrongArgument(string arg)
195+
{
196+
Console.WriteLine("Wrong parameter: " + arg);
197+
return false;
198+
}
199+
}
200+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.Crank.EventSources" Version="0.2.0-alpha.22228.2" />
10+
<PackageReference Include="System.ServiceModel.Duplex" Version="4.9.0" />
11+
<PackageReference Include="System.ServiceModel.Http" Version="4.9.0" />
12+
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.9.0" />
13+
<PackageReference Include="System.ServiceModel.Security" Version="4.9.0" />
14+
</ItemGroup>
15+
16+
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using CoreWCF;
2+
using System.Threading.Tasks;
3+
4+
namespace WCFCorePerfService
5+
{
6+
[ServiceContract]
7+
public interface ISayHello
8+
{
9+
[OperationContract]
10+
Task<string> HelloAsync(string name);
11+
}
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using CoreWCF.IdentityModel.Selectors;
2+
using System;
3+
using System.Threading.Tasks;
4+
5+
namespace WCFCorePerfService
6+
{
7+
public class MyCustomValidator : UserNamePasswordValidator
8+
{
9+
public override ValueTask ValidateAsync(string userName, string password)
10+
{
11+
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
12+
{
13+
return new ValueTask(Task.CompletedTask);
14+
}
15+
return new ValueTask(Task.FromException(new Exception("username and password cannot be empty")));
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)