-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathSecureClientFixture.cs
More file actions
96 lines (84 loc) · 4.09 KB
/
SecureClientFixture.cs
File metadata and controls
96 lines (84 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Halibut.Diagnostics;
using Halibut.ServiceModel;
using Halibut.Tests.Support;
using Halibut.Tests.Support.TestAttributes;
using Halibut.TestUtils.Contracts;
using Halibut.Transport;
using Halibut.Transport.Protocol;
using NSubstitute;
using NUnit.Framework;
namespace Halibut.Tests.Transport
{
public class SecureClientFixture : IDisposable
{
ServiceEndPoint endpoint;
HalibutRuntime tentacle;
ILog log;
ClientCertificateValidatorFactory clientCertificateValidatorFactory;
[SetUp]
public void SetUp()
{
var services = new DelegateServiceFactory();
services.Register<IEchoService>(() => new EchoService());
tentacle = new HalibutRuntime(services, Certificates.TentacleListening);
clientCertificateValidatorFactory = new ClientCertificateValidatorFactory();
var tentaclePort = tentacle.Listen();
tentacle.Trust(Certificates.OctopusPublicThumbprint);
endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint)
{
ConnectionErrorRetryTimeout = TimeSpan.MaxValue
};
log = new InMemoryConnectionLog(endpoint.ToString());
}
public void Dispose()
{
tentacle.Dispose();
}
[Test]
[SyncAndAsync]
public async Task SecureClientClearsPoolWhenAllConnectionsCorrupt(SyncOrAsync syncOrAsync)
{
var connectionManager = new ConnectionManager();
var stream = Substitute.For<IMessageExchangeStream>();
syncOrAsync
.WhenSync(() => stream.When(x => x.IdentifyAsClient()).Do(x => throw new ConnectionInitializationFailedException("")))
.WhenAsync(() => stream.IdentifyAsClientAsync(Arg.Any<CancellationToken>()).Returns(Task.FromException(new ConnectionInitializationFailedException(""))));
for (int i = 0; i < HalibutLimits.RetryCountLimit; i++)
{
var connection = Substitute.For<IConnection>();
connection.Protocol.Returns(new MessageExchangeProtocol(stream, log));
connectionManager.ReleaseConnection(endpoint, connection);
}
var request = new RequestMessage
{
Destination = endpoint,
ServiceName = "IEchoService",
MethodName = "SayHello",
Params = new object[] { "Fred" }
};
var secureClient = new SecureListeningClient((s, l) => GetProtocol(s, l, syncOrAsync), endpoint, Certificates.Octopus, log, connectionManager, clientCertificateValidatorFactory);
ResponseMessage response = null!;
using var requestCancellationTokens = new RequestCancellationTokens(CancellationToken.None, CancellationToken.None);
#pragma warning disable CS0612
await syncOrAsync
.WhenSync(() => secureClient.ExecuteTransaction((mep) => response = mep.ExchangeAsClient(request), CancellationToken.None))
.WhenAsync(async () => await secureClient.ExecuteTransactionAsync(async (mep, ct) => response = await mep.ExchangeAsClientAsync(request, ct), requestCancellationTokens));
#pragma warning restore CS0612
// The pool should be cleared after the second failure
await syncOrAsync
.WhenSync(() => stream.Received(2).IdentifyAsClient())
.WhenAsync(async () => await stream.Received(2).IdentifyAsClientAsync(Arg.Any<CancellationToken>()));
// And a new valid connection should then be made
response.Result.Should().Be("Fred...");
}
public MessageExchangeProtocol GetProtocol(Stream stream, ILog logger, SyncOrAsync syncOrAsync)
{
return new MessageExchangeProtocol(new MessageExchangeStream(stream, new MessageSerializerBuilder().Build(), syncOrAsync.ToAsyncHalibutFeature(), logger), logger);
}
}
}