2
2
3
3
namespace MongoDB \Tests \UnifiedSpecTests ;
4
4
5
+ use MongoDB \Driver \Exception \BulkWriteCommandException ;
5
6
use MongoDB \Driver \Exception \BulkWriteException ;
6
7
use MongoDB \Driver \Exception \CommandException ;
7
8
use MongoDB \Driver \Exception \ExecutionTimeoutException ;
12
13
use stdClass ;
13
14
use Throwable ;
14
15
16
+ use function count ;
15
17
use function PHPUnit \Framework \assertArrayHasKey ;
16
18
use function PHPUnit \Framework \assertContainsOnly ;
17
19
use function PHPUnit \Framework \assertCount ;
@@ -56,14 +58,18 @@ final class ExpectedError
56
58
57
59
private ?string $ codeName = null ;
58
60
59
- private ?Matches $ matchesResultDocument = null ;
61
+ private ?Matches $ matchesErrorResponse = null ;
60
62
61
63
private array $ includedLabels = [];
62
64
63
65
private array $ excludedLabels = [];
64
66
65
67
private ?ExpectedResult $ expectedResult = null ;
66
68
69
+ private ?array $ writeErrors = null ;
70
+
71
+ private ?array $ writeConcernErrors = null ;
72
+
67
73
public function __construct (?stdClass $ o , EntityMap $ entityMap )
68
74
{
69
75
if ($ o === null ) {
@@ -98,7 +104,7 @@ public function __construct(?stdClass $o, EntityMap $entityMap)
98
104
99
105
if (isset ($ o ->errorResponse )) {
100
106
assertIsObject ($ o ->errorResponse );
101
- $ this ->matchesResultDocument = new Matches ($ o ->errorResponse , $ entityMap );
107
+ $ this ->matchesErrorResponse = new Matches ($ o ->errorResponse , $ entityMap );
102
108
}
103
109
104
110
if (isset ($ o ->errorLabelsContain )) {
@@ -116,6 +122,24 @@ public function __construct(?stdClass $o, EntityMap $entityMap)
116
122
if (property_exists ($ o , 'expectResult ' )) {
117
123
$ this ->expectedResult = new ExpectedResult ($ o , $ entityMap );
118
124
}
125
+
126
+ if (isset ($ o ->writeErrors )) {
127
+ assertIsObject ($ o ->writeErrors );
128
+ assertContainsOnly ('object ' , (array ) $ o ->writeErrors );
129
+
130
+ foreach ($ o ->writeErrors as $ i => $ writeError ) {
131
+ $ this ->writeErrors [$ i ] = new Matches ($ writeError , $ entityMap );
132
+ }
133
+ }
134
+
135
+ if (isset ($ o ->writeConcernErrors )) {
136
+ assertIsArray ($ o ->writeConcernErrors );
137
+ assertContainsOnly ('object ' , $ o ->writeConcernErrors );
138
+
139
+ foreach ($ o ->writeConcernErrors as $ i => $ writeConcernError ) {
140
+ $ this ->writeConcernErrors [$ i ] = new Matches ($ writeConcernError , $ entityMap );
141
+ }
142
+ }
119
143
}
120
144
121
145
/**
@@ -155,15 +179,21 @@ public function assert(?Throwable $e = null): void
155
179
$ this ->assertCodeName ($ e );
156
180
}
157
181
158
- if (isset ($ this ->matchesResultDocument )) {
159
- assertThat ($ e , logicalOr (isInstanceOf (CommandException::class), isInstanceOf (BulkWriteException::class)));
182
+ if (isset ($ this ->matchesErrorResponse )) {
183
+ assertThat ($ e , logicalOr (
184
+ isInstanceOf (CommandException::class),
185
+ isInstanceOf (BulkWriteException::class),
186
+ isInstanceOf (BulkWriteCommandException::class),
187
+ ));
160
188
161
189
if ($ e instanceof CommandException) {
162
- assertThat ($ e ->getResultDocument (), $ this ->matchesResultDocument , 'CommandException result document matches ' );
190
+ assertThat ($ e ->getResultDocument (), $ this ->matchesErrorResponse , 'CommandException result document matches expected errorResponse ' );
191
+ } elseif ($ e instanceof BulkWriteCommandException) {
192
+ assertThat ($ e ->getErrorReply (), $ this ->matchesErrorResponse , 'BulkWriteCommandException error reply matches expected errorResponse ' );
163
193
} elseif ($ e instanceof BulkWriteException) {
164
194
$ writeErrors = $ e ->getWriteResult ()->getErrorReplies ();
165
195
assertCount (1 , $ writeErrors );
166
- assertThat ($ writeErrors [0 ], $ this ->matchesResultDocument , 'BulkWriteException result document matches ' );
196
+ assertThat ($ writeErrors [0 ], $ this ->matchesErrorResponse , 'BulkWriteException first error reply matches expected errorResponse ' );
167
197
}
168
198
}
169
199
@@ -180,16 +210,34 @@ public function assert(?Throwable $e = null): void
180
210
}
181
211
182
212
if (isset ($ this ->expectedResult )) {
183
- assertInstanceOf (BulkWriteException::class, $ e );
184
- $ this ->expectedResult ->assert ($ e ->getWriteResult ());
213
+ assertThat ($ e , logicalOr (
214
+ isInstanceOf (BulkWriteException::class),
215
+ isInstanceOf (BulkWriteCommandException::class),
216
+ ));
217
+
218
+ if ($ e instanceof BulkWriteCommandException) {
219
+ $ this ->expectedResult ->assert ($ e ->getPartialResult ());
220
+ } elseif ($ e instanceof BulkWriteException) {
221
+ $ this ->expectedResult ->assert ($ e ->getWriteResult ());
222
+ }
223
+ }
224
+
225
+ if (isset ($ this ->writeErrors )) {
226
+ assertInstanceOf (BulkWriteCommandException::class, $ e );
227
+ $ this ->assertWriteErrors ($ e ->getWriteErrors ());
228
+ }
229
+
230
+ if (isset ($ this ->writeConcernErrors )) {
231
+ assertInstanceOf (BulkWriteCommandException::class, $ e );
232
+ $ this ->assertWriteConcernErrors ($ e ->getWriteConcernErrors ());
185
233
}
186
234
}
187
235
188
236
private function assertIsClientError (Throwable $ e ): void
189
237
{
190
- /* Note: BulkWriteException may proxy a previous exception. Unwrap it
191
- * to check the original error. */
192
- if ($ e instanceof BulkWriteException && $ e ->getPrevious () !== null ) {
238
+ /* Note: BulkWriteException and BulkWriteCommandException may proxy a
239
+ * previous exception. Unwrap it to check the original error. */
240
+ if (( $ e instanceof BulkWriteException || $ e instanceof BulkWriteCommandException) && $ e ->getPrevious () !== null ) {
193
241
$ e = $ e ->getPrevious ();
194
242
}
195
243
@@ -226,4 +274,47 @@ private function assertCodeName(ServerException $e): void
226
274
assertObjectHasProperty ('codeName ' , $ result );
227
275
assertSame ($ this ->codeName , $ result ->codeName );
228
276
}
277
+
278
+ private function assertWriteErrors (array $ writeErrors ): void
279
+ {
280
+ assertCount (count ($ this ->writeErrors ), $ writeErrors );
281
+
282
+ foreach ($ this ->writeErrors as $ i => $ matchesWriteError ) {
283
+ assertArrayHasKey ($ i , $ writeErrors );
284
+ $ writeError = $ writeErrors [$ i ];
285
+
286
+ // Not required by the spec test, but asserts PHPC correctness
287
+ assertSame ((int ) $ i , $ writeError ->getIndex ());
288
+
289
+ /* Convert the WriteError into a document for matching. These
290
+ * field names are derived from the CRUD spec. */
291
+ $ writeErrorDocument = [
292
+ 'code ' => $ writeError ->getCode (),
293
+ 'message ' => $ writeError ->getMessage (),
294
+ 'details ' => $ writeError ->getInfo (),
295
+ ];
296
+
297
+ assertThat ($ writeErrorDocument , $ matchesWriteError );
298
+ }
299
+ }
300
+
301
+ private function assertWriteConcernErrors (array $ writeConcernErrors ): void
302
+ {
303
+ assertCount (count ($ this ->writeConcernErrors ), $ writeConcernErrors );
304
+
305
+ foreach ($ this ->writeConcernErrors as $ i => $ matchesWriteConcernError ) {
306
+ assertArrayHasKey ($ i , $ writeConcernErrors );
307
+ $ writeConcernError = $ writeConcernErrors [$ i ];
308
+
309
+ /* Convert the WriteConcernError into a document for matching.
310
+ * These field names are derived from the CRUD spec. */
311
+ $ writeConcernErrorDocument = [
312
+ 'code ' => $ writeConcernError ->getCode (),
313
+ 'message ' => $ writeConcernError ->getMessage (),
314
+ 'details ' => $ writeConcernError ->getInfo (),
315
+ ];
316
+
317
+ assertThat ($ writeConcernErrorDocument , $ matchesWriteConcernError );
318
+ }
319
+ }
229
320
}
0 commit comments