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,196 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::ServerSelector::Secondary do
4
+
5
+ include_context 'server selector'
6
+
7
+ it_behaves_like 'a read preference mode' do
8
+ let(:name) { :secondary }
9
+ let(:slave_ok) { true }
10
+ end
11
+
12
+ it_behaves_like 'a read preference mode accepting tag sets'
13
+
14
+ describe '#to_mongos' do
15
+
16
+ it 'returns read preference formatted for mongos' do
17
+ expect(read_pref.to_mongos).to eq(
18
+ { :mode => 'secondary' }
19
+ )
20
+ end
21
+
22
+ context 'tag sets provided' do
23
+ let(:tag_sets) { [tag_set] }
24
+
25
+ it 'returns read preference formatted for mongos with tag sets' do
26
+ expect(read_pref.to_mongos).to eq(
27
+ { :mode => 'secondary', :tags => tag_sets}
28
+ )
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#select' do
34
+
35
+ context 'no candidates' do
36
+ let(:candidates) { [] }
37
+
38
+ it 'returns an empty array' do
39
+ expect(read_pref.send(:select, candidates)).to be_empty
40
+ end
41
+ end
42
+
43
+ context 'single primary candidate' do
44
+ let(:candidates) { [primary] }
45
+
46
+ it 'returns an empty array' do
47
+ expect(read_pref.send(:select, candidates)).to be_empty
48
+ end
49
+ end
50
+
51
+ context 'single secondary candidate' do
52
+ let(:candidates) { [secondary] }
53
+
54
+ it 'returns array with secondary' do
55
+ expect(read_pref.send(:select, candidates)).to eq([secondary])
56
+ end
57
+ end
58
+
59
+ context 'primary and secondary candidates' do
60
+ let(:candidates) { [primary, secondary] }
61
+
62
+ it 'returns array with secondary' do
63
+ expect(read_pref.send(:select, candidates)).to eq([secondary])
64
+ end
65
+ end
66
+
67
+ context 'multiple secondary candidates' do
68
+ let(:candidates) { [secondary, secondary, primary] }
69
+
70
+ it 'returns array with all secondaries' do
71
+ expect(read_pref.send(:select, candidates)).to eq([secondary, secondary])
72
+ end
73
+ end
74
+
75
+ context 'tag sets provided' do
76
+ let(:tag_sets) { [tag_set] }
77
+ let(:matching_secondary) { server(:secondary, :tags => server_tags) }
78
+
79
+ context 'single candidate' do
80
+
81
+ context 'primary' do
82
+ let(:candidates) { [primary] }
83
+
84
+ it 'returns an empty array' do
85
+ expect(read_pref.send(:select, candidates)).to be_empty
86
+ end
87
+ end
88
+
89
+ context 'secondary' do
90
+ let(:candidates) { [secondary] }
91
+
92
+ it 'returns an empty array' do
93
+ expect(read_pref.send(:select, candidates)).to be_empty
94
+ end
95
+ end
96
+
97
+ context 'matching secondary' do
98
+ let(:candidates) { [matching_secondary] }
99
+
100
+ it 'returns an array with matching secondary' do
101
+ expect(read_pref.send(:select, candidates)).to eq([matching_secondary])
102
+ end
103
+ end
104
+ end
105
+
106
+ context 'multiple candidates' do
107
+
108
+ context 'no matching candidates' do
109
+ let(:candidates) { [primary, secondary, secondary] }
110
+
111
+ it 'returns an emtpy array' do
112
+ expect(read_pref.send(:select, candidates)).to be_empty
113
+ end
114
+ end
115
+
116
+ context 'one matching secondary' do
117
+ let(:candidates) { [secondary, matching_secondary]}
118
+
119
+ it 'returns array with matching secondary' do
120
+ expect(read_pref.send(:select, candidates)).to eq([matching_secondary])
121
+ end
122
+ end
123
+
124
+ context 'two matching secondaries' do
125
+ let(:candidates) { [matching_secondary, matching_secondary] }
126
+
127
+ it 'returns an array with both matching secondaries' do
128
+ expect(read_pref.send(:select, candidates)).to eq([matching_secondary, matching_secondary])
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ context 'high latency servers' do
135
+ let(:far_primary) { server(:primary, :average_round_trip_time => 100) }
136
+ let(:far_secondary) { server(:secondary, :average_round_trip_time => 113) }
137
+
138
+ context 'single candidate' do
139
+
140
+ context 'far primary' do
141
+ let(:candidates) { [far_primary] }
142
+
143
+ it 'returns an empty array' do
144
+ expect(read_pref.send(:select, candidates)).to be_empty
145
+ end
146
+ end
147
+
148
+ context 'far secondary' do
149
+ let(:candidates) { [far_secondary] }
150
+
151
+ it 'returns an array with the secondary' do
152
+ expect(read_pref.send(:select, candidates)).to eq([far_secondary])
153
+ end
154
+ end
155
+ end
156
+
157
+ context 'multiple candidates' do
158
+
159
+ context 'local primary, far secondary' do
160
+ let(:candidates) { [primary, far_secondary] }
161
+
162
+ it 'returns an array with the secondary' do
163
+ expect(read_pref.send(:select, candidates)).to eq([far_secondary])
164
+ end
165
+ end
166
+
167
+ context 'far primary, far secondary' do
168
+ let(:candidates) { [far_primary, far_secondary] }
169
+
170
+ it 'returns an array with the secondary' do
171
+ expect(read_pref.send(:select, candidates)).to eq([far_secondary])
172
+ end
173
+ end
174
+
175
+ context 'two near servers, one far server' do
176
+
177
+ context 'near primary, near and far secondaries' do
178
+ let(:candidates) { [primary, secondary, far_secondary] }
179
+
180
+ it 'returns an array with near secondary' do
181
+ expect(read_pref.send(:select, candidates)).to eq([secondary])
182
+ end
183
+ end
184
+
185
+ context 'far primary and two near secondaries' do
186
+ let(:candidates) { [far_primary, secondary, secondary] }
187
+
188
+ it 'returns an array with two secondaries' do
189
+ expect(read_pref.send(:select, candidates)).to eq([secondary, secondary])
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::ServerSelector do
4
+
5
+ include_context 'server selector'
6
+
7
+ describe '.get' do
8
+
9
+ let(:read_pref) do
10
+ described_class.get({ :mode => name })
11
+ end
12
+
13
+ let(:name) { :secondary }
14
+ let(:tag_sets) { [{ 'test' => 'tag' }] }
15
+
16
+ context 'when the mode is primary' do
17
+ let(:name) { :primary }
18
+
19
+ it 'returns a read preference of class Primary' do
20
+ expect(read_pref).to be_a(Mongo::ServerSelector::Primary)
21
+ end
22
+ end
23
+
24
+ context 'when the mode is primary_preferred' do
25
+ let(:name) { :primary_preferred }
26
+
27
+ it 'returns a read preference of class PrimaryPreferred' do
28
+ expect(read_pref).to be_a(Mongo::ServerSelector::PrimaryPreferred)
29
+ end
30
+ end
31
+
32
+ context 'when the mode is secondary' do
33
+ let(:name) { :secondary }
34
+
35
+ it 'returns a read preference of class Secondary' do
36
+ expect(read_pref).to be_a(Mongo::ServerSelector::Secondary)
37
+ end
38
+ end
39
+
40
+ context 'when the mode is secondary_preferred' do
41
+ let(:name) { :secondary_preferred }
42
+
43
+ it 'returns a read preference of class SecondaryPreferred' do
44
+ expect(read_pref).to be_a(Mongo::ServerSelector::SecondaryPreferred)
45
+ end
46
+ end
47
+
48
+ context 'when the mode is nearest' do
49
+ let(:name) { :nearest }
50
+
51
+ it 'returns a read preference of class Nearest' do
52
+ expect(read_pref).to be_a(Mongo::ServerSelector::Nearest)
53
+ end
54
+ end
55
+
56
+ context 'when a mode is not provided' do
57
+ let(:read_pref) { described_class.get }
58
+
59
+ it 'returns a read preference of class Primary' do
60
+ expect(read_pref).to be_a(Mongo::ServerSelector::Primary)
61
+ end
62
+ end
63
+
64
+ context 'when tag sets provided' do
65
+ let(:read_pref) { described_class.get(:mode => name, :tag_sets => tag_sets) }
66
+
67
+ it 'sets tag sets on the read preference object' do
68
+ expect(read_pref.tag_sets).to eq(tag_sets)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#select_server" do
74
+
75
+ context 'when #select returns a list of nils' do
76
+
77
+ let(:servers) { [ server(:primary) ] }
78
+
79
+ let(:cluster) do
80
+ double('cluster').tap do |c|
81
+ allow(c).to receive(:servers).and_return(servers)
82
+ allow(c).to receive(:standalone?).and_return(false)
83
+ allow(c).to receive(:sharded?).and_return(false)
84
+ allow(c).to receive(:scan!).and_return(true)
85
+ end
86
+ end
87
+
88
+ let(:read_pref) do
89
+ described_class.get({ mode: :primary }, server_selection_timeout: 1).tap do |pref|
90
+ allow(pref).to receive(:select).and_return([ nil, nil ])
91
+ end
92
+ end
93
+
94
+ it 'raises a NoServerAvailable error' do
95
+ expect do
96
+ read_pref.select_server(cluster)
97
+ end.to raise_exception(Mongo::ServerSelector::NoServerAvailable)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Server do
4
+
5
+ let(:listeners) do
6
+ Mongo::Event::Listeners.new
7
+ end
8
+
9
+ let(:address) do
10
+ Mongo::Address.new('127.0.0.1:27017')
11
+ end
12
+
13
+ describe '#==' do
14
+
15
+ let(:server) do
16
+ described_class.new(address, listeners)
17
+ end
18
+
19
+ context 'when the other is not a server' do
20
+
21
+ let(:other) do
22
+ false
23
+ end
24
+
25
+ it 'returns false' do
26
+ expect(server).to_not eq(other)
27
+ end
28
+ end
29
+
30
+ context 'when the other is a server' do
31
+
32
+ context 'when the addresses match' do
33
+
34
+ let(:other) do
35
+ described_class.new(address, listeners)
36
+ end
37
+
38
+ it 'returns true' do
39
+ expect(server).to eq(other)
40
+ end
41
+ end
42
+
43
+ context 'when the addresses dont match' do
44
+
45
+ let(:other_address) do
46
+ Mongo::Address.new('127.0.0.1:27018')
47
+ end
48
+
49
+ let(:other) do
50
+ described_class.new(other_address, listeners)
51
+ end
52
+
53
+ it 'returns false' do
54
+ expect(server).to_not eq(other)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#context' do
61
+
62
+ let(:server) do
63
+ described_class.new(address, listeners)
64
+ end
65
+
66
+ let(:context) do
67
+ server.context
68
+ end
69
+
70
+ it 'returns a new server context' do
71
+ expect(context.server).to eq(server)
72
+ end
73
+ end
74
+
75
+ describe '#disconnect!' do
76
+
77
+ let(:server) do
78
+ described_class.new(address, listeners)
79
+ end
80
+
81
+ it 'stops the monitor instance' do
82
+ expect(server.instance_variable_get(:@monitor)).to receive(:stop!).and_return(true)
83
+ server.disconnect!
84
+ end
85
+ end
86
+
87
+ describe '#initialize' do
88
+
89
+ let(:server) do
90
+ described_class.new(address, listeners, :heartbeat_frequency => 5)
91
+ end
92
+
93
+ it 'sets the address host' do
94
+ expect(server.address.host).to eq('127.0.0.1')
95
+ end
96
+
97
+ it 'sets the address port' do
98
+ expect(server.address.port).to eq(27017)
99
+ end
100
+
101
+ it 'sets the options' do
102
+ expect(server.options).to eq(:heartbeat_frequency => 5)
103
+ end
104
+ end
105
+
106
+ describe '#pool' do
107
+
108
+ let(:server) do
109
+ described_class.new(address, listeners)
110
+ end
111
+
112
+ let(:pool) do
113
+ server.pool
114
+ end
115
+
116
+ it 'returns the connection pool for the server' do
117
+ expect(pool).to be_a(Mongo::Server::ConnectionPool)
118
+ end
119
+ end
120
+
121
+ describe '#scan!' do
122
+
123
+ let(:server) do
124
+ described_class.new(address, listeners)
125
+ end
126
+
127
+ it 'forces a scan on the monitor' do
128
+ expect(server.scan!).to eq(server.description)
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,517 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::URI do
4
+ let(:scheme) { 'mongodb://' }
5
+ let(:uri) { described_class.new(string) }
6
+
7
+ describe '#initialize' do
8
+ context 'string is not uri' do
9
+ let(:string) { 'tyler' }
10
+ it 'raises an error' do
11
+ expect { uri }.to raise_error(Mongo::URI::Invalid)
12
+ end
13
+ end
14
+ end
15
+
16
+ describe '#servers' do
17
+ let(:string) { "#{scheme}#{servers}" }
18
+
19
+ context 'single server' do
20
+ let(:servers) { 'localhost' }
21
+
22
+ it 'returns an array with the parsed server' do
23
+ expect(uri.servers).to eq([servers])
24
+ end
25
+ end
26
+
27
+ context 'single server with port' do
28
+ let(:servers) { 'localhost:27017' }
29
+
30
+ it 'returns an array with the parsed server' do
31
+ expect(uri.servers).to eq([servers])
32
+ end
33
+ end
34
+
35
+ context 'numerical ipv4 server' do
36
+ let(:servers) { '127.0.0.1' }
37
+
38
+ it 'returns an array with the parsed server' do
39
+ expect(uri.servers).to eq([servers])
40
+ end
41
+ end
42
+
43
+ context 'numerical ipv6 server' do
44
+ let(:servers) { '[::1]:27107' }
45
+
46
+ it 'returns an array with the parsed server' do
47
+ expect(uri.servers).to eq([servers])
48
+ end
49
+ end
50
+
51
+ context 'unix socket server' do
52
+ let(:servers) { '/tmp/mongodb-27017.sock' }
53
+
54
+ it 'returns an array with the parsed server' do
55
+ expect(uri.servers).to eq([servers])
56
+ end
57
+ end
58
+
59
+ context 'multiple servers' do
60
+ let(:servers) { 'localhost,127.0.0.1' }
61
+
62
+ it 'returns an array with the parsed servers' do
63
+ expect(uri.servers).to eq(servers.split(','))
64
+ end
65
+ end
66
+
67
+ context 'multiple servers with ports' do
68
+ let(:servers) { '127.0.0.1:27107,localhost:27018' }
69
+
70
+ it 'returns an array with the parsed servers' do
71
+ expect(uri.servers).to eq(servers.split(','))
72
+ end
73
+ end
74
+ end
75
+
76
+ describe '#client_options' do
77
+
78
+ let(:db) { TEST_DB }
79
+ let(:servers) { 'localhost' }
80
+ let(:string) { "#{scheme}#{credentials}@#{servers}/#{db}" }
81
+ let(:user) { 'tyler' }
82
+ let(:password) { 's3kr4t' }
83
+ let(:credentials) { "#{user}:#{password}" }
84
+
85
+ let(:options) do
86
+ uri.client_options
87
+ end
88
+
89
+ it 'includes the database in the options' do
90
+ expect(options[:database]).to eq(TEST_DB)
91
+ end
92
+
93
+ it 'includes the credentials in the options' do
94
+ expect(options[:user]).to eq(user)
95
+ end
96
+
97
+ it 'includes the options in the options' do
98
+ expect(options[:password]).to eq(password)
99
+ end
100
+ end
101
+
102
+ describe '#credentials' do
103
+ let(:servers) { 'localhost' }
104
+ let(:string) { "#{scheme}#{credentials}@#{servers}" }
105
+ let(:user) { 'tyler' }
106
+
107
+ context 'username provided' do
108
+ let(:credentials) { "#{user}:" }
109
+
110
+ it 'returns the username' do
111
+ expect(uri.credentials[:user]).to eq(user)
112
+ end
113
+ end
114
+
115
+ context 'username and password provided' do
116
+ let(:password) { 's3kr4t' }
117
+ let(:credentials) { "#{user}:#{password}" }
118
+
119
+ it 'returns the username' do
120
+ expect(uri.credentials[:user]).to eq(user)
121
+ end
122
+
123
+ it 'returns the password' do
124
+ expect(uri.credentials[:password]).to eq(password)
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '#database' do
130
+ let(:servers) { 'localhost' }
131
+ let(:string) { "#{scheme}#{servers}/#{db}" }
132
+ let(:db) { TEST_DB }
133
+
134
+ context 'database provided' do
135
+ it 'returns the database name' do
136
+ expect(uri.database).to eq(TEST_DB)
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#options' do
142
+ let(:servers) { 'localhost' }
143
+ let(:string) { "#{scheme}#{servers}/?#{options}" }
144
+
145
+ context 'when no options were provided' do
146
+ let(:string) { "#{scheme}#{servers}" }
147
+
148
+ it 'returns an empty hash' do
149
+ expect(uri.options).to be_empty
150
+ end
151
+ end
152
+
153
+ context 'write concern options provided' do
154
+
155
+ context 'numerical w value' do
156
+ let(:options) { 'w=1' }
157
+ let(:concern) { { :w => 1 } }
158
+
159
+ it 'sets the write concern options' do
160
+ expect(uri.options[:write]).to eq(concern)
161
+ end
162
+ end
163
+
164
+ context 'w=majority' do
165
+ let(:options) { 'w=majority' }
166
+ let(:concern) { { :w => :majority } }
167
+
168
+ it 'sets the write concern options' do
169
+ expect(uri.options[:write]).to eq(concern)
170
+ end
171
+ end
172
+
173
+ context 'journal' do
174
+ let(:options) { 'j=true' }
175
+ let(:concern) { { :j => true } }
176
+
177
+ it 'sets the write concern options' do
178
+ expect(uri.options[:write]).to eq(concern)
179
+ end
180
+ end
181
+
182
+ context 'fsync' do
183
+ let(:options) { 'fsync=true' }
184
+ let(:concern) { { :fsync => true } }
185
+
186
+ it 'sets the write concern options' do
187
+ expect(uri.options[:write]).to eq(concern)
188
+ end
189
+ end
190
+
191
+ context 'wtimeoutMS' do
192
+ let(:timeout) { 1234 }
193
+ let(:options) { "w=2&wtimeoutMS=#{timeout}" }
194
+ let(:concern) { { :w => 2, :timeout => timeout } }
195
+
196
+ it 'sets the write concern options' do
197
+ expect(uri.options[:write]).to eq(concern)
198
+ end
199
+ end
200
+ end
201
+
202
+ context 'read preference option provided' do
203
+ let(:options) { "readPreference=#{mode}" }
204
+
205
+ context 'primary' do
206
+ let(:mode) { 'primary' }
207
+ let(:read) { { :mode => :primary } }
208
+
209
+ it 'sets the read preference' do
210
+ expect(uri.options[:read]).to eq(read)
211
+ end
212
+ end
213
+
214
+ context 'primaryPreferred' do
215
+ let(:mode) { 'primaryPreferred' }
216
+ let(:read) { { :mode => :primary_preferred } }
217
+
218
+ it 'sets the read preference' do
219
+ expect(uri.options[:read]).to eq(read)
220
+ end
221
+ end
222
+
223
+ context 'secondary' do
224
+ let(:mode) { 'secondary' }
225
+ let(:read) { { :mode => :secondary } }
226
+
227
+ it 'sets the read preference' do
228
+ expect(uri.options[:read]).to eq(read)
229
+ end
230
+ end
231
+
232
+ context 'secondaryPreferred' do
233
+ let(:mode) { 'secondaryPreferred' }
234
+ let(:read) { { :mode => :secondary_preferred } }
235
+
236
+ it 'sets the read preference' do
237
+ expect(uri.options[:read]).to eq(read)
238
+ end
239
+ end
240
+
241
+ context 'nearest' do
242
+ let(:mode) { 'nearest' }
243
+ let(:read) { { :mode => :nearest } }
244
+
245
+ it 'sets the read preference' do
246
+ expect(uri.options[:read]).to eq(read)
247
+ end
248
+ end
249
+ end
250
+
251
+ context 'read preferece tags provided' do
252
+
253
+ context 'single read preference tag set' do
254
+ let(:options) do
255
+ 'readPreferenceTags=dc:ny,rack:1'
256
+ end
257
+
258
+ let(:read) do
259
+ { :tag_sets => [{ :dc => 'ny', :rack => '1' }] }
260
+ end
261
+
262
+ it 'sets the read preference tag set' do
263
+ expect(uri.options[:read]).to eq(read)
264
+ end
265
+ end
266
+
267
+ context 'multiple read preference tag sets' do
268
+ let(:options) do
269
+ 'readPreferenceTags=dc:ny&readPreferenceTags=dc:bos'
270
+ end
271
+
272
+ let(:read) do
273
+ { :tag_sets => [{ :dc => 'ny' }, { :dc => 'bos' }] }
274
+ end
275
+
276
+ it 'sets the read preference tag sets' do
277
+ expect(uri.options[:read]).to eq(read)
278
+ end
279
+ end
280
+ end
281
+
282
+ context 'replica set option provided' do
283
+ let(:rs_name) { TEST_SET }
284
+ let(:options) { "replicaSet=#{rs_name}" }
285
+
286
+ it 'sets the replica set option' do
287
+ expect(uri.options[:replica_set]).to eq(rs_name)
288
+ end
289
+ end
290
+
291
+ context 'auth mechanism provided' do
292
+ let(:options) { "authMechanism=#{mechanism}" }
293
+
294
+ context 'plain' do
295
+ let(:mechanism) { 'PLAIN' }
296
+ let(:auth) { { :mechanism => :plain } }
297
+
298
+ it 'sets the auth mechanism to :plain' do
299
+ expect(uri.options[:auth]).to eq(auth)
300
+ end
301
+ end
302
+
303
+ context 'mongodb-cr' do
304
+ let(:mechanism) { 'MONGODB-CR' }
305
+ let(:auth) { { :mechanism => :mongodb_cr } }
306
+
307
+ it 'sets the auth mechanism to :mongodb_cr' do
308
+ expect(uri.options[:auth]).to eq(auth)
309
+ end
310
+ end
311
+
312
+ context 'gssapi' do
313
+ let(:mechanism) { 'GSSAPI' }
314
+ let(:auth) { { :mechanism => :gssapi } }
315
+
316
+ it 'sets the auth mechanism to :gssapi' do
317
+ expect(uri.options[:auth]).to eq(auth)
318
+ end
319
+ end
320
+ end
321
+
322
+ context 'auth source provided' do
323
+ let(:options) { "authSource=#{source}" }
324
+
325
+ context 'regular db' do
326
+ let(:source) { 'foo' }
327
+ let(:auth) { { :source => 'foo' } }
328
+
329
+ it 'sets the auth source to the database' do
330
+ expect(uri.options[:auth]).to eq(auth)
331
+ end
332
+ end
333
+
334
+ context '$external' do
335
+ let(:source) { '$external' }
336
+ let(:auth) { { :source => :external } }
337
+
338
+ it 'sets the auth source to :external' do
339
+ expect(uri.options[:auth]).to eq(auth)
340
+ end
341
+ end
342
+ end
343
+
344
+ context 'auth mechanism properties provided' do
345
+
346
+ context 'service_name' do
347
+ let(:options) do
348
+ "authMechanismProperties=SERVICE_NAME:#{service_name}"
349
+ end
350
+
351
+ let(:service_name) { 'foo' }
352
+ let(:auth) do
353
+ { auth_mech_properties: { service_name: service_name } }
354
+ end
355
+
356
+ it 'sets the auth mechanism properties' do
357
+ expect(uri.options[:auth]).to eq(auth)
358
+ end
359
+ end
360
+
361
+ context 'canonicalize_host_name' do
362
+ let(:options) do
363
+ "authMechanismProperties=CANONICALIZE_HOST_NAME:#{canonicalize_host_name}"
364
+ end
365
+
366
+ let(:canonicalize_host_name) { 'true' }
367
+ let(:auth) do
368
+ { auth_mech_properties: { canonicalize_host_name: true } }
369
+ end
370
+
371
+ it 'sets the auth mechanism properties' do
372
+ expect(uri.options[:auth]).to eq(auth)
373
+ end
374
+ end
375
+
376
+ context 'service_realm' do
377
+ let(:options) do
378
+ "authMechanismProperties=SERVICE_REALM:#{service_realm}"
379
+ end
380
+
381
+ let(:service_realm) { 'dumdum' }
382
+ let(:auth) do
383
+ { auth_mech_properties: { service_realm: service_realm } }
384
+ end
385
+
386
+ it 'sets the auth mechanism properties' do
387
+ expect(uri.options[:auth]).to eq(auth)
388
+ end
389
+ end
390
+
391
+ context 'multiple properties' do
392
+ let(:options) do
393
+ "authMechanismProperties=SERVICE_REALM:#{service_realm}," +
394
+ "CANONICALIZE_HOST_NAME:#{canonicalize_host_name}," +
395
+ "SERVICE_NAME:#{service_name}"
396
+ end
397
+
398
+ let(:service_name) { 'foo' }
399
+ let(:canonicalize_host_name) { 'true' }
400
+ let(:service_realm) { 'dumdum' }
401
+
402
+ let(:auth) do
403
+ { auth_mech_properties: { service_name: service_name,
404
+ canonicalize_host_name: true,
405
+ service_realm: service_realm } }
406
+ end
407
+
408
+ it 'sets the auth mechanism properties' do
409
+ expect(uri.options[:auth]).to eq(auth)
410
+ end
411
+ end
412
+ end
413
+
414
+ context 'connectTimeoutMS' do
415
+ let(:options) { "connectTimeoutMS=4567" }
416
+
417
+ it 'sets the the connect timeout' do
418
+ expect(uri.options[:connect_timeout]).to eq(4.567)
419
+ end
420
+ end
421
+
422
+ context 'socketTimeoutMS' do
423
+ let(:options) { "socketTimeoutMS=8910" }
424
+
425
+ it 'sets the socket timeout' do
426
+ expect(uri.options[:socket_timeout]).to eq(8.910)
427
+ end
428
+ end
429
+
430
+ context 'when providing serverSelectionTimeoutMS' do
431
+
432
+ let(:options) { "serverSelectionTimeoutMS=3561" }
433
+
434
+ it 'sets the the connect timeout' do
435
+ expect(uri.options[:server_selection_timeout]).to eq(3.561)
436
+ end
437
+ end
438
+
439
+ context 'when providing localThresholdMS' do
440
+
441
+ let(:options) { "localThresholdMS=3561" }
442
+
443
+ it 'sets the the connect timeout' do
444
+ expect(uri.options[:local_threshold]).to eq(3.561)
445
+ end
446
+ end
447
+
448
+ context 'when providing maxPoolSize' do
449
+
450
+ let(:max_pool_size) { 10 }
451
+ let(:options) { "maxPoolSize=#{max_pool_size}" }
452
+
453
+ it 'sets the max pool size option' do
454
+ expect(uri.options[:max_pool_size]).to eq(max_pool_size)
455
+ end
456
+ end
457
+
458
+ context 'when providing minPoolSize' do
459
+
460
+ let(:min_pool_size) { 5 }
461
+ let(:options) { "minPoolSize=#{min_pool_size}" }
462
+
463
+ it 'sets the min pool size option' do
464
+ expect(uri.options[:min_pool_size]).to eq(min_pool_size)
465
+ end
466
+ end
467
+
468
+ context 'when providing waitQueueTimeoutMS' do
469
+
470
+ let(:wait_queue_timeout) { 500 }
471
+ let(:options) { "waitQueueTimeoutMS=#{wait_queue_timeout}" }
472
+
473
+ it 'sets the wait queue timeout option' do
474
+ expect(uri.options[:wait_queue_timeout]).to eq(0.5)
475
+ end
476
+ end
477
+
478
+ context 'ssl' do
479
+ let(:options) { "ssl=#{ssl}" }
480
+
481
+ context 'true' do
482
+ let(:ssl) { true }
483
+
484
+ it 'sets the ssl option to true' do
485
+ expect(uri.options[:ssl]).to be true
486
+ end
487
+ end
488
+
489
+ context 'false' do
490
+ let(:ssl) { false }
491
+
492
+ it 'sets the ssl option to false' do
493
+ expect(uri.options[:ssl]).to be false
494
+ end
495
+ end
496
+ end
497
+
498
+ context 'grouped and non-grouped options provided' do
499
+ let(:options) { 'w=1&ssl=true' }
500
+
501
+ it 'do not overshadow top level options' do
502
+ expect(uri.options).not_to be_empty
503
+ end
504
+ end
505
+
506
+ context 'when an invalid option is provided' do
507
+
508
+ let(:options) { 'iDontKnow=10' }
509
+
510
+ it 'raises an exception' do
511
+ expect {
512
+ uri.options
513
+ }.to raise_error(Mongo::URI::InvalidOption)
514
+ end
515
+ end
516
+ end
517
+ end