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,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Client-Side Encryption' do
4
+ describe 'Prose tests: Data key and double encryption' do
5
+ require_libmongocrypt
6
+ require_enterprise
7
+ min_server_fcv '4.2'
8
+
9
+ include_context 'define shared FLE helpers'
10
+
11
+ let(:client) do
12
+ new_local_client(
13
+ SpecConfig.instance.addresses,
14
+ SpecConfig.instance.test_options
15
+ )
16
+ end
17
+
18
+ let(:client_encrypted) do
19
+ new_local_client(
20
+ SpecConfig.instance.addresses,
21
+ SpecConfig.instance.test_options.merge(
22
+ auto_encryption_options: {
23
+ kms_providers: local_kms_providers,
24
+ key_vault_namespace: 'admin.datakeys',
25
+ # Spawn mongocryptd on non-default port for sharded cluster tests
26
+ extra_options: extra_options,
27
+ },
28
+ database: 'db',
29
+ )
30
+ )
31
+ end
32
+
33
+ before do
34
+ client.use('db')['view'].drop
35
+ client.use('db').database.command(create: 'view', viewOn: 'coll')
36
+ end
37
+
38
+ it 'does not perform encryption on views' do
39
+ expect do
40
+ client_encrypted['view'].insert_one({})
41
+ end.to raise_error(Mongo::Error::CryptError, /cannot auto encrypt a view/)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Client do
4
+ clean_slate
5
+
6
+ context 'auto encryption options' do
7
+ require_libmongocrypt
8
+ min_server_fcv '4.2'
9
+ require_enterprise
10
+
11
+ include_context 'define shared FLE helpers'
12
+ include_context 'with local kms_providers'
13
+
14
+ before do
15
+ authorized_client.use(:admin)[:datakeys].drop
16
+ authorized_client.use(:admin)[:datakeys].insert_one(data_key)
17
+ authorized_client.use(:auto_encryption)[:users].drop
18
+ authorized_client.use(:auto_encryption)[:users,
19
+ {
20
+ 'validator' => { '$jsonSchema' => schema_map }
21
+ }
22
+ ].create
23
+ end
24
+
25
+ describe '#with' do
26
+ let(:old_client) do
27
+ new_local_client(
28
+ SpecConfig.instance.addresses,
29
+ SpecConfig.instance.test_options.merge(
30
+ auto_encryption_options: {
31
+ kms_providers: kms_providers,
32
+ key_vault_namespace: key_vault_namespace,
33
+ # Spawn mongocryptd on non-default port for sharded cluster tests
34
+ extra_options: extra_options,
35
+ },
36
+ database: :auto_encryption
37
+ ),
38
+ )
39
+ end
40
+
41
+ context 'with new, invalid auto_encryption_options' do
42
+ let(:new_auto_encryption_options) { { kms_providers: nil } }
43
+
44
+ let(:new_client) do
45
+ old_client.with(auto_encryption_options: new_auto_encryption_options)
46
+ end
47
+
48
+ # Detection of leaked background threads only, these tests do not
49
+ # actually require a clean slate. https://jira.mongodb.org/browse/RUBY-2138
50
+ clean_slate
51
+
52
+ it 'raises an exception' do
53
+ expect do
54
+ new_client
55
+ end.to raise_error(ArgumentError)
56
+ end
57
+
58
+ it 'allows the original client to keep encrypting' do
59
+ old_client[:users].insert_one(ssn: ssn)
60
+ document = authorized_client.use(:auto_encryption)[:users].find.first
61
+ expect(document['ssn']).to be_ciphertext
62
+ end
63
+ end
64
+
65
+ context 'with new auto_encryption_options' do
66
+ let!(:new_client) do
67
+ old_client.with(auto_encryption_options: new_auto_encryption_options)
68
+ end
69
+
70
+ let(:new_auto_encryption_options) do
71
+ {
72
+ kms_providers: kms_providers,
73
+ key_vault_namespace: key_vault_namespace,
74
+ schema_map: { 'auto_encryption.users' => schema_map },
75
+ # Spawn mongocryptd on non-default port for sharded cluster tests
76
+ extra_options: extra_options,
77
+ }
78
+ end
79
+
80
+ it 'creates a new client' do
81
+ expect(new_client).not_to eq(old_client)
82
+ end
83
+
84
+ it 'maintains the old client\'s auto encryption options' do
85
+ expect(old_client.encrypter.options[:schema_map]).to be_nil
86
+ end
87
+
88
+ it 'updates the client\'s auto encryption options' do
89
+ expect(new_client.encrypter.options[:schema_map]).to eq('auto_encryption.users' => schema_map)
90
+ end
91
+
92
+ it 'shares a cluster with the old client' do
93
+ expect(old_client.cluster).to eq(new_client.cluster)
94
+ end
95
+
96
+ it 'allows the original client to keep encrypting' do
97
+ old_client[:users].insert_one(ssn: ssn)
98
+ document = authorized_client.use(:auto_encryption)[:users].find.first
99
+ expect(document['ssn']).to be_ciphertext
100
+ end
101
+
102
+ it 'allows the new client to keep encrypting' do
103
+ old_client[:users].insert_one(ssn: ssn)
104
+ document = authorized_client.use(:auto_encryption)[:users].find.first
105
+ expect(document['ssn']).to be_ciphertext
106
+ end
107
+ end
108
+
109
+ context 'with nil auto_encryption_options' do
110
+ let!(:new_client) do
111
+ old_client.with(auto_encryption_options: new_auto_encryption_options)
112
+ end
113
+
114
+ let(:new_auto_encryption_options) { nil }
115
+
116
+ it 'removes auto encryption options' do
117
+ expect(new_client.encrypter).to be_nil
118
+ end
119
+
120
+ it 'allows original client to keep encrypting' do
121
+ old_client[:users].insert_one(ssn: ssn)
122
+ document = authorized_client.use(:auto_encryption)[:users].find.first
123
+ expect(document['ssn']).to be_ciphertext
124
+ end
125
+ end
126
+ end
127
+
128
+ describe '#use' do
129
+ let(:old_client) do
130
+ new_local_client(
131
+ SpecConfig.instance.addresses,
132
+ SpecConfig.instance.test_options.merge(
133
+ auto_encryption_options: {
134
+ kms_providers: kms_providers,
135
+ key_vault_namespace: key_vault_namespace,
136
+ # Spawn mongocryptd on non-default port for sharded cluster tests
137
+ extra_options: extra_options,
138
+ }
139
+ )
140
+ )
141
+ end
142
+
143
+ let(:new_client) do
144
+ old_client.use(:auto_encryption)
145
+ end
146
+
147
+ it 'creates a new client with encryption enabled' do
148
+ new_client[:users].insert_one(ssn: ssn)
149
+ document = authorized_client.use(:auto_encryption)[:users].find.first
150
+ expect(document['ssn']).to be_ciphertext
151
+ end
152
+ end
153
+ end
154
+ end
@@ -21,6 +21,7 @@ describe 'Command monitoring' do
21
21
  started_event = started_events.first
22
22
  expect(started_event.command_name).to eql('ismaster')
23
23
  expect(started_event.address).to be_a(Mongo::Address)
24
+ expect(started_event.command).to have_key('$db')
24
25
 
25
26
  succeeded_events = subscriber.succeeded_events.select do |event|
26
27
  event.command_name == 'ismaster'
@@ -30,6 +31,7 @@ describe 'Command monitoring' do
30
31
  expect(succeeded_event.command_name).to eql('ismaster')
31
32
  expect(succeeded_event.reply).to be_a(BSON::Document)
32
33
  expect(succeeded_event.reply['ismaster']).to eql(true)
34
+ expect(succeeded_event.reply['ok']).to eq(1)
33
35
  expect(succeeded_event.address).to be_a(Mongo::Address)
34
36
  expect(succeeded_event.duration).to be_a(Float)
35
37
 
@@ -109,7 +111,7 @@ describe 'Command monitoring' do
109
111
 
110
112
  subscriber.clear_events!
111
113
  expect do
112
- command.execute(server)
114
+ command.execute(server, client: nil)
113
115
  end.to raise_error(Mongo::Error::OperationFailure, /Not enough data-bearing nodes \(100\)/)
114
116
 
115
117
  expect(subscriber.started_events.length).to eq(1)
@@ -47,7 +47,10 @@ describe 'Command' do
47
47
 
48
48
  let(:expected_payload) do
49
49
  {
50
- 'command' => {'commitTransaction' => 1},
50
+ 'command' => {
51
+ 'commitTransaction' => 1,
52
+ '$db' => 'admin',
53
+ },
51
54
  'command_name' => 'commitTransaction',
52
55
  'database_name' => 'admin',
53
56
  'request_id' => 42,
@@ -75,6 +78,7 @@ describe 'Command' do
75
78
  'commitTransaction' => 1,
76
79
  'lsid' => session.session_id,
77
80
  'txnNumber' => BSON::Int64.new(123),
81
+ '$db' => 'admin',
78
82
  },
79
83
  'command_name' => 'commitTransaction',
80
84
  'database_name' => 'admin',
@@ -93,6 +97,7 @@ describe 'Command' do
93
97
  let(:expected_payload) do
94
98
  {
95
99
  'command' => {
100
+ '$db' => 'admin',
96
101
  'commitTransaction' => 1,
97
102
  'writeConcern' => {'w' => 'majority'},
98
103
  },
@@ -121,17 +126,46 @@ describe 'Command' do
121
126
  )
122
127
  end
123
128
 
124
- let(:expected_payload) do
125
- {
126
- 'command' => {'find' => 'collection_name'},
127
- 'command_name' => 'find',
128
- 'database_name' => 'foo',
129
- 'request_id' => 42,
130
- }
129
+ context 'OP_MSG-capable servers' do
130
+ min_server_fcv '3.6'
131
+
132
+ let(:expected_payload) do
133
+ {
134
+ 'command' => {
135
+ '$db' => 'foo',
136
+ 'find' => 'collection_name',
137
+ },
138
+ 'command_name' => 'find',
139
+ 'database_name' => 'foo',
140
+ 'request_id' => 42,
141
+ }
142
+ end
143
+
144
+ it 'returns expected payload' do
145
+ expect(payload).to eq(expected_payload)
146
+ end
131
147
  end
132
148
 
133
- it 'returns expected payload' do
134
- expect(payload).to eq(expected_payload)
149
+ # Servers using legacy wire protocol message do not have $db in payload.
150
+ # $db is added to the payload later when the command monitoring event is
151
+ # published.
152
+ context 'pre-OP_MSG servers' do
153
+ max_server_version '3.4'
154
+
155
+ let(:expected_payload) do
156
+ {
157
+ 'command' => {
158
+ 'find' => 'collection_name',
159
+ },
160
+ 'command_name' => 'find',
161
+ 'database_name' => 'foo',
162
+ 'request_id' => 42,
163
+ }
164
+ end
165
+
166
+ it 'returns expected payload' do
167
+ expect(payload).to eq(expected_payload)
168
+ end
135
169
  end
136
170
  end
137
171
 
@@ -168,6 +168,63 @@ describe 'Connections' do
168
168
  it_behaves_like 'is 1 per connection'
169
169
  end
170
170
  end
171
+
172
+ context 'when socket connection fails' do
173
+
174
+ before do
175
+ server
176
+ end
177
+
178
+ let(:socket_cls) { ::Socket }
179
+
180
+ let(:socket) do
181
+ double('socket').tap do |socket|
182
+ allow(socket).to receive(:setsockopt)
183
+ allow(socket).to receive(:set_encoding)
184
+ allow(socket).to receive(:getsockopt)
185
+ expect(socket).to receive(:connect).and_raise(IOError, 'test error')
186
+
187
+ # This test is testing for the close call:
188
+ expect(socket).to receive(:close)
189
+ end
190
+ end
191
+
192
+ it 'closes the socket' do
193
+ RSpec::Mocks.with_temporary_scope do
194
+ expect(::Socket).to receive(:new).with(
195
+ Socket::AF_INET, Socket::SOCK_STREAM, 0).and_return(socket)
196
+
197
+ lambda do
198
+ connection.connect!
199
+ end.should raise_error(Mongo::Error::SocketError, /test error/)
200
+ end
201
+ end
202
+
203
+ context 'with tls' do
204
+ require_tls
205
+
206
+ let(:socket) do
207
+ double('socket').tap do |socket|
208
+ allow(socket).to receive(:hostname=)
209
+ allow(socket).to receive(:sync_close=)
210
+ expect(socket).to receive(:connect).and_raise(IOError, 'test error')
211
+
212
+ # This test is testing for the close call:
213
+ expect(socket).to receive(:close)
214
+ end
215
+ end
216
+
217
+ it 'closes the SSL socket' do
218
+ RSpec::Mocks.with_temporary_scope do
219
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).and_return(socket)
220
+
221
+ lambda do
222
+ connection.connect!
223
+ end.should raise_error(Mongo::Error::SocketError, /test error/)
224
+ end
225
+ end
226
+ end
227
+ end
171
228
  end
172
229
 
173
230
  describe 'wire protocol version range update' do
@@ -7,6 +7,95 @@ describe 'CRUD operations' do
7
7
  collection.delete_many
8
8
  end
9
9
 
10
+ describe 'insert' do
11
+ context 'inserting a BSON::Int64' do
12
+ before do
13
+ collection.insert_one(int64: BSON::Int64.new(42))
14
+ end
15
+
16
+ it 'is stored as the correct type' do
17
+ # 18 is the number that represents the Int64 type for the $type
18
+ # operator; string aliases in the $type operator are only supported on
19
+ # server versions 3.2 and newer.
20
+ result = collection.find(int64: { '$type' => 18 }).first
21
+ expect(result).not_to be_nil
22
+ expect(result['int64']).to eq(42)
23
+ end
24
+ end
25
+
26
+ context 'inserting a BSON::Int32' do
27
+ before do
28
+ collection.insert_one(int32: BSON::Int32.new(42))
29
+ end
30
+
31
+ it 'is stored as the correct type' do
32
+ # 16 is the number that represents the Int32 type for the $type
33
+ # operator; string aliases in the $type operator are only supported on
34
+ # server versions 3.2 and newer.
35
+ result = collection.find(int32: { '$type' => 16 }).first
36
+ expect(result).not_to be_nil
37
+ expect(result['int32']).to eq(42)
38
+ end
39
+ end
40
+
41
+ context 'with automatic encryption' do
42
+ require_libmongocrypt
43
+ require_enterprise
44
+ min_server_fcv '4.2'
45
+
46
+ include_context 'define shared FLE helpers'
47
+ include_context 'with local kms_providers'
48
+
49
+ let(:encrypted_collection) do
50
+ new_local_client(
51
+ SpecConfig.instance.addresses,
52
+ SpecConfig.instance.test_options.merge(
53
+ auto_encryption_options: {
54
+ kms_providers: kms_providers,
55
+ key_vault_namespace: key_vault_namespace,
56
+ schema_map: { 'auto_encryption.users' => schema_map },
57
+ # Spawn mongocryptd on non-default port for sharded cluster tests
58
+ extra_options: extra_options,
59
+ },
60
+ database: 'auto_encryption'
61
+ )
62
+ )['users']
63
+ end
64
+
65
+ let(:collection) { authorized_client.use('auto_encryption')['users'] }
66
+
67
+ context 'inserting a BSON::Int64' do
68
+ before do
69
+ encrypted_collection.insert_one(ssn: '123-456-7890', int64: BSON::Int64.new(42))
70
+ end
71
+
72
+ it 'is stored as the correct type' do
73
+ # 18 is the number that represents the Int64 type for the $type
74
+ # operator; string aliases in the $type operator are only supported on
75
+ # server versions 3.2 and newer.
76
+ result = collection.find(int64: { '$type' => 18 }).first
77
+ expect(result).not_to be_nil
78
+ expect(result['int64']).to eq(42)
79
+ end
80
+ end
81
+
82
+ context 'inserting a BSON::Int32' do
83
+ before do
84
+ encrypted_collection.insert_one(ssn: '123-456-7890', int32: BSON::Int32.new(42))
85
+ end
86
+
87
+ it 'is stored as the correct type' do
88
+ # 16 is the number that represents the Int32 type for the $type
89
+ # operator; string aliases in the $type operator are only supported on
90
+ # server versions 3.2 and newer.
91
+ result = collection.find(int32: { '$type' => 16 }).first
92
+ expect(result).not_to be_nil
93
+ expect(result['int32']).to eq(42)
94
+ end
95
+ end
96
+ end
97
+ end
98
+
10
99
  describe 'upsert' do
11
100
  context 'with default write concern' do
12
101
  it 'upserts' do