mongo 2.13.1 → 2.14.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -4
  4. data/lib/mongo.rb +9 -0
  5. data/lib/mongo/address/ipv4.rb +1 -1
  6. data/lib/mongo/address/ipv6.rb +1 -1
  7. data/lib/mongo/bulk_write.rb +17 -0
  8. data/lib/mongo/caching_cursor.rb +74 -0
  9. data/lib/mongo/client.rb +47 -8
  10. data/lib/mongo/cluster.rb +3 -3
  11. data/lib/mongo/cluster/topology/single.rb +1 -1
  12. data/lib/mongo/collection.rb +26 -0
  13. data/lib/mongo/collection/view.rb +24 -20
  14. data/lib/mongo/collection/view/aggregation.rb +25 -4
  15. data/lib/mongo/collection/view/builder/find_command.rb +38 -18
  16. data/lib/mongo/collection/view/explainable.rb +27 -8
  17. data/lib/mongo/collection/view/iterable.rb +72 -12
  18. data/lib/mongo/collection/view/readable.rb +12 -2
  19. data/lib/mongo/collection/view/writable.rb +15 -1
  20. data/lib/mongo/crypt/encryption_io.rb +6 -6
  21. data/lib/mongo/cursor.rb +1 -0
  22. data/lib/mongo/database.rb +6 -0
  23. data/lib/mongo/error.rb +2 -0
  24. data/lib/mongo/error/invalid_read_concern.rb +28 -0
  25. data/lib/mongo/error/server_certificate_revoked.rb +22 -0
  26. data/lib/mongo/error/unsupported_option.rb +14 -12
  27. data/lib/mongo/lint.rb +2 -1
  28. data/lib/mongo/logger.rb +3 -3
  29. data/lib/mongo/operation.rb +2 -0
  30. data/lib/mongo/operation/aggregate/result.rb +9 -8
  31. data/lib/mongo/operation/collections_info/result.rb +2 -0
  32. data/lib/mongo/operation/delete/bulk_result.rb +2 -0
  33. data/lib/mongo/operation/delete/result.rb +3 -0
  34. data/lib/mongo/operation/explain/command.rb +4 -0
  35. data/lib/mongo/operation/explain/legacy.rb +4 -0
  36. data/lib/mongo/operation/explain/op_msg.rb +6 -0
  37. data/lib/mongo/operation/explain/result.rb +3 -0
  38. data/lib/mongo/operation/find/legacy/result.rb +2 -0
  39. data/lib/mongo/operation/find/result.rb +3 -0
  40. data/lib/mongo/operation/get_more/result.rb +3 -0
  41. data/lib/mongo/operation/indexes/result.rb +5 -0
  42. data/lib/mongo/operation/insert/bulk_result.rb +5 -0
  43. data/lib/mongo/operation/insert/result.rb +5 -0
  44. data/lib/mongo/operation/list_collections/result.rb +5 -0
  45. data/lib/mongo/operation/map_reduce/result.rb +10 -0
  46. data/lib/mongo/operation/parallel_scan/result.rb +4 -0
  47. data/lib/mongo/operation/result.rb +35 -6
  48. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -0
  49. data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -0
  50. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +2 -0
  51. data/lib/mongo/operation/shared/executable.rb +1 -0
  52. data/lib/mongo/operation/shared/idable.rb +2 -1
  53. data/lib/mongo/operation/shared/limited.rb +1 -0
  54. data/lib/mongo/operation/shared/object_id_generator.rb +1 -0
  55. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -0
  56. data/lib/mongo/operation/shared/sessions_supported.rb +1 -0
  57. data/lib/mongo/operation/shared/specifiable.rb +1 -0
  58. data/lib/mongo/operation/shared/write.rb +1 -0
  59. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -0
  60. data/lib/mongo/operation/update/legacy/result.rb +7 -0
  61. data/lib/mongo/operation/update/result.rb +8 -0
  62. data/lib/mongo/operation/users_info/result.rb +3 -0
  63. data/lib/mongo/query_cache.rb +242 -0
  64. data/lib/mongo/retryable.rb +8 -1
  65. data/lib/mongo/server.rb +5 -1
  66. data/lib/mongo/server/connection_common.rb +2 -2
  67. data/lib/mongo/server/connection_pool.rb +3 -0
  68. data/lib/mongo/server/monitor.rb +1 -1
  69. data/lib/mongo/server/monitor/connection.rb +3 -3
  70. data/lib/mongo/server/pending_connection.rb +2 -2
  71. data/lib/mongo/server/push_monitor.rb +1 -1
  72. data/lib/mongo/server_selector/base.rb +5 -1
  73. data/lib/mongo/session.rb +3 -0
  74. data/lib/mongo/socket.rb +6 -4
  75. data/lib/mongo/socket/ocsp_cache.rb +97 -0
  76. data/lib/mongo/socket/ocsp_verifier.rb +368 -0
  77. data/lib/mongo/socket/ssl.rb +45 -24
  78. data/lib/mongo/srv/monitor.rb +7 -13
  79. data/lib/mongo/srv/resolver.rb +14 -10
  80. data/lib/mongo/timeout.rb +2 -0
  81. data/lib/mongo/uri.rb +21 -390
  82. data/lib/mongo/uri/options_mapper.rb +582 -0
  83. data/lib/mongo/uri/srv_protocol.rb +3 -2
  84. data/lib/mongo/utils.rb +12 -1
  85. data/lib/mongo/version.rb +1 -1
  86. data/spec/NOTES.aws-auth.md +12 -7
  87. data/spec/README.md +56 -1
  88. data/spec/integration/bulk_write_spec.rb +48 -0
  89. data/spec/integration/client_authentication_options_spec.rb +55 -28
  90. data/spec/integration/connection_pool_populator_spec.rb +3 -1
  91. data/spec/integration/cursor_reaping_spec.rb +53 -17
  92. data/spec/integration/ocsp_connectivity_spec.rb +26 -0
  93. data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
  94. data/spec/integration/ocsp_verifier_spec.rb +334 -0
  95. data/spec/integration/query_cache_spec.rb +1045 -0
  96. data/spec/integration/query_cache_transactions_spec.rb +179 -0
  97. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -0
  98. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +2 -0
  99. data/spec/integration/sdam_error_handling_spec.rb +68 -0
  100. data/spec/integration/server_selection_spec.rb +36 -0
  101. data/spec/integration/srv_monitoring_spec.rb +38 -3
  102. data/spec/integration/srv_spec.rb +56 -0
  103. data/spec/lite_spec_helper.rb +3 -1
  104. data/spec/mongo/address_spec.rb +1 -1
  105. data/spec/mongo/caching_cursor_spec.rb +70 -0
  106. data/spec/mongo/client_construction_spec.rb +54 -1
  107. data/spec/mongo/client_spec.rb +40 -0
  108. data/spec/mongo/cluster/topology/single_spec.rb +14 -5
  109. data/spec/mongo/cluster_spec.rb +3 -0
  110. data/spec/mongo/collection/view/explainable_spec.rb +87 -4
  111. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -0
  112. data/spec/mongo/collection_spec.rb +60 -0
  113. data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
  114. data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
  115. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
  116. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +1 -1
  117. data/spec/mongo/database_spec.rb +44 -0
  118. data/spec/mongo/error/no_server_available_spec.rb +1 -1
  119. data/spec/mongo/logger_spec.rb +13 -11
  120. data/spec/mongo/query_cache_spec.rb +279 -0
  121. data/spec/mongo/server/connection_pool_spec.rb +7 -3
  122. data/spec/mongo/server/connection_spec.rb +14 -7
  123. data/spec/mongo/socket/ssl_spec.rb +1 -1
  124. data/spec/mongo/socket_spec.rb +1 -1
  125. data/spec/mongo/uri/srv_protocol_spec.rb +64 -33
  126. data/spec/mongo/uri_option_parsing_spec.rb +11 -11
  127. data/spec/mongo/uri_spec.rb +68 -41
  128. data/spec/mongo/utils_spec.rb +39 -0
  129. data/spec/runners/auth.rb +3 -0
  130. data/spec/runners/connection_string.rb +35 -124
  131. data/spec/spec_tests/cmap_spec.rb +7 -3
  132. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +0 -1
  133. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
  134. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +6 -2
  135. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +3 -0
  136. data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
  137. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -3
  138. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +2 -2
  139. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
  140. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
  141. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
  142. data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
  143. data/spec/spec_tests/data/uri_options/compression-options.yml +6 -3
  144. data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
  145. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
  146. data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
  147. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +9 -1
  148. data/spec/spec_tests/uri_options_spec.rb +31 -33
  149. data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
  150. data/spec/support/certificates/atlas-ocsp.crt +41 -0
  151. data/spec/support/client_registry_macros.rb +11 -2
  152. data/spec/support/common_shortcuts.rb +45 -0
  153. data/spec/support/constraints.rb +23 -0
  154. data/spec/support/lite_constraints.rb +24 -0
  155. data/spec/support/matchers.rb +16 -0
  156. data/spec/support/ocsp +1 -0
  157. data/spec/support/session_registry.rb +52 -0
  158. data/spec/support/spec_config.rb +22 -0
  159. data/spec/support/utils.rb +19 -1
  160. metadata +38 -3
  161. metadata.gz.sig +0 -0
@@ -97,7 +97,7 @@ module Mongo
97
97
 
98
98
  # @return [ String ] NO_SRV_RECORDS Error message format string indicating that no SRV records
99
99
  # were found.
100
- NO_SRV_RECORDS = "The DNS query returned no SRV records at hostname (%s)".freeze
100
+ NO_SRV_RECORDS = "The DNS query returned no SRV records for '%s'".freeze
101
101
 
102
102
  # @return [ String ] INVALID_TXT_RECORD_OPTION Error message format string indicating that an
103
103
  # unexpected TXT record option was found.
@@ -130,6 +130,7 @@ module Mongo
130
130
  @resolver ||= Srv::Resolver.new(
131
131
  raise_on_invalid: true,
132
132
  resolv_options: options[:resolv_options],
133
+ timeout: options[:connect_timeout],
133
134
  )
134
135
  end
135
136
 
@@ -220,7 +221,7 @@ module Mongo
220
221
  raise Error::InvalidTXTRecord.new(INVALID_OPTS_VALUE_DELIM) unless opt.index(URI_OPTS_VALUE_DELIM)
221
222
  key, value = opt.split(URI_OPTS_VALUE_DELIM)
222
223
  raise Error::InvalidTXTRecord.new(INVALID_TXT_RECORD_OPTION) unless VALID_TXT_OPTIONS.include?(key.downcase)
223
- add_uri_option(key, value, txt_options)
224
+ options_mapper.add_uri_option(key, value, txt_options)
224
225
  txt_options
225
226
  end
226
227
  end
@@ -34,7 +34,7 @@ module Mongo
34
34
  # @option opts [ Logger ] :logger A custom logger to use.
35
35
  # @option opts [ String ] :log_prefix A custom log prefix to use when
36
36
  # logging.
37
- module_function def warn_monitor_exception(msg, exc, **opts)
37
+ module_function def warn_bg_exception(msg, exc, **opts)
38
38
  bt_excerpt = excerpt_backtrace(exc, **opts)
39
39
  logger = LocalLogger.new(**opts)
40
40
  logger.log_warn("#{msg}: #{exc.class}: #{exc}#{bt_excerpt}")
@@ -55,8 +55,19 @@ module Mongo
55
55
  end
56
56
  end
57
57
 
58
+ # Symbolizes the keys in the provided hash.
58
59
  module_function def shallow_symbolize_keys(hash)
59
60
  Hash[hash.map { |k, v| [k.to_sym, v] }]
60
61
  end
62
+
63
+ # Stringifies the keys in the provided hash and converts underscore
64
+ # style keys to camel case style keys.
65
+ module_function def shallow_camelize_keys(hash)
66
+ Hash[hash.map { |k, v| [camelize(k), v] }]
67
+ end
68
+
69
+ module_function def camelize(sym)
70
+ sym.to_s.gsub(/_(\w)/) { $1.upcase }
71
+ end
61
72
  end
62
73
  end
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.13.1'.freeze
20
+ VERSION = '2.14.0.rc1'.freeze
21
21
  end
@@ -145,13 +145,16 @@ problem. Below are some of the puzzling responses I encountered:
145
145
  line) but the value is otherwise completely valid. This error has no relation
146
146
  to the "session token" or "security token" as used with temporary AWS
147
147
  credentials.
148
- - *The security token included in the request is invalid*: this error is
149
- produced when the AWS access key id, as specified in the scope part of the
150
- `Authorization` header, is not a valid access key id. In the case of
151
- non-temporary credentials being used for authentication, the error refers to
152
- a "security token" but the authentication process does not actually use a
153
- security token as this term is used in the AWS documentation describing
154
- temporary credentials.
148
+ - *The security token included in the request is invalid*: this error can be
149
+ produced in several circumstances:
150
+ - When the AWS access key id, as specified in the scope part of the
151
+ `Authorization` header, is not a valid access key id. In the case of
152
+ non-temporary credentials being used for authentication, the error refers to
153
+ a "security token" but the authentication process does not actually use a
154
+ security token as this term is used in the AWS documentation describing
155
+ temporary credentials.
156
+ - When using temporary credentials and the security token is not provided
157
+ in the STS request at all (x-amz-security-token header).
155
158
  - *Signature expired: 20200317T000000Z is now earlier than 20200317T222541Z
156
159
  (20200317T224041Z - 15 min.)*: This error happens when `x-amz-date` header
157
160
  value is the formatted date (`YYYYMMDD`) rather than the ISO8601 formatted
@@ -168,6 +171,8 @@ problem. Below are some of the puzzling responses I encountered:
168
171
  produced when temporary credentials are used and the credentials have
169
172
  expired.
170
173
 
174
+ See also [AWS documentation for STS error messages](https://docs.aws.amazon.com/STS/latest/APIReference/CommonErrors.html).
175
+
171
176
  ### Resources
172
177
 
173
178
  Generally I found Amazon's own documentation to be the best for implementing
@@ -107,7 +107,7 @@ other tests require a sharded cluster with more than one shard. Tests requiring
107
107
  a single shard can be run against a deployment with multiple shards by
108
108
  specifying only one mongos address in MONGODB_URI.
109
109
 
110
- ## Note Regarding SSL/TLS Arguments
110
+ ## Note Regarding TLS/SSL Arguments
111
111
 
112
112
  MongoDB 4.2 (server and shell) added new command line options for setting TLS
113
113
  parameters. These options follow the naming of URI options used by both the
@@ -185,6 +185,51 @@ verification, run:
185
185
  Note that there are tests in the test suite that cover TLS verification, and
186
186
  they may fail if the test suite is run in this way.
187
187
 
188
+ ## OCSP
189
+
190
+ There are several types of OCSP tests implemented in the test suite.
191
+
192
+ OCSP unit tests are in `spec/integration/ocsp_verifier_spec.rb`. To run
193
+ these, set `OCSP_VERIFIER=1` in the environment. There must NOT be a process
194
+ running on the host port 8100 as that port will be used by the OCSP responder
195
+ launched by the tests.
196
+
197
+ For the remaining OCSP tests, the following environment variables must be set
198
+ to the possible values indicated below:
199
+
200
+ OCSP_ALGORITHM=rsa|ecdsa
201
+ OCSP_STATUS=valid|revoked|unknown
202
+ OCSP_DELEGATE=0|1
203
+ OCSP_MUST_STAPLE=0|1
204
+
205
+ These tests also require the mock OCSP responder running on the host machine
206
+ on port 8100 with the configuration that matches the environment variables
207
+ just described. Please refer to the Docker and Evergreen scripts in the
208
+ driver repository for further details.
209
+
210
+ Additionally, the server must be configured to use the appropriate server
211
+ certificate and CA certificate from the respective subdirectory of
212
+ `spec/support/ocsp`. This is easiest to achieve by using the Docker tooling
213
+ described in `.evergreen/README.md`.
214
+
215
+ OCSP connectivity tests are in `spec/integration/ocsp_connectivity.rb`.
216
+ These test the combinations described
217
+ [here](https://github.com/mongodb/specifications/blob/master/source/ocsp-support/tests/README.rst#integration-tests-permutations-to-be-tested).
218
+ To run these tests, set `OCSP_CONNECTIVITY=pass` environment variable if
219
+ the tests are expected to connect successfully or `OCSP_CONNECTIVITY=fail` if
220
+ the tests are expected to not connect.
221
+ Note that some of these configurations require OCSP responder to return
222
+ the failure response; in such configurations, ONLY the OCSP connectivity tests
223
+ may pass (since the driver may reject connections to servers when OCSP
224
+ responder returns the failure response, or OCSP verification otherwise
225
+ definitively fails).
226
+
227
+ When not running either OCSP verifier tests or OCSP connectivity tests but
228
+ when OCSP algorithm is configured, the test suite will execute normally
229
+ using the provided `MONGO_URI`. This configuration may be used to exercise
230
+ OCSP while running the full test suite. In this case, setting `OCSP_STATUS`
231
+ to `revoked` will generally cause the test suite to fail.
232
+
188
233
  ## Authentication
189
234
 
190
235
  mlaunch can configure authentication on the server:
@@ -511,6 +556,16 @@ following environment variable:
511
556
 
512
557
  FORK=1
513
558
 
559
+ OCSP tests require Python 3 with asn1crypto, oscrypto and flask packages
560
+ installed, and they require the drivers-evergreen-tools submodule to be
561
+ checked out. To run these tests, set the following environment variable:
562
+
563
+ OCSP=1
564
+
565
+ To check out the submodule, run:
566
+
567
+ git submodule update --init --recursive
568
+
514
569
  ## Debug Logging
515
570
 
516
571
  The test suite is run with the driver log level set to `WARN` by default.
@@ -16,4 +16,52 @@ describe 'Bulk writes' do
16
16
  end.not_to raise_error
17
17
  end
18
18
  end
19
+
20
+ context 'when bulk write needs to be split' do
21
+ let(:subscriber) { EventSubscriber.new }
22
+
23
+ let(:max_bson_size) { Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE }
24
+
25
+ let(:insert_events) do
26
+ subscriber.command_started_events('insert')
27
+ end
28
+
29
+ let(:failed_events) do
30
+ subscriber.failed_events
31
+ end
32
+
33
+ let(:operations) do
34
+ [{ insert_one: { text: 'a' * (max_bson_size/2) } }] * 6
35
+ end
36
+
37
+ before do
38
+ authorized_client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
39
+ authorized_collection.bulk_write(operations)
40
+ end
41
+
42
+ context '3.6+ server' do
43
+ min_server_fcv '3.6'
44
+
45
+ it 'splits the operations' do
46
+ # 3.6+ servers can send multiple bulk operations in one message,
47
+ # with the whole message being limited to 48m.
48
+ expect(insert_events.length).to eq(2)
49
+ end
50
+ end
51
+
52
+ context 'pre-3.6 server' do
53
+ max_server_version '3.4'
54
+
55
+ it 'splits the operations' do
56
+ # Pre-3.6 servers limit the entire message payload to the size of
57
+ # a single document which is 16m. Given our test data this means
58
+ # twice as many messages are sent.
59
+ expect(insert_events.length).to eq(4)
60
+ end
61
+ end
62
+
63
+ it 'does not have a command failed event' do
64
+ expect(failed_events).to be_empty
65
+ end
66
+ end
19
67
  end
@@ -131,7 +131,7 @@ describe 'Client authentication options' do
131
131
  end
132
132
  end
133
133
 
134
- shared_examples_for 'an auth mechanism that doesn\'t support auth_mech_properties' do
134
+ shared_examples_for 'an auth mechanism that does not support auth_mech_properties' do
135
135
  context 'with URI options' do
136
136
  let(:credentials) { "#{user}:#{pwd}@" }
137
137
  let(:options) { "?authMechanism=#{auth_mech_string}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
@@ -163,7 +163,7 @@ describe 'Client authentication options' do
163
163
  end
164
164
  end
165
165
 
166
- shared_examples_for 'an auth mechanism that doesn\'t support invalid auth sources' do
166
+ shared_examples_for 'an auth mechanism that does not support invalid auth sources' do
167
167
  context 'with URI options' do
168
168
  let(:credentials) { "#{user}:#{pwd}@" }
169
169
  let(:options) { "?authMechanism=#{auth_mech_string}&authSource=foo" }
@@ -199,7 +199,7 @@ describe 'Client authentication options' do
199
199
 
200
200
  it_behaves_like 'a supported auth mechanism'
201
201
  it_behaves_like 'auth mechanism that uses database or default auth source', 'admin'
202
- it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
202
+ it_behaves_like 'an auth mechanism that does not support auth_mech_properties'
203
203
  end
204
204
 
205
205
  context 'with SCRAM-SHA-1 auth mechanism' do
@@ -208,7 +208,7 @@ describe 'Client authentication options' do
208
208
 
209
209
  it_behaves_like 'a supported auth mechanism'
210
210
  it_behaves_like 'auth mechanism that uses database or default auth source', 'admin'
211
- it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
211
+ it_behaves_like 'an auth mechanism that does not support auth_mech_properties'
212
212
  end
213
213
 
214
214
  context 'with SCRAM-SHA-256 auth mechanism' do
@@ -217,7 +217,7 @@ describe 'Client authentication options' do
217
217
 
218
218
  it_behaves_like 'a supported auth mechanism'
219
219
  it_behaves_like 'auth mechanism that uses database or default auth source', 'admin'
220
- it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
220
+ it_behaves_like 'an auth mechanism that does not support auth_mech_properties'
221
221
  end
222
222
 
223
223
  context 'with GSSAPI auth mechanism' do
@@ -227,7 +227,7 @@ describe 'Client authentication options' do
227
227
  let(:auth_mech_sym) { :gssapi }
228
228
 
229
229
  it_behaves_like 'a supported auth mechanism'
230
- it_behaves_like 'an auth mechanism that doesn\'t support invalid auth sources'
230
+ it_behaves_like 'an auth mechanism that does not support invalid auth sources'
231
231
 
232
232
  let(:auth_mech_properties) { { canonicalize_host_name: true, service_name: 'other'} }
233
233
 
@@ -302,7 +302,7 @@ describe 'Client authentication options' do
302
302
  it_behaves_like 'a supported auth mechanism'
303
303
  it_behaves_like 'auth mechanism that uses database or default auth source', '$external'
304
304
  it_behaves_like 'an auth mechanism with ssl'
305
- it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
305
+ it_behaves_like 'an auth mechanism that does not support auth_mech_properties'
306
306
  end
307
307
 
308
308
  context 'with MONGODB-X509 auth mechanism' do
@@ -313,8 +313,8 @@ describe 'Client authentication options' do
313
313
 
314
314
  it_behaves_like 'a supported auth mechanism'
315
315
  it_behaves_like 'an auth mechanism with ssl'
316
- it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
317
- it_behaves_like 'an auth mechanism that doesn\'t support invalid auth sources'
316
+ it_behaves_like 'an auth mechanism that does not support auth_mech_properties'
317
+ it_behaves_like 'an auth mechanism that does not support invalid auth sources'
318
318
 
319
319
  context 'with URI options' do
320
320
  let(:credentials) { "#{user}@" }
@@ -439,35 +439,62 @@ describe 'Client authentication options' do
439
439
  {
440
440
  service_name: service_name,
441
441
  canonicalize_host_name: canonicalize_host_name,
442
- service_realm: service_realm
443
- }
442
+ service_realm: service_realm,
443
+ }.freeze
444
444
  end
445
445
 
446
- context 'with URI options' do
447
- let(:options) do
448
- "?authMechanismProperties=SERVICE_NAME:#{service_name}," +
449
- "CANONICALIZE_HOST_NAME:#{canonicalize_host_name}," +
450
- "SERVICE_REALM:#{service_realm}"
451
- end
452
-
446
+ shared_examples 'correctly sets auth mechanism properties on the client' do
453
447
  it 'correctly sets auth mechanism properties on the client' do
454
- expect(client.options[:auth_mech_properties]).to eq({
448
+ expect(client.options[:auth_mech_properties]).to eq(
455
449
  'service_name' => service_name,
456
450
  'canonicalize_host_name' => canonicalize_host_name,
457
- 'service_realm' => service_realm
458
- })
451
+ 'service_realm' => service_realm,
452
+ )
453
+ end
454
+ end
455
+
456
+ context 'with URI options' do
457
+ let(:options) do
458
+ "?authMechanismProperties=SERVICE_name:#{service_name}," +
459
+ "CANONICALIZE_HOST_name:#{canonicalize_host_name}," +
460
+ "SERVICE_realm:#{service_realm}"
459
461
  end
462
+
463
+ include_examples 'correctly sets auth mechanism properties on the client'
460
464
  end
461
465
 
462
466
  context 'with client options' do
463
- let(:client_opts) { { auth_mech_properties: auth_mechanism_properties } }
467
+ [:auth_mech_properties, 'auth_mech_properties'].each do |key|
464
468
 
465
- it 'correctly sets auth mechanism properties on the client' do
466
- expect(client.options[:auth_mech_properties]).to eq({
467
- 'service_name' => service_name,
468
- 'canonicalize_host_name' => canonicalize_host_name,
469
- 'service_realm' => service_realm
470
- })
469
+ context "using #{key.class} keys" do
470
+ let(:client_opts) { { key => auth_mechanism_properties } }
471
+
472
+ include_examples 'correctly sets auth mechanism properties on the client'
473
+
474
+ context 'when options are given in mixed case' do
475
+ let(:auth_mechanism_properties) do
476
+ {
477
+ service_NAME: service_name,
478
+ canonicalize_host_NAME: canonicalize_host_name,
479
+ service_REALM: service_realm,
480
+ }.freeze
481
+ end
482
+
483
+ context 'using URI and options' do
484
+
485
+ let(:client) { new_local_client_nmio(uri, client_opts) }
486
+
487
+ include_examples 'correctly sets auth mechanism properties on the client'
488
+ end
489
+
490
+ context 'using host and options' do
491
+
492
+ let(:client) { new_local_client_nmio(['localhost'], client_opts) }
493
+
494
+ include_examples 'correctly sets auth mechanism properties on the client'
495
+ end
496
+ end
497
+ end
471
498
  end
472
499
  end
473
500
  end
@@ -4,7 +4,9 @@ describe 'Connection pool populator integration' do
4
4
  let(:options) { {} }
5
5
 
6
6
  let(:server_options) do
7
- SpecConfig.instance.test_options.merge(options).merge(SpecConfig.instance.auth_options)
7
+ Mongo::Utils.shallow_symbolize_keys(Mongo::Client.canonicalize_ruby_options(
8
+ SpecConfig.instance.all_test_options,
9
+ )).update(options)
8
10
  end
9
11
 
10
12
  let(:address) do
@@ -5,6 +5,16 @@ describe 'Cursor reaping' do
5
5
  # in MRI, I don't currently know how to force GC to run in JRuby
6
6
  only_mri
7
7
 
8
+ around(:all) do |example|
9
+ saved_level = Mongo::Logger.logger.level
10
+ Mongo::Logger.logger.level = Logger::DEBUG
11
+ begin
12
+ example.run
13
+ ensure
14
+ Mongo::Logger.logger.level = saved_level
15
+ end
16
+ end
17
+
8
18
  let(:subscriber) { EventSubscriber.new }
9
19
 
10
20
  let(:client) do
@@ -37,37 +47,63 @@ describe 'Cursor reaping' do
37
47
  expect(events).to be_empty
38
48
  end
39
49
 
50
+ def abandon_cursors
51
+ [].tap do |cursor_ids|
52
+ # scopes are weird, having this result in a let block
53
+ # makes it not garbage collected
54
+ 10.times do
55
+ scope = collection.find.batch_size(2).no_cursor_timeout
56
+
57
+ # there is no API for retrieving the cursor
58
+ scope.each.first
59
+ # and keep the first cursor
60
+ cursor_ids << scope.instance_variable_get('@cursor').id
61
+ end
62
+ end
63
+ end
64
+
40
65
  # this let block is a kludge to avoid copy pasting all of this code
41
66
  let(:cursor_id_and_kill_event) do
42
67
  expect(Mongo::Operation::KillCursors).to receive(:new).at_least(:once).and_call_original
43
68
 
44
- cursor_id = nil
45
-
46
- # scopes are weird, having this result in a let block
47
- # makes it not garbage collected
48
- 2.times do
49
- scope = collection.find.batch_size(2).no_cursor_timeout
69
+ cursor_ids = abandon_cursors
50
70
 
51
- # there is no API for retrieving the cursor
52
- scope.each.first
53
- # and keep the first cursor
54
- cursor_id ||= scope.instance_variable_get('@cursor').id
71
+ cursor_ids.each do |cursor_id|
72
+ expect(cursor_id).to be_a(Integer)
73
+ expect(cursor_id > 0).to be true
55
74
  end
56
75
 
57
- expect(cursor_id).to be_a(Integer)
58
- expect(cursor_id > 0).to be true
59
-
60
76
  GC.start
77
+ sleep 1
61
78
 
62
79
  # force periodic executor to run because its frequency is not configurable
63
80
  client.cluster.instance_variable_get('@periodic_executor').execute
64
81
 
65
82
  started_event = subscriber.started_events.detect do |event|
66
- event.command['killCursors'] &&
67
- event.command['cursors'].map { |c| Utils.int64_value(c) }.include?(cursor_id)
83
+ event.command['killCursors']
84
+ end
85
+ started_event.should_not be nil
86
+
87
+ found_cursor_id = nil
88
+ started_event = subscriber.started_events.detect do |event|
89
+ found = false
90
+ if event.command['killCursors']
91
+ cursor_ids.each do |cursor_id|
92
+ if event.command['cursors'].map { |c| Utils.int64_value(c) }.include?(cursor_id)
93
+ found_cursor_id = cursor_id
94
+ found = true
95
+ break
96
+ end
97
+ end
98
+ end
99
+ found
100
+ end
101
+
102
+ if started_event.nil?
103
+ p subscriber.started_events
68
104
  end
69
105
 
70
- expect(started_event).not_to be_nil
106
+ started_event.should_not be nil
71
107
 
72
108
  succeeded_event = subscriber.succeeded_events.detect do |event|
73
109
  event.command_name == 'killCursors' && event.request_id == started_event.request_id
@@ -77,7 +113,7 @@ describe 'Cursor reaping' do
77
113
 
78
114
  expect(succeeded_event.reply['ok']).to eq 1
79
115
 
80
- [cursor_id, succeeded_event]
116
+ [found_cursor_id, succeeded_event]
81
117
  end
82
118
 
83
119
  it 'is reaped' do