mongo 2.11.4 → 2.12.3
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/CONTRIBUTING.md +1 -1
- data/README.md +2 -1
- data/lib/mongo.rb +3 -0
- data/lib/mongo/address.rb +44 -19
- data/lib/mongo/auth.rb +1 -0
- data/lib/mongo/auth/credential_cache.rb +51 -0
- data/lib/mongo/auth/scram/conversation.rb +20 -16
- data/lib/mongo/auth/user.rb +0 -8
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/background_thread.rb +1 -1
- data/lib/mongo/bulk_write.rb +5 -5
- data/lib/mongo/client.rb +143 -14
- data/lib/mongo/client_encryption.rb +103 -0
- data/lib/mongo/cluster.rb +8 -4
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
- data/lib/mongo/cluster/sdam_flow.rb +54 -58
- data/lib/mongo/collection.rb +3 -3
- data/lib/mongo/collection/view.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +12 -3
- data/lib/mongo/collection/view/iterable.rb +14 -5
- data/lib/mongo/collection/view/map_reduce.rb +2 -2
- data/lib/mongo/collection/view/readable.rb +9 -7
- data/lib/mongo/collection/view/writable.rb +7 -7
- data/lib/mongo/crypt.rb +33 -0
- data/lib/mongo/crypt/auto_decryption_context.rb +40 -0
- data/lib/mongo/crypt/auto_encrypter.rb +179 -0
- data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
- data/lib/mongo/crypt/binary.rb +155 -0
- data/lib/mongo/crypt/binding.rb +1229 -0
- data/lib/mongo/crypt/context.rb +135 -0
- data/lib/mongo/crypt/data_key_context.rb +162 -0
- data/lib/mongo/crypt/encryption_io.rb +289 -0
- data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
- data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
- data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
- data/lib/mongo/crypt/handle.rb +315 -0
- data/lib/mongo/crypt/hooks.rb +90 -0
- data/lib/mongo/crypt/kms_context.rb +67 -0
- data/lib/mongo/crypt/status.rb +131 -0
- data/lib/mongo/cursor.rb +64 -32
- data/lib/mongo/database.rb +23 -6
- data/lib/mongo/database/view.rb +13 -4
- data/lib/mongo/dbref.rb +9 -2
- data/lib/mongo/error.rb +5 -1
- data/lib/mongo/error/bulk_write_error.rb +16 -14
- data/lib/mongo/error/crypt_error.rb +31 -0
- data/lib/mongo/error/{failed_stringprep_validation.rb → failed_string_prep_validation.rb} +0 -0
- data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
- data/lib/mongo/error/kms_error.rb +22 -0
- data/lib/mongo/error/max_bson_size.rb +14 -3
- data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
- data/lib/mongo/error/no_server_available.rb +8 -3
- data/lib/mongo/error/notable.rb +0 -15
- data/lib/mongo/error/operation_failure.rb +1 -0
- data/lib/mongo/error/parser.rb +1 -1
- data/lib/mongo/grid/file.rb +5 -0
- data/lib/mongo/grid/file/chunk.rb +2 -0
- data/lib/mongo/grid/file/info.rb +3 -2
- 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 -3
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -1
- data/lib/mongo/monitoring/event/command_started.rb +6 -1
- data/lib/mongo/operation/collections_info.rb +6 -3
- data/lib/mongo/operation/delete/op_msg.rb +1 -1
- data/lib/mongo/operation/find/op_msg.rb +4 -1
- data/lib/mongo/operation/get_more/op_msg.rb +4 -1
- data/lib/mongo/operation/insert/command.rb +3 -2
- data/lib/mongo/operation/insert/legacy.rb +3 -2
- data/lib/mongo/operation/insert/op_msg.rb +3 -3
- data/lib/mongo/operation/result.rb +36 -27
- data/lib/mongo/operation/shared/executable.rb +11 -9
- data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_find_command.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +2 -2
- data/lib/mongo/operation/shared/read_preference_supported.rb +68 -19
- data/lib/mongo/operation/shared/response_handling.rb +1 -1
- data/lib/mongo/operation/shared/sessions_supported.rb +44 -3
- data/lib/mongo/operation/shared/write.rb +17 -10
- data/lib/mongo/operation/update/op_msg.rb +1 -1
- data/lib/mongo/protocol/bit_vector.rb +2 -1
- data/lib/mongo/protocol/compressed.rb +6 -5
- data/lib/mongo/protocol/insert.rb +3 -1
- data/lib/mongo/protocol/message.rb +94 -15
- data/lib/mongo/protocol/msg.rb +207 -37
- data/lib/mongo/protocol/query.rb +7 -9
- data/lib/mongo/protocol/serializers.rb +43 -15
- data/lib/mongo/retryable.rb +1 -1
- data/lib/mongo/server.rb +10 -4
- data/lib/mongo/server/connection.rb +20 -9
- data/lib/mongo/server/connection_base.rb +118 -18
- data/lib/mongo/server/connection_common.rb +61 -0
- data/lib/mongo/server/connection_pool.rb +37 -1
- data/lib/mongo/server/connection_pool/populator.rb +1 -1
- data/lib/mongo/server/description.rb +9 -11
- data/lib/mongo/server/monitor.rb +2 -0
- data/lib/mongo/server/monitor/connection.rb +3 -18
- data/lib/mongo/server/pending_connection.rb +2 -1
- data/lib/mongo/session.rb +3 -3
- data/lib/mongo/session/session_pool.rb +8 -3
- data/lib/mongo/socket.rb +29 -16
- data/lib/mongo/socket/ssl.rb +23 -8
- data/lib/mongo/socket/tcp.rb +12 -3
- data/lib/mongo/srv/monitor.rb +73 -42
- data/lib/mongo/srv/result.rb +0 -1
- data/lib/mongo/timeout.rb +49 -0
- data/lib/mongo/uri.rb +30 -1
- data/lib/mongo/uri/srv_protocol.rb +1 -1
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -3
- data/spec/README.md +228 -7
- data/spec/integration/auth_spec.rb +53 -0
- data/spec/integration/bulk_write_spec.rb +19 -0
- data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
- data/spec/integration/client_construction_spec.rb +100 -1
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +353 -0
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +303 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +72 -0
- data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +79 -0
- data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +221 -0
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +601 -0
- data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +187 -0
- data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +78 -0
- data/spec/integration/client_side_encryption/client_close_spec.rb +63 -0
- data/spec/integration/client_side_encryption/corpus_spec.rb +233 -0
- data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
- data/spec/integration/client_side_encryption/data_key_spec.rb +165 -0
- data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
- data/spec/integration/client_side_encryption/external_key_vault_spec.rb +141 -0
- data/spec/integration/client_side_encryption/views_spec.rb +44 -0
- data/spec/integration/client_update_spec.rb +154 -0
- data/spec/integration/command_monitoring_spec.rb +3 -1
- data/spec/integration/command_spec.rb +44 -10
- data/spec/integration/connection_spec.rb +57 -0
- data/spec/integration/crud_spec.rb +89 -0
- data/spec/integration/grid_fs_bucket_spec.rb +48 -0
- data/spec/integration/read_preference_spec.rb +26 -0
- data/spec/integration/reconnect_spec.rb +7 -6
- data/spec/integration/size_limit_spec.rb +111 -0
- data/spec/integration/srv_monitoring_spec.rb +16 -8
- data/spec/integration/zlib_compression_spec.rb +25 -0
- data/spec/kerberos/kerberos_spec.rb +87 -0
- data/spec/lite_spec_helper.rb +34 -29
- data/spec/mongo/auth/cr_spec.rb +8 -0
- data/spec/mongo/auth/ldap_spec.rb +5 -1
- data/spec/mongo/auth/scram/conversation_spec.rb +5 -6
- data/spec/mongo/auth/scram/negotiation_spec.rb +74 -75
- data/spec/mongo/auth/scram_spec.rb +45 -35
- data/spec/mongo/auth/user/view_spec.rb +3 -6
- data/spec/mongo/auth/x509_spec.rb +5 -1
- data/spec/mongo/bulk_write/result_spec.rb +11 -7
- data/spec/mongo/client_construction_spec.rb +206 -2
- data/spec/mongo/client_encryption_spec.rb +405 -0
- data/spec/mongo/cluster/cursor_reaper_spec.rb +12 -8
- data/spec/mongo/cluster/socket_reaper_spec.rb +14 -3
- data/spec/mongo/collection/view/aggregation_spec.rb +0 -2
- data/spec/mongo/collection/view/change_stream_spec.rb +7 -7
- data/spec/mongo/collection/view/map_reduce_spec.rb +3 -3
- data/spec/mongo/collection/view_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +28 -9
- data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
- data/spec/mongo/crypt/auto_encrypter_spec.rb +187 -0
- data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
- data/spec/mongo/crypt/binary_spec.rb +115 -0
- data/spec/mongo/crypt/binding/binary_spec.rb +56 -0
- data/spec/mongo/crypt/binding/context_spec.rb +257 -0
- data/spec/mongo/crypt/binding/helpers_spec.rb +46 -0
- data/spec/mongo/crypt/binding/mongocrypt_spec.rb +144 -0
- data/spec/mongo/crypt/binding/status_spec.rb +99 -0
- data/spec/mongo/crypt/binding/version_spec.rb +22 -0
- data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
- data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
- data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
- data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
- data/spec/mongo/crypt/handle_spec.rb +232 -0
- data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
- data/spec/mongo/crypt/status_spec.rb +152 -0
- data/spec/mongo/cursor_spec.rb +24 -4
- data/spec/mongo/database_spec.rb +20 -0
- data/spec/mongo/error/bulk_write_error_spec.rb +49 -0
- data/spec/mongo/error/crypt_error_spec.rb +26 -0
- data/spec/mongo/error/max_bson_size_spec.rb +35 -0
- data/spec/mongo/error/no_server_available_spec.rb +11 -1
- data/spec/mongo/error/notable_spec.rb +59 -0
- data/spec/mongo/error/operation_failure_spec.rb +6 -6
- data/spec/mongo/operation/aggregate_spec.rb +1 -1
- data/spec/mongo/operation/collections_info_spec.rb +1 -1
- data/spec/mongo/operation/command_spec.rb +3 -3
- data/spec/mongo/operation/create_index_spec.rb +3 -3
- data/spec/mongo/operation/create_user_spec.rb +3 -3
- data/spec/mongo/operation/delete/bulk_spec.rb +6 -6
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -6
- data/spec/mongo/operation/delete_spec.rb +7 -7
- data/spec/mongo/operation/drop_index_spec.rb +2 -2
- data/spec/mongo/operation/find/legacy_spec.rb +2 -1
- data/spec/mongo/operation/get_more_spec.rb +1 -1
- data/spec/mongo/operation/indexes_spec.rb +1 -1
- data/spec/mongo/operation/insert/bulk_spec.rb +7 -7
- data/spec/mongo/operation/insert/op_msg_spec.rb +3 -6
- data/spec/mongo/operation/insert_spec.rb +12 -12
- data/spec/mongo/operation/map_reduce_spec.rb +2 -2
- data/spec/mongo/operation/read_preference_legacy_spec.rb +351 -0
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +194 -0
- data/spec/mongo/operation/remove_user_spec.rb +3 -3
- data/spec/mongo/operation/update/bulk_spec.rb +6 -6
- data/spec/mongo/operation/update/op_msg_spec.rb +3 -6
- data/spec/mongo/operation/update_spec.rb +7 -7
- data/spec/mongo/operation/update_user_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +2 -3
- data/spec/mongo/protocol/delete_spec.rb +9 -8
- data/spec/mongo/protocol/get_more_spec.rb +9 -8
- data/spec/mongo/protocol/insert_spec.rb +9 -8
- data/spec/mongo/protocol/kill_cursors_spec.rb +6 -5
- data/spec/mongo/protocol/msg_spec.rb +57 -53
- data/spec/mongo/protocol/query_spec.rb +12 -12
- data/spec/mongo/protocol/registry_spec.rb +1 -1
- data/spec/mongo/protocol/reply_spec.rb +1 -1
- data/spec/mongo/protocol/update_spec.rb +10 -9
- data/spec/mongo/server/connection_pool_spec.rb +1 -1
- data/spec/mongo/server/connection_spec.rb +28 -7
- data/spec/mongo/socket_spec.rb +1 -1
- data/spec/mongo/srv/monitor_spec.rb +88 -69
- data/spec/mongo/timeout_spec.rb +85 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +2 -2
- data/spec/mongo/uri_spec.rb +52 -5
- data/spec/mongo/write_concern_spec.rb +13 -1
- data/spec/{support → runners}/auth.rb +14 -1
- data/spec/{support → runners}/change_streams.rb +1 -1
- data/spec/{support → runners}/change_streams/operation.rb +0 -0
- data/spec/{support → runners}/cmap.rb +1 -1
- data/spec/{support → runners}/cmap/verifier.rb +0 -0
- data/spec/{support → runners}/command_monitoring.rb +0 -0
- data/spec/runners/connection_string.rb +358 -4
- data/spec/{support → runners}/crud.rb +9 -9
- data/spec/{support → runners}/crud/context.rb +0 -0
- data/spec/{support → runners}/crud/operation.rb +7 -3
- data/spec/{support → runners}/crud/outcome.rb +0 -0
- data/spec/{support → runners}/crud/requirement.rb +1 -1
- data/spec/{support → runners}/crud/spec.rb +12 -1
- data/spec/{support → runners}/crud/test.rb +0 -0
- data/spec/{support → runners}/crud/test_base.rb +0 -0
- data/spec/{support → runners}/crud/verifier.rb +10 -12
- data/spec/{support → runners}/gridfs.rb +0 -0
- data/spec/{support → runners}/sdam_monitoring.rb +0 -0
- data/spec/{support → runners}/server_discovery_and_monitoring.rb +0 -0
- data/spec/{support → runners}/server_selection.rb +0 -0
- data/spec/{support → runners}/server_selection_rtt.rb +0 -0
- data/spec/{support → runners}/transactions.rb +9 -11
- data/spec/{support → runners}/transactions/context.rb +0 -0
- data/spec/{support → runners}/transactions/operation.rb +0 -0
- data/spec/{support → runners}/transactions/spec.rb +0 -0
- data/spec/{support → runners}/transactions/test.rb +37 -5
- data/spec/spec_helper.rb +0 -5
- data/spec/spec_tests/auth_spec.rb +3 -3
- data/spec/spec_tests/client_side_encryption_spec.rb +8 -0
- data/spec/spec_tests/connection_string_spec.rb +1 -1
- data/spec/spec_tests/data/auth/connection-string.yml +13 -0
- data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
- data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
- data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
- data/spec/spec_tests/data/client_side_encryption/bulk.yml +88 -0
- data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
- data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
- data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
- data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
- data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
- data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
- data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
- data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
- data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
- data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
- data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
- data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
- data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
- data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
- data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
- data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +64 -0
- data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
- data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
- data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
- data/spec/spec_tests/data/client_side_encryption/updateOne.yml +171 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +1 -4
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +21 -0
- data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -4
- data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +1 -1
- data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
- data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +1 -2
- data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
- data/spec/spec_tests/data/sdam/rs/{primary_address_change.yml → ruby_primary_address_change.yml} +2 -0
- data/spec/spec_tests/data/sdam/rs/{secondary_wrong_set_name_with_primary_second.yml → ruby_secondary_wrong_set_name_with_primary_second.yml} +0 -0
- data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +27 -0
- data/spec/spec_tests/data/sdam/sharded/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
- data/spec/spec_tests/data/sdam/sharded/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
- data/spec/spec_tests/data/sdam/single/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
- data/spec/spec_tests/data/sdam/single/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
- data/spec/spec_tests/data/sdam_monitoring/{replica_set_with_primary_change.yml → replica_set_primary_address_change.yml} +27 -5
- data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +26 -74
- data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +20 -16
- data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
- data/spec/spec_tests/data/transactions/pin-mongos.yml +2 -3
- data/spec/spec_tests/data/uri_options/auth-options.yml +10 -0
- data/spec/spec_tests/data/uri_options/tls-options.yml +75 -4
- data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
- data/spec/spec_tests/uri_options_spec.rb +6 -8
- data/spec/stress/connection_pool_timing_spec.rb +6 -3
- data/spec/support/certificates/README.md +4 -0
- data/spec/support/certificates/server-second-level-bundle.pem +77 -77
- data/spec/support/certificates/server-second-level.crt +52 -52
- data/spec/support/certificates/server-second-level.key +25 -25
- data/spec/support/certificates/server-second-level.pem +77 -77
- data/spec/support/client_registry.rb +19 -3
- data/spec/support/cluster_config.rb +9 -1
- data/spec/support/cluster_tools.rb +6 -1
- data/spec/support/common_shortcuts.rb +12 -0
- data/spec/support/constraints.rb +16 -0
- data/spec/support/crypt.rb +154 -0
- data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
- data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
- data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
- data/spec/support/crypt/corpus/corpus.json +3657 -0
- data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
- data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
- data/spec/support/crypt/data_keys/key_document_local.json +31 -0
- data/spec/support/crypt/external/external-key.json +31 -0
- data/spec/support/crypt/external/external-schema.json +19 -0
- data/spec/support/crypt/limits/limits-doc.json +102 -0
- data/spec/support/crypt/limits/limits-key.json +31 -0
- data/spec/support/crypt/limits/limits-schema.json +1405 -0
- data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
- data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/lite_constraints.rb +19 -1
- data/spec/support/matchers.rb +19 -0
- data/spec/support/shared/protocol.rb +2 -0
- data/spec/support/spec_config.rb +53 -13
- data/spec/support/utils.rb +140 -10
- metadata +894 -687
- metadata.gz.sig +0 -0
- data/lib/mongo/cluster/srv_monitor.rb +0 -127
- data/lib/mongo/srv/warning_result.rb +0 -35
- data/spec/enterprise_auth/kerberos_spec.rb +0 -58
- data/spec/mongo/cluster/srv_monitor_spec.rb +0 -214
- data/spec/mongo/operation/read_preference_spec.rb +0 -245
- data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
- data/spec/support/connection_string.rb +0 -354
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'GridFS bucket integration' do
|
4
|
+
let(:fs) do
|
5
|
+
authorized_client.database.fs
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'UTF-8 string write' do
|
9
|
+
let(:data) { "hello\u2210" }
|
10
|
+
|
11
|
+
before do
|
12
|
+
data.length.should_not == data.bytesize
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples 'round-trips' do
|
16
|
+
it 'round-trips' do
|
17
|
+
stream = fs.open_upload_stream('test') do |stream|
|
18
|
+
stream.write(data_to_write)
|
19
|
+
end
|
20
|
+
|
21
|
+
actual = nil
|
22
|
+
fs.open_download_stream(stream.file_id) do |stream|
|
23
|
+
actual = stream.read
|
24
|
+
end
|
25
|
+
|
26
|
+
actual.encoding.name.should == 'ASCII-8BIT'
|
27
|
+
actual.should == data.dup.force_encoding('binary')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'in binary encoding' do
|
32
|
+
let(:data_to_write) do
|
33
|
+
data.force_encoding('binary').freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like 'round-trips'
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'in UTF-8 encoding' do
|
40
|
+
let(:data_to_write) do
|
41
|
+
data.encoding.name.should == 'UTF-8'
|
42
|
+
data.freeze
|
43
|
+
end
|
44
|
+
|
45
|
+
it_behaves_like 'round-trips'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -482,4 +482,30 @@ describe 'Read preference' do
|
|
482
482
|
end
|
483
483
|
end
|
484
484
|
end
|
485
|
+
|
486
|
+
context 'secondary read with direct connection' do
|
487
|
+
require_topology :replica_set
|
488
|
+
|
489
|
+
let(:address_str) do
|
490
|
+
Mongo::ServerSelector.get(mode: :secondary).
|
491
|
+
select_server(authorized_client.cluster).address.seed
|
492
|
+
end
|
493
|
+
|
494
|
+
let(:secondary_client) do
|
495
|
+
new_local_client([address_str],
|
496
|
+
SpecConfig.instance.all_test_options.merge(connect: :direct))
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'succeeds without read preference' do
|
500
|
+
secondary_client['foo'].find.to_a
|
501
|
+
end
|
502
|
+
|
503
|
+
it 'succeeds with read preference: secondary' do
|
504
|
+
secondary_client['foo', {read: {mode: :secondary}}].find.to_a
|
505
|
+
end
|
506
|
+
|
507
|
+
it 'succeeds with read preference: primary' do
|
508
|
+
secondary_client['foo', {read: {mode: :primary}}].find.to_a
|
509
|
+
end
|
510
|
+
end
|
485
511
|
end
|
@@ -54,9 +54,7 @@ describe 'Client after reconnect' do
|
|
54
54
|
context 'SRV monitor thread' do
|
55
55
|
|
56
56
|
let(:uri) do
|
57
|
-
"mongodb+srv://test1.test.build.10gen.cc/?tls=#{SpecConfig.instance.ssl?}
|
58
|
-
puts "Constructed URI: #{uri}"
|
59
|
-
end
|
57
|
+
"mongodb+srv://test1.test.build.10gen.cc/?tls=#{SpecConfig.instance.ssl?}"
|
60
58
|
end
|
61
59
|
|
62
60
|
# Debug logging to troubleshoot failures in Evergreen
|
@@ -68,8 +66,8 @@ describe 'Client after reconnect' do
|
|
68
66
|
|
69
67
|
let(:client) do
|
70
68
|
ClientRegistry.instance.register_local_client(
|
71
|
-
Mongo::Client.new(uri,
|
72
|
-
logger: logger))
|
69
|
+
Mongo::Client.new(uri, SpecConfig.instance.ssl_options.merge(
|
70
|
+
server_selection_timeout: 3.86, logger: logger)))
|
73
71
|
end
|
74
72
|
|
75
73
|
let(:wait_for_discovery) do
|
@@ -134,7 +132,10 @@ describe 'Client after reconnect' do
|
|
134
132
|
|
135
133
|
let(:client) do
|
136
134
|
ClientRegistry.instance.register_local_client(
|
137
|
-
Mongo::Client.new(uri,
|
135
|
+
Mongo::Client.new(uri,
|
136
|
+
timeout: 5,
|
137
|
+
connect_timeout: 5,
|
138
|
+
server_selection_timeout: 3.89,
|
138
139
|
resolv_options: {
|
139
140
|
nameserver: 'localhost',
|
140
141
|
nameserver_port: [['localhost', 5300], ['127.0.0.1', 5300]],
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'BSON & command size limits' do
|
4
|
+
let(:max_document_size) { 16*1024*1024 }
|
5
|
+
|
6
|
+
before do
|
7
|
+
authorized_collection.delete_many
|
8
|
+
end
|
9
|
+
|
10
|
+
# This test uses a large document that is significantly smaller than the
|
11
|
+
# size limit. It is a basic sanity check.
|
12
|
+
it 'allows user-provided documents to be 15MiB' do
|
13
|
+
document = { key: 'a' * 15*1024*1024, _id: 'foo' }
|
14
|
+
|
15
|
+
authorized_collection.insert_one(document)
|
16
|
+
end
|
17
|
+
|
18
|
+
# This test uses a large document that is significantly larger than the
|
19
|
+
# size limit. It is a basic sanity check.
|
20
|
+
it 'fails single write of oversized documents' do
|
21
|
+
document = { key: 'a' * 17*1024*1024, _id: 'foo' }
|
22
|
+
|
23
|
+
lambda do
|
24
|
+
authorized_collection.insert_one(document)
|
25
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
26
|
+
end
|
27
|
+
|
28
|
+
# This test checks our bulk write splitting when documents are not close
|
29
|
+
# to the limit, but where splitting is definitely required.
|
30
|
+
it 'allows split bulk write of medium sized documents' do
|
31
|
+
# 8 documents of 4 MiB each = 32 MiB total data, should be split over
|
32
|
+
# either 2 or 3 bulk writes depending on how well the driver splits
|
33
|
+
documents = []
|
34
|
+
1.upto(8) do |index|
|
35
|
+
documents << { key: 'a' * 4*1024*1024, _id: "in#{index}" }
|
36
|
+
end
|
37
|
+
|
38
|
+
authorized_collection.insert_many(documents)
|
39
|
+
authorized_collection.count_documents({}).should == 8
|
40
|
+
end
|
41
|
+
|
42
|
+
# This test ensures that document which are too big definitely fail insertion.
|
43
|
+
it 'fails bulk write of oversized documents' do
|
44
|
+
documents = []
|
45
|
+
1.upto(3) do |index|
|
46
|
+
documents << { key: 'a' * 17*1024*1024, _id: "in#{index}" }
|
47
|
+
end
|
48
|
+
|
49
|
+
lambda do
|
50
|
+
authorized_collection.insert_many(documents)
|
51
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
52
|
+
authorized_collection.count_documents({}).should == 0
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'allows user-provided documents to be exactly 16MiB' do
|
56
|
+
# The document must contain the _id field, otherwise the server will
|
57
|
+
# add it which will increase the size of the document as persisted by
|
58
|
+
# the server.
|
59
|
+
document = { key: 'a' * (max_document_size - 28), _id: 'foo' }
|
60
|
+
expect(document.to_bson.length).to eq(max_document_size)
|
61
|
+
|
62
|
+
authorized_collection.insert_one(document)
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'on server versions >= 3.6' do
|
66
|
+
min_server_fcv '3.6'
|
67
|
+
|
68
|
+
it 'fails on the driver when a document larger than 16MiB is inserted' do
|
69
|
+
document = { key: 'a' * (max_document_size - 27), _id: 'foo' }
|
70
|
+
expect(document.to_bson.length).to eq(max_document_size+1)
|
71
|
+
|
72
|
+
lambda do
|
73
|
+
authorized_collection.insert_one(document)
|
74
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'on server versions <= 3.4' do
|
79
|
+
max_server_fcv '3.4'
|
80
|
+
|
81
|
+
it 'fails on the server when a document larger than 16MiB is inserted' do
|
82
|
+
document = { key: 'a' * (max_document_size - 27), _id: 'foo' }
|
83
|
+
expect(document.to_bson.length).to eq(max_document_size+1)
|
84
|
+
|
85
|
+
lambda do
|
86
|
+
authorized_collection.insert_one(document)
|
87
|
+
end.should raise_error(Mongo::Error::OperationFailure, /object to insert too large/)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'fails in the driver when a document larger than 16MiB+16KiB is inserted' do
|
92
|
+
document = { key: 'a' * (max_document_size - 27 + 16*1024), _id: 'foo' }
|
93
|
+
expect(document.to_bson.length).to eq(max_document_size+16*1024+1)
|
94
|
+
|
95
|
+
lambda do
|
96
|
+
authorized_collection.insert_one(document)
|
97
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'allows bulk writes of multiple documents of exactly 16 MiB each' do
|
101
|
+
documents = []
|
102
|
+
1.upto(3) do |index|
|
103
|
+
document = { key: 'a' * (max_document_size - 28), _id: "in#{index}" }
|
104
|
+
expect(document.to_bson.length).to eq(max_document_size)
|
105
|
+
documents << document
|
106
|
+
end
|
107
|
+
|
108
|
+
authorized_collection.insert_many(documents)
|
109
|
+
authorized_collection.count_documents({}).should == 3
|
110
|
+
end
|
111
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'SRV Monitoring' do
|
4
|
+
clean_slate_for_all
|
5
|
+
|
4
6
|
context 'with SRV lookups mocked at Resolver' do
|
5
7
|
let(:srv_result) do
|
6
8
|
double('srv result').tap do |result|
|
@@ -51,7 +53,7 @@ describe 'SRV Monitoring' do
|
|
51
53
|
|
52
54
|
expect(client.cluster.topology).to be_a(Mongo::Cluster::Topology::Sharded)
|
53
55
|
|
54
|
-
expect(client.cluster.instance_variable_get('@srv_monitor')).to be_a(Mongo::
|
56
|
+
expect(client.cluster.instance_variable_get('@srv_monitor')).to be_a(Mongo::Srv::Monitor)
|
55
57
|
|
56
58
|
# Close the client in the test rather than allowing our post-test cleanup
|
57
59
|
# to take care of it, since the client references test doubles.
|
@@ -84,18 +86,22 @@ describe 'SRV Monitoring' do
|
|
84
86
|
|
85
87
|
let(:client) do
|
86
88
|
new_local_client(uri,
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
SpecConfig.instance.ssl_options.merge(
|
90
|
+
server_selection_timeout: 3.16,
|
91
|
+
timeout: 8.11,
|
92
|
+
connect_timeout: 8.12,
|
93
|
+
resolv_options: {
|
94
|
+
nameserver: 'localhost',
|
95
|
+
nameserver_port: [['localhost', 5300], ['127.0.0.1', 5300]],
|
96
|
+
},
|
97
|
+
logger: logger,
|
98
|
+
),
|
93
99
|
)
|
94
100
|
end
|
95
101
|
|
96
102
|
before do
|
97
103
|
# Expedite the polling process
|
98
|
-
allow_any_instance_of(Mongo::
|
104
|
+
allow_any_instance_of(Mongo::Srv::Monitor).to receive(:scan_interval).and_return(1)
|
99
105
|
end
|
100
106
|
|
101
107
|
context 'sharded cluster' do
|
@@ -352,6 +358,8 @@ describe 'SRV Monitoring' do
|
|
352
358
|
# Covers both NoPrimary and WithPrimary replica sets
|
353
359
|
expect(client.cluster.topology).to be_a(Mongo::Cluster::Topology::ReplicaSetNoPrimary)
|
354
360
|
|
361
|
+
# give the thread another moment to stop
|
362
|
+
sleep 0.1
|
355
363
|
expect(client.cluster.srv_monitor).not_to be_running
|
356
364
|
end
|
357
365
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Zlib compression' do
|
4
|
+
require_compression
|
5
|
+
|
6
|
+
before do
|
7
|
+
authorized_client['test'].drop
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when client has zlib compressor option enabled' do
|
11
|
+
it 'compresses the message to the server' do
|
12
|
+
# Double check that the client has zlib compression enabled
|
13
|
+
expect(authorized_client.options[:compressors]).to include('zlib')
|
14
|
+
|
15
|
+
expect(Mongo::Protocol::Compressed).to receive(:new).twice.and_call_original
|
16
|
+
expect(Zlib::Deflate).to receive(:deflate).twice.and_call_original
|
17
|
+
expect(Zlib::Inflate).to receive(:inflate).twice.and_call_original
|
18
|
+
|
19
|
+
authorized_client['test'].insert_one(_id: 1, text: 'hello world')
|
20
|
+
document = authorized_client['test'].find(_id: 1).first
|
21
|
+
|
22
|
+
expect(document['text']).to eq('hello world')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'lite_spec_helper'
|
2
|
+
|
3
|
+
describe 'kerberos authentication' do
|
4
|
+
require_mongo_kerberos
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
unless %w(1 yes true).include?(ENV['MONGO_RUBY_DRIVER_KERBEROS_INTEGRATION']&.downcase)
|
8
|
+
skip "Set MONGO_RUBY_DRIVER_KERBEROS_INTEGRATION=1 in environment to run the Kerberos integration tests"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def require_env_value(key)
|
13
|
+
ENV[key].tap do |value|
|
14
|
+
if value.nil? || value.empty?
|
15
|
+
raise "Value for key #{key} is not present in environment as required"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:user) do
|
21
|
+
"#{require_env_value('SASL_USER')}%40#{require_env_value('SASL_HOST').upcase}"
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:host) do
|
25
|
+
"#{require_env_value('SASL_HOST')}"
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:kerberos_db) do
|
29
|
+
"#{require_env_value('KERBEROS_DB')}"
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:auth_source) do
|
33
|
+
"#{require_env_value('SASL_DB')}"
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:uri) do
|
37
|
+
uri = "mongodb://#{user}@#{host}/#{kerberos_db}?authMechanism=GSSAPI&authSource=#{auth_source}"
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:client) do
|
41
|
+
Mongo::Client.new(uri, server_selection_timeout: 6.31)
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:doc) do
|
45
|
+
client.database[:test].find.first
|
46
|
+
end
|
47
|
+
|
48
|
+
shared_examples_for 'correctly authenticates' do
|
49
|
+
it 'correctly authenticates' do
|
50
|
+
expect(doc['kerberos']).to eq(true)
|
51
|
+
expect(doc['authenticated']).to eq('yeah')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it_behaves_like 'correctly authenticates'
|
56
|
+
|
57
|
+
context 'when host is lowercased' do
|
58
|
+
let(:host) do
|
59
|
+
"#{require_env_value('SASL_HOST').downcase}"
|
60
|
+
end
|
61
|
+
|
62
|
+
it_behaves_like 'correctly authenticates'
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when host is uppercased' do
|
66
|
+
let(:host) do
|
67
|
+
"#{require_env_value('SASL_HOST').upcase}"
|
68
|
+
end
|
69
|
+
|
70
|
+
it_behaves_like 'correctly authenticates'
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when canonicalize_host_name is true' do
|
74
|
+
let(:host) do
|
75
|
+
"#{require_env_value('IP_ADDR')}"
|
76
|
+
end
|
77
|
+
|
78
|
+
let(:uri) do
|
79
|
+
uri = "mongodb://#{user}@#{host}/#{kerberos_db}?authMechanism=GSSAPI&authSource=#{auth_source}&authMechanismProperties=CANONICALIZE_HOST_NAME:true"
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'correctly authenticates when using the IP' do
|
83
|
+
expect(doc['kerberos']).to eq(true)
|
84
|
+
expect(doc['authenticated']).to eq('yeah')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/spec/lite_spec_helper.rb
CHANGED
@@ -20,26 +20,25 @@ TRANSACTIONS_API_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/transactions_
|
|
20
20
|
CHANGE_STREAMS_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/change_streams/*.yml").sort
|
21
21
|
CMAP_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/cmap/*.yml").sort
|
22
22
|
AUTH_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/auth/*.yml").sort
|
23
|
-
|
24
|
-
require 'mongo'
|
25
|
-
require 'pp'
|
26
|
-
|
27
|
-
autoload :Benchmark, 'benchmark'
|
23
|
+
CLIENT_SIDE_ENCRYPTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/client_side_encryption/*.yml").sort
|
28
24
|
|
29
25
|
unless ENV['CI']
|
26
|
+
# Load debuggers before loading the driver code, so that breakpoints
|
27
|
+
# can be placed in the driver code on file/class level.
|
30
28
|
begin
|
31
29
|
require 'byebug'
|
32
30
|
rescue LoadError
|
33
|
-
|
34
|
-
begin
|
35
|
-
require 'pry'
|
36
|
-
# jruby likes to raise random error classes, in this case
|
37
|
-
# NameError in addition to LoadError
|
38
|
-
rescue Exception
|
39
|
-
end
|
31
|
+
require 'ruby-debug'
|
40
32
|
end
|
41
33
|
end
|
42
34
|
|
35
|
+
require 'mongo'
|
36
|
+
require 'pp'
|
37
|
+
|
38
|
+
autoload :Benchmark, 'benchmark'
|
39
|
+
autoload :IceNine, 'ice_nine'
|
40
|
+
autoload :Timecop, 'timecop'
|
41
|
+
|
43
42
|
if BSON::Environment.jruby?
|
44
43
|
require 'concurrent-ruby'
|
45
44
|
PossiblyConcurrentArray = Concurrent::Array
|
@@ -56,31 +55,30 @@ unless SpecConfig.instance.client_debug?
|
|
56
55
|
end
|
57
56
|
Encoding.default_external = Encoding::UTF_8
|
58
57
|
|
59
|
-
autoload :Timecop, 'timecop'
|
60
|
-
|
61
|
-
require 'ice_nine'
|
62
58
|
require 'support/matchers'
|
63
59
|
require 'support/lite_constraints'
|
64
60
|
require 'support/event_subscriber'
|
65
|
-
require 'support/server_discovery_and_monitoring'
|
66
|
-
require 'support/server_selection_rtt'
|
67
|
-
require 'support/server_selection'
|
68
|
-
require 'support/sdam_monitoring'
|
69
|
-
require 'support/crud'
|
70
|
-
require 'support/command_monitoring'
|
71
|
-
require 'support/cmap'
|
72
|
-
require 'runners/connection_string'
|
73
|
-
require 'support/connection_string'
|
74
|
-
require 'support/gridfs'
|
75
|
-
require 'support/transactions'
|
76
|
-
require 'support/change_streams'
|
77
61
|
require 'support/common_shortcuts'
|
78
62
|
require 'support/client_registry'
|
79
63
|
require 'support/client_registry_macros'
|
64
|
+
require 'support/crypt'
|
80
65
|
require 'support/json_ext_formatter'
|
81
66
|
require 'support/sdam_formatter_integration'
|
82
67
|
require 'support/background_thread_registry'
|
83
|
-
|
68
|
+
|
69
|
+
require 'runners/server_discovery_and_monitoring'
|
70
|
+
require 'runners/server_selection_rtt'
|
71
|
+
require 'runners/server_selection'
|
72
|
+
require 'runners/sdam_monitoring'
|
73
|
+
require 'runners/crud'
|
74
|
+
require 'runners/command_monitoring'
|
75
|
+
require 'runners/cmap'
|
76
|
+
require 'runners/connection_string'
|
77
|
+
require 'runners/connection_string'
|
78
|
+
require 'runners/gridfs'
|
79
|
+
require 'runners/transactions'
|
80
|
+
require 'runners/change_streams'
|
81
|
+
require 'runners/auth'
|
84
82
|
|
85
83
|
if SpecConfig.instance.mri?
|
86
84
|
require 'timeout_interrupt'
|
@@ -122,7 +120,9 @@ RSpec.configure do |config|
|
|
122
120
|
|
123
121
|
if SpecConfig.instance.ci?
|
124
122
|
unless BSON::Environment.jruby?
|
125
|
-
Rfc
|
123
|
+
if defined?(Rfc)
|
124
|
+
Rfc::Rif.output_object_space_stats = true
|
125
|
+
end
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -138,3 +138,8 @@ if SpecConfig.instance.active_support?
|
|
138
138
|
require "active_support/time"
|
139
139
|
require 'mongo/active_support'
|
140
140
|
end
|
141
|
+
|
142
|
+
if File.exist?('.env.private')
|
143
|
+
require 'dotenv'
|
144
|
+
Dotenv.load('.env.private')
|
145
|
+
end
|