mongo 2.1.0.beta → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +10 -3
  4. data/Rakefile +1 -7
  5. data/lib/mongo/address/ipv4.rb +6 -1
  6. data/lib/mongo/address/unix.rb +2 -2
  7. data/lib/mongo/address.rb +32 -10
  8. data/lib/mongo/auth/cr/conversation.rb +1 -1
  9. data/lib/mongo/auth/ldap/conversation.rb +7 -3
  10. data/lib/mongo/auth/scram/conversation.rb +9 -3
  11. data/lib/mongo/auth/user/view.rb +23 -2
  12. data/lib/mongo/auth/x509/conversation.rb +1 -1
  13. data/lib/mongo/bulk_write/combineable.rb +51 -0
  14. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  15. data/lib/mongo/bulk_write/result.rb +61 -8
  16. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  17. data/lib/mongo/bulk_write/transformable.rb +132 -0
  18. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  19. data/lib/mongo/bulk_write/validatable.rb +62 -0
  20. data/lib/mongo/bulk_write.rb +164 -23
  21. data/lib/mongo/client.rb +75 -18
  22. data/lib/mongo/cluster/topology/replica_set.rb +8 -6
  23. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  24. data/lib/mongo/cluster.rb +85 -5
  25. data/lib/mongo/collection/view/aggregation.rb +19 -45
  26. data/lib/mongo/collection/view/builder/aggregation.rb +98 -0
  27. data/lib/mongo/collection/view/builder/find_command.rb +111 -0
  28. data/lib/mongo/collection/view/builder/flags.rb +62 -0
  29. data/lib/mongo/collection/view/builder/map_reduce.rb +134 -0
  30. data/lib/mongo/collection/view/builder/modifiers.rb +80 -0
  31. data/lib/mongo/collection/view/builder/op_query.rb +83 -0
  32. data/lib/mongo/collection/view/builder.rb +20 -0
  33. data/lib/mongo/collection/view/explainable.rb +15 -0
  34. data/lib/mongo/collection/view/immutable.rb +4 -11
  35. data/lib/mongo/collection/view/iterable.rb +40 -5
  36. data/lib/mongo/collection/view/map_reduce.rb +67 -37
  37. data/lib/mongo/collection/view/readable.rb +114 -100
  38. data/lib/mongo/collection/view/writable.rb +46 -22
  39. data/lib/mongo/collection/view.rb +25 -22
  40. data/lib/mongo/collection.rb +130 -12
  41. data/lib/mongo/cursor/builder/get_more_command.rb +71 -0
  42. data/lib/mongo/cursor/builder/kill_cursors_command.rb +62 -0
  43. data/lib/mongo/cursor/builder/op_get_more.rb +61 -0
  44. data/lib/mongo/cursor/builder/op_kill_cursors.rb +56 -0
  45. data/lib/mongo/cursor/builder.rb +18 -0
  46. data/lib/mongo/cursor.rb +76 -21
  47. data/lib/mongo/database/view.rb +11 -6
  48. data/lib/mongo/database.rb +16 -6
  49. data/lib/mongo/dbref.rb +9 -9
  50. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → error/closed_stream.rb} +12 -21
  51. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → error/extra_file_chunk.rb} +13 -27
  52. data/lib/mongo/error/file_not_found.rb +37 -0
  53. data/lib/mongo/error/invalid_file.rb +2 -2
  54. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  55. data/lib/mongo/error/invalid_uri.rb +5 -4
  56. data/lib/mongo/error/invalid_write_concern.rb +35 -0
  57. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  58. data/lib/mongo/error/operation_failure.rb +33 -2
  59. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  60. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  61. data/lib/mongo/error.rb +8 -0
  62. data/lib/mongo/grid/file/chunk.rb +9 -9
  63. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  64. data/lib/mongo/grid/file.rb +12 -9
  65. data/lib/mongo/grid/fs_bucket.rb +448 -0
  66. data/lib/mongo/grid/stream/read.rb +208 -0
  67. data/lib/mongo/grid/stream/write.rb +187 -0
  68. data/lib/mongo/grid/stream.rb +64 -0
  69. data/lib/mongo/grid.rb +2 -1
  70. data/lib/mongo/index/view.rb +7 -4
  71. data/lib/mongo/index.rb +5 -0
  72. data/lib/mongo/loggable.rb +34 -57
  73. data/lib/mongo/logger.rb +16 -78
  74. data/lib/mongo/monitoring/command_log_subscriber.rb +38 -14
  75. data/lib/mongo/monitoring/event/command_started.rb +2 -1
  76. data/lib/mongo/monitoring/event/command_succeeded.rb +24 -2
  77. data/lib/mongo/monitoring/event/secure.rb +58 -0
  78. data/lib/mongo/monitoring/event.rb +1 -0
  79. data/lib/mongo/monitoring/publishable.rb +22 -12
  80. data/lib/mongo/monitoring.rb +1 -5
  81. data/lib/mongo/operation/commands/aggregate/result.rb +89 -0
  82. data/lib/mongo/operation/commands/aggregate.rb +64 -0
  83. data/lib/mongo/operation/commands/collections_info/result.rb +41 -0
  84. data/lib/mongo/operation/{read → commands}/collections_info.rb +5 -3
  85. data/lib/mongo/operation/commands/command.rb +47 -0
  86. data/lib/mongo/operation/commands/find/result.rb +62 -0
  87. data/lib/mongo/operation/commands/find.rb +27 -0
  88. data/lib/mongo/operation/commands/get_more/result.rb +62 -0
  89. data/lib/mongo/operation/commands/get_more.rb +27 -0
  90. data/lib/mongo/operation/{read → commands}/indexes.rb +9 -6
  91. data/lib/mongo/operation/{list_collections → commands/list_collections}/result.rb +1 -21
  92. data/lib/mongo/operation/{read → commands}/list_collections.rb +4 -32
  93. data/lib/mongo/operation/{list_indexes → commands/list_indexes}/result.rb +1 -21
  94. data/lib/mongo/operation/{read → commands}/list_indexes.rb +3 -33
  95. data/lib/mongo/operation/commands/map_reduce/result.rb +119 -0
  96. data/lib/mongo/operation/commands/map_reduce.rb +49 -0
  97. data/lib/mongo/operation/commands/parallel_scan/result.rb +64 -0
  98. data/lib/mongo/operation/commands/parallel_scan.rb +52 -0
  99. data/lib/mongo/operation/commands/user_query.rb +71 -0
  100. data/lib/mongo/operation/commands/users_info/result.rb +38 -0
  101. data/lib/mongo/operation/commands/users_info.rb +48 -0
  102. data/lib/mongo/operation/commands.rb +26 -0
  103. data/lib/mongo/operation/executable.rb +4 -68
  104. data/lib/mongo/operation/kill_cursors.rb +3 -3
  105. data/lib/mongo/operation/object_id_generator.rb +36 -0
  106. data/lib/mongo/operation/read/get_more.rb +2 -22
  107. data/lib/mongo/operation/read/query/result.rb +40 -0
  108. data/lib/mongo/operation/read/query.rb +4 -21
  109. data/lib/mongo/operation/read.rb +0 -4
  110. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  111. data/lib/mongo/operation/result.rb +43 -1
  112. data/lib/mongo/operation/specifiable.rb +59 -1
  113. data/lib/mongo/operation/write/bulk/bulkable.rb +83 -0
  114. data/lib/mongo/operation/write/bulk/delete/result.rb +67 -0
  115. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  116. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  117. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  118. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  119. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  120. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  121. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  122. data/lib/mongo/operation/write/bulk.rb +6 -3
  123. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  124. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  125. data/lib/mongo/operation/write/command/delete.rb +3 -3
  126. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  127. data/lib/mongo/operation/write/command/insert.rb +4 -3
  128. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  129. data/lib/mongo/operation/write/command/update.rb +6 -4
  130. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  131. data/lib/mongo/operation/write/command/writable.rb +13 -18
  132. data/lib/mongo/operation/write/create_index.rb +4 -27
  133. data/lib/mongo/operation/write/create_user.rb +4 -30
  134. data/lib/mongo/operation/write/delete.rb +6 -29
  135. data/lib/mongo/operation/write/drop_index.rb +3 -3
  136. data/lib/mongo/operation/write/gle.rb +49 -0
  137. data/lib/mongo/operation/write/idable.rb +24 -2
  138. data/lib/mongo/operation/write/insert.rb +2 -24
  139. data/lib/mongo/operation/write/remove_user.rb +4 -27
  140. data/lib/mongo/operation/write/update.rb +13 -36
  141. data/lib/mongo/operation/write/update_user.rb +4 -30
  142. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  143. data/lib/mongo/operation/write.rb +2 -0
  144. data/lib/mongo/operation.rb +33 -5
  145. data/lib/mongo/options/mapper.rb +26 -2
  146. data/lib/mongo/options/redacted.rb +156 -0
  147. data/lib/mongo/options.rb +1 -0
  148. data/lib/mongo/protocol/bit_vector.rb +11 -9
  149. data/lib/mongo/protocol/delete.rb +78 -3
  150. data/lib/mongo/protocol/get_more.rb +59 -2
  151. data/lib/mongo/protocol/insert.rb +73 -1
  152. data/lib/mongo/protocol/kill_cursors.rb +66 -4
  153. data/lib/mongo/protocol/message.rb +44 -20
  154. data/lib/mongo/protocol/query.rb +153 -65
  155. data/lib/mongo/protocol/reply.rb +92 -1
  156. data/lib/mongo/protocol/serializers.rb +49 -40
  157. data/lib/mongo/protocol/update.rb +93 -1
  158. data/lib/mongo/retryable.rb +101 -0
  159. data/lib/mongo/server/connectable.rb +28 -8
  160. data/lib/mongo/server/connection.rb +52 -10
  161. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  162. data/lib/mongo/server/connection_pool.rb +12 -15
  163. data/lib/mongo/server/description/features.rb +4 -2
  164. data/lib/mongo/server/description.rb +39 -3
  165. data/lib/mongo/server/monitor/connection.rb +49 -28
  166. data/lib/mongo/server/monitor.rb +3 -14
  167. data/lib/mongo/server.rb +31 -4
  168. data/lib/mongo/server_selector/selectable.rb +58 -32
  169. data/lib/mongo/server_selector.rb +19 -10
  170. data/lib/mongo/socket/ssl.rb +4 -1
  171. data/lib/mongo/socket/tcp.rb +2 -2
  172. data/lib/mongo/socket/unix.rb +5 -8
  173. data/lib/mongo/socket.rb +11 -4
  174. data/lib/mongo/uri.rb +245 -139
  175. data/lib/mongo/version.rb +1 -1
  176. data/lib/mongo/write_concern.rb +21 -6
  177. data/lib/mongo.rb +4 -4
  178. data/mongo.gemspec +1 -2
  179. data/spec/mongo/address/unix_spec.rb +1 -1
  180. data/spec/mongo/address_spec.rb +25 -0
  181. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  182. data/spec/mongo/auth/user/view_spec.rb +26 -1
  183. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +284 -0
  184. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  185. data/spec/mongo/bulk_write_spec.rb +385 -161
  186. data/spec/mongo/client_spec.rb +193 -23
  187. data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
  188. data/spec/mongo/collection/view/aggregation_spec.rb +65 -0
  189. data/spec/mongo/collection/view/builder/find_command_spec.rb +167 -0
  190. data/spec/mongo/collection/view/builder/flags_spec.rb +106 -0
  191. data/spec/mongo/collection/view/builder/modifiers_spec.rb +210 -0
  192. data/spec/mongo/collection/view/builder/op_query_spec.rb +154 -0
  193. data/spec/mongo/collection/view/explainable_spec.rb +1 -2
  194. data/spec/mongo/collection/view/immutable_spec.rb +54 -0
  195. data/spec/mongo/collection/view/map_reduce_spec.rb +104 -9
  196. data/spec/mongo/collection/view/readable_spec.rb +109 -112
  197. data/spec/mongo/collection/view_spec.rb +119 -487
  198. data/spec/mongo/collection_spec.rb +1002 -33
  199. data/spec/mongo/command_monitoring_spec.rb +64 -0
  200. data/spec/mongo/connection_string_spec.rb +115 -0
  201. data/spec/mongo/cursor/builder/get_more_command_spec.rb +160 -0
  202. data/spec/mongo/cursor/builder/op_get_more_spec.rb +52 -0
  203. data/spec/mongo/cursor_spec.rb +10 -60
  204. data/spec/mongo/database_spec.rb +81 -12
  205. data/spec/mongo/dbref_spec.rb +4 -4
  206. data/spec/mongo/grid/file/chunk_spec.rb +6 -6
  207. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  208. data/spec/mongo/grid/file_spec.rb +8 -8
  209. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  210. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  211. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  212. data/spec/mongo/grid/stream_spec.rb +48 -0
  213. data/spec/mongo/gridfs_spec.rb +50 -0
  214. data/spec/mongo/index/view_spec.rb +41 -0
  215. data/spec/mongo/logger_spec.rb +0 -40
  216. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  217. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  218. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  219. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  220. data/spec/mongo/operation/{aggregate → commands/aggregate}/result_spec.rb +1 -1
  221. data/spec/mongo/operation/commands/aggregate_spec.rb +69 -0
  222. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  223. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +1 -19
  224. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  225. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +1 -19
  226. data/spec/mongo/operation/kill_cursors_spec.rb +1 -17
  227. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  228. data/spec/mongo/operation/read/query_spec.rb +19 -16
  229. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  230. data/spec/mongo/operation/result_spec.rb +19 -0
  231. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +17 -28
  232. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +1 -12
  233. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +7 -18
  234. data/spec/mongo/operation/write/command/delete_spec.rb +18 -9
  235. data/spec/mongo/operation/write/command/insert_spec.rb +18 -9
  236. data/spec/mongo/operation/write/command/update_spec.rb +18 -9
  237. data/spec/mongo/operation/write/delete_spec.rb +3 -3
  238. data/spec/mongo/operation/write/insert_spec.rb +0 -11
  239. data/spec/mongo/operation/write/update_spec.rb +6 -6
  240. data/spec/mongo/options/redacted_spec.rb +350 -0
  241. data/spec/mongo/protocol/delete_spec.rb +4 -4
  242. data/spec/mongo/protocol/get_more_spec.rb +4 -4
  243. data/spec/mongo/protocol/insert_spec.rb +3 -3
  244. data/spec/mongo/protocol/kill_cursors_spec.rb +8 -6
  245. data/spec/mongo/protocol/query_spec.rb +21 -7
  246. data/spec/mongo/protocol/update_spec.rb +5 -5
  247. data/spec/mongo/retryable_spec.rb +221 -0
  248. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  249. data/spec/mongo/server/connection_pool_spec.rb +42 -6
  250. data/spec/mongo/server/connection_spec.rb +86 -1
  251. data/spec/mongo/server/description/features_spec.rb +25 -0
  252. data/spec/mongo/server/description_spec.rb +42 -0
  253. data/spec/mongo/server/monitor_spec.rb +44 -0
  254. data/spec/mongo/server_discovery_and_monitoring_spec.rb +25 -59
  255. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  256. data/spec/mongo/server_selection_spec.rb +5 -3
  257. data/spec/mongo/server_selector/nearest_spec.rb +35 -27
  258. data/spec/mongo/server_selector/primary_preferred_spec.rb +32 -30
  259. data/spec/mongo/server_selector/primary_spec.rb +21 -14
  260. data/spec/mongo/server_selector/secondary_preferred_spec.rb +28 -26
  261. data/spec/mongo/server_selector/secondary_spec.rb +24 -22
  262. data/spec/mongo/server_selector_spec.rb +87 -24
  263. data/spec/mongo/server_spec.rb +78 -15
  264. data/spec/mongo/socket/ssl_spec.rb +101 -57
  265. data/spec/mongo/socket/unix_spec.rb +52 -0
  266. data/spec/mongo/uri_spec.rb +271 -59
  267. data/spec/mongo/write_concern_spec.rb +126 -0
  268. data/spec/spec_helper.rb +29 -23
  269. data/spec/support/authorization.rb +4 -5
  270. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  271. data/spec/support/command_monitoring/command.yml +42 -0
  272. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  273. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  274. data/spec/support/command_monitoring/find.yml +268 -0
  275. data/spec/support/command_monitoring/insertMany.yml +81 -0
  276. data/spec/support/command_monitoring/insertOne.yml +51 -0
  277. data/spec/support/command_monitoring/updateMany.yml +67 -0
  278. data/spec/support/command_monitoring/updateOne.yml +95 -0
  279. data/spec/support/command_monitoring.rb +373 -0
  280. data/spec/support/connection_string.rb +228 -0
  281. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  282. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  283. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  284. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  285. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  286. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  287. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  288. data/spec/support/crud/read.rb +14 -10
  289. data/spec/support/crud/write.rb +36 -9
  290. data/spec/support/crud.rb +10 -2
  291. data/spec/support/gridfs.rb +637 -0
  292. data/spec/support/gridfs_tests/delete.yml +157 -0
  293. data/spec/support/gridfs_tests/download.yml +210 -0
  294. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  295. data/spec/support/gridfs_tests/upload.yml +158 -0
  296. data/spec/support/matchers.rb +2 -2
  297. data/spec/support/sdam/rs/equal_electionids.yml +1 -2
  298. data/spec/support/sdam/rs/new_primary_new_electionid.yml +0 -3
  299. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  300. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  301. data/spec/support/sdam/rs/rsother_discovered.yml +24 -3
  302. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  303. data/spec/support/sdam/rs/stepdown_change_set_name.yml +59 -0
  304. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  305. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  306. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  307. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  308. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  309. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  310. data/spec/support/server_discovery_and_monitoring.rb +3 -1
  311. data/spec/support/server_selection.rb +3 -1
  312. data/spec/support/shared/bulk_write.rb +192 -0
  313. data/spec/support/shared/protocol.rb +5 -5
  314. data/spec/support/shared/server_selector.rb +78 -13
  315. data/spec/support/travis.rb +1 -1
  316. data.tar.gz.sig +0 -0
  317. metadata +211 -72
  318. metadata.gz.sig +0 -0
  319. data/lib/mongo/bulk_write/bulk_writable.rb +0 -252
  320. data/lib/mongo/bulk_write/deletable.rb +0 -57
  321. data/lib/mongo/bulk_write/insertable.rb +0 -49
  322. data/lib/mongo/bulk_write/replacable.rb +0 -58
  323. data/lib/mongo/bulk_write/updatable.rb +0 -69
  324. data/lib/mongo/grid/fs.rb +0 -146
  325. data/lib/mongo/operation/aggregate/result.rb +0 -103
  326. data/lib/mongo/operation/aggregate.rb +0 -108
  327. data/lib/mongo/operation/command.rb +0 -61
  328. data/lib/mongo/operation/map_reduce/result.rb +0 -122
  329. data/lib/mongo/operation/map_reduce.rb +0 -95
  330. data/lib/mongo/operation/parallel_scan/result.rb +0 -72
  331. data/lib/mongo/operation/parallel_scan.rb +0 -76
  332. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  333. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  334. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  335. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  336. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  337. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -174
  338. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  339. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  340. data/spec/mongo/grid/fs_spec.rb +0 -160
  341. data/spec/mongo/loggable_spec.rb +0 -63
  342. data/spec/mongo/operation/aggregate_spec.rb +0 -127
@@ -0,0 +1,221 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Retryable do
4
+
5
+ let(:klass) do
6
+ Class.new do
7
+ include Mongo::Retryable
8
+
9
+ attr_reader :cluster
10
+ attr_reader :operation
11
+
12
+ def initialize(operation, cluster)
13
+ @operation = operation
14
+ @cluster = cluster
15
+ end
16
+
17
+ def max_read_retries
18
+ cluster.max_read_retries
19
+ end
20
+
21
+ def read_retry_interval
22
+ cluster.read_retry_interval
23
+ end
24
+
25
+ def read
26
+ read_with_retry do
27
+ operation.execute
28
+ end
29
+ end
30
+
31
+ def write
32
+ write_with_retry do
33
+ operation.execute
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ describe '#read_with_retry' do
40
+
41
+ let(:operation) do
42
+ double('operation')
43
+ end
44
+
45
+ let(:cluster) do
46
+ double('cluster')
47
+ end
48
+
49
+ let(:retryable) do
50
+ klass.new(operation, cluster)
51
+ end
52
+
53
+ context 'when no exception occurs' do
54
+
55
+ before do
56
+ expect(operation).to receive(:execute).and_return(true)
57
+ end
58
+
59
+ it 'executes the operation once' do
60
+ expect(retryable.read).to be true
61
+ end
62
+ end
63
+
64
+ context 'when a socket error occurs' do
65
+
66
+ before do
67
+ expect(operation).to receive(:execute).and_raise(Mongo::Error::SocketError).ordered
68
+ expect(cluster).to receive(:scan!).and_return(true).ordered
69
+ expect(operation).to receive(:execute).and_return(true).ordered
70
+ end
71
+
72
+ it 'executes the operation twice' do
73
+ expect(retryable.read).to be true
74
+ end
75
+ end
76
+
77
+ context 'when a socket timeout error occurs' do
78
+
79
+ before do
80
+ expect(operation).to receive(:execute).and_raise(Mongo::Error::SocketTimeoutError).ordered
81
+ expect(cluster).to receive(:scan!).and_return(true).ordered
82
+ expect(operation).to receive(:execute).and_return(true).ordered
83
+ end
84
+
85
+ it 'executes the operation twice' do
86
+ expect(retryable.read).to be true
87
+ end
88
+ end
89
+
90
+ context 'when an operation failure occurs' do
91
+
92
+ context 'when the cluster is not a mongos' do
93
+
94
+ before do
95
+ expect(operation).to receive(:execute).and_raise(Mongo::Error::OperationFailure).ordered
96
+ expect(cluster).to receive(:sharded?).and_return(false)
97
+ end
98
+
99
+ it 'raises an exception' do
100
+ expect {
101
+ retryable.read
102
+ }.to raise_error(Mongo::Error::OperationFailure)
103
+ end
104
+ end
105
+
106
+ context 'when the cluster is a mongos' do
107
+
108
+ context 'when the operation failure is not retryable' do
109
+
110
+ let(:error) do
111
+ Mongo::Error::OperationFailure.new('not authorized')
112
+ end
113
+
114
+ before do
115
+ expect(operation).to receive(:execute).and_raise(error).ordered
116
+ expect(cluster).to receive(:sharded?).and_return(true)
117
+ end
118
+
119
+ it 'raises the exception' do
120
+ expect {
121
+ retryable.read
122
+ }.to raise_error(Mongo::Error::OperationFailure)
123
+ end
124
+ end
125
+
126
+ context 'when the operation failure is retryable' do
127
+
128
+ let(:error) do
129
+ Mongo::Error::OperationFailure.new('no master')
130
+ end
131
+
132
+ context 'when the retry succeeds' do
133
+
134
+ before do
135
+ expect(operation).to receive(:execute).and_raise(error).ordered
136
+ expect(cluster).to receive(:sharded?).and_return(true)
137
+ expect(cluster).to receive(:max_read_retries).and_return(1).ordered
138
+ expect(cluster).to receive(:read_retry_interval).and_return(0.1).ordered
139
+ expect(operation).to receive(:execute).and_return(true).ordered
140
+ end
141
+
142
+ it 'returns the result' do
143
+ expect(retryable.read).to be true
144
+ end
145
+ end
146
+
147
+ context 'when the retry fails once and then succeeds' do
148
+
149
+ before do
150
+ expect(operation).to receive(:execute).and_raise(error).ordered
151
+ expect(cluster).to receive(:sharded?).and_return(true)
152
+ expect(cluster).to receive(:max_read_retries).and_return(2).ordered
153
+ expect(cluster).to receive(:read_retry_interval).and_return(0.1).ordered
154
+ expect(operation).to receive(:execute).and_raise(error).ordered
155
+ expect(cluster).to receive(:sharded?).and_return(true)
156
+ expect(cluster).to receive(:max_read_retries).and_return(2).ordered
157
+ expect(cluster).to receive(:read_retry_interval).and_return(0.1).ordered
158
+ expect(operation).to receive(:execute).and_return(true).ordered
159
+ end
160
+
161
+ it 'returns the result' do
162
+ expect(retryable.read).to be true
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ describe '#write_with_retry' do
171
+
172
+ let(:operation) do
173
+ double('operation')
174
+ end
175
+
176
+ let(:cluster) do
177
+ double('cluster')
178
+ end
179
+
180
+ let(:retryable) do
181
+ klass.new(operation, cluster)
182
+ end
183
+
184
+ context 'when no exception occurs' do
185
+
186
+ before do
187
+ expect(operation).to receive(:execute).and_return(true)
188
+ end
189
+
190
+ it 'executes the operation once' do
191
+ expect(retryable.write).to be true
192
+ end
193
+ end
194
+
195
+ context 'when a not master error occurs' do
196
+
197
+ before do
198
+ expect(operation).to receive(:execute).and_raise(Mongo::Error::OperationFailure.new('not master')).ordered
199
+ expect(cluster).to receive(:scan!).and_return(true).ordered
200
+ expect(operation).to receive(:execute).and_return(true).ordered
201
+ end
202
+
203
+ it 'executes the operation twice' do
204
+ expect(retryable.write).to be true
205
+ end
206
+ end
207
+
208
+ context 'when a normal operation failure occurs' do
209
+
210
+ before do
211
+ expect(operation).to receive(:execute).and_raise(Mongo::Error::OperationFailure).ordered
212
+ end
213
+
214
+ it 'raises an exception' do
215
+ expect {
216
+ retryable.write
217
+ }.to raise_error(Mongo::Error::OperationFailure)
218
+ end
219
+ end
220
+ end
221
+ end
@@ -47,6 +47,22 @@ describe Mongo::Server::ConnectionPool::Queue do
47
47
  end
48
48
  end
49
49
 
50
+ describe '#disconnect!' do
51
+
52
+ let(:connection) do
53
+ double('connection')
54
+ end
55
+
56
+ let(:queue) do
57
+ described_class.new(:max_pool_size => 1) { connection }
58
+ end
59
+
60
+ it 'disconnects all connections in the queue' do
61
+ expect(connection).to receive(:disconnect!)
62
+ queue.disconnect!
63
+ end
64
+ end
65
+
50
66
  describe '#enqueue' do
51
67
 
52
68
  let(:connection) do
@@ -18,16 +18,25 @@ describe Mongo::Server::ConnectionPool do
18
18
  Mongo::Event::Listeners.new
19
19
  end
20
20
 
21
+ let(:cluster) do
22
+ double('cluster')
23
+ end
24
+
21
25
  describe '#checkin' do
22
26
 
23
27
  let(:server) do
24
- Mongo::Server.new(address, double('cluster'), monitoring, listeners, options)
28
+ Mongo::Server.new(address, cluster, monitoring, listeners, options)
25
29
  end
26
30
 
27
31
  let!(:pool) do
28
32
  described_class.get(server)
29
33
  end
30
34
 
35
+ after do
36
+ expect(cluster).to receive(:pool).with(server).and_return(pool)
37
+ server.disconnect!
38
+ end
39
+
31
40
  context 'when a connection is checked out on the thread' do
32
41
 
33
42
  let!(:connection) do
@@ -51,7 +60,7 @@ describe Mongo::Server::ConnectionPool do
51
60
  describe '#checkout' do
52
61
 
53
62
  let(:server) do
54
- Mongo::Server.new(address, double('cluster'), monitoring, listeners, options)
63
+ Mongo::Server.new(address, cluster, monitoring, listeners, options)
55
64
  end
56
65
 
57
66
  let!(:pool) do
@@ -96,31 +105,58 @@ describe Mongo::Server::ConnectionPool do
96
105
  end
97
106
  end
98
107
 
108
+ describe '#disconnect!' do
109
+
110
+ let(:server) do
111
+ Mongo::Server.new(address, cluster, monitoring, listeners, options)
112
+ end
113
+
114
+ let!(:pool) do
115
+ described_class.get(server)
116
+ end
117
+
118
+ it 'disconnects the queue' do
119
+ expect(cluster).to receive(:pool).with(server).and_return(pool)
120
+ expect(pool.send(:queue)).to receive(:disconnect!).once.and_call_original
121
+ server.disconnect!
122
+ end
123
+ end
124
+
99
125
  describe '.get' do
100
126
 
101
127
  let(:server) do
102
- Mongo::Server.new(address, double('cluster'), monitoring, listeners, options)
128
+ Mongo::Server.new(address, cluster, monitoring, listeners, options)
103
129
  end
104
130
 
105
131
  let!(:pool) do
106
132
  described_class.get(server)
107
133
  end
108
134
 
135
+ after do
136
+ expect(cluster).to receive(:pool).with(server).and_return(pool)
137
+ server.disconnect!
138
+ end
139
+
109
140
  it 'returns the pool for the server' do
110
- expect(pool).to eql(described_class.get(server))
141
+ expect(pool).to_not be_nil
111
142
  end
112
143
  end
113
144
 
114
145
  describe '#inspect' do
115
146
 
116
147
  let(:server) do
117
- Mongo::Server.new(address, double('cluster'), monitoring, listeners, options)
148
+ Mongo::Server.new(address, cluster, monitoring, listeners, options)
118
149
  end
119
150
 
120
151
  let!(:pool) do
121
152
  described_class.get(server)
122
153
  end
123
154
 
155
+ after do
156
+ expect(cluster).to receive(:pool).with(server).and_return(pool)
157
+ server.disconnect!
158
+ end
159
+
124
160
  it 'includes the object id' do
125
161
  expect(pool.inspect).to include(pool.object_id.to_s)
126
162
  end
@@ -133,7 +169,7 @@ describe Mongo::Server::ConnectionPool do
133
169
  describe '#with_connection' do
134
170
 
135
171
  let(:server) do
136
- Mongo::Server.new(address, double('cluster'), monitoring, listeners, options)
172
+ Mongo::Server.new(address, cluster, monitoring, listeners, options)
137
173
  end
138
174
 
139
175
  let!(:pool) do
@@ -14,8 +14,44 @@ describe Mongo::Server::Connection do
14
14
  Mongo::Event::Listeners.new
15
15
  end
16
16
 
17
+ let(:cluster) do
18
+ double('cluster')
19
+ end
20
+
17
21
  let(:server) do
18
- Mongo::Server.new(address, double('cluster'), monitoring, listeners, TEST_OPTIONS)
22
+ Mongo::Server.new(address, cluster, monitoring, listeners, TEST_OPTIONS)
23
+ end
24
+
25
+ let(:pool) do
26
+ double('pool')
27
+ end
28
+
29
+ after do
30
+ expect(cluster).to receive(:pool).with(server).and_return(pool)
31
+ expect(pool).to receive(:disconnect!).and_return(true)
32
+ server.disconnect!
33
+ end
34
+
35
+ describe '#connectable?' do
36
+
37
+ context 'when the connection is not connectable' do
38
+
39
+ let(:bad_address) do
40
+ Mongo::Address.new('127.0.0.1:666')
41
+ end
42
+
43
+ let(:bad_server) do
44
+ Mongo::Server.new(bad_address, cluster, monitoring, listeners, TEST_OPTIONS)
45
+ end
46
+
47
+ let(:connection) do
48
+ described_class.new(bad_server)
49
+ end
50
+
51
+ it 'returns false' do
52
+ expect(connection).to_not be_connectable
53
+ end
54
+ end
19
55
  end
20
56
 
21
57
  describe '#connect!' do
@@ -203,6 +239,55 @@ describe Mongo::Server::Connection do
203
239
  end
204
240
  end
205
241
 
242
+ context 'when the message exceeds the max size' do
243
+
244
+ context 'when the message is an insert' do
245
+
246
+ before do
247
+ allow(connection).to receive(:max_message_size).and_return(200)
248
+ end
249
+
250
+ let(:documents) do
251
+ [{ 'name' => 'testing' } ] * 10
252
+ end
253
+
254
+ let(:reply) do
255
+ connection.dispatch([ insert ])
256
+ end
257
+
258
+ it 'checks the size against the max message size' do
259
+ expect {
260
+ reply
261
+ }.to raise_exception(Mongo::Error::MaxMessageSize)
262
+ end
263
+ end
264
+
265
+ context 'when the message is a command' do
266
+
267
+ before do
268
+ allow(connection).to receive(:max_bson_object_size).and_return(100)
269
+ end
270
+
271
+ let(:selector) do
272
+ { :getlasterror => '1' }
273
+ end
274
+
275
+ let(:command) do
276
+ Mongo::Protocol::Query.new(TEST_DB, '$cmd', selector, :limit => -1)
277
+ end
278
+
279
+ let(:reply) do
280
+ connection.dispatch([ command ])
281
+ end
282
+
283
+ it 'checks the size against the max bson size' do
284
+ expect {
285
+ reply
286
+ }.to raise_exception(Mongo::Error::MaxBSONSize)
287
+ end
288
+ end
289
+ end
290
+
206
291
  context 'when a network or socket error occurs' do
207
292
 
208
293
  let(:socket) do
@@ -56,6 +56,31 @@ describe Mongo::Server::Description::Features do
56
56
  end
57
57
  end
58
58
 
59
+ describe '#find_command_enabled?' do
60
+
61
+ context 'when the wire range includes 4' do
62
+
63
+ let(:features) do
64
+ described_class.new(0..4)
65
+ end
66
+
67
+ it 'returns true' do
68
+ expect(features).to be_find_command_enabled
69
+ end
70
+ end
71
+
72
+ context 'when the wire range does not include 4' do
73
+
74
+ let(:features) do
75
+ described_class.new(0..2)
76
+ end
77
+
78
+ it 'returns false' do
79
+ expect(features).to_not be_find_command_enabled
80
+ end
81
+ end
82
+ end
83
+
59
84
  describe '#list_collections_enabled?' do
60
85
 
61
86
  context 'when the wire range includes 3' do
@@ -617,6 +617,48 @@ describe Mongo::Server::Description do
617
617
  end
618
618
  end
619
619
 
620
+ describe '#me_mismatch?' do
621
+
622
+ let(:description) do
623
+ described_class.new(address, config)
624
+ end
625
+
626
+ context 'when the server address matches the me field' do
627
+
628
+ let(:config) do
629
+ replica.merge('me' => address.to_s)
630
+ end
631
+
632
+ it 'returns false' do
633
+ expect(description.me_mismatch?).to be(false)
634
+ end
635
+ end
636
+
637
+ context 'when the server address does not match the me field' do
638
+
639
+ let(:config) do
640
+ replica.merge('me' => 'localhost:27020')
641
+ end
642
+
643
+ it 'returns true' do
644
+ expect(description.me_mismatch?).to be(true)
645
+ end
646
+ end
647
+
648
+ context 'when there is no me field' do
649
+
650
+ let(:config) do
651
+ replica.tap do |r|
652
+ r.delete('me')
653
+ end
654
+ end
655
+
656
+ it 'returns false' do
657
+ expect(description.me_mismatch?).to be(false)
658
+ end
659
+ end
660
+ end
661
+
620
662
  describe '#lists_server?' do
621
663
 
622
664
  let(:description) do
@@ -171,4 +171,48 @@ describe Mongo::Server::Monitor do
171
171
  end
172
172
  end
173
173
  end
174
+
175
+ describe '#stop' do
176
+
177
+ let(:monitor) do
178
+ described_class.new(address, listeners, TEST_OPTIONS)
179
+ end
180
+
181
+ let!(:thread) do
182
+ monitor.run!
183
+ end
184
+
185
+ before do
186
+ expect(monitor.connection).to receive(:disconnect!).and_call_original
187
+ monitor.stop!
188
+ sleep(1)
189
+ end
190
+
191
+ it 'kills the monitor thread' do
192
+ expect(thread.stop?).to be(true)
193
+ end
194
+ end
195
+
196
+ describe '#connection' do
197
+
198
+ context 'when there is a connect_timeout option set' do
199
+
200
+ let(:connect_timeout) do
201
+ 1
202
+ end
203
+
204
+ let(:monitor) do
205
+ described_class.new(address, listeners, TEST_OPTIONS.merge(connect_timeout: connect_timeout))
206
+ end
207
+
208
+ it 'sets the value as the timeout on the connection' do
209
+ expect(monitor.connection.timeout).to eq(connect_timeout)
210
+ end
211
+
212
+ it 'set the value as the timeout on the socket' do
213
+ monitor.connection.connect!
214
+ expect(monitor.connection.send(:socket).timeout).to eq(connect_timeout)
215
+ end
216
+ end
217
+ end
174
218
  end
@@ -11,40 +11,26 @@ describe 'Server Discovery and Monitoring' do
11
11
 
12
12
  before(:all) do
13
13
 
14
- # We monkey-patch the address, so that looking up the spec's hostname does
15
- # not throw an error.
16
- #
17
- # @since 2.0.0
18
- class Mongo::Address
19
- private
20
-
21
- def family(host)
22
- fam = host == 'localhost' ? ::Socket::AF_INET : ::Socket::AF_UNSPEC
23
- ::Socket.getaddrinfo(host, nil, fam, ::Socket::SOCK_STREAM).first[4]
24
- rescue SocketError
25
- end
26
- end
14
+ module Mongo
15
+ # We monkey-patch the server here, so the monitors do not run and no
16
+ # real TCP connection is attempted. Thus we can control the server
17
+ # descriptions per-phase.
18
+ #
19
+ # @since 2.0.0
20
+ class Server
21
+
22
+ alias :original_initialize :initialize
23
+ def initialize(address, cluster, monitoring, event_listeners, options = {})
24
+ @address = address
25
+ @cluster = cluster
26
+ @monitoring = monitoring
27
+ @options = options.freeze
28
+ @monitor = Monitor.new(address, event_listeners, options)
29
+ end
27
30
 
28
- # We monkey-patch the server here, so the monitors do not run and no
29
- # real TCP connection is attempted. Thus we can control the server
30
- # descriptions per-phase.
31
- #
32
- # @since 2.0.0
33
- class Mongo::Server
34
-
35
- # The constructor keeps the same API, but does not instantiate a
36
- # monitor and run it.
37
- def initialize(address, cluster, monitoring, event_listeners, options = {})
38
- @address = address
39
- @cluster = cluster
40
- @monitoring = monitoring
41
- @options = options.freeze
42
- @monitor = Monitor.new(address, event_listeners, options)
31
+ alias :original_disconnect! :disconnect!
32
+ def disconnect!; true; end
43
33
  end
44
-
45
- # Disconnect simply needs to return true since we have no monitor and
46
- # no connection.
47
- def disconnect!; true; end
48
34
  end
49
35
 
50
36
  # Client is set as an instance variable inside the scope of the spec to
@@ -54,37 +40,17 @@ describe 'Server Discovery and Monitoring' do
54
40
  end
55
41
 
56
42
  after(:all) do
43
+ @client.close
57
44
 
58
45
  # Return the server implementation to its original for the other
59
46
  # tests in the suite.
60
- class Mongo::Server
61
-
62
- # Returns the constructor to its original implementation.
63
- def initialize(address, cluster, monitoring, event_listeners, options = {})
64
- @address = address
65
- @cluster = cluster
66
- @monitoring = monitoring
67
- @options = options.freeze
68
- @monitor = Monitor.new(address, event_listeners, options)
69
- @monitor.scan!
70
- @monitor.run!
71
- end
72
-
73
- # Returns disconnect! to its original implementation.
74
- def disconnect!
75
- context.with_connection do |connection|
76
- connection.disconnect!
77
- end
78
- @monitor.stop! and true
79
- end
80
- end
81
-
82
- class Mongo::Address
83
- private
47
+ module Mongo
48
+ class Server
49
+ alias :initialize :original_initialize
50
+ remove_method(:original_initialize)
84
51
 
85
- def family(host)
86
- fam = host == 'localhost' ? ::Socket::AF_INET : ::Socket::AF_UNSPEC
87
- ::Socket.getaddrinfo(host, nil, fam, ::Socket::SOCK_STREAM).first[4]
52
+ alias :disconnect! :original_disconnect!
53
+ remove_method(:original_disconnect!)
88
54
  end
89
55
  end
90
56
  end