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,92 @@
1
+ require 'spec_helper'
2
+
3
+ class TestCommandMonitoringSubscriber
4
+ def initialize
5
+ @started_events = []
6
+ @succeeded_events = []
7
+ @failed_events = []
8
+ end
9
+
10
+ attr_reader :started_events, :succeeded_events, :failed_events
11
+
12
+ def started(event)
13
+ @started_events << event
14
+ end
15
+
16
+ def succeeded(event)
17
+ @succeeded_events << event
18
+ end
19
+
20
+ def failed(event)
21
+ @failed_events << event
22
+ end
23
+ end
24
+
25
+ describe 'Command monitoring' do
26
+ let(:subscriber) { TestCommandMonitoringSubscriber.new }
27
+
28
+ before do
29
+ Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::COMMAND, subscriber)
30
+ end
31
+
32
+ after do
33
+ Mongo::Monitoring::Global.unsubscribe(Mongo::Monitoring::COMMAND, subscriber)
34
+ end
35
+
36
+ let(:client) { Mongo::Client.new(authorized_client.cluster.addresses.map(&:to_s), authorized_client.options) }
37
+
38
+ it 'notifies on successful commands' do
39
+ result = client.database.command(:ismaster => 1)
40
+ expect(result.documents.first['ismaster']).to be true
41
+
42
+ started_events = subscriber.started_events.select do |event|
43
+ event.command_name == 'ismaster'
44
+ end
45
+ expect(started_events.length).to eql(1)
46
+ started_event = started_events.first
47
+ expect(started_event.command_name).to eql('ismaster')
48
+ expect(started_event.address).to be_a(Mongo::Address)
49
+
50
+ succeeded_events = subscriber.succeeded_events.select do |event|
51
+ event.command_name == 'ismaster'
52
+ end
53
+ expect(succeeded_events.length).to eql(1)
54
+ succeeded_event = succeeded_events.first
55
+ expect(succeeded_event.command_name).to eql('ismaster')
56
+ expect(succeeded_event.reply).to be_a(BSON::Document)
57
+ expect(succeeded_event.reply['ismaster']).to eql(true)
58
+ expect(succeeded_event.address).to be_a(Mongo::Address)
59
+ expect(succeeded_event.duration).to be_a(Float)
60
+
61
+ expect(subscriber.failed_events.length).to eql(0)
62
+ end
63
+
64
+ it 'notifies on failed commands' do
65
+ expect do
66
+ result = client.database.command(:bogus => 1)
67
+ end.to raise_error(Mongo::Error::OperationFailure, /no such c(om)?m(an)?d/)
68
+
69
+ started_events = subscriber.started_events.select do |event|
70
+ event.command_name == 'bogus'
71
+ end
72
+ expect(started_events.length).to eql(1)
73
+ started_event = started_events.first
74
+ expect(started_event.command_name).to eql('bogus')
75
+ expect(started_event.address).to be_a(Mongo::Address)
76
+
77
+ succeeded_events = subscriber.succeeded_events.select do |event|
78
+ event.command_name == 'ismaster'
79
+ end
80
+ expect(succeeded_events.length).to eql(0)
81
+
82
+ failed_events = subscriber.failed_events.select do |event|
83
+ event.command_name == 'bogus'
84
+ end
85
+ expect(failed_events.length).to eql(1)
86
+ failed_event = failed_events.first
87
+ expect(failed_event.command_name).to eql('bogus')
88
+ expect(failed_event.message).to match(/no such c(om)?m(an)?d/)
89
+ expect(failed_event.address).to be_a(Mongo::Address)
90
+ expect(failed_event.duration).to be_a(Float)
91
+ end
92
+ end
@@ -0,0 +1,63 @@
1
+ COVERAGE_MIN = 90
2
+ CURRENT_PATH = File.expand_path(File.dirname(__FILE__))
3
+ SERVER_DISCOVERY_TESTS = Dir.glob("#{CURRENT_PATH}/support/sdam/**/*.yml")
4
+ SDAM_MONITORING_TESTS = Dir.glob("#{CURRENT_PATH}/support/sdam_monitoring/*.yml")
5
+ SERVER_SELECTION_RTT_TESTS = Dir.glob("#{CURRENT_PATH}/support/server_selection/rtt/*.yml")
6
+ SERVER_SELECTION_TESTS = Dir.glob("#{CURRENT_PATH}/support/server_selection/selection/**/*.yml")
7
+ MAX_STALENESS_TESTS = Dir.glob("#{CURRENT_PATH}/support/max_staleness/**/*.yml")
8
+ CRUD_TESTS = Dir.glob("#{CURRENT_PATH}/support/crud_tests/**/*.yml")
9
+ RETRYABLE_WRITES_TESTS = Dir.glob("#{CURRENT_PATH}/support/retryable_writes_tests/**/*.yml")
10
+ COMMAND_MONITORING_TESTS = Dir.glob("#{CURRENT_PATH}/support/command_monitoring/**/*.yml")
11
+ CONNECTION_STRING_TESTS = Dir.glob("#{CURRENT_PATH}/support/connection_string_tests/*.yml")
12
+ DNS_SEEDLIST_DISCOVERY_TESTS = Dir.glob("#{CURRENT_PATH}/support/dns_seedlist_discovery_tests/*.yml")
13
+ GRIDFS_TESTS = Dir.glob("#{CURRENT_PATH}/support/gridfs_tests/*.yml")
14
+ TRANSACTIONS_TESTS = Dir.glob("#{CURRENT_PATH}/support/transactions_tests/*.yml")
15
+ CHANGE_STREAMS_TESTS = Dir.glob("#{CURRENT_PATH}/support/change_streams_tests/*.yml")
16
+
17
+ if ENV['DRIVERS_TOOLS']
18
+ CLIENT_CERT_PEM = ENV['DRIVER_TOOLS_CLIENT_CERT_PEM']
19
+ CLIENT_KEY_PEM = ENV['DRIVER_TOOLS_CLIENT_KEY_PEM']
20
+ CA_PEM = ENV['DRIVER_TOOLS_CA_PEM']
21
+ CLIENT_KEY_ENCRYPTED_PEM = ENV['DRIVER_TOOLS_CLIENT_KEY_ENCRYPTED_PEM']
22
+ else
23
+ SSL_CERTS_DIR = "#{CURRENT_PATH}/support/certificates"
24
+ CLIENT_PEM = "#{SSL_CERTS_DIR}/client.pem"
25
+ CLIENT_PASSWORD_PEM = "#{SSL_CERTS_DIR}/password_protected.pem"
26
+ CA_PEM = "#{SSL_CERTS_DIR}/ca.pem"
27
+ CRL_PEM = "#{SSL_CERTS_DIR}/crl.pem"
28
+ CLIENT_KEY_PEM = "#{SSL_CERTS_DIR}/client_key.pem"
29
+ CLIENT_CERT_PEM = "#{SSL_CERTS_DIR}/client_cert.pem"
30
+ CLIENT_KEY_ENCRYPTED_PEM = "#{SSL_CERTS_DIR}/client_key_encrypted.pem"
31
+ CLIENT_KEY_PASSPHRASE = "passphrase"
32
+ end
33
+
34
+ require 'mongo'
35
+ begin
36
+ require 'byebug'
37
+ rescue LoadError
38
+ end
39
+
40
+ Mongo::Logger.logger = Logger.new($stdout)
41
+ unless %w(1 true yes).include?((ENV['CLIENT_DEBUG'] || '').downcase)
42
+ Mongo::Logger.logger.level = Logger::INFO
43
+ end
44
+ Encoding.default_external = Encoding::UTF_8
45
+
46
+ require 'support/matchers'
47
+ require 'support/event_subscriber'
48
+ require 'support/server_discovery_and_monitoring'
49
+ require 'support/server_selection_rtt'
50
+ require 'support/server_selection'
51
+ require 'support/sdam_monitoring'
52
+ require 'support/crud'
53
+ require 'support/command_monitoring'
54
+ require 'support/connection_string'
55
+ require 'support/gridfs'
56
+ require 'support/transactions'
57
+ require 'support/change_streams'
58
+
59
+ RSpec.configure do |config|
60
+ if ENV['CI'] && RUBY_PLATFORM =~ /\bjava\b/
61
+ config.formatter = 'documentation'
62
+ end
63
+ end
@@ -15,12 +15,40 @@ describe Mongo::Address::IPv6 do
15
15
  end
16
16
  end
17
17
 
18
- context 'when no port is provided' do
18
+ context 'when no port is provided and host is in brackets' do
19
19
 
20
20
  it 'returns the host and port' do
21
21
  expect(described_class.parse('[::1]')).to eq(['::1', 27017])
22
22
  end
23
23
  end
24
+
25
+ context 'when no port is provided and host is not in brackets' do
26
+
27
+ it 'returns the host and port' do
28
+ expect(described_class.parse('::1')).to eq(['::1', 27017])
29
+ end
30
+ end
31
+
32
+ context 'when invalid address is provided' do
33
+
34
+ it 'raises ArgumentError' do
35
+ expect do
36
+ described_class.parse('::1:27017')
37
+ end.to raise_error(ArgumentError, 'Invalid IPv6 address: ::1:27017')
38
+ end
39
+
40
+ it 'rejects extra data around the address' do
41
+ expect do
42
+ described_class.parse('[::1]:27017oh')
43
+ end.to raise_error(ArgumentError, 'Invalid IPv6 address: [::1]:27017oh')
44
+ end
45
+
46
+ it 'rejects bogus data in brackets' do
47
+ expect do
48
+ described_class.parse('[::hello]:27017')
49
+ end.to raise_error(ArgumentError, 'Invalid IPv6 address: [::hello]:27017')
50
+ end
51
+ end
24
52
  end
25
53
 
26
54
  describe '#initialize' do
@@ -276,4 +276,38 @@ describe Mongo::Address do
276
276
  end
277
277
  end
278
278
  end
279
+
280
+ describe '#to_s' do
281
+ context 'address with ipv4 host only' do
282
+ let(:address) { Mongo::Address.new('127.0.0.1') }
283
+
284
+ it 'is host with port' do
285
+ expect(address.to_s).to eql('127.0.0.1:27017')
286
+ end
287
+ end
288
+
289
+ context 'address with ipv4 host and port' do
290
+ let(:address) { Mongo::Address.new('127.0.0.1:27000') }
291
+
292
+ it 'is host with port' do
293
+ expect(address.to_s).to eql('127.0.0.1:27000')
294
+ end
295
+ end
296
+
297
+ context 'address with ipv6 host only' do
298
+ let(:address) { Mongo::Address.new('::1') }
299
+
300
+ it 'is host with port' do
301
+ expect(address.to_s).to eql('[::1]:27017')
302
+ end
303
+ end
304
+
305
+ context 'address with ipv6 host and port' do
306
+ let(:address) { Mongo::Address.new('[::1]:27000') }
307
+
308
+ it 'is host with port' do
309
+ expect(address.to_s).to eql('[::1]:27000')
310
+ end
311
+ end
312
+ end
279
313
  end
@@ -2,195 +2,401 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongo::Auth::SCRAM::Conversation do
4
4
 
5
- let(:user) do
6
- Mongo::Auth::User.new(
7
- database: Mongo::Database::ADMIN,
8
- user: 'user',
9
- password: 'pencil'
10
- )
11
- end
12
-
13
5
  let(:conversation) do
14
- described_class.new(user)
6
+ described_class.new(user, mechanism)
15
7
  end
16
8
 
17
- describe '#start' do
9
+ context 'when SCRAM-SHA-1 is used', if: scram_sha_1_enabled? do
18
10
 
19
- let(:query) do
20
- conversation.start
11
+ let(:user) do
12
+ Mongo::Auth::User.new(
13
+ database: Mongo::Database::ADMIN,
14
+ user: 'user',
15
+ password: 'pencil',
16
+ # We specify SCRAM-SHA-1 so that we don't accidentally use SCRAM-SHA-256 on newer server versions.
17
+ auth_mech: 'SCRAM-SHA-1'
18
+ )
21
19
  end
22
20
 
23
- before do
24
- expect(SecureRandom).to receive(:base64).once.and_return('NDA2NzU3MDY3MDYwMTgy')
21
+ let(:mechanism) do
22
+ 'SCRAM-SHA-1'
25
23
  end
26
24
 
27
- let(:selector) do
28
- query.selector
29
- end
25
+ describe '#start' do
30
26
 
31
- it 'sets the sasl start flag' do
32
- expect(selector[:saslStart]).to eq(1)
33
- end
27
+ let(:query) do
28
+ conversation.start
29
+ end
34
30
 
35
- it 'sets the auto authorize flag' do
36
- expect(selector[:autoAuthorize]).to eq(1)
37
- end
31
+ before do
32
+ expect(SecureRandom).to receive(:base64).once.and_return('NDA2NzU3MDY3MDYwMTgy')
33
+ end
38
34
 
39
- it 'sets the mechanism' do
40
- expect(selector[:mechanism]).to eq('SCRAM-SHA-1')
41
- end
35
+ let(:selector) do
36
+ query.selector
37
+ end
42
38
 
43
- it 'sets the payload' do
44
- expect(selector[:payload].data).to eq('n,,n=user,r=NDA2NzU3MDY3MDYwMTgy')
45
- end
46
- end
39
+ it 'sets the sasl start flag' do
40
+ expect(selector[:saslStart]).to eq(1)
41
+ end
47
42
 
48
- describe '#continue' do
43
+ it 'sets the auto authorize flag' do
44
+ expect(selector[:autoAuthorize]).to eq(1)
45
+ end
49
46
 
50
- let(:reply) do
51
- Mongo::Protocol::Message.new
52
- end
47
+ it 'sets the mechanism' do
48
+ expect(selector[:mechanism]).to eq('SCRAM-SHA-1')
49
+ end
53
50
 
54
- let(:documents) do
55
- [{
56
- 'conversationId' => 1,
57
- 'done' => false,
58
- 'payload' => payload,
59
- 'ok' => 1.0
60
- }]
51
+ it 'sets the payload' do
52
+ expect(selector[:payload].data).to eq('n,,n=user,r=NDA2NzU3MDY3MDYwMTgy')
53
+ end
61
54
  end
62
55
 
63
- before do
64
- expect(SecureRandom).to receive(:base64).once.and_return('NDA2NzU3MDY3MDYwMTgy')
65
- allow(reply).to receive(:documents).and_return(documents)
56
+ describe '#continue' do
57
+
58
+ let(:reply) do
59
+ Mongo::Protocol::Message.new
60
+ end
61
+
62
+ let(:documents) do
63
+ [{
64
+ 'conversationId' => 1,
65
+ 'done' => false,
66
+ 'payload' => payload,
67
+ 'ok' => 1.0
68
+ }]
69
+ end
70
+
71
+ before do
72
+ expect(SecureRandom).to receive(:base64).once.and_return('NDA2NzU3MDY3MDYwMTgy')
73
+ allow(reply).to receive(:documents).and_return(documents)
74
+ end
75
+
76
+ context 'when the server rnonce starts with the nonce' do
77
+
78
+ let(:payload) do
79
+ BSON::Binary.new(
80
+ 'r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
81
+ )
82
+ end
83
+
84
+ let(:query) do
85
+ conversation.continue(reply)
86
+ end
87
+
88
+ let(:selector) do
89
+ query.selector
90
+ end
91
+
92
+ it 'sets the conversation id' do
93
+ expect(selector[:conversationId]).to eq(1)
94
+ end
95
+
96
+ it 'sets the payload' do
97
+ expect(selector[:payload].data).to eq(
98
+ 'c=biws,r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,p=qYUYNy6SQ9Jucq9rFA9nVgXQdbM='
99
+ )
100
+ end
101
+
102
+ it 'sets the continue flag' do
103
+ expect(selector[:saslContinue]).to eq(1)
104
+ end
105
+ end
106
+
107
+ context 'when the server nonce does not start with the nonce' do
108
+
109
+ let(:payload) do
110
+ BSON::Binary.new(
111
+ 'r=NDA2NzU4MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
112
+ )
113
+ end
114
+
115
+ it 'raises an error' do
116
+ expect {
117
+ conversation.continue(reply)
118
+ }.to raise_error(Mongo::Error::InvalidNonce)
119
+ end
120
+ end
66
121
  end
67
122
 
68
- context 'when the server rnonce starts with the nonce' do
123
+ describe '#finalize' do
124
+
125
+ let(:continue_reply) do
126
+ Mongo::Protocol::Message.new
127
+ end
128
+
129
+ let(:continue_documents) do
130
+ [{
131
+ 'conversationId' => 1,
132
+ 'done' => false,
133
+ 'payload' => continue_payload,
134
+ 'ok' => 1.0
135
+ }]
136
+ end
69
137
 
70
- let(:payload) do
138
+ let(:continue_payload) do
71
139
  BSON::Binary.new(
72
140
  'r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
73
141
  )
74
142
  end
75
143
 
144
+ let(:reply) do
145
+ Mongo::Protocol::Message.new
146
+ end
147
+
148
+ let(:documents) do
149
+ [{
150
+ 'conversationId' => 1,
151
+ 'done' => false,
152
+ 'payload' => payload,
153
+ 'ok' => 1.0
154
+ }]
155
+ end
156
+
157
+ before do
158
+ expect(SecureRandom).to receive(:base64).once.and_return('NDA2NzU3MDY3MDYwMTgy')
159
+ allow(continue_reply).to receive(:documents).and_return(continue_documents)
160
+ allow(reply).to receive(:documents).and_return(documents)
161
+ end
162
+
163
+ context 'when the verifier matches the server signature' do
164
+
165
+ let(:payload) do
166
+ BSON::Binary.new('v=gwo9E8+uifshm7ixj441GvIfuUY=')
167
+ end
168
+
169
+ let(:query) do
170
+ conversation.continue(continue_reply)
171
+ conversation.finalize(reply)
172
+ end
173
+
174
+ let(:selector) do
175
+ query.selector
176
+ end
177
+
178
+ it 'sets the conversation id' do
179
+ expect(selector[:conversationId]).to eq(1)
180
+ end
181
+
182
+ it 'sets the empty payload' do
183
+ expect(selector[:payload].data).to eq('')
184
+ end
185
+
186
+ it 'sets the continue flag' do
187
+ expect(selector[:saslContinue]).to eq(1)
188
+ end
189
+ end
190
+
191
+ context 'when the verifier does not match the server signature' do
192
+
193
+ let(:payload) do
194
+ BSON::Binary.new('v=LQ+8yhQeVL2a3Dh+TDJ7xHz4Srk=')
195
+ end
196
+
197
+ it 'raises an error' do
198
+ expect {
199
+ conversation.continue(continue_reply)
200
+ conversation.finalize(reply)
201
+ }.to raise_error(Mongo::Error::InvalidSignature)
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ context 'when SCRAM-SHA-256 is used', if: scram_sha_256_enabled? do
208
+
209
+ let(:user) do
210
+ Mongo::Auth::User.new(
211
+ database: Mongo::Database::ADMIN,
212
+ user: 'user',
213
+ password: 'pencil',
214
+ auth_mech: 'SCRAM-SHA-256'
215
+ )
216
+ end
217
+
218
+ let(:mechanism) do
219
+ 'SCRAM-SHA-256'
220
+ end
221
+
222
+ describe '#start' do
223
+
76
224
  let(:query) do
77
- conversation.continue(reply)
225
+ conversation.start
226
+ end
227
+
228
+ before do
229
+ expect(SecureRandom).to receive(:base64).once.and_return('rOprNGfwEbeRWgbNEkqO')
78
230
  end
79
231
 
80
232
  let(:selector) do
81
233
  query.selector
82
234
  end
83
235
 
84
- it 'sets the conversation id' do
85
- expect(selector[:conversationId]).to eq(1)
236
+ it 'sets the sasl start flag' do
237
+ expect(selector[:saslStart]).to eq(1)
86
238
  end
87
239
 
88
- it 'sets the payload' do
89
- expect(selector[:payload].data).to eq(
90
- 'c=biws,r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,p=qYUYNy6SQ9Jucq9rFA9nVgXQdbM='
91
- )
240
+ it 'sets the auto authorize flag' do
241
+ expect(selector[:autoAuthorize]).to eq(1)
242
+ end
243
+
244
+ it 'sets the mechanism' do
245
+ expect(selector[:mechanism]).to eq('SCRAM-SHA-256')
92
246
  end
93
247
 
94
- it 'sets the continue flag' do
95
- expect(selector[:saslContinue]).to eq(1)
248
+ it 'sets the payload' do
249
+ expect(selector[:payload].data).to eq('n,,n=user,r=rOprNGfwEbeRWgbNEkqO')
96
250
  end
97
251
  end
98
252
 
99
- context 'when the server nonce does not start with the nonce' do
253
+ describe '#continue' do
100
254
 
101
- let(:payload) do
102
- BSON::Binary.new(
103
- 'r=NDA2NzU4MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
104
- )
255
+ let(:reply) do
256
+ Mongo::Protocol::Message.new
105
257
  end
106
258
 
107
- it 'raises an error' do
108
- expect {
109
- conversation.continue(reply)
110
- }.to raise_error(Mongo::Error::InvalidNonce)
259
+ let(:documents) do
260
+ [{
261
+ 'conversationId' => 1,
262
+ 'done' => false,
263
+ 'payload' => payload,
264
+ 'ok' => 1.0
265
+ }]
111
266
  end
112
- end
113
- end
114
267
 
115
- describe '#finalize' do
268
+ before do
269
+ expect(SecureRandom).to receive(:base64).once.and_return('rOprNGfwEbeRWgbNEkqO')
270
+ allow(reply).to receive(:documents).and_return(documents)
271
+ end
116
272
 
117
- let(:continue_reply) do
118
- Mongo::Protocol::Message.new
119
- end
273
+ context 'when the server rnonce starts with the nonce' do
120
274
 
121
- let(:continue_documents) do
122
- [{
123
- 'conversationId' => 1,
124
- 'done' => false,
125
- 'payload' => continue_payload,
126
- 'ok' => 1.0
127
- }]
128
- end
275
+ let(:payload) do
276
+ BSON::Binary.new(
277
+ 'r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,s=W22ZaJ0SNY7soEsUEjb6gQ==,i=4096'
278
+ )
279
+ end
129
280
 
130
- let(:continue_payload) do
131
- BSON::Binary.new(
132
- 'r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
133
- )
134
- end
281
+ let(:query) do
282
+ conversation.continue(reply)
283
+ end
135
284
 
136
- let(:reply) do
137
- Mongo::Protocol::Message.new
138
- end
285
+ let(:selector) do
286
+ query.selector
287
+ end
139
288
 
140
- let(:documents) do
141
- [{
142
- 'conversationId' => 1,
143
- 'done' => false,
144
- 'payload' => payload,
145
- 'ok' => 1.0
146
- }]
147
- end
289
+ it 'sets the conversation id' do
290
+ expect(selector[:conversationId]).to eq(1)
291
+ end
148
292
 
149
- before do
150
- expect(SecureRandom).to receive(:base64).once.and_return('NDA2NzU3MDY3MDYwMTgy')
151
- allow(continue_reply).to receive(:documents).and_return(continue_documents)
152
- allow(reply).to receive(:documents).and_return(documents)
293
+ it 'sets the payload' do
294
+ expect(selector[:payload].data).to eq(
295
+ 'c=biws,r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,p=dHzbZapWIk4jUhN+Ute9ytag9zjfMHgsqmmiz7AndVQ='
296
+ )
297
+ end
298
+
299
+ it 'sets the continue flag' do
300
+ expect(selector[:saslContinue]).to eq(1)
301
+ end
302
+ end
303
+
304
+ context 'when the server nonce does not start with the nonce' do
305
+
306
+ let(:payload) do
307
+ BSON::Binary.new(
308
+ 'r=sOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,s=W22ZaJ0SNY7soEsUEjb6gQ==,i=4096'
309
+ )
310
+ end
311
+
312
+ it 'raises an error' do
313
+ expect {
314
+ conversation.continue(reply)
315
+ }.to raise_error(Mongo::Error::InvalidNonce)
316
+ end
317
+ end
153
318
  end
154
319
 
155
- context 'when the verifier matches the server signature' do
320
+ describe '#finalize' do
156
321
 
157
- let(:payload) do
158
- BSON::Binary.new('v=gwo9E8+uifshm7ixj441GvIfuUY=')
322
+ let(:continue_reply) do
323
+ Mongo::Protocol::Message.new
159
324
  end
160
325
 
161
- let(:query) do
162
- conversation.continue(continue_reply)
163
- conversation.finalize(reply)
326
+ let(:continue_documents) do
327
+ [{
328
+ 'conversationId' => 1,
329
+ 'done' => false,
330
+ 'payload' => continue_payload,
331
+ 'ok' => 1.0
332
+ }]
164
333
  end
165
334
 
166
- let(:selector) do
167
- query.selector
335
+ let(:continue_payload) do
336
+ BSON::Binary.new(
337
+ 'r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,s=W22ZaJ0SNY7soEsUEjb6gQ==,i=4096'
338
+ )
168
339
  end
169
340
 
170
- it 'sets the conversation id' do
171
- expect(selector[:conversationId]).to eq(1)
341
+ let(:reply) do
342
+ Mongo::Protocol::Message.new
172
343
  end
173
344
 
174
- it 'sets the empty payload' do
175
- expect(selector[:payload].data).to eq('')
345
+ let(:documents) do
346
+ [{
347
+ 'conversationId' => 1,
348
+ 'done' => false,
349
+ 'payload' => payload,
350
+ 'ok' => 1.0
351
+ }]
176
352
  end
177
353
 
178
- it 'sets the continue flag' do
179
- expect(selector[:saslContinue]).to eq(1)
354
+ before do
355
+ expect(SecureRandom).to receive(:base64).once.and_return('rOprNGfwEbeRWgbNEkqO')
356
+ allow(continue_reply).to receive(:documents).and_return(continue_documents)
357
+ allow(reply).to receive(:documents).and_return(documents)
180
358
  end
181
- end
182
359
 
183
- context 'when the verifier does not match the server signature' do
360
+ context 'when the verifier matches the server signature' do
184
361
 
185
- let(:payload) do
186
- BSON::Binary.new('v=LQ+8yhQeVL2a3Dh+TDJ7xHz4Srk=')
187
- end
362
+ let(:payload) do
363
+ BSON::Binary.new(' v=6rriTRBi23WpRR/wtup+mMhUZUn/dB5nLTJRsjl95G4=')
364
+ end
188
365
 
189
- it 'raises an error' do
190
- expect {
366
+ let(:query) do
191
367
  conversation.continue(continue_reply)
192
368
  conversation.finalize(reply)
193
- }.to raise_error(Mongo::Error::InvalidSignature)
369
+ end
370
+
371
+ let(:selector) do
372
+ query.selector
373
+ end
374
+
375
+ it 'sets the conversation id' do
376
+ expect(selector[:conversationId]).to eq(1)
377
+ end
378
+
379
+ it 'sets the empty payload' do
380
+ expect(selector[:payload].data).to eq('')
381
+ end
382
+
383
+ it 'sets the continue flag' do
384
+ expect(selector[:saslContinue]).to eq(1)
385
+ end
386
+ end
387
+
388
+ context 'when the verifier does not match the server signature' do
389
+
390
+ let(:payload) do
391
+ BSON::Binary.new('v=7rriTRBi23WpRR/wtup+mMhUZUn/dB5nLTJRsjl95G4=')
392
+ end
393
+
394
+ it 'raises an error' do
395
+ expect {
396
+ conversation.continue(continue_reply)
397
+ conversation.finalize(reply)
398
+ }.to raise_error(Mongo::Error::InvalidSignature)
399
+ end
194
400
  end
195
401
  end
196
402
  end