mongo 2.15.0 → 2.16.1

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 (332) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/lib/mongo/bulk_write.rb +2 -2
  5. data/lib/mongo/client.rb +45 -5
  6. data/lib/mongo/cluster/periodic_executor.rb +4 -3
  7. data/lib/mongo/cluster/reapers/cursor_reaper.rb +76 -43
  8. data/lib/mongo/cluster/sdam_flow.rb +9 -3
  9. data/lib/mongo/cluster/topology/base.rb +13 -9
  10. data/lib/mongo/cluster/topology/load_balanced.rb +102 -0
  11. data/lib/mongo/cluster/topology.rb +28 -8
  12. data/lib/mongo/cluster.rb +136 -51
  13. data/lib/mongo/collection/view/aggregation.rb +5 -10
  14. data/lib/mongo/collection/view/builder/aggregation.rb +6 -5
  15. data/lib/mongo/collection/view/builder/map_reduce.rb +12 -49
  16. data/lib/mongo/collection/view/builder.rb +0 -4
  17. data/lib/mongo/collection/view/iterable.rb +58 -24
  18. data/lib/mongo/collection/view/map_reduce.rb +39 -15
  19. data/lib/mongo/collection/view/readable.rb +60 -51
  20. data/lib/mongo/collection/view/writable.rb +178 -175
  21. data/lib/mongo/collection/view.rb +15 -21
  22. data/lib/mongo/collection.rb +13 -13
  23. data/lib/mongo/cursor/kill_spec.rb +38 -0
  24. data/lib/mongo/cursor.rb +72 -31
  25. data/lib/mongo/database/view.rb +1 -1
  26. data/lib/mongo/error/bad_load_balancer_target.rb +26 -0
  27. data/lib/mongo/error/missing_service_id.rb +26 -0
  28. data/lib/mongo/error/no_service_connection_available.rb +49 -0
  29. data/lib/mongo/error/notable.rb +7 -0
  30. data/lib/mongo/error.rb +3 -0
  31. data/lib/mongo/grid/fs_bucket.rb +21 -2
  32. data/lib/mongo/id.rb +7 -5
  33. data/lib/mongo/index/view.rb +22 -41
  34. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +7 -4
  35. data/lib/mongo/monitoring/event/command_failed.rb +1 -1
  36. data/lib/mongo/monitoring/event/command_started.rb +2 -0
  37. data/lib/mongo/monitoring/publishable.rb +2 -2
  38. data/lib/mongo/operation/aggregate/command.rb +8 -0
  39. data/lib/mongo/operation/context.rb +19 -1
  40. data/lib/mongo/operation/count/command.rb +6 -0
  41. data/lib/mongo/operation/count/op_msg.rb +6 -0
  42. data/lib/mongo/operation/create/command.rb +7 -1
  43. data/lib/mongo/operation/create/op_msg.rb +7 -0
  44. data/lib/mongo/operation/create_index/command.rb +17 -1
  45. data/lib/mongo/operation/create_index/op_msg.rb +17 -4
  46. data/lib/mongo/operation/delete/command.rb +6 -3
  47. data/lib/mongo/operation/delete/legacy.rb +9 -2
  48. data/lib/mongo/operation/delete/op_msg.rb +8 -1
  49. data/lib/mongo/operation/distinct/command.rb +6 -0
  50. data/lib/mongo/operation/distinct/op_msg.rb +7 -0
  51. data/lib/mongo/operation/explain/command.rb +13 -1
  52. data/lib/mongo/operation/explain/legacy.rb +12 -5
  53. data/lib/mongo/operation/explain/op_msg.rb +9 -1
  54. data/lib/mongo/operation/find/builder/command.rb +110 -0
  55. data/lib/mongo/{collection/view → operation/find}/builder/flags.rb +10 -14
  56. data/lib/mongo/operation/find/builder/legacy.rb +123 -0
  57. data/lib/mongo/{collection/view → operation/find}/builder/modifiers.rb +31 -25
  58. data/lib/mongo/{cursor → operation/find}/builder.rb +4 -4
  59. data/lib/mongo/operation/find/command.rb +9 -0
  60. data/lib/mongo/operation/find/legacy.rb +10 -1
  61. data/lib/mongo/operation/find/op_msg.rb +12 -0
  62. data/lib/mongo/operation/find.rb +1 -0
  63. data/lib/mongo/operation/get_more/command.rb +1 -0
  64. data/lib/mongo/operation/get_more/command_builder.rb +38 -0
  65. data/lib/mongo/operation/get_more/op_msg.rb +1 -0
  66. data/lib/mongo/operation/get_more.rb +1 -0
  67. data/lib/mongo/operation/kill_cursors/command.rb +8 -0
  68. data/lib/mongo/operation/kill_cursors/command_builder.rb +35 -0
  69. data/lib/mongo/operation/kill_cursors/legacy.rb +2 -1
  70. data/lib/mongo/operation/kill_cursors/op_msg.rb +10 -0
  71. data/lib/mongo/operation/kill_cursors.rb +1 -0
  72. data/lib/mongo/operation/map_reduce/command.rb +8 -0
  73. data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
  74. data/lib/mongo/operation/shared/executable.rb +15 -1
  75. data/lib/mongo/operation/shared/polymorphic_operation.rb +1 -1
  76. data/lib/mongo/operation/shared/read_preference_supported.rb +3 -1
  77. data/lib/mongo/operation/shared/response_handling.rb +1 -0
  78. data/lib/mongo/operation/shared/sessions_supported.rb +12 -12
  79. data/lib/mongo/operation/shared/specifiable.rb +11 -29
  80. data/lib/mongo/operation/shared/validatable.rb +87 -0
  81. data/lib/mongo/operation/shared/write.rb +1 -1
  82. data/lib/mongo/operation/update/command.rb +6 -3
  83. data/lib/mongo/operation/update/legacy.rb +19 -11
  84. data/lib/mongo/operation/update/op_msg.rb +7 -4
  85. data/lib/mongo/operation/write_command/command.rb +51 -0
  86. data/lib/mongo/operation/write_command/op_msg.rb +43 -0
  87. data/lib/mongo/operation/write_command.rb +32 -0
  88. data/lib/mongo/operation.rb +10 -0
  89. data/lib/mongo/protocol/query.rb +35 -18
  90. data/lib/mongo/server/connection.rb +25 -3
  91. data/lib/mongo/server/connection_base.rb +12 -1
  92. data/lib/mongo/server/connection_common.rb +38 -1
  93. data/lib/mongo/server/connection_pool/generation_manager.rb +71 -0
  94. data/lib/mongo/server/connection_pool.rb +100 -27
  95. data/lib/mongo/server/description/features.rb +17 -16
  96. data/lib/mongo/server/description/load_balancer.rb +33 -0
  97. data/lib/mongo/server/description.rb +85 -6
  98. data/lib/mongo/server/monitor/connection.rb +5 -6
  99. data/lib/mongo/server/monitor.rb +2 -1
  100. data/lib/mongo/server/pending_connection.rb +47 -31
  101. data/lib/mongo/server/push_monitor.rb +10 -1
  102. data/lib/mongo/server.rb +73 -26
  103. data/lib/mongo/server_selector/base.rb +5 -1
  104. data/lib/mongo/session/session_pool.rb +11 -0
  105. data/lib/mongo/session.rb +21 -1
  106. data/lib/mongo/socket/ocsp_verifier.rb +6 -37
  107. data/lib/mongo/uri/options_mapper.rb +1 -0
  108. data/lib/mongo/uri/srv_protocol.rb +6 -8
  109. data/lib/mongo/uri.rb +18 -0
  110. data/lib/mongo/utils.rb +0 -7
  111. data/lib/mongo/version.rb +1 -1
  112. data/mongo.gemspec +1 -1
  113. data/spec/integration/auth_spec.rb +31 -1
  114. data/spec/integration/awaited_ismaster_spec.rb +1 -1
  115. data/spec/integration/bulk_write_spec.rb +1 -1
  116. data/spec/integration/change_stream_spec.rb +3 -3
  117. data/spec/integration/client_construction_spec.rb +54 -0
  118. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +1 -1
  119. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +1 -1
  120. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +1 -1
  121. data/spec/integration/client_side_encryption/data_key_spec.rb +1 -1
  122. data/spec/integration/client_spec.rb +2 -0
  123. data/spec/integration/command_monitoring_spec.rb +1 -1
  124. data/spec/integration/command_spec.rb +1 -1
  125. data/spec/integration/connection_spec.rb +52 -35
  126. data/spec/integration/crud_spec.rb +174 -1
  127. data/spec/integration/cursor_pinning_spec.rb +121 -0
  128. data/spec/integration/cursor_reaping_spec.rb +8 -4
  129. data/spec/integration/fork_reconnect_spec.rb +1 -5
  130. data/spec/integration/get_more_spec.rb +1 -1
  131. data/spec/integration/heartbeat_events_spec.rb +1 -1
  132. data/spec/integration/map_reduce_spec.rb +77 -0
  133. data/spec/integration/query_cache_spec.rb +47 -2
  134. data/spec/integration/query_cache_transactions_spec.rb +1 -1
  135. data/spec/integration/read_concern_spec.rb +1 -1
  136. data/spec/integration/read_preference_spec.rb +1 -1
  137. data/spec/integration/reconnect_spec.rb +30 -12
  138. data/spec/integration/retryable_errors_spec.rb +1 -1
  139. data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +1 -1
  140. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -1
  141. data/spec/integration/sdam_error_handling_spec.rb +5 -3
  142. data/spec/integration/sdam_events_spec.rb +35 -19
  143. data/spec/integration/sdam_prose_spec.rb +1 -1
  144. data/spec/integration/server_monitor_spec.rb +1 -0
  145. data/spec/integration/server_selector_spec.rb +22 -5
  146. data/spec/integration/server_spec.rb +2 -0
  147. data/spec/integration/srv_monitoring_spec.rb +1 -1
  148. data/spec/integration/step_down_spec.rb +1 -1
  149. data/spec/integration/transaction_pinning_spec.rb +120 -0
  150. data/spec/integration/versioned_api_examples_spec.rb +45 -0
  151. data/spec/integration/x509_auth_spec.rb +1 -1
  152. data/spec/lite_spec_helper.rb +1 -2
  153. data/spec/mongo/address/unix_spec.rb +1 -0
  154. data/spec/mongo/auth/cr_spec.rb +2 -3
  155. data/spec/mongo/auth/ldap_spec.rb +2 -3
  156. data/spec/mongo/auth/scram_spec.rb +2 -3
  157. data/spec/mongo/auth/user/view_spec.rb +1 -1
  158. data/spec/mongo/auth/x509_spec.rb +2 -3
  159. data/spec/mongo/bulk_write_spec.rb +3 -3
  160. data/spec/mongo/client_construction_spec.rb +259 -28
  161. data/spec/mongo/client_spec.rb +6 -4
  162. data/spec/mongo/cluster/cursor_reaper_spec.rb +36 -21
  163. data/spec/mongo/cluster/periodic_executor_spec.rb +3 -1
  164. data/spec/mongo/cluster_spec.rb +44 -3
  165. data/spec/mongo/collection/view/aggregation_spec.rb +1 -1
  166. data/spec/mongo/collection/view/builder/find_command_spec.rb +4 -0
  167. data/spec/mongo/collection/view/builder/op_query_spec.rb +4 -0
  168. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  169. data/spec/mongo/collection_crud_spec.rb +7 -2
  170. data/spec/mongo/collection_ddl_spec.rb +1 -1
  171. data/spec/mongo/collection_spec.rb +1 -1
  172. data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -0
  173. data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -0
  174. data/spec/mongo/cursor_spec.rb +15 -5
  175. data/spec/mongo/database_spec.rb +15 -15
  176. data/spec/mongo/error/operation_failure_heavy_spec.rb +1 -1
  177. data/spec/mongo/grid/fs_bucket_spec.rb +18 -12
  178. data/spec/mongo/grid/stream/write_spec.rb +3 -9
  179. data/spec/mongo/grid/stream_spec.rb +1 -1
  180. data/spec/mongo/index/view_spec.rb +2 -2
  181. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
  182. data/spec/mongo/{collection/view → operation/find}/builder/flags_spec.rb +2 -2
  183. data/spec/mongo/{collection/view → operation/find}/builder/modifiers_spec.rb +2 -2
  184. data/spec/mongo/operation/find/legacy_spec.rb +1 -0
  185. data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
  186. data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
  187. data/spec/mongo/operation/kill_cursors_spec.rb +4 -1
  188. data/spec/mongo/operation/read_preference_legacy_spec.rb +4 -0
  189. data/spec/mongo/operation/read_preference_op_msg_spec.rb +2 -0
  190. data/spec/mongo/operation/update/bulk_spec.rb +1 -1
  191. data/spec/mongo/operation/update/op_msg_spec.rb +1 -1
  192. data/spec/mongo/query_cache_spec.rb +6 -2
  193. data/spec/mongo/server/connection_common_spec.rb +62 -11
  194. data/spec/mongo/server/connection_pool_spec.rb +73 -7
  195. data/spec/mongo/server/connection_spec.rb +138 -43
  196. data/spec/mongo/server/description_spec.rb +1 -1
  197. data/spec/mongo/server/monitor/connection_spec.rb +22 -0
  198. data/spec/mongo/server/monitor_spec.rb +4 -3
  199. data/spec/mongo/server/push_monitor_spec.rb +101 -0
  200. data/spec/mongo/session/session_pool_spec.rb +42 -10
  201. data/spec/mongo/session_transaction_spec.rb +15 -30
  202. data/spec/mongo/socket/unix_spec.rb +1 -0
  203. data/spec/mongo/uri_option_parsing_spec.rb +38 -5
  204. data/spec/runners/change_streams/test.rb +1 -1
  205. data/spec/runners/cmap.rb +1 -1
  206. data/spec/runners/connection_string.rb +7 -3
  207. data/spec/runners/crud/operation.rb +5 -3
  208. data/spec/runners/crud/requirement.rb +1 -0
  209. data/spec/runners/crud.rb +1 -1
  210. data/spec/runners/sdam.rb +2 -1
  211. data/spec/runners/transactions/test.rb +2 -2
  212. data/spec/runners/unified/assertions.rb +2 -3
  213. data/spec/runners/unified/event_subscriber.rb +2 -2
  214. data/spec/runners/unified/support_operations.rb +10 -2
  215. data/spec/runners/unified/test.rb +3 -0
  216. data/spec/runners/unified.rb +1 -1
  217. data/spec/shared/lib/mrss/cluster_config.rb +6 -1
  218. data/spec/shared/lib/mrss/constraints.rb +11 -5
  219. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  220. data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
  221. data/spec/shared/share/Dockerfile.erb +5 -4
  222. data/spec/shared/shlib/server.sh +70 -20
  223. data/spec/spec_tests/change_streams_spec.rb +1 -1
  224. data/spec/spec_tests/cmap_spec.rb +4 -1
  225. data/spec/spec_tests/command_monitoring_spec.rb +2 -2
  226. data/spec/spec_tests/data/command_monitoring/find.yml +9 -9
  227. data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
  228. data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
  229. data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
  230. data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
  231. data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
  232. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
  233. data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
  234. data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
  235. data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
  236. data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
  237. data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
  238. data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
  239. data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
  240. data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
  241. data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
  242. data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
  243. data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
  244. data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
  245. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +1 -1
  246. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
  247. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +1 -1
  248. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
  249. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +1 -1
  250. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
  251. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +3 -1
  252. data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
  253. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +2 -0
  254. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +2 -0
  255. data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +3 -1
  256. data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +3 -1
  257. data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +2 -0
  258. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +2 -0
  259. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +2 -0
  260. data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
  261. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +13 -0
  262. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
  263. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
  264. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +10 -0
  265. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
  266. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
  267. data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
  268. data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
  269. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
  270. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
  271. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
  272. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
  273. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
  274. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
  275. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
  276. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
  277. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
  278. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
  279. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
  280. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
  281. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
  282. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
  283. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
  284. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
  285. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
  286. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
  287. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
  288. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
  289. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
  290. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
  291. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
  292. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
  293. data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
  294. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +2 -0
  295. data/spec/spec_tests/data/transactions/retryable-abort.yml +2 -0
  296. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +2 -0
  297. data/spec/spec_tests/data/transactions/retryable-commit.yml +2 -0
  298. data/spec/spec_tests/data/transactions/retryable-writes.yml +2 -0
  299. data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
  300. data/spec/spec_tests/load_balancers_spec.rb +15 -0
  301. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  302. data/spec/spec_tests/retryable_writes_spec.rb +1 -1
  303. data/spec/spec_tests/sdam_integration_spec.rb +1 -1
  304. data/spec/spec_tests/sdam_monitoring_spec.rb +10 -5
  305. data/spec/spec_tests/sdam_spec.rb +1 -1
  306. data/spec/spec_tests/seed_list_discovery_spec.rb +118 -0
  307. data/spec/spec_tests/uri_options_spec.rb +4 -4
  308. data/spec/stress/fork_reconnect_stress_spec.rb +1 -5
  309. data/spec/stress/push_monitor_close_spec.rb +44 -0
  310. data/spec/support/certificates/atlas-ocsp-ca.crt +82 -90
  311. data/spec/support/certificates/atlas-ocsp.crt +127 -122
  312. data/spec/support/common_shortcuts.rb +2 -3
  313. data/spec/support/matchers.rb +13 -0
  314. data/spec/support/shared/auth_context.rb +16 -0
  315. data/spec/support/shared/session.rb +2 -2
  316. data/spec/support/spec_config.rb +10 -11
  317. data/spec/support/using_hash.rb +31 -0
  318. data/spec/support/utils.rb +1 -1
  319. data.tar.gz.sig +0 -0
  320. metadata +1077 -1029
  321. metadata.gz.sig +0 -0
  322. data/lib/mongo/collection/view/builder/find_command.rb +0 -173
  323. data/lib/mongo/collection/view/builder/op_query.rb +0 -94
  324. data/lib/mongo/cursor/builder/get_more_command.rb +0 -80
  325. data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -111
  326. data/lib/mongo/cursor/builder/op_get_more.rb +0 -64
  327. data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -106
  328. data/lib/mongo/server/context.rb +0 -72
  329. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -66
  330. data/spec/runners/unified/using_hash.rb +0 -34
  331. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -79
  332. data/spec/support/event_subscriber.rb +0 -221
@@ -31,15 +31,18 @@ module Mongo
31
31
  # @since 2.9.0
32
32
  attr_reader :address
33
33
 
34
+ # @return [ nil | Object ] The service id, if any.
35
+ attr_reader :service_id
36
+
34
37
  # Create the event.
35
38
  #
36
- # @example Create the event.
37
- # PoolCleared.new(address)
39
+ # @param [ Address ] address
40
+ # @param [ Object ] service_id The service id, if any.
38
41
  #
39
- # @since 2.9.0
40
42
  # @api private
41
- def initialize(address)
43
+ def initialize(address, service_id: nil)
42
44
  @address = address
45
+ @service_id = service_id
43
46
  end
44
47
 
45
48
  # Returns a concise yet useful summary of the event.
@@ -88,11 +88,11 @@ module Mongo
88
88
  @address = address
89
89
  @request_id = request_id
90
90
  @operation_id = operation_id
91
+ @service_id = service_id
91
92
  @message = message
92
93
  @started_event = started_event
93
94
  @failure = redacted(command_name, failure)
94
95
  @duration = duration
95
- @service_id = service_id
96
96
  end
97
97
 
98
98
  # Returns a concise yet useful summary of the event.
@@ -78,6 +78,7 @@ module Mongo
78
78
  # @param [ Integer ] request_id The request id.
79
79
  # @param [ Integer ] operation_id The operation id.
80
80
  # @param [ BSON::Document ] command The command arguments.
81
+ # @param [ Object ] service_id The service id, if any.
81
82
  #
82
83
  # @since 2.1.0
83
84
  # @api private
@@ -140,6 +141,7 @@ module Mongo
140
141
  # @param [ Server::Address ] address The server address.
141
142
  # @param [ Integer ] operation_id The operation id.
142
143
  # @param [ Hash ] payload The message payload.
144
+ # @param [ Object ] service_id The service id, if any.
143
145
  #
144
146
  # @return [ CommandStarted ] The event.
145
147
  #
@@ -35,7 +35,6 @@ module Mongo
35
35
  def publish_sdam_event(topic, event)
36
36
  return unless monitoring?
37
37
 
38
- #log_debug("EVENT: #{event.summary}")
39
38
  monitoring.succeeded(topic, event)
40
39
  end
41
40
 
@@ -49,12 +48,13 @@ module Mongo
49
48
 
50
49
  def command_started(address, operation_id, payload,
51
50
  socket_object_id: nil, connection_id: nil, connection_generation: nil,
52
- server_connection_id: nil
51
+ server_connection_id: nil, service_id: nil
53
52
  )
54
53
  event = Event::CommandStarted.generate(address, operation_id, payload,
55
54
  socket_object_id: socket_object_id, connection_id: connection_id,
56
55
  connection_generation: connection_generation,
57
56
  server_connection_id: server_connection_id,
57
+ service_id: service_id,
58
58
  )
59
59
  monitoring.started(
60
60
  Monitoring::COMMAND,
@@ -34,6 +34,14 @@ module Mongo
34
34
 
35
35
  private
36
36
 
37
+ def selector(connection)
38
+ super.tap do |selector|
39
+ if selector[:collation] && !connection.features.collation_enabled?
40
+ raise Error::UnsupportedCollation
41
+ end
42
+ end
43
+ end
44
+
37
45
  def write_concern_supported?(connection)
38
46
  connection.features.collation_enabled?
39
47
  end
@@ -24,9 +24,18 @@ module Mongo
24
24
  # in a single container, and provides facade methods for the contained
25
25
  # objects.
26
26
  #
27
+ # The context contains parameters for operations, and as such while an
28
+ # operation is being prepared nothing in the context should change.
29
+ # When the result of the operation is being processed, the data
30
+ # returned by the context may change (for example, because a transaction
31
+ # is aborted), but at that point the operation should no longer read
32
+ # anything from the context. Because context data may change during
33
+ # operation execution, context objects should not be reused for multiple
34
+ # operations.
35
+ #
27
36
  # @api private
28
37
  class Context
29
- def initialize(client: nil, session: nil, options: nil)
38
+ def initialize(client: nil, session: nil, service_id: nil, options: nil)
30
39
  if options
31
40
  if client
32
41
  raise ArgumentError, 'Client and options cannot both be specified'
@@ -37,8 +46,13 @@ module Mongo
37
46
  end
38
47
  end
39
48
 
49
+ if service_id && session&.pinned_service_id
50
+ raise ArgumentError, 'Trying to pin context to a service when the session is already pinned to a service'
51
+ end
52
+
40
53
  @client = client
41
54
  @session = session
55
+ @service_id = service_id
42
56
  @options = options
43
57
  end
44
58
 
@@ -46,6 +60,10 @@ module Mongo
46
60
  attr_reader :session
47
61
  attr_reader :options
48
62
 
63
+ def service_id
64
+ @service_id || session&.pinned_service_id
65
+ end
66
+
49
67
  def in_transaction?
50
68
  session&.in_transaction? || false
51
69
  end
@@ -32,6 +32,12 @@ module Mongo
32
32
 
33
33
  private
34
34
 
35
+ def selector(connection)
36
+ selector = spec[:selector]
37
+ selector = apply_collation(selector, connection, spec[:collation])
38
+ selector
39
+ end
40
+
35
41
  def message(connection)
36
42
  Protocol::Query.new(db_name, Database::COMMAND, command(connection), options(connection))
37
43
  end
@@ -26,6 +26,12 @@ module Mongo
26
26
  # @since 2.5.2
27
27
  class OpMsg < OpMsgBase
28
28
  include CausalConsistencySupported
29
+
30
+ private
31
+
32
+ def selector(connection)
33
+ spec[:selector].merge(collation: spec[:collation]).compact
34
+ end
29
35
  end
30
36
  end
31
37
  end
@@ -19,7 +19,7 @@ module Mongo
19
19
  module Operation
20
20
  class Create
21
21
 
22
- # A MongoDB count operation sent as a command message.
22
+ # A MongoDB create collection operation sent as a command message.
23
23
  #
24
24
  # @api private
25
25
  #
@@ -32,6 +32,12 @@ module Mongo
32
32
 
33
33
  private
34
34
 
35
+ def selector(connection)
36
+ selector = spec[:selector]
37
+ selector = apply_collation(selector, connection, spec[:collation])
38
+ selector
39
+ end
40
+
35
41
  def message(connection)
36
42
  Protocol::Query.new(db_name, Database::COMMAND, command(connection), options(connection))
37
43
  end
@@ -26,6 +26,13 @@ module Mongo
26
26
  # @since 2.5.2
27
27
  class OpMsg < OpMsgBase
28
28
  include ExecutableTransactionLabel
29
+
30
+ private
31
+
32
+ def selector(connection)
33
+ # Collation is always supported on 3.6+ servers that would use OP_MSG.
34
+ spec[:selector].merge(collation: spec[:collation]).compact
35
+ end
29
36
  end
30
37
  end
31
38
  end
@@ -33,7 +33,23 @@ module Mongo
33
33
  private
34
34
 
35
35
  def selector(connection)
36
- { :createIndexes => coll_name, :indexes => indexes }
36
+ indexes.each do |index|
37
+ if index[:collation] && !connection.features.collation_enabled?
38
+ raise Error::UnsupportedCollation
39
+ end
40
+ end
41
+
42
+ {
43
+ createIndexes: coll_name,
44
+ indexes: indexes,
45
+ }.tap do |selector|
46
+ if commit_quorum = spec[:commit_quorum]
47
+ unless connection.features.commit_quorum_enabled?
48
+ raise Error::UnsupportedOption.commit_quorum_error
49
+ end
50
+ selector[:commitQuorum] = commit_quorum
51
+ end
52
+ end
37
53
  end
38
54
 
39
55
  def message(connection)
@@ -30,10 +30,23 @@ module Mongo
30
30
  private
31
31
 
32
32
  def selector(connection)
33
- selector = { :createIndexes => coll_name, :indexes => indexes }
34
- selector[:commitQuorum] = commit_quorum if commit_quorum
35
-
36
- selector
33
+ {
34
+ createIndexes: coll_name,
35
+ indexes: indexes,
36
+ }.tap do |selector|
37
+ if commit_quorum = spec[:commit_quorum]
38
+ # While server versions 3.4 and newer generally perform option
39
+ # validation, there was a bug on server versions 4.2.0 - 4.2.5 where
40
+ # the server would accept the commitQuorum option and use it internally
41
+ # (see SERVER-47193). As a result, the drivers specifications require
42
+ # drivers to perform validation and raise an error when the commitQuorum
43
+ # option is passed to servers that don't support it.
44
+ unless connection.features.commit_quorum_enabled?
45
+ raise Error::UnsupportedOption.commit_quorum_error
46
+ end
47
+ selector[:commitQuorum] = commit_quorum
48
+ end
49
+ end
37
50
  end
38
51
  end
39
52
  end
@@ -31,13 +31,16 @@ module Mongo
31
31
  include WriteConcernSupported
32
32
  include ExecutableNoValidate
33
33
  include PolymorphicResult
34
+ include Validatable
34
35
 
35
36
  private
36
37
 
37
38
  def selector(connection)
38
- { delete: coll_name,
39
- deletes: send(IDENTIFIER),
40
- ordered: ordered? }
39
+ {
40
+ delete: coll_name,
41
+ deletes: validate_updates(connection, send(IDENTIFIER)),
42
+ ordered: ordered?,
43
+ }
41
44
  end
42
45
 
43
46
  def message(connection)
@@ -28,14 +28,21 @@ module Mongo
28
28
  include Specifiable
29
29
  include Executable
30
30
  include PolymorphicResult
31
+ include Validatable
31
32
 
32
33
  private
33
34
 
34
- def selector
35
- send(IDENTIFIER).first
35
+ def selector(connection)
36
+ # This returns the first delete.
37
+ # The driver only puts one delete into the list normally, so this
38
+ # doesn't discard operations.
39
+ send(IDENTIFIER).first.tap do |selector|
40
+ validate_find_options(connection, selector)
41
+ end
36
42
  end
37
43
 
38
44
  def message(connection)
45
+ selector = selector(connection)
39
46
  opts = (selector[Operation::LIMIT] || 0) <= 0 ? {} : { :flags => [ :single_remove ] }
40
47
  Protocol::Delete.new(db_name, coll_name, selector[Operation::Q], opts)
41
48
  end
@@ -29,13 +29,20 @@ module Mongo
29
29
  include ExecutableNoValidate
30
30
  include ExecutableTransactionLabel
31
31
  include PolymorphicResult
32
+ include Validatable
32
33
 
33
34
  private
34
35
 
35
36
  def selector(connection)
36
37
  { delete: coll_name,
37
38
  Protocol::Msg::DATABASE_IDENTIFIER => db_name,
38
- ordered: ordered? }
39
+ ordered: ordered?,
40
+ }.tap do |selector|
41
+ if hint = spec[:hint]
42
+ validate_hint_on_update(connection, selector)
43
+ selector[:hint] = hint
44
+ end
45
+ end
39
46
  end
40
47
 
41
48
  def message(connection)
@@ -32,6 +32,12 @@ module Mongo
32
32
 
33
33
  private
34
34
 
35
+ def selector(connection)
36
+ selector = spec[:selector]
37
+ selector = apply_collation(selector, connection, spec[:collation])
38
+ selector
39
+ end
40
+
35
41
  def message(connection)
36
42
  Protocol::Query.new(db_name, Database::COMMAND, command(connection), options(connection))
37
43
  end
@@ -27,6 +27,13 @@ module Mongo
27
27
  class OpMsg < OpMsgBase
28
28
  include CausalConsistencySupported
29
29
  include ExecutableTransactionLabel
30
+
31
+ private
32
+
33
+ def selector(connection)
34
+ # Collation is always supported on 3.6+ servers that would use OP_MSG.
35
+ spec[:selector].merge(collation: spec[:collation]).compact
36
+ end
30
37
  end
31
38
  end
32
39
  end
@@ -34,7 +34,19 @@ module Mongo
34
34
  private
35
35
 
36
36
  def selector(connection)
37
- super.merge(spec[:explain])
37
+ # The mappings are BSON::Documents and as such store keys as
38
+ # strings, the spec here has symbol keys.
39
+ spec = BSON::Document.new(self.spec)
40
+
41
+ if spec[:collation] && !connection.features.collation_enabled?
42
+ raise Error::UnsupportedCollation
43
+ end
44
+
45
+ {
46
+ explain: {
47
+ find: coll_name,
48
+ }.update(Find::Builder::Command.selector(spec, connection)),
49
+ }.update(spec[:explain] || {})
38
50
  end
39
51
 
40
52
  def message(connection)
@@ -32,12 +32,19 @@ module Mongo
32
32
 
33
33
  private
34
34
 
35
- def selector(connection)
36
- super.merge(spec[:explain])
37
- end
38
-
39
35
  def message(connection)
40
- Protocol::Query.new(db_name, coll_name, command(connection), options(connection))
36
+ if spec[:collation] && !connection.features.collation_enabled?
37
+ raise Error::UnsupportedCollation
38
+ end
39
+
40
+ Protocol::Query.new(
41
+ db_name,
42
+ coll_name,
43
+ Find::Builder::Legacy.selector(spec, connection),
44
+ options(connection).update(
45
+ Find::Builder::Legacy.query_options(spec, connection),
46
+ ),
47
+ )
41
48
  end
42
49
  end
43
50
  end
@@ -32,7 +32,15 @@ module Mongo
32
32
  private
33
33
 
34
34
  def selector(connection)
35
- super.merge(spec[:explain])
35
+ # The mappings are BSON::Documents and as such store keys as
36
+ # strings, the spec here has symbol keys.
37
+ spec = BSON::Document.new(self.spec)
38
+ {
39
+ explain: {
40
+ find: coll_name,
41
+ }.update(Find::Builder::Command.selector(spec, connection)),
42
+ Protocol::Msg::DATABASE_IDENTIFIER => db_name,
43
+ }.update(spec[:explain] || {})
36
44
  end
37
45
  end
38
46
  end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ # Copyright (C) 2015-2020 MongoDB Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ module Mongo
19
+ module Operation
20
+ class Find
21
+ module Builder
22
+
23
+ # Builds a find command specification from options.
24
+ #
25
+ # @api private
26
+ module Command
27
+
28
+ # The mappings from ruby options to the find command.
29
+ OPTION_MAPPINGS = BSON::Document.new(
30
+ allow_disk_use: 'allowDiskUse',
31
+ allow_partial_results: 'allowPartialResults',
32
+ await_data: 'awaitData',
33
+ batch_size: 'batchSize',
34
+ collation: 'collation',
35
+ comment: 'comment',
36
+ filter: 'filter',
37
+ hint: 'hint',
38
+ limit: 'limit',
39
+ max_scan: 'maxScan',
40
+ max_time_ms: 'maxTimeMS',
41
+ max_value: 'max',
42
+ min_value: 'min',
43
+ no_cursor_timeout: 'noCursorTimeout',
44
+ oplog_replay: 'oplogReplay',
45
+ projection: 'projection',
46
+ read_concern: 'readConcern',
47
+ return_key: 'returnKey',
48
+ show_disk_loc: 'showRecordId',
49
+ single_batch: 'singleBatch',
50
+ skip: 'skip',
51
+ snapshot: 'snapshot',
52
+ sort: 'sort',
53
+ tailable: 'tailable',
54
+ tailable_cursor: 'tailable',
55
+ ).freeze
56
+
57
+ module_function def selector(spec, connection)
58
+ if spec[:collation] && !connection.features.collation_enabled?
59
+ raise Error::UnsupportedCollation
60
+ end
61
+
62
+ BSON::Document.new.tap do |selector|
63
+ OPTION_MAPPINGS.each do |k, server_k|
64
+ unless (value = spec[k]).nil?
65
+ selector[server_k] = value
66
+ end
67
+ end
68
+
69
+ if rc = selector[:readConcern]
70
+ selector[:readConcern] = Options::Mapper.transform_values_to_strings(rc)
71
+ end
72
+
73
+ convert_limit_and_batch_size!(selector)
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # Converts negative limit and batchSize parameters in the
80
+ # find command to positive ones. Removes the parameters if their
81
+ # values are zero.
82
+ #
83
+ # This is only used for find commmand, not for OP_QUERY path.
84
+ #
85
+ # The +command+ parameter is mutated by this method.
86
+ module_function def convert_limit_and_batch_size!(command)
87
+ if command[:limit] && command[:limit] < 0 &&
88
+ command[:batchSize] && command[:batchSize] < 0
89
+ then
90
+ command[:limit] = command[:limit].abs
91
+ command[:batchSize] = command[:limit].abs
92
+ command[:singleBatch] = true
93
+ else
94
+ [:limit, :batchSize].each do |opt|
95
+ if command[opt]
96
+ if command[opt] < 0
97
+ command[opt] = command[opt].abs
98
+ command[:singleBatch] = true
99
+ elsif command[opt] == 0
100
+ command.delete(opt)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -16,19 +16,17 @@
16
16
  # limitations under the License.
17
17
 
18
18
  module Mongo
19
- class Collection
20
- class View
19
+ module Operation
20
+ class Find
21
21
  module Builder
22
22
 
23
- # Provides behavior for mapping flags.
23
+ # Provides behavior for converting Ruby options to wire protocol flags
24
+ # when sending find and related commands (e.g. explain).
24
25
  #
25
- # @since 2.2.0
26
+ # @api private
26
27
  module Flags
27
- extend self
28
28
 
29
29
  # Options to cursor flags mapping.
30
- #
31
- # @since 2.2.0
32
30
  MAPPINGS = {
33
31
  :allow_partial_results => [ :partial ],
34
32
  :oplog_replay => [ :oplog_replay ],
@@ -36,20 +34,18 @@ module Mongo
36
34
  :tailable => [ :tailable_cursor ],
37
35
  :tailable_await => [ :await_data, :tailable_cursor],
38
36
  :await_data => [ :await_data ],
39
- :exhaust => [ :exhaust ]
37
+ :exhaust => [ :exhaust ],
40
38
  }.freeze
41
39
 
42
- # Maps an array of flags from the provided options.
40
+ # Converts Ruby find options to an array of flags.
43
41
  #
44
- # @example Map the flags.
45
- # Flags.map_flags(options)
42
+ # Any keys in the input hash that are not options that map to flags
43
+ # are ignored.
46
44
  #
47
45
  # @param [ Hash, BSON::Document ] options The options.
48
46
  #
49
47
  # @return [ Array<Symbol> ] The flags.
50
- #
51
- # @since 2.2.0
52
- def map_flags(options)
48
+ module_function def map_flags(options)
53
49
  MAPPINGS.each.reduce(options[:flags] || []) do |flags, (key, value)|
54
50
  cursor_type = options[:cursor_type]
55
51
  if options[key] || (cursor_type && cursor_type == key)