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,373 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ RSpec::Matchers.define :match_command_name do |expectation|
17
+
18
+ match do |event|
19
+ expect(event.command_name.to_s).to eq(expectation.command_name.to_s)
20
+ end
21
+ end
22
+
23
+ RSpec::Matchers.define :match_database_name do |expectation|
24
+
25
+ match do |event|
26
+ expect(event.database_name.to_s).to eq(expectation.database_name.to_s)
27
+ end
28
+ end
29
+
30
+ RSpec::Matchers.define :generate_request_id do |expectation|
31
+
32
+ match do |event|
33
+ expect(event.request_id).to be > 0
34
+ end
35
+ end
36
+
37
+ RSpec::Matchers.define :generate_operation_id do |expectation|
38
+
39
+ match do |event|
40
+ expect(event.request_id).to be > 0
41
+ end
42
+ end
43
+
44
+ RSpec::Matchers.define :match_command do |expectation|
45
+ include Mongo::CommandMonitoring::Matchable
46
+
47
+ match do |event|
48
+ data_matches?(event.command, expectation.event_data['command'])
49
+ end
50
+ end
51
+
52
+ RSpec::Matchers.define :match_reply do |expectation|
53
+ include Mongo::CommandMonitoring::Matchable
54
+
55
+ match do |event|
56
+ data_matches?(event.reply, expectation.event_data['reply'])
57
+ end
58
+ end
59
+
60
+ RSpec::Matchers.define :match_command_started_event do |expectation|
61
+
62
+ match do |event|
63
+ expect(event).to match_command_name(expectation)
64
+ expect(event).to match_database_name(expectation)
65
+ expect(event).to generate_operation_id
66
+ expect(event).to generate_request_id
67
+ expect(event).to match_command(expectation)
68
+ end
69
+ end
70
+
71
+ RSpec::Matchers.define :match_command_succeeded_event do |expectation|
72
+
73
+ match do |event|
74
+ expect(event).to match_command_name(expectation)
75
+ expect(event).to generate_operation_id
76
+ expect(event).to generate_request_id
77
+ expect(event).to match_reply(expectation)
78
+ end
79
+ end
80
+
81
+ RSpec::Matchers.define :match_command_failed_event do |expectation|
82
+
83
+ match do |event|
84
+ expect(event).to match_command_name(expectation)
85
+ expect(event).to generate_operation_id
86
+ expect(event).to generate_request_id
87
+ end
88
+ end
89
+
90
+ module Mongo
91
+ module CommandMonitoring
92
+
93
+ # Matchers common behaviour.
94
+ #
95
+ # @since 2.1.0
96
+ module Matchable
97
+
98
+ # Determine if the data matches.
99
+ #
100
+ # @example Does the data match?
101
+ # matchable.data_matches?(actual, expected)
102
+ #
103
+ # @param [ Object ] actual The actual data.
104
+ # @param [ Object ] expected The expected data.
105
+ #
106
+ # @return [ true, false ] If the data matches.
107
+ #
108
+ # @since 2.1.0
109
+ def data_matches?(actual, expected)
110
+ case expected
111
+ when ::Hash, BSON::Document then
112
+ hash_matches?(actual, expected)
113
+ when ::Array
114
+ array_matches?(actual, expected)
115
+ else
116
+ value_matches?(actual, expected)
117
+ end
118
+ end
119
+
120
+ # Determine if the hash matches.
121
+ #
122
+ # @example Does the hash match?
123
+ # matchable.hash_matches?(actual, expected)
124
+ #
125
+ # @param [ Hash ] actual The actual hash.
126
+ # @param [ Hash ] expected The expected hash.
127
+ #
128
+ # @return [ true, false ] If the hash matches.
129
+ #
130
+ # @since 2.1.0
131
+ def hash_matches?(actual, expected)
132
+ if expected.keys.first == '$numberLong'
133
+ converted = expected.values.first.to_i
134
+ (actual == converted) || actual >= 0
135
+ else
136
+ expected.each do |key, value|
137
+ return false unless data_matches?(actual[key], value)
138
+ end
139
+ end
140
+ end
141
+
142
+ # Determine if an array matches.
143
+ #
144
+ # @example Does the array match?
145
+ # matchable.array_matches?(actual, expected)
146
+ #
147
+ # @param [ Array ] actual The actual array.
148
+ # @param [ Array ] expected The expected array.
149
+ #
150
+ # @return [ true, false ] If the array matches.
151
+ #
152
+ # @since 2.1.0
153
+ def array_matches?(actual, expected)
154
+ expected.each_with_index do |value, i|
155
+ # @todo: Durran: fix for kill cursors replies
156
+ if actual
157
+ return false unless data_matches?(actual[i], value)
158
+ end
159
+ end
160
+ end
161
+
162
+ # Check if a value matches.
163
+ #
164
+ # @example Does a value match.
165
+ # matchable.value_matches?(actual, expected)
166
+ #
167
+ # @param [ Object ] actual The actual value.
168
+ # @param [ Object ] expected The expected object.
169
+ #
170
+ # @return [ true, false ] If the value matches.
171
+ #
172
+ # @since 2.1.0
173
+ def value_matches?(actual, expected)
174
+ case expected
175
+ when '42', 42 then
176
+ actual > 0
177
+ when '' then
178
+ !actual.nil?
179
+ else
180
+ actual == expected
181
+ end
182
+ end
183
+ end
184
+
185
+ # Represents a command monitoring spec in its entirety.
186
+ #
187
+ # @since 2.1.0
188
+ class Spec
189
+
190
+ # Create the spec.
191
+ #
192
+ # @example Create the spec.
193
+ # Spec.new('/path/to/test')
194
+ #
195
+ # @param [ String ] file The yaml test file.
196
+ #
197
+ # @since 2.1.0
198
+ def initialize(file)
199
+ file = File.new(file)
200
+ @spec = YAML.load(ERB.new(file.read).result)
201
+ file.close
202
+ @data = @spec['data']
203
+ @tests = @spec['tests']
204
+ end
205
+
206
+ # Get all the tests in the spec.
207
+ #
208
+ # @example Get all the tests.
209
+ # spec.tests
210
+ #
211
+ # @return [ Array<Test> ] The tests.
212
+ def tests
213
+ @tests.map do |test|
214
+ Test.new(@data, test)
215
+ end
216
+ end
217
+ end
218
+
219
+ # Represents an individual command monitoring test.
220
+ #
221
+ # @since 2.1.0
222
+ class Test
223
+
224
+ # @return [ String ] description The test description.
225
+ attr_reader :description
226
+
227
+ # @return [ Array<Expectation> ] The expectations.
228
+ attr_reader :expectations
229
+
230
+ # @return [ String ] The server version to ignore if greater.
231
+ attr_reader :ignore_if_server_version_greater_than
232
+
233
+ # @return [ String ] The server version to ignore if lower.
234
+ attr_reader :ignore_if_server_version_less_than
235
+
236
+ # Create the new test.
237
+ #
238
+ # @example Create the test.
239
+ # Test.new(data, test)
240
+ #
241
+ # @param [ Array<Hash> ] data The test data.
242
+ # @param [ Hash ] The test itself.
243
+ #
244
+ # @since 2.1.0
245
+ def initialize(data, test)
246
+ @data = data
247
+ @description = test['description']
248
+ @ignore_if_server_version_greater_than = test['ignore_if_server_version_greater_than']
249
+ @ignore_if_server_version_less_than = test['ignore_if_server_version_less_than']
250
+ @operation = Mongo::CRUD::Operation.get(test['operation'])
251
+ @expectations = test['expectations'].map{ |e| Expectation.new(e) }
252
+ end
253
+
254
+ # Run the test against the provided collection.
255
+ #
256
+ # @example Run the test.
257
+ # test.run(collection)
258
+ #
259
+ # @param [ Mongo::Collection ] collection The collection.
260
+ #
261
+ # @since 2.1.0
262
+ def run(collection)
263
+ collection.insert_many(@data)
264
+ @operation.execute(collection)
265
+ end
266
+ end
267
+
268
+ # Encapsulates expectation behaviour.
269
+ #
270
+ # @since 2.1.0
271
+ class Expectation
272
+
273
+ # @return [ String ] event_type The type of expected event.
274
+ attr_reader :event_type
275
+
276
+ # @return [ Hash ] event_data The event data.
277
+ attr_reader :event_data
278
+
279
+ # Get the expected command name.
280
+ #
281
+ # @example Get the expected command name.
282
+ # expectation.command_name
283
+ #
284
+ # @return [ String ] The command name.
285
+ #
286
+ # @since 2.1.0
287
+ def command_name
288
+ @event_data['command_name']
289
+ end
290
+
291
+ # Get the expected database name.
292
+ #
293
+ # @example Get the expected database name.
294
+ # expectation.database_name
295
+ #
296
+ # @return [ String ] The database name.
297
+ #
298
+ # @since 2.1.0
299
+ def database_name
300
+ @event_data['database_name']
301
+ end
302
+
303
+ # Get a readable event name.
304
+ #
305
+ # @example Get the event name.
306
+ # expectation.event_name
307
+ #
308
+ # @return [ String ] The event name.
309
+ #
310
+ # @since 2.1.0
311
+ def event_name
312
+ event_type.gsub('_', ' ')
313
+ end
314
+
315
+ # Create the new expectation.
316
+ #
317
+ # @example Create the new expectation.
318
+ # Expectation.new(expectation)
319
+ #
320
+ # @param [ Hash ] expectation The expectation.
321
+ #
322
+ # @since 2.1.0
323
+ def initialize(expectation)
324
+ @event_type = expectation.keys.first
325
+ @event_data = expectation[@event_type]
326
+ end
327
+
328
+ # Get the name of the matcher.
329
+ #
330
+ # @example Get the matcher name.
331
+ # expectation.matcher
332
+ #
333
+ # @return [ String ] The matcher name.
334
+ #
335
+ # @since 2.1.0
336
+ def matcher
337
+ "match_#{event_type}"
338
+ end
339
+ end
340
+
341
+ # The test subscriber to track the events.
342
+ #
343
+ # @since 2.1.0
344
+ class TestSubscriber
345
+
346
+ def started(event)
347
+ command_started_event[event.command_name] = event
348
+ end
349
+
350
+ def succeeded(event)
351
+ command_succeeded_event[event.command_name] = event
352
+ end
353
+
354
+ def failed(event)
355
+ command_failed_event[event.command_name] = event
356
+ end
357
+
358
+ private
359
+
360
+ def command_started_event
361
+ @started_events ||= BSON::Document.new
362
+ end
363
+
364
+ def command_succeeded_event
365
+ @succeeded_events ||= BSON::Document.new
366
+ end
367
+
368
+ def command_failed_event
369
+ @failed_events ||= BSON::Document.new
370
+ end
371
+ end
372
+ end
373
+ end
@@ -0,0 +1,228 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ RSpec::Matchers.define :have_hosts do |test|
16
+
17
+ match do |client|
18
+
19
+ def find_server(client, host)
20
+ client.cluster.instance_variable_get(:@servers).detect do |s|
21
+ s.address.host == host.host
22
+ end
23
+ end
24
+
25
+ def match_host?(server, host)
26
+ server.address.host == host.host
27
+ end
28
+
29
+ def match_port?(server, host)
30
+ server.address.port == host.port || !host.port
31
+ end
32
+
33
+ def match_address_family?(server, host)
34
+ address_family(server) == host.address_family
35
+ end
36
+
37
+ def address_family(server)
38
+ server.address.socket(2)
39
+ server.address.instance_variable_get(:@resolver).class
40
+ end
41
+
42
+ test.hosts.all? do |host|
43
+ server = find_server(client, host)
44
+ match_host?(server, host) &&
45
+ match_port?(server, host) if server #&&
46
+ #match_address_family?(server, host) if server
47
+ end
48
+
49
+ failure_message do |client|
50
+ "With URI: #{test.uri_string}\n" +
51
+ "Expected that test hosts: #{test.hosts} would match " +
52
+ "client hosts: #{client.cluster.instance_variable_get(:@servers)}"
53
+ end
54
+ end
55
+ end
56
+
57
+ RSpec::Matchers.define :match_auth do |test|
58
+
59
+ def match_database?(client, auth)
60
+ client.options[:database] == auth.database || !auth.database
61
+ end
62
+
63
+ def match_password?(client, auth)
64
+ client.options[:password] == auth.password ||
65
+ client.options[:password].nil? && auth.password == ''
66
+ end
67
+
68
+ match do |client|
69
+ auth = test.auth
70
+ return true unless auth
71
+ client.options[:user] == auth.username &&
72
+ match_password?(client, auth) &&
73
+ match_database?(client, auth)
74
+ end
75
+
76
+ failure_message do |client|
77
+ "With URI: #{test.uri_string}\n" +
78
+ "Expected that test auth: #{test.auth} would match client auth: #{client.options}"
79
+ end
80
+ end
81
+
82
+ RSpec::Matchers.define :match_options do |test|
83
+
84
+ match do |client|
85
+ options = test.options
86
+ return true unless options
87
+ options.match?(client.options)
88
+ end
89
+
90
+ failure_message do |client|
91
+ "With URI: #{test.uri_string}\n" +
92
+ "Expected that test options: #{test.options.options} would match client options: #{client.options}"
93
+ end
94
+ end
95
+
96
+ module Mongo
97
+ module ConnectionString
98
+
99
+ class Spec
100
+
101
+ attr_reader :description
102
+
103
+ # Instantiate the new spec.
104
+ #
105
+ # @example Create the spec.
106
+ # Spec.new(file)
107
+ #
108
+ # @param [ String ] file The name of the file.
109
+ #
110
+ # @since 2.0.0
111
+ def initialize(file)
112
+ file = File.new(file)
113
+ @spec = YAML.load(ERB.new(file.read).result)
114
+ file.close
115
+ @description = File.basename(file)
116
+ end
117
+
118
+ def tests
119
+ @tests ||= @spec['tests'].collect do |spec|
120
+ Test.new(spec)
121
+ end
122
+ end
123
+ end
124
+
125
+ class Test
126
+
127
+ attr_reader :description
128
+ attr_reader :uri_string
129
+
130
+ def initialize(spec)
131
+ @spec = spec
132
+ @description = @spec['description']
133
+ @uri_string = @spec['uri']
134
+ end
135
+
136
+ def valid?
137
+ @spec['valid']
138
+ end
139
+
140
+ def warn?
141
+ @spec['warning']
142
+ end
143
+
144
+ def hosts
145
+ @hosts ||= @spec['hosts'].collect do |host|
146
+ Host.new(host)
147
+ end
148
+ end
149
+
150
+ def options
151
+ @options ||= Options.new(@spec['options']) if @spec['options']
152
+ end
153
+
154
+ def client
155
+ @client ||= Mongo::Client.new(@spec['uri'])
156
+ end
157
+
158
+ def uri
159
+ @uri ||= Mongo::URI.new(@spec['uri'])
160
+ end
161
+
162
+ def auth
163
+ @auth ||= Auth.new(@spec['auth']) if @spec['auth']
164
+ end
165
+ end
166
+
167
+ class Host
168
+
169
+ MAPPING = {
170
+ 'ipv4' => Mongo::Address::IPv4,
171
+ 'ipv6' => Mongo::Address::IPv6,
172
+ 'unix' => Mongo::Address::Unix
173
+ }
174
+
175
+ attr_reader :host
176
+ attr_reader :port
177
+
178
+ def initialize(spec)
179
+ @spec = spec
180
+ @host = @spec['host']
181
+ @port = @spec['port']
182
+ end
183
+
184
+ def address_family
185
+ MAPPING[@spec['type']]
186
+ end
187
+ end
188
+
189
+ class Auth
190
+
191
+ attr_reader :username
192
+ attr_reader :password
193
+ attr_reader :database
194
+
195
+ def initialize(spec)
196
+ @spec = spec
197
+ @username = @spec['username']
198
+ @password = @spec['password']
199
+ @database = @spec['db']
200
+ end
201
+
202
+ def to_s
203
+ "username: #{username}, password: #{password}, database: #{database}"
204
+ end
205
+ end
206
+
207
+ class Options
208
+
209
+ MAPPINGS = {
210
+ 'replicaset' => :replica_set,
211
+ 'authmechanism' => :auth_mech
212
+ }
213
+
214
+ attr_reader :options
215
+
216
+ def initialize(options)
217
+ @options = options
218
+ end
219
+
220
+ def match?(opts)
221
+ @options.keys.all? do |k|
222
+ opts[MAPPINGS[k]] == @options[k] ||
223
+ Mongo::URI::AUTH_MECH_MAP[@options[k]] == opts[MAPPINGS[k]]
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end