1+ using System ;
2+ using System . IO ;
3+ using System . Linq ;
4+ using System . Net ;
5+ using System . Net . Sockets ;
6+ using DockerComposeFixture . Exceptions ;
7+ using Xunit ;
8+
9+ namespace DockerComposeFixture . Tests ;
10+
11+ public class RequiredPortsIntegrationTests : IClassFixture < DockerFixture > , IDisposable
12+ {
13+ private readonly DockerFixture dockerFixture ;
14+ private readonly string dockerComposeFile ;
15+
16+ private const string DockerCompose = @"
17+ version: '3.4'
18+ services:
19+ echo_server:
20+ image: hashicorp/http-echo
21+ ports:
22+ - 12871:8080
23+ command: -listen=:8080 -text=""hello world""
24+ " ;
25+
26+ public RequiredPortsIntegrationTests ( DockerFixture dockerFixture )
27+ {
28+ this . dockerFixture = dockerFixture ;
29+ this . dockerComposeFile = Path . GetTempFileName ( ) ;
30+ File . WriteAllText ( this . dockerComposeFile , DockerCompose ) ;
31+ }
32+
33+ [ Fact ]
34+ public void Ports_DetermineUtilizedPorts_ReturnsThoseInUse ( )
35+ {
36+ // Arrange
37+ const ushort portToOccupy = 12871 ;
38+ var ipEndPoint = new IPEndPoint ( IPAddress . Loopback , portToOccupy ) ;
39+ using Socket listener = new (
40+ ipEndPoint . AddressFamily ,
41+ SocketType . Stream ,
42+ ProtocolType . Tcp ) ;
43+ listener . Bind ( ipEndPoint ) ;
44+ listener . Listen ( ) ;
45+
46+ // Act
47+ var usedPorts = Ports . DetermineUtilizedPorts ( [ 12870 , 12871 , 12872 ] ) ;
48+
49+ // Assert
50+ Assert . Single ( usedPorts , p => p == 12871 ) ;
51+ }
52+
53+ [ Fact ]
54+ public void GivenRequiredPortInUse_ThenExceptionIsThrownWithPortNumber ( )
55+ {
56+ const ushort portToOccupy = 12871 ;
57+ var ipEndPoint = new IPEndPoint ( IPAddress . Loopback , portToOccupy ) ;
58+ using Socket listener = new (
59+ ipEndPoint . AddressFamily ,
60+ SocketType . Stream ,
61+ ProtocolType . Tcp ) ;
62+ listener . Bind ( ipEndPoint ) ;
63+ listener . Listen ( ) ;
64+
65+ var thrownException = Assert . Throws < PortsUnavailableException > ( ( ) =>
66+ {
67+ dockerFixture . InitOnce ( ( ) => new DockerFixtureOptions
68+ {
69+ DockerComposeFiles = new [ ] { this . dockerComposeFile } ,
70+ CustomUpTest = output => output . Any ( l => l . Contains ( "server is listening" ) ) ,
71+ RequiredPorts = new ushort [ ] { portToOccupy }
72+ } ) ;
73+ } ) ;
74+
75+ Assert . Equivalent ( new ushort [ ] { portToOccupy } , thrownException . Ports ) ;
76+ }
77+
78+ public void Dispose ( )
79+ {
80+ File . Delete ( this . dockerComposeFile ) ;
81+ }
82+ }
0 commit comments