@@ -65,7 +65,7 @@ public MongoDbBuilder WithPassword(string password)
6565 }
6666
6767 /// <summary>
68- /// Initialize MongoDB as a single-node replica set.
68+ /// Initializes MongoDB as a single-node replica set.
6969 /// </summary>
7070 /// <param name="replicaSetName">The replica set name.</param>
7171 /// <returns>A configured instance of <see cref="MongoDbBuilder" />.</returns>
@@ -97,7 +97,7 @@ public override MongoDbContainer Build()
9797 }
9898 else
9999 {
100- waitUntil = new WaitInitiateReplicaSet ( DockerResourceConfiguration ) ;
100+ waitUntil = new WaitInitiateReplicaSet ( ) ;
101101 }
102102
103103 // If the user does not provide a custom waiting strategy, append the default MongoDb waiting strategy.
@@ -112,7 +112,8 @@ protected override MongoDbBuilder Init()
112112 . WithImage ( MongoDbImage )
113113 . WithPortBinding ( MongoDbPort , true )
114114 . WithUsername ( DefaultUsername )
115- . WithPassword ( DefaultPassword ) ;
115+ . WithPassword ( DefaultPassword )
116+ . WithStartupCallback ( InitiateReplicaSetAsync ) ;
116117 }
117118
118119 /// <inheritdoc />
@@ -150,6 +151,34 @@ protected override MongoDbBuilder Merge(MongoDbConfiguration oldValue, MongoDbCo
150151 return new MongoDbBuilder ( new MongoDbConfiguration ( oldValue , newValue ) ) ;
151152 }
152153
154+ /// <summary>
155+ /// Initiates the MongoDB replica set.
156+ /// </summary>
157+ /// <param name="container">The container instance.</param>
158+ /// <param name="configuration">The container configuration.</param>
159+ /// <param name="ct">Cancellation token.</param>
160+ /// <returns>Task that completes when the replica set initiation has been executed.</returns>
161+ private async Task InitiateReplicaSetAsync ( MongoDbContainer container , MongoDbConfiguration configuration , CancellationToken ct )
162+ {
163+ if ( string . IsNullOrEmpty ( configuration . ReplicaSetName ) )
164+ {
165+ return ;
166+ }
167+
168+ var scriptContent = $ "var r=rs.initiate({{_id:\" { configuration . ReplicaSetName } \" ,members:[{{_id:0,host:\" 127.0.0.1:27017\" }}]}});quit(r.ok===1?0:1);";
169+
170+ var initiate = async ( ) =>
171+ {
172+ var execResult = await container . ExecScriptAsync ( scriptContent , ct )
173+ . ConfigureAwait ( false ) ;
174+
175+ return 0L . Equals ( execResult . ExitCode ) ;
176+ } ;
177+
178+ await WaitStrategy . WaitUntilAsync ( initiate , TimeSpan . FromSeconds ( 2 ) , TimeSpan . FromMinutes ( 5 ) , - 1 , ct )
179+ . ConfigureAwait ( false ) ;
180+ }
181+
153182 /// <inheritdoc cref="IWaitUntil" />
154183 private sealed class WaitIndicateReadiness : IWaitUntil
155184 {
@@ -182,16 +211,7 @@ public async Task<bool> UntilAsync(IContainer container)
182211 /// <inheritdoc cref="IWaitUntil" />
183212 private sealed class WaitInitiateReplicaSet : IWaitUntil
184213 {
185- private readonly string _scriptContent ;
186-
187- /// <summary>
188- /// Initializes a new instance of the <see cref="WaitInitiateReplicaSet" /> class.
189- /// </summary>
190- /// <param name="configuration">The container configuration.</param>
191- public WaitInitiateReplicaSet ( MongoDbConfiguration configuration )
192- {
193- _scriptContent = $ "try{{rs.status()}}catch(e){{rs.initiate({{_id:'{ configuration . ReplicaSetName } ',members:[{{_id:0,host:'127.0.0.1:27017'}}]}});throw e;}}";
194- }
214+ private const string ScriptContent = "var r=db.runCommand({hello:1}).isWritablePrimary;quit(r===true?0:1);" ;
195215
196216 /// <inheritdoc />
197217 public Task < bool > UntilAsync ( IContainer container )
@@ -202,7 +222,7 @@ public Task<bool> UntilAsync(IContainer container)
202222 /// <inheritdoc cref="IWaitUntil.UntilAsync" />
203223 private async Task < bool > UntilAsync ( MongoDbContainer container )
204224 {
205- var execResult = await container . ExecScriptAsync ( _scriptContent )
225+ var execResult = await container . ExecScriptAsync ( ScriptContent )
206226 . ConfigureAwait ( false ) ;
207227
208228 return 0L . Equals ( execResult . ExitCode ) ;
0 commit comments