mongo 2.4.1 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1703) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/CONTRIBUTING.md +12 -54
  4. data/LICENSE +1 -1
  5. data/README.md +71 -44
  6. data/Rakefile +104 -9
  7. data/lib/mongo/active_support.rb +17 -0
  8. data/lib/mongo/address/ipv4.rb +38 -8
  9. data/lib/mongo/address/ipv6.rb +61 -12
  10. data/lib/mongo/address/unix.rb +9 -6
  11. data/lib/mongo/address/validator.rb +99 -0
  12. data/lib/mongo/address.rb +160 -59
  13. data/lib/mongo/auth/aws/conversation.rb +128 -0
  14. data/lib/mongo/auth/aws/credentials_retriever.rb +219 -0
  15. data/lib/mongo/auth/aws/request.rb +283 -0
  16. data/lib/mongo/auth/aws.rb +37 -0
  17. data/lib/mongo/auth/base.rb +129 -0
  18. data/lib/mongo/auth/conversation_base.rb +52 -0
  19. data/lib/mongo/auth/cr/conversation.rb +47 -71
  20. data/lib/mongo/auth/cr.rb +14 -35
  21. data/lib/mongo/auth/credential_cache.rb +51 -0
  22. data/lib/mongo/auth/gssapi/conversation.rb +108 -0
  23. data/lib/mongo/auth/gssapi.rb +38 -0
  24. data/lib/mongo/auth/ldap/conversation.rb +22 -53
  25. data/lib/mongo/auth/ldap.rb +11 -33
  26. data/lib/mongo/auth/roles.rb +1 -1
  27. data/lib/mongo/auth/sasl_conversation_base.rb +111 -0
  28. data/lib/mongo/auth/scram/conversation.rb +10 -411
  29. data/lib/mongo/auth/scram.rb +42 -37
  30. data/lib/mongo/auth/scram256/conversation.rb +63 -0
  31. data/lib/mongo/auth/scram256.rb +31 -0
  32. data/lib/mongo/auth/scram_conversation_base.rb +402 -0
  33. data/lib/mongo/auth/stringprep/profiles/sasl.rb +74 -0
  34. data/lib/mongo/auth/stringprep/tables.rb +3233 -0
  35. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +175 -0
  36. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1171 -0
  37. data/lib/mongo/auth/stringprep.rb +115 -0
  38. data/lib/mongo/auth/user/view.rb +53 -25
  39. data/lib/mongo/auth/user.rb +73 -10
  40. data/lib/mongo/auth/x509/conversation.rb +46 -52
  41. data/lib/mongo/auth/x509.rb +26 -31
  42. data/lib/mongo/auth.rb +93 -17
  43. data/lib/mongo/background_thread.rb +159 -0
  44. data/lib/mongo/bson.rb +1 -1
  45. data/lib/mongo/bulk_write/combineable.rb +22 -5
  46. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  47. data/lib/mongo/bulk_write/result.rb +2 -2
  48. data/lib/mongo/bulk_write/result_combiner.rb +18 -8
  49. data/lib/mongo/bulk_write/transformable.rb +20 -11
  50. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  51. data/lib/mongo/bulk_write/validatable.rb +10 -2
  52. data/lib/mongo/bulk_write.rb +134 -46
  53. data/lib/mongo/caching_cursor.rb +74 -0
  54. data/lib/mongo/client.rb +1050 -113
  55. data/lib/mongo/client_encryption.rb +103 -0
  56. data/lib/mongo/cluster/periodic_executor.rb +101 -0
  57. data/lib/mongo/cluster/reapers/cursor_reaper.rb +152 -0
  58. data/lib/mongo/cluster/reapers/socket_reaper.rb +62 -0
  59. data/lib/mongo/cluster/sdam_flow.rb +603 -0
  60. data/lib/mongo/cluster/topology/base.rb +218 -0
  61. data/lib/mongo/cluster/topology/no_replica_set_options.rb +34 -0
  62. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +169 -0
  63. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +27 -0
  64. data/lib/mongo/cluster/topology/sharded.rb +13 -116
  65. data/lib/mongo/cluster/topology/single.rb +19 -113
  66. data/lib/mongo/cluster/topology/unknown.rb +11 -152
  67. data/lib/mongo/cluster/topology.rb +65 -17
  68. data/lib/mongo/cluster.rb +798 -274
  69. data/lib/mongo/cluster_time.rb +139 -0
  70. data/lib/mongo/collection/view/aggregation.rb +47 -14
  71. data/lib/mongo/collection/view/builder/aggregation.rb +39 -8
  72. data/lib/mongo/collection/view/builder/find_command.rb +56 -23
  73. data/lib/mongo/collection/view/builder/flags.rb +2 -2
  74. data/lib/mongo/collection/view/builder/map_reduce.rb +17 -6
  75. data/lib/mongo/collection/view/builder/modifiers.rb +2 -2
  76. data/lib/mongo/collection/view/builder/op_query.rb +10 -2
  77. data/lib/mongo/collection/view/builder.rb +1 -1
  78. data/lib/mongo/collection/view/change_stream/retryable.rb +40 -0
  79. data/lib/mongo/collection/view/change_stream.rb +369 -0
  80. data/lib/mongo/collection/view/explainable.rb +29 -10
  81. data/lib/mongo/collection/view/immutable.rb +2 -2
  82. data/lib/mongo/collection/view/iterable.rb +107 -24
  83. data/lib/mongo/collection/view/map_reduce.rb +65 -36
  84. data/lib/mongo/collection/view/readable.rb +211 -52
  85. data/lib/mongo/collection/view/writable.rb +283 -60
  86. data/lib/mongo/collection/view.rb +52 -28
  87. data/lib/mongo/collection.rb +324 -60
  88. data/lib/mongo/crypt/auto_decryption_context.rb +40 -0
  89. data/lib/mongo/crypt/auto_encrypter.rb +179 -0
  90. data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
  91. data/lib/mongo/crypt/binary.rb +155 -0
  92. data/lib/mongo/crypt/binding.rb +1229 -0
  93. data/lib/mongo/crypt/context.rb +135 -0
  94. data/lib/mongo/crypt/data_key_context.rb +162 -0
  95. data/lib/mongo/crypt/encryption_io.rb +306 -0
  96. data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
  97. data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
  98. data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
  99. data/lib/mongo/crypt/handle.rb +315 -0
  100. data/lib/mongo/crypt/hooks.rb +90 -0
  101. data/lib/mongo/crypt/kms_context.rb +67 -0
  102. data/lib/mongo/crypt/status.rb +131 -0
  103. data/lib/mongo/crypt.rb +33 -0
  104. data/lib/mongo/cursor/builder/get_more_command.rb +9 -4
  105. data/lib/mongo/cursor/builder/kill_cursors_command.rb +24 -6
  106. data/lib/mongo/cursor/builder/op_get_more.rb +4 -4
  107. data/lib/mongo/cursor/builder/op_kill_cursors.rb +26 -7
  108. data/lib/mongo/cursor/builder.rb +1 -1
  109. data/lib/mongo/cursor.rb +226 -44
  110. data/lib/mongo/database/view.rb +104 -26
  111. data/lib/mongo/database.rb +214 -31
  112. data/lib/mongo/dbref.rb +10 -3
  113. data/lib/mongo/distinguishing_semaphore.rb +55 -0
  114. data/lib/mongo/error/auth_error.rb +29 -0
  115. data/lib/mongo/error/bulk_write_error.rb +20 -2
  116. data/lib/mongo/error/change_stream_resumable.rb +37 -0
  117. data/lib/mongo/error/closed_stream.rb +1 -1
  118. data/lib/mongo/error/connection_check_out_timeout.rb +48 -0
  119. data/lib/mongo/error/connection_perished.rb +23 -0
  120. data/lib/mongo/error/credential_check_error.rb +26 -0
  121. data/lib/mongo/error/crypt_error.rb +31 -0
  122. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  123. data/lib/mongo/error/failed_string_prep_validation.rb +38 -0
  124. data/lib/mongo/error/file_not_found.rb +1 -1
  125. data/lib/mongo/error/handshake_error.rb +24 -0
  126. data/lib/mongo/error/insufficient_iteration_count.rb +38 -0
  127. data/lib/mongo/error/invalid_address.rb +24 -0
  128. data/lib/mongo/error/invalid_application_name.rb +1 -1
  129. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  130. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  131. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  132. data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
  133. data/lib/mongo/error/invalid_database_name.rb +1 -1
  134. data/lib/mongo/error/invalid_document.rb +1 -1
  135. data/lib/mongo/error/invalid_file.rb +1 -1
  136. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  137. data/lib/mongo/error/invalid_min_pool_size.rb +35 -0
  138. data/lib/mongo/error/invalid_nonce.rb +2 -2
  139. data/lib/mongo/error/invalid_read_concern.rb +28 -0
  140. data/lib/mongo/error/invalid_read_option.rb +35 -0
  141. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  142. data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
  143. data/lib/mongo/error/invalid_server_auth_response.rb +23 -0
  144. data/lib/mongo/error/invalid_server_preference.rb +7 -1
  145. data/lib/mongo/error/invalid_session.rb +37 -0
  146. data/lib/mongo/error/invalid_signature.rb +1 -1
  147. data/lib/mongo/error/invalid_transaction_operation.rb +82 -0
  148. data/lib/mongo/error/invalid_txt_record.rb +27 -0
  149. data/lib/mongo/error/invalid_update_document.rb +1 -1
  150. data/lib/mongo/error/invalid_uri.rb +8 -7
  151. data/lib/mongo/error/invalid_write_concern.rb +3 -3
  152. data/lib/mongo/error/kms_error.rb +22 -0
  153. data/lib/mongo/error/lint_error.rb +35 -0
  154. data/lib/mongo/error/max_bson_size.rb +15 -4
  155. data/lib/mongo/error/max_message_size.rb +1 -1
  156. data/lib/mongo/error/mismatched_domain.rb +27 -0
  157. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  158. data/lib/mongo/error/missing_password.rb +29 -0
  159. data/lib/mongo/error/missing_resume_token.rb +39 -0
  160. data/lib/mongo/error/missing_scram_server_signature.rb +27 -0
  161. data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
  162. data/lib/mongo/error/multi_index_drop.rb +1 -1
  163. data/lib/mongo/error/need_primary_server.rb +1 -1
  164. data/lib/mongo/error/no_server_available.rb +14 -5
  165. data/lib/mongo/error/no_srv_records.rb +26 -0
  166. data/lib/mongo/error/notable.rb +80 -0
  167. data/lib/mongo/error/operation_failure.rb +244 -13
  168. data/lib/mongo/error/parser.rb +156 -7
  169. data/lib/mongo/error/pool_closed_error.rb +50 -0
  170. data/lib/mongo/error/raise_original_error.rb +29 -0
  171. data/lib/mongo/error/sdam_error_detection.rb +72 -0
  172. data/lib/mongo/error/server_certificate_revoked.rb +22 -0
  173. data/lib/mongo/error/session_ended.rb +27 -0
  174. data/lib/mongo/error/sessions_not_supported.rb +35 -0
  175. data/lib/mongo/error/socket_error.rb +5 -2
  176. data/lib/mongo/error/socket_timeout_error.rb +5 -2
  177. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  178. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  179. data/lib/mongo/error/unexpected_response.rb +1 -1
  180. data/lib/mongo/error/unknown_payload_type.rb +41 -0
  181. data/lib/mongo/error/unsupported_array_filters.rb +56 -0
  182. data/lib/mongo/error/unsupported_collation.rb +7 -2
  183. data/lib/mongo/error/unsupported_features.rb +1 -19
  184. data/lib/mongo/error/unsupported_message_type.rb +23 -0
  185. data/lib/mongo/error/unsupported_option.rb +101 -0
  186. data/lib/mongo/error/write_retryable.rb +27 -0
  187. data/lib/mongo/error.rb +130 -1
  188. data/lib/mongo/event/base.rb +42 -0
  189. data/lib/mongo/event/listeners.rb +1 -1
  190. data/lib/mongo/event/publisher.rb +1 -1
  191. data/lib/mongo/event/subscriber.rb +1 -1
  192. data/lib/mongo/event.rb +10 -11
  193. data/lib/mongo/grid/file/chunk.rb +6 -6
  194. data/lib/mongo/grid/file/info.rb +35 -5
  195. data/lib/mongo/grid/file.rb +6 -1
  196. data/lib/mongo/grid/fs_bucket.rb +76 -34
  197. data/lib/mongo/grid/stream/read.rb +47 -24
  198. data/lib/mongo/grid/stream/write.rb +34 -12
  199. data/lib/mongo/grid/stream.rb +1 -1
  200. data/lib/mongo/grid.rb +1 -1
  201. data/lib/mongo/id.rb +64 -0
  202. data/lib/mongo/index/view.rb +98 -34
  203. data/lib/mongo/index.rb +2 -1
  204. data/lib/mongo/lint.rb +102 -0
  205. data/lib/mongo/loggable.rb +6 -2
  206. data/lib/mongo/logger.rb +4 -6
  207. data/lib/mongo/monitoring/cmap_log_subscriber.rb +53 -0
  208. data/lib/mongo/monitoring/command_log_subscriber.rb +22 -5
  209. data/lib/mongo/monitoring/event/cmap/base.rb +28 -0
  210. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +85 -0
  211. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +56 -0
  212. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +71 -0
  213. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +72 -0
  214. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +103 -0
  215. data/lib/mongo/monitoring/event/cmap/connection_created.rb +64 -0
  216. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +64 -0
  217. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +57 -0
  218. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +65 -0
  219. data/lib/mongo/monitoring/event/cmap/pool_created.rb +72 -0
  220. data/lib/mongo/monitoring/event/cmap.rb +25 -0
  221. data/lib/mongo/monitoring/event/command_failed.rb +30 -6
  222. data/lib/mongo/monitoring/event/command_started.rb +82 -6
  223. data/lib/mongo/monitoring/event/command_succeeded.rb +16 -3
  224. data/lib/mongo/monitoring/event/secure.rb +23 -3
  225. data/lib/mongo/monitoring/event/server_closed.rb +15 -2
  226. data/lib/mongo/monitoring/event/server_description_changed.rb +41 -3
  227. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +78 -0
  228. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +62 -0
  229. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +70 -0
  230. data/lib/mongo/monitoring/event/server_opening.rb +15 -2
  231. data/lib/mongo/monitoring/event/topology_changed.rb +16 -2
  232. data/lib/mongo/monitoring/event/topology_closed.rb +15 -2
  233. data/lib/mongo/monitoring/event/topology_opening.rb +15 -2
  234. data/lib/mongo/monitoring/event.rb +6 -1
  235. data/lib/mongo/monitoring/publishable.rb +27 -45
  236. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  237. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  238. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +10 -2
  239. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  240. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +5 -5
  241. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +30 -0
  242. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +2 -2
  243. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +62 -0
  244. data/lib/mongo/monitoring.rb +198 -67
  245. data/lib/mongo/operation/aggregate/command.rb +44 -0
  246. data/lib/mongo/operation/aggregate/op_msg.rb +31 -0
  247. data/lib/mongo/operation/aggregate/result.rb +101 -0
  248. data/lib/mongo/operation/aggregate.rb +36 -0
  249. data/lib/mongo/operation/collections_info/command.rb +45 -0
  250. data/lib/mongo/operation/collections_info/result.rb +56 -0
  251. data/lib/mongo/operation/collections_info.rb +31 -0
  252. data/lib/mongo/operation/command/command.rb +38 -0
  253. data/lib/mongo/operation/command/op_msg.rb +28 -0
  254. data/lib/mongo/operation/command.rb +31 -0
  255. data/lib/mongo/operation/count/command.rb +38 -0
  256. data/lib/mongo/operation/count/op_msg.rb +29 -0
  257. data/lib/mongo/operation/count.rb +31 -0
  258. data/lib/mongo/operation/create/command.rb +38 -0
  259. data/lib/mongo/operation/create/op_msg.rb +29 -0
  260. data/lib/mongo/operation/create.rb +31 -0
  261. data/lib/mongo/operation/create_index/command.rb +42 -0
  262. data/lib/mongo/operation/create_index/op_msg.rb +38 -0
  263. data/lib/mongo/operation/create_index.rb +31 -0
  264. data/lib/mongo/operation/create_user/command.rb +43 -0
  265. data/lib/mongo/operation/create_user/op_msg.rb +35 -0
  266. data/lib/mongo/operation/create_user.rb +31 -0
  267. data/lib/mongo/operation/delete/bulk_result.rb +48 -0
  268. data/lib/mongo/operation/delete/command.rb +46 -0
  269. data/lib/mongo/operation/delete/legacy.rb +54 -0
  270. data/lib/mongo/operation/delete/op_msg.rb +45 -0
  271. data/lib/mongo/operation/delete/result.rb +45 -0
  272. data/lib/mongo/operation/delete.rb +38 -0
  273. data/lib/mongo/operation/distinct/command.rb +38 -0
  274. data/lib/mongo/operation/distinct/op_msg.rb +30 -0
  275. data/lib/mongo/operation/distinct.rb +31 -0
  276. data/lib/mongo/operation/drop/command.rb +38 -0
  277. data/lib/mongo/operation/drop/op_msg.rb +29 -0
  278. data/lib/mongo/operation/drop.rb +31 -0
  279. data/lib/mongo/operation/drop_database/command.rb +38 -0
  280. data/lib/mongo/operation/drop_database/op_msg.rb +29 -0
  281. data/lib/mongo/operation/drop_database.rb +31 -0
  282. data/lib/mongo/operation/drop_index/command.rb +42 -0
  283. data/lib/mongo/operation/drop_index/op_msg.rb +35 -0
  284. data/lib/mongo/operation/drop_index.rb +31 -0
  285. data/lib/mongo/operation/explain/command.rb +43 -0
  286. data/lib/mongo/operation/explain/legacy.rb +42 -0
  287. data/lib/mongo/operation/explain/op_msg.rb +37 -0
  288. data/lib/mongo/operation/explain/result.rb +53 -0
  289. data/lib/mongo/operation/explain.rb +33 -0
  290. data/lib/mongo/operation/find/command.rb +39 -0
  291. data/lib/mongo/operation/find/legacy/result.rb +43 -0
  292. data/lib/mongo/operation/find/legacy.rb +40 -0
  293. data/lib/mongo/operation/find/op_msg.rb +31 -0
  294. data/lib/mongo/operation/find/result.rb +73 -0
  295. data/lib/mongo/operation/find.rb +33 -0
  296. data/lib/mongo/operation/get_more/command.rb +39 -0
  297. data/lib/mongo/operation/get_more/legacy.rb +36 -0
  298. data/lib/mongo/operation/get_more/op_msg.rb +30 -0
  299. data/lib/mongo/operation/get_more/result.rb +72 -0
  300. data/lib/mongo/operation/get_more.rb +33 -0
  301. data/lib/mongo/operation/indexes/command.rb +39 -0
  302. data/lib/mongo/operation/indexes/legacy.rb +45 -0
  303. data/lib/mongo/operation/indexes/op_msg.rb +31 -0
  304. data/lib/mongo/operation/indexes/result.rb +102 -0
  305. data/lib/mongo/operation/indexes.rb +33 -0
  306. data/lib/mongo/operation/insert/bulk_result.rb +109 -0
  307. data/lib/mongo/operation/insert/command.rb +56 -0
  308. data/lib/mongo/operation/insert/legacy.rb +65 -0
  309. data/lib/mongo/operation/insert/op_msg.rb +51 -0
  310. data/lib/mongo/operation/insert/result.rb +72 -0
  311. data/lib/mongo/operation/insert.rb +41 -0
  312. data/lib/mongo/operation/kill_cursors/command.rb +37 -0
  313. data/lib/mongo/operation/kill_cursors/legacy.rb +37 -0
  314. data/lib/mongo/operation/kill_cursors/op_msg.rb +29 -0
  315. data/lib/mongo/operation/kill_cursors.rb +8 -16
  316. data/lib/mongo/operation/list_collections/command.rb +43 -0
  317. data/lib/mongo/operation/list_collections/op_msg.rb +36 -0
  318. data/lib/mongo/operation/list_collections/result.rb +107 -0
  319. data/lib/mongo/operation/list_collections.rb +32 -0
  320. data/lib/mongo/operation/map_reduce/command.rb +40 -0
  321. data/lib/mongo/operation/map_reduce/op_msg.rb +31 -0
  322. data/lib/mongo/operation/map_reduce/result.rb +139 -0
  323. data/lib/mongo/operation/map_reduce.rb +32 -0
  324. data/lib/mongo/operation/op_msg_base.rb +30 -0
  325. data/lib/mongo/operation/parallel_scan/command.rb +55 -0
  326. data/lib/mongo/operation/parallel_scan/op_msg.rb +43 -0
  327. data/lib/mongo/operation/parallel_scan/result.rb +65 -0
  328. data/lib/mongo/operation/parallel_scan.rb +32 -0
  329. data/lib/mongo/operation/remove_user/command.rb +43 -0
  330. data/lib/mongo/operation/remove_user/op_msg.rb +35 -0
  331. data/lib/mongo/operation/remove_user.rb +31 -0
  332. data/lib/mongo/operation/result.rb +190 -39
  333. data/lib/mongo/operation/shared/bypass_document_validation.rb +43 -0
  334. data/lib/mongo/operation/shared/causal_consistency_supported.rb +42 -0
  335. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +58 -0
  336. data/lib/mongo/operation/shared/executable.rb +106 -0
  337. data/lib/mongo/operation/shared/executable_no_validate.rb +29 -0
  338. data/lib/mongo/operation/shared/executable_transaction_label.rb +27 -0
  339. data/lib/mongo/operation/shared/idable.rb +65 -0
  340. data/lib/mongo/operation/shared/limited.rb +39 -0
  341. data/lib/mongo/operation/shared/object_id_generator.rb +37 -0
  342. data/lib/mongo/operation/shared/op_msg_or_command.rb +44 -0
  343. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +47 -0
  344. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +47 -0
  345. data/lib/mongo/operation/shared/polymorphic_lookup.rb +33 -0
  346. data/lib/mongo/operation/shared/polymorphic_result.rb +47 -0
  347. data/lib/mongo/operation/shared/read_preference_supported.rb +109 -0
  348. data/lib/mongo/operation/shared/response_handling.rb +169 -0
  349. data/lib/mongo/operation/shared/result/aggregatable.rb +71 -0
  350. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +29 -0
  351. data/lib/mongo/operation/shared/sessions_supported.rb +239 -0
  352. data/lib/mongo/operation/shared/specifiable.rb +582 -0
  353. data/lib/mongo/operation/shared/write.rb +97 -0
  354. data/lib/mongo/operation/shared/write_concern_supported.rb +40 -0
  355. data/lib/mongo/operation/update/bulk_result.rb +126 -0
  356. data/lib/mongo/operation/update/command.rb +47 -0
  357. data/lib/mongo/operation/update/legacy/result.rb +109 -0
  358. data/lib/mongo/operation/update/legacy.rb +65 -0
  359. data/lib/mongo/operation/update/op_msg.rb +45 -0
  360. data/lib/mongo/operation/update/result.rb +110 -0
  361. data/lib/mongo/operation/update.rb +38 -0
  362. data/lib/mongo/operation/update_user/command.rb +42 -0
  363. data/lib/mongo/operation/update_user/op_msg.rb +35 -0
  364. data/lib/mongo/operation/update_user.rb +31 -0
  365. data/lib/mongo/operation/users_info/command.rb +43 -0
  366. data/lib/mongo/operation/users_info/op_msg.rb +36 -0
  367. data/lib/mongo/operation/users_info/result.rb +45 -0
  368. data/lib/mongo/operation/users_info.rb +32 -0
  369. data/lib/mongo/operation.rb +65 -22
  370. data/lib/mongo/options/mapper.rb +10 -3
  371. data/lib/mongo/options/redacted.rb +1 -1
  372. data/lib/mongo/options.rb +1 -1
  373. data/lib/mongo/protocol/bit_vector.rb +5 -4
  374. data/lib/mongo/protocol/compressed.rb +135 -0
  375. data/lib/mongo/protocol/delete.rb +9 -7
  376. data/lib/mongo/protocol/get_more.rb +17 -14
  377. data/lib/mongo/protocol/insert.rb +12 -8
  378. data/lib/mongo/protocol/kill_cursors.rb +15 -20
  379. data/lib/mongo/protocol/message.rb +166 -27
  380. data/lib/mongo/protocol/msg.rb +381 -0
  381. data/lib/mongo/protocol/query.rb +65 -10
  382. data/lib/mongo/protocol/registry.rb +76 -0
  383. data/lib/mongo/protocol/reply.rb +20 -15
  384. data/lib/mongo/protocol/serializers.rb +280 -12
  385. data/lib/mongo/protocol/update.rb +15 -9
  386. data/lib/mongo/protocol.rb +3 -0
  387. data/lib/mongo/query_cache.rb +242 -0
  388. data/lib/mongo/retryable.rb +411 -47
  389. data/lib/mongo/semaphore.rb +46 -0
  390. data/lib/mongo/server/app_metadata.rb +211 -0
  391. data/lib/mongo/server/connection.rb +223 -109
  392. data/lib/mongo/server/connection_base.rb +250 -0
  393. data/lib/mongo/server/connection_common.rb +135 -0
  394. data/lib/mongo/server/connection_pool/populator.rb +58 -0
  395. data/lib/mongo/server/connection_pool.rb +717 -58
  396. data/lib/mongo/server/context.rb +13 -13
  397. data/lib/mongo/server/description/features.rb +71 -14
  398. data/lib/mongo/server/description.rb +257 -70
  399. data/lib/mongo/server/monitor/app_metadata.rb +34 -0
  400. data/lib/mongo/server/monitor/connection.rb +177 -66
  401. data/lib/mongo/server/monitor.rb +232 -93
  402. data/lib/mongo/server/pending_connection.rb +255 -0
  403. data/lib/mongo/server/push_monitor/connection.rb +28 -0
  404. data/lib/mongo/server/push_monitor.rb +173 -0
  405. data/lib/mongo/server/round_trip_time_averager.rb +73 -0
  406. data/lib/mongo/server.rb +365 -54
  407. data/lib/mongo/server_selector/base.rb +622 -0
  408. data/lib/mongo/server_selector/nearest.rb +31 -20
  409. data/lib/mongo/server_selector/primary.rb +30 -14
  410. data/lib/mongo/server_selector/primary_preferred.rb +37 -24
  411. data/lib/mongo/server_selector/secondary.rb +31 -20
  412. data/lib/mongo/server_selector/secondary_preferred.rb +37 -22
  413. data/lib/mongo/server_selector.rb +14 -3
  414. data/lib/mongo/session/server_session.rb +119 -0
  415. data/lib/mongo/session/session_pool.rb +150 -0
  416. data/lib/mongo/session.rb +1067 -0
  417. data/lib/mongo/socket/ocsp_cache.rb +97 -0
  418. data/lib/mongo/socket/ocsp_verifier.rb +368 -0
  419. data/lib/mongo/socket/ssl.rb +278 -67
  420. data/lib/mongo/socket/tcp.rb +45 -32
  421. data/lib/mongo/socket/unix.rb +21 -34
  422. data/lib/mongo/socket.rb +273 -49
  423. data/lib/mongo/srv/monitor.rb +121 -0
  424. data/lib/mongo/srv/resolver.rb +134 -0
  425. data/lib/mongo/srv/result.rb +125 -0
  426. data/lib/mongo/srv.rb +17 -0
  427. data/lib/mongo/timeout.rb +51 -0
  428. data/lib/mongo/topology_version.rb +89 -0
  429. data/lib/mongo/uri/options_mapper.rb +582 -0
  430. data/lib/mongo/uri/srv_protocol.rb +238 -0
  431. data/lib/mongo/uri.rb +269 -320
  432. data/lib/mongo/utils.rb +73 -0
  433. data/lib/mongo/version.rb +2 -2
  434. data/lib/mongo/write_concern/acknowledged.rb +14 -4
  435. data/lib/mongo/write_concern/base.rb +67 -0
  436. data/lib/mongo/write_concern/unacknowledged.rb +14 -4
  437. data/lib/mongo/write_concern.rb +16 -35
  438. data/lib/mongo.rb +43 -5
  439. data/mongo.gemspec +14 -6
  440. data/spec/NOTES.aws-auth.md +296 -0
  441. data/spec/README.aws-auth.md +318 -0
  442. data/spec/README.md +692 -0
  443. data/spec/USERS.md +72 -0
  444. data/spec/atlas/atlas_connectivity_spec.rb +24 -0
  445. data/spec/atlas/operations_spec.rb +25 -0
  446. data/spec/integration/auth_spec.rb +266 -0
  447. data/spec/integration/awaited_ismaster_spec.rb +28 -0
  448. data/spec/integration/aws_auth_request_spec.rb +74 -0
  449. data/spec/integration/aws_credentials_retriever_spec.rb +103 -0
  450. data/spec/integration/bson_symbol_spec.rb +36 -0
  451. data/spec/integration/bulk_insert_spec.rb +80 -0
  452. data/spec/integration/bulk_write_spec.rb +67 -0
  453. data/spec/integration/change_stream_examples_spec.rb +205 -0
  454. data/spec/integration/change_stream_spec.rb +805 -0
  455. data/spec/integration/check_clean_slate_spec.rb +16 -0
  456. data/spec/integration/client_authentication_options_spec.rb +501 -0
  457. data/spec/integration/client_connectivity_spec.rb +38 -0
  458. data/spec/integration/client_construction_aws_auth_spec.rb +191 -0
  459. data/spec/integration/client_construction_spec.rb +236 -0
  460. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +357 -0
  461. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +303 -0
  462. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +72 -0
  463. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +79 -0
  464. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +221 -0
  465. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +601 -0
  466. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +187 -0
  467. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +78 -0
  468. data/spec/integration/client_side_encryption/client_close_spec.rb +63 -0
  469. data/spec/integration/client_side_encryption/corpus_spec.rb +233 -0
  470. data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
  471. data/spec/integration/client_side_encryption/data_key_spec.rb +165 -0
  472. data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
  473. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +141 -0
  474. data/spec/integration/client_side_encryption/views_spec.rb +44 -0
  475. data/spec/integration/client_spec.rb +44 -0
  476. data/spec/integration/client_update_spec.rb +154 -0
  477. data/spec/integration/collection_indexes_prose_spec.rb +55 -0
  478. data/spec/integration/command_monitoring_spec.rb +146 -0
  479. data/spec/integration/command_spec.rb +176 -0
  480. data/spec/integration/connect_single_rs_name_spec.rb +72 -0
  481. data/spec/integration/connection_pool_populator_spec.rb +302 -0
  482. data/spec/integration/connection_spec.rb +331 -0
  483. data/spec/integration/crud_spec.rb +162 -0
  484. data/spec/integration/cursor_reaping_spec.rb +136 -0
  485. data/spec/integration/docs_examples_spec.rb +197 -0
  486. data/spec/integration/error_detection_spec.rb +39 -0
  487. data/spec/integration/fork_reconnect_spec.rb +198 -0
  488. data/spec/integration/get_more_spec.rb +39 -0
  489. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  490. data/spec/integration/heartbeat_events_spec.rb +99 -0
  491. data/spec/integration/mmapv1_spec.rb +28 -0
  492. data/spec/integration/mongos_pinning_spec.rb +34 -0
  493. data/spec/integration/ocsp_connectivity_spec.rb +26 -0
  494. data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
  495. data/spec/integration/ocsp_verifier_spec.rb +334 -0
  496. data/spec/integration/operation_failure_code_spec.rb +26 -0
  497. data/spec/integration/query_cache_spec.rb +1045 -0
  498. data/spec/integration/query_cache_transactions_spec.rb +190 -0
  499. data/spec/integration/read_concern_spec.rb +89 -0
  500. data/spec/integration/read_preference_spec.rb +541 -0
  501. data/spec/integration/reconnect_spec.rb +174 -0
  502. data/spec/integration/retryable_errors_spec.rb +283 -0
  503. data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +761 -0
  504. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +402 -0
  505. data/spec/integration/retryable_writes/shared/adds_diagnostics.rb +15 -0
  506. data/spec/integration/retryable_writes/shared/does_not_support_retries.rb +24 -0
  507. data/spec/integration/retryable_writes/shared/only_supports_legacy_retries.rb +25 -0
  508. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +217 -0
  509. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +232 -0
  510. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +110 -0
  511. data/spec/integration/retryable_writes/shared/supports_legacy_retries.rb +19 -0
  512. data/spec/integration/retryable_writes/shared/supports_modern_retries.rb +25 -0
  513. data/spec/integration/retryable_writes/shared/supports_retries.rb +16 -0
  514. data/spec/integration/retryable_writes_errors_spec.rb +31 -0
  515. data/spec/integration/sdam_error_handling_spec.rb +421 -0
  516. data/spec/integration/sdam_events_spec.rb +118 -0
  517. data/spec/integration/sdam_prose_spec.rb +64 -0
  518. data/spec/integration/server_description_spec.rb +45 -0
  519. data/spec/integration/server_monitor_spec.rb +52 -0
  520. data/spec/integration/server_selection_spec.rb +36 -0
  521. data/spec/integration/server_selector_spec.rb +85 -0
  522. data/spec/integration/server_spec.rb +64 -0
  523. data/spec/integration/shell_examples_spec.rb +981 -0
  524. data/spec/integration/size_limit_spec.rb +112 -0
  525. data/spec/integration/srv_monitoring_spec.rb +403 -0
  526. data/spec/integration/srv_spec.rb +56 -0
  527. data/spec/integration/ssl_uri_options_spec.rb +25 -0
  528. data/spec/integration/step_down_spec.rb +204 -0
  529. data/spec/integration/time_zone_querying_spec.rb +52 -0
  530. data/spec/integration/transactions_api_examples_spec.rb +59 -0
  531. data/spec/integration/transactions_examples_spec.rb +226 -0
  532. data/spec/integration/x509_auth_spec.rb +109 -0
  533. data/spec/integration/zlib_compression_spec.rb +25 -0
  534. data/spec/kerberos/kerberos_spec.rb +91 -0
  535. data/spec/lite_spec_helper.rb +158 -0
  536. data/spec/mongo/address/ipv4_spec.rb +5 -1
  537. data/spec/mongo/address/ipv6_spec.rb +33 -1
  538. data/spec/mongo/address/unix_spec.rb +1 -1
  539. data/spec/mongo/address/validator_spec.rb +51 -0
  540. data/spec/mongo/address_spec.rb +113 -7
  541. data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
  542. data/spec/mongo/auth/aws/request_spec.rb +76 -0
  543. data/spec/mongo/auth/cr_spec.rb +30 -32
  544. data/spec/mongo/auth/gssapi/conversation_spec.rb +121 -0
  545. data/spec/mongo/auth/invalid_mechanism_spec.rb +11 -0
  546. data/spec/mongo/auth/ldap/conversation_spec.rb +2 -2
  547. data/spec/mongo/auth/ldap_spec.rb +11 -30
  548. data/spec/mongo/auth/scram/conversation_spec.rb +63 -58
  549. data/spec/mongo/auth/scram256/conversation_spec.rb +171 -0
  550. data/spec/mongo/auth/scram_negotiation_spec.rb +528 -0
  551. data/spec/mongo/auth/scram_spec.rb +92 -47
  552. data/spec/mongo/auth/stringprep/profiles/sasl_spec.rb +113 -0
  553. data/spec/mongo/auth/stringprep_spec.rb +188 -0
  554. data/spec/mongo/auth/user/view_spec.rb +401 -70
  555. data/spec/mongo/auth/user_spec.rb +162 -12
  556. data/spec/mongo/auth/x509/conversation_spec.rb +2 -2
  557. data/spec/mongo/auth/x509_spec.rb +40 -29
  558. data/spec/mongo/auth_spec.rb +4 -4
  559. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
  560. data/spec/mongo/bulk_write/result_spec.rb +124 -0
  561. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
  562. data/spec/mongo/bulk_write_spec.rb +803 -236
  563. data/spec/mongo/caching_cursor_spec.rb +70 -0
  564. data/spec/mongo/client_construction_spec.rb +2210 -0
  565. data/spec/mongo/client_encryption_spec.rb +411 -0
  566. data/spec/mongo/client_spec.rb +492 -431
  567. data/spec/mongo/cluster/cursor_reaper_spec.rb +40 -69
  568. data/spec/mongo/cluster/periodic_executor_spec.rb +16 -0
  569. data/spec/mongo/cluster/socket_reaper_spec.rb +43 -0
  570. data/spec/mongo/cluster/topology/replica_set_spec.rb +247 -226
  571. data/spec/mongo/cluster/topology/sharded_spec.rb +56 -55
  572. data/spec/mongo/cluster/topology/single_spec.rb +91 -31
  573. data/spec/mongo/cluster/topology/unknown_spec.rb +30 -115
  574. data/spec/mongo/cluster/topology_spec.rb +132 -19
  575. data/spec/mongo/cluster_spec.rb +447 -159
  576. data/spec/mongo/cluster_time_spec.rb +148 -0
  577. data/spec/mongo/collection/view/aggregation_spec.rb +143 -41
  578. data/spec/mongo/collection/view/builder/find_command_spec.rb +76 -10
  579. data/spec/mongo/collection/view/change_stream_resume_spec.rb +392 -0
  580. data/spec/mongo/collection/view/change_stream_spec.rb +531 -0
  581. data/spec/mongo/collection/view/explainable_spec.rb +88 -5
  582. data/spec/mongo/collection/view/immutable_spec.rb +1 -1
  583. data/spec/mongo/collection/view/iterable_spec.rb +38 -0
  584. data/spec/mongo/collection/view/map_reduce_spec.rb +253 -32
  585. data/spec/mongo/collection/view/readable_spec.rb +125 -60
  586. data/spec/mongo/collection/view/writable_spec.rb +273 -34
  587. data/spec/mongo/collection/view_spec.rb +10 -9
  588. data/spec/mongo/collection_spec.rb +2533 -232
  589. data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
  590. data/spec/mongo/crypt/auto_encrypter_spec.rb +187 -0
  591. data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
  592. data/spec/mongo/crypt/binary_spec.rb +110 -0
  593. data/spec/mongo/crypt/binding/binary_spec.rb +51 -0
  594. data/spec/mongo/crypt/binding/context_spec.rb +252 -0
  595. data/spec/mongo/crypt/binding/helpers_spec.rb +41 -0
  596. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +139 -0
  597. data/spec/mongo/crypt/binding/status_spec.rb +94 -0
  598. data/spec/mongo/crypt/binding/version_spec.rb +17 -0
  599. data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
  600. data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
  601. data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
  602. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
  603. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
  604. data/spec/mongo/crypt/handle_spec.rb +232 -0
  605. data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
  606. data/spec/mongo/crypt/status_spec.rb +147 -0
  607. data/spec/mongo/cursor/builder/get_more_command_spec.rb +37 -11
  608. data/spec/mongo/cursor/builder/op_get_more_spec.rb +11 -4
  609. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +61 -0
  610. data/spec/mongo/cursor_spec.rb +317 -46
  611. data/spec/mongo/database_spec.rb +739 -65
  612. data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
  613. data/spec/mongo/error/bulk_write_error_spec.rb +49 -0
  614. data/spec/mongo/error/crypt_error_spec.rb +26 -0
  615. data/spec/mongo/error/max_bson_size_spec.rb +35 -0
  616. data/spec/mongo/error/no_server_available_spec.rb +32 -0
  617. data/spec/mongo/error/notable_spec.rb +59 -0
  618. data/spec/mongo/error/operation_failure_heavy_spec.rb +58 -0
  619. data/spec/mongo/error/operation_failure_spec.rb +490 -0
  620. data/spec/mongo/error/parser_spec.rb +392 -5
  621. data/spec/mongo/error/unsupported_option_spec.rb +54 -0
  622. data/spec/mongo/grid/file/info_spec.rb +3 -3
  623. data/spec/mongo/grid/fs_bucket_spec.rb +299 -191
  624. data/spec/mongo/grid/stream/read_spec.rb +13 -19
  625. data/spec/mongo/grid/stream/write_spec.rb +88 -28
  626. data/spec/mongo/id_spec.rb +35 -0
  627. data/spec/mongo/index/view_spec.rb +511 -140
  628. data/spec/mongo/lint_spec.rb +228 -0
  629. data/spec/mongo/logger_spec.rb +14 -12
  630. data/spec/mongo/monitoring/event/cmap/connection_check_out_failed_spec.rb +23 -0
  631. data/spec/mongo/monitoring/event/cmap/connection_check_out_started_spec.rb +19 -0
  632. data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +30 -0
  633. data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +30 -0
  634. data/spec/mongo/monitoring/event/cmap/connection_closed_spec.rb +27 -0
  635. data/spec/mongo/monitoring/event/cmap/connection_created_spec.rb +24 -0
  636. data/spec/mongo/monitoring/event/cmap/connection_ready_spec.rb +24 -0
  637. data/spec/mongo/monitoring/event/cmap/pool_cleared_spec.rb +19 -0
  638. data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +26 -0
  639. data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +33 -0
  640. data/spec/mongo/monitoring/event/command_failed_spec.rb +30 -0
  641. data/spec/mongo/monitoring/event/command_started_spec.rb +27 -5
  642. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +30 -8
  643. data/spec/mongo/monitoring/event/secure_spec.rb +43 -1
  644. data/spec/mongo/monitoring/event/server_closed_spec.rb +35 -0
  645. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +35 -0
  646. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +31 -0
  647. data/spec/mongo/monitoring/event/server_heartbeat_started_spec.rb +31 -0
  648. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +31 -0
  649. data/spec/mongo/monitoring/event/server_opening_spec.rb +35 -0
  650. data/spec/mongo/monitoring/event/topology_changed_spec.rb +41 -0
  651. data/spec/mongo/monitoring/event/topology_closed_spec.rb +35 -0
  652. data/spec/mongo/monitoring/event/topology_opening_spec.rb +35 -0
  653. data/spec/mongo/monitoring_spec.rb +30 -5
  654. data/spec/mongo/operation/aggregate/result_spec.rb +85 -0
  655. data/spec/mongo/operation/aggregate_spec.rb +72 -0
  656. data/spec/mongo/operation/collections_info_spec.rb +42 -0
  657. data/spec/mongo/operation/command_spec.rb +80 -0
  658. data/spec/mongo/operation/create_index_spec.rb +56 -0
  659. data/spec/mongo/operation/create_user_spec.rb +47 -0
  660. data/spec/mongo/operation/delete/bulk_spec.rb +239 -0
  661. data/spec/mongo/operation/delete/command_spec.rb +112 -0
  662. data/spec/mongo/operation/delete/op_msg_spec.rb +254 -0
  663. data/spec/mongo/operation/delete_spec.rb +226 -0
  664. data/spec/mongo/operation/drop_index_spec.rb +54 -0
  665. data/spec/mongo/operation/find/legacy_spec.rb +125 -0
  666. data/spec/mongo/operation/get_more_spec.rb +58 -0
  667. data/spec/mongo/operation/indexes_spec.rb +34 -0
  668. data/spec/mongo/operation/insert/bulk_spec.rb +267 -0
  669. data/spec/mongo/operation/insert/command_spec.rb +115 -0
  670. data/spec/mongo/operation/insert/op_msg_spec.rb +285 -0
  671. data/spec/mongo/operation/insert_spec.rb +284 -0
  672. data/spec/mongo/operation/kill_cursors_spec.rb +4 -4
  673. data/spec/mongo/operation/limited_spec.rb +5 -3
  674. data/spec/mongo/operation/map_reduce_spec.rb +125 -0
  675. data/spec/mongo/operation/read_preference_legacy_spec.rb +363 -0
  676. data/spec/mongo/operation/read_preference_op_msg_spec.rb +304 -0
  677. data/spec/mongo/operation/remove_user_spec.rb +46 -0
  678. data/spec/mongo/operation/result_spec.rb +39 -4
  679. data/spec/mongo/operation/specifiable_spec.rb +2 -2
  680. data/spec/mongo/operation/update/bulk_spec.rb +233 -0
  681. data/spec/mongo/operation/update/command_spec.rb +119 -0
  682. data/spec/mongo/operation/update/op_msg_spec.rb +260 -0
  683. data/spec/mongo/operation/update_spec.rb +258 -0
  684. data/spec/mongo/operation/update_user_spec.rb +46 -0
  685. data/spec/mongo/protocol/compressed_spec.rb +66 -0
  686. data/spec/mongo/protocol/delete_spec.rb +24 -9
  687. data/spec/mongo/protocol/get_more_spec.rb +26 -11
  688. data/spec/mongo/protocol/insert_spec.rb +24 -9
  689. data/spec/mongo/protocol/kill_cursors_spec.rb +21 -6
  690. data/spec/mongo/protocol/msg_spec.rb +525 -0
  691. data/spec/mongo/protocol/query_spec.rb +56 -11
  692. data/spec/mongo/protocol/registry_spec.rb +31 -0
  693. data/spec/mongo/protocol/reply_spec.rb +15 -1
  694. data/spec/mongo/protocol/update_spec.rb +25 -10
  695. data/spec/mongo/query_cache_spec.rb +280 -0
  696. data/spec/mongo/retryable_spec.rb +464 -97
  697. data/spec/mongo/semaphore_spec.rb +51 -0
  698. data/spec/mongo/server/app_metadata_shared.rb +136 -0
  699. data/spec/mongo/server/app_metadata_spec.rb +145 -0
  700. data/spec/mongo/server/connection_auth_spec.rb +139 -0
  701. data/spec/mongo/server/connection_pool/populator_spec.rb +101 -0
  702. data/spec/mongo/server/connection_pool_spec.rb +894 -88
  703. data/spec/mongo/server/connection_spec.rb +786 -164
  704. data/spec/mongo/server/description/features_spec.rb +51 -37
  705. data/spec/mongo/server/description_query_methods_spec.rb +288 -0
  706. data/spec/mongo/server/description_spec.rb +186 -242
  707. data/spec/mongo/server/monitor/app_metadata_spec.rb +23 -0
  708. data/spec/mongo/server/monitor/connection_spec.rb +125 -0
  709. data/spec/mongo/server/monitor_spec.rb +165 -100
  710. data/spec/mongo/server/round_trip_time_averager_spec.rb +45 -0
  711. data/spec/mongo/server_selector/nearest_spec.rb +24 -23
  712. data/spec/mongo/server_selector/primary_preferred_spec.rb +27 -26
  713. data/spec/mongo/server_selector/primary_spec.rb +27 -9
  714. data/spec/mongo/server_selector/secondary_preferred_spec.rb +40 -23
  715. data/spec/mongo/server_selector/secondary_spec.rb +19 -18
  716. data/spec/mongo/server_selector_spec.rb +260 -4
  717. data/spec/mongo/server_spec.rb +294 -78
  718. data/spec/mongo/session/server_session_spec.rb +59 -0
  719. data/spec/mongo/session/session_pool_spec.rb +237 -0
  720. data/spec/mongo/session_spec.rb +345 -0
  721. data/spec/mongo/session_transaction_spec.rb +226 -0
  722. data/spec/mongo/socket/ssl_spec.rb +459 -168
  723. data/spec/mongo/socket/tcp_spec.rb +14 -0
  724. data/spec/mongo/socket/unix_spec.rb +9 -9
  725. data/spec/mongo/socket_spec.rb +116 -0
  726. data/spec/mongo/srv/monitor_spec.rb +230 -0
  727. data/spec/mongo/srv/result_spec.rb +54 -0
  728. data/spec/mongo/timeout_spec.rb +39 -0
  729. data/spec/mongo/uri/srv_protocol_spec.rb +1104 -0
  730. data/spec/mongo/uri_option_parsing_spec.rb +589 -0
  731. data/spec/mongo/uri_spec.rb +443 -93
  732. data/spec/mongo/utils_spec.rb +39 -0
  733. data/spec/mongo/write_concern/acknowledged_spec.rb +11 -0
  734. data/spec/mongo/write_concern/unacknowledged_spec.rb +11 -0
  735. data/spec/mongo/write_concern_spec.rb +69 -4
  736. data/spec/runners/auth.rb +119 -0
  737. data/spec/runners/change_streams/outcome.rb +42 -0
  738. data/spec/runners/change_streams/spec.rb +57 -0
  739. data/spec/runners/change_streams/test.rb +229 -0
  740. data/spec/runners/cmap/verifier.rb +45 -0
  741. data/spec/runners/cmap.rb +370 -0
  742. data/spec/runners/command_monitoring.rb +343 -0
  743. data/spec/runners/connection_string.rb +382 -0
  744. data/spec/runners/crud/context.rb +27 -0
  745. data/spec/runners/crud/operation.rb +466 -0
  746. data/spec/runners/crud/outcome.rb +53 -0
  747. data/spec/runners/crud/requirement.rb +69 -0
  748. data/spec/runners/crud/spec.rb +70 -0
  749. data/spec/runners/crud/test.rb +120 -0
  750. data/spec/runners/crud/test_base.rb +50 -0
  751. data/spec/runners/crud/verifier.rb +206 -0
  752. data/spec/runners/crud.rb +235 -0
  753. data/spec/runners/gridfs.rb +638 -0
  754. data/spec/runners/read_write_concern_document.rb +67 -0
  755. data/spec/runners/sdam/verifier.rb +109 -0
  756. data/spec/runners/sdam.rb +275 -0
  757. data/spec/runners/server_selection.rb +362 -0
  758. data/spec/runners/server_selection_rtt.rb +38 -0
  759. data/spec/runners/transactions/operation.rb +314 -0
  760. data/spec/runners/transactions/spec.rb +26 -0
  761. data/spec/runners/transactions/test.rb +322 -0
  762. data/spec/runners/transactions.rb +101 -0
  763. data/spec/shared/LICENSE +20 -0
  764. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  765. data/spec/shared/lib/mrss/constraints.rb +303 -0
  766. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  767. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  768. data/spec/spec_helper.rb +17 -197
  769. data/spec/spec_tests/auth_spec.rb +41 -0
  770. data/spec/spec_tests/change_streams_spec.rb +90 -0
  771. data/spec/spec_tests/client_side_encryption_spec.rb +11 -0
  772. data/spec/spec_tests/cmap_spec.rb +106 -0
  773. data/spec/spec_tests/command_monitoring_spec.rb +66 -0
  774. data/spec/spec_tests/connection_string_spec.rb +7 -0
  775. data/spec/spec_tests/crud_spec.rb +19 -0
  776. data/spec/spec_tests/data/auth/connection-string.yml +366 -0
  777. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +101 -0
  778. data/spec/spec_tests/data/change_streams/change-streams-resume-errorLabels.yml +1105 -0
  779. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +1173 -0
  780. data/spec/spec_tests/data/change_streams/change-streams.yml +536 -0
  781. data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
  782. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
  783. data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
  784. data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
  785. data/spec/spec_tests/data/client_side_encryption/bulk.yml +88 -0
  786. data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
  787. data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
  788. data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
  789. data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
  790. data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
  791. data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
  792. data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
  793. data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
  794. data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
  795. data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
  796. data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
  797. data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
  798. data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
  799. data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
  800. data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
  801. data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
  802. data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
  803. data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
  804. data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
  805. data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +64 -0
  806. data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
  807. data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
  808. data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
  809. data/spec/spec_tests/data/client_side_encryption/updateOne.yml +171 -0
  810. data/spec/spec_tests/data/cmap/connection-must-have-id.yml +27 -0
  811. data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +27 -0
  812. data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +27 -0
  813. data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +27 -0
  814. data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +24 -0
  815. data/spec/spec_tests/data/cmap/pool-checkin.yml +19 -0
  816. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +19 -0
  817. data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +36 -0
  818. data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +37 -0
  819. data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +35 -0
  820. data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +33 -0
  821. data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +28 -0
  822. data/spec/spec_tests/data/cmap/pool-close.yml +11 -0
  823. data/spec/spec_tests/data/cmap/pool-create-max-size.yml +71 -0
  824. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +34 -0
  825. data/spec/spec_tests/data/cmap/pool-create-with-options.yml +21 -0
  826. data/spec/spec_tests/data/cmap/pool-create.yml +12 -0
  827. data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +124 -0
  828. data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +46 -0
  829. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +49 -0
  830. data/spec/spec_tests/data/command_monitoring/command.yml +61 -0
  831. data/spec/spec_tests/data/command_monitoring/find.yml +266 -0
  832. data/spec/spec_tests/data/command_monitoring/insertMany.yml +75 -0
  833. data/spec/spec_tests/data/command_monitoring/unacknowledgedBulkWrite.yml +34 -0
  834. data/spec/spec_tests/data/command_monitoring/updateMany.yml +65 -0
  835. data/spec/spec_tests/data/command_monitoring/updateOne.yml +90 -0
  836. data/spec/spec_tests/data/connection_string/invalid-uris.yml +261 -0
  837. data/spec/spec_tests/data/connection_string/valid-auth.yml +257 -0
  838. data/spec/spec_tests/data/connection_string/valid-db-with-dotted-name.yml +77 -0
  839. data/spec/spec_tests/data/connection_string/valid-options.yml +17 -0
  840. data/spec/spec_tests/data/connection_string/valid-unix_socket-absolute.yml +197 -0
  841. data/spec/spec_tests/data/connection_string/valid-unix_socket-relative.yml +213 -0
  842. data/spec/spec_tests/data/connection_string/valid-warnings.yml +75 -0
  843. data/spec/spec_tests/data/crud/read/aggregate-out.yml +43 -0
  844. data/spec/spec_tests/data/crud/read/count-collation.yml +25 -0
  845. data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
  846. data/spec/spec_tests/data/crud/read/count.yml +74 -0
  847. data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +45 -0
  848. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
  849. data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
  850. data/spec/spec_tests/data/crud/write/findOneAndReplace-upsert.yml +91 -0
  851. data/spec/spec_tests/data/crud/write/findOneAndReplace-upsert_pre_2.6.yml +88 -0
  852. data/spec/spec_tests/data/crud/write/findOneAndReplace.yml +113 -0
  853. data/spec/spec_tests/data/crud/write/findOneAndUpdate-arrayFilters.yml +69 -0
  854. data/spec/spec_tests/data/crud/write/findOneAndUpdate.yml +163 -0
  855. data/spec/spec_tests/data/crud/write/insertMany.yml +77 -0
  856. data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +24 -0
  857. data/spec/spec_tests/data/crud/write/replaceOne-pre_2.6.yml +98 -0
  858. data/spec/spec_tests/data/crud/write/replaceOne.yml +102 -0
  859. data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +66 -0
  860. data/spec/spec_tests/data/crud/write/updateMany-collation.yml +28 -0
  861. data/spec/spec_tests/data/crud/write/updateMany-pre_2.6.yml +86 -0
  862. data/spec/spec_tests/data/crud/write/updateMany.yml +87 -0
  863. data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +114 -0
  864. data/spec/spec_tests/data/crud/write/updateOne-collation.yml +25 -0
  865. data/spec/spec_tests/data/crud/write/updateOne-pre_2.6.yml +83 -0
  866. data/spec/spec_tests/data/crud/write/updateOne.yml +84 -0
  867. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
  868. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
  869. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +103 -0
  870. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-clientError.yml +63 -0
  871. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint-serverError.yml +92 -0
  872. data/spec/spec_tests/data/crud_v2/bulkWrite-delete-hint.yml +103 -0
  873. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-clientError.yml +90 -0
  874. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint-serverError.yml +147 -0
  875. data/spec/spec_tests/data/crud_v2/bulkWrite-update-hint.yml +164 -0
  876. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
  877. data/spec/spec_tests/data/crud_v2/deleteMany-hint-clientError.yml +43 -0
  878. data/spec/spec_tests/data/crud_v2/deleteMany-hint-serverError.yml +62 -0
  879. data/spec/spec_tests/data/crud_v2/deleteMany-hint.yml +58 -0
  880. data/spec/spec_tests/data/crud_v2/deleteOne-hint-clientError.yml +41 -0
  881. data/spec/spec_tests/data/crud_v2/deleteOne-hint-serverError.yml +60 -0
  882. data/spec/spec_tests/data/crud_v2/deleteOne-hint.yml +57 -0
  883. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-clientError.yml +28 -0
  884. data/spec/spec_tests/data/crud_v2/find-allowdiskuse-serverError.yml +44 -0
  885. data/spec/spec_tests/data/crud_v2/find-allowdiskuse.yml +50 -0
  886. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-clientError.yml +45 -0
  887. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint-serverError.yml +60 -0
  888. data/spec/spec_tests/data/crud_v2/findOneAndDelete-hint.yml +56 -0
  889. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-clientError.yml +40 -0
  890. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint-serverError.yml +59 -0
  891. data/spec/spec_tests/data/crud_v2/findOneAndReplace-hint.yml +55 -0
  892. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-clientError.yml +40 -0
  893. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint-serverError.yml +58 -0
  894. data/spec/spec_tests/data/crud_v2/findOneAndUpdate-hint.yml +55 -0
  895. data/spec/spec_tests/data/crud_v2/replaceOne-hint.yml +61 -0
  896. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-delete-hint-clientError.yml +60 -0
  897. data/spec/spec_tests/data/crud_v2/unacknowledged-bulkWrite-update-hint-clientError.yml +88 -0
  898. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteMany-hint-clientError.yml +40 -0
  899. data/spec/spec_tests/data/crud_v2/unacknowledged-deleteOne-hint-clientError.yml +38 -0
  900. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndDelete-hint-clientError.yml +42 -0
  901. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndReplace-hint-clientError.yml +40 -0
  902. data/spec/spec_tests/data/crud_v2/unacknowledged-findOneAndUpdate-hint-clientError.yml +40 -0
  903. data/spec/spec_tests/data/crud_v2/unacknowledged-replaceOne-hint-clientError.yml +40 -0
  904. data/spec/spec_tests/data/crud_v2/unacknowledged-updateMany-hint-clientError.yml +43 -0
  905. data/spec/spec_tests/data/crud_v2/unacknowledged-updateOne-hint-clientError.yml +40 -0
  906. data/spec/spec_tests/data/crud_v2/updateMany-hint-clientError.yml +45 -0
  907. data/spec/spec_tests/data/crud_v2/updateMany-hint-serverError.yml +66 -0
  908. data/spec/spec_tests/data/crud_v2/updateMany-hint.yml +65 -0
  909. data/spec/spec_tests/data/crud_v2/updateOne-hint-clientError.yml +43 -0
  910. data/spec/spec_tests/data/crud_v2/updateOne-hint-serverError.yml +62 -0
  911. data/spec/spec_tests/data/crud_v2/updateOne-hint.yml +61 -0
  912. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +157 -0
  913. data/spec/spec_tests/data/dns_seedlist_discovery/direct-connection-false.yml +10 -0
  914. data/spec/spec_tests/data/dns_seedlist_discovery/direct-connection-true.yml +5 -0
  915. data/spec/spec_tests/data/dns_seedlist_discovery/longer-parent-in-return.yml +11 -0
  916. data/spec/spec_tests/data/dns_seedlist_discovery/misformatted-option.yml +5 -0
  917. data/spec/spec_tests/data/dns_seedlist_discovery/no-results.yml +5 -0
  918. data/spec/spec_tests/data/dns_seedlist_discovery/not-enough-parts.yml +5 -0
  919. data/spec/spec_tests/data/dns_seedlist_discovery/one-result-default-port.yml +10 -0
  920. data/spec/spec_tests/data/dns_seedlist_discovery/one-txt-record-multiple-strings.yml +10 -0
  921. data/spec/spec_tests/data/dns_seedlist_discovery/one-txt-record.yml +11 -0
  922. data/spec/spec_tests/data/dns_seedlist_discovery/parent-part-mismatch1.yml +5 -0
  923. data/spec/spec_tests/data/dns_seedlist_discovery/parent-part-mismatch2.yml +5 -0
  924. data/spec/spec_tests/data/dns_seedlist_discovery/parent-part-mismatch3.yml +5 -0
  925. data/spec/spec_tests/data/dns_seedlist_discovery/parent-part-mismatch4.yml +5 -0
  926. data/spec/spec_tests/data/dns_seedlist_discovery/parent-part-mismatch5.yml +5 -0
  927. data/spec/spec_tests/data/dns_seedlist_discovery/returned-parent-too-short.yml +5 -0
  928. data/spec/spec_tests/data/dns_seedlist_discovery/returned-parent-wrong.yml +5 -0
  929. data/spec/spec_tests/data/dns_seedlist_discovery/two-results-default-port.yml +11 -0
  930. data/spec/spec_tests/data/dns_seedlist_discovery/two-results-nonstandard-port.yml +11 -0
  931. data/spec/spec_tests/data/dns_seedlist_discovery/two-txt-records.yml +5 -0
  932. data/spec/spec_tests/data/dns_seedlist_discovery/txt-record-not-allowed-option.yml +5 -0
  933. data/spec/spec_tests/data/dns_seedlist_discovery/txt-record-with-overridden-ssl-option.yml +11 -0
  934. data/spec/spec_tests/data/dns_seedlist_discovery/txt-record-with-overridden-uri-option.yml +11 -0
  935. data/spec/spec_tests/data/dns_seedlist_discovery/txt-record-with-unallowed-option.yml +5 -0
  936. data/spec/spec_tests/data/dns_seedlist_discovery/uri-with-port.yml +5 -0
  937. data/spec/spec_tests/data/dns_seedlist_discovery/uri-with-two-hosts.yml +5 -0
  938. data/spec/spec_tests/data/gridfs/delete.yml +123 -0
  939. data/spec/spec_tests/data/gridfs/download.yml +192 -0
  940. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +16 -0
  941. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +15 -0
  942. data/spec/spec_tests/data/read_write_concern/connection-string/read-concern.yml +32 -0
  943. data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +79 -0
  944. data/spec/spec_tests/data/read_write_concern/document/read-concern.yml +37 -0
  945. data/spec/spec_tests/data/read_write_concern/document/write-concern.yml +100 -0
  946. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-2.6.yml +215 -0
  947. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-3.2.yml +58 -0
  948. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-3.4.yml +95 -0
  949. data/spec/spec_tests/data/read_write_concern/operation/default-write-concern-4.2.yml +36 -0
  950. data/spec/spec_tests/data/retryable_reads/aggregate-merge.yml +39 -0
  951. data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +157 -0
  952. data/spec/spec_tests/data/retryable_reads/aggregate.yml +87 -0
  953. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +149 -0
  954. data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +61 -0
  955. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +149 -0
  956. data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +65 -0
  957. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +153 -0
  958. data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +61 -0
  959. data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +150 -0
  960. data/spec/spec_tests/data/retryable_reads/count.yml +64 -0
  961. data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +150 -0
  962. data/spec/spec_tests/data/retryable_reads/countDocuments.yml +64 -0
  963. data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +156 -0
  964. data/spec/spec_tests/data/retryable_reads/distinct.yml +71 -0
  965. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +148 -0
  966. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount.yml +62 -0
  967. data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +160 -0
  968. data/spec/spec_tests/data/retryable_reads/find.yml +86 -0
  969. data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +154 -0
  970. data/spec/spec_tests/data/retryable_reads/findOne.yml +68 -0
  971. data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +173 -0
  972. data/spec/spec_tests/data/retryable_reads/gridfs-download.yml +79 -0
  973. data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +174 -0
  974. data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName.yml +79 -0
  975. data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +143 -0
  976. data/spec/spec_tests/data/retryable_reads/listCollectionNames.yml +59 -0
  977. data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +144 -0
  978. data/spec/spec_tests/data/retryable_reads/listCollectionObjects.yml +59 -0
  979. data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +143 -0
  980. data/spec/spec_tests/data/retryable_reads/listCollections.yml +59 -0
  981. data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +143 -0
  982. data/spec/spec_tests/data/retryable_reads/listDatabaseNames.yml +59 -0
  983. data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +144 -0
  984. data/spec/spec_tests/data/retryable_reads/listDatabaseObjects.yml +59 -0
  985. data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +144 -0
  986. data/spec/spec_tests/data/retryable_reads/listDatabases.yml +59 -0
  987. data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +144 -0
  988. data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +60 -0
  989. data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +145 -0
  990. data/spec/spec_tests/data/retryable_reads/listIndexes.yml +60 -0
  991. data/spec/spec_tests/data/retryable_reads/mapReduce.yml +60 -0
  992. data/spec/spec_tests/data/retryable_writes/bulkWrite-errorLabels.yml +77 -0
  993. data/spec/spec_tests/data/retryable_writes/bulkWrite-serverErrors.yml +130 -0
  994. data/spec/spec_tests/data/retryable_writes/bulkWrite.yml +396 -0
  995. data/spec/spec_tests/data/retryable_writes/deleteMany.yml +22 -0
  996. data/spec/spec_tests/data/retryable_writes/deleteOne-errorLabels.yml +48 -0
  997. data/spec/spec_tests/data/retryable_writes/deleteOne-serverErrors.yml +73 -0
  998. data/spec/spec_tests/data/retryable_writes/deleteOne.yml +57 -0
  999. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-errorLabels.yml +49 -0
  1000. data/spec/spec_tests/data/retryable_writes/findOneAndDelete-serverErrors.yml +74 -0
  1001. data/spec/spec_tests/data/retryable_writes/findOneAndDelete.yml +58 -0
  1002. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-errorLabels.yml +52 -0
  1003. data/spec/spec_tests/data/retryable_writes/findOneAndReplace-serverErrors.yml +80 -0
  1004. data/spec/spec_tests/data/retryable_writes/findOneAndReplace.yml +63 -0
  1005. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-errorLabels.yml +52 -0
  1006. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate-serverErrors.yml +79 -0
  1007. data/spec/spec_tests/data/retryable_writes/findOneAndUpdate.yml +62 -0
  1008. data/spec/spec_tests/data/retryable_writes/insertMany-errorLabels.yml +54 -0
  1009. data/spec/spec_tests/data/retryable_writes/insertMany-serverErrors.yml +84 -0
  1010. data/spec/spec_tests/data/retryable_writes/insertMany.yml +74 -0
  1011. data/spec/spec_tests/data/retryable_writes/insertOne-errorLabels.yml +44 -0
  1012. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +526 -0
  1013. data/spec/spec_tests/data/retryable_writes/insertOne.yml +61 -0
  1014. data/spec/spec_tests/data/retryable_writes/replaceOne-errorLabels.yml +53 -0
  1015. data/spec/spec_tests/data/retryable_writes/replaceOne-serverErrors.yml +82 -0
  1016. data/spec/spec_tests/data/retryable_writes/replaceOne.yml +66 -0
  1017. data/spec/spec_tests/data/retryable_writes/updateMany.yml +27 -0
  1018. data/spec/spec_tests/data/retryable_writes/updateOne-errorLabels.yml +53 -0
  1019. data/spec/spec_tests/data/retryable_writes/updateOne-serverErrors.yml +82 -0
  1020. data/spec/spec_tests/data/retryable_writes/updateOne.yml +129 -0
  1021. data/spec/spec_tests/data/sdam/errors/error_handling_handshake.yml +54 -0
  1022. data/spec/spec_tests/data/sdam/errors/non-stale-network-error.yml +46 -0
  1023. data/spec/spec_tests/data/sdam/errors/non-stale-network-timeout-error.yml +37 -0
  1024. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedAtShutdown.yml +60 -0
  1025. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-InterruptedDueToReplStateChange.yml +60 -0
  1026. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMaster.yml +60 -0
  1027. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterNoSlaveOk.yml +60 -0
  1028. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-NotMasterOrSecondary.yml +60 -0
  1029. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-PrimarySteppedDown.yml +60 -0
  1030. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-greater-ShutdownInProgress.yml +60 -0
  1031. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedAtShutdown.yml +51 -0
  1032. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-InterruptedDueToReplStateChange.yml +51 -0
  1033. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMaster.yml +51 -0
  1034. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterNoSlaveOk.yml +51 -0
  1035. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-NotMasterOrSecondary.yml +51 -0
  1036. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-PrimarySteppedDown.yml +51 -0
  1037. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-missing-ShutdownInProgress.yml +51 -0
  1038. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedAtShutdown.yml +60 -0
  1039. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-InterruptedDueToReplStateChange.yml +60 -0
  1040. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMaster.yml +60 -0
  1041. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterNoSlaveOk.yml +60 -0
  1042. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-NotMasterOrSecondary.yml +60 -0
  1043. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-PrimarySteppedDown.yml +60 -0
  1044. data/spec/spec_tests/data/sdam/errors/non-stale-topologyVersion-proccessId-changed-ShutdownInProgress.yml +60 -0
  1045. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedAtShutdown.yml +46 -0
  1046. data/spec/spec_tests/data/sdam/errors/post-42-InterruptedDueToReplStateChange.yml +46 -0
  1047. data/spec/spec_tests/data/sdam/errors/post-42-NotMaster.yml +46 -0
  1048. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterNoSlaveOk.yml +46 -0
  1049. data/spec/spec_tests/data/sdam/errors/post-42-NotMasterOrSecondary.yml +46 -0
  1050. data/spec/spec_tests/data/sdam/errors/post-42-PrimarySteppedDown.yml +46 -0
  1051. data/spec/spec_tests/data/sdam/errors/post-42-ShutdownInProgress.yml +46 -0
  1052. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedAtShutdown.yml +46 -0
  1053. data/spec/spec_tests/data/sdam/errors/pre-42-InterruptedDueToReplStateChange.yml +46 -0
  1054. data/spec/spec_tests/data/sdam/errors/pre-42-NotMaster.yml +46 -0
  1055. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterNoSlaveOk.yml +46 -0
  1056. data/spec/spec_tests/data/sdam/errors/pre-42-NotMasterOrSecondary.yml +46 -0
  1057. data/spec/spec_tests/data/sdam/errors/pre-42-PrimarySteppedDown.yml +46 -0
  1058. data/spec/spec_tests/data/sdam/errors/pre-42-ShutdownInProgress.yml +46 -0
  1059. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedAtShutdown.yml +89 -0
  1060. data/spec/spec_tests/data/sdam/errors/stale-generation-InterruptedDueToReplStateChange.yml +89 -0
  1061. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMaster.yml +89 -0
  1062. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterNoSlaveOk.yml +89 -0
  1063. data/spec/spec_tests/data/sdam/errors/stale-generation-NotMasterOrSecondary.yml +89 -0
  1064. data/spec/spec_tests/data/sdam/errors/stale-generation-PrimarySteppedDown.yml +89 -0
  1065. data/spec/spec_tests/data/sdam/errors/stale-generation-ShutdownInProgress.yml +89 -0
  1066. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedAtShutdown.yml +89 -0
  1067. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-InterruptedDueToReplStateChange.yml +89 -0
  1068. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMaster.yml +89 -0
  1069. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterNoSlaveOk.yml +89 -0
  1070. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-NotMasterOrSecondary.yml +89 -0
  1071. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-PrimarySteppedDown.yml +89 -0
  1072. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-ShutdownInProgress.yml +89 -0
  1073. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-network.yml +80 -0
  1074. data/spec/spec_tests/data/sdam/errors/stale-generation-afterHandshakeCompletes-timeout.yml +80 -0
  1075. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedAtShutdown.yml +89 -0
  1076. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-InterruptedDueToReplStateChange.yml +89 -0
  1077. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMaster.yml +89 -0
  1078. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterNoSlaveOk.yml +89 -0
  1079. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-NotMasterOrSecondary.yml +89 -0
  1080. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-PrimarySteppedDown.yml +89 -0
  1081. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-ShutdownInProgress.yml +89 -0
  1082. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-network.yml +80 -0
  1083. data/spec/spec_tests/data/sdam/errors/stale-generation-beforeHandshakeCompletes-timeout.yml +80 -0
  1084. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedAtShutdown.yml +64 -0
  1085. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-InterruptedDueToReplStateChange.yml +64 -0
  1086. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMaster.yml +64 -0
  1087. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterNoSlaveOk.yml +64 -0
  1088. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-NotMasterOrSecondary.yml +64 -0
  1089. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-PrimarySteppedDown.yml +64 -0
  1090. data/spec/spec_tests/data/sdam/errors/stale-topologyVersion-ShutdownInProgress.yml +64 -0
  1091. data/spec/spec_tests/data/sdam/rs/compatible.yml +43 -0
  1092. data/spec/spec_tests/data/sdam/rs/compatible_unknown.yml +33 -0
  1093. data/spec/spec_tests/data/sdam/rs/discover_arbiters.yml +43 -0
  1094. data/spec/spec_tests/data/sdam/rs/discover_arbiters_replicaset.yml +43 -0
  1095. data/spec/spec_tests/data/sdam/rs/discover_ghost.yml +35 -0
  1096. data/spec/spec_tests/data/sdam/rs/discover_ghost_replicaset.yml +41 -0
  1097. data/spec/spec_tests/data/sdam/rs/discover_hidden.yml +50 -0
  1098. data/spec/spec_tests/data/sdam/rs/discover_hidden_replicaset.yml +50 -0
  1099. data/spec/spec_tests/data/sdam/rs/discover_passives.yml +81 -0
  1100. data/spec/spec_tests/data/sdam/rs/discover_passives_replicaset.yml +81 -0
  1101. data/spec/spec_tests/data/sdam/rs/discover_primary.yml +42 -0
  1102. data/spec/spec_tests/data/sdam/rs/discover_primary_replicaset.yml +42 -0
  1103. data/spec/spec_tests/data/sdam/rs/discover_rsother.yml +49 -0
  1104. data/spec/spec_tests/data/sdam/rs/discover_rsother_replicaset.yml +66 -0
  1105. data/spec/spec_tests/data/sdam/rs/discover_secondary.yml +43 -0
  1106. data/spec/spec_tests/data/sdam/rs/discover_secondary_replicaset.yml +43 -0
  1107. data/spec/spec_tests/data/sdam/rs/discovery.yml +203 -0
  1108. data/spec/spec_tests/data/sdam/rs/equal_electionids.yml +55 -0
  1109. data/spec/spec_tests/data/sdam/rs/hosts_differ_from_seeds.yml +36 -0
  1110. data/spec/spec_tests/data/sdam/rs/incompatible_arbiter.yml +34 -0
  1111. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +32 -0
  1112. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +34 -0
  1113. data/spec/spec_tests/data/sdam/rs/ls_timeout.yml +243 -0
  1114. data/spec/spec_tests/data/sdam/rs/member_reconfig.yml +72 -0
  1115. data/spec/spec_tests/data/sdam/rs/member_standalone.yml +64 -0
  1116. data/spec/spec_tests/data/sdam/rs/new_primary.yml +78 -0
  1117. data/spec/spec_tests/data/sdam/rs/new_primary_new_electionid.yml +116 -0
  1118. data/spec/spec_tests/data/sdam/rs/new_primary_new_setversion.yml +116 -0
  1119. data/spec/spec_tests/data/sdam/rs/new_primary_wrong_set_name.yml +75 -0
  1120. data/spec/spec_tests/data/sdam/rs/non_rs_member.yml +32 -0
  1121. data/spec/spec_tests/data/sdam/rs/normalize_case.yml +51 -0
  1122. data/spec/spec_tests/data/sdam/rs/normalize_case_me.yml +100 -0
  1123. data/spec/spec_tests/data/sdam/rs/null_election_id.yml +171 -0
  1124. data/spec/spec_tests/data/sdam/rs/primary_becomes_ghost.yml +63 -0
  1125. data/spec/spec_tests/data/sdam/rs/primary_becomes_mongos.yml +56 -0
  1126. data/spec/spec_tests/data/sdam/rs/primary_becomes_standalone.yml +54 -0
  1127. data/spec/spec_tests/data/sdam/rs/primary_changes_set_name.yml +61 -0
  1128. data/spec/spec_tests/data/sdam/rs/primary_disconnect.yml +58 -0
  1129. data/spec/spec_tests/data/sdam/rs/primary_disconnect_electionid.yml +184 -0
  1130. data/spec/spec_tests/data/sdam/rs/primary_disconnect_setversion.yml +184 -0
  1131. data/spec/spec_tests/data/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +62 -0
  1132. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +26 -0
  1133. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
  1134. data/spec/spec_tests/data/sdam/rs/primary_reports_new_member.yml +171 -0
  1135. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +79 -0
  1136. data/spec/spec_tests/data/sdam/rs/primary_wrong_set_name.yml +29 -0
  1137. data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
  1138. data/spec/spec_tests/data/sdam/rs/replicaset_rsnp.yml +20 -0
  1139. data/spec/spec_tests/data/sdam/rs/response_from_removed.yml +67 -0
  1140. data/spec/spec_tests/data/sdam/rs/ruby_primary_address_change.yml +31 -0
  1141. data/spec/spec_tests/data/sdam/rs/ruby_secondary_wrong_set_name_with_primary_second.yml +73 -0
  1142. data/spec/spec_tests/data/sdam/rs/sec_not_auth.yml +53 -0
  1143. data/spec/spec_tests/data/sdam/rs/secondary_ignore_ok_0.yml +85 -0
  1144. data/spec/spec_tests/data/sdam/rs/secondary_mismatched_me.yml +27 -0
  1145. data/spec/spec_tests/data/sdam/rs/secondary_wrong_set_name.yml +30 -0
  1146. data/spec/spec_tests/data/sdam/rs/secondary_wrong_set_name_with_primary.yml +73 -0
  1147. data/spec/spec_tests/data/sdam/rs/setversion_without_electionid.yml +77 -0
  1148. data/spec/spec_tests/data/sdam/rs/stepdown_change_set_name.yml +63 -0
  1149. data/spec/spec_tests/data/sdam/rs/too_new.yml +43 -0
  1150. data/spec/spec_tests/data/sdam/rs/too_old.yml +39 -0
  1151. data/spec/spec_tests/data/sdam/rs/topology_version_equal.yml +66 -0
  1152. data/spec/spec_tests/data/sdam/rs/topology_version_greater.yml +189 -0
  1153. data/spec/spec_tests/data/sdam/rs/topology_version_less.yml +62 -0
  1154. data/spec/spec_tests/data/sdam/rs/unexpected_mongos.yml +28 -0
  1155. data/spec/spec_tests/data/sdam/rs/use_setversion_without_electionid.yml +114 -0
  1156. data/spec/spec_tests/data/sdam/rs/wrong_set_name.yml +37 -0
  1157. data/spec/spec_tests/data/sdam/sharded/compatible.yml +38 -0
  1158. data/spec/spec_tests/data/sdam/sharded/discover_single_mongos.yml +23 -0
  1159. data/spec/spec_tests/data/sdam/sharded/ls_timeout_mongos.yml +97 -0
  1160. data/spec/spec_tests/data/sdam/sharded/mongos_disconnect.yml +110 -0
  1161. data/spec/spec_tests/data/sdam/sharded/multiple_mongoses.yml +50 -0
  1162. data/spec/spec_tests/data/sdam/sharded/non_mongos_removed.yml +45 -0
  1163. data/spec/spec_tests/data/sdam/sharded/normalize_uri_case.yml +32 -0
  1164. data/spec/spec_tests/data/sdam/sharded/ruby_primary_different_address.yml +21 -0
  1165. data/spec/spec_tests/data/sdam/sharded/ruby_primary_mismatched_me.yml +22 -0
  1166. data/spec/spec_tests/data/sdam/sharded/too_new.yml +36 -0
  1167. data/spec/spec_tests/data/sdam/sharded/too_old.yml +36 -0
  1168. data/spec/spec_tests/data/sdam/single/compatible.yml +26 -0
  1169. data/spec/spec_tests/data/sdam/single/direct_connection_external_ip.yml +36 -0
  1170. data/spec/spec_tests/data/sdam/single/direct_connection_mongos.yml +35 -0
  1171. data/spec/spec_tests/data/sdam/single/direct_connection_replicaset.yml +22 -0
  1172. data/spec/spec_tests/data/sdam/single/direct_connection_rsarbiter.yml +37 -0
  1173. data/spec/spec_tests/data/sdam/single/direct_connection_rsprimary.yml +36 -0
  1174. data/spec/spec_tests/data/sdam/single/direct_connection_rssecondary.yml +37 -0
  1175. data/spec/spec_tests/data/sdam/single/direct_connection_slave.yml +34 -0
  1176. data/spec/spec_tests/data/sdam/single/direct_connection_standalone.yml +34 -0
  1177. data/spec/spec_tests/data/sdam/single/direct_connection_unavailable_seed.yml +28 -0
  1178. data/spec/spec_tests/data/sdam/single/direct_connection_wrong_set_name.yml +38 -0
  1179. data/spec/spec_tests/data/sdam/single/discover_standalone.yml +34 -0
  1180. data/spec/spec_tests/data/sdam/single/discover_unavailable_seed.yml +28 -0
  1181. data/spec/spec_tests/data/sdam/single/ls_timeout_standalone.yml +35 -0
  1182. data/spec/spec_tests/data/sdam/single/not_ok_response.yml +42 -0
  1183. data/spec/spec_tests/data/sdam/single/ruby_primary_different_address.yml +24 -0
  1184. data/spec/spec_tests/data/sdam/single/ruby_primary_mismatched_me.yml +25 -0
  1185. data/spec/spec_tests/data/sdam/single/standalone_removed.yml +34 -0
  1186. data/spec/spec_tests/data/sdam/single/too_new.yml +26 -0
  1187. data/spec/spec_tests/data/sdam/single/too_old.yml +24 -0
  1188. data/spec/spec_tests/data/sdam/single/too_old_then_upgraded.yml +46 -0
  1189. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
  1190. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
  1191. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
  1192. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
  1193. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
  1194. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
  1195. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
  1196. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
  1197. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
  1198. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
  1199. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +70 -0
  1200. data/spec/spec_tests/data/sdam_monitoring/replica_set_other_chain.yml +222 -0
  1201. data/spec/spec_tests/data/sdam_monitoring/replica_set_other_change.yml +225 -0
  1202. data/spec/spec_tests/data/sdam_monitoring/replica_set_primary_address_change.yml +251 -0
  1203. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +111 -0
  1204. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_and_secondary.yml +198 -0
  1205. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +175 -0
  1206. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +110 -0
  1207. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_second_seed_removal.yml +106 -0
  1208. data/spec/spec_tests/data/sdam_monitoring/required_replica_set.yml +107 -0
  1209. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +70 -0
  1210. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +86 -0
  1211. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
  1212. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +90 -0
  1213. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/Nearest.yml +25 -0
  1214. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/Nearest_multiple.yml +26 -0
  1215. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +20 -0
  1216. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/PossiblePrimary.yml +15 -0
  1217. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.yml +15 -0
  1218. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/Primary.yml +18 -0
  1219. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +25 -0
  1220. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +20 -0
  1221. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/Secondary.yml +25 -0
  1222. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +25 -0
  1223. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +20 -0
  1224. data/spec/spec_tests/data/server_selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +20 -0
  1225. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/Nearest.yml +32 -0
  1226. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/Nearest_multiple.yml +33 -0
  1227. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +25 -0
  1228. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/Primary.yml +26 -0
  1229. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +28 -0
  1230. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +28 -0
  1231. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/Secondary.yml +30 -0
  1232. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +30 -0
  1233. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +28 -0
  1234. data/spec/spec_tests/data/server_selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +25 -0
  1235. data/spec/spec_tests/data/server_selection/Sharded/read/Nearest.yml +21 -0
  1236. data/spec/spec_tests/data/server_selection/Sharded/read/Primary.yml +19 -0
  1237. data/spec/spec_tests/data/server_selection/Sharded/read/PrimaryPreferred.yml +21 -0
  1238. data/spec/spec_tests/data/server_selection/Sharded/read/Secondary.yml +21 -0
  1239. data/spec/spec_tests/data/server_selection/Sharded/read/SecondaryPreferred.yml +21 -0
  1240. data/spec/spec_tests/data/server_selection/Single/read/SecondaryPreferred.yml +18 -0
  1241. data/spec/spec_tests/data/server_selection/Unknown/read/SecondaryPreferred.yml +10 -0
  1242. data/spec/spec_tests/data/transactions/abort.yml +413 -0
  1243. data/spec/spec_tests/data/transactions/bulk.yml +267 -0
  1244. data/spec/spec_tests/data/transactions/causal-consistency.yml +175 -0
  1245. data/spec/spec_tests/data/transactions/commit.yml +603 -0
  1246. data/spec/spec_tests/data/transactions/count.yml +67 -0
  1247. data/spec/spec_tests/data/transactions/create-collection.yml +131 -0
  1248. data/spec/spec_tests/data/transactions/create-index.yml +152 -0
  1249. data/spec/spec_tests/data/transactions/delete.yml +192 -0
  1250. data/spec/spec_tests/data/transactions/error-labels.yml +1027 -0
  1251. data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
  1252. data/spec/spec_tests/data/transactions/errors.yml +133 -0
  1253. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +134 -0
  1254. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +148 -0
  1255. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +236 -0
  1256. data/spec/spec_tests/data/transactions/insert.yml +390 -0
  1257. data/spec/spec_tests/data/transactions/isolation.yml +133 -0
  1258. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
  1259. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +348 -0
  1260. data/spec/spec_tests/data/transactions/pin-mongos.yml +556 -0
  1261. data/spec/spec_tests/data/transactions/read-concern.yml +623 -0
  1262. data/spec/spec_tests/data/transactions/read-pref.yml +348 -0
  1263. data/spec/spec_tests/data/transactions/reads.yml +261 -0
  1264. data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +124 -0
  1265. data/spec/spec_tests/data/transactions/retryable-abort.yml +1315 -0
  1266. data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +132 -0
  1267. data/spec/spec_tests/data/transactions/retryable-commit.yml +1460 -0
  1268. data/spec/spec_tests/data/transactions/retryable-writes.yml +216 -0
  1269. data/spec/spec_tests/data/transactions/run-command.yml +197 -0
  1270. data/spec/spec_tests/data/transactions/transaction-options-repl.yml +117 -0
  1271. data/spec/spec_tests/data/transactions/transaction-options.yml +781 -0
  1272. data/spec/spec_tests/data/transactions/update.yml +246 -0
  1273. data/spec/spec_tests/data/transactions/write-concern.yml +554 -0
  1274. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +170 -0
  1275. data/spec/spec_tests/data/transactions_api/callback-commits.yml +204 -0
  1276. data/spec/spec_tests/data/transactions_api/callback-retry.yml +215 -0
  1277. data/spec/spec_tests/data/transactions_api/commit-retry.yml +324 -0
  1278. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +139 -0
  1279. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +175 -0
  1280. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +216 -0
  1281. data/spec/spec_tests/data/transactions_api/commit.yml +193 -0
  1282. data/spec/spec_tests/data/transactions_api/transaction-options.yml +274 -0
  1283. data/spec/spec_tests/data/uri_options/auth-options.yml +49 -0
  1284. data/spec/spec_tests/data/uri_options/compression-options.yml +51 -0
  1285. data/spec/spec_tests/data/uri_options/concern-options.yml +55 -0
  1286. data/spec/spec_tests/data/uri_options/connection-options.yml +149 -0
  1287. data/spec/spec_tests/data/uri_options/connection-pool-options.yml +26 -0
  1288. data/spec/spec_tests/data/uri_options/read-preference-options.yml +66 -0
  1289. data/spec/spec_tests/data/uri_options/ruby-auth-options.yml +12 -0
  1290. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +58 -0
  1291. data/spec/spec_tests/data/uri_options/tls-options.yml +364 -0
  1292. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +76 -0
  1293. data/spec/spec_tests/gridfs_spec.rb +52 -0
  1294. data/spec/spec_tests/max_staleness_spec.rb +9 -0
  1295. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +10 -0
  1296. data/spec/spec_tests/read_write_concern_document_spec.rb +74 -0
  1297. data/spec/spec_tests/read_write_concern_operaton_spec.rb +10 -0
  1298. data/spec/spec_tests/retryable_reads_spec.rb +47 -0
  1299. data/spec/spec_tests/retryable_writes_spec.rb +19 -0
  1300. data/spec/spec_tests/sdam_integration_spec.rb +13 -0
  1301. data/spec/spec_tests/sdam_monitoring_spec.rb +93 -0
  1302. data/spec/spec_tests/sdam_spec.rb +239 -0
  1303. data/spec/spec_tests/server_selection_rtt_spec.rb +30 -0
  1304. data/spec/spec_tests/server_selection_spec.rb +9 -0
  1305. data/spec/spec_tests/transactions_api_spec.rb +10 -0
  1306. data/spec/spec_tests/transactions_spec.rb +10 -0
  1307. data/spec/spec_tests/uri_options_spec.rb +74 -0
  1308. data/spec/stress/cleanup_spec.rb +58 -0
  1309. data/spec/stress/connection_pool_stress_spec.rb +201 -0
  1310. data/spec/stress/connection_pool_timing_spec.rb +181 -0
  1311. data/spec/stress/fork_reconnect_stress_spec.rb +109 -0
  1312. data/spec/support/authorization.rb +51 -153
  1313. data/spec/support/aws_utils/base.rb +134 -0
  1314. data/spec/support/aws_utils/inspector.rb +224 -0
  1315. data/spec/support/aws_utils/orchestrator.rb +370 -0
  1316. data/spec/support/aws_utils/provisioner.rb +360 -0
  1317. data/spec/support/aws_utils.rb +62 -0
  1318. data/spec/support/background_thread_registry.rb +67 -0
  1319. data/spec/support/certificates/README.md +105 -0
  1320. data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
  1321. data/spec/support/certificates/atlas-ocsp.crt +41 -0
  1322. data/spec/support/certificates/ca.crt +76 -0
  1323. data/spec/support/certificates/client-encrypted.key +30 -0
  1324. data/spec/support/certificates/client-int.crt +78 -0
  1325. data/spec/support/certificates/client-second-level-bundle.pem +179 -0
  1326. data/spec/support/certificates/client-second-level.crt +74 -0
  1327. data/spec/support/certificates/client-second-level.key +27 -0
  1328. data/spec/support/certificates/client-second-level.pem +101 -0
  1329. data/spec/support/certificates/client-x509.crt +78 -0
  1330. data/spec/support/certificates/client-x509.key +27 -0
  1331. data/spec/support/certificates/client-x509.pem +105 -0
  1332. data/spec/support/certificates/client.crt +74 -0
  1333. data/spec/support/certificates/client.key +27 -0
  1334. data/spec/support/certificates/client.pem +90 -90
  1335. data/spec/support/certificates/crl.pem +10 -8
  1336. data/spec/support/certificates/crl_client_revoked.pem +11 -10
  1337. data/spec/support/certificates/multi-ca.crt +152 -0
  1338. data/spec/support/certificates/python-ca.crt +76 -0
  1339. data/spec/support/certificates/server-int.crt +78 -0
  1340. data/spec/support/certificates/server-second-level-bundle.pem +179 -0
  1341. data/spec/support/certificates/server-second-level.crt +74 -0
  1342. data/spec/support/certificates/server-second-level.key +27 -0
  1343. data/spec/support/certificates/server-second-level.pem +101 -0
  1344. data/spec/support/certificates/server.pem +99 -32
  1345. data/spec/support/client_registry.rb +247 -0
  1346. data/spec/support/client_registry_macros.rb +23 -0
  1347. data/spec/support/cluster_config.rb +207 -0
  1348. data/spec/support/cluster_tools.rb +376 -0
  1349. data/spec/support/common_shortcuts.rb +342 -0
  1350. data/spec/support/constraints.rb +16 -0
  1351. data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
  1352. data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
  1353. data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
  1354. data/spec/support/crypt/corpus/corpus.json +3657 -0
  1355. data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
  1356. data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
  1357. data/spec/support/crypt/data_keys/key_document_local.json +31 -0
  1358. data/spec/support/crypt/external/external-key.json +31 -0
  1359. data/spec/support/crypt/external/external-schema.json +19 -0
  1360. data/spec/support/crypt/limits/limits-doc.json +102 -0
  1361. data/spec/support/crypt/limits/limits-key.json +31 -0
  1362. data/spec/support/crypt/limits/limits-schema.json +1405 -0
  1363. data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
  1364. data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1365. data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
  1366. data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1367. data/spec/support/crypt.rb +154 -0
  1368. data/spec/support/dns.rb +13 -0
  1369. data/spec/support/event_subscriber.rb +212 -0
  1370. data/spec/support/json_ext_formatter.rb +13 -0
  1371. data/spec/support/keyword_struct.rb +26 -0
  1372. data/spec/support/local_resource_registry.rb +34 -0
  1373. data/spec/support/matchers.rb +35 -0
  1374. data/spec/support/monitoring_ext.rb +16 -0
  1375. data/spec/support/ocsp +1 -0
  1376. data/spec/support/primary_socket.rb +21 -0
  1377. data/spec/support/sdam_formatter_integration.rb +116 -0
  1378. data/spec/support/session_registry.rb +52 -0
  1379. data/spec/support/shared/protocol.rb +2 -0
  1380. data/spec/support/shared/scram_conversation.rb +100 -0
  1381. data/spec/support/shared/server_selector.rb +109 -63
  1382. data/spec/support/shared/session.rb +907 -0
  1383. data/spec/support/spec_config.rb +560 -0
  1384. data/spec/support/spec_setup.rb +70 -0
  1385. data/spec/support/utils.rb +534 -0
  1386. data.tar.gz.sig +0 -0
  1387. metadata +2229 -653
  1388. metadata.gz.sig +0 -0
  1389. data/lib/csasl/csasl.bundle +0 -0
  1390. data/lib/mongo/cluster/app_metadata.rb +0 -146
  1391. data/lib/mongo/cluster/cursor_reaper.rb +0 -174
  1392. data/lib/mongo/cluster/topology/replica_set.rb +0 -317
  1393. data/lib/mongo/event/description_changed.rb +0 -72
  1394. data/lib/mongo/event/member_discovered.rb +0 -65
  1395. data/lib/mongo/event/primary_elected.rb +0 -55
  1396. data/lib/mongo/event/standalone_discovered.rb +0 -53
  1397. data/lib/mongo/operation/commands/aggregate/result.rb +0 -89
  1398. data/lib/mongo/operation/commands/aggregate.rb +0 -64
  1399. data/lib/mongo/operation/commands/collections_info/result.rb +0 -41
  1400. data/lib/mongo/operation/commands/collections_info.rb +0 -71
  1401. data/lib/mongo/operation/commands/command.rb +0 -47
  1402. data/lib/mongo/operation/commands/create.rb +0 -45
  1403. data/lib/mongo/operation/commands/drop.rb +0 -45
  1404. data/lib/mongo/operation/commands/drop_database.rb +0 -45
  1405. data/lib/mongo/operation/commands/find/result.rb +0 -62
  1406. data/lib/mongo/operation/commands/find.rb +0 -27
  1407. data/lib/mongo/operation/commands/get_more/result.rb +0 -62
  1408. data/lib/mongo/operation/commands/get_more.rb +0 -27
  1409. data/lib/mongo/operation/commands/indexes.rb +0 -73
  1410. data/lib/mongo/operation/commands/list_collections/result.rb +0 -94
  1411. data/lib/mongo/operation/commands/list_collections.rb +0 -48
  1412. data/lib/mongo/operation/commands/list_indexes/result.rb +0 -98
  1413. data/lib/mongo/operation/commands/list_indexes.rb +0 -48
  1414. data/lib/mongo/operation/commands/map_reduce/result.rb +0 -119
  1415. data/lib/mongo/operation/commands/map_reduce.rb +0 -60
  1416. data/lib/mongo/operation/commands/parallel_scan/result.rb +0 -64
  1417. data/lib/mongo/operation/commands/parallel_scan.rb +0 -53
  1418. data/lib/mongo/operation/commands/user_query.rb +0 -72
  1419. data/lib/mongo/operation/commands/users_info/result.rb +0 -44
  1420. data/lib/mongo/operation/commands/users_info.rb +0 -48
  1421. data/lib/mongo/operation/commands.rb +0 -29
  1422. data/lib/mongo/operation/executable.rb +0 -42
  1423. data/lib/mongo/operation/limited.rb +0 -37
  1424. data/lib/mongo/operation/object_id_generator.rb +0 -36
  1425. data/lib/mongo/operation/read/get_more.rb +0 -52
  1426. data/lib/mongo/operation/read/query/result.rb +0 -40
  1427. data/lib/mongo/operation/read/query.rb +0 -55
  1428. data/lib/mongo/operation/read.rb +0 -16
  1429. data/lib/mongo/operation/read_preference.rb +0 -61
  1430. data/lib/mongo/operation/specifiable.rb +0 -507
  1431. data/lib/mongo/operation/takes_write_concern.rb +0 -35
  1432. data/lib/mongo/operation/write/bulk/bulkable.rb +0 -83
  1433. data/lib/mongo/operation/write/bulk/delete/result.rb +0 -71
  1434. data/lib/mongo/operation/write/bulk/delete.rb +0 -71
  1435. data/lib/mongo/operation/write/bulk/insert/result.rb +0 -129
  1436. data/lib/mongo/operation/write/bulk/insert.rb +0 -96
  1437. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +0 -87
  1438. data/lib/mongo/operation/write/bulk/mergable.rb +0 -71
  1439. data/lib/mongo/operation/write/bulk/update/result.rb +0 -205
  1440. data/lib/mongo/operation/write/bulk/update.rb +0 -81
  1441. data/lib/mongo/operation/write/bulk.rb +0 -20
  1442. data/lib/mongo/operation/write/command/create_index.rb +0 -55
  1443. data/lib/mongo/operation/write/command/create_user.rb +0 -42
  1444. data/lib/mongo/operation/write/command/delete.rb +0 -56
  1445. data/lib/mongo/operation/write/command/drop_index.rb +0 -56
  1446. data/lib/mongo/operation/write/command/insert.rb +0 -66
  1447. data/lib/mongo/operation/write/command/remove_user.rb +0 -41
  1448. data/lib/mongo/operation/write/command/update.rb +0 -63
  1449. data/lib/mongo/operation/write/command/update_user.rb +0 -42
  1450. data/lib/mongo/operation/write/command/writable.rb +0 -57
  1451. data/lib/mongo/operation/write/command.rb +0 -23
  1452. data/lib/mongo/operation/write/create_index.rb +0 -67
  1453. data/lib/mongo/operation/write/create_user.rb +0 -50
  1454. data/lib/mongo/operation/write/delete/result.rb +0 -40
  1455. data/lib/mongo/operation/write/delete.rb +0 -75
  1456. data/lib/mongo/operation/write/drop_index.rb +0 -63
  1457. data/lib/mongo/operation/write/gle.rb +0 -49
  1458. data/lib/mongo/operation/write/idable.rb +0 -63
  1459. data/lib/mongo/operation/write/insert/result.rb +0 -62
  1460. data/lib/mongo/operation/write/insert.rb +0 -71
  1461. data/lib/mongo/operation/write/remove_user.rb +0 -48
  1462. data/lib/mongo/operation/write/update/result.rb +0 -160
  1463. data/lib/mongo/operation/write/update.rb +0 -85
  1464. data/lib/mongo/operation/write/update_user.rb +0 -50
  1465. data/lib/mongo/operation/write/write_command_enabled.rb +0 -62
  1466. data/lib/mongo/operation/write.rb +0 -27
  1467. data/lib/mongo/server/connectable.rb +0 -119
  1468. data/lib/mongo/server/connection_pool/queue.rb +0 -197
  1469. data/lib/mongo/server/description/inspector/description_changed.rb +0 -57
  1470. data/lib/mongo/server/description/inspector/member_discovered.rb +0 -59
  1471. data/lib/mongo/server/description/inspector/primary_elected.rb +0 -60
  1472. data/lib/mongo/server/description/inspector/standalone_discovered.rb +0 -56
  1473. data/lib/mongo/server/description/inspector.rb +0 -81
  1474. data/lib/mongo/server_selector/selectable.rb +0 -281
  1475. data/lib/mongo/write_concern/normalizable.rb +0 -52
  1476. data/spec/mongo/cluster/app_metadata_spec.rb +0 -104
  1477. data/spec/mongo/command_monitoring_spec.rb +0 -64
  1478. data/spec/mongo/connection_string_spec.rb +0 -115
  1479. data/spec/mongo/crud_spec.rb +0 -41
  1480. data/spec/mongo/gridfs_spec.rb +0 -50
  1481. data/spec/mongo/max_staleness_spec.rb +0 -126
  1482. data/spec/mongo/operation/commands/aggregate/result_spec.rb +0 -80
  1483. data/spec/mongo/operation/commands/aggregate_spec.rb +0 -72
  1484. data/spec/mongo/operation/commands/collections_info_spec.rb +0 -40
  1485. data/spec/mongo/operation/commands/command_spec.rb +0 -80
  1486. data/spec/mongo/operation/commands/indexes_spec.rb +0 -31
  1487. data/spec/mongo/operation/commands/map_reduce_spec.rb +0 -125
  1488. data/spec/mongo/operation/read/get_more_spec.rb +0 -53
  1489. data/spec/mongo/operation/read/query_spec.rb +0 -102
  1490. data/spec/mongo/operation/read_preference_spec.rb +0 -245
  1491. data/spec/mongo/operation/write/bulk/delete_spec.rb +0 -223
  1492. data/spec/mongo/operation/write/bulk/insert_spec.rb +0 -250
  1493. data/spec/mongo/operation/write/bulk/update_spec.rb +0 -220
  1494. data/spec/mongo/operation/write/command/delete_spec.rb +0 -106
  1495. data/spec/mongo/operation/write/command/insert_spec.rb +0 -105
  1496. data/spec/mongo/operation/write/command/update_spec.rb +0 -110
  1497. data/spec/mongo/operation/write/create_index_spec.rb +0 -63
  1498. data/spec/mongo/operation/write/create_user_spec.rb +0 -44
  1499. data/spec/mongo/operation/write/delete_spec.rb +0 -215
  1500. data/spec/mongo/operation/write/drop_index_spec.rb +0 -51
  1501. data/spec/mongo/operation/write/insert_spec.rb +0 -291
  1502. data/spec/mongo/operation/write/remove_user_spec.rb +0 -46
  1503. data/spec/mongo/operation/write/update_spec.rb +0 -256
  1504. data/spec/mongo/operation/write/update_user_spec.rb +0 -46
  1505. data/spec/mongo/sdam_monitoring_spec.rb +0 -60
  1506. data/spec/mongo/sdam_spec.rb +0 -84
  1507. data/spec/mongo/server/connection_pool/queue_spec.rb +0 -190
  1508. data/spec/mongo/server/description/inspector/description_changed_spec.rb +0 -78
  1509. data/spec/mongo/server/description/inspector/primary_elected_spec.rb +0 -94
  1510. data/spec/mongo/server_selection_rtt_spec.rb +0 -85
  1511. data/spec/mongo/server_selection_spec.rb +0 -93
  1512. data/spec/support/certificates/ca.pem +0 -17
  1513. data/spec/support/certificates/client_cert.pem +0 -21
  1514. data/spec/support/certificates/client_key.pem +0 -28
  1515. data/spec/support/certificates/client_key_encrypted.pem +0 -30
  1516. data/spec/support/certificates/password_protected.pem +0 -51
  1517. data/spec/support/command_monitoring/bulkWrite.yml +0 -73
  1518. data/spec/support/command_monitoring/command.yml +0 -42
  1519. data/spec/support/command_monitoring/find.yml +0 -268
  1520. data/spec/support/command_monitoring/insertMany.yml +0 -81
  1521. data/spec/support/command_monitoring/updateMany.yml +0 -67
  1522. data/spec/support/command_monitoring/updateOne.yml +0 -95
  1523. data/spec/support/command_monitoring.rb +0 -376
  1524. data/spec/support/connection_string.rb +0 -228
  1525. data/spec/support/connection_string_tests/invalid-uris.yml +0 -193
  1526. data/spec/support/connection_string_tests/valid-auth.yml +0 -256
  1527. data/spec/support/connection_string_tests/valid-options.yml +0 -30
  1528. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +0 -197
  1529. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +0 -213
  1530. data/spec/support/connection_string_tests/valid-warnings.yml +0 -55
  1531. data/spec/support/crud/read.rb +0 -154
  1532. data/spec/support/crud/write.rb +0 -224
  1533. data/spec/support/crud.rb +0 -271
  1534. data/spec/support/crud_tests/read/aggregate-out.yml +0 -28
  1535. data/spec/support/crud_tests/read/count-collation.yml +0 -15
  1536. data/spec/support/crud_tests/read/count.yml +0 -36
  1537. data/spec/support/crud_tests/write/findOneAndReplace-upsert.yml +0 -47
  1538. data/spec/support/crud_tests/write/findOneAndReplace.yml +0 -142
  1539. data/spec/support/crud_tests/write/findOneAndUpdate.yml +0 -160
  1540. data/spec/support/crud_tests/write/insertMany.yml +0 -23
  1541. data/spec/support/crud_tests/write/replaceOne-collation.yml +0 -23
  1542. data/spec/support/crud_tests/write/replaceOne.yml +0 -86
  1543. data/spec/support/crud_tests/write/updateMany-collation.yml +0 -27
  1544. data/spec/support/crud_tests/write/updateMany.yml +0 -82
  1545. data/spec/support/crud_tests/write/updateOne-collation.yml +0 -24
  1546. data/spec/support/crud_tests/write/updateOne.yml +0 -79
  1547. data/spec/support/gridfs.rb +0 -637
  1548. data/spec/support/gridfs_tests/delete.yml +0 -157
  1549. data/spec/support/gridfs_tests/download.yml +0 -210
  1550. data/spec/support/helpers.rb +0 -140
  1551. data/spec/support/max_staleness/Unknown/SmallMaxStaleness.yml +0 -14
  1552. data/spec/support/sdam/rs/discover_arbiters.yml +0 -41
  1553. data/spec/support/sdam/rs/discover_passives.yml +0 -77
  1554. data/spec/support/sdam/rs/discover_primary.yml +0 -40
  1555. data/spec/support/sdam/rs/discover_secondary.yml +0 -41
  1556. data/spec/support/sdam/rs/discovery.yml +0 -195
  1557. data/spec/support/sdam/rs/equal_electionids.yml +0 -48
  1558. data/spec/support/sdam/rs/ghost_discovered.yml +0 -39
  1559. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +0 -34
  1560. data/spec/support/sdam/rs/member_reconfig.yml +0 -68
  1561. data/spec/support/sdam/rs/member_standalone.yml +0 -60
  1562. data/spec/support/sdam/rs/new_primary.yml +0 -74
  1563. data/spec/support/sdam/rs/new_primary_new_electionid.yml +0 -101
  1564. data/spec/support/sdam/rs/new_primary_new_setversion.yml +0 -101
  1565. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +0 -71
  1566. data/spec/support/sdam/rs/non_rs_member.yml +0 -31
  1567. data/spec/support/sdam/rs/normalize_case.yml +0 -49
  1568. data/spec/support/sdam/rs/null_election_id.yml +0 -152
  1569. data/spec/support/sdam/rs/primary_becomes_standalone.yml +0 -52
  1570. data/spec/support/sdam/rs/primary_changes_set_name.yml +0 -57
  1571. data/spec/support/sdam/rs/primary_disconnect.yml +0 -56
  1572. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +0 -159
  1573. data/spec/support/sdam/rs/primary_disconnect_setversion.yml +0 -159
  1574. data/spec/support/sdam/rs/primary_mismatched_me.yml +0 -37
  1575. data/spec/support/sdam/rs/primary_reports_new_member.yml +0 -163
  1576. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +0 -75
  1577. data/spec/support/sdam/rs/primary_wrong_set_name.yml +0 -27
  1578. data/spec/support/sdam/rs/response_from_removed.yml +0 -63
  1579. data/spec/support/sdam/rs/rsother_discovered.yml +0 -62
  1580. data/spec/support/sdam/rs/sec_not_auth.yml +0 -49
  1581. data/spec/support/sdam/rs/secondary_mismatched_me.yml +0 -37
  1582. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +0 -28
  1583. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +0 -69
  1584. data/spec/support/sdam/rs/set_version_without_electionid.yml +0 -69
  1585. data/spec/support/sdam/rs/setversion_without_electionid.yml +0 -69
  1586. data/spec/support/sdam/rs/stepdown_change_set_name.yml +0 -59
  1587. data/spec/support/sdam/rs/unexpected_mongos.yml +0 -26
  1588. data/spec/support/sdam/rs/use_setversion_without_electionid.yml +0 -99
  1589. data/spec/support/sdam/rs/wrong_set_name.yml +0 -35
  1590. data/spec/support/sdam/sharded/mongos_disconnect.yml +0 -104
  1591. data/spec/support/sdam/sharded/multiple_mongoses.yml +0 -46
  1592. data/spec/support/sdam/sharded/non_mongos_removed.yml +0 -41
  1593. data/spec/support/sdam/sharded/normalize_uri_case.yml +0 -32
  1594. data/spec/support/sdam/sharded/single_mongos.yml +0 -33
  1595. data/spec/support/sdam/single/direct_connection_external_ip.yml +0 -34
  1596. data/spec/support/sdam/single/direct_connection_mongos.yml +0 -33
  1597. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +0 -35
  1598. data/spec/support/sdam/single/direct_connection_rsprimary.yml +0 -34
  1599. data/spec/support/sdam/single/direct_connection_rssecondary.yml +0 -35
  1600. data/spec/support/sdam/single/direct_connection_slave.yml +0 -32
  1601. data/spec/support/sdam/single/direct_connection_standalone.yml +0 -32
  1602. data/spec/support/sdam/single/not_ok_response.yml +0 -38
  1603. data/spec/support/sdam/single/standalone_removed.yml +0 -32
  1604. data/spec/support/sdam/single/unavailable_seed.yml +0 -28
  1605. data/spec/support/sdam_monitoring/replica_set_with_removal.yml +0 -106
  1606. data/spec/support/sdam_monitoring/required_replica_set.yml +0 -84
  1607. data/spec/support/sdam_monitoring/standalone.yml +0 -70
  1608. data/spec/support/sdam_monitoring.rb +0 -144
  1609. data/spec/support/server_discovery_and_monitoring.rb +0 -219
  1610. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +0 -26
  1611. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_multiple.yml +0 -27
  1612. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +0 -21
  1613. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +0 -21
  1614. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +0 -26
  1615. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +0 -21
  1616. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +0 -26
  1617. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +0 -26
  1618. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +0 -21
  1619. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +0 -21
  1620. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +0 -33
  1621. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_multiple.yml +0 -34
  1622. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +0 -26
  1623. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +0 -29
  1624. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +0 -29
  1625. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +0 -29
  1626. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary.yml +0 -31
  1627. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +0 -31
  1628. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +0 -29
  1629. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +0 -26
  1630. data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +0 -26
  1631. data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +0 -19
  1632. data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +0 -11
  1633. data/spec/support/server_selection.rb +0 -163
  1634. data/spec/support/server_selection_rtt.rb +0 -41
  1635. data/spec/support/travis.rb +0 -14
  1636. /data/spec/{support → spec_tests/data}/command_monitoring/deleteMany.yml +0 -0
  1637. /data/spec/{support → spec_tests/data}/command_monitoring/deleteOne.yml +0 -0
  1638. /data/spec/{support → spec_tests/data}/command_monitoring/insertOne.yml +0 -0
  1639. /data/spec/{support/connection_string_tests → spec_tests/data/connection_string}/valid-host_identifiers.yml +0 -0
  1640. /data/spec/{support/crud_tests → spec_tests/data/crud}/read/aggregate-collation.yml +0 -0
  1641. /data/spec/{support/crud_tests → spec_tests/data/crud}/read/aggregate.yml +0 -0
  1642. /data/spec/{support/crud_tests → spec_tests/data/crud}/read/distinct-collation.yml +0 -0
  1643. /data/spec/{support/crud_tests → spec_tests/data/crud}/read/distinct.yml +0 -0
  1644. /data/spec/{support/crud_tests → spec_tests/data/crud}/read/find-collation.yml +0 -0
  1645. /data/spec/{support/crud_tests → spec_tests/data/crud}/read/find.yml +0 -0
  1646. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteMany-collation.yml +0 -0
  1647. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteMany.yml +0 -0
  1648. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteOne-collation.yml +0 -0
  1649. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/deleteOne.yml +0 -0
  1650. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndDelete-collation.yml +0 -0
  1651. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndDelete.yml +0 -0
  1652. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndReplace-collation.yml +0 -0
  1653. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/findOneAndUpdate-collation.yml +0 -0
  1654. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/insertOne.yml +0 -0
  1655. /data/spec/{support/crud_tests → spec_tests/data/crud}/write/replaceOne-upsert.yml +0 -0
  1656. /data/spec/{support/gridfs_tests → spec_tests/data/gridfs}/download_by_name.yml +0 -0
  1657. /data/spec/{support/gridfs_tests → spec_tests/data/gridfs}/upload.yml +0 -0
  1658. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +0 -0
  1659. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Incompatible.yml +0 -0
  1660. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +0 -0
  1661. /data/spec/{support/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml → spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml} +0 -0
  1662. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Nearest.yml +0 -0
  1663. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +0 -0
  1664. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +0 -0
  1665. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +0 -0
  1666. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/Secondary.yml +0 -0
  1667. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +0 -0
  1668. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +0 -0
  1669. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +0 -0
  1670. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +0 -0
  1671. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Incompatible.yml +0 -0
  1672. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +0 -0
  1673. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +0 -0
  1674. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +0 -0
  1675. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +0 -0
  1676. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +0 -0
  1677. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Nearest.yml +0 -0
  1678. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +0 -0
  1679. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +0 -0
  1680. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +0 -0
  1681. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.yml +0 -0
  1682. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +0 -0
  1683. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +0 -0
  1684. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +0 -0
  1685. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +0 -0
  1686. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +0 -0
  1687. /data/spec/{support → spec_tests/data}/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +0 -0
  1688. /data/spec/{support → spec_tests/data}/max_staleness/Sharded/Incompatible.yml +0 -0
  1689. /data/spec/{support → spec_tests/data}/max_staleness/Sharded/SmallMaxStaleness.yml +0 -0
  1690. /data/spec/{support → spec_tests/data}/max_staleness/Single/Incompatible.yml +0 -0
  1691. /data/spec/{support → spec_tests/data}/max_staleness/Single/SmallMaxStaleness.yml +0 -0
  1692. /data/spec/{support → spec_tests/data}/sdam_monitoring/replica_set_with_no_primary.yml +0 -0
  1693. /data/spec/{support → spec_tests/data}/sdam_monitoring/replica_set_with_primary.yml +0 -0
  1694. /data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Secondary_multi_tags.yml +0 -0
  1695. /data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetNoPrimary/read/Secondary_multi_tags2.yml +0 -0
  1696. /data/spec/{support/server_selection/selection → spec_tests/data/server_selection}/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.yml +0 -0
  1697. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/first_value.yml +0 -0
  1698. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/first_value_zero.yml +0 -0
  1699. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_1.yml +0 -0
  1700. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_2.yml +0 -0
  1701. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_3.yml +0 -0
  1702. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_4.yml +0 -0
  1703. /data/spec/{support/server_selection/rtt → spec_tests/data/server_selection_rtt}/value_test_5.yml +0 -0
@@ -2,12 +2,22 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongo::Collection do
4
4
 
5
- after do
6
- authorized_collection.delete_many
5
+ let(:subscriber) { EventSubscriber.new }
6
+
7
+ let(:client) do
8
+ authorized_client.tap do |client|
9
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
10
+ end
11
+ end
12
+
13
+ let(:authorized_collection) { client['collection_spec'] }
14
+
15
+ before do
16
+ authorized_client['collection_spec'].drop
7
17
  end
8
18
 
9
19
  let(:collection_invalid_write_concern) do
10
- authorized_collection.client.with(write: { w: (WRITE_CONCERN[:w] + 1) })[authorized_collection.name]
20
+ authorized_collection.client.with(write: INVALID_WRITE_CONCERN)[authorized_collection.name]
11
21
  end
12
22
 
13
23
  let(:collection_with_validator) do
@@ -94,18 +104,116 @@ describe Mongo::Collection do
94
104
  end
95
105
  end
96
106
 
107
+ describe '#initialize' do
108
+
109
+ let(:client) do
110
+ new_local_client(SpecConfig.instance.addresses,
111
+ SpecConfig.instance.test_options.merge(monitoring_io: false))
112
+ end
113
+
114
+ let(:database) { client.database }
115
+
116
+ context 'write concern given in :write option' do
117
+ let(:collection) do
118
+ Mongo::Collection.new(database, 'foo', write: {w: 1})
119
+ end
120
+
121
+ it 'stores write concern' do
122
+ expect(collection.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
123
+ expect(collection.write_concern.options).to eq(w: 1)
124
+ end
125
+
126
+ it 'stores write concern under :write' do
127
+ expect(collection.options[:write]).to eq(w: 1)
128
+ expect(collection.options[:write_concern]).to be nil
129
+ end
130
+ end
131
+
132
+ context 'write concern given in :write_concern option' do
133
+ let(:collection) do
134
+ Mongo::Collection.new(database, 'foo', write_concern: {w: 1})
135
+ end
136
+
137
+ it 'stores write concern' do
138
+ expect(collection.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
139
+ expect(collection.write_concern.options).to eq(w: 1)
140
+ end
141
+
142
+ it 'stores write concern under :write_concern' do
143
+ expect(collection.options[:write_concern]).to eq(w: 1)
144
+ expect(collection.options[:write]).to be nil
145
+ end
146
+ end
147
+
148
+ context 'write concern given in both :write and :write_concern options' do
149
+ context 'identical values' do
150
+
151
+ let(:collection) do
152
+ Mongo::Collection.new(database, 'foo',
153
+ write: {w: 1}, write_concern: {w: 1})
154
+ end
155
+
156
+ it 'stores write concern' do
157
+ expect(collection.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
158
+ expect(collection.write_concern.options).to eq(w: 1)
159
+ end
160
+
161
+ it 'stores write concern under both options' do
162
+ expect(collection.options[:write]).to eq(w: 1)
163
+ expect(collection.options[:write_concern]).to eq(w: 1)
164
+ end
165
+ end
166
+
167
+ context 'different values' do
168
+
169
+ let(:collection) do
170
+ Mongo::Collection.new(database, 'foo',
171
+ write: {w: 1}, write_concern: {w: 2})
172
+ end
173
+
174
+ it 'raises an exception' do
175
+ expect do
176
+ collection
177
+ end.to raise_error(ArgumentError, /If :write and :write_concern are both given, they must be identical/)
178
+ end
179
+ end
180
+ end
181
+
182
+ =begin WriteConcern object support
183
+ context 'when write concern is provided via a WriteConcern object' do
184
+
185
+ let(:collection) do
186
+ Mongo::Collection.new(database, 'foo', write_concern: wc)
187
+ end
188
+
189
+ let(:wc) { Mongo::WriteConcern.get(w: 2) }
190
+
191
+ it 'stores write concern options in collection options' do
192
+ expect(collection.options[:write_concern]).to eq(w: 2)
193
+ end
194
+
195
+ it 'caches write concern object' do
196
+ expect(collection.write_concern).to be wc
197
+ end
198
+ end
199
+ =end
200
+ end
201
+
97
202
  describe '#with' do
98
203
 
99
204
  let(:client) do
100
- Mongo::Client.new(ADDRESSES)
205
+ new_local_client_nmio(SpecConfig.instance.addresses,
206
+ SpecConfig.instance.test_options.merge(
207
+ SpecConfig.instance.auth_options
208
+ ))
101
209
  end
102
210
 
103
211
  let(:database) do
104
- Mongo::Database.new(client, :test)
212
+ Mongo::Database.new(client, SpecConfig.instance.test_db)
105
213
  end
106
214
 
107
215
  let(:collection) do
108
- database.collection(:users)
216
+ database.collection('test-collection')
109
217
  end
110
218
 
111
219
  let(:new_collection) do
@@ -123,13 +231,14 @@ describe Mongo::Collection do
123
231
  end
124
232
 
125
233
  it 'sets the new read options on the new collection' do
126
- expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
234
+ expect(new_collection.read_preference).to eq(new_options[:read])
127
235
  end
128
236
 
129
237
  context 'when the client has a server selection timeout setting' do
130
238
 
131
239
  let(:client) do
132
- Mongo::Client.new(ADDRESSES, server_selection_timeout: 2)
240
+ new_local_client(SpecConfig.instance.addresses,
241
+ SpecConfig.instance.test_options.merge(server_selection_timeout: 2, monitoring_io: false))
133
242
  end
134
243
 
135
244
  it 'passes the the server_selection_timeout to the cluster' do
@@ -140,23 +249,105 @@ describe Mongo::Collection do
140
249
  context 'when the client has a read preference set' do
141
250
 
142
251
  let(:client) do
143
- Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred })
252
+ authorized_client.with(client_options).tap do |client|
253
+ expect(client.options[:read]).to eq(Mongo::Options::Redacted.new(
254
+ mode: :primary_preferred))
255
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
256
+ end
257
+ end
258
+
259
+ let(:client_options) do
260
+ {
261
+ read: { mode: :primary_preferred },
262
+ monitoring_io: false,
263
+ }
264
+ end
265
+
266
+ let(:new_options) do
267
+ { read: { mode: :secondary } }
144
268
  end
145
269
 
146
270
  it 'sets the new read options on the new collection' do
147
- expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
148
- expect(new_collection.read_preference).not_to eq(client.read_preference)
271
+ # This is strictly a Hash, not a BSON::Document like the client's
272
+ # read preference.
273
+ expect(new_collection.read_preference).to eq(mode: :secondary)
274
+ end
275
+
276
+ it 'duplicates the read option' do
277
+ expect(new_collection.read_preference).not_to eql(client.read_preference)
278
+ end
279
+
280
+ context 'when reading from collection' do
281
+ # Since we are requesting a secondary read, we need a replica set.
282
+ require_topology :replica_set
283
+
284
+ let(:client_options) do
285
+ {read: { mode: :primary_preferred }}
286
+ end
287
+
288
+ shared_examples_for "uses collection's read preference when reading" do
289
+ it "uses collection's read preference when reading" do
290
+ expect do
291
+ new_collection.find.to_a.count
292
+ end.not_to raise_error
293
+
294
+ event = subscriber.started_events.detect do |event|
295
+ event.command['find']
296
+ end
297
+ actual_rp = event.command['$readPreference']
298
+ expect(actual_rp).to eq(expected_read_preference)
299
+ end
300
+ end
301
+
302
+ context 'post-OP_MSG server' do
303
+ min_server_fcv '3.6'
304
+
305
+ context 'standalone' do
306
+ require_topology :single
307
+
308
+ let(:expected_read_preference) do
309
+ nil
310
+ end
311
+
312
+ it_behaves_like "uses collection's read preference when reading"
313
+ end
314
+
315
+ context 'RS, sharded' do
316
+ require_topology :replica_set, :sharded
317
+
318
+ let(:expected_read_preference) do
319
+ {'mode' => 'secondary'}
320
+ end
321
+
322
+ it_behaves_like "uses collection's read preference when reading"
323
+ end
324
+ end
325
+
326
+ context 'pre-OP-MSG server' do
327
+ max_server_version '3.4'
328
+
329
+ let(:expected_read_preference) do
330
+ nil
331
+ end
332
+
333
+ it_behaves_like "uses collection's read preference when reading"
334
+ end
149
335
  end
150
336
  end
151
337
 
152
338
  context 'when the client has a read preference and server selection timeout set' do
153
339
 
154
340
  let(:client) do
155
- Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred }, server_selection_timeout: 2)
341
+ new_local_client(SpecConfig.instance.addresses,
342
+ SpecConfig.instance.test_options.merge(
343
+ read: { mode: :primary_preferred },
344
+ server_selection_timeout: 2,
345
+ monitoring_io: false
346
+ ))
156
347
  end
157
348
 
158
349
  it 'sets the new read options on the new collection' do
159
- expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
350
+ expect(new_collection.read_preference).to eq(new_options[:read])
160
351
  end
161
352
 
162
353
  it 'passes the server_selection_timeout setting to the cluster' do
@@ -182,12 +373,116 @@ describe Mongo::Collection do
182
373
  context 'when the client has a write concern set' do
183
374
 
184
375
  let(:client) do
185
- Mongo::Client.new(ADDRESSES, write: { w: 10 })
376
+ new_local_client(SpecConfig.instance.addresses,
377
+ SpecConfig.instance.test_options.merge(
378
+ write: INVALID_WRITE_CONCERN,
379
+ monitoring_io: false,
380
+ ))
186
381
  end
187
382
 
188
383
  it 'sets the new write options on the new collection' do
189
384
  expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
190
385
  end
386
+
387
+ context 'when client uses :write_concern and collection uses :write' do
388
+
389
+ let(:client) do
390
+ new_local_client(SpecConfig.instance.addresses,
391
+ SpecConfig.instance.test_options.merge(
392
+ write_concern: {w: 1},
393
+ monitoring_io: false,
394
+ ))
395
+ end
396
+
397
+ it 'uses :write from collection options only' do
398
+ expect(new_collection.options[:write]).to eq(w: 5)
399
+ expect(new_collection.options[:write_concern]).to be nil
400
+ end
401
+ end
402
+
403
+ context 'when client uses :write and collection uses :write_concern' do
404
+
405
+ let(:client) do
406
+ new_local_client(SpecConfig.instance.addresses,
407
+ SpecConfig.instance.test_options.merge(
408
+ write: {w: 1},
409
+ monitoring_io: false,
410
+ ))
411
+ end
412
+
413
+ let(:new_options) do
414
+ { write_concern: { w: 5 } }
415
+ end
416
+
417
+ it 'uses :write_concern from collection options only' do
418
+ expect(new_collection.options[:write_concern]).to eq(w: 5)
419
+ expect(new_collection.options[:write]).to be nil
420
+ end
421
+ end
422
+
423
+ context 'when collection previously had :wrte_concern and :write is used with a different value' do
424
+
425
+ let(:collection) do
426
+ database.collection(:users, write_concern: {w: 2})
427
+ end
428
+
429
+ let(:new_options) do
430
+ { write: { w: 5 } }
431
+ end
432
+
433
+ it 'uses the new option' do
434
+ expect(new_collection.options[:write]).to eq(w: 5)
435
+ expect(new_collection.options[:write_concern]).to be nil
436
+ end
437
+ end
438
+
439
+ context 'when collection previously had :wrte and :write_concern is used with a different value' do
440
+
441
+ let(:collection) do
442
+ database.collection(:users, write: {w: 2})
443
+ end
444
+
445
+ let(:new_options) do
446
+ { write_concern: { w: 5 } }
447
+ end
448
+
449
+ it 'uses the new option' do
450
+ expect(new_collection.options[:write_concern]).to eq(w: 5)
451
+ expect(new_collection.options[:write]).to be nil
452
+ end
453
+ end
454
+
455
+ context 'when collection previously had :wrte_concern and :write is used with the same value' do
456
+
457
+ let(:collection) do
458
+ database.collection(:users, write_concern: {w: 2})
459
+ end
460
+
461
+ let(:new_options) do
462
+ { write: { w: 2 } }
463
+ end
464
+
465
+ it 'uses the new option' do
466
+ expect(new_collection.options[:write]).to eq(w: 2)
467
+ expect(new_collection.options[:write_concern]).to be nil
468
+ end
469
+ end
470
+
471
+ context 'when collection previously had :wrte and :write_concern is used with the same value' do
472
+
473
+ let(:collection) do
474
+ database.collection(:users, write: {w: 2})
475
+ end
476
+
477
+ let(:new_options) do
478
+ { write_concern: { w: 2 } }
479
+ end
480
+
481
+ it 'uses the new option' do
482
+ expect(new_collection.options[:write]).to be nil
483
+ expect(new_collection.options[:write_concern]).to eq(w: 2)
484
+ end
485
+ end
191
486
  end
192
487
  end
193
488
 
@@ -205,7 +500,7 @@ describe Mongo::Collection do
205
500
  end
206
501
 
207
502
  it 'sets the new read options on the new collection' do
208
- expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
503
+ expect(new_collection.read_preference).to eq(new_options[:read])
209
504
  end
210
505
 
211
506
  it 'sets the new write options on the new collection' do
@@ -215,7 +510,11 @@ describe Mongo::Collection do
215
510
  context 'when the client has a server selection timeout setting' do
216
511
 
217
512
  let(:client) do
218
- Mongo::Client.new(ADDRESSES, server_selection_timeout: 2)
513
+ new_local_client(SpecConfig.instance.addresses,
514
+ SpecConfig.instance.test_options.merge(
515
+ server_selection_timeout: 2,
516
+ monitoring_io: false,
517
+ ))
219
518
  end
220
519
 
221
520
  it 'passes the server_selection_timeout setting to the cluster' do
@@ -226,11 +525,15 @@ describe Mongo::Collection do
226
525
  context 'when the client has a read preference set' do
227
526
 
228
527
  let(:client) do
229
- Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred })
528
+ new_local_client(SpecConfig.instance.addresses,
529
+ SpecConfig.instance.test_options.merge(
530
+ read: { mode: :primary_preferred },
531
+ monitoring_io: false,
532
+ ))
230
533
  end
231
534
 
232
535
  it 'sets the new read options on the new collection' do
233
- expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
536
+ expect(new_collection.read_preference).to eq(new_options[:read])
234
537
  expect(new_collection.read_preference).not_to be(client.read_preference)
235
538
  end
236
539
  end
@@ -250,6 +553,96 @@ describe Mongo::Collection do
250
553
  end
251
554
  end
252
555
 
556
+ describe '#read_preference' do
557
+
558
+ let(:collection) do
559
+ described_class.new(authorized_client.database, :users, options)
560
+ end
561
+
562
+ let(:options) { {} }
563
+
564
+ context 'when a read preference is set in the options' do
565
+
566
+ let(:options) do
567
+ { read: { mode: :secondary } }
568
+ end
569
+
570
+ it 'returns the read preference' do
571
+ expect(collection.read_preference).to eq(options[:read])
572
+ end
573
+ end
574
+
575
+ context 'when a read preference is not set in the options' do
576
+
577
+ context 'when the database has a read preference set' do
578
+
579
+ let(:client) do
580
+ authorized_client.with(read: { mode: :secondary_preferred })
581
+ end
582
+
583
+ let(:collection) do
584
+ described_class.new(client.database, :users, options)
585
+ end
586
+
587
+ it 'returns the database read preference' do
588
+ expect(collection.read_preference).to eq(BSON::Document.new({ mode: :secondary_preferred }))
589
+ end
590
+ end
591
+
592
+ context 'when the database does not have a read preference' do
593
+
594
+ it 'returns nil' do
595
+ expect(collection.read_preference).to be_nil
596
+ end
597
+ end
598
+ end
599
+ end
600
+
601
+ describe '#server_selector' do
602
+
603
+ let(:collection) do
604
+ described_class.new(authorized_client.database, :users, options)
605
+ end
606
+
607
+ let(:options) { {} }
608
+
609
+ context 'when a read preference is set in the options' do
610
+
611
+ let(:options) do
612
+ { read: { mode: :secondary } }
613
+ end
614
+
615
+ it 'returns the server selector for that read preference' do
616
+ expect(collection.server_selector).to be_a(Mongo::ServerSelector::Secondary)
617
+ end
618
+ end
619
+
620
+ context 'when a read preference is not set in the options' do
621
+
622
+ context 'when the database has a read preference set' do
623
+
624
+ let(:client) do
625
+ authorized_client.with(read: { mode: :secondary_preferred })
626
+ end
627
+
628
+ let(:collection) do
629
+ described_class.new(client.database, :users, options)
630
+ end
631
+
632
+ it 'returns the server selector for that read preference' do
633
+ expect(collection.server_selector).to be_a(Mongo::ServerSelector::SecondaryPreferred)
634
+ end
635
+ end
636
+
637
+ context 'when the database does not have a read preference' do
638
+
639
+ it 'returns a primary server selector' do
640
+ expect(collection.server_selector).to be_a(Mongo::ServerSelector::Primary)
641
+ end
642
+ end
643
+ end
644
+ end
645
+
253
646
  describe '#capped?' do
254
647
 
255
648
  let(:database) do
@@ -263,13 +656,10 @@ describe Mongo::Collection do
263
656
  end
264
657
 
265
658
  before do
659
+ authorized_client[:specs].drop
266
660
  collection.create
267
661
  end
268
662
 
269
- after do
270
- collection.drop
271
- end
272
-
273
663
  it 'returns true' do
274
664
  expect(collection).to be_capped
275
665
  end
@@ -282,13 +672,10 @@ describe Mongo::Collection do
282
672
  end
283
673
 
284
674
  before do
675
+ authorized_client[:specs].drop
285
676
  collection.create
286
677
  end
287
678
 
288
- after do
289
- collection.drop
290
- end
291
-
292
679
  it 'returns false' do
293
680
  expect(collection).to_not be_capped
294
681
  end
@@ -296,6 +683,9 @@ describe Mongo::Collection do
296
683
  end
297
684
 
298
685
  describe '#create' do
686
+ before do
687
+ authorized_client[:specs].drop
688
+ end
299
689
 
300
690
  let(:database) do
301
691
  authorized_client.database
@@ -311,10 +701,6 @@ describe Mongo::Collection do
311
701
  collection.create
312
702
  end
313
703
 
314
- after do
315
- collection.drop
316
- end
317
-
318
704
  it 'executes the command' do
319
705
  expect(response).to be_successful
320
706
  end
@@ -338,10 +724,6 @@ describe Mongo::Collection do
338
724
  { :capped => true, :size => 1024 }
339
725
  end
340
726
 
341
- after do
342
- collection.drop
343
- end
344
-
345
727
  it 'executes the command' do
346
728
  expect(response).to be_successful
347
729
  end
@@ -370,10 +752,6 @@ describe Mongo::Collection do
370
752
  database.list_collections.find { |i| i['name'] == 'specs' }
371
753
  end
372
754
 
373
- after do
374
- collection.drop
375
- end
376
-
377
755
  it 'executes the command' do
378
756
  expect(response).to be_successful
379
757
  end
@@ -395,7 +773,8 @@ describe Mongo::Collection do
395
773
 
396
774
  it_behaves_like 'a capped collection command'
397
775
 
398
- context 'when validators can be set', if: find_command_enabled? do
776
+ context 'when validators can be set' do
777
+ min_server_fcv '3.2'
399
778
  it_behaves_like 'a validated collection command'
400
779
  end
401
780
  end
@@ -408,7 +787,8 @@ describe Mongo::Collection do
408
787
 
409
788
  it_behaves_like 'a capped collection command'
410
789
 
411
- context 'when validators can be set', if: find_command_enabled? do
790
+ context 'when validators can be set' do
791
+ min_server_fcv '3.2'
412
792
  it_behaves_like 'a validated collection command'
413
793
  end
414
794
  end
@@ -416,13 +796,13 @@ describe Mongo::Collection do
416
796
 
417
797
  context 'when the collection has a write concern' do
418
798
 
419
- after do
799
+ before do
420
800
  database[:specs].drop
421
801
  end
422
802
 
423
803
  let(:options) do
424
804
  {
425
- write: { w: WRITE_CONCERN[:w] + 1}
805
+ write: INVALID_WRITE_CONCERN
426
806
  }
427
807
  end
428
808
 
@@ -430,7 +810,9 @@ describe Mongo::Collection do
430
810
  described_class.new(database, :specs, options)
431
811
  end
432
812
 
433
- context 'when the server supports write concern on the create command', if: replica_set? && collation_enabled? do
813
+ context 'when the server supports write concern on the create command' do
814
+ min_server_fcv '3.4'
815
+ require_topology :replica_set
434
816
 
435
817
  it 'applies the write concern' do
436
818
  expect{
@@ -439,7 +821,40 @@ describe Mongo::Collection do
439
821
  end
440
822
  end
441
823
 
442
- context 'when the server does not support write concern on the create command', unless: collation_enabled? do
824
+ context 'when write concern passed in as an option' do
825
+ min_server_fcv '3.4'
826
+ require_topology :replica_set
827
+
828
+ before do
829
+ database['collection_spec'].drop
830
+ end
831
+
832
+ let(:events) do
833
+ subscriber.command_started_events('create')
834
+ end
835
+
836
+ let(:options) do
837
+ { write_concern: {w: 1} }
838
+ end
839
+
840
+ let!(:collection) do
841
+ authorized_collection.with(options)
842
+ end
843
+
844
+ let!(:command) do
845
+ Utils.get_command_event(authorized_client, 'create') do |client|
846
+ collection.create({ write_concern: {w: 2} })
847
+ end.command
848
+ end
849
+
850
+ it 'applies the write concern passed in as an option' do
851
+ expect(events.length).to eq(1)
852
+ expect(command[:writeConcern][:w]).to eq(2)
853
+ end
854
+ end
855
+
856
+ context 'when the server does not support write concern on the create command' do
857
+ max_server_version '3.2'
443
858
 
444
859
  it 'does not apply the write concern' do
445
860
  expect(collection.create).to be_successful
@@ -463,11 +878,12 @@ describe Mongo::Collection do
463
878
  database.list_collections.find { |i| i['name'] == 'specs' }
464
879
  end
465
880
 
466
- after do
881
+ before do
467
882
  collection.drop
468
883
  end
469
884
 
470
- context 'when the server supports collations', if: collation_enabled? do
885
+ context 'when the server supports collations' do
886
+ min_server_fcv '3.4'
471
887
 
472
888
  it 'executes the command' do
473
889
  expect(response).to be_successful
@@ -484,7 +900,8 @@ describe Mongo::Collection do
484
900
  end
485
901
  end
486
902
 
487
- context 'when the server does not support collations', unless: collation_enabled? do
903
+ context 'when the server does not support collations' do
904
+ max_server_version '3.2'
488
905
 
489
906
  it 'raises an error' do
490
907
  expect {
@@ -525,31 +942,116 @@ describe Mongo::Collection do
525
942
  it_behaves_like 'a collection command with a collation option'
526
943
  end
527
944
  end
528
- end
529
- end
530
945
 
531
- describe '#drop' do
946
+ context 'when a session is provided' do
532
947
 
533
- let(:database) do
534
- authorized_client.database
535
- end
948
+ let(:collection) do
949
+ authorized_client[:specs]
950
+ end
536
951
 
537
- let(:collection) do
538
- described_class.new(database, :specs)
539
- end
952
+ let(:operation) do
953
+ collection.create(session: session)
954
+ end
540
955
 
541
- context 'when the collection exists' do
542
- before do
543
- collection.create
544
- end
956
+ let(:session) do
957
+ authorized_client.start_session
958
+ end
545
959
 
546
- context 'when the collection does not have a write concern set' do
960
+ let(:client) do
961
+ authorized_client
962
+ end
547
963
 
548
- let!(:response) do
549
- collection.drop
964
+ let(:failed_operation) do
965
+ authorized_client[:specs, invalid: true].create(session: session)
550
966
  end
551
967
 
552
- it 'executes the command' do
968
+ before do
969
+ collection.drop
970
+ end
971
+
972
+ it_behaves_like 'an operation using a session'
973
+ it_behaves_like 'a failed operation using a session'
974
+ end
975
+ end
976
+
977
+ context 'when collation has a strength' do
978
+ min_server_fcv '3.4'
979
+
980
+ let(:band_collection) do
981
+ described_class.new(database, :bands)
982
+ end
983
+
984
+ before do
985
+ band_collection.delete_many
986
+ band_collection.insert_many([{ name: "Depeche Mode" }, { name: "New Order" }])
987
+ end
988
+
989
+ let(:options) do
990
+ { collation: { locale: 'en_US', strength: 2 } }
991
+ end
992
+ let(:band_result) do
993
+ band_collection.find({ name: 'DEPECHE MODE' }, options)
994
+ end
995
+
996
+ it 'finds Capitalize from UPPER CASE' do
997
+ expect(band_result.count_documents).to eq(1)
998
+ end
999
+ end
1000
+ end
1001
+
1002
+ describe '#drop' do
1003
+
1004
+ let(:database) do
1005
+ authorized_client.database
1006
+ end
1007
+
1008
+ let(:collection) do
1009
+ described_class.new(database, :specs)
1010
+ end
1011
+
1012
+ context 'when the collection exists' do
1013
+
1014
+ before do
1015
+ authorized_client[:specs].drop
1016
+ collection.create
1017
+ # wait for the collection to be created
1018
+ sleep 0.4
1019
+ end
1020
+
1021
+ context 'when a session is provided' do
1022
+
1023
+ let(:operation) do
1024
+ collection.drop(session: session)
1025
+ end
1026
+
1027
+ let(:failed_operation) do
1028
+ collection.with(write: INVALID_WRITE_CONCERN).drop(session: session)
1029
+ end
1030
+
1031
+ let(:session) do
1032
+ authorized_client.start_session
1033
+ end
1034
+
1035
+ let(:client) do
1036
+ authorized_client
1037
+ end
1038
+
1039
+ it_behaves_like 'an operation using a session'
1040
+
1041
+ context 'can set write concern' do
1042
+ require_set_write_concern
1043
+
1044
+ it_behaves_like 'a failed operation using a session'
1045
+ end
1046
+ end
1047
+
1048
+ context 'when the collection does not have a write concern set' do
1049
+
1050
+ let!(:response) do
1051
+ collection.drop
1052
+ end
1053
+
1054
+ it 'executes the command' do
553
1055
  expect(response).to be_successful
554
1056
  end
555
1057
 
@@ -558,6 +1060,7 @@ describe Mongo::Collection do
558
1060
  end
559
1061
 
560
1062
  context 'when the collection does not exist' do
1063
+ require_set_write_concern
561
1064
 
562
1065
  it 'does not raise an error' do
563
1066
  expect(database['non-existent-coll'].drop).to be(false)
@@ -569,7 +1072,7 @@ describe Mongo::Collection do
569
1072
 
570
1073
  let(:write_options) do
571
1074
  {
572
- write: { w: WRITE_CONCERN[:w] + 1}
1075
+ write: INVALID_WRITE_CONCERN
573
1076
  }
574
1077
  end
575
1078
 
@@ -577,11 +1080,9 @@ describe Mongo::Collection do
577
1080
  collection.with(write_options)
578
1081
  end
579
1082
 
580
- after do
581
- collection.drop
582
- end
583
-
584
- context 'when the server supports write concern on the drop command', if: collation_enabled? do
1083
+ context 'when the server supports write concern on the drop command' do
1084
+ min_server_fcv '3.4'
1085
+ require_set_write_concern
585
1086
 
586
1087
  it 'applies the write concern' do
587
1088
  expect{
@@ -590,7 +1091,36 @@ describe Mongo::Collection do
590
1091
  end
591
1092
  end
592
1093
 
593
- context 'when the server does not support write concern on the drop command', unless: collation_enabled? do
1094
+ context 'when write concern passed in as an option' do
1095
+ min_server_fcv '3.4'
1096
+ require_set_write_concern
1097
+
1098
+ let(:events) do
1099
+ subscriber.command_started_events('drop')
1100
+ end
1101
+
1102
+ let(:options) do
1103
+ { write_concern: {w: 1} }
1104
+ end
1105
+
1106
+ let!(:collection) do
1107
+ authorized_collection.with(options)
1108
+ end
1109
+
1110
+ let!(:command) do
1111
+ Utils.get_command_event(authorized_client, 'drop') do |client|
1112
+ collection.drop({ write_concern: {w: 0} })
1113
+ end.command
1114
+ end
1115
+
1116
+ it 'applies the write concern passed in as an option' do
1117
+ expect(events.length).to eq(1)
1118
+ expect(command[:writeConcern][:w]).to eq(0)
1119
+ end
1120
+ end
1121
+
1122
+ context 'when the server does not support write concern on the drop command' do
1123
+ max_server_version '3.2'
594
1124
 
595
1125
  it 'does not apply the write concern' do
596
1126
  expect(collection_with_write_options.drop).to be_successful
@@ -600,6 +1130,14 @@ describe Mongo::Collection do
600
1130
  end
601
1131
 
602
1132
  context 'when the collection does not exist' do
1133
+ require_set_write_concern
1134
+
1135
+ before do
1136
+ begin
1137
+ collection.drop
1138
+ rescue Mongo::Error::OperationFailure
1139
+ end
1140
+ end
603
1141
 
604
1142
  it 'returns false' do
605
1143
  expect(collection.drop).to be(false)
@@ -609,6 +1147,23 @@ describe Mongo::Collection do
609
1147
 
610
1148
  describe '#find' do
611
1149
 
1150
+ describe 'updating cluster time' do
1151
+
1152
+ let(:operation) do
1153
+ client[TEST_COLL].find.first
1154
+ end
1155
+
1156
+ let(:operation_with_session) do
1157
+ client[TEST_COLL].find({}, session: session).first
1158
+ end
1159
+
1160
+ let(:second_operation) do
1161
+ client[TEST_COLL].find({}, session: session).first
1162
+ end
1163
+
1164
+ it_behaves_like 'an operation updating cluster time'
1165
+ end
1166
+
612
1167
  context 'when provided a filter' do
613
1168
 
614
1169
  let(:view) do
@@ -661,7 +1216,8 @@ describe Mongo::Collection do
661
1216
  end
662
1217
  end
663
1218
 
664
- context 'when the user is not authorized', if: auth_enabled? do
1219
+ context 'when the user is not authorized' do
1220
+ require_auth
665
1221
 
666
1222
  let(:view) do
667
1223
  unauthorized_collection.find
@@ -703,6 +1259,71 @@ describe Mongo::Collection do
703
1259
 
704
1260
  context 'when provided options' do
705
1261
 
1262
+ context 'when a session is provided' do
1263
+ require_wired_tiger
1264
+
1265
+ let(:operation) do
1266
+ authorized_collection.find({}, session: session).to_a
1267
+ end
1268
+
1269
+ let(:session) do
1270
+ authorized_client.start_session
1271
+ end
1272
+
1273
+ let(:failed_operation) do
1274
+ client[authorized_collection.name].find({ '$._id' => 1 }, session: session).to_a
1275
+ end
1276
+
1277
+ let(:client) do
1278
+ authorized_client
1279
+ end
1280
+
1281
+ it_behaves_like 'an operation using a session'
1282
+ it_behaves_like 'a failed operation using a session'
1283
+ end
1284
+
1285
+ context 'session id' do
1286
+ min_server_fcv '3.6'
1287
+ require_topology :replica_set, :sharded
1288
+ require_wired_tiger
1289
+
1290
+ let(:options) do
1291
+ { session: session }
1292
+ end
1293
+
1294
+ let(:session) do
1295
+ client.start_session
1296
+ end
1297
+
1298
+ let(:view) do
1299
+ Mongo::Collection::View.new(client[TEST_COLL], selector, view_options)
1300
+ end
1301
+
1302
+ let(:command) do
1303
+ client[TEST_COLL].find({}, session: session).explain
1304
+ subscriber.started_events.find { |c| c.command_name == 'explain' }.command
1305
+ end
1306
+
1307
+ it 'sends the session id' do
1308
+ expect(command['lsid']).to eq(session.session_id)
1309
+ end
1310
+ end
1311
+
1312
+ context 'when a session supporting causal consistency is used' do
1313
+ require_wired_tiger
1314
+
1315
+ let(:operation) do
1316
+ collection.find({}, session: session).to_a
1317
+ end
1318
+
1319
+ let(:command) do
1320
+ operation
1321
+ subscriber.started_events.find { |cmd| cmd.command_name == 'find' }.command
1322
+ end
1323
+
1324
+ it_behaves_like 'an operation supporting causally consistent reads'
1325
+ end
1326
+
706
1327
  let(:view) do
707
1328
  authorized_collection.find({}, options)
708
1329
  end
@@ -859,6 +1480,54 @@ describe Mongo::Collection do
859
1480
  expect(result.inserted_ids.size).to eq(2)
860
1481
  end
861
1482
 
1483
+ context 'when a session is provided' do
1484
+
1485
+ let(:session) do
1486
+ authorized_client.start_session
1487
+ end
1488
+
1489
+ let(:operation) do
1490
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session)
1491
+ end
1492
+
1493
+ let(:failed_operation) do
1494
+ authorized_collection.insert_many([{ _id: 'test1' }, { _id: 'test1' }], session: session)
1495
+ end
1496
+
1497
+ let(:client) do
1498
+ authorized_client
1499
+ end
1500
+
1501
+ it_behaves_like 'an operation using a session'
1502
+ it_behaves_like 'a failed operation using a session'
1503
+ end
1504
+
1505
+ context 'when unacknowledged writes is used with an explicit session' do
1506
+
1507
+ let(:collection_with_unacknowledged_write_concern) do
1508
+ authorized_collection.with(write: { w: 0 })
1509
+ end
1510
+
1511
+ let(:operation) do
1512
+ collection_with_unacknowledged_write_concern.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session)
1513
+ end
1514
+
1515
+ it_behaves_like 'an explicit session with an unacknowledged write'
1516
+ end
1517
+
1518
+ context 'when unacknowledged writes is used with an implicit session' do
1519
+
1520
+ let(:collection_with_unacknowledged_write_concern) do
1521
+ client.with(write: { w: 0 })[TEST_COLL]
1522
+ end
1523
+
1524
+ let(:operation) do
1525
+ collection_with_unacknowledged_write_concern.insert_many([{ name: 'test1' }, { name: 'test2' }])
1526
+ end
1527
+
1528
+ it_behaves_like 'an implicit session with an unacknowledged write'
1529
+ end
1530
+
862
1531
  context 'when a document contains invalid keys' do
863
1532
 
864
1533
  let(:docs) do
@@ -887,18 +1556,17 @@ describe Mongo::Collection do
887
1556
  end
888
1557
 
889
1558
  let(:custom_collection) do
890
- custom_client[TEST_COLL]
1559
+ custom_client['custom_id_generator_test_collection']
891
1560
  end
892
1561
 
893
1562
  before do
1563
+ custom_collection.delete_many
894
1564
  custom_collection.insert_many([{ name: 'testing' }])
895
- end
896
-
897
- after do
898
- custom_client.close
1565
+ expect(custom_collection.count).to eq(1)
899
1566
  end
900
1567
 
901
1568
  it 'inserts with the custom id' do
1569
+ expect(custom_collection.count).to eq(1)
902
1570
  expect(custom_collection.find.first[:_id]).to eq(1)
903
1571
  end
904
1572
  end
@@ -929,9 +1597,32 @@ describe Mongo::Collection do
929
1597
  end
930
1598
  end
931
1599
 
932
- context 'when collection has a validator', if: find_command_enabled? do
1600
+ context 'when the documents are sent with OP_MSG' do
1601
+ min_server_fcv '3.6'
1602
+
1603
+ let(:documents) do
1604
+ [{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
1605
+ end
1606
+
1607
+ before do
1608
+ authorized_collection.insert_many(documents)
1609
+ end
1610
+
1611
+ let(:insert_events) do
1612
+ subscriber.started_events.select { |e| e.command_name == 'insert' }
1613
+ end
1614
+
1615
+ it 'sends the documents in one OP_MSG' do
1616
+ expect(insert_events.size).to eq(1)
1617
+ expect(insert_events[0].command['documents']).to eq(documents)
1618
+ end
1619
+ end
1620
+
1621
+ context 'when collection has a validator' do
1622
+ min_server_fcv '3.2'
933
1623
 
934
1624
  around(:each) do |spec|
1625
+ authorized_client[:validating].drop
935
1626
  authorized_client[:validating,
936
1627
  :validator => { :a => { '$exists' => true } }].tap do |c|
937
1628
  c.create
@@ -970,7 +1661,7 @@ describe Mongo::Collection do
970
1661
 
971
1662
  let(:result3) do
972
1663
  collection_with_validator.insert_many(
973
- [{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
1664
+ [{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
974
1665
  end
975
1666
 
976
1667
  it 'inserts successfully' do
@@ -979,26 +1670,168 @@ describe Mongo::Collection do
979
1670
  end
980
1671
  end
981
1672
  end
1673
+
1674
+ context 'when unacknowledged writes is used' do
1675
+
1676
+ let(:collection_with_unacknowledged_write_concern) do
1677
+ authorized_collection.with(write: { w: 0 })
1678
+ end
1679
+
1680
+ let(:result) do
1681
+ collection_with_unacknowledged_write_concern.insert_many([{ _id: 1 }, { _id: 1 }])
1682
+ end
1683
+
1684
+ it 'does not raise an exception' do
1685
+ expect(result.inserted_count).to be(0)
1686
+ end
1687
+ end
1688
+
1689
+ context 'when various options passed in' do
1690
+ # w: 2 requires a replica set
1691
+ require_topology :replica_set
1692
+
1693
+ # https://jira.mongodb.org/browse/RUBY-2306
1694
+ min_server_fcv '3.6'
1695
+
1696
+ let(:session) do
1697
+ authorized_client.start_session
1698
+ end
1699
+
1700
+ let(:events) do
1701
+ subscriber.command_started_events('insert')
1702
+ end
1703
+
1704
+ let(:collection) do
1705
+ authorized_collection.with(write_concern: {w: 2})
1706
+ end
1707
+
1708
+ let!(:command) do
1709
+ Utils.get_command_event(authorized_client, 'insert') do |client|
1710
+ collection.insert_many([{ name: 'test1' }, { name: 'test2' }], session: session,
1711
+ write_concern: {w: 1}, bypass_document_validation: true)
1712
+ end.command
1713
+ end
1714
+
1715
+ it 'inserts many successfully with correct options sent to server' do
1716
+ expect(events.length).to eq(1)
1717
+ expect(command[:writeConcern]).to_not be_nil
1718
+ expect(command[:writeConcern][:w]).to eq(1)
1719
+ expect(command[:bypassDocumentValidation]).to be(true)
1720
+ end
1721
+ end
982
1722
  end
983
1723
 
984
1724
  describe '#insert_one' do
985
1725
 
1726
+ describe 'updating cluster time' do
1727
+
1728
+ let(:operation) do
1729
+ client[TEST_COLL].insert_one({ name: 'testing' })
1730
+ end
1731
+
1732
+ let(:operation_with_session) do
1733
+ client[TEST_COLL].insert_one({ name: 'testing' }, session: session)
1734
+ end
1735
+
1736
+ let(:second_operation) do
1737
+ client[TEST_COLL].insert_one({ name: 'testing' }, session: session)
1738
+ end
1739
+
1740
+ it_behaves_like 'an operation updating cluster time'
1741
+ end
1742
+
986
1743
  let(:result) do
987
1744
  authorized_collection.insert_one({ name: 'testing' })
988
1745
  end
989
1746
 
990
- it 'inserts the document into the collection', if: write_command_enabled? do
1747
+ it 'inserts the document into the collection'do
991
1748
  expect(result.written_count).to eq(1)
992
1749
  end
993
1750
 
994
- it 'inserts the document into the collection', unless: write_command_enabled? do
995
- expect(result.written_count).to eq(0)
996
- end
997
-
998
1751
  it 'contains the id in the result' do
999
1752
  expect(result.inserted_id).to_not be_nil
1000
1753
  end
1001
1754
 
1755
+ context 'when a session is provided' do
1756
+
1757
+ let(:session) do
1758
+ authorized_client.start_session
1759
+ end
1760
+
1761
+ let(:operation) do
1762
+ authorized_collection.insert_one({ name: 'testing' }, session: session)
1763
+ end
1764
+
1765
+ let(:failed_operation) do
1766
+ authorized_collection.insert_one({ _id: 'testing' })
1767
+ authorized_collection.insert_one({ _id: 'testing' }, session: session)
1768
+ end
1769
+
1770
+ let(:client) do
1771
+ authorized_client
1772
+ end
1773
+
1774
+ it_behaves_like 'an operation using a session'
1775
+ it_behaves_like 'a failed operation using a session'
1776
+ end
1777
+
1778
+ context 'when unacknowledged writes is used with an explicit session' do
1779
+
1780
+ let(:collection_with_unacknowledged_write_concern) do
1781
+ authorized_collection.with(write: { w: 0 })
1782
+ end
1783
+
1784
+ let(:operation) do
1785
+ collection_with_unacknowledged_write_concern.insert_one({ name: 'testing' }, session: session)
1786
+ end
1787
+
1788
+ it_behaves_like 'an explicit session with an unacknowledged write'
1789
+ end
1790
+
1791
+ context 'when unacknowledged writes is used with an implicit session' do
1792
+
1793
+ let(:collection_with_unacknowledged_write_concern) do
1794
+ client.with(write: { w: 0 })[TEST_COLL]
1795
+ end
1796
+
1797
+ let(:operation) do
1798
+ collection_with_unacknowledged_write_concern.insert_one({ name: 'testing' })
1799
+ end
1800
+
1801
+ it_behaves_like 'an implicit session with an unacknowledged write'
1802
+ end
1803
+
1804
+ context 'when various options passed in' do
1805
+ # https://jira.mongodb.org/browse/RUBY-2306
1806
+ min_server_fcv '3.6'
1807
+
1808
+ let(:session) do
1809
+ authorized_client.start_session
1810
+ end
1811
+
1812
+ let(:events) do
1813
+ subscriber.command_started_events('insert')
1814
+ end
1815
+
1816
+ let(:collection) do
1817
+ authorized_collection.with(write_concern: {w: 3})
1818
+ end
1819
+
1820
+ let!(:command) do
1821
+ Utils.get_command_event(authorized_client, 'insert') do |client|
1822
+ collection.insert_one({name: 'test1'}, session: session, write_concern: {w: 1},
1823
+ bypass_document_validation: true)
1824
+ end.command
1825
+ end
1826
+
1827
+ it 'inserts one successfully with correct options sent to server' do
1828
+ expect(events.length).to eq(1)
1829
+ expect(command[:writeConcern]).to_not be_nil
1830
+ expect(command[:writeConcern][:w]).to eq(1)
1831
+ expect(command[:bypassDocumentValidation]).to be(true)
1832
+ end
1833
+ end
1834
+
1002
1835
  context 'when the document contains invalid keys' do
1003
1836
 
1004
1837
  let(:doc) do
@@ -1012,6 +1845,18 @@ describe Mongo::Collection do
1012
1845
  end
1013
1846
  end
1014
1847
 
1848
+ context 'when the document is nil' do
1849
+ let(:result) do
1850
+ authorized_collection.insert_one(nil)
1851
+ end
1852
+
1853
+ it 'raises an ArgumentError' do
1854
+ expect {
1855
+ result
1856
+ }.to raise_error(ArgumentError, "Document to be inserted cannot be nil")
1857
+ end
1858
+ end
1859
+
1015
1860
  context 'when the insert fails' do
1016
1861
 
1017
1862
  let(:result) do
@@ -1045,19 +1890,17 @@ describe Mongo::Collection do
1045
1890
  end
1046
1891
 
1047
1892
  before do
1893
+ custom_collection.delete_many
1048
1894
  custom_collection.insert_one({ name: 'testing' })
1049
1895
  end
1050
1896
 
1051
- after do
1052
- custom_client.close
1053
- end
1054
-
1055
1897
  it 'inserts with the custom id' do
1056
1898
  expect(custom_collection.find.first[:_id]).to eq(1)
1057
1899
  end
1058
1900
  end
1059
1901
 
1060
- context 'when collection has a validator', if: find_command_enabled? do
1902
+ context 'when collection has a validator' do
1903
+ min_server_fcv '3.2'
1061
1904
 
1062
1905
  around(:each) do |spec|
1063
1906
  authorized_client[:validating,
@@ -1098,7 +1941,7 @@ describe Mongo::Collection do
1098
1941
 
1099
1942
  let(:result3) do
1100
1943
  collection_with_validator.insert_one(
1101
- { x: 1 }, :bypass_document_validation => true)
1944
+ { x: 1 }, :bypass_document_validation => true)
1102
1945
  end
1103
1946
 
1104
1947
  it 'inserts successfully' do
@@ -1109,22 +1952,68 @@ describe Mongo::Collection do
1109
1952
  end
1110
1953
  end
1111
1954
 
1112
- describe '#inspect' do
1955
+ describe '#bulk_write' do
1113
1956
 
1114
- it 'includes the object id' do
1115
- expect(authorized_collection.inspect).to include(authorized_collection.object_id.to_s)
1116
- end
1957
+ context 'when various options passed in' do
1958
+ min_server_fcv '3.2'
1959
+ require_topology :replica_set
1117
1960
 
1118
- it 'includes the namespace' do
1119
- expect(authorized_collection.inspect).to include(authorized_collection.namespace)
1120
- end
1121
- end
1961
+ # https://jira.mongodb.org/browse/RUBY-2306
1962
+ min_server_fcv '3.6'
1122
1963
 
1123
- describe '#indexes' do
1964
+ let(:requests) do
1965
+ [
1966
+ { insert_one: { name: "anne" }},
1967
+ { insert_one: { name: "bob" }},
1968
+ { insert_one: { name: "charlie" }}
1969
+ ]
1970
+ end
1124
1971
 
1125
- let(:index_spec) do
1126
- { name: 1 }
1127
- end
1972
+ let(:session) do
1973
+ authorized_client.start_session
1974
+ end
1975
+
1976
+ let!(:command) do
1977
+ Utils.get_command_event(authorized_client, 'insert') do |client|
1978
+ collection.bulk_write(requests, session: session, write_concern: {w: 1},
1979
+ bypass_document_validation: true)
1980
+ end.command
1981
+ end
1982
+
1983
+ let(:events) do
1984
+ subscriber.command_started_events('insert')
1985
+ end
1986
+
1987
+ let(:collection) do
1988
+ authorized_collection.with(write_concern: {w: 2})
1989
+ end
1990
+
1991
+ it 'inserts successfully with correct options sent to server' do
1992
+ expect(collection.count).to eq(3)
1993
+ expect(events.length).to eq(1)
1994
+ expect(command[:writeConcern]).to_not be_nil
1995
+ expect(command[:writeConcern][:w]).to eq(1)
1996
+ expect(command[:bypassDocumentValidation]).to eq(true)
1997
+ end
1998
+ end
1999
+ end
2000
+
2001
+ describe '#inspect' do
2002
+
2003
+ it 'includes the object id' do
2004
+ expect(authorized_collection.inspect).to include(authorized_collection.object_id.to_s)
2005
+ end
2006
+
2007
+ it 'includes the namespace' do
2008
+ expect(authorized_collection.inspect).to include(authorized_collection.namespace)
2009
+ end
2010
+ end
2011
+
2012
+ describe '#indexes' do
2013
+
2014
+ let(:index_spec) do
2015
+ { name: 1 }
2016
+ end
1128
2017
 
1129
2018
  let(:batch_size) { nil }
1130
2019
 
@@ -1136,14 +2025,33 @@ describe Mongo::Collection do
1136
2025
  authorized_collection.indexes.create_one(index_spec, unique: true)
1137
2026
  end
1138
2027
 
1139
- after do
1140
- authorized_collection.indexes.drop_one('name_1')
1141
- end
1142
-
1143
2028
  it 'returns a list of indexes' do
1144
2029
  expect(index_names).to include(*'name_1', '_id_')
1145
2030
  end
1146
2031
 
2032
+ context 'when a session is provided' do
2033
+ require_wired_tiger
2034
+
2035
+ let(:session) do
2036
+ authorized_client.start_session
2037
+ end
2038
+
2039
+ let(:operation) do
2040
+ authorized_collection.indexes(batch_size: batch_size, session: session).collect { |i| i['name'] }
2041
+ end
2042
+
2043
+ let(:failed_operation) do
2044
+ authorized_collection.indexes(batch_size: -100, session: session).collect { |i| i['name'] }
2045
+ end
2046
+
2047
+ let(:client) do
2048
+ authorized_client
2049
+ end
2050
+
2051
+ it_behaves_like 'an operation using a session'
2052
+ it_behaves_like 'a failed operation using a session'
2053
+ end
2054
+
1147
2055
  context 'when batch size is specified' do
1148
2056
 
1149
2057
  let(:batch_size) { 1 }
@@ -1156,6 +2064,38 @@ describe Mongo::Collection do
1156
2064
 
1157
2065
  describe '#aggregate' do
1158
2066
 
2067
+ describe 'updating cluster time' do
2068
+
2069
+ let(:operation) do
2070
+ client[TEST_COLL].aggregate([]).first
2071
+ end
2072
+
2073
+ let(:operation_with_session) do
2074
+ client[TEST_COLL].aggregate([], session: session).first
2075
+ end
2076
+
2077
+ let(:second_operation) do
2078
+ client[TEST_COLL].aggregate([], session: session).first
2079
+ end
2080
+
2081
+ it_behaves_like 'an operation updating cluster time'
2082
+ end
2083
+
2084
+ context 'when a session supporting causal consistency is used' do
2085
+ require_wired_tiger
2086
+
2087
+ let(:operation) do
2088
+ collection.aggregate([], session: session).first
2089
+ end
2090
+
2091
+ let(:command) do
2092
+ operation
2093
+ subscriber.started_events.find { |cmd| cmd.command_name == 'aggregate' }.command
2094
+ end
2095
+
2096
+ it_behaves_like 'an operation supporting causally consistent reads'
2097
+ end
2098
+
1159
2099
  it 'returns an Aggregation object' do
1160
2100
  expect(authorized_collection.aggregate([])).to be_a(Mongo::Collection::View::Aggregation)
1161
2101
  end
@@ -1170,6 +2110,50 @@ describe Mongo::Collection do
1170
2110
  expect(authorized_collection.aggregate([], options).options).to eq(BSON::Document.new(options))
1171
2111
  end
1172
2112
 
2113
+ context 'when the :comment option is provided' do
2114
+
2115
+ let(:options) do
2116
+ { :comment => 'testing' }
2117
+ end
2118
+
2119
+ it 'sets the options on the Aggregation object' do
2120
+ expect(authorized_collection.aggregate([], options).options).to eq(BSON::Document.new(options))
2121
+ end
2122
+ end
2123
+
2124
+ context 'when a session is provided' do
2125
+
2126
+ let(:session) do
2127
+ authorized_client.start_session
2128
+ end
2129
+
2130
+ let(:operation) do
2131
+ authorized_collection.aggregate([], session: session).to_a
2132
+ end
2133
+
2134
+ let(:failed_operation) do
2135
+ authorized_collection.aggregate([ { '$invalid' => 1 }], session: session).to_a
2136
+ end
2137
+
2138
+ let(:client) do
2139
+ authorized_client
2140
+ end
2141
+
2142
+ it_behaves_like 'an operation using a session'
2143
+ it_behaves_like 'a failed operation using a session'
2144
+ end
2145
+
2146
+ context 'when a hint is provided' do
2147
+
2148
+ let(:options) do
2149
+ { 'hint' => { 'y' => 1 } }
2150
+ end
2151
+
2152
+ it 'sets the options on the Aggregation object' do
2153
+ expect(authorized_collection.aggregate([], options).options).to eq(options)
2154
+ end
2155
+ end
2156
+
1173
2157
  context 'when collation is provided' do
1174
2158
 
1175
2159
  before do
@@ -1188,14 +2172,16 @@ describe Mongo::Collection do
1188
2172
  authorized_collection.aggregate(pipeline, options).collect { |doc| doc['name']}
1189
2173
  end
1190
2174
 
1191
- context 'when the server selected supports collations', if: collation_enabled? do
2175
+ context 'when the server selected supports collations' do
2176
+ min_server_fcv '3.4'
1192
2177
 
1193
2178
  it 'applies the collation' do
1194
2179
  expect(result).to eq(['bang', 'bang'])
1195
2180
  end
1196
2181
  end
1197
2182
 
1198
- context 'when the server selected does not support collations', unless: collation_enabled? do
2183
+ context 'when the server selected does not support collations' do
2184
+ max_server_version '3.2'
1199
2185
 
1200
2186
  it 'raises an exception' do
1201
2187
  expect {
@@ -1220,6 +2206,76 @@ describe Mongo::Collection do
1220
2206
  end
1221
2207
  end
1222
2208
 
2209
+ describe '#count_documents' do
2210
+
2211
+ before do
2212
+ authorized_collection.delete_many
2213
+ end
2214
+
2215
+ context 'no argument provided' do
2216
+
2217
+ context 'when collection is empty' do
2218
+ it 'returns 0 matching documents' do
2219
+ expect(authorized_collection.count_documents).to eq(0)
2220
+ end
2221
+ end
2222
+
2223
+ context 'when collection is not empty' do
2224
+
2225
+ let(:documents) do
2226
+ documents = []
2227
+ 1.upto(10) do |index|
2228
+ documents << { key: 'a', _id: "in#{index}" }
2229
+ end
2230
+ documents
2231
+ end
2232
+
2233
+ before do
2234
+ authorized_collection.insert_many(documents)
2235
+ end
2236
+
2237
+ it 'returns 10 matching documents' do
2238
+ expect(authorized_collection.count_documents).to eq(10)
2239
+ end
2240
+ end
2241
+ end
2242
+
2243
+ context 'when transactions are enabled' do
2244
+ require_wired_tiger
2245
+ require_transaction_support
2246
+
2247
+ before do
2248
+ # Ensure that the collection is created
2249
+ authorized_collection.insert_one(x: 1)
2250
+ authorized_collection.delete_many({})
2251
+ end
2252
+
2253
+ let(:session) do
2254
+ authorized_client.start_session
2255
+ end
2256
+
2257
+ it 'successfully starts a transaction and executes a transaction' do
2258
+ session.start_transaction
2259
+ expect(
2260
+ session.instance_variable_get(:@state)
2261
+ ).to eq(Mongo::Session::STARTING_TRANSACTION_STATE)
2262
+
2263
+ expect(authorized_collection.count_documents({}, { session: session })).to eq(0)
2264
+ expect(
2265
+ session.instance_variable_get(:@state)
2266
+ ).to eq(Mongo::Session::TRANSACTION_IN_PROGRESS_STATE)
2267
+
2268
+ authorized_collection.insert_one({ x: 1 }, { session: session })
2269
+ expect(authorized_collection.count_documents({}, { session: session })).to eq(1)
2270
+
2271
+ session.commit_transaction
2272
+ expect(
2273
+ session.instance_variable_get(:@state)
2274
+ ).to eq(Mongo::Session::TRANSACTION_COMMITTED_STATE)
2275
+ end
2276
+ end
2277
+ end
2278
+
1223
2279
  describe '#count' do
1224
2280
 
1225
2281
  let(:documents) do
@@ -1240,6 +2296,44 @@ describe Mongo::Collection do
1240
2296
  expect(authorized_collection.count({}, limit: 5)).to eq(5)
1241
2297
  end
1242
2298
 
2299
+ context 'when a session is provided' do
2300
+ require_wired_tiger
2301
+
2302
+ let(:session) do
2303
+ authorized_client.start_session
2304
+ end
2305
+
2306
+ let(:operation) do
2307
+ authorized_collection.count({}, session: session)
2308
+ end
2309
+
2310
+ let(:failed_operation) do
2311
+ authorized_collection.count({ '$._id' => 1 }, session: session)
2312
+ end
2313
+
2314
+ let(:client) do
2315
+ authorized_client
2316
+ end
2317
+
2318
+ it_behaves_like 'an operation using a session'
2319
+ it_behaves_like 'a failed operation using a session'
2320
+ end
2321
+
2322
+ context 'when a session supporting causal consistency is used' do
2323
+ require_wired_tiger
2324
+
2325
+ let(:operation) do
2326
+ collection.count({}, session: session)
2327
+ end
2328
+
2329
+ let(:command) do
2330
+ operation
2331
+ subscriber.started_events.find { |cmd| cmd.command_name == 'count' }.command
2332
+ end
2333
+
2334
+ it_behaves_like 'an operation supporting causally consistent reads'
2335
+ end
2336
+
1243
2337
  context 'when a collation is specified' do
1244
2338
 
1245
2339
  let(:selector) do
@@ -1258,14 +2352,16 @@ describe Mongo::Collection do
1258
2352
  { collation: { locale: 'en_US', strength: 2 } }
1259
2353
  end
1260
2354
 
1261
- context 'when the server selected supports collations', if: collation_enabled? do
2355
+ context 'when the server selected supports collations' do
2356
+ min_server_fcv '3.4'
1262
2357
 
1263
2358
  it 'applies the collation to the count' do
1264
2359
  expect(result).to eq(1)
1265
2360
  end
1266
2361
  end
1267
2362
 
1268
- context 'when the server selected does not support collations', unless: collation_enabled? do
2363
+ context 'when the server selected does not support collations' do
2364
+ max_server_version '3.2'
1269
2365
 
1270
2366
  it 'raises an exception' do
1271
2367
  expect {
@@ -1316,6 +2412,44 @@ describe Mongo::Collection do
1316
2412
  it 'passes the options to the distinct command' do
1317
2413
  expect(authorized_collection.distinct(:field, {}, max_time_ms: 100).sort).to eq([ 'test1', 'test2', 'test3' ])
1318
2414
  end
2415
+
2416
+ context 'when a session is provided' do
2417
+ require_wired_tiger
2418
+
2419
+ let(:session) do
2420
+ authorized_client.start_session
2421
+ end
2422
+
2423
+ let(:operation) do
2424
+ authorized_collection.distinct(:field, {}, session: session)
2425
+ end
2426
+
2427
+ let(:failed_operation) do
2428
+ authorized_collection.distinct(:field, { '$._id' => 1 }, session: session)
2429
+ end
2430
+
2431
+ let(:client) do
2432
+ authorized_client
2433
+ end
2434
+
2435
+ it_behaves_like 'an operation using a session'
2436
+ it_behaves_like 'a failed operation using a session'
2437
+ end
2438
+ end
2439
+
2440
+ context 'when a session supporting causal consistency is used' do
2441
+ require_wired_tiger
2442
+
2443
+ let(:operation) do
2444
+ collection.distinct(:field, {}, session: session)
2445
+ end
2446
+
2447
+ let(:command) do
2448
+ operation
2449
+ subscriber.started_events.find { |cmd| cmd.command_name == 'distinct' }.command
2450
+ end
2451
+
2452
+ it_behaves_like 'an operation supporting causally consistent reads'
1319
2453
  end
1320
2454
 
1321
2455
  context 'when a collation is specified' do
@@ -1333,14 +2467,16 @@ describe Mongo::Collection do
1333
2467
  { collation: { locale: 'en_US', strength: 2 } }
1334
2468
  end
1335
2469
 
1336
- context 'when the server selected supports collations', if: collation_enabled? do
2470
+ context 'when the server selected supports collations' do
2471
+ min_server_fcv '3.4'
1337
2472
 
1338
2473
  it 'applies the collation to the distinct' do
1339
2474
  expect(result).to eq(['bang'])
1340
2475
  end
1341
2476
  end
1342
2477
 
1343
- context 'when the server selected does not support collations', unless: collation_enabled? do
2478
+ context 'when the server selected does not support collations' do
2479
+ max_server_version '3.2'
1344
2480
 
1345
2481
  it 'raises an exception' do
1346
2482
  expect {
@@ -1375,7 +2511,7 @@ describe Mongo::Collection do
1375
2511
  end
1376
2512
 
1377
2513
  it 'does not apply the collation to the distinct' do
1378
- expect(result).to eq(['bang', 'BANG'])
2514
+ expect(result).to match_array(['bang', 'BANG'])
1379
2515
  end
1380
2516
  end
1381
2517
  end
@@ -1390,9 +2526,9 @@ describe Mongo::Collection do
1390
2526
 
1391
2527
  before do
1392
2528
  authorized_collection.insert_many([
1393
- { field: 'test1' },
1394
- { field: 'test1' },
1395
- { field: 'test1' }
2529
+ { field: 'test1' },
2530
+ { field: 'test1' },
2531
+ { field: 'test1' }
1396
2532
  ])
1397
2533
  end
1398
2534
 
@@ -1420,7 +2556,8 @@ describe Mongo::Collection do
1420
2556
  end
1421
2557
  end
1422
2558
 
1423
- context 'when the delete fails', if: standalone? do
2559
+ context 'when the delete fails' do
2560
+ require_topology :single
1424
2561
 
1425
2562
  let(:result) do
1426
2563
  collection_invalid_write_concern.delete_one
@@ -1433,6 +2570,54 @@ describe Mongo::Collection do
1433
2570
  end
1434
2571
  end
1435
2572
 
2573
+ context 'when a session is provided' do
2574
+
2575
+ let(:session) do
2576
+ authorized_client.start_session
2577
+ end
2578
+
2579
+ let(:operation) do
2580
+ authorized_collection.delete_one({}, session: session)
2581
+ end
2582
+
2583
+ let(:failed_operation) do
2584
+ authorized_collection.delete_one({ '$._id' => 1}, session: session)
2585
+ end
2586
+
2587
+ let(:client) do
2588
+ authorized_client
2589
+ end
2590
+
2591
+ it_behaves_like 'an operation using a session'
2592
+ it_behaves_like 'a failed operation using a session'
2593
+ end
2594
+
2595
+ context 'when unacknowledged writes is used' do
2596
+
2597
+ let(:collection_with_unacknowledged_write_concern) do
2598
+ authorized_collection.with(write: { w: 0 })
2599
+ end
2600
+
2601
+ let(:operation) do
2602
+ collection_with_unacknowledged_write_concern.delete_one({}, session: session)
2603
+ end
2604
+
2605
+ it_behaves_like 'an explicit session with an unacknowledged write'
2606
+ end
2607
+
2608
+ context 'when unacknowledged writes is used with an implicit session' do
2609
+
2610
+ let(:collection_with_unacknowledged_write_concern) do
2611
+ client.with(write: { w: 0 })[TEST_COLL]
2612
+ end
2613
+
2614
+ let(:operation) do
2615
+ collection_with_unacknowledged_write_concern.delete_one
2616
+ end
2617
+
2618
+ it_behaves_like 'an implicit session with an unacknowledged write'
2619
+ end
2620
+
1436
2621
  context 'when a collation is provided' do
1437
2622
 
1438
2623
  let(:selector) do
@@ -1451,7 +2636,8 @@ describe Mongo::Collection do
1451
2636
  { collation: { locale: 'en_US', strength: 2 } }
1452
2637
  end
1453
2638
 
1454
- context 'when the server selected supports collations', if: collation_enabled? do
2639
+ context 'when the server selected supports collations' do
2640
+ min_server_fcv '3.4'
1455
2641
 
1456
2642
  it 'applies the collation' do
1457
2643
  expect(result.written_count).to eq(1)
@@ -1489,7 +2675,8 @@ describe Mongo::Collection do
1489
2675
  end
1490
2676
  end
1491
2677
 
1492
- context 'when the server selected does not support collations', unless: collation_enabled? do
2678
+ context 'when the server selected does not support collations' do
2679
+ max_server_version '3.2'
1493
2680
 
1494
2681
  it 'raises an exception' do
1495
2682
  expect {
@@ -1531,6 +2718,48 @@ describe Mongo::Collection do
1531
2718
  expect(authorized_collection.find(name: 'bang').count).to eq(1)
1532
2719
  end
1533
2720
  end
2721
+
2722
+ context 'when various options passed in' do
2723
+ # w: 2 requires a replica set
2724
+ require_topology :replica_set
2725
+
2726
+ # https://jira.mongodb.org/browse/RUBY-2306
2727
+ min_server_fcv '3.6'
2728
+
2729
+ before do
2730
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
2731
+ end
2732
+
2733
+ let(:selector) do
2734
+ {name: 'test2'}
2735
+ end
2736
+
2737
+ let(:session) do
2738
+ authorized_client.start_session
2739
+ end
2740
+
2741
+ let(:events) do
2742
+ subscriber.command_started_events('delete')
2743
+ end
2744
+
2745
+ let(:collection) do
2746
+ authorized_collection.with(write_concern: {w: 2})
2747
+ end
2748
+
2749
+ let!(:command) do
2750
+ Utils.get_command_event(authorized_client, 'delete') do |client|
2751
+ collection.delete_one(selector, session: session, write_concern: {w: 1},
2752
+ bypass_document_validation: true)
2753
+ end.command
2754
+ end
2755
+
2756
+ it 'deletes one successfully with correct options sent to server' do
2757
+ expect(events.length).to eq(1)
2758
+ expect(command[:writeConcern]).to_not be_nil
2759
+ expect(command[:writeConcern][:w]).to eq(1)
2760
+ expect(command[:bypassDocumentValidation]).to eq(true)
2761
+ end
2762
+ end
1534
2763
  end
1535
2764
 
1536
2765
  describe '#delete_many' do
@@ -1557,7 +2786,8 @@ describe Mongo::Collection do
1557
2786
  end
1558
2787
  end
1559
2788
 
1560
- context 'when the deletes fail', if: standalone? do
2789
+ context 'when the deletes fail' do
2790
+ require_topology :single
1561
2791
 
1562
2792
  let(:result) do
1563
2793
  collection_invalid_write_concern.delete_many
@@ -1570,6 +2800,54 @@ describe Mongo::Collection do
1570
2800
  end
1571
2801
  end
1572
2802
 
2803
+ context 'when a session is provided' do
2804
+
2805
+ let(:session) do
2806
+ authorized_client.start_session
2807
+ end
2808
+
2809
+ let(:operation) do
2810
+ authorized_collection.delete_many({}, session: session)
2811
+ end
2812
+
2813
+ let(:failed_operation) do
2814
+ authorized_collection.delete_many({ '$._id' => 1}, session: session)
2815
+ end
2816
+
2817
+ let(:client) do
2818
+ authorized_client
2819
+ end
2820
+
2821
+ it_behaves_like 'an operation using a session'
2822
+ it_behaves_like 'a failed operation using a session'
2823
+ end
2824
+
2825
+ context 'when unacknowledged writes are used with an explicit session' do
2826
+
2827
+ let(:collection_with_unacknowledged_write_concern) do
2828
+ authorized_collection.with(write: { w: 0 })
2829
+ end
2830
+
2831
+ let(:operation) do
2832
+ collection_with_unacknowledged_write_concern.delete_many({ '$._id' => 1}, session: session)
2833
+ end
2834
+
2835
+ it_behaves_like 'an explicit session with an unacknowledged write'
2836
+ end
2837
+
2838
+ context 'when unacknowledged writes are used with an implicit session' do
2839
+
2840
+ let(:collection_with_unacknowledged_write_concern) do
2841
+ client.with(write: { w: 0 })[TEST_COLL]
2842
+ end
2843
+
2844
+ let(:operation) do
2845
+ collection_with_unacknowledged_write_concern.delete_many({ '$._id' => 1 })
2846
+ end
2847
+
2848
+ it_behaves_like 'an implicit session with an unacknowledged write'
2849
+ end
2850
+
1573
2851
  context 'when a collation is specified' do
1574
2852
 
1575
2853
  let(:selector) do
@@ -1589,7 +2867,8 @@ describe Mongo::Collection do
1589
2867
  { collation: { locale: 'en_US', strength: 2 } }
1590
2868
  end
1591
2869
 
1592
- context 'when the server selected supports collations', if: collation_enabled? do
2870
+ context 'when the server selected supports collations' do
2871
+ min_server_fcv '3.4'
1593
2872
 
1594
2873
  it 'applies the collation' do
1595
2874
  expect(result.written_count).to eq(2)
@@ -1627,7 +2906,8 @@ describe Mongo::Collection do
1627
2906
  end
1628
2907
  end
1629
2908
 
1630
- context 'when the server selected does not support collations', unless: collation_enabled? do
2909
+ context 'when the server selected does not support collations' do
2910
+ max_server_version '3.2'
1631
2911
 
1632
2912
  it 'raises an exception' do
1633
2913
  expect {
@@ -1670,9 +2950,53 @@ describe Mongo::Collection do
1670
2950
  expect(authorized_collection.find(name: 'bang').count).to eq(2)
1671
2951
  end
1672
2952
  end
2953
+
2954
+ context 'when various options passed in' do
2955
+ # w: 2 requires a replica set
2956
+ require_topology :replica_set
2957
+
2958
+ # https://jira.mongodb.org/browse/RUBY-2306
2959
+ min_server_fcv '3.6'
2960
+
2961
+ before do
2962
+ collection.insert_many([{ name: 'test1' }, { name: 'test2' }, { name: 'test3'}])
2963
+ end
2964
+
2965
+ let(:selector) do
2966
+ {name: 'test1'}
2967
+ end
2968
+
2969
+ let(:session) do
2970
+ authorized_client.start_session
2971
+ end
2972
+
2973
+ let(:events) do
2974
+ subscriber.command_started_events('delete')
2975
+ end
2976
+
2977
+ let(:collection) do
2978
+ authorized_collection.with(write_concern: {w: 1})
2979
+ end
2980
+
2981
+ let!(:command) do
2982
+ Utils.get_command_event(authorized_client, 'delete') do |client|
2983
+ collection.delete_many(selector, session: session, write_concern: {w: 2},
2984
+ bypass_document_validation: true)
2985
+ end.command
2986
+ end
2987
+
2988
+ it 'deletes many successfully with correct options sent to server' do
2989
+ expect(events.length).to eq(1)
2990
+ expect(command[:writeConcern]).to_not be_nil
2991
+ expect(command[:writeConcern][:w]).to eq(2)
2992
+ expect(command[:bypassDocumentValidation]).to be(true)
2993
+ end
2994
+ end
1673
2995
  end
1674
2996
 
1675
- describe '#parallel_scan', unless: sharded? do
2997
+ describe '#parallel_scan' do
2998
+ max_server_version '4.0'
2999
+ require_topology :single, :replica_set
1676
3000
 
1677
3001
  let(:documents) do
1678
3002
  (1..200).map do |i|
@@ -1688,33 +3012,99 @@ describe Mongo::Collection do
1688
3012
  authorized_collection.parallel_scan(2)
1689
3013
  end
1690
3014
 
1691
- it 'returns an array of cursors', if: write_command_enabled? do
3015
+ it 'returns an array of cursors' do
1692
3016
  cursors.each do |cursor|
1693
3017
  expect(cursor.class).to be(Mongo::Cursor)
1694
3018
  end
1695
3019
  end
1696
3020
 
1697
- it 'returns the correct number of documents', if: write_command_enabled? do
3021
+ it 'returns the correct number of documents' do
1698
3022
  expect(
1699
3023
  cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1700
3024
  ).to eq(200)
1701
3025
  end
1702
3026
 
1703
- it 'raises an error', unless: write_command_enabled? do
1704
- expect {
1705
- cursors
1706
- }.to raise_error(Mongo::Error::OperationFailure)
1707
- end
3027
+ context 'when a session is provided' do
3028
+ require_wired_tiger
1708
3029
 
1709
- context 'when a read concern is provided', if: find_command_enabled? do
3030
+ let(:cursors) do
3031
+ authorized_collection.parallel_scan(2, session: session)
3032
+ end
1710
3033
 
1711
- let(:result) do
1712
- authorized_collection.with(options).parallel_scan(2)
3034
+ let(:operation) do
3035
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1713
3036
  end
1714
3037
 
1715
- context 'when the read concern is valid' do
3038
+ let(:failed_operation) do
3039
+ authorized_collection.parallel_scan(-2, session: session)
3040
+ end
1716
3041
 
1717
- let(:options) do
3042
+ let(:client) do
3043
+ authorized_client
3044
+ end
3045
+
3046
+ it_behaves_like 'an operation using a session'
3047
+ it_behaves_like 'a failed operation using a session'
3048
+ end
3049
+
3050
+ context 'when a session is not provided' do
3051
+ let(:collection) { client['test'] }
3052
+
3053
+ let(:cursors) do
3054
+ collection.parallel_scan(2)
3055
+ end
3056
+
3057
+ let(:operation) do
3058
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
3059
+ end
3060
+
3061
+ let(:failed_operation) do
3062
+ collection.parallel_scan(-2)
3063
+ end
3064
+
3065
+ let(:command) do
3066
+ operation
3067
+ event = subscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
3068
+ expect(event).not_to be_nil
3069
+ event.command
3070
+ end
3071
+
3072
+ it_behaves_like 'an operation not using a session'
3073
+ it_behaves_like 'a failed operation not using a session'
3074
+ end
3075
+
3076
+ context 'when a session supporting causal consistency is used' do
3077
+ require_wired_tiger
3078
+
3079
+ let(:cursors) do
3080
+ collection.parallel_scan(2, session: session)
3081
+ end
3082
+
3083
+ let(:operation) do
3084
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
3085
+ end
3086
+
3087
+ let(:command) do
3088
+ operation
3089
+ event = subscriber.started_events.find { |cmd| cmd.command_name == 'parallelCollectionScan' }
3090
+ expect(event).not_to be_nil
3091
+ event.command
3092
+ end
3093
+
3094
+ it_behaves_like 'an operation supporting causally consistent reads'
3095
+ end
3096
+
3097
+ context 'when a read concern is provided' do
3098
+ require_wired_tiger
3099
+ min_server_fcv '3.2'
3100
+
3101
+ let(:result) do
3102
+ authorized_collection.with(options).parallel_scan(2)
3103
+ end
3104
+
3105
+ context 'when the read concern is valid' do
3106
+
3107
+ let(:options) do
1718
3108
  { read_concern: { level: 'local' }}
1719
3109
  end
1720
3110
 
@@ -1737,16 +3127,13 @@ describe Mongo::Collection do
1737
3127
  end
1738
3128
  end
1739
3129
 
1740
- context 'when the collection has a read preference', unless: sharded? do
3130
+ context 'when the collection has a read preference' do
3131
+ require_topology :single, :replica_set
1741
3132
 
1742
3133
  before do
1743
3134
  allow(collection.client.cluster).to receive(:single?).and_return(false)
1744
3135
  end
1745
3136
 
1746
- after do
1747
- client.close
1748
- end
1749
-
1750
3137
  let(:client) do
1751
3138
  authorized_client.with(server_selection_timeout: 0.2)
1752
3139
  end
@@ -1767,7 +3154,8 @@ describe Mongo::Collection do
1767
3154
  end
1768
3155
  end
1769
3156
 
1770
- context 'when a max time ms value is provided', if: (!sharded? && write_command_enabled?) do
3157
+ context 'when a max time ms value is provided' do
3158
+ require_topology :single, :replica_set
1771
3159
 
1772
3160
  let(:result) do
1773
3161
  authorized_collection.parallel_scan(2, options)
@@ -1776,7 +3164,7 @@ describe Mongo::Collection do
1776
3164
  context 'when the read concern is valid' do
1777
3165
 
1778
3166
  let(:options) do
1779
- { max_time_ms: 2 }
3167
+ { max_time_ms: 5 }
1780
3168
  end
1781
3169
 
1782
3170
  it 'sends the max time ms value' do
@@ -1838,7 +3226,7 @@ describe Mongo::Collection do
1838
3226
  authorized_collection.find(field: 'test1').to_a
1839
3227
  end
1840
3228
 
1841
- it 'reports that no documents were written' do
3229
+ it 'reports that no documents were written' do
1842
3230
  expect(response.modified_count).to eq(0)
1843
3231
  end
1844
3232
 
@@ -1898,7 +3286,8 @@ describe Mongo::Collection do
1898
3286
  end
1899
3287
  end
1900
3288
 
1901
- context 'when collection has a validator', if: find_command_enabled? do
3289
+ context 'when collection has a validator' do
3290
+ min_server_fcv '3.2'
1902
3291
 
1903
3292
  around(:each) do |spec|
1904
3293
  authorized_client[:validating,
@@ -1943,7 +3332,7 @@ describe Mongo::Collection do
1943
3332
 
1944
3333
  let(:result3) do
1945
3334
  collection_with_validator.replace_one(
1946
- { a: 1 }, { x: 1 }, :bypass_document_validation => true)
3335
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true)
1947
3336
  end
1948
3337
 
1949
3338
  it 'replaces successfully' do
@@ -1971,7 +3360,8 @@ describe Mongo::Collection do
1971
3360
  { collation: { locale: 'en_US', strength: 2 } }
1972
3361
  end
1973
3362
 
1974
- context 'when the server selected supports collations', if: collation_enabled? do
3363
+ context 'when the server selected supports collations' do
3364
+ min_server_fcv '3.4'
1975
3365
 
1976
3366
  it 'applies the collation' do
1977
3367
  expect(result.written_count).to eq(1)
@@ -2009,7 +3399,8 @@ describe Mongo::Collection do
2009
3399
  end
2010
3400
  end
2011
3401
 
2012
- context 'when the server selected does not support collations', unless: collation_enabled? do
3402
+ context 'when the server selected does not support collations' do
3403
+ max_server_version '3.2'
2013
3404
 
2014
3405
  it 'raises an exception' do
2015
3406
  expect {
@@ -2051,6 +3442,107 @@ describe Mongo::Collection do
2051
3442
  expect(authorized_collection.find(name: 'bang').count).to eq(1)
2052
3443
  end
2053
3444
  end
3445
+
3446
+ context 'when a session is provided' do
3447
+
3448
+ let(:selector) do
3449
+ { name: 'BANG' }
3450
+ end
3451
+
3452
+ before do
3453
+ authorized_collection.insert_one(name: 'bang')
3454
+ end
3455
+
3456
+ let(:session) do
3457
+ authorized_client.start_session
3458
+ end
3459
+
3460
+ let(:operation) do
3461
+ authorized_collection.replace_one(selector, { name: 'doink' }, session: session)
3462
+ end
3463
+
3464
+ let(:failed_operation) do
3465
+ authorized_collection.replace_one({ '$._id' => 1 }, { name: 'doink' }, session: session)
3466
+ end
3467
+
3468
+ let(:client) do
3469
+ authorized_client
3470
+ end
3471
+
3472
+ it_behaves_like 'an operation using a session'
3473
+ it_behaves_like 'a failed operation using a session'
3474
+ end
3475
+
3476
+ context 'when unacknowledged writes is used with an explicit session' do
3477
+
3478
+ let(:collection_with_unacknowledged_write_concern) do
3479
+ authorized_collection.with(write: { w: 0 })
3480
+ end
3481
+
3482
+ let(:operation) do
3483
+ collection_with_unacknowledged_write_concern.replace_one({ a: 1 }, { x: 5 }, session: session)
3484
+ end
3485
+
3486
+ it_behaves_like 'an explicit session with an unacknowledged write'
3487
+ end
3488
+
3489
+ context 'when unacknowledged writes is used with an implicit session' do
3490
+
3491
+ let(:collection_with_unacknowledged_write_concern) do
3492
+ client.with(write: { w: 0 })[TEST_COLL]
3493
+ end
3494
+
3495
+ let(:operation) do
3496
+ collection_with_unacknowledged_write_concern.replace_one({ a: 1 }, { x: 5 })
3497
+ end
3498
+
3499
+ it_behaves_like 'an implicit session with an unacknowledged write'
3500
+ end
3501
+
3502
+ context 'when various options passed in' do
3503
+ # w: 2 requires a replica set
3504
+ require_topology :replica_set
3505
+
3506
+ # https://jira.mongodb.org/browse/RUBY-2306
3507
+ min_server_fcv '3.6'
3508
+
3509
+ before do
3510
+ authorized_collection.insert_one({field: 'test1'})
3511
+ end
3512
+
3513
+ let(:session) do
3514
+ authorized_client.start_session
3515
+ end
3516
+
3517
+ let(:events) do
3518
+ subscriber.command_started_events('update')
3519
+ end
3520
+
3521
+ let(:collection) do
3522
+ authorized_collection.with(write_concern: {w: 3})
3523
+ end
3524
+
3525
+ let(:updated) do
3526
+ collection.find(field: 'test4').first
3527
+ end
3528
+
3529
+ let!(:command) do
3530
+ Utils.get_command_event(authorized_client, 'update') do |client|
3531
+ collection.replace_one(selector, { field: 'test4'},
3532
+ session: session, :return_document => :after, write_concern: {w: 2},
3533
+ upsert: true, bypass_document_validation: true)
3534
+ end.command
3535
+ end
3536
+
3537
+ it 'replaced one successfully with correct options sent to server' do
3538
+ expect(updated[:field]).to eq('test4')
3539
+ expect(events.length).to eq(1)
3540
+ expect(command[:writeConcern]).to_not be_nil
3541
+ expect(command[:writeConcern][:w]).to eq(2)
3542
+ expect(command[:bypassDocumentValidation]).to be(true)
3543
+ expect(command[:updates][0][:upsert]).to be(true)
3544
+ end
3545
+ end
2054
3546
  end
2055
3547
 
2056
3548
  describe '#update_many' do
@@ -2086,7 +3578,7 @@ describe Mongo::Collection do
2086
3578
 
2087
3579
  let(:response) do
2088
3580
  authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
2089
- upsert: false)
3581
+ upsert: false)
2090
3582
  end
2091
3583
 
2092
3584
  let(:updated) do
@@ -2106,7 +3598,7 @@ describe Mongo::Collection do
2106
3598
 
2107
3599
  let!(:response) do
2108
3600
  authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
2109
- upsert: true)
3601
+ upsert: true)
2110
3602
  end
2111
3603
 
2112
3604
  let(:updated) do
@@ -2141,6 +3633,108 @@ describe Mongo::Collection do
2141
3633
  end
2142
3634
  end
2143
3635
 
3636
+ context 'when arrayFilters is provided' do
3637
+
3638
+ let(:selector) do
3639
+ { '$or' => [{ _id: 0 }, { _id: 1 }]}
3640
+ end
3641
+
3642
+ context 'when the server supports arrayFilters' do
3643
+ min_server_fcv '3.6'
3644
+
3645
+ before do
3646
+ authorized_collection.insert_many([{
3647
+ _id: 0, x: [
3648
+ { y: 1 },
3649
+ { y: 2 },
3650
+ { y: 3 }
3651
+ ]
3652
+ },
3653
+ {
3654
+ _id: 1,
3655
+ x: [
3656
+ { y: 3 },
3657
+ { y: 2 },
3658
+ { y: 1 }
3659
+ ]
3660
+ }])
3661
+ end
3662
+
3663
+ let(:result) do
3664
+ authorized_collection.update_many(selector,
3665
+ { '$set' => { 'x.$[i].y' => 5 } },
3666
+ options)
3667
+ end
3668
+
3669
+ context 'when a Symbol key is used' do
3670
+
3671
+ let(:options) do
3672
+ { array_filters: [{ 'i.y' => 3 }] }
3673
+ end
3674
+
3675
+ it 'applies the arrayFilters' do
3676
+ expect(result.matched_count).to eq(2)
3677
+ expect(result.modified_count).to eq(2)
3678
+
3679
+ docs = authorized_collection.find(selector, sort: { _id: 1 }).to_a
3680
+ expect(docs[0]['x']).to eq ([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 5 }])
3681
+ expect(docs[1]['x']).to eq ([{ 'y' => 5 }, { 'y' => 2 }, { 'y' => 1 }])
3682
+ end
3683
+ end
3684
+
3685
+ context 'when a String key is used' do
3686
+ let(:options) do
3687
+ { 'array_filters' => [{ 'i.y' => 3 }] }
3688
+ end
3689
+
3690
+ it 'applies the arrayFilters' do
3691
+ expect(result.matched_count).to eq(2)
3692
+ expect(result.modified_count).to eq(2)
3693
+
3694
+ docs = authorized_collection.find({}, sort: { _id: 1 }).to_a
3695
+ expect(docs[0]['x']).to eq ([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 5 }])
3696
+ expect(docs[1]['x']).to eq ([{ 'y' => 5 }, { 'y' => 2 }, { 'y' => 1 }])
3697
+ end
3698
+ end
3699
+ end
3700
+
3701
+ context 'when the server does not support arrayFilters' do
3702
+ max_server_version '3.4'
3703
+
3704
+ let(:result) do
3705
+ authorized_collection.update_many(selector,
3706
+ { '$set' => { 'x.$[i].y' => 5 } },
3707
+ options)
3708
+ end
3709
+
3710
+ context 'when a Symbol key is used' do
3711
+
3712
+ let(:options) do
3713
+ { array_filters: [{ 'i.y' => 3 }] }
3714
+ end
3715
+
3716
+ it 'raises an exception' do
3717
+ expect {
3718
+ result
3719
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
3720
+ end
3721
+ end
3722
+
3723
+ context 'when a String key is used' do
3724
+
3725
+ let(:options) do
3726
+ { 'array_filters' => [{ 'i.y' => 3 }] }
3727
+ end
3728
+
3729
+ it 'raises an exception' do
3730
+ expect {
3731
+ result
3732
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
3733
+ end
3734
+ end
3735
+ end
3736
+ end
3737
+
2144
3738
  context 'when the updates fail' do
2145
3739
 
2146
3740
  let(:result) do
@@ -2154,7 +3748,8 @@ describe Mongo::Collection do
2154
3748
  end
2155
3749
  end
2156
3750
 
2157
- context 'when collection has a validator', if: find_command_enabled? do
3751
+ context 'when collection has a validator' do
3752
+ min_server_fcv '3.2'
2158
3753
 
2159
3754
  around(:each) do |spec|
2160
3755
  authorized_client[:validating,
@@ -2173,7 +3768,7 @@ describe Mongo::Collection do
2173
3768
 
2174
3769
  let(:result) do
2175
3770
  collection_with_validator.update_many(
2176
- { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
3771
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
2177
3772
  end
2178
3773
 
2179
3774
  it 'updates successfully' do
@@ -2187,7 +3782,7 @@ describe Mongo::Collection do
2187
3782
 
2188
3783
  let(:result2) do
2189
3784
  collection_with_validator.update_many(
2190
- { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
3785
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
2191
3786
  end
2192
3787
 
2193
3788
  it 'raises OperationFailure' do
@@ -2201,8 +3796,8 @@ describe Mongo::Collection do
2201
3796
 
2202
3797
  let(:result3) do
2203
3798
  collection_with_validator.update_many(
2204
- { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
2205
- :bypass_document_validation => true)
3799
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
3800
+ :bypass_document_validation => true)
2206
3801
  end
2207
3802
 
2208
3803
  it 'updates successfully' do
@@ -2231,7 +3826,8 @@ describe Mongo::Collection do
2231
3826
  { collation: { locale: 'en_US', strength: 2 } }
2232
3827
  end
2233
3828
 
2234
- context 'when the server selected supports collations', if: collation_enabled? do
3829
+ context 'when the server selected supports collations' do
3830
+ min_server_fcv '3.4'
2235
3831
 
2236
3832
  it 'applies the collation' do
2237
3833
  expect(result.written_count).to eq(2)
@@ -2269,7 +3865,8 @@ describe Mongo::Collection do
2269
3865
  end
2270
3866
  end
2271
3867
 
2272
- context 'when the server selected does not support collations', unless: collation_enabled? do
3868
+ context 'when the server selected does not support collations' do
3869
+ max_server_version '3.2'
2273
3870
 
2274
3871
  it 'raises an exception' do
2275
3872
  expect {
@@ -2311,6 +3908,102 @@ describe Mongo::Collection do
2311
3908
  expect(result.written_count).to eq(0)
2312
3909
  end
2313
3910
  end
3911
+
3912
+ context 'when a session is provided' do
3913
+
3914
+ let(:selector) do
3915
+ { name: 'BANG' }
3916
+ end
3917
+
3918
+ let(:operation) do
3919
+ authorized_collection.update_many(selector, { '$set' => {other: 'doink'} }, session: session)
3920
+ end
3921
+
3922
+ before do
3923
+ authorized_collection.insert_one(name: 'bang')
3924
+ authorized_collection.insert_one(name: 'baNG')
3925
+ end
3926
+
3927
+ let(:session) do
3928
+ authorized_client.start_session
3929
+ end
3930
+
3931
+ let(:failed_operation) do
3932
+ authorized_collection.update_many({ '$._id' => 1 }, { '$set' => {other: 'doink'} }, session: session)
3933
+ end
3934
+
3935
+ let(:client) do
3936
+ authorized_client
3937
+ end
3938
+
3939
+ it_behaves_like 'an operation using a session'
3940
+ it_behaves_like 'a failed operation using a session'
3941
+ end
3942
+
3943
+ context 'when unacknowledged writes is used with an explicit session' do
3944
+
3945
+ let(:collection_with_unacknowledged_write_concern) do
3946
+ authorized_collection.with(write: { w: 0 })
3947
+ end
3948
+
3949
+ let(:operation) do
3950
+ collection_with_unacknowledged_write_concern.update_many({a: 1}, { '$set' => {x: 1} }, session: session)
3951
+ end
3952
+
3953
+ it_behaves_like 'an explicit session with an unacknowledged write'
3954
+ end
3955
+
3956
+ context 'when unacknowledged writes is used with an implicit session' do
3957
+
3958
+ let(:collection_with_unacknowledged_write_concern) do
3959
+ client.with(write: { w: 0 })[TEST_COLL]
3960
+ end
3961
+
3962
+ let(:operation) do
3963
+ collection_with_unacknowledged_write_concern.update_many({a: 1}, {'$set' => {x: 1}})
3964
+ end
3965
+
3966
+ it_behaves_like 'an implicit session with an unacknowledged write'
3967
+ end
3968
+
3969
+ context 'when various options passed in' do
3970
+ # w: 2 requires a replica set
3971
+ require_topology :replica_set
3972
+
3973
+ # https://jira.mongodb.org/browse/RUBY-2306
3974
+ min_server_fcv '3.6'
3975
+
3976
+ before do
3977
+ collection.insert_many([{ field: 'test' }, { field: 'test2' }], session: session)
3978
+ end
3979
+
3980
+ let(:session) do
3981
+ authorized_client.start_session
3982
+ end
3983
+
3984
+ let(:collection) do
3985
+ authorized_collection.with(write_concern: {w: 1})
3986
+ end
3987
+
3988
+ let(:events) do
3989
+ subscriber.command_started_events('update')
3990
+ end
3991
+
3992
+ let!(:command) do
3993
+ Utils.get_command_event(authorized_client, 'update') do |client|
3994
+ collection.update_many(selector, {'$set'=> { field: 'testing' }}, session: session,
3995
+ write_concern: {w: 2}, bypass_document_validation: true, upsert: true)
3996
+ end.command
3997
+ end
3998
+
3999
+ it 'updates many successfully with correct options sent to server' do
4000
+ expect(events.length).to eq(1)
4001
+ expect(collection.options[:write_concern]).to eq(w: 1)
4002
+ expect(command[:writeConcern][:w]).to eq(2)
4003
+ expect(command[:bypassDocumentValidation]).to be(true)
4004
+ expect(command[:updates][0][:upsert]).to be(true)
4005
+ end
4006
+ end
2314
4007
  end
2315
4008
 
2316
4009
  describe '#update_one' do
@@ -2346,7 +4039,7 @@ describe Mongo::Collection do
2346
4039
 
2347
4040
  let(:response) do
2348
4041
  authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
2349
- upsert: false)
4042
+ upsert: false)
2350
4043
  end
2351
4044
 
2352
4045
  let(:updated) do
@@ -2366,7 +4059,7 @@ describe Mongo::Collection do
2366
4059
 
2367
4060
  let!(:response) do
2368
4061
  authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
2369
- upsert: true)
4062
+ upsert: true)
2370
4063
  end
2371
4064
 
2372
4065
  let(:updated) do
@@ -2414,7 +4107,8 @@ describe Mongo::Collection do
2414
4107
  end
2415
4108
  end
2416
4109
 
2417
- context 'when collection has a validator', if: find_command_enabled? do
4110
+ context 'when collection has a validator' do
4111
+ min_server_fcv '3.2'
2418
4112
 
2419
4113
  around(:each) do |spec|
2420
4114
  authorized_client[:validating,
@@ -2433,7 +4127,7 @@ describe Mongo::Collection do
2433
4127
 
2434
4128
  let(:result) do
2435
4129
  collection_with_validator.update_one(
2436
- { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
4130
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
2437
4131
  end
2438
4132
 
2439
4133
  it 'updates successfully' do
@@ -2447,7 +4141,7 @@ describe Mongo::Collection do
2447
4141
 
2448
4142
  let(:result2) do
2449
4143
  collection_with_validator.update_one(
2450
- { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
4144
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
2451
4145
  end
2452
4146
 
2453
4147
  it 'raises OperationFailure' do
@@ -2461,8 +4155,8 @@ describe Mongo::Collection do
2461
4155
 
2462
4156
  let(:result3) do
2463
4157
  collection_with_validator.update_one(
2464
- { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
2465
- :bypass_document_validation => true)
4158
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
4159
+ :bypass_document_validation => true)
2466
4160
  end
2467
4161
 
2468
4162
  it 'updates successfully' do
@@ -2490,7 +4184,8 @@ describe Mongo::Collection do
2490
4184
  { collation: { locale: 'en_US', strength: 2 } }
2491
4185
  end
2492
4186
 
2493
- context 'when the server selected supports collations', if: collation_enabled? do
4187
+ context 'when the server selected supports collations' do
4188
+ min_server_fcv '3.4'
2494
4189
 
2495
4190
  it 'applies the collation' do
2496
4191
  expect(result.written_count).to eq(1)
@@ -2513,60 +4208,259 @@ describe Mongo::Collection do
2513
4208
  }.to raise_exception(Mongo::Error::UnsupportedCollation)
2514
4209
  end
2515
4210
 
2516
- context 'when a String key is used' do
4211
+ context 'when a String key is used' do
4212
+
4213
+ let(:options) do
4214
+ { 'collation' => { locale: 'en_US', strength: 2 } }
4215
+ end
4216
+
4217
+ it 'raises an exception' do
4218
+ expect {
4219
+ result
4220
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
4221
+ end
4222
+ end
4223
+ end
4224
+ end
4225
+
4226
+ context 'when the server selected does not support collations' do
4227
+ max_server_version '3.2'
4228
+
4229
+ it 'raises an exception' do
4230
+ expect {
4231
+ result
4232
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
4233
+ end
4234
+
4235
+ context 'when a String key is used' do
4236
+
4237
+ let(:options) do
4238
+ { 'collation' => { locale: 'en_US', strength: 2 } }
4239
+ end
4240
+
4241
+ it 'raises an exception' do
4242
+ expect {
4243
+ result
4244
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
4245
+ end
4246
+ end
4247
+ end
4248
+ end
4249
+
4250
+ context 'when a collation is not specified' do
4251
+
4252
+ let(:selector) do
4253
+ { name: 'BANG' }
4254
+ end
4255
+
4256
+ let(:result) do
4257
+ authorized_collection.update_one(selector, { '$set' => { other: 'doink' } })
4258
+ end
4259
+
4260
+ before do
4261
+ authorized_collection.insert_one(name: 'bang')
4262
+ end
4263
+
4264
+ it 'does not apply the collation' do
4265
+ expect(result.written_count).to eq(0)
4266
+ end
4267
+ end
4268
+
4269
+
4270
+ context 'when arrayFilters is provided' do
4271
+
4272
+ let(:selector) do
4273
+ { _id: 0}
4274
+ end
4275
+
4276
+ context 'when the server supports arrayFilters' do
4277
+ min_server_fcv '3.6'
4278
+
4279
+ before do
4280
+ authorized_collection.insert_one(_id: 0, x: [{ y: 1 }, { y: 2 }, {y: 3 }])
4281
+ end
4282
+
4283
+ let(:result) do
4284
+ authorized_collection.update_one(selector,
4285
+ { '$set' => { 'x.$[i].y' => 5 } },
4286
+ options)
4287
+ end
4288
+
4289
+ context 'when a Symbol key is used' do
4290
+
4291
+ let(:options) do
4292
+ { array_filters: [{ 'i.y' => 3 }] }
4293
+ end
4294
+
4295
+ it 'applies the arrayFilters' do
4296
+ expect(result.matched_count).to eq(1)
4297
+ expect(result.modified_count).to eq(1)
4298
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
4299
+ end
4300
+ end
4301
+
4302
+ context 'when a String key is used' do
4303
+
4304
+ let(:options) do
4305
+ { 'array_filters' => [{ 'i.y' => 3 }] }
4306
+ end
4307
+
4308
+ it 'applies the arrayFilters' do
4309
+ expect(result.matched_count).to eq(1)
4310
+ expect(result.modified_count).to eq(1)
4311
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
4312
+ end
4313
+ end
4314
+ end
4315
+
4316
+ context 'when the server does not support arrayFilters' do
4317
+ max_server_version '3.4'
4318
+
4319
+ let(:result) do
4320
+ authorized_collection.update_one(selector,
4321
+ { '$set' => { 'x.$[i].y' => 5 } },
4322
+ options)
4323
+ end
4324
+
4325
+ context 'when a Symbol key is used' do
4326
+
4327
+ let(:options) do
4328
+ { array_filters: [{ 'i.y' => 3 }] }
4329
+ end
4330
+
4331
+ it 'raises an exception' do
4332
+ expect {
4333
+ result
4334
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
4335
+ end
4336
+ end
4337
+
4338
+ context 'when a String key is used' do
4339
+
4340
+ let(:options) do
4341
+ { 'array_filters' => [{ 'i.y' => 3 }] }
4342
+ end
4343
+
4344
+ it 'raises an exception' do
4345
+ expect {
4346
+ result
4347
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
4348
+ end
4349
+ end
4350
+ end
4351
+ end
4352
+
4353
+ context 'when the documents are sent with OP_MSG' do
4354
+ min_server_fcv '3.6'
4355
+
4356
+ let(:documents) do
4357
+ [{ '_id' => 1, 'name' => '1'*16777191 }, { '_id' => 'y' }]
4358
+ end
4359
+
4360
+ before do
4361
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
4362
+ client[TEST_COLL].update_one({ a: 1 }, {'$set' => { 'name' => '1'*16777149 }})
4363
+ end
4364
+
4365
+ let(:update_events) do
4366
+ subscriber.started_events.select { |e| e.command_name == 'update' }
4367
+ end
4368
+
4369
+ it 'sends the documents in one OP_MSG' do
4370
+ expect(update_events.size).to eq(1)
4371
+ end
4372
+ end
4373
+
4374
+ context 'when a session is provided' do
4375
+
4376
+ before do
4377
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
4378
+ end
4379
+
4380
+ let(:session) do
4381
+ authorized_client.start_session
4382
+ end
4383
+
4384
+ let(:operation) do
4385
+ authorized_collection.update_one({ field: 'test' }, { '$set'=> { field: 'testing' } }, session: session)
4386
+ end
4387
+
4388
+ let(:failed_operation) do
4389
+ authorized_collection.update_one({ '$._id' => 1 }, { '$set'=> { field: 'testing' } }, session: session)
4390
+ end
4391
+
4392
+ let(:client) do
4393
+ authorized_client
4394
+ end
4395
+
4396
+ it_behaves_like 'an operation using a session'
4397
+ it_behaves_like 'a failed operation using a session'
4398
+ end
4399
+
4400
+ context 'when unacknowledged writes is used with an explicit session' do
4401
+
4402
+ let(:collection_with_unacknowledged_write_concern) do
4403
+ authorized_collection.with(write: { w: 0 })
4404
+ end
4405
+
4406
+ let(:operation) do
4407
+ collection_with_unacknowledged_write_concern.update_one({ a: 1 }, { '$set' => { x: 1 } }, session: session)
4408
+ end
2517
4409
 
2518
- let(:options) do
2519
- { 'collation' => { locale: 'en_US', strength: 2 } }
2520
- end
4410
+ it_behaves_like 'an explicit session with an unacknowledged write'
4411
+ end
2521
4412
 
2522
- it 'raises an exception' do
2523
- expect {
2524
- result
2525
- }.to raise_exception(Mongo::Error::UnsupportedCollation)
2526
- end
2527
- end
2528
- end
4413
+ context 'when unacknowledged writes is used with an implicit session' do
4414
+
4415
+ let(:collection_with_unacknowledged_write_concern) do
4416
+ client.with(write: { w: 0 })[TEST_COLL]
2529
4417
  end
2530
4418
 
2531
- context 'when the server selected does not support collations', unless: collation_enabled? do
4419
+ let(:operation) do
4420
+ collection_with_unacknowledged_write_concern.update_one({ a: 1 }, { '$set' => { x: 1 }})
4421
+ end
2532
4422
 
2533
- it 'raises an exception' do
2534
- expect {
2535
- result
2536
- }.to raise_exception(Mongo::Error::UnsupportedCollation)
2537
- end
4423
+ it_behaves_like 'an implicit session with an unacknowledged write'
4424
+ end
2538
4425
 
2539
- context 'when a String key is used' do
4426
+ context 'when various options passed in' do
4427
+ # w: 2 requires a replica set
4428
+ require_topology :replica_set
2540
4429
 
2541
- let(:options) do
2542
- { 'collation' => { locale: 'en_US', strength: 2 } }
2543
- end
4430
+ # https://jira.mongodb.org/browse/RUBY-2306
4431
+ min_server_fcv '3.6'
2544
4432
 
2545
- it 'raises an exception' do
2546
- expect {
2547
- result
2548
- }.to raise_exception(Mongo::Error::UnsupportedCollation)
2549
- end
2550
- end
4433
+ before do
4434
+ collection.insert_many([{ field: 'test1' }, { field: 'test2' }], session: session)
2551
4435
  end
2552
- end
2553
4436
 
2554
- context 'when a collation is not specified' do
4437
+ let(:session) do
4438
+ authorized_client.start_session
4439
+ end
2555
4440
 
2556
- let(:selector) do
2557
- { name: 'BANG' }
4441
+ let(:collection) do
4442
+ authorized_collection.with(write_concern: {w: 1})
2558
4443
  end
2559
4444
 
2560
- let(:result) do
2561
- authorized_collection.update_one(selector, { '$set' => { other: 'doink' } })
4445
+ let(:events) do
4446
+ subscriber.command_started_events('update')
2562
4447
  end
2563
4448
 
2564
- before do
2565
- authorized_collection.insert_one(name: 'bang')
4449
+ let!(:command) do
4450
+ Utils.get_command_event(authorized_client, 'update') do |client|
4451
+ collection.update_one(selector, { '$set'=> { field: 'testing' } }, session: session,
4452
+ write_concern: {w: 2}, bypass_document_validation: true, :return_document => :after,
4453
+ upsert: true)
4454
+ end.command
2566
4455
  end
2567
4456
 
2568
- it 'does not apply the collation' do
2569
- expect(result.written_count).to eq(0)
4457
+ it 'updates one successfully with correct options sent to server' do
4458
+ expect(events.length).to eq(1)
4459
+ expect(command[:writeConcern]).to_not be_nil
4460
+ expect(command[:writeConcern][:w]).to eq(2)
4461
+ expect(collection.options[:write_concern]).to eq(w:1)
4462
+ expect(command[:bypassDocumentValidation]).to be(true)
4463
+ expect(command[:updates][0][:upsert]).to be(true)
2570
4464
  end
2571
4465
  end
2572
4466
  end
@@ -2583,6 +4477,28 @@ describe Mongo::Collection do
2583
4477
 
2584
4478
  context 'when a matching document is found' do
2585
4479
 
4480
+ context 'when a session is provided' do
4481
+
4482
+ let(:operation) do
4483
+ authorized_collection.find_one_and_delete(selector, session: session)
4484
+ end
4485
+
4486
+ let(:failed_operation) do
4487
+ authorized_collection.find_one_and_delete({ '$._id' => 1 }, session: session)
4488
+ end
4489
+
4490
+ let(:session) do
4491
+ authorized_client.start_session
4492
+ end
4493
+
4494
+ let(:client) do
4495
+ authorized_client
4496
+ end
4497
+
4498
+ it_behaves_like 'an operation using a session'
4499
+ it_behaves_like 'a failed operation using a session'
4500
+ end
4501
+
2586
4502
  context 'when no options are provided' do
2587
4503
 
2588
4504
  let!(:document) do
@@ -2629,7 +4545,7 @@ describe Mongo::Collection do
2629
4545
  end
2630
4546
  end
2631
4547
 
2632
- context 'when max_time_ms is provided', if: write_command_enabled? do
4548
+ context 'when max_time_ms is provided' do
2633
4549
 
2634
4550
  it 'includes the max_time_ms value in the command' do
2635
4551
  expect {
@@ -2654,7 +4570,7 @@ describe Mongo::Collection do
2654
4570
  end
2655
4571
  end
2656
4572
 
2657
- context 'when the operation fails', if: write_command_enabled? do
4573
+ context 'when the operation fails' do
2658
4574
 
2659
4575
  let(:result) do
2660
4576
  authorized_collection.find_one_and_delete(selector, max_time_ms: 0.1)
@@ -2667,7 +4583,9 @@ describe Mongo::Collection do
2667
4583
  end
2668
4584
  end
2669
4585
 
2670
- context 'when write_concern is provided', if: find_command_enabled? && standalone? do
4586
+ context 'when write_concern is provided' do
4587
+ min_server_fcv '3.2'
4588
+ require_topology :single
2671
4589
 
2672
4590
  it 'uses the write concern' do
2673
4591
  expect {
@@ -2677,7 +4595,9 @@ describe Mongo::Collection do
2677
4595
  end
2678
4596
  end
2679
4597
 
2680
- context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
4598
+ context 'when the collection has a write concern' do
4599
+ min_server_fcv '3.2'
4600
+ require_topology :single
2681
4601
 
2682
4602
  let(:collection) do
2683
4603
  authorized_collection.with(write: { w: 2 })
@@ -2709,7 +4629,8 @@ describe Mongo::Collection do
2709
4629
  { collation: { locale: 'en_US', strength: 2 } }
2710
4630
  end
2711
4631
 
2712
- context 'when the server selected supports collations', if: collation_enabled? do
4632
+ context 'when the server selected supports collations' do
4633
+ min_server_fcv '3.4'
2713
4634
 
2714
4635
  it 'applies the collation' do
2715
4636
  expect(result['name']).to eq('bang')
@@ -2717,7 +4638,8 @@ describe Mongo::Collection do
2717
4638
  end
2718
4639
  end
2719
4640
 
2720
- context 'when the server selected does not support collations', unless: collation_enabled? do
4641
+ context 'when the server selected does not support collations' do
4642
+ max_server_version '3.2'
2721
4643
 
2722
4644
  it 'raises an exception' do
2723
4645
  expect {
@@ -2758,6 +4680,46 @@ describe Mongo::Collection do
2758
4680
  expect(result).to be_nil
2759
4681
  end
2760
4682
  end
4683
+
4684
+ context 'when various options passed in' do
4685
+ # w: 2 requires a replica set
4686
+ require_topology :replica_set
4687
+
4688
+ # https://jira.mongodb.org/browse/RUBY-2306
4689
+ min_server_fcv '3.6'
4690
+
4691
+ before do
4692
+ authorized_collection.delete_many
4693
+ authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
4694
+ end
4695
+
4696
+ let(:collection) do
4697
+ authorized_collection.with(write_concern: {w: 2})
4698
+ end
4699
+
4700
+ let(:session) do
4701
+ authorized_client.start_session
4702
+ end
4703
+
4704
+ let!(:command) do
4705
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
4706
+ collection.find_one_and_delete(selector, session: session, write_concern: {w: 2},
4707
+ bypass_document_validation: true, max_time_ms: 300)
4708
+ end.command
4709
+ end
4710
+
4711
+ let(:events) do
4712
+ subscriber.command_started_events('findAndModify')
4713
+ end
4714
+
4715
+ it 'finds and deletes successfully with correct options sent to server' do
4716
+ expect(events.length).to eq(1)
4717
+ expect(command[:writeConcern]).to_not be_nil
4718
+ expect(command[:writeConcern][:w]).to eq(2)
4719
+ expect(command[:bypassDocumentValidation]).to eq(true)
4720
+ expect(command[:maxTimeMS]).to eq(300)
4721
+ end
4722
+ end
2761
4723
  end
2762
4724
 
2763
4725
  describe '#find_one_and_update' do
@@ -2783,6 +4745,28 @@ describe Mongo::Collection do
2783
4745
  end
2784
4746
  end
2785
4747
 
4748
+ context 'when a session is provided' do
4749
+
4750
+ let(:operation) do
4751
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, session: session)
4752
+ end
4753
+
4754
+ let(:failed_operation) do
4755
+ authorized_collection.find_one_and_update({ '$._id' => 1 }, { '$set' => { field: 'testing' }}, session: session)
4756
+ end
4757
+
4758
+ let(:session) do
4759
+ authorized_client.start_session
4760
+ end
4761
+
4762
+ let(:client) do
4763
+ authorized_client
4764
+ end
4765
+
4766
+ it_behaves_like 'an operation using a session'
4767
+ it_behaves_like 'a failed operation using a session'
4768
+ end
4769
+
2786
4770
  context 'when no options are provided' do
2787
4771
 
2788
4772
  let(:document) do
@@ -2845,7 +4829,7 @@ describe Mongo::Collection do
2845
4829
 
2846
4830
  context 'when max_time_ms is provided' do
2847
4831
 
2848
- it 'includes the max_time_ms value in the command', if: write_command_enabled? do
4832
+ it 'includes the max_time_ms value in the command' do
2849
4833
  expect {
2850
4834
  authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
2851
4835
  }.to raise_error(Mongo::Error::OperationFailure)
@@ -2900,7 +4884,7 @@ describe Mongo::Collection do
2900
4884
  end
2901
4885
  end
2902
4886
 
2903
- context 'when the operation fails', if: write_command_enabled? do
4887
+ context 'when the operation fails' do
2904
4888
 
2905
4889
  let(:result) do
2906
4890
  authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
@@ -2913,9 +4897,11 @@ describe Mongo::Collection do
2913
4897
  end
2914
4898
  end
2915
4899
 
2916
- context 'when collection has a validator', if: find_command_enabled? do
4900
+ context 'when collection has a validator' do
4901
+ min_server_fcv '3.2'
2917
4902
 
2918
4903
  around(:each) do |spec|
4904
+ authorized_client[:validating].drop
2919
4905
  authorized_client[:validating,
2920
4906
  :validator => { :a => { '$exists' => true } }].tap do |c|
2921
4907
  c.create
@@ -2932,7 +4918,7 @@ describe Mongo::Collection do
2932
4918
 
2933
4919
  let(:result) do
2934
4920
  collection_with_validator.find_one_and_update(
2935
- { a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
4921
+ { a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
2936
4922
  end
2937
4923
 
2938
4924
  it 'updates successfully' do
@@ -2946,7 +4932,7 @@ describe Mongo::Collection do
2946
4932
 
2947
4933
  let(:result2) do
2948
4934
  collection_with_validator.find_one_and_update(
2949
- { a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
4935
+ { a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
2950
4936
  end
2951
4937
 
2952
4938
  it 'raises OperationFailure' do
@@ -2960,9 +4946,9 @@ describe Mongo::Collection do
2960
4946
 
2961
4947
  let(:result3) do
2962
4948
  collection_with_validator.find_one_and_update(
2963
- { a: 1 }, { '$unset' => { :a => '' } },
2964
- :bypass_document_validation => true,
2965
- :return_document => :after)
4949
+ { a: 1 }, { '$unset' => { :a => '' } },
4950
+ :bypass_document_validation => true,
4951
+ :return_document => :after)
2966
4952
  end
2967
4953
 
2968
4954
  it 'updates successfully' do
@@ -2972,18 +4958,22 @@ describe Mongo::Collection do
2972
4958
  end
2973
4959
  end
2974
4960
 
2975
- context 'when write_concern is provided', if: find_command_enabled? && standalone? do
4961
+ context 'when write_concern is provided' do
4962
+ min_server_fcv '3.2'
4963
+ require_topology :single
2976
4964
 
2977
4965
  it 'uses the write concern' do
2978
4966
  expect {
2979
4967
  authorized_collection.find_one_and_update(selector,
2980
- { '$set' => { field: 'testing' }},
2981
- write_concern: { w: 2 })
4968
+ { '$set' => { field: 'testing' }},
4969
+ write_concern: { w: 2 })
2982
4970
  }.to raise_error(Mongo::Error::OperationFailure)
2983
4971
  end
2984
4972
  end
2985
4973
 
2986
- context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
4974
+ context 'when the collection has a write concern' do
4975
+ min_server_fcv '3.2'
4976
+ require_topology :single
2987
4977
 
2988
4978
  let(:collection) do
2989
4979
  authorized_collection.with(write: { w: 2 })
@@ -3018,7 +5008,8 @@ describe Mongo::Collection do
3018
5008
  { collation: { locale: 'en_US', strength: 2 } }
3019
5009
  end
3020
5010
 
3021
- context 'when the server selected supports collations', if: collation_enabled? do
5011
+ context 'when the server selected supports collations' do
5012
+ min_server_fcv '3.4'
3022
5013
 
3023
5014
  it 'applies the collation' do
3024
5015
  expect(result['name']).to eq('bang')
@@ -3026,7 +5017,8 @@ describe Mongo::Collection do
3026
5017
  end
3027
5018
  end
3028
5019
 
3029
- context 'when the server selected does not support collations', unless: collation_enabled? do
5020
+ context 'when the server selected does not support collations' do
5021
+ max_server_version '3.2'
3030
5022
 
3031
5023
  it 'raises an exception' do
3032
5024
  expect {
@@ -3067,6 +5059,133 @@ describe Mongo::Collection do
3067
5059
  expect(result).to be_nil
3068
5060
  end
3069
5061
  end
5062
+
5063
+ context 'when arrayFilters is provided' do
5064
+
5065
+ let(:selector) do
5066
+ { _id: 0 }
5067
+ end
5068
+
5069
+ context 'when the server supports arrayFilters' do
5070
+ min_server_fcv '3.6'
5071
+
5072
+ before do
5073
+ authorized_collection.insert_one(_id: 0, x: [{ y: 1 }, { y: 2 }, { y: 3 }])
5074
+ end
5075
+
5076
+ let(:result) do
5077
+ authorized_collection.find_one_and_update(selector,
5078
+ { '$set' => { 'x.$[i].y' => 5 } },
5079
+ options)
5080
+ end
5081
+
5082
+ context 'when a Symbol key is used' do
5083
+
5084
+ let(:options) do
5085
+ { array_filters: [{ 'i.y' => 3 }] }
5086
+ end
5087
+
5088
+
5089
+ it 'applies the arrayFilters' do
5090
+ expect(result['x']).to eq([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 3 }])
5091
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
5092
+ end
5093
+ end
5094
+
5095
+ context 'when a String key is used' do
5096
+
5097
+ let(:options) do
5098
+ { 'array_filters' => [{ 'i.y' => 3 }] }
5099
+ end
5100
+
5101
+ it 'applies the arrayFilters' do
5102
+ expect(result['x']).to eq([{ 'y' => 1 }, { 'y' => 2 }, { 'y' => 3 }])
5103
+ expect(authorized_collection.find(selector).first['x'].last['y']).to eq(5)
5104
+ end
5105
+ end
5106
+ end
5107
+
5108
+ context 'when the server selected does not support arrayFilters' do
5109
+ max_server_version '3.4'
5110
+
5111
+ let(:result) do
5112
+ authorized_collection.find_one_and_update(selector,
5113
+ { '$set' => { 'x.$[i].y' => 5 } },
5114
+ options)
5115
+ end
5116
+
5117
+ context 'when a Symbol key is used' do
5118
+
5119
+ let(:options) do
5120
+ { array_filters: [{ 'i.y' => 3 }] }
5121
+ end
5122
+
5123
+ it 'raises an exception' do
5124
+ expect {
5125
+ result
5126
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
5127
+ end
5128
+ end
5129
+
5130
+ context 'when a String key is used' do
5131
+
5132
+ let(:options) do
5133
+ { 'array_filters' => [{ 'i.y' => 3 }] }
5134
+ end
5135
+
5136
+ it 'raises an exception' do
5137
+ expect {
5138
+ result
5139
+ }.to raise_exception(Mongo::Error::UnsupportedArrayFilters)
5140
+ end
5141
+ end
5142
+ end
5143
+ end
5144
+
5145
+ context 'when various options passed in' do
5146
+ # w: 2 requires a replica set
5147
+ require_topology :replica_set
5148
+
5149
+ # https://jira.mongodb.org/browse/RUBY-2306
5150
+ min_server_fcv '3.6'
5151
+
5152
+ let(:session) do
5153
+ authorized_client.start_session
5154
+ end
5155
+
5156
+ let(:events) do
5157
+ subscriber.command_started_events('findAndModify')
5158
+ end
5159
+
5160
+ let(:collection) do
5161
+ authorized_collection.with(write_concern: {w: 2})
5162
+ end
5163
+
5164
+ let(:selector) do
5165
+ {field: 'test1'}
5166
+ end
5167
+
5168
+ before do
5169
+ collection.insert_one({field: 'test1'}, session: session)
5170
+ end
5171
+
5172
+ let!(:command) do
5173
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
5174
+ collection.find_one_and_update(selector, { '$set' => {field: 'testing'}},
5175
+ :return_document => :after, write_concern: {w: 1}, upsert: true,
5176
+ bypass_document_validation: true, max_time_ms: 100, session: session)
5177
+ end.command
5178
+ end
5179
+
5180
+ it 'find and updates successfully with correct options sent to server' do
5181
+ expect(events.length).to eq(1)
5182
+ expect(command[:writeConcern]).to_not be_nil
5183
+ expect(command[:writeConcern][:w]).to eq(1)
5184
+ expect(command[:upsert]).to eq(true)
5185
+ expect(command[:bypassDocumentValidation]).to be(true)
5186
+ expect(command[:maxTimeMS]).to eq(100)
5187
+ end
5188
+ end
3070
5189
  end
3071
5190
 
3072
5191
  describe '#find_one_and_replace' do
@@ -3092,6 +5211,28 @@ describe Mongo::Collection do
3092
5211
  end
3093
5212
  end
3094
5213
 
5214
+ context 'when a session is provided' do
5215
+
5216
+ let(:operation) do
5217
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, session: session)
5218
+ end
5219
+
5220
+ let(:failed_operation) do
5221
+ authorized_collection.find_one_and_replace({ '$._id' => 1}, { field: 'testing' }, session: session)
5222
+ end
5223
+
5224
+ let(:session) do
5225
+ authorized_client.start_session
5226
+ end
5227
+
5228
+ let(:client) do
5229
+ authorized_client
5230
+ end
5231
+
5232
+ it_behaves_like 'an operation using a session'
5233
+ it_behaves_like 'a failed operation using a session'
5234
+ end
5235
+
3095
5236
  context 'when return_document options are provided' do
3096
5237
 
3097
5238
  context 'when return_document is :after' do
@@ -3174,7 +5315,7 @@ describe Mongo::Collection do
3174
5315
  end
3175
5316
  end
3176
5317
 
3177
- context 'when max_time_ms is provided', if: write_command_enabled? do
5318
+ context 'when max_time_ms is provided' do
3178
5319
 
3179
5320
  it 'includes the max_time_ms value in the command' do
3180
5321
  expect {
@@ -3183,7 +5324,7 @@ describe Mongo::Collection do
3183
5324
  end
3184
5325
  end
3185
5326
 
3186
- context 'when the operation fails', if: write_command_enabled? do
5327
+ context 'when the operation fails' do
3187
5328
 
3188
5329
  let(:result) do
3189
5330
  authorized_collection.find_one_and_replace(selector, { field: 'testing' }, max_time_ms: 0.1)
@@ -3196,9 +5337,11 @@ describe Mongo::Collection do
3196
5337
  end
3197
5338
  end
3198
5339
 
3199
- context 'when collection has a validator', if: find_command_enabled? do
5340
+ context 'when collection has a validator' do
5341
+ min_server_fcv '3.2'
3200
5342
 
3201
5343
  around(:each) do |spec|
5344
+ authorized_client[:validating].drop
3202
5345
  authorized_client[:validating,
3203
5346
  :validator => { :a => { '$exists' => true } }].tap do |c|
3204
5347
  c.create
@@ -3215,7 +5358,7 @@ describe Mongo::Collection do
3215
5358
 
3216
5359
  let(:result) do
3217
5360
  collection_with_validator.find_one_and_replace(
3218
- { a: 1 }, { a: 5 }, :return_document => :after)
5361
+ { a: 1 }, { a: 5 }, :return_document => :after)
3219
5362
  end
3220
5363
 
3221
5364
  it 'replaces successfully when document is valid' do
@@ -3229,7 +5372,7 @@ describe Mongo::Collection do
3229
5372
 
3230
5373
  let(:result2) do
3231
5374
  collection_with_validator.find_one_and_replace(
3232
- { a: 1 }, { x: 5 }, :return_document => :after)
5375
+ { a: 1 }, { x: 5 }, :return_document => :after)
3233
5376
  end
3234
5377
 
3235
5378
  it 'raises OperationFailure' do
@@ -3243,8 +5386,8 @@ describe Mongo::Collection do
3243
5386
 
3244
5387
  let(:result3) do
3245
5388
  collection_with_validator.find_one_and_replace(
3246
- { a: 1 }, { x: 1 }, :bypass_document_validation => true,
3247
- :return_document => :after)
5389
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true,
5390
+ :return_document => :after)
3248
5391
  end
3249
5392
 
3250
5393
  it 'replaces successfully' do
@@ -3255,7 +5398,9 @@ describe Mongo::Collection do
3255
5398
  end
3256
5399
  end
3257
5400
 
3258
- context 'when write_concern is provided', if: find_command_enabled? && standalone? do
5401
+ context 'when write_concern is provided' do
5402
+ min_server_fcv '3.2'
5403
+ require_topology :single
3259
5404
 
3260
5405
  it 'uses the write concern' do
3261
5406
  expect {
@@ -3266,7 +5411,9 @@ describe Mongo::Collection do
3266
5411
  end
3267
5412
  end
3268
5413
 
3269
- context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
5414
+ context 'when the collection has a write concern' do
5415
+ min_server_fcv '3.2'
5416
+ require_topology :single
3270
5417
 
3271
5418
  let(:collection) do
3272
5419
  authorized_collection.with(write: { w: 2 })
@@ -3301,7 +5448,8 @@ describe Mongo::Collection do
3301
5448
  { collation: { locale: 'en_US', strength: 2 } }
3302
5449
  end
3303
5450
 
3304
- context 'when the server selected supports collations', if: collation_enabled? do
5451
+ context 'when the server selected supports collations' do
5452
+ min_server_fcv '3.4'
3305
5453
 
3306
5454
  it 'applies the collation' do
3307
5455
  expect(result['name']).to eq('bang')
@@ -3309,7 +5457,8 @@ describe Mongo::Collection do
3309
5457
  end
3310
5458
  end
3311
5459
 
3312
- context 'when the server selected does not support collations', unless: collation_enabled? do
5460
+ context 'when the server selected does not support collations' do
5461
+ max_server_version '3.2'
3313
5462
 
3314
5463
  it 'raises an exception' do
3315
5464
  expect {
@@ -3350,5 +5499,157 @@ describe Mongo::Collection do
3350
5499
  expect(result).to be_nil
3351
5500
  end
3352
5501
  end
5502
+
5503
+ context 'when various options passed in' do
5504
+ # https://jira.mongodb.org/browse/RUBY-2306
5505
+ min_server_fcv '3.6'
5506
+
5507
+ before do
5508
+ authorized_collection.insert_one({field: 'test1'})
5509
+ end
5510
+
5511
+ let(:session) do
5512
+ authorized_client.start_session
5513
+ end
5514
+
5515
+ let(:events) do
5516
+ subscriber.command_started_events('findAndModify')
5517
+ end
5518
+
5519
+ let(:collection) do
5520
+ authorized_collection.with(write_concern: { w: 2 })
5521
+ end
5522
+
5523
+ let!(:command) do
5524
+ Utils.get_command_event(authorized_client, 'findAndModify') do |client|
5525
+ collection.find_one_and_replace(selector, { '$set' => {field: 'test5'}},
5526
+ :return_document => :after, write_concern: {w: 1}, session: session,
5527
+ upsert: true, bypass_document_validation: false, max_time_ms: 200)
5528
+ end.command
5529
+ end
5530
+
5531
+ it 'find and replaces successfully with correct options sent to server' do
5532
+ expect(events.length).to eq(1)
5533
+ expect(command[:writeConcern]).to_not be_nil
5534
+ expect(command[:writeConcern][:w]).to eq(1)
5535
+ expect(command[:upsert]).to be(true)
5536
+ expect(command[:bypassDocumentValidation]).to be_nil
5537
+ expect(command[:maxTimeMS]).to eq(200)
5538
+ end
5539
+ end
5540
+ end
5541
+
5542
+ describe '#watch' do
5543
+
5544
+ context 'when change streams can be tested' do
5545
+ require_wired_tiger
5546
+ min_server_fcv '3.6'
5547
+ require_topology :replica_set
5548
+
5549
+ let(:change_stream) do
5550
+ authorized_collection.watch
5551
+ end
5552
+
5553
+ let(:enum) do
5554
+ change_stream.to_enum
5555
+ end
5556
+
5557
+ before do
5558
+ change_stream
5559
+ authorized_collection.insert_one(a: 1)
5560
+ end
5561
+
5562
+ context 'when no options are provided' do
5563
+
5564
+ context 'when the operation type is an insert' do
5565
+
5566
+ it 'returns the change' do
5567
+ expect(enum.next[:fullDocument][:a]).to eq(1)
5568
+ end
5569
+ end
5570
+
5571
+ context 'when the operation type is an update' do
5572
+
5573
+ before do
5574
+ authorized_collection.update_one({ a: 1 }, { '$set' => { a: 2 } })
5575
+ end
5576
+
5577
+ let(:change_doc) do
5578
+ enum.next
5579
+ enum.next
5580
+ end
5581
+
5582
+ it 'returns the change' do
5583
+ expect(change_doc[:operationType]).to eq('update')
5584
+ expect(change_doc[:updateDescription][:updatedFields]).to eq('a' => 2)
5585
+ end
5586
+ end
5587
+ end
5588
+
5589
+ context 'when options are provided' do
5590
+
5591
+ context 'when full_document is updateLookup' do
5592
+
5593
+ let(:change_stream) do
5594
+ authorized_collection.watch([], full_document: 'updateLookup').to_enum
5595
+ end
5596
+
5597
+ before do
5598
+ authorized_collection.update_one({ a: 1 }, { '$set' => { a: 2 } })
5599
+ end
5600
+
5601
+ let(:change_doc) do
5602
+ enum.next
5603
+ enum.next
5604
+ end
5605
+
5606
+ it 'returns the change' do
5607
+ expect(change_doc[:operationType]).to eq('update')
5608
+ expect(change_doc[:fullDocument][:a]).to eq(2)
5609
+ end
5610
+ end
5611
+
5612
+ context 'when batch_size is provided' do
5613
+
5614
+ before do
5615
+ Thread.new do
5616
+ sleep 1
5617
+ authorized_collection.insert_one(a: 2)
5618
+ authorized_collection.insert_one(a: 3)
5619
+ end
5620
+ end
5621
+
5622
+ let(:change_stream) do
5623
+ authorized_collection.watch([], batch_size: 2)
5624
+ end
5625
+
5626
+ it 'returns the documents in the batch size specified' do
5627
+ expect(change_stream.instance_variable_get(:@cursor)).to receive(:get_more).once.and_call_original
5628
+ enum.next
5629
+ end
5630
+ end
5631
+
5632
+ context 'when collation is provided' do
5633
+
5634
+ before do
5635
+ authorized_collection.update_one({ a: 1 }, { '$set' => { a: 2 } })
5636
+ end
5637
+
5638
+ let(:change_doc) do
5639
+ enum.next
5640
+ end
5641
+
5642
+ let(:change_stream) do
5643
+ authorized_collection.watch([ { '$match' => { operationType: 'UPDATE'}}],
5644
+ collation: { locale: 'en_US', strength: 2 } ).to_enum
5645
+ end
5646
+
5647
+ it 'returns the change' do
5648
+ expect(change_doc['operationType']).to eq('update')
5649
+ expect(change_doc['updateDescription']['updatedFields']['a']).to eq(2)
5650
+ end
5651
+ end
5652
+ end
5653
+ end
3353
5654
  end
3354
5655
  end