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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -5
- data/Rakefile +15 -9
- data/lib/mongo.rb +4 -2
- data/lib/mongo/auth/aws/request.rb +4 -2
- data/lib/mongo/bulk_write.rb +1 -0
- data/lib/mongo/client.rb +143 -21
- data/lib/mongo/cluster.rb +53 -17
- data/lib/mongo/cluster/sdam_flow.rb +13 -10
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -2
- data/lib/mongo/cluster/topology/sharded.rb +1 -1
- data/lib/mongo/cluster/topology/single.rb +1 -1
- data/lib/mongo/collection.rb +17 -13
- data/lib/mongo/collection/view/readable.rb +3 -1
- data/lib/mongo/collection/view/writable.rb +41 -5
- data/lib/mongo/database.rb +31 -4
- data/lib/mongo/database/view.rb +19 -4
- data/lib/mongo/distinguishing_semaphore.rb +55 -0
- data/lib/mongo/error.rb +1 -0
- data/lib/mongo/error/invalid_session.rb +2 -1
- data/lib/mongo/error/operation_failure.rb +6 -0
- data/lib/mongo/error/sessions_not_supported.rb +35 -0
- data/lib/mongo/event/base.rb +6 -0
- data/lib/mongo/grid/file.rb +5 -0
- data/lib/mongo/grid/file/chunk.rb +2 -0
- data/lib/mongo/grid/fs_bucket.rb +15 -13
- data/lib/mongo/grid/stream/write.rb +9 -3
- data/lib/mongo/monitoring.rb +38 -0
- data/lib/mongo/monitoring/command_log_subscriber.rb +10 -2
- data/lib/mongo/monitoring/event/command_failed.rb +11 -0
- data/lib/mongo/monitoring/event/command_started.rb +37 -2
- data/lib/mongo/monitoring/event/command_succeeded.rb +11 -0
- data/lib/mongo/monitoring/event/server_closed.rb +1 -1
- data/lib/mongo/monitoring/event/server_description_changed.rb +27 -4
- data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +9 -2
- data/lib/mongo/monitoring/event/server_heartbeat_started.rb +9 -2
- data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +9 -2
- data/lib/mongo/monitoring/event/server_opening.rb +1 -1
- data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
- data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
- data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
- data/lib/mongo/monitoring/publishable.rb +6 -3
- data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +9 -1
- data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
- data/lib/mongo/protocol/message.rb +36 -8
- data/lib/mongo/protocol/msg.rb +14 -0
- data/lib/mongo/protocol/serializers.rb +5 -2
- data/lib/mongo/server.rb +10 -3
- data/lib/mongo/server/connection.rb +4 -4
- data/lib/mongo/server/connection_base.rb +3 -1
- data/lib/mongo/server/description.rb +5 -0
- data/lib/mongo/server/monitor.rb +76 -44
- data/lib/mongo/server/monitor/connection.rb +55 -7
- data/lib/mongo/server/pending_connection.rb +14 -4
- data/lib/mongo/server/push_monitor.rb +173 -0
- data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
- data/lib/mongo/server_selector.rb +0 -1
- data/lib/mongo/server_selector/base.rb +579 -1
- data/lib/mongo/server_selector/nearest.rb +1 -6
- data/lib/mongo/server_selector/primary.rb +1 -6
- data/lib/mongo/server_selector/primary_preferred.rb +7 -10
- data/lib/mongo/server_selector/secondary.rb +1 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +1 -7
- data/lib/mongo/session.rb +2 -0
- data/lib/mongo/socket.rb +20 -8
- data/lib/mongo/socket/ssl.rb +1 -1
- data/lib/mongo/socket/tcp.rb +1 -1
- data/lib/mongo/topology_version.rb +9 -0
- data/lib/mongo/utils.rb +62 -0
- data/lib/mongo/version.rb +1 -1
- data/spec/README.aws-auth.md +2 -2
- data/spec/integration/awaited_ismaster_spec.rb +28 -0
- data/spec/integration/change_stream_examples_spec.rb +6 -2
- data/spec/integration/check_clean_slate_spec.rb +16 -0
- data/spec/integration/client_construction_spec.rb +1 -0
- data/spec/integration/connect_single_rs_name_spec.rb +5 -2
- data/spec/integration/connection_spec.rb +7 -4
- data/spec/integration/crud_spec.rb +4 -4
- data/spec/integration/docs_examples_spec.rb +6 -0
- data/spec/integration/grid_fs_bucket_spec.rb +48 -0
- data/spec/integration/heartbeat_events_spec.rb +4 -23
- data/spec/integration/read_concern_spec.rb +1 -1
- data/spec/integration/retryable_errors_spec.rb +1 -1
- data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +2 -2
- data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -3
- data/spec/integration/retryable_writes/shared/performs_no_retries.rb +2 -2
- data/spec/integration/sdam_error_handling_spec.rb +37 -15
- data/spec/integration/sdam_events_spec.rb +77 -6
- data/spec/integration/sdam_prose_spec.rb +64 -0
- data/spec/integration/server_monitor_spec.rb +25 -1
- data/spec/integration/size_limit_spec.rb +7 -3
- data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +98 -0
- data/spec/integration/ssl_uri_options_spec.rb +2 -2
- data/spec/integration/zlib_compression_spec.rb +25 -0
- data/spec/lite_spec_helper.rb +12 -5
- data/spec/mongo/auth/aws/request_spec.rb +76 -0
- data/spec/mongo/auth/scram_spec.rb +1 -1
- data/spec/mongo/client_construction_spec.rb +207 -0
- data/spec/mongo/client_spec.rb +38 -3
- data/spec/mongo/cluster/topology/replica_set_spec.rb +52 -9
- data/spec/mongo/cluster/topology/single_spec.rb +4 -2
- data/spec/mongo/cluster_spec.rb +34 -35
- data/spec/mongo/collection/view/change_stream_resume_spec.rb +6 -6
- data/spec/mongo/collection_spec.rb +500 -0
- data/spec/mongo/database_spec.rb +245 -8
- data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
- data/spec/mongo/error/operation_failure_spec.rb +40 -0
- data/spec/mongo/index/view_spec.rb +2 -2
- data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
- data/spec/mongo/protocol/msg_spec.rb +10 -0
- data/spec/mongo/semaphore_spec.rb +51 -0
- data/spec/mongo/server/connection_auth_spec.rb +2 -2
- data/spec/mongo/server_selector/nearest_spec.rb +23 -23
- data/spec/mongo/server_selector/primary_preferred_spec.rb +26 -26
- data/spec/mongo/server_selector/primary_spec.rb +9 -9
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +22 -22
- data/spec/mongo/server_selector/secondary_spec.rb +18 -18
- data/spec/mongo/server_selector_spec.rb +4 -4
- data/spec/mongo/session_spec.rb +35 -0
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/command_monitoring.rb +3 -34
- data/spec/runners/crud/context.rb +9 -5
- data/spec/runners/crud/operation.rb +59 -27
- data/spec/runners/crud/spec.rb +0 -8
- data/spec/runners/crud/test.rb +1 -1
- data/spec/runners/sdam.rb +2 -2
- data/spec/runners/server_selection.rb +242 -28
- data/spec/runners/transactions.rb +12 -12
- data/spec/runners/transactions/operation.rb +151 -25
- data/spec/runners/transactions/test.rb +60 -16
- data/spec/spec_tests/command_monitoring_spec.rb +22 -12
- data/spec/spec_tests/crud_spec.rb +1 -1
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +4 -8
- data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +66 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
- data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
- data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
- data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
- data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
- data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
- data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
- data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
- data/spec/spec_tests/max_staleness_spec.rb +4 -142
- data/spec/spec_tests/retryable_reads_spec.rb +2 -2
- data/spec/spec_tests/sdam_integration_spec.rb +13 -0
- data/spec/spec_tests/sdam_monitoring_spec.rb +1 -2
- data/spec/spec_tests/server_selection_spec.rb +4 -116
- data/spec/stress/cleanup_spec.rb +17 -2
- data/spec/stress/connection_pool_stress_spec.rb +10 -8
- data/spec/support/child_process_helper.rb +78 -0
- data/spec/support/client_registry.rb +1 -0
- data/spec/support/cluster_config.rb +4 -0
- data/spec/support/event_subscriber.rb +123 -33
- data/spec/support/keyword_struct.rb +26 -0
- data/spec/support/shared/server_selector.rb +13 -1
- data/spec/support/spec_config.rb +38 -13
- data/spec/support/spec_organizer.rb +129 -0
- data/spec/support/spec_setup.rb +1 -1
- data/spec/support/utils.rb +46 -0
- metadata +992 -942
- metadata.gz.sig +0 -0
- data/lib/mongo/server_selector/selectable.rb +0 -560
- 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 '
|
1
|
+
require 'lite_spec_helper'
|
2
2
|
|
3
3
|
require 'runners/server_selection'
|
4
4
|
|
5
|
-
|
5
|
+
MAX_STALENESS_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/max_staleness/**/*.yml").sort
|
6
6
|
|
7
|
-
|
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
|