mongo 2.10.5 → 2.11.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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