mongo 2.13.3 → 2.14.0.rc1

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.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/mongo/address/ipv4.rb +1 -1
  4. data/lib/mongo/address/ipv6.rb +1 -1
  5. data/lib/mongo/address.rb +1 -1
  6. data/lib/mongo/bulk_write.rb +17 -0
  7. data/lib/mongo/caching_cursor.rb +74 -0
  8. data/lib/mongo/client.rb +47 -8
  9. data/lib/mongo/cluster/topology/single.rb +1 -1
  10. data/lib/mongo/cluster.rb +3 -3
  11. data/lib/mongo/collection/view/aggregation.rb +25 -4
  12. data/lib/mongo/collection/view/builder/find_command.rb +38 -18
  13. data/lib/mongo/collection/view/explainable.rb +27 -8
  14. data/lib/mongo/collection/view/iterable.rb +72 -12
  15. data/lib/mongo/collection/view/readable.rb +12 -2
  16. data/lib/mongo/collection/view/writable.rb +15 -1
  17. data/lib/mongo/collection/view.rb +24 -20
  18. data/lib/mongo/collection.rb +26 -2
  19. data/lib/mongo/crypt/encryption_io.rb +6 -6
  20. data/lib/mongo/cursor.rb +1 -0
  21. data/lib/mongo/database/view.rb +1 -1
  22. data/lib/mongo/database.rb +8 -14
  23. data/lib/mongo/error/invalid_read_concern.rb +28 -0
  24. data/lib/mongo/error/server_certificate_revoked.rb +22 -0
  25. data/lib/mongo/error/unsupported_option.rb +14 -12
  26. data/lib/mongo/error.rb +2 -0
  27. data/lib/mongo/grid/fs_bucket.rb +37 -37
  28. data/lib/mongo/lint.rb +2 -1
  29. data/lib/mongo/logger.rb +3 -3
  30. data/lib/mongo/operation/aggregate/result.rb +9 -8
  31. data/lib/mongo/operation/collections_info/command.rb +0 -5
  32. data/lib/mongo/operation/collections_info/result.rb +3 -16
  33. data/lib/mongo/operation/delete/bulk_result.rb +2 -0
  34. data/lib/mongo/operation/delete/result.rb +3 -0
  35. data/lib/mongo/operation/explain/command.rb +4 -0
  36. data/lib/mongo/operation/explain/legacy.rb +4 -0
  37. data/lib/mongo/operation/explain/op_msg.rb +6 -0
  38. data/lib/mongo/operation/explain/result.rb +3 -0
  39. data/lib/mongo/operation/find/legacy/result.rb +2 -0
  40. data/lib/mongo/operation/find/result.rb +3 -0
  41. data/lib/mongo/operation/get_more/result.rb +3 -0
  42. data/lib/mongo/operation/indexes/result.rb +5 -0
  43. data/lib/mongo/operation/insert/bulk_result.rb +5 -0
  44. data/lib/mongo/operation/insert/result.rb +5 -0
  45. data/lib/mongo/operation/list_collections/result.rb +5 -0
  46. data/lib/mongo/operation/map_reduce/result.rb +10 -0
  47. data/lib/mongo/operation/parallel_scan/command.rb +2 -1
  48. data/lib/mongo/operation/parallel_scan/result.rb +4 -0
  49. data/lib/mongo/operation/result.rb +35 -6
  50. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -0
  51. data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -0
  52. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +2 -0
  53. data/lib/mongo/operation/shared/executable.rb +1 -0
  54. data/lib/mongo/operation/shared/idable.rb +2 -1
  55. data/lib/mongo/operation/shared/limited.rb +1 -0
  56. data/lib/mongo/operation/shared/object_id_generator.rb +1 -0
  57. data/lib/mongo/operation/shared/read_preference_supported.rb +36 -38
  58. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -0
  59. data/lib/mongo/operation/shared/sessions_supported.rb +3 -3
  60. data/lib/mongo/operation/shared/specifiable.rb +1 -0
  61. data/lib/mongo/operation/shared/write.rb +1 -0
  62. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -0
  63. data/lib/mongo/operation/update/legacy/result.rb +7 -0
  64. data/lib/mongo/operation/update/result.rb +8 -0
  65. data/lib/mongo/operation/users_info/result.rb +3 -0
  66. data/lib/mongo/operation.rb +2 -0
  67. data/lib/mongo/protocol/msg.rb +2 -2
  68. data/lib/mongo/protocol/query.rb +11 -11
  69. data/lib/mongo/query_cache.rb +242 -0
  70. data/lib/mongo/retryable.rb +8 -1
  71. data/lib/mongo/server/connection_common.rb +2 -2
  72. data/lib/mongo/server/connection_pool.rb +3 -0
  73. data/lib/mongo/server/monitor/connection.rb +3 -3
  74. data/lib/mongo/server/monitor.rb +1 -1
  75. data/lib/mongo/server/pending_connection.rb +2 -2
  76. data/lib/mongo/server/push_monitor.rb +1 -1
  77. data/lib/mongo/server.rb +5 -1
  78. data/lib/mongo/server_selector/base.rb +5 -1
  79. data/lib/mongo/server_selector/secondary_preferred.rb +7 -2
  80. data/lib/mongo/session.rb +3 -0
  81. data/lib/mongo/socket/ocsp_cache.rb +97 -0
  82. data/lib/mongo/socket/ocsp_verifier.rb +368 -0
  83. data/lib/mongo/socket/ssl.rb +45 -24
  84. data/lib/mongo/socket.rb +6 -4
  85. data/lib/mongo/srv/monitor.rb +7 -13
  86. data/lib/mongo/srv/resolver.rb +14 -10
  87. data/lib/mongo/timeout.rb +2 -0
  88. data/lib/mongo/uri/options_mapper.rb +582 -0
  89. data/lib/mongo/uri/srv_protocol.rb +3 -2
  90. data/lib/mongo/uri.rb +21 -390
  91. data/lib/mongo/utils.rb +12 -1
  92. data/lib/mongo/version.rb +1 -1
  93. data/lib/mongo.rb +9 -0
  94. data/spec/NOTES.aws-auth.md +12 -7
  95. data/spec/README.md +56 -1
  96. data/spec/integration/bson_symbol_spec.rb +2 -4
  97. data/spec/integration/bulk_write_spec.rb +48 -0
  98. data/spec/integration/client_authentication_options_spec.rb +55 -28
  99. data/spec/integration/connection_pool_populator_spec.rb +3 -1
  100. data/spec/integration/cursor_reaping_spec.rb +53 -17
  101. data/spec/integration/ocsp_connectivity_spec.rb +26 -0
  102. data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
  103. data/spec/integration/ocsp_verifier_spec.rb +334 -0
  104. data/spec/integration/query_cache_spec.rb +1045 -0
  105. data/spec/integration/query_cache_transactions_spec.rb +179 -0
  106. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -0
  107. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +2 -0
  108. data/spec/integration/sdam_error_handling_spec.rb +69 -18
  109. data/spec/integration/sdam_events_spec.rb +7 -8
  110. data/spec/integration/server_selection_spec.rb +36 -0
  111. data/spec/integration/srv_monitoring_spec.rb +38 -3
  112. data/spec/integration/srv_spec.rb +56 -0
  113. data/spec/lite_spec_helper.rb +4 -2
  114. data/spec/mongo/address_spec.rb +1 -1
  115. data/spec/mongo/caching_cursor_spec.rb +70 -0
  116. data/spec/mongo/client_construction_spec.rb +54 -1
  117. data/spec/mongo/client_encryption_spec.rb +10 -16
  118. data/spec/mongo/client_spec.rb +40 -0
  119. data/spec/mongo/cluster/topology/single_spec.rb +14 -5
  120. data/spec/mongo/cluster_spec.rb +3 -0
  121. data/spec/mongo/collection/view/explainable_spec.rb +87 -4
  122. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -0
  123. data/spec/mongo/collection_spec.rb +60 -0
  124. data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
  125. data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
  126. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  127. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
  128. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +1 -1
  129. data/spec/mongo/database_spec.rb +44 -64
  130. data/spec/mongo/error/no_server_available_spec.rb +1 -1
  131. data/spec/mongo/index/view_spec.rb +2 -4
  132. data/spec/mongo/logger_spec.rb +13 -11
  133. data/spec/mongo/operation/read_preference_legacy_spec.rb +19 -9
  134. data/spec/mongo/operation/read_preference_op_msg_spec.rb +3 -3
  135. data/spec/mongo/query_cache_spec.rb +279 -0
  136. data/spec/mongo/server/app_metadata_shared.rb +7 -33
  137. data/spec/mongo/server/connection_pool_spec.rb +7 -3
  138. data/spec/mongo/server/connection_spec.rb +14 -7
  139. data/spec/mongo/server_selector/secondary_preferred_spec.rb +6 -6
  140. data/spec/mongo/socket/ssl_spec.rb +1 -1
  141. data/spec/mongo/socket_spec.rb +1 -1
  142. data/spec/mongo/uri/srv_protocol_spec.rb +64 -33
  143. data/spec/mongo/uri_option_parsing_spec.rb +11 -11
  144. data/spec/mongo/uri_spec.rb +68 -41
  145. data/spec/mongo/utils_spec.rb +39 -0
  146. data/spec/runners/auth.rb +3 -0
  147. data/spec/runners/connection_string.rb +35 -124
  148. data/spec/runners/transactions/operation.rb +2 -13
  149. data/spec/spec_tests/cmap_spec.rb +7 -3
  150. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +0 -1
  151. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
  152. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +6 -2
  153. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +3 -0
  154. data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
  155. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -3
  156. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +2 -2
  157. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
  158. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
  159. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
  160. data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
  161. data/spec/spec_tests/data/uri_options/compression-options.yml +6 -3
  162. data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
  163. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
  164. data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
  165. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +9 -1
  166. data/spec/spec_tests/uri_options_spec.rb +31 -33
  167. data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
  168. data/spec/support/certificates/atlas-ocsp.crt +41 -0
  169. data/spec/support/client_registry.rb +4 -8
  170. data/spec/support/client_registry_macros.rb +4 -4
  171. data/spec/support/common_shortcuts.rb +45 -0
  172. data/spec/support/constraints.rb +23 -0
  173. data/spec/support/lite_constraints.rb +24 -0
  174. data/spec/support/matchers.rb +16 -0
  175. data/spec/support/ocsp +1 -0
  176. data/spec/support/session_registry.rb +52 -0
  177. data/spec/support/spec_config.rb +22 -12
  178. data/spec/support/spec_setup.rb +38 -48
  179. data/spec/support/utils.rb +19 -1
  180. data.tar.gz.sig +1 -3
  181. metadata +938 -933
  182. metadata.gz.sig +0 -0
  183. data/spec/integration/secondary_reads_spec.rb +0 -102
  184. data/spec/shared/LICENSE +0 -20
  185. data/spec/shared/bin/get-mongodb-download-url +0 -17
  186. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  187. data/spec/shared/lib/mrss/cluster_config.rb +0 -221
  188. data/spec/shared/lib/mrss/constraints.rb +0 -346
  189. data/spec/shared/lib/mrss/docker_runner.rb +0 -265
  190. data/spec/shared/lib/mrss/lite_constraints.rb +0 -191
  191. data/spec/shared/lib/mrss/server_version_registry.rb +0 -115
  192. data/spec/shared/lib/mrss/spec_organizer.rb +0 -152
  193. data/spec/shared/lib/mrss/utils.rb +0 -15
  194. data/spec/shared/share/Dockerfile.erb +0 -231
  195. data/spec/shared/shlib/distro.sh +0 -73
  196. data/spec/shared/shlib/server.sh +0 -290
  197. data/spec/shared/shlib/set_env.sh +0 -128
@@ -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
@@ -0,0 +1,26 @@
1
+ require 'lite_spec_helper'
2
+
3
+ # These tests test the configurations described in
4
+ # https://github.com/mongodb/specifications/blob/master/source/ocsp-support/tests/README.rst#integration-tests-permutations-to-be-tested
5
+ describe 'OCSP connectivity' do
6
+ require_ocsp_connectivity
7
+ clear_ocsp_cache
8
+
9
+ let(:client) do
10
+ new_local_client(ENV.fetch('MONGODB_URI'),
11
+ server_selection_timeout: 5,
12
+ )
13
+ end
14
+
15
+ if ENV['OCSP_CONNECTIVITY'] == 'fail'
16
+ it 'fails to connect' do
17
+ lambda do
18
+ client.command(ping: 1)
19
+ end.should raise_error(Mongo::Error::NoServerAvailable, /UNKNOWN/)
20
+ end
21
+ else
22
+ it 'works' do
23
+ client.command(ping: 1)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,188 @@
1
+ require 'lite_spec_helper'
2
+ require 'webrick'
3
+
4
+ describe Mongo::Socket::OcspVerifier do
5
+ require_ocsp_verifier
6
+
7
+ shared_examples 'verifies' do
8
+ context 'mri' do
9
+ fails_on_jruby
10
+
11
+ it 'verifies the first time and reads from cache the second time' do
12
+ RSpec::Mocks.with_temporary_scope do
13
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
14
+
15
+ verifier.verify_with_cache.should be true
16
+ end
17
+
18
+ RSpec::Mocks.with_temporary_scope do
19
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).not_to receive(:do_verify)
20
+
21
+ verifier.verify_with_cache.should be true
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'jruby' do
27
+ require_jruby
28
+
29
+ # JRuby does not return OCSP endpoints, therefore we never perform
30
+ # any validation.
31
+ # https://github.com/jruby/jruby-openssl/issues/210
32
+ it 'does not verify' do
33
+ RSpec::Mocks.with_temporary_scope do
34
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
35
+
36
+ verifier.verify.should be false
37
+ end
38
+
39
+ RSpec::Mocks.with_temporary_scope do
40
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
41
+
42
+ verifier.verify.should be false
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ shared_examples 'fails verification' do
49
+ context 'mri' do
50
+ fails_on_jruby
51
+
52
+ it 'verifies the first time, reads from cache the second time, raises an exception in both cases' do
53
+ RSpec::Mocks.with_temporary_scope do
54
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
55
+
56
+ lambda do
57
+ verifier.verify
58
+ # Redirect tests receive responses from port 8101,
59
+ # tests without redirects receive responses from port 8100.
60
+ end.should raise_error(Mongo::Error::ServerCertificateRevoked, %r,TLS certificate of 'foo' has been revoked according to 'http://localhost:810[01]/status',)
61
+ end
62
+
63
+ RSpec::Mocks.with_temporary_scope do
64
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).not_to receive(:do_verify)
65
+
66
+ lambda do
67
+ verifier.verify
68
+ # Redirect tests receive responses from port 8101,
69
+ # tests without redirects receive responses from port 8100.
70
+ end.should raise_error(Mongo::Error::ServerCertificateRevoked, %r,TLS certificate of 'foo' has been revoked according to 'http://localhost:810[01]/status',)
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'jruby' do
76
+ require_jruby
77
+
78
+ # JRuby does not return OCSP endpoints, therefore we never perform
79
+ # any validation.
80
+ # https://github.com/jruby/jruby-openssl/issues/210
81
+ it 'does not verify' do
82
+ RSpec::Mocks.with_temporary_scope do
83
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
84
+
85
+ verifier.verify.should be false
86
+ end
87
+
88
+ RSpec::Mocks.with_temporary_scope do
89
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
90
+
91
+ verifier.verify.should be false
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ shared_examples 'does not verify' do
98
+ it 'does not verify and does not raise an exception' do
99
+ RSpec::Mocks.with_temporary_scope do
100
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
101
+
102
+ verifier.verify.should be false
103
+ end
104
+
105
+ RSpec::Mocks.with_temporary_scope do
106
+ expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
107
+
108
+ verifier.verify.should be false
109
+ end
110
+ end
111
+ end
112
+
113
+ shared_context 'verifier' do |opts|
114
+ algorithm = opts[:algorithm]
115
+
116
+ let(:cert_path) { SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/server.pem") }
117
+ let(:ca_cert_path) { SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem") }
118
+
119
+ let(:cert) { OpenSSL::X509::Certificate.new(File.read(cert_path)) }
120
+ let(:ca_cert) { OpenSSL::X509::Certificate.new(File.read(ca_cert_path)) }
121
+
122
+ let(:cert_store) do
123
+ OpenSSL::X509::Store.new.tap do |store|
124
+ store.add_cert(ca_cert)
125
+ end
126
+ end
127
+
128
+ let(:verifier) do
129
+ described_class.new('foo', cert, ca_cert, cert_store, timeout: 3)
130
+ end
131
+ end
132
+
133
+ include_context 'verifier', algorithm: 'rsa'
134
+ algorithm = 'rsa'
135
+
136
+ %w(ca delegate).each do |responder_cert|
137
+ responder_cert_file_name = {
138
+ 'ca' => 'ca',
139
+ 'delegate' => 'ocsp-responder',
140
+ }.fetch(responder_cert)
141
+
142
+ context "when responder uses #{responder_cert} cert" do
143
+ context 'good response' do
144
+ with_ocsp_mock(
145
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem"),
146
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.crt"),
147
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.key"),
148
+ )
149
+
150
+ include_examples 'verifies'
151
+
152
+ it 'does not wait for the timeout' do
153
+ lambda do
154
+ verifier.verify
155
+ end.should take_shorter_than 3
156
+ end
157
+ end
158
+
159
+ context 'revoked response' do
160
+ with_ocsp_mock(
161
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem"),
162
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.crt"),
163
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.key"),
164
+ fault: 'revoked'
165
+ )
166
+
167
+ include_examples 'fails verification'
168
+ end
169
+
170
+ context 'unknown response' do
171
+ with_ocsp_mock(
172
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem"),
173
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.crt"),
174
+ SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.key"),
175
+ fault: 'unknown',
176
+ )
177
+
178
+ include_examples 'does not verify'
179
+
180
+ it 'does not wait for the timeout' do
181
+ lambda do
182
+ verifier.verify
183
+ end.should take_shorter_than 3
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end