mongo 2.13.0 → 2.15.0.alpha

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 (375) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -4
  3. data.tar.gz.sig +0 -0
  4. data/README.md +4 -1
  5. data/Rakefile +46 -18
  6. data/lib/mongo.rb +32 -0
  7. data/lib/mongo/address.rb +1 -1
  8. data/lib/mongo/address/ipv4.rb +1 -1
  9. data/lib/mongo/address/ipv6.rb +1 -1
  10. data/lib/mongo/auth/aws/conversation.rb +1 -4
  11. data/lib/mongo/auth/base.rb +13 -7
  12. data/lib/mongo/auth/conversation_base.rb +32 -0
  13. data/lib/mongo/auth/cr/conversation.rb +6 -29
  14. data/lib/mongo/auth/gssapi/conversation.rb +4 -15
  15. data/lib/mongo/auth/ldap/conversation.rb +3 -14
  16. data/lib/mongo/auth/sasl_conversation_base.rb +1 -13
  17. data/lib/mongo/auth/scram_conversation_base.rb +7 -34
  18. data/lib/mongo/auth/user/view.rb +16 -9
  19. data/lib/mongo/auth/x509/conversation.rb +4 -25
  20. data/lib/mongo/background_thread.rb +11 -0
  21. data/lib/mongo/bulk_write.rb +38 -18
  22. data/lib/mongo/caching_cursor.rb +74 -0
  23. data/lib/mongo/client.rb +142 -16
  24. data/lib/mongo/cluster.rb +22 -31
  25. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -2
  26. data/lib/mongo/cluster/sdam_flow.rb +14 -0
  27. data/lib/mongo/cluster/topology/single.rb +1 -1
  28. data/lib/mongo/collection.rb +58 -18
  29. data/lib/mongo/collection/view.rb +24 -20
  30. data/lib/mongo/collection/view/aggregation.rb +26 -5
  31. data/lib/mongo/collection/view/builder/find_command.rb +38 -18
  32. data/lib/mongo/collection/view/change_stream.rb +1 -1
  33. data/lib/mongo/collection/view/explainable.rb +27 -8
  34. data/lib/mongo/collection/view/iterable.rb +73 -13
  35. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  36. data/lib/mongo/collection/view/readable.rb +57 -21
  37. data/lib/mongo/collection/view/writable.rb +29 -15
  38. data/lib/mongo/crypt/encryption_io.rb +6 -6
  39. data/lib/mongo/cursor.rb +18 -5
  40. data/lib/mongo/database.rb +28 -5
  41. data/lib/mongo/database/view.rb +2 -2
  42. data/lib/mongo/error.rb +11 -1
  43. data/lib/mongo/error/bulk_write_error.rb +17 -3
  44. data/lib/mongo/error/internal_driver_error.rb +22 -0
  45. data/lib/mongo/error/invalid_read_concern.rb +28 -0
  46. data/lib/mongo/error/operation_failure.rb +26 -7
  47. data/lib/mongo/error/parser.rb +65 -12
  48. data/lib/mongo/error/server_api_conflict.rb +23 -0
  49. data/lib/mongo/error/server_api_not_supported.rb +24 -0
  50. data/lib/mongo/error/server_certificate_revoked.rb +22 -0
  51. data/lib/mongo/error/unmet_dependency.rb +21 -0
  52. data/lib/mongo/error/unsupported_option.rb +14 -12
  53. data/lib/mongo/grid/fs_bucket.rb +37 -37
  54. data/lib/mongo/index/view.rb +21 -11
  55. data/lib/mongo/lint.rb +2 -1
  56. data/lib/mongo/logger.rb +3 -3
  57. data/lib/mongo/monitoring.rb +13 -4
  58. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +27 -16
  59. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +26 -15
  60. data/lib/mongo/operation.rb +4 -2
  61. data/lib/mongo/operation/aggregate/result.rb +9 -8
  62. data/lib/mongo/operation/collections_info.rb +18 -1
  63. data/lib/mongo/operation/collections_info/command.rb +5 -0
  64. data/lib/mongo/operation/collections_info/result.rb +18 -1
  65. data/lib/mongo/operation/context.rb +99 -0
  66. data/lib/mongo/operation/delete/bulk_result.rb +2 -0
  67. data/lib/mongo/operation/delete/result.rb +3 -0
  68. data/lib/mongo/operation/explain/command.rb +4 -0
  69. data/lib/mongo/operation/explain/legacy.rb +4 -0
  70. data/lib/mongo/operation/explain/op_msg.rb +6 -0
  71. data/lib/mongo/operation/explain/result.rb +3 -0
  72. data/lib/mongo/operation/find/legacy/result.rb +2 -0
  73. data/lib/mongo/operation/find/result.rb +13 -0
  74. data/lib/mongo/operation/get_more/result.rb +3 -0
  75. data/lib/mongo/operation/indexes.rb +15 -1
  76. data/lib/mongo/operation/indexes/result.rb +5 -0
  77. data/lib/mongo/operation/insert/bulk_result.rb +5 -0
  78. data/lib/mongo/operation/insert/command.rb +2 -2
  79. data/lib/mongo/operation/insert/legacy.rb +2 -2
  80. data/lib/mongo/operation/insert/op_msg.rb +2 -2
  81. data/lib/mongo/operation/insert/result.rb +5 -0
  82. data/lib/mongo/operation/list_collections/result.rb +9 -1
  83. data/lib/mongo/operation/map_reduce/result.rb +10 -0
  84. data/lib/mongo/operation/parallel_scan/result.rb +4 -0
  85. data/lib/mongo/operation/result.rb +37 -6
  86. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -0
  87. data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -0
  88. data/lib/mongo/operation/shared/executable.rb +25 -14
  89. data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
  90. data/lib/mongo/operation/shared/idable.rb +2 -1
  91. data/lib/mongo/operation/shared/limited.rb +1 -0
  92. data/lib/mongo/operation/shared/object_id_generator.rb +1 -0
  93. data/lib/mongo/operation/shared/op_msg_or_command.rb +1 -7
  94. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +1 -7
  95. data/lib/mongo/operation/shared/polymorphic_operation.rb +39 -0
  96. data/lib/mongo/operation/shared/response_handling.rb +23 -23
  97. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -0
  98. data/lib/mongo/operation/shared/sessions_supported.rb +14 -2
  99. data/lib/mongo/operation/shared/specifiable.rb +1 -0
  100. data/lib/mongo/operation/shared/write.rb +9 -18
  101. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -0
  102. data/lib/mongo/operation/update/legacy/result.rb +7 -0
  103. data/lib/mongo/operation/update/result.rb +8 -0
  104. data/lib/mongo/operation/users_info/result.rb +3 -0
  105. data/lib/mongo/protocol/compressed.rb +51 -5
  106. data/lib/mongo/protocol/message.rb +31 -4
  107. data/lib/mongo/protocol/msg.rb +37 -12
  108. data/lib/mongo/protocol/query.rb +36 -0
  109. data/lib/mongo/query_cache.rb +272 -0
  110. data/lib/mongo/retryable.rb +9 -2
  111. data/lib/mongo/server.rb +12 -16
  112. data/lib/mongo/server/app_metadata.rb +52 -18
  113. data/lib/mongo/server/connection.rb +5 -0
  114. data/lib/mongo/server/connection_base.rb +16 -15
  115. data/lib/mongo/server/connection_common.rb +2 -2
  116. data/lib/mongo/server/connection_pool.rb +9 -4
  117. data/lib/mongo/server/description.rb +12 -1
  118. data/lib/mongo/server/description/features.rb +9 -8
  119. data/lib/mongo/server/monitor.rb +21 -2
  120. data/lib/mongo/server/monitor/app_metadata.rb +1 -1
  121. data/lib/mongo/server/monitor/connection.rb +12 -13
  122. data/lib/mongo/server/pending_connection.rb +26 -8
  123. data/lib/mongo/server/push_monitor.rb +12 -2
  124. data/lib/mongo/server_selector/base.rb +5 -1
  125. data/lib/mongo/session.rb +7 -3
  126. data/lib/mongo/session/session_pool.rb +4 -2
  127. data/lib/mongo/socket.rb +35 -8
  128. data/lib/mongo/socket/ocsp_cache.rb +97 -0
  129. data/lib/mongo/socket/ocsp_verifier.rb +368 -0
  130. data/lib/mongo/socket/ssl.rb +53 -24
  131. data/lib/mongo/srv/monitor.rb +7 -24
  132. data/lib/mongo/srv/resolver.rb +14 -10
  133. data/lib/mongo/timeout.rb +2 -0
  134. data/lib/mongo/uri.rb +21 -390
  135. data/lib/mongo/uri/options_mapper.rb +620 -0
  136. data/lib/mongo/uri/srv_protocol.rb +3 -2
  137. data/lib/mongo/utils.rb +27 -1
  138. data/lib/mongo/version.rb +1 -1
  139. data/spec/NOTES.aws-auth.md +12 -7
  140. data/spec/README.md +87 -2
  141. data/spec/integration/auth_spec.rb +25 -15
  142. data/spec/integration/bson_symbol_spec.rb +4 -2
  143. data/spec/integration/bulk_write_error_message_spec.rb +41 -0
  144. data/spec/integration/bulk_write_spec.rb +48 -0
  145. data/spec/integration/change_stream_spec.rb +5 -5
  146. data/spec/integration/client_authentication_options_spec.rb +92 -28
  147. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +6 -2
  148. data/spec/integration/command_monitoring_spec.rb +2 -2
  149. data/spec/integration/connection_pool_populator_spec.rb +4 -2
  150. data/spec/integration/connection_spec.rb +2 -0
  151. data/spec/integration/cursor_reaping_spec.rb +54 -18
  152. data/spec/integration/docs_examples_spec.rb +8 -1
  153. data/spec/integration/fork_reconnect_spec.rb +60 -2
  154. data/spec/integration/ocsp_connectivity_spec.rb +26 -0
  155. data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
  156. data/spec/integration/ocsp_verifier_spec.rb +340 -0
  157. data/spec/integration/operation_failure_code_spec.rb +1 -1
  158. data/spec/integration/operation_failure_message_spec.rb +90 -0
  159. data/spec/integration/query_cache_spec.rb +1045 -0
  160. data/spec/integration/query_cache_transactions_spec.rb +190 -0
  161. data/spec/integration/reconnect_spec.rb +1 -1
  162. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -0
  163. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +2 -0
  164. data/spec/integration/sdam_error_handling_spec.rb +86 -1
  165. data/spec/integration/sdam_events_spec.rb +8 -7
  166. data/spec/integration/server_selection_spec.rb +36 -0
  167. data/spec/integration/size_limit_spec.rb +20 -19
  168. data/spec/integration/snappy_compression_spec.rb +25 -0
  169. data/spec/integration/srv_monitoring_spec.rb +39 -4
  170. data/spec/integration/srv_spec.rb +56 -0
  171. data/spec/integration/transactions_examples_spec.rb +23 -7
  172. data/spec/integration/zlib_compression_spec.rb +1 -1
  173. data/spec/integration/zstd_compression_spec.rb +26 -0
  174. data/spec/lite_spec_helper.rb +15 -5
  175. data/spec/mongo/address_spec.rb +16 -12
  176. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  177. data/spec/mongo/auth/ldap_spec.rb +5 -1
  178. data/spec/mongo/auth/scram_negotiation_spec.rb +1 -1
  179. data/spec/mongo/auth/scram_spec.rb +1 -1
  180. data/spec/mongo/auth/user_spec.rb +1 -1
  181. data/spec/mongo/auth/x509/conversation_spec.rb +3 -3
  182. data/spec/mongo/bulk_write_spec.rb +2 -2
  183. data/spec/mongo/caching_cursor_spec.rb +70 -0
  184. data/spec/mongo/client_construction_spec.rb +273 -35
  185. data/spec/mongo/client_encryption_spec.rb +16 -10
  186. data/spec/mongo/client_spec.rb +64 -0
  187. data/spec/mongo/cluster/topology/replica_set_spec.rb +1 -1
  188. data/spec/mongo/cluster/topology/sharded_spec.rb +1 -1
  189. data/spec/mongo/cluster/topology/single_spec.rb +15 -6
  190. data/spec/mongo/cluster/topology/unknown_spec.rb +1 -1
  191. data/spec/mongo/cluster/topology_spec.rb +1 -1
  192. data/spec/mongo/cluster_spec.rb +6 -18
  193. data/spec/mongo/collection/view/change_stream_resume_spec.rb +1 -1
  194. data/spec/mongo/collection/view/explainable_spec.rb +87 -4
  195. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -0
  196. data/spec/mongo/collection/view/readable_spec.rb +50 -0
  197. data/spec/mongo/collection_crud_spec.rb +4357 -0
  198. data/spec/mongo/collection_ddl_spec.rb +534 -0
  199. data/spec/mongo/collection_spec.rb +5 -4787
  200. data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
  201. data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
  202. data/spec/mongo/crypt/binary_spec.rb +1 -6
  203. data/spec/mongo/crypt/binding/binary_spec.rb +1 -6
  204. data/spec/mongo/crypt/binding/context_spec.rb +2 -7
  205. data/spec/mongo/crypt/binding/helpers_spec.rb +1 -6
  206. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +2 -7
  207. data/spec/mongo/crypt/binding/status_spec.rb +1 -6
  208. data/spec/mongo/crypt/binding/version_spec.rb +1 -6
  209. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  210. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
  211. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +1 -1
  212. data/spec/mongo/crypt/status_spec.rb +1 -6
  213. data/spec/mongo/database_spec.rb +174 -4
  214. data/spec/mongo/error/bulk_write_error_spec.rb +3 -3
  215. data/spec/mongo/error/no_server_available_spec.rb +1 -1
  216. data/spec/mongo/error/parser_spec.rb +37 -6
  217. data/spec/mongo/index/view_spec.rb +8 -2
  218. data/spec/mongo/logger_spec.rb +13 -11
  219. data/spec/mongo/monitoring/event/server_closed_spec.rb +1 -1
  220. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +1 -1
  221. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +1 -1
  222. data/spec/mongo/monitoring/event/server_opening_spec.rb +1 -1
  223. data/spec/mongo/monitoring/event/topology_changed_spec.rb +1 -1
  224. data/spec/mongo/monitoring/event/topology_closed_spec.rb +1 -1
  225. data/spec/mongo/monitoring/event/topology_opening_spec.rb +1 -1
  226. data/spec/mongo/operation/aggregate_spec.rb +2 -1
  227. data/spec/mongo/operation/collections_info_spec.rb +4 -1
  228. data/spec/mongo/operation/command_spec.rb +6 -3
  229. data/spec/mongo/operation/create_index_spec.rb +6 -3
  230. data/spec/mongo/operation/create_user_spec.rb +6 -3
  231. data/spec/mongo/operation/delete/bulk_spec.rb +9 -6
  232. data/spec/mongo/operation/delete/op_msg_spec.rb +3 -3
  233. data/spec/mongo/operation/delete_spec.rb +11 -7
  234. data/spec/mongo/operation/drop_index_spec.rb +6 -2
  235. data/spec/mongo/operation/find/legacy_spec.rb +3 -1
  236. data/spec/mongo/operation/get_more_spec.rb +3 -1
  237. data/spec/mongo/operation/indexes_spec.rb +5 -1
  238. data/spec/mongo/operation/insert/bulk_spec.rb +10 -7
  239. data/spec/mongo/operation/insert/command_spec.rb +2 -2
  240. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -3
  241. data/spec/mongo/operation/insert_spec.rb +15 -12
  242. data/spec/mongo/operation/map_reduce_spec.rb +5 -2
  243. data/spec/mongo/operation/read_preference_op_msg_spec.rb +1 -1
  244. data/spec/mongo/operation/remove_user_spec.rb +6 -3
  245. data/spec/mongo/operation/result_spec.rb +1 -1
  246. data/spec/mongo/operation/update/bulk_spec.rb +9 -6
  247. data/spec/mongo/operation/update/command_spec.rb +2 -2
  248. data/spec/mongo/operation/update/op_msg_spec.rb +3 -3
  249. data/spec/mongo/operation/update_spec.rb +10 -7
  250. data/spec/mongo/operation/update_user_spec.rb +4 -1
  251. data/spec/mongo/protocol/compressed_spec.rb +26 -12
  252. data/spec/mongo/query_cache_middleware_spec.rb +55 -0
  253. data/spec/mongo/query_cache_spec.rb +280 -0
  254. data/spec/mongo/retryable_spec.rb +3 -2
  255. data/spec/mongo/server/app_metadata_shared.rb +2 -2
  256. data/spec/mongo/server/app_metadata_spec.rb +2 -0
  257. data/spec/mongo/server/connection_pool/populator_spec.rb +3 -1
  258. data/spec/mongo/server/connection_pool_spec.rb +8 -4
  259. data/spec/mongo/server/connection_spec.rb +39 -25
  260. data/spec/mongo/server/description_spec.rb +18 -0
  261. data/spec/mongo/server/monitor/connection_spec.rb +17 -7
  262. data/spec/mongo/server/monitor_spec.rb +9 -1
  263. data/spec/mongo/server_selector_spec.rb +2 -2
  264. data/spec/mongo/server_spec.rb +15 -2
  265. data/spec/mongo/socket/ssl_spec.rb +44 -4
  266. data/spec/mongo/socket_spec.rb +2 -2
  267. data/spec/mongo/tls_context_hooks_spec.rb +37 -0
  268. data/spec/mongo/uri/srv_protocol_spec.rb +64 -33
  269. data/spec/mongo/uri_option_parsing_spec.rb +11 -11
  270. data/spec/mongo/uri_spec.rb +68 -41
  271. data/spec/mongo/utils_spec.rb +39 -0
  272. data/spec/runners/auth.rb +3 -0
  273. data/spec/runners/change_streams/test.rb +1 -1
  274. data/spec/runners/connection_string.rb +31 -124
  275. data/spec/runners/crud/requirement.rb +40 -3
  276. data/spec/runners/crud/test_base.rb +0 -19
  277. data/spec/runners/crud/verifier.rb +8 -0
  278. data/spec/runners/server_selection.rb +1 -1
  279. data/spec/runners/transactions/operation.rb +13 -2
  280. data/spec/runners/transactions/test.rb +3 -2
  281. data/spec/runners/unified.rb +96 -0
  282. data/spec/runners/unified/assertions.rb +249 -0
  283. data/spec/runners/unified/change_stream_operations.rb +26 -0
  284. data/spec/runners/unified/crud_operations.rb +199 -0
  285. data/spec/runners/unified/ddl_operations.rb +96 -0
  286. data/spec/runners/unified/entity_map.rb +39 -0
  287. data/spec/runners/unified/error.rb +25 -0
  288. data/spec/runners/unified/event_subscriber.rb +91 -0
  289. data/spec/runners/unified/exceptions.rb +21 -0
  290. data/spec/runners/unified/grid_fs_operations.rb +55 -0
  291. data/spec/runners/unified/support_operations.rb +250 -0
  292. data/spec/runners/unified/test.rb +393 -0
  293. data/spec/runners/unified/test_group.rb +28 -0
  294. data/spec/runners/unified/using_hash.rb +31 -0
  295. data/spec/shared/LICENSE +20 -0
  296. data/spec/shared/bin/get-mongodb-download-url +17 -0
  297. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  298. data/spec/shared/lib/mrss/cluster_config.rb +218 -0
  299. data/spec/shared/lib/mrss/constraints.rb +346 -0
  300. data/spec/shared/lib/mrss/docker_runner.rb +262 -0
  301. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  302. data/spec/shared/lib/mrss/server_version_registry.rb +112 -0
  303. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  304. data/spec/shared/lib/mrss/utils.rb +15 -0
  305. data/spec/shared/share/Dockerfile.erb +231 -0
  306. data/spec/shared/shlib/distro.sh +73 -0
  307. data/spec/shared/shlib/server.sh +290 -0
  308. data/spec/shared/shlib/set_env.sh +128 -0
  309. data/spec/solo/clean_exit_spec.rb +21 -0
  310. data/spec/spec_helper.rb +7 -2
  311. data/spec/spec_tests/cmap_spec.rb +7 -3
  312. data/spec/spec_tests/crud_unified_spec.rb +10 -0
  313. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +0 -1
  314. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -2
  315. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +6 -2
  316. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +3 -0
  317. data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
  318. data/spec/spec_tests/data/crud_unified/estimatedDocumentCount.yml +267 -0
  319. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-4.9.yml +60 -0
  320. data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount.yml → estimatedDocumentCount-pre4.9.yml} +2 -0
  321. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors-4.9.yml +146 -0
  322. data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount-serverErrors.yml → estimatedDocumentCount-serverErrors-pre4.9.yml} +2 -0
  323. data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +1 -1
  324. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -3
  325. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +2 -2
  326. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
  327. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
  328. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
  329. data/spec/spec_tests/data/unified/valid-fail/operation-failure.yml +31 -0
  330. data/spec/spec_tests/data/unified/valid-pass/poc-change-streams.yml +220 -0
  331. data/spec/spec_tests/data/unified/valid-pass/poc-command-monitoring.yml +102 -0
  332. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +184 -0
  333. data/spec/spec_tests/data/unified/valid-pass/poc-gridfs.yml +155 -0
  334. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-reads.yml +193 -0
  335. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +210 -0
  336. data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +215 -0
  337. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +235 -0
  338. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +169 -0
  339. data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +170 -0
  340. data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
  341. data/spec/spec_tests/data/uri_options/compression-options.yml +7 -4
  342. data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
  343. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
  344. data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
  345. data/spec/spec_tests/data/versioned_api/crud-api-version-1-strict.yml +416 -0
  346. data/spec/spec_tests/data/versioned_api/crud-api-version-1.yml +409 -0
  347. data/spec/spec_tests/data/versioned_api/runcommand-helper-no-api-version-declared.yml +67 -0
  348. data/spec/spec_tests/data/versioned_api/test-commands-deprecation-errors.yml +47 -0
  349. data/spec/spec_tests/data/versioned_api/test-commands-strict-mode.yml +44 -0
  350. data/spec/spec_tests/data/versioned_api/transaction-handling.yml +180 -0
  351. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +9 -1
  352. data/spec/spec_tests/unified_spec.rb +15 -0
  353. data/spec/spec_tests/uri_options_spec.rb +47 -33
  354. data/spec/spec_tests/versioned_api_spec.rb +10 -0
  355. data/spec/stress/fork_reconnect_stress_spec.rb +1 -1
  356. data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
  357. data/spec/support/certificates/atlas-ocsp.crt +41 -0
  358. data/spec/support/client_registry_macros.rb +11 -2
  359. data/spec/support/common_shortcuts.rb +59 -0
  360. data/spec/support/constraints.rb +6 -253
  361. data/spec/support/matchers.rb +16 -0
  362. data/spec/support/ocsp +1 -0
  363. data/spec/support/session_registry.rb +52 -0
  364. data/spec/support/shared/session.rb +2 -2
  365. data/spec/support/spec_config.rb +68 -3
  366. data/spec/support/spec_setup.rb +48 -38
  367. data/spec/support/utils.rb +102 -4
  368. metadata +1087 -936
  369. metadata.gz.sig +0 -0
  370. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +0 -56
  371. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +0 -47
  372. data/spec/support/child_process_helper.rb +0 -78
  373. data/spec/support/cluster_config.rb +0 -207
  374. data/spec/support/lite_constraints.rb +0 -141
  375. data/spec/support/spec_organizer.rb +0 -129
@@ -43,6 +43,11 @@ module Mongo
43
43
  # @api private
44
44
  AUTH_OPTION_KEYS = [:user, :auth_source, :auth_mech].freeze
45
45
 
46
+ # Possible connection purposes.
47
+ #
48
+ # @api private
49
+ PURPOSES = %i(application monitor push_monitor).freeze
50
+
46
51
  # Instantiate the new AppMetadata object.
47
52
  #
48
53
  # @api private
@@ -60,10 +65,16 @@ module Mongo
60
65
  # @option options [ Array<String> ] :compressors A list of potential
61
66
  # compressors to use, in order of preference. The driver chooses the
62
67
  # first compressor that is also supported by the server. Currently the
63
- # driver only supports 'zlib'.
68
+ # driver only supports 'zstd', 'snappy' and 'zlib'.
64
69
  # @option options [ String ] :platform Platform information to include in
65
70
  # the metadata printed to the mongod logs upon establishing a connection
66
71
  # in server versions >= 3.4.
72
+ # @option options [ Symbol ] :purpose The purpose of this connection.
73
+ # @option options [ Hash ] :server_api The requested server API version.
74
+ # This hash can have the following items:
75
+ # - *:version* -- string
76
+ # - *:strict* -- boolean
77
+ # - *:deprecation_errors* -- boolean
67
78
  # @option options [ String ] :user The user name.
68
79
  # @option options [ Array<Hash> ] :wrapping_libraries Information about
69
80
  # libraries such as ODMs that are wrapping the driver. Specify the
@@ -71,11 +82,17 @@ module Mongo
71
82
  # :platform.
72
83
  #
73
84
  # @since 2.4.0
74
- def initialize(options)
85
+ def initialize(options = {})
75
86
  @app_name = options[:app_name].to_s if options[:app_name]
76
87
  @platform = options[:platform]
88
+ if @purpose = options[:purpose]
89
+ unless PURPOSES.include?(@purpose)
90
+ raise ArgumentError, "Invalid purpose: #{@purpose}"
91
+ end
92
+ end
77
93
  @compressors = options[:compressors] || []
78
94
  @wrapping_libraries = options[:wrapping_libraries]
95
+ @server_api = options[:server_api]
79
96
 
80
97
  if options[:user] && !options[:auth_mech]
81
98
  auth_db = options[:auth_source] || 'admin'
@@ -83,6 +100,12 @@ module Mongo
83
100
  end
84
101
  end
85
102
 
103
+ # @return [ Symbol ] The purpose of the connection for which this
104
+ # app metadata is created.
105
+ #
106
+ # @api private
107
+ attr_reader :purpose
108
+
86
109
  # @return [ Array<Hash> | nil ] Information about libraries wrapping
87
110
  # the driver.
88
111
  attr_reader :wrapping_libraries
@@ -130,22 +153,29 @@ module Mongo
130
153
  end
131
154
 
132
155
  def document
133
- client_document = full_client_document
134
- while client_document.to_bson.to_s.size > MAX_DOCUMENT_SIZE do
135
- if client_document[:os][:name] || client_document[:os][:architecture]
136
- client_document[:os].delete(:name)
137
- client_document[:os].delete(:architecture)
138
- elsif client_document[:platform]
139
- client_document.delete(:platform)
140
- else
141
- client_document = nil
156
+ @document ||= begin
157
+ client_document = full_client_document
158
+ while client_document.to_bson.to_s.size > MAX_DOCUMENT_SIZE do
159
+ if client_document[:os][:name] || client_document[:os][:architecture]
160
+ client_document[:os].delete(:name)
161
+ client_document[:os].delete(:architecture)
162
+ elsif client_document[:platform]
163
+ client_document.delete(:platform)
164
+ else
165
+ client_document = nil
166
+ end
167
+ end
168
+ document = Server::Monitor::Connection::ISMASTER
169
+ document = document.merge(compression: @compressors)
170
+ document[:client] = client_document
171
+ document[:saslSupportedMechs] = @request_auth_mech if @request_auth_mech
172
+ if @server_api
173
+ document.update(
174
+ Utils.transform_server_api(@server_api)
175
+ )
142
176
  end
177
+ document
143
178
  end
144
- document = Server::Monitor::Connection::ISMASTER
145
- document = document.merge(compression: @compressors)
146
- document[:client] = client_document
147
- document[:saslSupportedMechs] = @request_auth_mech if @request_auth_mech
148
- document
149
179
  end
150
180
 
151
181
  def driver_doc
@@ -192,12 +222,16 @@ module Mongo
192
222
  ruby_versions = ["Ruby #{RUBY_VERSION}"]
193
223
  platforms = [RUBY_PLATFORM]
194
224
  end
195
- platform = [
225
+ platforms = [
196
226
  @platform,
197
227
  *ruby_versions,
198
228
  *platforms,
199
229
  RbConfig::CONFIG['build'],
200
- ].compact.join(', ')
230
+ ]
231
+ if @purpose
232
+ platforms << @purpose.to_s[0].upcase
233
+ end
234
+ platform = platforms.compact.join(', ')
201
235
  platforms = [platform]
202
236
  if wrapping_libraries
203
237
  wrapping_libraries.each do |library|
@@ -85,6 +85,11 @@ module Mongo
85
85
  #
86
86
  # @option options [ Integer ] :generation Connection pool's generation
87
87
  # for this connection.
88
+ # @option options [ Hash ] :server_api The requested server API version.
89
+ # This hash can have the following items:
90
+ # - *:version* -- string
91
+ # - *:strict* -- boolean
92
+ # - *:deprecation_errors* -- boolean
88
93
  #
89
94
  # @since 2.0.0
90
95
  def initialize(server, options = {})
@@ -105,7 +105,7 @@ module Mongo
105
105
  if same
106
106
  @server.app_metadata
107
107
  else
108
- AppMetadata.new(options)
108
+ AppMetadata.new(options.merge(purpose: @server.app_metadata.purpose))
109
109
  end
110
110
  end
111
111
  end
@@ -124,7 +124,7 @@ module Mongo
124
124
  #
125
125
  # @param [ Array<Message> ] messages A one-element array containing
126
126
  # the message to dispatch.
127
- # @param [ Integer ] operation_id The operation id to link messages.
127
+ # @param [ Operation::Context ] context The operation context.
128
128
  # @param [ Hash ] options
129
129
  #
130
130
  # @option options [ Boolean ] :deserialize_as_bson Whether to deserialize
@@ -134,24 +134,27 @@ module Mongo
134
134
  # @return [ Protocol::Message | nil ] The reply if needed.
135
135
  #
136
136
  # @since 2.0.0
137
- def dispatch(messages, operation_id = nil, client = nil, options = {})
137
+ def dispatch(messages, context, options = {})
138
138
  # The monitoring code does not correctly handle multiple messages,
139
139
  # and the driver internally does not send more than one message at
140
140
  # a time ever. Thus prohibit multiple message use for now.
141
141
  if messages.length != 1
142
142
  raise ArgumentError, 'Can only dispatch one message at a time'
143
143
  end
144
+ if description.unknown?
145
+ raise Error::InternalDriverError, "Cannot dispatch a message on a connection with unknown description: #{description.inspect}"
146
+ end
144
147
  message = messages.first
145
- deliver(message, client, options)
148
+ deliver(message, context, options)
146
149
  end
147
150
 
148
151
  private
149
152
 
150
- def deliver(message, client, options = {})
153
+ def deliver(message, context, options = {})
151
154
  if Lint.enabled? && !@socket
152
155
  raise Error::LintError, "Trying to deliver a message over a disconnected connection (to #{address})"
153
156
  end
154
- buffer = serialize(message, client)
157
+ buffer = serialize(message, context)
155
158
  ensure_connected do |socket|
156
159
  operation_id = Monitoring.next_operation_id
157
160
  command_started(address, operation_id, message.payload,
@@ -178,14 +181,14 @@ module Mongo
178
181
  total_duration = Time.now - start
179
182
  command_completed(result, address, operation_id, message.payload, total_duration)
180
183
  end
181
- if client && result
182
- result = result.maybe_decrypt(client)
184
+ if result && context.decrypt?
185
+ result = result.maybe_decrypt(context)
183
186
  end
184
187
  result
185
188
  end
186
189
  end
187
190
 
188
- def serialize(message, client, buffer = BSON::ByteBuffer.new)
191
+ def serialize(message, context, buffer = BSON::ByteBuffer.new)
189
192
  # Driver specifications only mandate the fixed 16MiB limit for
190
193
  # serialized BSON documents. However, the server returns its
191
194
  # active serialized BSON document size limit in the ismaster response,
@@ -194,7 +197,7 @@ module Mongo
194
197
  # only as the default if the server's ismaster did not contain
195
198
  # maxBsonObjectSize.
196
199
  max_bson_size = max_bson_object_size || DEFAULT_MAX_BSON_OBJECT_SIZE
197
- if client && client.encrypter && client.encrypter.encrypt?
200
+ if context.encrypt?
198
201
  # The client-side encryption specification requires bulk writes to
199
202
  # be split at a reduced maxBsonObjectSize. If this message is a bulk
200
203
  # write and its size exceeds the reduced size limit, the serializer
@@ -204,10 +207,8 @@ module Mongo
204
207
  if message.bulk_write?
205
208
  # Make the new maximum size equal to the specified reduced size
206
209
  # limit plus the 16KiB overhead allowance.
207
- max_bson_size = REDUCED_MAX_BSON_SIZE + MAX_BSON_COMMAND_OVERHEAD
210
+ max_bson_size = REDUCED_MAX_BSON_SIZE
208
211
  end
209
- else
210
- max_bson_size += MAX_BSON_COMMAND_OVERHEAD
211
212
  end
212
213
 
213
214
  # RUBY-2234: It is necessary to check that the message size does not
@@ -232,7 +233,7 @@ module Mongo
232
233
  # TODO: address the fact that this line mutates the buffer.
233
234
  temp_buffer.put_bytes(buffer.get_bytes(buffer.length))
234
235
 
235
- message.serialize(temp_buffer, max_bson_size)
236
+ message.serialize(temp_buffer, max_bson_size, MAX_BSON_COMMAND_OVERHEAD)
236
237
  if temp_buffer.length > max_message_size
237
238
  raise Error::MaxMessageSize.new(max_message_size)
238
239
  end
@@ -243,7 +244,7 @@ module Mongo
243
244
  # layer should be refactored to allow compression on an already-
244
245
  # serialized message.
245
246
  final_message = message.maybe_compress(compressor, options[:zlib_compression_level])
246
- final_message.serialize(buffer, max_bson_size)
247
+ final_message.serialize(buffer, max_bson_size, MAX_BSON_COMMAND_OVERHEAD)
247
248
 
248
249
  buffer
249
250
  end
@@ -105,8 +105,8 @@ module Mongo
105
105
  options.select { |k, v| k.to_s.start_with?('ssl') }
106
106
  else
107
107
  # Due to the way options are propagated from the client, if we
108
- # decide that we don't want to use TLS we need to have the ssl
109
- # options explicitly set to false or the value provided to the
108
+ # decide that we don't want to use TLS we need to have the :ssl
109
+ # option explicitly set to false or the value provided to the
110
110
  # connection might be overwritten by the default inherited from
111
111
  # the client.
112
112
  {ssl: false}
@@ -684,8 +684,6 @@ module Mongo
684
684
  # @return [ Proc ] The Finalizer.
685
685
  def self.finalize(available_connections, pending_connections, populator)
686
686
  proc do
687
- populator.stop!
688
-
689
687
  available_connections.each do |connection|
690
688
  connection.disconnect!(reason: :pool_closed)
691
689
  end
@@ -705,8 +703,12 @@ module Mongo
705
703
  private
706
704
 
707
705
  def create_connection
708
- connection = Connection.new(@server, options.merge(generation: generation,
709
- connection_pool: self))
706
+ connection = Connection.new(@server, options.merge(
707
+ generation: generation,
708
+ connection_pool: self,
709
+ # Do not pass app metadata - this will be retrieved by the connection
710
+ # based on the auth needs.
711
+ ))
710
712
  end
711
713
 
712
714
  # Create a connection, connect it, and add it to the pool.
@@ -766,6 +768,9 @@ module Mongo
766
768
  connection.disconnect!(reason: :error)
767
769
  raise
768
770
  end
771
+ rescue Error::SocketError, Error::SocketTimeoutError => exc
772
+ @server.unknown!(generation: exc.generation, stop_push_monitor: true)
773
+ raise
769
774
  end
770
775
 
771
776
  def check_invariants
@@ -182,13 +182,20 @@ module Mongo
182
182
  # @since 2.5.0
183
183
  LOGICAL_SESSION_TIMEOUT_MINUTES = 'logicalSessionTimeoutMinutes'.freeze
184
184
 
185
+ # Constant for reading connectionId info from config.
186
+ #
187
+ # @api private
188
+ CONNECTION_ID = 'connectionId'.freeze
189
+
185
190
  # Fields to exclude when comparing two descriptions.
186
191
  #
187
192
  # @since 2.0.6
188
193
  EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME,
189
194
  LAST_WRITE,
190
195
  OPERATION_TIME,
191
- Operation::CLUSTER_TIME ].freeze
196
+ Operation::CLUSTER_TIME,
197
+ CONNECTION_ID,
198
+ ].freeze
192
199
 
193
200
  # Instantiate the new server description from the result of the ismaster
194
201
  # command.
@@ -783,6 +790,10 @@ module Mongo
783
790
  # @api private
784
791
  def server_version_gte?(version)
785
792
  required_wv = case version
793
+ when '5.0'
794
+ 12
795
+ when '4.4'
796
+ 9
786
797
  when '4.2'
787
798
  8
788
799
  when '4.0'
@@ -23,14 +23,15 @@ module Mongo
23
23
  # List of features and the wire protocol version they appear in.
24
24
  #
25
25
  # Wire protocol versions map to server releases as follows:
26
- # - 2 => 2.6
27
- # - 3 => 3.0
28
- # - 4 => 3.2
29
- # - 5 => 3.4
30
- # - 6 => 3.6
31
- # - 7 => 4.0
32
- # - 8 => 4.2
33
- # - 9 => 4.4
26
+ # - 2 => 2.6
27
+ # - 3 => 3.0
28
+ # - 4 => 3.2
29
+ # - 5 => 3.4
30
+ # - 6 => 3.6
31
+ # - 7 => 4.0
32
+ # - 8 => 4.2
33
+ # - 9 => 4.4
34
+ # - 12 => 5.0
34
35
  #
35
36
  # @since 2.0.0
36
37
  MAPPINGS = {
@@ -63,6 +63,10 @@ module Mongo
63
63
  # @option options [ Float ] :heartbeat_interval The interval between
64
64
  # regular server checks.
65
65
  # @option options [ Logger ] :logger A custom logger to use.
66
+ # @option options [ Mongo::Server::Monitor::AppMetadata ] :monitor_app_metadata
67
+ # The metadata to use for regular monitoring connection.
68
+ # @option options [ Mongo::Server::Monitor::AppMetadata ] :push_monitor_app_metadata
69
+ # The metadata to use for push monitor's connection.
66
70
  # @option options [ Float ] :socket_timeout The timeout, in seconds, to
67
71
  # execute operations on the monitoring connection.
68
72
  #
@@ -72,6 +76,12 @@ module Mongo
72
76
  unless monitoring.is_a?(Monitoring)
73
77
  raise ArgumentError, "Wrong monitoring type: #{monitoring.inspect}"
74
78
  end
79
+ unless options[:app_metadata]
80
+ raise ArgumentError, 'App metadata is required'
81
+ end
82
+ unless options[:push_monitor_app_metadata]
83
+ raise ArgumentError, 'Push monitor app metadata is required'
84
+ end
75
85
  @server = server
76
86
  @event_listeners = event_listeners
77
87
  @monitoring = monitoring
@@ -254,7 +264,7 @@ module Mongo
254
264
  end
255
265
  rescue => exc
256
266
  msg = "Error running ismaster on #{server.address}"
257
- Utils.warn_monitor_exception(msg, exc,
267
+ Utils.warn_bg_exception(msg, exc,
258
268
  logger: options[:logger],
259
269
  log_prefix: options[:log_prefix],
260
270
  bg_error_backtrace: options[:bg_error_backtrace],
@@ -273,7 +283,15 @@ module Mongo
273
283
  if @connection
274
284
  result = server.round_trip_time_averager.measure do
275
285
  begin
276
- message = @connection.dispatch_bytes(Monitor::Connection::ISMASTER_BYTES)
286
+ ismaster_bytes = if server_api = options[:server_api]
287
+ ismaster_doc = Monitor::Connection::ISMASTER.merge(
288
+ Utils.transform_server_api(server_api)
289
+ )
290
+ Protocol::Query.new(Database::ADMIN, Database::COMMAND, ismaster_doc, limit: -1).serialize.to_s
291
+ else
292
+ Monitor::Connection::ISMASTER_BYTES
293
+ end
294
+ message = @connection.dispatch_bytes(ismaster_bytes)
277
295
  message.documents.first
278
296
  rescue Mongo::Error
279
297
  @connection.disconnect!
@@ -297,6 +315,7 @@ module Mongo
297
315
  monitoring,
298
316
  **Utils.shallow_symbolize_keys(options.merge(
299
317
  socket_timeout: heartbeat_interval + connection.socket_timeout,
318
+ app_metadata: options[:push_monitor_app_metadata],
300
319
  )),
301
320
  )
302
321
  end
@@ -22,7 +22,7 @@ module Mongo
22
22
  #
23
23
  # @api private
24
24
  class AppMetadata < Server::AppMetadata
25
- def initialize(options)
25
+ def initialize(options = {})
26
26
  super
27
27
  if instance_variable_defined?(:@request_auth_mech)
28
28
  remove_instance_variable(:@request_auth_mech)
@@ -44,7 +44,7 @@ module Mongo
44
44
  # The constant for the ismaster command.
45
45
  #
46
46
  # @since 2.2.0
47
- ISMASTER_MESSAGE = Protocol::Query.new(Database::ADMIN, Database::COMMAND, ISMASTER, :limit => -1)
47
+ ISMASTER_MESSAGE = Protocol::Query.new(Database::ADMIN, Database::COMMAND, ISMASTER, limit: -1)
48
48
 
49
49
  # The constant for the ismaster command as an OP_MSG (server versions >= 3.6).
50
50
  #
@@ -83,7 +83,7 @@ module Mongo
83
83
  # @option options [ Array<String> ] :compressors A list of potential
84
84
  # compressors to use, in order of preference. The driver chooses the
85
85
  # first compressor that is also supported by the server. Currently the
86
- # driver only supports 'zlib'.
86
+ # driver only supports 'zstd', 'snappy' and 'zlib'.
87
87
  # @option options [ Float ] :connect_timeout The timeout, in seconds,
88
88
  # to use for network operations. This timeout is used for all
89
89
  # socket operations rather than connect calls only, contrary to
@@ -93,7 +93,9 @@ module Mongo
93
93
  def initialize(address, options = {})
94
94
  @address = address
95
95
  @options = options.dup.freeze
96
- @app_metadata = options[:app_metadata]
96
+ unless @app_metadata = options[:app_metadata]
97
+ raise ArgumentError, 'App metadata is required'
98
+ end
97
99
  @socket = nil
98
100
  @pid = Process.pid
99
101
  @compressor = nil
@@ -122,7 +124,7 @@ module Mongo
122
124
 
123
125
  # Sends a message and returns the result.
124
126
  #
125
- # @param [ Protocol::Message ] The message to send.
127
+ # @param [ Protocol::Message ] message The message to send.
126
128
  #
127
129
  # @return [ Protocol::Message ] The result.
128
130
  def dispatch(message)
@@ -131,7 +133,7 @@ module Mongo
131
133
 
132
134
  # Sends a preserialized message and returns the result.
133
135
  #
134
- # @param [ String ] The serialized message to send.
136
+ # @param [ String ] bytes The serialized message to send.
135
137
  #
136
138
  # @option opts [ Numeric ] :read_socket_timeout The timeout to use for
137
139
  # each read operation.
@@ -221,20 +223,17 @@ module Mongo
221
223
  end
222
224
 
223
225
  def handshake!
224
- payload = if @app_metadata
225
- @app_metadata.ismaster_bytes
226
- else
227
- log_warn("No app metadata provided for handshake with #{address}")
228
- ISMASTER_BYTES
229
- end
226
+ payload = @app_metadata.ismaster_bytes
230
227
  message = dispatch_bytes(payload)
231
- reply = message.documents.first
228
+ result = Operation::Result.new(message)
229
+ result.validate!
230
+ reply = result.documents.first
232
231
  set_compressor!(reply)
233
232
  @server_connection_id = reply['connectionId']
234
233
  reply
235
234
  rescue => exc
236
235
  msg = "Failed to handshake with #{address}"
237
- Utils.warn_monitor_exception(msg, exc,
236
+ Utils.warn_bg_exception(msg, exc,
238
237
  logger: options[:logger],
239
238
  log_prefix: options[:log_prefix],
240
239
  bg_error_backtrace: options[:bg_error_backtrace],