Skip to content

Commit 1a45dfd

Browse files
authored
GODRIVER-2487 Add spec tests for errorResponse. (#1097)
1 parent 410bcea commit 1a45dfd

14 files changed

+882
-1
lines changed

mongo/integration/unified/error.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type expectedError struct {
2626
IncludedLabels []string `bson:"errorLabelsContain"`
2727
OmittedLabels []string `bson:"errorLabelsOmit"`
2828
ExpectedResult *bson.RawValue `bson:"expectResult"`
29+
ErrorResponse *bson.Raw `bson:"errorResponse"`
2930
}
3031

3132
// verifyOperationError compares the expected error to the actual operation result. If the expected parameter is nil,
@@ -125,6 +126,19 @@ func verifyOperationError(ctx context.Context, expected *expectedError, result *
125126
return fmt.Errorf("result comparison error: %v", err)
126127
}
127128
}
129+
130+
if expected.ErrorResponse != nil {
131+
if details.raw == nil {
132+
return fmt.Errorf("expected error response from the server, got none")
133+
}
134+
135+
// Allow extra keys as 'errorResponse' functions like a root-level document.
136+
gotValue := documentToRawValue(details.raw)
137+
expectedValue := documentToRawValue(*expected.ErrorResponse)
138+
if err := verifyValuesMatch(ctx, expectedValue, gotValue, true); err != nil {
139+
return fmt.Errorf("error response comparison error: %v", err)
140+
}
141+
}
128142
return nil
129143
}
130144

@@ -133,6 +147,7 @@ type errorDetails struct {
133147
codes []int32
134148
codeNames []string
135149
labels []string
150+
raw bson.Raw
136151
}
137152

138153
// extractErrorDetails creates an errorDetails instance based on the provided error. It returns the details and an "ok"
@@ -145,6 +160,7 @@ func extractErrorDetails(err error) (errorDetails, bool) {
145160
details.codes = []int32{converted.Code}
146161
details.codeNames = []string{converted.Name}
147162
details.labels = converted.Labels
163+
details.raw = converted.Raw
148164
case mongo.WriteException:
149165
if converted.WriteConcernError != nil {
150166
details.codes = append(details.codes, int32(converted.WriteConcernError.Code))
@@ -154,13 +170,15 @@ func extractErrorDetails(err error) (errorDetails, bool) {
154170
details.codes = append(details.codes, int32(we.Code))
155171
}
156172
details.labels = converted.Labels
173+
details.raw = converted.Raw
157174
case mongo.BulkWriteException:
158175
if converted.WriteConcernError != nil {
159176
details.codes = append(details.codes, int32(converted.WriteConcernError.Code))
160177
details.codeNames = append(details.codeNames, converted.WriteConcernError.Name)
161178
}
162179
for _, we := range converted.WriteErrors {
163180
details.codes = append(details.codes, int32(we.Code))
181+
details.raw = we.Raw
164182
}
165183
details.labels = converted.Labels
166184
default:

mongo/integration/unified/schema_version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616

1717
var (
1818
supportedSchemaVersions = map[int]string{
19-
1: "1.9",
19+
1: "1.12",
2020
}
2121
)
2222

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
"description": "aggregate-merge-errorResponse",
3+
"schemaVersion": "1.12",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client0"
8+
}
9+
},
10+
{
11+
"database": {
12+
"id": "database0",
13+
"client": "client0",
14+
"databaseName": "crud-tests"
15+
}
16+
},
17+
{
18+
"collection": {
19+
"id": "collection0",
20+
"database": "database0",
21+
"collectionName": "test"
22+
}
23+
}
24+
],
25+
"initialData": [
26+
{
27+
"collectionName": "test",
28+
"databaseName": "crud-tests",
29+
"documents": [
30+
{
31+
"_id": 1,
32+
"x": 1
33+
},
34+
{
35+
"_id": 2,
36+
"x": 1
37+
}
38+
]
39+
}
40+
],
41+
"tests": [
42+
{
43+
"description": "aggregate $merge DuplicateKey error is accessible",
44+
"runOnRequirements": [
45+
{
46+
"minServerVersion": "5.1",
47+
"topologies": [
48+
"single",
49+
"replicaset"
50+
]
51+
}
52+
],
53+
"operations": [
54+
{
55+
"name": "aggregate",
56+
"object": "database0",
57+
"arguments": {
58+
"pipeline": [
59+
{
60+
"$documents": [
61+
{
62+
"_id": 2,
63+
"x": 1
64+
}
65+
]
66+
},
67+
{
68+
"$merge": {
69+
"into": "test",
70+
"whenMatched": "fail"
71+
}
72+
}
73+
]
74+
},
75+
"expectError": {
76+
"errorCode": 11000,
77+
"errorResponse": {
78+
"keyPattern": {
79+
"_id": 1
80+
},
81+
"keyValue": {
82+
"_id": 2
83+
}
84+
}
85+
}
86+
}
87+
]
88+
}
89+
]
90+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
description: "aggregate-merge-errorResponse"
2+
3+
schemaVersion: "1.12"
4+
5+
createEntities:
6+
- client:
7+
id: &client0 client0
8+
- database:
9+
id: &database0 database0
10+
client: *client0
11+
databaseName: &database0Name crud-tests
12+
- collection:
13+
id: &collection0 collection0
14+
database: *database0
15+
collectionName: &collection0Name test
16+
17+
initialData: &initialData
18+
- collectionName: *collection0Name
19+
databaseName: *database0Name
20+
documents:
21+
- { _id: 1, x: 1 }
22+
- { _id: 2, x: 1 }
23+
24+
tests:
25+
- description: "aggregate $merge DuplicateKey error is accessible"
26+
runOnRequirements:
27+
- minServerVersion: "5.1" # SERVER-59097
28+
# Exclude sharded topologies since the aggregate command fails with
29+
# IllegalOperation(20) instead of DuplicateKey(11000)
30+
topologies: [ single, replicaset ]
31+
operations:
32+
- name: aggregate
33+
object: *database0
34+
arguments:
35+
pipeline:
36+
- { $documents: [ { _id: 2, x: 1 } ] }
37+
- { $merge: { into: *collection0Name, whenMatched: "fail" } }
38+
expectError:
39+
errorCode: 11000 # DuplicateKey
40+
errorResponse:
41+
keyPattern: { _id: 1 }
42+
keyValue: { _id: 2 }
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"description": "bulkWrite-errorResponse",
3+
"schemaVersion": "1.12",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client0",
8+
"useMultipleMongoses": false
9+
}
10+
},
11+
{
12+
"database": {
13+
"id": "database0",
14+
"client": "client0",
15+
"databaseName": "crud-tests"
16+
}
17+
},
18+
{
19+
"collection": {
20+
"id": "collection0",
21+
"database": "database0",
22+
"collectionName": "test"
23+
}
24+
}
25+
],
26+
"tests": [
27+
{
28+
"description": "bulkWrite operations support errorResponse assertions",
29+
"runOnRequirements": [
30+
{
31+
"minServerVersion": "4.0.0",
32+
"topologies": [
33+
"single",
34+
"replicaset"
35+
]
36+
},
37+
{
38+
"minServerVersion": "4.2.0",
39+
"topologies": [
40+
"sharded"
41+
]
42+
}
43+
],
44+
"operations": [
45+
{
46+
"name": "failPoint",
47+
"object": "testRunner",
48+
"arguments": {
49+
"client": "client0",
50+
"failPoint": {
51+
"configureFailPoint": "failCommand",
52+
"mode": {
53+
"times": 1
54+
},
55+
"data": {
56+
"failCommands": [
57+
"insert"
58+
],
59+
"errorCode": 8
60+
}
61+
}
62+
}
63+
},
64+
{
65+
"name": "bulkWrite",
66+
"object": "collection0",
67+
"arguments": {
68+
"requests": [
69+
{
70+
"insertOne": {
71+
"document": {
72+
"_id": 1
73+
}
74+
}
75+
}
76+
]
77+
},
78+
"expectError": {
79+
"errorCode": 8,
80+
"errorResponse": {
81+
"code": 8
82+
}
83+
}
84+
}
85+
]
86+
}
87+
]
88+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
description: "bulkWrite-errorResponse"
2+
3+
schemaVersion: "1.12"
4+
5+
createEntities:
6+
- client:
7+
id: &client0 client0
8+
useMultipleMongoses: false
9+
- database:
10+
id: &database0 database0
11+
client: *client0
12+
databaseName: &database0Name crud-tests
13+
- collection:
14+
id: &collection0 collection0
15+
database: *database0
16+
collectionName: &collection0Name test
17+
18+
tests:
19+
# This test intentionally executes only a single insert operation in the bulk
20+
# write to make the error code and response assertions less ambiguous. That
21+
# said, some drivers may still need to skip this test because the CRUD spec
22+
# does not prescribe how drivers should formulate a BulkWriteException beyond
23+
# collecting write and write concern errors.
24+
- description: "bulkWrite operations support errorResponse assertions"
25+
runOnRequirements:
26+
- minServerVersion: "4.0.0"
27+
topologies: [ single, replicaset ]
28+
- minServerVersion: "4.2.0"
29+
topologies: [ sharded ]
30+
operations:
31+
- name: failPoint
32+
object: testRunner
33+
arguments:
34+
client: *client0
35+
failPoint:
36+
configureFailPoint: failCommand
37+
mode: { times: 1 }
38+
data:
39+
failCommands: [ insert ]
40+
errorCode: &errorCode 8 # UnknownError
41+
- name: bulkWrite
42+
object: *collection0
43+
arguments:
44+
requests:
45+
- insertOne:
46+
document: { _id: 1 }
47+
expectError:
48+
errorCode: *errorCode
49+
errorResponse:
50+
code: *errorCode

0 commit comments

Comments
 (0)