mongo 2.11.4 → 2.12.3

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 (357) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/README.md +2 -1
  6. data/lib/mongo.rb +3 -0
  7. data/lib/mongo/address.rb +44 -19
  8. data/lib/mongo/auth.rb +1 -0
  9. data/lib/mongo/auth/credential_cache.rb +51 -0
  10. data/lib/mongo/auth/scram/conversation.rb +20 -16
  11. data/lib/mongo/auth/user.rb +0 -8
  12. data/lib/mongo/auth/user/view.rb +4 -4
  13. data/lib/mongo/background_thread.rb +1 -1
  14. data/lib/mongo/bulk_write.rb +5 -5
  15. data/lib/mongo/client.rb +143 -14
  16. data/lib/mongo/client_encryption.rb +103 -0
  17. data/lib/mongo/cluster.rb +8 -4
  18. data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
  19. data/lib/mongo/cluster/sdam_flow.rb +54 -58
  20. data/lib/mongo/collection.rb +3 -3
  21. data/lib/mongo/collection/view.rb +1 -1
  22. data/lib/mongo/collection/view/aggregation.rb +1 -1
  23. data/lib/mongo/collection/view/change_stream.rb +12 -3
  24. data/lib/mongo/collection/view/iterable.rb +14 -5
  25. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  26. data/lib/mongo/collection/view/readable.rb +9 -7
  27. data/lib/mongo/collection/view/writable.rb +7 -7
  28. data/lib/mongo/crypt.rb +33 -0
  29. data/lib/mongo/crypt/auto_decryption_context.rb +40 -0
  30. data/lib/mongo/crypt/auto_encrypter.rb +179 -0
  31. data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
  32. data/lib/mongo/crypt/binary.rb +155 -0
  33. data/lib/mongo/crypt/binding.rb +1229 -0
  34. data/lib/mongo/crypt/context.rb +135 -0
  35. data/lib/mongo/crypt/data_key_context.rb +162 -0
  36. data/lib/mongo/crypt/encryption_io.rb +289 -0
  37. data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
  38. data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
  39. data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
  40. data/lib/mongo/crypt/handle.rb +315 -0
  41. data/lib/mongo/crypt/hooks.rb +90 -0
  42. data/lib/mongo/crypt/kms_context.rb +67 -0
  43. data/lib/mongo/crypt/status.rb +131 -0
  44. data/lib/mongo/cursor.rb +64 -32
  45. data/lib/mongo/database.rb +23 -6
  46. data/lib/mongo/database/view.rb +13 -4
  47. data/lib/mongo/dbref.rb +9 -2
  48. data/lib/mongo/error.rb +5 -1
  49. data/lib/mongo/error/bulk_write_error.rb +16 -14
  50. data/lib/mongo/error/crypt_error.rb +31 -0
  51. data/lib/mongo/error/{failed_stringprep_validation.rb → failed_string_prep_validation.rb} +0 -0
  52. data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
  53. data/lib/mongo/error/kms_error.rb +22 -0
  54. data/lib/mongo/error/max_bson_size.rb +14 -3
  55. data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
  56. data/lib/mongo/error/no_server_available.rb +8 -3
  57. data/lib/mongo/error/notable.rb +0 -15
  58. data/lib/mongo/error/operation_failure.rb +1 -0
  59. data/lib/mongo/error/parser.rb +1 -1
  60. data/lib/mongo/grid/file.rb +5 -0
  61. data/lib/mongo/grid/file/chunk.rb +2 -0
  62. data/lib/mongo/grid/file/info.rb +3 -2
  63. data/lib/mongo/grid/fs_bucket.rb +15 -13
  64. data/lib/mongo/grid/stream/write.rb +9 -3
  65. data/lib/mongo/index/view.rb +3 -3
  66. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -1
  67. data/lib/mongo/monitoring/event/command_started.rb +6 -1
  68. data/lib/mongo/operation/collections_info.rb +6 -3
  69. data/lib/mongo/operation/delete/op_msg.rb +1 -1
  70. data/lib/mongo/operation/find/op_msg.rb +4 -1
  71. data/lib/mongo/operation/get_more/op_msg.rb +4 -1
  72. data/lib/mongo/operation/insert/command.rb +3 -2
  73. data/lib/mongo/operation/insert/legacy.rb +3 -2
  74. data/lib/mongo/operation/insert/op_msg.rb +3 -3
  75. data/lib/mongo/operation/result.rb +36 -27
  76. data/lib/mongo/operation/shared/executable.rb +11 -9
  77. data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
  78. data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
  79. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +2 -2
  80. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +2 -2
  81. data/lib/mongo/operation/shared/read_preference_supported.rb +68 -19
  82. data/lib/mongo/operation/shared/response_handling.rb +1 -1
  83. data/lib/mongo/operation/shared/sessions_supported.rb +44 -3
  84. data/lib/mongo/operation/shared/write.rb +17 -10
  85. data/lib/mongo/operation/update/op_msg.rb +1 -1
  86. data/lib/mongo/protocol/bit_vector.rb +2 -1
  87. data/lib/mongo/protocol/compressed.rb +6 -5
  88. data/lib/mongo/protocol/insert.rb +3 -1
  89. data/lib/mongo/protocol/message.rb +94 -15
  90. data/lib/mongo/protocol/msg.rb +207 -37
  91. data/lib/mongo/protocol/query.rb +7 -9
  92. data/lib/mongo/protocol/serializers.rb +43 -15
  93. data/lib/mongo/retryable.rb +1 -1
  94. data/lib/mongo/server.rb +10 -4
  95. data/lib/mongo/server/connection.rb +20 -9
  96. data/lib/mongo/server/connection_base.rb +118 -18
  97. data/lib/mongo/server/connection_common.rb +61 -0
  98. data/lib/mongo/server/connection_pool.rb +37 -1
  99. data/lib/mongo/server/connection_pool/populator.rb +1 -1
  100. data/lib/mongo/server/description.rb +9 -11
  101. data/lib/mongo/server/monitor.rb +2 -0
  102. data/lib/mongo/server/monitor/connection.rb +3 -18
  103. data/lib/mongo/server/pending_connection.rb +2 -1
  104. data/lib/mongo/session.rb +3 -3
  105. data/lib/mongo/session/session_pool.rb +8 -3
  106. data/lib/mongo/socket.rb +29 -16
  107. data/lib/mongo/socket/ssl.rb +23 -8
  108. data/lib/mongo/socket/tcp.rb +12 -3
  109. data/lib/mongo/srv/monitor.rb +73 -42
  110. data/lib/mongo/srv/result.rb +0 -1
  111. data/lib/mongo/timeout.rb +49 -0
  112. data/lib/mongo/uri.rb +30 -1
  113. data/lib/mongo/uri/srv_protocol.rb +1 -1
  114. data/lib/mongo/version.rb +1 -1
  115. data/mongo.gemspec +1 -3
  116. data/spec/README.md +228 -7
  117. data/spec/integration/auth_spec.rb +53 -0
  118. data/spec/integration/bulk_write_spec.rb +19 -0
  119. data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
  120. data/spec/integration/client_construction_spec.rb +100 -1
  121. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +353 -0
  122. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +303 -0
  123. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +72 -0
  124. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +79 -0
  125. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +221 -0
  126. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +601 -0
  127. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +187 -0
  128. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +78 -0
  129. data/spec/integration/client_side_encryption/client_close_spec.rb +63 -0
  130. data/spec/integration/client_side_encryption/corpus_spec.rb +233 -0
  131. data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
  132. data/spec/integration/client_side_encryption/data_key_spec.rb +165 -0
  133. data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
  134. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +141 -0
  135. data/spec/integration/client_side_encryption/views_spec.rb +44 -0
  136. data/spec/integration/client_update_spec.rb +154 -0
  137. data/spec/integration/command_monitoring_spec.rb +3 -1
  138. data/spec/integration/command_spec.rb +44 -10
  139. data/spec/integration/connection_spec.rb +57 -0
  140. data/spec/integration/crud_spec.rb +89 -0
  141. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  142. data/spec/integration/read_preference_spec.rb +26 -0
  143. data/spec/integration/reconnect_spec.rb +7 -6
  144. data/spec/integration/size_limit_spec.rb +111 -0
  145. data/spec/integration/srv_monitoring_spec.rb +16 -8
  146. data/spec/integration/zlib_compression_spec.rb +25 -0
  147. data/spec/kerberos/kerberos_spec.rb +87 -0
  148. data/spec/lite_spec_helper.rb +34 -29
  149. data/spec/mongo/auth/cr_spec.rb +8 -0
  150. data/spec/mongo/auth/ldap_spec.rb +5 -1
  151. data/spec/mongo/auth/scram/conversation_spec.rb +5 -6
  152. data/spec/mongo/auth/scram/negotiation_spec.rb +74 -75
  153. data/spec/mongo/auth/scram_spec.rb +45 -35
  154. data/spec/mongo/auth/user/view_spec.rb +3 -6
  155. data/spec/mongo/auth/x509_spec.rb +5 -1
  156. data/spec/mongo/bulk_write/result_spec.rb +11 -7
  157. data/spec/mongo/client_construction_spec.rb +206 -2
  158. data/spec/mongo/client_encryption_spec.rb +405 -0
  159. data/spec/mongo/cluster/cursor_reaper_spec.rb +12 -8
  160. data/spec/mongo/cluster/socket_reaper_spec.rb +14 -3
  161. data/spec/mongo/collection/view/aggregation_spec.rb +0 -2
  162. data/spec/mongo/collection/view/change_stream_spec.rb +7 -7
  163. data/spec/mongo/collection/view/map_reduce_spec.rb +3 -3
  164. data/spec/mongo/collection/view_spec.rb +1 -1
  165. data/spec/mongo/collection_spec.rb +28 -9
  166. data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
  167. data/spec/mongo/crypt/auto_encrypter_spec.rb +187 -0
  168. data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
  169. data/spec/mongo/crypt/binary_spec.rb +115 -0
  170. data/spec/mongo/crypt/binding/binary_spec.rb +56 -0
  171. data/spec/mongo/crypt/binding/context_spec.rb +257 -0
  172. data/spec/mongo/crypt/binding/helpers_spec.rb +46 -0
  173. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +144 -0
  174. data/spec/mongo/crypt/binding/status_spec.rb +99 -0
  175. data/spec/mongo/crypt/binding/version_spec.rb +22 -0
  176. data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
  177. data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
  178. data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
  179. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
  180. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
  181. data/spec/mongo/crypt/handle_spec.rb +232 -0
  182. data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
  183. data/spec/mongo/crypt/status_spec.rb +152 -0
  184. data/spec/mongo/cursor_spec.rb +24 -4
  185. data/spec/mongo/database_spec.rb +20 -0
  186. data/spec/mongo/error/bulk_write_error_spec.rb +49 -0
  187. data/spec/mongo/error/crypt_error_spec.rb +26 -0
  188. data/spec/mongo/error/max_bson_size_spec.rb +35 -0
  189. data/spec/mongo/error/no_server_available_spec.rb +11 -1
  190. data/spec/mongo/error/notable_spec.rb +59 -0
  191. data/spec/mongo/error/operation_failure_spec.rb +6 -6
  192. data/spec/mongo/operation/aggregate_spec.rb +1 -1
  193. data/spec/mongo/operation/collections_info_spec.rb +1 -1
  194. data/spec/mongo/operation/command_spec.rb +3 -3
  195. data/spec/mongo/operation/create_index_spec.rb +3 -3
  196. data/spec/mongo/operation/create_user_spec.rb +3 -3
  197. data/spec/mongo/operation/delete/bulk_spec.rb +6 -6
  198. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -6
  199. data/spec/mongo/operation/delete_spec.rb +7 -7
  200. data/spec/mongo/operation/drop_index_spec.rb +2 -2
  201. data/spec/mongo/operation/find/legacy_spec.rb +2 -1
  202. data/spec/mongo/operation/get_more_spec.rb +1 -1
  203. data/spec/mongo/operation/indexes_spec.rb +1 -1
  204. data/spec/mongo/operation/insert/bulk_spec.rb +7 -7
  205. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -6
  206. data/spec/mongo/operation/insert_spec.rb +12 -12
  207. data/spec/mongo/operation/map_reduce_spec.rb +2 -2
  208. data/spec/mongo/operation/read_preference_legacy_spec.rb +351 -0
  209. data/spec/mongo/operation/read_preference_op_msg_spec.rb +194 -0
  210. data/spec/mongo/operation/remove_user_spec.rb +3 -3
  211. data/spec/mongo/operation/update/bulk_spec.rb +6 -6
  212. data/spec/mongo/operation/update/op_msg_spec.rb +3 -6
  213. data/spec/mongo/operation/update_spec.rb +7 -7
  214. data/spec/mongo/operation/update_user_spec.rb +1 -1
  215. data/spec/mongo/protocol/compressed_spec.rb +2 -3
  216. data/spec/mongo/protocol/delete_spec.rb +9 -8
  217. data/spec/mongo/protocol/get_more_spec.rb +9 -8
  218. data/spec/mongo/protocol/insert_spec.rb +9 -8
  219. data/spec/mongo/protocol/kill_cursors_spec.rb +6 -5
  220. data/spec/mongo/protocol/msg_spec.rb +57 -53
  221. data/spec/mongo/protocol/query_spec.rb +12 -12
  222. data/spec/mongo/protocol/registry_spec.rb +1 -1
  223. data/spec/mongo/protocol/reply_spec.rb +1 -1
  224. data/spec/mongo/protocol/update_spec.rb +10 -9
  225. data/spec/mongo/server/connection_pool_spec.rb +1 -1
  226. data/spec/mongo/server/connection_spec.rb +28 -7
  227. data/spec/mongo/socket_spec.rb +1 -1
  228. data/spec/mongo/srv/monitor_spec.rb +88 -69
  229. data/spec/mongo/timeout_spec.rb +85 -0
  230. data/spec/mongo/uri/srv_protocol_spec.rb +2 -2
  231. data/spec/mongo/uri_spec.rb +52 -5
  232. data/spec/mongo/write_concern_spec.rb +13 -1
  233. data/spec/{support → runners}/auth.rb +14 -1
  234. data/spec/{support → runners}/change_streams.rb +1 -1
  235. data/spec/{support → runners}/change_streams/operation.rb +0 -0
  236. data/spec/{support → runners}/cmap.rb +1 -1
  237. data/spec/{support → runners}/cmap/verifier.rb +0 -0
  238. data/spec/{support → runners}/command_monitoring.rb +0 -0
  239. data/spec/runners/connection_string.rb +358 -4
  240. data/spec/{support → runners}/crud.rb +9 -9
  241. data/spec/{support → runners}/crud/context.rb +0 -0
  242. data/spec/{support → runners}/crud/operation.rb +7 -3
  243. data/spec/{support → runners}/crud/outcome.rb +0 -0
  244. data/spec/{support → runners}/crud/requirement.rb +1 -1
  245. data/spec/{support → runners}/crud/spec.rb +12 -1
  246. data/spec/{support → runners}/crud/test.rb +0 -0
  247. data/spec/{support → runners}/crud/test_base.rb +0 -0
  248. data/spec/{support → runners}/crud/verifier.rb +10 -12
  249. data/spec/{support → runners}/gridfs.rb +0 -0
  250. data/spec/{support → runners}/sdam_monitoring.rb +0 -0
  251. data/spec/{support → runners}/server_discovery_and_monitoring.rb +0 -0
  252. data/spec/{support → runners}/server_selection.rb +0 -0
  253. data/spec/{support → runners}/server_selection_rtt.rb +0 -0
  254. data/spec/{support → runners}/transactions.rb +9 -11
  255. data/spec/{support → runners}/transactions/context.rb +0 -0
  256. data/spec/{support → runners}/transactions/operation.rb +0 -0
  257. data/spec/{support → runners}/transactions/spec.rb +0 -0
  258. data/spec/{support → runners}/transactions/test.rb +37 -5
  259. data/spec/spec_helper.rb +0 -5
  260. data/spec/spec_tests/auth_spec.rb +3 -3
  261. data/spec/spec_tests/client_side_encryption_spec.rb +8 -0
  262. data/spec/spec_tests/connection_string_spec.rb +1 -1
  263. data/spec/spec_tests/data/auth/connection-string.yml +13 -0
  264. data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
  265. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
  266. data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
  267. data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
  268. data/spec/spec_tests/data/client_side_encryption/bulk.yml +88 -0
  269. data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
  270. data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
  271. data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
  272. data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
  273. data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
  274. data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
  275. data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
  276. data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
  277. data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
  278. data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
  279. data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
  280. data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
  281. data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
  282. data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
  283. data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
  284. data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
  285. data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
  286. data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
  287. data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
  288. data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +64 -0
  289. data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
  290. data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
  291. data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
  292. data/spec/spec_tests/data/client_side_encryption/updateOne.yml +171 -0
  293. data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +1 -4
  294. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +21 -0
  295. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -4
  296. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +1 -1
  297. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
  298. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +1 -2
  299. data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
  300. data/spec/spec_tests/data/sdam/rs/{primary_address_change.yml → ruby_primary_address_change.yml} +2 -0
  301. data/spec/spec_tests/data/sdam/rs/{secondary_wrong_set_name_with_primary_second.yml → ruby_secondary_wrong_set_name_with_primary_second.yml} +0 -0
  302. data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +27 -0
  303. data/spec/spec_tests/data/sdam/sharded/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
  304. data/spec/spec_tests/data/sdam/sharded/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
  305. data/spec/spec_tests/data/sdam/single/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
  306. data/spec/spec_tests/data/sdam/single/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
  307. data/spec/spec_tests/data/sdam_monitoring/{replica_set_with_primary_change.yml → replica_set_primary_address_change.yml} +27 -5
  308. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +26 -74
  309. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +20 -16
  310. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
  311. data/spec/spec_tests/data/transactions/pin-mongos.yml +2 -3
  312. data/spec/spec_tests/data/uri_options/auth-options.yml +10 -0
  313. data/spec/spec_tests/data/uri_options/tls-options.yml +75 -4
  314. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
  315. data/spec/spec_tests/uri_options_spec.rb +6 -8
  316. data/spec/stress/connection_pool_timing_spec.rb +6 -3
  317. data/spec/support/certificates/README.md +4 -0
  318. data/spec/support/certificates/server-second-level-bundle.pem +77 -77
  319. data/spec/support/certificates/server-second-level.crt +52 -52
  320. data/spec/support/certificates/server-second-level.key +25 -25
  321. data/spec/support/certificates/server-second-level.pem +77 -77
  322. data/spec/support/client_registry.rb +19 -3
  323. data/spec/support/cluster_config.rb +9 -1
  324. data/spec/support/cluster_tools.rb +6 -1
  325. data/spec/support/common_shortcuts.rb +12 -0
  326. data/spec/support/constraints.rb +16 -0
  327. data/spec/support/crypt.rb +154 -0
  328. data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
  329. data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
  330. data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
  331. data/spec/support/crypt/corpus/corpus.json +3657 -0
  332. data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
  333. data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
  334. data/spec/support/crypt/data_keys/key_document_local.json +31 -0
  335. data/spec/support/crypt/external/external-key.json +31 -0
  336. data/spec/support/crypt/external/external-schema.json +19 -0
  337. data/spec/support/crypt/limits/limits-doc.json +102 -0
  338. data/spec/support/crypt/limits/limits-key.json +31 -0
  339. data/spec/support/crypt/limits/limits-schema.json +1405 -0
  340. data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
  341. data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  342. data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
  343. data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
  344. data/spec/support/lite_constraints.rb +19 -1
  345. data/spec/support/matchers.rb +19 -0
  346. data/spec/support/shared/protocol.rb +2 -0
  347. data/spec/support/spec_config.rb +53 -13
  348. data/spec/support/utils.rb +140 -10
  349. metadata +894 -687
  350. metadata.gz.sig +0 -0
  351. data/lib/mongo/cluster/srv_monitor.rb +0 -127
  352. data/lib/mongo/srv/warning_result.rb +0 -35
  353. data/spec/enterprise_auth/kerberos_spec.rb +0 -58
  354. data/spec/mongo/cluster/srv_monitor_spec.rb +0 -214
  355. data/spec/mongo/operation/read_preference_spec.rb +0 -245
  356. data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
  357. data/spec/support/connection_string.rb +0 -354
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Bulk writes' do
4
+ before do
5
+ authorized_collection.drop
6
+ end
7
+
8
+ context 'when bulk write is larger than 48MB' do
9
+ let(:operations) do
10
+ [ { insert_one: { text: 'a' * 1000 * 1000 } } ] * 48
11
+ end
12
+
13
+ it 'succeeds' do
14
+ expect do
15
+ authorized_collection.bulk_write(operations)
16
+ end.not_to raise_error
17
+ end
18
+ end
19
+ end
@@ -1,6 +1,6 @@
1
- require 'spec_helper'
1
+ require 'lite_spec_helper'
2
2
 
3
- describe 'Client options' do
3
+ describe 'Client authentication options' do
4
4
  let(:uri) { "mongodb://#{credentials}127.0.0.1:27017/#{options}" }
5
5
 
6
6
  let(:credentials) { nil }
@@ -299,9 +299,9 @@ describe 'Client options' do
299
299
  let(:credentials) { "#{user}:password@" }
300
300
 
301
301
  it 'raises an exception on client creation' do
302
- expect {
302
+ expect do
303
303
  client
304
- }.to raise_error(Mongo::Auth::InvalidConfiguration, /password is not supported/)
304
+ end.to raise_error(Mongo::Auth::InvalidConfiguration, /Password is not supported/)
305
305
  end
306
306
  end
307
307
  end
@@ -325,9 +325,9 @@ describe 'Client options' do
325
325
  let(:client_opts) { { auth_mech: :mongodb_x509, user: user, password: 'password' } }
326
326
 
327
327
  it 'raises an exception on client creation' do
328
- expect {
328
+ expect do
329
329
  client
330
- }.to raise_error(Mongo::Auth::InvalidConfiguration, /password is not supported/)
330
+ end.to raise_error(Mongo::Auth::InvalidConfiguration, /Password is not supported/)
331
331
  end
332
332
  end
333
333
  end
@@ -346,9 +346,9 @@ describe 'Client options' do
346
346
  let(:credentials) { '@' }
347
347
 
348
348
  it 'raises an exception' do
349
- expect {
349
+ expect do
350
350
  client
351
- }.to raise_error(Mongo::Auth::InvalidConfiguration, /empty username is not supported/)
351
+ end.to raise_error(Mongo::Auth::InvalidConfiguration, /Empty username is not supported/)
352
352
  end
353
353
  end
354
354
  end
@@ -365,9 +365,9 @@ describe 'Client options' do
365
365
  let(:client_opts) { { user: '', password: '' } }
366
366
 
367
367
  it 'raises an exception' do
368
- expect {
368
+ expect do
369
369
  client
370
- }.to raise_error(Mongo::Auth::InvalidConfiguration, /empty username is not supported/)
370
+ end.to raise_error(Mongo::Auth::InvalidConfiguration, /Empty username is not supported/)
371
371
  end
372
372
  end
373
373
  end
@@ -36,7 +36,7 @@ describe 'Client construction' do
36
36
 
37
37
  it 'creates connection pool and keeps it populated' do
38
38
  client = ClientRegistry.instance.new_local_client([SpecConfig.instance.addresses.first],
39
- base_options.merge(min_pool_size: 1))
39
+ base_options.merge(min_pool_size: 1, max_pool_size: 1))
40
40
  # allow connection pool to populate
41
41
  sleep 0.1
42
42
 
@@ -133,4 +133,103 @@ describe 'Client construction' do
133
133
  expect(client.cluster.topology).not_to be_a(Mongo::Cluster::Topology::Unknown)
134
134
  end
135
135
  end
136
+
137
+ context 'with auto encryption options'do
138
+ require_libmongocrypt
139
+ require_enterprise
140
+ min_server_fcv '4.2'
141
+
142
+ # Diagnostics of leaked background threads only, these tests do not
143
+ # actually require a clean slate. https://jira.mongodb.org/browse/RUBY-2138
144
+ clean_slate
145
+
146
+ include_context 'define shared FLE helpers'
147
+ include_context 'with local kms_providers'
148
+
149
+ let(:options) { { auto_encryption_options: auto_encryption_options } }
150
+
151
+ let(:auto_encryption_options) do
152
+ {
153
+ key_vault_client: key_vault_client,
154
+ key_vault_namespace: key_vault_namespace,
155
+ kms_providers: kms_providers,
156
+ # Spawn mongocryptd on non-default port for sharded cluster tests
157
+ extra_options: extra_options,
158
+ }
159
+ end
160
+
161
+ let(:client) do
162
+ ClientRegistry.instance.new_local_client([SpecConfig.instance.addresses.first], options)
163
+ end
164
+
165
+ context 'with AWS kms providers with empty string credentials' do
166
+ let(:auto_encryption_options) do
167
+ {
168
+ key_vault_namespace: key_vault_namespace,
169
+ kms_providers: {
170
+ aws: {
171
+ access_key_id: '',
172
+ secret_access_key: '',
173
+ }
174
+ },
175
+ # Spawn mongocryptd on non-default port for sharded cluster tests
176
+ extra_options: extra_options,
177
+ }
178
+ end
179
+
180
+ it 'raises an exception' do
181
+ expect do
182
+ client
183
+ end.to raise_error(ArgumentError, /The aws access_key_id option must be a String with at least one character; it is currently an empty string/)
184
+ end
185
+ end
186
+
187
+ context 'with default key vault client' do
188
+ let(:key_vault_client) { nil }
189
+
190
+ it 'creates a working key vault client' do
191
+ key_vault_client = client.encrypter.key_vault_client
192
+
193
+ result = key_vault_client[:test].insert_one(test: 1)
194
+ expect(result).to be_ok
195
+ end
196
+
197
+ it 'creates a key vault client with the same cluster as the existing client' do
198
+ key_vault_client = client.encrypter.key_vault_client
199
+ expect(key_vault_client.cluster).to eq(client.cluster)
200
+ end
201
+ end
202
+ end
203
+
204
+ context 'when seed addresses are repeated in host list' do
205
+ require_topology :single
206
+
207
+ let(:primary_address) do
208
+ ClusterConfig.instance.primary_address_host
209
+ end
210
+
211
+ let(:client) do
212
+ new_local_client([primary_address, primary_address], SpecConfig.instance.test_options)
213
+ end
214
+
215
+ it 'deduplicates the addresses' do
216
+ expect(client.cluster.addresses).to eq([Mongo::Address.new(primary_address)])
217
+ end
218
+ end
219
+
220
+ context 'when seed addresses are repeated in URI' do
221
+ require_topology :single
222
+
223
+ let(:primary_address) do
224
+ ClusterConfig.instance.primary_address_host
225
+ end
226
+
227
+ let(:client) do
228
+ new_local_client("mongodb://#{primary_address},#{primary_address}", SpecConfig.instance.test_options)
229
+ end
230
+
231
+ it 'deduplicates the addresses' do
232
+ expect(client.cluster.addresses).to eq([Mongo::Address.new(primary_address)])
233
+ end
234
+ end
136
235
  end
@@ -0,0 +1,353 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Bulk writes with auto-encryption enabled' do
4
+ require_libmongocrypt
5
+ require_enterprise
6
+ min_server_fcv '4.2'
7
+
8
+ include_context 'define shared FLE helpers'
9
+ include_context 'with local kms_providers'
10
+
11
+ let(:subscriber) { EventSubscriber.new }
12
+
13
+ let(:client) do
14
+ new_local_client(
15
+ SpecConfig.instance.addresses,
16
+ SpecConfig.instance.test_options.merge(
17
+ auto_encryption_options: {
18
+ kms_providers: kms_providers,
19
+ key_vault_namespace: key_vault_namespace,
20
+ schema_map: { "auto_encryption.users" => schema_map },
21
+ # Spawn mongocryptd on non-default port for sharded cluster tests
22
+ extra_options: extra_options,
23
+ },
24
+ database: 'auto_encryption'
25
+ ),
26
+ ).tap do |client|
27
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
28
+ end
29
+ end
30
+
31
+ let(:size_limit) { Mongo::Server::ConnectionBase::REDUCED_MAX_BSON_SIZE }
32
+
33
+ before do
34
+ authorized_client.use('auto_encryption')['users'].drop
35
+
36
+ key_vault_collection.drop
37
+ key_vault_collection.insert_one(data_key)
38
+ end
39
+
40
+ let(:command_succeeded_events) do
41
+ subscriber.succeeded_events.select do |event|
42
+ event.command_name == command_name
43
+ end
44
+ end
45
+
46
+ shared_examples 'a functioning encrypted bulk write' do |options={}|
47
+ num_writes = options[:num_writes]
48
+
49
+ before do
50
+ perform_bulk_write
51
+ end
52
+
53
+ it 'executes an encrypted bulk write' do
54
+ documents = authorized_client.use('auto_encryption')['users'].find
55
+ ssns = documents.map { |doc| doc['ssn'] }
56
+ expect(ssns).to all(be_ciphertext)
57
+ end
58
+
59
+ it 'executes the correct number of writes' do
60
+ expect(command_succeeded_events.length).to eq(num_writes)
61
+ end
62
+ end
63
+
64
+ context 'using BulkWrite' do
65
+ let(:collection) { client['users'] }
66
+ let(:bulk_write) { Mongo::BulkWrite.new(collection, requests, {}) }
67
+ let(:perform_bulk_write) { bulk_write.execute }
68
+
69
+ context 'with insert operations' do
70
+ let(:command_name) { 'insert' }
71
+
72
+ context 'when total request size does not exceed 2MiB' do
73
+ let(:requests) do
74
+ [
75
+ { insert_one: { ssn: 'a' * (size_limit/2) } },
76
+ { insert_one: { ssn: 'a' * (size_limit/2) } }
77
+ ]
78
+ end
79
+
80
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 1
81
+ end
82
+
83
+ context 'when each operation is smaller than 2MiB, but the total request size is greater than 2MiB' do
84
+ let(:requests) do
85
+ [
86
+ { insert_one: { ssn: 'a' * (size_limit - 2000) } },
87
+ { insert_one: { ssn: 'a' * (size_limit - 2000) } }
88
+ ]
89
+ end
90
+
91
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 2
92
+ end
93
+
94
+ context 'when each operation is larger than 2MiB' do
95
+ let(:requests) do
96
+ [
97
+ { insert_one: { ssn: 'a' * (size_limit * 2) } },
98
+ { insert_one: { ssn: 'a' * (size_limit * 2) } }
99
+ ]
100
+ end
101
+
102
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 2
103
+ end
104
+
105
+ context 'when one operation is larger than 16MiB' do
106
+ let(:requests) do
107
+ [
108
+ { insert_one: { ssn: 'a' * (Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE + 1000) } },
109
+ { insert_one: { ssn: 'a' * size_limit } }
110
+ ]
111
+ end
112
+
113
+ it 'raises an exception' do
114
+ expect do
115
+ bulk_write.execute
116
+ end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
117
+ end
118
+ end
119
+ end
120
+
121
+ context 'with update operations' do
122
+ let(:command_name) { 'update' }
123
+
124
+ before do
125
+ client['users'].insert_one(_id: 1)
126
+ client['users'].insert_one(_id: 2)
127
+ end
128
+
129
+ context 'when total request size does not exceed 2MiB' do
130
+ let(:requests) do
131
+ [
132
+ { update_one: { filter: { _id: 1 }, update: { ssn: 'a' * (size_limit/2) } } },
133
+ { update_one: { filter: { _id: 2 }, update: { ssn: 'a' * (size_limit/2) } } },
134
+ ]
135
+ end
136
+
137
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 1
138
+ end
139
+
140
+ context 'when each operation is smaller than 2MiB, but the total request size is greater than 2MiB' do
141
+ let(:requests) do
142
+ [
143
+ { update_one: { filter: { _id: 1 }, update: { ssn: 'a' * (size_limit - 2000) } } },
144
+ { update_one: { filter: { _id: 2 }, update: { ssn: 'a' * (size_limit - 2000) } } },
145
+ ]
146
+ end
147
+
148
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 2
149
+ end
150
+
151
+ context 'when each operation is larger than 2MiB' do
152
+ let(:requests) do
153
+ [
154
+ { update_one: { filter: { _id: 1 }, update: { ssn: 'a' * (size_limit * 2) } } },
155
+ { update_one: { filter: { _id: 2 }, update: { ssn: 'a' * (size_limit * 2) } } },
156
+ ]
157
+ end
158
+
159
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 2
160
+ end
161
+
162
+ context 'when one operation is larger than 16MiB' do
163
+ let(:requests) do
164
+ [
165
+ { update_one: { filter: { _id: 1 }, update: { ssn: 'a' * (Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE - 100) } } },
166
+ { update_one: { filter: { _id: 2 }, update: { ssn: 'a' * size_limit } } },
167
+ ]
168
+ end
169
+
170
+ it 'raises an exception' do
171
+ expect do
172
+ bulk_write.execute
173
+ end.to raise_error(Mongo::Error::MaxBSONSize, /maximum allowed size: 16777216 bytes/)
174
+ end
175
+ end
176
+ end
177
+
178
+ context 'with delete operations' do
179
+ let(:command_name) { 'delete' }
180
+
181
+ context 'when total request size does not exceed 2MiB' do
182
+ before do
183
+ client['users'].insert_one(ssn: 'a' * (size_limit/2))
184
+ client['users'].insert_one(ssn: 'b' * (size_limit/2))
185
+ end
186
+
187
+ let(:requests) do
188
+ [
189
+ { delete_one: { filter: { ssn: 'a' * (size_limit/2) } } },
190
+ { delete_one: { filter: { ssn: 'b' * (size_limit/2) } } }
191
+ ]
192
+ end
193
+
194
+ it 'performs one delete' do
195
+ bulk_write.execute
196
+
197
+ documents = authorized_client.use('auto_encryption')['users'].find.to_a
198
+ expect(documents.length).to eq(0)
199
+ expect(command_succeeded_events.length).to eq(1)
200
+ end
201
+ end
202
+
203
+ context 'when each operation is smaller than 2MiB, but the total request size is greater than 2MiB' do
204
+ before do
205
+ client['users'].insert_one(ssn: 'a' * (size_limit - 2000))
206
+ client['users'].insert_one(ssn: 'b' * (size_limit - 2000))
207
+ end
208
+
209
+ let(:requests) do
210
+ [
211
+ { delete_one: { filter: { ssn: 'a' * (size_limit - 2000) } } },
212
+ { delete_one: { filter: { ssn: 'b' * (size_limit - 2000) } } }
213
+ ]
214
+ end
215
+
216
+ it 'performs two deletes' do
217
+ bulk_write.execute
218
+
219
+ documents = authorized_client.use('auto_encryption')['users'].find.to_a
220
+ expect(documents.length).to eq(0)
221
+ expect(command_succeeded_events.length).to eq(2)
222
+ end
223
+ end
224
+
225
+ context 'when each operation is larger than 2MiB' do
226
+ before do
227
+ client['users'].insert_one(ssn: 'a' * (size_limit * 2))
228
+ client['users'].insert_one(ssn: 'b' * (size_limit * 2))
229
+ end
230
+
231
+ let(:requests) do
232
+ [
233
+ { delete_one: { filter: { ssn: 'a' * (size_limit * 2) } } },
234
+ { delete_one: { filter: { ssn: 'b' * (size_limit * 2) } } }
235
+ ]
236
+ end
237
+
238
+ it 'performs two deletes' do
239
+ bulk_write.execute
240
+
241
+ documents = authorized_client.use('auto_encryption')['users'].find.to_a
242
+ expect(documents.length).to eq(0)
243
+ expect(command_succeeded_events.length).to eq(2)
244
+ end
245
+ end
246
+
247
+ context 'when one operation is larger than 16MiB' do
248
+ let(:requests) do
249
+ [
250
+ { delete_one: { filter: { ssn: 'a' * (Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE + 1000) } } },
251
+ { delete_one: { filter: { ssn: 'b' * (size_limit * 2) } } }
252
+ ]
253
+ end
254
+
255
+ it 'raises an exception' do
256
+ expect do
257
+ bulk_write.execute
258
+ end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
259
+ end
260
+ end
261
+ end
262
+
263
+ context 'with insert, update, and delete operations' do
264
+ context 'when total request size does not exceed 2MiB' do
265
+ let(:requests) do
266
+ [
267
+ { insert_one: { _id: 1, ssn: 'a' * (size_limit/3) } },
268
+ { update_one: { filter: { _id: 1 }, update: { ssn: 'b' * (size_limit/3) } } },
269
+ { delete_one: { filter: { ssn: 'b' * (size_limit/3) } } }
270
+ ]
271
+ end
272
+
273
+ it 'successfully performs the bulk write' do
274
+ bulk_write.execute
275
+
276
+ documents = authorized_client.use('auto_encryption')['users'].find.to_a
277
+ expect(documents.length).to eq(0)
278
+ end
279
+
280
+ # Bulk writes with different types of operations should
281
+ it 'performs 1 insert, 1 update, and 1 delete' do
282
+ bulk_write.execute
283
+
284
+ command_succeeded_events = subscriber.succeeded_events
285
+
286
+ inserts = command_succeeded_events.select { |event| event.command_name == 'insert' }
287
+ updates = command_succeeded_events.select { |event| event.command_name == 'update' }
288
+ deletes = command_succeeded_events.select { |event| event.command_name == 'delete' }
289
+
290
+ expect(inserts.length).to eq(1)
291
+ expect(updates.length).to eq(1)
292
+ expect(deletes.length).to eq(1)
293
+ end
294
+ end
295
+ end
296
+ end
297
+
298
+ context '#insert_many' do
299
+ let(:perform_bulk_write) do
300
+ client['users'].insert_many(documents)
301
+ end
302
+
303
+ let(:command_name) { 'insert' }
304
+
305
+ context 'when total request size does not exceed 2MiB' do
306
+ let(:documents) do
307
+ [
308
+ { ssn: 'a' * (size_limit/2) },
309
+ { ssn: 'a' * (size_limit/2) },
310
+ ]
311
+ end
312
+
313
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 1
314
+ end
315
+
316
+ context 'when each operation is smaller than 2MiB, but the total request size is greater than 2MiB' do
317
+ let(:documents) do
318
+ [
319
+ { ssn: 'a' * (size_limit - 2000) },
320
+ { ssn: 'a' * (size_limit - 2000) },
321
+ ]
322
+ end
323
+
324
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 2
325
+ end
326
+
327
+ context 'when each operation is larger than 2MiB' do
328
+ let(:documents) do
329
+ [
330
+ { ssn: 'a' * (size_limit * 2) },
331
+ { ssn: 'a' * (size_limit * 2) },
332
+ ]
333
+ end
334
+
335
+ it_behaves_like 'a functioning encrypted bulk write', num_writes: 2
336
+ end
337
+
338
+ context 'when one operation is larger than 16MiB' do
339
+ let(:documents) do
340
+ [
341
+ { ssn: 'a' * (Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE + 1000) },
342
+ { ssn: 'a' * size_limit },
343
+ ]
344
+ end
345
+
346
+ it 'raises an exception' do
347
+ expect do
348
+ perform_bulk_write
349
+ end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
350
+ end
351
+ end
352
+ end
353
+ end