mongo 2.12.1 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (856) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +8 -36
  5. data/LICENSE +1 -1
  6. data/README.md +54 -54
  7. data/Rakefile +16 -10
  8. data/lib/mongo.rb +8 -3
  9. data/lib/mongo/active_support.rb +1 -1
  10. data/lib/mongo/address.rb +78 -37
  11. data/lib/mongo/address/ipv4.rb +32 -5
  12. data/lib/mongo/address/ipv6.rb +32 -5
  13. data/lib/mongo/address/unix.rb +3 -3
  14. data/lib/mongo/address/validator.rb +1 -1
  15. data/lib/mongo/auth.rb +36 -13
  16. data/lib/mongo/auth/aws.rb +37 -0
  17. data/lib/mongo/auth/aws/conversation.rb +128 -0
  18. data/lib/mongo/auth/aws/credentials_retriever.rb +219 -0
  19. data/lib/mongo/auth/aws/request.rb +283 -0
  20. data/lib/mongo/auth/base.rb +129 -0
  21. data/lib/mongo/auth/conversation_base.rb +52 -0
  22. data/lib/mongo/auth/cr.rb +9 -36
  23. data/lib/mongo/auth/cr/conversation.rb +24 -69
  24. data/lib/mongo/auth/credential_cache.rb +1 -1
  25. data/lib/mongo/auth/gssapi.rb +38 -0
  26. data/lib/mongo/auth/gssapi/conversation.rb +108 -0
  27. data/lib/mongo/auth/ldap.rb +9 -34
  28. data/lib/mongo/auth/ldap/conversation.rb +3 -43
  29. data/lib/mongo/auth/roles.rb +1 -1
  30. data/lib/mongo/auth/sasl_conversation_base.rb +111 -0
  31. data/lib/mongo/auth/scram.rb +39 -51
  32. data/lib/mongo/auth/scram/conversation.rb +12 -506
  33. data/lib/mongo/auth/scram256.rb +31 -0
  34. data/lib/mongo/auth/scram256/conversation.rb +63 -0
  35. data/lib/mongo/auth/scram_conversation_base.rb +402 -0
  36. data/lib/mongo/auth/stringprep.rb +5 -4
  37. data/lib/mongo/auth/stringprep/profiles/sasl.rb +2 -1
  38. data/lib/mongo/auth/stringprep/tables.rb +2 -1
  39. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +1 -0
  40. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1 -0
  41. data/lib/mongo/auth/user.rb +2 -2
  42. data/lib/mongo/auth/user/view.rb +1 -1
  43. data/lib/mongo/auth/x509.rb +14 -32
  44. data/lib/mongo/auth/x509/conversation.rb +15 -42
  45. data/lib/mongo/background_thread.rb +11 -2
  46. data/lib/mongo/bson.rb +1 -1
  47. data/lib/mongo/bulk_write.rb +62 -26
  48. data/lib/mongo/bulk_write/combineable.rb +20 -8
  49. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  50. data/lib/mongo/bulk_write/result.rb +1 -1
  51. data/lib/mongo/bulk_write/result_combiner.rb +1 -1
  52. data/lib/mongo/bulk_write/transformable.rb +9 -10
  53. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  54. data/lib/mongo/bulk_write/validatable.rb +5 -1
  55. data/lib/mongo/client.rb +214 -31
  56. data/lib/mongo/client_encryption.rb +1 -1
  57. data/lib/mongo/cluster.rb +177 -69
  58. data/lib/mongo/cluster/periodic_executor.rb +1 -1
  59. data/lib/mongo/cluster/reapers/cursor_reaper.rb +1 -1
  60. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
  61. data/lib/mongo/cluster/sdam_flow.rb +36 -17
  62. data/lib/mongo/cluster/topology.rb +19 -2
  63. data/lib/mongo/cluster/topology/base.rb +1 -1
  64. data/lib/mongo/cluster/topology/no_replica_set_options.rb +1 -1
  65. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +4 -3
  66. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +1 -1
  67. data/lib/mongo/cluster/topology/sharded.rb +2 -2
  68. data/lib/mongo/cluster/topology/single.rb +2 -2
  69. data/lib/mongo/cluster/topology/unknown.rb +1 -1
  70. data/lib/mongo/cluster_time.rb +1 -1
  71. data/lib/mongo/collection.rb +39 -15
  72. data/lib/mongo/collection/view.rb +6 -2
  73. data/lib/mongo/collection/view/aggregation.rb +6 -3
  74. data/lib/mongo/collection/view/builder.rb +1 -1
  75. data/lib/mongo/collection/view/builder/aggregation.rb +1 -1
  76. data/lib/mongo/collection/view/builder/find_command.rb +9 -1
  77. data/lib/mongo/collection/view/builder/flags.rb +1 -1
  78. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  79. data/lib/mongo/collection/view/builder/modifiers.rb +1 -1
  80. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  81. data/lib/mongo/collection/view/change_stream.rb +3 -6
  82. data/lib/mongo/collection/view/change_stream/retryable.rb +1 -1
  83. data/lib/mongo/collection/view/explainable.rb +1 -1
  84. data/lib/mongo/collection/view/immutable.rb +1 -1
  85. data/lib/mongo/collection/view/iterable.rb +8 -2
  86. data/lib/mongo/collection/view/map_reduce.rb +7 -4
  87. data/lib/mongo/collection/view/readable.rb +13 -3
  88. data/lib/mongo/collection/view/writable.rb +93 -13
  89. data/lib/mongo/crypt.rb +1 -1
  90. data/lib/mongo/crypt/auto_decryption_context.rb +1 -1
  91. data/lib/mongo/crypt/auto_encrypter.rb +1 -1
  92. data/lib/mongo/crypt/auto_encryption_context.rb +1 -1
  93. data/lib/mongo/crypt/binary.rb +1 -1
  94. data/lib/mongo/crypt/binding.rb +1 -1
  95. data/lib/mongo/crypt/context.rb +1 -1
  96. data/lib/mongo/crypt/data_key_context.rb +1 -1
  97. data/lib/mongo/crypt/encryption_io.rb +41 -24
  98. data/lib/mongo/crypt/explicit_decryption_context.rb +1 -1
  99. data/lib/mongo/crypt/explicit_encrypter.rb +1 -1
  100. data/lib/mongo/crypt/explicit_encryption_context.rb +1 -1
  101. data/lib/mongo/crypt/handle.rb +1 -1
  102. data/lib/mongo/crypt/hooks.rb +1 -1
  103. data/lib/mongo/crypt/kms_context.rb +1 -1
  104. data/lib/mongo/crypt/status.rb +1 -1
  105. data/lib/mongo/cursor.rb +3 -3
  106. data/lib/mongo/cursor/builder.rb +1 -1
  107. data/lib/mongo/cursor/builder/get_more_command.rb +1 -1
  108. data/lib/mongo/cursor/builder/kill_cursors_command.rb +1 -1
  109. data/lib/mongo/cursor/builder/op_get_more.rb +1 -1
  110. data/lib/mongo/cursor/builder/op_kill_cursors.rb +1 -1
  111. data/lib/mongo/database.rb +35 -5
  112. data/lib/mongo/database/view.rb +21 -6
  113. data/lib/mongo/dbref.rb +1 -1
  114. data/lib/mongo/distinguishing_semaphore.rb +55 -0
  115. data/lib/mongo/error.rb +28 -2
  116. data/lib/mongo/error/auth_error.rb +1 -1
  117. data/lib/mongo/error/bulk_write_error.rb +1 -1
  118. data/lib/mongo/error/change_stream_resumable.rb +1 -1
  119. data/lib/mongo/error/closed_stream.rb +1 -1
  120. data/lib/mongo/error/connection_check_out_timeout.rb +1 -1
  121. data/lib/mongo/error/connection_perished.rb +23 -0
  122. data/lib/mongo/error/credential_check_error.rb +26 -0
  123. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  124. data/lib/mongo/error/file_not_found.rb +1 -1
  125. data/lib/mongo/error/handshake_error.rb +1 -1
  126. data/lib/mongo/error/insufficient_iteration_count.rb +1 -1
  127. data/lib/mongo/error/invalid_address.rb +1 -1
  128. data/lib/mongo/error/invalid_application_name.rb +1 -1
  129. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  130. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  131. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  132. data/lib/mongo/error/invalid_cursor_operation.rb +1 -1
  133. data/lib/mongo/error/invalid_database_name.rb +1 -1
  134. data/lib/mongo/error/invalid_document.rb +1 -1
  135. data/lib/mongo/error/invalid_file.rb +1 -1
  136. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  137. data/lib/mongo/error/invalid_min_pool_size.rb +1 -1
  138. data/lib/mongo/error/invalid_nonce.rb +2 -2
  139. data/lib/mongo/error/invalid_read_option.rb +1 -1
  140. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  141. data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
  142. data/lib/mongo/error/invalid_server_auth_response.rb +23 -0
  143. data/lib/mongo/error/invalid_server_preference.rb +6 -1
  144. data/lib/mongo/error/invalid_session.rb +3 -2
  145. data/lib/mongo/error/invalid_signature.rb +1 -1
  146. data/lib/mongo/error/invalid_transaction_operation.rb +1 -1
  147. data/lib/mongo/error/invalid_txt_record.rb +1 -1
  148. data/lib/mongo/error/invalid_update_document.rb +1 -1
  149. data/lib/mongo/error/invalid_uri.rb +1 -1
  150. data/lib/mongo/error/invalid_write_concern.rb +1 -1
  151. data/lib/mongo/error/lint_error.rb +1 -1
  152. data/lib/mongo/error/max_bson_size.rb +1 -1
  153. data/lib/mongo/error/max_message_size.rb +1 -1
  154. data/lib/mongo/error/mismatched_domain.rb +1 -1
  155. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  156. data/lib/mongo/error/missing_password.rb +1 -1
  157. data/lib/mongo/error/missing_resume_token.rb +1 -1
  158. data/lib/mongo/error/missing_scram_server_signature.rb +27 -0
  159. data/lib/mongo/error/multi_index_drop.rb +1 -1
  160. data/lib/mongo/error/need_primary_server.rb +1 -1
  161. data/lib/mongo/error/no_server_available.rb +1 -1
  162. data/lib/mongo/error/no_srv_records.rb +1 -1
  163. data/lib/mongo/error/notable.rb +18 -3
  164. data/lib/mongo/error/operation_failure.rb +63 -44
  165. data/lib/mongo/error/parser.rb +16 -5
  166. data/lib/mongo/error/pool_closed_error.rb +1 -1
  167. data/lib/mongo/error/raise_original_error.rb +29 -0
  168. data/lib/mongo/error/session_ended.rb +1 -1
  169. data/lib/mongo/error/sessions_not_supported.rb +35 -0
  170. data/lib/mongo/error/socket_error.rb +1 -1
  171. data/lib/mongo/error/socket_timeout_error.rb +1 -1
  172. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  173. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  174. data/lib/mongo/error/unexpected_response.rb +1 -1
  175. data/lib/mongo/error/unknown_payload_type.rb +1 -1
  176. data/lib/mongo/error/unsupported_array_filters.rb +7 -2
  177. data/lib/mongo/error/unsupported_collation.rb +7 -2
  178. data/lib/mongo/error/unsupported_features.rb +1 -1
  179. data/lib/mongo/error/unsupported_message_type.rb +1 -1
  180. data/lib/mongo/error/unsupported_option.rb +99 -0
  181. data/lib/mongo/error/write_retryable.rb +1 -1
  182. data/lib/mongo/event.rb +1 -1
  183. data/lib/mongo/event/base.rb +7 -1
  184. data/lib/mongo/event/listeners.rb +1 -1
  185. data/lib/mongo/event/publisher.rb +1 -1
  186. data/lib/mongo/event/subscriber.rb +1 -1
  187. data/lib/mongo/grid.rb +1 -1
  188. data/lib/mongo/grid/file.rb +6 -1
  189. data/lib/mongo/grid/file/chunk.rb +3 -1
  190. data/lib/mongo/grid/file/info.rb +1 -1
  191. data/lib/mongo/grid/fs_bucket.rb +22 -15
  192. data/lib/mongo/grid/stream.rb +1 -1
  193. data/lib/mongo/grid/stream/read.rb +1 -1
  194. data/lib/mongo/grid/stream/write.rb +10 -4
  195. data/lib/mongo/id.rb +1 -1
  196. data/lib/mongo/index.rb +2 -1
  197. data/lib/mongo/index/view.rb +61 -11
  198. data/lib/mongo/lint.rb +10 -0
  199. data/lib/mongo/loggable.rb +1 -1
  200. data/lib/mongo/logger.rb +1 -1
  201. data/lib/mongo/monitoring.rb +39 -1
  202. data/lib/mongo/monitoring/cmap_log_subscriber.rb +1 -1
  203. data/lib/mongo/monitoring/command_log_subscriber.rb +20 -5
  204. data/lib/mongo/monitoring/event.rb +1 -1
  205. data/lib/mongo/monitoring/event/cmap.rb +1 -1
  206. data/lib/mongo/monitoring/event/cmap/base.rb +1 -1
  207. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -1
  208. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +1 -1
  209. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -1
  210. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +1 -1
  211. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -1
  212. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -1
  213. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -1
  214. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +1 -1
  215. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -1
  216. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -1
  217. data/lib/mongo/monitoring/event/command_failed.rb +12 -1
  218. data/lib/mongo/monitoring/event/command_started.rb +44 -3
  219. data/lib/mongo/monitoring/event/command_succeeded.rb +12 -1
  220. data/lib/mongo/monitoring/event/secure.rb +8 -2
  221. data/lib/mongo/monitoring/event/server_closed.rb +2 -2
  222. data/lib/mongo/monitoring/event/server_description_changed.rb +28 -5
  223. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +10 -3
  224. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +10 -3
  225. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +10 -3
  226. data/lib/mongo/monitoring/event/server_opening.rb +2 -2
  227. data/lib/mongo/monitoring/event/topology_changed.rb +2 -2
  228. data/lib/mongo/monitoring/event/topology_closed.rb +2 -2
  229. data/lib/mongo/monitoring/event/topology_opening.rb +2 -2
  230. data/lib/mongo/monitoring/publishable.rb +9 -9
  231. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  232. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  233. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +10 -2
  234. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  235. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +2 -2
  236. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +1 -1
  237. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +1 -1
  238. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -1
  239. data/lib/mongo/operation.rb +1 -0
  240. data/lib/mongo/operation/aggregate.rb +1 -1
  241. data/lib/mongo/operation/aggregate/command.rb +5 -5
  242. data/lib/mongo/operation/aggregate/op_msg.rb +1 -1
  243. data/lib/mongo/operation/aggregate/result.rb +1 -1
  244. data/lib/mongo/operation/collections_info.rb +3 -36
  245. data/lib/mongo/operation/collections_info/command.rb +40 -0
  246. data/lib/mongo/operation/collections_info/result.rb +1 -1
  247. data/lib/mongo/operation/command.rb +1 -1
  248. data/lib/mongo/operation/command/command.rb +3 -3
  249. data/lib/mongo/operation/command/op_msg.rb +1 -1
  250. data/lib/mongo/operation/count.rb +1 -1
  251. data/lib/mongo/operation/count/command.rb +3 -3
  252. data/lib/mongo/operation/count/op_msg.rb +1 -1
  253. data/lib/mongo/operation/create.rb +1 -1
  254. data/lib/mongo/operation/create/command.rb +3 -3
  255. data/lib/mongo/operation/create/op_msg.rb +1 -1
  256. data/lib/mongo/operation/create_index.rb +1 -1
  257. data/lib/mongo/operation/create_index/command.rb +4 -4
  258. data/lib/mongo/operation/create_index/op_msg.rb +6 -3
  259. data/lib/mongo/operation/create_user.rb +1 -1
  260. data/lib/mongo/operation/create_user/command.rb +4 -4
  261. data/lib/mongo/operation/create_user/op_msg.rb +2 -2
  262. data/lib/mongo/operation/delete.rb +1 -1
  263. data/lib/mongo/operation/delete/bulk_result.rb +1 -1
  264. data/lib/mongo/operation/delete/command.rb +4 -4
  265. data/lib/mongo/operation/delete/legacy.rb +2 -2
  266. data/lib/mongo/operation/delete/op_msg.rb +4 -4
  267. data/lib/mongo/operation/delete/result.rb +2 -2
  268. data/lib/mongo/operation/distinct.rb +1 -1
  269. data/lib/mongo/operation/distinct/command.rb +3 -3
  270. data/lib/mongo/operation/distinct/op_msg.rb +1 -1
  271. data/lib/mongo/operation/drop.rb +1 -1
  272. data/lib/mongo/operation/drop/command.rb +3 -3
  273. data/lib/mongo/operation/drop/op_msg.rb +1 -1
  274. data/lib/mongo/operation/drop_database.rb +1 -1
  275. data/lib/mongo/operation/drop_database/command.rb +3 -3
  276. data/lib/mongo/operation/drop_database/op_msg.rb +1 -1
  277. data/lib/mongo/operation/drop_index.rb +1 -1
  278. data/lib/mongo/operation/drop_index/command.rb +4 -4
  279. data/lib/mongo/operation/drop_index/op_msg.rb +2 -2
  280. data/lib/mongo/operation/explain.rb +1 -1
  281. data/lib/mongo/operation/explain/command.rb +3 -3
  282. data/lib/mongo/operation/explain/legacy.rb +3 -3
  283. data/lib/mongo/operation/explain/op_msg.rb +1 -1
  284. data/lib/mongo/operation/explain/result.rb +1 -1
  285. data/lib/mongo/operation/find.rb +1 -1
  286. data/lib/mongo/operation/find/command.rb +3 -3
  287. data/lib/mongo/operation/find/legacy.rb +3 -3
  288. data/lib/mongo/operation/find/legacy/result.rb +1 -1
  289. data/lib/mongo/operation/find/op_msg.rb +2 -12
  290. data/lib/mongo/operation/find/result.rb +1 -1
  291. data/lib/mongo/operation/get_more.rb +1 -1
  292. data/lib/mongo/operation/get_more/command.rb +3 -3
  293. data/lib/mongo/operation/get_more/legacy.rb +2 -2
  294. data/lib/mongo/operation/get_more/op_msg.rb +2 -12
  295. data/lib/mongo/operation/get_more/result.rb +1 -1
  296. data/lib/mongo/operation/indexes.rb +1 -1
  297. data/lib/mongo/operation/indexes/command.rb +3 -3
  298. data/lib/mongo/operation/indexes/legacy.rb +4 -4
  299. data/lib/mongo/operation/indexes/op_msg.rb +1 -1
  300. data/lib/mongo/operation/indexes/result.rb +1 -1
  301. data/lib/mongo/operation/insert.rb +3 -2
  302. data/lib/mongo/operation/insert/bulk_result.rb +6 -2
  303. data/lib/mongo/operation/insert/command.rb +7 -7
  304. data/lib/mongo/operation/insert/legacy.rb +9 -5
  305. data/lib/mongo/operation/insert/op_msg.rb +6 -6
  306. data/lib/mongo/operation/insert/result.rb +7 -4
  307. data/lib/mongo/operation/kill_cursors.rb +1 -1
  308. data/lib/mongo/operation/kill_cursors/command.rb +3 -3
  309. data/lib/mongo/operation/kill_cursors/legacy.rb +2 -2
  310. data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -1
  311. data/lib/mongo/operation/list_collections.rb +1 -1
  312. data/lib/mongo/operation/list_collections/command.rb +4 -4
  313. data/lib/mongo/operation/list_collections/op_msg.rb +2 -2
  314. data/lib/mongo/operation/list_collections/result.rb +1 -1
  315. data/lib/mongo/operation/map_reduce.rb +1 -1
  316. data/lib/mongo/operation/map_reduce/command.rb +3 -3
  317. data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
  318. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  319. data/lib/mongo/operation/op_msg_base.rb +3 -3
  320. data/lib/mongo/operation/parallel_scan.rb +1 -1
  321. data/lib/mongo/operation/parallel_scan/command.rb +5 -5
  322. data/lib/mongo/operation/parallel_scan/op_msg.rb +2 -2
  323. data/lib/mongo/operation/parallel_scan/result.rb +1 -1
  324. data/lib/mongo/operation/remove_user.rb +1 -1
  325. data/lib/mongo/operation/remove_user/command.rb +4 -4
  326. data/lib/mongo/operation/remove_user/op_msg.rb +2 -2
  327. data/lib/mongo/operation/result.rb +28 -4
  328. data/lib/mongo/operation/shared/bypass_document_validation.rb +10 -4
  329. data/lib/mongo/operation/shared/causal_consistency_supported.rb +3 -3
  330. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +56 -0
  331. data/lib/mongo/operation/shared/executable.rb +46 -28
  332. data/lib/mongo/operation/shared/executable_no_validate.rb +3 -3
  333. data/lib/mongo/operation/shared/executable_transaction_label.rb +1 -1
  334. data/lib/mongo/operation/shared/idable.rb +1 -1
  335. data/lib/mongo/operation/shared/limited.rb +10 -2
  336. data/lib/mongo/operation/shared/object_id_generator.rb +1 -1
  337. data/lib/mongo/operation/shared/op_msg_or_command.rb +7 -5
  338. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +8 -6
  339. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +8 -6
  340. data/lib/mongo/operation/shared/polymorphic_lookup.rb +1 -1
  341. data/lib/mongo/operation/shared/polymorphic_result.rb +1 -1
  342. data/lib/mongo/operation/shared/read_preference_supported.rb +19 -16
  343. data/lib/mongo/operation/shared/response_handling.rb +83 -8
  344. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -1
  345. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +1 -1
  346. data/lib/mongo/operation/shared/sessions_supported.rb +50 -27
  347. data/lib/mongo/operation/shared/specifiable.rb +32 -20
  348. data/lib/mongo/operation/shared/write.rb +25 -19
  349. data/lib/mongo/operation/shared/write_concern_supported.rb +6 -6
  350. data/lib/mongo/operation/update.rb +1 -1
  351. data/lib/mongo/operation/update/bulk_result.rb +1 -1
  352. data/lib/mongo/operation/update/command.rb +4 -4
  353. data/lib/mongo/operation/update/legacy.rb +2 -2
  354. data/lib/mongo/operation/update/legacy/result.rb +1 -1
  355. data/lib/mongo/operation/update/op_msg.rb +4 -4
  356. data/lib/mongo/operation/update/result.rb +2 -2
  357. data/lib/mongo/operation/update_user.rb +1 -1
  358. data/lib/mongo/operation/update_user/command.rb +4 -4
  359. data/lib/mongo/operation/update_user/op_msg.rb +2 -2
  360. data/lib/mongo/operation/users_info.rb +1 -1
  361. data/lib/mongo/operation/users_info/command.rb +4 -4
  362. data/lib/mongo/operation/users_info/op_msg.rb +2 -2
  363. data/lib/mongo/operation/users_info/result.rb +1 -1
  364. data/lib/mongo/options.rb +1 -1
  365. data/lib/mongo/options/mapper.rb +1 -1
  366. data/lib/mongo/options/redacted.rb +1 -1
  367. data/lib/mongo/protocol/bit_vector.rb +1 -1
  368. data/lib/mongo/protocol/compressed.rb +1 -1
  369. data/lib/mongo/protocol/delete.rb +1 -1
  370. data/lib/mongo/protocol/get_more.rb +1 -1
  371. data/lib/mongo/protocol/insert.rb +1 -1
  372. data/lib/mongo/protocol/kill_cursors.rb +1 -1
  373. data/lib/mongo/protocol/message.rb +37 -9
  374. data/lib/mongo/protocol/msg.rb +37 -4
  375. data/lib/mongo/protocol/query.rb +1 -1
  376. data/lib/mongo/protocol/registry.rb +1 -1
  377. data/lib/mongo/protocol/reply.rb +1 -1
  378. data/lib/mongo/protocol/serializers.rb +6 -3
  379. data/lib/mongo/protocol/update.rb +1 -1
  380. data/lib/mongo/retryable.rb +23 -10
  381. data/lib/mongo/semaphore.rb +1 -1
  382. data/lib/mongo/server.rb +40 -8
  383. data/lib/mongo/server/app_metadata.rb +44 -7
  384. data/lib/mongo/server/connection.rb +37 -133
  385. data/lib/mongo/server/connection_base.rb +56 -15
  386. data/lib/mongo/server/connection_common.rb +75 -1
  387. data/lib/mongo/server/connection_pool.rb +20 -1
  388. data/lib/mongo/server/connection_pool/populator.rb +1 -1
  389. data/lib/mongo/server/context.rb +1 -1
  390. data/lib/mongo/server/description.rb +49 -2
  391. data/lib/mongo/server/description/features.rb +12 -3
  392. data/lib/mongo/server/monitor.rb +145 -69
  393. data/lib/mongo/server/monitor/app_metadata.rb +1 -1
  394. data/lib/mongo/server/monitor/connection.rb +110 -80
  395. data/lib/mongo/server/pending_connection.rb +215 -3
  396. data/lib/mongo/server/push_monitor.rb +173 -0
  397. data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
  398. data/lib/mongo/server/round_trip_time_averager.rb +12 -3
  399. data/lib/mongo/server_selector.rb +2 -2
  400. data/lib/mongo/server_selector/{selectable.rb → base.rb} +159 -86
  401. data/lib/mongo/server_selector/nearest.rb +26 -21
  402. data/lib/mongo/server_selector/primary.rb +24 -28
  403. data/lib/mongo/server_selector/primary_preferred.rb +32 -25
  404. data/lib/mongo/server_selector/secondary.rb +26 -21
  405. data/lib/mongo/server_selector/secondary_preferred.rb +29 -34
  406. data/lib/mongo/session.rb +14 -1
  407. data/lib/mongo/session/server_session.rb +1 -1
  408. data/lib/mongo/session/session_pool.rb +1 -1
  409. data/lib/mongo/socket.rb +121 -41
  410. data/lib/mongo/socket/ssl.rb +98 -35
  411. data/lib/mongo/socket/tcp.rb +39 -31
  412. data/lib/mongo/socket/unix.rb +14 -6
  413. data/lib/mongo/srv.rb +1 -1
  414. data/lib/mongo/srv/monitor.rb +1 -1
  415. data/lib/mongo/srv/resolver.rb +1 -1
  416. data/lib/mongo/srv/result.rb +1 -1
  417. data/lib/mongo/timeout.rb +9 -9
  418. data/lib/mongo/topology_version.rb +89 -0
  419. data/lib/mongo/uri.rb +61 -47
  420. data/lib/mongo/uri/srv_protocol.rb +9 -1
  421. data/lib/mongo/utils.rb +62 -0
  422. data/lib/mongo/version.rb +2 -2
  423. data/lib/mongo/write_concern.rb +1 -1
  424. data/lib/mongo/write_concern/acknowledged.rb +1 -1
  425. data/lib/mongo/write_concern/base.rb +1 -1
  426. data/lib/mongo/write_concern/unacknowledged.rb +1 -1
  427. data/mongo.gemspec +1 -1
  428. data/spec/NOTES.aws-auth.md +291 -0
  429. data/spec/README.aws-auth.md +318 -0
  430. data/spec/README.md +64 -17
  431. data/spec/integration/auth_spec.rb +29 -9
  432. data/spec/integration/awaited_ismaster_spec.rb +28 -0
  433. data/spec/integration/aws_auth_request_spec.rb +74 -0
  434. data/spec/integration/aws_credentials_retriever_spec.rb +103 -0
  435. data/spec/integration/bulk_write_spec.rb +19 -0
  436. data/spec/integration/change_stream_examples_spec.rb +6 -2
  437. data/spec/integration/change_stream_spec.rb +123 -51
  438. data/spec/integration/check_clean_slate_spec.rb +16 -0
  439. data/spec/integration/client_construction_aws_auth_spec.rb +191 -0
  440. data/spec/integration/client_construction_spec.rb +2 -1
  441. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +3 -3
  442. data/spec/integration/collection_indexes_prose_spec.rb +55 -0
  443. data/spec/integration/command_monitoring_spec.rb +30 -6
  444. data/spec/integration/command_spec.rb +11 -9
  445. data/spec/integration/connect_single_rs_name_spec.rb +10 -5
  446. data/spec/integration/connection_spec.rb +7 -3
  447. data/spec/integration/crud_spec.rb +32 -4
  448. data/spec/integration/cursor_reaping_spec.rb +14 -10
  449. data/spec/integration/docs_examples_spec.rb +6 -0
  450. data/spec/integration/fork_reconnect_spec.rb +143 -0
  451. data/spec/integration/get_more_spec.rb +10 -3
  452. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  453. data/spec/integration/heartbeat_events_spec.rb +5 -24
  454. data/spec/integration/read_concern_spec.rb +1 -1
  455. data/spec/integration/read_preference_spec.rb +41 -11
  456. data/spec/integration/reconnect_spec.rb +2 -3
  457. data/spec/integration/retryable_errors_spec.rb +33 -14
  458. data/spec/integration/{retryable_writes_spec.rb → retryable_writes/retryable_writes_36_and_older_spec.rb} +55 -51
  459. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +401 -0
  460. data/spec/integration/retryable_writes/shared/adds_diagnostics.rb +15 -0
  461. data/spec/integration/retryable_writes/shared/does_not_support_retries.rb +24 -0
  462. data/spec/integration/retryable_writes/shared/only_supports_legacy_retries.rb +25 -0
  463. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +215 -0
  464. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +232 -0
  465. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +110 -0
  466. data/spec/integration/retryable_writes/shared/supports_legacy_retries.rb +19 -0
  467. data/spec/integration/retryable_writes/shared/supports_modern_retries.rb +25 -0
  468. data/spec/integration/retryable_writes/shared/supports_retries.rb +16 -0
  469. data/spec/integration/sdam_error_handling_spec.rb +142 -22
  470. data/spec/integration/sdam_events_spec.rb +77 -5
  471. data/spec/integration/sdam_prose_spec.rb +64 -0
  472. data/spec/integration/server_monitor_spec.rb +25 -1
  473. data/spec/integration/server_spec.rb +42 -26
  474. data/spec/integration/size_limit_spec.rb +26 -9
  475. data/spec/integration/ssl_uri_options_spec.rb +2 -2
  476. data/spec/integration/step_down_spec.rb +15 -15
  477. data/spec/integration/transactions_api_examples_spec.rb +59 -0
  478. data/spec/integration/transactions_examples_spec.rb +5 -2
  479. data/spec/integration/x509_auth_spec.rb +109 -0
  480. data/spec/integration/zlib_compression_spec.rb +25 -0
  481. data/spec/kerberos/kerberos_spec.rb +10 -6
  482. data/spec/lite_spec_helper.rb +31 -22
  483. data/spec/mongo/address/ipv4_spec.rb +1 -1
  484. data/spec/mongo/address_spec.rb +2 -2
  485. data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
  486. data/spec/mongo/auth/aws/request_spec.rb +76 -0
  487. data/spec/mongo/auth/cr_spec.rb +7 -7
  488. data/spec/mongo/auth/gssapi/conversation_spec.rb +121 -0
  489. data/spec/mongo/auth/invalid_mechanism_spec.rb +1 -1
  490. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  491. data/spec/mongo/auth/ldap_spec.rb +3 -3
  492. data/spec/mongo/auth/scram/conversation_spec.rb +119 -334
  493. data/spec/mongo/auth/scram256/conversation_spec.rb +171 -0
  494. data/spec/mongo/auth/{scram/negotiation_spec.rb → scram_negotiation_spec.rb} +13 -8
  495. data/spec/mongo/auth/scram_spec.rb +29 -69
  496. data/spec/mongo/auth/user_spec.rb +1 -1
  497. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  498. data/spec/mongo/auth/x509_spec.rb +8 -8
  499. data/spec/mongo/auth_spec.rb +4 -4
  500. data/spec/mongo/bulk_write_spec.rb +206 -2
  501. data/spec/mongo/client_construction_spec.rb +609 -86
  502. data/spec/mongo/client_spec.rb +59 -5
  503. data/spec/mongo/cluster/topology/replica_set_spec.rb +52 -9
  504. data/spec/mongo/cluster/topology/single_spec.rb +4 -2
  505. data/spec/mongo/cluster_spec.rb +37 -36
  506. data/spec/mongo/collection/view/aggregation_spec.rb +6 -2
  507. data/spec/mongo/collection/view/builder/find_command_spec.rb +17 -6
  508. data/spec/mongo/collection/view/change_stream_resume_spec.rb +392 -0
  509. data/spec/mongo/collection/view/change_stream_spec.rb +0 -318
  510. data/spec/mongo/collection/view/iterable_spec.rb +38 -0
  511. data/spec/mongo/collection/view/map_reduce_spec.rb +6 -2
  512. data/spec/mongo/collection/view/readable_spec.rb +15 -1
  513. data/spec/mongo/collection/view/writable_spec.rb +208 -1
  514. data/spec/mongo/collection_spec.rb +531 -43
  515. data/spec/mongo/cursor/builder/get_more_command_spec.rb +6 -1
  516. data/spec/mongo/cursor/builder/op_get_more_spec.rb +6 -1
  517. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +6 -1
  518. data/spec/mongo/cursor_spec.rb +9 -1
  519. data/spec/mongo/database_spec.rb +251 -10
  520. data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
  521. data/spec/mongo/error/operation_failure_heavy_spec.rb +58 -0
  522. data/spec/mongo/error/operation_failure_spec.rb +167 -69
  523. data/spec/mongo/error/unsupported_option_spec.rb +54 -0
  524. data/spec/mongo/grid/fs_bucket_spec.rb +18 -0
  525. data/spec/mongo/grid/stream/write_spec.rb +32 -0
  526. data/spec/mongo/index/view_spec.rb +312 -0
  527. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
  528. data/spec/mongo/operation/aggregate/result_spec.rb +6 -1
  529. data/spec/mongo/operation/delete/bulk_spec.rb +18 -6
  530. data/spec/mongo/operation/delete/op_msg_spec.rb +22 -14
  531. data/spec/mongo/operation/find/legacy_spec.rb +27 -7
  532. data/spec/mongo/operation/get_more_spec.rb +6 -1
  533. data/spec/mongo/operation/insert/bulk_spec.rb +21 -7
  534. data/spec/mongo/operation/insert/command_spec.rb +4 -0
  535. data/spec/mongo/operation/insert/op_msg_spec.rb +22 -14
  536. data/spec/mongo/operation/limited_spec.rb +5 -3
  537. data/spec/mongo/operation/read_preference_legacy_spec.rb +16 -4
  538. data/spec/mongo/operation/read_preference_op_msg_spec.rb +115 -5
  539. data/spec/mongo/operation/result_spec.rb +6 -1
  540. data/spec/mongo/operation/update/bulk_spec.rb +18 -6
  541. data/spec/mongo/operation/update/command_spec.rb +4 -0
  542. data/spec/mongo/operation/update/op_msg_spec.rb +22 -14
  543. data/spec/mongo/protocol/msg_spec.rb +10 -0
  544. data/spec/mongo/retryable_spec.rb +71 -70
  545. data/spec/mongo/semaphore_spec.rb +51 -0
  546. data/spec/mongo/server/app_metadata_shared.rb +136 -0
  547. data/spec/mongo/server/app_metadata_spec.rb +8 -1
  548. data/spec/mongo/server/connection_auth_spec.rb +33 -14
  549. data/spec/mongo/server/connection_pool_spec.rb +0 -31
  550. data/spec/mongo/server/connection_spec.rb +118 -71
  551. data/spec/mongo/server/monitor/app_metadata_spec.rb +8 -1
  552. data/spec/mongo/server/monitor/connection_spec.rb +1 -82
  553. data/spec/mongo/server/monitor_spec.rb +76 -17
  554. data/spec/mongo/server/round_trip_time_averager_spec.rb +5 -3
  555. data/spec/mongo/server_selector/nearest_spec.rb +24 -23
  556. data/spec/mongo/server_selector/primary_preferred_spec.rb +27 -26
  557. data/spec/mongo/server_selector/primary_spec.rb +27 -9
  558. data/spec/mongo/server_selector/secondary_preferred_spec.rb +40 -23
  559. data/spec/mongo/server_selector/secondary_spec.rb +19 -18
  560. data/spec/mongo/server_selector_spec.rb +4 -5
  561. data/spec/mongo/session/session_pool_spec.rb +7 -3
  562. data/spec/mongo/session_spec.rb +35 -0
  563. data/spec/mongo/socket/ssl_spec.rb +2 -2
  564. data/spec/mongo/socket/tcp_spec.rb +2 -2
  565. data/spec/mongo/socket/unix_spec.rb +2 -2
  566. data/spec/mongo/socket_spec.rb +9 -9
  567. data/spec/mongo/timeout_spec.rb +22 -68
  568. data/spec/mongo/uri_spec.rb +21 -6
  569. data/spec/runners/auth.rb +5 -6
  570. data/spec/runners/change_streams/outcome.rb +42 -0
  571. data/spec/runners/change_streams/spec.rb +57 -0
  572. data/spec/runners/change_streams/test.rb +229 -0
  573. data/spec/runners/cmap.rb +1 -1
  574. data/spec/runners/cmap/verifier.rb +1 -1
  575. data/spec/runners/command_monitoring.rb +4 -35
  576. data/spec/runners/connection_string.rb +3 -2
  577. data/spec/runners/crud.rb +2 -2
  578. data/spec/runners/crud/context.rb +10 -6
  579. data/spec/runners/crud/operation.rb +177 -55
  580. data/spec/runners/crud/outcome.rb +1 -1
  581. data/spec/runners/crud/spec.rb +0 -7
  582. data/spec/runners/crud/test.rb +8 -26
  583. data/spec/runners/crud/test_base.rb +47 -0
  584. data/spec/runners/crud/verifier.rb +21 -3
  585. data/spec/runners/gridfs.rb +1 -1
  586. data/spec/runners/{server_discovery_and_monitoring.rb → sdam.rb} +41 -22
  587. data/spec/runners/sdam/verifier.rb +26 -8
  588. data/spec/runners/server_selection.rb +242 -28
  589. data/spec/runners/transactions.rb +13 -14
  590. data/spec/runners/transactions/operation.rb +155 -25
  591. data/spec/runners/transactions/spec.rb +1 -1
  592. data/spec/runners/transactions/test.rb +103 -65
  593. data/spec/spec_tests/auth_spec.rb +2 -0
  594. data/spec/spec_tests/change_streams_spec.rb +39 -4
  595. data/spec/spec_tests/client_side_encryption_spec.rb +3 -0
  596. data/spec/spec_tests/cmap_spec.rb +5 -0
  597. data/spec/spec_tests/command_monitoring_spec.rb +25 -12
  598. data/spec/spec_tests/connection_string_spec.rb +2 -0
  599. data/spec/spec_tests/crud_spec.rb +3 -1
  600. data/spec/spec_tests/data/auth/connection-string.yml +57 -1
  601. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +27 -1
  602. data/spec/spec_tests/data/change_streams/change-streams-resume-errorLabels.yml +1105 -0
  603. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +1173 -0
  604. data/spec/spec_tests/data/change_streams/change-streams.yml +5 -4
  605. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +1 -1
  606. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +33 -11
  607. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-clientError.yml +63 -0
  608. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-serverError.yml +92 -0
  609. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint.yml +103 -0
  610. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-clientError.yml +90 -0
  611. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-serverError.yml +147 -0
  612. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint.yml +164 -0
  613. data/spec/spec_tests/data/crud_v2/deleteMany-hint-clientError.yml +43 -0
  614. data/spec/spec_tests/data/crud_v2/deleteMany-hint-serverError.yml +62 -0
  615. data/spec/spec_tests/data/crud_v2/deleteMany-hint.yml +58 -0
  616. data/spec/spec_tests/data/crud_v2/deleteOne-hint-clientError.yml +41 -0
  617. data/spec/spec_tests/data/crud_v2/deleteOne-hint-serverError.yml +60 -0
  618. data/spec/spec_tests/data/crud_v2/deleteOne-hint.yml +57 -0
  619. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-clientError.yml +28 -0
  620. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-serverError.yml +44 -0
  621. data/spec/spec_tests/data/crud_v2/find-allowdiskuse.yml +50 -0
  622. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-clientError.yml +45 -0
  623. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-serverError.yml +60 -0
  624. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint.yml +56 -0
  625. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-clientError.yml +40 -0
  626. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-serverError.yml +59 -0
  627. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint.yml +55 -0
  628. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-clientError.yml +40 -0
  629. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-serverError.yml +58 -0
  630. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint.yml +55 -0
  631. data/spec/spec_tests/data/crud_v2/replaceOne-hint.yml +61 -0
  632. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-delete-hint-clientError.yml +60 -0
  633. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-update-hint-clientError.yml +88 -0
  634. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteMany-hint-clientError.yml +40 -0
  635. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteOne-hint-clientError.yml +38 -0
  636. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndDelete-hint-clientError.yml +42 -0
  637. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndReplace-hint-clientError.yml +40 -0
  638. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndUpdate-hint-clientError.yml +40 -0
  639. data/spec/spec_tests/data/crud_v2/unacknowledged-replaceOne-hint-clientError.yml +40 -0
  640. data/spec/spec_tests/data/crud_v2/unacknowledged-updateMany-hint-clientError.yml +43 -0
  641. data/spec/spec_tests/data/crud_v2/unacknowledged-updateOne-hint-clientError.yml +40 -0
  642. data/spec/spec_tests/data/crud_v2/updateMany-hint-clientError.yml +45 -0
  643. data/spec/spec_tests/data/crud_v2/updateMany-hint-serverError.yml +66 -0
  644. data/spec/spec_tests/data/crud_v2/updateMany-hint.yml +65 -0
  645. data/spec/spec_tests/data/crud_v2/updateOne-hint-clientError.yml +43 -0
  646. data/spec/spec_tests/data/crud_v2/updateOne-hint-serverError.yml +62 -0
  647. data/spec/spec_tests/data/crud_v2/updateOne-hint.yml +61 -0
  648. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +65 -0
  649. data/spec/spec_tests/data/dns_seedlist_discovery/direct-connection-false.yml +10 -0
  650. data/spec/spec_tests/data/dns_seedlist_discovery/direct-connection-true.yml +5 -0
  651. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
  652. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
  653. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
  654. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-2.6.yml +215 -0
  655. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-3.2.yml +58 -0
  656. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-3.4.yml +95 -0
  657. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-4.2.yml +36 -0
  658. data/spec/spec_tests/data/retryable_writes/bulkWrite-errorLabels.yml +77 -0
  659. data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +37 -0
  660. data/spec/spec_tests/data/retryable_writes/deleteOne-errorLabels.yml +48 -0
  661. data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +22 -0
  662. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-errorLabels.yml +49 -0
  663. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +23 -0
  664. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-errorLabels.yml +52 -0
  665. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +25 -0
  666. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-errorLabels.yml +52 -0
  667. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +24 -0
  668. data/spec/spec_tests/data/retryable_writes/insertMany-errorLabels.yml +54 -0
  669. data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +24 -0
  670. data/spec/spec_tests/data/retryable_writes/insertOne-errorLabels.yml +44 -0
  671. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +69 -0
  672. data/spec/spec_tests/data/retryable_writes/replaceOne-errorLabels.yml +53 -0
  673. data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +23 -0
  674. data/spec/spec_tests/data/retryable_writes/updateOne-errorLabels.yml +53 -0
  675. data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +23 -0
  676. data/spec/spec_tests/data/sdam/errors/error_handling_handshake.yml +54 -0
  677. data/spec/spec_tests/data/sdam/errors/non-stale-network-error.yml +46 -0
  678. data/spec/spec_tests/data/sdam/errors/non-stale-network-timeout-error.yml +37 -0
  679. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedAtShutdown.yml +60 -0
  680. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedDueToReplStateChange.yml +60 -0
  681. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMaster.yml +60 -0
  682. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterNoSlaveOk.yml +60 -0
  683. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterOrSecondary.yml +60 -0
  684. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-PrimarySteppedDown.yml +60 -0
  685. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-ShutdownInProgress.yml +60 -0
  686. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedAtShutdown.yml +51 -0
  687. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedDueToReplStateChange.yml +51 -0
  688. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMaster.yml +51 -0
  689. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterNoSlaveOk.yml +51 -0
  690. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterOrSecondary.yml +51 -0
  691. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-PrimarySteppedDown.yml +51 -0
  692. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-ShutdownInProgress.yml +51 -0
  693. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedAtShutdown.yml +60 -0
  694. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedDueToReplStateChange.yml +60 -0
  695. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMaster.yml +60 -0
  696. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterNoSlaveOk.yml +60 -0
  697. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterOrSecondary.yml +60 -0
  698. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-PrimarySteppedDown.yml +60 -0
  699. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-ShutdownInProgress.yml +60 -0
  700. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedAtShutdown.yml +46 -0
  701. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedDueToReplStateChange.yml +46 -0
  702. data/spec/spec_tests/data/sdam/errors/post-42-NotMaster.yml +46 -0
  703. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterNoSlaveOk.yml +46 -0
  704. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterOrSecondary.yml +46 -0
  705. data/spec/spec_tests/data/sdam/errors/post-42-PrimarySteppedDown.yml +46 -0
  706. data/spec/spec_tests/data/sdam/errors/post-42-ShutdownInProgress.yml +46 -0
  707. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedAtShutdown.yml +46 -0
  708. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedDueToReplStateChange.yml +46 -0
  709. data/spec/spec_tests/data/sdam/errors/pre-42-NotMaster.yml +46 -0
  710. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterNoSlaveOk.yml +46 -0
  711. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterOrSecondary.yml +46 -0
  712. data/spec/spec_tests/data/sdam/errors/pre-42-PrimarySteppedDown.yml +46 -0
  713. data/spec/spec_tests/data/sdam/errors/pre-42-ShutdownInProgress.yml +46 -0
  714. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedAtShutdown.yml +89 -0
  715. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedDueToReplStateChange.yml +89 -0
  716. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMaster.yml +89 -0
  717. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterNoSlaveOk.yml +89 -0
  718. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterOrSecondary.yml +89 -0
  719. data/spec/spec_tests/data/sdam/errors/stale-generation-PrimarySteppedDown.yml +89 -0
  720. data/spec/spec_tests/data/sdam/errors/stale-generation-ShutdownInProgress.yml +89 -0
  721. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedAtShutdown.yml +89 -0
  722. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedDueToReplStateChange.yml +89 -0
  723. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMaster.yml +89 -0
  724. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterNoSlaveOk.yml +89 -0
  725. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterOrSecondary.yml +89 -0
  726. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-PrimarySteppedDown.yml +89 -0
  727. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-ShutdownInProgress.yml +89 -0
  728. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-network.yml +80 -0
  729. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-timeout.yml +80 -0
  730. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedAtShutdown.yml +89 -0
  731. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedDueToReplStateChange.yml +89 -0
  732. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMaster.yml +89 -0
  733. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterNoSlaveOk.yml +89 -0
  734. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterOrSecondary.yml +89 -0
  735. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-PrimarySteppedDown.yml +89 -0
  736. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-ShutdownInProgress.yml +89 -0
  737. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-network.yml +80 -0
  738. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-timeout.yml +80 -0
  739. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedAtShutdown.yml +64 -0
  740. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedDueToReplStateChange.yml +64 -0
  741. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMaster.yml +64 -0
  742. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterNoSlaveOk.yml +64 -0
  743. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterOrSecondary.yml +64 -0
  744. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-PrimarySteppedDown.yml +64 -0
  745. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-ShutdownInProgress.yml +64 -0
  746. data/spec/spec_tests/data/sdam/rs/compatible.yml +2 -0
  747. data/spec/spec_tests/data/sdam/rs/compatible_unknown.yml +2 -0
  748. data/spec/spec_tests/data/sdam/rs/discover_arbiters.yml +2 -2
  749. data/spec/spec_tests/data/sdam/rs/discover_arbiters_replicaset.yml +43 -0
  750. data/spec/spec_tests/data/sdam/rs/discover_ghost.yml +35 -0
  751. data/spec/spec_tests/data/sdam/rs/{ghost_discovered.yml → discover_ghost_replicaset.yml} +1 -1
  752. data/spec/spec_tests/data/sdam/rs/discover_hidden.yml +50 -0
  753. data/spec/spec_tests/data/sdam/rs/discover_hidden_replicaset.yml +50 -0
  754. data/spec/spec_tests/data/sdam/rs/discover_passives.yml +2 -2
  755. data/spec/spec_tests/data/sdam/rs/discover_passives_replicaset.yml +81 -0
  756. data/spec/spec_tests/data/sdam/rs/discover_primary.yml +2 -2
  757. data/spec/spec_tests/data/sdam/rs/discover_primary_replicaset.yml +42 -0
  758. data/spec/spec_tests/data/sdam/rs/discover_rsother.yml +49 -0
  759. data/spec/spec_tests/data/sdam/rs/{rsother_discovered.yml → discover_rsother_replicaset.yml} +1 -1
  760. data/spec/spec_tests/data/sdam/rs/discover_secondary.yml +2 -2
  761. data/spec/spec_tests/data/sdam/rs/discover_secondary_replicaset.yml +43 -0
  762. data/spec/spec_tests/data/sdam/rs/incompatible_arbiter.yml +2 -0
  763. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -0
  764. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +2 -0
  765. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +23 -27
  766. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +79 -55
  767. data/spec/spec_tests/data/sdam/rs/replicaset_rsnp.yml +20 -0
  768. data/spec/spec_tests/data/sdam/rs/secondary_mismatched_me.yml +3 -2
  769. data/spec/spec_tests/data/sdam/rs/too_new.yml +2 -0
  770. data/spec/spec_tests/data/sdam/rs/topology_version_equal.yml +66 -0
  771. data/spec/spec_tests/data/sdam/rs/topology_version_greater.yml +189 -0
  772. data/spec/spec_tests/data/sdam/rs/topology_version_less.yml +62 -0
  773. data/spec/spec_tests/data/sdam/sharded/discover_single_mongos.yml +23 -0
  774. data/spec/spec_tests/data/sdam/single/direct_connection_external_ip.yml +1 -1
  775. data/spec/spec_tests/data/sdam/single/direct_connection_mongos.yml +2 -2
  776. data/spec/spec_tests/data/sdam/single/direct_connection_replicaset.yml +22 -0
  777. data/spec/spec_tests/data/sdam/single/direct_connection_rsarbiter.yml +2 -2
  778. data/spec/spec_tests/data/sdam/single/direct_connection_rsprimary.yml +2 -2
  779. data/spec/spec_tests/data/sdam/single/direct_connection_rssecondary.yml +2 -2
  780. data/spec/spec_tests/data/sdam/single/direct_connection_slave.yml +1 -1
  781. data/spec/spec_tests/data/sdam/single/direct_connection_standalone.yml +2 -2
  782. data/spec/spec_tests/data/sdam/single/{unavailable_seed.yml → direct_connection_unavailable_seed.yml} +2 -2
  783. data/spec/spec_tests/data/sdam/single/direct_connection_wrong_set_name.yml +38 -0
  784. data/spec/spec_tests/data/sdam/single/discover_standalone.yml +34 -0
  785. data/spec/spec_tests/data/sdam/single/discover_unavailable_seed.yml +28 -0
  786. data/spec/spec_tests/data/sdam/single/too_old_then_upgraded.yml +46 -0
  787. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
  788. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
  789. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
  790. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
  791. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
  792. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
  793. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
  794. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
  795. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
  796. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
  797. data/spec/spec_tests/data/transactions/create-collection.yml +131 -0
  798. data/spec/spec_tests/data/transactions/create-index.yml +152 -0
  799. data/spec/spec_tests/data/transactions/error-labels.yml +87 -21
  800. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +1 -0
  801. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +124 -0
  802. data/spec/spec_tests/data/transactions/retryable-abort.yml +17 -2
  803. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +132 -0
  804. data/spec/spec_tests/data/transactions/retryable-commit.yml +24 -9
  805. data/spec/spec_tests/data/uri_options/connection-options.yml +43 -0
  806. data/spec/spec_tests/data/uri_options/ruby-auth-options.yml +12 -0
  807. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +57 -0
  808. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +3 -1
  809. data/spec/spec_tests/gridfs_spec.rb +2 -0
  810. data/spec/spec_tests/max_staleness_spec.rb +5 -141
  811. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +2 -0
  812. data/spec/spec_tests/read_write_concern_operaton_spec.rb +10 -0
  813. data/spec/spec_tests/retryable_reads_spec.rb +4 -2
  814. data/spec/spec_tests/retryable_writes_spec.rb +8 -1
  815. data/spec/spec_tests/sdam_integration_spec.rb +13 -0
  816. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -2
  817. data/spec/spec_tests/sdam_spec.rb +70 -1
  818. data/spec/spec_tests/server_selection_rtt_spec.rb +2 -0
  819. data/spec/spec_tests/server_selection_spec.rb +5 -115
  820. data/spec/spec_tests/transactions_api_spec.rb +5 -0
  821. data/spec/spec_tests/transactions_spec.rb +5 -0
  822. data/spec/spec_tests/uri_options_spec.rb +2 -0
  823. data/spec/stress/cleanup_spec.rb +58 -0
  824. data/spec/stress/connection_pool_stress_spec.rb +11 -13
  825. data/spec/stress/connection_pool_timing_spec.rb +3 -6
  826. data/spec/stress/fork_reconnect_stress_spec.rb +109 -0
  827. data/spec/support/authorization.rb +1 -11
  828. data/spec/support/aws_utils.rb +62 -0
  829. data/spec/support/aws_utils/base.rb +134 -0
  830. data/spec/support/aws_utils/inspector.rb +224 -0
  831. data/spec/support/aws_utils/orchestrator.rb +370 -0
  832. data/spec/support/aws_utils/provisioner.rb +360 -0
  833. data/spec/support/background_thread_registry.rb +6 -2
  834. data/spec/support/child_process_helper.rb +78 -0
  835. data/spec/support/client_registry.rb +6 -24
  836. data/spec/support/cluster_config.rb +5 -0
  837. data/spec/support/common_shortcuts.rb +43 -0
  838. data/spec/support/constraints.rb +27 -7
  839. data/spec/support/crypt.rb +1 -1
  840. data/spec/support/event_subscriber.rb +184 -84
  841. data/spec/support/keyword_struct.rb +26 -0
  842. data/spec/support/lite_constraints.rb +47 -0
  843. data/spec/support/shared/scram_conversation.rb +100 -0
  844. data/spec/support/shared/server_selector.rb +93 -1
  845. data/spec/support/shared/session.rb +29 -21
  846. data/spec/support/spec_config.rb +76 -21
  847. data/spec/support/spec_organizer.rb +129 -0
  848. data/spec/support/spec_setup.rb +9 -5
  849. data/spec/support/utils.rb +161 -24
  850. metadata +1189 -742
  851. metadata.gz.sig +0 -0
  852. data/lib/mongo/server/connectable.rb +0 -107
  853. data/spec/runners/change_streams.rb +0 -262
  854. data/spec/runners/change_streams/operation.rb +0 -89
  855. data/spec/runners/sdam_monitoring.rb +0 -89
  856. data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +0 -27
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Collection::View::Iterable do
4
+ let(:selector) do
5
+ {}
6
+ end
7
+
8
+ let(:options) do
9
+ {}
10
+ end
11
+
12
+ let(:view) do
13
+ Mongo::Collection::View.new(authorized_collection, selector, options)
14
+ end
15
+
16
+ before do
17
+ authorized_collection.drop
18
+ end
19
+
20
+ describe '#each' do
21
+ context 'when allow_disk_use is provided' do
22
+ let(:options) { { allow_disk_use: true } }
23
+
24
+ # Other cases are adequately covered by spec tests.
25
+ context 'on server versions < 3.2' do
26
+ max_server_fcv '3.0'
27
+
28
+ it 'raises an exception' do
29
+ expect do
30
+ view.each do |document|
31
+ #Do nothing
32
+ end
33
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the allow_disk_use option on this command/)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -239,12 +239,16 @@ describe Mongo::Collection::View::MapReduce do
239
239
  Mongo::Collection::View.new(client[TEST_COLL], selector, view_options)
240
240
  end
241
241
 
242
+ let(:subscriber) { EventSubscriber.new }
243
+
242
244
  let(:client) do
243
- subscribed_client
245
+ authorized_client.tap do |client|
246
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
247
+ end
244
248
  end
245
249
 
246
250
  let(:find_command) do
247
- EventSubscriber.started_events[-1].command
251
+ subscriber.started_events[-1].command
248
252
  end
249
253
 
250
254
  before do
@@ -68,6 +68,20 @@ describe Mongo::Collection::View::Readable do
68
68
  end
69
69
  end
70
70
 
71
+ describe '#allow_disk_use' do
72
+ let(:new_view) do
73
+ view.allow_disk_use
74
+ end
75
+
76
+ it 'sets the flag' do
77
+ expect(new_view.options[:allow_disk_use]).to be true
78
+ end
79
+
80
+ it 'returns the new View' do
81
+ expect(new_view).not_to be(view)
82
+ end
83
+ end
84
+
71
85
  describe '#aggregate' do
72
86
 
73
87
  let(:documents) do
@@ -192,7 +206,7 @@ describe Mongo::Collection::View::Readable do
192
206
 
193
207
  let(:command) do
194
208
  operation
195
- EventSubscriber.started_events.find { |cmd| cmd.command_name == 'mapReduce' }.command
209
+ subscriber.started_events.find { |cmd| cmd.command_name == 'mapReduce' }.command
196
210
  end
197
211
 
198
212
  it_behaves_like 'an operation supporting causally consistent reads'
@@ -10,8 +10,12 @@ describe Mongo::Collection::View::Writable do
10
10
  {}
11
11
  end
12
12
 
13
+ let(:view_collection) do
14
+ authorized_collection
15
+ end
16
+
13
17
  let(:view) do
14
- Mongo::Collection::View.new(authorized_collection, selector, options)
18
+ Mongo::Collection::View.new(view_collection, selector, options)
15
19
  end
16
20
 
17
21
  before do
@@ -24,6 +28,32 @@ describe Mongo::Collection::View::Writable do
24
28
  authorized_collection.insert_many([{ field: 'test1' }])
25
29
  end
26
30
 
31
+ context 'when hint option is provided' do
32
+ # Functionality on more recent servers is sufficiently covered by spec tests.
33
+ context 'on server versions < 4.2' do
34
+ max_server_fcv '4.0'
35
+
36
+ it 'raises a client-side exception' do
37
+ expect do
38
+ view.find_one_and_delete(hint: '_id_')
39
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
40
+ end
41
+ end
42
+
43
+ context 'when the write concern is unacknowledged' do
44
+ let(:view_collection) do
45
+ client = authorized_client.with(write_concern: { w: 0 })
46
+ client[authorized_collection.name]
47
+ end
48
+
49
+ it 'raises a client-side error' do
50
+ expect do
51
+ view.find_one_and_delete(hint: '_id_')
52
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
53
+ end
54
+ end
55
+ end
56
+
27
57
  context 'when a matching document is found' do
28
58
 
29
59
  let(:selector) do
@@ -218,6 +248,32 @@ describe Mongo::Collection::View::Writable do
218
248
  authorized_collection.insert_many([{ field: 'test1', other: 'sth' }])
219
249
  end
220
250
 
251
+ context 'when hint option is provided' do
252
+ # Functionality on more recent servers is sufficiently covered by spec tests.
253
+ context 'on server versions < 4.2' do
254
+ max_server_fcv '4.0'
255
+
256
+ it 'raises a client-side exception' do
257
+ expect do
258
+ view.find_one_and_replace({ field: 'testing' }, { hint: '_id_' })
259
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
260
+ end
261
+ end
262
+
263
+ context 'when the write concern is unacknowledged' do
264
+ let(:view_collection) do
265
+ client = authorized_client.with(write_concern: { w: 0 })
266
+ client[authorized_collection.name]
267
+ end
268
+
269
+ it 'raises a client-side error' do
270
+ expect do
271
+ view.find_one_and_replace({ field: 'testing' }, { hint: '_id_' })
272
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
273
+ end
274
+ end
275
+ end
276
+
221
277
  context 'when a matching document is found' do
222
278
 
223
279
  let(:selector) do
@@ -435,6 +491,32 @@ describe Mongo::Collection::View::Writable do
435
491
  authorized_collection.insert_many([{ field: 'test1' }])
436
492
  end
437
493
 
494
+ context 'when hint option is provided' do
495
+ # Functionality on more recent servers is sufficiently covered by spec tests.
496
+ context 'on server versions < 4.2' do
497
+ max_server_fcv '4.0'
498
+
499
+ it 'raises a client-side exception' do
500
+ expect do
501
+ view.find_one_and_update({ '$set' => { field: 'testing' } }, { hint: '_id_' })
502
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
503
+ end
504
+ end
505
+
506
+ context 'when the write concern is unacknowledged' do
507
+ let(:view_collection) do
508
+ client = authorized_client.with(write_concern: { w: 0 })
509
+ client[authorized_collection.name]
510
+ end
511
+
512
+ it 'raises a client-side error' do
513
+ expect do
514
+ view.find_one_and_update({ '$set' => { field: 'testing' } }, { hint: '_id_' })
515
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
516
+ end
517
+ end
518
+ end
519
+
438
520
  context 'when a matching document is found' do
439
521
 
440
522
  let(:selector) do
@@ -625,6 +707,31 @@ describe Mongo::Collection::View::Writable do
625
707
  end
626
708
 
627
709
  describe '#delete_many' do
710
+ context 'when a hint option is provided' do
711
+ # Functionality on more recent servers is sufficiently covered by spec tests.
712
+ context 'on server versions < 3.4' do
713
+ max_server_fcv '3.2'
714
+
715
+ it 'raises a client-side exception' do
716
+ expect do
717
+ view.delete_many(hint: '_id_')
718
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
719
+ end
720
+ end
721
+
722
+ context 'when the write concern is unacknowledged' do
723
+ let(:view_collection) do
724
+ client = authorized_client.with(write_concern: { w: 0 })
725
+ client[authorized_collection.name]
726
+ end
727
+
728
+ it 'raises a client-side error' do
729
+ expect do
730
+ view.delete_many(hint: '_id_')
731
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
732
+ end
733
+ end
734
+ end
628
735
 
629
736
  context 'when a selector was provided' do
630
737
 
@@ -787,6 +894,31 @@ describe Mongo::Collection::View::Writable do
787
894
  end
788
895
 
789
896
  describe '#delete_one' do
897
+ context 'when a hint option is provided' do
898
+ # Functionality on more recent servers is sufficiently covered by spec tests.
899
+ context 'on server versions < 3.4' do
900
+ max_server_fcv '3.2'
901
+
902
+ it 'raises a client-side exception' do
903
+ expect do
904
+ view.delete_one(hint: '_id_')
905
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
906
+ end
907
+ end
908
+
909
+ context 'when the write concern is unacknowledged' do
910
+ let(:view_collection) do
911
+ client = authorized_client.with(write_concern: { w: 0 })
912
+ client[authorized_collection.name]
913
+ end
914
+
915
+ it 'raises a client-side error' do
916
+ expect do
917
+ view.delete_many(hint: '_id_')
918
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
919
+ end
920
+ end
921
+ end
790
922
 
791
923
  context 'when a selector was provided' do
792
924
 
@@ -950,6 +1082,31 @@ describe Mongo::Collection::View::Writable do
950
1082
  end
951
1083
 
952
1084
  describe '#replace_one' do
1085
+ context 'when a hint option is provided' do
1086
+ # Functionality on more recent servers is sufficiently covered by spec tests.
1087
+ context 'on server versions < 3.4' do
1088
+ max_server_fcv '3.2'
1089
+
1090
+ it 'raises a client-side exception' do
1091
+ expect do
1092
+ view.replace_one({ field: 'testing' }, { hint: '_id_' })
1093
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
1094
+ end
1095
+ end
1096
+
1097
+ context 'when the write concern is unacknowledged' do
1098
+ let(:view_collection) do
1099
+ client = authorized_client.with(write_concern: { w: 0 })
1100
+ client[authorized_collection.name]
1101
+ end
1102
+
1103
+ it 'raises a client-side error' do
1104
+ expect do
1105
+ view.delete_many(hint: '_id_')
1106
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
1107
+ end
1108
+ end
1109
+ end
953
1110
 
954
1111
  context 'when a selector was provided' do
955
1112
 
@@ -1182,6 +1339,31 @@ describe Mongo::Collection::View::Writable do
1182
1339
  end
1183
1340
 
1184
1341
  describe '#update_many' do
1342
+ context 'when a hint option is provided' do
1343
+ # Functionality on more recent servers is sufficiently covered by spec tests.
1344
+ context 'on server versions < 3.4' do
1345
+ max_server_fcv '3.2'
1346
+
1347
+ it 'raises a client-side exception' do
1348
+ expect do
1349
+ view.update_many({ '$set' => { field: 'testing' } }, { hint: '_id_' })
1350
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
1351
+ end
1352
+ end
1353
+
1354
+ context 'when the write concern is unacknowledged' do
1355
+ let(:view_collection) do
1356
+ client = authorized_client.with(write_concern: { w: 0 })
1357
+ client[authorized_collection.name]
1358
+ end
1359
+
1360
+ it 'raises a client-side error' do
1361
+ expect do
1362
+ view.delete_many(hint: '_id_')
1363
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
1364
+ end
1365
+ end
1366
+ end
1185
1367
 
1186
1368
  context 'when a selector was provided' do
1187
1369
 
@@ -1420,6 +1602,31 @@ describe Mongo::Collection::View::Writable do
1420
1602
  end
1421
1603
 
1422
1604
  describe '#update_one' do
1605
+ context 'when a hint option is provided' do
1606
+ # Functionality on more recent servers is sufficiently covered by spec tests.
1607
+ context 'on server versions < 3.4' do
1608
+ max_server_fcv '3.2'
1609
+
1610
+ it 'raises a client-side exception' do
1611
+ expect do
1612
+ view.update_one({ '$set' => { field: 'testing' } }, { hint: '_id_' })
1613
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The MongoDB server handling this request does not support the hint option on this command./)
1614
+ end
1615
+ end
1616
+
1617
+ context 'when the write concern is unacknowledged' do
1618
+ let(:view_collection) do
1619
+ client = authorized_client.with(write_concern: { w: 0 })
1620
+ client[authorized_collection.name]
1621
+ end
1622
+
1623
+ it 'raises a client-side error' do
1624
+ expect do
1625
+ view.update_one({ '$set' => { field: 'testing' } }, { hint: '_id_' })
1626
+ end.to raise_error(Mongo::Error::UnsupportedOption, /The hint option cannot be specified on an unacknowledged write operation/)
1627
+ end
1628
+ end
1629
+ end
1423
1630
 
1424
1631
  context 'when a selector was provided' do
1425
1632
 
@@ -2,8 +2,18 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongo::Collection do
4
4
 
5
+ let(:subscriber) { EventSubscriber.new }
6
+
7
+ let(:client) do
8
+ authorized_client.tap do |client|
9
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
10
+ end
11
+ end
12
+
13
+ let(:authorized_collection) { client['collection_spec'] }
14
+
5
15
  before do
6
- authorized_collection.drop
16
+ authorized_client['collection_spec'].drop
7
17
  end
8
18
 
9
19
  let(:collection_invalid_write_concern) do
@@ -14,10 +24,6 @@ describe Mongo::Collection do
14
24
  authorized_client[:validating]
15
25
  end
16
26
 
17
- let(:client) do
18
- authorized_client
19
- end
20
-
21
27
  describe '#==' do
22
28
 
23
29
  let(:database) do
@@ -246,6 +252,7 @@ describe Mongo::Collection do
246
252
  authorized_client.with(client_options).tap do |client|
247
253
  expect(client.options[:read]).to eq(Mongo::Options::Redacted.new(
248
254
  mode: :primary_preferred))
255
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
249
256
  end
250
257
  end
251
258
 
@@ -278,12 +285,6 @@ describe Mongo::Collection do
278
285
  {read: { mode: :primary_preferred }}
279
286
  end
280
287
 
281
- let(:subscriber) { EventSubscriber.new }
282
-
283
- before do
284
- client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
285
- end
286
-
287
288
  shared_examples_for "uses collection's read preference when reading" do
288
289
  it "uses collection's read preference when reading" do
289
290
  expect do
@@ -940,6 +941,30 @@ describe Mongo::Collection do
940
941
  it_behaves_like 'a failed operation using a session'
941
942
  end
942
943
  end
944
+
945
+ context 'when collation has a strength' do
946
+ min_server_fcv '3.4'
947
+
948
+ let(:band_collection) do
949
+ described_class.new(database, :bands)
950
+ end
951
+
952
+ before do
953
+ band_collection.delete_many
954
+ band_collection.insert_many([{ name: "Depeche Mode" }, { name: "New Order" }])
955
+ end
956
+
957
+ let(:options) do
958
+ { collation: { locale: 'en_US', strength: 2 } }
959
+ end
960
+ let(:band_result) do
961
+ band_collection.find({ name: 'DEPECHE MODE' }, options)
962
+ end
963
+
964
+ it 'finds Capitalize from UPPER CASE' do
965
+ expect(band_result.count_documents).to eq(1)
966
+ end
967
+ end
943
968
  end
944
969
 
945
970
  describe '#drop' do
@@ -1206,10 +1231,6 @@ describe Mongo::Collection do
1206
1231
  { session: session }
1207
1232
  end
1208
1233
 
1209
- let(:client) do
1210
- subscribed_client
1211
- end
1212
-
1213
1234
  let(:session) do
1214
1235
  client.start_session
1215
1236
  end
@@ -1220,7 +1241,7 @@ describe Mongo::Collection do
1220
1241
 
1221
1242
  let(:command) do
1222
1243
  client[TEST_COLL].find({}, session: session).explain
1223
- EventSubscriber.started_events.find { |c| c.command_name == 'explain' }.command
1244
+ subscriber.started_events.find { |c| c.command_name == 'explain' }.command
1224
1245
  end
1225
1246
 
1226
1247
  it 'sends the session id' do
@@ -1237,7 +1258,7 @@ describe Mongo::Collection do
1237
1258
 
1238
1259
  let(:command) do
1239
1260
  operation
1240
- EventSubscriber.started_events.find { |cmd| cmd.command_name == 'find' }.command
1261
+ subscriber.started_events.find { |cmd| cmd.command_name == 'find' }.command
1241
1262
  end
1242
1263
 
1243
1264
  it_behaves_like 'an operation supporting causally consistent reads'
@@ -1437,7 +1458,7 @@ describe Mongo::Collection do
1437
1458
  context 'when unacknowledged writes is used with an implicit session' do
1438
1459
 
1439
1460
  let(:collection_with_unacknowledged_write_concern) do
1440
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
1461
+ client.with(write: { w: 0 })[TEST_COLL]
1441
1462
  end
1442
1463
 
1443
1464
  let(:operation) do
@@ -1519,20 +1540,16 @@ describe Mongo::Collection do
1519
1540
  context 'when the documents are sent with OP_MSG' do
1520
1541
  min_server_fcv '3.6'
1521
1542
 
1522
- let(:client) do
1523
- subscribed_client
1524
- end
1525
-
1526
1543
  let(:documents) do
1527
1544
  [{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
1528
1545
  end
1529
1546
 
1530
1547
  before do
1531
- client[TEST_COLL].insert_many(documents)
1548
+ authorized_collection.insert_many(documents)
1532
1549
  end
1533
1550
 
1534
1551
  let(:insert_events) do
1535
- EventSubscriber.started_events.select { |e| e.command_name == 'insert' }
1552
+ subscriber.started_events.select { |e| e.command_name == 'insert' }
1536
1553
  end
1537
1554
 
1538
1555
  it 'sends the documents in one OP_MSG' do
@@ -1608,6 +1625,40 @@ describe Mongo::Collection do
1608
1625
  expect(result.inserted_count).to be(0)
1609
1626
  end
1610
1627
  end
1628
+
1629
+ context 'when various options passed in' do
1630
+ # w: 2 requires a replica set
1631
+ require_topology :replica_set
1632
+
1633
+ # https://jira.mongodb.org/browse/RUBY-2306
1634
+ min_server_fcv '3.6'
1635
+
1636
+ let(:session) do
1637
+ authorized_client.start_session
1638
+ end
1639
+
1640
+ let(:events) do
1641
+ subscriber.command_started_events('insert')
1642
+ end
1643
+
1644
+ let(:collection) do
1645
+ authorized_collection.with(write_concern: {w: 2})
1646
+ end
1647
+
1648
+ let!(:command) do
1649
+ Utils.get_command_event(authorized_client, 'insert') do |client|
1650
+ collection.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session,
1651
+ write_concern: {w: 1}, bypass_document_validation: true)
1652
+ end.command
1653
+ end
1654
+
1655
+ it 'inserts many successfully with correct options sent to server' do
1656
+ expect(events.length).to eq(1)
1657
+ expect(command[:writeConcern]).to_not be_nil
1658
+ expect(command[:writeConcern][:w]).to eq(1)
1659
+ expect(command[:bypassDocumentValidation]).to be(true)
1660
+ end
1661
+ end
1611
1662
  end
1612
1663
 
1613
1664
  describe '#insert_one' do
@@ -1680,7 +1731,7 @@ describe Mongo::Collection do
1680
1731
  context 'when unacknowledged writes is used with an implicit session' do
1681
1732
 
1682
1733
  let(:collection_with_unacknowledged_write_concern) do
1683
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
1734
+ client.with(write: { w: 0 })[TEST_COLL]
1684
1735
  end
1685
1736
 
1686
1737
  let(:operation) do
@@ -1690,6 +1741,37 @@ describe Mongo::Collection do
1690
1741
  it_behaves_like 'an implicit session with an unacknowledged write'
1691
1742
  end
1692
1743
 
1744
+ context 'when various options passed in' do
1745
+ # https://jira.mongodb.org/browse/RUBY-2306
1746
+ min_server_fcv '3.6'
1747
+
1748
+ let(:session) do
1749
+ authorized_client.start_session
1750
+ end
1751
+
1752
+ let(:events) do
1753
+ subscriber.command_started_events('insert')
1754
+ end
1755
+
1756
+ let(:collection) do
1757
+ authorized_collection.with(write_concern: {w: 3})
1758
+ end
1759
+
1760
+ let!(:command) do
1761
+ Utils.get_command_event(authorized_client, 'insert') do |client|
1762
+ collection.insert_one({name: 'test1'}, session: session, write_concern: {w: 1},
1763
+ bypass_document_validation: true)
1764
+ end.command
1765
+ end
1766
+
1767
+ it 'inserts one successfully with correct options sent to server' do
1768
+ expect(events.length).to eq(1)
1769
+ expect(command[:writeConcern]).to_not be_nil
1770
+ expect(command[:writeConcern][:w]).to eq(1)
1771
+ expect(command[:bypassDocumentValidation]).to be(true)
1772
+ end
1773
+ end
1774
+
1693
1775
  context 'when the document contains invalid keys' do
1694
1776
 
1695
1777
  let(:doc) do
@@ -1798,6 +1880,52 @@ describe Mongo::Collection do
1798
1880
  end
1799
1881
  end
1800
1882
 
1883
+ describe '#bulk_write' do
1884
+
1885
+ context 'when various options passed in' do
1886
+ min_server_fcv '3.2'
1887
+ require_topology :replica_set
1888
+
1889
+ # https://jira.mongodb.org/browse/RUBY-2306
1890
+ min_server_fcv '3.6'
1891
+
1892
+ let(:requests) do
1893
+ [
1894
+ { insert_one: { name: "anne" }},
1895
+ { insert_one: { name: "bob" }},
1896
+ { insert_one: { name: "charlie" }}
1897
+ ]
1898
+ end
1899
+
1900
+ let(:session) do
1901
+ authorized_client.start_session
1902
+ end
1903
+
1904
+ let!(:command) do
1905
+ Utils.get_command_event(authorized_client, 'insert') do |client|
1906
+ collection.bulk_write(requests, session: session, write_concern: {w: 1},
1907
+ bypass_document_validation: true)
1908
+ end.command
1909
+ end
1910
+
1911
+ let(:events) do
1912
+ subscriber.command_started_events('insert')
1913
+ end
1914
+
1915
+ let(:collection) do
1916
+ authorized_collection.with(write_concern: {w: 2})
1917
+ end
1918
+
1919
+ it 'inserts successfully with correct options sent to server' do
1920
+ expect(collection.count).to eq(3)
1921
+ expect(events.length).to eq(1)
1922
+ expect(command[:writeConcern]).to_not be_nil
1923
+ expect(command[:writeConcern][:w]).to eq(1)
1924
+ expect(command[:bypassDocumentValidation]).to eq(true)
1925
+ end
1926
+ end
1927
+ end
1928
+
1801
1929
  describe '#inspect' do
1802
1930
 
1803
1931
  it 'includes the object id' do
@@ -1890,7 +2018,7 @@ describe Mongo::Collection do
1890
2018
 
1891
2019
  let(:command) do
1892
2020
  operation
1893
- EventSubscriber.started_events.find { |cmd| cmd.command_name == 'aggregate' }.command
2021
+ subscriber.started_events.find { |cmd| cmd.command_name == 'aggregate' }.command
1894
2022
  end
1895
2023
 
1896
2024
  it_behaves_like 'an operation supporting causally consistent reads'
@@ -2007,6 +2135,39 @@ describe Mongo::Collection do
2007
2135
  end
2008
2136
 
2009
2137
  describe '#count_documents' do
2138
+
2139
+ before do
2140
+ authorized_collection.delete_many
2141
+ end
2142
+
2143
+ context 'no argument provided' do
2144
+
2145
+ context 'when collection is empty' do
2146
+ it 'returns 0 matching documents' do
2147
+ expect(authorized_collection.count_documents).to eq(0)
2148
+ end
2149
+ end
2150
+
2151
+ context 'when collection is not empty' do
2152
+
2153
+ let(:documents) do
2154
+ documents = []
2155
+ 1.upto(10) do |index|
2156
+ documents << { key: 'a', _id: "in#{index}" }
2157
+ end
2158
+ documents
2159
+ end
2160
+
2161
+ before do
2162
+ authorized_collection.insert_many(documents)
2163
+ end
2164
+
2165
+ it 'returns 10 matching documents' do
2166
+ expect(authorized_collection.count_documents).to eq(10)
2167
+ end
2168
+ end
2169
+ end
2170
+
2010
2171
  context 'when transactions are enabled' do
2011
2172
  require_wired_tiger
2012
2173
  require_transaction_support
@@ -2095,7 +2256,7 @@ describe Mongo::Collection do
2095
2256
 
2096
2257
  let(:command) do
2097
2258
  operation
2098
- EventSubscriber.started_events.find { |cmd| cmd.command_name == 'count' }.command
2259
+ subscriber.started_events.find { |cmd| cmd.command_name == 'count' }.command
2099
2260
  end
2100
2261
 
2101
2262
  it_behaves_like 'an operation supporting causally consistent reads'
@@ -2213,7 +2374,7 @@ describe Mongo::Collection do
2213
2374
 
2214
2375
  let(:command) do
2215
2376
  operation
2216
- EventSubscriber.started_events.find { |cmd| cmd.command_name == 'distinct' }.command
2377
+ subscriber.started_events.find { |cmd| cmd.command_name == 'distinct' }.command
2217
2378
  end
2218
2379
 
2219
2380
  it_behaves_like 'an operation supporting causally consistent reads'
@@ -2375,7 +2536,7 @@ describe Mongo::Collection do
2375
2536
  context 'when unacknowledged writes is used with an implicit session' do
2376
2537
 
2377
2538
  let(:collection_with_unacknowledged_write_concern) do
2378
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
2539
+ client.with(write: { w: 0 })[TEST_COLL]
2379
2540
  end
2380
2541
 
2381
2542
  let(:operation) do
@@ -2485,6 +2646,48 @@ describe Mongo::Collection do
2485
2646
  expect(authorized_collection.find(name: 'bang').count).to eq(1)
2486
2647
  end
2487
2648
  end
2649
+
2650
+ context 'when various options passed in' do
2651
+ # w: 2 requires a replica set
2652
+ require_topology :replica_set
2653
+
2654
+ # https://jira.mongodb.org/browse/RUBY-2306
2655
+ min_server_fcv '3.6'
2656
+
2657
+ before do
2658
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
2659
+ end
2660
+
2661
+ let(:selector) do
2662
+ {name: 'test2'}
2663
+ end
2664
+
2665
+ let(:session) do
2666
+ authorized_client.start_session
2667
+ end
2668
+
2669
+ let(:events) do
2670
+ subscriber.command_started_events('delete')
2671
+ end
2672
+
2673
+ let(:collection) do
2674
+ authorized_collection.with(write_concern: {w: 2})
2675
+ end
2676
+
2677
+ let!(:command) do
2678
+ Utils.get_command_event(authorized_client, 'delete') do |client|
2679
+ collection.delete_one(selector, session: session, write_concern: {w: 1},
2680
+ bypass_document_validation: true)
2681
+ end.command
2682
+ end
2683
+
2684
+ it 'deletes one successfully with correct options sent to server' do
2685
+ expect(events.length).to eq(1)
2686
+ expect(command[:writeConcern]).to_not be_nil
2687
+ expect(command[:writeConcern][:w]).to eq(1)
2688
+ expect(command[:bypassDocumentValidation]).to eq(true)
2689
+ end
2690
+ end
2488
2691
  end
2489
2692
 
2490
2693
  describe '#delete_many' do
@@ -2547,7 +2750,7 @@ describe Mongo::Collection do
2547
2750
  it_behaves_like 'a failed operation using a session'
2548
2751
  end
2549
2752
 
2550
- context 'when unacknowledged writes is used with an explicit session' do
2753
+ context 'when unacknowledged writes are used with an explicit session' do
2551
2754
 
2552
2755
  let(:collection_with_unacknowledged_write_concern) do
2553
2756
  authorized_collection.with(write: { w: 0 })
@@ -2560,10 +2763,10 @@ describe Mongo::Collection do
2560
2763
  it_behaves_like 'an explicit session with an unacknowledged write'
2561
2764
  end
2562
2765
 
2563
- context 'when unacknowledged writes is used with an implicit session' do
2766
+ context 'when unacknowledged writes are used with an implicit session' do
2564
2767
 
2565
2768
  let(:collection_with_unacknowledged_write_concern) do
2566
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
2769
+ client.with(write: { w: 0 })[TEST_COLL]
2567
2770
  end
2568
2771
 
2569
2772
  let(:operation) do
@@ -2675,6 +2878,48 @@ describe Mongo::Collection do
2675
2878
  expect(authorized_collection.find(name: 'bang').count).to eq(2)
2676
2879
  end
2677
2880
  end
2881
+
2882
+ context 'when various options passed in' do
2883
+ # w: 2 requires a replica set
2884
+ require_topology :replica_set
2885
+
2886
+ # https://jira.mongodb.org/browse/RUBY-2306
2887
+ min_server_fcv '3.6'
2888
+
2889
+ before do
2890
+ collection.insert_many([{ name: 'test1' }, { name: 'test2' }, { name: 'test3'}])
2891
+ end
2892
+
2893
+ let(:selector) do
2894
+ {name: 'test1'}
2895
+ end
2896
+
2897
+ let(:session) do
2898
+ authorized_client.start_session
2899
+ end
2900
+
2901
+ let(:events) do
2902
+ subscriber.command_started_events('delete')
2903
+ end
2904
+
2905
+ let(:collection) do
2906
+ authorized_collection.with(write_concern: {w: 1})
2907
+ end
2908
+
2909
+ let!(:command) do
2910
+ Utils.get_command_event(authorized_client, 'delete') do |client|
2911
+ collection.delete_many(selector, session: session, write_concern: {w: 2},
2912
+ bypass_document_validation: true)
2913
+ end.command
2914
+ end
2915
+
2916
+ it 'deletes many successfully with correct options sent to server' do
2917
+ expect(events.length).to eq(1)
2918
+ expect(command[:writeConcern]).to_not be_nil
2919
+ expect(command[:writeConcern][:w]).to eq(2)
2920
+ expect(command[:bypassDocumentValidation]).to be(true)
2921
+ end
2922
+ end
2678
2923
  end
2679
2924
 
2680
2925
  describe '#parallel_scan' do
@@ -2731,7 +2976,6 @@ describe Mongo::Collection do
2731
2976
  end
2732
2977
 
2733
2978
  context 'when a session is not provided' do
2734
- let(:client) { subscribed_client }
2735
2979
  let(:collection) { client['test'] }
2736
2980
 
2737
2981
  let(:cursors) do
@@ -2748,7 +2992,7 @@ describe Mongo::Collection do
2748
2992
 
2749
2993
  let(:command) do
2750
2994
  operation
2751
- event = EventSubscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
2995
+ event = subscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
2752
2996
  expect(event).not_to be_nil
2753
2997
  event.command
2754
2998
  end
@@ -2770,7 +3014,7 @@ describe Mongo::Collection do
2770
3014
 
2771
3015
  let(:command) do
2772
3016
  operation
2773
- event = EventSubscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
3017
+ event = subscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
2774
3018
  expect(event).not_to be_nil
2775
3019
  event.command
2776
3020
  end
@@ -3173,7 +3417,7 @@ describe Mongo::Collection do
3173
3417
  context 'when unacknowledged writes is used with an implicit session' do
3174
3418
 
3175
3419
  let(:collection_with_unacknowledged_write_concern) do
3176
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
3420
+ client.with(write: { w: 0 })[TEST_COLL]
3177
3421
  end
3178
3422
 
3179
3423
  let(:operation) do
@@ -3182,6 +3426,51 @@ describe Mongo::Collection do
3182
3426
 
3183
3427
  it_behaves_like 'an implicit session with an unacknowledged write'
3184
3428
  end
3429
+
3430
+ context 'when various options passed in' do
3431
+ # w: 2 requires a replica set
3432
+ require_topology :replica_set
3433
+
3434
+ # https://jira.mongodb.org/browse/RUBY-2306
3435
+ min_server_fcv '3.6'
3436
+
3437
+ before do
3438
+ authorized_collection.insert_one({field: 'test1'})
3439
+ end
3440
+
3441
+ let(:session) do
3442
+ authorized_client.start_session
3443
+ end
3444
+
3445
+ let(:events) do
3446
+ subscriber.command_started_events('update')
3447
+ end
3448
+
3449
+ let(:collection) do
3450
+ authorized_collection.with(write_concern: {w: 3})
3451
+ end
3452
+
3453
+ let(:updated) do
3454
+ collection.find(field: 'test4').first
3455
+ end
3456
+
3457
+ let!(:command) do
3458
+ Utils.get_command_event(authorized_client, 'update') do |client|
3459
+ collection.replace_one(selector, { field: 'test4'},
3460
+ session: session, :return_document => :after, write_concern: {w: 2},
3461
+ upsert: true, bypass_document_validation: true)
3462
+ end.command
3463
+ end
3464
+
3465
+ it 'replaced one successfully with correct options sent to server' do
3466
+ expect(updated[:field]).to eq('test4')
3467
+ expect(events.length).to eq(1)
3468
+ expect(command[:writeConcern]).to_not be_nil
3469
+ expect(command[:writeConcern][:w]).to eq(2)
3470
+ expect(command[:bypassDocumentValidation]).to be(true)
3471
+ expect(command[:updates][0][:upsert]).to be(true)
3472
+ end
3473
+ end
3185
3474
  end
3186
3475
 
3187
3476
  describe '#update_many' do
@@ -3595,7 +3884,7 @@ describe Mongo::Collection do
3595
3884
  context 'when unacknowledged writes is used with an implicit session' do
3596
3885
 
3597
3886
  let(:collection_with_unacknowledged_write_concern) do
3598
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
3887
+ client.with(write: { w: 0 })[TEST_COLL]
3599
3888
  end
3600
3889
 
3601
3890
  let(:operation) do
@@ -3604,6 +3893,45 @@ describe Mongo::Collection do
3604
3893
 
3605
3894
  it_behaves_like 'an implicit session with an unacknowledged write'
3606
3895
  end
3896
+
3897
+ context 'when various options passed in' do
3898
+ # w: 2 requires a replica set
3899
+ require_topology :replica_set
3900
+
3901
+ # https://jira.mongodb.org/browse/RUBY-2306
3902
+ min_server_fcv '3.6'
3903
+
3904
+ before do
3905
+ collection.insert_many([{ field: 'test' }, { field: 'test2' }], session: session)
3906
+ end
3907
+
3908
+ let(:session) do
3909
+ authorized_client.start_session
3910
+ end
3911
+
3912
+ let(:collection) do
3913
+ authorized_collection.with(write_concern: {w: 1})
3914
+ end
3915
+
3916
+ let(:events) do
3917
+ subscriber.command_started_events('update')
3918
+ end
3919
+
3920
+ let!(:command) do
3921
+ Utils.get_command_event(authorized_client, 'update') do |client|
3922
+ collection.update_many(selector, {'$set'=> { field: 'testing' }}, session: session,
3923
+ write_concern: {w: 2}, bypass_document_validation: true, upsert: true)
3924
+ end.command
3925
+ end
3926
+
3927
+ it 'updates many successfully with correct options sent to server' do
3928
+ expect(events.length).to eq(1)
3929
+ expect(collection.options[:write_concern]).to eq(w: 1)
3930
+ expect(command[:writeConcern][:w]).to eq(2)
3931
+ expect(command[:bypassDocumentValidation]).to be(true)
3932
+ expect(command[:updates][0][:upsert]).to be(true)
3933
+ end
3934
+ end
3607
3935
  end
3608
3936
 
3609
3937
  describe '#update_one' do
@@ -3953,10 +4281,6 @@ describe Mongo::Collection do
3953
4281
  context 'when the documents are sent with OP_MSG' do
3954
4282
  min_server_fcv '3.6'
3955
4283
 
3956
- let(:client) do
3957
- subscribed_client
3958
- end
3959
-
3960
4284
  let(:documents) do
3961
4285
  [{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
3962
4286
  end
@@ -3967,7 +4291,7 @@ describe Mongo::Collection do
3967
4291
  end
3968
4292
 
3969
4293
  let(:update_events) do
3970
- EventSubscriber.started_events.select { |e| e.command_name == 'update' }
4294
+ subscriber.started_events.select { |e| e.command_name == 'update' }
3971
4295
  end
3972
4296
 
3973
4297
  it 'sends the documents in one OP_MSG' do
@@ -4017,7 +4341,7 @@ describe Mongo::Collection do
4017
4341
  context 'when unacknowledged writes is used with an implicit session' do
4018
4342
 
4019
4343
  let(:collection_with_unacknowledged_write_concern) do
4020
- subscribed_client.with(write: { w: 0 })[TEST_COLL]
4344
+ client.with(write: { w: 0 })[TEST_COLL]
4021
4345
  end
4022
4346
 
4023
4347
  let(:operation) do
@@ -4026,6 +4350,47 @@ describe Mongo::Collection do
4026
4350
 
4027
4351
  it_behaves_like 'an implicit session with an unacknowledged write'
4028
4352
  end
4353
+
4354
+ context 'when various options passed in' do
4355
+ # w: 2 requires a replica set
4356
+ require_topology :replica_set
4357
+
4358
+ # https://jira.mongodb.org/browse/RUBY-2306
4359
+ min_server_fcv '3.6'
4360
+
4361
+ before do
4362
+ collection.insert_many([{ field: 'test1' }, { field: 'test2' }], session: session)
4363
+ end
4364
+
4365
+ let(:session) do
4366
+ authorized_client.start_session
4367
+ end
4368
+
4369
+ let(:collection) do
4370
+ authorized_collection.with(write_concern: {w: 1})
4371
+ end
4372
+
4373
+ let(:events) do
4374
+ subscriber.command_started_events('update')
4375
+ end
4376
+
4377
+ let!(:command) do
4378
+ Utils.get_command_event(authorized_client, 'update') do |client|
4379
+ collection.update_one(selector, { '$set'=> { field: 'testing' } }, session: session,
4380
+ write_concern: {w: 2}, bypass_document_validation: true, :return_document => :after,
4381
+ upsert: true)
4382
+ end.command
4383
+ end
4384
+
4385
+ it 'updates one successfully with correct options sent to server' do
4386
+ expect(events.length).to eq(1)
4387
+ expect(command[:writeConcern]).to_not be_nil
4388
+ expect(command[:writeConcern][:w]).to eq(2)
4389
+ expect(collection.options[:write_concern]).to eq(w:1)
4390
+ expect(command[:bypassDocumentValidation]).to be(true)
4391
+ expect(command[:updates][0][:upsert]).to be(true)
4392
+ end
4393
+ end
4029
4394
  end
4030
4395
 
4031
4396
  describe '#find_one_and_delete' do
@@ -4243,6 +4608,46 @@ describe Mongo::Collection do
4243
4608
  expect(result).to be_nil
4244
4609
  end
4245
4610
  end
4611
+
4612
+ context 'when various options passed in' do
4613
+ # w: 2 requires a replica set
4614
+ require_topology :replica_set
4615
+
4616
+ # https://jira.mongodb.org/browse/RUBY-2306
4617
+ min_server_fcv '3.6'
4618
+
4619
+ before do
4620
+ authorized_collection.delete_many
4621
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
4622
+ end
4623
+
4624
+ let(:collection) do
4625
+ authorized_collection.with(write_concern: {w: 2})
4626
+ end
4627
+
4628
+ let(:session) do
4629
+ authorized_client.start_session
4630
+ end
4631
+
4632
+ let!(:command) do
4633
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
4634
+ collection.find_one_and_delete(selector, session: session, write_concern: {w: 2},
4635
+ bypass_document_validation: true, max_time_ms: 300)
4636
+ end.command
4637
+ end
4638
+
4639
+ let(:events) do
4640
+ subscriber.command_started_events('findAndModify')
4641
+ end
4642
+
4643
+ it 'finds and deletes successfully with correct options sent to server' do
4644
+ expect(events.length).to eq(1)
4645
+ expect(command[:writeConcern]).to_not be_nil
4646
+ expect(command[:writeConcern][:w]).to eq(2)
4647
+ expect(command[:bypassDocumentValidation]).to eq(true)
4648
+ expect(command[:maxTimeMS]).to eq(300)
4649
+ end
4650
+ end
4246
4651
  end
4247
4652
 
4248
4653
  describe '#find_one_and_update' do
@@ -4664,6 +5069,51 @@ describe Mongo::Collection do
4664
5069
  end
4665
5070
  end
4666
5071
  end
5072
+
5073
+ context 'when various options passed in' do
5074
+ # w: 2 requires a replica set
5075
+ require_topology :replica_set
5076
+
5077
+ # https://jira.mongodb.org/browse/RUBY-2306
5078
+ min_server_fcv '3.6'
5079
+
5080
+ let(:session) do
5081
+ authorized_client.start_session
5082
+ end
5083
+
5084
+ let(:events) do
5085
+ subscriber.command_started_events('findAndModify')
5086
+ end
5087
+
5088
+ let(:collection) do
5089
+ authorized_collection.with(write_concern: {w: 2})
5090
+ end
5091
+
5092
+ let(:selector) do
5093
+ {field: 'test1'}
5094
+ end
5095
+
5096
+ before do
5097
+ collection.insert_one({field: 'test1'}, session: session)
5098
+ end
5099
+
5100
+ let!(:command) do
5101
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
5102
+ collection.find_one_and_update(selector, { '$set' => {field: 'testing'}},
5103
+ :return_document => :after, write_concern: {w: 1}, upsert: true,
5104
+ bypass_document_validation: true, max_time_ms: 100, session: session)
5105
+ end.command
5106
+ end
5107
+
5108
+ it 'find and updates successfully with correct options sent to server' do
5109
+ expect(events.length).to eq(1)
5110
+ expect(command[:writeConcern]).to_not be_nil
5111
+ expect(command[:writeConcern][:w]).to eq(1)
5112
+ expect(command[:upsert]).to eq(true)
5113
+ expect(command[:bypassDocumentValidation]).to be(true)
5114
+ expect(command[:maxTimeMS]).to eq(100)
5115
+ end
5116
+ end
4667
5117
  end
4668
5118
 
4669
5119
  describe '#find_one_and_replace' do
@@ -4977,6 +5427,44 @@ describe Mongo::Collection do
4977
5427
  expect(result).to be_nil
4978
5428
  end
4979
5429
  end
5430
+
5431
+ context 'when various options passed in' do
5432
+ # https://jira.mongodb.org/browse/RUBY-2306
5433
+ min_server_fcv '3.6'
5434
+
5435
+ before do
5436
+ authorized_collection.insert_one({field: 'test1'})
5437
+ end
5438
+
5439
+ let(:session) do
5440
+ authorized_client.start_session
5441
+ end
5442
+
5443
+ let(:events) do
5444
+ subscriber.command_started_events('findAndModify')
5445
+ end
5446
+
5447
+ let(:collection) do
5448
+ authorized_collection.with(write_concern: { w: 2 })
5449
+ end
5450
+
5451
+ let!(:command) do
5452
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
5453
+ collection.find_one_and_replace(selector, { '$set' => {field: 'test5'}},
5454
+ :return_document => :after, write_concern: {w: 1}, session: session,
5455
+ upsert: true, bypass_document_validation: false, max_time_ms: 200)
5456
+ end.command
5457
+ end
5458
+
5459
+ it 'find and replaces successfully with correct options sent to server' do
5460
+ expect(events.length).to eq(1)
5461
+ expect(command[:writeConcern]).to_not be_nil
5462
+ expect(command[:writeConcern][:w]).to eq(1)
5463
+ expect(command[:upsert]).to be(true)
5464
+ expect(command[:bypassDocumentValidation]).to be_nil
5465
+ expect(command[:maxTimeMS]).to eq(200)
5466
+ end
5467
+ end
4980
5468
  end
4981
5469
 
4982
5470
  describe '#watch' do