1+ // Copyright 2012-2013 Octopus Deploy Pty. Ltd.
2+ //
3+ // Licensed under the Apache License, Version 2.0 (the "License");
4+ // you may not use this file except in compliance with the License.
5+ // You may obtain a copy of the License at
6+ //
7+ // http://www.apache.org/licenses/LICENSE-2.0
8+ //
9+ // Unless required by applicable law or agreed to in writing, software
10+ // distributed under the License is distributed on an "AS IS" BASIS,
11+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ // See the License for the specific language governing permissions and
13+ // limitations under the License.
14+
15+ using System ;
16+ using System . Threading ;
17+ using System . Threading . Tasks ;
18+ using FluentAssertions ;
19+ using Halibut . Diagnostics ;
20+ using Halibut . ServiceModel ;
21+ using Halibut . Tests . Support ;
22+ using NUnit . Framework ;
23+
24+ namespace Halibut . Tests
25+ {
26+ public class ClientServerLifecycleTests : BaseTest
27+ {
28+ [ Test ]
29+ public async Task ListeningConfiguration ( )
30+ {
31+ await using var server = RunServer ( out var serverPort ) ;
32+
33+ await using var runtime = CreateRuntimeForListener ( ) ;
34+ var client = CreateClient ( runtime , serverPort ) ;
35+ var result = await client . AddAsync ( 2 , 2 ) ;
36+ result . Should ( ) . Be ( 4 ) ;
37+ }
38+
39+ [ Test ]
40+ public async Task PollingConfiguration ( )
41+ {
42+ await using var server = RunServer ( out var serverPort ) ;
43+ await using var runtime = CreateRuntimeForPoller ( server , out var client ) ;
44+ var result = await client . AddAsync ( 2 , 2 ) ;
45+ result . Should ( ) . Be ( 4 ) ;
46+ }
47+
48+ [ Test ]
49+ public async Task ListeningThenPollingConfiguration ( )
50+ {
51+ // On NET4.8 with SslProtocols.None this will result in SSPI errors
52+ await ListeningConfiguration ( ) ;
53+ await PollingConfiguration ( ) ;
54+ }
55+
56+ HalibutRuntime CreateRuntimeForListener ( )
57+ {
58+ var runtime = new HalibutRuntimeBuilder ( )
59+ . WithServerCertificate ( Certificates . TentacleListening )
60+ . WithLogFactory ( new TestLogFactory ( HalibutLog ) )
61+ . Build ( ) ;
62+ return runtime ;
63+ }
64+
65+ HalibutRuntime CreateRuntimeForPoller ( HalibutRuntime serverRuntime , out IAsyncClientCalculatorService client )
66+ {
67+ var runtime = new HalibutRuntimeBuilder ( )
68+ . WithServerCertificate ( Certificates . TentaclePolling )
69+ . WithLogFactory ( new TestLogFactory ( HalibutLog ) )
70+ . Build ( ) ;
71+ var port = runtime . Listen ( ) ;
72+ runtime . Trust ( Certificates . OctopusPublicThumbprint ) ;
73+
74+ var pollEndpoint = new ServiceEndPoint (
75+ baseUri : new Uri ( $ "https://localhost:{ port } /") ,
76+ remoteThumbprint : Certificates . TentaclePollingPublicThumbprint ,
77+ halibutTimeoutsAndLimits : runtime . TimeoutsAndLimits
78+ )
79+ {
80+ TcpClientConnectTimeout = TimeSpan . FromSeconds ( 5 )
81+ } ;
82+ var pollingUri = new Uri ( "poll://TEST-POLL" ) ;
83+ serverRuntime . Poll ( pollingUri , pollEndpoint , CancellationToken ) ;
84+ var clientEndpoint = new ServiceEndPoint (
85+ baseUri : pollingUri ,
86+ remoteThumbprint : Certificates . OctopusPublicThumbprint ,
87+ halibutTimeoutsAndLimits : runtime . TimeoutsAndLimits
88+ ) ;
89+ client = runtime . CreateAsyncClient < ICalculatorService , IAsyncClientCalculatorService > ( clientEndpoint ) ;
90+
91+ return runtime ;
92+ }
93+
94+ static IAsyncClientCalculatorService CreateClient ( HalibutRuntime runtime , int port )
95+ {
96+ var endpoint = new ServiceEndPoint (
97+ baseUri : $ "https://localhost:{ port } ",
98+ remoteThumbprint : Certificates . OctopusPublicThumbprint ,
99+ halibutTimeoutsAndLimits : runtime . TimeoutsAndLimits
100+ ) ;
101+ var client = runtime
102+ . CreateAsyncClient < ICalculatorService , IAsyncClientCalculatorService > ( endpoint ) ;
103+ return client ;
104+ }
105+
106+ static IServiceFactory CreateServiceFactory ( )
107+ {
108+ var services = new DelegateServiceFactory ( ) ;
109+ services . Register < ICalculatorService , IAsyncCalculatorService > ( ( ) => new AsyncCalculatorService ( ) ) ;
110+ return services ;
111+ }
112+
113+ HalibutRuntime RunServer ( out int port )
114+ {
115+ var services = CreateServiceFactory ( ) ;
116+
117+ var runtime = new HalibutRuntimeBuilder ( )
118+ . WithServerCertificate ( Certificates . Octopus )
119+ . WithServiceFactory ( services )
120+ . WithLogFactory ( new TestLogFactory ( HalibutLog ) )
121+ . Build ( ) ;
122+
123+ runtime . Trust ( Certificates . TentacleListeningPublicThumbprint ) ;
124+ runtime . Trust ( Certificates . TentaclePollingPublicThumbprint ) ;
125+ port = runtime . Listen ( ) ;
126+
127+ return runtime ;
128+ }
129+
130+ public class TestLogFactory : ILogFactory
131+ {
132+ readonly ILog _log ;
133+ public TestLogFactory ( ILog log )
134+ {
135+ _log = log ;
136+ }
137+
138+ public ILog ForEndpoint ( Uri endpoint ) => _log ;
139+
140+ public ILog ForPrefix ( string endPoint ) => _log ;
141+ }
142+
143+ public interface ICalculatorService
144+ {
145+ long Add ( long a , long b ) ;
146+ }
147+
148+ public interface IAsyncCalculatorService
149+ {
150+ Task < long > AddAsync ( long a , long b , CancellationToken cancellationToken ) ;
151+ }
152+
153+ public interface IAsyncClientCalculatorService
154+ {
155+ Task < long > AddAsync ( long a , long b ) ;
156+ }
157+
158+ public class AsyncCalculatorService : IAsyncCalculatorService
159+ {
160+ public async Task < long > AddAsync ( long a , long b , CancellationToken cancellationToken )
161+ {
162+ await Task . CompletedTask ;
163+ return a + b ;
164+ }
165+ }
166+ }
167+ }
0 commit comments