mongo 2.9.2 → 2.10.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo.rb +1 -0
  5. data/lib/mongo/auth/user/view.rb +4 -4
  6. data/lib/mongo/bulk_write.rb +14 -8
  7. data/lib/mongo/bulk_write/result.rb +1 -1
  8. data/lib/mongo/bulk_write/result_combiner.rb +2 -2
  9. data/lib/mongo/bulk_write/transformable.rb +17 -9
  10. data/lib/mongo/client.rb +107 -16
  11. data/lib/mongo/cluster.rb +47 -25
  12. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
  13. data/lib/mongo/cluster_time.rb +139 -0
  14. data/lib/mongo/collection.rb +84 -25
  15. data/lib/mongo/collection/view.rb +7 -3
  16. data/lib/mongo/collection/view/aggregation.rb +4 -4
  17. data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
  18. data/lib/mongo/collection/view/builder/find_command.rb +4 -1
  19. data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
  20. data/lib/mongo/collection/view/change_stream.rb +54 -66
  21. data/lib/mongo/collection/view/iterable.rb +2 -2
  22. data/lib/mongo/collection/view/map_reduce.rb +6 -4
  23. data/lib/mongo/collection/view/readable.rb +36 -16
  24. data/lib/mongo/collection/view/writable.rb +68 -22
  25. data/lib/mongo/cursor.rb +87 -20
  26. data/lib/mongo/database.rb +47 -43
  27. data/lib/mongo/database/view.rb +54 -11
  28. data/lib/mongo/error.rb +13 -4
  29. data/lib/mongo/error/invalid_write_concern.rb +2 -2
  30. data/lib/mongo/error/operation_failure.rb +65 -11
  31. data/lib/mongo/error/parser.rb +41 -8
  32. data/lib/mongo/grid/fs_bucket.rb +26 -6
  33. data/lib/mongo/grid/stream/read.rb +9 -2
  34. data/lib/mongo/grid/stream/write.rb +21 -5
  35. data/lib/mongo/index/view.rb +3 -3
  36. data/lib/mongo/lint.rb +10 -3
  37. data/lib/mongo/operation.rb +2 -0
  38. data/lib/mongo/operation/aggregate/result.rb +19 -6
  39. data/lib/mongo/operation/collections_info.rb +1 -1
  40. data/lib/mongo/operation/get_more/result.rb +9 -0
  41. data/lib/mongo/operation/list_collections/command.rb +1 -3
  42. data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
  43. data/lib/mongo/operation/parallel_scan/command.rb +4 -1
  44. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
  45. data/lib/mongo/operation/result.rb +27 -4
  46. data/lib/mongo/operation/shared/executable.rb +19 -5
  47. data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
  48. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
  49. data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
  50. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  51. data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
  52. data/lib/mongo/operation/shared/specifiable.rb +40 -0
  53. data/lib/mongo/operation/shared/unpinnable.rb +39 -0
  54. data/lib/mongo/operation/shared/write.rb +1 -1
  55. data/lib/mongo/protocol/update.rb +6 -2
  56. data/lib/mongo/retryable.rb +79 -39
  57. data/lib/mongo/server/connection.rb +10 -3
  58. data/lib/mongo/server/description.rb +25 -1
  59. data/lib/mongo/server/monitor/connection.rb +1 -1
  60. data/lib/mongo/server_selector.rb +10 -0
  61. data/lib/mongo/server_selector/selectable.rb +172 -32
  62. data/lib/mongo/session.rb +654 -581
  63. data/lib/mongo/session/session_pool.rb +1 -1
  64. data/lib/mongo/socket.rb +7 -28
  65. data/lib/mongo/socket/ssl.rb +26 -1
  66. data/lib/mongo/socket/tcp.rb +3 -0
  67. data/lib/mongo/socket/unix.rb +3 -0
  68. data/lib/mongo/uri.rb +112 -265
  69. data/lib/mongo/uri/srv_protocol.rb +4 -1
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +10 -29
  72. data/lib/mongo/write_concern/acknowledged.rb +12 -0
  73. data/lib/mongo/write_concern/base.rb +17 -13
  74. data/lib/mongo/write_concern/unacknowledged.rb +12 -0
  75. data/spec/atlas/atlas_connectivity_spec.rb +7 -37
  76. data/spec/atlas/operations_spec.rb +25 -0
  77. data/spec/integration/change_stream_examples_spec.rb +45 -31
  78. data/spec/integration/change_stream_spec.rb +305 -5
  79. data/spec/integration/client_spec.rb +44 -0
  80. data/spec/integration/command_monitoring_spec.rb +1 -0
  81. data/spec/integration/command_spec.rb +7 -1
  82. data/spec/integration/mmapv1_spec.rb +28 -0
  83. data/spec/integration/mongos_pinning_spec.rb +34 -0
  84. data/spec/integration/operation_failure_code_spec.rb +2 -2
  85. data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
  86. data/spec/integration/read_preference_spec.rb +485 -0
  87. data/spec/integration/retryable_writes_spec.rb +8 -19
  88. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  89. data/spec/integration/sdam_events_spec.rb +2 -2
  90. data/spec/integration/server_description_spec.rb +14 -17
  91. data/spec/integration/server_selector_spec.rb +7 -3
  92. data/spec/integration/server_spec.rb +48 -0
  93. data/spec/integration/ssl_uri_options_spec.rb +1 -1
  94. data/spec/integration/step_down_spec.rb +10 -4
  95. data/spec/integration/transactions_examples_spec.rb +11 -10
  96. data/spec/lite_spec_helper.rb +19 -16
  97. data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
  98. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
  99. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
  100. data/spec/mongo/bulk_write_spec.rb +12 -2
  101. data/spec/mongo/client_construction_spec.rb +160 -8
  102. data/spec/mongo/client_spec.rb +5 -4
  103. data/spec/mongo/cluster_spec.rb +6 -6
  104. data/spec/mongo/cluster_time_spec.rb +148 -0
  105. data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
  106. data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
  107. data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
  108. data/spec/mongo/collection/view/readable_spec.rb +4 -4
  109. data/spec/mongo/collection_spec.rb +331 -14
  110. data/spec/mongo/cursor_spec.rb +117 -5
  111. data/spec/mongo/database_spec.rb +240 -8
  112. data/spec/mongo/error/operation_failure_spec.rb +47 -1
  113. data/spec/mongo/error/parser_spec.rb +160 -23
  114. data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
  115. data/spec/mongo/operation/result_spec.rb +27 -0
  116. data/spec/mongo/operation/update/bulk_spec.rb +1 -0
  117. data/spec/mongo/retryable_spec.rb +2 -0
  118. data/spec/mongo/server/app_metadata_spec.rb +2 -2
  119. data/spec/mongo/server/connection_spec.rb +13 -17
  120. data/spec/mongo/server/monitor/connection_spec.rb +13 -10
  121. data/spec/mongo/server_selector_spec.rb +34 -2
  122. data/spec/mongo/session/session_pool_spec.rb +14 -3
  123. data/spec/mongo/session_spec.rb +3 -3
  124. data/spec/mongo/session_transaction_spec.rb +4 -3
  125. data/spec/mongo/socket/ssl_spec.rb +19 -5
  126. data/spec/mongo/socket_spec.rb +1 -62
  127. data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
  128. data/spec/mongo/uri_option_parsing_spec.rb +94 -8
  129. data/spec/mongo/uri_spec.rb +23 -10
  130. data/spec/mongo/write_concern_spec.rb +56 -3
  131. data/spec/spec_tests/change_streams_spec.rb +2 -1
  132. data/spec/spec_tests/cmap_spec.rb +1 -1
  133. data/spec/spec_tests/crud_spec.rb +12 -2
  134. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
  135. data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
  136. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
  137. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
  138. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
  139. data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
  140. data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
  141. data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
  142. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
  143. data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
  144. data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
  145. data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
  146. data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
  147. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
  148. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
  149. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
  150. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
  151. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
  152. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
  153. data/spec/spec_tests/data/transactions/abort.yml +3 -0
  154. data/spec/spec_tests/data/transactions/bulk.yml +3 -8
  155. data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
  156. data/spec/spec_tests/data/transactions/commit.yml +3 -1
  157. data/spec/spec_tests/data/transactions/count.yml +3 -0
  158. data/spec/spec_tests/data/transactions/delete.yml +3 -0
  159. data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
  160. data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
  161. data/spec/spec_tests/data/transactions/errors.yml +3 -0
  162. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
  163. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
  164. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
  165. data/spec/spec_tests/data/transactions/insert.yml +3 -0
  166. data/spec/spec_tests/data/transactions/isolation.yml +3 -0
  167. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
  168. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
  169. data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
  170. data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
  171. data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
  172. data/spec/spec_tests/data/transactions/reads.yml +3 -0
  173. data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
  174. data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
  175. data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
  176. data/spec/spec_tests/data/transactions/run-command.yml +3 -0
  177. data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
  178. data/spec/spec_tests/data/transactions/update.yml +3 -8
  179. data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
  180. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
  181. data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
  182. data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
  183. data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
  184. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
  185. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
  186. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
  187. data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
  188. data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
  189. data/spec/spec_tests/retryable_reads_spec.rb +5 -2
  190. data/spec/spec_tests/retryable_writes_spec.rb +5 -2
  191. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
  192. data/spec/spec_tests/sdam_spec.rb +2 -2
  193. data/spec/spec_tests/transactions_api_spec.rb +1 -67
  194. data/spec/spec_tests/transactions_spec.rb +2 -66
  195. data/spec/support/authorization.rb +4 -0
  196. data/spec/support/change_streams.rb +30 -10
  197. data/spec/support/change_streams/operation.rb +27 -0
  198. data/spec/support/client_registry.rb +44 -25
  199. data/spec/support/cluster_config.rb +25 -14
  200. data/spec/support/cluster_tools.rb +32 -10
  201. data/spec/support/command_monitoring.rb +1 -1
  202. data/spec/support/common_shortcuts.rb +30 -0
  203. data/spec/support/connection_string.rb +8 -3
  204. data/spec/support/constraints.rb +34 -0
  205. data/spec/support/crud.rb +31 -16
  206. data/spec/support/crud/context.rb +23 -0
  207. data/spec/support/crud/operation.rb +311 -14
  208. data/spec/support/crud/spec.rb +2 -1
  209. data/spec/support/crud/test.rb +24 -27
  210. data/spec/support/crud/test_base.rb +22 -0
  211. data/spec/support/crud/verifier.rb +15 -1
  212. data/spec/support/event_subscriber.rb +12 -0
  213. data/spec/support/sdam_formatter_integration.rb +12 -6
  214. data/spec/support/shared/server_selector.rb +10 -0
  215. data/spec/support/shared/session.rb +13 -12
  216. data/spec/support/spec_config.rb +32 -22
  217. data/spec/support/spec_setup.rb +2 -2
  218. data/spec/support/transactions.rb +87 -0
  219. data/spec/support/transactions/context.rb +33 -0
  220. data/spec/support/transactions/operation.rb +99 -349
  221. data/spec/support/transactions/spec.rb +1 -3
  222. data/spec/support/transactions/test.rb +110 -49
  223. data/spec/support/utils.rb +74 -1
  224. metadata +52 -10
  225. metadata.gz.sig +0 -0
  226. data/spec/support/crud/read.rb +0 -265
  227. data/spec/support/crud/write.rb +0 -284
@@ -2,6 +2,9 @@ runOn:
2
2
  -
3
3
  minServerVersion: "4.0"
4
4
  topology: ["replicaset"]
5
+ -
6
+ minServerVersion: "4.1.8"
7
+ topology: ["sharded"]
5
8
 
6
9
  database_name: &database_name "withTransaction-tests"
7
10
  collection_name: &collection_name "test"
@@ -11,6 +14,7 @@ data: []
11
14
  tests:
12
15
  -
13
16
  description: withTransaction commits after callback returns
17
+ useMultipleMongoses: true
14
18
  operations:
15
19
  -
16
20
  name: withTransaction
@@ -91,6 +95,7 @@ tests:
91
95
  # withTransaction only examines the session's state, it should commit that
92
96
  # second transaction after the callback returns.
93
97
  description: withTransaction commits after callback returns (second transaction)
98
+ useMultipleMongoses: true
94
99
  operations:
95
100
  -
96
101
  name: withTransaction
@@ -2,6 +2,10 @@ runOn:
2
2
  -
3
3
  minServerVersion: "4.0"
4
4
  topology: ["replicaset"]
5
+ # Disabled due to https://jira.mongodb.org/browse/SERVER-41532
6
+ #-
7
+ # minServerVersion: "4.1.8"
8
+ # topology: ["sharded"]
5
9
 
6
10
  database_name: &database_name "withTransaction-tests"
7
11
  collection_name: &collection_name "test"
@@ -11,6 +15,7 @@ data: []
11
15
  tests:
12
16
  -
13
17
  description: withTransaction and no transaction options set
18
+ useMultipleMongoses: true
14
19
  operations: &operations
15
20
  -
16
21
  name: withTransaction
@@ -62,6 +67,7 @@ tests:
62
67
  - { _id: 1 }
63
68
  -
64
69
  description: withTransaction inherits transaction options from client
70
+ useMultipleMongoses: true
65
71
  clientOptions:
66
72
  readConcernLevel: local
67
73
  w: 1
@@ -99,6 +105,7 @@ tests:
99
105
  outcome: *outcome
100
106
  -
101
107
  description: withTransaction inherits transaction options from defaultTransactionOptions
108
+ useMultipleMongoses: true
102
109
  sessionOptions:
103
110
  session0:
104
111
  defaultTransactionOptions:
@@ -138,6 +145,7 @@ tests:
138
145
  outcome: *outcome
139
146
  -
140
147
  description: withTransaction explicit transaction options
148
+ useMultipleMongoses: true
141
149
  operations: &operations_explicit_transactionOptions
142
150
  -
143
151
  name: withTransaction
@@ -189,6 +197,7 @@ tests:
189
197
  outcome: *outcome
190
198
  -
191
199
  description: withTransaction explicit transaction options override defaultTransactionOptions
200
+ useMultipleMongoses: true
192
201
  sessionOptions:
193
202
  session0:
194
203
  defaultTransactionOptions:
@@ -228,6 +237,7 @@ tests:
228
237
  outcome: *outcome
229
238
  -
230
239
  description: withTransaction explicit transaction options override client options
240
+ useMultipleMongoses: true
231
241
  clientOptions:
232
242
  readConcernLevel: majority
233
243
  w: majority
@@ -1,7 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe do
4
- define_crud_spec_tests('Retryable reads spec tests', RETRYABLE_READS_TESTS.sort) do |spec, req, test|
3
+ describe 'Retryable reads spec tests' do
4
+ require_wired_tiger
5
+ require_no_multi_shard
6
+
7
+ define_crud_spec_tests(RETRYABLE_READS_TESTS) do |spec, req, test|
5
8
  let(:client) do
6
9
  root_authorized_client.with({max_read_retries: 0}.update(test.client_options)).tap do |client|
7
10
  client.subscribe(Mongo::Monitoring::COMMAND, event_subscriber)
@@ -1,7 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe do
4
- define_crud_spec_tests('Retryable writes spec tests', RETRYABLE_WRITES_TESTS.sort) do |spec, req, test|
3
+ describe 'Retryable writes spec tests' do
4
+ require_wired_tiger
5
+ require_no_multi_shard
6
+
7
+ define_crud_spec_tests(RETRYABLE_WRITES_TESTS) do |spec, req, test|
5
8
  let(:client) do
6
9
  authorized_client_with_retry_writes
7
10
  end
@@ -18,8 +18,8 @@ describe 'SDAM Monitoring' do
18
18
  client.subscribe(Mongo::Monitoring::TOPOLOGY_OPENING, @subscriber)
19
19
  client.subscribe(Mongo::Monitoring::TOPOLOGY_CHANGED, @subscriber)
20
20
  end
21
- @client = Mongo::Client.new(spec.uri_string,
22
- sdam_proc: sdam_proc, monitoring_io: false,
21
+ @client = new_local_client_nmio(spec.uri_string,
22
+ sdam_proc: sdam_proc,
23
23
  heartbeat_frequency: 100, connect_timeout: 0.1)
24
24
  # We do not want to create servers when an event referencing them
25
25
  # is processed, because this may result in server duplication
@@ -33,7 +33,7 @@ describe 'SDAM Monitoring' do
33
33
  end
34
34
 
35
35
  after(:all) do
36
- @client.close
36
+ @client.close(true)
37
37
  end
38
38
 
39
39
  spec.phases.each_with_index do |phase, phase_index|
@@ -36,7 +36,7 @@ describe 'Server Discovery and Monitoring' do
36
36
  end
37
37
 
38
38
  after(:all) do
39
- @client && @client.close
39
+ @client && @client.close(true)
40
40
  end
41
41
 
42
42
  spec.phases.each_with_index do |phase, index|
@@ -160,7 +160,7 @@ describe 'Server Discovery and Monitoring' do
160
160
 
161
161
  it 'raises an UnsupportedFeatures error' do
162
162
  expect {
163
- p = Mongo::ServerSelector.get(mode: :primary).select_server(@client.cluster)
163
+ p = Mongo::ServerSelector.primary.select_server(@client.cluster)
164
164
  s = Mongo::ServerSelector.get(mode: :secondary).select_server(@client.cluster)
165
165
  raise "UnsupportedFeatures not raised but we got #{p.inspect} as primary and #{s.inspect} as secondary"
166
166
  }.to raise_exception(Mongo::Error::UnsupportedFeatures)
@@ -1,71 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Transactions API' do
4
-
5
- TRANSACTIONS_API_TESTS.sort.each do |file|
6
-
7
- spec = Mongo::Transactions::Spec.new(file)
8
-
9
- context(spec.description) do
10
- define_spec_tests_with_requirements(spec) do |req|
11
- spec.tests.each do |test_factory|
12
- test_instance = test_factory.call
13
-
14
- context(test_instance.description) do
15
-
16
- let(:test) { test_factory.call }
17
-
18
- if test_instance.skip_reason
19
- before do
20
- skip test_instance.skip_reason
21
- end
22
- end
23
-
24
- before(:each) do
25
- if req.satisfied?
26
- test.setup_test
27
- end
28
- end
29
-
30
- after(:each) do
31
- if req.satisfied?
32
- test.teardown_test
33
- end
34
- end
35
-
36
- let(:results) do
37
- test.run
38
- end
39
-
40
- let(:verifier) { Mongo::CRUD::Verifier.new(test) }
41
-
42
- it 'returns the correct result' do
43
- verifier.verify_operation_result(test_instance.expected_results, results[:results])
44
- end
45
-
46
- it 'has the correct data in the collection', if: test_instance.outcome.collection_data? do
47
- results
48
- verifier.verify_collection_data(
49
- test_instance.outcome.collection_data,
50
- results[:contents])
51
- end
52
-
53
- if test_instance.expectations
54
- it 'has the correct number of command_started events' do
55
- verifier.verify_command_started_event_count(
56
- test_instance.expectations, results[:events])
57
- end
58
-
59
- test_instance.expectations.each_with_index do |expectation, i|
60
- it "has the correct command_started event #{i}" do
61
- verifier.verify_command_started_event(
62
- test_instance.expectations, results[:events], i)
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
4
+ define_transactions_spec_tests(TRANSACTIONS_API_TESTS)
71
5
  end
@@ -1,71 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Transactions' do
4
+ clean_slate_on_evergreen
4
5
 
5
- TRANSACTIONS_TESTS.sort.each do |file|
6
-
7
- spec = Mongo::Transactions::Spec.new(file)
8
-
9
- context(spec.description) do
10
- define_spec_tests_with_requirements(spec) do |req|
11
- spec.tests.each do |test_factory|
12
- test_instance = test_factory.call
13
-
14
- context(test_instance.description) do
15
-
16
- let(:test) { test_factory.call }
17
-
18
- if test_instance.skip_reason
19
- before do
20
- skip test_instance.skip_reason
21
- end
22
- end
23
-
24
- before(:each) do
25
- if req.satisfied?
26
- test.setup_test
27
- end
28
- end
29
-
30
- after(:each) do
31
- if req.satisfied?
32
- test.teardown_test
33
- end
34
- end
35
-
36
- let(:results) do
37
- test.run
38
- end
39
-
40
- let(:verifier) { Mongo::CRUD::Verifier.new(test) }
41
-
42
- it 'returns the correct result' do
43
- verifier.verify_operation_result(test_instance.expected_results, results[:results])
44
- end
45
-
46
- it 'has the correct data in the collection', if: test_instance.outcome && test_instance.outcome.collection_data? do
47
- results
48
- verifier.verify_collection_data(
49
- test_instance.outcome.collection_data,
50
- results[:contents])
51
- end
52
-
53
- if test_instance.expectations
54
- it 'has the correct number of command_started events' do
55
- verifier.verify_command_started_event_count(
56
- test_instance.expectations, results[:events])
57
- end
58
-
59
- test_instance.expectations.each_with_index do |expectation, i|
60
- it "has the correct command_started event #{i}" do
61
- verifier.verify_command_started_event(
62
- test_instance.expectations, results[:events], i)
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
6
+ define_transactions_spec_tests(TRANSACTIONS_TESTS)
71
7
  end
@@ -111,6 +111,10 @@ module Authorization
111
111
  # @since 2.0.0
112
112
  context.let(:root_authorized_client) { ClientRegistry.instance.global_client('root_authorized') }
113
113
 
114
+ context.let(:root_authorized_admin_client) do
115
+ ClientRegistry.instance.global_client('root_authorized').use(:admin)
116
+ end
117
+
114
118
  # Gets the default test collection from the authorized client.
115
119
  #
116
120
  # @since 2.0.0
@@ -77,6 +77,11 @@ module Mongo
77
77
  # @since 2.0.0
78
78
  attr_reader :description
79
79
 
80
+ # Optional list of command-started events in Extended JSON format
81
+ #
82
+ # @return [ Array<Hash> ] The list of command-started events
83
+ attr_reader :expectations
84
+
80
85
  def initialize(test, coll1, coll2, db1, db2)
81
86
  @description = test['description']
82
87
  @min_server_version = test['minServerVersion']
@@ -132,22 +137,36 @@ module Mongo
132
137
  }
133
138
  end
134
139
 
140
+ # JRuby must iterate the same object, not switch from
141
+ # enum to change stream
142
+ enum = change_stream.to_enum
143
+
135
144
  @operations.each do |op|
136
145
  op.execute(@db1, @db2)
137
146
  end
138
147
 
139
- changes = [].tap do |changes|
140
- next unless @result['success']
148
+ changes = []
141
149
 
142
- unless @result['success'].empty?
143
- change_stream.take_while do |change|
144
- changes << change
145
- changes.length < @result['success'].length
146
- end
147
- end
150
+ # attempt first next call (catch NonResumableChangeStreamError errors)
151
+ begin
152
+ change = enum.next
153
+ changes << change
154
+ rescue Mongo::Error::OperationFailure => e
155
+ return {
156
+ result: { 'error' => { 'code' => e.code, 'errorLabels' => e.labels} },
157
+ events: events
158
+ }
159
+ end
160
+
161
+ # continue until changeStream has received as many changes as there
162
+ # are in result.success
163
+ if @result['success'] && changes.length < @result['success'].length
164
+ while changes.length < @result['success'].length
165
+ changes << enum.next
166
+ end
167
+ end
148
168
 
149
- change_stream.close
150
- end
169
+ change_stream.close
151
170
 
152
171
  {
153
172
  result: { 'success' => changes },
@@ -204,6 +223,7 @@ module Mongo
204
223
 
205
224
  def match_array?(expected, actual)
206
225
  return false unless actual.is_a?(Array)
226
+ return false unless expected.length == actual.length
207
227
 
208
228
  expected.each_with_index.all? do |e, i|
209
229
  actual[i] && match?(e, actual[i])
@@ -50,6 +50,29 @@ module Mongo
50
50
  coll.insert_one(document)
51
51
  end
52
52
 
53
+ def update_one(coll)
54
+ coll.update_one(filter, arguments['update'])
55
+ end
56
+
57
+ def replace_one(coll)
58
+ coll.replace_one(filter, arguments['replacement'])
59
+ end
60
+
61
+ def delete_one(coll)
62
+ coll.delete_one(filter)
63
+ end
64
+
65
+ def drop(coll)
66
+ coll.drop
67
+ end
68
+
69
+ def rename(coll)
70
+ coll.client.use(:admin).command({
71
+ renameCollection: "#{coll.database.name}.#{coll.name}",
72
+ to: "#{coll.database.name}.#{arguments['to']}"
73
+ })
74
+ end
75
+
53
76
  def arguments
54
77
  @spec['arguments']
55
78
  end
@@ -57,6 +80,10 @@ module Mongo
57
80
  def document
58
81
  arguments['document']
59
82
  end
83
+
84
+ def filter
85
+ arguments['filter']
86
+ end
60
87
  end
61
88
  end
62
89
  end
@@ -45,24 +45,38 @@ class ClientRegistry
45
45
  # clients global to the test suite, should not be closed in an after hooks
46
46
  # but their monitoring may need to be suspended/resumed
47
47
  @global_clients = {}
48
+
49
+ # JRuby appears to somehow manage to access client registry concurrently
50
+ @lock = Mutex.new
48
51
  end
49
52
 
50
- def global_client(name)
51
- if client = @global_clients[name]
53
+ class << self
54
+ def client_perished?(client)
52
55
  if !client.cluster.connected?
53
- reconnect = true
56
+ true
54
57
  else
55
- reconnect = false
58
+ perished = false
56
59
  client.cluster.servers_list.each do |server|
57
60
  thread = server.monitor.instance_variable_get('@thread')
58
61
  if thread.nil? || !thread.alive?
59
- reconnect = true
62
+ perished = true
60
63
  end
61
64
  end
65
+ perished
62
66
  end
63
- if reconnect
67
+ end
68
+ private :client_perished?
69
+
70
+ def reconnect_client_if_perished(client)
71
+ if client_perished?(client)
64
72
  client.reconnect
65
73
  end
74
+ end
75
+ end
76
+
77
+ def global_client(name)
78
+ if client = @global_clients[name]
79
+ self.class.reconnect_client_if_perished(client)
66
80
  return client
67
81
  end
68
82
 
@@ -122,6 +136,15 @@ class ClientRegistry
122
136
  ).tap do |client|
123
137
  client.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber)
124
138
  end
139
+ # Provides an authorized mongo client that does not retry writes
140
+ # using either modern or legacy mechanisms.
141
+ when 'authorized_without_any_retry_writes'
142
+ global_client('authorized').with(
143
+ retry_writes: false, max_write_retries: 0,
144
+ server_selection_timeout: 4.99,
145
+ ).tap do |client|
146
+ client.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber)
147
+ end
125
148
  # Provides an authorized mongo client that does not retry reads or writes
126
149
  # at all.
127
150
  when 'authorized_without_any_retries'
@@ -152,19 +175,6 @@ class ClientRegistry
152
175
  monitoring: false
153
176
  ),
154
177
  )
155
- # Get an authorized client on the admin database logged in as the admin
156
- # root user.
157
- when 'root_authorized_admin'
158
- Mongo::Client.new(
159
- SpecConfig.instance.addresses,
160
- SpecConfig.instance.test_options.merge(
161
- user: SpecConfig.instance.root_user.name,
162
- password: SpecConfig.instance.root_user.password,
163
- database: 'admin',
164
- auth_source: SpecConfig.instance.auth_source || Mongo::Database::ADMIN,
165
- monitoring: false
166
- ),
167
- )
168
178
  # A client that has an event subscriber for commands.
169
179
  when 'subscribed'
170
180
  Mongo::Client.new(
@@ -184,24 +194,33 @@ class ClientRegistry
184
194
 
185
195
  def new_local_client(*args)
186
196
  Mongo::Client.new(*args).tap do |client|
187
- @local_clients << client
197
+ @lock.synchronize do
198
+ @local_clients << client
199
+ end
188
200
  end
189
201
  end
190
202
 
191
203
  def register_local_client(client)
192
- @local_clients << client
204
+ @lock.synchronize do
205
+ @local_clients << client
206
+ end
193
207
  client
194
208
  end
195
209
 
196
210
  def close_local_clients
197
- @local_clients.map(&:close)
198
- @local_clients = []
211
+ @lock.synchronize do
212
+ @local_clients.map(&:close)
213
+ @local_clients = []
214
+ end
199
215
  end
200
216
 
201
217
  def close_all_clients
218
+ ClusterTools.instance.close_clients
202
219
  close_local_clients
203
- @global_clients.each do |name, client|
204
- client.close(true)
220
+ @lock.synchronize do
221
+ @global_clients.each do |name, client|
222
+ client.close(true)
223
+ end
205
224
  end
206
225
  end
207
226
  end