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