mongo 2.13.0.beta1 → 2.14.0
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 +1 -5
- data/Rakefile +50 -9
- data/lib/mongo.rb +13 -2
- data/lib/mongo/address.rb +1 -1
- data/lib/mongo/address/ipv4.rb +1 -1
- data/lib/mongo/address/ipv6.rb +1 -1
- data/lib/mongo/auth/aws/request.rb +31 -5
- data/lib/mongo/bulk_write.rb +18 -0
- data/lib/mongo/caching_cursor.rb +74 -0
- data/lib/mongo/client.rb +238 -31
- data/lib/mongo/cluster.rb +56 -20
- data/lib/mongo/cluster/sdam_flow.rb +13 -10
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -2
- data/lib/mongo/cluster/topology/sharded.rb +1 -1
- data/lib/mongo/cluster/topology/single.rb +2 -2
- data/lib/mongo/collection.rb +66 -24
- data/lib/mongo/collection/view.rb +24 -20
- data/lib/mongo/collection/view/aggregation.rb +25 -4
- data/lib/mongo/collection/view/builder/find_command.rb +38 -18
- data/lib/mongo/collection/view/explainable.rb +27 -8
- data/lib/mongo/collection/view/iterable.rb +72 -12
- data/lib/mongo/collection/view/readable.rb +19 -3
- data/lib/mongo/collection/view/writable.rb +55 -5
- data/lib/mongo/crypt/encryption_io.rb +6 -6
- data/lib/mongo/cursor.rb +16 -3
- data/lib/mongo/database.rb +37 -4
- data/lib/mongo/database/view.rb +18 -3
- data/lib/mongo/distinguishing_semaphore.rb +55 -0
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/error/invalid_read_concern.rb +28 -0
- data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
- data/lib/mongo/error/invalid_session.rb +2 -1
- data/lib/mongo/error/operation_failure.rb +11 -5
- data/lib/mongo/error/server_certificate_revoked.rb +22 -0
- data/lib/mongo/error/sessions_not_supported.rb +35 -0
- data/lib/mongo/error/unsupported_option.rb +14 -12
- data/lib/mongo/event/base.rb +6 -0
- data/lib/mongo/grid/file.rb +5 -0
- data/lib/mongo/grid/file/chunk.rb +2 -0
- data/lib/mongo/grid/fs_bucket.rb +15 -13
- data/lib/mongo/grid/stream/write.rb +9 -3
- data/lib/mongo/index/view.rb +3 -0
- data/lib/mongo/lint.rb +2 -1
- data/lib/mongo/logger.rb +3 -3
- data/lib/mongo/monitoring.rb +38 -0
- data/lib/mongo/monitoring/command_log_subscriber.rb +10 -2
- data/lib/mongo/monitoring/event/command_failed.rb +11 -0
- data/lib/mongo/monitoring/event/command_started.rb +37 -2
- data/lib/mongo/monitoring/event/command_succeeded.rb +11 -0
- data/lib/mongo/monitoring/event/server_closed.rb +1 -1
- data/lib/mongo/monitoring/event/server_description_changed.rb +27 -4
- data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +9 -2
- data/lib/mongo/monitoring/event/server_heartbeat_started.rb +9 -2
- data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +9 -2
- data/lib/mongo/monitoring/event/server_opening.rb +1 -1
- data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
- data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
- data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
- data/lib/mongo/monitoring/publishable.rb +6 -3
- data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +9 -1
- data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
- data/lib/mongo/operation.rb +2 -0
- data/lib/mongo/operation/aggregate/result.rb +9 -8
- data/lib/mongo/operation/collections_info/command.rb +5 -0
- data/lib/mongo/operation/collections_info/result.rb +18 -1
- data/lib/mongo/operation/delete/bulk_result.rb +2 -0
- data/lib/mongo/operation/delete/result.rb +3 -0
- data/lib/mongo/operation/explain/command.rb +4 -0
- data/lib/mongo/operation/explain/legacy.rb +4 -0
- data/lib/mongo/operation/explain/op_msg.rb +6 -0
- data/lib/mongo/operation/explain/result.rb +3 -0
- data/lib/mongo/operation/find/legacy/result.rb +2 -0
- data/lib/mongo/operation/find/result.rb +13 -0
- data/lib/mongo/operation/get_more/result.rb +3 -0
- data/lib/mongo/operation/indexes/result.rb +5 -0
- data/lib/mongo/operation/insert/bulk_result.rb +5 -0
- data/lib/mongo/operation/insert/result.rb +5 -0
- data/lib/mongo/operation/list_collections/result.rb +5 -0
- data/lib/mongo/operation/map_reduce/result.rb +10 -0
- data/lib/mongo/operation/parallel_scan/result.rb +4 -0
- data/lib/mongo/operation/result.rb +35 -6
- data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -0
- data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -0
- data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +2 -0
- data/lib/mongo/operation/shared/executable.rb +1 -0
- data/lib/mongo/operation/shared/idable.rb +2 -1
- data/lib/mongo/operation/shared/limited.rb +1 -0
- data/lib/mongo/operation/shared/object_id_generator.rb +1 -0
- data/lib/mongo/operation/shared/result/aggregatable.rb +1 -0
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -0
- data/lib/mongo/operation/shared/specifiable.rb +1 -0
- data/lib/mongo/operation/shared/write.rb +1 -0
- data/lib/mongo/operation/shared/write_concern_supported.rb +1 -0
- data/lib/mongo/operation/update/legacy/result.rb +7 -0
- data/lib/mongo/operation/update/result.rb +8 -0
- data/lib/mongo/operation/users_info/result.rb +3 -0
- data/lib/mongo/protocol/message.rb +47 -10
- data/lib/mongo/protocol/msg.rb +34 -1
- data/lib/mongo/protocol/query.rb +36 -0
- data/lib/mongo/protocol/serializers.rb +5 -2
- data/lib/mongo/query_cache.rb +242 -0
- data/lib/mongo/retryable.rb +8 -1
- data/lib/mongo/server.rb +15 -4
- data/lib/mongo/server/app_metadata.rb +27 -3
- data/lib/mongo/server/connection.rb +4 -4
- data/lib/mongo/server/connection_base.rb +38 -12
- data/lib/mongo/server/connection_common.rb +2 -2
- data/lib/mongo/server/connection_pool.rb +3 -0
- data/lib/mongo/server/description.rb +13 -1
- data/lib/mongo/server/monitor.rb +76 -44
- data/lib/mongo/server/monitor/connection.rb +57 -9
- data/lib/mongo/server/pending_connection.rb +14 -4
- data/lib/mongo/server/push_monitor.rb +173 -0
- data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
- data/lib/mongo/server_selector.rb +0 -1
- data/lib/mongo/server_selector/base.rb +583 -1
- data/lib/mongo/server_selector/nearest.rb +1 -6
- data/lib/mongo/server_selector/primary.rb +1 -6
- data/lib/mongo/server_selector/primary_preferred.rb +7 -10
- data/lib/mongo/server_selector/secondary.rb +1 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +1 -7
- data/lib/mongo/session.rb +7 -1
- data/lib/mongo/socket.rb +26 -12
- data/lib/mongo/socket/ocsp_cache.rb +97 -0
- data/lib/mongo/socket/ocsp_verifier.rb +368 -0
- data/lib/mongo/socket/ssl.rb +46 -25
- data/lib/mongo/socket/tcp.rb +1 -1
- data/lib/mongo/srv/monitor.rb +7 -13
- data/lib/mongo/srv/resolver.rb +14 -10
- data/lib/mongo/timeout.rb +2 -0
- data/lib/mongo/topology_version.rb +9 -0
- data/lib/mongo/uri.rb +21 -390
- data/lib/mongo/uri/options_mapper.rb +582 -0
- data/lib/mongo/uri/srv_protocol.rb +3 -2
- data/lib/mongo/utils.rb +73 -0
- data/lib/mongo/version.rb +1 -1
- data/spec/NOTES.aws-auth.md +12 -7
- data/spec/README.aws-auth.md +2 -2
- data/spec/README.md +63 -1
- data/spec/integration/awaited_ismaster_spec.rb +28 -0
- data/spec/integration/bson_symbol_spec.rb +4 -2
- data/spec/integration/bulk_write_spec.rb +67 -0
- data/spec/integration/change_stream_examples_spec.rb +6 -2
- data/spec/integration/change_stream_spec.rb +1 -1
- data/spec/integration/check_clean_slate_spec.rb +16 -0
- data/spec/integration/client_authentication_options_spec.rb +92 -28
- data/spec/integration/client_construction_spec.rb +1 -0
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +9 -5
- data/spec/integration/connect_single_rs_name_spec.rb +5 -2
- data/spec/integration/connection_pool_populator_spec.rb +4 -2
- data/spec/integration/connection_spec.rb +7 -4
- data/spec/integration/crud_spec.rb +4 -4
- data/spec/integration/cursor_reaping_spec.rb +54 -18
- data/spec/integration/docs_examples_spec.rb +6 -0
- data/spec/integration/fork_reconnect_spec.rb +56 -1
- data/spec/integration/grid_fs_bucket_spec.rb +48 -0
- data/spec/integration/heartbeat_events_spec.rb +4 -23
- data/spec/integration/ocsp_connectivity_spec.rb +26 -0
- data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
- data/spec/integration/ocsp_verifier_spec.rb +334 -0
- data/spec/integration/query_cache_spec.rb +1045 -0
- data/spec/integration/query_cache_transactions_spec.rb +190 -0
- data/spec/integration/read_concern_spec.rb +1 -1
- data/spec/integration/retryable_errors_spec.rb +1 -1
- data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -0
- data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +4 -2
- data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -3
- data/spec/integration/retryable_writes/shared/performs_no_retries.rb +2 -2
- data/spec/integration/sdam_error_handling_spec.rb +122 -15
- data/spec/integration/sdam_events_spec.rb +80 -6
- data/spec/integration/sdam_prose_spec.rb +64 -0
- data/spec/integration/server_monitor_spec.rb +25 -1
- data/spec/integration/server_selection_spec.rb +36 -0
- data/spec/integration/size_limit_spec.rb +23 -5
- data/spec/integration/srv_monitoring_spec.rb +38 -3
- data/spec/integration/srv_spec.rb +56 -0
- data/spec/integration/ssl_uri_options_spec.rb +2 -2
- data/spec/integration/transactions_examples_spec.rb +17 -7
- data/spec/integration/zlib_compression_spec.rb +25 -0
- data/spec/lite_spec_helper.rb +20 -9
- data/spec/mongo/address_spec.rb +1 -1
- data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
- data/spec/mongo/auth/aws/request_spec.rb +76 -0
- data/spec/mongo/auth/scram_spec.rb +1 -1
- data/spec/mongo/auth/user_spec.rb +1 -1
- data/spec/mongo/bulk_write_spec.rb +2 -2
- data/spec/mongo/caching_cursor_spec.rb +70 -0
- data/spec/mongo/client_construction_spec.rb +386 -3
- data/spec/mongo/client_encryption_spec.rb +16 -10
- data/spec/mongo/client_spec.rb +85 -3
- data/spec/mongo/cluster/topology/replica_set_spec.rb +53 -10
- data/spec/mongo/cluster/topology/sharded_spec.rb +1 -1
- data/spec/mongo/cluster/topology/single_spec.rb +19 -8
- data/spec/mongo/cluster/topology/unknown_spec.rb +1 -1
- data/spec/mongo/cluster/topology_spec.rb +1 -1
- data/spec/mongo/cluster_spec.rb +37 -35
- data/spec/mongo/collection/view/change_stream_resume_spec.rb +7 -7
- data/spec/mongo/collection/view/explainable_spec.rb +87 -4
- data/spec/mongo/collection/view/map_reduce_spec.rb +2 -0
- data/spec/mongo/collection/view/readable_spec.rb +36 -0
- data/spec/mongo/collection_spec.rb +572 -0
- data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
- data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
- data/spec/mongo/crypt/binary_spec.rb +1 -6
- data/spec/mongo/crypt/binding/binary_spec.rb +1 -6
- data/spec/mongo/crypt/binding/context_spec.rb +2 -7
- data/spec/mongo/crypt/binding/helpers_spec.rb +1 -6
- data/spec/mongo/crypt/binding/mongocrypt_spec.rb +2 -7
- data/spec/mongo/crypt/binding/status_spec.rb +1 -6
- data/spec/mongo/crypt/binding/version_spec.rb +1 -6
- data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
- data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +1 -1
- data/spec/mongo/crypt/status_spec.rb +1 -6
- data/spec/mongo/database_spec.rb +353 -8
- data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
- data/spec/mongo/error/no_server_available_spec.rb +1 -1
- data/spec/mongo/error/operation_failure_spec.rb +40 -0
- data/spec/mongo/index/view_spec.rb +148 -2
- data/spec/mongo/logger_spec.rb +13 -11
- data/spec/mongo/monitoring/event/server_closed_spec.rb +1 -1
- data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
- data/spec/mongo/monitoring/event/server_opening_spec.rb +1 -1
- data/spec/mongo/monitoring/event/topology_changed_spec.rb +1 -1
- data/spec/mongo/monitoring/event/topology_closed_spec.rb +1 -1
- data/spec/mongo/monitoring/event/topology_opening_spec.rb +1 -1
- data/spec/mongo/operation/delete/op_msg_spec.rb +3 -3
- data/spec/mongo/operation/insert/command_spec.rb +2 -2
- data/spec/mongo/operation/insert/op_msg_spec.rb +3 -3
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +1 -1
- data/spec/mongo/operation/update/command_spec.rb +2 -2
- data/spec/mongo/operation/update/op_msg_spec.rb +3 -3
- data/spec/mongo/protocol/msg_spec.rb +10 -0
- data/spec/mongo/query_cache_spec.rb +280 -0
- data/spec/mongo/semaphore_spec.rb +51 -0
- data/spec/mongo/server/app_metadata_shared.rb +82 -2
- data/spec/mongo/server/connection_auth_spec.rb +2 -2
- data/spec/mongo/server/connection_pool_spec.rb +7 -3
- data/spec/mongo/server/connection_spec.rb +15 -8
- data/spec/mongo/server/description_spec.rb +18 -0
- data/spec/mongo/server_selector/nearest_spec.rb +23 -23
- data/spec/mongo/server_selector/primary_preferred_spec.rb +26 -26
- data/spec/mongo/server_selector/primary_spec.rb +9 -9
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +22 -22
- data/spec/mongo/server_selector/secondary_spec.rb +18 -18
- data/spec/mongo/server_selector_spec.rb +6 -6
- data/spec/mongo/session_spec.rb +35 -0
- data/spec/mongo/socket/ssl_spec.rb +4 -4
- data/spec/mongo/socket_spec.rb +1 -1
- data/spec/mongo/uri/srv_protocol_spec.rb +64 -33
- data/spec/mongo/uri_option_parsing_spec.rb +11 -11
- data/spec/mongo/uri_spec.rb +68 -41
- data/spec/mongo/utils_spec.rb +39 -0
- data/spec/runners/auth.rb +3 -0
- data/spec/runners/change_streams/test.rb +3 -3
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/command_monitoring.rb +3 -34
- data/spec/runners/connection_string.rb +35 -124
- data/spec/runners/crud/context.rb +9 -5
- data/spec/runners/crud/operation.rb +59 -27
- data/spec/runners/crud/spec.rb +0 -8
- data/spec/runners/crud/test.rb +1 -1
- data/spec/runners/crud/test_base.rb +0 -19
- data/spec/runners/sdam.rb +2 -2
- data/spec/runners/server_selection.rb +242 -28
- data/spec/runners/transactions.rb +12 -12
- data/spec/runners/transactions/operation.rb +151 -25
- data/spec/runners/transactions/test.rb +62 -18
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/constraints.rb +303 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/spec_tests/cmap_spec.rb +7 -3
- data/spec/spec_tests/command_monitoring_spec.rb +22 -12
- data/spec/spec_tests/crud_spec.rb +1 -1
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +4 -9
- data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +66 -0
- data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
- data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +6 -2
- data/spec/spec_tests/data/cmap/pool-create-min-size.yml +3 -0
- data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
- data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
- data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
- data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
- data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
- data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
- data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
- data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
- data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -3
- data/spec/spec_tests/data/sdam_monitoring/standalone.yml +2 -2
- data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
- data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
- data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
- data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
- data/spec/spec_tests/data/uri_options/compression-options.yml +6 -3
- data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
- data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
- data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
- data/spec/spec_tests/dns_seedlist_discovery_spec.rb +9 -1
- data/spec/spec_tests/max_staleness_spec.rb +4 -142
- data/spec/spec_tests/retryable_reads_spec.rb +2 -2
- data/spec/spec_tests/sdam_integration_spec.rb +13 -0
- data/spec/spec_tests/sdam_monitoring_spec.rb +1 -2
- data/spec/spec_tests/server_selection_spec.rb +4 -116
- data/spec/spec_tests/uri_options_spec.rb +31 -33
- data/spec/stress/cleanup_spec.rb +17 -2
- data/spec/stress/connection_pool_stress_spec.rb +10 -8
- data/spec/stress/fork_reconnect_stress_spec.rb +1 -1
- data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
- data/spec/support/certificates/atlas-ocsp.crt +41 -0
- data/spec/support/client_registry.rb +1 -0
- data/spec/support/client_registry_macros.rb +11 -2
- data/spec/support/cluster_config.rb +4 -0
- data/spec/support/common_shortcuts.rb +45 -0
- data/spec/support/constraints.rb +6 -253
- data/spec/support/event_subscriber.rb +123 -33
- data/spec/support/keyword_struct.rb +26 -0
- data/spec/support/matchers.rb +16 -0
- data/spec/support/ocsp +1 -0
- data/spec/support/session_registry.rb +52 -0
- data/spec/support/shared/server_selector.rb +13 -1
- data/spec/support/spec_config.rb +60 -13
- data/spec/support/spec_setup.rb +1 -1
- data/spec/support/utils.rb +84 -1
- metadata +1027 -937
- metadata.gz.sig +0 -0
- data/lib/mongo/server_selector/selectable.rb +0 -560
- data/spec/runners/sdam_monitoring.rb +0 -89
- data/spec/support/lite_constraints.rb +0 -141
data/spec/runners/crud/spec.rb
CHANGED
@@ -11,14 +11,6 @@ module Mongo
|
|
11
11
|
def initialize(test_path)
|
12
12
|
contents = File.read(test_path)
|
13
13
|
|
14
|
-
# Since Ruby driver binds a client to a database, change the
|
15
|
-
# database name in the spec to the one we are using
|
16
|
-
contents.sub!(/"crud-tests"/, '"ruby-driver"')
|
17
|
-
contents.sub!(/"retryable-reads-tests"/, '"ruby-driver"')
|
18
|
-
contents.sub!(/"transaction-tests"/, '"ruby-driver"')
|
19
|
-
contents.sub!(/"withTransaction-tests"/, '"ruby-driver"')
|
20
|
-
contents.sub!(/ default_write_concern_db/, ' ruby-driver')
|
21
|
-
|
22
14
|
@spec = YAML.load(contents)
|
23
15
|
@description = File.basename(test_path)
|
24
16
|
@data = BSON::ExtJSON.parse_obj(@spec['data'])
|
data/spec/runners/crud/test.rb
CHANGED
@@ -28,7 +28,7 @@ module Mongo
|
|
28
28
|
@spec = crud_spec
|
29
29
|
@data = data
|
30
30
|
@description = test['description']
|
31
|
-
@client_options = Utils.convert_client_options(test['clientOptions'] || {})
|
31
|
+
@client_options = ::Utils.convert_client_options(test['clientOptions'] || {})
|
32
32
|
|
33
33
|
if test['failPoint']
|
34
34
|
@fail_point_command = FAIL_POINT_BASE_COMMAND.merge(test['failPoint'])
|
@@ -45,25 +45,6 @@ module Mongo
|
|
45
45
|
raise "Unknown target #{operation.object}"
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
49
|
-
# If the deployment is a sharded cluster, creates a direct client
|
50
|
-
# to each of the mongos nodes and yields each in turn to the
|
51
|
-
# provided block. Does nothing in other topologies.
|
52
|
-
def mongos_each_direct_client
|
53
|
-
if ClusterConfig.instance.topology == :sharded
|
54
|
-
client = ClientRegistry.instance.global_client('basic')
|
55
|
-
client.cluster.next_primary
|
56
|
-
client.cluster.servers.each do |server|
|
57
|
-
direct_client = ClientRegistry.instance.new_local_client(
|
58
|
-
[server.address.to_s],
|
59
|
-
SpecConfig.instance.test_options.merge(
|
60
|
-
connect: :sharded
|
61
|
-
).merge(SpecConfig.instance.auth_options))
|
62
|
-
yield direct_client
|
63
|
-
direct_client.close
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
48
|
end
|
68
49
|
end
|
69
50
|
end
|
data/spec/runners/sdam.rb
CHANGED
@@ -149,7 +149,7 @@ module Mongo
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def when
|
152
|
-
Utils.underscore(@spec.fetch('when'))
|
152
|
+
::Utils.underscore(@spec.fetch('when'))
|
153
153
|
end
|
154
154
|
|
155
155
|
def max_wire_version
|
@@ -161,7 +161,7 @@ module Mongo
|
|
161
161
|
end
|
162
162
|
|
163
163
|
def type
|
164
|
-
Utils.underscore(@spec.fetch('type'))
|
164
|
+
::Utils.underscore(@spec.fetch('type'))
|
165
165
|
end
|
166
166
|
|
167
167
|
def result
|
@@ -73,19 +73,6 @@ module Mongo
|
|
73
73
|
@type = Mongo::Cluster::Topology.const_get(@test['topology_description']['type'])
|
74
74
|
end
|
75
75
|
|
76
|
-
# Whether this spec describes a replica set.
|
77
|
-
#
|
78
|
-
# @example Determine if the spec describes a replica set.
|
79
|
-
# spec.replica_set?
|
80
|
-
#
|
81
|
-
# @return [true, false] If the spec describes a replica set.
|
82
|
-
#
|
83
|
-
# @since 2.0.0
|
84
|
-
def replica_set?
|
85
|
-
type == Mongo::Cluster::Topology::ReplicaSetNoPrimary ||
|
86
|
-
type == Mongo::Cluster::Topology::ReplicaSetWithPrimary
|
87
|
-
end
|
88
|
-
|
89
76
|
# Does this spec expect a server to be found.
|
90
77
|
#
|
91
78
|
# @example Will a server be found with this spec.
|
@@ -98,15 +85,10 @@ module Mongo
|
|
98
85
|
!in_latency_window.empty?
|
99
86
|
end
|
100
87
|
|
101
|
-
#
|
88
|
+
# Whether the test requires an error to be raised during server selection.
|
102
89
|
#
|
103
|
-
# @
|
104
|
-
|
105
|
-
#
|
106
|
-
# @return [ true, false ] If an error will be raised by the max staleness setting.
|
107
|
-
#
|
108
|
-
# @since 2.4.0
|
109
|
-
def invalid_max_staleness?
|
90
|
+
# @return [ true, false ] Whether the test expects an error.
|
91
|
+
def error?
|
110
92
|
@test['error']
|
111
93
|
end
|
112
94
|
|
@@ -122,9 +104,6 @@ module Mongo
|
|
122
104
|
#
|
123
105
|
# @since 2.0.0
|
124
106
|
def in_latency_window
|
125
|
-
if read_preference['mode'] == :secondary_preferred && primary
|
126
|
-
return @in_latency_window.push(primary).uniq
|
127
|
-
end
|
128
107
|
@in_latency_window
|
129
108
|
end
|
130
109
|
|
@@ -134,13 +113,248 @@ module Mongo
|
|
134
113
|
#
|
135
114
|
# @since 2.0.0
|
136
115
|
def candidate_servers
|
137
|
-
@candidate_servers
|
116
|
+
@candidate_servers
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def define_server_selection_spec_tests(test_paths)
|
124
|
+
# Linter insists that a server selection semaphore is present when
|
125
|
+
# performing server selection.
|
126
|
+
require_no_linting
|
127
|
+
|
128
|
+
test_paths.each do |file|
|
129
|
+
|
130
|
+
spec = Mongo::ServerSelection::Read::Spec.new(file)
|
131
|
+
|
132
|
+
context(spec.description) do
|
133
|
+
# Cluster needs a topology and topology needs a cluster...
|
134
|
+
# This temporary cluster is used for topology construction.
|
135
|
+
let(:temp_cluster) do
|
136
|
+
double('temp cluster').tap do |cluster|
|
137
|
+
allow(cluster).to receive(:servers_list).and_return([])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
let(:topology) do
|
142
|
+
options = if spec.type <= Mongo::Cluster::Topology::ReplicaSetNoPrimary
|
143
|
+
{replica_set_name: 'foo'}
|
144
|
+
else
|
145
|
+
{}
|
146
|
+
end
|
147
|
+
spec.type.new(options, monitoring, temp_cluster)
|
148
|
+
end
|
149
|
+
|
150
|
+
let(:monitoring) do
|
151
|
+
Mongo::Monitoring.new(monitoring: false)
|
152
|
+
end
|
153
|
+
|
154
|
+
let(:listeners) do
|
155
|
+
Mongo::Event::Listeners.new
|
156
|
+
end
|
157
|
+
|
158
|
+
let(:options) do
|
159
|
+
if spec.heartbeat_frequency
|
160
|
+
{server_selection_timeout: 0.1, heartbeat_frequency: spec.heartbeat_frequency}
|
161
|
+
else
|
162
|
+
{server_selection_timeout: 0.1}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
let(:cluster) do
|
167
|
+
double('cluster').tap do |c|
|
168
|
+
allow(c).to receive(:server_selection_semaphore)
|
169
|
+
allow(c).to receive(:connected?).and_return(true)
|
170
|
+
allow(c).to receive(:summary)
|
171
|
+
allow(c).to receive(:topology).and_return(topology)
|
172
|
+
allow(c).to receive(:single?).and_return(topology.single?)
|
173
|
+
allow(c).to receive(:sharded?).and_return(topology.sharded?)
|
174
|
+
allow(c).to receive(:replica_set?).and_return(topology.replica_set?)
|
175
|
+
allow(c).to receive(:unknown?).and_return(topology.unknown?)
|
176
|
+
allow(c).to receive(:options).and_return(options)
|
177
|
+
allow(c).to receive(:scan!).and_return(true)
|
178
|
+
allow(c).to receive(:app_metadata).and_return(app_metadata)
|
179
|
+
allow(c).to receive(:heartbeat_interval).and_return(
|
180
|
+
spec.heartbeat_frequency || Mongo::Server::Monitor::DEFAULT_HEARTBEAT_INTERVAL)
|
138
181
|
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# One of the spec test assertions is on the set of servers that are
|
185
|
+
# eligible for selection without taking latency into account.
|
186
|
+
# In the driver, latency is taken into account at various points during
|
187
|
+
# server selection, hence there isn't a method that can be called to
|
188
|
+
# retrieve the list of servers without accounting for latency.
|
189
|
+
# Work around this by executing server selection with all servers set
|
190
|
+
# to zero latency, when evaluating the candidate server set.
|
191
|
+
let(:ignore_latency) { false }
|
192
|
+
|
193
|
+
let(:candidate_servers) do
|
194
|
+
spec.candidate_servers.collect do |server|
|
195
|
+
features = double('features').tap do |feat|
|
196
|
+
allow(feat).to receive(:max_staleness_enabled?).and_return(server['maxWireVersion'] && server['maxWireVersion'] >= 5)
|
197
|
+
allow(feat).to receive(:check_driver_support!).and_return(true)
|
198
|
+
end
|
199
|
+
address = Mongo::Address.new(server['address'])
|
200
|
+
Mongo::Server.new(address, cluster, monitoring, listeners,
|
201
|
+
{monitoring_io: false}.update(options)
|
202
|
+
).tap do |s|
|
203
|
+
allow(s).to receive(:average_round_trip_time) do
|
204
|
+
if ignore_latency
|
205
|
+
0
|
206
|
+
elsif server['avg_rtt_ms']
|
207
|
+
server['avg_rtt_ms'] / 1000.0
|
208
|
+
end
|
209
|
+
end
|
210
|
+
allow(s).to receive(:tags).and_return(server['tags'])
|
211
|
+
allow(s).to receive(:secondary?).and_return(server['type'] == 'RSSecondary')
|
212
|
+
allow(s).to receive(:primary?).and_return(server['type'] == 'RSPrimary')
|
213
|
+
allow(s).to receive(:mongos?).and_return(server['type'] == 'Mongos')
|
214
|
+
allow(s).to receive(:standalone?).and_return(server['type'] == 'Standalone')
|
215
|
+
allow(s).to receive(:unknown?).and_return(server['type'] == 'Unknown')
|
216
|
+
allow(s).to receive(:connectable?).and_return(true)
|
217
|
+
allow(s).to receive(:last_write_date).and_return(
|
218
|
+
Time.at(server['lastWrite']['lastWriteDate']['$numberLong'].to_f / 1000)) if server['lastWrite']
|
219
|
+
allow(s).to receive(:last_scan).and_return(
|
220
|
+
Time.at(server['lastUpdateTime'].to_f / 1000))
|
221
|
+
allow(s).to receive(:features).and_return(features)
|
222
|
+
allow(s).to receive(:replica_set_name).and_return('foo')
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
let(:suitable_servers) do
|
228
|
+
spec.suitable_servers.collect do |server|
|
229
|
+
Mongo::Server.new(Mongo::Address.new(server['address']), cluster, monitoring, listeners,
|
230
|
+
options.merge(monitoring_io: false))
|
231
|
+
end
|
232
|
+
end
|
139
233
|
|
140
|
-
|
234
|
+
let(:in_latency_window) do
|
235
|
+
spec.in_latency_window.collect do |server|
|
236
|
+
Mongo::Server.new(Mongo::Address.new(server['address']), cluster, monitoring, listeners,
|
237
|
+
options.merge(monitoring_io: false))
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
let(:server_selector_definition) do
|
242
|
+
{ mode: spec.read_preference['mode'] }.tap do |definition|
|
243
|
+
definition[:tag_sets] = spec.read_preference['tag_sets']
|
244
|
+
definition[:max_staleness] = spec.max_staleness if spec.max_staleness
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
let(:server_selector) do
|
249
|
+
Mongo::ServerSelector.get(server_selector_definition)
|
250
|
+
end
|
251
|
+
|
252
|
+
let(:app_metadata) do
|
253
|
+
Mongo::Server::AppMetadata.new({})
|
254
|
+
end
|
255
|
+
|
256
|
+
before do
|
257
|
+
allow(cluster).to receive(:servers_list).and_return(candidate_servers)
|
258
|
+
allow(cluster).to receive(:servers) do
|
259
|
+
# Copy Cluster#servers definition because clusters is a double
|
260
|
+
cluster.topology.servers(cluster.servers_list)
|
261
|
+
end
|
262
|
+
allow(cluster).to receive(:addresses).and_return(candidate_servers.map(&:address))
|
263
|
+
end
|
264
|
+
|
265
|
+
if spec.error?
|
266
|
+
|
267
|
+
it 'Raises an InvalidServerPreference exception' do
|
268
|
+
|
269
|
+
expect do
|
270
|
+
server_selector.select_server(cluster)
|
271
|
+
end.to raise_exception(Mongo::Error::InvalidServerPreference)
|
272
|
+
end
|
273
|
+
|
274
|
+
else
|
275
|
+
|
276
|
+
if spec.server_available?
|
277
|
+
|
278
|
+
it 'has non-empty suitable servers' do
|
279
|
+
spec.suitable_servers.should be_a(Array)
|
280
|
+
spec.suitable_servers.should_not be_empty
|
281
|
+
end
|
282
|
+
|
283
|
+
if spec.in_latency_window.length == 1
|
284
|
+
|
285
|
+
it 'selects the expected server' do
|
286
|
+
[server_selector.select_server(cluster)].should == in_latency_window
|
287
|
+
end
|
288
|
+
|
289
|
+
else
|
290
|
+
|
291
|
+
it 'selects a server in the suitable list' do
|
292
|
+
in_latency_window.should include(server_selector.select_server(cluster))
|
293
|
+
end
|
294
|
+
|
295
|
+
let(:expected_addresses) do
|
296
|
+
in_latency_window.map(&:address).map(&:seed).sort
|
297
|
+
end
|
298
|
+
|
299
|
+
let(:actual_addresses) do
|
300
|
+
server_selector.suitable_servers(cluster).map(&:address).map(&:seed).sort
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'identifies expected suitable servers' do
|
304
|
+
actual_addresses.should == expected_addresses
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
context 'candidate servers without taking latency into account' do
|
310
|
+
let(:ignore_latency) { true }
|
311
|
+
|
312
|
+
let(:expected_addresses) do
|
313
|
+
suitable_servers.map(&:address).map(&:seed).sort
|
314
|
+
end
|
315
|
+
|
316
|
+
let(:actual_addresses) do
|
317
|
+
servers = server_selector.send(:suitable_servers, cluster)
|
318
|
+
|
319
|
+
# The tests expect that only secondaries are "suitable" for
|
320
|
+
# server selection with secondary preferred read preference.
|
321
|
+
# In actuality, primaries are also suitable, and the driver
|
322
|
+
# returns the primaries also. Remove primaries from the
|
323
|
+
# actual set when read preference is secondary preferred.
|
324
|
+
# HOWEVER, if a test ends up selecting a primary, then it
|
325
|
+
# includes that primary into its suitable servers. Therefore
|
326
|
+
# only remove primaries when the number of suitable servers
|
327
|
+
# is greater than 1.
|
328
|
+
servers.delete_if do |server|
|
329
|
+
server_selector.is_a?(Mongo::ServerSelector::SecondaryPreferred) &&
|
330
|
+
server.primary? &&
|
331
|
+
servers.length > 1
|
332
|
+
end
|
333
|
+
|
334
|
+
# Since we remove the latency requirement, the servers
|
335
|
+
# may be returned in arbitrary order.
|
336
|
+
servers.map(&:address).map(&:seed).sort
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'identifies expected suitable servers' do
|
340
|
+
actual_addresses.should == expected_addresses
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
else
|
345
|
+
|
346
|
+
# Runner does not handle non-empty suitable servers with
|
347
|
+
# no servers in latency window.
|
348
|
+
it 'has empty suitable servers' do
|
349
|
+
expect(spec.suitable_servers).to eq([])
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'Raises a NoServerAvailable Exception' do
|
353
|
+
expect do
|
354
|
+
server_selector.select_server(cluster)
|
355
|
+
end.to raise_exception(Mongo::Error::NoServerAvailable)
|
356
|
+
end
|
141
357
|
|
142
|
-
def primary
|
143
|
-
@candidate_servers.find { |s| s['type'] == 'RSPrimary' }
|
144
358
|
end
|
145
359
|
end
|
146
360
|
end
|
@@ -12,7 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require 'runners/transactions/context'
|
16
15
|
require 'runners/transactions/operation'
|
17
16
|
require 'runners/transactions/spec'
|
18
17
|
require 'runners/transactions/test'
|
@@ -26,21 +25,22 @@ def define_transactions_spec_tests(test_paths)
|
|
26
25
|
context(spec.description) do
|
27
26
|
|
28
27
|
define_spec_tests_with_requirements(spec) do |req|
|
28
|
+
|
29
29
|
spec.tests.each do |test|
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
context(test.description) do
|
32
|
+
|
33
|
+
before(:all) do
|
34
|
+
if ClusterConfig.instance.topology == :sharded
|
35
|
+
if test.multiple_mongoses? && SpecConfig.instance.addresses.length == 1
|
36
|
+
skip "Test requires multiple mongoses"
|
37
|
+
elsif !test.multiple_mongoses? && SpecConfig.instance.addresses.length > 1
|
38
|
+
# Many transaction spec tests that do not specifically deal with
|
39
|
+
# sharded transactions fail when run against a multi-mongos cluster
|
40
|
+
skip "Test does not specify multiple mongoses"
|
41
|
+
end
|
39
42
|
end
|
40
43
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context(test.description) do
|
44
44
|
|
45
45
|
if test.skip_reason
|
46
46
|
before(:all) do
|
@@ -21,23 +21,8 @@ module Mongo
|
|
21
21
|
arguments && arguments['session'] || object =~ /session/
|
22
22
|
end
|
23
23
|
|
24
|
-
def execute(target,
|
25
|
-
|
26
|
-
when 'session0'
|
27
|
-
session0
|
28
|
-
when 'session1'
|
29
|
-
session1
|
30
|
-
else
|
31
|
-
# active session could be nil
|
32
|
-
active_session
|
33
|
-
end
|
34
|
-
|
35
|
-
context = Context.new(
|
36
|
-
session0,
|
37
|
-
session1,
|
38
|
-
session)
|
39
|
-
|
40
|
-
op_name = Utils.underscore(name).to_sym
|
24
|
+
def execute(target, context)
|
25
|
+
op_name = ::Utils.underscore(name).to_sym
|
41
26
|
if op_name == :with_transaction
|
42
27
|
args = [target]
|
43
28
|
else
|
@@ -53,9 +38,14 @@ module Mongo
|
|
53
38
|
result['error'] = false
|
54
39
|
end
|
55
40
|
end
|
41
|
+
|
56
42
|
result
|
57
43
|
rescue Mongo::Error::OperationFailure => e
|
58
|
-
|
44
|
+
result = e.instance_variable_get(:@result)
|
45
|
+
if result.nil?
|
46
|
+
raise "OperationFailure had nil result: #{e}"
|
47
|
+
end
|
48
|
+
err_doc = result.send(:first_document)
|
59
49
|
error_code_name = err_doc['codeName'] || err_doc['writeConcernError'] && err_doc['writeConcernError']['codeName']
|
60
50
|
if error_code_name.nil?
|
61
51
|
# Sometimes the server does not return the error code name,
|
@@ -102,13 +92,13 @@ module Mongo
|
|
102
92
|
command_value = cmd.delete(command_name)
|
103
93
|
cmd = { command_name.to_sym => command_value }.merge(cmd)
|
104
94
|
|
105
|
-
opts = Utils.snakeize_hash(context
|
95
|
+
opts = ::Utils.snakeize_hash(transformed_options(context)).dup
|
106
96
|
opts[:read] = opts.delete(:read_preference)
|
107
97
|
database.command(cmd, opts).documents.first
|
108
98
|
end
|
109
99
|
|
110
100
|
def start_transaction(session, context)
|
111
|
-
session.start_transaction(Utils.convert_operation_options(arguments['options']))
|
101
|
+
session.start_transaction(::Utils.convert_operation_options(arguments['options']))
|
112
102
|
nil
|
113
103
|
end
|
114
104
|
|
@@ -128,7 +118,7 @@ module Mongo
|
|
128
118
|
end
|
129
119
|
|
130
120
|
if arguments['options']
|
131
|
-
options = Utils.snakeize_hash(arguments['options'])
|
121
|
+
options = ::Utils.snakeize_hash(arguments['options'])
|
132
122
|
else
|
133
123
|
options = nil
|
134
124
|
end
|
@@ -136,7 +126,7 @@ module Mongo
|
|
136
126
|
callback['operations'].each do |op_spec|
|
137
127
|
op = Operation.new(@crud_test, op_spec)
|
138
128
|
target = @crud_test.resolve_target(@crud_test.test_client, op)
|
139
|
-
rv = op.execute(target, context
|
129
|
+
rv = op.execute(target, context)
|
140
130
|
if rv && rv['exception']
|
141
131
|
raise rv['exception']
|
142
132
|
end
|
@@ -151,7 +141,7 @@ module Mongo
|
|
151
141
|
end
|
152
142
|
|
153
143
|
def targeted_fail_point(collection, context)
|
154
|
-
args = context
|
144
|
+
args = transformed_options(context)
|
155
145
|
session = args[:session]
|
156
146
|
unless session.pinned_server
|
157
147
|
raise ArgumentError, 'Targeted fail point requires session to be pinned to a server'
|
@@ -169,7 +159,7 @@ module Mongo
|
|
169
159
|
end
|
170
160
|
|
171
161
|
def assert_session_pinned(collection, context)
|
172
|
-
args = context
|
162
|
+
args = transformed_options(context)
|
173
163
|
session = args[:session]
|
174
164
|
unless session.pinned_server
|
175
165
|
raise ArgumentError, 'Expected session to be pinned'
|
@@ -177,12 +167,148 @@ module Mongo
|
|
177
167
|
end
|
178
168
|
|
179
169
|
def assert_session_unpinned(collection, context)
|
180
|
-
args = context
|
170
|
+
args = transformed_options(context)
|
181
171
|
session = args[:session]
|
182
172
|
if session.pinned_server
|
183
173
|
raise ArgumentError, 'Expected session to not be pinned'
|
184
174
|
end
|
185
175
|
end
|
176
|
+
|
177
|
+
def wait_for_event(client, context)
|
178
|
+
deadline = Time.now + 5
|
179
|
+
loop do
|
180
|
+
events = _select_events(context)
|
181
|
+
if events.length >= arguments['count']
|
182
|
+
break
|
183
|
+
end
|
184
|
+
if Time.now >= deadline
|
185
|
+
raise "Did not receive an event matching #{arguments} in 5 seconds; received #{events.length} but expected #{arguments['count']} events"
|
186
|
+
else
|
187
|
+
sleep 0.1
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def assert_event_count(client, context)
|
193
|
+
events = _select_events(context)
|
194
|
+
unless events.length == arguments['count']
|
195
|
+
raise "Exppected #{arguments['count']} #{arguments['event']} events, but have #{events.length}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def _select_events(context)
|
200
|
+
case arguments['event']
|
201
|
+
when 'ServerMarkedUnknownEvent'
|
202
|
+
context.sdam_subscriber.all_events.select do |event|
|
203
|
+
event.is_a?(Mongo::Monitoring::Event::ServerDescriptionChanged) &&
|
204
|
+
event.new_description.unknown?
|
205
|
+
end
|
206
|
+
else
|
207
|
+
context.sdam_subscriber.all_events.select do |event|
|
208
|
+
event.class.name.sub(/.*::/, '') == arguments['event'].sub(/Event$/, '')
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
class ThreadContext
|
214
|
+
def initialize
|
215
|
+
@operations = Queue.new
|
216
|
+
@unexpected_operation_results = []
|
217
|
+
end
|
218
|
+
|
219
|
+
def stop?
|
220
|
+
!!@stop
|
221
|
+
end
|
222
|
+
|
223
|
+
def signal_stop
|
224
|
+
@stop = true
|
225
|
+
end
|
226
|
+
|
227
|
+
attr_reader :operations
|
228
|
+
attr_reader :unexpected_operation_results
|
229
|
+
end
|
230
|
+
|
231
|
+
def start_thread(client, context)
|
232
|
+
thread_context = ThreadContext.new
|
233
|
+
thread = Thread.new do
|
234
|
+
loop do
|
235
|
+
begin
|
236
|
+
op_spec = thread_context.operations.pop(true)
|
237
|
+
op = Operation.new(@crud_test, op_spec)
|
238
|
+
target = @crud_test.resolve_target(@crud_test.test_client, op)
|
239
|
+
result = op.execute(target, context)
|
240
|
+
if op_spec['error']
|
241
|
+
unless result['error']
|
242
|
+
thread_context.unexpected_operation_results << result
|
243
|
+
end
|
244
|
+
else
|
245
|
+
if result['error']
|
246
|
+
thread_context.unexpected_operation_results << result
|
247
|
+
end
|
248
|
+
end
|
249
|
+
rescue ThreadError
|
250
|
+
# Queue is empty
|
251
|
+
end
|
252
|
+
if thread_context.stop?
|
253
|
+
break
|
254
|
+
else
|
255
|
+
sleep 1
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
class << thread
|
260
|
+
attr_accessor :context
|
261
|
+
end
|
262
|
+
thread.context = thread_context
|
263
|
+
unless context.threads
|
264
|
+
context.threads ||= {}
|
265
|
+
end
|
266
|
+
context.threads[arguments['name']] = thread
|
267
|
+
end
|
268
|
+
|
269
|
+
def run_on_thread(client, context)
|
270
|
+
thread = context.threads.fetch(arguments['name'])
|
271
|
+
thread.context.operations << arguments['operation']
|
272
|
+
end
|
273
|
+
|
274
|
+
def wait_for_thread(client, context)
|
275
|
+
thread = context.threads.fetch(arguments['name'])
|
276
|
+
thread.context.signal_stop
|
277
|
+
thread.join
|
278
|
+
unless thread.context.unexpected_operation_results.empty?
|
279
|
+
raise "Thread #{arguments['name']} had #{thread.context.unexpected_operation_results}.length unexpected operation results"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def wait(client, context)
|
284
|
+
sleep arguments['ms'] / 1000.0
|
285
|
+
end
|
286
|
+
|
287
|
+
def record_primary(client, context)
|
288
|
+
context.primary_address = client.cluster.next_primary.address
|
289
|
+
end
|
290
|
+
|
291
|
+
def run_admin_command(support_client, context)
|
292
|
+
support_client.use('admin').database.command(arguments['command'])
|
293
|
+
end
|
294
|
+
|
295
|
+
def wait_for_primary_change(client, context)
|
296
|
+
timeout = if arguments['timeoutMS']
|
297
|
+
arguments['timeoutMS'] / 1000.0
|
298
|
+
else
|
299
|
+
10
|
300
|
+
end
|
301
|
+
deadline = Time.now + timeout
|
302
|
+
loop do
|
303
|
+
client.cluster.scan!
|
304
|
+
if client.cluster.next_primary.address != context.primary_address
|
305
|
+
break
|
306
|
+
end
|
307
|
+
if Time.now >= deadline
|
308
|
+
raise "Failed to change primary in #{timeout} seconds"
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
186
312
|
end
|
187
313
|
end
|
188
314
|
end
|