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
@@ -146,7 +146,7 @@ module Mongo
146
146
  # @return [ BSON::ByteBuffer ] buffer containing the serialized message.
147
147
  #
148
148
  # @since 2.5.0
149
- def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil)
149
+ def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil)
150
150
  validate_document_size!(max_bson_size)
151
151
 
152
152
  super
@@ -199,15 +199,16 @@ module Mongo
199
199
  # represents one of the command types whitelisted by libmongocrypt and it
200
200
  # contains data that is required to be encrypted by a local or remote json schema.
201
201
  #
202
- # @param [ Mongo::Client | nil ] client The client used to make the original
203
- # command. This client may have auto-encryption options specified.
202
+ # @param [ Mongo::Server::Connection ] connection The connection on which
203
+ # the operation is performed.
204
+ # @param [ Mongo::Operation::Context ] context The operation context.
204
205
  #
205
206
  # @return [ Mongo::Protocol::Msg ] The encrypted message, or the original
206
207
  # message if encryption was not possible or necessary.
207
- def maybe_encrypt(connection, client)
208
+ def maybe_encrypt(connection, context)
208
209
  # TODO verify compression happens later, i.e. when this method runs
209
210
  # the message is not compressed.
210
- if client && client.encrypter && client.encrypter.encrypt?
211
+ if context.encrypt?
211
212
  if connection.description.max_wire_version < 8
212
213
  raise Error::CryptError.new(
213
214
  "Cannot perform encryption against a MongoDB server older than " +
@@ -219,7 +220,7 @@ module Mongo
219
220
 
220
221
  db_name = @main_document[DATABASE_IDENTIFIER]
221
222
  cmd = merge_sections
222
- enc_cmd = client.encrypter.encrypt(db_name, cmd)
223
+ enc_cmd = context.encrypter.encrypt(db_name, cmd)
223
224
  if cmd.key?('$db') && !enc_cmd.key?('$db')
224
225
  enc_cmd['$db'] = cmd['$db']
225
226
  end
@@ -237,15 +238,14 @@ module Mongo
237
238
  # types whitelisted by libmongocrypt and it contains data that is required
238
239
  # to be encrypted by a local or remote json schema.
239
240
  #
240
- # @param [ Mongo::Client | nil ] client The client used to make the original
241
- # command. This client may have auto-encryption options specified.
241
+ # @param [ Mongo::Operation::Context ] context The operation context.
242
242
  #
243
- # @return [ Mongo::Protocol::Msg ] The decryption message, or the original
243
+ # @return [ Mongo::Protocol::Msg ] The decrypted message, or the original
244
244
  # message if decryption was not possible or necessary.
245
- def maybe_decrypt(client)
246
- if client && client.encrypter
245
+ def maybe_decrypt(context)
246
+ if context.decrypt?
247
247
  cmd = merge_sections
248
- enc_cmd = client.encrypter.decrypt(cmd)
248
+ enc_cmd = context.encrypter.decrypt(cmd)
249
249
  Msg.new(@flags, @options, enc_cmd)
250
250
  else
251
251
  self
@@ -275,6 +275,31 @@ module Mongo
275
275
  num_inserts > 1 || num_updates > 1 || num_deletes > 1
276
276
  end
277
277
 
278
+ def maybe_add_server_api(server_api)
279
+ if @main_document[:getMore]
280
+ # getMore does not allow API parameters.
281
+ return self
282
+ end
283
+
284
+ conflicts = {}
285
+ %i(apiVersion apiStrict apiDeprecationErrors).each do |key|
286
+ if @main_document.key?(key)
287
+ conflicts[key] = @main_document[key]
288
+ end
289
+ if @main_document.key?(key.to_s)
290
+ conflicts[key] = @main_document[key.to_s]
291
+ end
292
+ end
293
+ unless conflicts.empty?
294
+ raise Error::ServerApiConflict, "The Client is configured with :server_api option but the operation provided the following conflicting parameters: #{conflicts.inspect}"
295
+ end
296
+
297
+ main_document = @main_document.merge(
298
+ Utils.transform_server_api(server_api)
299
+ )
300
+ Msg.new(@flags, @options, main_document, *@sequences)
301
+ end
302
+
278
303
  private
279
304
 
280
305
  # Validate that the documents in this message are all smaller than the
@@ -115,12 +115,48 @@ module Mongo
115
115
  compress_if_possible(selector.keys.first, compressor, zlib_compression_level)
116
116
  end
117
117
 
118
+ # Serializes message into bytes that can be sent on the wire.
119
+ #
120
+ # @param [ BSON::ByteBuffer ] buffer where the message should be inserted.
121
+ # @param [ Integer ] max_bson_size The maximum bson object size.
122
+ #
123
+ # @return [ BSON::ByteBuffer ] buffer containing the serialized message.
124
+ def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil)
125
+ validate_document_size!(max_bson_size)
126
+
127
+ super
128
+ end
129
+
118
130
  protected
119
131
 
120
132
  attr_reader :upconverter
121
133
 
122
134
  private
123
135
 
136
+ # Validate that the documents in this message are all smaller than the
137
+ # maxBsonObjectSize. If not, raise an exception.
138
+ def validate_document_size!(max_bson_size)
139
+ max_bson_size ||= Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE
140
+
141
+ documents = if @selector.key?(:documents)
142
+ @selector[:documents]
143
+ elsif @selector.key?(:deletes)
144
+ @selector[:deletes]
145
+ elsif @selector.key?(:updates)
146
+ @selector[:updates]
147
+ else
148
+ []
149
+ end
150
+
151
+ contains_too_large_document = documents.any? do |doc|
152
+ doc.to_bson.length > max_bson_size
153
+ end
154
+
155
+ if contains_too_large_document
156
+ raise Error::MaxBSONSize.new('The document exceeds maximum allowed BSON object size after serialization')
157
+ end
158
+ end
159
+
124
160
  # The operation code required to specify a Query message.
125
161
  # @return [Fixnum] the operation code.
126
162
  #
@@ -0,0 +1,272 @@
1
+ # Copyright (C) 2020 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module QueryCache
17
+ class << self
18
+
19
+ # Set whether the cache is enabled.
20
+ #
21
+ # @example Set if the cache is enabled.
22
+ # QueryCache.enabled = true
23
+ #
24
+ # @param [ true, false ] value The enabled value.
25
+ def enabled=(value)
26
+ Thread.current["[mongo]:query_cache:enabled"] = value
27
+ end
28
+
29
+ # Is the query cache enabled on the current thread?
30
+ #
31
+ # @example Is the query cache enabled?
32
+ # QueryCache.enabled?
33
+ #
34
+ # @return [ true, false ] If the cache is enabled.
35
+ def enabled?
36
+ !!Thread.current["[mongo]:query_cache:enabled"]
37
+ end
38
+
39
+ # Execute the block while using the query cache.
40
+ #
41
+ # @example Execute with the cache.
42
+ # QueryCache.cache { collection.find }
43
+ #
44
+ # @return [ Object ] The result of the block.
45
+ def cache
46
+ enabled = enabled?
47
+ self.enabled = true
48
+ begin
49
+ yield
50
+ ensure
51
+ self.enabled = enabled
52
+ end
53
+ end
54
+
55
+ # Execute the block with the query cache disabled.
56
+ #
57
+ # @example Execute without the cache.
58
+ # QueryCache.uncached { collection.find }
59
+ #
60
+ # @return [ Object ] The result of the block.
61
+ def uncached
62
+ enabled = enabled?
63
+ self.enabled = false
64
+ begin
65
+ yield
66
+ ensure
67
+ self.enabled = enabled
68
+ end
69
+ end
70
+
71
+ # Get the cached queries.
72
+ #
73
+ # @example Get the cached queries from the current thread.
74
+ # QueryCache.cache_table
75
+ #
76
+ # @return [ Hash ] The hash of cached queries.
77
+ private def cache_table
78
+ Thread.current["[mongo]:query_cache"] ||= {}
79
+ end
80
+
81
+ # Clear the query cache.
82
+ #
83
+ # @example Clear the cache.
84
+ # QueryCache.clear
85
+ #
86
+ # @return [ nil ] Always nil.
87
+ def clear
88
+ Thread.current["[mongo]:query_cache"] = nil
89
+ end
90
+
91
+ # Clear the section of the query cache storing cursors with results
92
+ # from this namespace.
93
+ #
94
+ # @param [ String ] namespace The namespace to be cleared, in the format
95
+ # "database.collection".
96
+ #
97
+ # @return [ nil ] Always nil.
98
+ #
99
+ # @api private
100
+ def clear_namespace(namespace)
101
+ cache_table.delete(namespace)
102
+ # The nil key is where cursors are stored that could potentially read from
103
+ # multiple collections. This key should be cleared on every write operation
104
+ # to prevent returning stale data.
105
+ cache_table.delete(nil)
106
+ nil
107
+ end
108
+
109
+ # Store a CachingCursor instance in the query cache associated with the
110
+ # specified query options.
111
+ #
112
+ # @param [ Mongo::CachingCursor ] cursor The CachingCursor instance to store.
113
+ #
114
+ # @option opts [ String | nil ] namespace The namespace of the query,
115
+ # in the format "database_name.collection_name".
116
+ # @option opts [ Array, Hash ] selector The selector passed to the query.
117
+ # For most queries, this will be a Hash, but for aggregations, this
118
+ # will be an Array representing the aggregation pipeline. May not be nil.
119
+ # @option opts [ Integer | nil ] skip The skip value of the query.
120
+ # @option opts [ Hash | nil ] sort The order of the query results
121
+ # (e.g. { name: -1 }).
122
+ # @option opts [ Integer | nil ] limit The limit value of the query.
123
+ # @option opts [ Hash | nil ] projection The projection of the query
124
+ # results (e.g. { name: 1 }).
125
+ # @option opts [ Hash | nil ] collation The collation of the query
126
+ # (e.g. { "locale" => "fr_CA" }).
127
+ # @option opts [ Hash | nil ] read_concern The read concern of the query
128
+ # (e.g. { level: :majority }).
129
+ # @option opts [ Hash | nil ] read_preference The read preference of
130
+ # the query (e.g. { mode: :secondary }).
131
+ # @option opts [ Boolean | nil ] multi_collection Whether the query
132
+ # results could potentially come from multiple collections. When true,
133
+ # these results will be stored under the nil namespace key and cleared
134
+ # on every write command.
135
+ #
136
+ # @return [ true ] Always true.
137
+ #
138
+ # @api private
139
+ def set(cursor, **opts)
140
+ _cache_key = cache_key(**opts)
141
+ _namespace_key = namespace_key(**opts)
142
+
143
+ cache_table[_namespace_key] ||= {}
144
+ cache_table[_namespace_key][_cache_key] = cursor
145
+
146
+ true
147
+ end
148
+
149
+ # For the given query options, retrieve a cached cursor that can be used
150
+ # to obtain the correct query results, if one exists in the cache.
151
+ #
152
+ # @option opts [ String | nil ] namespace The namespace of the query,
153
+ # in the format "database_name.collection_name".
154
+ # @option opts [ Array, Hash ] selector The selector passed to the query.
155
+ # For most queries, this will be a Hash, but for aggregations, this
156
+ # will be an Array representing the aggregation pipeline. May not be nil.
157
+ # @option opts [ Integer | nil ] skip The skip value of the query.
158
+ # @option opts [ Hash | nil ] sort The order of the query results
159
+ # (e.g. { name: -1 }).
160
+ # @option opts [ Integer | nil ] limit The limit value of the query.
161
+ # @option opts [ Hash | nil ] projection The projection of the query
162
+ # results (e.g. { name: 1 }).
163
+ # @option opts [ Hash | nil ] collation The collation of the query
164
+ # (e.g. { "locale" => "fr_CA" }).
165
+ # @option opts [ Hash | nil ] read_concern The read concern of the query
166
+ # (e.g. { level: :majority }).
167
+ # @option opts [ Hash | nil ] read_preference The read preference of
168
+ # the query (e.g. { mode: :secondary }).
169
+ # @option opts [ Boolean | nil ] multi_collection Whether the query
170
+ # results could potentially come from multiple collections. When true,
171
+ # these results will be stored under the nil namespace key and cleared
172
+ # on every write command.
173
+ #
174
+ # @return [ Mongo::CachingCursor | nil ] Returns a CachingCursor if one
175
+ # exists in the query cache, otherwise returns nil.
176
+ #
177
+ # @api private
178
+ def get(**opts)
179
+ limit = opts[:limit]
180
+ _namespace_key = namespace_key(**opts)
181
+ _cache_key = cache_key(**opts)
182
+
183
+ namespace_hash = cache_table[_namespace_key]
184
+ return nil unless namespace_hash
185
+
186
+ caching_cursor = namespace_hash[_cache_key]
187
+ return nil unless caching_cursor
188
+
189
+ caching_cursor_limit = caching_cursor.view.limit
190
+
191
+ # There are two scenarios in which a caching cursor could fulfill the
192
+ # query:
193
+ # 1. The query has a limit, and the stored cursor has no limit or
194
+ # a larger limit.
195
+ # 2. The query has no limit and the stored cursor has no limit.
196
+ #
197
+ # Otherwise, return nil because the stored cursor will not satisfy
198
+ # the query.
199
+ if limit && (caching_cursor_limit.nil? || caching_cursor_limit >= limit)
200
+ caching_cursor
201
+ elsif limit.nil? && caching_cursor_limit.nil?
202
+ caching_cursor
203
+ else
204
+ nil
205
+ end
206
+ end
207
+
208
+ private
209
+
210
+ def cache_key(**opts)
211
+ unless opts[:namespace]
212
+ raise ArgumentError.new("Cannot generate cache key without namespace")
213
+ end
214
+ unless opts[:selector]
215
+ raise ArgumentError.new("Cannot generate cache key without selector")
216
+ end
217
+
218
+ [
219
+ opts[:namespace],
220
+ opts[:selector],
221
+ opts[:skip],
222
+ opts[:sort],
223
+ opts[:projection],
224
+ opts[:collation],
225
+ opts[:read_concern],
226
+ opts[:read_preference]
227
+ ]
228
+ end
229
+
230
+ # If the cached results can come from multiple collections, store this
231
+ # cursor under the nil namespace to be cleared on every write operation.
232
+ # Otherwise, store it under the specified namespace.
233
+ def namespace_key(**opts)
234
+ if opts[:multi_collection]
235
+ nil
236
+ else
237
+ opts[:namespace]
238
+ end
239
+ end
240
+ end
241
+
242
+ # Rack middleware that activates the query cache for each request.
243
+ class Middleware
244
+
245
+ # Instantiate the middleware.
246
+ #
247
+ # @example Create the new middleware.
248
+ # Middleware.new(app)
249
+ #
250
+ # @param [ Object ] app The rack application stack.
251
+ def initialize(app)
252
+ @app = app
253
+ end
254
+
255
+ # Enable query cache and execute the request.
256
+ #
257
+ # @example Execute the request.
258
+ # middleware.call(env)
259
+ #
260
+ # @param [ Object ] env The environment.
261
+ #
262
+ # @return [ Object ] The result of the call.
263
+ def call(env)
264
+ QueryCache.cache do
265
+ @app.call(env)
266
+ end
267
+ ensure
268
+ QueryCache.clear
269
+ end
270
+ end
271
+ end
272
+ end
@@ -59,7 +59,14 @@ module Mongo
59
59
  def read_with_retry_cursor(session, server_selector, view, &block)
60
60
  read_with_retry(session, server_selector) do |server|
61
61
  result = yield server
62
- Cursor.new(view, result, server, session: session)
62
+
63
+ # RUBY-2367: This will be updated to allow the query cache to
64
+ # cache cursors with multi-batch results.
65
+ if QueryCache.enabled? && !view.collection.system_collection?
66
+ CachingCursor.new(view, result, server, session: session)
67
+ else
68
+ Cursor.new(view, result, server, session: session)
69
+ end
63
70
  end
64
71
  end
65
72
 
@@ -470,7 +477,7 @@ module Mongo
470
477
  else
471
478
  "Retry"
472
479
  end
473
- Logger.logger.warn "#{message} due to: #{e.class.name} #{e.message}"
480
+ Logger.logger.warn "#{message} due to: #{e.class.name}: #{e.message}"
474
481
  end
475
482
 
476
483
  # Retry writes on MMAPv1 should raise an actionable error; append actionable
data/lib/mongo/server.rb CHANGED
@@ -71,7 +71,8 @@ module Mongo
71
71
  unless options[:monitoring_io] == false
72
72
  @monitor = Monitor.new(self, event_listeners, monitoring,
73
73
  options.merge(
74
- app_metadata: Monitor::AppMetadata.new(cluster.options),
74
+ app_metadata: cluster.monitor_app_metadata,
75
+ push_monitor_app_metadata: cluster.push_monitor_app_metadata,
75
76
  heartbeat_interval: cluster.heartbeat_interval,
76
77
  ))
77
78
  unless _monitor == false
@@ -172,6 +173,11 @@ module Mongo
172
173
  :cluster_time,
173
174
  :update_cluster_time
174
175
 
176
+ # @api private
177
+ def_delegators :cluster,
178
+ :monitor_app_metadata,
179
+ :push_monitor_app_metadata
180
+
175
181
  def_delegators :features,
176
182
  :check_driver_support!
177
183
 
@@ -272,19 +278,6 @@ module Mongo
272
278
  @connected
273
279
  end
274
280
 
275
- # When the server is flagged for garbage collection, stop the monitor
276
- # thread.
277
- #
278
- # @example Finalize the object.
279
- # Server.finalize(monitor)
280
- #
281
- # @param [ Server::Monitor ] monitor The server monitor.
282
- #
283
- # @since 2.2.0
284
- def self.finalize(monitor)
285
- proc { monitor.stop! }
286
- end
287
-
288
281
  # Start monitoring the server.
289
282
  #
290
283
  # Used internally by the driver to add a server to a cluster
@@ -297,7 +290,6 @@ module Mongo
297
290
  Monitoring::Event::ServerOpening.new(address, cluster.topology)
298
291
  )
299
292
  if options[:monitoring_io] != false
300
- ObjectSpace.define_finalizer(self, self.class.finalize(monitor))
301
293
  monitor.run!
302
294
  end
303
295
  end
@@ -311,7 +303,7 @@ module Mongo
311
303
  #
312
304
  # @since 2.0.0
313
305
  def inspect
314
- "#<Mongo::Server:0x#{object_id} address=#{address.host}:#{address.port}>"
306
+ "#<Mongo::Server:0x#{object_id} address=#{address.host}:#{address.port} #{status}>"
315
307
  end
316
308
 
317
309
  # @return [ String ] String representing server status (e.g. PRIMARY).
@@ -352,6 +344,10 @@ module Mongo
352
344
  status += " replica_set=#{replica_set_name}"
353
345
  end
354
346
 
347
+ unless monitor&.running?
348
+ status += " NO-MONITORING"
349
+ end
350
+
355
351
  if @pool
356
352
  status += " pool=#{@pool.summary}"
357
353
  end