mongo 2.20.0 → 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 (296) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -1
  3. data/Rakefile +59 -23
  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/config.rb +2 -2
  25. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  26. data/lib/mongo/crypt/binding.rb +4 -4
  27. data/lib/mongo/crypt/context.rb +20 -14
  28. data/lib/mongo/crypt/encryption_io.rb +56 -26
  29. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  30. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  31. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  32. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  33. data/lib/mongo/csot_timeout_holder.rb +119 -0
  34. data/lib/mongo/cursor/kill_spec.rb +5 -2
  35. data/lib/mongo/cursor/nontailable.rb +27 -0
  36. data/lib/mongo/cursor.rb +86 -24
  37. data/lib/mongo/cursor_host.rb +82 -0
  38. data/lib/mongo/database/view.rb +81 -14
  39. data/lib/mongo/database.rb +88 -18
  40. data/lib/mongo/error/operation_failure.rb +209 -204
  41. data/lib/mongo/error/server_timeout_error.rb +12 -0
  42. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  43. data/lib/mongo/error/timeout_error.rb +23 -0
  44. data/lib/mongo/error.rb +2 -0
  45. data/lib/mongo/grid/fs_bucket.rb +45 -12
  46. data/lib/mongo/grid/stream/read.rb +15 -1
  47. data/lib/mongo/grid/stream/write.rb +21 -4
  48. data/lib/mongo/index/view.rb +77 -16
  49. data/lib/mongo/operation/context.rb +40 -2
  50. data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
  51. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  52. data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
  53. data/lib/mongo/operation/find/op_msg.rb +45 -0
  54. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  55. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  56. data/lib/mongo/operation/insert/result.rb +4 -2
  57. data/lib/mongo/operation/list_collections/result.rb +1 -1
  58. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  59. data/lib/mongo/operation/op_msg_base.rb +3 -1
  60. data/lib/mongo/operation/result.rb +26 -5
  61. data/lib/mongo/operation/shared/executable.rb +12 -1
  62. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  63. data/lib/mongo/operation/shared/response_handling.rb +3 -3
  64. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  65. data/lib/mongo/operation/shared/timed.rb +52 -0
  66. data/lib/mongo/operation/shared/write.rb +4 -1
  67. data/lib/mongo/operation/update/op_msg.rb +2 -1
  68. data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
  69. data/lib/mongo/operation.rb +1 -0
  70. data/lib/mongo/protocol/message.rb +1 -4
  71. data/lib/mongo/protocol/msg.rb +2 -2
  72. data/lib/mongo/retryable/base_worker.rb +28 -3
  73. data/lib/mongo/retryable/read_worker.rb +76 -35
  74. data/lib/mongo/retryable/write_worker.rb +53 -22
  75. data/lib/mongo/retryable.rb +8 -2
  76. data/lib/mongo/server/connection.rb +11 -5
  77. data/lib/mongo/server/connection_base.rb +22 -2
  78. data/lib/mongo/server/connection_pool.rb +32 -14
  79. data/lib/mongo/server/description/features.rb +1 -1
  80. data/lib/mongo/server/description.rb +18 -5
  81. data/lib/mongo/server/monitor.rb +7 -4
  82. data/lib/mongo/server/pending_connection.rb +25 -8
  83. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  84. data/lib/mongo/server.rb +11 -6
  85. data/lib/mongo/server_selector/base.rb +25 -9
  86. data/lib/mongo/session.rb +78 -9
  87. data/lib/mongo/socket/ssl.rb +131 -18
  88. data/lib/mongo/socket/tcp.rb +40 -6
  89. data/lib/mongo/socket.rb +154 -25
  90. data/lib/mongo/uri/options_mapper.rb +1 -0
  91. data/lib/mongo/version.rb +1 -5
  92. data/lib/mongo.rb +1 -0
  93. data/mongo.gemspec +8 -11
  94. data/spec/atlas/atlas_connectivity_spec.rb +4 -0
  95. data/spec/atlas/operations_spec.rb +4 -0
  96. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  97. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  98. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  99. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +67 -20
  100. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  101. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  102. data/spec/integration/cursor_pinning_spec.rb +15 -60
  103. data/spec/integration/cursor_reaping_spec.rb +1 -1
  104. data/spec/integration/docs_examples_spec.rb +1 -1
  105. data/spec/integration/operation_failure_code_spec.rb +1 -1
  106. data/spec/integration/operation_failure_message_spec.rb +3 -3
  107. data/spec/integration/retryable_errors_spec.rb +2 -2
  108. data/spec/integration/retryable_reads_errors_spec.rb +35 -23
  109. data/spec/integration/sdam_error_handling_spec.rb +4 -1
  110. data/spec/integration/search_indexes_prose_spec.rb +4 -0
  111. data/spec/integration/server_spec.rb +4 -3
  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 -11
  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_crud_spec.rb +1 -0
  122. data/spec/mongo/collection_spec.rb +5 -6
  123. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  124. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  125. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  126. data/spec/mongo/crypt/handle_spec.rb +1 -1
  127. data/spec/mongo/cursor_spec.rb +26 -9
  128. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  129. data/spec/mongo/operation/context_spec.rb +79 -0
  130. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  131. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  132. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  133. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  134. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  135. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  136. data/spec/mongo/query_cache_spec.rb +243 -225
  137. data/spec/mongo/retryable_spec.rb +1 -0
  138. data/spec/mongo/server/connection_spec.rb +22 -0
  139. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  140. data/spec/mongo/socket/ssl_spec.rb +0 -10
  141. data/spec/runners/change_streams/test.rb +2 -2
  142. data/spec/runners/crud/operation.rb +1 -1
  143. data/spec/runners/crud/verifier.rb +3 -1
  144. data/spec/runners/transactions/operation.rb +4 -6
  145. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  146. data/spec/runners/unified/assertions.rb +4 -0
  147. data/spec/runners/unified/change_stream_operations.rb +14 -24
  148. data/spec/runners/unified/crud_operations.rb +82 -59
  149. data/spec/runners/unified/ddl_operations.rb +38 -7
  150. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  151. data/spec/runners/unified/support_operations.rb +43 -4
  152. data/spec/runners/unified/test.rb +22 -10
  153. data/spec/runners/unified.rb +1 -1
  154. data/spec/solo/clean_exit_spec.rb +2 -0
  155. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  156. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  157. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  158. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  159. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  160. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  161. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  162. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  163. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  164. data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +1 -0
  165. data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
  166. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
  167. data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
  168. data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
  169. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
  170. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
  171. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
  172. data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
  173. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
  174. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
  175. data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
  176. data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
  177. data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
  178. data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +2 -1
  179. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  180. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  181. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  182. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  183. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  184. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  185. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  186. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  187. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  188. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  189. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  190. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  191. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  192. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  193. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  194. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  195. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  196. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  197. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  198. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  199. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  200. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  201. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  202. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  203. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  204. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  205. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +6 -0
  206. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -0
  207. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
  208. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  209. data/spec/spec_tests/transactions_unified_spec.rb +2 -1
  210. data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
  211. data/spec/support/certificates/atlas-ocsp.crt +117 -122
  212. data/spec/support/certificates/retrieve-atlas-cert +1 -1
  213. data/spec/support/cluster_tools.rb +3 -3
  214. data/spec/support/common_shortcuts.rb +2 -2
  215. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  216. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  217. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  218. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  219. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  220. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  221. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  222. data/spec/support/shared/session.rb +2 -2
  223. data/spec/support/spec_setup.rb +2 -2
  224. data/spec/support/utils.rb +3 -1
  225. metadata +88 -173
  226. checksums.yaml.gz.sig +0 -0
  227. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  228. data/spec/shared/LICENSE +0 -20
  229. data/spec/shared/bin/get-mongodb-download-url +0 -17
  230. data/spec/shared/bin/s3-copy +0 -45
  231. data/spec/shared/bin/s3-upload +0 -69
  232. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  233. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  234. data/spec/shared/lib/mrss/constraints.rb +0 -378
  235. data/spec/shared/lib/mrss/docker_runner.rb +0 -298
  236. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  237. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  238. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  239. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  240. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  241. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  242. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  243. data/spec/shared/lib/mrss/utils.rb +0 -37
  244. data/spec/shared/share/Dockerfile.erb +0 -281
  245. data/spec/shared/share/haproxy-1.conf +0 -16
  246. data/spec/shared/share/haproxy-2.conf +0 -17
  247. data/spec/shared/shlib/config.sh +0 -27
  248. data/spec/shared/shlib/distro.sh +0 -74
  249. data/spec/shared/shlib/server.sh +0 -417
  250. data/spec/shared/shlib/set_env.sh +0 -146
  251. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
  252. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
  253. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
  254. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
  255. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
  256. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
  257. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
  258. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
  259. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
  260. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
  261. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
  262. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
  263. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
  264. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
  265. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
  266. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
  267. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
  268. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
  269. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
  270. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
  271. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
  272. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
  273. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
  274. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
  275. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
  276. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
  277. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
  278. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
  279. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
  280. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
  281. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
  282. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
  283. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
  284. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
  285. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
  286. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
  287. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
  288. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
  289. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
  290. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
  291. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
  292. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
  293. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
  294. data/spec/support/faas/app/aws_lambda/mongodb/Gemfile.lock +0 -19
  295. data.tar.gz.sig +0 -0
  296. metadata.gz.sig +0 -3
data/lib/mongo/session.rb CHANGED
@@ -57,6 +57,12 @@ module Mongo
57
57
  #
58
58
  # @option options [ true|false ] :causal_consistency Whether to enable
59
59
  # causal consistency for this session.
60
+ # @option options [ Integer ] :default_timeout_ms The timeoutMS value for
61
+ # the following operations executed on the session:
62
+ # - commitTransaction
63
+ # - abortTransaction
64
+ # - withTransaction
65
+ # - endSession
60
66
  # @option options [ Hash ] :default_transaction_options Options to pass
61
67
  # to start_transaction by default, can contain any of the options that
62
68
  # start_transaction accepts.
@@ -96,6 +102,7 @@ module Mongo
96
102
  @options = options.dup.freeze
97
103
  @cluster_time = nil
98
104
  @state = NO_TRANSACTION_STATE
105
+ @with_transaction_deadline = nil
99
106
  end
100
107
 
101
108
  # @return [ Hash ] The options for this session.
@@ -438,9 +445,21 @@ module Mongo
438
445
  # progress or if the write concern is unacknowledged.
439
446
  #
440
447
  # @since 2.7.0
441
- def with_transaction(options=nil)
442
- # Non-configurable 120 second timeout for the entire operation
443
- deadline = Utils.monotonic_time + 120
448
+ def with_transaction(options = nil)
449
+ if timeout_ms = (options || {})[:timeout_ms]
450
+ timeout_sec = timeout_ms / 1_000.0
451
+ deadline = Utils.monotonic_time + timeout_sec
452
+ @with_transaction_deadline = deadline
453
+ elsif default_timeout_ms = @options[:default_timeout_ms]
454
+ timeout_sec = default_timeout_ms / 1_000.0
455
+ deadline = Utils.monotonic_time + timeout_sec
456
+ @with_transaction_deadline = deadline
457
+ elsif @client.timeout_sec
458
+ deadline = Utils.monotonic_time + @client.timeout_sec
459
+ @with_transaction_deadline = deadline
460
+ else
461
+ deadline = Utils.monotonic_time + 120
462
+ end
444
463
  transaction_in_progress = false
445
464
  loop do
446
465
  commit_options = {}
@@ -454,6 +473,7 @@ module Mongo
454
473
  rescue Exception => e
455
474
  if within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
456
475
  log_warn("Aborting transaction due to #{e.class}: #{e}")
476
+ @with_transaction_deadline = nil
457
477
  abort_transaction
458
478
  transaction_in_progress = false
459
479
  end
@@ -481,7 +501,7 @@ module Mongo
481
501
  rescue Mongo::Error => e
482
502
  if e.label?('UnknownTransactionCommitResult')
483
503
  if Utils.monotonic_time >= deadline ||
484
- e.is_a?(Error::OperationFailure) && e.max_time_ms_expired?
504
+ e.is_a?(Error::OperationFailure::Family) && e.max_time_ms_expired?
485
505
  then
486
506
  transaction_in_progress = false
487
507
  raise
@@ -522,9 +542,10 @@ module Mongo
522
542
  log_warn('with_transaction callback broke out of with_transaction loop, aborting transaction')
523
543
  begin
524
544
  abort_transaction
525
- rescue Error::OperationFailure, Error::InvalidTransactionOperation
545
+ rescue Error::OperationFailure::Family, Error::InvalidTransactionOperation
526
546
  end
527
547
  end
548
+ @with_transaction_deadline = nil
528
549
  end
529
550
 
530
551
  # Places subsequent operations in this session into a new transaction.
@@ -539,6 +560,7 @@ module Mongo
539
560
  #
540
561
  # @option options [ Integer ] :max_commit_time_ms The maximum amount of
541
562
  # time to allow a single commitTransaction command to run, in milliseconds.
563
+ # This options is deprecated, use :timeout_ms instead.
542
564
  # @option options [ Hash ] :read_concern The read concern options hash,
543
565
  # with the following optional keys:
544
566
  # - *:level* -- the read preference level as a symbol; valid values
@@ -549,6 +571,10 @@ module Mongo
549
571
  # items:
550
572
  # - *:mode* -- read preference specified as a symbol; the only valid value is
551
573
  # *:primary*.
574
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
575
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
576
+ # The default value is unset which means the value is inherited from
577
+ # the client.
552
578
  #
553
579
  # @raise [ Error::InvalidTransactionOperation ] If a transaction is already in
554
580
  # progress or if the write concern is unacknowledged.
@@ -611,6 +637,10 @@ module Mongo
611
637
  #
612
638
  # @option options :write_concern [ nil | WriteConcern::Base ] The write
613
639
  # concern to use for this operation.
640
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
641
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
642
+ # The default value is unset which means the value is inherited from
643
+ # the client.
614
644
  #
615
645
  # @raise [ Error::InvalidTransactionOperation ] If there is no active transaction.
616
646
  #
@@ -647,7 +677,11 @@ module Mongo
647
677
  write_concern = WriteConcern.get(write_concern)
648
678
  end
649
679
 
650
- context = Operation::Context.new(client: @client, session: self)
680
+ context = Operation::Context.new(
681
+ client: @client,
682
+ session: self,
683
+ operation_timeouts: operation_timeouts(options)
684
+ )
651
685
  write_with_retry(write_concern, ending_transaction: true,
652
686
  context: context,
653
687
  ) do |connection, txn_num, context|
@@ -685,10 +719,15 @@ module Mongo
685
719
  # @example Abort the transaction.
686
720
  # session.abort_transaction
687
721
  #
722
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
723
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
724
+ # The default value is unset which means the value is inherited from
725
+ # the client.
726
+ #
688
727
  # @raise [ Error::InvalidTransactionOperation ] If there is no active transaction.
689
728
  #
690
729
  # @since 2.6.0
691
- def abort_transaction
730
+ def abort_transaction(options = nil)
692
731
  QueryCache.clear
693
732
 
694
733
  check_if_ended!
@@ -705,10 +744,16 @@ module Mongo
705
744
  Mongo::Error::InvalidTransactionOperation.cannot_call_twice_msg(:abortTransaction))
706
745
  end
707
746
 
747
+ options ||= {}
748
+
708
749
  begin
709
750
  unless starting_transaction?
710
751
  @aborting_transaction = true
711
- context = Operation::Context.new(client: @client, session: self)
752
+ context = Operation::Context.new(
753
+ client: @client,
754
+ session: self,
755
+ operation_timeouts: operation_timeouts(options)
756
+ )
712
757
  write_with_retry(txn_options[:write_concern],
713
758
  ending_transaction: true, context: context,
714
759
  ) do |connection, txn_num, context|
@@ -898,7 +943,7 @@ module Mongo
898
943
  #
899
944
  # @since 2.6.0
900
945
  # @api private
901
- def add_txn_opts!(command, read)
946
+ def add_txn_opts!(command, read, context)
902
947
  command.tap do |c|
903
948
  # The read concern should be added to any command that starts a transaction.
904
949
  if starting_transaction?
@@ -952,6 +997,14 @@ module Mongo
952
997
  if c[:writeConcern] && c[:writeConcern][:w] && c[:writeConcern][:w].is_a?(Symbol)
953
998
  c[:writeConcern][:w] = c[:writeConcern][:w].to_s
954
999
  end
1000
+
1001
+ # Ignore wtimeout if csot
1002
+ if context&.csot?
1003
+ c[:writeConcern]&.delete(:wtimeout)
1004
+ end
1005
+
1006
+ # We must not send an empty (server default) write concern.
1007
+ c.delete(:writeConcern) if c[:writeConcern]&.empty?
955
1008
  end
956
1009
  end
957
1010
 
@@ -1138,6 +1191,8 @@ module Mongo
1138
1191
  # @api private
1139
1192
  attr_accessor :snapshot_timestamp
1140
1193
 
1194
+ attr_reader :with_transaction_deadline
1195
+
1141
1196
  private
1142
1197
 
1143
1198
  # Get the read concern the session will use when starting a transaction.
@@ -1217,5 +1272,19 @@ module Mongo
1217
1272
  end
1218
1273
  end
1219
1274
  end
1275
+
1276
+ def operation_timeouts(opts)
1277
+ {
1278
+ inherited_timeout_ms: @client.timeout_ms
1279
+ }.tap do |result|
1280
+ if @with_transaction_deadline.nil?
1281
+ if timeout_ms = opts[:timeout_ms]
1282
+ result[:operation_timeout_ms] = timeout_ms
1283
+ elsif default_timeout_ms = options[:default_timeout_ms]
1284
+ result[:operation_timeout_ms] = default_timeout_ms
1285
+ end
1286
+ end
1287
+ end
1288
+ end
1220
1289
  end
1221
1290
  end
@@ -142,26 +142,37 @@ module Mongo
142
142
  #
143
143
  # @since 2.0.0
144
144
  def connect!
145
- Timeout.timeout(options[:connect_timeout], Error::SocketTimeoutError, "The socket took over #{options[:connect_timeout]} seconds to connect") do
146
- map_exceptions do
147
- @tcp_socket.connect(::Socket.pack_sockaddr_in(port, host))
148
- end
149
- @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
150
- begin
151
- @socket.hostname = @host_name
152
- @socket.sync_close = true
153
- map_exceptions do
154
- @socket.connect
145
+ sockaddr = ::Socket.pack_sockaddr_in(port, host)
146
+ connect_timeout = options[:connect_timeout]
147
+ map_exceptions do
148
+ if connect_timeout && connect_timeout != 0
149
+ deadline = Utils.monotonic_time + connect_timeout
150
+ if BSON::Environment.jruby?
151
+ # We encounter some strange problems with connect_nonblock for
152
+ # ssl sockets on JRuby. Therefore, we use the old +Timeout.timeout+
153
+ # solution, even though it is known to be not very reliable.
154
+ raise Error::SocketTimeoutError, 'connect_timeout expired' if connect_timeout < 0
155
+
156
+ Timeout.timeout(connect_timeout, Error::SocketTimeoutError, "The socket took over #{options[:connect_timeout]} seconds to connect") do
157
+ connect_without_timeout(sockaddr)
158
+ end
159
+ else
160
+ connect_with_timeout(sockaddr, connect_timeout)
155
161
  end
162
+ remaining_timeout = deadline - Utils.monotonic_time
163
+ verify_certificate!(@socket)
164
+ verify_ocsp_endpoint!(@socket, remaining_timeout)
165
+ else
166
+ connect_without_timeout(sockaddr)
156
167
  verify_certificate!(@socket)
157
168
  verify_ocsp_endpoint!(@socket)
158
- rescue
159
- @socket.close
160
- @socket = nil
161
- raise
162
169
  end
163
- self
164
170
  end
171
+ self
172
+ rescue
173
+ @socket&.close
174
+ @socket = nil
175
+ raise
165
176
  end
166
177
  private :connect!
167
178
 
@@ -182,6 +193,87 @@ module Mongo
182
193
 
183
194
  private
184
195
 
196
+ # Connects the socket without a timeout provided.
197
+ #
198
+ # @param [ String ] sockaddr Address to connect to.
199
+ def connect_without_timeout(sockaddr)
200
+ @tcp_socket.connect(sockaddr)
201
+ @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
202
+ @socket.hostname = @host_name
203
+ @socket.sync_close = true
204
+ @socket.connect
205
+ end
206
+
207
+ # Connects the socket with the connect timeout. The timeout applies to
208
+ # connecting both ssl socket and the underlying tcp socket.
209
+ #
210
+ # @param [ String ] sockaddr Address to connect to.
211
+ def connect_with_timeout(sockaddr, connect_timeout)
212
+ if connect_timeout <= 0
213
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
214
+ end
215
+
216
+ deadline = Utils.monotonic_time + connect_timeout
217
+ connect_tcp_socket_with_timeout(sockaddr, deadline, connect_timeout)
218
+ connnect_ssl_socket_with_timeout(deadline, connect_timeout)
219
+ end
220
+
221
+ def connect_tcp_socket_with_timeout(sockaddr, deadline, connect_timeout)
222
+ if deadline <= Utils.monotonic_time
223
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
224
+ end
225
+ begin
226
+ @tcp_socket.connect_nonblock(sockaddr)
227
+ rescue IO::WaitWritable
228
+ with_select_timeout(deadline, connect_timeout) do |select_timeout|
229
+ IO.select(nil, [@tcp_socket], nil, select_timeout)
230
+ end
231
+ retry
232
+ rescue Errno::EISCONN
233
+ # Socket is connected, nothing to do.
234
+ end
235
+ end
236
+
237
+ def connnect_ssl_socket_with_timeout(deadline, connect_timeout)
238
+ if deadline <= Utils.monotonic_time
239
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
240
+ end
241
+ @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
242
+ @socket.hostname = @host_name
243
+ @socket.sync_close = true
244
+
245
+ # We still have time, connecting ssl socket.
246
+ begin
247
+ @socket.connect_nonblock
248
+ rescue IO::WaitReadable, OpenSSL::SSL::SSLErrorWaitReadable
249
+ with_select_timeout(deadline, connect_timeout) do |select_timeout|
250
+ IO.select([@socket], nil, nil, select_timeout)
251
+ end
252
+ retry
253
+ rescue IO::WaitWritable, OpenSSL::SSL::SSLErrorWaitWritable
254
+ with_select_timeout(deadline, connect_timeout) do |select_timeout|
255
+ IO.select(nil, [@socket], nil, select_timeout)
256
+ end
257
+ retry
258
+ rescue Errno::EISCONN
259
+ # Socket is connected, nothing to do
260
+ end
261
+ end
262
+
263
+ # Raises +Error::SocketTimeoutError+ exception if deadline reached or the
264
+ # block returns nil. The block should call +IO.select+ with the
265
+ # +connect_timeout+ value. It returns nil if the +connect_timeout+ expires.
266
+ def with_select_timeout(deadline, connect_timeout, &block)
267
+ select_timeout = deadline - Utils.monotonic_time
268
+ if select_timeout <= 0
269
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
270
+ end
271
+ rv = block.call(select_timeout)
272
+ if rv.nil?
273
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
274
+ end
275
+ end
276
+
185
277
  def verify_certificate?
186
278
  # If ssl_verify_certificate is not present, disable only if
187
279
  # ssl_verify is explicitly set to false.
@@ -287,7 +379,7 @@ module Mongo
287
379
  # for instance, if there is no newline between two certificates
288
380
  # this code will extract them both but OpenSSL fails in this situation.
289
381
  if cert_text
290
- certs = cert_text.scan(/-----BEGIN CERTIFICATE-----(?:.|\n)+?-----END CERTIFICATE-----/)
382
+ certs = extract_certs(cert_text)
291
383
  if certs.length > 1
292
384
  context.cert = OpenSSL::X509::Certificate.new(certs.shift)
293
385
  context.extra_chain_cert = certs.map do |cert|
@@ -362,7 +454,7 @@ module Mongo
362
454
  end
363
455
  end
364
456
 
365
- def verify_ocsp_endpoint!(socket)
457
+ def verify_ocsp_endpoint!(socket, timeout = nil)
366
458
  unless verify_ocsp_endpoint?
367
459
  return
368
460
  end
@@ -371,7 +463,7 @@ module Mongo
371
463
  ca_cert = socket.peer_cert_chain.last
372
464
 
373
465
  verifier = OcspVerifier.new(@host_name, cert, ca_cert, context.cert_store,
374
- **Utils.shallow_symbolize_keys(options))
466
+ **Utils.shallow_symbolize_keys(options).merge(timeout: timeout))
375
467
  verifier.verify_with_cache
376
468
  end
377
469
 
@@ -390,6 +482,27 @@ module Mongo
390
482
  hook.call(@context)
391
483
  end
392
484
  end
485
+
486
+ BEGIN_CERT = "-----BEGIN CERTIFICATE-----"
487
+ END_CERT = "-----END CERTIFICATE-----"
488
+
489
+ # This was originally a scan + regex, but the regex was particularly
490
+ # inefficient and was flagged as a concern by static analysis.
491
+ def extract_certs(text)
492
+ [].tap do |list|
493
+ pos = 0
494
+
495
+ while (begin_idx = text.index(BEGIN_CERT, pos))
496
+ end_idx = text.index(END_CERT, begin_idx)
497
+ break unless end_idx
498
+
499
+ end_idx += END_CERT.length
500
+ list.push(text[begin_idx...end_idx])
501
+
502
+ pos = end_idx
503
+ end
504
+ end
505
+ end
393
506
  end
394
507
  end
395
508
  end
@@ -79,16 +79,50 @@ module Mongo
79
79
  # @return [ TCP ] The connected socket instance.
80
80
  #
81
81
  # @since 2.0.0
82
+ # @api private
82
83
  def connect!
83
- Timeout.timeout(options[:connect_timeout], Error::SocketTimeoutError, "The socket took over #{options[:connect_timeout]} seconds to connect") do
84
- socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
85
- map_exceptions do
86
- socket.connect(::Socket.pack_sockaddr_in(port, host))
84
+ socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
85
+ sockaddr = ::Socket.pack_sockaddr_in(port, host)
86
+ connect_timeout = options[:connect_timeout]
87
+ map_exceptions do
88
+ if connect_timeout && connect_timeout != 0
89
+ connect_with_timeout(sockaddr, connect_timeout)
90
+ else
91
+ connect_without_timeout(sockaddr)
92
+ end
93
+ end
94
+ self
95
+ end
96
+
97
+ # @api private
98
+ def connect_without_timeout(sockaddr)
99
+ socket.connect(sockaddr)
100
+ end
101
+
102
+ # @api private
103
+ def connect_with_timeout(sockaddr, connect_timeout)
104
+ if connect_timeout <= 0
105
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
106
+ end
107
+
108
+ deadline = Utils.monotonic_time + connect_timeout
109
+ begin
110
+ socket.connect_nonblock(sockaddr)
111
+ rescue IO::WaitWritable
112
+ select_timeout = deadline - Utils.monotonic_time
113
+ if select_timeout <= 0
114
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
115
+ end
116
+ if IO.select(nil, [socket], nil, select_timeout)
117
+ retry
118
+ else
119
+ socket.close
120
+ raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
87
121
  end
88
- self
122
+ rescue Errno::EISCONN
123
+ # Socket is connected, nothing more to do
89
124
  end
90
125
  end
91
- private :connect!
92
126
 
93
127
  private
94
128