@@ -41,8 +41,10 @@ private MongoDbBuilder(MongoDbConfiguration resourceConfiguration)
41
41
/// <returns>A configured instance of <see cref="MongoDbBuilder" />.</returns>
42
42
public MongoDbBuilder WithUsername ( string username )
43
43
{
44
- return Merge ( DockerResourceConfiguration , new MongoDbConfiguration ( username : username ) )
45
- . WithEnvironment ( "MONGO_INITDB_ROOT_USERNAME" , username ) ;
44
+ var initDbRootUsername = username ?? string . Empty ;
45
+
46
+ return Merge ( DockerResourceConfiguration , new MongoDbConfiguration ( username : initDbRootUsername ) )
47
+ . WithEnvironment ( "MONGO_INITDB_ROOT_USERNAME" , initDbRootUsername ) ;
46
48
}
47
49
48
50
/// <summary>
@@ -52,15 +54,22 @@ public MongoDbBuilder WithUsername(string username)
52
54
/// <returns>A configured instance of <see cref="MongoDbBuilder" />.</returns>
53
55
public MongoDbBuilder WithPassword ( string password )
54
56
{
55
- return Merge ( DockerResourceConfiguration , new MongoDbConfiguration ( password : password ) )
56
- . WithEnvironment ( "MONGO_INITDB_ROOT_PASSWORD" , password ) ;
57
+ var initDbRootPassword = password ?? string . Empty ;
58
+
59
+ return Merge ( DockerResourceConfiguration , new MongoDbConfiguration ( password : initDbRootPassword ) )
60
+ . WithEnvironment ( "MONGO_INITDB_ROOT_PASSWORD" , initDbRootPassword ) ;
57
61
}
58
62
59
63
/// <inheritdoc />
60
64
public override MongoDbContainer Build ( )
61
65
{
62
66
Validate ( ) ;
63
- return new MongoDbContainer ( DockerResourceConfiguration , TestcontainersSettings . Logger ) ;
67
+
68
+ // The wait strategy relies on the configuration of MongoDb. If credentials are
69
+ // provided, the log message "Waiting for connections" appears twice.
70
+ // If the user does not provide a custom waiting strategy, append the default MongoDb waiting strategy.
71
+ var mongoDbBuilder = DockerResourceConfiguration . WaitStrategies . Count ( ) > 1 ? this : WithWaitStrategy ( Wait . ForUnixContainer ( ) . AddCustomWaitStrategy ( new WaitUntil ( DockerResourceConfiguration ) ) ) ;
72
+ return new MongoDbContainer ( mongoDbBuilder . DockerResourceConfiguration , TestcontainersSettings . Logger ) ;
64
73
}
65
74
66
75
/// <inheritdoc />
@@ -70,22 +79,24 @@ protected override MongoDbBuilder Init()
70
79
. WithImage ( MongoDbImage )
71
80
. WithPortBinding ( MongoDbPort , true )
72
81
. WithUsername ( DefaultUsername )
73
- . WithPassword ( DefaultPassword )
74
- . WithWaitStrategy ( Wait . ForUnixContainer ( ) . AddCustomWaitStrategy ( new WaitUntil ( ) ) ) ;
82
+ . WithPassword ( DefaultPassword ) ;
75
83
}
76
84
77
85
/// <inheritdoc />
78
86
protected override void Validate ( )
79
87
{
88
+ const string message = "Missing username or password. Both must be specified for a user to be created." ;
89
+
80
90
base . Validate ( ) ;
81
91
82
92
_ = Guard . Argument ( DockerResourceConfiguration . Username , nameof ( DockerResourceConfiguration . Username ) )
83
- . NotNull ( )
84
- . NotEmpty ( ) ;
93
+ . NotNull ( ) ;
85
94
86
95
_ = Guard . Argument ( DockerResourceConfiguration . Password , nameof ( DockerResourceConfiguration . Password ) )
87
- . NotNull ( )
88
- . NotEmpty ( ) ;
96
+ . NotNull ( ) ;
97
+
98
+ _ = Guard . Argument ( DockerResourceConfiguration , "Credentials" )
99
+ . ThrowIf ( argument => 1 . Equals ( new [ ] { argument . Value . Username , argument . Value . Password } . Count ( string . IsNullOrEmpty ) ) , argument => new ArgumentException ( message , argument . Name ) ) ;
89
100
}
90
101
91
102
/// <inheritdoc />
@@ -111,13 +122,24 @@ private sealed class WaitUntil : IWaitUntil
111
122
{
112
123
private static readonly string [ ] LineEndings = { "\r \n " , "\n " } ;
113
124
125
+ private readonly int _count ;
126
+
127
+ /// <summary>
128
+ /// Initializes a new instance of the <see cref="WaitUntil" /> class.
129
+ /// </summary>
130
+ /// <param name="configuration">The container configuration.</param>
131
+ public WaitUntil ( MongoDbConfiguration configuration )
132
+ {
133
+ _count = string . IsNullOrEmpty ( configuration . Username ) && string . IsNullOrEmpty ( configuration . Password ) ? 1 : 2 ;
134
+ }
135
+
114
136
/// <inheritdoc />
115
137
public async Task < bool > UntilAsync ( IContainer container )
116
138
{
117
139
var ( stdout , stderr ) = await container . GetLogsAsync ( timestampsEnabled : false )
118
140
. ConfigureAwait ( false ) ;
119
141
120
- return 2 . Equals ( Array . Empty < string > ( )
142
+ return _count . Equals ( Array . Empty < string > ( )
121
143
. Concat ( stdout . Split ( LineEndings , StringSplitOptions . RemoveEmptyEntries ) )
122
144
. Concat ( stderr . Split ( LineEndings , StringSplitOptions . RemoveEmptyEntries ) )
123
145
. Count ( line => line . Contains ( "Waiting for connections" ) ) ) ;
0 commit comments