11using System ;
2+ using System . Linq ;
23using System . Net . Http ;
34using System . Threading . Tasks ;
5+ using Docker . DotNet ;
6+ using Docker . DotNet . Models ;
47using DotNet . Testcontainers . Builders ;
58using DotNet . Testcontainers . Containers ;
69using ManagedCode . Database . Core ;
710using ManagedCode . Database . Cosmos ;
811using ManagedCode . Database . Tests . Common ;
912using Microsoft . Azure . Cosmos ;
13+ using Xunit ;
1014
1115namespace ManagedCode . Database . Tests . TestContainers ;
1216
13- public class CosmosTestContainer : ITestContainer < string , TestCosmosItem >
17+ [ CollectionDefinition ( nameof ( CosmosTestContainer ) ) ]
18+ public class CosmosTestContainer : ITestContainer < string , TestCosmosItem > ,
19+ ICollectionFixture < CosmosTestContainer > , IDisposable
1420{
21+ private readonly TestcontainersContainer _cosmosTestContainer ;
1522 private CosmosDatabase _database ;
16- private readonly TestcontainersContainer _cosmosContainer ;
23+ private DockerClient _dockerClient ;
24+ private const string containerName = "cosmosContainer" ;
25+ private const ushort privatePort = 8081 ;
26+ private bool containerExsist = false ;
27+ private string containerId ;
1728
1829 public CosmosTestContainer ( )
1930 {
20- // Docker container for cosmos db is not working at all, to test database use local windows emulator
21- _cosmosContainer = new TestcontainersBuilder < TestcontainersContainer > ( )
31+ _cosmosTestContainer = new TestcontainersBuilder < TestcontainersContainer > ( )
2232 . WithImage ( "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator" )
23- . WithName ( $ "azure-cosmos-emulator{ Guid . NewGuid ( ) . ToString ( "N" ) } ")
24- // .WithExposedPort(8081)
25- // .WithExposedPort(10250)
26- // .WithExposedPort(10251)
27- // .WithExposedPort(10252)
28- // .WithExposedPort(10253)
29- // .WithExposedPort(10254)
30- // .WithExposedPort(10255)
33+ . WithName ( containerName )
3134 . WithExposedPort ( 8081 )
35+ . WithExposedPort ( 10251 )
36+ . WithExposedPort ( 10252 )
37+ . WithExposedPort ( 10253 )
38+ . WithExposedPort ( 10254 )
39+ . WithExposedPort ( 10255 )
3240 . WithPortBinding ( 8081 , 8081 )
33- . WithPortBinding ( 10250 , 10250 )
3441 . WithPortBinding ( 10251 , 10251 )
3542 . WithPortBinding ( 10252 , 10252 )
3643 . WithPortBinding ( 10253 , 10253 )
3744 . WithPortBinding ( 10254 , 10254 )
38- . WithPortBinding ( 10255 , 10255 )
45+ . WithPortBinding ( 8081 , 8081 )
3946 . WithEnvironment ( "AZURE_COSMOS_EMULATOR_PARTITION_COUNT" , "1" )
4047 . WithEnvironment ( "AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE" , "127.0.0.1" )
4148 . WithEnvironment ( "AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE" , "false" )
42- // .WithCleanUp(true )
49+ . WithCleanUp ( false )
4350 . WithWaitStrategy ( Wait . ForUnixContainer ( )
44- . UntilPortIsAvailable ( 8081 ) )
51+ . UntilPortIsAvailable ( privatePort ) )
4552 . Build ( ) ;
53+
54+ _dockerClient = new DockerClientConfiguration ( ) . CreateClient ( ) ;
4655 }
4756
4857 public IDatabaseCollection < string , TestCosmosItem > Collection =>
@@ -55,28 +64,56 @@ public string GenerateId()
5564
5665 public async Task InitializeAsync ( )
5766 {
58- await _cosmosContainer . StartAsync ( ) ;
59- Console . WriteLine ( $ "Cosmos container State:{ _cosmosContainer . State } ") ;
67+ ushort publicPort = privatePort ;
68+
69+ try
70+ {
71+ await _cosmosTestContainer . StartAsync ( ) ;
72+
73+ containerExsist = false ;
74+ }
75+ catch ( Exception ex ) //TODO catch name already using exception
76+ {
77+ containerExsist = true ;
78+ }
79+
80+ if ( ! containerExsist )
81+ {
82+ publicPort = _cosmosTestContainer . GetMappedPublicPort ( privatePort ) ;
83+ containerId = _cosmosTestContainer . Id ;
84+ }
85+ else
86+ {
87+ var listContainers = await _dockerClient . Containers . ListContainersAsync ( new ContainersListParameters ( ) ) ;
88+
89+ ContainerListResponse containerListResponse = listContainers . FirstOrDefault ( container => container . Names . Contains ( $ "/{ containerName } ") ) ;
90+
91+ if ( containerListResponse != null )
92+ {
93+ publicPort = containerListResponse . Ports . Single ( port => port . PrivatePort == privatePort ) . PublicPort ;
94+
95+ containerId = containerListResponse . ID ;
96+ }
97+ }
98+
99+ var httpMessageHandler = new HttpClientHandler ( )
100+ {
101+ ServerCertificateCustomValidationCallback = HttpClientHandler . DangerousAcceptAnyServerCertificateValidator
102+ } ;
103+
104+
60105 _database = new CosmosDatabase ( new CosmosOptions
61106 {
62107 ConnectionString =
63- $ "AccountEndpoint=https://localhost:{ _cosmosContainer . GetMappedPublicPort ( 8081 ) } /;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
108+ $ "AccountEndpoint=https://localhost:{ publicPort } /;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
64109 DatabaseName = "database" ,
65- CollectionName = "testContainer" ,
110+ CollectionName = $ "testContainer",
66111 AllowTableCreation = true ,
67112 CosmosClientOptions = new CosmosClientOptions ( )
68113 {
69- HttpClientFactory = ( ) =>
70- {
71- HttpMessageHandler httpMessageHandler = new HttpClientHandler ( )
72- {
73- ServerCertificateCustomValidationCallback = ( _ , _ , _ , _ ) => true
74- } ;
75-
76- return new HttpClient ( httpMessageHandler ) ;
77- } ,
114+ HttpClientFactory = ( ) => new HttpClient ( httpMessageHandler ) ,
78115 ConnectionMode = ConnectionMode . Gateway ,
79- RequestTimeout = TimeSpan . FromMinutes ( 3 )
116+ // RequestTimeout = TimeSpan.FromMinutes(3)
80117 } ,
81118 } ) ;
82119
@@ -86,9 +123,20 @@ public async Task InitializeAsync()
86123
87124 public async Task DisposeAsync ( )
88125 {
126+ // await _database.DeleteAsync();
89127 await _database . DisposeAsync ( ) ;
90- await _cosmosContainer . StopAsync ( ) ;
91- await _cosmosContainer . CleanUpAsync ( ) ;
92- Console . WriteLine ( $ "Cosmos container State:{ _cosmosContainer . State } ") ;
128+
129+ /* _testOutputHelper.WriteLine($"Cosmos container State:{_cosmosContainer.State}");
130+ _testOutputHelper.WriteLine("=STOP=");*/
131+ }
132+
133+ public async void Dispose ( )
134+ {
135+
136+ await _dockerClient . Containers . RemoveContainerAsync ( containerId ,
137+ new ContainerRemoveParameters
138+ {
139+ Force = true
140+ } ) ;
93141 }
94- }
142+ }
0 commit comments