mongo 2.8.0 → 2.9.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +12 -0
- data/lib/mongo.rb +15 -1
- data/lib/mongo/address/ipv6.rb +0 -2
- data/lib/mongo/auth/scram/conversation.rb +0 -3
- data/lib/mongo/bulk_write/result_combiner.rb +12 -2
- data/lib/mongo/client.rb +59 -6
- data/lib/mongo/cluster.rb +19 -8
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +0 -2
- data/lib/mongo/cluster/reapers/socket_reaper.rb +12 -9
- data/lib/mongo/collection.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +30 -10
- data/lib/mongo/collection/view/iterable.rb +13 -6
- data/lib/mongo/collection/view/map_reduce.rb +12 -10
- data/lib/mongo/collection/view/readable.rb +19 -14
- data/lib/mongo/cursor.rb +12 -8
- data/lib/mongo/database.rb +10 -7
- data/lib/mongo/database/view.rb +18 -11
- data/lib/mongo/error.rb +2 -2
- data/lib/mongo/error/connection_check_out_timeout.rb +49 -0
- data/lib/mongo/error/operation_failure.rb +9 -9
- data/lib/mongo/error/parser.rb +25 -3
- data/lib/mongo/error/pool_closed_error.rb +43 -0
- data/lib/mongo/error/sdam_error_detection.rb +18 -0
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/fs_bucket.rb +26 -12
- data/lib/mongo/grid/stream/read.rb +36 -21
- data/lib/mongo/index/view.rb +11 -7
- data/lib/mongo/logger.rb +0 -2
- data/lib/mongo/monitoring.rb +31 -0
- data/lib/mongo/monitoring/cmap_log_subscriber.rb +53 -0
- data/lib/mongo/monitoring/event.rb +1 -0
- data/lib/mongo/monitoring/event/cmap.rb +25 -0
- data/lib/mongo/monitoring/event/cmap/base.rb +28 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +78 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +56 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +63 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +64 -0
- data/lib/mongo/monitoring/event/cmap/connection_closed.rb +103 -0
- data/lib/mongo/monitoring/event/cmap/connection_created.rb +64 -0
- data/lib/mongo/monitoring/event/cmap/connection_ready.rb +64 -0
- data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +57 -0
- data/lib/mongo/monitoring/event/cmap/pool_closed.rb +57 -0
- data/lib/mongo/monitoring/event/cmap/pool_created.rb +63 -0
- data/lib/mongo/monitoring/event/command_started.rb +12 -3
- data/lib/mongo/monitoring/publishable.rb +10 -2
- data/lib/mongo/operation.rb +0 -1
- data/lib/mongo/operation/find/legacy/result.rb +1 -0
- data/lib/mongo/operation/list_collections/result.rb +7 -1
- data/lib/mongo/operation/result.rb +10 -1
- data/lib/mongo/operation/shared/executable.rb +15 -0
- data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +29 -0
- data/lib/mongo/operation/shared/specifiable.rb +0 -16
- data/lib/mongo/operation/update/legacy/result.rb +1 -0
- data/lib/mongo/protocol/compressed.rb +0 -2
- data/lib/mongo/protocol/msg.rb +25 -2
- data/lib/mongo/retryable.rb +171 -33
- data/lib/mongo/server.rb +26 -7
- data/lib/mongo/server/app_metadata.rb +0 -2
- data/lib/mongo/server/connectable.rb +8 -2
- data/lib/mongo/server/connection.rb +83 -13
- data/lib/mongo/server/connection_base.rb +1 -1
- data/lib/mongo/server/connection_pool.rb +439 -43
- data/lib/mongo/server/monitor/connection.rb +4 -1
- data/lib/mongo/session.rb +37 -5
- data/lib/mongo/session/session_pool.rb +2 -2
- data/lib/mongo/socket.rb +0 -2
- data/lib/mongo/socket/ssl.rb +0 -2
- data/lib/mongo/uri.rb +127 -66
- data/lib/mongo/uri/srv_protocol.rb +35 -13
- data/lib/mongo/version.rb +1 -1
- data/spec/README.md +190 -63
- data/spec/integration/change_stream_spec.rb +64 -0
- data/spec/integration/command_spec.rb +0 -7
- data/spec/integration/error_detection_spec.rb +39 -0
- data/spec/integration/read_concern.rb +83 -0
- data/spec/integration/retryable_writes_spec.rb +6 -50
- data/spec/integration/sdam_error_handling_spec.rb +60 -7
- data/spec/integration/ssl_uri_options_spec.rb +24 -0
- data/spec/integration/step_down_spec.rb +197 -0
- data/spec/lite_spec_helper.rb +4 -0
- data/spec/mongo/client_construction_spec.rb +42 -17
- data/spec/mongo/client_spec.rb +32 -1
- data/spec/mongo/cluster/socket_reaper_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +36 -2
- data/spec/mongo/collection/view/aggregation_spec.rb +2 -0
- data/spec/mongo/collection/view/change_stream_spec.rb +28 -28
- data/spec/mongo/collection/view/readable_spec.rb +1 -1
- data/spec/mongo/collection/view_spec.rb +3 -1
- data/spec/mongo/cursor_spec.rb +5 -5
- data/spec/mongo/error/parser_spec.rb +61 -1
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/monitoring/event/cmap/connection_check_out_failed_spec.rb +23 -0
- data/spec/mongo/monitoring/event/cmap/connection_check_out_started_spec.rb +19 -0
- data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +23 -0
- data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +23 -0
- data/spec/mongo/monitoring/event/cmap/connection_closed_spec.rb +27 -0
- data/spec/mongo/monitoring/event/cmap/connection_created_spec.rb +24 -0
- data/spec/mongo/monitoring/event/cmap/connection_ready_spec.rb +24 -0
- data/spec/mongo/monitoring/event/cmap/pool_cleared_spec.rb +19 -0
- data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +19 -0
- data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +26 -0
- data/spec/mongo/operation/delete/bulk_spec.rb +1 -6
- data/spec/mongo/operation/delete/command_spec.rb +1 -1
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
- data/spec/mongo/operation/delete_spec.rb +4 -4
- data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
- data/spec/mongo/operation/insert/command_spec.rb +1 -1
- data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
- data/spec/mongo/operation/update/bulk_spec.rb +1 -1
- data/spec/mongo/operation/update/command_spec.rb +2 -2
- data/spec/mongo/operation/update/op_msg_spec.rb +2 -2
- data/spec/mongo/protocol/msg_spec.rb +11 -0
- data/spec/mongo/retryable_spec.rb +78 -25
- data/spec/mongo/server/connection_pool_spec.rb +661 -126
- data/spec/mongo/server/connection_spec.rb +55 -7
- data/spec/mongo/server_spec.rb +5 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +135 -2
- data/spec/mongo/uri_option_parsing_spec.rb +511 -0
- data/spec/mongo/uri_spec.rb +42 -6
- data/spec/spec_helper.rb +1 -84
- data/spec/spec_tests/cmap_spec.rb +50 -0
- data/spec/spec_tests/command_monitoring_spec.rb +7 -18
- data/spec/spec_tests/crud_spec.rb +3 -49
- data/spec/spec_tests/data/cmap/connection-must-have-id.yml +21 -0
- data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +21 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +24 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +24 -0
- data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +21 -0
- data/spec/spec_tests/data/cmap/pool-checkin.yml +18 -0
- data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +13 -0
- data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +28 -0
- data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +34 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +31 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +29 -0
- data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +26 -0
- data/spec/spec_tests/data/cmap/pool-close.yml +11 -0
- data/spec/spec_tests/data/cmap/pool-create-max-size.yml +56 -0
- data/spec/spec_tests/data/cmap/pool-create-min-size.yml +27 -0
- data/spec/spec_tests/data/cmap/pool-create-with-options.yml +20 -0
- data/spec/spec_tests/data/cmap/pool-create.yml +12 -0
- data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +94 -0
- data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +41 -0
- data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +157 -0
- data/spec/spec_tests/data/retryable_reads/aggregate.yml +87 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +149 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +61 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +149 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +65 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +153 -0
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +61 -0
- data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +150 -0
- data/spec/spec_tests/data/retryable_reads/count.yml +64 -0
- data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +150 -0
- data/spec/spec_tests/data/retryable_reads/countDocuments.yml +64 -0
- data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +156 -0
- data/spec/spec_tests/data/retryable_reads/distinct.yml +71 -0
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +148 -0
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount.yml +62 -0
- data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +160 -0
- data/spec/spec_tests/data/retryable_reads/find.yml +86 -0
- data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +154 -0
- data/spec/spec_tests/data/retryable_reads/findOne.yml +68 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +173 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-download.yml +79 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +174 -0
- data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName.yml +79 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +143 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionNames.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listCollectionObjects.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +143 -0
- data/spec/spec_tests/data/retryable_reads/listCollections.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +143 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseNames.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listDatabaseObjects.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listDatabases.yml +59 -0
- data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +144 -0
- data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +60 -0
- data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +145 -0
- data/spec/spec_tests/data/retryable_reads/listIndexes.yml +60 -0
- data/spec/spec_tests/data/retryable_reads/mapReduce.yml +60 -0
- data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +10 -7
- data/spec/spec_tests/data/retryable_writes/bulkWrite.yml +15 -22
- data/spec/spec_tests/data/retryable_writes/deleteMany.yml +22 -0
- data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/deleteOne.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/findOneAndDelete.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/findOneAndReplace.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/findOneAndUpdate.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/insertMany.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +10 -45
- data/spec/spec_tests/data/retryable_writes/insertOne.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/replaceOne.yml +5 -8
- data/spec/spec_tests/data/retryable_writes/updateMany.yml +27 -0
- data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +8 -7
- data/spec/spec_tests/data/retryable_writes/updateOne.yml +5 -14
- data/spec/spec_tests/data/transactions/abort.yml +7 -2
- data/spec/spec_tests/data/transactions/bulk.yml +7 -2
- data/spec/spec_tests/data/transactions/causal-consistency.yml +11 -4
- data/spec/spec_tests/data/transactions/commit.yml +11 -4
- data/spec/spec_tests/data/transactions/count.yml +64 -0
- data/spec/spec_tests/data/transactions/delete.yml +7 -2
- data/spec/spec_tests/data/transactions/error-labels.yml +8 -2
- data/spec/spec_tests/data/transactions/errors.yml +7 -2
- data/spec/spec_tests/data/transactions/findOneAndDelete.yml +7 -2
- data/spec/spec_tests/data/transactions/findOneAndReplace.yml +7 -2
- data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +7 -2
- data/spec/spec_tests/data/transactions/insert.yml +9 -2
- data/spec/spec_tests/data/transactions/isolation.yml +7 -2
- data/spec/spec_tests/data/transactions/read-concern.yml +15 -6
- data/spec/spec_tests/data/transactions/read-pref.yml +7 -2
- data/spec/spec_tests/data/transactions/reads.yml +8 -48
- data/spec/spec_tests/data/transactions/retryable-abort.yml +7 -2
- data/spec/spec_tests/data/transactions/retryable-commit.yml +7 -2
- data/spec/spec_tests/data/transactions/retryable-writes.yml +7 -2
- data/spec/spec_tests/data/transactions/run-command.yml +7 -2
- data/spec/spec_tests/data/transactions/transaction-options.yml +7 -2
- data/spec/spec_tests/data/transactions/update.yml +7 -2
- data/spec/spec_tests/data/transactions/write-concern.yml +7 -2
- data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -1
- data/spec/spec_tests/data/transactions_api/callback-commits.yml +6 -1
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit-retry.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +6 -3
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +6 -1
- data/spec/spec_tests/data/transactions_api/commit.yml +6 -1
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +6 -1
- data/spec/spec_tests/retryable_reads_spec.rb +11 -0
- data/spec/spec_tests/retryable_writes_spec.rb +4 -69
- data/spec/spec_tests/transactions_api_spec.rb +42 -37
- data/spec/spec_tests/transactions_spec.rb +42 -33
- data/spec/support/authorization.rb +12 -0
- data/spec/support/change_streams/operation.rb +1 -1
- data/spec/support/client_registry.rb +20 -0
- data/spec/support/cluster_config.rb +16 -15
- data/spec/support/cluster_tools.rb +346 -0
- data/spec/support/cmap.rb +367 -0
- data/spec/support/cmap/verifier.rb +46 -0
- data/spec/support/command_monitoring.rb +4 -6
- data/spec/support/common_shortcuts.rb +6 -0
- data/spec/support/connection_string.rb +2 -2
- data/spec/support/crud.rb +171 -184
- data/spec/support/crud/operation.rb +43 -0
- data/spec/support/crud/outcome.rb +53 -0
- data/spec/support/crud/read.rb +102 -12
- data/spec/support/crud/requirement.rb +69 -0
- data/spec/support/crud/spec.rb +68 -0
- data/spec/support/crud/test.rb +141 -0
- data/spec/support/crud/verifier.rb +96 -18
- data/spec/support/crud/write.rb +18 -3
- data/spec/support/event_subscriber.rb +15 -0
- data/spec/support/primary_socket.rb +2 -2
- data/spec/support/spec_config.rb +89 -20
- data/spec/support/transactions.rb +2 -306
- data/spec/support/transactions/operation.rb +7 -7
- data/spec/support/transactions/spec.rb +28 -0
- data/spec/support/transactions/test.rb +191 -0
- data/spec/support/utils.rb +123 -0
- metadata +202 -9
- metadata.gz.sig +0 -0
- data/lib/mongo/server/connection_pool/queue.rb +0 -359
- data/spec/mongo/server/connection_pool/queue_spec.rb +0 -353
- data/spec/support/transactions/verifier.rb +0 -97
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright (C) 2014-2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
module CRUD
|
17
|
+
class Outcome
|
18
|
+
def initialize(spec)
|
19
|
+
if spec.nil?
|
20
|
+
raise ArgumentError, 'Outcome specification cannot be nil'
|
21
|
+
end
|
22
|
+
@result = spec['result']
|
23
|
+
@collection = spec['collection']
|
24
|
+
@error = spec['error']
|
25
|
+
end
|
26
|
+
|
27
|
+
def error?
|
28
|
+
!!@error
|
29
|
+
end
|
30
|
+
|
31
|
+
def collection_data?
|
32
|
+
!!collection_data
|
33
|
+
end
|
34
|
+
|
35
|
+
# The expected data in the collection as an outcome after running an
|
36
|
+
# operation.
|
37
|
+
#
|
38
|
+
# @return [ Array<Hash> ] The list of documents expected to be in the collection.
|
39
|
+
def collection_data
|
40
|
+
@collection && @collection['data']
|
41
|
+
end
|
42
|
+
|
43
|
+
def collection_name
|
44
|
+
@collection && @collection['name']
|
45
|
+
end
|
46
|
+
|
47
|
+
# The expected result of running an operation.
|
48
|
+
#
|
49
|
+
# @return [ Array<Hash> ] The expected result.
|
50
|
+
attr_reader :result
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/spec/support/crud/read.rb
CHANGED
@@ -42,23 +42,45 @@ module Mongo
|
|
42
42
|
'nearest' => :nearest
|
43
43
|
}.freeze
|
44
44
|
|
45
|
-
# The operation name.
|
46
|
-
#
|
47
|
-
# @return [ String ] name The operation name.
|
48
|
-
#
|
49
|
-
# @since 2.0.0
|
50
|
-
attr_reader :name
|
51
|
-
|
52
45
|
# Instantiate the operation.
|
53
46
|
#
|
54
47
|
# @return [ Hash ] spec The operation spec.
|
55
48
|
#
|
56
49
|
# @since 2.0.0
|
57
|
-
def initialize(spec)
|
50
|
+
def initialize(spec, outcome_spec = nil)
|
58
51
|
@spec = spec
|
52
|
+
@outcome = Outcome.new(outcome_spec || spec)
|
59
53
|
@name = spec['name']
|
60
54
|
end
|
61
55
|
|
56
|
+
# The operation name.
|
57
|
+
#
|
58
|
+
# @return [ String ] name The operation name.
|
59
|
+
#
|
60
|
+
# @since 2.0.0
|
61
|
+
attr_reader :name
|
62
|
+
|
63
|
+
attr_reader :outcome
|
64
|
+
|
65
|
+
def object
|
66
|
+
@spec['object'] || 'collection'
|
67
|
+
end
|
68
|
+
|
69
|
+
# Which collection to verify results from.
|
70
|
+
# Returns the collection name specified on the operation, or
|
71
|
+
# the collection name for the entire spec file.
|
72
|
+
def verify_collection_name
|
73
|
+
if outcome && outcome.collection_name
|
74
|
+
outcome.collection_name
|
75
|
+
else
|
76
|
+
spec.collection_name.tap do |cn|
|
77
|
+
if cn.nil?
|
78
|
+
raise "Collection name cannot be nil"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
62
84
|
# Execute the operation.
|
63
85
|
#
|
64
86
|
# @example Execute the operation.
|
@@ -69,11 +91,17 @@ module Mongo
|
|
69
91
|
# @return [ Result, Array<Hash> ] The result of executing the operation.
|
70
92
|
#
|
71
93
|
# @since 2.0.0
|
72
|
-
def execute(
|
73
|
-
|
94
|
+
def execute(target)
|
95
|
+
op_name = Utils.underscore(name)
|
96
|
+
if target.is_a?(Mongo::Database)
|
97
|
+
op_name = "db_#{op_name}"
|
98
|
+
elsif target.is_a?(Mongo::Client)
|
99
|
+
op_name= "client_#{op_name}"
|
100
|
+
end
|
101
|
+
send(op_name, target)
|
74
102
|
end
|
75
103
|
|
76
|
-
# Whether the operation is expected to have
|
104
|
+
# Whether the operation is expected to have results.
|
77
105
|
#
|
78
106
|
# @example Whether the operation is expected to have results.
|
79
107
|
# operation.has_results?
|
@@ -105,8 +133,10 @@ module Mongo
|
|
105
133
|
end
|
106
134
|
|
107
135
|
def estimated_document_count(collection)
|
136
|
+
# estimated_document_count defaults options to {}
|
137
|
+
args = arguments || {}
|
108
138
|
options = ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
|
109
|
-
opts.merge!(key =>
|
139
|
+
opts.merge!(key => args[value]) if args[value]
|
110
140
|
opts
|
111
141
|
end
|
112
142
|
collection.estimated_document_count(options)
|
@@ -125,6 +155,66 @@ module Mongo
|
|
125
155
|
(read_preference ? collection.with(read: read_preference) : collection).find(filter, opts).to_a
|
126
156
|
end
|
127
157
|
|
158
|
+
def find_one(collection)
|
159
|
+
find(collection).first
|
160
|
+
end
|
161
|
+
|
162
|
+
def client_list_databases(client)
|
163
|
+
client.list_databases
|
164
|
+
end
|
165
|
+
|
166
|
+
def client_list_database_names(client)
|
167
|
+
client.list_databases({}, true)
|
168
|
+
end
|
169
|
+
|
170
|
+
def client_list_database_objects(client)
|
171
|
+
client.list_mongo_databases
|
172
|
+
end
|
173
|
+
|
174
|
+
def db_list_collections(database)
|
175
|
+
database.list_collections
|
176
|
+
end
|
177
|
+
|
178
|
+
def db_list_collection_names(database)
|
179
|
+
database.collection_names
|
180
|
+
end
|
181
|
+
|
182
|
+
def db_list_collection_objects(database)
|
183
|
+
database.collections
|
184
|
+
end
|
185
|
+
|
186
|
+
def list_indexes(collection)
|
187
|
+
collection.indexes.to_a
|
188
|
+
end
|
189
|
+
|
190
|
+
def watch(collection)
|
191
|
+
collection.watch
|
192
|
+
end
|
193
|
+
|
194
|
+
def db_watch(database)
|
195
|
+
database.watch
|
196
|
+
end
|
197
|
+
|
198
|
+
def client_watch(client)
|
199
|
+
client.watch
|
200
|
+
end
|
201
|
+
|
202
|
+
def download(fs_bucket)
|
203
|
+
stream = fs_bucket.open_download_stream(BSON::ObjectId.from_string(arguments['id']['$oid']))
|
204
|
+
stream.read
|
205
|
+
end
|
206
|
+
|
207
|
+
def download_by_name(fs_bucket)
|
208
|
+
stream = fs_bucket.open_download_stream_by_name(arguments['filename'])
|
209
|
+
stream.read
|
210
|
+
end
|
211
|
+
|
212
|
+
def map_reduce(collection)
|
213
|
+
view = Mongo::Collection::View.new(collection)
|
214
|
+
mr = Mongo::Collection::View::MapReduce.new(view, arguments['map']['$code'], arguments['reduce']['$code'])
|
215
|
+
mr.to_a
|
216
|
+
end
|
217
|
+
|
128
218
|
def options
|
129
219
|
ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
|
130
220
|
value = if arguments[value].is_a?(Hash) && arguments[value]['$numberLong']
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Mongo
|
2
|
+
module CRUD
|
3
|
+
class Requirement
|
4
|
+
YAML_KEYS = %w(minServerVersion maxServerVersion topology).freeze
|
5
|
+
|
6
|
+
def initialize(spec)
|
7
|
+
@min_server_version = spec['minServerVersion']
|
8
|
+
@max_server_version = spec['maxServerVersion']
|
9
|
+
@topologies = if topologies = spec['topology']
|
10
|
+
topologies.map do |topology|
|
11
|
+
{'replicaset' => :replica_set, 'single' => :single, 'sharded' => :sharded}[topology]
|
12
|
+
end
|
13
|
+
else
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :min_server_version
|
19
|
+
attr_reader :max_server_version
|
20
|
+
attr_reader :topologies
|
21
|
+
|
22
|
+
def short_min_server_version
|
23
|
+
if min_server_version
|
24
|
+
min_server_version.split('.')[0..1].join('.')
|
25
|
+
else
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def short_max_server_version
|
31
|
+
if max_server_version
|
32
|
+
max_server_version.split('.')[0..1].join('.')
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def satisfied?
|
39
|
+
cc = ClusterConfig.instance
|
40
|
+
ok = true
|
41
|
+
if short_min_server_version
|
42
|
+
ok &&= cc.fcv_ish >= short_min_server_version
|
43
|
+
end
|
44
|
+
if max_server_version
|
45
|
+
ok &&= cc.server_version <= max_server_version
|
46
|
+
end
|
47
|
+
if topologies
|
48
|
+
ok &&= topologies.include?(cc.topology)
|
49
|
+
end
|
50
|
+
ok
|
51
|
+
end
|
52
|
+
|
53
|
+
def description
|
54
|
+
versions = [min_server_version, max_server_version].compact
|
55
|
+
if versions.any?
|
56
|
+
versions = versions.join('-')
|
57
|
+
else
|
58
|
+
versions = nil
|
59
|
+
end
|
60
|
+
topologies = if self.topologies
|
61
|
+
self.topologies.map(&:to_s).join(',')
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
[versions, topologies].compact.join('/')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Mongo
|
2
|
+
module CRUD
|
3
|
+
# Represents a CRUD specification test.
|
4
|
+
class Spec
|
5
|
+
|
6
|
+
# Instantiate the new spec.
|
7
|
+
#
|
8
|
+
# @example Create the spec.
|
9
|
+
# Spec.new(file)
|
10
|
+
#
|
11
|
+
# @param [ String ] file The name of the file.
|
12
|
+
#
|
13
|
+
# @since 2.0.0
|
14
|
+
def initialize(file)
|
15
|
+
contents = ERB.new(File.read(file)).result
|
16
|
+
|
17
|
+
# Since Ruby driver binds a client to a database, change the
|
18
|
+
# database name in the spec to the one we are using
|
19
|
+
contents.sub!(/"retryable-reads-tests"/, '"ruby-driver"')
|
20
|
+
contents.sub!(/"transaction-tests"/, '"ruby-driver"')
|
21
|
+
contents.sub!(/"withTransaction-tests"/, '"ruby-driver"')
|
22
|
+
|
23
|
+
@spec = YAML.load(ERB.new(contents).result)
|
24
|
+
@description = File.basename(file)
|
25
|
+
@data = @spec['data']
|
26
|
+
@tests = @spec['tests']
|
27
|
+
|
28
|
+
@requirements = if run_on = @spec['runOn']
|
29
|
+
run_on.map do |spec|
|
30
|
+
Requirement.new(spec)
|
31
|
+
end
|
32
|
+
elsif Requirement::YAML_KEYS.any? { |key| @spec.key?(key) }
|
33
|
+
[Requirement.new(@spec)]
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [ String ] description The spec description.
|
40
|
+
#
|
41
|
+
# @since 2.0.0
|
42
|
+
attr_reader :description
|
43
|
+
|
44
|
+
attr_reader :requirements
|
45
|
+
|
46
|
+
def collection_name
|
47
|
+
# Older spec tests do not specify a collection name, thus
|
48
|
+
# we provide a default here
|
49
|
+
@spec['collection_name'] || 'crud_spec_test'
|
50
|
+
end
|
51
|
+
|
52
|
+
def bucket_name
|
53
|
+
@spec['bucket_name']
|
54
|
+
end
|
55
|
+
|
56
|
+
def database_name
|
57
|
+
@spec['database_name']
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get a list of Test instances, one for each test definition.
|
61
|
+
def tests
|
62
|
+
@tests.map do |test|
|
63
|
+
Mongo::CRUD::CRUDTest.new(@data, test)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Mongo
|
2
|
+
module CRUD
|
3
|
+
|
4
|
+
# Represents a single CRUD test.
|
5
|
+
#
|
6
|
+
# @since 2.0.0
|
7
|
+
class CRUDTest
|
8
|
+
|
9
|
+
# The test description.
|
10
|
+
#
|
11
|
+
# @return [ String ] description The test description.
|
12
|
+
#
|
13
|
+
# @since 2.0.0
|
14
|
+
attr_reader :description
|
15
|
+
|
16
|
+
# Spec tests have configureFailPoint as a string, make it a string here too
|
17
|
+
FAIL_POINT_BASE_COMMAND = BSON::Document.new(
|
18
|
+
'configureFailPoint' => "onPrimaryTransactionalWrite",
|
19
|
+
).freeze
|
20
|
+
|
21
|
+
# Instantiate the new CRUDTest.
|
22
|
+
#
|
23
|
+
# data can be an array of hashes, with each hash corresponding to a
|
24
|
+
# document to be inserted into the collection whose name is given in
|
25
|
+
# collection_name as configured in the YAML file. Alternatively data
|
26
|
+
# can be a map of collection names to arrays of hashes.
|
27
|
+
#
|
28
|
+
# @param [ Hash | Array<Hash> ] data The documents the collection
|
29
|
+
# must have before the test runs.
|
30
|
+
# @param [ Hash ] test The test specification.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def initialize(data, test)
|
34
|
+
@data = data
|
35
|
+
if test['failPoint']
|
36
|
+
@fail_point_command = FAIL_POINT_BASE_COMMAND.merge(test['failPoint'])
|
37
|
+
end
|
38
|
+
@description = test['description']
|
39
|
+
@client_options = Utils.convert_client_options(test['clientOptions'] || {})
|
40
|
+
if test['operations']
|
41
|
+
@operations = test['operations'].map do |op_spec|
|
42
|
+
Operation.get(op_spec)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
@operations = [Operation.get(test['operation'], test['outcome'])]
|
46
|
+
end
|
47
|
+
@expectations = test['expectations']
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_reader :client_options
|
51
|
+
|
52
|
+
# Operations to be performed by the test.
|
53
|
+
#
|
54
|
+
# For CRUD tests, there is one operation for test. For retryable writes,
|
55
|
+
# there are multiple operations for each test. In either case we build
|
56
|
+
# an array of operations.
|
57
|
+
attr_reader :operations
|
58
|
+
|
59
|
+
# The expected command monitoring events
|
60
|
+
attr_reader :expectations
|
61
|
+
|
62
|
+
# Run the test.
|
63
|
+
#
|
64
|
+
# The specified number of operations are executed, so that the
|
65
|
+
# test can assert on the outcome of each specified operation in turn.
|
66
|
+
#
|
67
|
+
# @param [ Client ] client The client the test
|
68
|
+
# should be run with.
|
69
|
+
# @param [ Integer ] num_ops Number of operations to run.
|
70
|
+
#
|
71
|
+
# @return [ Result, Array<Hash> ] The result(s) of running the test.
|
72
|
+
#
|
73
|
+
# @since 2.0.0
|
74
|
+
def run(spec, client, num_ops)
|
75
|
+
result = nil
|
76
|
+
1.upto(num_ops) do |i|
|
77
|
+
operation = @operations[i-1]
|
78
|
+
target = case operation.object
|
79
|
+
when 'collection'
|
80
|
+
client[spec.collection_name]
|
81
|
+
when 'database'
|
82
|
+
client.database
|
83
|
+
when 'client'
|
84
|
+
client
|
85
|
+
when 'gridfsbucket'
|
86
|
+
client.database.fs
|
87
|
+
else
|
88
|
+
raise "Unknown target #{operation.object}"
|
89
|
+
end
|
90
|
+
result = operation.execute(target)
|
91
|
+
end
|
92
|
+
result
|
93
|
+
end
|
94
|
+
|
95
|
+
class DataConverter
|
96
|
+
include Mongo::GridFS::Convertible
|
97
|
+
end
|
98
|
+
|
99
|
+
def setup_test(spec, client)
|
100
|
+
clear_fail_point(client)
|
101
|
+
if @data.is_a?(Array)
|
102
|
+
collection = client[spec.collection_name]
|
103
|
+
collection.delete_many
|
104
|
+
collection.insert_many(@data)
|
105
|
+
elsif @data.is_a?(Hash)
|
106
|
+
converter = DataConverter.new
|
107
|
+
@data.each do |collection_name, data|
|
108
|
+
collection = client[collection_name]
|
109
|
+
collection.delete_many
|
110
|
+
data = converter.transform_docs(data)
|
111
|
+
collection.insert_many(data)
|
112
|
+
end
|
113
|
+
else
|
114
|
+
raise "Unknown type of data: #{@data}"
|
115
|
+
end
|
116
|
+
set_up_fail_point(client)
|
117
|
+
end
|
118
|
+
|
119
|
+
def set_up_fail_point(client)
|
120
|
+
if @fail_point_command
|
121
|
+
client.use(:admin).command(@fail_point_command)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def clear_fail_point(client)
|
126
|
+
if @fail_point_command
|
127
|
+
client.use(:admin).command(@fail_point_command.merge(mode: "off"))
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
def actual_collection_data
|
134
|
+
if expected_outcome.collection_data?
|
135
|
+
collection_name = expected_outcome.collection_name || @collection.name
|
136
|
+
@collection.database[collection_name].find.to_a
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|