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{
15- private static int _port = 20000 ;
16-
17- private readonly CosmosDatabase _database ;
18- private readonly TestcontainersContainer _cosmosContainer ;
21+ private readonly TestcontainersContainer _cosmosTestContainer ;
22+ private CosmosDatabase _database ;
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 ;
1928
2029 public CosmosTestContainer ( )
2130 {
22- var port = ++ _port ;
23-
24- _cosmosContainer = new TestcontainersBuilder < TestcontainersContainer > ( )
25- . WithImage ( "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest" )
26- . WithPortBinding ( port , 8081 )
27- . WithEnvironment ( "AZURE_COSMOS_EMULATOR_PARTITION_COUNT" , "30" )
31+ _cosmosTestContainer = new TestcontainersBuilder < TestcontainersContainer > ( )
32+ . WithImage ( "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator" )
33+ . WithName ( containerName )
34+ . WithExposedPort ( 8081 )
35+ . WithExposedPort ( 10251 )
36+ . WithExposedPort ( 10252 )
37+ . WithExposedPort ( 10253 )
38+ . WithExposedPort ( 10254 )
39+ . WithExposedPort ( 10255 )
40+ . WithPortBinding ( 8081 , 8081 )
41+ . WithPortBinding ( 10251 , 10251 )
42+ . WithPortBinding ( 10252 , 10252 )
43+ . WithPortBinding ( 10253 , 10253 )
44+ . WithPortBinding ( 10254 , 10254 )
45+ . WithPortBinding ( 8081 , 8081 )
46+ . WithEnvironment ( "AZURE_COSMOS_EMULATOR_PARTITION_COUNT" , "1" )
47+ . WithEnvironment ( "AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE" , "127.0.0.1" )
2848 . WithEnvironment ( "AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE" , "false" )
29- . WithWaitStrategy ( Wait . ForUnixContainer ( ) )
49+ . WithCleanUp ( false )
50+ . WithWaitStrategy ( Wait . ForUnixContainer ( )
51+ . UntilPortIsAvailable ( privatePort ) )
3052 . Build ( ) ;
3153
54+ _dockerClient = new DockerClientConfiguration ( ) . CreateClient ( ) ;
55+ }
56+
57+ public IDatabaseCollection < string , TestCosmosItem > Collection =>
58+ _database . GetCollection < TestCosmosItem > ( ) ;
59+
60+ public string GenerateId ( )
61+ {
62+ return $ "{ Guid . NewGuid ( ) : N} ";
63+ }
64+
65+ public async Task InitializeAsync ( )
66+ {
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+
3299 _database = new CosmosDatabase ( new CosmosOptions
33100 {
34101 ConnectionString =
35- $ "AccountEndpoint=https://localhost:{ port } ;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
102+ $ "AccountEndpoint=https://localhost:{ publicPort } / ;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
36103 DatabaseName = "database" ,
37- CollectionName = "testContainer" ,
104+ CollectionName = $ "testContainer",
38105 AllowTableCreation = true ,
39106 CosmosClientOptions = new CosmosClientOptions ( )
40107 {
@@ -51,25 +118,27 @@ public CosmosTestContainer()
51118 ConnectionMode = ConnectionMode . Gateway
52119 } ,
53120 } ) ;
54- }
55121
56- public IDatabaseCollection < string , TestCosmosItem > Collection =>
57- _database . GetCollection < TestCosmosItem > ( ) ;
58-
59- public string GenerateId ( )
60- {
61- return $ "{ Guid . NewGuid ( ) : N} ";
62- }
63122
64- public async Task InitializeAsync ( )
65- {
66- await _cosmosContainer . StartAsync ( ) ;
67123 await _database . InitializeAsync ( ) ;
68124 }
69125
70126 public async Task DisposeAsync ( )
71127 {
128+ // await _database.DeleteAsync();
72129 await _database . DisposeAsync ( ) ;
73- await _cosmosContainer . StopAsync ( ) ;
130+
131+ /* _testOutputHelper.WriteLine($"Cosmos container State:{_cosmosContainer.State}");
132+ _testOutputHelper.WriteLine("=STOP=");*/
133+ }
134+
135+ public async void Dispose ( )
136+ {
137+
138+ await _dockerClient . Containers . RemoveContainerAsync ( containerId ,
139+ new ContainerRemoveParameters
140+ {
141+ Force = true
142+ } ) ;
74143 }
75- }
144+ }
0 commit comments