mongo 1.12.5 → 2.0.0.beta

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 (437) 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 +64 -0
  5. data/LICENSE +1 -1
  6. data/README.md +23 -125
  7. data/Rakefile +26 -21
  8. data/bin/mongo_console +6 -38
  9. data/lib/mongo.rb +23 -82
  10. data/lib/mongo/address.rb +111 -0
  11. data/lib/mongo/address/ipv4.rb +85 -0
  12. data/lib/mongo/address/ipv6.rb +85 -0
  13. data/lib/mongo/address/unix.rb +76 -0
  14. data/lib/mongo/auth.rb +108 -0
  15. data/lib/mongo/auth/cr.rb +44 -0
  16. data/lib/mongo/auth/cr/conversation.rb +119 -0
  17. data/lib/mongo/auth/executable.rb +52 -0
  18. data/lib/mongo/auth/ldap.rb +48 -0
  19. data/lib/mongo/auth/ldap/conversation.rb +92 -0
  20. data/lib/mongo/auth/roles.rb +104 -0
  21. data/lib/mongo/auth/scram.rb +53 -0
  22. data/lib/mongo/auth/scram/conversation.rb +450 -0
  23. data/lib/mongo/auth/user.rb +159 -0
  24. data/lib/mongo/auth/user/view.rb +102 -0
  25. data/lib/mongo/auth/x509.rb +48 -0
  26. data/lib/mongo/auth/x509/conversation.rb +92 -0
  27. data/lib/mongo/{gridfs.rb → bulk.rb} +2 -5
  28. data/lib/mongo/bulk/bulk_write.rb +307 -0
  29. data/lib/mongo/client.rb +233 -0
  30. data/lib/mongo/cluster.rb +203 -0
  31. data/lib/mongo/cluster/topology.rb +60 -0
  32. data/lib/mongo/cluster/topology/replica_set.rb +160 -0
  33. data/lib/mongo/cluster/topology/sharded.rb +132 -0
  34. data/lib/mongo/cluster/topology/standalone.rb +132 -0
  35. data/lib/mongo/cluster/topology/unknown.rb +155 -0
  36. data/lib/mongo/collection.rb +130 -1101
  37. data/lib/mongo/collection/view.rb +169 -0
  38. data/lib/mongo/collection/view/aggregation.rb +108 -0
  39. data/lib/mongo/collection/view/explainable.rb +49 -0
  40. data/lib/mongo/collection/view/immutable.rb +43 -0
  41. data/lib/mongo/collection/view/iterable.rb +48 -0
  42. data/lib/mongo/collection/view/map_reduce.rb +191 -0
  43. data/lib/mongo/collection/view/readable.rb +363 -0
  44. data/lib/mongo/collection/view/writable.rb +169 -0
  45. data/lib/mongo/cursor.rb +79 -680
  46. data/lib/mongo/database.rb +224 -0
  47. data/lib/mongo/database/view.rb +101 -0
  48. data/lib/mongo/error.rb +81 -0
  49. data/lib/mongo/error/bulk_write_failure.rb +41 -0
  50. data/lib/mongo/{utils/thread_local_variable_manager.rb → error/empty_batch.rb} +22 -8
  51. data/{test/functional/db_connection_test.rb → lib/mongo/error/invalid_bulk_operation.rb} +19 -8
  52. data/lib/mongo/error/invalid_collection_name.rb +39 -0
  53. data/lib/mongo/error/invalid_database_name.rb +39 -0
  54. data/{test/replica_set/ssl_test.rb → lib/mongo/error/invalid_document.rb} +21 -14
  55. data/lib/mongo/error/invalid_file.rb +38 -0
  56. data/lib/mongo/error/invalid_nonce.rb +46 -0
  57. data/lib/mongo/error/invalid_replacement_document.rb +39 -0
  58. data/lib/mongo/error/invalid_signature.rb +47 -0
  59. data/{test/functional/ssl_test.rb → lib/mongo/error/invalid_update_document.rb} +22 -12
  60. data/lib/mongo/error/max_bson_size.rb +40 -0
  61. data/lib/mongo/error/max_message_size.rb +42 -0
  62. data/lib/mongo/{utils.rb → error/need_primary_server.rb} +10 -6
  63. data/lib/mongo/{connection.rb → error/operation_failure.rb} +10 -6
  64. data/lib/mongo/error/parser.rb +77 -0
  65. data/lib/mongo/{connection/socket.rb → error/socket_error.rb} +10 -5
  66. data/lib/mongo/error/socket_timeout_error.rb +23 -0
  67. data/lib/mongo/error/unsupported_features.rb +43 -0
  68. data/lib/mongo/event.rb +40 -0
  69. data/lib/mongo/event/listeners.rb +63 -0
  70. data/lib/mongo/event/primary_elected.rb +53 -0
  71. data/lib/mongo/event/publisher.rb +42 -0
  72. data/lib/mongo/event/server_added.rb +53 -0
  73. data/lib/mongo/event/server_removed.rb +53 -0
  74. data/lib/mongo/event/subscriber.rb +41 -0
  75. data/lib/mongo/grid.rb +16 -0
  76. data/lib/mongo/grid/file.rb +94 -0
  77. data/lib/mongo/grid/file/chunk.rb +184 -0
  78. data/lib/mongo/grid/file/metadata.rb +223 -0
  79. data/lib/mongo/grid/fs.rb +149 -0
  80. data/lib/mongo/index.rb +64 -0
  81. data/lib/mongo/index/view.rb +205 -0
  82. data/lib/mongo/loggable.rb +126 -0
  83. data/lib/mongo/logger.rb +132 -0
  84. data/lib/mongo/operation.rb +26 -0
  85. data/lib/mongo/operation/aggregate.rb +100 -0
  86. data/lib/mongo/operation/aggregate/result.rb +84 -0
  87. data/lib/mongo/operation/batchable.rb +103 -0
  88. data/lib/mongo/operation/bulk_delete/result.rb +197 -0
  89. data/lib/mongo/operation/bulk_insert/result.rb +195 -0
  90. data/lib/mongo/operation/bulk_update/result.rb +295 -0
  91. data/lib/mongo/operation/command.rb +62 -0
  92. data/lib/mongo/operation/executable.rb +105 -0
  93. data/lib/mongo/operation/kill_cursors.rb +39 -0
  94. data/lib/mongo/operation/limited.rb +37 -0
  95. data/lib/mongo/operation/list_collections/result.rb +116 -0
  96. data/lib/mongo/operation/list_indexes/result.rb +118 -0
  97. data/lib/mongo/operation/map_reduce.rb +96 -0
  98. data/lib/mongo/operation/map_reduce/result.rb +122 -0
  99. data/lib/mongo/{functional.rb → operation/read.rb} +7 -7
  100. data/lib/mongo/operation/read/collections_info.rb +67 -0
  101. data/lib/mongo/operation/read/get_more.rb +71 -0
  102. data/lib/mongo/operation/read/indexes.rb +68 -0
  103. data/lib/mongo/operation/read/list_collections.rb +75 -0
  104. data/lib/mongo/operation/read/list_indexes.rb +77 -0
  105. data/lib/mongo/operation/read/query.rb +71 -0
  106. data/lib/mongo/operation/read_preferrable.rb +34 -0
  107. data/lib/mongo/operation/result.rb +259 -0
  108. data/lib/mongo/operation/specifiable.rb +380 -0
  109. data/lib/mongo/operation/write.rb +25 -0
  110. data/lib/mongo/operation/write/bulk_delete.rb +158 -0
  111. data/lib/mongo/operation/write/bulk_insert.rb +160 -0
  112. data/lib/mongo/operation/write/bulk_update.rb +167 -0
  113. data/lib/mongo/{connection/socket/socket_util.rb → operation/write/command.rb} +9 -24
  114. data/lib/mongo/operation/write/command/create_user.rb +43 -0
  115. data/lib/mongo/operation/write/command/delete.rb +56 -0
  116. data/lib/mongo/operation/write/command/drop_index.rb +51 -0
  117. data/lib/mongo/operation/write/command/ensure_index.rb +55 -0
  118. data/lib/mongo/operation/write/command/insert.rb +55 -0
  119. data/lib/mongo/operation/write/command/remove_user.rb +42 -0
  120. data/lib/mongo/operation/write/command/update.rb +60 -0
  121. data/lib/mongo/operation/write/command/writable.rb +61 -0
  122. data/lib/mongo/operation/write/create_index.rb +84 -0
  123. data/lib/mongo/operation/write/create_user.rb +75 -0
  124. data/lib/mongo/operation/write/delete.rb +91 -0
  125. data/lib/mongo/operation/write/drop_index.rb +62 -0
  126. data/lib/mongo/operation/write/insert.rb +88 -0
  127. data/lib/mongo/operation/write/remove_user.rb +70 -0
  128. data/lib/mongo/operation/write/update.rb +98 -0
  129. data/lib/mongo/protocol.rb +15 -0
  130. data/lib/mongo/protocol/bit_vector.rb +61 -0
  131. data/lib/mongo/protocol/delete.rb +94 -0
  132. data/lib/mongo/protocol/get_more.rb +99 -0
  133. data/lib/mongo/protocol/insert.rb +99 -0
  134. data/lib/mongo/protocol/kill_cursors.rb +74 -0
  135. data/lib/mongo/protocol/message.rb +252 -0
  136. data/lib/mongo/protocol/query.rb +147 -0
  137. data/lib/mongo/protocol/reply.rb +72 -0
  138. data/lib/mongo/protocol/serializers.rb +180 -0
  139. data/lib/mongo/protocol/update.rb +111 -0
  140. data/lib/mongo/server.rb +163 -0
  141. data/lib/mongo/server/connectable.rb +99 -0
  142. data/lib/mongo/server/connection.rb +133 -0
  143. data/lib/mongo/server/connection_pool.rb +141 -0
  144. data/lib/mongo/server/connection_pool/queue.rb +182 -0
  145. data/lib/mongo/server/context.rb +66 -0
  146. data/lib/mongo/server/description.rb +450 -0
  147. data/lib/mongo/server/description/features.rb +85 -0
  148. data/lib/mongo/server/description/inspector.rb +79 -0
  149. data/lib/mongo/server/description/inspector/primary_elected.rb +58 -0
  150. data/lib/mongo/server/description/inspector/server_added.rb +59 -0
  151. data/lib/mongo/server/description/inspector/server_removed.rb +59 -0
  152. data/lib/mongo/server/monitor.rb +160 -0
  153. data/lib/mongo/server/monitor/connection.rb +88 -0
  154. data/lib/mongo/server_selector.rb +81 -0
  155. data/lib/mongo/server_selector/nearest.rb +94 -0
  156. data/lib/mongo/server_selector/primary.rb +88 -0
  157. data/lib/mongo/server_selector/primary_preferred.rb +94 -0
  158. data/lib/mongo/server_selector/secondary.rb +91 -0
  159. data/lib/mongo/server_selector/secondary_preferred.rb +96 -0
  160. data/lib/mongo/server_selector/selectable.rb +209 -0
  161. data/lib/mongo/socket.rb +179 -0
  162. data/lib/mongo/socket/ssl.rb +108 -0
  163. data/lib/mongo/socket/tcp.rb +69 -0
  164. data/lib/mongo/socket/unix.rb +66 -0
  165. data/lib/mongo/uri.rb +504 -0
  166. data/lib/mongo/version.rb +21 -0
  167. data/lib/mongo/write_concern.rb +99 -0
  168. data/lib/mongo/write_concern/acknowledged.rb +38 -0
  169. data/lib/mongo/write_concern/normalizable.rb +73 -0
  170. data/lib/mongo/write_concern/unacknowledged.rb +43 -0
  171. data/mongo.gemspec +17 -14
  172. data/spec/mongo/address/ipv4_spec.rb +74 -0
  173. data/spec/mongo/address/ipv6_spec.rb +74 -0
  174. data/spec/mongo/address/unix_spec.rb +30 -0
  175. data/spec/mongo/address_spec.rb +206 -0
  176. data/spec/mongo/auth/cr_spec.rb +59 -0
  177. data/spec/mongo/auth/ldap_spec.rb +40 -0
  178. data/spec/mongo/auth/scram/conversation_spec.rb +197 -0
  179. data/spec/mongo/auth/scram_spec.rb +55 -0
  180. data/spec/mongo/auth/user/view_spec.rb +76 -0
  181. data/spec/mongo/auth/user_spec.rb +190 -0
  182. data/spec/mongo/auth/x509_spec.rb +40 -0
  183. data/spec/mongo/auth_spec.rb +65 -0
  184. data/spec/mongo/bulk/bulk_write_spec.rb +175 -0
  185. data/spec/mongo/client_spec.rb +564 -0
  186. data/spec/mongo/cluster/topology/replica_set_spec.rb +101 -0
  187. data/spec/mongo/cluster/topology/sharded_spec.rb +74 -0
  188. data/spec/mongo/cluster/topology/standalone_spec.rb +79 -0
  189. data/spec/mongo/cluster/topology_spec.rb +65 -0
  190. data/spec/mongo/cluster_spec.rb +129 -0
  191. data/spec/mongo/collection/view/aggregation_spec.rb +135 -0
  192. data/spec/mongo/collection/view/explainable_spec.rb +32 -0
  193. data/spec/mongo/collection/view/map_reduce_spec.rb +242 -0
  194. data/spec/mongo/collection/view/readable_spec.rb +603 -0
  195. data/spec/mongo/collection/view/writable_spec.rb +504 -0
  196. data/spec/mongo/collection/view_spec.rb +521 -0
  197. data/spec/mongo/collection_spec.rb +362 -0
  198. data/spec/mongo/cursor_spec.rb +295 -0
  199. data/spec/mongo/database_spec.rb +306 -0
  200. data/spec/mongo/error/parser_spec.rb +119 -0
  201. data/spec/mongo/event/publisher_spec.rb +50 -0
  202. data/spec/mongo/event/subscriber_spec.rb +34 -0
  203. data/spec/mongo/grid/file/chunk_spec.rb +226 -0
  204. data/spec/mongo/grid/file/metadata_spec.rb +69 -0
  205. data/spec/mongo/grid/file_spec.rb +138 -0
  206. data/spec/mongo/grid/fs_spec.rb +129 -0
  207. data/spec/mongo/index/view_spec.rb +226 -0
  208. data/spec/mongo/loggable_spec.rb +62 -0
  209. data/spec/mongo/logger_spec.rb +97 -0
  210. data/spec/mongo/operation/aggregate/result_spec.rb +80 -0
  211. data/spec/mongo/operation/aggregate_spec.rb +135 -0
  212. data/spec/mongo/operation/command_spec.rb +106 -0
  213. data/spec/mongo/operation/kill_cursors_spec.rb +66 -0
  214. data/spec/mongo/operation/limited_spec.rb +50 -0
  215. data/spec/mongo/operation/map_reduce_spec.rb +143 -0
  216. data/spec/mongo/operation/read/collections_info_spec.rb +40 -0
  217. data/spec/mongo/operation/read/get_more_spec.rb +81 -0
  218. data/spec/mongo/operation/read/indexes_spec.rb +31 -0
  219. data/spec/mongo/operation/read/query_spec.rb +84 -0
  220. data/spec/mongo/operation/result_spec.rb +275 -0
  221. data/spec/mongo/operation/specifiable_spec.rb +53 -0
  222. data/spec/mongo/operation/write/bulk_delete_spec.rb +473 -0
  223. data/spec/mongo/operation/write/bulk_insert_spec.rb +466 -0
  224. data/spec/mongo/operation/write/bulk_update_spec.rb +524 -0
  225. data/spec/mongo/operation/write/command/delete_spec.rb +116 -0
  226. data/spec/mongo/operation/write/command/insert_spec.rb +117 -0
  227. data/spec/mongo/operation/write/command/update_spec.rb +123 -0
  228. data/spec/mongo/operation/write/create_user_spec.rb +44 -0
  229. data/spec/mongo/operation/write/delete_spec.rb +178 -0
  230. data/spec/mongo/operation/write/drop_index_spec.rb +51 -0
  231. data/spec/mongo/operation/write/ensure_index_spec.rb +81 -0
  232. data/spec/mongo/operation/write/insert_spec.rb +231 -0
  233. data/spec/mongo/operation/write/remove_user_spec.rb +46 -0
  234. data/spec/mongo/operation/write/response_spec.rb +85 -0
  235. data/spec/mongo/operation/write/update_spec.rb +177 -0
  236. data/spec/mongo/protocol/delete_spec.rb +167 -0
  237. data/spec/mongo/protocol/get_more_spec.rb +146 -0
  238. data/spec/mongo/protocol/insert_spec.rb +161 -0
  239. data/spec/mongo/protocol/kill_cursors_spec.rb +101 -0
  240. data/spec/mongo/protocol/query_spec.rb +285 -0
  241. data/spec/mongo/protocol/reply_spec.rb +157 -0
  242. data/spec/mongo/protocol/update_spec.rb +186 -0
  243. data/spec/mongo/server/connection_pool/queue_spec.rb +170 -0
  244. data/spec/mongo/server/connection_pool_spec.rb +120 -0
  245. data/spec/mongo/server/connection_spec.rb +289 -0
  246. data/spec/mongo/server/description/features_spec.rb +138 -0
  247. data/spec/mongo/server/description/inspector/primary_elected_spec.rb +94 -0
  248. data/spec/mongo/server/description/inspector/server_added_spec.rb +92 -0
  249. data/spec/mongo/server/description/inspector/server_removed_spec.rb +95 -0
  250. data/spec/mongo/server/description_spec.rb +510 -0
  251. data/spec/mongo/server/monitor_spec.rb +130 -0
  252. data/spec/mongo/server_discovery_and_monitoring_spec.rb +103 -0
  253. data/spec/mongo/server_selection_rtt_spec.rb +104 -0
  254. data/spec/mongo/server_selection_spec.rb +89 -0
  255. data/spec/mongo/server_selector/nearest_spec.rb +250 -0
  256. data/spec/mongo/server_selector/primary_preferred_spec.rb +290 -0
  257. data/spec/mongo/server_selector/primary_spec.rb +114 -0
  258. data/spec/mongo/server_selector/secondary_preferred_spec.rb +252 -0
  259. data/spec/mongo/server_selector/secondary_spec.rb +196 -0
  260. data/spec/mongo/server_selector_spec.rb +101 -0
  261. data/spec/mongo/server_spec.rb +131 -0
  262. data/spec/mongo/uri_spec.rb +517 -0
  263. data/spec/mongo/write_concern/acknowledged_spec.rb +44 -0
  264. data/spec/mongo/write_concern/unacknowledged_spec.rb +15 -0
  265. data/spec/mongo_orchestration_spec.rb +70 -0
  266. data/spec/spec_helper.rb +148 -0
  267. data/spec/support/authorization.rb +245 -0
  268. data/spec/support/helpers.rb +140 -0
  269. data/spec/support/matchers.rb +37 -0
  270. data/spec/support/mongo_orchestration.rb +61 -0
  271. data/spec/support/mongo_orchestration/requestable.rb +109 -0
  272. data/spec/support/mongo_orchestration/standalone.rb +57 -0
  273. data/spec/support/sdam/rs/discover_arbiters.yml +41 -0
  274. data/spec/support/sdam/rs/discover_passives.yml +41 -0
  275. data/spec/support/sdam/rs/discover_primary.yml +40 -0
  276. data/spec/support/sdam/rs/discover_secondary.yml +41 -0
  277. data/spec/support/sdam/rs/discovery.yml +195 -0
  278. data/spec/support/sdam/rs/ghost_discovered.yml +39 -0
  279. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +34 -0
  280. data/spec/support/sdam/rs/member_reconfig.yml +68 -0
  281. data/spec/support/sdam/rs/member_standalone.yml +60 -0
  282. data/spec/support/sdam/rs/new_primary.yml +74 -0
  283. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +71 -0
  284. data/spec/support/sdam/rs/non_rs_member.yml +31 -0
  285. data/spec/support/sdam/rs/normalize_case.yml +49 -0
  286. data/spec/support/sdam/rs/primary_becomes_standalone.yml +52 -0
  287. data/spec/support/sdam/rs/primary_changes_set_name.yml +57 -0
  288. data/spec/support/sdam/rs/primary_disconnect.yml +56 -0
  289. data/spec/support/sdam/rs/primary_wrong_set_name.yml +27 -0
  290. data/spec/support/sdam/rs/response_from_removed.yml +63 -0
  291. data/spec/support/sdam/rs/rsother_discovered.yml +41 -0
  292. data/spec/support/sdam/rs/sec_not_auth.yml +49 -0
  293. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +28 -0
  294. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +69 -0
  295. data/spec/support/sdam/rs/unexpected_mongos.yml +26 -0
  296. data/spec/support/sdam/rs/wrong_set_name.yml +35 -0
  297. data/spec/support/sdam/sharded/multiple_mongoses.yml +46 -0
  298. data/spec/support/sdam/sharded/non_mongos_removed.yml +41 -0
  299. data/spec/support/sdam/sharded/normalize_uri_case.yml +32 -0
  300. data/spec/support/sdam/single/direct_connection_external_ip.yml +34 -0
  301. data/spec/support/sdam/single/direct_connection_mongos.yml +33 -0
  302. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +35 -0
  303. data/spec/support/sdam/single/direct_connection_rsprimary.yml +34 -0
  304. data/spec/support/sdam/single/direct_connection_rssecondary.yml +35 -0
  305. data/spec/support/sdam/single/direct_connection_slave.yml +32 -0
  306. data/spec/support/sdam/single/direct_connection_standalone.yml +32 -0
  307. data/spec/support/sdam/single/not_ok_response.yml +39 -0
  308. data/spec/support/sdam/single/standalone_removed.yml +32 -0
  309. data/spec/support/sdam/single/unavailable_seed.yml +28 -0
  310. data/spec/support/server_discovery_and_monitoring.rb +167 -0
  311. data/spec/support/server_selection.rb +140 -0
  312. data/spec/support/server_selection/rtt/first_value.yml +4 -0
  313. data/spec/support/server_selection/rtt/first_value_zero.yml +4 -0
  314. data/spec/support/server_selection/rtt/value_test_1.yml +4 -0
  315. data/spec/support/server_selection/rtt/value_test_2.yml +4 -0
  316. data/spec/support/server_selection/rtt/value_test_3.yml +4 -0
  317. data/spec/support/server_selection/rtt/value_test_4.yml +4 -0
  318. data/spec/support/server_selection/rtt/value_test_5.yml +4 -0
  319. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +32 -0
  320. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +27 -0
  321. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +23 -0
  322. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +32 -0
  323. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +27 -0
  324. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +32 -0
  325. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +32 -0
  326. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +27 -0
  327. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +27 -0
  328. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +41 -0
  329. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +34 -0
  330. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +33 -0
  331. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +39 -0
  332. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +36 -0
  333. data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +32 -0
  334. data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +23 -0
  335. data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +13 -0
  336. data/spec/support/server_selection_rtt.rb +41 -0
  337. data/spec/support/shared/bulk_write.rb +498 -0
  338. data/spec/support/shared/cursor.rb +38 -0
  339. data/spec/support/shared/operation.rb +77 -0
  340. data/spec/support/shared/protocol.rb +31 -0
  341. data/spec/support/shared/server_selector.rb +111 -0
  342. data/spec/support/shared/socket.rb +82 -0
  343. data/spec/support/travis.rb +14 -0
  344. metadata +523 -189
  345. metadata.gz.sig +0 -0
  346. data/VERSION +0 -1
  347. data/lib/mongo/bulk_write_collection_view.rb +0 -387
  348. data/lib/mongo/collection_writer.rb +0 -364
  349. data/lib/mongo/connection/node.rb +0 -249
  350. data/lib/mongo/connection/pool.rb +0 -340
  351. data/lib/mongo/connection/pool_manager.rb +0 -320
  352. data/lib/mongo/connection/sharding_pool_manager.rb +0 -67
  353. data/lib/mongo/connection/socket/ssl_socket.rb +0 -95
  354. data/lib/mongo/connection/socket/tcp_socket.rb +0 -87
  355. data/lib/mongo/connection/socket/unix_socket.rb +0 -39
  356. data/lib/mongo/db.rb +0 -808
  357. data/lib/mongo/exception.rb +0 -145
  358. data/lib/mongo/functional/authentication.rb +0 -455
  359. data/lib/mongo/functional/logging.rb +0 -85
  360. data/lib/mongo/functional/read_preference.rb +0 -183
  361. data/lib/mongo/functional/scram.rb +0 -556
  362. data/lib/mongo/functional/uri_parser.rb +0 -409
  363. data/lib/mongo/functional/write_concern.rb +0 -66
  364. data/lib/mongo/gridfs/grid.rb +0 -112
  365. data/lib/mongo/gridfs/grid_ext.rb +0 -53
  366. data/lib/mongo/gridfs/grid_file_system.rb +0 -163
  367. data/lib/mongo/gridfs/grid_io.rb +0 -484
  368. data/lib/mongo/legacy.rb +0 -140
  369. data/lib/mongo/mongo_client.rb +0 -697
  370. data/lib/mongo/mongo_replica_set_client.rb +0 -535
  371. data/lib/mongo/mongo_sharded_client.rb +0 -159
  372. data/lib/mongo/networking.rb +0 -372
  373. data/lib/mongo/utils/conversions.rb +0 -110
  374. data/lib/mongo/utils/core_ext.rb +0 -70
  375. data/lib/mongo/utils/server_version.rb +0 -69
  376. data/lib/mongo/utils/support.rb +0 -80
  377. data/test/functional/authentication_test.rb +0 -39
  378. data/test/functional/bulk_api_stress_test.rb +0 -133
  379. data/test/functional/bulk_write_collection_view_test.rb +0 -1198
  380. data/test/functional/client_test.rb +0 -627
  381. data/test/functional/collection_test.rb +0 -2175
  382. data/test/functional/collection_writer_test.rb +0 -83
  383. data/test/functional/conversions_test.rb +0 -163
  384. data/test/functional/cursor_fail_test.rb +0 -57
  385. data/test/functional/cursor_message_test.rb +0 -56
  386. data/test/functional/cursor_test.rb +0 -683
  387. data/test/functional/db_api_test.rb +0 -835
  388. data/test/functional/db_test.rb +0 -348
  389. data/test/functional/grid_file_system_test.rb +0 -285
  390. data/test/functional/grid_io_test.rb +0 -252
  391. data/test/functional/grid_test.rb +0 -273
  392. data/test/functional/pool_test.rb +0 -136
  393. data/test/functional/safe_test.rb +0 -98
  394. data/test/functional/support_test.rb +0 -62
  395. data/test/functional/timeout_test.rb +0 -60
  396. data/test/functional/uri_test.rb +0 -446
  397. data/test/functional/write_concern_test.rb +0 -118
  398. data/test/helpers/general.rb +0 -50
  399. data/test/helpers/test_unit.rb +0 -476
  400. data/test/replica_set/authentication_test.rb +0 -37
  401. data/test/replica_set/basic_test.rb +0 -189
  402. data/test/replica_set/client_test.rb +0 -393
  403. data/test/replica_set/connection_test.rb +0 -138
  404. data/test/replica_set/count_test.rb +0 -66
  405. data/test/replica_set/cursor_test.rb +0 -220
  406. data/test/replica_set/insert_test.rb +0 -157
  407. data/test/replica_set/max_values_test.rb +0 -151
  408. data/test/replica_set/pinning_test.rb +0 -105
  409. data/test/replica_set/query_test.rb +0 -73
  410. data/test/replica_set/read_preference_test.rb +0 -219
  411. data/test/replica_set/refresh_test.rb +0 -211
  412. data/test/replica_set/replication_ack_test.rb +0 -95
  413. data/test/sharded_cluster/basic_test.rb +0 -203
  414. data/test/shared/authentication/basic_auth_shared.rb +0 -260
  415. data/test/shared/authentication/bulk_api_auth_shared.rb +0 -249
  416. data/test/shared/authentication/gssapi_shared.rb +0 -176
  417. data/test/shared/authentication/sasl_plain_shared.rb +0 -96
  418. data/test/shared/authentication/scram_shared.rb +0 -92
  419. data/test/shared/ssl_shared.rb +0 -235
  420. data/test/test_helper.rb +0 -61
  421. data/test/threading/basic_test.rb +0 -120
  422. data/test/tools/mongo_config.rb +0 -708
  423. data/test/tools/mongo_config_test.rb +0 -160
  424. data/test/unit/client_test.rb +0 -381
  425. data/test/unit/collection_test.rb +0 -166
  426. data/test/unit/connection_test.rb +0 -335
  427. data/test/unit/cursor_test.rb +0 -307
  428. data/test/unit/db_test.rb +0 -136
  429. data/test/unit/grid_test.rb +0 -76
  430. data/test/unit/mongo_sharded_client_test.rb +0 -48
  431. data/test/unit/node_test.rb +0 -93
  432. data/test/unit/pool_manager_test.rb +0 -111
  433. data/test/unit/read_pref_test.rb +0 -406
  434. data/test/unit/read_test.rb +0 -159
  435. data/test/unit/safe_test.rb +0 -158
  436. data/test/unit/sharding_pool_manager_test.rb +0 -84
  437. data/test/unit/write_concern_test.rb +0 -175
@@ -0,0 +1,41 @@
1
+ ---
2
+ topology_description:
3
+ type: ReplicaSetWithPrimary
4
+ servers:
5
+ - &1
6
+ address: b:27017
7
+ avg_rtt_ms: 5
8
+ type: RSSecondary
9
+ tag_sets:
10
+ - data_center: nyc
11
+ - &2
12
+ address: c:27017
13
+ avg_rtt_ms: 100
14
+ type: RSSecondary
15
+ tag_sets:
16
+ - data_center: nyc
17
+ - &3
18
+ address: a:27017
19
+ avg_rtt_ms: 26
20
+ type: RSPrimary
21
+ tag_sets:
22
+ - data_center: nyc
23
+ operation: read
24
+ read_preference:
25
+ mode: Nearest
26
+ tag_sets:
27
+ - data_center: nyc
28
+ candidate_servers:
29
+ - *1
30
+ - *2
31
+ - *3
32
+ eligible_servers:
33
+ - *1
34
+ - *2
35
+ - *3
36
+ suitable_servers:
37
+ - *1
38
+ - *3
39
+ - *2
40
+ in_latency_window:
41
+ - *1
@@ -0,0 +1,34 @@
1
+ ---
2
+ topology_description:
3
+ type: ReplicaSetWithPrimary
4
+ servers:
5
+ - &1
6
+ address: b:27017
7
+ avg_rtt_ms: 5
8
+ type: RSSecondary
9
+ tag_sets:
10
+ - data_center: nyc
11
+ - &2
12
+ address: c:27017
13
+ avg_rtt_ms: 100
14
+ type: RSSecondary
15
+ tag_sets:
16
+ - data_center: nyc
17
+ - &3
18
+ address: a:27017
19
+ avg_rtt_ms: 26
20
+ type: RSPrimary
21
+ tag_sets:
22
+ - data_center: nyc
23
+ operation: read
24
+ read_preference:
25
+ mode: Nearest
26
+ tag_sets:
27
+ - data_center: sf
28
+ candidate_servers:
29
+ - *1
30
+ - *2
31
+ - *3
32
+ eligible_servers: []
33
+ suitable_servers: []
34
+ in_latency_window: []
@@ -0,0 +1,33 @@
1
+ ---
2
+ topology_description:
3
+ type: ReplicaSetWithPrimary
4
+ servers:
5
+ - address: b:27017
6
+ avg_rtt_ms: 5
7
+ type: RSSecondary
8
+ tag_sets:
9
+ - data_center: nyc
10
+ - address: c:27017
11
+ avg_rtt_ms: 100
12
+ type: RSSecondary
13
+ tag_sets:
14
+ - data_center: nyc
15
+ - &1
16
+ address: a:27017
17
+ avg_rtt_ms: 26
18
+ type: RSPrimary
19
+ tag_sets:
20
+ - data_center: nyc
21
+ operation: read
22
+ read_preference:
23
+ mode: Primary
24
+ tag_sets:
25
+ - {}
26
+ candidate_servers:
27
+ - *1
28
+ eligible_servers:
29
+ - *1
30
+ suitable_servers:
31
+ - *1
32
+ in_latency_window:
33
+ - *1
@@ -0,0 +1,39 @@
1
+ ---
2
+ topology_description:
3
+ type: ReplicaSetWithPrimary
4
+ servers:
5
+ - &1
6
+ address: b:27017
7
+ avg_rtt_ms: 5
8
+ type: RSSecondary
9
+ tag_sets:
10
+ - data_center: nyc
11
+ - &2
12
+ address: c:27017
13
+ avg_rtt_ms: 100
14
+ type: RSSecondary
15
+ tag_sets:
16
+ - data_center: nyc
17
+ - &3
18
+ address: a:27017
19
+ avg_rtt_ms: 26
20
+ type: RSPrimary
21
+ tag_sets:
22
+ - data_center: nyc
23
+ operation: read
24
+ read_preference:
25
+ mode: PrimaryPreferred
26
+ tag_sets:
27
+ - {}
28
+ candidate_servers:
29
+ - *1
30
+ - *2
31
+ - *3
32
+ eligible_servers:
33
+ - *1
34
+ - *2
35
+ - *3
36
+ suitable_servers:
37
+ - *3
38
+ in_latency_window:
39
+ - *3
@@ -0,0 +1,36 @@
1
+ ---
2
+ topology_description:
3
+ type: ReplicaSetWithPrimary
4
+ servers:
5
+ - &1
6
+ address: b:27017
7
+ avg_rtt_ms: 5
8
+ type: RSSecondary
9
+ tag_sets:
10
+ - data_center: nyc
11
+ - &2
12
+ address: c:27017
13
+ avg_rtt_ms: 100
14
+ type: RSSecondary
15
+ tag_sets:
16
+ - data_center: nyc
17
+ - &3
18
+ address: a:27017
19
+ avg_rtt_ms: 26
20
+ type: RSPrimary
21
+ tag_sets:
22
+ - data_center: nyc
23
+ operation: read
24
+ read_preference:
25
+ mode: PrimaryPreferred
26
+ tag_sets:
27
+ - data_center: sf
28
+ candidate_servers:
29
+ - *1
30
+ - *2
31
+ - *3
32
+ eligible_servers: []
33
+ suitable_servers:
34
+ - *3
35
+ in_latency_window:
36
+ - *3
@@ -0,0 +1,32 @@
1
+ ---
2
+ topology_description:
3
+ type: Sharded
4
+ servers:
5
+ - &1
6
+ address: g:27017
7
+ avg_rtt_ms: 5
8
+ type: Mongos
9
+ tag_sets:
10
+ - data_center: nyc
11
+ - &2
12
+ address: h:27017
13
+ avg_rtt_ms: 35
14
+ type: Mongos
15
+ tag_sets:
16
+ - data_center: dc
17
+ operation: read
18
+ read_preference:
19
+ mode: SecondaryPreferred
20
+ tag_sets:
21
+ - data_center: nyc
22
+ candidate_servers:
23
+ - *1
24
+ - *2
25
+ eligible_servers:
26
+ - *1
27
+ - *2
28
+ suitable_servers:
29
+ - *1
30
+ - *2
31
+ in_latency_window:
32
+ - *1
@@ -0,0 +1,23 @@
1
+ ---
2
+ topology_description:
3
+ type: Single
4
+ servers:
5
+ - &1
6
+ address: a:27017
7
+ avg_rtt_ms: 5
8
+ type: Standalone
9
+ tag_sets:
10
+ - data_center: dc
11
+ operation: read
12
+ read_preference:
13
+ mode: SecondaryPreferred
14
+ tag_sets:
15
+ - data_center: nyc
16
+ candidate_servers:
17
+ - *1
18
+ eligible_servers:
19
+ - *1
20
+ suitable_servers:
21
+ - *1
22
+ in_latency_window:
23
+ - *1
@@ -0,0 +1,13 @@
1
+ ---
2
+ topology_description:
3
+ type: Unknown
4
+ servers: []
5
+ operation: read
6
+ read_preference:
7
+ mode: SecondaryPreferred
8
+ tag_sets:
9
+ - data_center: nyc
10
+ candidate_servers: []
11
+ eligible_servers: []
12
+ suitable_servers: []
13
+ in_latency_window: []
@@ -0,0 +1,41 @@
1
+ module Mongo
2
+ module ServerSelection
3
+ module RTT
4
+
5
+ # Represents a specification.
6
+ #
7
+ # @since 2.0.0
8
+ class Spec
9
+
10
+ # @return [ String ] description The spec description.
11
+ attr_reader :description
12
+
13
+ # @return [ Float ] avg_rtt_ms The starting average round trip time.
14
+ attr_reader :avg_rtt_ms
15
+
16
+ # @return [ Float ] new_rtt_ms The new round trip time for ismaster.
17
+ attr_reader :new_rtt_ms
18
+
19
+ # @return [ Float ] new_avg_rtt The newly calculated moving average round trip time.
20
+ attr_reader :new_avg_rtt
21
+
22
+ # Instantiate the new spec.
23
+ #
24
+ # @example Create the spec.
25
+ # Spec.new(file)
26
+ #
27
+ # @param [ String ] file The name of the file.
28
+ #
29
+ # @since 2.0.0
30
+ def initialize(file)
31
+ @test = YAML.load(ERB.new(File.new(file).read).result)
32
+ @description = "avg_rtt_ms: #{@test['avg_rtt_ms']}, new_rtt_ms: #{@test['new_rtt_ms']}," +
33
+ " new_avg_rtt: #{@test['new_avg_rtt']}"
34
+ @avg_rtt_ms = @test['avg_rtt_ms'] == 'NULL' ? nil : @test['avg_rtt_ms'].to_f
35
+ @new_rtt_ms = @test['new_rtt_ms'].to_f
36
+ @new_avg_rtt = @test['new_avg_rtt'].to_f
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,498 @@
1
+ shared_examples 'a bulk write object' do
2
+
3
+ context 'when no operations are provided' do
4
+
5
+ let(:operations) {[]}
6
+
7
+ it 'raises an error' do
8
+ expect {
9
+ bulk.execute
10
+ }.to raise_error(Mongo::Error::EmptyBatch)
11
+ end
12
+ end
13
+
14
+ context 'when invalid operations are provided' do
15
+
16
+ let(:operations) do
17
+ [{ :not_an_op => {}}]
18
+ end
19
+
20
+ it 'raises an error' do
21
+ expect {
22
+ bulk.execute
23
+ }.to raise_error(Mongo::Error::InvalidBulkOperation)
24
+ end
25
+ end
26
+
27
+ context 'when an insert_one operation is provided' do
28
+
29
+ context 'when a document is provided' do
30
+
31
+ let(:operations) do
32
+ [{ insert_one: { name: 'test' }}]
33
+ end
34
+
35
+ it 'returns nInserted of 1' do
36
+ expect(bulk.execute['nInserted']).to eq(1)
37
+ end
38
+
39
+ it 'only inserts that document' do
40
+ bulk.execute
41
+ expect(authorized_collection.find.first['name']).to eq('test')
42
+ end
43
+ end
44
+
45
+ context 'when an invalid object is provided' do
46
+
47
+ let(:operations) do
48
+ [{ insert_one: [] }]
49
+ end
50
+
51
+ it 'raises an exception' do
52
+ expect {
53
+ bulk.execute
54
+ }.to raise_error(Mongo::Error::InvalidDocument)
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'delete_one' do
60
+
61
+ let(:docs) do
62
+ [ { a: 1 }, { a: 1 } ]
63
+ end
64
+
65
+ let(:expected) do
66
+ [{ 'a' => 1 }]
67
+ end
68
+
69
+ before do
70
+ authorized_collection.insert_many(docs)
71
+ end
72
+
73
+ let(:operations) do
74
+ [{ delete_one: { a: 1 }}]
75
+ end
76
+
77
+ context 'when no selector is specified' do
78
+
79
+ let(:operations) do
80
+ [{ delete_one: nil }]
81
+ end
82
+
83
+ it 'raises an exception' do
84
+ expect {
85
+ bulk.execute
86
+ }.to raise_exception(Mongo::Error::InvalidDocument)
87
+ end
88
+ end
89
+
90
+ context 'when multiple documents match delete selector' do
91
+
92
+ it 'reports nRemoved correctly' do
93
+ expect(bulk.execute['nRemoved']).to eq(1)
94
+ end
95
+
96
+ it 'deletes only matching documents' do
97
+ bulk.execute
98
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
99
+ end
100
+ end
101
+ end
102
+
103
+ context 'when a delete_many operation is provided' do
104
+
105
+ let(:docs) do
106
+ [{ a: 1 }, { a: 1 }]
107
+ end
108
+
109
+ before do
110
+ authorized_collection.insert_many(docs)
111
+ end
112
+
113
+ let(:operations) do
114
+ [{ delete_many: { a: 1 }}]
115
+ end
116
+
117
+ context 'when no selector is specified' do
118
+
119
+ let(:operations) do
120
+ [{ delete_many: nil }]
121
+ end
122
+
123
+ it 'raises an exception' do
124
+ expect {
125
+ bulk.execute
126
+ }.to raise_exception(Mongo::Error::InvalidDocument)
127
+ end
128
+ end
129
+
130
+ context 'when a selector is specified' do
131
+
132
+ context 'when multiple documents match delete selector' do
133
+
134
+ it 'reports nRemoved correctly' do
135
+ expect(bulk.execute['nRemoved']).to eq(2)
136
+ end
137
+
138
+ it 'deletes all matching documents' do
139
+ bulk.execute
140
+ expect(authorized_collection.find.to_a).to be_empty
141
+ end
142
+ end
143
+
144
+ context 'when only one document matches delete selector' do
145
+
146
+ let(:docs) do
147
+ [{ a: 1 }, { a: 2 }]
148
+ end
149
+
150
+ let(:expected) do
151
+ [{ 'a' => 2 }]
152
+ end
153
+
154
+ it 'reports nRemoved correctly' do
155
+ expect(bulk.execute['nRemoved']).to eq(1)
156
+ end
157
+
158
+ it 'deletes all matching documents' do
159
+ bulk.execute
160
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ context 'when a replace_one operation is provided' do
167
+
168
+ let(:docs) do
169
+ [{ a: 1 }, { a: 1 }]
170
+ end
171
+
172
+ let(:expected) do
173
+ [{ 'a' => 2 }, { 'a' => 1 }]
174
+ end
175
+
176
+ before do
177
+ authorized_collection.insert_many(docs)
178
+ end
179
+
180
+ let(:replacement) do
181
+ { a: 2 }
182
+ end
183
+
184
+ let(:operations) do
185
+ [{ replace_one: [{ a: 1 }, replacement ]}]
186
+ end
187
+
188
+ context 'when a replace document is not specified' do
189
+
190
+ let(:operations) do
191
+ [{ replace_one: [{ a: 1 }]}]
192
+ end
193
+
194
+ it 'raises an exception' do
195
+ expect {
196
+ bulk.execute
197
+ }.to raise_exception(ArgumentError)
198
+ end
199
+ end
200
+
201
+ context 'when there are $-operator top-level keys' do
202
+
203
+ let(:replacement) do
204
+ { :$set => { a: 3 }}
205
+ end
206
+
207
+ it 'raises an exception' do
208
+ expect {
209
+ bulk.execute
210
+ }.to raise_exception(Mongo::Error::InvalidReplacementDocument)
211
+ end
212
+
213
+ end
214
+
215
+ context 'when a replace document is specified' do
216
+
217
+ it 'applies the replacement to only one matching document' do
218
+ bulk.execute
219
+ expect(authorized_collection.find(replacement).count).to eq(1)
220
+ end
221
+
222
+ it 'reports nMatched correctly' do
223
+ expect(bulk.execute['nMatched']).to eq(1)
224
+ end
225
+
226
+ it 'only applies the replacement to one matching document' do
227
+ bulk.execute
228
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
229
+ end
230
+
231
+ context 'when upsert is true' do
232
+
233
+ let(:operations) do
234
+ [{ replace_one: [{ a: 4 }, replacement, { :upsert => true }]}]
235
+ end
236
+
237
+ let(:expected) do
238
+ [{ 'a' => 1 }, { 'a' => 1 }, { 'a' => 2 }]
239
+ end
240
+
241
+ it 'upserts the replacement document' do
242
+ bulk.execute
243
+ expect(authorized_collection.find(replacement).count).to eq(1)
244
+ end
245
+
246
+ it 'reports nMatched correctly' do
247
+ expect(bulk.execute['nMatched']).to eq(0)
248
+ end
249
+
250
+ it 'does not replace any documents' do
251
+ bulk.execute
252
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ context 'when an update_one operation is provided' do
259
+
260
+ let(:docs) do
261
+ [{ a: 1 }, { a: 1 }]
262
+ end
263
+
264
+ let(:update) do
265
+ { :$set => { a: 2 }}
266
+ end
267
+
268
+ let(:operations) do
269
+ [{ update_one: [{ a: 1 }, update ]}]
270
+ end
271
+
272
+ before do
273
+ authorized_collection.insert_many(docs)
274
+ end
275
+
276
+ let(:expected) do
277
+ [{ 'a' => 2 }, { 'a' => 1 }]
278
+ end
279
+
280
+ context 'when an update document is not specified' do
281
+
282
+ let(:operations) do
283
+ [{ update_one: [{ a: 1 }]}]
284
+ end
285
+
286
+ it 'raises an exception' do
287
+ expect {
288
+ bulk.execute
289
+ }.to raise_exception(ArgumentError)
290
+ end
291
+ end
292
+
293
+ context 'when an invalid update document is specified' do
294
+
295
+ let(:update) do
296
+ { a: 2 }
297
+ end
298
+
299
+ it 'raises an exception' do
300
+ expect {
301
+ bulk.execute
302
+ }.to raise_exception(Mongo::Error::InvalidUpdateDocument)
303
+ end
304
+ end
305
+
306
+ context 'when a valid update document is specified' do
307
+
308
+ it 'reports nModified correctly', if: write_command_enabled? do
309
+ expect(bulk.execute['nModified']).to eq(1)
310
+ end
311
+
312
+ it 'reports nModified correctly', unless: write_command_enabled? do
313
+ expect(bulk.execute['nModified']).to eq(nil)
314
+ end
315
+
316
+ it 'reports nUpserted correctly' do
317
+ expect(bulk.execute['nUpserted']).to eq(0)
318
+ end
319
+
320
+ it 'reports nMatched correctly' do
321
+ expect(bulk.execute['nMatched']).to eq(1)
322
+ end
323
+
324
+ it 'applies the correct writes' do
325
+ bulk.execute
326
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
327
+ end
328
+
329
+ context 'when upsert is true' do
330
+
331
+ let(:operations) do
332
+ [{ update_one: [{ a: 3 }, update, { upsert: true }]}]
333
+ end
334
+
335
+ let(:expected) do
336
+ [{ 'a' => 1 }, { 'a' => 1 }, { 'a' => 2 }]
337
+ end
338
+
339
+ it 'reports nModified correctly', if: write_command_enabled? do
340
+ expect(bulk.execute['nModified']).to eq(0)
341
+ end
342
+
343
+ it 'reports nModified correctly', unless: write_command_enabled? do
344
+ expect(bulk.execute['nModified']).to eq(nil)
345
+ end
346
+
347
+ it 'reports nUpserted correctly' do
348
+ expect(bulk.execute['nUpserted']).to eq(1)
349
+ end
350
+
351
+ it 'reports nMatched correctly' do
352
+ expect(bulk.execute['nMatched']).to eq(0)
353
+ end
354
+
355
+ it 'applies the correct writes' do
356
+ bulk.execute
357
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
358
+ end
359
+ end
360
+ end
361
+ end
362
+
363
+ context 'when an update_many operation is provided' do
364
+
365
+ let(:docs) do
366
+ [{ a: 1 }, { a: 1 }]
367
+ end
368
+
369
+ let(:update) do
370
+ { :$set => { a: 2 }}
371
+ end
372
+
373
+ let(:operations) do
374
+ [{ update_many: [{ a: 1 }, update ]}]
375
+ end
376
+
377
+ let(:expected) do
378
+ [{ 'a' => 2 }, { 'a' => 2 }]
379
+ end
380
+
381
+ before do
382
+ authorized_collection.insert_many(docs)
383
+ end
384
+
385
+ context 'when an update document is not specified' do
386
+
387
+ let(:operations) do
388
+ [{ update_many: [{ a: 1 }]}]
389
+ end
390
+
391
+ it 'raises an exception' do
392
+ expect do
393
+ bulk.execute
394
+ end.to raise_exception(ArgumentError)
395
+ end
396
+ end
397
+
398
+ context 'when an invalid update document is specified' do
399
+
400
+ let(:update) do
401
+ { a: 2 }
402
+ end
403
+
404
+ it 'raises an exception' do
405
+ expect do
406
+ bulk.execute
407
+ end.to raise_exception(Mongo::Error::InvalidUpdateDocument)
408
+ end
409
+ end
410
+
411
+ context 'when a valid update document is specified' do
412
+
413
+ it 'reports nModified correctly', if: write_command_enabled? do
414
+ expect(bulk.execute['nModified']).to eq(2)
415
+ end
416
+
417
+ it 'reports nModified correctly', unless: write_command_enabled? do
418
+ expect(bulk.execute['nModified']).to eq(nil)
419
+ end
420
+
421
+ it 'reports nUpserted correctly' do
422
+ expect(bulk.execute['nUpserted']).to eq(0)
423
+ end
424
+
425
+ it 'reports nMatched correctly' do
426
+ expect(bulk.execute['nMatched']).to eq(2)
427
+ end
428
+
429
+ it 'applies the correct writes' do
430
+ bulk.execute
431
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
432
+ end
433
+
434
+ context 'when upsert is true' do
435
+
436
+ let(:operations) do
437
+ [{ update_one: [{ a: 3 }, update, { upsert: true }]}]
438
+ end
439
+
440
+ let(:expected) do
441
+ [ { 'a' => 1 }, { 'a' => 1 }, { 'a' => 2 } ]
442
+ end
443
+
444
+ it 'reports nModified correctly', if: write_command_enabled? do
445
+ expect(bulk.execute['nModified']).to eq(0)
446
+ end
447
+
448
+ it 'reports nModified correctly', unless: write_command_enabled? do
449
+ expect(bulk.execute['nModified']).to eq(nil)
450
+ end
451
+
452
+ it 'reports nUpserted correctly' do
453
+ expect(bulk.execute['nUpserted']).to eq(1)
454
+ end
455
+
456
+ it 'reports nMatched correctly' do
457
+ expect(bulk.execute['nMatched']).to eq(0)
458
+ end
459
+
460
+ it 'applies the correct writes' do
461
+ bulk.execute
462
+ expect(authorized_collection.find.projection(_id: 0).to_a).to eq(expected)
463
+ end
464
+ end
465
+ end
466
+ end
467
+
468
+ context 'when the operations need to be split' do
469
+
470
+ before do
471
+ authorized_collection.find.remove_many
472
+ 6000.times do |i|
473
+ authorized_collection.insert_one(x: i)
474
+ end
475
+ end
476
+
477
+ let(:operations) do
478
+ [].tap do |ops|
479
+ 3000.times do |i|
480
+ ops << { :update_one => [ { x: i },
481
+ {'$set' => { x: 6000-i } }]
482
+ }
483
+ end
484
+ ops << { :insert_one => { test: 'emily' } }
485
+ 3000.times do |i|
486
+ ops << { :update_one => [ { x: 3000+i },
487
+ {'$set' => { x: 3000-i } }]
488
+ }
489
+ end
490
+ end
491
+ end
492
+
493
+ it 'completes all operations' do
494
+ bulk.execute
495
+ expect(authorized_collection.find(x: { '$lte' => 3000 }).to_a.size).to eq(3000)
496
+ end
497
+ end
498
+ end