mongo 2.5.3 → 2.6.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 (394) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +1 -1
  5. data/README.md +3 -2
  6. data/lib/mongo.rb +2 -2
  7. data/lib/mongo/address.rb +10 -2
  8. data/lib/mongo/address/ipv4.rb +1 -1
  9. data/lib/mongo/address/ipv6.rb +26 -5
  10. data/lib/mongo/address/unix.rb +1 -1
  11. data/lib/mongo/auth.rb +10 -3
  12. data/lib/mongo/auth/cr.rb +4 -1
  13. data/lib/mongo/auth/cr/conversation.rb +4 -1
  14. data/lib/mongo/auth/ldap.rb +1 -1
  15. data/lib/mongo/auth/ldap/conversation.rb +1 -1
  16. data/lib/mongo/auth/roles.rb +1 -1
  17. data/lib/mongo/auth/scram.rb +24 -7
  18. data/lib/mongo/auth/scram/conversation.rb +52 -19
  19. data/lib/mongo/auth/stringprep.rb +114 -0
  20. data/lib/mongo/auth/stringprep/profiles/sasl.rb +73 -0
  21. data/lib/mongo/auth/stringprep/tables.rb +3232 -0
  22. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +174 -0
  23. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1170 -0
  24. data/lib/mongo/auth/user.rb +14 -3
  25. data/lib/mongo/auth/user/view.rb +1 -1
  26. data/lib/mongo/auth/x509.rb +1 -1
  27. data/lib/mongo/auth/x509/conversation.rb +1 -1
  28. data/lib/mongo/bson.rb +1 -1
  29. data/lib/mongo/bulk_write.rb +8 -8
  30. data/lib/mongo/bulk_write/combineable.rb +1 -1
  31. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  32. data/lib/mongo/bulk_write/result.rb +1 -1
  33. data/lib/mongo/bulk_write/result_combiner.rb +4 -4
  34. data/lib/mongo/bulk_write/transformable.rb +1 -1
  35. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  36. data/lib/mongo/bulk_write/validatable.rb +1 -1
  37. data/lib/mongo/client.rb +115 -24
  38. data/lib/mongo/cluster.rb +17 -10
  39. data/lib/mongo/cluster/app_metadata.rb +7 -1
  40. data/lib/mongo/cluster/periodic_executor.rb +1 -1
  41. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
  42. data/lib/mongo/cluster/topology.rb +12 -2
  43. data/lib/mongo/cluster/topology/replica_set.rb +9 -1
  44. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  45. data/lib/mongo/cluster/topology/single.rb +1 -1
  46. data/lib/mongo/cluster/topology/unknown.rb +1 -1
  47. data/lib/mongo/collection.rb +75 -19
  48. data/lib/mongo/collection/view.rb +1 -1
  49. data/lib/mongo/collection/view/aggregation.rb +1 -1
  50. data/lib/mongo/collection/view/builder.rb +1 -1
  51. data/lib/mongo/collection/view/builder/aggregation.rb +3 -3
  52. data/lib/mongo/collection/view/builder/find_command.rb +1 -1
  53. data/lib/mongo/collection/view/builder/flags.rb +1 -1
  54. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  55. data/lib/mongo/collection/view/builder/modifiers.rb +1 -1
  56. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  57. data/lib/mongo/collection/view/change_stream.rb +193 -17
  58. data/lib/mongo/collection/view/change_stream/retryable.rb +3 -20
  59. data/lib/mongo/collection/view/explainable.rb +1 -1
  60. data/lib/mongo/collection/view/immutable.rb +1 -1
  61. data/lib/mongo/collection/view/iterable.rb +2 -2
  62. data/lib/mongo/collection/view/map_reduce.rb +1 -1
  63. data/lib/mongo/collection/view/readable.rb +108 -29
  64. data/lib/mongo/collection/view/writable.rb +3 -3
  65. data/lib/mongo/cursor.rb +44 -4
  66. data/lib/mongo/cursor/builder.rb +1 -1
  67. data/lib/mongo/cursor/builder/get_more_command.rb +1 -1
  68. data/lib/mongo/cursor/builder/kill_cursors_command.rb +1 -1
  69. data/lib/mongo/cursor/builder/op_get_more.rb +1 -1
  70. data/lib/mongo/cursor/builder/op_kill_cursors.rb +1 -1
  71. data/lib/mongo/database.rb +46 -3
  72. data/lib/mongo/database/view.rb +11 -11
  73. data/lib/mongo/dbref.rb +1 -1
  74. data/lib/mongo/error.rb +57 -1
  75. data/lib/mongo/error/bulk_write_error.rb +2 -2
  76. data/lib/mongo/error/change_stream_resumable.rb +37 -0
  77. data/lib/mongo/error/closed_stream.rb +1 -1
  78. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  79. data/lib/mongo/error/failed_stringprep_validation.rb +38 -0
  80. data/lib/mongo/error/file_not_found.rb +1 -1
  81. data/lib/mongo/error/insufficient_iteration_count.rb +38 -0
  82. data/lib/mongo/error/invalid_application_name.rb +1 -1
  83. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  84. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  85. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  86. data/lib/mongo/error/invalid_database_name.rb +1 -1
  87. data/lib/mongo/error/invalid_document.rb +1 -1
  88. data/lib/mongo/error/invalid_file.rb +1 -1
  89. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  90. data/lib/mongo/error/invalid_min_pool_size.rb +1 -1
  91. data/lib/mongo/error/invalid_nonce.rb +1 -1
  92. data/lib/mongo/error/invalid_read_option.rb +35 -0
  93. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  94. data/lib/mongo/error/invalid_server_preference.rb +1 -1
  95. data/lib/mongo/error/invalid_session.rb +1 -1
  96. data/lib/mongo/error/invalid_signature.rb +1 -1
  97. data/lib/mongo/error/invalid_transaction_operation.rb +82 -0
  98. data/lib/mongo/error/invalid_txt_record.rb +1 -1
  99. data/lib/mongo/error/invalid_update_document.rb +1 -1
  100. data/lib/mongo/error/invalid_uri.rb +1 -1
  101. data/lib/mongo/error/invalid_write_concern.rb +1 -1
  102. data/lib/mongo/error/max_bson_size.rb +1 -1
  103. data/lib/mongo/error/max_message_size.rb +1 -1
  104. data/lib/mongo/error/mismatched_domain.rb +1 -1
  105. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  106. data/lib/mongo/error/missing_resume_token.rb +1 -1
  107. data/lib/mongo/error/multi_index_drop.rb +1 -1
  108. data/lib/mongo/error/need_primary_server.rb +1 -1
  109. data/lib/mongo/error/no_server_available.rb +1 -1
  110. data/lib/mongo/error/no_srv_records.rb +1 -1
  111. data/lib/mongo/error/operation_failure.rb +108 -14
  112. data/lib/mongo/error/parser.rb +50 -1
  113. data/lib/mongo/error/socket_error.rb +5 -2
  114. data/lib/mongo/error/socket_timeout_error.rb +5 -2
  115. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  116. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  117. data/lib/mongo/error/unexpected_response.rb +1 -1
  118. data/lib/mongo/error/unknown_payload_type.rb +1 -1
  119. data/lib/mongo/error/unsupported_array_filters.rb +1 -1
  120. data/lib/mongo/error/unsupported_collation.rb +1 -1
  121. data/lib/mongo/error/unsupported_features.rb +1 -1
  122. data/lib/mongo/error/unsupported_message_type.rb +1 -1
  123. data/lib/mongo/error/write_retryable.rb +27 -0
  124. data/lib/mongo/event.rb +10 -9
  125. data/lib/mongo/event/base.rb +33 -0
  126. data/lib/mongo/event/description_changed.rb +2 -2
  127. data/lib/mongo/event/listeners.rb +1 -1
  128. data/lib/mongo/event/member_discovered.rb +4 -2
  129. data/lib/mongo/event/primary_elected.rb +2 -2
  130. data/lib/mongo/event/publisher.rb +1 -1
  131. data/lib/mongo/event/standalone_discovered.rb +2 -2
  132. data/lib/mongo/event/subscriber.rb +1 -1
  133. data/lib/mongo/grid.rb +1 -1
  134. data/lib/mongo/grid/file.rb +1 -1
  135. data/lib/mongo/grid/file/chunk.rb +3 -3
  136. data/lib/mongo/grid/file/info.rb +26 -3
  137. data/lib/mongo/grid/fs_bucket.rb +1 -1
  138. data/lib/mongo/grid/stream.rb +1 -1
  139. data/lib/mongo/grid/stream/read.rb +1 -1
  140. data/lib/mongo/grid/stream/write.rb +1 -1
  141. data/lib/mongo/index.rb +1 -1
  142. data/lib/mongo/index/view.rb +1 -1
  143. data/lib/mongo/loggable.rb +1 -1
  144. data/lib/mongo/logger.rb +1 -1
  145. data/lib/mongo/monitoring.rb +99 -62
  146. data/lib/mongo/monitoring/command_log_subscriber.rb +2 -2
  147. data/lib/mongo/monitoring/event.rb +2 -1
  148. data/lib/mongo/monitoring/event/command_failed.rb +19 -6
  149. data/lib/mongo/monitoring/event/command_started.rb +14 -3
  150. data/lib/mongo/monitoring/event/command_succeeded.rb +5 -3
  151. data/lib/mongo/monitoring/event/secure.rb +1 -1
  152. data/lib/mongo/monitoring/event/server_closed.rb +2 -2
  153. data/lib/mongo/monitoring/event/server_description_changed.rb +2 -2
  154. data/lib/mongo/monitoring/event/server_opening.rb +11 -2
  155. data/lib/mongo/monitoring/event/topology_changed.rb +13 -2
  156. data/lib/mongo/monitoring/event/topology_closed.rb +2 -2
  157. data/lib/mongo/monitoring/event/topology_opening.rb +11 -2
  158. data/lib/mongo/monitoring/publishable.rb +10 -6
  159. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  160. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  161. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +1 -1
  162. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  163. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
  164. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +1 -1
  165. data/lib/mongo/operation/aggregate/op_msg.rb +3 -0
  166. data/lib/mongo/operation/create/op_msg.rb +9 -0
  167. data/lib/mongo/operation/create_index/op_msg.rb +9 -0
  168. data/lib/mongo/operation/create_user/command.rb +1 -1
  169. data/lib/mongo/operation/create_user/op_msg.rb +10 -1
  170. data/lib/mongo/operation/delete/op_msg.rb +3 -0
  171. data/lib/mongo/operation/distinct/op_msg.rb +9 -0
  172. data/lib/mongo/operation/drop/op_msg.rb +9 -0
  173. data/lib/mongo/operation/drop_database/op_msg.rb +9 -0
  174. data/lib/mongo/operation/drop_index/op_msg.rb +9 -0
  175. data/lib/mongo/operation/explain/op_msg.rb +3 -0
  176. data/lib/mongo/operation/find/op_msg.rb +3 -0
  177. data/lib/mongo/operation/get_more.rb +1 -1
  178. data/lib/mongo/operation/get_more/command.rb +1 -1
  179. data/lib/mongo/operation/get_more/legacy.rb +1 -1
  180. data/lib/mongo/operation/get_more/op_msg.rb +3 -0
  181. data/lib/mongo/operation/indexes/op_msg.rb +3 -0
  182. data/lib/mongo/operation/indexes/result.rb +1 -1
  183. data/lib/mongo/operation/insert/bulk_result.rb +32 -2
  184. data/lib/mongo/operation/insert/op_msg.rb +3 -0
  185. data/lib/mongo/operation/insert/result.rb +1 -1
  186. data/lib/mongo/operation/kill_cursors/op_msg.rb +9 -0
  187. data/lib/mongo/operation/list_collections/op_msg.rb +3 -0
  188. data/lib/mongo/operation/list_collections/result.rb +5 -1
  189. data/lib/mongo/operation/map_reduce/op_msg.rb +3 -0
  190. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  191. data/lib/mongo/operation/parallel_scan/op_msg.rb +3 -0
  192. data/lib/mongo/operation/remove_user/op_msg.rb +9 -0
  193. data/lib/mongo/operation/result.rb +27 -14
  194. data/lib/mongo/operation/shared/executable.rb +1 -0
  195. data/lib/mongo/operation/shared/sessions_supported.rb +78 -7
  196. data/lib/mongo/operation/shared/specifiable.rb +18 -2
  197. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -1
  198. data/lib/mongo/operation/update/op_msg.rb +3 -0
  199. data/lib/mongo/operation/update_user/command.rb +1 -1
  200. data/lib/mongo/operation/update_user/op_msg.rb +10 -1
  201. data/lib/mongo/operation/users_info/op_msg.rb +3 -0
  202. data/lib/mongo/options.rb +1 -1
  203. data/lib/mongo/options/mapper.rb +1 -1
  204. data/lib/mongo/options/redacted.rb +1 -1
  205. data/lib/mongo/protocol/bit_vector.rb +1 -1
  206. data/lib/mongo/protocol/compressed.rb +1 -1
  207. data/lib/mongo/protocol/delete.rb +1 -1
  208. data/lib/mongo/protocol/get_more.rb +7 -7
  209. data/lib/mongo/protocol/insert.rb +1 -1
  210. data/lib/mongo/protocol/kill_cursors.rb +1 -1
  211. data/lib/mongo/protocol/message.rb +5 -5
  212. data/lib/mongo/protocol/msg.rb +9 -7
  213. data/lib/mongo/protocol/query.rb +1 -1
  214. data/lib/mongo/protocol/registry.rb +1 -1
  215. data/lib/mongo/protocol/reply.rb +10 -10
  216. data/lib/mongo/protocol/serializers.rb +1 -1
  217. data/lib/mongo/protocol/update.rb +1 -1
  218. data/lib/mongo/retryable.rb +22 -14
  219. data/lib/mongo/server.rb +1 -1
  220. data/lib/mongo/server/connectable.rb +1 -1
  221. data/lib/mongo/server/connection.rb +16 -4
  222. data/lib/mongo/server/connection_pool.rb +1 -1
  223. data/lib/mongo/server/connection_pool/queue.rb +1 -1
  224. data/lib/mongo/server/context.rb +1 -1
  225. data/lib/mongo/server/description.rb +14 -2
  226. data/lib/mongo/server/description/features.rb +10 -9
  227. data/lib/mongo/server/description/inspector.rb +1 -1
  228. data/lib/mongo/server/description/inspector/description_changed.rb +1 -1
  229. data/lib/mongo/server/description/inspector/member_discovered.rb +1 -1
  230. data/lib/mongo/server/description/inspector/primary_elected.rb +1 -1
  231. data/lib/mongo/server/description/inspector/standalone_discovered.rb +1 -1
  232. data/lib/mongo/server/monitor.rb +15 -3
  233. data/lib/mongo/server/monitor/connection.rb +1 -1
  234. data/lib/mongo/server_selector.rb +1 -1
  235. data/lib/mongo/server_selector/nearest.rb +1 -1
  236. data/lib/mongo/server_selector/primary.rb +1 -1
  237. data/lib/mongo/server_selector/primary_preferred.rb +1 -1
  238. data/lib/mongo/server_selector/secondary.rb +1 -1
  239. data/lib/mongo/server_selector/secondary_preferred.rb +1 -1
  240. data/lib/mongo/server_selector/selectable.rb +7 -2
  241. data/lib/mongo/session.rb +389 -12
  242. data/lib/mongo/session/server_session.rb +7 -2
  243. data/lib/mongo/session/session_pool.rb +1 -1
  244. data/lib/mongo/socket.rb +1 -1
  245. data/lib/mongo/socket/ssl.rb +1 -1
  246. data/lib/mongo/socket/tcp.rb +1 -1
  247. data/lib/mongo/socket/unix.rb +1 -1
  248. data/lib/mongo/uri.rb +6 -4
  249. data/lib/mongo/uri/srv_protocol.rb +1 -1
  250. data/lib/mongo/version.rb +2 -2
  251. data/lib/mongo/write_concern.rb +1 -1
  252. data/lib/mongo/write_concern/acknowledged.rb +1 -1
  253. data/lib/mongo/write_concern/normalizable.rb +1 -1
  254. data/lib/mongo/write_concern/unacknowledged.rb +1 -1
  255. data/mongo.gemspec +4 -1
  256. data/spec/atlas/atlas_connectivity_spec.rb +54 -0
  257. data/spec/integration/bulk_insert_spec.rb +78 -0
  258. data/spec/integration/change_stream_spec.rb +365 -0
  259. data/spec/integration/command_monitoring_spec.rb +92 -0
  260. data/spec/lite_spec_helper.rb +63 -0
  261. data/spec/mongo/address/ipv6_spec.rb +29 -1
  262. data/spec/mongo/address_spec.rb +34 -0
  263. data/spec/mongo/auth/scram/conversation_spec.rb +326 -120
  264. data/spec/mongo/auth/scram/negotiation_spec.rb +574 -0
  265. data/spec/mongo/auth/scram_spec.rb +107 -38
  266. data/spec/mongo/auth/stringprep/profiles/sasl_spec.rb +113 -0
  267. data/spec/mongo/auth/stringprep_spec.rb +188 -0
  268. data/spec/mongo/auth/user/view_spec.rb +5 -2
  269. data/spec/mongo/auth/user_spec.rb +1 -1
  270. data/spec/mongo/bulk_write/result_spec.rb +120 -0
  271. data/spec/mongo/bulk_write_spec.rb +42 -2
  272. data/spec/mongo/client_spec.rb +121 -9
  273. data/spec/mongo/cluster/app_metadata_spec.rb +14 -1
  274. data/spec/mongo/cluster/topology_spec.rb +1 -23
  275. data/spec/mongo/collection/view/change_stream_spec.rb +62 -180
  276. data/spec/mongo/collection_spec.rb +45 -12
  277. data/spec/mongo/cursor/builder/get_more_command_spec.rb +7 -7
  278. data/spec/mongo/cursor_spec.rb +2 -2
  279. data/spec/mongo/database_spec.rb +3 -3
  280. data/spec/mongo/docs_examples_spec.rb +194 -0
  281. data/spec/mongo/error/operation_failure_spec.rb +152 -0
  282. data/spec/mongo/error/parser_spec.rb +127 -0
  283. data/spec/mongo/grid/fs_bucket_spec.rb +32 -0
  284. data/spec/mongo/grid/stream/write_spec.rb +40 -1
  285. data/spec/mongo/monitoring/event/command_failed_spec.rb +30 -0
  286. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -4
  287. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +29 -7
  288. data/spec/mongo/monitoring_spec.rb +28 -3
  289. data/spec/mongo/protocol/get_more_spec.rb +2 -2
  290. data/spec/mongo/retryable_spec.rb +252 -34
  291. data/spec/mongo/retryable_writes_spec.rb +468 -544
  292. data/spec/mongo/server/connection_spec.rb +5 -5
  293. data/spec/mongo/server/description_spec.rb +23 -6
  294. data/spec/mongo/session/server_session_spec.rb +2 -2
  295. data/spec/mongo/session/session_pool_spec.rb +2 -2
  296. data/spec/mongo/transactions_examples_spec.rb +227 -0
  297. data/spec/mongo/transactions_spec.rb +44 -0
  298. data/spec/spec_helper.rb +135 -49
  299. data/spec/spec_tests/change_streams_spec.rb +42 -0
  300. data/spec/{mongo → spec_tests}/command_monitoring_spec.rb +8 -2
  301. data/spec/{mongo → spec_tests}/connection_string_spec.rb +1 -1
  302. data/spec/{mongo → spec_tests}/crud_spec.rb +5 -7
  303. data/spec/{mongo → spec_tests}/dns_seedlist_discovery_spec.rb +1 -1
  304. data/spec/{mongo → spec_tests}/gridfs_spec.rb +0 -0
  305. data/spec/{mongo → spec_tests}/max_staleness_spec.rb +0 -0
  306. data/spec/spec_tests/retryable_writes_spec.rb +78 -0
  307. data/spec/{mongo → spec_tests}/sdam_monitoring_spec.rb +4 -3
  308. data/spec/{mongo → spec_tests}/sdam_spec.rb +7 -7
  309. data/spec/{mongo → spec_tests}/server_selection_rtt_spec.rb +0 -0
  310. data/spec/{mongo → spec_tests}/server_selection_spec.rb +0 -0
  311. data/spec/support/authorization.rb +18 -6
  312. data/spec/support/change_streams.rb +265 -0
  313. data/spec/support/change_streams/operation.rb +62 -0
  314. data/spec/support/change_streams_tests/change-streams-errors.yml +53 -0
  315. data/spec/support/change_streams_tests/change-streams.yml +299 -0
  316. data/spec/support/command_monitoring.rb +1 -1
  317. data/spec/support/command_monitoring/bulkWrite.yml +4 -28
  318. data/spec/support/command_monitoring/command.yml +19 -0
  319. data/spec/support/command_monitoring/find.yml +17 -19
  320. data/spec/support/command_monitoring/insertMany.yml +2 -8
  321. data/spec/support/command_monitoring/unacknowledgedBulkWrite.yml +34 -0
  322. data/spec/support/connection_string.rb +1 -1
  323. data/spec/support/constraints.rb +56 -0
  324. data/spec/support/crud.rb +9 -4
  325. data/spec/support/crud/read.rb +24 -3
  326. data/spec/support/crud/write.rb +7 -2
  327. data/spec/support/crud_tests/read/count-collation.yml +12 -2
  328. data/spec/support/crud_tests/read/count.yml +43 -5
  329. data/spec/support/gridfs.rb +1 -1
  330. data/spec/support/primary_socket.rb +21 -0
  331. data/spec/support/retryable_writes_tests/bulkWrite-serverErrors.yml +90 -0
  332. data/spec/support/retryable_writes_tests/bulkWrite.yml +99 -1
  333. data/spec/support/retryable_writes_tests/deleteOne-serverErrors.yml +50 -0
  334. data/spec/support/retryable_writes_tests/deleteOne.yml +10 -1
  335. data/spec/support/retryable_writes_tests/findOneAndDelete-serverErrors.yml +50 -0
  336. data/spec/support/retryable_writes_tests/findOneAndDelete.yml +39 -30
  337. data/spec/support/retryable_writes_tests/findOneAndReplace-serverErrors.yml +54 -0
  338. data/spec/support/retryable_writes_tests/findOneAndReplace.yml +9 -0
  339. data/spec/support/retryable_writes_tests/findOneAndUpdate-serverErrors.yml +54 -0
  340. data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +9 -0
  341. data/spec/support/retryable_writes_tests/insertMany-serverErrors.yml +59 -0
  342. data/spec/support/retryable_writes_tests/insertMany.yml +11 -6
  343. data/spec/support/retryable_writes_tests/insertOne-serverErrors.yml +471 -0
  344. data/spec/support/retryable_writes_tests/insertOne.yml +9 -0
  345. data/spec/support/retryable_writes_tests/replaceOne-serverErrors.yml +58 -0
  346. data/spec/support/retryable_writes_tests/replaceOne.yml +9 -0
  347. data/spec/support/retryable_writes_tests/updateOne-serverErrors.yml +58 -0
  348. data/spec/support/retryable_writes_tests/updateOne.yml +71 -53
  349. data/spec/support/sdam/rs/normalize_case_me.yml +100 -0
  350. data/spec/support/sdam/sharded/compatible.yml +38 -0
  351. data/spec/support/sdam/sharded/mongos_disconnect.yml +9 -3
  352. data/spec/support/sdam/sharded/multiple_mongoses.yml +6 -2
  353. data/spec/support/sdam/sharded/non_mongos_removed.yml +6 -2
  354. data/spec/support/sdam/sharded/too_new.yml +36 -0
  355. data/spec/support/sdam/sharded/too_old.yml +36 -0
  356. data/spec/support/sdam/single/compatible.yml +26 -0
  357. data/spec/support/sdam/single/direct_connection_external_ip.yml +3 -1
  358. data/spec/support/sdam/single/direct_connection_mongos.yml +3 -1
  359. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +3 -1
  360. data/spec/support/sdam/single/direct_connection_rsprimary.yml +3 -1
  361. data/spec/support/sdam/single/direct_connection_rssecondary.yml +3 -1
  362. data/spec/support/sdam/single/direct_connection_slave.yml +3 -1
  363. data/spec/support/sdam/single/direct_connection_standalone.yml +3 -1
  364. data/spec/support/sdam/single/not_ok_response.yml +6 -2
  365. data/spec/support/sdam/single/standalone_removed.yml +3 -1
  366. data/spec/support/sdam/single/too_new.yml +26 -0
  367. data/spec/support/sdam/single/too_old.yml +24 -0
  368. data/spec/support/shared/session.rb +107 -0
  369. data/spec/support/transactions.rb +391 -0
  370. data/spec/support/transactions/operation.rb +373 -0
  371. data/spec/support/transactions_tests/abort.yml +403 -0
  372. data/spec/support/transactions_tests/bulk.yml +267 -0
  373. data/spec/support/transactions_tests/causal-consistency.yml +173 -0
  374. data/spec/support/transactions_tests/commit.yml +593 -0
  375. data/spec/support/transactions_tests/delete.yml +184 -0
  376. data/spec/support/transactions_tests/error-labels.yml +948 -0
  377. data/spec/support/transactions_tests/errors.yml +125 -0
  378. data/spec/support/transactions_tests/findOneAndDelete.yml +126 -0
  379. data/spec/support/transactions_tests/findOneAndReplace.yml +140 -0
  380. data/spec/support/transactions_tests/findOneAndUpdate.yml +228 -0
  381. data/spec/support/transactions_tests/insert.yml +264 -0
  382. data/spec/support/transactions_tests/isolation.yml +125 -0
  383. data/spec/support/transactions_tests/read-pref.yml +340 -0
  384. data/spec/support/transactions_tests/reads.yml +298 -0
  385. data/spec/support/transactions_tests/retryable-abort.yml +1292 -0
  386. data/spec/support/transactions_tests/retryable-commit.yml +1332 -0
  387. data/spec/support/transactions_tests/retryable-writes.yml +208 -0
  388. data/spec/support/transactions_tests/run-command.yml +189 -0
  389. data/spec/support/transactions_tests/transaction-options.yml +877 -0
  390. data/spec/support/transactions_tests/update.yml +246 -0
  391. data/spec/support/transactions_tests/write-concern.yml +236 -0
  392. metadata +494 -359
  393. metadata.gz.sig +0 -0
  394. data/lib/csasl/csasl.bundle +0 -0
@@ -1,813 +1,737 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Retryable Writes' do
3
+ describe 'Retryable writes integration tests' do
4
+ include PrimarySocket
4
5
 
5
- RETRYABLE_WRITES_TESTS.each do |file|
6
+ after do
7
+ authorized_collection.delete_many
8
+ end
6
9
 
7
- spec = Mongo::CRUD::Spec.new(file)
10
+ shared_examples_for 'an operation that is retried' do
8
11
 
9
- context(spec.description) do
12
+ context 'when the operation fails on the first attempt' do
10
13
 
11
- spec.tests.each do |test|
14
+ before do
15
+ # Note that for writes, server.connectable? is called, refreshing the socket
16
+ allow(primary_server).to receive(:connectable?).and_return(true)
17
+ expect(primary_socket).to receive(:write).and_raise(error)
18
+ end
12
19
 
13
- context(test.description) do
20
+ context 'when the error is retryable' do
14
21
 
15
- let(:collection) do
16
- client[TEST_COLL]
17
- end
22
+ before do
23
+ expect(Mongo::Logger.logger).to receive(:warn).once.and_call_original
24
+ expect(client.cluster).to receive(:scan!)
25
+ end
26
+
27
+ context 'when the error is a SocketError' do
18
28
 
19
- let(:client) do
20
- authorized_client_with_retry_writes
29
+ let(:error) do
30
+ Mongo::Error::SocketError
21
31
  end
22
32
 
23
- before do
24
- test.setup_test(collection)
33
+ it 'retries writes' do
34
+ operation
35
+ expect(expectation).to eq(successful_retry_value)
25
36
  end
37
+ end
26
38
 
27
- after do
28
- test.clear_fail_point(collection)
29
- collection.delete_many
39
+ context 'when the error is a SocketTimeoutError' do
40
+
41
+ let(:error) do
42
+ Mongo::Error::SocketTimeoutError
30
43
  end
31
44
 
32
- let(:results) do
33
- if test.error?
34
- error = nil
35
- begin; test.run(collection); rescue => e; error = e; end
36
- error
37
- else
38
- test.run(collection)
39
- end
45
+ it 'retries writes' do
46
+ operation
47
+ expect(expectation).to eq(successful_retry_value)
40
48
  end
49
+ end
41
50
 
42
- it 'has the correct data in the collection', if: (sessions_enabled? && replica_set? && test.outcome_collection_data) do
43
- skip 'Test cannot be run on this server version' unless spec.server_version_satisfied?(client)
44
- results
45
- expect(collection.find.to_a).to match_collection_data(test)
51
+ context 'when the error is a retryable OperationFailure' do
52
+
53
+ let(:error) do
54
+ Mongo::Error::OperationFailure.new('not master')
46
55
  end
47
56
 
48
- if test.error?
49
- it 'raises an error', if: sessions_enabled? && replica_set? do
50
- skip 'Test cannot be run on this server version' unless spec.server_version_satisfied?(client)
51
- expect(results).to be_a(Mongo::Error)
52
- end
53
- else
54
- it 'returns the correct result', if: sessions_enabled? && replica_set? do
55
- skip 'Test cannot be run on this server version' unless spec.server_version_satisfied?(client)
56
- expect(results).to match_operation_result(test)
57
- end
57
+ it 'retries writes' do
58
+ operation
59
+ expect(expectation).to eq(successful_retry_value)
58
60
  end
59
61
  end
60
62
  end
61
- end
62
- end
63
63
 
64
- describe 'Retryable writes integration tests' do
64
+ context 'when the error is not retryable' do
65
65
 
66
- let(:primary) do
67
- primary = client.cluster.next_primary
68
- end
66
+ context 'when the error is a non-retryable OperationFailure' do
69
67
 
70
- let(:primary_connection) do
71
- connection = primary.pool.checkout
72
- connection.connect!
73
- primary.pool.checkin(connection)
74
- connection
75
- end
68
+ let(:error) do
69
+ Mongo::Error::OperationFailure.new('other error')
70
+ end
76
71
 
77
- let(:primary_socket) do
78
- primary_connection.send(:socket)
72
+ it 'does not retry writes' do
73
+ expect {
74
+ operation
75
+ }.to raise_error(error)
76
+ expect(expectation).to eq(unsuccessful_retry_value)
77
+ end
78
+ end
79
+ end
79
80
  end
80
81
 
81
- after do
82
- authorized_collection.delete_many
83
- end
82
+ context 'when the operation fails on the first attempt and again on the second attempt' do
84
83
 
85
- shared_examples_for 'an operation that is retried' do
84
+ before do
85
+ # Note that for writes, server.connectable? is called, refreshing the socket
86
+ allow(primary_server).to receive(:connectable?).and_return(true)
87
+ allow(primary_socket).to receive(:write).and_raise(error)
88
+ end
86
89
 
87
- context 'when the operation fails on the first attempt' do
90
+ context 'when the selected server does not support retryable writes' do
88
91
 
89
92
  before do
90
- # Note that for writes, server.connectable? is called, refreshing the socket
91
- allow(primary).to receive(:connectable?).and_return(true)
93
+ legacy_primary = double('legacy primary', :'retry_writes?' => false)
94
+ allow(client.cluster).to receive(:next_primary).and_return(primary_server, legacy_primary)
92
95
  expect(primary_socket).to receive(:write).and_raise(error)
93
96
  end
94
97
 
95
- context 'when the error is retryable' do
98
+ context 'when the error is a SocketError' do
96
99
 
97
- before do
98
- expect(Mongo::Logger.logger).to receive(:warn).once.and_call_original
99
- expect(client.cluster).to receive(:scan!)
100
+ let(:error) do
101
+ Mongo::Error::SocketError
100
102
  end
101
103
 
102
- context 'when the error is a SocketError' do
103
-
104
- let(:error) do
105
- Mongo::Error::SocketError
106
- end
107
-
108
- it 'retries writes' do
104
+ it 'does not retry writes and raises the original error' do
105
+ expect {
109
106
  operation
110
- expect(expectation).to eq(successful_retry_value)
111
- end
107
+ }.to raise_error(error)
108
+ expect(expectation).to eq(unsuccessful_retry_value)
112
109
  end
110
+ end
113
111
 
114
- context 'when the error is a SocketTimeoutError' do
115
-
116
- let(:error) do
117
- Mongo::Error::SocketTimeoutError
118
- end
112
+ context 'when the error is a SocketTimeoutError' do
119
113
 
120
- it 'retries writes' do
121
- operation
122
- expect(expectation).to eq(successful_retry_value)
123
- end
114
+ let(:error) do
115
+ Mongo::Error::SocketTimeoutError
124
116
  end
125
117
 
126
- context 'when the error is a retryable OperationFailure' do
127
-
128
- let(:error) do
129
- Mongo::Error::OperationFailure.new('not master')
130
- end
131
-
132
- it 'retries writes' do
118
+ it 'does not retry writes and raises the original error' do
119
+ expect {
133
120
  operation
134
- expect(expectation).to eq(successful_retry_value)
135
- end
121
+ }.to raise_error(error)
122
+ expect(expectation).to eq(unsuccessful_retry_value)
136
123
  end
137
124
  end
138
125
 
139
- context 'when the error is not retryable' do
140
-
141
- context 'when the error is a non-retryable OperationFailure' do
126
+ context 'when the error is a retryable OperationFailure' do
142
127
 
143
- let(:error) do
144
- Mongo::Error::OperationFailure.new('other error')
145
- end
128
+ let(:error) do
129
+ Mongo::Error::OperationFailure.new('not master')
130
+ end
146
131
 
147
- it 'does not retry writes' do
148
- expect {
149
- operation
150
- }.to raise_error(error)
151
- expect(expectation).to eq(unsuccessful_retry_value)
152
- end
132
+ it 'does not retry writes and raises the original error' do
133
+ expect {
134
+ operation
135
+ }.to raise_error(error)
136
+ expect(expectation).to eq(unsuccessful_retry_value)
153
137
  end
154
138
  end
155
139
  end
156
140
 
157
- context 'when the operation fails on the first attempt and again on the second attempt' do
141
+ [Mongo::Error::SocketError,
142
+ Mongo::Error::SocketTimeoutError,
143
+ Mongo::Error::OperationFailure.new('not master')].each do |retryable_error|
158
144
 
159
- before do
160
- # Note that for writes, server.connectable? is called, refreshing the socket
161
- allow(primary).to receive(:connectable?).and_return(true)
162
- allow(primary_socket).to receive(:write).and_raise(error)
163
- end
145
+ context "when the first error is a #{retryable_error}" do
164
146
 
165
- context 'when the selected server does not support retryable writes' do
147
+ let(:error) do
148
+ retryable_error
149
+ end
166
150
 
167
151
  before do
168
- legacy_primary = double('legacy primary', :'retry_writes?' => false)
169
- allow(client.cluster).to receive(:next_primary).and_return(primary, legacy_primary)
170
- expect(primary_socket).to receive(:write).and_raise(error)
152
+ bad_socket = primary_connection.address.socket(primary_connection.socket_timeout,
153
+ primary_connection.send(:ssl_options))
154
+ good_socket = primary_connection.address.socket(primary_connection.socket_timeout,
155
+ primary_connection.send(:ssl_options))
156
+ allow(bad_socket).to receive(:write).and_raise(second_error)
157
+ allow(primary_connection.address).to receive(:socket).and_return(bad_socket, good_socket)
171
158
  end
172
159
 
173
- context 'when the error is a SocketError' do
160
+ context 'when the second error is a SocketError' do
174
161
 
175
- let(:error) do
162
+ let(:second_error) do
176
163
  Mongo::Error::SocketError
177
164
  end
178
165
 
179
- it 'does not retry writes and raises the original error' do
166
+ before do
167
+ expect(client.cluster).to receive(:scan!).twice
168
+ end
169
+
170
+ it 'does not retry writes and raises the second error' do
180
171
  expect {
181
172
  operation
182
- }.to raise_error(error)
173
+ }.to raise_error(second_error)
183
174
  expect(expectation).to eq(unsuccessful_retry_value)
184
175
  end
185
176
  end
186
177
 
187
- context 'when the error is a SocketTimeoutError' do
178
+ context 'when the second error is a SocketTimeoutError' do
188
179
 
189
- let(:error) do
180
+ before do
181
+ expect(client.cluster).to receive(:scan!).twice
182
+ end
183
+
184
+ let(:second_error) do
190
185
  Mongo::Error::SocketTimeoutError
191
186
  end
192
187
 
193
- it 'does not retry writes and raises the original error' do
188
+ it 'does not retry writes and raises the second error' do
194
189
  expect {
195
190
  operation
196
- }.to raise_error(error)
191
+ }.to raise_error(second_error)
197
192
  expect(expectation).to eq(unsuccessful_retry_value)
198
193
  end
199
194
  end
200
195
 
201
- context 'when the error is a retryable OperationFailure' do
196
+ context 'when the second error is a retryable OperationFailure' do
202
197
 
203
- let(:error) do
198
+ before do
199
+ expect(client.cluster).to receive(:scan!).twice
200
+ end
201
+
202
+ let(:second_error) do
204
203
  Mongo::Error::OperationFailure.new('not master')
205
204
  end
206
205
 
207
- it 'does not retry writes and raises the original error' do
206
+ it 'does not retry writes and raises the second error' do
208
207
  expect {
209
208
  operation
210
- }.to raise_error(error)
209
+ }.to raise_error(second_error)
211
210
  expect(expectation).to eq(unsuccessful_retry_value)
212
211
  end
213
212
  end
214
- end
215
-
216
- [Mongo::Error::SocketError,
217
- Mongo::Error::SocketTimeoutError,
218
- Mongo::Error::OperationFailure.new('not master')].each do |retryable_error|
219
213
 
220
- context "when the first error is a #{retryable_error}" do
221
-
222
- let(:error) do
223
- retryable_error
224
- end
214
+ context 'when the second error is a non-retryable OperationFailure' do
225
215
 
226
216
  before do
227
- bad_socket = primary_connection.address.socket(primary_connection.socket_timeout,
228
- primary_connection.send(:ssl_options))
229
- good_socket = primary_connection.address.socket(primary_connection.socket_timeout,
230
- primary_connection.send(:ssl_options))
231
- allow(bad_socket).to receive(:write).and_raise(second_error)
232
- allow(primary_connection.address).to receive(:socket).and_return(bad_socket, good_socket)
217
+ expect(client.cluster).to receive(:scan!).once
233
218
  end
234
219
 
235
- context 'when the second error is a SocketError' do
236
-
237
- let(:second_error) do
238
- Mongo::Error::SocketError
239
- end
240
-
241
- before do
242
- expect(client.cluster).to receive(:scan!).twice
243
- end
244
-
245
- it 'does not retry writes and raises the second error' do
246
- expect {
247
- operation
248
- }.to raise_error(second_error)
249
- expect(expectation).to eq(unsuccessful_retry_value)
250
- end
251
- end
252
-
253
- context 'when the second error is a SocketTimeoutError' do
254
-
255
- before do
256
- expect(client.cluster).to receive(:scan!).twice
257
- end
258
-
259
- let(:second_error) do
260
- Mongo::Error::SocketTimeoutError
261
- end
262
-
263
- it 'does not retry writes and raises the second error' do
264
- expect {
265
- operation
266
- }.to raise_error(second_error)
267
- expect(expectation).to eq(unsuccessful_retry_value)
268
- end
220
+ let(:second_error) do
221
+ Mongo::Error::OperationFailure.new('other error')
269
222
  end
270
223
 
271
- context 'when the second error is a retryable OperationFailure' do
272
-
273
- before do
274
- expect(client.cluster).to receive(:scan!).twice
275
- end
276
-
277
- let(:second_error) do
278
- Mongo::Error::OperationFailure.new('not master')
279
- end
280
-
281
- it 'does not retry writes and raises the second error' do
282
- expect {
283
- operation
284
- }.to raise_error(second_error)
285
- expect(expectation).to eq(unsuccessful_retry_value)
286
- end
224
+ it 'does not retry writes and raises the first error' do
225
+ expect {
226
+ operation
227
+ }.to raise_error(error)
228
+ expect(expectation).to eq(unsuccessful_retry_value)
287
229
  end
230
+ end
288
231
 
289
- context 'when the second error is a non-retryable OperationFailure' do
290
-
291
- before do
292
- expect(client.cluster).to receive(:scan!).once
293
- end
294
-
295
- let(:second_error) do
296
- Mongo::Error::OperationFailure.new('other error')
297
- end
232
+ context 'when the second error is a another error' do
298
233
 
299
- it 'does not retry writes and raises the first error' do
300
- expect {
301
- operation
302
- }.to raise_error(error)
303
- expect(expectation).to eq(unsuccessful_retry_value)
304
- end
234
+ let(:second_error) do
235
+ StandardError
305
236
  end
306
237
 
307
- context 'when the second error is a another error' do
308
-
309
- let(:second_error) do
310
- StandardError
311
- end
312
-
313
- it 'does not retry writes and raises the first error' do
314
- expect {
315
- operation
316
- }.to raise_error(error)
317
- expect(expectation).to eq(unsuccessful_retry_value)
318
- end
238
+ it 'does not retry writes and raises the first error' do
239
+ expect {
240
+ operation
241
+ }.to raise_error(error)
242
+ expect(expectation).to eq(unsuccessful_retry_value)
319
243
  end
320
244
  end
321
245
  end
322
246
  end
323
247
  end
248
+ end
324
249
 
325
- shared_examples_for 'an operation that is not retried' do
326
-
327
- before do
328
- # Note that for writes, server.connectable? is called, refreshing the socket
329
- allow(primary).to receive(:connectable?).and_return(true)
330
- expect(primary_socket).to receive(:write).and_raise(Mongo::Error::SocketError)
331
- expect(client.cluster).not_to receive(:scan!)
332
- end
250
+ shared_examples_for 'an operation that is not retried' do
333
251
 
334
- it 'does not retry writes' do
335
- expect {
336
- operation
337
- }.to raise_error(Mongo::Error::SocketError)
338
- expect(expectation).to eq(unsuccessful_retry_value)
339
- end
252
+ before do
253
+ # Note that for writes, server.connectable? is called, refreshing the socket
254
+ allow(primary_server).to receive(:connectable?).and_return(true)
255
+ expect(primary_socket).to receive(:write).and_raise(Mongo::Error::SocketError)
256
+ expect(client.cluster).not_to receive(:scan!)
340
257
  end
341
258
 
342
- shared_examples_for 'an operation that does not support retryable writes' do
259
+ it 'does not retry writes' do
260
+ expect {
261
+ operation
262
+ }.to raise_error(Mongo::Error::SocketError)
263
+ expect(expectation).to eq(unsuccessful_retry_value)
264
+ end
265
+ end
343
266
 
344
- let!(:client) do
345
- authorized_client_with_retry_writes
346
- end
267
+ shared_examples_for 'an operation that does not support retryable writes' do
347
268
 
348
- let!(:collection) do
349
- client[TEST_COLL, write: WRITE_CONCERN]
350
- end
269
+ let!(:client) do
270
+ authorized_client_with_retry_writes
271
+ end
351
272
 
352
- before do
353
- # Note that for writes, server.connectable? is called, refreshing the socket
354
- allow(primary).to receive(:connectable?).and_return(true)
355
- expect(primary_socket).to receive(:write).and_raise(Mongo::Error::SocketError)
356
- expect(client.cluster).not_to receive(:scan!)
357
- end
273
+ let!(:collection) do
274
+ client[TEST_COLL, write: WRITE_CONCERN]
275
+ end
358
276
 
359
- it 'does not retry writes' do
360
- expect {
361
- operation
362
- }.to raise_error(Mongo::Error::SocketError)
363
- expect(expectation).to eq(unsuccessful_retry_value)
364
- end
277
+ before do
278
+ # Note that for writes, server.connectable? is called, refreshing the socket
279
+ allow(primary_server).to receive(:connectable?).and_return(true)
280
+ expect(primary_socket).to receive(:write).and_raise(Mongo::Error::SocketError)
281
+ expect(client.cluster).not_to receive(:scan!)
365
282
  end
366
283
 
367
- shared_examples_for 'supported retryable writes' do
284
+ it 'does not retry writes' do
285
+ expect {
286
+ operation
287
+ }.to raise_error(Mongo::Error::SocketError)
288
+ expect(expectation).to eq(unsuccessful_retry_value)
289
+ end
290
+ end
368
291
 
369
- context 'when the client has retry_writes set to true' do
292
+ shared_examples_for 'supported retryable writes' do
370
293
 
371
- let!(:client) do
372
- authorized_client_with_retry_writes
373
- end
294
+ context 'when the client has retry_writes set to true' do
374
295
 
375
- context 'when the collection has write concern acknowledged' do
296
+ let!(:client) do
297
+ authorized_client_with_retry_writes
298
+ end
376
299
 
377
- let!(:collection) do
378
- client[TEST_COLL, write: WRITE_CONCERN]
379
- end
300
+ context 'when the collection has write concern acknowledged' do
380
301
 
381
- context 'when the server supports retryable writes' do
302
+ let!(:collection) do
303
+ client[TEST_COLL, write: WRITE_CONCERN]
304
+ end
382
305
 
383
- before do
384
- allow(primary).to receive(:retry_writes?).and_return(true)
385
- end
306
+ context 'when the server supports retryable writes' do
386
307
 
387
- if standalone? && sessions_enabled?
388
- it_behaves_like 'an operation that is not retried'
389
- elsif sessions_enabled?
390
- it_behaves_like 'an operation that is retried'
391
- end
308
+ before do
309
+ allow(primary_server).to receive(:retry_writes?).and_return(true)
392
310
  end
393
311
 
394
- context 'when the server does not support retryable writes' do
395
-
396
- before do
397
- allow(primary).to receive(:retry_writes?).and_return(false)
398
- end
399
-
312
+ if standalone? && sessions_enabled?
400
313
  it_behaves_like 'an operation that is not retried'
314
+ elsif sessions_enabled?
315
+ it_behaves_like 'an operation that is retried'
401
316
  end
402
317
  end
403
318
 
404
- context 'when the collection has write concern unacknowledged' do
319
+ context 'when the server does not support retryable writes' do
405
320
 
406
- let!(:collection) do
407
- client[TEST_COLL, write: { w: 0 }]
321
+ before do
322
+ allow(primary_server).to receive(:retry_writes?).and_return(false)
408
323
  end
409
324
 
410
325
  it_behaves_like 'an operation that is not retried'
411
326
  end
327
+ end
412
328
 
413
- context 'when the collection has write concern not set' do
329
+ context 'when the collection has write concern unacknowledged' do
414
330
 
415
- let!(:collection) do
416
- client[TEST_COLL]
417
- end
331
+ let!(:collection) do
332
+ client[TEST_COLL, write: { w: 0 }]
333
+ end
418
334
 
419
- context 'when the server supports retryable writes' do
335
+ it_behaves_like 'an operation that is not retried'
336
+ end
420
337
 
421
- before do
422
- allow(primary).to receive(:retry_writes?).and_return(true)
423
- end
338
+ context 'when the collection has write concern not set' do
424
339
 
425
- if standalone? && sessions_enabled?
426
- it_behaves_like 'an operation that is not retried'
427
- elsif sessions_enabled?
428
- it_behaves_like 'an operation that is retried'
429
- end
430
- end
340
+ let!(:collection) do
341
+ client[TEST_COLL]
342
+ end
431
343
 
432
- context 'when the server does not support retryable writes' do
344
+ context 'when the server supports retryable writes' do
433
345
 
434
- before do
435
- allow(primary).to receive(:retry_writes?).and_return(false)
436
- end
346
+ before do
347
+ allow(primary_server).to receive(:retry_writes?).and_return(true)
348
+ end
437
349
 
350
+ if standalone? && sessions_enabled?
438
351
  it_behaves_like 'an operation that is not retried'
352
+ elsif sessions_enabled?
353
+ it_behaves_like 'an operation that is retried'
439
354
  end
440
355
  end
441
- end
442
-
443
- context 'when the client has retry_writes set to false' do
444
-
445
- let!(:client) do
446
- authorized_client.with(retry_writes: false)
447
- end
448
-
449
- after do
450
- client.close
451
- end
452
356
 
453
- context 'when the collection has write concern acknowledged' do
357
+ context 'when the server does not support retryable writes' do
454
358
 
455
- let!(:collection) do
456
- client[TEST_COLL, write: WRITE_CONCERN]
359
+ before do
360
+ allow(primary_server).to receive(:retry_writes?).and_return(false)
457
361
  end
458
362
 
459
363
  it_behaves_like 'an operation that is not retried'
460
364
  end
365
+ end
366
+ end
461
367
 
462
- context 'when the collection has write concern unacknowledged' do
368
+ context 'when the client has retry_writes set to false' do
463
369
 
464
- let!(:collection) do
465
- client[TEST_COLL, write: { w: 0 }]
466
- end
370
+ let!(:client) do
371
+ authorized_client.with(retry_writes: false)
372
+ end
467
373
 
468
- it_behaves_like 'an operation that is not retried'
374
+ after do
375
+ client.close
376
+ end
377
+
378
+ context 'when the collection has write concern acknowledged' do
379
+
380
+ let!(:collection) do
381
+ client[TEST_COLL, write: WRITE_CONCERN]
469
382
  end
470
383
 
471
- context 'when the collection has write concern not set' do
384
+ it_behaves_like 'an operation that is not retried'
385
+ end
472
386
 
473
- let!(:collection) do
474
- client[TEST_COLL]
475
- end
387
+ context 'when the collection has write concern unacknowledged' do
476
388
 
477
- it_behaves_like 'an operation that is not retried'
389
+ let!(:collection) do
390
+ client[TEST_COLL, write: { w: 0 }]
478
391
  end
392
+
393
+ it_behaves_like 'an operation that is not retried'
479
394
  end
480
395
 
481
- context 'when the client has retry_writes not set' do
396
+ context 'when the collection has write concern not set' do
482
397
 
483
- let!(:client) do
484
- authorized_client
398
+ let!(:collection) do
399
+ client[TEST_COLL]
485
400
  end
486
401
 
487
- context 'when the collection has write concern acknowledged' do
402
+ it_behaves_like 'an operation that is not retried'
403
+ end
404
+ end
488
405
 
489
- let!(:collection) do
490
- client[TEST_COLL, write: WRITE_CONCERN]
491
- end
406
+ context 'when the client has retry_writes not set' do
492
407
 
493
- it_behaves_like 'an operation that is not retried'
408
+ let!(:client) do
409
+ authorized_client
410
+ end
411
+
412
+ context 'when the collection has write concern acknowledged' do
413
+
414
+ let!(:collection) do
415
+ client[TEST_COLL, write: WRITE_CONCERN]
494
416
  end
495
417
 
496
- context 'when the collection has write concern unacknowledged' do
418
+ it_behaves_like 'an operation that is not retried'
419
+ end
497
420
 
498
- let!(:collection) do
499
- client[TEST_COLL, write: { w: 0 }]
500
- end
421
+ context 'when the collection has write concern unacknowledged' do
501
422
 
502
- it_behaves_like 'an operation that is not retried'
423
+ let!(:collection) do
424
+ client[TEST_COLL, write: { w: 0 }]
503
425
  end
504
426
 
505
- context 'when the collection has write concern not set' do
427
+ it_behaves_like 'an operation that is not retried'
428
+ end
506
429
 
507
- let!(:collection) do
508
- client[TEST_COLL]
509
- end
430
+ context 'when the collection has write concern not set' do
510
431
 
511
- it_behaves_like 'an operation that is not retried'
432
+ let!(:collection) do
433
+ client[TEST_COLL]
512
434
  end
435
+
436
+ it_behaves_like 'an operation that is not retried'
513
437
  end
514
438
  end
439
+ end
515
440
 
516
- context 'when the operation is insert_one' do
517
-
518
- let(:operation) do
519
- collection.insert_one(a:1)
520
- end
441
+ context 'when the operation is insert_one' do
521
442
 
522
- let(:expectation) do
523
- collection.find(a: 1).count
524
- end
443
+ let(:operation) do
444
+ collection.insert_one(a:1)
445
+ end
525
446
 
526
- let(:successful_retry_value) do
527
- 1
528
- end
447
+ let(:expectation) do
448
+ collection.find(a: 1).count
449
+ end
529
450
 
530
- let(:unsuccessful_retry_value) do
531
- 0
532
- end
451
+ let(:successful_retry_value) do
452
+ 1
453
+ end
533
454
 
534
- it_behaves_like 'supported retryable writes'
455
+ let(:unsuccessful_retry_value) do
456
+ 0
535
457
  end
536
458
 
537
- context 'when the operation is update_one' do
459
+ it_behaves_like 'supported retryable writes'
460
+ end
538
461
 
539
- before do
540
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
541
- authorized_collection.insert_one(a:0)
542
- end
462
+ context 'when the operation is update_one' do
543
463
 
544
- let(:operation) do
545
- collection.update_one({ a: 0 }, { '$set' => { a: 1 } })
546
- end
464
+ before do
465
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
466
+ authorized_collection.insert_one(a:0)
467
+ end
547
468
 
548
- let(:expectation) do
549
- collection.find(a: 1).count
550
- end
469
+ let(:operation) do
470
+ collection.update_one({ a: 0 }, { '$set' => { a: 1 } })
471
+ end
551
472
 
552
- let(:successful_retry_value) do
553
- 1
554
- end
473
+ let(:expectation) do
474
+ collection.find(a: 1).count
475
+ end
555
476
 
556
- let(:unsuccessful_retry_value) do
557
- 0
558
- end
477
+ let(:successful_retry_value) do
478
+ 1
479
+ end
559
480
 
560
- it_behaves_like 'supported retryable writes'
481
+ let(:unsuccessful_retry_value) do
482
+ 0
561
483
  end
562
484
 
563
- context 'when the operation is replace_one' do
485
+ it_behaves_like 'supported retryable writes'
486
+ end
564
487
 
565
- before do
566
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
567
- authorized_collection.insert_one(a:0)
568
- end
488
+ context 'when the operation is replace_one' do
569
489
 
570
- let(:operation) do
571
- collection.replace_one({ a: 0 }, { a: 1 })
572
- end
490
+ before do
491
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
492
+ authorized_collection.insert_one(a:0)
493
+ end
573
494
 
574
- let(:expectation) do
575
- collection.find(a: 1).count
576
- end
495
+ let(:operation) do
496
+ collection.replace_one({ a: 0 }, { a: 1 })
497
+ end
577
498
 
578
- let(:successful_retry_value) do
579
- 1
580
- end
499
+ let(:expectation) do
500
+ collection.find(a: 1).count
501
+ end
581
502
 
582
- let(:unsuccessful_retry_value) do
583
- 0
584
- end
503
+ let(:successful_retry_value) do
504
+ 1
505
+ end
585
506
 
586
- it_behaves_like 'supported retryable writes'
507
+ let(:unsuccessful_retry_value) do
508
+ 0
587
509
  end
588
510
 
589
- context 'when the operation is delete_one' do
511
+ it_behaves_like 'supported retryable writes'
512
+ end
590
513
 
591
- before do
592
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
593
- authorized_collection.insert_one(a:1)
594
- end
514
+ context 'when the operation is delete_one' do
595
515
 
596
- let(:operation) do
597
- collection.delete_one(a:1)
598
- end
516
+ before do
517
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
518
+ authorized_collection.insert_one(a:1)
519
+ end
599
520
 
600
- let(:expectation) do
601
- collection.find(a: 1).count
602
- end
521
+ let(:operation) do
522
+ collection.delete_one(a:1)
523
+ end
603
524
 
604
- let(:successful_retry_value) do
605
- 0
606
- end
525
+ let(:expectation) do
526
+ collection.find(a: 1).count
527
+ end
607
528
 
608
- let(:unsuccessful_retry_value) do
609
- 1
610
- end
529
+ let(:successful_retry_value) do
530
+ 0
531
+ end
611
532
 
612
- it_behaves_like 'supported retryable writes'
533
+ let(:unsuccessful_retry_value) do
534
+ 1
613
535
  end
614
536
 
615
- context 'when the operation is find_one_and_update' do
537
+ it_behaves_like 'supported retryable writes'
538
+ end
616
539
 
617
- before do
618
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
619
- authorized_collection.insert_one(a:0)
620
- end
540
+ context 'when the operation is find_one_and_update' do
621
541
 
622
- let(:operation) do
623
- collection.find_one_and_update({ a: 0 }, { '$set' => { a: 1 } })
624
- end
542
+ before do
543
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
544
+ authorized_collection.insert_one(a:0)
545
+ end
625
546
 
626
- let(:expectation) do
627
- collection.find(a: 1).count
628
- end
547
+ let(:operation) do
548
+ collection.find_one_and_update({ a: 0 }, { '$set' => { a: 1 } })
549
+ end
629
550
 
630
- let(:successful_retry_value) do
631
- 1
632
- end
551
+ let(:expectation) do
552
+ collection.find(a: 1).count
553
+ end
633
554
 
634
- let(:unsuccessful_retry_value) do
635
- 0
636
- end
555
+ let(:successful_retry_value) do
556
+ 1
557
+ end
637
558
 
638
- it_behaves_like 'supported retryable writes'
559
+ let(:unsuccessful_retry_value) do
560
+ 0
639
561
  end
640
562
 
641
- context 'when the operation is find_one_and_replace' do
563
+ it_behaves_like 'supported retryable writes'
564
+ end
642
565
 
643
- before do
644
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
645
- authorized_collection.insert_one(a:0)
646
- end
566
+ context 'when the operation is find_one_and_replace' do
647
567
 
648
- let(:operation) do
649
- collection.find_one_and_replace({ a: 0 }, { a: 3 })
650
- end
568
+ before do
569
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
570
+ authorized_collection.insert_one(a:0)
571
+ end
651
572
 
652
- let(:expectation) do
653
- collection.find(a: 3).count
654
- end
573
+ let(:operation) do
574
+ collection.find_one_and_replace({ a: 0 }, { a: 3 })
575
+ end
655
576
 
656
- let(:successful_retry_value) do
657
- 1
658
- end
577
+ let(:expectation) do
578
+ collection.find(a: 3).count
579
+ end
659
580
 
660
- let(:unsuccessful_retry_value) do
661
- 0
662
- end
581
+ let(:successful_retry_value) do
582
+ 1
583
+ end
663
584
 
664
- it_behaves_like 'supported retryable writes'
585
+ let(:unsuccessful_retry_value) do
586
+ 0
665
587
  end
666
588
 
667
- context 'when the operation is find_one_and_delete' do
589
+ it_behaves_like 'supported retryable writes'
590
+ end
668
591
 
669
- before do
670
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
671
- authorized_collection.insert_one(a:1)
672
- end
592
+ context 'when the operation is find_one_and_delete' do
673
593
 
674
- let(:operation) do
675
- collection.find_one_and_delete({ a: 1 })
676
- end
594
+ before do
595
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
596
+ authorized_collection.insert_one(a:1)
597
+ end
677
598
 
678
- let(:expectation) do
679
- collection.find(a: 1).count
680
- end
599
+ let(:operation) do
600
+ collection.find_one_and_delete({ a: 1 })
601
+ end
681
602
 
682
- let(:successful_retry_value) do
683
- 0
684
- end
603
+ let(:expectation) do
604
+ collection.find(a: 1).count
605
+ end
685
606
 
686
- let(:unsuccessful_retry_value) do
687
- 1
688
- end
607
+ let(:successful_retry_value) do
608
+ 0
609
+ end
689
610
 
690
- it_behaves_like 'supported retryable writes'
611
+ let(:unsuccessful_retry_value) do
612
+ 1
691
613
  end
692
614
 
693
- context 'when the operation is update_many' do
615
+ it_behaves_like 'supported retryable writes'
616
+ end
694
617
 
695
- before do
696
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
697
- authorized_collection.insert_one(a:0)
698
- authorized_collection.insert_one(a:0)
699
- end
618
+ context 'when the operation is update_many' do
700
619
 
701
- let(:operation) do
702
- collection.update_many({ a: 0 }, { '$set' => { a: 1 } })
703
- end
620
+ before do
621
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
622
+ authorized_collection.insert_one(a:0)
623
+ authorized_collection.insert_one(a:0)
624
+ end
704
625
 
705
- let(:expectation) do
706
- collection.find(a: 1).count
707
- end
626
+ let(:operation) do
627
+ collection.update_many({ a: 0 }, { '$set' => { a: 1 } })
628
+ end
708
629
 
709
- let(:unsuccessful_retry_value) do
710
- 0
711
- end
630
+ let(:expectation) do
631
+ collection.find(a: 1).count
632
+ end
712
633
 
713
- it_behaves_like 'an operation that does not support retryable writes'
634
+ let(:unsuccessful_retry_value) do
635
+ 0
714
636
  end
715
637
 
716
- context 'when the operation is delete_many' do
638
+ it_behaves_like 'an operation that does not support retryable writes'
639
+ end
717
640
 
718
- before do
719
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
720
- authorized_collection.insert_one(a:1)
721
- authorized_collection.insert_one(a:1)
722
- end
641
+ context 'when the operation is delete_many' do
723
642
 
724
- let(:operation) do
725
- collection.delete_many(a: 1)
726
- end
643
+ before do
644
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
645
+ authorized_collection.insert_one(a:1)
646
+ authorized_collection.insert_one(a:1)
647
+ end
727
648
 
728
- let(:expectation) do
729
- collection.find(a: 1).count
730
- end
649
+ let(:operation) do
650
+ collection.delete_many(a: 1)
651
+ end
731
652
 
732
- let(:unsuccessful_retry_value) do
733
- 2
734
- end
653
+ let(:expectation) do
654
+ collection.find(a: 1).count
655
+ end
735
656
 
736
- it_behaves_like 'an operation that does not support retryable writes'
657
+ let(:unsuccessful_retry_value) do
658
+ 2
737
659
  end
738
660
 
739
- context 'when the operation is a bulk write' do
661
+ it_behaves_like 'an operation that does not support retryable writes'
662
+ end
740
663
 
741
- before do
742
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
743
- authorized_collection.insert_one(a: 1)
744
- end
664
+ context 'when the operation is a bulk write' do
745
665
 
746
- let(:operation) do
747
- collection.bulk_write([{ delete_one: { filter: { a: 1 } } },
748
- { insert_one: { a: 1 } },
749
- { insert_one: { a: 1 } }])
750
- end
666
+ before do
667
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
668
+ authorized_collection.insert_one(a: 1)
669
+ end
751
670
 
752
- let(:expectation) do
753
- collection.find(a: 1).count
754
- end
671
+ let(:operation) do
672
+ collection.bulk_write([{ delete_one: { filter: { a: 1 } } },
673
+ { insert_one: { a: 1 } },
674
+ { insert_one: { a: 1 } }])
675
+ end
755
676
 
756
- let(:successful_retry_value) do
757
- 2
758
- end
677
+ let(:expectation) do
678
+ collection.find(a: 1).count
679
+ end
759
680
 
760
- let(:unsuccessful_retry_value) do
761
- 1
762
- end
681
+ let(:successful_retry_value) do
682
+ 2
683
+ end
763
684
 
764
- it_behaves_like 'supported retryable writes'
685
+ let(:unsuccessful_retry_value) do
686
+ 1
765
687
  end
766
688
 
767
- context 'when the operation is bulk write including delete_many' do
689
+ it_behaves_like 'supported retryable writes'
690
+ end
768
691
 
769
- before do
770
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
771
- authorized_collection.insert_one(a:1)
772
- authorized_collection.insert_one(a:1)
773
- end
692
+ context 'when the operation is bulk write including delete_many' do
774
693
 
775
- let(:operation) do
776
- collection.bulk_write([{ delete_many: { filter: { a: 1 } } }])
777
- end
694
+ before do
695
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
696
+ authorized_collection.insert_one(a:1)
697
+ authorized_collection.insert_one(a:1)
698
+ end
778
699
 
779
- let(:expectation) do
780
- collection.find(a: 1).count
781
- end
700
+ let(:operation) do
701
+ collection.bulk_write([{ delete_many: { filter: { a: 1 } } }])
702
+ end
782
703
 
783
- let(:unsuccessful_retry_value) do
784
- 2
785
- end
704
+ let(:expectation) do
705
+ collection.find(a: 1).count
706
+ end
786
707
 
787
- it_behaves_like 'an operation that does not support retryable writes'
708
+ let(:unsuccessful_retry_value) do
709
+ 2
788
710
  end
789
711
 
790
- context 'when the operation is bulk write including update_many' do
712
+ it_behaves_like 'an operation that does not support retryable writes'
713
+ end
791
714
 
792
- before do
793
- # Account for when the collection has unacknowledged write concern and use authorized_collection here.
794
- authorized_collection.insert_one(a:0)
795
- authorized_collection.insert_one(a:0)
796
- end
715
+ context 'when the operation is bulk write including update_many' do
797
716
 
798
- let(:operation) do
799
- collection.bulk_write([{ update_many: { filter: { a: 0 }, update: { a: 1 } } }])
800
- end
717
+ before do
718
+ # Account for when the collection has unacknowledged write concern and use authorized_collection here.
719
+ authorized_collection.insert_one(a:0)
720
+ authorized_collection.insert_one(a:0)
721
+ end
801
722
 
802
- let(:expectation) do
803
- collection.find(a: 1).count
804
- end
723
+ let(:operation) do
724
+ collection.bulk_write([{ update_many: { filter: { a: 0 }, update: { a: 1 } } }])
725
+ end
805
726
 
806
- let(:unsuccessful_retry_value) do
807
- 0
808
- end
727
+ let(:expectation) do
728
+ collection.find(a: 1).count
729
+ end
809
730
 
810
- it_behaves_like 'an operation that does not support retryable writes'
731
+ let(:unsuccessful_retry_value) do
732
+ 0
811
733
  end
734
+
735
+ it_behaves_like 'an operation that does not support retryable writes'
812
736
  end
813
737
  end