@@ -11,6 +11,12 @@ public class HealthCheckTests : IDisposable
1111 private SmtpServer ? _smtpServer ;
1212 private HealthCheckService ? _healthCheckService ;
1313 private readonly HttpClient _httpClient = new ( ) ;
14+ private static int _portCounter = 40000 ; // Starting port for tests
15+
16+ private static int GetNextPort ( )
17+ {
18+ return Interlocked . Increment ( ref _portCounter ) ;
19+ }
1420
1521 public void Dispose ( )
1622 {
@@ -25,18 +31,19 @@ public async Task HealthCheck_WhenServerIsRunning_ReturnsHealthy()
2531 // Arrange
2632 SmtpServerConfiguration config = new ( )
2733 {
28- Port = new Random ( ) . Next ( 50000 , 65536 ) , // Random port
34+ Port = GetNextPort ( ) ,
2935 ServerName = "Test SMTP Server"
3036 } ;
3137 _smtpServer = new SmtpServer ( config ) ;
3238 await _smtpServer . StartAsync ( ) ;
3339
34- _healthCheckService = _smtpServer . EnableHealthCheck ( 8181 ) ;
40+ int healthCheckPort = GetNextPort ( ) ;
41+ _healthCheckService = _smtpServer . EnableHealthCheck ( healthCheckPort ) ;
3542 await _healthCheckService . StartAsync ( ) ;
3643
3744 // Act
3845 await Task . Delay ( 500 ) ; // Give the service time to start
39- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8181 /health/" ) ;
46+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
4047 string content = await response . Content . ReadAsStringAsync ( ) ;
4148
4249 // Parse JSON response
@@ -57,17 +64,18 @@ public async Task HealthCheck_WhenServerIsStopped_ReturnsUnhealthy()
5764 // Arrange
5865 SmtpServerConfiguration config = new ( )
5966 {
60- Port = new Random ( ) . Next ( 50000 , 65536 ) ,
67+ Port = GetNextPort ( ) ,
6168 ServerName = "Test SMTP Server"
6269 } ;
6370 _smtpServer = new SmtpServer ( config ) ;
6471
65- _healthCheckService = _smtpServer . EnableHealthCheck ( 8182 ) ;
72+ int healthCheckPort = GetNextPort ( ) ;
73+ _healthCheckService = _smtpServer . EnableHealthCheck ( healthCheckPort ) ;
6674 await _healthCheckService . StartAsync ( ) ;
6775
6876 // Act
6977 await Task . Delay ( 500 ) ;
70- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8182 /health/" ) ;
78+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
7179
7280 // Assert
7381 Assert . Equal ( HttpStatusCode . ServiceUnavailable , response . StatusCode ) ;
@@ -82,14 +90,15 @@ public async Task HealthCheck_WhenServerIsStopped_ReturnsUnhealthy()
8290 public async Task LivenessCheck_AlwaysReturnsOK ( )
8391 {
8492 // Arrange
85- SmtpServerConfiguration config = new ( ) { Port = new Random ( ) . Next ( 50000 , 65536 ) } ;
93+ SmtpServerConfiguration config = new ( ) { Port = GetNextPort ( ) } ;
8694 _smtpServer = new SmtpServer ( config ) ;
87- _healthCheckService = _smtpServer . EnableHealthCheck ( 8183 ) ;
95+ int healthCheckPort = GetNextPort ( ) ;
96+ _healthCheckService = _smtpServer . EnableHealthCheck ( healthCheckPort ) ;
8897 await _healthCheckService . StartAsync ( ) ;
8998
9099 // Act
91100 await Task . Delay ( 500 ) ;
92- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8183 /health/livez" ) ;
101+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/livez") ;
93102
94103 // Assert
95104 Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
@@ -104,11 +113,12 @@ public async Task LivenessCheck_AlwaysReturnsOK()
104113 public async Task CustomHealthCheck_CanBeAdded ( )
105114 {
106115 // Arrange
107- SmtpServerConfiguration config = new ( ) { Port = new Random ( ) . Next ( 50000 , 65536 ) } ;
116+ SmtpServerConfiguration config = new ( ) { Port = GetNextPort ( ) } ;
108117 _smtpServer = new SmtpServer ( config ) ;
109118 await _smtpServer . StartAsync ( ) ;
110119
111- _healthCheckService = _smtpServer . EnableHealthCheck ( 8184 ) ;
120+ int healthCheckPort = GetNextPort ( ) ;
121+ _healthCheckService = _smtpServer . EnableHealthCheck ( healthCheckPort ) ;
112122
113123 // Add custom health check
114124 _healthCheckService . AddHealthCheck ( "custom_check" , async ( ct ) =>
@@ -125,7 +135,7 @@ public async Task CustomHealthCheck_CanBeAdded()
125135
126136 // Act
127137 await Task . Delay ( 500 ) ;
128- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8184 /health/" ) ;
138+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
129139 string content = await response . Content . ReadAsStringAsync ( ) ;
130140
131141 // Parse JSON response
@@ -146,20 +156,22 @@ public async Task HealthCheck_IncludesServerMetrics()
146156 // Arrange
147157 SmtpServerConfiguration config = new ( )
148158 {
149- Port = new Random ( ) . Next ( 50000 , 65536 ) ,
159+ Port = GetNextPort ( ) ,
150160 MaxConnections = 100 ,
151161 MaxMessageSize = 10485760 , // 10MB
152- RequireAuthentication = true
162+ RequireAuthentication = true ,
163+ AllowPlainTextAuthentication = true // Fix: Allow plain text auth without secure connection
153164 } ;
154165 _smtpServer = new SmtpServer ( config ) ;
155166 await _smtpServer . StartAsync ( ) ;
156167
157- _healthCheckService = _smtpServer . EnableHealthCheck ( 8185 ) ;
168+ int healthCheckPort = GetNextPort ( ) ; // Use incremental port to avoid conflicts
169+ _healthCheckService = _smtpServer . EnableHealthCheck ( healthCheckPort ) ;
158170 await _healthCheckService . StartAsync ( ) ;
159171
160172 // Act
161173 await Task . Delay ( 500 ) ;
162- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8185 /health/" ) ;
174+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
163175 string content = await response . Content . ReadAsStringAsync ( ) ;
164176
165177 // Parse JSON response
@@ -183,72 +195,79 @@ public async Task HealthCheck_IncludesServerMetrics()
183195 public async Task StartWithHealthCheck_StartsSmtpServerAndHealthCheck ( )
184196 {
185197 // Arrange
186- SmtpServerConfiguration config = new ( ) { Port = new Random ( ) . Next ( 50000 , 65536 ) } ;
198+ SmtpServerConfiguration config = new ( )
199+ {
200+ Port = GetNextPort ( )
201+ } ;
187202 _smtpServer = new SmtpServer ( config ) ;
188203
189204 // Act
190- _healthCheckService = await _smtpServer . StartWithHealthCheckAsync ( 8186 ) ;
205+ int healthCheckPort = GetNextPort ( ) ;
206+ _healthCheckService = await _smtpServer . StartWithHealthCheckAsync ( healthCheckPort ) ;
191207
192208 // Assert
193209 Assert . True ( _smtpServer . IsRunning ) ;
194210 Assert . True ( _healthCheckService . IsRunning ) ;
195211
196212 // Verify health endpoint
197213 await Task . Delay ( 500 ) ;
198- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8186 /health/" ) ;
214+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
199215 Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
200216 }
201217
202218 [ Fact ]
203219 public async Task HealthCheck_WithIPBinding_Works ( )
204220 {
205221 // Arrange
206- SmtpServerConfiguration config = new ( ) { Port = new Random ( ) . Next ( 50000 , 65536 ) } ;
222+ SmtpServerConfiguration config = new ( ) { Port = GetNextPort ( ) } ;
207223 _smtpServer = new SmtpServer ( config ) ;
208224 await _smtpServer . StartAsync ( ) ;
209225
210226 // Act - Bind to specific IP
211227 IPAddress ipAddress = IPAddress . Loopback ;
212- _healthCheckService = _smtpServer . EnableHealthCheck ( ipAddress , 8188 ) ;
228+ int healthCheckPort = GetNextPort ( ) ;
229+ _healthCheckService = _smtpServer . EnableHealthCheck ( ipAddress , healthCheckPort ) ;
213230 await _healthCheckService . StartAsync ( ) ;
214231
215232 // Assert
216233 Assert . True ( _healthCheckService . IsRunning ) ;
217234
218235 await Task . Delay ( 500 ) ;
219- HttpResponseMessage response = await _httpClient . GetAsync ( "http://127.0.0.1:8188 /health/" ) ;
236+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://127.0.0.1:{ healthCheckPort } /health/") ;
220237 Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
221238 }
222239
223240 [ Fact ]
224241 public async Task HealthCheck_WithHostnameBinding_Works ( )
225242 {
226243 // Arrange
227- SmtpServerConfiguration config = new ( ) { Port = new Random ( ) . Next ( 50000 , 65536 ) } ;
244+ SmtpServerConfiguration config = new ( ) { Port = GetNextPort ( ) } ;
228245 _smtpServer = new SmtpServer ( config ) ;
229246 await _smtpServer . StartAsync ( ) ;
230247
231248 // Act - Bind to hostname
232- _healthCheckService = _smtpServer . EnableHealthCheck ( "localhost" , 8189 ) ;
249+ int healthCheckPort = GetNextPort ( ) ;
250+ _healthCheckService = _smtpServer . EnableHealthCheck ( "localhost" , healthCheckPort ) ;
233251 await _healthCheckService . StartAsync ( ) ;
234252
235253 // Assert
236254 Assert . True ( _healthCheckService . IsRunning ) ;
237255
238256 await Task . Delay ( 500 ) ;
239- HttpResponseMessage response = await _httpClient . GetAsync ( "http://localhost:8189 /health/" ) ;
257+ HttpResponseMessage response = await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
240258 Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
241259 }
242260
243261 [ Fact ]
244262 public async Task HealthCheckService_CanBeStopped ( )
245263 {
246264 // Arrange
247- SmtpServerConfiguration config = new ( ) { Port = new Random ( ) . Next ( 50000 , 65536 ) } ;
265+ SmtpServerConfiguration config = new ( ) { Port = GetNextPort ( ) } ;
248266 _smtpServer = new SmtpServer ( config ) ;
249267 await _smtpServer . StartAsync ( ) ;
250268
251- _healthCheckService = _smtpServer . EnableHealthCheck ( 8187 ) ;
269+ int healthCheckPort = GetNextPort ( ) ;
270+ _healthCheckService = _smtpServer . EnableHealthCheck ( healthCheckPort ) ;
252271 await _healthCheckService . StartAsync ( ) ;
253272
254273 await Task . Delay ( 500 ) ;
@@ -262,7 +281,7 @@ public async Task HealthCheckService_CanBeStopped()
262281 // Should not be able to connect
263282 await Assert . ThrowsAsync < HttpRequestException > ( async ( ) =>
264283 {
265- await _httpClient . GetAsync ( "http://localhost:8187 /health/" ) ;
284+ await _httpClient . GetAsync ( $ "http://localhost:{ healthCheckPort } /health/") ;
266285 } ) ;
267286 }
268287 }
0 commit comments