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
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'ChangeStreams' do
4
+
5
+ CHANGE_STREAMS_TESTS.each do |file|
6
+
7
+ spec = Mongo::ChangeStreams::Spec.new(file)
8
+
9
+ context(spec.description) do
10
+
11
+ spec.tests.each do |test|
12
+
13
+ context(test.description) do
14
+
15
+ before(:each) do
16
+ unless test.configuration_satisfied?(authorized_client)
17
+ skip 'Version or topology requirements not satisfied'
18
+ end
19
+
20
+ test.setup_test
21
+ end
22
+
23
+ after(:each) do
24
+ test.teardown_test if test.configuration_satisfied?(authorized_client)
25
+ end
26
+
27
+ let(:result) do
28
+ test.run
29
+ end
30
+
31
+ it 'returns the correct result' do
32
+ expect(result[:result]).to match_result(test)
33
+ end
34
+
35
+ it 'has the correct command_started events' do
36
+ expect(result[:events]).to match_commands(test)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -26,7 +26,7 @@ describe 'Command Monitoring Events' do
26
26
  end
27
27
 
28
28
  let(:monitoring) do
29
- authorized_client.instance_variable_get(:@monitoring)
29
+ authorized_client.send(:monitoring)
30
30
  end
31
31
 
32
32
  before do
@@ -41,7 +41,13 @@ describe 'Command Monitoring Events' do
41
41
 
42
42
  test.expectations.each do |expectation|
43
43
 
44
- it "generates a #{expectation.event_name} for #{expectation.command_name}", unless: ignore?(test) do
44
+ before do
45
+ if ignore?(test)
46
+ skip 'Preconditions not met'
47
+ end
48
+ end
49
+
50
+ it "generates a #{expectation.event_name} for #{expectation.command_name}" do
45
51
  begin
46
52
  test.run(authorized_collection)
47
53
  event = subscriber.send(expectation.event_type)[expectation.command_name]
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'lite_spec_helper'
2
2
 
3
3
  describe 'ConnectionString' do
4
4
  include Mongo::ConnectionString
@@ -10,15 +10,13 @@ describe 'CRUD' do
10
10
 
11
11
  spec.tests.each do |test|
12
12
 
13
- around do |example|
14
- if spec.server_version_satisfied?(authorized_client)
15
- example.run
16
- end
17
- end
18
-
19
13
  context(test.description) do
20
14
 
21
15
  before(:each) do
16
+ unless spec.server_version_satisfied?(authorized_client)
17
+ skip 'Version requirement not satisfied'
18
+ end
19
+
22
20
  test.setup_test(authorized_collection)
23
21
  end
24
22
 
@@ -26,7 +24,7 @@ describe 'CRUD' do
26
24
  authorized_collection.delete_many
27
25
  end
28
26
 
29
- let(:results) do
27
+ let!(:results) do
30
28
  test.run(authorized_collection)
31
29
  end
32
30
 
@@ -54,7 +54,7 @@ describe 'DNS Seedlist Discovery' do
54
54
 
55
55
  test = Mongo::ConnectionString::Test.new(spec)
56
56
 
57
- context(File.basename(file_name), if: test_connecting_externally?) do
57
+ context(File.basename(file_name)) do
58
58
 
59
59
  context 'when the uri is invalid', if: test.raise_error? do
60
60
 
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Retryable writes spec tests' do
4
+
5
+ RETRYABLE_WRITES_TESTS.each do |file|
6
+
7
+ spec = Mongo::CRUD::Spec.new(file)
8
+
9
+ context(spec.description) do
10
+
11
+ spec.tests.each do |test|
12
+
13
+ context(test.description) do
14
+
15
+ let(:collection) do
16
+ client[TEST_COLL]
17
+ end
18
+
19
+ let(:client) do
20
+ authorized_client_with_retry_writes
21
+ end
22
+
23
+ before do
24
+ unless sessions_enabled?
25
+ skip 'Sessions not enabled'
26
+ end
27
+ unless replica_set?
28
+ skip 'Not in replica set'
29
+ end
30
+ unless spec.server_version_satisfied?(client)
31
+ skip 'Test cannot be run on this server version'
32
+ end
33
+ end
34
+
35
+ before do
36
+ test.setup_test(collection)
37
+ end
38
+
39
+ after do
40
+ test.clear_fail_point(collection)
41
+ collection.delete_many
42
+ end
43
+
44
+ let(:results) do
45
+ if test.error?
46
+ error = nil
47
+ begin
48
+ test.run(collection)
49
+ rescue => e
50
+ error = e
51
+ end
52
+ error
53
+ else
54
+ test.run(collection)
55
+ end
56
+ end
57
+
58
+ if test.outcome_collection_data
59
+ it 'has the correct data in the collection' do
60
+ results
61
+ expect(collection.find.to_a).to match_collection_data(test)
62
+ end
63
+ end
64
+
65
+ if test.error?
66
+ it 'raises an error' do
67
+ expect(results).to be_a(Mongo::Error)
68
+ end
69
+ else
70
+ it 'returns the correct result' do
71
+ expect(results).to match_operation_result(test)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'lite_spec_helper'
2
2
 
3
3
  describe 'SDAM Monitoring' do
4
4
  include Mongo::SDAM
@@ -7,7 +7,7 @@ describe 'SDAM Monitoring' do
7
7
 
8
8
  spec = Mongo::SDAM::Spec.new(file)
9
9
 
10
- context(spec.description) do
10
+ context("#{spec.description} (#{file.sub(%r'.*support/sdam_monitoring/', '')})") do
11
11
 
12
12
  before(:all) do
13
13
  @client = Mongo::Client.new([], heartbeat_frequency: 100, connect_timeout: 0.1)
@@ -35,10 +35,11 @@ describe 'SDAM Monitoring' do
35
35
  server ||= Mongo::Server.new(
36
36
  Mongo::Address.new(response.address),
37
37
  @client.cluster,
38
- @client.instance_variable_get(:@monitoring),
38
+ @client.send(:monitoring),
39
39
  @client.cluster.send(:event_listeners),
40
40
  @client.cluster.options
41
41
  )
42
+
42
43
  monitor = server.instance_variable_get(:@monitor)
43
44
  description = monitor.inspector.run(server.description, response.ismaster, 0.5)
44
45
  monitor.instance_variable_set(:@description, description)
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'lite_spec_helper'
2
2
 
3
3
  describe 'Server Discovery and Monitoring' do
4
4
  include Mongo::SDAM
@@ -7,11 +7,10 @@ describe 'Server Discovery and Monitoring' do
7
7
 
8
8
  spec = Mongo::SDAM::Spec.new(file)
9
9
 
10
- context(spec.description) do
10
+ context("#{spec.description} (#{file.sub(%r'.*support/sdam/', '')})") do
11
11
 
12
12
  before(:all) do
13
- @client = Mongo::Client.new([])
14
- @client.send(:create_from_uri, spec.uri_string)
13
+ @client = Mongo::Client.new(spec.uri_string)
15
14
  client_options = @client.instance_variable_get(:@options)
16
15
  @client.instance_variable_set(:@options, client_options.merge(heartbeat_frequency: 100, connect_timeout: 0.1))
17
16
  @client.cluster.instance_variable_set(:@options, client_options.merge(heartbeat_frequency: 100, connect_timeout: 0.1))
@@ -33,7 +32,7 @@ describe 'Server Discovery and Monitoring' do
33
32
  server = Mongo::Server.new(
34
33
  Mongo::Address.new(response.address),
35
34
  @client.cluster,
36
- @client.instance_variable_get(:@monitoring),
35
+ @client.send(:monitoring),
37
36
  @client.cluster.send(:event_listeners),
38
37
  @client.cluster.options
39
38
  )
@@ -94,8 +93,9 @@ describe 'Server Discovery and Monitoring' do
94
93
 
95
94
  it 'raises an UnsupportedFeatures error' do
96
95
  expect {
97
- Mongo::ServerSelector.get(mode: :primary).select_server(@client.cluster)
98
- Mongo::ServerSelector.get(mode: :secondary).select_server(@client.cluster)
96
+ p = Mongo::ServerSelector.get(mode: :primary).select_server(@client.cluster)
97
+ s = Mongo::ServerSelector.get(mode: :secondary).select_server(@client.cluster)
98
+ raise "UnsupportedFeatures not raised but we got #{p.inspect} as primary and #{s.inspect} as secondary"
99
99
  }.to raise_exception(Mongo::Error::UnsupportedFeatures)
100
100
  end
101
101
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2017 MongoDB, Inc.
1
+ # Copyright (C) 2009-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -85,6 +85,13 @@ BASE_OPTIONS = {
85
85
  write: WRITE_CONCERN,
86
86
  heartbeat_frequency: 20,
87
87
  max_read_retries: 5,
88
+ # The test suite seems to perform a number of operations
89
+ # requiring server selection. Hence a timeout of 1 here,
90
+ # together with e.g. a misconfigured replica set,
91
+ # means the test suite hangs for about 4 seconds before
92
+ # failing.
93
+ # Server selection timeout of 1 is insufficient for evergreen.
94
+ server_selection_timeout: 2,
88
95
  wait_queue_timeout: 2,
89
96
  connect_timeout: 3,
90
97
  max_idle_time: 5
@@ -129,14 +136,19 @@ ROOT_USER = Mongo::Auth::User.new(
129
136
  #
130
137
  # @since 2.0.0
131
138
  TEST_USER = Mongo::Auth::User.new(
132
- database: Mongo::Database::ADMIN,
139
+ database: TEST_DB,
133
140
  user: 'test-user',
134
141
  password: 'password',
135
142
  roles: [
136
143
  { role: Mongo::Auth::Roles::READ_WRITE, db: TEST_DB },
137
144
  { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: TEST_DB },
138
145
  { role: Mongo::Auth::Roles::READ_WRITE, db: 'invalid_database' },
139
- { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'invalid_database' }
146
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'invalid_database' },
147
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'hr' }, # For transactions examples
148
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'hr' }, # For transactions examples
149
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'reporting' }, # For transactions examples
150
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'reporting' } # For transactions examples
151
+
140
152
  ]
141
153
  )
142
154
 
@@ -206,9 +218,9 @@ ADMIN_AUTHORIZED_TEST_CLIENT = ADMIN_UNAUTHORIZED_CLIENT.with(
206
218
  SUBSCRIBED_CLIENT = Mongo::Client.new(
207
219
  ADDRESSES,
208
220
  TEST_OPTIONS.merge(
209
- database: TEST_DB,
210
- user: TEST_USER.name,
211
- password: TEST_USER.password)
221
+ database: TEST_DB,
222
+ user: TEST_USER.name,
223
+ password: TEST_USER.password)
212
224
  )
213
225
  SUBSCRIBED_CLIENT.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber)
214
226
  AUTHROIZED_CLIENT_WITH_RETRY_WRITES.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber)
@@ -0,0 +1,265 @@
1
+ # Copyright (C) 2014-2018 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ RSpec::Matchers.define :match_result do |test|
16
+ match do |actual|
17
+ test.match_result?(actual)
18
+ end
19
+ end
20
+
21
+ RSpec::Matchers.define :match_commands do |test|
22
+ match do |actual|
23
+ test.match_commands?(actual)
24
+ end
25
+ end
26
+
27
+ require 'support/change_streams/operation'
28
+
29
+ module Mongo
30
+ module ChangeStreams
31
+ class Spec
32
+
33
+ # @return [ String ] description The spec description.
34
+ #
35
+ # @since 2.6.0
36
+ attr_reader :description
37
+
38
+ # Instantiate the new spec.
39
+ #
40
+ # @example Create the spec.
41
+ # Spec.new(file)
42
+ #
43
+ # @param [ String ] file The name of the file.
44
+ #
45
+ # @since 2.6.0
46
+ def initialize(file)
47
+ file = File.new(file)
48
+ @spec = YAML.load(ERB.new(file.read).result)
49
+ file.close
50
+ @description = File.basename(file)
51
+ @spec_tests = @spec['tests']
52
+ @coll1 = @spec['collection_name']
53
+ @coll2 = @spec['collection2_name']
54
+ @db1 = @spec['database_name']
55
+ @db2 = @spec['database2_name']
56
+ end
57
+
58
+ # Get a list of ChangeStreamsTests for each test definition.
59
+ #
60
+ # @example Get the list of ChangeStreamsTests.
61
+ # spec.tests
62
+ #
63
+ # @return [ Array<ChangeStreamsTest> ] The list of ChangeStreamsTests.
64
+ #
65
+ # @since 2.0.0
66
+ def tests
67
+ @spec_tests.map do |test|
68
+ ChangeStreamsTest.new(test, @coll1, @coll2, @db1, @db2)
69
+ end
70
+ end
71
+
72
+ class ChangeStreamsTest
73
+ # The test description.
74
+ #
75
+ # @return [ String ] description The test description.
76
+ #
77
+ # @since 2.0.0
78
+ attr_reader :description
79
+
80
+ def configuration_satisfied?(client)
81
+ server_version_satisfied?(client) && topology_satisfied?
82
+ end
83
+
84
+ def initialize(test, coll1, coll2, db1, db2)
85
+ @description = test['description']
86
+ @min_server_version = test['minServerVersion']
87
+ @max_server_version = test['maxServerVersion']
88
+ @target_type = test['target']
89
+ @topologies = test['topology']
90
+ @pipeline = test['changeStreamPipeline'] || []
91
+ @options = test['changeStreamOptions'] || {}
92
+ @operations = test['operations'].map { |op| Operation.new(op) }
93
+ @expectations = test['expectations']
94
+ @result = test['result']
95
+ @coll1_name = coll1
96
+ @coll2_name = coll2
97
+ @db1_name = db1
98
+ @db2_name = db2
99
+ end
100
+
101
+ def setup_test
102
+ @global_client = ADMIN_AUTHORIZED_TEST_CLIENT.use('admin')
103
+
104
+ @db1 = @global_client.use(@db1_name).database.tap(&:drop)
105
+ @db2 = @global_client.use(@db2_name).database.tap(&:drop)
106
+
107
+ @db1[@coll1_name].create
108
+ @db2[@coll2_name].create
109
+
110
+ client = ADMIN_AUTHORIZED_TEST_CLIENT.with(
111
+ database: @db1_name,
112
+ app_name: 'this is used solely to force the new client to create its own cluster')
113
+ client.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber.clear_events!)
114
+
115
+ @target = case @target_type
116
+ when 'client'
117
+ client
118
+ when 'database'
119
+ client.database
120
+ when 'collection'
121
+ client[@coll1_name]
122
+ end
123
+ end
124
+
125
+ def run
126
+ change_stream = begin
127
+ @target.watch(@pipeline, @options)
128
+ rescue Mongo::Error::OperationFailure => e
129
+ return {
130
+ result: { 'error' => { 'code' => e.code } },
131
+ events: events
132
+ }
133
+ end
134
+
135
+ @operations.each do |op|
136
+ op.execute(@db1, @db2)
137
+ end
138
+
139
+ changes = [].tap do |changes|
140
+ next unless @result['success']
141
+
142
+ unless @result['success'].empty?
143
+ change_stream.take_while do |change|
144
+ changes << change
145
+ changes.length < @result['success'].length
146
+ end
147
+ end
148
+
149
+ change_stream.close
150
+ end
151
+
152
+ {
153
+ result: { 'success' => changes },
154
+ events: events,
155
+ }
156
+ end
157
+
158
+ def teardown_test
159
+ @global_client.close
160
+ @db1.drop
161
+ @db2.drop
162
+ end
163
+
164
+ def match_result?(result)
165
+ case @result.first.first
166
+ when 'success'
167
+ match_success?(result)
168
+ when 'error'
169
+ @result == result
170
+ end
171
+ end
172
+
173
+ def match_commands?(actual)
174
+ @expectations.each_with_index.all? do |e, i|
175
+ actual[i] && match?(e, actual[i])
176
+ end
177
+ end
178
+
179
+ private
180
+
181
+ def events
182
+ EventSubscriber.started_events.reduce([]) do |evs, e|
183
+ next evs if [:saslStart, :saslContinue, :killCursors].include?(e.command_name)
184
+
185
+ evs << {
186
+ 'command_started_event' => {
187
+ 'command' => e.command,
188
+ 'command_name' => e.command_name.to_s,
189
+ 'database_name' => e.database_name
190
+ }
191
+ }
192
+ end
193
+ end
194
+
195
+ def match_success?(result)
196
+ return false unless result['success']
197
+ match?(@result['success'], result['success'])
198
+ end
199
+
200
+ def match?(expected, actual)
201
+ return !!actual if expected.to_s == '42'
202
+ return match_array?(expected, actual) if expected.is_a?(Array)
203
+ return match_hash?(expected, actual) if expected.is_a?(Hash)
204
+ expected == actual
205
+ end
206
+
207
+ def match_array?(expected, actual)
208
+ return false unless actual.is_a?(Array)
209
+
210
+ expected.each_with_index.all? do |e, i|
211
+ actual[i] && match?(e, actual[i])
212
+ end
213
+ end
214
+
215
+ def match_hash?(expected, actual)
216
+ return false unless actual.is_a?(Hash)
217
+
218
+ expected.all? do |k, v|
219
+ if v.is_a?(Hash) && !v.empty?
220
+ case v.first.first
221
+ when '$numberInt'
222
+ v = v.first.last.to_i
223
+ end
224
+ end
225
+
226
+ actual[k] && match?(v, actual[k])
227
+ end
228
+ end
229
+
230
+ def topology_satisfied?
231
+ @topologies.any? do |topology|
232
+ case topology
233
+ when 'single'
234
+ standalone?
235
+ when 'replicaset'
236
+ replica_set?
237
+ when 'sharded'
238
+ sharded?
239
+ else
240
+ false
241
+ end
242
+ end
243
+ end
244
+
245
+ def server_version_satisfied?(client)
246
+ lower_bound_satisfied?(client) && upper_bound_satisfied?(client)
247
+ end
248
+
249
+ def server_version(client)
250
+ @server_version ||= client.database.command(buildInfo: 1).first['version']
251
+ end
252
+
253
+ def upper_bound_satisfied?(client)
254
+ return true unless @max_server_version
255
+ server_version(client) <= @max_server_version
256
+ end
257
+
258
+ def lower_bound_satisfied?(client)
259
+ return true unless @min_server_version
260
+ @min_server_version <= server_version(client)
261
+ end
262
+ end
263
+ end
264
+ end
265
+ end