|
16 | 16 |
|
17 | 17 | package com.mongodb.client.unified;
|
18 | 18 |
|
| 19 | +import com.mongodb.ClientBulkWriteException; |
19 | 20 | import com.mongodb.MongoBulkWriteException;
|
20 | 21 | import com.mongodb.MongoClientException;
|
21 | 22 | import com.mongodb.MongoCommandException;
|
|
27 | 28 | import com.mongodb.MongoSocketException;
|
28 | 29 | import com.mongodb.MongoWriteConcernException;
|
29 | 30 | import com.mongodb.MongoWriteException;
|
| 31 | +import com.mongodb.WriteError; |
| 32 | +import com.mongodb.bulk.WriteConcernError; |
30 | 33 | import org.bson.BsonDocument;
|
| 34 | +import org.bson.BsonInt32; |
| 35 | +import org.bson.BsonString; |
31 | 36 | import org.bson.BsonValue;
|
32 | 37 |
|
33 | 38 | import java.util.HashSet;
|
| 39 | +import java.util.List; |
34 | 40 | import java.util.Locale;
|
| 41 | +import java.util.Map; |
35 | 42 | import java.util.Set;
|
36 | 43 |
|
| 44 | +import static java.lang.Long.parseLong; |
37 | 45 | import static java.util.Arrays.asList;
|
| 46 | +import static java.util.stream.Collectors.toList; |
38 | 47 | import static org.junit.Assert.assertEquals;
|
39 | 48 | import static org.junit.Assert.assertFalse;
|
| 49 | +import static org.junit.Assert.assertNotNull; |
40 | 50 | import static org.junit.Assert.assertTrue;
|
41 |
| -import static org.spockframework.util.Assert.fail; |
| 51 | +import static org.junit.jupiter.api.Assertions.fail; |
42 | 52 |
|
43 | 53 | final class ErrorMatcher {
|
44 | 54 | private static final Set<String> EXPECTED_ERROR_FIELDS = new HashSet<>(
|
45 | 55 | asList("isError", "expectError", "isClientError", "errorCode", "errorCodeName", "errorContains", "errorResponse",
|
46 |
| - "isClientError", "isTimeoutError", "errorLabelsOmit", "errorLabelsContain", "expectResult")); |
| 56 | + "isClientError", "isTimeoutError", "errorLabelsOmit", "errorLabelsContain", |
| 57 | + "writeErrors", "writeConcernErrors", "expectResult")); |
47 | 58 |
|
48 | 59 | private final AssertionContext context;
|
49 | 60 | private final ValueMatcher valueMatcher;
|
@@ -134,13 +145,55 @@ void assertErrorsMatch(final BsonDocument expectedError, final Exception e) {
|
134 | 145 | mongoException.hasErrorLabel(cur.asString().getValue()));
|
135 | 146 | }
|
136 | 147 | }
|
| 148 | + if (expectedError.containsKey("writeErrors")) { |
| 149 | + assertTrue(context.getMessage("Exception must be of type ClientBulkWriteException when checking for write errors"), |
| 150 | + e instanceof ClientBulkWriteException); |
| 151 | + BsonDocument writeErrors = expectedError.getDocument("writeErrors"); |
| 152 | + ClientBulkWriteException actualException = (ClientBulkWriteException) e; |
| 153 | + Map<Long, WriteError> actualWriteErrors = actualException.getWriteErrors(); |
| 154 | + assertEquals("The number of write errors must match", writeErrors.size(), actualWriteErrors.size()); |
| 155 | + writeErrors.forEach((index, writeError) -> { |
| 156 | + WriteError actualWriteError = actualWriteErrors.get(parseLong(index)); |
| 157 | + assertNotNull("Expected a write error with index " + index, actualWriteError); |
| 158 | + valueMatcher.assertValuesMatch(writeError, toMatchableValue(actualWriteError)); |
| 159 | + }); |
| 160 | + } |
| 161 | + if (expectedError.containsKey("writeConcernErrors")) { |
| 162 | + assertTrue(context.getMessage("Exception must be of type ClientBulkWriteException when checking for write errors"), |
| 163 | + e instanceof ClientBulkWriteException); |
| 164 | + List<BsonDocument> writeConcernErrors = expectedError.getArray("writeConcernErrors").stream() |
| 165 | + .map(BsonValue::asDocument).collect(toList()); |
| 166 | + ClientBulkWriteException actualException = (ClientBulkWriteException) e; |
| 167 | + List<WriteConcernError> actualWriteConcernErrors = actualException.getWriteConcernErrors(); |
| 168 | + assertEquals("The number of write concern errors must match", writeConcernErrors.size(), actualWriteConcernErrors.size()); |
| 169 | + for (int index = 0; index < writeConcernErrors.size(); index++) { |
| 170 | + BsonDocument writeConcernError = writeConcernErrors.get(index); |
| 171 | + WriteConcernError actualWriteConcernError = actualWriteConcernErrors.get(index); |
| 172 | + valueMatcher.assertValuesMatch(writeConcernError, toMatchableValue(actualWriteConcernError)); |
| 173 | + } |
| 174 | + } |
137 | 175 | if (expectedError.containsKey("expectResult")) {
|
138 |
| - // Neither MongoBulkWriteException nor MongoSocketException includes information about the successful writes, so this |
139 |
| - // is the only check that can currently be done |
140 |
| - assertTrue(context.getMessage("Exception must be of type MongoBulkWriteException or MongoSocketException " |
141 |
| - + "when checking for results, but actual type is " + e.getClass().getSimpleName()), |
142 |
| - e instanceof MongoBulkWriteException || e instanceof MongoSocketException); |
| 176 | + assertTrue(context.getMessage("Exception must be of type" |
| 177 | + + " MongoBulkWriteException, or MongoSocketException, or ClientBulkWriteException" |
| 178 | + + " when checking for results, but actual type is " + e.getClass().getSimpleName()), |
| 179 | + e instanceof MongoBulkWriteException || e instanceof ClientBulkWriteException || e instanceof MongoSocketException); |
| 180 | + // neither `MongoBulkWriteException` nor `MongoSocketException` includes information about the successful individual operations |
| 181 | + if (e instanceof ClientBulkWriteException) { |
| 182 | + BsonDocument actualPartialResult = ((ClientBulkWriteException) e).getPartialResult() |
| 183 | + .map(UnifiedCrudHelper::toMatchableValue) |
| 184 | + .orElse(new BsonDocument()); |
| 185 | + valueMatcher.assertValuesMatch(expectedError.getDocument("expectResult"), actualPartialResult); |
| 186 | + } |
143 | 187 | }
|
144 | 188 | context.pop();
|
145 | 189 | }
|
| 190 | + |
| 191 | + private static BsonDocument toMatchableValue(final WriteError writeError) { |
| 192 | + return new BsonDocument("code", new BsonInt32(writeError.getCode())); |
| 193 | + } |
| 194 | + |
| 195 | + private static BsonDocument toMatchableValue(final WriteConcernError writeConcernError) { |
| 196 | + return new BsonDocument("code", new BsonInt32(writeConcernError.getCode())) |
| 197 | + .append("message", new BsonString(writeConcernError.getMessage())); |
| 198 | + } |
146 | 199 | }
|
0 commit comments