mongo 2.13.0.beta1 → 2.13.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 (170) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -5
  4. data/Rakefile +15 -9
  5. data/lib/mongo.rb +4 -2
  6. data/lib/mongo/auth/aws/request.rb +4 -2
  7. data/lib/mongo/bulk_write.rb +1 -0
  8. data/lib/mongo/client.rb +143 -21
  9. data/lib/mongo/cluster.rb +53 -17
  10. data/lib/mongo/cluster/sdam_flow.rb +13 -10
  11. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -2
  12. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  13. data/lib/mongo/cluster/topology/single.rb +1 -1
  14. data/lib/mongo/collection.rb +17 -13
  15. data/lib/mongo/collection/view/readable.rb +3 -1
  16. data/lib/mongo/collection/view/writable.rb +41 -5
  17. data/lib/mongo/database.rb +31 -4
  18. data/lib/mongo/database/view.rb +19 -4
  19. data/lib/mongo/distinguishing_semaphore.rb +55 -0
  20. data/lib/mongo/error.rb +1 -0
  21. data/lib/mongo/error/invalid_session.rb +2 -1
  22. data/lib/mongo/error/operation_failure.rb +6 -0
  23. data/lib/mongo/error/sessions_not_supported.rb +35 -0
  24. data/lib/mongo/event/base.rb +6 -0
  25. data/lib/mongo/grid/file.rb +5 -0
  26. data/lib/mongo/grid/file/chunk.rb +2 -0
  27. data/lib/mongo/grid/fs_bucket.rb +15 -13
  28. data/lib/mongo/grid/stream/write.rb +9 -3
  29. data/lib/mongo/monitoring.rb +38 -0
  30. data/lib/mongo/monitoring/command_log_subscriber.rb +10 -2
  31. data/lib/mongo/monitoring/event/command_failed.rb +11 -0
  32. data/lib/mongo/monitoring/event/command_started.rb +37 -2
  33. data/lib/mongo/monitoring/event/command_succeeded.rb +11 -0
  34. data/lib/mongo/monitoring/event/server_closed.rb +1 -1
  35. data/lib/mongo/monitoring/event/server_description_changed.rb +27 -4
  36. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +9 -2
  37. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +9 -2
  38. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +9 -2
  39. data/lib/mongo/monitoring/event/server_opening.rb +1 -1
  40. data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
  41. data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
  42. data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
  43. data/lib/mongo/monitoring/publishable.rb +6 -3
  44. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +9 -1
  45. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
  46. data/lib/mongo/protocol/message.rb +36 -8
  47. data/lib/mongo/protocol/msg.rb +14 -0
  48. data/lib/mongo/protocol/serializers.rb +5 -2
  49. data/lib/mongo/server.rb +10 -3
  50. data/lib/mongo/server/connection.rb +4 -4
  51. data/lib/mongo/server/connection_base.rb +3 -1
  52. data/lib/mongo/server/description.rb +5 -0
  53. data/lib/mongo/server/monitor.rb +76 -44
  54. data/lib/mongo/server/monitor/connection.rb +55 -7
  55. data/lib/mongo/server/pending_connection.rb +14 -4
  56. data/lib/mongo/server/push_monitor.rb +173 -0
  57. data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
  58. data/lib/mongo/server_selector.rb +0 -1
  59. data/lib/mongo/server_selector/base.rb +579 -1
  60. data/lib/mongo/server_selector/nearest.rb +1 -6
  61. data/lib/mongo/server_selector/primary.rb +1 -6
  62. data/lib/mongo/server_selector/primary_preferred.rb +7 -10
  63. data/lib/mongo/server_selector/secondary.rb +1 -6
  64. data/lib/mongo/server_selector/secondary_preferred.rb +1 -7
  65. data/lib/mongo/session.rb +2 -0
  66. data/lib/mongo/socket.rb +20 -8
  67. data/lib/mongo/socket/ssl.rb +1 -1
  68. data/lib/mongo/socket/tcp.rb +1 -1
  69. data/lib/mongo/topology_version.rb +9 -0
  70. data/lib/mongo/utils.rb +62 -0
  71. data/lib/mongo/version.rb +1 -1
  72. data/spec/README.aws-auth.md +2 -2
  73. data/spec/integration/awaited_ismaster_spec.rb +28 -0
  74. data/spec/integration/change_stream_examples_spec.rb +6 -2
  75. data/spec/integration/check_clean_slate_spec.rb +16 -0
  76. data/spec/integration/client_construction_spec.rb +1 -0
  77. data/spec/integration/connect_single_rs_name_spec.rb +5 -2
  78. data/spec/integration/connection_spec.rb +7 -4
  79. data/spec/integration/crud_spec.rb +4 -4
  80. data/spec/integration/docs_examples_spec.rb +6 -0
  81. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  82. data/spec/integration/heartbeat_events_spec.rb +4 -23
  83. data/spec/integration/read_concern_spec.rb +1 -1
  84. data/spec/integration/retryable_errors_spec.rb +1 -1
  85. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +2 -2
  86. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -3
  87. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +2 -2
  88. data/spec/integration/sdam_error_handling_spec.rb +37 -15
  89. data/spec/integration/sdam_events_spec.rb +77 -6
  90. data/spec/integration/sdam_prose_spec.rb +64 -0
  91. data/spec/integration/server_monitor_spec.rb +25 -1
  92. data/spec/integration/size_limit_spec.rb +7 -3
  93. data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +98 -0
  94. data/spec/integration/ssl_uri_options_spec.rb +2 -2
  95. data/spec/integration/zlib_compression_spec.rb +25 -0
  96. data/spec/lite_spec_helper.rb +12 -5
  97. data/spec/mongo/auth/aws/request_spec.rb +76 -0
  98. data/spec/mongo/auth/scram_spec.rb +1 -1
  99. data/spec/mongo/client_construction_spec.rb +207 -0
  100. data/spec/mongo/client_spec.rb +38 -3
  101. data/spec/mongo/cluster/topology/replica_set_spec.rb +52 -9
  102. data/spec/mongo/cluster/topology/single_spec.rb +4 -2
  103. data/spec/mongo/cluster_spec.rb +34 -35
  104. data/spec/mongo/collection/view/change_stream_resume_spec.rb +6 -6
  105. data/spec/mongo/collection_spec.rb +500 -0
  106. data/spec/mongo/database_spec.rb +245 -8
  107. data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
  108. data/spec/mongo/error/operation_failure_spec.rb +40 -0
  109. data/spec/mongo/index/view_spec.rb +2 -2
  110. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
  111. data/spec/mongo/protocol/msg_spec.rb +10 -0
  112. data/spec/mongo/semaphore_spec.rb +51 -0
  113. data/spec/mongo/server/connection_auth_spec.rb +2 -2
  114. data/spec/mongo/server_selector/nearest_spec.rb +23 -23
  115. data/spec/mongo/server_selector/primary_preferred_spec.rb +26 -26
  116. data/spec/mongo/server_selector/primary_spec.rb +9 -9
  117. data/spec/mongo/server_selector/secondary_preferred_spec.rb +22 -22
  118. data/spec/mongo/server_selector/secondary_spec.rb +18 -18
  119. data/spec/mongo/server_selector_spec.rb +4 -4
  120. data/spec/mongo/session_spec.rb +35 -0
  121. data/spec/runners/change_streams/test.rb +2 -2
  122. data/spec/runners/cmap.rb +1 -1
  123. data/spec/runners/command_monitoring.rb +3 -34
  124. data/spec/runners/crud/context.rb +9 -5
  125. data/spec/runners/crud/operation.rb +59 -27
  126. data/spec/runners/crud/spec.rb +0 -8
  127. data/spec/runners/crud/test.rb +1 -1
  128. data/spec/runners/sdam.rb +2 -2
  129. data/spec/runners/server_selection.rb +242 -28
  130. data/spec/runners/transactions.rb +12 -12
  131. data/spec/runners/transactions/operation.rb +151 -25
  132. data/spec/runners/transactions/test.rb +60 -16
  133. data/spec/spec_tests/command_monitoring_spec.rb +22 -12
  134. data/spec/spec_tests/crud_spec.rb +1 -1
  135. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +4 -8
  136. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +66 -0
  137. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
  138. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
  139. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
  140. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
  141. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
  142. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
  143. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
  144. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
  145. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
  146. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
  147. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
  148. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
  149. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
  150. data/spec/spec_tests/max_staleness_spec.rb +4 -142
  151. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  152. data/spec/spec_tests/sdam_integration_spec.rb +13 -0
  153. data/spec/spec_tests/sdam_monitoring_spec.rb +1 -2
  154. data/spec/spec_tests/server_selection_spec.rb +4 -116
  155. data/spec/stress/cleanup_spec.rb +17 -2
  156. data/spec/stress/connection_pool_stress_spec.rb +10 -8
  157. data/spec/support/child_process_helper.rb +78 -0
  158. data/spec/support/client_registry.rb +1 -0
  159. data/spec/support/cluster_config.rb +4 -0
  160. data/spec/support/event_subscriber.rb +123 -33
  161. data/spec/support/keyword_struct.rb +26 -0
  162. data/spec/support/shared/server_selector.rb +13 -1
  163. data/spec/support/spec_config.rb +38 -13
  164. data/spec/support/spec_organizer.rb +129 -0
  165. data/spec/support/spec_setup.rb +1 -1
  166. data/spec/support/utils.rb +46 -0
  167. metadata +992 -942
  168. metadata.gz.sig +0 -0
  169. data/lib/mongo/server_selector/selectable.rb +0 -560
  170. data/spec/runners/sdam_monitoring.rb +0 -89
@@ -0,0 +1,229 @@
1
+ # Test SDAM error handling.
2
+ runOn:
3
+ # failCommand appName requirements
4
+ - minServerVersion: "4.4"
5
+
6
+ database_name: &database_name "sdam-tests"
7
+ collection_name: &collection_name "isMaster-timeout"
8
+
9
+ data: []
10
+
11
+ tests:
12
+ - description: Network timeout on Monitor handshake
13
+ # Configure the initial handshake to fail with a timeout.
14
+ # Use times: 2 so that the RTT isMaster is blocked as well.
15
+ failPoint:
16
+ configureFailPoint: failCommand
17
+ mode: { times: 2 }
18
+ data:
19
+ failCommands: ["isMaster"]
20
+ appName: timeoutMonitorHandshakeTest
21
+ blockConnection: true
22
+ blockTimeMS: 1000
23
+ clientOptions:
24
+ retryWrites: false
25
+ connectTimeoutMS: 250
26
+ heartbeatFrequencyMS: 500
27
+ appname: timeoutMonitorHandshakeTest
28
+ operations:
29
+ # The network error on the initial handshake should mark the server
30
+ # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool.
31
+ - name: waitForEvent
32
+ object: testRunner
33
+ arguments:
34
+ event: ServerMarkedUnknownEvent
35
+ count: 1
36
+ # https://jira.mongodb.org/browse/DRIVERS-1314
37
+ # - name: waitForEvent
38
+ # object: testRunner
39
+ # arguments:
40
+ # event: PoolClearedEvent
41
+ # count: 1
42
+ # Perform an operation to ensure the node is discovered.
43
+ - name: insertMany
44
+ object: collection
45
+ arguments:
46
+ documents:
47
+ - _id: 1
48
+ - _id: 2
49
+ # We cannot assert the server was marked Unknown and pool was cleared an
50
+ # exact number of times because the RTT isMaster may or may not have
51
+ # triggered this failpoint as well.
52
+ # - name: assertEventCount
53
+ # object: testRunner
54
+ # arguments:
55
+ # event: ServerMarkedUnknownEvent
56
+ # count: 1
57
+ # - name: assertEventCount
58
+ # object: testRunner
59
+ # arguments:
60
+ # event: PoolClearedEvent
61
+ # count: 1
62
+
63
+ expectations:
64
+ - command_started_event:
65
+ command:
66
+ insert: *collection_name
67
+ documents:
68
+ - _id: 1
69
+ - _id: 2
70
+ command_name: insert
71
+ database_name: *database_name
72
+
73
+ outcome:
74
+ collection:
75
+ data:
76
+ - {_id: 1}
77
+ - {_id: 2}
78
+
79
+ - description: Network timeout on Monitor check
80
+ clientOptions:
81
+ retryWrites: false
82
+ connectTimeoutMS: 750
83
+ heartbeatFrequencyMS: 500
84
+ appname: timeoutMonitorCheckTest
85
+ operations:
86
+ # Perform an operation to ensure the node is discovered.
87
+ - name: insertMany
88
+ object: collection
89
+ arguments:
90
+ documents:
91
+ - _id: 1
92
+ - _id: 2
93
+ # Configure the next streaming isMaster check to fail with a timeout
94
+ # Use times: 2 so that the RTT isMaster is blocked as well.
95
+ - name: configureFailPoint
96
+ object: testRunner
97
+ arguments:
98
+ failPoint:
99
+ configureFailPoint: failCommand
100
+ mode: { times: 2 }
101
+ data:
102
+ failCommands: ["isMaster"]
103
+ appName: timeoutMonitorCheckTest
104
+ blockConnection: true
105
+ # blockTimeMS is evaluated after the waiting for heartbeatFrequencyMS server-side, so this value only
106
+ # needs to be greater than connectTimeoutMS. The driver will wait for (500+750)ms and the server will
107
+ # respond after (500+1000)ms.
108
+ blockTimeMS: 1000
109
+ # The network error on the next check should mark the server Unknown and
110
+ # clear the pool.
111
+ - name: waitForEvent
112
+ object: testRunner
113
+ arguments:
114
+ event: ServerMarkedUnknownEvent
115
+ count: 1
116
+ - name: waitForEvent
117
+ object: testRunner
118
+ arguments:
119
+ event: PoolClearedEvent
120
+ count: 1
121
+ # Perform an operation to ensure the node is rediscovered.
122
+ - name: insertMany
123
+ object: collection
124
+ arguments:
125
+ documents:
126
+ - _id: 3
127
+ - _id: 4
128
+ # Assert the server was marked Unknown and pool was cleared exactly once.
129
+ - name: assertEventCount
130
+ object: testRunner
131
+ arguments:
132
+ event: ServerMarkedUnknownEvent
133
+ count: 1
134
+ - name: assertEventCount
135
+ object: testRunner
136
+ arguments:
137
+ event: PoolClearedEvent
138
+ count: 1
139
+
140
+ expectations:
141
+ - command_started_event:
142
+ command:
143
+ insert: *collection_name
144
+ documents:
145
+ - _id: 1
146
+ - _id: 2
147
+ command_name: insert
148
+ database_name: *database_name
149
+ - command_started_event:
150
+ command:
151
+ insert: *collection_name
152
+ documents:
153
+ - _id: 3
154
+ - _id: 4
155
+ command_name: insert
156
+ database_name: *database_name
157
+
158
+ outcome:
159
+ collection:
160
+ data:
161
+ - {_id: 1}
162
+ - {_id: 2}
163
+ - {_id: 3}
164
+ - {_id: 4}
165
+
166
+ - description: Driver extends timeout while streaming
167
+ clientOptions:
168
+ retryWrites: false
169
+ connectTimeoutMS: 250
170
+ heartbeatFrequencyMS: 500
171
+ appname: extendsTimeoutTest
172
+ operations:
173
+ # Perform an operation to ensure the node is discovered.
174
+ - name: insertMany
175
+ object: collection
176
+ arguments:
177
+ documents:
178
+ - _id: 1
179
+ - _id: 2
180
+ # Wait for multiple monitor checks to complete.
181
+ - name: wait
182
+ object: testRunner
183
+ arguments:
184
+ ms: 2000
185
+ # Perform an operation to ensure the node is still selectable.
186
+ - name: insertMany
187
+ object: collection
188
+ arguments:
189
+ documents:
190
+ - _id: 3
191
+ - _id: 4
192
+ # Assert that the server was never marked Unknown and the pool was never
193
+ # cleared.
194
+ - name: assertEventCount
195
+ object: testRunner
196
+ arguments:
197
+ event: ServerMarkedUnknownEvent
198
+ count: 0
199
+ - name: assertEventCount
200
+ object: testRunner
201
+ arguments:
202
+ event: PoolClearedEvent
203
+ count: 0
204
+
205
+ expectations:
206
+ - command_started_event:
207
+ command:
208
+ insert: *collection_name
209
+ documents:
210
+ - _id: 1
211
+ - _id: 2
212
+ command_name: insert
213
+ database_name: *database_name
214
+ - command_started_event:
215
+ command:
216
+ insert: *collection_name
217
+ documents:
218
+ - _id: 3
219
+ - _id: 4
220
+ command_name: insert
221
+ database_name: *database_name
222
+
223
+ outcome:
224
+ collection:
225
+ data:
226
+ - {_id: 1}
227
+ - {_id: 2}
228
+ - {_id: 3}
229
+ - {_id: 4}
@@ -0,0 +1,87 @@
1
+ runOn:
2
+ # 4.4 is required for streaming.
3
+ # A replica set is required for replSetStepDown.
4
+ - minServerVersion: "4.4"
5
+ topology: ["replicaset"]
6
+
7
+ database_name: &database_name "sdam-tests"
8
+ collection_name: &collection_name "test-replSetStepDown"
9
+
10
+ data: &data
11
+ - {_id: 1}
12
+ - {_id: 2}
13
+
14
+ tests:
15
+ - description: Rediscover quickly after replSetStepDown
16
+ clientOptions:
17
+ appname: replSetStepDownTest
18
+ # Configure a large heartbeatFrequencyMS
19
+ heartbeatFrequencyMS: 60000
20
+ # Configure a much smaller server selection timeout so that the test
21
+ # will error when it cannot discover the new primary soon.
22
+ serverSelectionTimeoutMS: 5000
23
+ w: majority
24
+ operations:
25
+ # Discover the primary.
26
+ - name: insertMany
27
+ object: collection
28
+ arguments:
29
+ documents:
30
+ - _id: 3
31
+ - _id: 4
32
+ - name: recordPrimary
33
+ object: testRunner
34
+ # Run replSetStepDown on the meta client.
35
+ - name: runAdminCommand
36
+ object: testRunner
37
+ command_name: replSetStepDown
38
+ arguments:
39
+ command:
40
+ replSetStepDown: 1
41
+ secondaryCatchUpPeriodSecs: 1
42
+ force: false
43
+ - name: waitForPrimaryChange
44
+ object: testRunner
45
+ arguments:
46
+ timeoutMS: 5000
47
+ # Rediscover the new primary.
48
+ - name: insertMany
49
+ object: collection
50
+ arguments:
51
+ documents:
52
+ - _id: 5
53
+ - _id: 6
54
+ # Assert that no pools were cleared.
55
+ - name: assertEventCount
56
+ object: testRunner
57
+ arguments:
58
+ event: PoolClearedEvent
59
+ count: 0
60
+
61
+ expectations:
62
+ - command_started_event:
63
+ command:
64
+ insert: *collection_name
65
+ documents:
66
+ - _id: 3
67
+ - _id: 4
68
+ command_name: insert
69
+ database_name: *database_name
70
+ - command_started_event:
71
+ command:
72
+ insert: *collection_name
73
+ documents:
74
+ - _id: 5
75
+ - _id: 6
76
+ command_name: insert
77
+ database_name: *database_name
78
+
79
+ outcome:
80
+ collection:
81
+ data:
82
+ - {_id: 1}
83
+ - {_id: 2}
84
+ - {_id: 3}
85
+ - {_id: 4}
86
+ - {_id: 5}
87
+ - {_id: 6}
@@ -1,147 +1,9 @@
1
- require 'spec_helper'
1
+ require 'lite_spec_helper'
2
2
 
3
3
  require 'runners/server_selection'
4
4
 
5
- describe 'Max Staleness Spec' do
5
+ MAX_STALENESS_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/max_staleness/**/*.yml").sort
6
6
 
7
- include Mongo::ServerSelection::Read
8
-
9
- MAX_STALENESS_TESTS.each do |file|
10
-
11
- spec = Mongo::ServerSelection::Read::Spec.new(file)
12
-
13
- context(spec.description) do
14
- # Cluster needs a topology and topology needs a cluster...
15
- # This temporary cluster is used for topology construction.
16
- let(:temp_cluster) do
17
- double('temp cluster').tap do |cluster|
18
- allow(cluster).to receive(:servers_list).and_return([])
19
- end
20
- end
21
-
22
- let(:topology) do
23
- options = if spec.type <= Mongo::Cluster::Topology::ReplicaSetNoPrimary
24
- {replica_set_name: 'foo'}
25
- else
26
- {}
27
- end
28
- spec.type.new(options, monitoring, temp_cluster)
29
- end
30
-
31
- let(:monitoring) do
32
- Mongo::Monitoring.new(monitoring: false)
33
- end
34
-
35
- let(:listeners) do
36
- Mongo::Event::Listeners.new
37
- end
38
-
39
- let(:options) do
40
- if spec.heartbeat_frequency
41
- SpecConfig.instance.test_options.merge(heartbeat_frequency: spec.heartbeat_frequency)
42
- else
43
- SpecConfig.instance.test_options.dup.tap do |opts|
44
- opts.delete(:heartbeat_frequency)
45
- end
46
- end.merge!(server_selection_timeout: 0.2, connect_timeout: 0.1)
47
- end
48
-
49
- let(:cluster) do
50
- double('cluster').tap do |c|
51
- allow(c).to receive(:connected?).and_return(true)
52
- allow(c).to receive(:summary)
53
- allow(c).to receive(:topology).and_return(topology)
54
- allow(c).to receive(:single?).and_return(topology.single?)
55
- allow(c).to receive(:sharded?).and_return(topology.sharded?)
56
- allow(c).to receive(:replica_set?).and_return(topology.replica_set?)
57
- allow(c).to receive(:unknown?).and_return(topology.unknown?)
58
- allow(c).to receive(:options).and_return(options)
59
- allow(c).to receive(:scan!).and_return(true)
60
- allow(c).to receive(:app_metadata).and_return(app_metadata)
61
- allow(c).to receive(:heartbeat_interval).and_return(
62
- spec.heartbeat_frequency || Mongo::Server::Monitor::DEFAULT_HEARTBEAT_INTERVAL)
63
- end
64
- end
65
-
66
- let(:candidate_servers) do
67
- spec.candidate_servers.collect do |server|
68
- features = double('features').tap do |feat|
69
- allow(feat).to receive(:max_staleness_enabled?).and_return(server['maxWireVersion'] && server['maxWireVersion'] >= 5)
70
- allow(feat).to receive(:check_driver_support!).and_return(true)
71
- end
72
- address = Mongo::Address.new(server['address'])
73
- Mongo::Server.new(address, cluster, monitoring, listeners,
74
- {monitoring_io: false}.update(options)
75
- ).tap do |s|
76
- allow(s).to receive(:average_round_trip_time).and_return(server['avg_rtt_ms'] / 1000.0) if server['avg_rtt_ms']
77
- allow(s).to receive(:tags).and_return(server['tags'])
78
- allow(s).to receive(:secondary?).and_return(server['type'] == 'RSSecondary')
79
- allow(s).to receive(:primary?).and_return(server['type'] == 'RSPrimary')
80
- allow(s).to receive(:connectable?).and_return(true)
81
- allow(s).to receive(:last_write_date).and_return(
82
- Time.at(server['lastWrite']['lastWriteDate']['$numberLong'].to_f / 1000)) if server['lastWrite']
83
- allow(s).to receive(:last_scan).and_return(
84
- Time.at(server['lastUpdateTime'].to_f / 1000))
85
- allow(s).to receive(:features).and_return(features)
86
- end
87
- end
88
- end
89
-
90
- let(:in_latency_window) do
91
- spec.in_latency_window.collect do |server|
92
- Mongo::Server.new(Mongo::Address.new(server['address']), cluster, monitoring, listeners,
93
- options.merge(monitoring_io: false))
94
- end
95
- end
96
-
97
- let(:server_selector_definition) do
98
- { mode: spec.read_preference['mode'] }.tap do |definition|
99
- definition[:tag_sets] = spec.read_preference['tag_sets']
100
- definition[:max_staleness] = spec.max_staleness if spec.max_staleness
101
- end
102
- end
103
-
104
- let(:server_selector) do
105
- Mongo::ServerSelector.get(server_selector_definition)
106
- end
107
-
108
- before do
109
- allow(cluster).to receive(:servers).and_return(candidate_servers)
110
- allow(cluster).to receive(:addresses).and_return(candidate_servers.map(&:address))
111
- end
112
-
113
- context 'when the max staleness is invalid' do
114
-
115
- it 'Raises an InvalidServerPreference exception', if: spec.invalid_max_staleness? do
116
-
117
- expect do
118
- server_selector.select_server(cluster)
119
- end.to raise_exception(Mongo::Error::InvalidServerPreference)
120
- end
121
- end
122
-
123
- context 'when the max staleness is valid' do
124
-
125
- context 'when there are available servers' do
126
-
127
- it 'Finds all suitable servers in the latency window', if: (spec.replica_set? && !spec.invalid_max_staleness? && spec.server_available?) do
128
- expect(server_selector.send(:select, cluster.servers)).to match_array(in_latency_window)
129
- end
130
-
131
- it 'Finds the most suitable server in the latency window', if: (!spec.invalid_max_staleness? && spec.server_available?) do
132
- expect(in_latency_window).to include(server_selector.select_server(cluster))
133
- end
134
- end
135
-
136
- context 'when there are no available servers', if: (!spec.invalid_max_staleness? && !spec.server_available?) do
137
-
138
- it 'Raises a NoServerAvailable Exception' do
139
- expect do
140
- server_selector.select_server(cluster)
141
- end.to raise_exception(Mongo::Error::NoServerAvailable)
142
- end
143
- end
144
- end
145
- end
146
- end
7
+ describe 'Max staleness spec tests' do
8
+ define_server_selection_spec_tests(MAX_STALENESS_TESTS)
147
9
  end