mongo 2.20.2 → 2.21.0

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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/Rakefile +11 -11
  4. data/lib/mongo/address.rb +22 -3
  5. data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
  6. data/lib/mongo/auth/base.rb +1 -1
  7. data/lib/mongo/bulk_write.rb +35 -2
  8. data/lib/mongo/client.rb +38 -6
  9. data/lib/mongo/client_encryption.rb +6 -3
  10. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
  11. data/lib/mongo/cluster/sdam_flow.rb +20 -7
  12. data/lib/mongo/cluster.rb +14 -4
  13. data/lib/mongo/collection/helpers.rb +1 -1
  14. data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
  15. data/lib/mongo/collection/view/aggregation.rb +33 -99
  16. data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
  17. data/lib/mongo/collection/view/change_stream.rb +80 -27
  18. data/lib/mongo/collection/view/iterable.rb +76 -60
  19. data/lib/mongo/collection/view/map_reduce.rb +25 -8
  20. data/lib/mongo/collection/view/readable.rb +79 -30
  21. data/lib/mongo/collection/view/writable.rb +109 -48
  22. data/lib/mongo/collection/view.rb +43 -3
  23. data/lib/mongo/collection.rb +158 -23
  24. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  25. data/lib/mongo/crypt/binding.rb +4 -4
  26. data/lib/mongo/crypt/context.rb +20 -14
  27. data/lib/mongo/crypt/encryption_io.rb +56 -26
  28. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  29. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  30. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  31. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  32. data/lib/mongo/csot_timeout_holder.rb +119 -0
  33. data/lib/mongo/cursor/kill_spec.rb +5 -2
  34. data/lib/mongo/cursor/nontailable.rb +27 -0
  35. data/lib/mongo/cursor.rb +86 -24
  36. data/lib/mongo/cursor_host.rb +82 -0
  37. data/lib/mongo/database/view.rb +81 -14
  38. data/lib/mongo/database.rb +88 -18
  39. data/lib/mongo/error/operation_failure.rb +209 -204
  40. data/lib/mongo/error/server_timeout_error.rb +12 -0
  41. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  42. data/lib/mongo/error/timeout_error.rb +23 -0
  43. data/lib/mongo/error.rb +2 -0
  44. data/lib/mongo/grid/fs_bucket.rb +45 -12
  45. data/lib/mongo/grid/stream/read.rb +15 -1
  46. data/lib/mongo/grid/stream/write.rb +21 -4
  47. data/lib/mongo/index/view.rb +77 -16
  48. data/lib/mongo/operation/context.rb +40 -2
  49. data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
  50. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  51. data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
  52. data/lib/mongo/operation/find/op_msg.rb +45 -0
  53. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  54. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  55. data/lib/mongo/operation/insert/result.rb +4 -2
  56. data/lib/mongo/operation/list_collections/result.rb +1 -1
  57. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  58. data/lib/mongo/operation/op_msg_base.rb +3 -1
  59. data/lib/mongo/operation/result.rb +26 -5
  60. data/lib/mongo/operation/shared/executable.rb +12 -1
  61. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  62. data/lib/mongo/operation/shared/response_handling.rb +3 -3
  63. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  64. data/lib/mongo/operation/shared/timed.rb +52 -0
  65. data/lib/mongo/operation/shared/write.rb +4 -1
  66. data/lib/mongo/operation/update/op_msg.rb +2 -1
  67. data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
  68. data/lib/mongo/operation.rb +1 -0
  69. data/lib/mongo/protocol/message.rb +1 -4
  70. data/lib/mongo/protocol/msg.rb +2 -2
  71. data/lib/mongo/retryable/read_worker.rb +69 -29
  72. data/lib/mongo/retryable/write_worker.rb +49 -18
  73. data/lib/mongo/retryable.rb +8 -2
  74. data/lib/mongo/server/connection.rb +11 -5
  75. data/lib/mongo/server/connection_base.rb +22 -2
  76. data/lib/mongo/server/connection_pool.rb +32 -14
  77. data/lib/mongo/server/description/features.rb +1 -1
  78. data/lib/mongo/server/description.rb +18 -5
  79. data/lib/mongo/server/monitor.rb +7 -4
  80. data/lib/mongo/server/pending_connection.rb +7 -3
  81. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  82. data/lib/mongo/server.rb +11 -6
  83. data/lib/mongo/server_selector/base.rb +25 -9
  84. data/lib/mongo/session.rb +78 -9
  85. data/lib/mongo/socket/ssl.rb +113 -30
  86. data/lib/mongo/socket/tcp.rb +40 -6
  87. data/lib/mongo/socket.rb +154 -25
  88. data/lib/mongo/uri/options_mapper.rb +1 -0
  89. data/lib/mongo/version.rb +15 -4
  90. data/lib/mongo.rb +1 -0
  91. data/spec/atlas/atlas_connectivity_spec.rb +4 -0
  92. data/spec/atlas/operations_spec.rb +4 -0
  93. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  94. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  95. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  96. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +66 -22
  97. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  98. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  99. data/spec/integration/cursor_pinning_spec.rb +15 -60
  100. data/spec/integration/cursor_reaping_spec.rb +1 -1
  101. data/spec/integration/docs_examples_spec.rb +1 -1
  102. data/spec/integration/ocsp_verifier_spec.rb +99 -30
  103. data/spec/integration/operation_failure_code_spec.rb +1 -1
  104. data/spec/integration/operation_failure_message_spec.rb +3 -3
  105. data/spec/integration/reconnect_spec.rb +2 -8
  106. data/spec/integration/retryable_errors_spec.rb +2 -2
  107. data/spec/integration/sdam_error_handling_spec.rb +2 -1
  108. data/spec/integration/search_indexes_prose_spec.rb +4 -0
  109. data/spec/integration/server_spec.rb +4 -3
  110. data/spec/integration/srv_monitoring_spec.rb +3 -2
  111. data/spec/integration/srv_spec.rb +4 -0
  112. data/spec/integration/transactions_api_examples_spec.rb +2 -0
  113. data/spec/kerberos/kerberos_spec.rb +4 -0
  114. data/spec/lite_spec_helper.rb +3 -1
  115. data/spec/mongo/auth/user/view_spec.rb +1 -1
  116. data/spec/mongo/caching_cursor_spec.rb +1 -1
  117. data/spec/mongo/client_encryption_spec.rb +1 -0
  118. data/spec/mongo/client_spec.rb +158 -4
  119. data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
  120. data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
  121. data/spec/mongo/collection_spec.rb +5 -6
  122. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  123. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  124. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  125. data/spec/mongo/crypt/handle_spec.rb +1 -1
  126. data/spec/mongo/cursor_spec.rb +26 -9
  127. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  128. data/spec/mongo/operation/context_spec.rb +79 -0
  129. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  130. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  131. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  132. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  133. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  134. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  135. data/spec/mongo/query_cache_spec.rb +243 -225
  136. data/spec/mongo/retryable_spec.rb +1 -0
  137. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  138. data/spec/mongo/socket/ssl_spec.rb +0 -10
  139. data/spec/runners/change_streams/test.rb +2 -2
  140. data/spec/runners/crud/operation.rb +1 -1
  141. data/spec/runners/crud/verifier.rb +3 -1
  142. data/spec/runners/transactions/operation.rb +4 -6
  143. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  144. data/spec/runners/unified/assertions.rb +4 -0
  145. data/spec/runners/unified/change_stream_operations.rb +14 -24
  146. data/spec/runners/unified/crud_operations.rb +82 -59
  147. data/spec/runners/unified/ddl_operations.rb +38 -7
  148. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  149. data/spec/runners/unified/support_operations.rb +43 -4
  150. data/spec/runners/unified/test.rb +22 -10
  151. data/spec/runners/unified.rb +1 -1
  152. data/spec/solo/clean_exit_spec.rb +2 -0
  153. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  154. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  155. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  156. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  157. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  158. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  159. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  160. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  161. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  162. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  163. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  164. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  165. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  166. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  167. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  168. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  169. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  170. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  171. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  172. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  173. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  174. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  175. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  176. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  177. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  178. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  179. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  180. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  181. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  182. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  183. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  184. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  185. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  186. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  187. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  188. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +4 -0
  189. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +4 -0
  190. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
  191. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  192. data/spec/support/certificates/atlas-ocsp-ca.crt +81 -83
  193. data/spec/support/certificates/atlas-ocsp.crt +107 -107
  194. data/spec/support/cluster_tools.rb +3 -3
  195. data/spec/support/common_shortcuts.rb +39 -21
  196. data/spec/support/constraints.rb +0 -10
  197. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  198. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  199. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  200. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  201. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  202. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  203. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  204. data/spec/support/dns.rb +16 -0
  205. data/spec/support/shared/session.rb +2 -2
  206. data/spec/support/spec_setup.rb +2 -2
  207. data/spec/support/utils.rb +3 -1
  208. metadata +91 -153
  209. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  210. data/spec/shared/CANDIDATE.md +0 -28
  211. data/spec/shared/LICENSE +0 -20
  212. data/spec/shared/bin/get-mongodb-download-url +0 -17
  213. data/spec/shared/bin/s3-copy +0 -45
  214. data/spec/shared/bin/s3-upload +0 -69
  215. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  216. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  217. data/spec/shared/lib/mrss/constraints.rb +0 -378
  218. data/spec/shared/lib/mrss/docker_runner.rb +0 -298
  219. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  220. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  221. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  222. data/spec/shared/lib/mrss/release/candidate.rb +0 -281
  223. data/spec/shared/lib/mrss/release/product_data.rb +0 -144
  224. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  225. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  226. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  227. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  228. data/spec/shared/lib/mrss/utils.rb +0 -37
  229. data/spec/shared/lib/tasks/candidate.rake +0 -64
  230. data/spec/shared/share/Dockerfile.erb +0 -251
  231. data/spec/shared/share/haproxy-1.conf +0 -16
  232. data/spec/shared/share/haproxy-2.conf +0 -17
  233. data/spec/shared/shlib/config.sh +0 -27
  234. data/spec/shared/shlib/distro.sh +0 -84
  235. data/spec/shared/shlib/server.sh +0 -423
  236. data/spec/shared/shlib/set_env.sh +0 -110
  237. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -242
  238. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -423
  239. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -183
  240. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -240
  241. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -236
  242. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -253
  243. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1688
  244. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -294
  245. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -906
  246. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1685
  247. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1681
  248. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1698
  249. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -330
  250. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -425
  251. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -227
  252. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -328
  253. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -320
  254. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -337
  255. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -914
  256. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -293
  257. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -519
  258. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -912
  259. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -908
  260. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -925
  261. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -326
  262. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -425
  263. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -225
  264. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -324
  265. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -320
  266. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -339
  267. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -242
  268. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -424
  269. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -183
  270. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -240
  271. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -236
  272. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -255
  273. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -242
  274. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -423
  275. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -183
  276. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -240
  277. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -236
  278. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -255
  279. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -44
@@ -111,10 +111,6 @@ describe 'Client after reconnect' do
111
111
  # thread.kill should've similarly failed, but it doesn't.
112
112
  fails_on_jruby
113
113
 
114
- # odd failures related to async on ruby <= 3.1, I suspect something
115
- # with how fibers worked in those versions.
116
- minimum_mri_version '3.2.0'
117
-
118
114
  it 'recreates SRV monitor' do
119
115
  wait_for_discovery
120
116
 
@@ -155,10 +151,6 @@ describe 'Client after reconnect' do
155
151
  # NotImplementedError: recvmsg_nonblock is not implemented
156
152
  fails_on_jruby
157
153
 
158
- # odd failures related to async on ruby <= 3.1, I suspect something
159
- # with how fibers worked in those versions.
160
- minimum_mri_version '3.2.0'
161
-
162
154
  let(:uri) do
163
155
  "mongodb+srv://test-fake.test.build.10gen.cc/"
164
156
  end
@@ -189,6 +181,8 @@ describe 'Client after reconnect' do
189
181
  end
190
182
 
191
183
  around do |example|
184
+ require 'support/dns'
185
+
192
186
  rules = [
193
187
  ['_mongodb._tcp.test-fake.test.build.10gen.cc', :srv,
194
188
  [0, 0, 2799, 'localhost.test.build.10gen.cc'],
@@ -83,7 +83,7 @@ describe 'Failing retryable operations' do
83
83
 
84
84
  begin
85
85
  collection.find(a: 1).to_a
86
- rescue Mongo::Error::OperationFailure => exception
86
+ rescue Mongo::Error::OperationFailure::Family => exception
87
87
  else
88
88
  fail('Expected operation to fail')
89
89
  end
@@ -128,7 +128,7 @@ describe 'Failing retryable operations' do
128
128
 
129
129
  begin
130
130
  collection.insert_one(a: 1)
131
- rescue Mongo::Error::OperationFailure => exception
131
+ rescue Mongo::Error::OperationFailure::Family => exception
132
132
  else
133
133
  fail('Expected operation to fail')
134
134
  end
@@ -420,7 +420,8 @@ describe 'SDAM error handling' do
420
420
  expect_server_state_change
421
421
  end
422
422
 
423
- it_behaves_like 'marks server unknown and clears connection pool'
423
+ # https://jira.mongodb.org/browse/RUBY-2523
424
+ # it_behaves_like 'marks server unknown and clears connection pool'
424
425
 
425
426
  after do
426
427
  admin_client.command(configureFailPoint: 'failCommand', mode: 'off')
@@ -87,6 +87,10 @@ describe 'Mongo::Collection#search_indexes prose tests' do
87
87
  let(:definition) { { 'mappings' => { 'dynamic' => false } } }
88
88
  let(:create_index) { helper.collection.search_indexes.create_one(definition, name: name) }
89
89
 
90
+ after do
91
+ client.close
92
+ end
93
+
90
94
  # Case 1: Driver can successfully create and list search indexes
91
95
  context 'when creating and listing search indexes' do
92
96
  let(:index) { helper.wait_for(name).first }
@@ -6,6 +6,7 @@ require 'spec_helper'
6
6
  describe 'Server' do
7
7
  let(:client) { authorized_client }
8
8
 
9
+ let(:context) { Mongo::Operation::Context.new(client: client) }
9
10
  let(:server) { client.cluster.next_primary }
10
11
 
11
12
  let(:collection) { client['collection'] }
@@ -15,7 +16,7 @@ describe 'Server' do
15
16
  context 'it performs read operations and receives the correct result type' do
16
17
  context 'normal server' do
17
18
  it 'can be used for reads' do
18
- result = view.send(:send_initial_query, server)
19
+ result = view.send(:send_initial_query, server, context)
19
20
  expect(result).to be_a(Mongo::Operation::Find::Result)
20
21
  end
21
22
  end
@@ -35,7 +36,7 @@ describe 'Server' do
35
36
 
36
37
  it 'can be used for reads' do
37
38
  # See also RUBY-3102.
38
- result = view.send(:send_initial_query, server)
39
+ result = view.send(:send_initial_query, server, context)
39
40
  expect(result).to be_a(Mongo::Operation::Find::Result)
40
41
  end
41
42
  end
@@ -57,7 +58,7 @@ describe 'Server' do
57
58
  it 'is unusable' do
58
59
  # See also RUBY-3102.
59
60
  lambda do
60
- view.send(:send_initial_query, server)
61
+ view.send(:send_initial_query, server, context)
61
62
  end.should raise_error(Mongo::Error::ServerNotUsable)
62
63
  end
63
64
  end
@@ -76,8 +76,9 @@ describe 'SRV Monitoring' do
76
76
  # NotImplementedError: recvmsg_nonblock is not implemented
77
77
  fails_on_jruby
78
78
 
79
- # mock dns implementation doesn't play nice with 2.7, etc.
80
- minimum_mri_version '3.0.0'
79
+ before(:all) do
80
+ require 'support/dns'
81
+ end
81
82
 
82
83
  around do |example|
83
84
  # Speed up the tests by listening on the fake ports we are using.
@@ -12,6 +12,10 @@ describe 'SRV lookup' do
12
12
  # NotImplementedError: recvmsg_nonblock is not implemented
13
13
  fails_on_jruby
14
14
 
15
+ before(:all) do
16
+ require 'support/dns'
17
+ end
18
+
15
19
  let(:uri) do
16
20
  "mongodb+srv://test-fake.test.build.10gen.cc/?tls=#{SpecConfig.instance.ssl?}&tlsInsecure=true"
17
21
  end
@@ -58,5 +58,7 @@ describe 'Transactions API examples' do
58
58
 
59
59
  # End Transactions withTxn API Example 1
60
60
 
61
+ # Do not leak clients.
62
+ client.close
61
63
  end
62
64
  end
@@ -20,6 +20,10 @@ describe 'kerberos authentication' do
20
20
  end
21
21
  end
22
22
 
23
+ after do
24
+ client&.close
25
+ end
26
+
23
27
  let(:user) do
24
28
  "#{require_env_value('SASL_USER')}%40#{realm}"
25
29
  end
@@ -22,7 +22,9 @@ CMAP_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/cmap/*.yml").sort.select
22
22
  !defined?(JRUBY_VERSION) || !f.include?('pool-checkout-minPoolSize-connection-maxConnecting.yml')
23
23
  end
24
24
  AUTH_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/auth/*.yml").sort
25
- CLIENT_SIDE_ENCRYPTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/client_side_encryption/*.yml").sort
25
+ CLIENT_SIDE_ENCRYPTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/client_side_encryption/*.yml").sort.delete_if do |spec|
26
+ ![ 1, '1', 'yes', 'true' ].include?(ENV['CSOT_SPEC_TESTS']) && spec =~ /.*timeoutMS.yml$/
27
+ end
26
28
 
27
29
  # Disable output buffering: https://www.rubyguides.com/2019/02/ruby-io/
28
30
  STDOUT.sync = true
@@ -526,7 +526,7 @@ describe Mongo::Auth::User::View do
526
526
  it "raises and reports the write concern error correctly" do
527
527
  begin
528
528
  view.send(method, input)
529
- rescue Mongo::Error::OperationFailure => e
529
+ rescue Mongo::Error::OperationFailure::Family => e
530
530
  expect(e.write_concern_error?).to be true
531
531
  expect(e.write_concern_error_document).to eq(
532
532
  "code" => 64,
@@ -23,7 +23,7 @@ describe Mongo::CachingCursor do
23
23
  end
24
24
 
25
25
  let(:reply) do
26
- view.send(:send_initial_query, server)
26
+ view.send(:send_initial_query, server, Mongo::Operation::Context.new(client: authorized_client))
27
27
  end
28
28
 
29
29
  let(:cursor) do
@@ -303,6 +303,7 @@ describe Mongo::ClientEncryption do
303
303
  end
304
304
 
305
305
  it 'raises a KmsError' do
306
+ skip 'https://jira.mongodb.org/browse/RUBY-3375'
306
307
  expect do
307
308
  data_key_id
308
309
  end.to raise_error(Mongo::Error::KmsError, /Error while connecting to socket/)
@@ -561,6 +561,75 @@ describe Mongo::Client do
561
561
  expect(command['comment']).to eq('comment')
562
562
  end
563
563
  end
564
+
565
+ context 'with timeout_ms' do
566
+ # To make it easier with failCommand
567
+ require_topology :single
568
+ min_server_version '4.4'
569
+
570
+ before do
571
+ root_authorized_client.use('admin').command({
572
+ configureFailPoint: "failCommand",
573
+ mode: "alwaysOn",
574
+ data: {
575
+ failCommands: ["listDatabases"],
576
+ blockConnection: true,
577
+ blockTimeMS: 100
578
+ }
579
+ })
580
+ end
581
+
582
+ after do
583
+ root_authorized_client.use('admin').command({
584
+ configureFailPoint: "failCommand",
585
+ mode: "off"
586
+ })
587
+ end
588
+
589
+ context 'when timeout_ms is set on command level' do
590
+ context 'when there is not enough time' do
591
+ it 'raises' do
592
+ expect do
593
+ monitored_client.database_names({}, timeout_ms: 50)
594
+ end.to raise_error(Mongo::Error::TimeoutError)
595
+ end
596
+ end
597
+
598
+ context 'when there is enough time' do
599
+ it 'does not raise' do
600
+ expect do
601
+ monitored_client.database_names({}, timeout_ms: 200)
602
+ end.not_to raise_error
603
+ end
604
+ end
605
+ end
606
+
607
+ context 'when timeout_ms is set on client level' do
608
+ context 'when there is not enough time' do
609
+ let(:client) do
610
+ root_authorized_client.with(timeout_ms: 50)
611
+ end
612
+
613
+ it 'raises' do
614
+ expect do
615
+ client.database_names({})
616
+ end.to raise_error(Mongo::Error::TimeoutError)
617
+ end
618
+ end
619
+
620
+ context 'when there is enough time' do
621
+ let(:client) do
622
+ root_authorized_client.with(timeout_ms: 200)
623
+ end
624
+
625
+ it 'does not raise' do
626
+ expect do
627
+ monitored_client.database_names({})
628
+ end.not_to raise_error
629
+ end
630
+ end
631
+ end
632
+ end
564
633
  end
565
634
 
566
635
  describe '#list_databases' do
@@ -572,8 +641,6 @@ describe Mongo::Client do
572
641
  end
573
642
 
574
643
  context 'when filter criteria is present' do
575
- min_server_fcv '3.6'
576
-
577
644
  include_context 'ensure test db exists'
578
645
 
579
646
  let(:result) do
@@ -591,8 +658,6 @@ describe Mongo::Client do
591
658
  end
592
659
 
593
660
  context 'when name_only is true' do
594
- min_server_fcv '3.6'
595
-
596
661
  let(:command) do
597
662
  Utils.get_command_event(root_authorized_client, 'listDatabases') do |client|
598
663
  client.list_databases({}, true)
@@ -667,6 +732,75 @@ describe Mongo::Client do
667
732
  expect(command['comment']).to eq('comment')
668
733
  end
669
734
  end
735
+
736
+ context 'with timeout_ms' do
737
+ # To make it easier with failCommand
738
+ require_topology :single
739
+ min_server_version '4.4'
740
+
741
+ before do
742
+ root_authorized_client.use('admin').command({
743
+ configureFailPoint: "failCommand",
744
+ mode: "alwaysOn",
745
+ data: {
746
+ failCommands: ["listDatabases"],
747
+ blockConnection: true,
748
+ blockTimeMS: 100
749
+ }
750
+ })
751
+ end
752
+
753
+ after do
754
+ root_authorized_client.use('admin').command({
755
+ configureFailPoint: "failCommand",
756
+ mode: "off"
757
+ })
758
+ end
759
+
760
+ context 'when timeout_ms is set on command level' do
761
+ context 'when there is not enough time' do
762
+ it 'raises' do
763
+ expect do
764
+ monitored_client.list_databases({}, false, timeout_ms: 50)
765
+ end.to raise_error(Mongo::Error::TimeoutError)
766
+ end
767
+ end
768
+
769
+ context 'when there is enough time' do
770
+ it 'does not raise' do
771
+ expect do
772
+ monitored_client.list_databases({}, false, timeout_ms: 200)
773
+ end.not_to raise_error
774
+ end
775
+ end
776
+ end
777
+
778
+ context 'when timeout_ms is set on client level' do
779
+ context 'when there is not enough time' do
780
+ let(:client) do
781
+ root_authorized_client.with(timeout_ms: 50)
782
+ end
783
+
784
+ it 'raises' do
785
+ expect do
786
+ client.list_databases({})
787
+ end.to raise_error(Mongo::Error::TimeoutError)
788
+ end
789
+ end
790
+
791
+ context 'when there is enough time' do
792
+ let(:client) do
793
+ root_authorized_client.with(timeout_ms: 200)
794
+ end
795
+
796
+ it 'does not raise' do
797
+ expect do
798
+ monitored_client.list_databases({})
799
+ end.not_to raise_error
800
+ end
801
+ end
802
+ end
803
+ end
670
804
  end
671
805
 
672
806
  describe '#list_mongo_databases' do
@@ -1156,6 +1290,26 @@ describe Mongo::Client do
1156
1290
  }.to raise_exception(Mongo::Error::InvalidSession)
1157
1291
  end
1158
1292
  end
1293
+
1294
+ context 'when CSOT is set on the client' do
1295
+ require_topology :replica_set
1296
+
1297
+ let(:timeout_ms) { 10 }
1298
+
1299
+ let(:timeout_sec) { timeout_ms / 1_000.0 }
1300
+
1301
+ let(:client) do
1302
+ authorized_client.with(timeout_ms: timeout_ms)
1303
+ end
1304
+
1305
+ it 'uses CSOT timeout set on the client' do
1306
+ expect_any_instance_of(Mongo::ServerSelector::PrimaryPreferred).to(
1307
+ receive(:select_server).with(anything, {timeout: timeout_sec}).and_call_original
1308
+ )
1309
+
1310
+ client.start_session
1311
+ end
1312
+ end
1159
1313
  end
1160
1314
 
1161
1315
  describe '#summary' do
@@ -156,8 +156,6 @@ describe Mongo::Collection::View::Aggregation do
156
156
  end
157
157
 
158
158
  context 'when the initial response has no results but an active cursor' do
159
- min_server_fcv '3.2'
160
-
161
159
  let(:documents) do
162
160
  [
163
161
  { city: 'a'*6000000 },
@@ -166,7 +164,7 @@ describe Mongo::Collection::View::Aggregation do
166
164
  end
167
165
 
168
166
  let(:options) do
169
- { :use_cursor => true }
167
+ {}
170
168
  end
171
169
 
172
170
  let(:pipeline) do
@@ -486,48 +484,25 @@ describe Mongo::Collection::View::Aggregation do
486
484
  end
487
485
  end
488
486
 
489
- context 'when use_cursor is set' do
490
-
491
- context 'when use_cursor is true' do
492
-
493
- context 'when batch_size is set' do
494
-
495
- let(:options) do
496
- { :use_cursor => true,
497
- :batch_size => 10
498
- }
499
- end
500
-
501
- it 'sets a batch size document in the spec' do
502
- expect(aggregation_spec[:selector][:cursor][:batchSize]).to eq(options[:batch_size])
503
- end
504
- end
505
-
506
- context 'when batch_size is not set' do
507
-
508
- let(:options) do
509
- { :use_cursor => true }
510
- end
487
+ context 'when batch_size is set' do
511
488
 
512
- it 'sets an empty document in the spec' do
513
- expect(aggregation_spec[:selector][:cursor]).to eq({})
514
- end
515
- end
489
+ let(:options) do
490
+ { :batch_size => 10 }
491
+ end
516
492
 
493
+ it 'sets a batch size document in the spec' do
494
+ expect(aggregation_spec[:selector][:cursor][:batchSize]).to eq(options[:batch_size])
517
495
  end
496
+ end
518
497
 
519
- context 'when use_cursor is false' do
498
+ context 'when batch_size is not set' do
520
499
 
521
- let(:options) do
522
- { :use_cursor => false }
523
- end
524
-
525
- context 'when batch_size is set' do
500
+ let(:options) do
501
+ {}
502
+ end
526
503
 
527
- it 'does not set the cursor option in the spec' do
528
- expect(aggregation_spec[:selector][:cursor]).to be_nil
529
- end
530
- end
504
+ it 'sets an empty document in the spec' do
505
+ expect(aggregation_spec[:selector][:cursor]).to eq({})
531
506
  end
532
507
  end
533
508
  end
@@ -507,7 +507,7 @@ describe Mongo::Collection::View::ChangeStream do
507
507
  end
508
508
 
509
509
  it 'includes the max_await_time value in the formatted string' do
510
- expect(change_stream.inspect).to include({ max_await_time_ms: 10 }.to_s)
510
+ expect(change_stream.inspect).to include({ 'max_await_time_ms' => 10 }.to_s)
511
511
  end
512
512
  end
513
513
 
@@ -518,7 +518,7 @@ describe Mongo::Collection::View::ChangeStream do
518
518
  end
519
519
 
520
520
  it 'includes the batch_size value in the formatted string' do
521
- expect(change_stream.inspect).to include({ batch_size: 5 }.to_s)
521
+ expect(change_stream.inspect).to include({ 'batch_size' => 5 }.to_s)
522
522
  end
523
523
  end
524
524
 
@@ -529,7 +529,7 @@ describe Mongo::Collection::View::ChangeStream do
529
529
  end
530
530
 
531
531
  it 'includes the collation value in the formatted string' do
532
- expect(change_stream.inspect).to include({ 'collation' => { locale: 'en_US', strength: 2 } }.to_s)
532
+ expect(change_stream.inspect).to include({ 'collation' => { 'locale' => 'en_US', 'strength' => 2 } }.to_s)
533
533
  end
534
534
  end
535
535
 
@@ -828,13 +828,12 @@ describe Mongo::Collection do
828
828
 
829
829
  let(:enum) { change_stream.to_enum }
830
830
 
831
+ let(:get_more) { subscriber.started_events.detect { |e| e.command['getMore'] }.command }
832
+
831
833
  it 'sets the option correctly' do
832
- expect(change_stream.instance_variable_get(:@cursor)).to receive(:get_more_operation).once.and_wrap_original do |m, *args, &block|
833
- m.call(*args).tap do |op|
834
- expect(op.max_time_ms).to eq(3000)
835
- end
836
- end
837
- enum.next
834
+ enum.try_next
835
+ expect(get_more).not_to be_nil
836
+ expect(get_more['maxTimeMS']).to be == 3000
838
837
  end
839
838
 
840
839
  it "waits the appropriate amount of time" do
@@ -58,6 +58,8 @@ describe Mongo::Crypt::AutoEncrypter do
58
58
  )
59
59
  end
60
60
 
61
+ let(:operation_context) { Mongo::Operation::Context.new }
62
+
61
63
  shared_context 'with jsonSchema validator' do
62
64
  before do
63
65
  users_collection = client.use(db_name)[collection_name]
@@ -81,14 +83,14 @@ describe Mongo::Crypt::AutoEncrypter do
81
83
  shared_examples 'a functioning auto encrypter' do
82
84
  describe '#encrypt' do
83
85
  it 'replaces the ssn field with a BSON::Binary' do
84
- result = auto_encrypter.encrypt(db_name, command)
86
+ result = auto_encrypter.encrypt(db_name, command, operation_context)
85
87
  expect(result).to eq(encrypted_command)
86
88
  end
87
89
  end
88
90
 
89
91
  describe '#decrypt' do
90
92
  it 'returns the unencrypted document' do
91
- result = auto_encrypter.decrypt(encrypted_command)
93
+ result = auto_encrypter.decrypt(encrypted_command, operation_context)
92
94
  expect(result).to eq(command)
93
95
  end
94
96
  end
@@ -329,14 +331,14 @@ describe Mongo::Crypt::AutoEncrypter do
329
331
 
330
332
  describe '#encrypt' do
331
333
  it 'does not perform encryption' do
332
- result = auto_encrypter.encrypt(db_name, command)
334
+ result = auto_encrypter.encrypt(db_name, command, operation_context)
333
335
  expect(result).to eq(command)
334
336
  end
335
337
  end
336
338
 
337
339
  describe '#decrypt' do
338
340
  it 'still performs decryption' do
339
- result = auto_encrypter.decrypt(encrypted_command)
341
+ result = auto_encrypter.decrypt(encrypted_command, operation_context)
340
342
  expect(result).to eq(command)
341
343
  end
342
344
  end
@@ -347,14 +349,14 @@ describe Mongo::Crypt::AutoEncrypter do
347
349
 
348
350
  describe '#encrypt' do
349
351
  it 'does not perform encryption' do
350
- result = auto_encrypter.encrypt(db_name, command)
352
+ result = auto_encrypter.encrypt(db_name, command, operation_context)
351
353
  expect(result).to eq(command)
352
354
  end
353
355
  end
354
356
 
355
357
  describe '#decrypt' do
356
358
  it 'still performs decryption' do
357
- result = auto_encrypter.decrypt(encrypted_command)
359
+ result = auto_encrypter.decrypt(encrypted_command, operation_context)
358
360
  expect(result).to eq(command)
359
361
  end
360
362
  end
@@ -365,14 +367,14 @@ describe Mongo::Crypt::AutoEncrypter do
365
367
 
366
368
  describe '#encrypt' do
367
369
  it 'does not perform encryption' do
368
- result = auto_encrypter.encrypt(db_name, command)
370
+ result = auto_encrypter.encrypt(db_name, command, operation_context)
369
371
  expect(result).to eq(command)
370
372
  end
371
373
  end
372
374
 
373
375
  describe '#decrypt' do
374
376
  it 'still performs decryption' do
375
- result = auto_encrypter.decrypt(encrypted_command)
377
+ result = auto_encrypter.decrypt(encrypted_command, operation_context)
376
378
  expect(result).to eq(command)
377
379
  end
378
380
  end
@@ -383,14 +385,14 @@ describe Mongo::Crypt::AutoEncrypter do
383
385
 
384
386
  describe '#encrypt' do
385
387
  it 'does not perform encryption' do
386
- result = auto_encrypter.encrypt(db_name, command)
388
+ result = auto_encrypter.encrypt(db_name, command, operation_context)
387
389
  expect(result).to eq(command)
388
390
  end
389
391
  end
390
392
 
391
393
  describe '#decrypt' do
392
394
  it 'still performs decryption' do
393
- result = auto_encrypter.decrypt(encrypted_command)
395
+ result = auto_encrypter.decrypt(encrypted_command, operation_context)
394
396
  expect(result).to eq(command)
395
397
  end
396
398
  end
@@ -401,14 +403,14 @@ describe Mongo::Crypt::AutoEncrypter do
401
403
 
402
404
  describe '#encrypt' do
403
405
  it 'does not perform encryption' do
404
- result = auto_encrypter.encrypt(db_name, command)
406
+ result = auto_encrypter.encrypt(db_name, command, operation_context)
405
407
  expect(result).to eq(command)
406
408
  end
407
409
  end
408
410
 
409
411
  describe '#decrypt' do
410
412
  it 'still performs decryption' do
411
- result = auto_encrypter.decrypt(encrypted_command)
413
+ result = auto_encrypter.decrypt(encrypted_command, operation_context)
412
414
  expect(result).to eq(command)
413
415
  end
414
416
  end
@@ -136,8 +136,10 @@ describe Mongo::Crypt::DataKeyContext do
136
136
  )
137
137
  end
138
138
 
139
+ let(:operation_context) { Mongo::Operation::Context.new }
140
+
139
141
  it 'creates a data key' do
140
- expect(context.run_state_machine).to be_a_kind_of(Hash)
142
+ expect(context.run_state_machine(operation_context)).to be_a_kind_of(Hash)
141
143
  end
142
144
  end
143
145
  end
@@ -139,7 +139,7 @@ describe Mongo::Crypt::ExplicitEncryptionContext do
139
139
  value,
140
140
  options.merge(query_type: "equality")
141
141
  )
142
- end.to raise_error(ArgumentError, /query_type is allowed only for "Indexed" or "RangePreview" algorithm/)
142
+ end.to raise_error(ArgumentError, /query_type is allowed only for "Indexed" or "Range" algorithm/)
143
143
  end
144
144
  end
145
145
 
@@ -154,7 +154,7 @@ describe Mongo::Crypt::ExplicitEncryptionContext do
154
154
  value,
155
155
  options.merge(contention_factor: 10)
156
156
  )
157
- end.to raise_error(ArgumentError, /contention_factor is allowed only for "Indexed" or "RangePreview" algorithm/)
157
+ end.to raise_error(ArgumentError, /contention_factor is allowed only for "Indexed" or "Range" algorithm/)
158
158
  end
159
159
  end
160
160
 
@@ -188,7 +188,7 @@ describe Mongo::Crypt::Handle do
188
188
  end
189
189
 
190
190
  it 'raises an exception' do
191
- expect { handle }.to raise_error(Mongo::Error::CryptError, 'local key must be 96 bytes (libmongocrypt error code 1)')
191
+ expect { handle }.to raise_error(Mongo::Error::CryptError, /local key must be 96 bytes \(libmongocrypt error code 1\)/)
192
192
  end
193
193
  end
194
194