mongo 2.10.5 → 2.11.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.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/lib/mongo.rb +2 -0
  6. data/lib/mongo/address.rb +4 -0
  7. data/lib/mongo/address/validator.rb +99 -0
  8. data/lib/mongo/auth.rb +7 -2
  9. data/lib/mongo/auth/user.rb +1 -7
  10. data/lib/mongo/background_thread.rb +135 -0
  11. data/lib/mongo/bulk_write/transformable.rb +3 -3
  12. data/lib/mongo/client.rb +74 -16
  13. data/lib/mongo/cluster.rb +193 -41
  14. data/lib/mongo/cluster/periodic_executor.rb +31 -43
  15. data/lib/mongo/cluster/sdam_flow.rb +26 -3
  16. data/lib/mongo/cluster/srv_monitor.rb +127 -0
  17. data/lib/mongo/collection/view/readable.rb +3 -5
  18. data/lib/mongo/collection/view/writable.rb +3 -3
  19. data/lib/mongo/cursor/builder/get_more_command.rb +1 -4
  20. data/lib/mongo/cursor/builder/kill_cursors_command.rb +5 -23
  21. data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
  22. data/lib/mongo/cursor/builder/op_kill_cursors.rb +5 -24
  23. data/lib/mongo/error.rb +1 -0
  24. data/lib/mongo/error/auth_error.rb +1 -1
  25. data/lib/mongo/error/connection_check_out_timeout.rb +7 -8
  26. data/lib/mongo/error/invalid_address.rb +24 -0
  27. data/lib/mongo/error/notable.rb +2 -2
  28. data/lib/mongo/error/operation_failure.rb +3 -3
  29. data/lib/mongo/error/pool_closed_error.rb +11 -4
  30. data/lib/mongo/event.rb +1 -1
  31. data/lib/mongo/grid/file.rb +0 -5
  32. data/lib/mongo/grid/file/chunk.rb +0 -2
  33. data/lib/mongo/grid/fs_bucket.rb +13 -15
  34. data/lib/mongo/grid/stream/write.rb +3 -9
  35. data/lib/mongo/loggable.rb +5 -1
  36. data/lib/mongo/monitoring.rb +1 -0
  37. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +7 -0
  38. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +11 -3
  39. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +11 -3
  40. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +11 -3
  41. data/lib/mongo/monitoring/event/cmap/pool_created.rb +12 -3
  42. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +62 -0
  43. data/lib/mongo/operation/shared/executable.rb +5 -10
  44. data/lib/mongo/operation/shared/sessions_supported.rb +1 -5
  45. data/lib/mongo/protocol/get_more.rb +1 -2
  46. data/lib/mongo/protocol/kill_cursors.rb +13 -6
  47. data/lib/mongo/protocol/serializers.rb +4 -20
  48. data/lib/mongo/retryable.rb +9 -34
  49. data/lib/mongo/semaphore.rb +1 -1
  50. data/lib/mongo/server.rb +113 -42
  51. data/lib/mongo/server/connection.rb +12 -5
  52. data/lib/mongo/server/connection_pool.rb +250 -40
  53. data/lib/mongo/server/connection_pool/populator.rb +58 -0
  54. data/lib/mongo/server/description.rb +9 -2
  55. data/lib/mongo/server/monitor.rb +68 -93
  56. data/lib/mongo/server/monitor/connection.rb +2 -0
  57. data/lib/mongo/server_selector/selectable.rb +13 -5
  58. data/lib/mongo/session.rb +0 -13
  59. data/lib/mongo/srv.rb +17 -0
  60. data/lib/mongo/srv/monitor.rb +96 -0
  61. data/lib/mongo/srv/resolver.rb +130 -0
  62. data/lib/mongo/srv/result.rb +126 -0
  63. data/lib/mongo/srv/warning_result.rb +35 -0
  64. data/lib/mongo/uri.rb +45 -55
  65. data/lib/mongo/uri/srv_protocol.rb +89 -42
  66. data/lib/mongo/version.rb +1 -1
  67. data/mongo.gemspec +3 -4
  68. data/spec/README.md +6 -1
  69. data/spec/enterprise_auth/kerberos_spec.rb +7 -6
  70. data/spec/integration/change_stream_examples_spec.rb +0 -4
  71. data/spec/integration/client_construction_spec.rb +14 -2
  72. data/spec/integration/connect_single_rs_name_spec.rb +2 -2
  73. data/spec/integration/connection_pool_populator_spec.rb +296 -0
  74. data/spec/integration/connection_spec.rb +31 -22
  75. data/spec/integration/cursor_reaping_spec.rb +1 -2
  76. data/spec/integration/docs_examples_spec.rb +0 -4
  77. data/spec/integration/heartbeat_events_spec.rb +17 -15
  78. data/spec/integration/reconnect_spec.rb +144 -1
  79. data/spec/integration/retryable_writes_errors_spec.rb +0 -4
  80. data/spec/integration/retryable_writes_spec.rb +36 -36
  81. data/spec/integration/sdam_error_handling_spec.rb +31 -25
  82. data/spec/integration/sdam_events_spec.rb +2 -6
  83. data/spec/integration/server_monitor_spec.rb +28 -0
  84. data/spec/integration/server_selector_spec.rb +7 -5
  85. data/spec/integration/srv_monitoring_spec.rb +360 -0
  86. data/spec/integration/step_down_spec.rb +4 -6
  87. data/spec/lite_spec_helper.rb +22 -0
  88. data/spec/mongo/address/validator_spec.rb +51 -0
  89. data/spec/mongo/auth/cr_spec.rb +1 -29
  90. data/spec/mongo/auth/ldap_spec.rb +1 -29
  91. data/spec/mongo/auth/scram/conversation_spec.rb +0 -2
  92. data/spec/mongo/auth/scram/negotiation_spec.rb +1 -1
  93. data/spec/mongo/auth/scram_spec.rb +1 -29
  94. data/spec/mongo/auth/user/view_spec.rb +1 -36
  95. data/spec/mongo/auth/user_spec.rb +0 -12
  96. data/spec/mongo/auth/x509_spec.rb +1 -29
  97. data/spec/mongo/bulk_write_spec.rb +2 -2
  98. data/spec/mongo/client_construction_spec.rb +56 -15
  99. data/spec/mongo/client_spec.rb +31 -27
  100. data/spec/mongo/cluster/periodic_executor_spec.rb +16 -0
  101. data/spec/mongo/cluster/srv_monitor_spec.rb +214 -0
  102. data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -11
  103. data/spec/mongo/cluster/topology/sharded_spec.rb +12 -9
  104. data/spec/mongo/cluster/topology/single_spec.rb +20 -11
  105. data/spec/mongo/cluster_spec.rb +45 -29
  106. data/spec/mongo/collection/view/map_reduce_spec.rb +14 -9
  107. data/spec/mongo/collection/view/readable_spec.rb +0 -16
  108. data/spec/mongo/collection_spec.rb +0 -44
  109. data/spec/mongo/cursor/builder/get_more_command_spec.rb +2 -4
  110. data/spec/mongo/cursor/builder/op_get_more_spec.rb +2 -4
  111. data/spec/mongo/cursor_spec.rb +27 -7
  112. data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +10 -3
  113. data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +10 -3
  114. data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +10 -3
  115. data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +10 -3
  116. data/spec/mongo/operation/delete/op_msg_spec.rb +17 -8
  117. data/spec/mongo/operation/insert/op_msg_spec.rb +50 -35
  118. data/spec/mongo/operation/update/op_msg_spec.rb +14 -7
  119. data/spec/mongo/retryable_spec.rb +52 -31
  120. data/spec/mongo/server/app_metadata_spec.rb +0 -8
  121. data/spec/mongo/server/connection_auth_spec.rb +5 -2
  122. data/spec/mongo/server/connection_pool/populator_spec.rb +101 -0
  123. data/spec/mongo/server/connection_pool_spec.rb +256 -107
  124. data/spec/mongo/server/connection_spec.rb +22 -33
  125. data/spec/mongo/server/description_spec.rb +42 -4
  126. data/spec/mongo/server/monitor/connection_spec.rb +22 -11
  127. data/spec/mongo/server/monitor_spec.rb +66 -107
  128. data/spec/mongo/server_spec.rb +82 -60
  129. data/spec/mongo/session/session_pool_spec.rb +1 -5
  130. data/spec/mongo/session_spec.rb +0 -4
  131. data/spec/mongo/socket/ssl_spec.rb +2 -2
  132. data/spec/mongo/srv/monitor_spec.rb +211 -0
  133. data/spec/mongo/srv/result_spec.rb +54 -0
  134. data/spec/mongo/uri/srv_protocol_spec.rb +30 -15
  135. data/spec/mongo/uri_spec.rb +125 -4
  136. data/spec/spec_helper.rb +6 -0
  137. data/spec/spec_tests/auth_spec.rb +39 -0
  138. data/spec/spec_tests/cmap_spec.rb +55 -8
  139. data/spec/spec_tests/connection_string_spec.rb +6 -31
  140. data/spec/spec_tests/data/auth/connection-string.yml +297 -0
  141. data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +4 -1
  142. data/spec/spec_tests/data/cmap/pool-create-with-options.yml +1 -0
  143. data/spec/spec_tests/data/command_monitoring/insertMany.yml +1 -1
  144. data/spec/spec_tests/data/connection_string/invalid-uris.yml +20 -0
  145. data/spec/spec_tests/data/connection_string/valid-auth.yml +16 -0
  146. data/spec/spec_tests/data/connection_string/valid-warnings.yml +26 -30
  147. data/spec/spec_tests/data/transactions/abort.yml +3 -3
  148. data/spec/spec_tests/data/transactions/error-labels.yml +3 -3
  149. data/spec/spec_tests/data/transactions_api/callback-retry.yml +3 -3
  150. data/spec/spec_tests/data/uri_options/auth-options.yml +1 -1
  151. data/spec/spec_tests/max_staleness_spec.rb +7 -2
  152. data/spec/spec_tests/retryable_reads_spec.rb +0 -31
  153. data/spec/spec_tests/sdam_monitoring_spec.rb +12 -12
  154. data/spec/spec_tests/sdam_spec.rb +4 -7
  155. data/spec/spec_tests/server_selection_spec.rb +6 -2
  156. data/spec/spec_tests/transactions_spec.rb +0 -2
  157. data/spec/spec_tests/uri_options_spec.rb +4 -2
  158. data/spec/stress/connection_pool_stress_spec.rb +203 -0
  159. data/spec/stress/connection_pool_timing_spec.rb +181 -0
  160. data/spec/support/auth.rb +113 -0
  161. data/spec/support/background_thread_registry.rb +63 -0
  162. data/spec/support/client_registry.rb +11 -2
  163. data/spec/support/cluster_config.rb +65 -46
  164. data/spec/support/cluster_tools.rb +2 -2
  165. data/spec/support/cmap.rb +13 -14
  166. data/spec/support/cmap/verifier.rb +4 -5
  167. data/spec/support/command_monitoring.rb +0 -5
  168. data/spec/support/common_shortcuts.rb +101 -1
  169. data/spec/support/constraints.rb +25 -0
  170. data/spec/support/dns.rb +13 -0
  171. data/spec/support/event_subscriber.rb +0 -7
  172. data/spec/support/json_ext_formatter.rb +5 -1
  173. data/spec/support/lite_constraints.rb +22 -6
  174. data/spec/support/local_resource_registry.rb +34 -0
  175. data/spec/support/sdam_monitoring.rb +115 -0
  176. data/spec/support/spec_config.rb +20 -6
  177. data/spec/support/spec_setup.rb +2 -2
  178. data/spec/support/transactions.rb +1 -1
  179. data/spec/support/transactions/test.rb +1 -1
  180. data/spec/support/utils.rb +1 -16
  181. metadata +685 -659
  182. metadata.gz.sig +0 -0
  183. data/lib/mongo/event/description_changed.rb +0 -52
  184. data/spec/integration/bson_symbol_spec.rb +0 -34
  185. data/spec/integration/crud_spec.rb +0 -45
  186. data/spec/integration/get_more_spec.rb +0 -32
  187. data/spec/integration/grid_fs_bucket_spec.rb +0 -48
  188. data/spec/integration/retryable_errors_spec.rb +0 -265
  189. data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +0 -98
  190. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -56
  191. data/spec/runners/sdam/verifier.rb +0 -88
@@ -31,9 +31,7 @@ describe Mongo::Server::Connection, retry: 3 do
31
31
  allow(cl).to receive(:options).and_return({})
32
32
  allow(cl).to receive(:cluster_time).and_return(nil)
33
33
  allow(cl).to receive(:update_cluster_time)
34
- pool = double('pool')
35
- allow(pool).to receive(:disconnect!)
36
- allow(cl).to receive(:pool).and_return(pool)
34
+ allow(cl).to receive(:run_sdam_flow)
37
35
  end
38
36
  end
39
37
 
@@ -41,31 +39,31 @@ describe Mongo::Server::Connection, retry: 3 do
41
39
 
42
40
  let(:server_options) { SpecConfig.instance.test_options.merge(monitoring_io: false) }
43
41
  let(:server) do
44
- Mongo::Server.new(address, cluster, monitoring, listeners, server_options)
42
+ register_server(
43
+ Mongo::Server.new(address, cluster, monitoring, listeners, server_options)
44
+ )
45
45
  end
46
46
 
47
47
  let(:monitored_server) do
48
- Mongo::Server.new(address, cluster, monitoring, listeners,
49
- SpecConfig.instance.test_options
50
- ).tap do |server|
51
- server.scan!
52
- expect(server).not_to be_unknown
53
- end
48
+ register_server(
49
+ Mongo::Server.new(address, cluster, monitoring, listeners,
50
+ SpecConfig.instance.test_options.merge(monitoring_io: false)
51
+ ).tap do |server|
52
+ allow(server).to receive(:description).and_return(ClusterConfig.instance.primary_description)
53
+ expect(server).not_to be_unknown
54
+ end
55
+ )
54
56
  end
55
57
 
56
58
  let(:pool) do
57
- double('pool')
59
+ double('pool').tap do |pool|
60
+ allow(pool).to receive(:close)
61
+ end
58
62
  end
59
63
 
60
64
  describe '#connect!' do
61
65
 
62
66
  shared_examples_for 'keeps server type and topology' do
63
- before do
64
- # we want the server to not start in unknown state,
65
- # hence scan it and transition to some other state here
66
- server.scan!
67
- end
68
-
69
67
  it 'does not mark server unknown' do
70
68
  expect(server).not_to receive(:unknown!)
71
69
  error
@@ -73,12 +71,6 @@ describe Mongo::Server::Connection, retry: 3 do
73
71
  end
74
72
 
75
73
  shared_examples_for 'marks server unknown' do
76
- before do
77
- # we want the server to not start in unknown state,
78
- # hence scan it and transition to some other state here
79
- server.scan!
80
- end
81
-
82
74
  it 'marks server unknown' do
83
75
  expect(server).to receive(:unknown!)
84
76
  error
@@ -281,7 +273,7 @@ describe Mongo::Server::Connection, retry: 3 do
281
273
 
282
274
  shared_examples_for 'disconnects connection pool' do
283
275
  it 'disconnects non-monitoring sockets' do
284
- expect(server).to receive(:pool).and_return(pool)
276
+ expect(server).to receive(:pool).at_least(:once).and_return(pool)
285
277
  expect(pool).to receive(:disconnect!).and_return(true)
286
278
  error
287
279
  end
@@ -571,7 +563,7 @@ describe Mongo::Server::Connection, retry: 3 do
571
563
 
572
564
  expect do
573
565
  connection.dispatch([ query_alice ]).documents
574
- end.to raise_error(Mongo::Error::LintError, 'Reconnecting closed connections is no longer supported')
566
+ end.to raise_error(Mongo::Error::LintError, /Reconnecting closed connections is no longer supported.*/)
575
567
  end
576
568
  end
577
569
 
@@ -708,13 +700,12 @@ describe Mongo::Server::Connection, retry: 3 do
708
700
  end
709
701
 
710
702
  it 'disconnects connection pool' do
711
- # Allow multiple calls due to RUBY-1894 backport
712
- expect(server.pool).to receive(:disconnect!).at_least(:once)
703
+ expect(server.pool).to receive(:disconnect!)
713
704
  result
714
705
  end
715
706
 
716
707
  it 'does not request server scan' do
717
- expect(server.monitor.scan_semaphore).not_to receive(:signal)
708
+ expect(server.scan_semaphore).not_to receive(:signal)
718
709
  result
719
710
  end
720
711
 
@@ -875,7 +866,9 @@ describe Mongo::Server::Connection, retry: 3 do
875
866
 
876
867
  context 'two pools for different servers' do
877
868
  let(:server2) do
878
- Mongo::Server.new(address, cluster, monitoring, listeners, server_options)
869
+ register_server(
870
+ Mongo::Server.new(address, cluster, monitoring, listeners, server_options)
871
+ )
879
872
  end
880
873
 
881
874
  it 'ids do not share namespace' do
@@ -1000,10 +993,6 @@ describe Mongo::Server::Connection, retry: 3 do
1000
993
  described_class.new(server, server.options)
1001
994
  end
1002
995
 
1003
- after do
1004
- client.close(true)
1005
- end
1006
-
1007
996
  context 'when a connect_timeout is in the options' do
1008
997
 
1009
998
  context 'when a socket_timeout is in the options' do
@@ -56,7 +56,7 @@ describe Mongo::Server::Description do
56
56
  expect(Time).to receive(:now).at_least(:once).and_return(obj)
57
57
  expect(obj.frozen?).to be false
58
58
 
59
- description = described_class.new(address)
59
+ description = described_class.new(address, replica)
60
60
  expect(description.last_update_time).to eq(obj)
61
61
  expect(obj.frozen?).to be false
62
62
  end
@@ -433,6 +433,23 @@ describe Mongo::Server::Description do
433
433
  it 'returns :sharded' do
434
434
  expect(description.server_type).to eq(:sharded)
435
435
  end
436
+
437
+ context 'when client and server addresses are different' do
438
+ let(:config) do
439
+ { 'msg' => 'isdbgrid', 'ismaster' => true,
440
+ 'minWireVersion' => 2, 'maxWireVersion' => 3, 'ok' => 1,
441
+ 'me' => '127.0.0.1',
442
+ }
443
+ end
444
+
445
+ let(:address) do
446
+ Mongo::Address.new('localhost')
447
+ end
448
+
449
+ it 'returns :sharded' do
450
+ expect(description.server_type).to eq(:sharded)
451
+ end
452
+ end
436
453
  end
437
454
 
438
455
  context 'when the server is a primary' do
@@ -516,7 +533,8 @@ describe Mongo::Server::Description do
516
533
  end
517
534
 
518
535
  let(:server) do
519
- Mongo::Server.new(address, cluster, monitoring, listeners)
536
+ Mongo::Server.new(address, cluster, monitoring, listeners,
537
+ monitoring_io: false)
520
538
  end
521
539
 
522
540
  let(:description) do
@@ -537,7 +555,8 @@ describe Mongo::Server::Description do
537
555
  end
538
556
 
539
557
  let(:server) do
540
- Mongo::Server.new(other_address, cluster, monitoring, listeners)
558
+ Mongo::Server.new(other_address, cluster, monitoring, listeners,
559
+ monitoring_io: false)
541
560
  end
542
561
 
543
562
  it 'returns false' do
@@ -603,7 +622,8 @@ describe Mongo::Server::Description do
603
622
  end
604
623
 
605
624
  let(:server) do
606
- Mongo::Server.new(server_address, cluster, monitoring, listeners)
625
+ Mongo::Server.new(server_address, cluster, monitoring, listeners,
626
+ monitoring_io: false)
607
627
  end
608
628
 
609
629
  context 'when the server is included in the description hosts list' do
@@ -774,4 +794,22 @@ describe Mongo::Server::Description do
774
794
  end
775
795
  end
776
796
  end
797
+
798
+ describe '#last_update_time' do
799
+ context 'stub description' do
800
+ let(:description) { described_class.new(address) }
801
+
802
+ it 'is present' do
803
+ expect(description.last_update_time).to be_a(Time)
804
+ end
805
+ end
806
+
807
+ context 'filled out description' do
808
+ let(:description) { described_class.new(address, replica) }
809
+
810
+ it 'is present' do
811
+ expect(description.last_update_time).to be_a(Time)
812
+ end
813
+ end
814
+ end
777
815
  end
@@ -4,7 +4,7 @@ describe Mongo::Server::Monitor::Connection do
4
4
  clean_slate
5
5
 
6
6
  let(:address) do
7
- Mongo::Address.new(ClusterConfig.instance.primary_address, options)
7
+ Mongo::Address.new(ClusterConfig.instance.primary_address_str, options)
8
8
  end
9
9
 
10
10
  declare_topology_double
@@ -14,17 +14,28 @@ describe Mongo::Server::Monitor::Connection do
14
14
  allow(cl).to receive(:topology).and_return(topology)
15
15
  allow(cl).to receive(:app_metadata).and_return(Mongo::Server::Monitor::AppMetadata.new({}))
16
16
  allow(cl).to receive(:options).and_return({})
17
+ allow(cl).to receive(:heartbeat_interval).and_return(1000)
18
+ allow(cl).to receive(:run_sdam_flow)
17
19
  end
18
20
  end
19
21
 
20
22
  let(:server) do
21
23
  Mongo::Server.new(address,
22
- cluster,
23
- Mongo::Monitoring.new,
24
- Mongo::Event::Listeners.new, options)
24
+ cluster,
25
+ Mongo::Monitoring.new,
26
+ Mongo::Event::Listeners.new, {monitoring_io: false}.update(options))
25
27
  end
26
28
 
27
- let(:monitor) { server.monitor }
29
+ let(:monitor) do
30
+ register_background_thread_object(
31
+ Mongo::Server::Monitor.new(server, server.event_listeners, server.monitoring,
32
+ {
33
+ app_metadata: Mongo::Server::Monitor::AppMetadata.new(options),
34
+ }.update(options))
35
+ ).tap do |monitor|
36
+ monitor.run!
37
+ end
38
+ end
28
39
 
29
40
  let(:connection) do
30
41
  # NB this connection is set up in the background thread,
@@ -32,10 +43,10 @@ describe Mongo::Server::Monitor::Connection do
32
43
  # we must wait here for the connection to be established.
33
44
  # Do not call connect! on this connection as then the main thread
34
45
  # will be racing the monitoring thread to connect.
35
- server.monitor.connection.tap do |connection|
46
+ monitor.connection.tap do |connection|
36
47
  expect(connection).not_to be nil
37
48
 
38
- deadline = Time.now + 1
49
+ deadline = Time.now + 5
39
50
  while Time.now < deadline
40
51
  if connection.send(:socket)
41
52
  break
@@ -168,9 +179,8 @@ describe Mongo::Server::Monitor::Connection do
168
179
  context 'network error' do
169
180
  before do
170
181
  address
171
- server.monitor.instance_variable_get('@thread').kill
172
- server.monitor.connection.disconnect!
173
- expect_any_instance_of(Mongo::Socket).to receive(:write).and_raise(Mongo::Error::SocketError, 'test error')
182
+ monitor.instance_variable_get('@thread').kill
183
+ monitor.connection.disconnect!
174
184
  end
175
185
 
176
186
  let(:options) { SpecConfig.instance.test_options }
@@ -178,9 +188,10 @@ describe Mongo::Server::Monitor::Connection do
178
188
  let(:expected_message) { "MONGODB | Failed to handshake with #{address}: Mongo::Error::SocketError: test error" }
179
189
 
180
190
  it 'logs a warning' do
191
+ expect_any_instance_of(Mongo::Socket).to receive(:write).and_raise(Mongo::Error::SocketError, 'test error')
181
192
  expect(Mongo::Logger.logger).to receive(:warn).with(expected_message).and_call_original
182
193
  expect do
183
- server.monitor.connection.connect!
194
+ monitor.connection.connect!
184
195
  end.to raise_error(Mongo::Error::SocketError, 'test error')
185
196
  end
186
197
  end
@@ -13,15 +13,33 @@ describe Mongo::Server::Monitor do
13
13
  Mongo::Event::Listeners.new
14
14
  end
15
15
 
16
+ let(:monitor_options) do
17
+ {}
18
+ end
19
+
20
+ let(:cluster) do
21
+ double('cluster').tap do |cluster|
22
+ allow(cluster).to receive(:run_sdam_flow)
23
+ allow(cluster).to receive(:heartbeat_interval).and_return(1000)
24
+ end
25
+ end
26
+
27
+ let(:server) do
28
+ Mongo::Server.new(address, cluster, Mongo::Monitoring.new, listeners,
29
+ monitoring_io: false)
30
+ end
31
+
32
+ let(:monitor) do
33
+ register_background_thread_object(
34
+ described_class.new(server, listeners, Mongo::Monitoring.new,
35
+ SpecConfig.instance.test_options.merge(cluster: cluster).merge(monitor_options))
36
+ )
37
+ end
38
+
16
39
  describe '#scan!' do
17
40
 
18
41
  context 'when calling multiple times in succession' do
19
42
 
20
- let(:monitor) do
21
- described_class.new(address, listeners, Mongo::Monitoring.new,
22
- SpecConfig.instance.test_options)
23
- end
24
-
25
43
  it 'throttles the scans to minimum 500ms' do
26
44
  start = Time.now
27
45
  monitor.scan!
@@ -32,9 +50,8 @@ describe Mongo::Server::Monitor do
32
50
 
33
51
  context 'when the ismaster fails the first time' do
34
52
 
35
- let(:monitor) do
36
- described_class.new(address, listeners, Mongo::Monitoring.new,
37
- SpecConfig.instance.test_options.merge(monitoring_io: false))
53
+ let(:monitor_options) do
54
+ {monitoring_io: false}
38
55
  end
39
56
 
40
57
  let(:socket) do
@@ -42,70 +59,27 @@ describe Mongo::Server::Monitor do
42
59
  monitor.connection.__send__(:socket)
43
60
  end
44
61
 
45
- before do
62
+ it 'retries the ismaster' do
46
63
  expect(socket).to receive(:write).once.and_raise(Mongo::Error::SocketError)
47
64
  expect(socket).to receive(:write).and_call_original
65
+ expect(cluster).to receive(:run_sdam_flow)
48
66
  monitor.scan!
49
67
  end
50
-
51
- context 'in single topology' do
52
- require_topology :single
53
-
54
- it 'retries the ismaster' do
55
- expect(monitor.description).to be_standalone
56
- end
57
- end
58
-
59
- context 'in replica set topology' do
60
- require_topology :replica_set
61
-
62
- it 'retries the ismaster' do
63
- expect(monitor.description).to be_primary
64
- end
65
- end
66
-
67
- context 'in sharded topology' do
68
- require_topology :sharded
69
-
70
- it 'retries the ismaster' do
71
- expect(monitor.description).to be_mongos
72
- end
73
- end
74
68
  end
75
69
 
76
70
  context 'when the ismaster command succeeds' do
77
71
 
78
- let(:monitor) do
79
- described_class.new(address, listeners, Mongo::Monitoring.new,
80
- SpecConfig.instance.test_options)
81
- end
82
-
83
- before do
84
- monitor.scan!
85
- end
86
-
87
- context 'in single topology' do
88
- require_topology :single
72
+ it 'invokes sdam flow' do
73
+ server.unknown!
74
+ expect(server.description).to be_unknown
89
75
 
90
- it 'updates the server description' do
91
- expect(monitor.description).to be_standalone
76
+ updated_desc = nil
77
+ expect(cluster).to receive(:run_sdam_flow) do |prev_desc, _updated_desc|
78
+ updated_desc = _updated_desc
92
79
  end
93
- end
94
-
95
- context 'in replica set topology' do
96
- require_topology :replica_set
97
-
98
- it 'updates the server description' do
99
- expect(monitor.description).to be_primary
100
- end
101
- end
102
-
103
- context 'in sharded topology' do
104
- require_topology :sharded
80
+ monitor.scan!
105
81
 
106
- it 'updates the server description' do
107
- expect(monitor.description).to be_mongos
108
- end
82
+ expect(updated_desc).not_to be_unknown
109
83
  end
110
84
  end
111
85
 
@@ -113,33 +87,27 @@ describe Mongo::Server::Monitor do
113
87
 
114
88
  context 'when no server is running on the address' do
115
89
 
116
- let(:bad_address) do
90
+ let(:address) do
117
91
  Mongo::Address.new('127.0.0.1:27050')
118
92
  end
119
93
 
120
- let(:monitor) do
121
- described_class.new(bad_address, listeners, Mongo::Monitoring.new)
122
- end
123
-
124
94
  before do
95
+ server.unknown!
96
+ expect(server.description).to be_unknown
125
97
  monitor.scan!
126
98
  end
127
99
 
128
100
  it 'keeps the server unknown' do
129
- expect(monitor.description).to be_unknown
101
+ expect(server.description).to be_unknown
130
102
  end
131
103
  end
132
104
 
133
105
  context 'when the socket gets an exception' do
134
106
 
135
- let(:bad_address) do
107
+ let(:address) do
136
108
  default_address
137
109
  end
138
110
 
139
- let(:monitor) do
140
- described_class.new(bad_address, listeners, Mongo::Monitoring.new)
141
- end
142
-
143
111
  let(:socket) do
144
112
  monitor.connection.connect!
145
113
  monitor.connection.__send__(:socket)
@@ -147,11 +115,13 @@ describe Mongo::Server::Monitor do
147
115
 
148
116
  before do
149
117
  expect(socket).to receive(:write).twice.and_raise(Mongo::Error::SocketError)
118
+ server.unknown!
119
+ expect(server.description).to be_unknown
150
120
  monitor.scan!
151
121
  end
152
122
 
153
123
  it 'keeps the server unknown' do
154
- expect(monitor.description).to be_unknown
124
+ expect(server.description).to be_unknown
155
125
  end
156
126
 
157
127
  it 'disconnects the connection' do
@@ -161,12 +131,13 @@ describe Mongo::Server::Monitor do
161
131
  end
162
132
  end
163
133
 
134
+ =begin heartbeat interval is now taken out of cluster, monitor has no useful options
164
135
  describe '#heartbeat_frequency' do
165
136
 
166
137
  context 'when an option is provided' do
167
138
 
168
- let(:monitor) do
169
- described_class.new(address, listeners, Mongo::Monitoring.new, :heartbeat_frequency => 5)
139
+ let(:monitor_options) do
140
+ {:heartbeat_frequency => 5}
170
141
  end
171
142
 
172
143
  it 'returns the option' do
@@ -176,8 +147,8 @@ describe Mongo::Server::Monitor do
176
147
 
177
148
  context 'when no option is provided' do
178
149
 
179
- let(:monitor) do
180
- described_class.new(address, listeners, Mongo::Monitoring.new)
150
+ let(:monitor_options) do
151
+ {:heartbeat_frequency => nil}
181
152
  end
182
153
 
183
154
  it 'defaults to 10' do
@@ -185,29 +156,10 @@ describe Mongo::Server::Monitor do
185
156
  end
186
157
  end
187
158
  end
188
-
189
- describe '#run!' do
190
-
191
- let(:monitor) do
192
- described_class.new(address, listeners, Mongo::Monitoring.new, :heartbeat_frequency => 1)
193
- end
194
-
195
- before do
196
- monitor.run!
197
- sleep(1)
198
- end
199
-
200
- it 'refreshes the server on the provided interval' do
201
- expect(monitor.description).to_not be_nil
202
- end
203
- end
159
+ =end
204
160
 
205
161
  describe '#restart!' do
206
162
 
207
- let(:monitor) do
208
- described_class.new(address, listeners, Mongo::Monitoring.new, SpecConfig.instance.test_options)
209
- end
210
-
211
163
  let!(:thread) do
212
164
  monitor.run!
213
165
  end
@@ -233,10 +185,6 @@ describe Mongo::Server::Monitor do
233
185
  end
234
186
 
235
187
  describe '#stop' do
236
- let(:monitor) do
237
- described_class.new(address, listeners, Mongo::Monitoring.new,
238
- SpecConfig.instance.test_options)
239
- end
240
188
 
241
189
  let(:thread) do
242
190
  monitor.run!
@@ -245,10 +193,13 @@ describe Mongo::Server::Monitor do
245
193
  it 'kills the monitor thread' do
246
194
  ClientRegistry.instance.close_all_clients
247
195
  thread
248
- sleep 1
249
- expect(monitor.connection).to receive(:disconnect!).and_call_original
250
- monitor.stop!(true)
251
- expect(thread.alive?).to be(false)
196
+ sleep 0.5
197
+
198
+ RSpec::Mocks.with_temporary_scope do
199
+ expect(monitor.connection).to receive(:disconnect!).and_call_original
200
+ monitor.stop!
201
+ expect(thread.alive?).to be(false)
202
+ end
252
203
  end
253
204
  end
254
205
 
@@ -260,8 +211,8 @@ describe Mongo::Server::Monitor do
260
211
  1
261
212
  end
262
213
 
263
- let(:monitor) do
264
- described_class.new(address, listeners, Mongo::Monitoring.new, SpecConfig.instance.test_options.merge(connect_timeout: connect_timeout))
214
+ let(:monitor_options) do
215
+ {connect_timeout: connect_timeout}
265
216
  end
266
217
 
267
218
  it 'sets the value as the timeout on the connection' do
@@ -274,4 +225,12 @@ describe Mongo::Server::Monitor do
274
225
  end
275
226
  end
276
227
  end
228
+
229
+ describe '#log_warn' do
230
+ it 'works' do
231
+ expect do
232
+ monitor.log_warn('test warning')
233
+ end.not_to raise_error
234
+ end
235
+ end
277
236
  end