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
@@ -21,7 +21,7 @@ module Mongo
21
21
  class Populator
22
22
  include BackgroundThread
23
23
 
24
- # @param [ Server::ConnectionPool ] The connection pool.
24
+ # @param [ Server::ConnectionPool ] pool The connection pool.
25
25
  # @param [ Hash ] options The options.
26
26
  #
27
27
  # @option options [ Logger ] :logger A custom logger to use.
@@ -370,8 +370,11 @@ module Mongo
370
370
 
371
371
  # Get the me field value.
372
372
  #
373
- # @example Get the me field value.
374
- # description.me
373
+ # @note The value in me field may differ from the server description's
374
+ # address. This can happen, for example, in split horizon configurations.
375
+ # The SDAM spec only requires removing servers whose me does not match
376
+ # their address in some of the situations (e.g. when the server in
377
+ # question is an RS member but not a primary).
375
378
  #
376
379
  # @return [ String ] The me field.
377
380
  #
@@ -723,7 +726,10 @@ module Mongo
723
726
  def ==(other)
724
727
  return false if self.class != other.class
725
728
  return false if unknown? || other.unknown?
726
- compare_config(other)
729
+
730
+ (config.keys + other.config.keys).uniq.all? do |k|
731
+ config[k] == other.config[k] || EXCLUDE_FOR_COMPARISON.include?(k)
732
+ end
727
733
  end
728
734
  alias_method :eql?, :==
729
735
 
@@ -750,14 +756,6 @@ module Mongo
750
756
 
751
757
  required_wv >= min_wire_version && required_wv <= max_wire_version
752
758
  end
753
-
754
- private
755
-
756
- def compare_config(other)
757
- (config.keys + other.config.keys).uniq.all? do |k|
758
- config[k] == other.config[k] || EXCLUDE_FOR_COMPARISON.include?(k)
759
- end
760
- end
761
759
  end
762
760
  end
763
761
  end
@@ -94,6 +94,8 @@ module Mongo
94
94
 
95
95
  # The compressor is determined during the handshake, so it must be an attribute
96
96
  # of the connection.
97
+ #
98
+ # @deprecated
97
99
  def_delegators :connection, :compressor
98
100
 
99
101
  # @return [ Monitoring ] monitoring The monitoring.
@@ -19,7 +19,7 @@ module Mongo
19
19
  # This class models the monitor connections and their behavior.
20
20
  #
21
21
  # @since 2.0.0
22
- class Connection
22
+ class Connection < Server::ConnectionCommon
23
23
  include Retryable
24
24
  include Connectable
25
25
  include Loggable
@@ -64,12 +64,14 @@ module Mongo
64
64
  # Key for compression algorithms in the response from the server during handshake.
65
65
  #
66
66
  # @since 2.5.0
67
+ # @deprecated
67
68
  COMPRESSION = 'compression'.freeze
68
69
 
69
70
  # Warning message that the server has no compression algorithms in common with those requested
70
71
  # by the client.
71
72
  #
72
73
  # @since 2.5.0
74
+ # @deprecated
73
75
  COMPRESSION_WARNING = 'The server has no compression algorithms in common with those requested. ' +
74
76
  'Compression will not be used.'.freeze
75
77
 
@@ -125,11 +127,6 @@ module Mongo
125
127
  # @return [ Mongo::Address ] address The address to connect to.
126
128
  attr_reader :address
127
129
 
128
- # The compressor, which is determined during the handshake.
129
- #
130
- # @since 2.5.0
131
- attr_reader :compressor
132
-
133
130
  # Send the preserialized ismaster call.
134
131
  #
135
132
  # @example Send a preserialized ismaster message.
@@ -209,18 +206,6 @@ module Mongo
209
206
 
210
207
  private
211
208
 
212
- def set_compressor!(reply)
213
- server_compressors = reply[COMPRESSION]
214
-
215
- if options[:compressors]
216
- if intersection = (server_compressors & options[:compressors])
217
- @compressor = intersection[0]
218
- else
219
- log_warn(COMPRESSION_WARNING)
220
- end
221
- end
222
- end
223
-
224
209
  def handshake!(socket)
225
210
  if @app_metadata
226
211
  socket.write(@app_metadata.ismaster_bytes)
@@ -21,8 +21,9 @@ module Mongo
21
21
  class PendingConnection < ConnectionBase
22
22
  extend Forwardable
23
23
 
24
- def initialize(socket, server, monitoring, options = {})
24
+ def initialize(socket, description, server, monitoring, options = {})
25
25
  @socket = socket
26
+ @description = description
26
27
  @options = options
27
28
  @server = server
28
29
  @monitoring = monitoring
@@ -578,7 +578,7 @@ module Mongo
578
578
  txn_num: txn_num,
579
579
  write_concern: write_concern,
580
580
  }
581
- Operation::Command.new(spec).execute(server)
581
+ Operation::Command.new(spec).execute(server, client: @client)
582
582
  end
583
583
  end
584
584
  ensure
@@ -622,7 +622,7 @@ module Mongo
622
622
  db_name: 'admin',
623
623
  session: self,
624
624
  txn_num: txn_num
625
- ).execute(server)
625
+ ).execute(server, client: @client)
626
626
  end
627
627
  end
628
628
 
@@ -697,7 +697,7 @@ module Mongo
697
697
  # The exception instance should already have all of the labels set on it
698
698
  # (both client- and server-side generated ones).
699
699
  #
700
- # @param [ Error ] The exception instance to process.
700
+ # @param [ Error ] error The exception instance to process.
701
701
  #
702
702
  # @api private
703
703
  def unpin_maybe(error)
@@ -113,9 +113,14 @@ module Mongo
113
113
  def end_sessions
114
114
  while !@queue.empty?
115
115
  server = ServerSelector.get(mode: :primary_preferred).select_server(@cluster)
116
- Operation::Command.new(
117
- :selector => {endSessions: @queue.shift(10_000).collect { |s| s.session_id }},
118
- :db_name => Database::ADMIN).execute(server)
116
+ op = Operation::Command.new(
117
+ selector: {
118
+ endSessions: @queue.shift(10_000).map(&:session_id),
119
+ },
120
+ db_name: Database::ADMIN,
121
+ )
122
+ # end_sessions does not take a client as an argument
123
+ op.execute(server, client: nil)
119
124
  end
120
125
  rescue Mongo::Error, Error::AuthError
121
126
  end
@@ -40,6 +40,11 @@ module Mongo
40
40
  # @since 2.0.0
41
41
  TIMEOUT_PACK = 'l_2'.freeze
42
42
 
43
+ # Write data to the socket in chunks of this size.
44
+ #
45
+ # @api private
46
+ WRITE_CHUNK_SIZE = 65536
47
+
43
48
  # @return [ Integer ] family The type of host family.
44
49
  attr_reader :family
45
50
 
@@ -87,7 +92,7 @@ module Mongo
87
92
  #
88
93
  # @since 2.0.0
89
94
  def close
90
- @socket.close rescue true
95
+ @socket.close rescue nil
91
96
  true
92
97
  end
93
98
 
@@ -105,20 +110,6 @@ module Mongo
105
110
  handle_errors { @socket.gets(*args) }
106
111
  end
107
112
 
108
- # Create the new socket for the provided family - ipv4, piv6, or unix.
109
- #
110
- # @example Create a new ipv4 socket.
111
- # Socket.new(Socket::PF_INET)
112
- #
113
- # @param [ Integer ] family The socket domain.
114
- #
115
- # @since 2.0.0
116
- def initialize(family)
117
- @family = family
118
- @socket = ::Socket.new(family, SOCK_STREAM, 0)
119
- set_socket_options(@socket)
120
- end
121
-
122
113
  # Will read all data from the socket for the provided number of bytes.
123
114
  # If no data is returned, an exception will be raised.
124
115
  #
@@ -172,7 +163,29 @@ module Mongo
172
163
  #
173
164
  # @since 2.0.0
174
165
  def write(*args)
175
- handle_errors { @socket.write(*args) }
166
+ handle_errors do
167
+ # This method used to forward arguments to @socket.write in a
168
+ # single call like so:
169
+ #
170
+ # @socket.write(*args)
171
+ #
172
+ # Turns out, when each buffer to be written is large (e.g. 32 MiB),
173
+ # this write call would take an extremely long time (20+ seconds)
174
+ # while using 100% CPU. Splitting the writes into chunks produced
175
+ # massively better performance (0.05 seconds to write the 32 MiB of
176
+ # data on the same hardware). Unfortunately splitting the data,
177
+ # one would assume, results in it being copied, but this seems to be
178
+ # a much more minor issue compared to CPU cost of writing large buffers.
179
+ args.each do |buf|
180
+ buf = buf.to_s
181
+ i = 0
182
+ while i < buf.length
183
+ chunk = buf[i...i+WRITE_CHUNK_SIZE]
184
+ @socket.write(chunk)
185
+ i += WRITE_CHUNK_SIZE
186
+ end
187
+ end
188
+ end
176
189
  end
177
190
 
178
191
  # Tests if this socket has reached EOF. Primarily used for liveness checks.
@@ -46,12 +46,22 @@ module Mongo
46
46
  # @since 2.0.0
47
47
  def connect!
48
48
  Timeout.timeout(options[:connect_timeout], Error::SocketTimeoutError) do
49
- handle_errors { @tcp_socket.connect(::Socket.pack_sockaddr_in(port, host)) }
49
+ handle_errors do
50
+ @tcp_socket.connect(::Socket.pack_sockaddr_in(port, host))
51
+ end
50
52
  @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
51
- @socket.hostname = @host_name
52
- @socket.sync_close = true
53
- handle_errors { @socket.connect }
54
- verify_certificate!(@socket)
53
+ begin
54
+ @socket.hostname = @host_name
55
+ @socket.sync_close = true
56
+ handle_errors do
57
+ @socket.connect
58
+ end
59
+ verify_certificate!(@socket)
60
+ rescue
61
+ @socket.close
62
+ @socket = nil
63
+ raise
64
+ end
55
65
  self
56
66
  end
57
67
  end
@@ -76,9 +86,14 @@ module Mongo
76
86
  @context = create_context(options)
77
87
  @family = family
78
88
  @tcp_socket = ::Socket.new(family, SOCK_STREAM, 0)
79
- @tcp_socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
80
- set_socket_options(@tcp_socket)
81
- connect!
89
+ begin
90
+ @tcp_socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
91
+ set_socket_options(@tcp_socket)
92
+ connect!
93
+ rescue
94
+ @tcp_socket.close
95
+ raise
96
+ end
82
97
  end
83
98
 
84
99
  # Read a single byte from the socket.
@@ -40,7 +40,9 @@ module Mongo
40
40
  def connect!
41
41
  Timeout.timeout(options[:connect_timeout], Error::SocketTimeoutError) do
42
42
  socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
43
- handle_errors { socket.connect(::Socket.pack_sockaddr_in(port, host)) }
43
+ handle_errors do
44
+ socket.connect(::Socket.pack_sockaddr_in(port, host))
45
+ end
44
46
  self
45
47
  end
46
48
  end
@@ -63,8 +65,15 @@ module Mongo
63
65
  # @since 2.0.0
64
66
  def initialize(host, port, timeout, family, options = {})
65
67
  @host, @port, @timeout, @options = host, port, timeout, options
66
- super(family)
67
- connect!
68
+ @family = family
69
+ @socket = ::Socket.new(family, SOCK_STREAM, 0)
70
+ begin
71
+ set_socket_options(@socket)
72
+ connect!
73
+ rescue
74
+ @socket.close
75
+ raise
76
+ end
68
77
  end
69
78
 
70
79
  private
@@ -13,65 +13,94 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Mongo
16
- module SRV
16
+ module Srv
17
17
 
18
- # Polls SRV records for the URI that a cluster was created for and
19
- # updates the list of servers in the cluster when records change.
18
+ # Periodically retrieves SRV records for the cluster's SRV URI, and
19
+ # sets the cluster's server list to the SRV lookup result.
20
+ #
21
+ # If an error is encountered during SRV lookup or an SRV record is invalid
22
+ # or disallowed for security reasons, a warning is logged and monitoring
23
+ # continues.
20
24
  #
21
25
  # @api private
22
26
  class Monitor
23
27
  include Loggable
24
-
25
- MIN_RESCAN_FREQUENCY = 60
28
+ include BackgroundThread
29
+
30
+ MIN_SCAN_INTERVAL = 60
31
+
32
+ DEFAULT_TIMEOUT = 10
33
+
34
+ # Creates the SRV monitor.
35
+ #
36
+ # @param [ Cluster ] cluster The cluster.
37
+ # @param [ Hash ] options The cluster options.
38
+ #
39
+ # @option options [ Float ] :timeout The timeout to use for DNS lookups.
40
+ # @option options [ URI::SRVProtocol ] :srv_uri The SRV URI to monitor.
41
+ # @option options [ Hash ] :resolv_options For internal driver use only.
42
+ # Options to pass through to Resolv::DNS constructor for SRV lookups.
43
+ def initialize(cluster, options = nil)
44
+ options = if options
45
+ options.dup
46
+ else
47
+ {}
48
+ end
49
+ @cluster = cluster
50
+ @resolver = Srv::Resolver.new(options)
51
+ unless @srv_uri = options.delete(:srv_uri)
52
+ raise ArgumentError, 'SRV URI is required'
53
+ end
54
+ @options = options.freeze
55
+ @last_result = @srv_uri.srv_result
56
+ @stop_semaphore = Semaphore.new
57
+ end
26
58
 
27
59
  attr_reader :options
28
60
 
29
- def initialize(cluster, resolver, srv_records, options = nil)
30
- @options = options || {}
31
- @cluster = cluster
32
- @resolver = resolver
33
- @records = srv_records
34
- @no_records_found = false
35
- end
61
+ attr_reader :cluster
36
62
 
37
- def start_monitor!
38
- @thread = Thread.new do
39
- loop do
40
- sleep(rescan_frequency)
41
- scan!
42
- end
43
- end
63
+ # @return [ Srv::Result ] Last known SRV lookup result. Used for
64
+ # determining intervals between SRV lookups, which depend on SRV DNS
65
+ # records' TTL values.
66
+ attr_reader :last_result
44
67
 
68
+ def start!
69
+ super
45
70
  ObjectSpace.define_finalizer(self, self.class.finalize(@thread))
46
71
  end
47
72
 
73
+ private
74
+
75
+ def do_work
76
+ scan!
77
+ @stop_semaphore.wait(scan_interval)
78
+ end
79
+
48
80
  def scan!
49
- @old_hosts = @records.hosts
81
+ old_hosts = last_result.address_strs
50
82
 
51
83
  begin
52
- @records = @resolver.get_records(@records.hostname)
84
+ last_result = Timeout.timeout(timeout) do
85
+ @resolver.get_records(@srv_uri.query_hostname)
86
+ end
53
87
  rescue Resolv::ResolvTimeout => e
54
- log_warn("Timed out trying to resolve hostname #{@records.hostname}")
88
+ log_warn("SRV monitor: timed out trying to resolve hostname #{@srv_uri.query_hostname}: #{e.class}: #{e}")
89
+ return
90
+ rescue ::Timeout::Error
91
+ log_warn("SRV monitor: timed out trying to resolve hostname #{@srv_uri.query_hostname} (timeout=#{timeout})")
55
92
  return
56
93
  rescue Resolv::ResolvError => e
57
- log_warn("Unable to resolve hostname #{@records.hostname}")
94
+ log_warn("SRV monitor: unable to resolve hostname #{@srv_uri.query_hostname}: #{e.class}: #{e}")
58
95
  return
59
96
  end
60
97
 
61
- if @records.empty?
62
- @no_records_found = true
98
+ if last_result.empty?
99
+ log_warn("SRV monitor: hostname #{@srv_uri.query_hostname} resolved to zero records")
63
100
  return
64
101
  end
65
102
 
66
- @no_records_found = false
67
-
68
- (@old_hosts - @records.hosts).each do |host|
69
- @cluster.remove(host)
70
- end
71
-
72
- (@records.hosts - @old_hosts).each do |host|
73
- @cluster.add(host)
74
- end
103
+ @cluster.set_server_list(last_result.address_strs)
75
104
  end
76
105
 
77
106
  def self.finalize(thread)
@@ -80,17 +109,19 @@ module Mongo
80
109
  end
81
110
  end
82
111
 
83
- private
84
-
85
- def rescan_frequency
86
- if @no_records_found
87
- Server:: Monitor::HEARTBEAT_FREQUENCY
88
- elsif @records.min_ttl.nil?
89
- MIN_RESCAN_FREQUENCY
112
+ def scan_interval
113
+ if last_result.empty?
114
+ [cluster.heartbeat_interval, MIN_SCAN_INTERVAL].min
115
+ elsif last_result.min_ttl.nil?
116
+ MIN_SCAN_INTERVAL
90
117
  else
91
- [@records.min_ttl, MIN_RESCAN_FREQUENCY].max
118
+ [last_result.min_ttl, MIN_SCAN_INTERVAL].max
92
119
  end
93
120
  end
121
+
122
+ def timeout
123
+ options[:timeout] || DEFAULT_TIMEOUT
124
+ end
94
125
  end
95
126
  end
96
127
  end