mongo 2.13.1 → 2.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1899) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +36 -39
  4. data/Rakefile +49 -20
  5. data/bin/mongo_console +2 -0
  6. data/lib/mongo/active_support.rb +3 -0
  7. data/lib/mongo/address/ipv4.rb +4 -1
  8. data/lib/mongo/address/ipv6.rb +4 -1
  9. data/lib/mongo/address/unix.rb +3 -0
  10. data/lib/mongo/address/validator.rb +3 -0
  11. data/lib/mongo/address.rb +4 -1
  12. data/lib/mongo/auth/aws/conversation.rb +4 -8
  13. data/lib/mongo/auth/aws/credentials.rb +38 -0
  14. data/lib/mongo/auth/aws/credentials_cache.rb +75 -0
  15. data/lib/mongo/auth/aws/credentials_retriever.rb +174 -36
  16. data/lib/mongo/auth/aws/request.rb +3 -2
  17. data/lib/mongo/auth/aws.rb +8 -5
  18. data/lib/mongo/auth/base.rb +25 -9
  19. data/lib/mongo/auth/conversation_base.rb +35 -0
  20. data/lib/mongo/auth/cr/conversation.rb +9 -29
  21. data/lib/mongo/auth/cr.rb +3 -0
  22. data/lib/mongo/auth/credential_cache.rb +3 -0
  23. data/lib/mongo/auth/gssapi/conversation.rb +7 -15
  24. data/lib/mongo/auth/gssapi.rb +3 -0
  25. data/lib/mongo/auth/ldap/conversation.rb +6 -14
  26. data/lib/mongo/auth/ldap.rb +3 -0
  27. data/lib/mongo/auth/roles.rb +19 -16
  28. data/lib/mongo/auth/sasl_conversation_base.rb +4 -13
  29. data/lib/mongo/auth/scram/conversation.rb +3 -0
  30. data/lib/mongo/auth/scram.rb +5 -2
  31. data/lib/mongo/auth/scram256/conversation.rb +3 -0
  32. data/lib/mongo/auth/scram256.rb +3 -0
  33. data/lib/mongo/auth/scram_conversation_base.rb +10 -34
  34. data/lib/mongo/auth/stringprep/profiles/sasl.rb +3 -0
  35. data/lib/mongo/auth/stringprep/tables.rb +3 -0
  36. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +2 -2
  37. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +2 -1
  38. data/lib/mongo/auth/stringprep.rb +4 -1
  39. data/lib/mongo/auth/user/view.rb +19 -9
  40. data/lib/mongo/auth/user.rb +3 -0
  41. data/lib/mongo/auth/x509/conversation.rb +7 -25
  42. data/lib/mongo/auth/x509.rb +3 -0
  43. data/lib/mongo/auth.rb +16 -2
  44. data/lib/mongo/background_thread.rb +16 -2
  45. data/lib/mongo/bson.rb +3 -0
  46. data/lib/mongo/bulk_write/combineable.rb +3 -0
  47. data/lib/mongo/bulk_write/ordered_combiner.rb +3 -0
  48. data/lib/mongo/bulk_write/result.rb +13 -1
  49. data/lib/mongo/bulk_write/result_combiner.rb +5 -4
  50. data/lib/mongo/bulk_write/transformable.rb +3 -0
  51. data/lib/mongo/bulk_write/unordered_combiner.rb +3 -0
  52. data/lib/mongo/bulk_write/validatable.rb +3 -0
  53. data/lib/mongo/bulk_write.rb +156 -45
  54. data/lib/mongo/caching_cursor.rb +77 -0
  55. data/lib/mongo/client.rb +367 -41
  56. data/lib/mongo/client_encryption.rb +217 -10
  57. data/lib/mongo/cluster/periodic_executor.rb +7 -3
  58. data/lib/mongo/cluster/reapers/cursor_reaper.rb +101 -43
  59. data/lib/mongo/cluster/reapers/socket_reaper.rb +4 -1
  60. data/lib/mongo/cluster/sdam_flow.rb +67 -17
  61. data/lib/mongo/cluster/topology/base.rb +16 -9
  62. data/lib/mongo/cluster/topology/load_balanced.rb +102 -0
  63. data/lib/mongo/cluster/topology/no_replica_set_options.rb +3 -0
  64. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -0
  65. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +3 -0
  66. data/lib/mongo/cluster/topology/sharded.rb +3 -0
  67. data/lib/mongo/cluster/topology/single.rb +4 -1
  68. data/lib/mongo/cluster/topology/unknown.rb +3 -0
  69. data/lib/mongo/cluster/topology.rb +31 -8
  70. data/lib/mongo/cluster.rb +210 -116
  71. data/lib/mongo/cluster_time.rb +3 -0
  72. data/lib/mongo/collection/helpers.rb +43 -0
  73. data/lib/mongo/collection/queryable_encryption.rb +162 -0
  74. data/lib/mongo/collection/view/aggregation.rb +94 -24
  75. data/lib/mongo/collection/view/builder/aggregation.rb +19 -17
  76. data/lib/mongo/collection/view/builder/map_reduce.rb +18 -49
  77. data/lib/mongo/collection/view/builder.rb +3 -4
  78. data/lib/mongo/collection/view/change_stream/retryable.rb +3 -0
  79. data/lib/mongo/collection/view/change_stream.rb +71 -22
  80. data/lib/mongo/collection/view/explainable.rb +30 -8
  81. data/lib/mongo/collection/view/immutable.rb +3 -0
  82. data/lib/mongo/collection/view/iterable.rb +121 -24
  83. data/lib/mongo/collection/view/map_reduce.rb +76 -25
  84. data/lib/mongo/collection/view/readable.rb +147 -67
  85. data/lib/mongo/collection/view/writable.rb +296 -162
  86. data/lib/mongo/collection/view.rb +42 -41
  87. data/lib/mongo/collection.rb +356 -89
  88. data/lib/mongo/condition_variable.rb +58 -0
  89. data/lib/mongo/config/options.rb +63 -0
  90. data/lib/mongo/config/validators/option.rb +27 -0
  91. data/lib/mongo/config.rb +43 -0
  92. data/lib/mongo/crypt/auto_decryption_context.rb +3 -0
  93. data/lib/mongo/crypt/auto_encrypter.rb +142 -15
  94. data/lib/mongo/crypt/auto_encryption_context.rb +3 -0
  95. data/lib/mongo/crypt/binary.rb +3 -0
  96. data/lib/mongo/crypt/binding.rb +717 -151
  97. data/lib/mongo/crypt/context.rb +74 -5
  98. data/lib/mongo/crypt/data_key_context.rb +15 -104
  99. data/lib/mongo/crypt/encryption_io.rb +101 -64
  100. data/lib/mongo/crypt/explicit_decryption_context.rb +3 -0
  101. data/lib/mongo/crypt/explicit_encrypter.rb +235 -29
  102. data/lib/mongo/crypt/explicit_encryption_context.rb +78 -21
  103. data/lib/mongo/crypt/explicit_encryption_expression_context.rb +30 -0
  104. data/lib/mongo/crypt/handle.rb +171 -86
  105. data/lib/mongo/crypt/hooks.rb +28 -2
  106. data/lib/mongo/crypt/kms/aws/credentials.rb +83 -0
  107. data/lib/mongo/crypt/kms/aws/master_document.rb +78 -0
  108. data/lib/mongo/crypt/kms/aws.rb +20 -0
  109. data/lib/mongo/crypt/kms/azure/access_token.rb +54 -0
  110. data/lib/mongo/crypt/kms/azure/credentials.rb +103 -0
  111. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +122 -0
  112. data/lib/mongo/crypt/kms/azure/master_document.rb +79 -0
  113. data/lib/mongo/crypt/kms/azure.rb +21 -0
  114. data/lib/mongo/crypt/kms/credentials.rb +96 -0
  115. data/lib/mongo/crypt/kms/gcp/credentials.rb +127 -0
  116. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +58 -0
  117. data/lib/mongo/crypt/kms/gcp/master_document.rb +99 -0
  118. data/lib/mongo/crypt/kms/gcp.rb +21 -0
  119. data/lib/mongo/crypt/kms/kmip/credentials.rb +68 -0
  120. data/lib/mongo/crypt/kms/kmip/master_document.rb +74 -0
  121. data/lib/mongo/crypt/kms/kmip.rb +19 -0
  122. data/lib/mongo/crypt/kms/local/credentials.rb +65 -0
  123. data/lib/mongo/crypt/kms/local/master_document.rb +43 -0
  124. data/lib/mongo/crypt/kms/local.rb +19 -0
  125. data/lib/mongo/crypt/kms/master_key_document.rb +65 -0
  126. data/lib/mongo/crypt/kms.rb +122 -0
  127. data/lib/mongo/crypt/kms_context.rb +3 -0
  128. data/lib/mongo/crypt/rewrap_many_data_key_context.rb +46 -0
  129. data/lib/mongo/crypt/rewrap_many_data_key_result.rb +37 -0
  130. data/lib/mongo/crypt/status.rb +11 -2
  131. data/lib/mongo/crypt.rb +18 -0
  132. data/lib/mongo/cursor/kill_spec.rb +76 -0
  133. data/lib/mongo/cursor.rb +150 -43
  134. data/lib/mongo/database/view.rb +55 -10
  135. data/lib/mongo/database.rb +95 -25
  136. data/lib/mongo/dbref.rb +4 -105
  137. data/lib/mongo/distinguishing_semaphore.rb +4 -1
  138. data/lib/mongo/error/auth_error.rb +3 -0
  139. data/lib/mongo/error/bad_load_balancer_target.rb +26 -0
  140. data/lib/mongo/error/bulk_write_error.rb +49 -5
  141. data/lib/mongo/error/change_stream_resumable.rb +3 -0
  142. data/lib/mongo/error/client_closed.rb +24 -0
  143. data/lib/mongo/error/closed_stream.rb +3 -0
  144. data/lib/mongo/error/connection_check_out_timeout.rb +3 -0
  145. data/lib/mongo/error/connection_perished.rb +5 -0
  146. data/lib/mongo/error/connection_unavailable.rb +27 -0
  147. data/lib/mongo/error/credential_check_error.rb +3 -0
  148. data/lib/mongo/error/crypt_error.rb +3 -0
  149. data/lib/mongo/error/extra_file_chunk.rb +3 -0
  150. data/lib/mongo/error/failed_string_prep_validation.rb +3 -0
  151. data/lib/mongo/error/file_not_found.rb +3 -0
  152. data/lib/mongo/error/handshake_error.rb +3 -0
  153. data/lib/mongo/error/insufficient_iteration_count.rb +3 -0
  154. data/lib/mongo/error/internal_driver_error.rb +25 -0
  155. data/lib/mongo/error/invalid_address.rb +3 -0
  156. data/lib/mongo/error/invalid_application_name.rb +3 -0
  157. data/lib/mongo/error/invalid_bulk_operation.rb +3 -0
  158. data/lib/mongo/error/invalid_bulk_operation_type.rb +3 -0
  159. data/lib/mongo/error/invalid_collection_name.rb +3 -0
  160. data/lib/mongo/error/invalid_config_option.rb +21 -0
  161. data/lib/mongo/error/invalid_cursor_operation.rb +3 -0
  162. data/lib/mongo/error/invalid_database_name.rb +3 -0
  163. data/lib/mongo/error/invalid_document.rb +3 -0
  164. data/lib/mongo/error/invalid_file.rb +3 -0
  165. data/lib/mongo/error/invalid_file_revision.rb +3 -0
  166. data/lib/mongo/error/invalid_max_connecting.rb +28 -0
  167. data/lib/mongo/error/invalid_min_pool_size.rb +3 -0
  168. data/lib/mongo/error/invalid_nonce.rb +3 -0
  169. data/lib/mongo/error/invalid_read_concern.rb +31 -0
  170. data/lib/mongo/error/invalid_read_option.rb +4 -1
  171. data/lib/mongo/error/invalid_replacement_document.rb +30 -9
  172. data/lib/mongo/error/invalid_server_auth_host.rb +3 -0
  173. data/lib/mongo/error/invalid_server_auth_response.rb +3 -0
  174. data/lib/mongo/error/invalid_server_preference.rb +3 -0
  175. data/lib/mongo/error/invalid_session.rb +3 -0
  176. data/lib/mongo/error/invalid_signature.rb +3 -0
  177. data/lib/mongo/error/invalid_transaction_operation.rb +3 -0
  178. data/lib/mongo/error/invalid_txt_record.rb +3 -0
  179. data/lib/mongo/error/invalid_update_document.rb +30 -7
  180. data/lib/mongo/error/invalid_uri.rb +3 -0
  181. data/lib/mongo/error/invalid_write_concern.rb +3 -0
  182. data/lib/mongo/error/kms_error.rb +3 -0
  183. data/lib/mongo/error/labelable.rb +72 -0
  184. data/lib/mongo/error/lint_error.rb +3 -0
  185. data/lib/mongo/error/max_bson_size.rb +3 -0
  186. data/lib/mongo/error/max_message_size.rb +3 -0
  187. data/lib/mongo/error/mismatched_domain.rb +3 -0
  188. data/lib/mongo/error/missing_connection.rb +27 -0
  189. data/lib/mongo/error/missing_file_chunk.rb +11 -2
  190. data/lib/mongo/error/missing_password.rb +3 -0
  191. data/lib/mongo/error/missing_resume_token.rb +3 -0
  192. data/lib/mongo/error/missing_scram_server_signature.rb +3 -0
  193. data/lib/mongo/error/missing_service_id.rb +26 -0
  194. data/lib/mongo/error/mongocryptd_spawn_error.rb +3 -0
  195. data/lib/mongo/error/multi_index_drop.rb +3 -0
  196. data/lib/mongo/error/need_primary_server.rb +3 -0
  197. data/lib/mongo/error/no_server_available.rb +3 -0
  198. data/lib/mongo/error/no_service_connection_available.rb +49 -0
  199. data/lib/mongo/error/no_srv_records.rb +3 -0
  200. data/lib/mongo/error/notable.rb +24 -0
  201. data/lib/mongo/error/operation_failure.rb +57 -87
  202. data/lib/mongo/error/parser.rb +69 -13
  203. data/lib/mongo/error/pool_cleared_error.rb +40 -0
  204. data/lib/mongo/error/pool_closed_error.rb +6 -16
  205. data/lib/mongo/error/pool_error.rb +45 -0
  206. data/lib/mongo/error/pool_paused_error.rb +40 -0
  207. data/lib/mongo/error/raise_original_error.rb +3 -0
  208. data/lib/mongo/error/read_write_retryable.rb +108 -0
  209. data/lib/mongo/error/sdam_error_detection.rb +16 -5
  210. data/lib/mongo/error/server_api_conflict.rb +26 -0
  211. data/lib/mongo/error/server_api_not_supported.rb +27 -0
  212. data/lib/mongo/error/server_certificate_revoked.rb +25 -0
  213. data/lib/mongo/error/server_not_usable.rb +36 -0
  214. data/lib/mongo/error/session_ended.rb +3 -0
  215. data/lib/mongo/error/session_not_materialized.rb +29 -0
  216. data/lib/mongo/error/sessions_not_supported.rb +3 -0
  217. data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
  218. data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
  219. data/lib/mongo/error/socket_error.rb +3 -0
  220. data/lib/mongo/error/socket_timeout_error.rb +3 -0
  221. data/lib/mongo/error/unchangeable_collection_option.rb +3 -0
  222. data/lib/mongo/error/unexpected_chunk_length.rb +3 -0
  223. data/lib/mongo/error/unexpected_response.rb +3 -0
  224. data/lib/mongo/error/unknown_payload_type.rb +3 -0
  225. data/lib/mongo/error/unmet_dependency.rb +24 -0
  226. data/lib/mongo/error/unsupported_array_filters.rb +3 -0
  227. data/lib/mongo/error/unsupported_collation.rb +3 -0
  228. data/lib/mongo/error/unsupported_features.rb +3 -0
  229. data/lib/mongo/error/unsupported_message_type.rb +3 -0
  230. data/lib/mongo/error/unsupported_option.rb +17 -12
  231. data/lib/mongo/error/write_retryable.rb +3 -0
  232. data/lib/mongo/error.rb +31 -38
  233. data/lib/mongo/event/base.rb +3 -0
  234. data/lib/mongo/event/listeners.rb +3 -0
  235. data/lib/mongo/event/publisher.rb +3 -0
  236. data/lib/mongo/event/subscriber.rb +3 -0
  237. data/lib/mongo/event.rb +3 -0
  238. data/lib/mongo/grid/file/chunk.rb +6 -2
  239. data/lib/mongo/grid/file/info.rb +5 -1
  240. data/lib/mongo/grid/file.rb +3 -0
  241. data/lib/mongo/grid/fs_bucket.rb +86 -46
  242. data/lib/mongo/grid/stream/read.rb +28 -7
  243. data/lib/mongo/grid/stream/write.rb +3 -0
  244. data/lib/mongo/grid/stream.rb +3 -0
  245. data/lib/mongo/grid.rb +3 -0
  246. data/lib/mongo/id.rb +10 -5
  247. data/lib/mongo/index/view.rb +68 -58
  248. data/lib/mongo/index.rb +3 -0
  249. data/lib/mongo/lint.rb +5 -1
  250. data/lib/mongo/loggable.rb +5 -2
  251. data/lib/mongo/logger.rb +6 -3
  252. data/lib/mongo/monitoring/cmap_log_subscriber.rb +3 -0
  253. data/lib/mongo/monitoring/command_log_subscriber.rb +3 -0
  254. data/lib/mongo/monitoring/event/cmap/base.rb +3 -0
  255. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +3 -0
  256. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +3 -0
  257. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +3 -0
  258. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +3 -0
  259. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +3 -0
  260. data/lib/mongo/monitoring/event/cmap/connection_created.rb +3 -0
  261. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +3 -0
  262. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +17 -4
  263. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +3 -0
  264. data/lib/mongo/monitoring/event/cmap/pool_created.rb +3 -0
  265. data/lib/mongo/monitoring/event/cmap/pool_ready.rb +67 -0
  266. data/lib/mongo/monitoring/event/cmap.rb +4 -0
  267. data/lib/mongo/monitoring/event/command_failed.rb +38 -5
  268. data/lib/mongo/monitoring/event/command_started.rb +23 -3
  269. data/lib/mongo/monitoring/event/command_succeeded.rb +36 -3
  270. data/lib/mongo/monitoring/event/secure.rb +39 -5
  271. data/lib/mongo/monitoring/event/server_closed.rb +3 -0
  272. data/lib/mongo/monitoring/event/server_description_changed.rb +4 -1
  273. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +32 -18
  274. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +3 -0
  275. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +30 -16
  276. data/lib/mongo/monitoring/event/server_opening.rb +3 -0
  277. data/lib/mongo/monitoring/event/topology_changed.rb +3 -0
  278. data/lib/mongo/monitoring/event/topology_closed.rb +3 -0
  279. data/lib/mongo/monitoring/event/topology_opening.rb +3 -0
  280. data/lib/mongo/monitoring/event.rb +3 -0
  281. data/lib/mongo/monitoring/publishable.rb +38 -12
  282. data/lib/mongo/monitoring/sdam_log_subscriber.rb +3 -0
  283. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +3 -0
  284. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +3 -0
  285. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +3 -0
  286. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +3 -0
  287. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +3 -0
  288. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +3 -0
  289. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +3 -0
  290. data/lib/mongo/monitoring.rb +20 -8
  291. data/lib/mongo/operation/aggregate/op_msg.rb +3 -0
  292. data/lib/mongo/operation/aggregate/result.rb +12 -8
  293. data/lib/mongo/operation/aggregate.rb +4 -2
  294. data/lib/mongo/operation/collections_info/result.rb +24 -1
  295. data/lib/mongo/operation/collections_info.rb +10 -2
  296. data/lib/mongo/operation/command/op_msg.rb +9 -0
  297. data/lib/mongo/operation/command.rb +4 -2
  298. data/lib/mongo/operation/context.rb +138 -0
  299. data/lib/mongo/operation/count/op_msg.rb +12 -0
  300. data/lib/mongo/operation/count.rb +4 -2
  301. data/lib/mongo/operation/create/op_msg.rb +13 -0
  302. data/lib/mongo/operation/create.rb +4 -2
  303. data/lib/mongo/operation/create_index/op_msg.rb +21 -4
  304. data/lib/mongo/operation/create_index.rb +4 -2
  305. data/lib/mongo/operation/create_user/op_msg.rb +3 -0
  306. data/lib/mongo/operation/create_user.rb +4 -2
  307. data/lib/mongo/operation/delete/bulk_result.rb +5 -0
  308. data/lib/mongo/operation/delete/op_msg.rb +13 -1
  309. data/lib/mongo/operation/delete/result.rb +6 -0
  310. data/lib/mongo/operation/delete.rb +3 -2
  311. data/lib/mongo/operation/distinct/op_msg.rb +13 -0
  312. data/lib/mongo/operation/distinct.rb +4 -2
  313. data/lib/mongo/operation/drop/op_msg.rb +3 -0
  314. data/lib/mongo/operation/drop.rb +4 -2
  315. data/lib/mongo/operation/drop_database/op_msg.rb +3 -0
  316. data/lib/mongo/operation/drop_database.rb +4 -2
  317. data/lib/mongo/operation/drop_index/op_msg.rb +8 -1
  318. data/lib/mongo/operation/drop_index.rb +4 -2
  319. data/lib/mongo/operation/explain/op_msg.rb +17 -0
  320. data/lib/mongo/operation/explain/result.rb +6 -0
  321. data/lib/mongo/operation/explain.rb +4 -3
  322. data/lib/mongo/operation/find/builder/command.rb +111 -0
  323. data/lib/mongo/operation/find/builder/flags.rb +61 -0
  324. data/lib/mongo/operation/find/builder/modifiers.rb +89 -0
  325. data/lib/mongo/operation/find/builder.rb +20 -0
  326. data/lib/mongo/operation/find/op_msg.rb +15 -0
  327. data/lib/mongo/operation/find/result.rb +16 -0
  328. data/lib/mongo/operation/find.rb +5 -3
  329. data/lib/mongo/operation/get_more/command_builder.rb +42 -0
  330. data/lib/mongo/operation/get_more/op_msg.rb +4 -0
  331. data/lib/mongo/operation/get_more/result.rb +6 -0
  332. data/lib/mongo/operation/get_more.rb +5 -3
  333. data/lib/mongo/operation/indexes/op_msg.rb +3 -0
  334. data/lib/mongo/operation/indexes/result.rb +8 -0
  335. data/lib/mongo/operation/indexes.rb +4 -3
  336. data/lib/mongo/operation/insert/bulk_result.rb +13 -1
  337. data/lib/mongo/operation/insert/op_msg.rb +11 -5
  338. data/lib/mongo/operation/insert/result.rb +14 -3
  339. data/lib/mongo/operation/insert.rb +3 -2
  340. data/lib/mongo/operation/kill_cursors/command_builder.rb +35 -0
  341. data/lib/mongo/operation/kill_cursors/op_msg.rb +13 -0
  342. data/lib/mongo/operation/kill_cursors.rb +5 -3
  343. data/lib/mongo/operation/list_collections/op_msg.rb +7 -1
  344. data/lib/mongo/operation/list_collections/result.rb +12 -1
  345. data/lib/mongo/operation/list_collections.rb +4 -2
  346. data/lib/mongo/operation/map_reduce/op_msg.rb +4 -1
  347. data/lib/mongo/operation/map_reduce/result.rb +29 -0
  348. data/lib/mongo/operation/map_reduce.rb +4 -2
  349. data/lib/mongo/operation/op_msg_base.rb +3 -0
  350. data/lib/mongo/operation/parallel_scan/op_msg.rb +3 -0
  351. data/lib/mongo/operation/parallel_scan/result.rb +7 -0
  352. data/lib/mongo/operation/parallel_scan.rb +4 -2
  353. data/lib/mongo/operation/remove_user/op_msg.rb +3 -0
  354. data/lib/mongo/operation/remove_user.rb +4 -2
  355. data/lib/mongo/operation/result.rb +67 -11
  356. data/lib/mongo/operation/shared/bypass_document_validation.rb +4 -0
  357. data/lib/mongo/operation/shared/causal_consistency_supported.rb +4 -0
  358. data/lib/mongo/operation/shared/executable.rb +61 -17
  359. data/lib/mongo/operation/shared/executable_no_validate.rb +5 -2
  360. data/lib/mongo/operation/shared/executable_transaction_label.rb +3 -0
  361. data/lib/mongo/operation/shared/idable.rb +5 -1
  362. data/lib/mongo/operation/shared/limited.rb +4 -0
  363. data/lib/mongo/operation/shared/object_id_generator.rb +4 -0
  364. data/lib/mongo/operation/shared/op_msg_executable.rb +59 -0
  365. data/lib/mongo/operation/shared/polymorphic_lookup.rb +3 -0
  366. data/lib/mongo/operation/shared/polymorphic_result.rb +3 -0
  367. data/lib/mongo/operation/shared/read_preference_supported.rb +44 -37
  368. data/lib/mongo/operation/shared/response_handling.rb +32 -27
  369. data/lib/mongo/operation/shared/result/aggregatable.rb +4 -0
  370. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +3 -0
  371. data/lib/mongo/operation/shared/sessions_supported.rb +55 -20
  372. data/lib/mongo/operation/shared/specifiable.rb +15 -29
  373. data/lib/mongo/operation/shared/validatable.rb +87 -0
  374. data/lib/mongo/operation/shared/write.rb +28 -28
  375. data/lib/mongo/operation/shared/write_concern_supported.rb +4 -0
  376. data/lib/mongo/operation/update/bulk_result.rb +3 -0
  377. data/lib/mongo/operation/update/op_msg.rb +12 -4
  378. data/lib/mongo/operation/update/result.rb +11 -0
  379. data/lib/mongo/operation/update.rb +3 -2
  380. data/lib/mongo/operation/update_user/op_msg.rb +3 -0
  381. data/lib/mongo/operation/update_user.rb +4 -2
  382. data/lib/mongo/operation/users_info/op_msg.rb +3 -0
  383. data/lib/mongo/operation/users_info/result.rb +6 -0
  384. data/lib/mongo/operation/users_info.rb +4 -2
  385. data/lib/mongo/operation/write_command/op_msg.rb +43 -0
  386. data/lib/mongo/operation/write_command.rb +31 -0
  387. data/lib/mongo/operation.rb +17 -4
  388. data/lib/mongo/options/mapper.rb +3 -0
  389. data/lib/mongo/options/redacted.rb +3 -0
  390. data/lib/mongo/options.rb +3 -0
  391. data/lib/mongo/protocol/bit_vector.rb +6 -1
  392. data/lib/mongo/protocol/caching_hash.rb +52 -0
  393. data/lib/mongo/protocol/compressed.rb +54 -5
  394. data/lib/mongo/protocol/get_more.rb +3 -0
  395. data/lib/mongo/protocol/kill_cursors.rb +3 -0
  396. data/lib/mongo/protocol/message.rb +27 -10
  397. data/lib/mongo/protocol/msg.rb +61 -17
  398. data/lib/mongo/protocol/query.rb +53 -32
  399. data/lib/mongo/protocol/registry.rb +3 -0
  400. data/lib/mongo/protocol/reply.rb +3 -0
  401. data/lib/mongo/protocol/serializers.rb +27 -17
  402. data/lib/mongo/protocol.rb +4 -3
  403. data/lib/mongo/query_cache.rb +300 -0
  404. data/lib/mongo/retryable/base_worker.rb +91 -0
  405. data/lib/mongo/retryable/read_worker.rb +296 -0
  406. data/lib/mongo/retryable/write_worker.rb +364 -0
  407. data/lib/mongo/retryable.rb +33 -446
  408. data/lib/mongo/semaphore.rb +4 -1
  409. data/lib/mongo/server/app_metadata/environment.rb +259 -0
  410. data/lib/mongo/server/app_metadata/platform.rb +114 -0
  411. data/lib/mongo/server/app_metadata/truncator.rb +142 -0
  412. data/lib/mongo/server/app_metadata.rb +117 -94
  413. data/lib/mongo/server/connection.rb +126 -22
  414. data/lib/mongo/server/connection_base.rb +49 -21
  415. data/lib/mongo/server/connection_common.rb +76 -3
  416. data/lib/mongo/server/connection_pool/generation_manager.rb +115 -0
  417. data/lib/mongo/server/connection_pool/populator.rb +35 -30
  418. data/lib/mongo/server/connection_pool.rb +776 -206
  419. data/lib/mongo/server/description/features.rb +34 -25
  420. data/lib/mongo/server/description/load_balancer.rb +33 -0
  421. data/lib/mongo/server/description.rb +126 -17
  422. data/lib/mongo/server/monitor/app_metadata.rb +4 -1
  423. data/lib/mongo/server/monitor/connection.rb +66 -50
  424. data/lib/mongo/server/monitor.rb +62 -32
  425. data/lib/mongo/server/pending_connection.rb +77 -44
  426. data/lib/mongo/server/push_monitor/connection.rb +3 -0
  427. data/lib/mongo/server/push_monitor.rb +54 -20
  428. data/lib/mongo/server/round_trip_time_averager.rb +6 -3
  429. data/lib/mongo/server.rb +197 -67
  430. data/lib/mongo/server_selector/base.rb +65 -11
  431. data/lib/mongo/server_selector/nearest.rb +6 -4
  432. data/lib/mongo/server_selector/primary.rb +6 -4
  433. data/lib/mongo/server_selector/primary_preferred.rb +6 -4
  434. data/lib/mongo/server_selector/secondary.rb +6 -4
  435. data/lib/mongo/server_selector/secondary_preferred.rb +8 -11
  436. data/lib/mongo/server_selector.rb +3 -0
  437. data/lib/mongo/session/server_session.rb +3 -0
  438. data/lib/mongo/session/session_pool.rb +26 -2
  439. data/lib/mongo/session.rb +164 -38
  440. data/lib/mongo/socket/ocsp_cache.rb +99 -0
  441. data/lib/mongo/socket/ocsp_verifier.rb +344 -0
  442. data/lib/mongo/socket/ssl.rb +56 -24
  443. data/lib/mongo/socket/tcp.rb +6 -0
  444. data/lib/mongo/socket/unix.rb +3 -0
  445. data/lib/mongo/socket.rb +71 -16
  446. data/lib/mongo/srv/monitor.rb +10 -26
  447. data/lib/mongo/srv/resolver.rb +41 -13
  448. data/lib/mongo/srv/result.rb +3 -0
  449. data/lib/mongo/srv.rb +3 -0
  450. data/lib/mongo/timeout.rb +6 -1
  451. data/lib/mongo/topology_version.rb +4 -1
  452. data/lib/mongo/uri/options_mapper.rb +867 -0
  453. data/lib/mongo/uri/srv_protocol.rb +13 -11
  454. data/lib/mongo/uri.rb +100 -400
  455. data/lib/mongo/utils.rb +44 -1
  456. data/lib/mongo/version.rb +4 -1
  457. data/lib/mongo/write_concern/acknowledged.rb +3 -0
  458. data/lib/mongo/write_concern/base.rb +3 -0
  459. data/lib/mongo/write_concern/unacknowledged.rb +3 -0
  460. data/lib/mongo/write_concern.rb +3 -0
  461. data/lib/mongo.rb +58 -0
  462. data/mongo.gemspec +16 -7
  463. data/spec/NOTES.aws-auth.md +12 -7
  464. data/spec/README.md +106 -3
  465. data/spec/atlas/atlas_connectivity_spec.rb +3 -0
  466. data/spec/atlas/operations_spec.rb +5 -7
  467. data/spec/integration/auth_spec.rb +58 -15
  468. data/spec/integration/awaited_ismaster_spec.rb +9 -6
  469. data/spec/integration/aws_auth_credentials_cache_spec.rb +51 -0
  470. data/spec/integration/aws_auth_request_spec.rb +4 -1
  471. data/spec/integration/aws_credentials_retriever_spec.rb +34 -1
  472. data/spec/integration/aws_lambda_examples_spec.rb +68 -0
  473. data/spec/integration/bson_symbol_spec.rb +8 -3
  474. data/spec/integration/bulk_insert_spec.rb +3 -0
  475. data/spec/integration/bulk_write_error_message_spec.rb +74 -0
  476. data/spec/integration/bulk_write_spec.rb +67 -0
  477. data/spec/integration/change_stream_examples_spec.rb +3 -0
  478. data/spec/integration/change_stream_spec.rb +18 -9
  479. data/spec/integration/check_clean_slate_spec.rb +3 -0
  480. data/spec/integration/client_authentication_options_spec.rb +76 -36
  481. data/spec/integration/client_connectivity_spec.rb +4 -1
  482. data/spec/integration/client_construction_aws_auth_spec.rb +14 -2
  483. data/spec/integration/client_construction_spec.rb +153 -8
  484. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +13 -10
  485. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +172 -169
  486. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +3 -1
  487. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +3 -0
  488. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +43 -4
  489. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +148 -2
  490. data/spec/integration/client_side_encryption/automatic_data_encryption_keys_prose_spec.rb +153 -0
  491. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +6 -3
  492. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +6 -3
  493. data/spec/integration/client_side_encryption/client_close_spec.rb +4 -1
  494. data/spec/integration/client_side_encryption/corpus_spec.rb +67 -35
  495. data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +42 -42
  496. data/spec/integration/client_side_encryption/data_key_spec.rb +101 -8
  497. data/spec/integration/client_side_encryption/decryption_events_prose_spec.rb +159 -0
  498. data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +62 -0
  499. data/spec/integration/client_side_encryption/explicit_queryable_encryption_spec.rb +150 -0
  500. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +9 -6
  501. data/spec/integration/client_side_encryption/kms_tls_options_spec.rb +436 -0
  502. data/spec/integration/client_side_encryption/kms_tls_spec.rb +92 -0
  503. data/spec/integration/client_side_encryption/mongocryptd_prose_spec.rb +105 -0
  504. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +49 -0
  505. data/spec/integration/client_side_encryption/on_demand_azure_credentials_spec.rb +46 -0
  506. data/spec/integration/client_side_encryption/on_demand_gcp_credentials_spec.rb +47 -0
  507. data/spec/integration/client_side_encryption/queryable_encryption_examples_spec.rb +114 -0
  508. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +536 -0
  509. data/spec/integration/client_side_encryption/rewrap_prose_spec.rb +114 -0
  510. data/spec/integration/client_side_encryption/unique_index_on_key_alt_names_prose_spec.rb +89 -0
  511. data/spec/integration/client_side_encryption/views_spec.rb +4 -1
  512. data/spec/integration/client_spec.rb +14 -4
  513. data/spec/integration/client_update_spec.rb +9 -2
  514. data/spec/integration/collection_indexes_prose_spec.rb +3 -0
  515. data/spec/integration/command_monitoring_spec.rb +64 -26
  516. data/spec/integration/command_spec.rb +5 -24
  517. data/spec/integration/connect_single_rs_name_spec.rb +6 -3
  518. data/spec/integration/connection/faas_env_spec.rb +62 -0
  519. data/spec/integration/connection_pool_populator_spec.rb +33 -8
  520. data/spec/integration/connection_spec.rb +58 -36
  521. data/spec/integration/crud_spec.rb +217 -1
  522. data/spec/integration/cursor_pinning_spec.rb +125 -0
  523. data/spec/integration/cursor_reaping_spec.rb +62 -19
  524. data/spec/integration/docs_examples_spec.rb +12 -2
  525. data/spec/integration/error_detection_spec.rb +3 -0
  526. data/spec/integration/fork_reconnect_spec.rb +73 -9
  527. data/spec/integration/get_more_spec.rb +4 -1
  528. data/spec/integration/grid_fs_bucket_spec.rb +7 -4
  529. data/spec/integration/heartbeat_events_spec.rb +8 -5
  530. data/spec/integration/map_reduce_spec.rb +81 -0
  531. data/spec/integration/mmapv1_spec.rb +3 -0
  532. data/spec/integration/mongos_pinning_spec.rb +3 -0
  533. data/spec/integration/ocsp_connectivity_spec.rb +29 -0
  534. data/spec/integration/ocsp_verifier_cache_spec.rb +191 -0
  535. data/spec/integration/ocsp_verifier_spec.rb +358 -0
  536. data/spec/integration/operation_failure_code_spec.rb +4 -1
  537. data/spec/integration/operation_failure_message_spec.rb +91 -0
  538. data/spec/integration/query_cache_spec.rb +1343 -0
  539. data/spec/integration/query_cache_transactions_spec.rb +193 -0
  540. data/spec/integration/read_concern_spec.rb +4 -1
  541. data/spec/integration/read_preference_spec.rb +20 -13
  542. data/spec/integration/reconnect_spec.rb +39 -13
  543. data/spec/integration/retryable_errors_spec.rb +4 -1
  544. data/spec/integration/retryable_reads_errors_spec.rb +110 -0
  545. data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +5 -2
  546. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +5 -1
  547. data/spec/integration/retryable_writes/shared/adds_diagnostics.rb +3 -0
  548. data/spec/integration/retryable_writes/shared/does_not_support_retries.rb +3 -0
  549. data/spec/integration/retryable_writes/shared/only_supports_legacy_retries.rb +3 -0
  550. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +5 -0
  551. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -0
  552. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +3 -0
  553. data/spec/integration/retryable_writes/shared/supports_legacy_retries.rb +3 -0
  554. data/spec/integration/retryable_writes/shared/supports_modern_retries.rb +3 -0
  555. data/spec/integration/retryable_writes/shared/supports_retries.rb +3 -0
  556. data/spec/integration/retryable_writes_errors_spec.rb +162 -1
  557. data/spec/integration/sdam_error_handling_spec.rb +159 -8
  558. data/spec/integration/sdam_events_spec.rb +94 -31
  559. data/spec/integration/sdam_prose_spec.rb +7 -4
  560. data/spec/integration/secondary_reads_spec.rb +103 -0
  561. data/spec/integration/server_description_spec.rb +3 -0
  562. data/spec/integration/server_monitor_spec.rb +7 -2
  563. data/spec/integration/server_selection_spec.rb +39 -0
  564. data/spec/integration/server_selector_spec.rb +29 -7
  565. data/spec/integration/server_spec.rb +27 -25
  566. data/spec/integration/shell_examples_spec.rb +3 -0
  567. data/spec/integration/size_limit_spec.rb +7 -1
  568. data/spec/integration/snappy_compression_spec.rb +28 -0
  569. data/spec/integration/snapshot_query_examples_spec.rb +129 -0
  570. data/spec/integration/srv_monitoring_spec.rb +82 -5
  571. data/spec/integration/srv_spec.rb +60 -0
  572. data/spec/integration/ssl_uri_options_spec.rb +3 -0
  573. data/spec/integration/step_down_spec.rb +28 -7
  574. data/spec/integration/time_zone_querying_spec.rb +3 -0
  575. data/spec/integration/transaction_pinning_spec.rb +134 -0
  576. data/spec/integration/transactions_api_examples_spec.rb +3 -0
  577. data/spec/integration/transactions_examples_spec.rb +26 -7
  578. data/spec/integration/truncated_utf8_spec.rb +26 -0
  579. data/spec/integration/versioned_api_examples_spec.rb +120 -0
  580. data/spec/integration/x509_auth_spec.rb +5 -2
  581. data/spec/integration/zlib_compression_spec.rb +4 -1
  582. data/spec/integration/zstd_compression_spec.rb +29 -0
  583. data/spec/kerberos/kerberos_spec.rb +3 -0
  584. data/spec/lite_spec_helper.rb +59 -16
  585. data/spec/mongo/address/ipv4_spec.rb +3 -0
  586. data/spec/mongo/address/ipv6_spec.rb +10 -0
  587. data/spec/mongo/address/unix_spec.rb +4 -0
  588. data/spec/mongo/address/validator_spec.rb +3 -0
  589. data/spec/mongo/address_spec.rb +33 -13
  590. data/spec/mongo/auth/aws/credential_cache_spec.rb +63 -0
  591. data/spec/mongo/auth/aws/credentials_retriever_spec.rb +90 -0
  592. data/spec/mongo/auth/aws/credentials_spec.rb +46 -0
  593. data/spec/mongo/auth/aws/request_region_spec.rb +3 -0
  594. data/spec/mongo/auth/aws/request_spec.rb +3 -0
  595. data/spec/mongo/auth/cr_spec.rb +6 -24
  596. data/spec/mongo/auth/gssapi/conversation_spec.rb +3 -0
  597. data/spec/mongo/auth/invalid_mechanism_spec.rb +3 -0
  598. data/spec/mongo/auth/ldap/conversation_spec.rb +4 -1
  599. data/spec/mongo/auth/ldap_spec.rb +10 -4
  600. data/spec/mongo/auth/scram/conversation_spec.rb +26 -23
  601. data/spec/mongo/auth/scram256/conversation_spec.rb +23 -20
  602. data/spec/mongo/auth/scram_negotiation_spec.rb +5 -1
  603. data/spec/mongo/auth/scram_spec.rb +5 -3
  604. data/spec/mongo/auth/stringprep/profiles/sasl_spec.rb +3 -0
  605. data/spec/mongo/auth/stringprep_spec.rb +3 -0
  606. data/spec/mongo/auth/user/view_spec.rb +99 -1
  607. data/spec/mongo/auth/user_spec.rb +4 -1
  608. data/spec/mongo/auth/x509/conversation_spec.rb +6 -3
  609. data/spec/mongo/auth/x509_spec.rb +5 -3
  610. data/spec/mongo/auth_spec.rb +3 -0
  611. data/spec/mongo/bson_spec.rb +3 -0
  612. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +3 -0
  613. data/spec/mongo/bulk_write/result_spec.rb +18 -1
  614. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +3 -0
  615. data/spec/mongo/bulk_write_spec.rb +149 -25
  616. data/spec/mongo/caching_cursor_spec.rb +73 -0
  617. data/spec/mongo/client_construction_spec.rb +1112 -546
  618. data/spec/mongo/client_encryption_spec.rb +27 -30
  619. data/spec/mongo/client_spec.rb +445 -139
  620. data/spec/mongo/cluster/cursor_reaper_spec.rb +66 -23
  621. data/spec/mongo/cluster/periodic_executor_spec.rb +6 -1
  622. data/spec/mongo/cluster/socket_reaper_spec.rb +3 -0
  623. data/spec/mongo/cluster/topology/replica_set_spec.rb +13 -10
  624. data/spec/mongo/cluster/topology/sharded_spec.rb +6 -3
  625. data/spec/mongo/cluster/topology/single_spec.rb +20 -8
  626. data/spec/mongo/cluster/topology/unknown_spec.rb +4 -1
  627. data/spec/mongo/cluster/topology_spec.rb +4 -1
  628. data/spec/mongo/cluster_spec.rb +183 -192
  629. data/spec/mongo/cluster_time_spec.rb +3 -0
  630. data/spec/mongo/collection/view/aggregation_spec.rb +181 -83
  631. data/spec/mongo/collection/view/builder/find_command_spec.rb +7 -0
  632. data/spec/mongo/collection/view/builder/op_query_spec.rb +7 -0
  633. data/spec/mongo/collection/view/change_stream_resume_spec.rb +8 -3
  634. data/spec/mongo/collection/view/change_stream_spec.rb +18 -2
  635. data/spec/mongo/collection/view/explainable_spec.rb +90 -4
  636. data/spec/mongo/collection/view/immutable_spec.rb +3 -0
  637. data/spec/mongo/collection/view/iterable_spec.rb +3 -0
  638. data/spec/mongo/collection/view/map_reduce_spec.rb +46 -2
  639. data/spec/mongo/collection/view/readable_spec.rb +868 -1
  640. data/spec/mongo/collection/view/writable_spec.rb +147 -32
  641. data/spec/mongo/collection/view_spec.rb +3 -0
  642. data/spec/mongo/collection_crud_spec.rb +4471 -0
  643. data/spec/mongo/collection_ddl_spec.rb +587 -0
  644. data/spec/mongo/collection_spec.rb +106 -4839
  645. data/spec/mongo/condition_variable_spec.rb +104 -0
  646. data/spec/mongo/config/options_spec.rb +76 -0
  647. data/spec/mongo/config_spec.rb +74 -0
  648. data/spec/mongo/crypt/auto_decryption_context_spec.rb +21 -2
  649. data/spec/mongo/crypt/auto_encrypter_spec.rb +266 -5
  650. data/spec/mongo/crypt/auto_encryption_context_spec.rb +21 -2
  651. data/spec/mongo/crypt/binary_spec.rb +3 -5
  652. data/spec/mongo/crypt/binding/binary_spec.rb +3 -5
  653. data/spec/mongo/crypt/binding/context_spec.rb +71 -23
  654. data/spec/mongo/crypt/binding/helpers_spec.rb +3 -5
  655. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +21 -52
  656. data/spec/mongo/crypt/binding/status_spec.rb +3 -5
  657. data/spec/mongo/crypt/binding/version_spec.rb +50 -5
  658. data/spec/mongo/crypt/binding_unloaded_spec.rb +17 -0
  659. data/spec/mongo/crypt/data_key_context_spec.rb +45 -114
  660. data/spec/mongo/crypt/encryption_io_spec.rb +5 -0
  661. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +36 -2
  662. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +98 -2
  663. data/spec/mongo/crypt/handle_spec.rb +189 -155
  664. data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +3 -0
  665. data/spec/mongo/crypt/hooks_spec.rb +30 -0
  666. data/spec/mongo/crypt/kms/azure/credentials_retriever_spec.rb +86 -0
  667. data/spec/mongo/crypt/kms/credentials_spec.rb +373 -0
  668. data/spec/mongo/crypt/kms_spec.rb +62 -0
  669. data/spec/mongo/crypt/status_spec.rb +3 -5
  670. data/spec/mongo/crypt_spec.rb +21 -0
  671. data/spec/mongo/cursor/builder/get_more_command_spec.rb +11 -2
  672. data/spec/mongo/cursor/builder/op_get_more_spec.rb +11 -2
  673. data/spec/mongo/cursor_spec.rb +230 -19
  674. data/spec/mongo/database_spec.rb +263 -25
  675. data/spec/mongo/distinguishing_semaphore_spec.rb +9 -6
  676. data/spec/mongo/error/bulk_write_error_spec.rb +6 -3
  677. data/spec/mongo/error/crypt_error_spec.rb +3 -0
  678. data/spec/mongo/error/max_bson_size_spec.rb +3 -0
  679. data/spec/mongo/error/no_server_available_spec.rb +4 -1
  680. data/spec/mongo/error/notable_spec.rb +3 -0
  681. data/spec/mongo/error/operation_failure_heavy_spec.rb +53 -1
  682. data/spec/mongo/error/operation_failure_spec.rb +94 -31
  683. data/spec/mongo/error/parser_spec.rb +40 -6
  684. data/spec/mongo/error/unsupported_option_spec.rb +3 -0
  685. data/spec/mongo/event/publisher_spec.rb +3 -0
  686. data/spec/mongo/event/subscriber_spec.rb +3 -0
  687. data/spec/mongo/grid/file/chunk_spec.rb +7 -4
  688. data/spec/mongo/grid/file/info_spec.rb +3 -0
  689. data/spec/mongo/grid/file_spec.rb +4 -1
  690. data/spec/mongo/grid/fs_bucket_spec.rb +40 -17
  691. data/spec/mongo/grid/stream/read_spec.rb +33 -10
  692. data/spec/mongo/grid/stream/write_spec.rb +6 -9
  693. data/spec/mongo/grid/stream_spec.rb +4 -1
  694. data/spec/mongo/id_spec.rb +4 -1
  695. data/spec/mongo/index/view_spec.rb +138 -4
  696. data/spec/mongo/lint_spec.rb +4 -1
  697. data/spec/mongo/logger_spec.rb +16 -11
  698. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +3 -0
  699. data/spec/mongo/monitoring/event/cmap/connection_check_out_failed_spec.rb +4 -1
  700. data/spec/mongo/monitoring/event/cmap/connection_check_out_started_spec.rb +4 -1
  701. data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +4 -1
  702. data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +4 -1
  703. data/spec/mongo/monitoring/event/cmap/connection_closed_spec.rb +4 -1
  704. data/spec/mongo/monitoring/event/cmap/connection_created_spec.rb +4 -1
  705. data/spec/mongo/monitoring/event/cmap/connection_ready_spec.rb +4 -1
  706. data/spec/mongo/monitoring/event/cmap/pool_cleared_spec.rb +4 -1
  707. data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +4 -1
  708. data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +4 -1
  709. data/spec/mongo/monitoring/event/command_failed_spec.rb +59 -2
  710. data/spec/mongo/monitoring/event/command_started_spec.rb +3 -0
  711. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +46 -6
  712. data/spec/mongo/monitoring/event/secure_spec.rb +28 -4
  713. data/spec/mongo/monitoring/event/server_closed_spec.rb +4 -1
  714. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +3 -0
  715. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +4 -1
  716. data/spec/mongo/monitoring/event/server_heartbeat_started_spec.rb +3 -0
  717. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +4 -1
  718. data/spec/mongo/monitoring/event/server_opening_spec.rb +4 -1
  719. data/spec/mongo/monitoring/event/topology_changed_spec.rb +4 -1
  720. data/spec/mongo/monitoring/event/topology_closed_spec.rb +4 -1
  721. data/spec/mongo/monitoring/event/topology_opening_spec.rb +4 -1
  722. data/spec/mongo/monitoring_spec.rb +3 -0
  723. data/spec/mongo/operation/aggregate/result_spec.rb +7 -2
  724. data/spec/mongo/operation/aggregate_spec.rb +5 -1
  725. data/spec/mongo/operation/collections_info_spec.rb +7 -1
  726. data/spec/mongo/operation/command_spec.rb +11 -5
  727. data/spec/mongo/operation/create/op_msg_spec.rb +244 -0
  728. data/spec/mongo/operation/create_index_spec.rb +9 -3
  729. data/spec/mongo/operation/create_user_spec.rb +9 -3
  730. data/spec/mongo/operation/delete/bulk_spec.rb +12 -6
  731. data/spec/mongo/operation/delete/op_msg_spec.rb +20 -8
  732. data/spec/mongo/operation/delete_spec.rb +13 -36
  733. data/spec/mongo/operation/drop_index_spec.rb +9 -2
  734. data/spec/mongo/operation/find/builder/flags_spec.rb +109 -0
  735. data/spec/mongo/operation/find/builder/modifiers_spec.rb +213 -0
  736. data/spec/mongo/operation/indexes_spec.rb +8 -1
  737. data/spec/mongo/operation/insert/bulk_spec.rb +14 -8
  738. data/spec/mongo/operation/insert/op_msg_spec.rb +25 -14
  739. data/spec/mongo/operation/insert_spec.rb +17 -43
  740. data/spec/mongo/operation/limited_spec.rb +3 -0
  741. data/spec/mongo/operation/map_reduce_spec.rb +8 -2
  742. data/spec/mongo/operation/read_preference_legacy_spec.rb +39 -42
  743. data/spec/mongo/operation/read_preference_op_msg_spec.rb +33 -5
  744. data/spec/mongo/operation/remove_user_spec.rb +9 -3
  745. data/spec/mongo/operation/result_spec.rb +30 -5
  746. data/spec/mongo/operation/specifiable_spec.rb +3 -0
  747. data/spec/mongo/operation/update/bulk_spec.rb +13 -7
  748. data/spec/mongo/operation/update/op_msg_spec.rb +20 -8
  749. data/spec/mongo/operation/update_spec.rb +12 -35
  750. data/spec/mongo/operation/update_user_spec.rb +7 -1
  751. data/spec/mongo/options/redacted_spec.rb +4 -1
  752. data/spec/mongo/protocol/caching_hash_spec.rb +37 -0
  753. data/spec/mongo/protocol/compressed_spec.rb +29 -12
  754. data/spec/mongo/protocol/get_more_spec.rb +3 -0
  755. data/spec/mongo/protocol/kill_cursors_spec.rb +3 -0
  756. data/spec/mongo/protocol/msg_spec.rb +48 -66
  757. data/spec/mongo/protocol/query_spec.rb +6 -3
  758. data/spec/mongo/protocol/registry_spec.rb +3 -0
  759. data/spec/mongo/protocol/reply_spec.rb +3 -0
  760. data/spec/mongo/query_cache_middleware_spec.rb +55 -0
  761. data/spec/mongo/query_cache_spec.rb +453 -0
  762. data/spec/mongo/retryable_spec.rb +42 -7
  763. data/spec/mongo/semaphore_spec.rb +9 -6
  764. data/spec/mongo/server/app_metadata/environment_spec.rb +209 -0
  765. data/spec/mongo/server/app_metadata/truncator_spec.rb +158 -0
  766. data/spec/mongo/server/app_metadata_spec.rb +55 -52
  767. data/spec/mongo/server/connection_auth_spec.rb +9 -10
  768. data/spec/mongo/server/connection_common_spec.rb +87 -0
  769. data/spec/mongo/server/connection_pool/populator_spec.rb +22 -3
  770. data/spec/mongo/server/connection_pool_spec.rb +635 -58
  771. data/spec/mongo/server/connection_spec.rb +226 -204
  772. data/spec/mongo/server/description/features_spec.rb +27 -0
  773. data/spec/mongo/server/description_query_methods_spec.rb +4 -1
  774. data/spec/mongo/server/description_spec.rb +625 -594
  775. data/spec/mongo/server/monitor/app_metadata_spec.rb +3 -1
  776. data/spec/mongo/server/monitor/connection_spec.rb +81 -9
  777. data/spec/mongo/server/monitor_spec.rb +31 -18
  778. data/spec/mongo/server/push_monitor_spec.rb +95 -0
  779. data/spec/mongo/server/round_trip_time_averager_spec.rb +3 -0
  780. data/spec/mongo/server_selector/nearest_spec.rb +8 -2
  781. data/spec/mongo/server_selector/primary_preferred_spec.rb +8 -2
  782. data/spec/mongo/server_selector/primary_spec.rb +8 -2
  783. data/spec/mongo/server_selector/secondary_preferred_spec.rb +14 -8
  784. data/spec/mongo/server_selector/secondary_spec.rb +8 -2
  785. data/spec/mongo/server_selector_spec.rb +143 -18
  786. data/spec/mongo/server_spec.rb +49 -6
  787. data/spec/mongo/session/server_session_spec.rb +3 -0
  788. data/spec/mongo/session/session_pool_spec.rb +45 -10
  789. data/spec/mongo/session_spec.rb +29 -6
  790. data/spec/mongo/session_transaction_spec.rb +17 -36
  791. data/spec/mongo/socket/ssl_spec.rb +91 -75
  792. data/spec/mongo/socket/tcp_spec.rb +3 -0
  793. data/spec/mongo/socket/unix_spec.rb +4 -0
  794. data/spec/mongo/socket_spec.rb +5 -2
  795. data/spec/mongo/srv/monitor_spec.rb +3 -0
  796. data/spec/mongo/srv/result_spec.rb +3 -0
  797. data/spec/mongo/timeout_spec.rb +3 -0
  798. data/spec/mongo/tls_context_hooks_spec.rb +40 -0
  799. data/spec/mongo/uri/options_mapper_spec.rb +1605 -0
  800. data/spec/mongo/uri/srv_protocol_spec.rb +330 -36
  801. data/spec/mongo/uri_option_parsing_spec.rb +52 -16
  802. data/spec/mongo/uri_spec.rb +238 -42
  803. data/spec/mongo/utils_spec.rb +42 -0
  804. data/spec/mongo/write_concern/acknowledged_spec.rb +3 -0
  805. data/spec/mongo/write_concern/unacknowledged_spec.rb +3 -0
  806. data/spec/mongo/write_concern_spec.rb +3 -0
  807. data/spec/runners/auth.rb +26 -2
  808. data/spec/runners/change_streams/outcome.rb +3 -0
  809. data/spec/runners/change_streams/spec.rb +4 -1
  810. data/spec/runners/change_streams/test.rb +5 -2
  811. data/spec/runners/cmap/verifier.rb +4 -1
  812. data/spec/runners/cmap.rb +192 -46
  813. data/spec/runners/command_monitoring.rb +4 -1
  814. data/spec/runners/connection_string.rb +48 -126
  815. data/spec/runners/crud/context.rb +3 -0
  816. data/spec/runners/crud/operation.rb +21 -7
  817. data/spec/runners/crud/outcome.rb +3 -0
  818. data/spec/runners/crud/requirement.rb +76 -6
  819. data/spec/runners/crud/spec.rb +9 -3
  820. data/spec/runners/crud/test.rb +4 -1
  821. data/spec/runners/crud/test_base.rb +4 -20
  822. data/spec/runners/crud/verifier.rb +20 -4
  823. data/spec/runners/crud.rb +23 -1
  824. data/spec/runners/gridfs.rb +4 -1
  825. data/spec/runners/read_write_concern_document.rb +4 -1
  826. data/spec/runners/sdam/verifier.rb +3 -0
  827. data/spec/runners/sdam.rb +9 -5
  828. data/spec/runners/server_selection.rb +5 -2
  829. data/spec/runners/server_selection_rtt.rb +5 -2
  830. data/spec/runners/transactions/operation.rb +30 -10
  831. data/spec/runners/transactions/spec.rb +5 -2
  832. data/spec/runners/transactions/test.rb +69 -21
  833. data/spec/runners/transactions.rb +14 -8
  834. data/spec/runners/unified/assertions.rb +379 -0
  835. data/spec/runners/unified/change_stream_operations.rb +52 -0
  836. data/spec/runners/unified/client_side_encryption_operations.rb +83 -0
  837. data/spec/runners/unified/crud_operations.rb +332 -0
  838. data/spec/runners/unified/ddl_operations.rb +255 -0
  839. data/spec/runners/unified/entity_map.rb +42 -0
  840. data/spec/runners/unified/error.rb +29 -0
  841. data/spec/runners/unified/event_subscriber.rb +110 -0
  842. data/spec/runners/unified/exceptions.rb +24 -0
  843. data/spec/runners/unified/grid_fs_operations.rb +79 -0
  844. data/spec/runners/unified/support_operations.rb +333 -0
  845. data/spec/runners/unified/test.rb +585 -0
  846. data/spec/runners/unified/test_group.rb +31 -0
  847. data/spec/runners/unified/thread_operations.rb +73 -0
  848. data/spec/runners/unified.rb +109 -0
  849. data/spec/shared/LICENSE +20 -0
  850. data/spec/shared/bin/get-mongodb-download-url +17 -0
  851. data/spec/shared/bin/s3-copy +45 -0
  852. data/spec/shared/bin/s3-upload +69 -0
  853. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  854. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  855. data/spec/shared/lib/mrss/constraints.rb +378 -0
  856. data/spec/shared/lib/mrss/docker_runner.rb +295 -0
  857. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  858. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  859. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  860. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  861. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  862. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  863. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  864. data/spec/shared/lib/mrss/utils.rb +37 -0
  865. data/spec/shared/share/Dockerfile.erb +330 -0
  866. data/spec/shared/share/haproxy-1.conf +16 -0
  867. data/spec/shared/share/haproxy-2.conf +17 -0
  868. data/spec/shared/shlib/config.sh +27 -0
  869. data/spec/shared/shlib/distro.sh +74 -0
  870. data/spec/shared/shlib/server.sh +416 -0
  871. data/spec/shared/shlib/set_env.sh +169 -0
  872. data/spec/solo/clean_exit_spec.rb +22 -0
  873. data/spec/spec_helper.rb +11 -5
  874. data/spec/spec_tests/auth_spec.rb +30 -13
  875. data/spec/spec_tests/change_streams_unified_spec.rb +14 -0
  876. data/spec/spec_tests/client_side_encryption_spec.rb +27 -1
  877. data/spec/spec_tests/client_side_encryption_unified_spec.rb +26 -0
  878. data/spec/spec_tests/cmap_spec.rb +41 -17
  879. data/spec/spec_tests/collection_management_spec.rb +13 -0
  880. data/spec/spec_tests/command_monitoring_unified_spec.rb +13 -0
  881. data/spec/spec_tests/connection_string_spec.rb +3 -0
  882. data/spec/spec_tests/crud_spec.rb +3 -10
  883. data/spec/spec_tests/crud_unified_spec.rb +13 -0
  884. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +41 -0
  885. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +103 -0
  886. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +120 -0
  887. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +351 -0
  888. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1169 -0
  889. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1069 -0
  890. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +307 -0
  891. data/spec/spec_tests/data/change_streams_unified/change-streams.yml +927 -0
  892. data/spec/spec_tests/data/client_side_encryption/aggregate.yml +3 -17
  893. data/spec/spec_tests/data/client_side_encryption/awsTemporary.yml +57 -0
  894. data/spec/spec_tests/data/client_side_encryption/azureKMS.yml +46 -0
  895. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +12 -2
  896. data/spec/spec_tests/data/client_side_encryption/basic.yml +3 -17
  897. data/spec/spec_tests/data/client_side_encryption/bulk.yml +1 -8
  898. data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +2 -2
  899. data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +5 -4
  900. data/spec/spec_tests/data/client_side_encryption/count.yml +1 -8
  901. data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +1 -8
  902. data/spec/spec_tests/data/client_side_encryption/create-and-createIndexes.yml +58 -0
  903. data/spec/spec_tests/data/client_side_encryption/delete.yml +2 -16
  904. data/spec/spec_tests/data/client_side_encryption/distinct.yml +1 -8
  905. data/spec/spec_tests/data/client_side_encryption/explain.yml +1 -8
  906. data/spec/spec_tests/data/client_side_encryption/find.yml +2 -16
  907. data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +1 -8
  908. data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +1 -8
  909. data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +1 -8
  910. data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +89 -0
  911. data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +82 -0
  912. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection-OldServer.yml +61 -0
  913. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +937 -0
  914. data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +66 -0
  915. data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +100 -0
  916. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +79 -0
  917. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +102 -0
  918. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +58 -0
  919. data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +200 -0
  920. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +96 -0
  921. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +89 -0
  922. data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +43 -0
  923. data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +44 -0
  924. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +241 -0
  925. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +422 -0
  926. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +182 -0
  927. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +239 -0
  928. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +235 -0
  929. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +252 -0
  930. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +1687 -0
  931. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +293 -0
  932. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +905 -0
  933. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +1684 -0
  934. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +1680 -0
  935. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +1697 -0
  936. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +329 -0
  937. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +424 -0
  938. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +226 -0
  939. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +327 -0
  940. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +319 -0
  941. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +336 -0
  942. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +913 -0
  943. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +292 -0
  944. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +518 -0
  945. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +911 -0
  946. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +907 -0
  947. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +924 -0
  948. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +325 -0
  949. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +424 -0
  950. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +224 -0
  951. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +323 -0
  952. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +319 -0
  953. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +338 -0
  954. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +241 -0
  955. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +423 -0
  956. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +182 -0
  957. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +239 -0
  958. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +235 -0
  959. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +254 -0
  960. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +241 -0
  961. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +422 -0
  962. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +182 -0
  963. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +239 -0
  964. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +235 -0
  965. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +254 -0
  966. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +43 -0
  967. data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +210 -0
  968. data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +169 -0
  969. data/spec/spec_tests/data/client_side_encryption/gcpKMS.yml +46 -0
  970. data/spec/spec_tests/data/client_side_encryption/getMore.yml +1 -8
  971. data/spec/spec_tests/data/client_side_encryption/insert.yml +2 -16
  972. data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +1 -8
  973. data/spec/spec_tests/data/client_side_encryption/localKMS.yml +1 -8
  974. data/spec/spec_tests/data/client_side_encryption/localSchema.yml +1 -8
  975. data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +3 -1
  976. data/spec/spec_tests/data/client_side_encryption/missingKey.yml +2 -9
  977. data/spec/spec_tests/data/client_side_encryption/noSchema.yml +39 -0
  978. data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +1 -8
  979. data/spec/spec_tests/data/client_side_encryption/types.yml +44 -70
  980. data/spec/spec_tests/data/client_side_encryption/unified/addKeyAltName.yml +194 -0
  981. data/spec/spec_tests/data/client_side_encryption/unified/createDataKey-kms_providers-invalid.yml +67 -0
  982. data/spec/spec_tests/data/client_side_encryption/unified/createDataKey.yml +309 -0
  983. data/spec/spec_tests/data/client_side_encryption/unified/deleteKey.yml +159 -0
  984. data/spec/spec_tests/data/client_side_encryption/unified/getKey.yml +105 -0
  985. data/spec/spec_tests/data/client_side_encryption/unified/getKeyByAltName.yml +104 -0
  986. data/spec/spec_tests/data/client_side_encryption/unified/getKeys.yml +122 -0
  987. data/spec/spec_tests/data/client_side_encryption/unified/removeKeyAltName.yml +157 -0
  988. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey-decrypt_failure.yml +69 -0
  989. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey-encrypt_failure.yml +122 -0
  990. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey.yml +432 -0
  991. data/spec/spec_tests/data/client_side_encryption/updateMany.yml +1 -8
  992. data/spec/spec_tests/data/client_side_encryption/updateOne.yml +1 -8
  993. data/spec/spec_tests/data/client_side_encryption/validatorAndPartialFieldExpression.yml +166 -0
  994. data/spec/spec_tests/data/cmap/connection-must-have-id.yml +2 -0
  995. data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +2 -0
  996. data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +2 -0
  997. data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +2 -0
  998. data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +3 -1
  999. data/spec/spec_tests/data/cmap/pool-checkin.yml +5 -0
  1000. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +8 -2
  1001. data/spec/spec_tests/data/cmap/pool-checkout-custom-maxConnecting-is-enforced.yml +50 -0
  1002. data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +2 -0
  1003. data/spec/spec_tests/data/cmap/pool-checkout-maxConnecting-is-enforced.yml +81 -0
  1004. data/spec/spec_tests/data/cmap/pool-checkout-maxConnecting-timeout.yml +71 -0
  1005. data/spec/spec_tests/data/cmap/pool-checkout-minPoolSize-connection-maxConnecting.yml +64 -0
  1006. data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +2 -0
  1007. data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +6 -0
  1008. data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +8 -0
  1009. data/spec/spec_tests/data/cmap/pool-checkout-returned-connection-maxConnecting.yml +88 -0
  1010. data/spec/spec_tests/data/cmap/pool-clear-interrupt-immediately.yml +49 -0
  1011. data/spec/spec_tests/data/cmap/pool-clear-interrupting-pending-connections.yml +43 -0
  1012. data/spec/spec_tests/data/cmap/pool-clear-min-size.yml +41 -0
  1013. data/spec/spec_tests/data/cmap/pool-clear-paused.yml +18 -0
  1014. data/spec/spec_tests/data/cmap/pool-clear-ready.yml +39 -0
  1015. data/spec/spec_tests/data/cmap/pool-clear-schedule-run-interruptInUseConnections-false.yml +48 -0
  1016. data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +2 -0
  1017. data/spec/spec_tests/data/cmap/pool-create-max-size.yml +2 -0
  1018. data/spec/spec_tests/data/cmap/pool-create-min-size-error.yml +43 -0
  1019. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +12 -0
  1020. data/spec/spec_tests/data/cmap/pool-ready-ready.yml +22 -0
  1021. data/spec/spec_tests/data/cmap/pool-ready.yml +30 -0
  1022. data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +2 -0
  1023. data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +6 -1
  1024. data/spec/spec_tests/data/collection_management/clustered-indexes.yml +135 -0
  1025. data/spec/spec_tests/data/collection_management/createCollection-pre_and_post_images.yml +50 -0
  1026. data/spec/spec_tests/data/collection_management/modifyCollection-errorResponse.yml +59 -0
  1027. data/spec/spec_tests/data/collection_management/modifyCollection-pre_and_post_images.yml +58 -0
  1028. data/spec/spec_tests/data/collection_management/timeseries-collection.yml +164 -0
  1029. data/spec/spec_tests/data/command_monitoring_unified/bulkWrite.yml +68 -0
  1030. data/spec/spec_tests/data/command_monitoring_unified/command.yml +50 -0
  1031. data/spec/spec_tests/data/command_monitoring_unified/deleteMany.yml +79 -0
  1032. data/spec/spec_tests/data/command_monitoring_unified/deleteOne.yml +79 -0
  1033. data/spec/spec_tests/data/command_monitoring_unified/find.yml +254 -0
  1034. data/spec/spec_tests/data/command_monitoring_unified/insertMany.yml +79 -0
  1035. data/spec/spec_tests/data/command_monitoring_unified/insertOne.yml +77 -0
  1036. data/spec/spec_tests/data/command_monitoring_unified/pre-42-server-connection-id.yml +56 -0
  1037. data/spec/spec_tests/data/command_monitoring_unified/redacted-commands.yml +348 -0
  1038. data/spec/spec_tests/data/command_monitoring_unified/server-connection-id.yml +56 -0
  1039. data/spec/spec_tests/data/command_monitoring_unified/unacknowledgedBulkWrite.yml +55 -0
  1040. data/spec/spec_tests/data/command_monitoring_unified/updateMany.yml +87 -0
  1041. data/spec/spec_tests/data/command_monitoring_unified/updateOne.yml +118 -0
  1042. data/spec/spec_tests/data/command_monitoring_unified/writeConcernError.yml +80 -0
  1043. data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
  1044. data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
  1045. data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
  1046. data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
  1047. data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
  1048. data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
  1049. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
  1050. data/spec/spec_tests/data/crud/write/bulkWrite.yml +26 -22
  1051. data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
  1052. data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
  1053. data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
  1054. data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
  1055. data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
  1056. data/spec/spec_tests/data/crud/write/insertMany.yml +26 -22
  1057. data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
  1058. data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
  1059. data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
  1060. data/spec/spec_tests/data/crud_unified/aggregate-allowdiskuse.yml +75 -0
  1061. data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
  1062. data/spec/spec_tests/data/crud_unified/aggregate-merge-errorResponse.yml +42 -0
  1063. data/spec/spec_tests/data/crud_unified/aggregate-merge.yml +185 -0
  1064. data/spec/spec_tests/data/crud_unified/aggregate-out-readConcern.yml +171 -0
  1065. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
  1066. data/spec/spec_tests/data/crud_unified/aggregate.yml +215 -0
  1067. data/spec/spec_tests/data/crud_unified/bulkWrite-arrayFilters-clientError.yml +98 -0
  1068. data/spec/spec_tests/data/crud_unified/bulkWrite-arrayFilters.yml +174 -0
  1069. data/spec/spec_tests/data/crud_unified/bulkWrite-comment.yml +189 -0
  1070. data/spec/spec_tests/data/crud_unified/bulkWrite-delete-hint-clientError.yml +113 -0
  1071. data/spec/spec_tests/data/crud_unified/bulkWrite-delete-hint-serverError.yml +142 -0
  1072. data/spec/spec_tests/data/crud_unified/bulkWrite-delete-hint.yml +154 -0
  1073. data/spec/spec_tests/data/crud_unified/bulkWrite-deleteMany-hint-unacknowledged.yml +98 -0
  1074. data/spec/spec_tests/data/crud_unified/bulkWrite-deleteMany-let.yml +86 -0
  1075. data/spec/spec_tests/data/crud_unified/bulkWrite-deleteOne-hint-unacknowledged.yml +97 -0
  1076. data/spec/spec_tests/data/crud_unified/bulkWrite-deleteOne-let.yml +86 -0
  1077. data/spec/spec_tests/data/crud_unified/bulkWrite-errorResponse.yml +50 -0
  1078. data/spec/spec_tests/data/crud_unified/bulkWrite-insertOne-dots_and_dollars.yml +138 -0
  1079. data/spec/spec_tests/data/crud_unified/bulkWrite-replaceOne-dots_and_dollars.yml +165 -0
  1080. data/spec/spec_tests/data/crud_unified/bulkWrite-replaceOne-hint-unacknowledged.yml +103 -0
  1081. data/spec/spec_tests/data/crud_unified/bulkWrite-replaceOne-let.yml +93 -0
  1082. data/spec/spec_tests/data/crud_unified/bulkWrite-update-hint-clientError.yml +148 -0
  1083. data/spec/spec_tests/data/crud_unified/bulkWrite-update-hint-serverError.yml +239 -0
  1084. data/spec/spec_tests/data/crud_unified/bulkWrite-update-hint.yml +256 -0
  1085. data/spec/spec_tests/data/crud_unified/bulkWrite-update-validation.yml +73 -0
  1086. data/spec/spec_tests/data/crud_unified/bulkWrite-updateMany-dots_and_dollars.yml +150 -0
  1087. data/spec/spec_tests/data/crud_unified/bulkWrite-updateMany-hint-unacknowledged.yml +104 -0
  1088. data/spec/spec_tests/data/crud_unified/bulkWrite-updateMany-let.yml +96 -0
  1089. data/spec/spec_tests/data/crud_unified/bulkWrite-updateOne-dots_and_dollars.yml +150 -0
  1090. data/spec/spec_tests/data/crud_unified/bulkWrite-updateOne-hint-unacknowledged.yml +103 -0
  1091. data/spec/spec_tests/data/crud_unified/bulkWrite-updateOne-let.yml +95 -0
  1092. data/spec/spec_tests/data/crud_unified/countDocuments-comment.yml +92 -0
  1093. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
  1094. data/spec/spec_tests/data/crud_unified/db-aggregate.yml +73 -0
  1095. data/spec/spec_tests/data/crud_unified/deleteMany-comment.yml +97 -0
  1096. data/spec/spec_tests/data/crud_unified/deleteMany-hint-clientError.yml +87 -0
  1097. data/spec/spec_tests/data/crud_unified/deleteMany-hint-serverError.yml +107 -0
  1098. data/spec/spec_tests/data/crud_unified/deleteMany-hint-unacknowledged.yml +90 -0
  1099. data/spec/spec_tests/data/crud_unified/deleteMany-hint.yml +99 -0
  1100. data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +93 -0
  1101. data/spec/spec_tests/data/crud_unified/deleteOne-comment.yml +98 -0
  1102. data/spec/spec_tests/data/crud_unified/deleteOne-errorResponse.yml +46 -0
  1103. data/spec/spec_tests/data/crud_unified/deleteOne-hint-clientError.yml +80 -0
  1104. data/spec/spec_tests/data/crud_unified/deleteOne-hint-serverError.yml +100 -0
  1105. data/spec/spec_tests/data/crud_unified/deleteOne-hint-unacknowledged.yml +89 -0
  1106. data/spec/spec_tests/data/crud_unified/deleteOne-hint.yml +95 -0
  1107. data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +91 -0
  1108. data/spec/spec_tests/data/crud_unified/distinct-comment.yml +98 -0
  1109. data/spec/spec_tests/data/crud_unified/estimatedDocumentCount-comment.yml +95 -0
  1110. data/spec/spec_tests/data/crud_unified/estimatedDocumentCount.yml +181 -0
  1111. data/spec/spec_tests/data/crud_unified/find-allowdiskuse-clientError.yml +55 -0
  1112. data/spec/spec_tests/data/crud_unified/find-allowdiskuse-serverError.yml +68 -0
  1113. data/spec/spec_tests/data/crud_unified/find-allowdiskuse.yml +79 -0
  1114. data/spec/spec_tests/data/crud_unified/find-comment.yml +166 -0
  1115. data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
  1116. data/spec/spec_tests/data/crud_unified/find.yml +68 -0
  1117. data/spec/spec_tests/data/crud_unified/findOneAndDelete-comment.yml +96 -0
  1118. data/spec/spec_tests/data/crud_unified/findOneAndDelete-hint-clientError.yml +91 -0
  1119. data/spec/spec_tests/data/crud_unified/findOneAndDelete-hint-serverError.yml +107 -0
  1120. data/spec/spec_tests/data/crud_unified/findOneAndDelete-hint-unacknowledged.yml +88 -0
  1121. data/spec/spec_tests/data/crud_unified/findOneAndDelete-hint.yml +102 -0
  1122. data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +86 -0
  1123. data/spec/spec_tests/data/crud_unified/findOneAndReplace-comment.yml +101 -0
  1124. data/spec/spec_tests/data/crud_unified/findOneAndReplace-dots_and_dollars.yml +140 -0
  1125. data/spec/spec_tests/data/crud_unified/findOneAndReplace-hint-clientError.yml +83 -0
  1126. data/spec/spec_tests/data/crud_unified/findOneAndReplace-hint-serverError.yml +99 -0
  1127. data/spec/spec_tests/data/crud_unified/findOneAndReplace-hint-unacknowledged.yml +96 -0
  1128. data/spec/spec_tests/data/crud_unified/findOneAndReplace-hint.yml +98 -0
  1129. data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
  1130. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-comment.yml +95 -0
  1131. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-dots_and_dollars.yml +127 -0
  1132. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-errorResponse.yml +69 -0
  1133. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-hint-clientError.yml +84 -0
  1134. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-hint-serverError.yml +100 -0
  1135. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-hint-unacknowledged.yml +92 -0
  1136. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-hint.yml +99 -0
  1137. data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
  1138. data/spec/spec_tests/data/crud_unified/insertMany-comment.yml +93 -0
  1139. data/spec/spec_tests/data/crud_unified/insertMany-dots_and_dollars.yml +128 -0
  1140. data/spec/spec_tests/data/crud_unified/insertOne-comment.yml +91 -0
  1141. data/spec/spec_tests/data/crud_unified/insertOne-dots_and_dollars.yml +238 -0
  1142. data/spec/spec_tests/data/crud_unified/insertOne-errorResponse.yml +46 -0
  1143. data/spec/spec_tests/data/crud_unified/replaceOne-comment.yml +105 -0
  1144. data/spec/spec_tests/data/crud_unified/replaceOne-dots_and_dollars.yml +180 -0
  1145. data/spec/spec_tests/data/crud_unified/replaceOne-hint-unacknowledged.yml +95 -0
  1146. data/spec/spec_tests/data/crud_unified/replaceOne-hint.yml +108 -0
  1147. data/spec/spec_tests/data/crud_unified/replaceOne-let.yml +98 -0
  1148. data/spec/spec_tests/data/crud_unified/replaceOne-validation.yml +37 -0
  1149. data/spec/spec_tests/data/crud_unified/updateMany-comment.yml +104 -0
  1150. data/spec/spec_tests/data/crud_unified/updateMany-dots_and_dollars.yml +138 -0
  1151. data/spec/spec_tests/data/crud_unified/updateMany-hint-clientError.yml +91 -0
  1152. data/spec/spec_tests/data/crud_unified/updateMany-hint-serverError.yml +115 -0
  1153. data/spec/spec_tests/data/crud_unified/updateMany-hint-unacknowledged.yml +96 -0
  1154. data/spec/spec_tests/data/crud_unified/updateMany-hint.yml +115 -0
  1155. data/spec/spec_tests/data/crud_unified/updateMany-let.yml +107 -0
  1156. data/spec/spec_tests/data/crud_unified/updateMany-validation.yml +39 -0
  1157. data/spec/spec_tests/data/crud_unified/updateOne-comment.yml +104 -0
  1158. data/spec/spec_tests/data/crud_unified/updateOne-dots_and_dollars.yml +138 -0
  1159. data/spec/spec_tests/data/crud_unified/updateOne-errorResponse.yml +47 -0
  1160. data/spec/spec_tests/data/crud_unified/updateOne-hint-clientError.yml +85 -0
  1161. data/spec/spec_tests/data/crud_unified/updateOne-hint-serverError.yml +109 -0
  1162. data/spec/spec_tests/data/crud_unified/updateOne-hint-unacknowledged.yml +95 -0
  1163. data/spec/spec_tests/data/crud_unified/updateOne-hint.yml +109 -0
  1164. data/spec/spec_tests/data/crud_unified/updateOne-let.yml +102 -0
  1165. data/spec/spec_tests/data/crud_unified/updateOne-validation.yml +37 -0
  1166. data/spec/spec_tests/data/crud_unified/updateWithPipelines.yml +299 -0
  1167. data/spec/spec_tests/data/gridfs_unified/delete.yml +198 -0
  1168. data/spec/spec_tests/data/gridfs_unified/download.yml +241 -0
  1169. data/spec/spec_tests/data/gridfs_unified/downloadByName.yml +159 -0
  1170. data/spec/spec_tests/data/gridfs_unified/upload-disableMD5.yml +92 -0
  1171. data/spec/spec_tests/data/gridfs_unified/upload.yml +288 -0
  1172. data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
  1173. data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
  1174. data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
  1175. data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
  1176. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
  1177. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
  1178. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
  1179. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
  1180. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
  1181. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
  1182. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
  1183. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
  1184. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
  1185. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
  1186. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
  1187. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
  1188. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
  1189. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
  1190. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
  1191. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
  1192. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
  1193. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
  1194. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
  1195. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
  1196. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
  1197. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
  1198. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
  1199. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
  1200. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
  1201. data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
  1202. data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
  1203. data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
  1204. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
  1205. data/spec/spec_tests/data/retryable_reads/legacy/aggregate-serverErrors.yml +157 -0
  1206. data/spec/spec_tests/data/retryable_reads/legacy/changeStreams-client.watch-serverErrors.yml +150 -0
  1207. data/spec/spec_tests/data/retryable_reads/legacy/changeStreams-client.watch.yml +62 -0
  1208. data/spec/spec_tests/data/retryable_reads/legacy/changeStreams-db.coll.watch-serverErrors.yml +150 -0
  1209. data/spec/spec_tests/data/retryable_reads/legacy/changeStreams-db.coll.watch.yml +66 -0
  1210. data/spec/spec_tests/data/retryable_reads/legacy/changeStreams-db.watch-serverErrors.yml +154 -0
  1211. data/spec/spec_tests/data/retryable_reads/legacy/changeStreams-db.watch.yml +62 -0
  1212. data/spec/spec_tests/data/retryable_reads/legacy/count-serverErrors.yml +150 -0
  1213. data/spec/spec_tests/data/retryable_reads/legacy/countDocuments-serverErrors.yml +150 -0
  1214. data/spec/spec_tests/data/retryable_reads/legacy/distinct-serverErrors.yml +156 -0
  1215. data/spec/spec_tests/data/retryable_reads/legacy/estimatedDocumentCount-serverErrors.yml +148 -0
  1216. data/spec/spec_tests/data/retryable_reads/legacy/find-serverErrors.yml +160 -0
  1217. data/spec/spec_tests/data/retryable_reads/legacy/findOne-serverErrors.yml +154 -0
  1218. data/spec/spec_tests/data/retryable_reads/legacy/gridfs-download-serverErrors.yml +173 -0
  1219. data/spec/spec_tests/data/retryable_reads/legacy/gridfs-downloadByName-serverErrors.yml +174 -0
  1220. data/spec/spec_tests/data/retryable_reads/legacy/listCollectionNames-serverErrors.yml +143 -0
  1221. data/spec/spec_tests/data/retryable_reads/legacy/listCollectionObjects-serverErrors.yml +144 -0
  1222. data/spec/spec_tests/data/retryable_reads/legacy/listCollections-serverErrors.yml +143 -0
  1223. data/spec/spec_tests/data/retryable_reads/legacy/listDatabaseNames-serverErrors.yml +143 -0
  1224. data/spec/spec_tests/data/retryable_reads/legacy/listDatabaseObjects-serverErrors.yml +144 -0
  1225. data/spec/spec_tests/data/retryable_reads/legacy/listDatabases-serverErrors.yml +144 -0
  1226. data/spec/spec_tests/data/retryable_reads/legacy/listIndexNames-serverErrors.yml +144 -0
  1227. data/spec/spec_tests/data/retryable_reads/legacy/listIndexNames.yml +60 -0
  1228. data/spec/spec_tests/data/retryable_reads/legacy/listIndexes-serverErrors.yml +145 -0
  1229. data/spec/spec_tests/data/retryable_reads/legacy/mapReduce.yml +62 -0
  1230. data/spec/spec_tests/data/retryable_reads/unified/handshakeError.yml +1342 -0
  1231. data/spec/spec_tests/data/retryable_writes/legacy/bulkWrite-serverErrors.yml +130 -0
  1232. data/spec/spec_tests/data/retryable_writes/legacy/bulkWrite.yml +402 -0
  1233. data/spec/spec_tests/data/retryable_writes/legacy/deleteOne-serverErrors.yml +73 -0
  1234. data/spec/spec_tests/data/retryable_writes/legacy/findOneAndDelete-serverErrors.yml +74 -0
  1235. data/spec/spec_tests/data/retryable_writes/legacy/findOneAndReplace-serverErrors.yml +80 -0
  1236. data/spec/spec_tests/data/retryable_writes/legacy/findOneAndUpdate-serverErrors.yml +79 -0
  1237. data/spec/spec_tests/data/retryable_writes/legacy/insertMany-serverErrors.yml +84 -0
  1238. data/spec/spec_tests/data/retryable_writes/legacy/insertOne-serverErrors.yml +527 -0
  1239. data/spec/spec_tests/data/retryable_writes/legacy/replaceOne-serverErrors.yml +82 -0
  1240. data/spec/spec_tests/data/retryable_writes/legacy/updateOne-serverErrors.yml +82 -0
  1241. data/spec/spec_tests/data/retryable_writes/unified/bulkWrite-serverErrors.yml +96 -0
  1242. data/spec/spec_tests/data/retryable_writes/unified/handshakeError.yml +785 -0
  1243. data/spec/spec_tests/data/retryable_writes/unified/insertOne-noWritesPerformedError.yml +54 -0
  1244. data/spec/spec_tests/data/retryable_writes/unified/insertOne-serverErrors.yml +78 -0
  1245. data/spec/spec_tests/data/sdam/errors/error_handling_handshake.yml +2 -1
  1246. data/spec/spec_tests/data/sdam/errors/non-stale-network-error.yml +2 -1
  1247. data/spec/spec_tests/data/sdam/errors/non-stale-network-timeout-error.yml +2 -1
  1248. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedAtShutdown.yml +2 -1
  1249. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedDueToReplStateChange.yml +2 -1
  1250. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-LegacyNotPrimary.yml +61 -0
  1251. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotPrimaryNoSecondaryOk.yml +61 -0
  1252. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotPrimaryOrSecondary.yml +61 -0
  1253. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotWritablePrimary.yml +61 -0
  1254. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-PrimarySteppedDown.yml +2 -1
  1255. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-ShutdownInProgress.yml +2 -1
  1256. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedAtShutdown.yml +2 -1
  1257. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedDueToReplStateChange.yml +2 -1
  1258. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-LegacyNotPrimary.yml +52 -0
  1259. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotPrimaryNoSecondaryOk.yml +52 -0
  1260. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotPrimaryOrSecondary.yml +52 -0
  1261. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotWritablePrimary.yml +52 -0
  1262. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-PrimarySteppedDown.yml +2 -1
  1263. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-ShutdownInProgress.yml +2 -1
  1264. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedAtShutdown.yml +2 -1
  1265. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedDueToReplStateChange.yml +2 -1
  1266. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-LegacyNotPrimary.yml +61 -0
  1267. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotPrimaryNoSecondaryOk.yml +61 -0
  1268. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotPrimaryOrSecondary.yml +61 -0
  1269. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotWritablePrimary.yml +61 -0
  1270. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-PrimarySteppedDown.yml +2 -1
  1271. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-ShutdownInProgress.yml +2 -1
  1272. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedAtShutdown.yml +2 -1
  1273. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedDueToReplStateChange.yml +2 -1
  1274. data/spec/spec_tests/data/sdam/errors/post-42-LegacyNotPrimary.yml +47 -0
  1275. data/spec/spec_tests/data/sdam/errors/post-42-NotPrimaryNoSecondaryOk.yml +47 -0
  1276. data/spec/spec_tests/data/sdam/errors/post-42-NotPrimaryOrSecondary.yml +47 -0
  1277. data/spec/spec_tests/data/sdam/errors/post-42-NotWritablePrimary.yml +47 -0
  1278. data/spec/spec_tests/data/sdam/errors/post-42-PrimarySteppedDown.yml +2 -1
  1279. data/spec/spec_tests/data/sdam/errors/post-42-ShutdownInProgress.yml +2 -1
  1280. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedAtShutdown.yml +2 -1
  1281. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedDueToReplStateChange.yml +2 -1
  1282. data/spec/spec_tests/data/sdam/errors/pre-42-LegacyNotPrimary.yml +47 -0
  1283. data/spec/spec_tests/data/sdam/errors/pre-42-NotPrimaryNoSecondaryOk.yml +47 -0
  1284. data/spec/spec_tests/data/sdam/errors/pre-42-NotPrimaryOrSecondary.yml +47 -0
  1285. data/spec/spec_tests/data/sdam/errors/pre-42-NotWritablePrimary.yml +47 -0
  1286. data/spec/spec_tests/data/sdam/errors/pre-42-PrimarySteppedDown.yml +2 -1
  1287. data/spec/spec_tests/data/sdam/errors/pre-42-ShutdownInProgress.yml +2 -1
  1288. data/spec/spec_tests/data/sdam/errors/prefer-error-code.yml +54 -0
  1289. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedAtShutdown.yml +4 -2
  1290. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedDueToReplStateChange.yml +4 -2
  1291. data/spec/spec_tests/data/sdam/errors/stale-generation-NotPrimaryNoSecondaryOk.yml +91 -0
  1292. data/spec/spec_tests/data/sdam/errors/stale-generation-NotPrimaryOrSecondary.yml +91 -0
  1293. data/spec/spec_tests/data/sdam/errors/stale-generation-NotWritablePrimary.yml +91 -0
  1294. data/spec/spec_tests/data/sdam/errors/stale-generation-PrimarySteppedDown.yml +4 -2
  1295. data/spec/spec_tests/data/sdam/errors/stale-generation-ShutdownInProgress.yml +4 -2
  1296. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedAtShutdown.yml +4 -2
  1297. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedDueToReplStateChange.yml +4 -2
  1298. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-LegacyNotPrimary.yml +91 -0
  1299. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotPrimaryNoSecondaryOk.yml +91 -0
  1300. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotPrimaryOrSecondary.yml +91 -0
  1301. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotWritablePrimary.yml +91 -0
  1302. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-PrimarySteppedDown.yml +4 -2
  1303. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-ShutdownInProgress.yml +4 -2
  1304. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-network.yml +6 -4
  1305. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-timeout.yml +6 -4
  1306. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedAtShutdown.yml +4 -2
  1307. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedDueToReplStateChange.yml +4 -2
  1308. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-LegacyNotPrimary.yml +91 -0
  1309. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotPrimaryNoSecondaryOk.yml +91 -0
  1310. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotPrimaryOrSecondary.yml +91 -0
  1311. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotWritablePrimary.yml +91 -0
  1312. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-PrimarySteppedDown.yml +4 -2
  1313. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-ShutdownInProgress.yml +4 -2
  1314. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-network.yml +6 -4
  1315. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-timeout.yml +6 -4
  1316. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedAtShutdown.yml +2 -1
  1317. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedDueToReplStateChange.yml +2 -1
  1318. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-LegacyNotPrimary.yml +65 -0
  1319. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotPrimaryNoSecondaryOk.yml +65 -0
  1320. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotPrimaryOrSecondary.yml +65 -0
  1321. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotWritablePrimary.yml +65 -0
  1322. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-PrimarySteppedDown.yml +2 -1
  1323. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-ShutdownInProgress.yml +2 -1
  1324. data/spec/spec_tests/data/sdam/errors/write_errors_ignored.yml +42 -0
  1325. data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
  1326. data/spec/spec_tests/data/sdam/rs/compatible.yml +4 -2
  1327. data/spec/spec_tests/data/sdam/rs/compatible_unknown.yml +2 -1
  1328. data/spec/spec_tests/data/sdam/rs/discover_arbiters.yml +2 -1
  1329. data/spec/spec_tests/data/sdam/rs/discover_arbiters_replicaset.yml +2 -1
  1330. data/spec/spec_tests/data/sdam/rs/discover_ghost.yml +2 -1
  1331. data/spec/spec_tests/data/sdam/rs/discover_ghost_replicaset.yml +2 -1
  1332. data/spec/spec_tests/data/sdam/rs/discover_hidden.yml +2 -1
  1333. data/spec/spec_tests/data/sdam/rs/discover_hidden_replicaset.yml +2 -1
  1334. data/spec/spec_tests/data/sdam/rs/discover_passives.yml +4 -2
  1335. data/spec/spec_tests/data/sdam/rs/discover_passives_replicaset.yml +4 -2
  1336. data/spec/spec_tests/data/sdam/rs/discover_primary.yml +2 -1
  1337. data/spec/spec_tests/data/sdam/rs/discover_primary_replicaset.yml +2 -1
  1338. data/spec/spec_tests/data/sdam/rs/discover_rsother.yml +2 -1
  1339. data/spec/spec_tests/data/sdam/rs/discover_rsother_replicaset.yml +4 -2
  1340. data/spec/spec_tests/data/sdam/rs/discover_secondary.yml +2 -1
  1341. data/spec/spec_tests/data/sdam/rs/discover_secondary_replicaset.yml +2 -1
  1342. data/spec/spec_tests/data/sdam/rs/discovery.yml +8 -4
  1343. data/spec/spec_tests/data/sdam/rs/electionId_precedence_setVersion.yml +62 -0
  1344. data/spec/spec_tests/data/sdam/rs/equal_electionids.yml +4 -2
  1345. data/spec/spec_tests/data/sdam/rs/hosts_differ_from_seeds.yml +2 -1
  1346. data/spec/spec_tests/data/sdam/rs/incompatible_arbiter.yml +3 -1
  1347. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +3 -1
  1348. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +3 -1
  1349. data/spec/spec_tests/data/sdam/rs/ls_timeout.yml +12 -6
  1350. data/spec/spec_tests/data/sdam/rs/member_reconfig.yml +4 -2
  1351. data/spec/spec_tests/data/sdam/rs/member_standalone.yml +4 -2
  1352. data/spec/spec_tests/data/sdam/rs/new_primary.yml +4 -2
  1353. data/spec/spec_tests/data/sdam/rs/new_primary_new_electionid.yml +6 -3
  1354. data/spec/spec_tests/data/sdam/rs/new_primary_new_setversion.yml +6 -3
  1355. data/spec/spec_tests/data/sdam/rs/new_primary_wrong_set_name.yml +4 -2
  1356. data/spec/spec_tests/data/sdam/rs/non_rs_member.yml +1 -0
  1357. data/spec/spec_tests/data/sdam/rs/normalize_case.yml +2 -1
  1358. data/spec/spec_tests/data/sdam/rs/normalize_case_me.yml +4 -2
  1359. data/spec/spec_tests/data/sdam/rs/null_election_id-pre-6.0.yml +175 -0
  1360. data/spec/spec_tests/data/sdam/rs/null_election_id.yml +28 -22
  1361. data/spec/spec_tests/data/sdam/rs/primary_becomes_ghost.yml +4 -2
  1362. data/spec/spec_tests/data/sdam/rs/primary_becomes_mongos.yml +4 -2
  1363. data/spec/spec_tests/data/sdam/rs/primary_becomes_standalone.yml +2 -1
  1364. data/spec/spec_tests/data/sdam/rs/primary_changes_set_name.yml +4 -2
  1365. data/spec/spec_tests/data/sdam/rs/primary_disconnect.yml +2 -1
  1366. data/spec/spec_tests/data/sdam/rs/primary_disconnect_electionid.yml +10 -5
  1367. data/spec/spec_tests/data/sdam/rs/primary_disconnect_setversion.yml +10 -5
  1368. data/spec/spec_tests/data/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +4 -2
  1369. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +2 -1
  1370. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +5 -3
  1371. data/spec/spec_tests/data/sdam/rs/primary_reports_new_member.yml +8 -4
  1372. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +4 -2
  1373. data/spec/spec_tests/data/sdam/rs/primary_wrong_set_name.yml +2 -1
  1374. data/spec/spec_tests/data/sdam/rs/repeated.yml +9 -5
  1375. data/spec/spec_tests/data/sdam/rs/replicaset_rsnp.yml +2 -1
  1376. data/spec/spec_tests/data/sdam/rs/response_from_removed.yml +4 -2
  1377. data/spec/spec_tests/data/sdam/rs/sec_not_auth.yml +4 -2
  1378. data/spec/spec_tests/data/sdam/rs/secondary_ignore_ok_0-pre-6.0.yml +87 -0
  1379. data/spec/spec_tests/data/sdam/rs/secondary_ignore_ok_0.yml +5 -3
  1380. data/spec/spec_tests/data/sdam/rs/secondary_mismatched_me.yml +2 -1
  1381. data/spec/spec_tests/data/sdam/rs/secondary_wrong_set_name.yml +2 -1
  1382. data/spec/spec_tests/data/sdam/rs/secondary_wrong_set_name_with_primary.yml +4 -2
  1383. data/spec/spec_tests/data/sdam/rs/set_version_can_rollback.yml +101 -0
  1384. data/spec/spec_tests/data/sdam/rs/setversion_equal_max_without_electionid.yml +78 -0
  1385. data/spec/spec_tests/data/sdam/rs/setversion_greaterthan_max_without_electionid.yml +79 -0
  1386. data/spec/spec_tests/data/sdam/rs/setversion_without_electionid-pre-6.0.yml +79 -0
  1387. data/spec/spec_tests/data/sdam/rs/setversion_without_electionid.yml +13 -12
  1388. data/spec/spec_tests/data/sdam/rs/stepdown_change_set_name.yml +4 -2
  1389. data/spec/spec_tests/data/sdam/rs/too_new.yml +4 -2
  1390. data/spec/spec_tests/data/sdam/rs/too_old.yml +4 -2
  1391. data/spec/spec_tests/data/sdam/rs/topology_version_equal.yml +4 -2
  1392. data/spec/spec_tests/data/sdam/rs/topology_version_greater.yml +10 -5
  1393. data/spec/spec_tests/data/sdam/rs/topology_version_less.yml +4 -2
  1394. data/spec/spec_tests/data/sdam/rs/unexpected_mongos.yml +2 -1
  1395. data/spec/spec_tests/data/sdam/rs/use_setversion_without_electionid-pre-6.0.yml +117 -0
  1396. data/spec/spec_tests/data/sdam/rs/use_setversion_without_electionid.yml +29 -24
  1397. data/spec/spec_tests/data/sdam/rs/wrong_set_name.yml +2 -1
  1398. data/spec/spec_tests/data/sdam/sharded/compatible.yml +4 -2
  1399. data/spec/spec_tests/data/sdam/sharded/discover_single_mongos.yml +2 -1
  1400. data/spec/spec_tests/data/sdam/sharded/ls_timeout_mongos.yml +9 -5
  1401. data/spec/spec_tests/data/sdam/sharded/mongos_disconnect.yml +6 -3
  1402. data/spec/spec_tests/data/sdam/sharded/multiple_mongoses.yml +4 -2
  1403. data/spec/spec_tests/data/sdam/sharded/non_mongos_removed.yml +4 -2
  1404. data/spec/spec_tests/data/sdam/sharded/too_new.yml +4 -2
  1405. data/spec/spec_tests/data/sdam/sharded/too_old.yml +4 -2
  1406. data/spec/spec_tests/data/sdam/single/compatible.yml +2 -1
  1407. data/spec/spec_tests/data/sdam/single/direct_connection_external_ip.yml +2 -1
  1408. data/spec/spec_tests/data/sdam/single/direct_connection_mongos.yml +2 -1
  1409. data/spec/spec_tests/data/sdam/single/direct_connection_replicaset.yml +2 -1
  1410. data/spec/spec_tests/data/sdam/single/direct_connection_rsarbiter.yml +2 -1
  1411. data/spec/spec_tests/data/sdam/single/direct_connection_rsprimary.yml +2 -1
  1412. data/spec/spec_tests/data/sdam/single/direct_connection_rssecondary.yml +2 -1
  1413. data/spec/spec_tests/data/sdam/single/direct_connection_standalone.yml +2 -1
  1414. data/spec/spec_tests/data/sdam/single/direct_connection_wrong_set_name.yml +4 -2
  1415. data/spec/spec_tests/data/sdam/single/discover_standalone.yml +2 -1
  1416. data/spec/spec_tests/data/sdam/single/ls_timeout_standalone.yml +2 -1
  1417. data/spec/spec_tests/data/sdam/single/not_ok_response.yml +5 -3
  1418. data/spec/spec_tests/data/sdam/single/standalone_removed.yml +2 -1
  1419. data/spec/spec_tests/data/sdam/single/standalone_using_legacy_hello.yml +34 -0
  1420. data/spec/spec_tests/data/sdam/single/too_new.yml +2 -1
  1421. data/spec/spec_tests/data/sdam/single/too_old.yml +2 -1
  1422. data/spec/spec_tests/data/sdam/single/too_old_then_upgraded.yml +4 -2
  1423. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +2 -4
  1424. data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
  1425. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_no_primary.yml +40 -40
  1426. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary.yml +40 -40
  1427. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +4 -3
  1428. data/spec/spec_tests/data/sdam_monitoring/required_replica_set.yml +3 -2
  1429. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +3 -3
  1430. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
  1431. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +4 -4
  1432. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
  1433. data/spec/spec_tests/data/sdam_unified/auth-error.yml +130 -0
  1434. data/spec/spec_tests/data/sdam_unified/auth-misc-command-error.yml +132 -0
  1435. data/spec/spec_tests/data/sdam_unified/auth-network-error.yml +132 -0
  1436. data/spec/spec_tests/data/sdam_unified/auth-network-timeout-error.yml +138 -0
  1437. data/spec/spec_tests/data/sdam_unified/auth-shutdown-error.yml +133 -0
  1438. data/spec/spec_tests/data/sdam_unified/cancel-server-check.yml +143 -0
  1439. data/spec/spec_tests/data/sdam_unified/connectTimeoutMS.yml +130 -0
  1440. data/spec/spec_tests/data/sdam_unified/find-network-error.yml +135 -0
  1441. data/spec/spec_tests/data/sdam_unified/find-network-timeout-error.yml +119 -0
  1442. data/spec/spec_tests/data/sdam_unified/find-shutdown-error.yml +163 -0
  1443. data/spec/spec_tests/data/sdam_unified/hello-command-error.yml +233 -0
  1444. data/spec/spec_tests/data/sdam_unified/hello-network-error.yml +228 -0
  1445. data/spec/spec_tests/data/sdam_unified/hello-timeout.yml +318 -0
  1446. data/spec/spec_tests/data/sdam_unified/insert-network-error.yml +137 -0
  1447. data/spec/spec_tests/data/sdam_unified/insert-shutdown-error.yml +162 -0
  1448. data/spec/spec_tests/data/sdam_unified/interruptInUse-pool-clear.yml +340 -0
  1449. data/spec/spec_tests/data/sdam_unified/minPoolSize-error.yml +125 -0
  1450. data/spec/spec_tests/data/sdam_unified/pool-cleared-error.yml +239 -0
  1451. data/spec/spec_tests/data/sdam_unified/rediscover-quickly-after-step-down.yml +144 -0
  1452. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +14 -0
  1453. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-no-results.yml +5 -0
  1454. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
  1455. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
  1456. data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +11 -0
  1457. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-conflicts_with_loadBalanced-true-txt.yml +5 -0
  1458. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-conflicts_with_loadBalanced-true.yml +5 -0
  1459. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-zero-txt.yml +11 -0
  1460. data/spec/spec_tests/data/seed_list_discovery/load-balanced/srvMaxHosts-zero.yml +11 -0
  1461. data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
  1462. data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
  1463. data/spec/spec_tests/data/seed_list_discovery/replica-set/srv-service-name.yml +11 -0
  1464. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-conflicts_with_replicaSet-txt.yml +5 -0
  1465. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-conflicts_with_replicaSet.yml +5 -0
  1466. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-equal_to_srv_records.yml +16 -0
  1467. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-greater_than_srv_records.yml +15 -0
  1468. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-less_than_srv_records.yml +15 -0
  1469. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-zero-txt.yml +15 -0
  1470. data/spec/spec_tests/data/seed_list_discovery/replica-set/srvMaxHosts-zero.yml +15 -0
  1471. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
  1472. data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
  1473. data/spec/spec_tests/data/seed_list_discovery/sharded/srvMaxHosts-equal_to_srv_records.yml +13 -0
  1474. data/spec/spec_tests/data/seed_list_discovery/sharded/srvMaxHosts-greater_than_srv_records.yml +12 -0
  1475. data/spec/spec_tests/data/seed_list_discovery/sharded/srvMaxHosts-less_than_srv_records.yml +10 -0
  1476. data/spec/spec_tests/data/seed_list_discovery/sharded/srvMaxHosts-zero.yml +11 -0
  1477. data/spec/spec_tests/data/server_selection/Unknown/read/ghost.yml +11 -0
  1478. data/spec/spec_tests/data/server_selection/Unknown/write/ghost.yml +11 -0
  1479. data/spec/spec_tests/data/sessions_unified/driver-sessions-server-support.yml +123 -0
  1480. data/spec/spec_tests/data/sessions_unified/implicit-sessions-default-causal-consistency.yml +119 -0
  1481. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +75 -0
  1482. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
  1483. data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
  1484. data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
  1485. data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
  1486. data/spec/spec_tests/data/transactions/errors-client.yml +8 -9
  1487. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +3 -0
  1488. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +3 -1
  1489. data/spec/spec_tests/data/transactions/pin-mongos.yml +6 -3
  1490. data/spec/spec_tests/data/transactions/retryable-abort.yml +7 -7
  1491. data/spec/spec_tests/data/transactions/retryable-commit.yml +7 -7
  1492. data/spec/spec_tests/data/transactions_unified/do-not-retry-read-in-transaction.yml +64 -0
  1493. data/spec/spec_tests/data/transactions_unified/mongos-unpin.yml +172 -0
  1494. data/spec/spec_tests/data/transactions_unified/retryable-abort-handshake.yml +118 -0
  1495. data/spec/spec_tests/data/transactions_unified/retryable-commit-handshake.yml +118 -0
  1496. data/spec/spec_tests/data/unified/valid-fail/entity-findCursor-malformed.yml +31 -0
  1497. data/spec/spec_tests/data/unified/valid-fail/entity-findCursor.yml +31 -0
  1498. data/spec/spec_tests/data/unified/valid-fail/ignoreResultAndError-malformed.yml +34 -0
  1499. data/spec/spec_tests/data/unified/valid-fail/ignoreResultAndError.yml +35 -0
  1500. data/spec/spec_tests/data/unified/valid-fail/operation-failure.yml +31 -0
  1501. data/spec/spec_tests/data/unified/valid-fail/operation-unsupported.yml +13 -0
  1502. data/spec/spec_tests/data/unified/valid-pass/assertNumberConnectionsCheckedOut.yml +17 -0
  1503. data/spec/spec_tests/data/unified/valid-pass/collectionData-createOptions.yml +37 -0
  1504. data/spec/spec_tests/data/unified/valid-pass/entity-client-cmap-events.yml +40 -0
  1505. data/spec/spec_tests/data/unified/valid-pass/entity-client-storeEventsAsEntities.yml +37 -0
  1506. data/spec/spec_tests/data/unified/valid-pass/expectedError-errorResponse.yml +39 -0
  1507. data/spec/spec_tests/data/unified/valid-pass/expectedEventsForClient-eventType.yml +66 -0
  1508. data/spec/spec_tests/data/unified/valid-pass/expectedEventsForClient-ignoreExtraEvents.yml +78 -0
  1509. data/spec/spec_tests/data/unified/valid-pass/ignoreResultAndError.yml +34 -0
  1510. data/spec/spec_tests/data/unified/valid-pass/observeSensitiveCommands.yml +255 -0
  1511. data/spec/spec_tests/data/unified/valid-pass/poc-change-streams.yml +241 -0
  1512. data/spec/spec_tests/data/unified/valid-pass/poc-command-monitoring.yml +102 -0
  1513. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +190 -0
  1514. data/spec/spec_tests/data/unified/valid-pass/poc-gridfs.yml +155 -0
  1515. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-reads.yml +193 -0
  1516. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +210 -0
  1517. data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +215 -0
  1518. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +235 -0
  1519. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +169 -0
  1520. data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +171 -0
  1521. data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
  1522. data/spec/spec_tests/data/uri_options/compression-options.yml +7 -4
  1523. data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
  1524. data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
  1525. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
  1526. data/spec/spec_tests/data/uri_options/srv-options.yml +96 -0
  1527. data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
  1528. data/spec/spec_tests/data/versioned_api/crud-api-version-1-strict.yml +419 -0
  1529. data/spec/spec_tests/data/versioned_api/crud-api-version-1.yml +413 -0
  1530. data/spec/spec_tests/data/versioned_api/runcommand-helper-no-api-version-declared.yml +75 -0
  1531. data/spec/spec_tests/data/versioned_api/test-commands-deprecation-errors.yml +47 -0
  1532. data/spec/spec_tests/data/versioned_api/test-commands-strict-mode.yml +46 -0
  1533. data/spec/spec_tests/data/versioned_api/transaction-handling.yml +128 -0
  1534. data/spec/spec_tests/gridfs_spec.rb +3 -0
  1535. data/spec/spec_tests/gridfs_unified_spec.rb +13 -0
  1536. data/spec/spec_tests/load_balancers_spec.rb +15 -0
  1537. data/spec/spec_tests/max_staleness_spec.rb +3 -0
  1538. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +3 -0
  1539. data/spec/spec_tests/read_write_concern_document_spec.rb +3 -0
  1540. data/spec/spec_tests/read_write_concern_operaton_spec.rb +3 -0
  1541. data/spec/spec_tests/retryable_reads_spec.rb +11 -3
  1542. data/spec/spec_tests/retryable_reads_unified_spec.rb +22 -0
  1543. data/spec/spec_tests/retryable_writes_spec.rb +14 -8
  1544. data/spec/spec_tests/retryable_writes_unified_spec.rb +21 -0
  1545. data/spec/spec_tests/sdam_monitoring_spec.rb +14 -6
  1546. data/spec/spec_tests/sdam_spec.rb +9 -2
  1547. data/spec/spec_tests/sdam_unified_spec.rb +13 -0
  1548. data/spec/spec_tests/seed_list_discovery_spec.rb +127 -0
  1549. data/spec/spec_tests/server_selection_rtt_spec.rb +3 -0
  1550. data/spec/spec_tests/server_selection_spec.rb +3 -0
  1551. data/spec/spec_tests/sessions_unified_spec.rb +13 -0
  1552. data/spec/spec_tests/transactions_api_spec.rb +3 -0
  1553. data/spec/spec_tests/transactions_spec.rb +3 -0
  1554. data/spec/spec_tests/transactions_unified_spec.rb +13 -0
  1555. data/spec/spec_tests/unified_spec.rb +18 -0
  1556. data/spec/spec_tests/uri_options_spec.rb +50 -33
  1557. data/spec/spec_tests/versioned_api_spec.rb +13 -0
  1558. data/spec/stress/cleanup_spec.rb +3 -0
  1559. data/spec/stress/connection_pool_stress_spec.rb +3 -61
  1560. data/spec/stress/connection_pool_timing_spec.rb +14 -35
  1561. data/spec/stress/fork_reconnect_stress_spec.rb +17 -18
  1562. data/spec/stress/push_monitor_close_spec.rb +44 -0
  1563. data/spec/support/authorization.rb +4 -1
  1564. data/spec/support/aws_utils/base.rb +3 -0
  1565. data/spec/support/aws_utils/inspector.rb +3 -0
  1566. data/spec/support/aws_utils/orchestrator.rb +22 -7
  1567. data/spec/support/aws_utils/provisioner.rb +3 -0
  1568. data/spec/support/aws_utils.rb +6 -2
  1569. data/spec/support/background_thread_registry.rb +7 -14
  1570. data/spec/support/certificates/README.md +3 -2
  1571. data/spec/support/certificates/atlas-ocsp-ca.crt +103 -0
  1572. data/spec/support/certificates/atlas-ocsp.crt +152 -0
  1573. data/spec/support/certificates/retrieve-atlas-cert +40 -0
  1574. data/spec/support/client_registry.rb +17 -6
  1575. data/spec/support/client_registry_macros.rb +17 -5
  1576. data/spec/support/cluster_tools.rb +17 -9
  1577. data/spec/support/common_shortcuts.rb +134 -10
  1578. data/spec/support/constraints.rb +16 -246
  1579. data/spec/support/crypt/corpus/corpus-encrypted.json +9515 -0
  1580. data/spec/support/crypt/corpus/corpus-key-aws.json +32 -32
  1581. data/spec/support/crypt/corpus/corpus-key-azure.json +33 -0
  1582. data/spec/support/crypt/corpus/corpus-key-gcp.json +35 -0
  1583. data/spec/support/crypt/corpus/corpus-key-kmip.json +32 -0
  1584. data/spec/support/crypt/corpus/corpus-key-local.json +30 -30
  1585. data/spec/support/crypt/corpus/corpus-schema.json +4399 -121
  1586. data/spec/support/crypt/corpus/corpus.json +4999 -37
  1587. data/spec/support/crypt/data_keys/key_document_azure.json +33 -0
  1588. data/spec/support/crypt/data_keys/key_document_gcp.json +37 -0
  1589. data/spec/support/crypt/data_keys/key_document_kmip.json +32 -0
  1590. data/spec/support/crypt/encrypted_fields/encryptedFields.json +32 -0
  1591. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +30 -0
  1592. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +21 -0
  1593. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +29 -0
  1594. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +21 -0
  1595. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +30 -0
  1596. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +27 -0
  1597. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +27 -0
  1598. data/spec/support/crypt/keys/key1-document.json +30 -0
  1599. data/spec/support/crypt/schema_maps/schema_map_azure.json +17 -0
  1600. data/spec/support/crypt/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1601. data/spec/support/crypt/schema_maps/schema_map_gcp.json +17 -0
  1602. data/spec/support/crypt/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1603. data/spec/support/crypt/schema_maps/schema_map_kmip.json +17 -0
  1604. data/spec/support/crypt/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1605. data/spec/support/crypt.rb +271 -13
  1606. data/spec/support/dns.rb +3 -0
  1607. data/spec/support/json_ext_formatter.rb +3 -0
  1608. data/spec/support/keyword_struct.rb +3 -0
  1609. data/spec/support/local_resource_registry.rb +3 -0
  1610. data/spec/support/macros.rb +29 -0
  1611. data/spec/support/matchers.rb +33 -1
  1612. data/spec/support/mongos_macros.rb +24 -0
  1613. data/spec/support/monitoring_ext.rb +3 -0
  1614. data/spec/support/ocsp +1 -0
  1615. data/spec/support/primary_socket.rb +3 -0
  1616. data/spec/support/sdam_formatter_integration.rb +3 -0
  1617. data/spec/support/shared/app_metadata.rb +179 -0
  1618. data/spec/support/shared/auth_context.rb +17 -0
  1619. data/spec/support/shared/protocol.rb +3 -0
  1620. data/spec/support/shared/scram_conversation.rb +5 -1
  1621. data/spec/support/shared/server_selector.rb +6 -3
  1622. data/spec/support/shared/session.rb +20 -11
  1623. data/spec/support/spec_config.rb +248 -24
  1624. data/spec/support/spec_setup.rb +51 -38
  1625. data/spec/support/using_hash.rb +40 -0
  1626. data/spec/support/utils.rb +353 -172
  1627. data.tar.gz.sig +0 -0
  1628. metadata +2052 -1217
  1629. metadata.gz.sig +0 -0
  1630. data/lib/mongo/collection/view/builder/find_command.rb +0 -150
  1631. data/lib/mongo/collection/view/builder/flags.rb +0 -62
  1632. data/lib/mongo/collection/view/builder/modifiers.rb +0 -80
  1633. data/lib/mongo/collection/view/builder/op_query.rb +0 -91
  1634. data/lib/mongo/cursor/builder/get_more_command.rb +0 -77
  1635. data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -108
  1636. data/lib/mongo/cursor/builder/op_get_more.rb +0 -61
  1637. data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -103
  1638. data/lib/mongo/cursor/builder.rb +0 -18
  1639. data/lib/mongo/operation/aggregate/command.rb +0 -44
  1640. data/lib/mongo/operation/collections_info/command.rb +0 -40
  1641. data/lib/mongo/operation/command/command.rb +0 -38
  1642. data/lib/mongo/operation/count/command.rb +0 -38
  1643. data/lib/mongo/operation/create/command.rb +0 -38
  1644. data/lib/mongo/operation/create_index/command.rb +0 -42
  1645. data/lib/mongo/operation/create_user/command.rb +0 -43
  1646. data/lib/mongo/operation/delete/command.rb +0 -46
  1647. data/lib/mongo/operation/delete/legacy.rb +0 -54
  1648. data/lib/mongo/operation/distinct/command.rb +0 -38
  1649. data/lib/mongo/operation/drop/command.rb +0 -38
  1650. data/lib/mongo/operation/drop_database/command.rb +0 -38
  1651. data/lib/mongo/operation/drop_index/command.rb +0 -42
  1652. data/lib/mongo/operation/explain/command.rb +0 -39
  1653. data/lib/mongo/operation/explain/legacy.rb +0 -38
  1654. data/lib/mongo/operation/find/command.rb +0 -39
  1655. data/lib/mongo/operation/find/legacy/result.rb +0 -41
  1656. data/lib/mongo/operation/find/legacy.rb +0 -40
  1657. data/lib/mongo/operation/get_more/command.rb +0 -39
  1658. data/lib/mongo/operation/get_more/legacy.rb +0 -36
  1659. data/lib/mongo/operation/indexes/command.rb +0 -39
  1660. data/lib/mongo/operation/indexes/legacy.rb +0 -45
  1661. data/lib/mongo/operation/insert/command.rb +0 -56
  1662. data/lib/mongo/operation/insert/legacy.rb +0 -65
  1663. data/lib/mongo/operation/kill_cursors/command.rb +0 -37
  1664. data/lib/mongo/operation/kill_cursors/legacy.rb +0 -37
  1665. data/lib/mongo/operation/list_collections/command.rb +0 -43
  1666. data/lib/mongo/operation/map_reduce/command.rb +0 -40
  1667. data/lib/mongo/operation/parallel_scan/command.rb +0 -55
  1668. data/lib/mongo/operation/remove_user/command.rb +0 -43
  1669. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +0 -56
  1670. data/lib/mongo/operation/shared/op_msg_or_command.rb +0 -44
  1671. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +0 -47
  1672. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +0 -47
  1673. data/lib/mongo/operation/update/command.rb +0 -47
  1674. data/lib/mongo/operation/update/legacy/result.rb +0 -102
  1675. data/lib/mongo/operation/update/legacy.rb +0 -65
  1676. data/lib/mongo/operation/update_user/command.rb +0 -42
  1677. data/lib/mongo/operation/users_info/command.rb +0 -43
  1678. data/lib/mongo/protocol/delete.rb +0 -169
  1679. data/lib/mongo/protocol/insert.rb +0 -178
  1680. data/lib/mongo/protocol/update.rb +0 -211
  1681. data/lib/mongo/server/context.rb +0 -69
  1682. data/spec/mongo/collection/view/builder/flags_spec.rb +0 -106
  1683. data/spec/mongo/collection/view/builder/modifiers_spec.rb +0 -210
  1684. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -61
  1685. data/spec/mongo/dbref_spec.rb +0 -149
  1686. data/spec/mongo/operation/delete/command_spec.rb +0 -112
  1687. data/spec/mongo/operation/find/legacy_spec.rb +0 -125
  1688. data/spec/mongo/operation/get_more_spec.rb +0 -58
  1689. data/spec/mongo/operation/insert/command_spec.rb +0 -115
  1690. data/spec/mongo/operation/kill_cursors_spec.rb +0 -41
  1691. data/spec/mongo/operation/update/command_spec.rb +0 -119
  1692. data/spec/mongo/protocol/delete_spec.rb +0 -182
  1693. data/spec/mongo/protocol/insert_spec.rb +0 -176
  1694. data/spec/mongo/protocol/update_spec.rb +0 -201
  1695. data/spec/mongo/server/app_metadata_shared.rb +0 -136
  1696. data/spec/spec_tests/change_streams_spec.rb +0 -90
  1697. data/spec/spec_tests/command_monitoring_spec.rb +0 -66
  1698. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +0 -102
  1699. data/spec/spec_tests/data/change_streams/change-streams-resume-errorLabels.yml +0 -1105
  1700. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +0 -1173
  1701. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -537
  1702. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +0 -49
  1703. data/spec/spec_tests/data/command_monitoring/command.yml +0 -61
  1704. data/spec/spec_tests/data/command_monitoring/deleteMany.yml +0 -55
  1705. data/spec/spec_tests/data/command_monitoring/deleteOne.yml +0 -55
  1706. data/spec/spec_tests/data/command_monitoring/find.yml +0 -266
  1707. data/spec/spec_tests/data/command_monitoring/insertMany.yml +0 -75
  1708. data/spec/spec_tests/data/command_monitoring/insertOne.yml +0 -51
  1709. data/spec/spec_tests/data/command_monitoring/unacknowledgedBulkWrite.yml +0 -34
  1710. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -65
  1711. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -90
  1712. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +0 -103
  1713. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +0 -110
  1714. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +0 -103
  1715. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-clientError.yml +0 -63
  1716. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-serverError.yml +0 -92
  1717. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint.yml +0 -103
  1718. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-clientError.yml +0 -90
  1719. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-serverError.yml +0 -147
  1720. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint.yml +0 -164
  1721. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +0 -38
  1722. data/spec/spec_tests/data/crud_v2/deleteMany-hint-clientError.yml +0 -43
  1723. data/spec/spec_tests/data/crud_v2/deleteMany-hint-serverError.yml +0 -62
  1724. data/spec/spec_tests/data/crud_v2/deleteMany-hint.yml +0 -58
  1725. data/spec/spec_tests/data/crud_v2/deleteOne-hint-clientError.yml +0 -41
  1726. data/spec/spec_tests/data/crud_v2/deleteOne-hint-serverError.yml +0 -60
  1727. data/spec/spec_tests/data/crud_v2/deleteOne-hint.yml +0 -57
  1728. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-clientError.yml +0 -28
  1729. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-serverError.yml +0 -44
  1730. data/spec/spec_tests/data/crud_v2/find-allowdiskuse.yml +0 -50
  1731. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-clientError.yml +0 -45
  1732. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-serverError.yml +0 -60
  1733. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint.yml +0 -56
  1734. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-clientError.yml +0 -40
  1735. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-serverError.yml +0 -59
  1736. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint.yml +0 -55
  1737. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-clientError.yml +0 -40
  1738. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-serverError.yml +0 -58
  1739. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint.yml +0 -55
  1740. data/spec/spec_tests/data/crud_v2/replaceOne-hint.yml +0 -61
  1741. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-delete-hint-clientError.yml +0 -60
  1742. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-update-hint-clientError.yml +0 -88
  1743. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteMany-hint-clientError.yml +0 -40
  1744. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteOne-hint-clientError.yml +0 -38
  1745. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndDelete-hint-clientError.yml +0 -42
  1746. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndReplace-hint-clientError.yml +0 -40
  1747. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndUpdate-hint-clientError.yml +0 -40
  1748. data/spec/spec_tests/data/crud_v2/unacknowledged-replaceOne-hint-clientError.yml +0 -40
  1749. data/spec/spec_tests/data/crud_v2/unacknowledged-updateMany-hint-clientError.yml +0 -43
  1750. data/spec/spec_tests/data/crud_v2/unacknowledged-updateOne-hint-clientError.yml +0 -40
  1751. data/spec/spec_tests/data/crud_v2/updateMany-hint-clientError.yml +0 -45
  1752. data/spec/spec_tests/data/crud_v2/updateMany-hint-serverError.yml +0 -66
  1753. data/spec/spec_tests/data/crud_v2/updateMany-hint.yml +0 -65
  1754. data/spec/spec_tests/data/crud_v2/updateOne-hint-clientError.yml +0 -43
  1755. data/spec/spec_tests/data/crud_v2/updateOne-hint-serverError.yml +0 -62
  1756. data/spec/spec_tests/data/crud_v2/updateOne-hint.yml +0 -61
  1757. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +0 -157
  1758. data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +0 -157
  1759. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +0 -149
  1760. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +0 -61
  1761. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +0 -149
  1762. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +0 -65
  1763. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +0 -153
  1764. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +0 -61
  1765. data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +0 -150
  1766. data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +0 -150
  1767. data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +0 -156
  1768. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +0 -148
  1769. data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +0 -160
  1770. data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +0 -154
  1771. data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +0 -173
  1772. data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +0 -174
  1773. data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +0 -143
  1774. data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +0 -144
  1775. data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +0 -143
  1776. data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +0 -143
  1777. data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +0 -144
  1778. data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +0 -144
  1779. data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +0 -144
  1780. data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +0 -60
  1781. data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +0 -145
  1782. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +0 -60
  1783. data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +0 -130
  1784. data/spec/spec_tests/data/retryable_writes/bulkWrite.yml +0 -396
  1785. data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +0 -73
  1786. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +0 -74
  1787. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +0 -80
  1788. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +0 -79
  1789. data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +0 -84
  1790. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +0 -526
  1791. data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +0 -82
  1792. data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +0 -82
  1793. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMaster.yml +0 -60
  1794. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterNoSlaveOk.yml +0 -60
  1795. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterOrSecondary.yml +0 -60
  1796. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMaster.yml +0 -51
  1797. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterNoSlaveOk.yml +0 -51
  1798. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterOrSecondary.yml +0 -51
  1799. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMaster.yml +0 -60
  1800. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterNoSlaveOk.yml +0 -60
  1801. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterOrSecondary.yml +0 -60
  1802. data/spec/spec_tests/data/sdam/errors/post-42-NotMaster.yml +0 -46
  1803. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterNoSlaveOk.yml +0 -46
  1804. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterOrSecondary.yml +0 -46
  1805. data/spec/spec_tests/data/sdam/errors/pre-42-NotMaster.yml +0 -46
  1806. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterNoSlaveOk.yml +0 -46
  1807. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterOrSecondary.yml +0 -46
  1808. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMaster.yml +0 -89
  1809. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterNoSlaveOk.yml +0 -89
  1810. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterOrSecondary.yml +0 -89
  1811. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMaster.yml +0 -89
  1812. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterNoSlaveOk.yml +0 -89
  1813. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterOrSecondary.yml +0 -89
  1814. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMaster.yml +0 -89
  1815. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterNoSlaveOk.yml +0 -89
  1816. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterOrSecondary.yml +0 -89
  1817. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMaster.yml +0 -64
  1818. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterNoSlaveOk.yml +0 -64
  1819. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterOrSecondary.yml +0 -64
  1820. data/spec/spec_tests/data/sdam/single/direct_connection_slave.yml +0 -34
  1821. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +0 -96
  1822. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +0 -88
  1823. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +0 -83
  1824. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +0 -116
  1825. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +0 -86
  1826. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +0 -115
  1827. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +0 -168
  1828. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +0 -162
  1829. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +0 -229
  1830. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +0 -87
  1831. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -68
  1832. data/spec/spec_tests/sdam_integration_spec.rb +0 -13
  1833. data/spec/support/child_process_helper.rb +0 -78
  1834. data/spec/support/cluster_config.rb +0 -207
  1835. data/spec/support/crypt/corpus/corpus_encrypted.json +0 -4152
  1836. data/spec/support/event_subscriber.rb +0 -212
  1837. data/spec/support/lite_constraints.rb +0 -141
  1838. data/spec/support/spec_organizer.rb +0 -129
  1839. /data/spec/spec_tests/data/retryable_reads/{aggregate-merge.yml → legacy/aggregate-merge.yml} +0 -0
  1840. /data/spec/spec_tests/data/retryable_reads/{aggregate.yml → legacy/aggregate.yml} +0 -0
  1841. /data/spec/spec_tests/data/retryable_reads/{count.yml → legacy/count.yml} +0 -0
  1842. /data/spec/spec_tests/data/retryable_reads/{countDocuments.yml → legacy/countDocuments.yml} +0 -0
  1843. /data/spec/spec_tests/data/retryable_reads/{distinct.yml → legacy/distinct.yml} +0 -0
  1844. /data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount.yml → legacy/estimatedDocumentCount.yml} +0 -0
  1845. /data/spec/spec_tests/data/retryable_reads/{find.yml → legacy/find.yml} +0 -0
  1846. /data/spec/spec_tests/data/retryable_reads/{findOne.yml → legacy/findOne.yml} +0 -0
  1847. /data/spec/spec_tests/data/retryable_reads/{gridfs-download.yml → legacy/gridfs-download.yml} +0 -0
  1848. /data/spec/spec_tests/data/retryable_reads/{gridfs-downloadByName.yml → legacy/gridfs-downloadByName.yml} +0 -0
  1849. /data/spec/spec_tests/data/retryable_reads/{listCollectionNames.yml → legacy/listCollectionNames.yml} +0 -0
  1850. /data/spec/spec_tests/data/retryable_reads/{listCollectionObjects.yml → legacy/listCollectionObjects.yml} +0 -0
  1851. /data/spec/spec_tests/data/retryable_reads/{listCollections.yml → legacy/listCollections.yml} +0 -0
  1852. /data/spec/spec_tests/data/retryable_reads/{listDatabaseNames.yml → legacy/listDatabaseNames.yml} +0 -0
  1853. /data/spec/spec_tests/data/retryable_reads/{listDatabaseObjects.yml → legacy/listDatabaseObjects.yml} +0 -0
  1854. /data/spec/spec_tests/data/retryable_reads/{listDatabases.yml → legacy/listDatabases.yml} +0 -0
  1855. /data/spec/spec_tests/data/retryable_reads/{listIndexes.yml → legacy/listIndexes.yml} +0 -0
  1856. /data/spec/spec_tests/data/retryable_writes/{bulkWrite-errorLabels.yml → legacy/bulkWrite-errorLabels.yml} +0 -0
  1857. /data/spec/spec_tests/data/retryable_writes/{deleteMany.yml → legacy/deleteMany.yml} +0 -0
  1858. /data/spec/spec_tests/data/retryable_writes/{deleteOne-errorLabels.yml → legacy/deleteOne-errorLabels.yml} +0 -0
  1859. /data/spec/spec_tests/data/retryable_writes/{deleteOne.yml → legacy/deleteOne.yml} +0 -0
  1860. /data/spec/spec_tests/data/retryable_writes/{findOneAndDelete-errorLabels.yml → legacy/findOneAndDelete-errorLabels.yml} +0 -0
  1861. /data/spec/spec_tests/data/retryable_writes/{findOneAndDelete.yml → legacy/findOneAndDelete.yml} +0 -0
  1862. /data/spec/spec_tests/data/retryable_writes/{findOneAndReplace-errorLabels.yml → legacy/findOneAndReplace-errorLabels.yml} +0 -0
  1863. /data/spec/spec_tests/data/retryable_writes/{findOneAndReplace.yml → legacy/findOneAndReplace.yml} +0 -0
  1864. /data/spec/spec_tests/data/retryable_writes/{findOneAndUpdate-errorLabels.yml → legacy/findOneAndUpdate-errorLabels.yml} +0 -0
  1865. /data/spec/spec_tests/data/retryable_writes/{findOneAndUpdate.yml → legacy/findOneAndUpdate.yml} +0 -0
  1866. /data/spec/spec_tests/data/retryable_writes/{insertMany-errorLabels.yml → legacy/insertMany-errorLabels.yml} +0 -0
  1867. /data/spec/spec_tests/data/retryable_writes/{insertMany.yml → legacy/insertMany.yml} +0 -0
  1868. /data/spec/spec_tests/data/retryable_writes/{insertOne-errorLabels.yml → legacy/insertOne-errorLabels.yml} +0 -0
  1869. /data/spec/spec_tests/data/retryable_writes/{insertOne.yml → legacy/insertOne.yml} +0 -0
  1870. /data/spec/spec_tests/data/retryable_writes/{replaceOne-errorLabels.yml → legacy/replaceOne-errorLabels.yml} +0 -0
  1871. /data/spec/spec_tests/data/retryable_writes/{replaceOne.yml → legacy/replaceOne.yml} +0 -0
  1872. /data/spec/spec_tests/data/retryable_writes/{updateMany.yml → legacy/updateMany.yml} +0 -0
  1873. /data/spec/spec_tests/data/retryable_writes/{updateOne-errorLabels.yml → legacy/updateOne-errorLabels.yml} +0 -0
  1874. /data/spec/spec_tests/data/retryable_writes/{updateOne.yml → legacy/updateOne.yml} +0 -0
  1875. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
  1876. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
  1877. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
  1878. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
  1879. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
  1880. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
  1881. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
  1882. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
  1883. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
  1884. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
  1885. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
  1886. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
  1887. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
  1888. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
  1889. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
  1890. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
  1891. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
  1892. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
  1893. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
  1894. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
  1895. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
  1896. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
  1897. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
  1898. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
  1899. /data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
@@ -0,0 +1,4471 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:todo all
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Mongo::Collection do
7
+
8
+ let(:subscriber) { Mrss::EventSubscriber.new }
9
+
10
+ let(:client) do
11
+ authorized_client.tap do |client|
12
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
13
+ end
14
+ end
15
+
16
+ let(:authorized_collection) { client['collection_spec'] }
17
+
18
+ before do
19
+ authorized_client['collection_spec'].drop
20
+ end
21
+
22
+ let(:collection_invalid_write_concern) do
23
+ authorized_collection.client.with(write: INVALID_WRITE_CONCERN)[authorized_collection.name]
24
+ end
25
+
26
+ let(:collection_with_validator) do
27
+ authorized_client[:validating]
28
+ end
29
+
30
+ describe '#find' do
31
+
32
+ describe 'updating cluster time' do
33
+
34
+ let(:operation) do
35
+ client[TEST_COLL].find.first
36
+ end
37
+
38
+ let(:operation_with_session) do
39
+ client[TEST_COLL].find({}, session: session).first
40
+ end
41
+
42
+ let(:second_operation) do
43
+ client[TEST_COLL].find({}, session: session).first
44
+ end
45
+
46
+ it_behaves_like 'an operation updating cluster time'
47
+ end
48
+
49
+ context 'when provided a filter' do
50
+
51
+ let(:view) do
52
+ authorized_collection.find(name: 1)
53
+ end
54
+
55
+ it 'returns a authorized_collection view for the filter' do
56
+ expect(view.filter).to eq('name' => 1)
57
+ end
58
+ end
59
+
60
+ context 'when provided no filter' do
61
+
62
+ let(:view) do
63
+ authorized_collection.find
64
+ end
65
+
66
+ it 'returns a authorized_collection view with an empty filter' do
67
+ expect(view.filter).to be_empty
68
+ end
69
+ end
70
+
71
+ context 'when providing a bad filter' do
72
+
73
+ let(:view) do
74
+ authorized_collection.find('$or' => [])
75
+ end
76
+
77
+ it 'raises an exception when iterating' do
78
+ expect {
79
+ view.to_a
80
+ }.to raise_exception(Mongo::Error::OperationFailure)
81
+ end
82
+ end
83
+
84
+ context 'when iterating the authorized_collection view' do
85
+
86
+ before do
87
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test2' }])
88
+ end
89
+
90
+ let(:view) do
91
+ authorized_collection.find
92
+ end
93
+
94
+ it 'iterates over the documents' do
95
+ view.each do |document|
96
+ expect(document).to_not be_nil
97
+ end
98
+ end
99
+ end
100
+
101
+ context 'when the user is not authorized' do
102
+ require_auth
103
+
104
+ let(:view) do
105
+ unauthorized_collection.find
106
+ end
107
+
108
+ it 'iterates over the documents' do
109
+ expect {
110
+ view.each{ |document| document }
111
+ }.to raise_error(Mongo::Error::OperationFailure)
112
+ end
113
+ end
114
+
115
+ context 'when documents contain potential error message fields' do
116
+
117
+ [ 'errmsg', 'error', Mongo::Operation::Result::OK ].each do |field|
118
+
119
+ context "when the document contains a '#{field}' field" do
120
+
121
+ let(:value) do
122
+ 'testing'
123
+ end
124
+
125
+ let(:view) do
126
+ authorized_collection.find
127
+ end
128
+
129
+ before do
130
+ authorized_collection.insert_one({ field => value })
131
+ end
132
+
133
+ it 'iterates over the documents' do
134
+ view.each do |document|
135
+ expect(document[field]).to eq(value)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ context 'when provided options' do
143
+
144
+ context 'when a session is provided' do
145
+ require_wired_tiger
146
+
147
+ let(:operation) do
148
+ authorized_collection.find({}, session: session).to_a
149
+ end
150
+
151
+ let(:session) do
152
+ authorized_client.start_session
153
+ end
154
+
155
+ let(:failed_operation) do
156
+ client[authorized_collection.name].find({ '$._id' => 1 }, session: session).to_a
157
+ end
158
+
159
+ let(:client) do
160
+ authorized_client
161
+ end
162
+
163
+ it_behaves_like 'an operation using a session'
164
+ it_behaves_like 'a failed operation using a session'
165
+ end
166
+
167
+ context 'session id' do
168
+ min_server_fcv '3.6'
169
+ require_topology :replica_set, :sharded
170
+ require_wired_tiger
171
+
172
+ let(:options) do
173
+ { session: session }
174
+ end
175
+
176
+ let(:session) do
177
+ client.start_session
178
+ end
179
+
180
+ let(:view) do
181
+ Mongo::Collection::View.new(client[TEST_COLL], selector, view_options)
182
+ end
183
+
184
+ let(:command) do
185
+ client[TEST_COLL].find({}, session: session).explain
186
+ subscriber.started_events.find { |c| c.command_name == 'explain' }.command
187
+ end
188
+
189
+ it 'sends the session id' do
190
+ expect(command['lsid']).to eq(session.session_id)
191
+ end
192
+ end
193
+
194
+ context 'when a session supporting causal consistency is used' do
195
+ require_wired_tiger
196
+
197
+ let(:operation) do
198
+ collection.find({}, session: session).to_a
199
+ end
200
+
201
+ let(:command) do
202
+ operation
203
+ subscriber.started_events.find { |cmd| cmd.command_name == 'find' }.command
204
+ end
205
+
206
+ it_behaves_like 'an operation supporting causally consistent reads'
207
+ end
208
+
209
+ let(:view) do
210
+ authorized_collection.find({}, options)
211
+ end
212
+
213
+ context 'when provided :allow_partial_results' do
214
+
215
+ let(:options) do
216
+ { allow_partial_results: true }
217
+ end
218
+
219
+ it 'returns a view with :allow_partial_results set' do
220
+ expect(view.options[:allow_partial_results]).to be(options[:allow_partial_results])
221
+ end
222
+ end
223
+
224
+ context 'when provided :batch_size' do
225
+
226
+ let(:options) do
227
+ { batch_size: 100 }
228
+ end
229
+
230
+ it 'returns a view with :batch_size set' do
231
+ expect(view.options[:batch_size]).to eq(options[:batch_size])
232
+ end
233
+ end
234
+
235
+ context 'when provided :comment' do
236
+
237
+ let(:options) do
238
+ { comment: 'slow query' }
239
+ end
240
+
241
+ it 'returns a view with :comment set' do
242
+ expect(view.modifiers[:$comment]).to eq(options[:comment])
243
+ end
244
+ end
245
+
246
+ context 'when provided :cursor_type' do
247
+
248
+ let(:options) do
249
+ { cursor_type: :tailable }
250
+ end
251
+
252
+ it 'returns a view with :cursor_type set' do
253
+ expect(view.options[:cursor_type]).to eq(options[:cursor_type])
254
+ end
255
+ end
256
+
257
+ context 'when provided :max_time_ms' do
258
+
259
+ let(:options) do
260
+ { max_time_ms: 500 }
261
+ end
262
+
263
+ it 'returns a view with :max_time_ms set' do
264
+ expect(view.modifiers[:$maxTimeMS]).to eq(options[:max_time_ms])
265
+ end
266
+ end
267
+
268
+ context 'when provided :modifiers' do
269
+
270
+ let(:options) do
271
+ { modifiers: { '$orderby' => Mongo::Index::ASCENDING } }
272
+ end
273
+
274
+ it 'returns a view with modifiers set' do
275
+ expect(view.modifiers).to eq(options[:modifiers])
276
+ end
277
+
278
+ it 'dups the modifiers hash' do
279
+ expect(view.modifiers).not_to be(options[:modifiers])
280
+ end
281
+ end
282
+
283
+ context 'when provided :no_cursor_timeout' do
284
+
285
+ let(:options) do
286
+ { no_cursor_timeout: true }
287
+ end
288
+
289
+ it 'returns a view with :no_cursor_timeout set' do
290
+ expect(view.options[:no_cursor_timeout]).to eq(options[:no_cursor_timeout])
291
+ end
292
+ end
293
+
294
+ context 'when provided :oplog_replay' do
295
+
296
+ let(:options) do
297
+ { oplog_replay: false }
298
+ end
299
+
300
+ it 'returns a view with :oplog_replay set' do
301
+ expect(view.options[:oplog_replay]).to eq(options[:oplog_replay])
302
+ end
303
+ end
304
+
305
+ context 'when provided :projection' do
306
+
307
+ let(:options) do
308
+ { projection: { 'x' => 1 } }
309
+ end
310
+
311
+ it 'returns a view with :projection set' do
312
+ expect(view.options[:projection]).to eq(options[:projection])
313
+ end
314
+ end
315
+
316
+ context 'when provided :skip' do
317
+
318
+ let(:options) do
319
+ { skip: 5 }
320
+ end
321
+
322
+ it 'returns a view with :skip set' do
323
+ expect(view.options[:skip]).to eq(options[:skip])
324
+ end
325
+ end
326
+
327
+ context 'when provided :sort' do
328
+
329
+ let(:options) do
330
+ { sort: { 'x' => Mongo::Index::ASCENDING } }
331
+ end
332
+
333
+ it 'returns a view with :sort set' do
334
+ expect(view.modifiers[:$orderby]).to eq(options[:sort])
335
+ end
336
+ end
337
+
338
+ context 'when provided :collation' do
339
+
340
+ let(:options) do
341
+ { collation: { 'locale' => 'en_US' } }
342
+ end
343
+
344
+ it 'returns a view with :collation set' do
345
+ expect(view.options[:collation]).to eq(options[:collation])
346
+ end
347
+ end
348
+ end
349
+ end
350
+
351
+ describe '#insert_many' do
352
+
353
+ let(:result) do
354
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
355
+ end
356
+
357
+ it 'inserts the documents into the collection' do
358
+ expect(result.inserted_count).to eq(2)
359
+ end
360
+
361
+ it 'contains the ids in the result' do
362
+ expect(result.inserted_ids.size).to eq(2)
363
+ end
364
+
365
+ context 'when an enumerable is used instead of an array' do
366
+
367
+ context 'when the enumerable is not empty' do
368
+
369
+ let(:source_data) do
370
+ [{ name: 'test1' }, { name: 'test2' }]
371
+ end
372
+
373
+ let(:result) do
374
+ authorized_collection.insert_many(source_data.lazy)
375
+ end
376
+
377
+ it 'should accepts them without raising an error' do
378
+ expect { result }.to_not raise_error
379
+ expect(result.inserted_count).to eq(source_data.size)
380
+ end
381
+ end
382
+
383
+ context 'when the enumerable is empty' do
384
+
385
+ let(:source_data) do
386
+ []
387
+ end
388
+
389
+ let(:result) do
390
+ authorized_collection.insert_many(source_data.lazy)
391
+ end
392
+
393
+ it 'should raise ArgumentError' do
394
+ expect do
395
+ result
396
+ end.to raise_error(ArgumentError, /Bulk write requests cannot be empty/)
397
+ end
398
+ end
399
+ end
400
+
401
+ context 'when a session is provided' do
402
+
403
+ let(:session) do
404
+ authorized_client.start_session
405
+ end
406
+
407
+ let(:operation) do
408
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session)
409
+ end
410
+
411
+ let(:failed_operation) do
412
+ authorized_collection.insert_many([{ _id: 'test1' }, { _id: 'test1' }], session: session)
413
+ end
414
+
415
+ let(:client) do
416
+ authorized_client
417
+ end
418
+
419
+ it_behaves_like 'an operation using a session'
420
+ it_behaves_like 'a failed operation using a session'
421
+ end
422
+
423
+ context 'when unacknowledged writes is used with an explicit session' do
424
+
425
+ let(:collection_with_unacknowledged_write_concern) do
426
+ authorized_collection.with(write: { w: 0 })
427
+ end
428
+
429
+ let(:operation) do
430
+ collection_with_unacknowledged_write_concern.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session)
431
+ end
432
+
433
+ it_behaves_like 'an explicit session with an unacknowledged write'
434
+ end
435
+
436
+ context 'when unacknowledged writes is used with an implicit session' do
437
+
438
+ let(:collection_with_unacknowledged_write_concern) do
439
+ client.with(write: { w: 0 })[TEST_COLL]
440
+ end
441
+
442
+ let(:operation) do
443
+ collection_with_unacknowledged_write_concern.insert_many([{ name: 'test1' }, { name: 'test2' }])
444
+ end
445
+
446
+ it_behaves_like 'an implicit session with an unacknowledged write'
447
+ end
448
+
449
+ context 'when a document contains dotted keys' do
450
+
451
+ let(:docs) do
452
+ [ { 'first.name' => 'test1' }, { name: 'test2' } ]
453
+ end
454
+
455
+ let(:view) { authorized_collection.find({}, { sort: { name: 1 } }) }
456
+
457
+ it 'inserts the documents correctly' do
458
+ expect {
459
+ authorized_collection.insert_many(docs)
460
+ }.to_not raise_error
461
+
462
+ expect(view.count).to eq(2)
463
+ expect(view.first['first.name']).to eq('test1')
464
+ expect(view.to_a[1]['name']).to eq('test2')
465
+ end
466
+ end
467
+
468
+ context 'when the client has a custom id generator' do
469
+
470
+ let(:generator) do
471
+ Class.new do
472
+ def generate
473
+ 1
474
+ end
475
+ end.new
476
+ end
477
+
478
+ let(:custom_client) do
479
+ authorized_client.with(id_generator: generator)
480
+ end
481
+
482
+ let(:custom_collection) do
483
+ custom_client['custom_id_generator_test_collection']
484
+ end
485
+
486
+ before do
487
+ custom_collection.delete_many
488
+ custom_collection.insert_many([{ name: 'testing' }])
489
+ expect(custom_collection.count).to eq(1)
490
+ end
491
+
492
+ it 'inserts with the custom id' do
493
+ expect(custom_collection.count).to eq(1)
494
+ expect(custom_collection.find.first[:_id]).to eq(1)
495
+ end
496
+ end
497
+
498
+ context 'when the inserts fail' do
499
+
500
+ let(:result) do
501
+ authorized_collection.insert_many([{ _id: 1 }, { _id: 1 }])
502
+ end
503
+
504
+ it 'raises an BulkWriteError' do
505
+ expect {
506
+ result
507
+ }.to raise_exception(Mongo::Error::BulkWriteError)
508
+ end
509
+ end
510
+
511
+ context "when the documents exceed the max bson size" do
512
+
513
+ let(:documents) do
514
+ [{ '_id' => 1, 'name' => '1'*17000000 }]
515
+ end
516
+
517
+ it 'raises a MaxBSONSize error' do
518
+ expect {
519
+ authorized_collection.insert_many(documents)
520
+ }.to raise_error(Mongo::Error::MaxBSONSize)
521
+ end
522
+ end
523
+
524
+ context 'when the documents are sent with OP_MSG' do
525
+ min_server_fcv '3.6'
526
+
527
+ let(:documents) do
528
+ [{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
529
+ end
530
+
531
+ before do
532
+ authorized_collection.insert_many(documents)
533
+ end
534
+
535
+ let(:insert_events) do
536
+ subscriber.started_events.select { |e| e.command_name == 'insert' }
537
+ end
538
+
539
+ it 'sends the documents in one OP_MSG' do
540
+ expect(insert_events.size).to eq(1)
541
+ expect(insert_events[0].command['documents']).to eq(documents)
542
+ end
543
+ end
544
+
545
+ context 'when collection has a validator' do
546
+ min_server_fcv '3.2'
547
+
548
+ around(:each) do |spec|
549
+ authorized_client[:validating].drop
550
+ authorized_client[:validating,
551
+ :validator => { :a => { '$exists' => true } }].tap do |c|
552
+ c.create
553
+ end
554
+ spec.run
555
+ collection_with_validator.drop
556
+ end
557
+
558
+ context 'when the document is valid' do
559
+
560
+ let(:result) do
561
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
562
+ end
563
+
564
+ it 'inserts successfully' do
565
+ expect(result.inserted_count).to eq(2)
566
+ end
567
+ end
568
+
569
+ context 'when the document is invalid' do
570
+
571
+ context 'when bypass_document_validation is not set' do
572
+
573
+ let(:result2) do
574
+ collection_with_validator.insert_many([{ x: 1 }, { x: 2 }])
575
+ end
576
+
577
+ it 'raises a BulkWriteError' do
578
+ expect {
579
+ result2
580
+ }.to raise_exception(Mongo::Error::BulkWriteError)
581
+ end
582
+ end
583
+
584
+ context 'when bypass_document_validation is true' do
585
+
586
+ let(:result3) do
587
+ collection_with_validator.insert_many(
588
+ [{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
589
+ end
590
+
591
+ it 'inserts successfully' do
592
+ expect(result3.inserted_count).to eq(2)
593
+ end
594
+ end
595
+ end
596
+ end
597
+
598
+ context 'when unacknowledged writes is used' do
599
+
600
+ let(:collection_with_unacknowledged_write_concern) do
601
+ authorized_collection.with(write: { w: 0 })
602
+ end
603
+
604
+ let(:result) do
605
+ collection_with_unacknowledged_write_concern.insert_many([{ _id: 1 }, { _id: 1 }])
606
+ end
607
+
608
+ it 'does not raise an exception' do
609
+ expect(result.inserted_count).to be(0)
610
+ end
611
+ end
612
+
613
+ context 'when various options passed in' do
614
+ # w: 2 requires a replica set
615
+ require_topology :replica_set
616
+
617
+ # https://jira.mongodb.org/browse/RUBY-2306
618
+ min_server_fcv '3.6'
619
+
620
+ let(:session) do
621
+ authorized_client.start_session
622
+ end
623
+
624
+ let(:events) do
625
+ subscriber.command_started_events('insert')
626
+ end
627
+
628
+ let(:collection) do
629
+ authorized_collection.with(write_concern: {w: 2})
630
+ end
631
+
632
+ let!(:command) do
633
+ Utils.get_command_event(authorized_client, 'insert') do |client|
634
+ collection.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session,
635
+ write_concern: {w: 1}, bypass_document_validation: true)
636
+ end.command
637
+ end
638
+
639
+ it 'inserts many successfully with correct options sent to server' do
640
+ expect(events.length).to eq(1)
641
+ expect(command[:writeConcern]).to_not be_nil
642
+ expect(command[:writeConcern][:w]).to eq(1)
643
+ expect(command[:bypassDocumentValidation]).to be(true)
644
+ end
645
+ end
646
+ end
647
+
648
+ describe '#insert_one' do
649
+
650
+ describe 'updating cluster time' do
651
+
652
+ let(:operation) do
653
+ client[TEST_COLL].insert_one({ name: 'testing' })
654
+ end
655
+
656
+ let(:operation_with_session) do
657
+ client[TEST_COLL].insert_one({ name: 'testing' }, session: session)
658
+ end
659
+
660
+ let(:second_operation) do
661
+ client[TEST_COLL].insert_one({ name: 'testing' }, session: session)
662
+ end
663
+
664
+ it_behaves_like 'an operation updating cluster time'
665
+ end
666
+
667
+ let(:result) do
668
+ authorized_collection.insert_one({ name: 'testing' })
669
+ end
670
+
671
+ it 'inserts the document into the collection'do
672
+ expect(result.written_count).to eq(1)
673
+ end
674
+
675
+ it 'contains the id in the result' do
676
+ expect(result.inserted_id).to_not be_nil
677
+ end
678
+
679
+ context 'when a session is provided' do
680
+
681
+ let(:session) do
682
+ authorized_client.start_session
683
+ end
684
+
685
+ let(:operation) do
686
+ authorized_collection.insert_one({ name: 'testing' }, session: session)
687
+ end
688
+
689
+ let(:failed_operation) do
690
+ authorized_collection.insert_one({ _id: 'testing' })
691
+ authorized_collection.insert_one({ _id: 'testing' }, session: session)
692
+ end
693
+
694
+ let(:client) do
695
+ authorized_client
696
+ end
697
+
698
+ it_behaves_like 'an operation using a session'
699
+ it_behaves_like 'a failed operation using a session'
700
+ end
701
+
702
+ context 'when unacknowledged writes is used with an explicit session' do
703
+
704
+ let(:collection_with_unacknowledged_write_concern) do
705
+ authorized_collection.with(write: { w: 0 })
706
+ end
707
+
708
+ let(:operation) do
709
+ collection_with_unacknowledged_write_concern.insert_one({ name: 'testing' }, session: session)
710
+ end
711
+
712
+ it_behaves_like 'an explicit session with an unacknowledged write'
713
+ end
714
+
715
+ context 'when unacknowledged writes is used with an implicit session' do
716
+
717
+ let(:collection_with_unacknowledged_write_concern) do
718
+ client.with(write: { w: 0 })[TEST_COLL]
719
+ end
720
+
721
+ let(:operation) do
722
+ collection_with_unacknowledged_write_concern.insert_one({ name: 'testing' })
723
+ end
724
+
725
+ it_behaves_like 'an implicit session with an unacknowledged write'
726
+ end
727
+
728
+ context 'when various options passed in' do
729
+ # https://jira.mongodb.org/browse/RUBY-2306
730
+ min_server_fcv '3.6'
731
+
732
+ let(:session) do
733
+ authorized_client.start_session
734
+ end
735
+
736
+ let(:events) do
737
+ subscriber.command_started_events('insert')
738
+ end
739
+
740
+ let(:collection) do
741
+ authorized_collection.with(write_concern: {w: 3})
742
+ end
743
+
744
+ let!(:command) do
745
+ Utils.get_command_event(authorized_client, 'insert') do |client|
746
+ collection.insert_one({name: 'test1'}, session: session, write_concern: {w: 1},
747
+ bypass_document_validation: true)
748
+ end.command
749
+ end
750
+
751
+ it 'inserts one successfully with correct options sent to server' do
752
+ expect(events.length).to eq(1)
753
+ expect(command[:writeConcern]).to_not be_nil
754
+ expect(command[:writeConcern][:w]).to eq(1)
755
+ expect(command[:bypassDocumentValidation]).to be(true)
756
+ end
757
+ end
758
+
759
+ context 'when the document contains dotted keys' do
760
+
761
+ let(:doc) do
762
+ { 'testing.test' => 'value' }
763
+ end
764
+
765
+ it 'inserts the document correctly' do
766
+ expect {
767
+ authorized_collection.insert_one(doc)
768
+ }.to_not raise_error
769
+
770
+ expect(authorized_collection.count).to eq(1)
771
+ expect(authorized_collection.find.first['testing.test']).to eq('value')
772
+ end
773
+ end
774
+
775
+ context 'when the document is nil' do
776
+ let(:result) do
777
+ authorized_collection.insert_one(nil)
778
+ end
779
+
780
+ it 'raises an ArgumentError' do
781
+ expect {
782
+ result
783
+ }.to raise_error(ArgumentError, "Document to be inserted cannot be nil")
784
+ end
785
+ end
786
+
787
+ context 'when the insert fails' do
788
+
789
+ let(:result) do
790
+ authorized_collection.insert_one(_id: 1)
791
+ authorized_collection.insert_one(_id: 1)
792
+ end
793
+
794
+ it 'raises an OperationFailure' do
795
+ expect {
796
+ result
797
+ }.to raise_exception(Mongo::Error::OperationFailure)
798
+ end
799
+ end
800
+
801
+ context 'when the client has a custom id generator' do
802
+
803
+ let(:generator) do
804
+ Class.new do
805
+ def generate
806
+ 1
807
+ end
808
+ end.new
809
+ end
810
+
811
+ let(:custom_client) do
812
+ authorized_client.with(id_generator: generator)
813
+ end
814
+
815
+ let(:custom_collection) do
816
+ custom_client[TEST_COLL]
817
+ end
818
+
819
+ before do
820
+ custom_collection.delete_many
821
+ custom_collection.insert_one({ name: 'testing' })
822
+ end
823
+
824
+ it 'inserts with the custom id' do
825
+ expect(custom_collection.find.first[:_id]).to eq(1)
826
+ end
827
+ end
828
+
829
+ context 'when collection has a validator' do
830
+ min_server_fcv '3.2'
831
+
832
+ around(:each) do |spec|
833
+ authorized_client[:validating,
834
+ :validator => { :a => { '$exists' => true } }].tap do |c|
835
+ c.create
836
+ end
837
+ spec.run
838
+ collection_with_validator.drop
839
+ end
840
+
841
+ context 'when the document is valid' do
842
+
843
+ let(:result) do
844
+ collection_with_validator.insert_one({ a: 1 })
845
+ end
846
+
847
+ it 'inserts successfully' do
848
+ expect(result.written_count).to eq(1)
849
+ end
850
+ end
851
+
852
+ context 'when the document is invalid' do
853
+
854
+ context 'when bypass_document_validation is not set' do
855
+
856
+ let(:result2) do
857
+ collection_with_validator.insert_one({ x: 1 })
858
+ end
859
+
860
+ it 'raises a OperationFailure' do
861
+ expect {
862
+ result2
863
+ }.to raise_exception(Mongo::Error::OperationFailure)
864
+ end
865
+ end
866
+
867
+ context 'when bypass_document_validation is true' do
868
+
869
+ let(:result3) do
870
+ collection_with_validator.insert_one(
871
+ { x: 1 }, :bypass_document_validation => true)
872
+ end
873
+
874
+ it 'inserts successfully' do
875
+ expect(result3.written_count).to eq(1)
876
+ end
877
+ end
878
+ end
879
+ end
880
+ end
881
+
882
+ describe '#bulk_write' do
883
+
884
+ context 'when various options passed in' do
885
+ min_server_fcv '3.2'
886
+ require_topology :replica_set
887
+
888
+ # https://jira.mongodb.org/browse/RUBY-2306
889
+ min_server_fcv '3.6'
890
+
891
+ let(:requests) do
892
+ [
893
+ { insert_one: { name: "anne" }},
894
+ { insert_one: { name: "bob" }},
895
+ { insert_one: { name: "charlie" }}
896
+ ]
897
+ end
898
+
899
+ let(:session) do
900
+ authorized_client.start_session
901
+ end
902
+
903
+ let!(:command) do
904
+ Utils.get_command_event(authorized_client, 'insert') do |client|
905
+ collection.bulk_write(requests, session: session, write_concern: {w: 1},
906
+ bypass_document_validation: true)
907
+ end.command
908
+ end
909
+
910
+ let(:events) do
911
+ subscriber.command_started_events('insert')
912
+ end
913
+
914
+ let(:collection) do
915
+ authorized_collection.with(write_concern: {w: 2})
916
+ end
917
+
918
+ it 'inserts successfully with correct options sent to server' do
919
+ expect(collection.count).to eq(3)
920
+ expect(events.length).to eq(1)
921
+ expect(command[:writeConcern]).to_not be_nil
922
+ expect(command[:writeConcern][:w]).to eq(1)
923
+ expect(command[:bypassDocumentValidation]).to eq(true)
924
+ end
925
+ end
926
+ end
927
+
928
+ describe '#aggregate' do
929
+
930
+ describe 'updating cluster time' do
931
+
932
+ let(:operation) do
933
+ client[TEST_COLL].aggregate([]).first
934
+ end
935
+
936
+ let(:operation_with_session) do
937
+ client[TEST_COLL].aggregate([], session: session).first
938
+ end
939
+
940
+ let(:second_operation) do
941
+ client[TEST_COLL].aggregate([], session: session).first
942
+ end
943
+
944
+ it_behaves_like 'an operation updating cluster time'
945
+ end
946
+
947
+ context 'when a session supporting causal consistency is used' do
948
+ require_wired_tiger
949
+
950
+ let(:operation) do
951
+ collection.aggregate([], session: session).first
952
+ end
953
+
954
+ let(:command) do
955
+ operation
956
+ subscriber.started_events.find { |cmd| cmd.command_name == 'aggregate' }.command
957
+ end
958
+
959
+ it_behaves_like 'an operation supporting causally consistent reads'
960
+ end
961
+
962
+ it 'returns an Aggregation object' do
963
+ expect(authorized_collection.aggregate([])).to be_a(Mongo::Collection::View::Aggregation)
964
+ end
965
+
966
+ context 'when options are provided' do
967
+
968
+ let(:options) do
969
+ { :allow_disk_use => true, :bypass_document_validation => true }
970
+ end
971
+
972
+ it 'sets the options on the Aggregation object' do
973
+ expect(authorized_collection.aggregate([], options).options).to eq(BSON::Document.new(options))
974
+ end
975
+
976
+ context 'when the :comment option is provided' do
977
+
978
+ let(:options) do
979
+ { :comment => 'testing' }
980
+ end
981
+
982
+ it 'sets the options on the Aggregation object' do
983
+ expect(authorized_collection.aggregate([], options).options).to eq(BSON::Document.new(options))
984
+ end
985
+ end
986
+
987
+ context 'when a session is provided' do
988
+
989
+ let(:session) do
990
+ authorized_client.start_session
991
+ end
992
+
993
+ let(:operation) do
994
+ authorized_collection.aggregate([], session: session).to_a
995
+ end
996
+
997
+ let(:failed_operation) do
998
+ authorized_collection.aggregate([ { '$invalid' => 1 }], session: session).to_a
999
+ end
1000
+
1001
+ let(:client) do
1002
+ authorized_client
1003
+ end
1004
+
1005
+ it_behaves_like 'an operation using a session'
1006
+ it_behaves_like 'a failed operation using a session'
1007
+ end
1008
+
1009
+ context 'when a hint is provided' do
1010
+
1011
+ let(:options) do
1012
+ { 'hint' => { 'y' => 1 } }
1013
+ end
1014
+
1015
+ it 'sets the options on the Aggregation object' do
1016
+ expect(authorized_collection.aggregate([], options).options).to eq(options)
1017
+ end
1018
+ end
1019
+
1020
+ context 'when collation is provided' do
1021
+
1022
+ before do
1023
+ authorized_collection.insert_many([ { name: 'bang' }, { name: 'bang' }])
1024
+ end
1025
+
1026
+ let(:pipeline) do
1027
+ [{ "$match" => { "name" => "BANG" } }]
1028
+ end
1029
+
1030
+ let(:options) do
1031
+ { collation: { locale: 'en_US', strength: 2 } }
1032
+ end
1033
+
1034
+ let(:result) do
1035
+ authorized_collection.aggregate(pipeline, options).collect { |doc| doc['name']}
1036
+ end
1037
+
1038
+ context 'when the server selected supports collations' do
1039
+ min_server_fcv '3.4'
1040
+
1041
+ it 'applies the collation' do
1042
+ expect(result).to eq(['bang', 'bang'])
1043
+ end
1044
+ end
1045
+
1046
+ context 'when the server selected does not support collations' do
1047
+ max_server_version '3.2'
1048
+
1049
+ it 'raises an exception' do
1050
+ expect {
1051
+ result
1052
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1053
+ end
1054
+
1055
+ context 'when a String key is used' do
1056
+
1057
+ let(:options) do
1058
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1059
+ end
1060
+
1061
+ it 'raises an exception' do
1062
+ expect {
1063
+ result
1064
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1065
+ end
1066
+ end
1067
+ end
1068
+ end
1069
+ end
1070
+ end
1071
+
1072
+ describe '#count_documents' do
1073
+
1074
+ before do
1075
+ authorized_collection.delete_many
1076
+ end
1077
+
1078
+ context 'no argument provided' do
1079
+
1080
+ context 'when collection is empty' do
1081
+ it 'returns 0 matching documents' do
1082
+ expect(authorized_collection.count_documents).to eq(0)
1083
+ end
1084
+ end
1085
+
1086
+ context 'when collection is not empty' do
1087
+
1088
+ let(:documents) do
1089
+ documents = []
1090
+ 1.upto(10) do |index|
1091
+ documents << { key: 'a', _id: "in#{index}" }
1092
+ end
1093
+ documents
1094
+ end
1095
+
1096
+ before do
1097
+ authorized_collection.insert_many(documents)
1098
+ end
1099
+
1100
+ it 'returns 10 matching documents' do
1101
+ expect(authorized_collection.count_documents).to eq(10)
1102
+ end
1103
+ end
1104
+ end
1105
+
1106
+ context 'when transactions are enabled' do
1107
+ require_wired_tiger
1108
+ require_transaction_support
1109
+
1110
+ before do
1111
+ # Ensure that the collection is created
1112
+ authorized_collection.insert_one(x: 1)
1113
+ authorized_collection.delete_many({})
1114
+ end
1115
+
1116
+ let(:session) do
1117
+ authorized_client.start_session
1118
+ end
1119
+
1120
+ it 'successfully starts a transaction and executes a transaction' do
1121
+ session.start_transaction
1122
+ expect(
1123
+ session.instance_variable_get(:@state)
1124
+ ).to eq(Mongo::Session::STARTING_TRANSACTION_STATE)
1125
+
1126
+ expect(authorized_collection.count_documents({}, { session: session })).to eq(0)
1127
+ expect(
1128
+ session.instance_variable_get(:@state)
1129
+ ).to eq(Mongo::Session::TRANSACTION_IN_PROGRESS_STATE)
1130
+
1131
+ authorized_collection.insert_one({ x: 1 }, { session: session })
1132
+ expect(authorized_collection.count_documents({}, { session: session })).to eq(1)
1133
+
1134
+ session.commit_transaction
1135
+ expect(
1136
+ session.instance_variable_get(:@state)
1137
+ ).to eq(Mongo::Session::TRANSACTION_COMMITTED_STATE)
1138
+ end
1139
+ end
1140
+ end
1141
+
1142
+ describe '#count' do
1143
+
1144
+ let(:documents) do
1145
+ (1..10).map{ |i| { field: "test#{i}" }}
1146
+ end
1147
+
1148
+ before do
1149
+ authorized_collection.insert_many(documents)
1150
+ end
1151
+
1152
+ it 'returns an integer count' do
1153
+ expect(authorized_collection.count).to eq(10)
1154
+ end
1155
+
1156
+ context 'when options are provided' do
1157
+
1158
+ it 'passes the options to the count' do
1159
+ expect(authorized_collection.count({}, limit: 5)).to eq(5)
1160
+ end
1161
+
1162
+ context 'when a session is provided' do
1163
+ require_wired_tiger
1164
+
1165
+ let(:session) do
1166
+ authorized_client.start_session
1167
+ end
1168
+
1169
+ let(:operation) do
1170
+ authorized_collection.count({}, session: session)
1171
+ end
1172
+
1173
+ let(:failed_operation) do
1174
+ authorized_collection.count({ '$._id' => 1 }, session: session)
1175
+ end
1176
+
1177
+ let(:client) do
1178
+ authorized_client
1179
+ end
1180
+
1181
+ it_behaves_like 'an operation using a session'
1182
+ it_behaves_like 'a failed operation using a session'
1183
+ end
1184
+
1185
+ context 'when a session supporting causal consistency is used' do
1186
+ require_wired_tiger
1187
+
1188
+ let(:operation) do
1189
+ collection.count({}, session: session)
1190
+ end
1191
+
1192
+ let(:command) do
1193
+ operation
1194
+ subscriber.started_events.find { |cmd| cmd.command_name == 'count' }.command
1195
+ end
1196
+
1197
+ it_behaves_like 'an operation supporting causally consistent reads'
1198
+ end
1199
+
1200
+ context 'when a collation is specified' do
1201
+
1202
+ let(:selector) do
1203
+ { name: 'BANG' }
1204
+ end
1205
+
1206
+ let(:result) do
1207
+ authorized_collection.count(selector, options)
1208
+ end
1209
+
1210
+ before do
1211
+ authorized_collection.insert_one(name: 'bang')
1212
+ end
1213
+
1214
+ let(:options) do
1215
+ { collation: { locale: 'en_US', strength: 2 } }
1216
+ end
1217
+
1218
+ context 'when the server selected supports collations' do
1219
+ min_server_fcv '3.4'
1220
+
1221
+ it 'applies the collation to the count' do
1222
+ expect(result).to eq(1)
1223
+ end
1224
+ end
1225
+
1226
+ context 'when the server selected does not support collations' do
1227
+ max_server_version '3.2'
1228
+
1229
+ it 'raises an exception' do
1230
+ expect {
1231
+ result
1232
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1233
+ end
1234
+
1235
+ context 'when a String key is used' do
1236
+
1237
+ let(:options) do
1238
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1239
+ end
1240
+
1241
+ it 'raises an exception' do
1242
+ expect {
1243
+ result
1244
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1245
+ end
1246
+ end
1247
+ end
1248
+ end
1249
+ end
1250
+ end
1251
+
1252
+ describe '#distinct' do
1253
+
1254
+ let(:documents) do
1255
+ (1..3).map{ |i| { field: "test#{i}" }}
1256
+ end
1257
+
1258
+ before do
1259
+ authorized_collection.insert_many(documents)
1260
+ end
1261
+
1262
+ it 'returns the distinct values' do
1263
+ expect(authorized_collection.distinct(:field).sort).to eq([ 'test1', 'test2', 'test3' ])
1264
+ end
1265
+
1266
+ context 'when a selector is provided' do
1267
+
1268
+ it 'returns the distinct values' do
1269
+ expect(authorized_collection.distinct(:field, field: 'test1')).to eq([ 'test1' ])
1270
+ end
1271
+ end
1272
+
1273
+ context 'when options are provided' do
1274
+
1275
+ it 'passes the options to the distinct command' do
1276
+ expect(authorized_collection.distinct(:field, {}, max_time_ms: 100).sort).to eq([ 'test1', 'test2', 'test3' ])
1277
+ end
1278
+
1279
+ context 'when a session is provided' do
1280
+ require_wired_tiger
1281
+
1282
+ let(:session) do
1283
+ authorized_client.start_session
1284
+ end
1285
+
1286
+ let(:operation) do
1287
+ authorized_collection.distinct(:field, {}, session: session)
1288
+ end
1289
+
1290
+ let(:failed_operation) do
1291
+ authorized_collection.distinct(:field, { '$._id' => 1 }, session: session)
1292
+ end
1293
+
1294
+ let(:client) do
1295
+ authorized_client
1296
+ end
1297
+
1298
+ it_behaves_like 'an operation using a session'
1299
+ it_behaves_like 'a failed operation using a session'
1300
+ end
1301
+ end
1302
+
1303
+ context 'when a session supporting causal consistency is used' do
1304
+ require_wired_tiger
1305
+
1306
+ let(:operation) do
1307
+ collection.distinct(:field, {}, session: session)
1308
+ end
1309
+
1310
+ let(:command) do
1311
+ operation
1312
+ subscriber.started_events.find { |cmd| cmd.command_name == 'distinct' }.command
1313
+ end
1314
+
1315
+ it_behaves_like 'an operation supporting causally consistent reads'
1316
+ end
1317
+
1318
+ context 'when a collation is specified' do
1319
+
1320
+ let(:result) do
1321
+ authorized_collection.distinct(:name, {}, options)
1322
+ end
1323
+
1324
+ before do
1325
+ authorized_collection.insert_one(name: 'bang')
1326
+ authorized_collection.insert_one(name: 'BANG')
1327
+ end
1328
+
1329
+ let(:options) do
1330
+ { collation: { locale: 'en_US', strength: 2 } }
1331
+ end
1332
+
1333
+ context 'when the server selected supports collations' do
1334
+ min_server_fcv '3.4'
1335
+
1336
+ it 'applies the collation to the distinct' do
1337
+ expect(result).to eq(['bang'])
1338
+ end
1339
+ end
1340
+
1341
+ context 'when the server selected does not support collations' do
1342
+ max_server_version '3.2'
1343
+
1344
+ it 'raises an exception' do
1345
+ expect {
1346
+ result
1347
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1348
+ end
1349
+
1350
+ context 'when a String key is used' do
1351
+
1352
+ let(:options) do
1353
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1354
+ end
1355
+
1356
+ it 'raises an exception' do
1357
+ expect {
1358
+ result
1359
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1360
+ end
1361
+ end
1362
+ end
1363
+ end
1364
+
1365
+ context 'when a collation is not specified' do
1366
+
1367
+ let(:result) do
1368
+ authorized_collection.distinct(:name)
1369
+ end
1370
+
1371
+ before do
1372
+ authorized_collection.insert_one(name: 'bang')
1373
+ authorized_collection.insert_one(name: 'BANG')
1374
+ end
1375
+
1376
+ it 'does not apply the collation to the distinct' do
1377
+ expect(result).to match_array(['bang', 'BANG'])
1378
+ end
1379
+ end
1380
+ end
1381
+
1382
+ describe '#delete_one' do
1383
+
1384
+ context 'when a selector was provided' do
1385
+
1386
+ let(:selector) do
1387
+ { field: 'test1' }
1388
+ end
1389
+
1390
+ before do
1391
+ authorized_collection.insert_many([
1392
+ { field: 'test1' },
1393
+ { field: 'test1' },
1394
+ { field: 'test1' }
1395
+ ])
1396
+ end
1397
+
1398
+ let(:response) do
1399
+ authorized_collection.delete_one(selector)
1400
+ end
1401
+
1402
+ it 'deletes the first matching document in the collection' do
1403
+ expect(response.deleted_count).to eq(1)
1404
+ end
1405
+ end
1406
+
1407
+ context 'when no selector was provided' do
1408
+
1409
+ before do
1410
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test2' }])
1411
+ end
1412
+
1413
+ let(:response) do
1414
+ authorized_collection.delete_one
1415
+ end
1416
+
1417
+ it 'deletes the first document in the collection' do
1418
+ expect(response.deleted_count).to eq(1)
1419
+ end
1420
+ end
1421
+
1422
+ context 'when the delete fails' do
1423
+ require_topology :single
1424
+
1425
+ let(:result) do
1426
+ collection_invalid_write_concern.delete_one
1427
+ end
1428
+
1429
+ it 'raises an OperationFailure' do
1430
+ expect {
1431
+ result
1432
+ }.to raise_exception(Mongo::Error::OperationFailure)
1433
+ end
1434
+ end
1435
+
1436
+ context 'when a session is provided' do
1437
+
1438
+ let(:session) do
1439
+ authorized_client.start_session
1440
+ end
1441
+
1442
+ let(:operation) do
1443
+ authorized_collection.delete_one({}, session: session)
1444
+ end
1445
+
1446
+ let(:failed_operation) do
1447
+ authorized_collection.delete_one({ '$._id' => 1}, session: session)
1448
+ end
1449
+
1450
+ let(:client) do
1451
+ authorized_client
1452
+ end
1453
+
1454
+ it_behaves_like 'an operation using a session'
1455
+ it_behaves_like 'a failed operation using a session'
1456
+ end
1457
+
1458
+ context 'when unacknowledged writes is used' do
1459
+
1460
+ let(:collection_with_unacknowledged_write_concern) do
1461
+ authorized_collection.with(write: { w: 0 })
1462
+ end
1463
+
1464
+ let(:operation) do
1465
+ collection_with_unacknowledged_write_concern.delete_one({}, session: session)
1466
+ end
1467
+
1468
+ it_behaves_like 'an explicit session with an unacknowledged write'
1469
+ end
1470
+
1471
+ context 'when unacknowledged writes is used with an implicit session' do
1472
+
1473
+ let(:collection_with_unacknowledged_write_concern) do
1474
+ client.with(write: { w: 0 })[TEST_COLL]
1475
+ end
1476
+
1477
+ let(:operation) do
1478
+ collection_with_unacknowledged_write_concern.delete_one
1479
+ end
1480
+
1481
+ it_behaves_like 'an implicit session with an unacknowledged write'
1482
+ end
1483
+
1484
+ context 'when a collation is provided' do
1485
+
1486
+ let(:selector) do
1487
+ { name: 'BANG' }
1488
+ end
1489
+
1490
+ let(:result) do
1491
+ authorized_collection.delete_one(selector, options)
1492
+ end
1493
+
1494
+ before do
1495
+ authorized_collection.insert_one(name: 'bang')
1496
+ end
1497
+
1498
+ let(:options) do
1499
+ { collation: { locale: 'en_US', strength: 2 } }
1500
+ end
1501
+
1502
+ context 'when the server selected supports collations' do
1503
+ min_server_fcv '3.4'
1504
+
1505
+ it 'applies the collation' do
1506
+ expect(result.written_count).to eq(1)
1507
+ expect(authorized_collection.find(name: 'bang').count).to eq(0)
1508
+ end
1509
+
1510
+ context 'when unacknowledged writes is used' do
1511
+
1512
+ let(:collection_with_unacknowledged_write_concern) do
1513
+ authorized_collection.with(write: { w: 0 })
1514
+ end
1515
+
1516
+ let(:result) do
1517
+ collection_with_unacknowledged_write_concern.delete_one(selector, options)
1518
+ end
1519
+
1520
+ it 'raises an exception' do
1521
+ expect {
1522
+ result
1523
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1524
+ end
1525
+
1526
+ context 'when a String key is used' do
1527
+
1528
+ let(:options) do
1529
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1530
+ end
1531
+
1532
+ it 'raises an exception' do
1533
+ expect {
1534
+ result
1535
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1536
+ end
1537
+ end
1538
+ end
1539
+ end
1540
+
1541
+ context 'when the server selected does not support collations' do
1542
+ max_server_version '3.2'
1543
+
1544
+ it 'raises an exception' do
1545
+ expect {
1546
+ result
1547
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1548
+ end
1549
+
1550
+ context 'when a String key is used' do
1551
+
1552
+ let(:options) do
1553
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1554
+ end
1555
+
1556
+ it 'raises an exception' do
1557
+ expect {
1558
+ result
1559
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1560
+ end
1561
+ end
1562
+ end
1563
+ end
1564
+
1565
+ context 'when collation is not specified' do
1566
+
1567
+ let(:selector) do
1568
+ { name: 'BANG' }
1569
+ end
1570
+
1571
+ let(:result) do
1572
+ authorized_collection.delete_one(selector)
1573
+ end
1574
+
1575
+ before do
1576
+ authorized_collection.insert_one(name: 'bang')
1577
+ end
1578
+
1579
+ it 'does not apply the collation' do
1580
+ expect(result.written_count).to eq(0)
1581
+ expect(authorized_collection.find(name: 'bang').count).to eq(1)
1582
+ end
1583
+ end
1584
+
1585
+ context 'when various options passed in' do
1586
+ # w: 2 requires a replica set
1587
+ require_topology :replica_set
1588
+
1589
+ # https://jira.mongodb.org/browse/RUBY-2306
1590
+ min_server_fcv '3.6'
1591
+
1592
+ before do
1593
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
1594
+ end
1595
+
1596
+ let(:selector) do
1597
+ {name: 'test2'}
1598
+ end
1599
+
1600
+ let(:session) do
1601
+ authorized_client.start_session
1602
+ end
1603
+
1604
+ let(:events) do
1605
+ subscriber.command_started_events('delete')
1606
+ end
1607
+
1608
+ let(:collection) do
1609
+ authorized_collection.with(write_concern: {w: 2})
1610
+ end
1611
+
1612
+ let!(:command) do
1613
+ Utils.get_command_event(authorized_client, 'delete') do |client|
1614
+ collection.delete_one(selector, session: session, write_concern: {w: 1},
1615
+ bypass_document_validation: true)
1616
+ end.command
1617
+ end
1618
+
1619
+ it 'deletes one successfully with correct options sent to server' do
1620
+ expect(events.length).to eq(1)
1621
+ expect(command[:writeConcern]).to_not be_nil
1622
+ expect(command[:writeConcern][:w]).to eq(1)
1623
+ expect(command[:bypassDocumentValidation]).to eq(true)
1624
+ end
1625
+ end
1626
+ end
1627
+
1628
+ describe '#delete_many' do
1629
+
1630
+ before do
1631
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test2' }])
1632
+ end
1633
+
1634
+ context 'when a selector was provided' do
1635
+
1636
+ let(:selector) do
1637
+ { field: 'test1' }
1638
+ end
1639
+
1640
+ it 'deletes the matching documents in the collection' do
1641
+ expect(authorized_collection.delete_many(selector).deleted_count).to eq(1)
1642
+ end
1643
+ end
1644
+
1645
+ context 'when no selector was provided' do
1646
+
1647
+ it 'deletes all the documents in the collection' do
1648
+ expect(authorized_collection.delete_many.deleted_count).to eq(2)
1649
+ end
1650
+ end
1651
+
1652
+ context 'when the deletes fail' do
1653
+ require_topology :single
1654
+
1655
+ let(:result) do
1656
+ collection_invalid_write_concern.delete_many
1657
+ end
1658
+
1659
+ it 'raises an OperationFailure' do
1660
+ expect {
1661
+ result
1662
+ }.to raise_exception(Mongo::Error::OperationFailure)
1663
+ end
1664
+ end
1665
+
1666
+ context 'when a session is provided' do
1667
+
1668
+ let(:session) do
1669
+ authorized_client.start_session
1670
+ end
1671
+
1672
+ let(:operation) do
1673
+ authorized_collection.delete_many({}, session: session)
1674
+ end
1675
+
1676
+ let(:failed_operation) do
1677
+ authorized_collection.delete_many({ '$._id' => 1}, session: session)
1678
+ end
1679
+
1680
+ let(:client) do
1681
+ authorized_client
1682
+ end
1683
+
1684
+ it_behaves_like 'an operation using a session'
1685
+ it_behaves_like 'a failed operation using a session'
1686
+ end
1687
+
1688
+ context 'when unacknowledged writes are used with an explicit session' do
1689
+
1690
+ let(:collection_with_unacknowledged_write_concern) do
1691
+ authorized_collection.with(write: { w: 0 })
1692
+ end
1693
+
1694
+ let(:operation) do
1695
+ collection_with_unacknowledged_write_concern.delete_many({ '$._id' => 1}, session: session)
1696
+ end
1697
+
1698
+ it_behaves_like 'an explicit session with an unacknowledged write'
1699
+ end
1700
+
1701
+ context 'when unacknowledged writes are used with an implicit session' do
1702
+
1703
+ let(:collection_with_unacknowledged_write_concern) do
1704
+ client.with(write: { w: 0 })[TEST_COLL]
1705
+ end
1706
+
1707
+ let(:operation) do
1708
+ collection_with_unacknowledged_write_concern.delete_many({ '$._id' => 1 })
1709
+ end
1710
+
1711
+ it_behaves_like 'an implicit session with an unacknowledged write'
1712
+ end
1713
+
1714
+ context 'when a collation is specified' do
1715
+
1716
+ let(:selector) do
1717
+ { name: 'BANG' }
1718
+ end
1719
+
1720
+ let(:result) do
1721
+ authorized_collection.delete_many(selector, options)
1722
+ end
1723
+
1724
+ before do
1725
+ authorized_collection.insert_one(name: 'bang')
1726
+ authorized_collection.insert_one(name: 'bang')
1727
+ end
1728
+
1729
+ let(:options) do
1730
+ { collation: { locale: 'en_US', strength: 2 } }
1731
+ end
1732
+
1733
+ context 'when the server selected supports collations' do
1734
+ min_server_fcv '3.4'
1735
+
1736
+ it 'applies the collation' do
1737
+ expect(result.written_count).to eq(2)
1738
+ expect(authorized_collection.find(name: 'bang').count).to eq(0)
1739
+ end
1740
+
1741
+ context 'when unacknowledged writes is used' do
1742
+
1743
+ let(:collection_with_unacknowledged_write_concern) do
1744
+ authorized_collection.with(write: { w: 0 })
1745
+ end
1746
+
1747
+ let(:result) do
1748
+ collection_with_unacknowledged_write_concern.delete_many(selector, options)
1749
+ end
1750
+
1751
+ it 'raises an exception' do
1752
+ expect {
1753
+ result
1754
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1755
+ end
1756
+
1757
+ context 'when a String key is used' do
1758
+
1759
+ let(:options) do
1760
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1761
+ end
1762
+
1763
+ it 'raises an exception' do
1764
+ expect {
1765
+ result
1766
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1767
+ end
1768
+ end
1769
+ end
1770
+ end
1771
+
1772
+ context 'when the server selected does not support collations' do
1773
+ max_server_version '3.2'
1774
+
1775
+ it 'raises an exception' do
1776
+ expect {
1777
+ result
1778
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1779
+ end
1780
+
1781
+ context 'when a String key is used' do
1782
+
1783
+ let(:options) do
1784
+ { 'collation' => { locale: 'en_US', strength: 2 } }
1785
+ end
1786
+
1787
+ it 'raises an exception' do
1788
+ expect {
1789
+ result
1790
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
1791
+ end
1792
+ end
1793
+ end
1794
+ end
1795
+
1796
+ context 'when a collation is not specified' do
1797
+
1798
+ let(:selector) do
1799
+ { name: 'BANG' }
1800
+ end
1801
+
1802
+ let(:result) do
1803
+ authorized_collection.delete_many(selector)
1804
+ end
1805
+
1806
+ before do
1807
+ authorized_collection.insert_one(name: 'bang')
1808
+ authorized_collection.insert_one(name: 'bang')
1809
+ end
1810
+
1811
+ it 'does not apply the collation' do
1812
+ expect(result.written_count).to eq(0)
1813
+ expect(authorized_collection.find(name: 'bang').count).to eq(2)
1814
+ end
1815
+ end
1816
+
1817
+ context 'when various options passed in' do
1818
+ # w: 2 requires a replica set
1819
+ require_topology :replica_set
1820
+
1821
+ # https://jira.mongodb.org/browse/RUBY-2306
1822
+ min_server_fcv '3.6'
1823
+
1824
+ before do
1825
+ collection.insert_many([{ name: 'test1' }, { name: 'test2' }, { name: 'test3'}])
1826
+ end
1827
+
1828
+ let(:selector) do
1829
+ {name: 'test1'}
1830
+ end
1831
+
1832
+ let(:session) do
1833
+ authorized_client.start_session
1834
+ end
1835
+
1836
+ let(:events) do
1837
+ subscriber.command_started_events('delete')
1838
+ end
1839
+
1840
+ let(:collection) do
1841
+ authorized_collection.with(write_concern: {w: 1})
1842
+ end
1843
+
1844
+ let!(:command) do
1845
+ Utils.get_command_event(authorized_client, 'delete') do |client|
1846
+ collection.delete_many(selector, session: session, write_concern: {w: 2},
1847
+ bypass_document_validation: true)
1848
+ end.command
1849
+ end
1850
+
1851
+ it 'deletes many successfully with correct options sent to server' do
1852
+ expect(events.length).to eq(1)
1853
+ expect(command[:writeConcern]).to_not be_nil
1854
+ expect(command[:writeConcern][:w]).to eq(2)
1855
+ expect(command[:bypassDocumentValidation]).to be(true)
1856
+ end
1857
+ end
1858
+ end
1859
+
1860
+ describe '#parallel_scan' do
1861
+ max_server_version '4.0'
1862
+ require_topology :single, :replica_set
1863
+
1864
+ let(:documents) do
1865
+ (1..200).map do |i|
1866
+ { name: "testing-scan-#{i}" }
1867
+ end
1868
+ end
1869
+
1870
+ before do
1871
+ authorized_collection.insert_many(documents)
1872
+ end
1873
+
1874
+ let(:cursors) do
1875
+ authorized_collection.parallel_scan(2)
1876
+ end
1877
+
1878
+ it 'returns an array of cursors' do
1879
+ cursors.each do |cursor|
1880
+ expect(cursor.class).to be(Mongo::Cursor)
1881
+ end
1882
+ end
1883
+
1884
+ it 'returns the correct number of documents' do
1885
+ expect(
1886
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1887
+ ).to eq(200)
1888
+ end
1889
+
1890
+ context 'when a session is provided' do
1891
+ require_wired_tiger
1892
+
1893
+ let(:cursors) do
1894
+ authorized_collection.parallel_scan(2, session: session)
1895
+ end
1896
+
1897
+ let(:operation) do
1898
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1899
+ end
1900
+
1901
+ let(:failed_operation) do
1902
+ authorized_collection.parallel_scan(-2, session: session)
1903
+ end
1904
+
1905
+ let(:client) do
1906
+ authorized_client
1907
+ end
1908
+
1909
+ it_behaves_like 'an operation using a session'
1910
+ it_behaves_like 'a failed operation using a session'
1911
+ end
1912
+
1913
+ context 'when a session is not provided' do
1914
+ let(:collection) { client['test'] }
1915
+
1916
+ let(:cursors) do
1917
+ collection.parallel_scan(2)
1918
+ end
1919
+
1920
+ let(:operation) do
1921
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1922
+ end
1923
+
1924
+ let(:failed_operation) do
1925
+ collection.parallel_scan(-2)
1926
+ end
1927
+
1928
+ let(:command) do
1929
+ operation
1930
+ event = subscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
1931
+ expect(event).not_to be_nil
1932
+ event.command
1933
+ end
1934
+
1935
+ it_behaves_like 'an operation not using a session'
1936
+ it_behaves_like 'a failed operation not using a session'
1937
+ end
1938
+
1939
+ context 'when a session supporting causal consistency is used' do
1940
+ require_wired_tiger
1941
+
1942
+ before do
1943
+ collection.drop
1944
+ collection.create
1945
+ end
1946
+
1947
+ let(:cursors) do
1948
+ collection.parallel_scan(2, session: session)
1949
+ end
1950
+
1951
+ let(:operation) do
1952
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1953
+ end
1954
+
1955
+ let(:command) do
1956
+ operation
1957
+ event = subscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
1958
+ expect(event).not_to be_nil
1959
+ event.command
1960
+ end
1961
+
1962
+ it_behaves_like 'an operation supporting causally consistent reads'
1963
+ end
1964
+
1965
+ context 'when a read concern is provided' do
1966
+ require_wired_tiger
1967
+ min_server_fcv '3.2'
1968
+
1969
+ let(:result) do
1970
+ authorized_collection.with(options).parallel_scan(2)
1971
+ end
1972
+
1973
+ context 'when the read concern is valid' do
1974
+
1975
+ let(:options) do
1976
+ { read_concern: { level: 'local' }}
1977
+ end
1978
+
1979
+ it 'sends the read concern' do
1980
+ expect { result }.to_not raise_error
1981
+ end
1982
+ end
1983
+
1984
+ context 'when the read concern is not valid' do
1985
+
1986
+ let(:options) do
1987
+ { read_concern: { level: 'idontknow' }}
1988
+ end
1989
+
1990
+ it 'raises an exception' do
1991
+ expect {
1992
+ result
1993
+ }.to raise_error(Mongo::Error::OperationFailure)
1994
+ end
1995
+ end
1996
+ end
1997
+
1998
+ context 'when the collection has a read preference' do
1999
+ require_topology :single, :replica_set
2000
+
2001
+ before do
2002
+ allow(collection.client.cluster).to receive(:single?).and_return(false)
2003
+ end
2004
+
2005
+ let(:client) do
2006
+ authorized_client.with(server_selection_timeout: 0.2)
2007
+ end
2008
+
2009
+ let(:collection) do
2010
+ client[authorized_collection.name,
2011
+ read: { :mode => :secondary, :tag_sets => [{ 'non' => 'existent' }] }]
2012
+ end
2013
+
2014
+ let(:result) do
2015
+ collection.parallel_scan(2)
2016
+ end
2017
+
2018
+ it 'uses that read preference' do
2019
+ expect {
2020
+ result
2021
+ }.to raise_exception(Mongo::Error::NoServerAvailable)
2022
+ end
2023
+ end
2024
+
2025
+ context 'when a max time ms value is provided' do
2026
+ require_topology :single, :replica_set
2027
+
2028
+ let(:result) do
2029
+ authorized_collection.parallel_scan(2, options)
2030
+ end
2031
+
2032
+ context 'when the read concern is valid' do
2033
+
2034
+ let(:options) do
2035
+ { max_time_ms: 5 }
2036
+ end
2037
+
2038
+ it 'sends the max time ms value' do
2039
+ expect { result }.to_not raise_error
2040
+ end
2041
+ end
2042
+
2043
+ context 'when the max time ms is not valid' do
2044
+
2045
+ let(:options) do
2046
+ { max_time_ms: 0.1 }
2047
+ end
2048
+
2049
+ it 'raises an exception' do
2050
+ expect {
2051
+ result
2052
+ }.to raise_error(Mongo::Error::OperationFailure)
2053
+ end
2054
+ end
2055
+ end
2056
+ end
2057
+
2058
+ describe '#replace_one' do
2059
+
2060
+ let(:selector) do
2061
+ { field: 'test1' }
2062
+ end
2063
+
2064
+ context 'when a selector was provided' do
2065
+
2066
+ before do
2067
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
2068
+ end
2069
+
2070
+ let!(:response) do
2071
+ authorized_collection.replace_one(selector, { field: 'testing' })
2072
+ end
2073
+
2074
+ let(:updated) do
2075
+ authorized_collection.find(field: 'testing').first
2076
+ end
2077
+
2078
+ it 'updates the first matching document in the collection' do
2079
+ expect(response.modified_count).to eq(1)
2080
+ end
2081
+
2082
+ it 'updates the documents in the collection' do
2083
+ expect(updated[:field]).to eq('testing')
2084
+ end
2085
+ end
2086
+
2087
+ context 'when upsert is false' do
2088
+
2089
+ let!(:response) do
2090
+ authorized_collection.replace_one(selector, { field: 'test1' }, upsert: false)
2091
+ end
2092
+
2093
+ let(:updated) do
2094
+ authorized_collection.find(field: 'test1').to_a
2095
+ end
2096
+
2097
+ it 'reports that no documents were written' do
2098
+ expect(response.modified_count).to eq(0)
2099
+ end
2100
+
2101
+ it 'does not insert the document' do
2102
+ expect(updated).to be_empty
2103
+ end
2104
+ end
2105
+
2106
+ context 'when upsert is true' do
2107
+
2108
+ let!(:response) do
2109
+ authorized_collection.replace_one(selector, { field: 'test1' }, upsert: true)
2110
+ end
2111
+
2112
+ let(:updated) do
2113
+ authorized_collection.find(field: 'test1').first
2114
+ end
2115
+
2116
+ it 'reports that a document was written' do
2117
+ expect(response.written_count).to eq(1)
2118
+ end
2119
+
2120
+ it 'inserts the document' do
2121
+ expect(updated[:field]).to eq('test1')
2122
+ end
2123
+ end
2124
+
2125
+ context 'when upsert is not specified' do
2126
+
2127
+ let!(:response) do
2128
+ authorized_collection.replace_one(selector, { field: 'test1' })
2129
+ end
2130
+
2131
+ let(:updated) do
2132
+ authorized_collection.find(field: 'test1').to_a
2133
+ end
2134
+
2135
+ it 'reports that no documents were written' do
2136
+ expect(response.modified_count).to eq(0)
2137
+ end
2138
+
2139
+ it 'does not insert the document' do
2140
+ expect(updated).to be_empty
2141
+ end
2142
+ end
2143
+
2144
+ context 'when the replace has an invalid key' do
2145
+
2146
+ context "when validate_update_replace is true" do
2147
+
2148
+ config_override :validate_update_replace, true
2149
+
2150
+ let(:result) do
2151
+ authorized_collection.replace_one(selector, { '$s' => 'test1' })
2152
+ end
2153
+
2154
+ it 'raises an InvalidReplacementDocument error' do
2155
+ expect {
2156
+ result
2157
+ }.to raise_exception(Mongo::Error::InvalidReplacementDocument)
2158
+ end
2159
+ end
2160
+
2161
+ context "when validate_update_replace is false" do
2162
+
2163
+ config_override :validate_update_replace, false
2164
+
2165
+ let(:result) do
2166
+ authorized_collection.replace_one(selector, { '$set' => { 'test1' => 1 } })
2167
+ end
2168
+
2169
+ it 'does not raise an error' do
2170
+ expect {
2171
+ result
2172
+ }.to_not raise_exception
2173
+ end
2174
+ end
2175
+ end
2176
+
2177
+ context 'when collection has a validator' do
2178
+ min_server_fcv '3.2'
2179
+
2180
+ around(:each) do |spec|
2181
+ collection_with_validator.drop
2182
+ authorized_client[:validating,
2183
+ :validator => { :a => { '$exists' => true } }].tap do |c|
2184
+ c.create
2185
+ end
2186
+ spec.run
2187
+ collection_with_validator.drop
2188
+ end
2189
+
2190
+ before do
2191
+ collection_with_validator.insert_one({ a: 1 })
2192
+ end
2193
+
2194
+ context 'when the document is valid' do
2195
+
2196
+ let(:result) do
2197
+ collection_with_validator.replace_one({ a: 1 }, { a: 5 })
2198
+ end
2199
+
2200
+ it 'replaces successfully' do
2201
+ expect(result.modified_count).to eq(1)
2202
+ end
2203
+ end
2204
+
2205
+ context 'when the document is invalid' do
2206
+
2207
+ context 'when bypass_document_validation is not set' do
2208
+
2209
+ let(:result2) do
2210
+ collection_with_validator.replace_one({ a: 1 }, { x: 5 })
2211
+ end
2212
+
2213
+ it 'raises OperationFailure' do
2214
+ expect {
2215
+ result2
2216
+ }.to raise_exception(Mongo::Error::OperationFailure)
2217
+ end
2218
+ end
2219
+
2220
+ context 'when bypass_document_validation is true' do
2221
+
2222
+ let(:result3) do
2223
+ collection_with_validator.replace_one(
2224
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true)
2225
+ end
2226
+
2227
+ it 'replaces successfully' do
2228
+ expect(result3.written_count).to eq(1)
2229
+ end
2230
+ end
2231
+ end
2232
+ end
2233
+
2234
+ context 'when a collation is specified' do
2235
+
2236
+ let(:selector) do
2237
+ { name: 'BANG' }
2238
+ end
2239
+
2240
+ let(:result) do
2241
+ authorized_collection.replace_one(selector, { name: 'doink' }, options)
2242
+ end
2243
+
2244
+ before do
2245
+ authorized_collection.insert_one(name: 'bang')
2246
+ end
2247
+
2248
+ let(:options) do
2249
+ { collation: { locale: 'en_US', strength: 2 } }
2250
+ end
2251
+
2252
+ context 'when the server selected supports collations' do
2253
+ min_server_fcv '3.4'
2254
+
2255
+ it 'applies the collation' do
2256
+ expect(result.written_count).to eq(1)
2257
+ expect(authorized_collection.find(name: 'doink').count).to eq(1)
2258
+ end
2259
+
2260
+ context 'when unacknowledged writes is used' do
2261
+
2262
+ let(:collection_with_unacknowledged_write_concern) do
2263
+ authorized_collection.with(write: { w: 0 })
2264
+ end
2265
+
2266
+ let(:result) do
2267
+ collection_with_unacknowledged_write_concern.replace_one(selector, { name: 'doink' }, options)
2268
+ end
2269
+
2270
+ it 'raises an exception' do
2271
+ expect {
2272
+ result
2273
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2274
+ end
2275
+
2276
+ context 'when a String key is used' do
2277
+
2278
+ let(:options) do
2279
+ { 'collation' => { locale: 'en_US', strength: 2 } }
2280
+ end
2281
+
2282
+ it 'raises an exception' do
2283
+ expect {
2284
+ result
2285
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2286
+ end
2287
+ end
2288
+ end
2289
+ end
2290
+
2291
+ context 'when the server selected does not support collations' do
2292
+ max_server_version '3.2'
2293
+
2294
+ it 'raises an exception' do
2295
+ expect {
2296
+ result
2297
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2298
+ end
2299
+
2300
+ context 'when a String key is used' do
2301
+
2302
+ let(:options) do
2303
+ { 'collation' => { locale: 'en_US', strength: 2 } }
2304
+ end
2305
+
2306
+ it 'raises an exception' do
2307
+ expect {
2308
+ result
2309
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2310
+ end
2311
+ end
2312
+ end
2313
+ end
2314
+
2315
+ context 'when a collation is not specified' do
2316
+
2317
+ let(:selector) do
2318
+ { name: 'BANG' }
2319
+ end
2320
+
2321
+ let(:result) do
2322
+ authorized_collection.replace_one(selector, { name: 'doink' })
2323
+ end
2324
+
2325
+ before do
2326
+ authorized_collection.insert_one(name: 'bang')
2327
+ end
2328
+
2329
+ it 'does not apply the collation' do
2330
+ expect(result.written_count).to eq(0)
2331
+ expect(authorized_collection.find(name: 'bang').count).to eq(1)
2332
+ end
2333
+ end
2334
+
2335
+ context 'when a session is provided' do
2336
+
2337
+ let(:selector) do
2338
+ { name: 'BANG' }
2339
+ end
2340
+
2341
+ before do
2342
+ authorized_collection.insert_one(name: 'bang')
2343
+ end
2344
+
2345
+ let(:session) do
2346
+ authorized_client.start_session
2347
+ end
2348
+
2349
+ let(:operation) do
2350
+ authorized_collection.replace_one(selector, { name: 'doink' }, session: session)
2351
+ end
2352
+
2353
+ let(:failed_operation) do
2354
+ authorized_collection.replace_one({ '$._id' => 1 }, { name: 'doink' }, session: session)
2355
+ end
2356
+
2357
+ let(:client) do
2358
+ authorized_client
2359
+ end
2360
+
2361
+ it_behaves_like 'an operation using a session'
2362
+ it_behaves_like 'a failed operation using a session'
2363
+ end
2364
+
2365
+ context 'when unacknowledged writes is used with an explicit session' do
2366
+
2367
+ let(:collection_with_unacknowledged_write_concern) do
2368
+ authorized_collection.with(write: { w: 0 })
2369
+ end
2370
+
2371
+ let(:operation) do
2372
+ collection_with_unacknowledged_write_concern.replace_one({ a: 1 }, { x: 5 }, session: session)
2373
+ end
2374
+
2375
+ it_behaves_like 'an explicit session with an unacknowledged write'
2376
+ end
2377
+
2378
+ context 'when unacknowledged writes is used with an implicit session' do
2379
+
2380
+ let(:collection_with_unacknowledged_write_concern) do
2381
+ client.with(write: { w: 0 })[TEST_COLL]
2382
+ end
2383
+
2384
+ let(:operation) do
2385
+ collection_with_unacknowledged_write_concern.replace_one({ a: 1 }, { x: 5 })
2386
+ end
2387
+
2388
+ it_behaves_like 'an implicit session with an unacknowledged write'
2389
+ end
2390
+
2391
+ context 'when various options passed in' do
2392
+ # w: 2 requires a replica set
2393
+ require_topology :replica_set
2394
+
2395
+ # https://jira.mongodb.org/browse/RUBY-2306
2396
+ min_server_fcv '3.6'
2397
+
2398
+ before do
2399
+ authorized_collection.insert_one({field: 'test1'})
2400
+ end
2401
+
2402
+ let(:session) do
2403
+ authorized_client.start_session
2404
+ end
2405
+
2406
+ let(:events) do
2407
+ subscriber.command_started_events('update')
2408
+ end
2409
+
2410
+ let(:collection) do
2411
+ authorized_collection.with(write_concern: {w: 3})
2412
+ end
2413
+
2414
+ let(:updated) do
2415
+ collection.find(field: 'test4').first
2416
+ end
2417
+
2418
+ let!(:command) do
2419
+ Utils.get_command_event(authorized_client, 'update') do |client|
2420
+ collection.replace_one(selector, { field: 'test4'},
2421
+ session: session, :return_document => :after, write_concern: {w: 2},
2422
+ upsert: true, bypass_document_validation: true)
2423
+ end.command
2424
+ end
2425
+
2426
+ it 'replaced one successfully with correct options sent to server' do
2427
+ expect(updated[:field]).to eq('test4')
2428
+ expect(events.length).to eq(1)
2429
+ expect(command[:writeConcern]).to_not be_nil
2430
+ expect(command[:writeConcern][:w]).to eq(2)
2431
+ expect(command[:bypassDocumentValidation]).to be(true)
2432
+ expect(command[:updates][0][:upsert]).to be(true)
2433
+ end
2434
+ end
2435
+ end
2436
+
2437
+ describe '#update_many' do
2438
+
2439
+ let(:selector) do
2440
+ { field: 'test' }
2441
+ end
2442
+
2443
+ context 'when a selector was provided' do
2444
+
2445
+ before do
2446
+ authorized_collection.insert_many([{ field: 'test' }, { field: 'test' }])
2447
+ end
2448
+
2449
+ let!(:response) do
2450
+ authorized_collection.update_many(selector, '$set'=> { field: 'testing' })
2451
+ end
2452
+
2453
+ let(:updated) do
2454
+ authorized_collection.find(field: 'testing').to_a.last
2455
+ end
2456
+
2457
+ it 'returns the number updated' do
2458
+ expect(response.modified_count).to eq(2)
2459
+ end
2460
+
2461
+ it 'updates the documents in the collection' do
2462
+ expect(updated[:field]).to eq('testing')
2463
+ end
2464
+ end
2465
+
2466
+ context 'when upsert is false' do
2467
+
2468
+ let(:response) do
2469
+ authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
2470
+ upsert: false)
2471
+ end
2472
+
2473
+ let(:updated) do
2474
+ authorized_collection.find.to_a
2475
+ end
2476
+
2477
+ it 'reports that no documents were updated' do
2478
+ expect(response.modified_count).to eq(0)
2479
+ end
2480
+
2481
+ it 'updates no documents in the collection' do
2482
+ expect(updated).to be_empty
2483
+ end
2484
+ end
2485
+
2486
+ context 'when upsert is true' do
2487
+
2488
+ let!(:response) do
2489
+ authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
2490
+ upsert: true)
2491
+ end
2492
+
2493
+ let(:updated) do
2494
+ authorized_collection.find.to_a.last
2495
+ end
2496
+
2497
+ it 'reports that a document was written' do
2498
+ expect(response.written_count).to eq(1)
2499
+ end
2500
+
2501
+ it 'inserts a document into the collection' do
2502
+ expect(updated[:field]).to eq('testing')
2503
+ end
2504
+ end
2505
+
2506
+ context 'when upsert is not specified' do
2507
+
2508
+ let(:response) do
2509
+ authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } })
2510
+ end
2511
+
2512
+ let(:updated) do
2513
+ authorized_collection.find.to_a
2514
+ end
2515
+
2516
+ it 'reports that no documents were updated' do
2517
+ expect(response.modified_count).to eq(0)
2518
+ end
2519
+
2520
+ it 'updates no documents in the collection' do
2521
+ expect(updated).to be_empty
2522
+ end
2523
+ end
2524
+
2525
+ context 'when arrayFilters is provided' do
2526
+
2527
+ let(:selector) do
2528
+ { '$or' => [{ _id: 0 }, { _id: 1 }]}
2529
+ end
2530
+
2531
+ context 'when the server supports arrayFilters' do
2532
+ min_server_fcv '3.6'
2533
+
2534
+ before do
2535
+ authorized_collection.insert_many([{
2536
+ _id: 0, x: [
2537
+ { y: 1 },
2538
+ { y: 2 },
2539
+ { y: 3 }
2540
+ ]
2541
+ },
2542
+ {
2543
+ _id: 1,
2544
+ x: [
2545
+ { y: 3 },
2546
+ { y: 2 },
2547
+ { y: 1 }
2548
+ ]
2549
+ }])
2550
+ end
2551
+
2552
+ let(:result) do
2553
+ authorized_collection.update_many(selector,
2554
+ { '$set' => { 'x.$[i].y' => 5 } },
2555
+ options)
2556
+ end
2557
+
2558
+ context 'when a Symbol key is used' do
2559
+
2560
+ let(:options) do
2561
+ { array_filters: [{ 'i.y' => 3 }] }
2562
+ end
2563
+
2564
+ it 'applies the arrayFilters' do
2565
+ expect(result.matched_count).to eq(2)
2566
+ expect(result.modified_count).to eq(2)
2567
+
2568
+ docs = authorized_collection.find(selector, sort: { _id: 1 }).to_a
2569
+ expect(docs[0]['x']).to eq ([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 5 }])
2570
+ expect(docs[1]['x']).to eq ([{ 'y' => 5 }, { 'y' => 2 }, { 'y' => 1 }])
2571
+ end
2572
+ end
2573
+
2574
+ context 'when a String key is used' do
2575
+ let(:options) do
2576
+ { 'array_filters' => [{ 'i.y' => 3 }] }
2577
+ end
2578
+
2579
+ it 'applies the arrayFilters' do
2580
+ expect(result.matched_count).to eq(2)
2581
+ expect(result.modified_count).to eq(2)
2582
+
2583
+ docs = authorized_collection.find({}, sort: { _id: 1 }).to_a
2584
+ expect(docs[0]['x']).to eq ([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 5 }])
2585
+ expect(docs[1]['x']).to eq ([{ 'y' => 5 }, { 'y' => 2 }, { 'y' => 1 }])
2586
+ end
2587
+ end
2588
+ end
2589
+
2590
+ context 'when the server does not support arrayFilters' do
2591
+ max_server_version '3.4'
2592
+
2593
+ let(:result) do
2594
+ authorized_collection.update_many(selector,
2595
+ { '$set' => { 'x.$[i].y' => 5 } },
2596
+ options)
2597
+ end
2598
+
2599
+ context 'when a Symbol key is used' do
2600
+
2601
+ let(:options) do
2602
+ { array_filters: [{ 'i.y' => 3 }] }
2603
+ end
2604
+
2605
+ it 'raises an exception' do
2606
+ expect {
2607
+ result
2608
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
2609
+ end
2610
+ end
2611
+
2612
+ context 'when a String key is used' do
2613
+
2614
+ let(:options) do
2615
+ { 'array_filters' => [{ 'i.y' => 3 }] }
2616
+ end
2617
+
2618
+ it 'raises an exception' do
2619
+ expect {
2620
+ result
2621
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
2622
+ end
2623
+ end
2624
+ end
2625
+ end
2626
+
2627
+ context 'when the updates fail' do
2628
+
2629
+ let(:result) do
2630
+ authorized_collection.update_many(selector, { '$s'=> { field: 'testing' } })
2631
+ end
2632
+
2633
+ it 'raises an OperationFailure' do
2634
+ expect {
2635
+ result
2636
+ }.to raise_exception(Mongo::Error::OperationFailure)
2637
+ end
2638
+ end
2639
+
2640
+ context 'when collection has a validator' do
2641
+ min_server_fcv '3.2'
2642
+
2643
+ around(:each) do |spec|
2644
+ authorized_client[:validating,
2645
+ :validator => { :a => { '$exists' => true } }].tap do |c|
2646
+ c.create
2647
+ end
2648
+ spec.run
2649
+ collection_with_validator.drop
2650
+ end
2651
+
2652
+ before do
2653
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
2654
+ end
2655
+
2656
+ context 'when the document is valid' do
2657
+
2658
+ let(:result) do
2659
+ collection_with_validator.update_many(
2660
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
2661
+ end
2662
+
2663
+ it 'updates successfully' do
2664
+ expect(result.modified_count).to eq(2)
2665
+ end
2666
+ end
2667
+
2668
+ context 'when the document is invalid' do
2669
+
2670
+ context 'when bypass_document_validation is not set' do
2671
+
2672
+ let(:result2) do
2673
+ collection_with_validator.update_many(
2674
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
2675
+ end
2676
+
2677
+ it 'raises OperationFailure' do
2678
+ expect {
2679
+ result2
2680
+ }.to raise_exception(Mongo::Error::OperationFailure)
2681
+ end
2682
+ end
2683
+
2684
+ context 'when bypass_document_validation is true' do
2685
+
2686
+ let(:result3) do
2687
+ collection_with_validator.update_many(
2688
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
2689
+ :bypass_document_validation => true)
2690
+ end
2691
+
2692
+ it 'updates successfully' do
2693
+ expect(result3.written_count).to eq(2)
2694
+ end
2695
+ end
2696
+ end
2697
+ end
2698
+
2699
+ context 'when a collation is specified' do
2700
+
2701
+ let(:selector) do
2702
+ { name: 'BANG' }
2703
+ end
2704
+
2705
+ let(:result) do
2706
+ authorized_collection.update_many(selector, { '$set' => { other: 'doink' } }, options)
2707
+ end
2708
+
2709
+ before do
2710
+ authorized_collection.insert_one(name: 'bang')
2711
+ authorized_collection.insert_one(name: 'baNG')
2712
+ end
2713
+
2714
+ let(:options) do
2715
+ { collation: { locale: 'en_US', strength: 2 } }
2716
+ end
2717
+
2718
+ context 'when the server selected supports collations' do
2719
+ min_server_fcv '3.4'
2720
+
2721
+ it 'applies the collation' do
2722
+ expect(result.written_count).to eq(2)
2723
+ expect(authorized_collection.find(other: 'doink').count).to eq(2)
2724
+ end
2725
+
2726
+ context 'when unacknowledged writes is used' do
2727
+
2728
+ let(:collection_with_unacknowledged_write_concern) do
2729
+ authorized_collection.with(write: { w: 0 })
2730
+ end
2731
+
2732
+ let(:result) do
2733
+ collection_with_unacknowledged_write_concern.update_many(selector, { '$set' => { other: 'doink' } }, options)
2734
+ end
2735
+
2736
+ it 'raises an exception' do
2737
+ expect {
2738
+ result
2739
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2740
+ end
2741
+
2742
+ context 'when a String key is used' do
2743
+
2744
+ let(:options) do
2745
+ { 'collation' => { locale: 'en_US', strength: 2 } }
2746
+ end
2747
+
2748
+ it 'raises an exception' do
2749
+ expect {
2750
+ result
2751
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2752
+ end
2753
+ end
2754
+ end
2755
+ end
2756
+
2757
+ context 'when the server selected does not support collations' do
2758
+ max_server_version '3.2'
2759
+
2760
+ it 'raises an exception' do
2761
+ expect {
2762
+ result
2763
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2764
+ end
2765
+
2766
+ context 'when a String key is used' do
2767
+
2768
+ let(:options) do
2769
+ { 'collation' => { locale: 'en_US', strength: 2 } }
2770
+ end
2771
+
2772
+ it 'raises an exception' do
2773
+ expect {
2774
+ result
2775
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
2776
+ end
2777
+ end
2778
+ end
2779
+ end
2780
+
2781
+ context 'when collation is not specified' do
2782
+
2783
+ let(:selector) do
2784
+ {name: 'BANG'}
2785
+ end
2786
+
2787
+ let(:result) do
2788
+ authorized_collection.update_many(selector, { '$set' => {other: 'doink'} })
2789
+ end
2790
+
2791
+ before do
2792
+ authorized_collection.insert_one(name: 'bang')
2793
+ authorized_collection.insert_one(name: 'baNG')
2794
+ end
2795
+
2796
+ it 'does not apply the collation' do
2797
+ expect(result.written_count).to eq(0)
2798
+ end
2799
+ end
2800
+
2801
+ context 'when a session is provided' do
2802
+
2803
+ let(:selector) do
2804
+ { name: 'BANG' }
2805
+ end
2806
+
2807
+ let(:operation) do
2808
+ authorized_collection.update_many(selector, { '$set' => {other: 'doink'} }, session: session)
2809
+ end
2810
+
2811
+ before do
2812
+ authorized_collection.insert_one(name: 'bang')
2813
+ authorized_collection.insert_one(name: 'baNG')
2814
+ end
2815
+
2816
+ let(:session) do
2817
+ authorized_client.start_session
2818
+ end
2819
+
2820
+ let(:failed_operation) do
2821
+ authorized_collection.update_many({ '$._id' => 1 }, { '$set' => {other: 'doink'} }, session: session)
2822
+ end
2823
+
2824
+ let(:client) do
2825
+ authorized_client
2826
+ end
2827
+
2828
+ it_behaves_like 'an operation using a session'
2829
+ it_behaves_like 'a failed operation using a session'
2830
+ end
2831
+
2832
+ context 'when unacknowledged writes is used with an explicit session' do
2833
+
2834
+ let(:collection_with_unacknowledged_write_concern) do
2835
+ authorized_collection.with(write: { w: 0 })
2836
+ end
2837
+
2838
+ let(:operation) do
2839
+ collection_with_unacknowledged_write_concern.update_many({a: 1}, { '$set' => {x: 1} }, session: session)
2840
+ end
2841
+
2842
+ it_behaves_like 'an explicit session with an unacknowledged write'
2843
+ end
2844
+
2845
+ context 'when unacknowledged writes is used with an implicit session' do
2846
+
2847
+ let(:collection_with_unacknowledged_write_concern) do
2848
+ client.with(write: { w: 0 })[TEST_COLL]
2849
+ end
2850
+
2851
+ let(:operation) do
2852
+ collection_with_unacknowledged_write_concern.update_many({a: 1}, {'$set' => {x: 1}})
2853
+ end
2854
+
2855
+ it_behaves_like 'an implicit session with an unacknowledged write'
2856
+ end
2857
+
2858
+ context 'when various options passed in' do
2859
+ # w: 2 requires a replica set
2860
+ require_topology :replica_set
2861
+
2862
+ # https://jira.mongodb.org/browse/RUBY-2306
2863
+ min_server_fcv '3.6'
2864
+
2865
+ before do
2866
+ collection.insert_many([{ field: 'test' }, { field: 'test2' }], session: session)
2867
+ end
2868
+
2869
+ let(:session) do
2870
+ authorized_client.start_session
2871
+ end
2872
+
2873
+ let(:collection) do
2874
+ authorized_collection.with(write_concern: {w: 1})
2875
+ end
2876
+
2877
+ let(:events) do
2878
+ subscriber.command_started_events('update')
2879
+ end
2880
+
2881
+ let!(:command) do
2882
+ Utils.get_command_event(authorized_client, 'update') do |client|
2883
+ collection.update_many(selector, {'$set'=> { field: 'testing' }}, session: session,
2884
+ write_concern: {w: 2}, bypass_document_validation: true, upsert: true)
2885
+ end.command
2886
+ end
2887
+
2888
+ it 'updates many successfully with correct options sent to server' do
2889
+ expect(events.length).to eq(1)
2890
+ expect(collection.options[:write_concern]).to eq(w: 1)
2891
+ expect(command[:writeConcern][:w]).to eq(2)
2892
+ expect(command[:bypassDocumentValidation]).to be(true)
2893
+ expect(command[:updates][0][:upsert]).to be(true)
2894
+ end
2895
+ end
2896
+ end
2897
+
2898
+ describe '#update_one' do
2899
+
2900
+ let(:selector) do
2901
+ { field: 'test1' }
2902
+ end
2903
+
2904
+ context 'when a selector was provided' do
2905
+
2906
+ before do
2907
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
2908
+ end
2909
+
2910
+ let!(:response) do
2911
+ authorized_collection.update_one(selector, '$set'=> { field: 'testing' })
2912
+ end
2913
+
2914
+ let(:updated) do
2915
+ authorized_collection.find(field: 'testing').first
2916
+ end
2917
+
2918
+ it 'updates the first matching document in the collection' do
2919
+ expect(response.modified_count).to eq(1)
2920
+ end
2921
+
2922
+ it 'updates the documents in the collection' do
2923
+ expect(updated[:field]).to eq('testing')
2924
+ end
2925
+ end
2926
+
2927
+ context 'when upsert is false' do
2928
+
2929
+ let(:response) do
2930
+ authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
2931
+ upsert: false)
2932
+ end
2933
+
2934
+ let(:updated) do
2935
+ authorized_collection.find.to_a
2936
+ end
2937
+
2938
+ it 'reports that no documents were updated' do
2939
+ expect(response.modified_count).to eq(0)
2940
+ end
2941
+
2942
+ it 'updates no documents in the collection' do
2943
+ expect(updated).to be_empty
2944
+ end
2945
+ end
2946
+
2947
+ context 'when upsert is true' do
2948
+
2949
+ let!(:response) do
2950
+ authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
2951
+ upsert: true)
2952
+ end
2953
+
2954
+ let(:updated) do
2955
+ authorized_collection.find.first
2956
+ end
2957
+
2958
+ it 'reports that a document was written' do
2959
+ expect(response.written_count).to eq(1)
2960
+ end
2961
+
2962
+ it 'inserts a document into the collection' do
2963
+ expect(updated[:field]).to eq('testing')
2964
+ end
2965
+ end
2966
+
2967
+ context 'when upsert is not specified' do
2968
+
2969
+ let(:response) do
2970
+ authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } })
2971
+ end
2972
+
2973
+ let(:updated) do
2974
+ authorized_collection.find.to_a
2975
+ end
2976
+
2977
+ it 'reports that no documents were updated' do
2978
+ expect(response.modified_count).to eq(0)
2979
+ end
2980
+
2981
+ it 'updates no documents in the collection' do
2982
+ expect(updated).to be_empty
2983
+ end
2984
+ end
2985
+
2986
+ context 'when the update fails' do
2987
+
2988
+ let(:result) do
2989
+ authorized_collection.update_one(selector, { '$s'=> { field: 'testing' } })
2990
+ end
2991
+
2992
+ it 'raises an OperationFailure' do
2993
+ expect {
2994
+ result
2995
+ }.to raise_exception(Mongo::Error::OperationFailure)
2996
+ end
2997
+ end
2998
+
2999
+ context 'when collection has a validator' do
3000
+ min_server_fcv '3.2'
3001
+
3002
+ around(:each) do |spec|
3003
+ authorized_client[:validating,
3004
+ :validator => { :a => { '$exists' => true } }].tap do |c|
3005
+ c.create
3006
+ end
3007
+ spec.run
3008
+ collection_with_validator.drop
3009
+ end
3010
+
3011
+ before do
3012
+ collection_with_validator.insert_one({ a: 1 })
3013
+ end
3014
+
3015
+ context 'when the document is valid' do
3016
+
3017
+ let(:result) do
3018
+ collection_with_validator.update_one(
3019
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
3020
+ end
3021
+
3022
+ it 'updates successfully' do
3023
+ expect(result.modified_count).to eq(1)
3024
+ end
3025
+ end
3026
+
3027
+ context 'when the document is invalid' do
3028
+
3029
+ context 'when bypass_document_validation is not set' do
3030
+
3031
+ let(:result2) do
3032
+ collection_with_validator.update_one(
3033
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
3034
+ end
3035
+
3036
+ it 'raises OperationFailure' do
3037
+ expect {
3038
+ result2
3039
+ }.to raise_exception(Mongo::Error::OperationFailure)
3040
+ end
3041
+ end
3042
+
3043
+ context 'when bypass_document_validation is true' do
3044
+
3045
+ let(:result3) do
3046
+ collection_with_validator.update_one(
3047
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
3048
+ :bypass_document_validation => true)
3049
+ end
3050
+
3051
+ it 'updates successfully' do
3052
+ expect(result3.written_count).to eq(1)
3053
+ end
3054
+ end
3055
+ end
3056
+ end
3057
+
3058
+ context 'when there is a collation specified' do
3059
+
3060
+ let(:selector) do
3061
+ { name: 'BANG' }
3062
+ end
3063
+
3064
+ let(:result) do
3065
+ authorized_collection.update_one(selector, { '$set' => { other: 'doink' } }, options)
3066
+ end
3067
+
3068
+ before do
3069
+ authorized_collection.insert_one(name: 'bang')
3070
+ end
3071
+
3072
+ let(:options) do
3073
+ { collation: { locale: 'en_US', strength: 2 } }
3074
+ end
3075
+
3076
+ context 'when the server selected supports collations' do
3077
+ min_server_fcv '3.4'
3078
+
3079
+ it 'applies the collation' do
3080
+ expect(result.written_count).to eq(1)
3081
+ expect(authorized_collection.find(other: 'doink').count).to eq(1)
3082
+ end
3083
+
3084
+ context 'when unacknowledged writes is used' do
3085
+
3086
+ let(:collection_with_unacknowledged_write_concern) do
3087
+ authorized_collection.with(write: { w: 0 })
3088
+ end
3089
+
3090
+ let(:result) do
3091
+ collection_with_unacknowledged_write_concern.update_one(selector, { '$set' => { other: 'doink' } }, options)
3092
+ end
3093
+
3094
+ it 'raises an exception' do
3095
+ expect {
3096
+ result
3097
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3098
+ end
3099
+
3100
+ context 'when a String key is used' do
3101
+
3102
+ let(:options) do
3103
+ { 'collation' => { locale: 'en_US', strength: 2 } }
3104
+ end
3105
+
3106
+ it 'raises an exception' do
3107
+ expect {
3108
+ result
3109
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3110
+ end
3111
+ end
3112
+ end
3113
+ end
3114
+
3115
+ context 'when the server selected does not support collations' do
3116
+ max_server_version '3.2'
3117
+
3118
+ it 'raises an exception' do
3119
+ expect {
3120
+ result
3121
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3122
+ end
3123
+
3124
+ context 'when a String key is used' do
3125
+
3126
+ let(:options) do
3127
+ { 'collation' => { locale: 'en_US', strength: 2 } }
3128
+ end
3129
+
3130
+ it 'raises an exception' do
3131
+ expect {
3132
+ result
3133
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3134
+ end
3135
+ end
3136
+ end
3137
+ end
3138
+
3139
+ context 'when a collation is not specified' do
3140
+
3141
+ let(:selector) do
3142
+ { name: 'BANG' }
3143
+ end
3144
+
3145
+ let(:result) do
3146
+ authorized_collection.update_one(selector, { '$set' => { other: 'doink' } })
3147
+ end
3148
+
3149
+ before do
3150
+ authorized_collection.insert_one(name: 'bang')
3151
+ end
3152
+
3153
+ it 'does not apply the collation' do
3154
+ expect(result.written_count).to eq(0)
3155
+ end
3156
+ end
3157
+
3158
+
3159
+ context 'when arrayFilters is provided' do
3160
+
3161
+ let(:selector) do
3162
+ { _id: 0}
3163
+ end
3164
+
3165
+ context 'when the server supports arrayFilters' do
3166
+ min_server_fcv '3.6'
3167
+
3168
+ before do
3169
+ authorized_collection.insert_one(_id: 0, x: [{ y: 1 }, { y: 2 }, {y: 3 }])
3170
+ end
3171
+
3172
+ let(:result) do
3173
+ authorized_collection.update_one(selector,
3174
+ { '$set' => { 'x.$[i].y' => 5 } },
3175
+ options)
3176
+ end
3177
+
3178
+ context 'when a Symbol key is used' do
3179
+
3180
+ let(:options) do
3181
+ { array_filters: [{ 'i.y' => 3 }] }
3182
+ end
3183
+
3184
+ it 'applies the arrayFilters' do
3185
+ expect(result.matched_count).to eq(1)
3186
+ expect(result.modified_count).to eq(1)
3187
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
3188
+ end
3189
+ end
3190
+
3191
+ context 'when a String key is used' do
3192
+
3193
+ let(:options) do
3194
+ { 'array_filters' => [{ 'i.y' => 3 }] }
3195
+ end
3196
+
3197
+ it 'applies the arrayFilters' do
3198
+ expect(result.matched_count).to eq(1)
3199
+ expect(result.modified_count).to eq(1)
3200
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
3201
+ end
3202
+ end
3203
+ end
3204
+
3205
+ context 'when the server does not support arrayFilters' do
3206
+ max_server_version '3.4'
3207
+
3208
+ let(:result) do
3209
+ authorized_collection.update_one(selector,
3210
+ { '$set' => { 'x.$[i].y' => 5 } },
3211
+ options)
3212
+ end
3213
+
3214
+ context 'when a Symbol key is used' do
3215
+
3216
+ let(:options) do
3217
+ { array_filters: [{ 'i.y' => 3 }] }
3218
+ end
3219
+
3220
+ it 'raises an exception' do
3221
+ expect {
3222
+ result
3223
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
3224
+ end
3225
+ end
3226
+
3227
+ context 'when a String key is used' do
3228
+
3229
+ let(:options) do
3230
+ { 'array_filters' => [{ 'i.y' => 3 }] }
3231
+ end
3232
+
3233
+ it 'raises an exception' do
3234
+ expect {
3235
+ result
3236
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
3237
+ end
3238
+ end
3239
+ end
3240
+ end
3241
+
3242
+ context 'when the documents are sent with OP_MSG' do
3243
+ min_server_fcv '3.6'
3244
+
3245
+ let(:documents) do
3246
+ [{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
3247
+ end
3248
+
3249
+ before do
3250
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
3251
+ client[TEST_COLL].update_one({ a: 1 }, {'$set' => { 'name' => '1'*16777149 }})
3252
+ end
3253
+
3254
+ let(:update_events) do
3255
+ subscriber.started_events.select { |e| e.command_name == 'update' }
3256
+ end
3257
+
3258
+ it 'sends the documents in one OP_MSG' do
3259
+ expect(update_events.size).to eq(1)
3260
+ end
3261
+ end
3262
+
3263
+ context 'when a session is provided' do
3264
+
3265
+ before do
3266
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
3267
+ end
3268
+
3269
+ let(:session) do
3270
+ authorized_client.start_session
3271
+ end
3272
+
3273
+ let(:operation) do
3274
+ authorized_collection.update_one({ field: 'test' }, { '$set'=> { field: 'testing' } }, session: session)
3275
+ end
3276
+
3277
+ let(:failed_operation) do
3278
+ authorized_collection.update_one({ '$._id' => 1 }, { '$set'=> { field: 'testing' } }, session: session)
3279
+ end
3280
+
3281
+ let(:client) do
3282
+ authorized_client
3283
+ end
3284
+
3285
+ it_behaves_like 'an operation using a session'
3286
+ it_behaves_like 'a failed operation using a session'
3287
+ end
3288
+
3289
+ context 'when unacknowledged writes is used with an explicit session' do
3290
+
3291
+ let(:collection_with_unacknowledged_write_concern) do
3292
+ authorized_collection.with(write: { w: 0 })
3293
+ end
3294
+
3295
+ let(:operation) do
3296
+ collection_with_unacknowledged_write_concern.update_one({ a: 1 }, { '$set' => { x: 1 } }, session: session)
3297
+ end
3298
+
3299
+ it_behaves_like 'an explicit session with an unacknowledged write'
3300
+ end
3301
+
3302
+ context 'when unacknowledged writes is used with an implicit session' do
3303
+
3304
+ let(:collection_with_unacknowledged_write_concern) do
3305
+ client.with(write: { w: 0 })[TEST_COLL]
3306
+ end
3307
+
3308
+ let(:operation) do
3309
+ collection_with_unacknowledged_write_concern.update_one({ a: 1 }, { '$set' => { x: 1 }})
3310
+ end
3311
+
3312
+ it_behaves_like 'an implicit session with an unacknowledged write'
3313
+ end
3314
+
3315
+ context 'when various options passed in' do
3316
+ # w: 2 requires a replica set
3317
+ require_topology :replica_set
3318
+
3319
+ # https://jira.mongodb.org/browse/RUBY-2306
3320
+ min_server_fcv '3.6'
3321
+
3322
+ before do
3323
+ collection.insert_many([{ field: 'test1' }, { field: 'test2' }], session: session)
3324
+ end
3325
+
3326
+ let(:session) do
3327
+ authorized_client.start_session
3328
+ end
3329
+
3330
+ let(:collection) do
3331
+ authorized_collection.with(write_concern: {w: 1})
3332
+ end
3333
+
3334
+ let(:events) do
3335
+ subscriber.command_started_events('update')
3336
+ end
3337
+
3338
+ let!(:command) do
3339
+ Utils.get_command_event(authorized_client, 'update') do |client|
3340
+ collection.update_one(selector, { '$set'=> { field: 'testing' } }, session: session,
3341
+ write_concern: {w: 2}, bypass_document_validation: true, :return_document => :after,
3342
+ upsert: true)
3343
+ end.command
3344
+ end
3345
+
3346
+ it 'updates one successfully with correct options sent to server' do
3347
+ expect(events.length).to eq(1)
3348
+ expect(command[:writeConcern]).to_not be_nil
3349
+ expect(command[:writeConcern][:w]).to eq(2)
3350
+ expect(collection.options[:write_concern]).to eq(w:1)
3351
+ expect(command[:bypassDocumentValidation]).to be(true)
3352
+ expect(command[:updates][0][:upsert]).to be(true)
3353
+ end
3354
+ end
3355
+ end
3356
+
3357
+ describe '#find_one_and_delete' do
3358
+
3359
+ before do
3360
+ authorized_collection.insert_many([{ field: 'test1' }])
3361
+ end
3362
+
3363
+ let(:selector) do
3364
+ { field: 'test1' }
3365
+ end
3366
+
3367
+ context 'when a matching document is found' do
3368
+
3369
+ context 'when a session is provided' do
3370
+
3371
+ let(:operation) do
3372
+ authorized_collection.find_one_and_delete(selector, session: session)
3373
+ end
3374
+
3375
+ let(:failed_operation) do
3376
+ authorized_collection.find_one_and_delete({ '$._id' => 1 }, session: session)
3377
+ end
3378
+
3379
+ let(:session) do
3380
+ authorized_client.start_session
3381
+ end
3382
+
3383
+ let(:client) do
3384
+ authorized_client
3385
+ end
3386
+
3387
+ it_behaves_like 'an operation using a session'
3388
+ it_behaves_like 'a failed operation using a session'
3389
+ end
3390
+
3391
+ context 'when no options are provided' do
3392
+
3393
+ let!(:document) do
3394
+ authorized_collection.find_one_and_delete(selector)
3395
+ end
3396
+
3397
+ it 'deletes the document from the database' do
3398
+ expect(authorized_collection.find.to_a).to be_empty
3399
+ end
3400
+
3401
+ it 'returns the document' do
3402
+ expect(document['field']).to eq('test1')
3403
+ end
3404
+ end
3405
+
3406
+ context 'when a projection is provided' do
3407
+
3408
+ let!(:document) do
3409
+ authorized_collection.find_one_and_delete(selector, projection: { _id: 1 })
3410
+ end
3411
+
3412
+ it 'deletes the document from the database' do
3413
+ expect(authorized_collection.find.to_a).to be_empty
3414
+ end
3415
+
3416
+ it 'returns the document with limited fields' do
3417
+ expect(document['field']).to be_nil
3418
+ expect(document['_id']).to_not be_nil
3419
+ end
3420
+ end
3421
+
3422
+ context 'when a sort is provided' do
3423
+
3424
+ let!(:document) do
3425
+ authorized_collection.find_one_and_delete(selector, sort: { field: 1 })
3426
+ end
3427
+
3428
+ it 'deletes the document from the database' do
3429
+ expect(authorized_collection.find.to_a).to be_empty
3430
+ end
3431
+
3432
+ it 'returns the document with limited fields' do
3433
+ expect(document['field']).to eq('test1')
3434
+ end
3435
+ end
3436
+
3437
+ context 'when max_time_ms is provided' do
3438
+
3439
+ it 'includes the max_time_ms value in the command' do
3440
+ expect {
3441
+ authorized_collection.find_one_and_delete(selector, max_time_ms: 0.1)
3442
+ }.to raise_error(Mongo::Error::OperationFailure)
3443
+ end
3444
+ end
3445
+ end
3446
+
3447
+ context 'when no matching document is found' do
3448
+
3449
+ let(:selector) do
3450
+ { field: 'test5' }
3451
+ end
3452
+
3453
+ let!(:document) do
3454
+ authorized_collection.find_one_and_delete(selector)
3455
+ end
3456
+
3457
+ it 'returns nil' do
3458
+ expect(document).to be_nil
3459
+ end
3460
+ end
3461
+
3462
+ context 'when the operation fails' do
3463
+
3464
+ let(:result) do
3465
+ authorized_collection.find_one_and_delete(selector, max_time_ms: 0.1)
3466
+ end
3467
+
3468
+ it 'raises an OperationFailure' do
3469
+ expect {
3470
+ result
3471
+ }.to raise_exception(Mongo::Error::OperationFailure)
3472
+ end
3473
+ end
3474
+
3475
+ context 'when write_concern is provided' do
3476
+ min_server_fcv '3.2'
3477
+ require_topology :single
3478
+
3479
+ it 'uses the write concern' do
3480
+ expect {
3481
+ authorized_collection.find_one_and_delete(selector,
3482
+ write_concern: { w: 2 })
3483
+ }.to raise_error(Mongo::Error::OperationFailure)
3484
+ end
3485
+ end
3486
+
3487
+ context 'when the collection has a write concern' do
3488
+ min_server_fcv '3.2'
3489
+ require_topology :single
3490
+
3491
+ let(:collection) do
3492
+ authorized_collection.with(write: { w: 2 })
3493
+ end
3494
+
3495
+ it 'uses the write concern' do
3496
+ expect {
3497
+ collection.find_one_and_delete(selector,
3498
+ write_concern: { w: 2 })
3499
+ }.to raise_error(Mongo::Error::OperationFailure)
3500
+ end
3501
+ end
3502
+
3503
+ context 'when collation is specified' do
3504
+
3505
+ let(:selector) do
3506
+ { name: 'BANG' }
3507
+ end
3508
+
3509
+ let(:result) do
3510
+ authorized_collection.find_one_and_delete(selector, options)
3511
+ end
3512
+
3513
+ before do
3514
+ authorized_collection.insert_one(name: 'bang')
3515
+ end
3516
+
3517
+ let(:options) do
3518
+ { collation: { locale: 'en_US', strength: 2 } }
3519
+ end
3520
+
3521
+ context 'when the server selected supports collations' do
3522
+ min_server_fcv '3.4'
3523
+
3524
+ it 'applies the collation' do
3525
+ expect(result['name']).to eq('bang')
3526
+ expect(authorized_collection.find(name: 'bang').count).to eq(0)
3527
+ end
3528
+ end
3529
+
3530
+ context 'when the server selected does not support collations' do
3531
+ max_server_version '3.2'
3532
+
3533
+ it 'raises an exception' do
3534
+ expect {
3535
+ result
3536
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3537
+ end
3538
+
3539
+ context 'when a String key is used' do
3540
+
3541
+ let(:options) do
3542
+ { 'collation' => { locale: 'en_US', strength: 2 } }
3543
+ end
3544
+
3545
+ it 'raises an exception' do
3546
+ expect {
3547
+ result
3548
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3549
+ end
3550
+ end
3551
+ end
3552
+ end
3553
+
3554
+ context 'when collation is not specified' do
3555
+
3556
+ let(:selector) do
3557
+ { name: 'BANG' }
3558
+ end
3559
+
3560
+ let(:result) do
3561
+ authorized_collection.find_one_and_delete(selector)
3562
+ end
3563
+
3564
+ before do
3565
+ authorized_collection.insert_one(name: 'bang')
3566
+ end
3567
+
3568
+ it 'does not apply the collation' do
3569
+ expect(result).to be_nil
3570
+ end
3571
+ end
3572
+
3573
+ context 'when various options passed in' do
3574
+ # w: 2 requires a replica set
3575
+ require_topology :replica_set
3576
+
3577
+ # https://jira.mongodb.org/browse/RUBY-2306
3578
+ min_server_fcv '3.6'
3579
+
3580
+ before do
3581
+ authorized_collection.delete_many
3582
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
3583
+ end
3584
+
3585
+ let(:collection) do
3586
+ authorized_collection.with(write_concern: {w: 2})
3587
+ end
3588
+
3589
+ let(:session) do
3590
+ authorized_client.start_session
3591
+ end
3592
+
3593
+ let!(:command) do
3594
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
3595
+ collection.find_one_and_delete(selector, session: session, write_concern: {w: 2},
3596
+ bypass_document_validation: true, max_time_ms: 300)
3597
+ end.command
3598
+ end
3599
+
3600
+ let(:events) do
3601
+ subscriber.command_started_events('findAndModify')
3602
+ end
3603
+
3604
+ it 'finds and deletes successfully with correct options sent to server' do
3605
+ expect(events.length).to eq(1)
3606
+ expect(command[:writeConcern]).to_not be_nil
3607
+ expect(command[:writeConcern][:w]).to eq(2)
3608
+ expect(command[:bypassDocumentValidation]).to eq(true)
3609
+ expect(command[:maxTimeMS]).to eq(300)
3610
+ end
3611
+ end
3612
+ end
3613
+
3614
+ describe '#find_one_and_update' do
3615
+
3616
+ let(:selector) do
3617
+ { field: 'test1' }
3618
+ end
3619
+
3620
+ before do
3621
+ authorized_collection.insert_many([{ field: 'test1' }])
3622
+ end
3623
+
3624
+ context 'when a matching document is found' do
3625
+
3626
+ context 'when no options are provided' do
3627
+
3628
+ let(:document) do
3629
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
3630
+ end
3631
+
3632
+ it 'returns the original document' do
3633
+ expect(document['field']).to eq('test1')
3634
+ end
3635
+ end
3636
+
3637
+ context 'when a session is provided' do
3638
+
3639
+ let(:operation) do
3640
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, session: session)
3641
+ end
3642
+
3643
+ let(:failed_operation) do
3644
+ authorized_collection.find_one_and_update({ '$._id' => 1 }, { '$set' => { field: 'testing' }}, session: session)
3645
+ end
3646
+
3647
+ let(:session) do
3648
+ authorized_client.start_session
3649
+ end
3650
+
3651
+ let(:client) do
3652
+ authorized_client
3653
+ end
3654
+
3655
+ it_behaves_like 'an operation using a session'
3656
+ it_behaves_like 'a failed operation using a session'
3657
+ end
3658
+
3659
+ context 'when no options are provided' do
3660
+
3661
+ let(:document) do
3662
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
3663
+ end
3664
+
3665
+ it 'returns the original document' do
3666
+ expect(document['field']).to eq('test1')
3667
+ end
3668
+ end
3669
+
3670
+ context 'when return_document options are provided' do
3671
+
3672
+ context 'when return_document is :after' do
3673
+
3674
+ let(:document) do
3675
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, :return_document => :after)
3676
+ end
3677
+
3678
+ it 'returns the new document' do
3679
+ expect(document['field']).to eq('testing')
3680
+ end
3681
+ end
3682
+
3683
+ context 'when return_document is :before' do
3684
+
3685
+ let(:document) do
3686
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, :return_document => :before)
3687
+ end
3688
+
3689
+ it 'returns the original document' do
3690
+ expect(document['field']).to eq('test1')
3691
+ end
3692
+ end
3693
+ end
3694
+
3695
+ context 'when a projection is provided' do
3696
+
3697
+ let(:document) do
3698
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, projection: { _id: 1 })
3699
+ end
3700
+
3701
+ it 'returns the document with limited fields' do
3702
+ expect(document['field']).to be_nil
3703
+ expect(document['_id']).to_not be_nil
3704
+ end
3705
+ end
3706
+
3707
+ context 'when a sort is provided' do
3708
+
3709
+ let(:document) do
3710
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, sort: { field: 1 })
3711
+ end
3712
+
3713
+ it 'returns the original document' do
3714
+ expect(document['field']).to eq('test1')
3715
+ end
3716
+ end
3717
+ end
3718
+
3719
+ context 'when max_time_ms is provided' do
3720
+
3721
+ it 'includes the max_time_ms value in the command' do
3722
+ expect {
3723
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
3724
+ }.to raise_error(Mongo::Error::OperationFailure)
3725
+ end
3726
+ end
3727
+
3728
+ context 'when no matching document is found' do
3729
+
3730
+ let(:selector) do
3731
+ { field: 'test5' }
3732
+ end
3733
+
3734
+ let(:document) do
3735
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
3736
+ end
3737
+
3738
+ it 'returns nil' do
3739
+ expect(document).to be_nil
3740
+ end
3741
+ end
3742
+
3743
+ context 'when no matching document is found' do
3744
+
3745
+ context 'when no upsert options are provided' do
3746
+
3747
+ let(:selector) do
3748
+ { field: 'test5' }
3749
+ end
3750
+
3751
+ let(:document) do
3752
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
3753
+ end
3754
+
3755
+ it 'returns nil' do
3756
+ expect(document).to be_nil
3757
+ end
3758
+ end
3759
+
3760
+ context 'when upsert options are provided' do
3761
+
3762
+ let(:selector) do
3763
+ { field: 'test5' }
3764
+ end
3765
+
3766
+ let(:document) do
3767
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, :upsert => true, :return_document => :after)
3768
+ end
3769
+
3770
+ it 'returns the new document' do
3771
+ expect(document['field']).to eq('testing')
3772
+ end
3773
+ end
3774
+ end
3775
+
3776
+ context 'when the operation fails' do
3777
+
3778
+ let(:result) do
3779
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
3780
+ end
3781
+
3782
+ it 'raises an OperationFailure' do
3783
+ expect {
3784
+ result
3785
+ }.to raise_exception(Mongo::Error::OperationFailure)
3786
+ end
3787
+ end
3788
+
3789
+ context 'when collection has a validator' do
3790
+ min_server_fcv '3.2'
3791
+
3792
+ around(:each) do |spec|
3793
+ authorized_client[:validating].drop
3794
+ authorized_client[:validating,
3795
+ :validator => { :a => { '$exists' => true } }].tap do |c|
3796
+ c.create
3797
+ end
3798
+ spec.run
3799
+ collection_with_validator.drop
3800
+ end
3801
+
3802
+ before do
3803
+ collection_with_validator.insert_one({ a: 1 })
3804
+ end
3805
+
3806
+ context 'when the document is valid' do
3807
+
3808
+ let(:result) do
3809
+ collection_with_validator.find_one_and_update(
3810
+ { a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
3811
+ end
3812
+
3813
+ it 'updates successfully' do
3814
+ expect(result['a']).to eq(2)
3815
+ end
3816
+ end
3817
+
3818
+ context 'when the document is invalid' do
3819
+
3820
+ context 'when bypass_document_validation is not set' do
3821
+
3822
+ let(:result2) do
3823
+ collection_with_validator.find_one_and_update(
3824
+ { a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
3825
+ end
3826
+
3827
+ it 'raises OperationFailure' do
3828
+ expect {
3829
+ result2
3830
+ }.to raise_exception(Mongo::Error::OperationFailure)
3831
+ end
3832
+ end
3833
+
3834
+ context 'when bypass_document_validation is true' do
3835
+
3836
+ let(:result3) do
3837
+ collection_with_validator.find_one_and_update(
3838
+ { a: 1 }, { '$unset' => { :a => '' } },
3839
+ :bypass_document_validation => true,
3840
+ :return_document => :after)
3841
+ end
3842
+
3843
+ it 'updates successfully' do
3844
+ expect(result3['a']).to be_nil
3845
+ end
3846
+ end
3847
+ end
3848
+ end
3849
+
3850
+ context 'when write_concern is provided' do
3851
+ min_server_fcv '3.2'
3852
+ require_topology :single
3853
+
3854
+ it 'uses the write concern' do
3855
+ expect {
3856
+ authorized_collection.find_one_and_update(selector,
3857
+ { '$set' => { field: 'testing' }},
3858
+ write_concern: { w: 2 })
3859
+ }.to raise_error(Mongo::Error::OperationFailure)
3860
+ end
3861
+ end
3862
+
3863
+ context 'when the collection has a write concern' do
3864
+ min_server_fcv '3.2'
3865
+ require_topology :single
3866
+
3867
+ let(:collection) do
3868
+ authorized_collection.with(write: { w: 2 })
3869
+ end
3870
+
3871
+ it 'uses the write concern' do
3872
+ expect {
3873
+ collection.find_one_and_update(selector,
3874
+ { '$set' => { field: 'testing' }},
3875
+ write_concern: { w: 2 })
3876
+ }.to raise_error(Mongo::Error::OperationFailure)
3877
+ end
3878
+ end
3879
+
3880
+ context 'when a collation is specified' do
3881
+
3882
+ let(:selector) do
3883
+ { name: 'BANG' }
3884
+ end
3885
+
3886
+ let(:result) do
3887
+ authorized_collection.find_one_and_update(selector,
3888
+ { '$set' => { other: 'doink' } },
3889
+ options)
3890
+ end
3891
+
3892
+ before do
3893
+ authorized_collection.insert_one(name: 'bang')
3894
+ end
3895
+
3896
+ let(:options) do
3897
+ { collation: { locale: 'en_US', strength: 2 } }
3898
+ end
3899
+
3900
+ context 'when the server selected supports collations' do
3901
+ min_server_fcv '3.4'
3902
+
3903
+ it 'applies the collation' do
3904
+ expect(result['name']).to eq('bang')
3905
+ expect(authorized_collection.find({ name: 'bang' }, limit: -1).first['other']).to eq('doink')
3906
+ end
3907
+ end
3908
+
3909
+ context 'when the server selected does not support collations' do
3910
+ max_server_version '3.2'
3911
+
3912
+ it 'raises an exception' do
3913
+ expect {
3914
+ result
3915
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3916
+ end
3917
+
3918
+ context 'when a String key is used' do
3919
+
3920
+ let(:options) do
3921
+ { 'collation' => { locale: 'en_US', strength: 2 } }
3922
+ end
3923
+
3924
+ it 'raises an exception' do
3925
+ expect {
3926
+ result
3927
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
3928
+ end
3929
+ end
3930
+ end
3931
+ end
3932
+
3933
+ context 'when there is no collation specified' do
3934
+
3935
+ let(:selector) do
3936
+ { name: 'BANG' }
3937
+ end
3938
+
3939
+ let(:result) do
3940
+ authorized_collection.find_one_and_update(selector, { '$set' => { other: 'doink' } })
3941
+ end
3942
+
3943
+ before do
3944
+ authorized_collection.insert_one(name: 'bang')
3945
+ end
3946
+
3947
+ it 'does not apply the collation' do
3948
+ expect(result).to be_nil
3949
+ end
3950
+ end
3951
+
3952
+ context 'when arrayFilters is provided' do
3953
+
3954
+ let(:selector) do
3955
+ { _id: 0 }
3956
+ end
3957
+
3958
+ context 'when the server supports arrayFilters' do
3959
+ min_server_fcv '3.6'
3960
+
3961
+ before do
3962
+ authorized_collection.insert_one(_id: 0, x: [{ y: 1 }, { y: 2 }, { y: 3 }])
3963
+ end
3964
+
3965
+ let(:result) do
3966
+ authorized_collection.find_one_and_update(selector,
3967
+ { '$set' => { 'x.$[i].y' => 5 } },
3968
+ options)
3969
+ end
3970
+
3971
+ context 'when a Symbol key is used' do
3972
+
3973
+ let(:options) do
3974
+ { array_filters: [{ 'i.y' => 3 }] }
3975
+ end
3976
+
3977
+
3978
+ it 'applies the arrayFilters' do
3979
+ expect(result['x']).to eq([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 3 }])
3980
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
3981
+ end
3982
+ end
3983
+
3984
+ context 'when a String key is used' do
3985
+
3986
+ let(:options) do
3987
+ { 'array_filters' => [{ 'i.y' => 3 }] }
3988
+ end
3989
+
3990
+ it 'applies the arrayFilters' do
3991
+ expect(result['x']).to eq([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 3 }])
3992
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
3993
+ end
3994
+ end
3995
+ end
3996
+
3997
+ context 'when the server selected does not support arrayFilters' do
3998
+ max_server_version '3.4'
3999
+
4000
+ let(:result) do
4001
+ authorized_collection.find_one_and_update(selector,
4002
+ { '$set' => { 'x.$[i].y' => 5 } },
4003
+ options)
4004
+ end
4005
+
4006
+ context 'when a Symbol key is used' do
4007
+
4008
+ let(:options) do
4009
+ { array_filters: [{ 'i.y' => 3 }] }
4010
+ end
4011
+
4012
+ it 'raises an exception' do
4013
+ expect {
4014
+ result
4015
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
4016
+ end
4017
+ end
4018
+
4019
+ context 'when a String key is used' do
4020
+
4021
+ let(:options) do
4022
+ { 'array_filters' => [{ 'i.y' => 3 }] }
4023
+ end
4024
+
4025
+ it 'raises an exception' do
4026
+ expect {
4027
+ result
4028
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
4029
+ end
4030
+ end
4031
+ end
4032
+ end
4033
+
4034
+ context 'when various options passed in' do
4035
+ # w: 2 requires a replica set
4036
+ require_topology :replica_set
4037
+
4038
+ # https://jira.mongodb.org/browse/RUBY-2306
4039
+ min_server_fcv '3.6'
4040
+
4041
+ let(:session) do
4042
+ authorized_client.start_session
4043
+ end
4044
+
4045
+ let(:events) do
4046
+ subscriber.command_started_events('findAndModify')
4047
+ end
4048
+
4049
+ let(:collection) do
4050
+ authorized_collection.with(write_concern: {w: 2})
4051
+ end
4052
+
4053
+ let(:selector) do
4054
+ {field: 'test1'}
4055
+ end
4056
+
4057
+ before do
4058
+ collection.insert_one({field: 'test1'}, session: session)
4059
+ end
4060
+
4061
+ let!(:command) do
4062
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
4063
+ collection.find_one_and_update(selector, { '$set' => {field: 'testing'}},
4064
+ :return_document => :after, write_concern: {w: 1}, upsert: true,
4065
+ bypass_document_validation: true, max_time_ms: 100, session: session)
4066
+ end.command
4067
+ end
4068
+
4069
+ it 'find and updates successfully with correct options sent to server' do
4070
+ expect(events.length).to eq(1)
4071
+ expect(command[:writeConcern]).to_not be_nil
4072
+ expect(command[:writeConcern][:w]).to eq(1)
4073
+ expect(command[:upsert]).to eq(true)
4074
+ expect(command[:bypassDocumentValidation]).to be(true)
4075
+ expect(command[:maxTimeMS]).to eq(100)
4076
+ end
4077
+ end
4078
+ end
4079
+
4080
+ describe '#find_one_and_replace' do
4081
+
4082
+ before do
4083
+ authorized_collection.insert_many([{ field: 'test1', other: 'sth' }])
4084
+ end
4085
+
4086
+ let(:selector) do
4087
+ { field: 'test1' }
4088
+ end
4089
+
4090
+ context 'when a matching document is found' do
4091
+
4092
+ context 'when no options are provided' do
4093
+
4094
+ let(:document) do
4095
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' })
4096
+ end
4097
+
4098
+ it 'returns the original document' do
4099
+ expect(document['field']).to eq('test1')
4100
+ end
4101
+ end
4102
+
4103
+ context 'when a session is provided' do
4104
+
4105
+ let(:operation) do
4106
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, session: session)
4107
+ end
4108
+
4109
+ let(:failed_operation) do
4110
+ authorized_collection.find_one_and_replace({ '$._id' => 1}, { field: 'testing' }, session: session)
4111
+ end
4112
+
4113
+ let(:session) do
4114
+ authorized_client.start_session
4115
+ end
4116
+
4117
+ let(:client) do
4118
+ authorized_client
4119
+ end
4120
+
4121
+ it_behaves_like 'an operation using a session'
4122
+ it_behaves_like 'a failed operation using a session'
4123
+ end
4124
+
4125
+ context 'when return_document options are provided' do
4126
+
4127
+ context 'when return_document is :after' do
4128
+
4129
+ let(:document) do
4130
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :return_document => :after)
4131
+ end
4132
+
4133
+ it 'returns the new document' do
4134
+ expect(document['field']).to eq('testing')
4135
+ end
4136
+ end
4137
+
4138
+ context 'when return_document is :before' do
4139
+
4140
+ let(:document) do
4141
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :return_document => :before)
4142
+ end
4143
+
4144
+ it 'returns the original document' do
4145
+ expect(document['field']).to eq('test1')
4146
+ end
4147
+ end
4148
+ end
4149
+
4150
+ context 'when a projection is provided' do
4151
+
4152
+ let(:document) do
4153
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, projection: { _id: 1 })
4154
+ end
4155
+
4156
+ it 'returns the document with limited fields' do
4157
+ expect(document['field']).to be_nil
4158
+ expect(document['_id']).to_not be_nil
4159
+ end
4160
+ end
4161
+
4162
+ context 'when a sort is provided' do
4163
+
4164
+ let(:document) do
4165
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :sort => { field: 1 })
4166
+ end
4167
+
4168
+ it 'returns the original document' do
4169
+ expect(document['field']).to eq('test1')
4170
+ end
4171
+ end
4172
+ end
4173
+
4174
+ context 'when no matching document is found' do
4175
+
4176
+ context 'when no upsert options are provided' do
4177
+
4178
+ let(:selector) do
4179
+ { field: 'test5' }
4180
+ end
4181
+
4182
+ let(:document) do
4183
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' })
4184
+ end
4185
+
4186
+ it 'returns nil' do
4187
+ expect(document).to be_nil
4188
+ end
4189
+ end
4190
+
4191
+ context 'when upsert options are provided' do
4192
+
4193
+ let(:selector) do
4194
+ { field: 'test5' }
4195
+ end
4196
+
4197
+ let(:document) do
4198
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :upsert => true, :return_document => :after)
4199
+ end
4200
+
4201
+ it 'returns the new document' do
4202
+ expect(document['field']).to eq('testing')
4203
+ end
4204
+ end
4205
+ end
4206
+
4207
+ context 'when max_time_ms is provided' do
4208
+
4209
+ it 'includes the max_time_ms value in the command' do
4210
+ expect {
4211
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, max_time_ms: 0.1)
4212
+ }.to raise_error(Mongo::Error::OperationFailure)
4213
+ end
4214
+ end
4215
+
4216
+ context 'when the operation fails' do
4217
+
4218
+ let(:result) do
4219
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, max_time_ms: 0.1)
4220
+ end
4221
+
4222
+ it 'raises an OperationFailure' do
4223
+ expect {
4224
+ result
4225
+ }.to raise_exception(Mongo::Error::OperationFailure)
4226
+ end
4227
+ end
4228
+
4229
+ context 'when collection has a validator' do
4230
+ min_server_fcv '3.2'
4231
+
4232
+ around(:each) do |spec|
4233
+ authorized_client[:validating].drop
4234
+ authorized_client[:validating,
4235
+ :validator => { :a => { '$exists' => true } }].tap do |c|
4236
+ c.create
4237
+ end
4238
+ spec.run
4239
+ collection_with_validator.drop
4240
+ end
4241
+
4242
+ before do
4243
+ collection_with_validator.insert_one({ a: 1 })
4244
+ end
4245
+
4246
+ context 'when the document is valid' do
4247
+
4248
+ let(:result) do
4249
+ collection_with_validator.find_one_and_replace(
4250
+ { a: 1 }, { a: 5 }, :return_document => :after)
4251
+ end
4252
+
4253
+ it 'replaces successfully when document is valid' do
4254
+ expect(result[:a]).to eq(5)
4255
+ end
4256
+ end
4257
+
4258
+ context 'when the document is invalid' do
4259
+
4260
+ context 'when bypass_document_validation is not set' do
4261
+
4262
+ let(:result2) do
4263
+ collection_with_validator.find_one_and_replace(
4264
+ { a: 1 }, { x: 5 }, :return_document => :after)
4265
+ end
4266
+
4267
+ it 'raises OperationFailure' do
4268
+ expect {
4269
+ result2
4270
+ }.to raise_exception(Mongo::Error::OperationFailure)
4271
+ end
4272
+ end
4273
+
4274
+ context 'when bypass_document_validation is true' do
4275
+
4276
+ let(:result3) do
4277
+ collection_with_validator.find_one_and_replace(
4278
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true,
4279
+ :return_document => :after)
4280
+ end
4281
+
4282
+ it 'replaces successfully' do
4283
+ expect(result3[:x]).to eq(1)
4284
+ expect(result3[:a]).to be_nil
4285
+ end
4286
+ end
4287
+ end
4288
+ end
4289
+
4290
+ context 'when write_concern is provided' do
4291
+ min_server_fcv '3.2'
4292
+ require_topology :single
4293
+
4294
+ it 'uses the write concern' do
4295
+ expect {
4296
+ authorized_collection.find_one_and_replace(selector,
4297
+ { field: 'testing' },
4298
+ write_concern: { w: 2 })
4299
+ }.to raise_error(Mongo::Error::OperationFailure)
4300
+ end
4301
+ end
4302
+
4303
+ context 'when the collection has a write concern' do
4304
+ min_server_fcv '3.2'
4305
+ require_topology :single
4306
+
4307
+ let(:collection) do
4308
+ authorized_collection.with(write: { w: 2 })
4309
+ end
4310
+
4311
+ it 'uses the write concern' do
4312
+ expect {
4313
+ collection.find_one_and_replace(selector,
4314
+ { field: 'testing' },
4315
+ write_concern: { w: 2 })
4316
+ }.to raise_error(Mongo::Error::OperationFailure)
4317
+ end
4318
+ end
4319
+
4320
+ context 'when collation is provided' do
4321
+
4322
+ let(:selector) do
4323
+ { name: 'BANG' }
4324
+ end
4325
+
4326
+ let(:result) do
4327
+ authorized_collection.find_one_and_replace(selector,
4328
+ { name: 'doink' },
4329
+ options)
4330
+ end
4331
+
4332
+ before do
4333
+ authorized_collection.insert_one(name: 'bang')
4334
+ end
4335
+
4336
+ let(:options) do
4337
+ { collation: { locale: 'en_US', strength: 2 } }
4338
+ end
4339
+
4340
+ context 'when the server selected supports collations' do
4341
+ min_server_fcv '3.4'
4342
+
4343
+ it 'applies the collation' do
4344
+ expect(result['name']).to eq('bang')
4345
+ expect(authorized_collection.find(name: 'doink').count).to eq(1)
4346
+ end
4347
+ end
4348
+
4349
+ context 'when the server selected does not support collations' do
4350
+ max_server_version '3.2'
4351
+
4352
+ it 'raises an exception' do
4353
+ expect {
4354
+ result
4355
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
4356
+ end
4357
+
4358
+ context 'when a String key is used' do
4359
+
4360
+ let(:options) do
4361
+ { 'collation' => { locale: 'en_US', strength: 2 } }
4362
+ end
4363
+
4364
+ it 'raises an exception' do
4365
+ expect {
4366
+ result
4367
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
4368
+ end
4369
+ end
4370
+ end
4371
+ end
4372
+
4373
+ context 'when collation is not specified' do
4374
+
4375
+ let(:selector) do
4376
+ { name: 'BANG' }
4377
+ end
4378
+
4379
+ let(:result) do
4380
+ authorized_collection.find_one_and_replace(selector, { name: 'doink' })
4381
+ end
4382
+
4383
+ before do
4384
+ authorized_collection.insert_one(name: 'bang')
4385
+ end
4386
+
4387
+ it 'does not apply the collation' do
4388
+ expect(result).to be_nil
4389
+ end
4390
+ end
4391
+
4392
+ context 'when various options passed in' do
4393
+ # https://jira.mongodb.org/browse/RUBY-2306
4394
+ min_server_fcv '3.6'
4395
+
4396
+ before do
4397
+ authorized_collection.insert_one({field: 'test1'})
4398
+ end
4399
+
4400
+ let(:session) do
4401
+ authorized_client.start_session
4402
+ end
4403
+
4404
+ let(:events) do
4405
+ subscriber.command_started_events('findAndModify')
4406
+ end
4407
+
4408
+ let(:collection) do
4409
+ authorized_collection.with(write_concern: { w: 2 })
4410
+ end
4411
+
4412
+ let!(:command) do
4413
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
4414
+ collection.find_one_and_replace(selector, { '$set' => {field: 'test5'}},
4415
+ :return_document => :after, write_concern: {w: 1}, session: session,
4416
+ upsert: true, bypass_document_validation: false, max_time_ms: 200)
4417
+ end.command
4418
+ end
4419
+
4420
+ it 'find and replaces successfully with correct options sent to server' do
4421
+ expect(events.length).to eq(1)
4422
+ expect(command[:writeConcern]).to_not be_nil
4423
+ expect(command[:writeConcern][:w]).to eq(1)
4424
+ expect(command[:upsert]).to be(true)
4425
+ expect(command[:bypassDocumentValidation]).to be false
4426
+ expect(command[:maxTimeMS]).to eq(200)
4427
+ end
4428
+ end
4429
+ end
4430
+
4431
+ context 'when unacknowledged writes is used on find_one_and_update' do
4432
+
4433
+ let(:selector) do
4434
+ { name: 'BANG' }
4435
+ end
4436
+
4437
+ let(:collection_with_unacknowledged_write_concern) do
4438
+ authorized_collection.with(write: { w: 0 })
4439
+ end
4440
+
4441
+ let(:result) do
4442
+ collection_with_unacknowledged_write_concern.find_one_and_update(selector,
4443
+ { '$set' => { field: 'testing' }},
4444
+ write_concern: { w: 0 })
4445
+ end
4446
+
4447
+ it 'does not raise an exception' do
4448
+ expect(result).to be_nil
4449
+ end
4450
+ end
4451
+
4452
+ context "when creating collection with view_on and pipeline" do
4453
+ before do
4454
+ authorized_client["my_view"].drop
4455
+ authorized_collection.insert_one({ bar: "here!" })
4456
+ authorized_client["my_view",
4457
+ view_on: authorized_collection.name,
4458
+ pipeline: [ { :'$project' => { "baz": "$bar" } } ]
4459
+ ].create
4460
+ end
4461
+
4462
+ it "the view has a document" do
4463
+ expect(authorized_client["my_view"].find.to_a.length).to eq(1)
4464
+ end
4465
+
4466
+ it "applies the pipeline" do
4467
+ expect(authorized_client["my_view"].find.first).to have_key("baz")
4468
+ expect(authorized_client["my_view"].find.first["baz"]).to eq("here!")
4469
+ end
4470
+ end
4471
+ end