Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions spec/runners/unified/assertions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,13 @@ def assert_matches(actual, expected, msg)
def get_actual_value(actual, key)
if actual.is_a?(Hash)
actual[key]
elsif actual.is_a?(Mongo::Operation::Result) && !actual.respond_to?(key.to_sym)
actual.documents.first[key]
elsif actual.is_a?(Mongo::Operation::Result)
snake_key = Utils.underscore(key)
if actual.respond_to?(snake_key)
actual.send(snake_key)
else
actual.documents.first[key]
end
else
actual.send(key)
end
Expand Down
5 changes: 5 additions & 0 deletions spec/runners/unified/crud_operations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,13 @@ def find_one_and_replace(op)
let: args.use('let'),
comment: args.use('comment'),
hint: args.use('hint'),
sort: args.use('sort'),
timeout_ms: args.use('timeoutMS'),
max_time_ms: args.use('maxTimeMS')
}
if return_document = args.use('returnDocument')
opts[:return_document] = return_document.downcase.to_sym
end
if session = args.use('session')
opts[:session] = entities.get(:session, session)
end
Expand All @@ -139,6 +143,7 @@ def find_one_and_delete(op)
let: args.use('let'),
comment: args.use('comment'),
hint: args.use('hint'),
sort: args.use('sort'),
timeout_ms: args.use('timeoutMS'),
max_time_ms: args.use('maxTimeMS')
}
Expand Down
2 changes: 1 addition & 1 deletion spec/runners/unified/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ def execute_operation(op, propagate_errors: false)
method_name = name
method_name = "_#{name}" if name.to_s == 'loop'

skip "Mongo Ruby Driver does not support #{name}" if %w[modify_collection list_index_names].include?(name.to_s)
skip "Mongo Ruby Driver does not support #{name}" if %w[modify_collection list_index_names client_bulk_write].include?(name.to_s)

if expected_error = op.use('expectError')
begin
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
description: "aggregate with $out/$merge does not set txnNumber"

schemaVersion: "1.4"

runOnRequirements:
- minServerVersion: "3.6"
topologies:
- replicaset
- sharded
- load-balanced

createEntities:
- client:
id: &client0 client0
observeEvents: [ commandStartedEvent ]
- database:
id: &database0 database0
client: *client0
databaseName: &database0Name retryable-writes-tests
- collection:
id: &collection0 collection0
database: *database0
collectionName: &collection0Name coll0

initialData:
# The output collection must already exist for $merge on a sharded cluster
- collectionName: &mergeCollection mergeCollection
databaseName: *database0Name
documents: []

tests:
- description: "aggregate with $out does not set txnNumber"
runOnRequirements:
- serverless: forbid # $out is not supported on serverless
operations:
- object: *collection0
name: aggregate
arguments:
pipeline:
- { $sort: { x: 1 } }
- { $match: { _id: { $gt: 1 } } }
- { $out: outCollection }
expectEvents:
- client: client0
events:
- commandStartedEvent:
commandName: aggregate
command:
txnNumber: { $$exists: false }
- description: "aggregate with $merge does not set txnNumber"
runOnRequirements:
- minServerVersion: "4.1.11"
operations:
- object: *collection0
name: aggregate
arguments:
pipeline:
- { $sort: { x: 1 } }
- { $match: { _id: { $gt: 1 } } }
- { $merge: { into: *mergeCollection } }
expectEvents:
- client: client0
events:
- commandStartedEvent:
commandName: aggregate
command:
txnNumber: { $$exists: false }
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
description: bulkWrite-errorLabels

schemaVersion: '1.3'

runOnRequirements:
-
minServerVersion: 4.3.1 # failCommand errorLabels option
topologies: [ replicaset, sharded, load-balanced ]

createEntities:
-
client:
id: &client0 client0
useMultipleMongoses: false
-
database:
id: &database0 database0
client: *client0
databaseName: &database_name retryable-writes-tests
-
collection:
id: &collection0 collection0
database: *database0
collectionName: &collection_name coll

initialData:
-
collectionName: *collection_name
databaseName: *database_name
documents:
- { _id: 1, x: 11 }
- { _id: 2, x: 22 }

tests:
-
description: 'BulkWrite succeeds with RetryableWriteError from server'
operations:
-
name: failPoint
object: testRunner
arguments:
client: *client0
failPoint:
configureFailPoint: failCommand
mode: { times: 1 }
data:
failCommands: [ update ]
errorCode: 112 # WriteConflict, not a retryable error code
# Override server behavior: send RetryableWriteError label with non-retryable error code
errorLabels:
- RetryableWriteError
-
object: *collection0
name: bulkWrite
arguments:
requests:
-
deleteOne:
filter: { _id: 1 }
-
insertOne:
document: { _id: 3, x: 33 }
-
updateOne:
filter: { _id: 2 }
update: { $inc: { x: 1 } }
ordered: true
# Driver retries operation and it succeeds
expectResult:
deletedCount: 1
insertedCount: 1
insertedIds: { $$unsetOrMatches: { '1': 3 } }
matchedCount: 1
modifiedCount: 1
upsertedCount: 0
upsertedIds: { }
outcome:
-
collectionName: *collection_name
databaseName: *database_name
documents:
- { _id: 2, x: 23 }
- { _id: 3, x: 33 }
-
description: 'BulkWrite fails if server does not return RetryableWriteError'
operations:
-
name: failPoint
object: testRunner
arguments:
client: *client0
failPoint:
configureFailPoint: failCommand
mode: { times: 1 }
data:
failCommands: [ update ]
errorCode: 11600 # InterruptedAtShutdown, normally a retryable error code
errorLabels: [] # Override server behavior: do not send RetryableWriteError label with retryable code
-
object: *collection0
name: bulkWrite
arguments:
requests:
-
deleteOne:
filter: { _id: 1 }
-
insertOne:
document: { _id: 3, x: 33 }
-
updateOne:
filter: { _id: 2 }
update: { $inc: { x: 1 } }
ordered: true
# Driver does not retry operation because there was no RetryableWriteError label on response
expectError:
isError: true
errorLabelsOmit:
- RetryableWriteError
outcome:
-
collectionName: *collection_name
databaseName: *database_name
documents:
- { _id: 2, x: 22 }
- { _id: 3, x: 33 }
-
description: 'BulkWrite succeeds after PrimarySteppedDown'
operations:
-
name: failPoint
object: testRunner
arguments:
client: *client0
failPoint:
configureFailPoint: failCommand
mode: { times: 1 }
data:
failCommands: [ update ]
errorCode: 189
errorLabels:
- RetryableWriteError
-
object: *collection0
name: bulkWrite
arguments:
requests:
-
deleteOne:
filter: { _id: 1 }
-
insertOne:
document: { _id: 3, x: 33 }
-
updateOne:
filter: { _id: 2 }
update: { $inc: { x: 1 } }
ordered: true
expectResult:
deletedCount: 1
insertedCount: 1
insertedIds: { $$unsetOrMatches: { '1': 3 } }
matchedCount: 1
modifiedCount: 1
upsertedCount: 0
upsertedIds: { }
outcome:
-
collectionName: *collection_name
databaseName: *database_name
documents:
- { _id: 2, x: 23 }
- { _id: 3, x: 33 }
-
description: 'BulkWrite succeeds after WriteConcernError ShutdownInProgress'
operations:
-
name: failPoint
object: testRunner
arguments:
client: *client0
failPoint:
configureFailPoint: failCommand
mode: { times: 1 }
data:
failCommands: [ insert ]
errorLabels:
- RetryableWriteError
writeConcernError:
code: 91
errmsg: 'Replication is being shut down'
-
object: *collection0
name: bulkWrite
arguments:
requests:
-
deleteOne:
filter: { _id: 1 }
-
insertOne:
document: { _id: 3, x: 33 }
-
updateOne:
filter: { _id: 2 }
update: { $inc: { x: 1 } }
ordered: true
expectResult:
deletedCount: 1
insertedCount: 1
insertedIds: { $$unsetOrMatches: { '1': 3 } }
matchedCount: 1
modifiedCount: 1
upsertedCount: 0
upsertedIds: { }
outcome:
-
collectionName: *collection_name
databaseName: *database_name
documents:
- { _id: 2, x: 23 }
- { _id: 3, x: 33 }
Loading
Loading