mongo 2.11.6 → 2.12.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 +2 -2
- data.tar.gz.sig +0 -0
- data/CONTRIBUTING.md +1 -1
- data/lib/mongo.rb +3 -0
- data/lib/mongo/address.rb +13 -2
- 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 +126 -11
- data/lib/mongo/client_encryption.rb +103 -0
- data/lib/mongo/cluster.rb +2 -2
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
- data/lib/mongo/cluster/sdam_flow.rb +54 -58
- data/lib/mongo/cluster/srv_monitor.rb +1 -1
- 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 +7 -9
- data/lib/mongo/collection/view/writable.rb +7 -7
- data/lib/mongo/crypt.rb +33 -0
- data/lib/mongo/crypt/auto_decryption_context.rb +42 -0
- data/lib/mongo/crypt/auto_encrypter.rb +169 -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 +1162 -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 +283 -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 +293 -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 +13 -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/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/operation_failure.rb +1 -0
- data/lib/mongo/grid/file.rb +0 -5
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/file/info.rb +2 -1
- data/lib/mongo/grid/fs_bucket.rb +13 -15
- data/lib/mongo/grid/stream/write.rb +3 -9
- data/lib/mongo/index/view.rb +3 -3
- 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 +2 -2
- data/lib/mongo/operation/insert/legacy.rb +2 -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 +10 -8
- 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/write.rb +17 -10
- data/lib/mongo/operation/update/op_msg.rb +1 -1
- data/lib/mongo/protocol/compressed.rb +6 -5
- data/lib/mongo/protocol/insert.rb +3 -1
- data/lib/mongo/protocol/message.rb +72 -8
- data/lib/mongo/protocol/msg.rb +191 -37
- data/lib/mongo/protocol/query.rb +7 -9
- data/lib/mongo/protocol/serializers.rb +6 -2
- data/lib/mongo/server.rb +10 -4
- data/lib/mongo/server/connection.rb +20 -9
- data/lib/mongo/server/connection_base.rb +81 -12
- data/lib/mongo/server/connection_common.rb +61 -0
- data/lib/mongo/server/connection_pool.rb +37 -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 +2 -2
- 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/timeout.rb +49 -0
- data/lib/mongo/uri.rb +30 -1
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/README.md +134 -7
- data/spec/integration/auth_spec.rb +53 -0
- data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
- data/spec/integration/client_construction_spec.rb +76 -1
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +351 -0
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +301 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +71 -0
- data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +76 -0
- data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +216 -0
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +600 -0
- data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +183 -0
- data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +74 -0
- data/spec/integration/client_side_encryption/client_close_spec.rb +59 -0
- data/spec/integration/client_side_encryption/corpus_spec.rb +228 -0
- data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
- data/spec/integration/client_side_encryption/data_key_spec.rb +163 -0
- data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
- data/spec/integration/client_side_encryption/external_key_vault_spec.rb +137 -0
- data/spec/integration/client_side_encryption/views_spec.rb +42 -0
- data/spec/integration/client_update_spec.rb +120 -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/reconnect_spec.rb +7 -6
- data/spec/integration/size_limit_spec.rb +94 -0
- data/spec/integration/srv_monitoring_spec.rb +14 -6
- data/spec/lite_spec_helper.rb +31 -22
- 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/x509_spec.rb +5 -1
- data/spec/mongo/client_construction_spec.rb +206 -3
- data/spec/mongo/client_encryption_spec.rb +408 -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 +4 -33
- data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
- data/spec/mongo/crypt/auto_encrypter_spec.rb +182 -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 +198 -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/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/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 +1 -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/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/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 +4 -4
- 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 +13 -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 +85 -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 +61 -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 +168 -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/common_shortcuts.rb +12 -0
- data/spec/support/constraints.rb +16 -0
- data/spec/support/crypt.rb +140 -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 +17 -1
- data/spec/support/matchers.rb +19 -0
- data/spec/support/shared/protocol.rb +2 -0
- data/spec/support/spec_config.rb +43 -13
- data/spec/support/utils.rb +132 -10
- metadata +277 -81
- metadata.gz.sig +0 -0
- data/spec/integration/grid_fs_bucket_spec.rb +0 -48
- data/spec/integration/zlib_compression_spec.rb +0 -25
- data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
- data/spec/support/connection_string.rb +0 -354
@@ -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|
|
@@ -84,12 +86,16 @@ 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
|
|
@@ -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
|
data/spec/lite_spec_helper.rb
CHANGED
@@ -20,11 +20,7 @@ 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']
|
30
26
|
begin
|
@@ -40,6 +36,13 @@ unless ENV['CI']
|
|
40
36
|
end
|
41
37
|
end
|
42
38
|
|
39
|
+
require 'mongo'
|
40
|
+
require 'pp'
|
41
|
+
|
42
|
+
autoload :Benchmark, 'benchmark'
|
43
|
+
autoload :Timecop, 'timecop'
|
44
|
+
autoload :IceNine, 'ice_nine'
|
45
|
+
|
43
46
|
if BSON::Environment.jruby?
|
44
47
|
require 'concurrent-ruby'
|
45
48
|
PossiblyConcurrentArray = Concurrent::Array
|
@@ -56,31 +59,30 @@ unless SpecConfig.instance.client_debug?
|
|
56
59
|
end
|
57
60
|
Encoding.default_external = Encoding::UTF_8
|
58
61
|
|
59
|
-
autoload :Timecop, 'timecop'
|
60
|
-
|
61
|
-
require 'ice_nine'
|
62
62
|
require 'support/matchers'
|
63
63
|
require 'support/lite_constraints'
|
64
64
|
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
65
|
require 'support/common_shortcuts'
|
78
66
|
require 'support/client_registry'
|
79
67
|
require 'support/client_registry_macros'
|
68
|
+
require 'support/crypt'
|
80
69
|
require 'support/json_ext_formatter'
|
81
70
|
require 'support/sdam_formatter_integration'
|
82
71
|
require 'support/background_thread_registry'
|
83
|
-
|
72
|
+
|
73
|
+
require 'runners/server_discovery_and_monitoring'
|
74
|
+
require 'runners/server_selection_rtt'
|
75
|
+
require 'runners/server_selection'
|
76
|
+
require 'runners/sdam_monitoring'
|
77
|
+
require 'runners/crud'
|
78
|
+
require 'runners/command_monitoring'
|
79
|
+
require 'runners/cmap'
|
80
|
+
require 'runners/connection_string'
|
81
|
+
require 'runners/connection_string'
|
82
|
+
require 'runners/gridfs'
|
83
|
+
require 'runners/transactions'
|
84
|
+
require 'runners/change_streams'
|
85
|
+
require 'runners/auth'
|
84
86
|
|
85
87
|
if SpecConfig.instance.mri?
|
86
88
|
require 'timeout_interrupt'
|
@@ -122,7 +124,9 @@ RSpec.configure do |config|
|
|
122
124
|
|
123
125
|
if SpecConfig.instance.ci?
|
124
126
|
unless BSON::Environment.jruby?
|
125
|
-
Rfc
|
127
|
+
if defined?(Rfc)
|
128
|
+
Rfc::Rif.output_object_space_stats = true
|
129
|
+
end
|
126
130
|
end
|
127
131
|
end
|
128
132
|
|
@@ -138,3 +142,8 @@ if SpecConfig.instance.active_support?
|
|
138
142
|
require "active_support/time"
|
139
143
|
require 'mongo/active_support'
|
140
144
|
end
|
145
|
+
|
146
|
+
if File.exist?('.env.private')
|
147
|
+
require 'dotenv'
|
148
|
+
Dotenv.load('.env.private')
|
149
|
+
end
|
data/spec/mongo/auth/cr_spec.rb
CHANGED
@@ -12,6 +12,10 @@ describe Mongo::Auth::CR do
|
|
12
12
|
|
13
13
|
describe '#login' do
|
14
14
|
|
15
|
+
before do
|
16
|
+
connection.connect!
|
17
|
+
end
|
18
|
+
|
15
19
|
context 'when the user is not authorized' do
|
16
20
|
|
17
21
|
let(:user) do
|
@@ -53,6 +57,10 @@ describe Mongo::Auth::CR do
|
|
53
57
|
context 'when the user is authorized for the database' do
|
54
58
|
max_server_fcv '2.6'
|
55
59
|
|
60
|
+
before do
|
61
|
+
connection.connect!
|
62
|
+
end
|
63
|
+
|
56
64
|
let(:cr) do
|
57
65
|
described_class.new(root_user)
|
58
66
|
end
|
@@ -16,6 +16,10 @@ describe Mongo::Auth::LDAP do
|
|
16
16
|
|
17
17
|
describe '#login' do
|
18
18
|
|
19
|
+
before do
|
20
|
+
connection.connect!
|
21
|
+
end
|
22
|
+
|
19
23
|
context 'when the user is not authorized for the database' do
|
20
24
|
|
21
25
|
let(:cr) do
|
@@ -26,7 +30,7 @@ describe Mongo::Auth::LDAP do
|
|
26
30
|
cr.login(connection).documents[0]
|
27
31
|
end
|
28
32
|
|
29
|
-
it '
|
33
|
+
it 'attempts to log the user into the connection' do
|
30
34
|
expect {
|
31
35
|
cr.login(connection)
|
32
36
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
describe Mongo::Auth::SCRAM::Conversation do
|
4
|
+
# Test uses global assertions
|
5
|
+
clean_slate
|
5
6
|
|
6
7
|
let(:conversation) do
|
7
8
|
described_class.new(user, mechanism)
|
@@ -35,8 +36,6 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
|
|
35
36
|
end
|
36
37
|
|
37
38
|
describe '#start' do
|
38
|
-
# Test uses global assertions
|
39
|
-
clean_slate
|
40
39
|
|
41
40
|
let(:query) do
|
42
41
|
conversation.start(nil)
|
@@ -407,10 +406,10 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
|
|
407
406
|
end
|
408
407
|
|
409
408
|
it 'raises an error' do
|
410
|
-
expect
|
409
|
+
expect do
|
411
410
|
conversation.continue(continue_reply, connection)
|
412
411
|
conversation.finalize(reply, connection)
|
413
|
-
|
412
|
+
end.to raise_error(Mongo::Error::InvalidSignature)
|
414
413
|
end
|
415
414
|
end
|
416
415
|
end
|
@@ -1,20 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# established after the client is closed which screws up our assertions on
|
6
|
-
# the auth calls. When 1772 is fixed, the cleanup should happen on existing
|
7
|
-
# connections and thus should no longer interfere with auth assertions.
|
3
|
+
# max_pool_size is set to 1 to force a single connection being used for
|
4
|
+
# all operations in a client.
|
8
5
|
|
9
6
|
describe 'SCRAM-SHA auth mechanism negotiation' do
|
10
7
|
min_server_fcv '4.0'
|
8
|
+
# Test uses global assertions
|
11
9
|
clean_slate
|
12
10
|
|
13
|
-
URI_OPTION_MAP = {
|
14
|
-
:auth_source => 'authsource',
|
15
|
-
:replica_set => 'replicaSet',
|
16
|
-
}
|
17
|
-
|
18
11
|
let(:create_user!) do
|
19
12
|
root_authorized_admin_client.tap do |client|
|
20
13
|
users = client.database.users
|
@@ -52,7 +45,7 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
52
45
|
|
53
46
|
new_local_client(
|
54
47
|
SpecConfig.instance.addresses,
|
55
|
-
SpecConfig.instance.test_options.merge(opts).update(
|
48
|
+
SpecConfig.instance.test_options.merge(opts).update(max_pool_size: 1)
|
56
49
|
)
|
57
50
|
end
|
58
51
|
|
@@ -199,19 +192,25 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
199
192
|
:scram
|
200
193
|
end
|
201
194
|
|
202
|
-
|
195
|
+
before do
|
203
196
|
create_user!
|
197
|
+
end
|
204
198
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
199
|
+
it 'authenticates successfully' do
|
200
|
+
RSpec::Mocks.with_temporary_scope do
|
201
|
+
mechanism = nil
|
202
|
+
expect(Mongo::Auth).to receive(:get).and_wrap_original do |m, user|
|
203
|
+
# copy mechanism here rather than whole user
|
204
|
+
# in case something mutates mechanism later
|
205
|
+
mechanism = user.mechanism
|
206
|
+
m.call(user)
|
207
|
+
end
|
208
|
+
|
209
|
+
expect do
|
210
|
+
result
|
211
|
+
end.not_to raise_error
|
212
|
+
expect(mechanism).to eq(:scram)
|
211
213
|
end
|
212
|
-
|
213
|
-
expect { result }.not_to raise_error
|
214
|
-
expect(mechanism).to eq(:scram)
|
215
214
|
end
|
216
215
|
end
|
217
216
|
|
@@ -221,19 +220,23 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
221
220
|
:scram256
|
222
221
|
end
|
223
222
|
|
224
|
-
|
223
|
+
before do
|
225
224
|
create_user!
|
225
|
+
end
|
226
226
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
227
|
+
it 'authenticates successfully with SCRAM-SHA-256' do
|
228
|
+
RSpec::Mocks.with_temporary_scope do
|
229
|
+
mechanism = nil
|
230
|
+
expect(Mongo::Auth).to receive(:get).and_wrap_original do |m, user|
|
231
|
+
# copy mechanism here rather than whole user
|
232
|
+
# in case something mutates mechanism later
|
233
|
+
mechanism = user.mechanism
|
234
|
+
m.call(user)
|
235
|
+
end
|
236
|
+
|
237
|
+
expect { result }.not_to raise_error
|
238
|
+
expect(mechanism).to eq(:scram256)
|
233
239
|
end
|
234
|
-
|
235
|
-
expect { result }.not_to raise_error
|
236
|
-
expect(mechanism).to eq(:scram256)
|
237
240
|
end
|
238
241
|
end
|
239
242
|
end
|
@@ -312,30 +315,18 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
312
315
|
context 'when the configuration is specified in the URI' do
|
313
316
|
|
314
317
|
let(:uri) do
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
k = URI_OPTION_MAP[k] || k
|
324
|
-
|
325
|
-
uri << "#{k}=#{v}"
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
if auth_mech
|
330
|
-
uri << (first ? '?' : '&')
|
331
|
-
|
332
|
-
uri << "authMechanism=#{Mongo::URI::AUTH_MECH_MAP.key(auth_mech)}"
|
333
|
-
end
|
334
|
-
end
|
318
|
+
Utils.create_mongodb_uri(
|
319
|
+
SpecConfig.instance.addresses,
|
320
|
+
username: user.name,
|
321
|
+
password: password,
|
322
|
+
uri_options: SpecConfig.instance.uri_options.merge(
|
323
|
+
auth_mech: auth_mech,
|
324
|
+
),
|
325
|
+
)
|
335
326
|
end
|
336
327
|
|
337
328
|
let(:client) do
|
338
|
-
new_local_client(uri, SpecConfig.instance.ssl_options.merge(
|
329
|
+
new_local_client(uri, SpecConfig.instance.ssl_options.merge(max_pool_size: 1))
|
339
330
|
end
|
340
331
|
|
341
332
|
context 'when the user exists' do
|
@@ -350,7 +341,7 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
350
341
|
Mongo::Auth::User.new(
|
351
342
|
user: 'sha1',
|
352
343
|
password: 'sha1',
|
353
|
-
auth_mech: auth_mech
|
344
|
+
auth_mech: auth_mech,
|
354
345
|
)
|
355
346
|
end
|
356
347
|
|
@@ -403,7 +394,7 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
403
394
|
Mongo::Auth::User.new(
|
404
395
|
user: 'sha256',
|
405
396
|
password: 'sha256',
|
406
|
-
auth_mech: auth_mech
|
397
|
+
auth_mech: auth_mech,
|
407
398
|
)
|
408
399
|
end
|
409
400
|
|
@@ -457,7 +448,7 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
457
448
|
Mongo::Auth::User.new(
|
458
449
|
user: 'both',
|
459
450
|
password: 'both',
|
460
|
-
auth_mech: auth_mech
|
451
|
+
auth_mech: auth_mech,
|
461
452
|
)
|
462
453
|
end
|
463
454
|
|
@@ -480,20 +471,24 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
480
471
|
:scram
|
481
472
|
end
|
482
473
|
|
483
|
-
|
474
|
+
before do
|
484
475
|
create_user!
|
485
476
|
expect(user.mechanism).to eq(:scram)
|
477
|
+
end
|
486
478
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
479
|
+
it 'authenticates successfully' do
|
480
|
+
RSpec::Mocks.with_temporary_scope do
|
481
|
+
mechanism = nil
|
482
|
+
expect(Mongo::Auth).to receive(:get).and_wrap_original do |m, user|
|
483
|
+
# copy mechanism here rather than whole user
|
484
|
+
# in case something mutates mechanism later
|
485
|
+
mechanism = user.mechanism
|
486
|
+
m.call(user)
|
487
|
+
end
|
488
|
+
|
489
|
+
expect { result }.not_to raise_error
|
490
|
+
expect(mechanism).to eq(:scram)
|
493
491
|
end
|
494
|
-
|
495
|
-
expect { result }.not_to raise_error
|
496
|
-
expect(mechanism).to eq(:scram)
|
497
492
|
end
|
498
493
|
end
|
499
494
|
|
@@ -503,19 +498,23 @@ describe 'SCRAM-SHA auth mechanism negotiation' do
|
|
503
498
|
:scram256
|
504
499
|
end
|
505
500
|
|
506
|
-
|
501
|
+
before do
|
507
502
|
create_user!
|
503
|
+
end
|
508
504
|
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
505
|
+
it 'authenticates successfully with SCRAM-SHA-256' do
|
506
|
+
RSpec::Mocks.with_temporary_scope do
|
507
|
+
mechanism = nil
|
508
|
+
expect(Mongo::Auth).to receive(:get).and_wrap_original do |m, user|
|
509
|
+
# copy mechanism here rather than whole user
|
510
|
+
# in case something mutates mechanism later
|
511
|
+
mechanism = user.mechanism
|
512
|
+
m.call(user)
|
513
|
+
end
|
514
|
+
|
515
|
+
expect { result }.not_to raise_error
|
516
|
+
expect(mechanism).to eq(:scram256)
|
515
517
|
end
|
516
|
-
|
517
|
-
expect { result }.not_to raise_error
|
518
|
-
expect(mechanism).to eq(:scram256)
|
519
518
|
end
|
520
519
|
end
|
521
520
|
end
|
@@ -11,9 +11,31 @@ describe Mongo::Auth::SCRAM do
|
|
11
11
|
Mongo::Server::Connection.new(server, SpecConfig.instance.test_options)
|
12
12
|
end
|
13
13
|
|
14
|
+
let(:cache_mod) { Mongo::Auth::CredentialCache }
|
15
|
+
|
16
|
+
shared_examples_for 'caches scram credentials' do |cache_key|
|
17
|
+
|
18
|
+
it 'caches scram credentials' do
|
19
|
+
cache_mod.clear
|
20
|
+
expect(cache_mod.store).to be_empty
|
21
|
+
|
22
|
+
expect(login['ok']).to eq(1)
|
23
|
+
|
24
|
+
expect(cache_mod.store).not_to be_empty
|
25
|
+
client_key_entry = cache_mod.store.keys.detect do |key|
|
26
|
+
key.include?(test_user.password) && key.include?(cache_key)
|
27
|
+
end
|
28
|
+
expect(client_key_entry).not_to be nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
14
32
|
context 'when SCRAM-SHA-1 is used' do
|
15
33
|
min_server_fcv '3.0'
|
16
34
|
|
35
|
+
before do
|
36
|
+
connection.connect!
|
37
|
+
end
|
38
|
+
|
17
39
|
describe '#login' do
|
18
40
|
|
19
41
|
context 'when the user is not authorized' do
|
@@ -27,13 +49,13 @@ describe Mongo::Auth::SCRAM do
|
|
27
49
|
)
|
28
50
|
end
|
29
51
|
|
30
|
-
let(:
|
52
|
+
let(:authenticator) do
|
31
53
|
described_class.new(user)
|
32
54
|
end
|
33
55
|
|
34
56
|
it 'raises an exception' do
|
35
57
|
expect {
|
36
|
-
|
58
|
+
authenticator.login(connection)
|
37
59
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
38
60
|
end
|
39
61
|
|
@@ -44,7 +66,7 @@ describe Mongo::Auth::SCRAM do
|
|
44
66
|
it 'does not compress the message' do
|
45
67
|
expect(Mongo::Protocol::Compressed).not_to receive(:new)
|
46
68
|
expect {
|
47
|
-
|
69
|
+
authenticator.login(connection)
|
48
70
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
49
71
|
end
|
50
72
|
end
|
@@ -52,29 +74,21 @@ describe Mongo::Auth::SCRAM do
|
|
52
74
|
|
53
75
|
context 'when the user is authorized for the database' do
|
54
76
|
|
55
|
-
let(:
|
56
|
-
described_class.new(
|
77
|
+
let(:authenticator) do
|
78
|
+
described_class.new(test_user)
|
57
79
|
end
|
58
80
|
|
59
81
|
let(:login) do
|
60
|
-
|
82
|
+
authenticator.login(connection).documents[0]
|
61
83
|
end
|
62
84
|
|
63
|
-
|
64
|
-
root_user.instance_variable_set(:@client_key, nil)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'logs the user into the connection and caches the client key' do
|
85
|
+
it 'logs the user into the connection' do
|
68
86
|
expect(login['ok']).to eq(1)
|
69
|
-
expect(root_user.send(:client_key)).not_to be_nil
|
70
87
|
end
|
71
88
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
cr.login(connection)
|
76
|
-
}.to raise_error(Mongo::Auth::Unauthorized)
|
77
|
-
end
|
89
|
+
it_behaves_like 'caches scram credentials', :salted_password
|
90
|
+
it_behaves_like 'caches scram credentials', :client_key
|
91
|
+
it_behaves_like 'caches scram credentials', :server_key
|
78
92
|
end
|
79
93
|
end
|
80
94
|
end
|
@@ -82,6 +96,10 @@ describe Mongo::Auth::SCRAM do
|
|
82
96
|
context 'when SCRAM-SHA-256 is used' do
|
83
97
|
min_server_fcv '4.0'
|
84
98
|
|
99
|
+
before do
|
100
|
+
connection.connect!
|
101
|
+
end
|
102
|
+
|
85
103
|
describe '#login' do
|
86
104
|
|
87
105
|
context 'when the user is not authorized' do
|
@@ -95,13 +113,13 @@ describe Mongo::Auth::SCRAM do
|
|
95
113
|
)
|
96
114
|
end
|
97
115
|
|
98
|
-
let(:
|
116
|
+
let(:authenticator) do
|
99
117
|
described_class.new(user)
|
100
118
|
end
|
101
119
|
|
102
120
|
it 'raises an exception' do
|
103
121
|
expect {
|
104
|
-
|
122
|
+
authenticator.login(connection)
|
105
123
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
106
124
|
end
|
107
125
|
|
@@ -112,7 +130,7 @@ describe Mongo::Auth::SCRAM do
|
|
112
130
|
it 'does not compress the message' do
|
113
131
|
expect(Mongo::Protocol::Compressed).not_to receive(:new)
|
114
132
|
expect {
|
115
|
-
|
133
|
+
authenticator.login(connection)
|
116
134
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
117
135
|
end
|
118
136
|
end
|
@@ -120,29 +138,21 @@ describe Mongo::Auth::SCRAM do
|
|
120
138
|
|
121
139
|
context 'when the user is authorized for the database' do
|
122
140
|
|
123
|
-
let(:
|
141
|
+
let(:authenticator) do
|
124
142
|
described_class.new(test_user)
|
125
143
|
end
|
126
144
|
|
127
145
|
let(:login) do
|
128
|
-
|
146
|
+
authenticator.login(connection).documents[0]
|
129
147
|
end
|
130
148
|
|
131
|
-
|
132
|
-
test_user.instance_variable_set(:@client_key, nil)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'logs the user into the connection and caches the client key' do
|
149
|
+
it 'logs the user into the connection' do
|
136
150
|
expect(login['ok']).to eq(1)
|
137
|
-
expect(test_user.send(:client_key)).not_to be_nil
|
138
151
|
end
|
139
152
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
cr.login(connection)
|
144
|
-
}.to raise_error(Mongo::Auth::Unauthorized)
|
145
|
-
end
|
153
|
+
it_behaves_like 'caches scram credentials', :salted_password
|
154
|
+
it_behaves_like 'caches scram credentials', :client_key
|
155
|
+
it_behaves_like 'caches scram credentials', :server_key
|
146
156
|
end
|
147
157
|
end
|
148
158
|
end
|