mongo 1.12.5 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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
data/test/test_helper.rb DELETED
@@ -1,61 +0,0 @@
1
- # Copyright (C) 2009-2013 MongoDB, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- # NOTE: on ruby <1.9 you need to run individual tests with 'bundle exec'
16
-
17
- unless RUBY_VERSION < '1.9' || ENV.key?('JENKINS_CI')
18
- require 'simplecov'
19
- require 'coveralls'
20
-
21
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
22
- SimpleCov::Formatter::HTMLFormatter,
23
- Coveralls::SimpleCov::Formatter
24
- ]
25
-
26
- SimpleCov.start do
27
- add_group 'Driver', 'lib/mongo'
28
- add_group 'BSON', 'lib/bson'
29
-
30
- add_filter 'tasks'
31
- add_filter 'test'
32
- add_filter 'bin'
33
- end
34
- end
35
-
36
- # required for at_exit, at_start hooks
37
- require 'test-unit'
38
-
39
- require 'test/unit'
40
- require 'shoulda'
41
- require 'mocha/setup'
42
-
43
- # cluster manager
44
- require 'tools/mongo_config'
45
-
46
- # For kerberos testing.
47
- begin
48
- require 'mongo_kerberos'
49
- rescue LoadError; end
50
-
51
- # test helpers
52
- require 'helpers/general'
53
- require 'helpers/test_unit'
54
-
55
- # optional development and debug utilities
56
- begin
57
- require 'pry-rescue'
58
- require 'pry-nav'
59
- rescue LoadError
60
- # failed to load, skipping pry
61
- end
@@ -1,120 +0,0 @@
1
- # Copyright (C) 2009-2013 MongoDB, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- require 'test_helper'
16
-
17
- class ThreadingTest < Test::Unit::TestCase
18
-
19
- include Mongo
20
-
21
- def setup
22
- @client = standard_connection(:pool_size => 10, :pool_timeout => 30)
23
- @db = @client.db(TEST_DB)
24
- @coll = @db.collection('thread-test-collection')
25
- @coll.drop
26
-
27
- collections = ['duplicate', 'unique']
28
-
29
- collections.each do |coll_name|
30
- coll = @db.collection(coll_name)
31
- coll.drop
32
- coll.insert("test" => "insert")
33
- coll.insert("test" => "update")
34
- instance_variable_set("@#{coll_name}", coll)
35
- end
36
-
37
- @unique.create_index("test", :unique => true)
38
- end
39
-
40
- def test_safe_update
41
- threads = []
42
- 300.times do |i|
43
- threads << Thread.new do
44
- if i % 2 == 0
45
- assert_raise Mongo::OperationFailure do
46
- @unique.update({"test" => "insert"}, {"$set" => {"test" => "update"}})
47
- end
48
- else
49
- @duplicate.update({"test" => "insert"}, {"$set" => {"test" => "update"}})
50
- @duplicate.update({"test" => "update"}, {"$set" => {"test" => "insert"}})
51
- end
52
- end
53
- end
54
-
55
- threads.each {|thread| thread.join}
56
- end
57
-
58
- def test_safe_insert
59
- threads = []
60
- 300.times do |i|
61
- threads << Thread.new do
62
- if i % 2 == 0
63
- assert_raise Mongo::OperationFailure do
64
- @unique.insert({"test" => "insert"})
65
- end
66
- else
67
- @duplicate.insert({"test" => "insert"})
68
- end
69
- end
70
- end
71
-
72
- threads.each {|thread| thread.join}
73
- end
74
-
75
- def test_concurrent_find
76
- n_threads = 50
77
-
78
- 1000.times do |i|
79
- @coll.insert({ "x" => "a" })
80
- end
81
-
82
- threads = []
83
- n_threads.times do |i|
84
- threads << Thread.new do
85
- sum = 0
86
- @coll.find.to_a.size
87
- end
88
- end
89
-
90
- thread_values = threads.map(&:value)
91
- assert thread_values.all?{|v| v == 1000}
92
- assert_equal thread_values.size, n_threads
93
- end
94
-
95
- def test_threading
96
- @coll.drop
97
- @coll = @db.collection('thread-test-collection')
98
-
99
- docs = []
100
- 1000.times {|i| docs << {:x => i}}
101
- @coll.insert(docs)
102
-
103
- threads = []
104
-
105
- 10.times do |i|
106
- threads[i] = Thread.new do
107
- sum = 0
108
- @coll.find().each do |document|
109
- sum += document["x"]
110
- end
111
- assert_equal 499500, sum
112
- end
113
- end
114
-
115
- 10.times do |i|
116
- threads[i].join
117
- end
118
- end
119
-
120
- end
@@ -1,708 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright (C) 2009-2013 MongoDB, Inc.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
- require 'socket'
18
- require 'fileutils'
19
- require 'mongo'
20
- require 'sfl'
21
-
22
- $debug_level = 2
23
- STDOUT.sync = true
24
-
25
- def debug(level, arg)
26
- if level <= $debug_level
27
- file_line = caller[0][/(.*:\d+):/, 1]
28
- calling_method = caller[0][/`([^']*)'/, 1]
29
- puts "#{file_line}:#{calling_method}:#{arg.class == String ? arg : arg.inspect}"
30
- end
31
- end
32
-
33
- #
34
- # Design Notes
35
- # Configuration and Cluster Management are modularized with the concept that the Cluster Manager
36
- # can be supplied with any configuration to run.
37
- # A configuration can be edited, modified, copied into a test file, and supplied to a cluster manager
38
- # as a parameter.
39
- #
40
- module Mongo
41
- class Config
42
- DEFAULT_BASE_OPTS = { :host => 'localhost', :dbpath => 'data', :logpath => 'data/log' }
43
- DEFAULT_REPLICA_SET = DEFAULT_BASE_OPTS.merge( :replicas => 3, :arbiters => 0 )
44
- DEFAULT_SHARDED_SIMPLE = DEFAULT_BASE_OPTS.merge( :shards => 2, :configs => 1, :routers => 2 )
45
- DEFAULT_SHARDED_REPLICA = DEFAULT_SHARDED_SIMPLE.merge( :replicas => 3, :arbiters => 0)
46
-
47
- IGNORE_KEYS = [:host, :command, :_id]
48
- SHARDING_OPT_KEYS = [:shards, :configs, :routers]
49
- REPLICA_OPT_KEYS = [:replicas, :arbiters]
50
- MONGODS_OPT_KEYS = [:mongods]
51
- CLUSTER_OPT_KEYS = SHARDING_OPT_KEYS + REPLICA_OPT_KEYS + MONGODS_OPT_KEYS
52
-
53
- FLAGS = [:noprealloc, :smallfiles, :logappend, :configsvr, :shardsvr, :quiet, :fastsync, :auth, :ipv6]
54
-
55
- DEFAULT_VERIFIES = 60
56
- BASE_PORT = 3000
57
- @@port = BASE_PORT
58
-
59
- def self.configdb(config)
60
- config[:configs].collect{|c|"#{c[:host]}:#{c[:port]}"}.join(' ')
61
- end
62
-
63
- def self.cluster(opts = DEFAULT_SHARDED_SIMPLE)
64
- raise "missing required option" if [:host, :dbpath].any?{|k| !opts[k]}
65
-
66
- config = opts.reject {|k,v| CLUSTER_OPT_KEYS.include?(k)}
67
-
68
- kinds = CLUSTER_OPT_KEYS.select{|key| opts.has_key?(key)} # order is significant
69
-
70
- replica_count = 0
71
-
72
- kinds.each do |kind|
73
- config[kind] = opts.fetch(kind,1).times.collect do |i| #default to 1 of whatever
74
- if kind == :shards && opts[:replicas]
75
- self.cluster(opts.reject{|k,v| SHARDING_OPT_KEYS.include?(k)}.merge(:dbpath => path))
76
- else
77
- node = case kind
78
- when :replicas
79
- make_replica(opts, replica_count)
80
- when :arbiters
81
- make_replica(opts, replica_count)
82
- when :configs
83
- make_config(opts)
84
- when :routers
85
- make_router(config, opts)
86
- when :shards
87
- make_standalone_shard(kind, opts)
88
- else
89
- make_mongod(kind, opts)
90
- end
91
-
92
- replica_count += 1 if [:replicas, :arbiters].member?(kind)
93
- node
94
- end
95
- end
96
- end
97
- config
98
- end
99
-
100
- def self.make_mongo(kind, opts)
101
- dbpath = opts[:dbpath]
102
- port = self.get_available_port
103
- path = "#{dbpath}/#{kind}-#{port}"
104
- logpath = "#{path}/#{kind}.log"
105
-
106
- { :host => opts[:host],
107
- :port => port,
108
- :logpath => logpath,
109
- :logappend => true }
110
- end
111
-
112
- def self.make_mongod(kind, opts)
113
- params = make_mongo('mongods', opts)
114
-
115
- mongod = ENV['MONGOD'] || 'mongod'
116
- path = File.dirname(params[:logpath])
117
-
118
- noprealloc = opts[:noprealloc] || true
119
- smallfiles = opts[:smallfiles] || true
120
- quiet = opts[:quiet] || true
121
- fast_sync = opts[:fastsync] || false
122
- auth = opts[:auth] || true
123
- ipv6 = opts[:ipv6].nil? ? true : opts[:ipv6]
124
- setParameter = opts[:setParameter] || 'enableTestCommands=1'
125
-
126
- params.merge(:command => mongod,
127
- :dbpath => path,
128
- :smallfiles => smallfiles,
129
- :noprealloc => noprealloc,
130
- :quiet => quiet,
131
- :fastsync => fast_sync,
132
- :auth => auth,
133
- :ipv6 => ipv6,
134
- :setParameter => setParameter)
135
- end
136
-
137
- def self.key_file(opts)
138
- keyFile = opts[:key_file] || '/test/fixtures/auth/keyfile'
139
- keyFile = Dir.pwd << keyFile
140
- system "chmod 600 #{keyFile}"
141
- keyFile
142
- end
143
-
144
- # A regular mongod minus --auth and plus --keyFile.
145
- def self.make_standalone_shard(kind, opts)
146
- params = make_mongod(kind, opts)
147
- params.delete(:auth)
148
- params.merge(:keyFile => key_file(opts))
149
- end
150
-
151
- def self.make_replica(opts, id)
152
- params = make_mongod('replicas', opts)
153
-
154
- replSet = opts[:replSet] || 'ruby-driver-test'
155
- oplogSize = opts[:oplog_size] || 5
156
-
157
- params.merge(:_id => id,
158
- :replSet => replSet,
159
- :oplogSize => oplogSize,
160
- :keyFile => key_file(opts))
161
- end
162
-
163
- def self.make_config(opts)
164
- params = make_mongod('configs', opts)
165
- params.delete(:auth)
166
- params.merge(:configsvr => true,
167
- :keyFile => key_file(opts))
168
- end
169
-
170
- def self.make_router(config, opts)
171
- params = make_mongo('routers', opts)
172
- mongos = ENV['MONGOS'] || 'mongos'
173
-
174
- params.merge(
175
- :command => mongos,
176
- :configdb => self.configdb(config),
177
- :keyFile => key_file(opts)
178
- )
179
- end
180
-
181
- def self.port_available?(port)
182
- ret = false
183
- socket = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0)
184
- socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
185
- sockaddr = Socket.sockaddr_in(port, '0.0.0.0')
186
- begin
187
- socket.bind(sockaddr)
188
- ret = true
189
- rescue Exception
190
- end
191
- socket.close
192
- ret
193
- end
194
-
195
- def self.get_available_port
196
- while true
197
- port = @@port
198
- @@port += 1
199
- break if port_available?(port)
200
- end
201
- port
202
- end
203
-
204
- class SysProc
205
- attr_reader :pid, :cmd
206
-
207
- def initialize(cmd = nil)
208
- @pid = nil
209
- @cmd = cmd
210
- end
211
-
212
- def clear_zombie
213
- if @pid
214
- begin
215
- pid = Process.waitpid(@pid, Process::WNOHANG)
216
- rescue Errno::ECHILD
217
- # JVM might have already reaped the exit status
218
- end
219
- @pid = nil if pid && pid > 0
220
- end
221
- end
222
-
223
- def start(verifies = 0)
224
- clear_zombie
225
- return @pid if running?
226
- begin
227
- # redirection not supported in jruby
228
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
229
- @pid = Process.spawn(*@cmd)
230
- else
231
- cmd_and_opts = [@cmd, {:out => '/dev/null'}].flatten
232
- @pid = Process.spawn(*cmd_and_opts)
233
- end
234
- verify(verifies) if verifies > 0
235
- @pid
236
- end
237
- end
238
-
239
- def stop
240
- kill
241
- wait
242
- end
243
-
244
- def kill(signal_no = 2)
245
- begin
246
- @pid && Process.kill(signal_no, @pid) && true
247
- rescue Errno::ESRCH
248
- false
249
- end
250
- # cleanup lock if unclean shutdown
251
- begin
252
- File.delete(File.join(@config[:dbpath], 'mongod.lock')) if @config[:dbpath]
253
- rescue Errno::ENOENT
254
- end
255
- end
256
-
257
- def wait
258
- begin
259
- Process.waitpid(@pid) if @pid
260
- rescue Errno::ECHILD
261
- # JVM might have already reaped the exit status
262
- end
263
- @pid = nil
264
- end
265
-
266
- def running?
267
- begin
268
- @pid && Process.kill(0, @pid) && true
269
- rescue Errno::ESRCH
270
- false
271
- end
272
- end
273
-
274
- def verify(verifies = DEFAULT_VERIFIES)
275
- verifies.times do |i|
276
- return @pid if running?
277
- sleep 1
278
- end
279
- nil
280
- end
281
- end
282
-
283
- class Server < SysProc
284
- attr_reader :host, :port
285
-
286
- def initialize(cmd = nil, host = nil, port = nil)
287
- super(cmd)
288
- @host = host
289
- @port = port
290
- end
291
-
292
- def host_port
293
- [@host, @port].join(':')
294
- end
295
-
296
- def host_port_a # for old format
297
- [@host, @port]
298
- end
299
- end
300
-
301
- class DbServer < Server
302
- attr_accessor :config
303
-
304
- def initialize(config)
305
- @config = config
306
- cmd = init_config!
307
- super(cmd, @config[:host], @config[:port])
308
- end
309
-
310
- def init_config!
311
- dbpath = @config[:dbpath]
312
- [dbpath, File.dirname(@config[:logpath])].compact.each{|dir| FileUtils.mkdir_p(dir) unless File.directory?(dir) }
313
- command = @config[:command] || 'mongod'
314
- params = @config.reject{|k,v| IGNORE_KEYS.include?(k)}
315
- arguments = params.sort{|a, b| a[0].to_s <=> b[0].to_s}.collect do |arg, value| # sort block is needed for 1.8.7 which lacks Symbol#<=>
316
- argument = '--' + arg.to_s
317
- if FLAGS.member?(arg) && value == true
318
- [argument]
319
- elsif !FLAGS.member?(arg)
320
- [argument, value.to_s]
321
- end
322
- end
323
- cmd = [command, arguments].flatten.compact
324
- end
325
-
326
- def start(verifies = DEFAULT_VERIFIES)
327
- super(verifies)
328
- verify(verifies)
329
- end
330
-
331
- def verify(verifies = 600)
332
- verifies.times do |i|
333
- #puts "DbServer.verify via connection probe - port:#{@port.inspect} iteration:#{i} @pid:#{@pid.inspect} kill:#{Process.kill(0, @pid).inspect} running?:#{running?.inspect} cmd:#{cmd.inspect}"
334
- begin
335
- raise Mongo::ConnectionFailure unless running?
336
- Mongo::MongoClient.new(@host, @port).close
337
- #puts "DbServer.verified via connection - port: #{@port} iteration: #{i}"
338
- return @pid
339
- rescue Mongo::ConnectionFailure
340
- sleep 1
341
- end
342
- end
343
- if @config.delete(:setParameter)
344
- @cmd = init_config!
345
- start(verifies)
346
- else
347
- system "ps -fp #{@pid}; cat #{@config[:logpath]}"
348
- raise Mongo::ConnectionFailure, "DbServer.start verify via connection probe failed - port:#{@port.inspect} @pid:#{@pid.inspect} kill:#{Process.kill(0, @pid).inspect} running?:#{running?.inspect} cmd:#{cmd.inspect}"
349
- end
350
- end
351
-
352
- end
353
-
354
- class ClusterManager
355
- attr_reader :config
356
- def initialize(config)
357
- @config = config
358
- @servers = {}
359
- Mongo::Config::CLUSTER_OPT_KEYS.each do |key|
360
- @servers[key] = @config[key].collect{|conf| p conf; DbServer.new(conf)} if @config[key]
361
- end
362
- end
363
-
364
- def servers(key = nil)
365
- @servers.collect{|k,v| (!key || key == k) ? v : nil}.flatten.compact
366
- end
367
-
368
- def ensure_authenticated(client)
369
- begin
370
- client[TEST_DB].authenticate(TEST_USER, TEST_USER_PWD)
371
- rescue Mongo::MongoArgumentError => ex
372
- # client is already authenticated
373
- raise ex unless ex.message =~ /already authenticated/
374
- rescue Mongo::AuthenticationError => ex
375
- # 1) The creds are wrong
376
- # 2) Or the user doesn't exist
377
- roles = [ 'dbAdminAnyDatabase',
378
- 'userAdminAnyDatabase',
379
- 'readWriteAnyDatabase',
380
- 'clusterAdmin' ]
381
- begin
382
- # Try to add the user for case (2)
383
- client[TEST_DB].add_user(TEST_USER, TEST_USER_PWD, nil, :roles => roles)
384
- client[TEST_DB].authenticate(TEST_USER, TEST_USER_PWD)
385
- rescue Mongo::ConnectionFailure, Mongo::OperationFailure => ex
386
- # Maybe not master, so try to authenticate
387
- # 2.2 throws an OperationFailure if add_user fails
388
- begin
389
- client[TEST_DB].authenticate(TEST_USER, TEST_USER_PWD)
390
- rescue => ex
391
- # Maybe creds are wrong, nothing we can do
392
- end
393
- end
394
- end
395
- end
396
-
397
- def command( cmd_servers, db_name, cmd, opts = {} )
398
- ret = []
399
- cmd = cmd.class == Array ? cmd : [ cmd ]
400
- debug 3, "ClusterManager.command cmd:#{cmd.inspect}"
401
- cmd_servers = cmd_servers.class == Array ? cmd_servers : [cmd_servers]
402
- cmd_servers.each do |cmd_server|
403
- debug 3, cmd_server.inspect
404
- cmd_server = cmd_server.config if cmd_server.is_a?(DbServer)
405
- client = Mongo::MongoClient.new(cmd_server[:host], cmd_server[:port])
406
- ensure_authenticated(client)
407
- cmd.each do |c|
408
- debug 3, "ClusterManager.command c:#{c.inspect}"
409
- response = client[db_name].command( c, opts )
410
- debug 3, "ClusterManager.command response:#{response.inspect}"
411
- raise Mongo::OperationFailure, "c:#{c.inspect} opts:#{opts.inspect} failed" unless response["ok"] == 1.0 || opts.fetch(:check_response, true) == false
412
- ret << response
413
- end
414
- client.close
415
- end
416
- debug 3, "command ret:#{ret.inspect}"
417
- ret.size == 1 ? ret.first : ret
418
- end
419
-
420
- def replica_set?
421
- !!config[:replicas]
422
- end
423
-
424
- def repl_set_get_status
425
- command( @config[:replicas], 'admin', { :replSetGetStatus => 1 }, {:check_response => false } )
426
- end
427
-
428
- def repl_set_get_config
429
- host, port = primary_name.split(":")
430
- client = Mongo::MongoClient.new(host, port)
431
- ensure_authenticated(client)
432
- client['local']['system.replset'].find_one
433
- end
434
-
435
- def repl_set_config
436
- members = []
437
- @config[:replicas].each{|s| members << { :_id => s[:_id], :host => "#{s[:host]}:#{s[:port]}", :tags => { :node => s[:_id].to_s } } }
438
- @config[:arbiters].each{|s| members << { :_id => s[:_id], :host => "#{s[:host]}:#{s[:port]}", :arbiterOnly => true } }
439
- {
440
- :_id => @config[:replicas].first[:replSet],
441
- :members => members
442
- }
443
- end
444
-
445
- def repl_set_initiate( cfg = nil )
446
- command( @config[:replicas].first, 'admin', { :replSetInitiate => cfg || repl_set_config } )
447
- end
448
-
449
- def repl_set_startup
450
- states = nil
451
- healthy = false
452
-
453
- 80.times do
454
- # enter the thunderdome...
455
- states = repl_set_get_status.zip(repl_set_is_master)
456
- healthy = states.all? do |status, is_master|
457
- # check replica set status for member list
458
- next unless status['ok'] == 1.0 && (members = status['members'])
459
-
460
- # ensure all replica set members are in a valid state
461
- next unless members.all? { |m| [1,2,7].include?(m['state']) }
462
-
463
- # check for primary replica set member
464
- next unless (primary = members.find { |m| m['state'] == 1 })
465
-
466
- # check replica set member optimes
467
- primary_optime = (primary['optime']['ts'] ? primary['optime']['ts'] : primary['optime']).seconds
468
- next unless primary_optime && members.all? do |m|
469
- m_optime = (m['optime']['ts'] ? m['optime']['ts'] : m['optime']).seconds
470
- m['state'] == 7 || primary_optime - m_optime < 5
471
- end
472
-
473
- # check replica set state
474
- case status['myState']
475
- when 1
476
- is_master['ismaster'] == true &&
477
- is_master['secondary'] == false
478
- when 2
479
- is_master['ismaster'] == false &&
480
- is_master['secondary'] == true
481
- when 7
482
- is_master['ismaster'] == false &&
483
- is_master['secondary'] == false
484
- end
485
- end
486
-
487
- return healthy if healthy
488
- sleep(1)
489
- end
490
-
491
- raise Mongo::OperationFailure,
492
- "replSet startup failed - status: #{states.inspect}"
493
- end
494
-
495
- def repl_set_seeds
496
- @config[:replicas].collect{|node| "#{node[:host]}:#{node[:port]}"}
497
- end
498
-
499
- def repl_set_seeds_old
500
- @config[:replicas].collect{|node| [node[:host], node[:port]]}
501
- end
502
-
503
- def repl_set_seeds_uri
504
- repl_set_seeds.join(',')
505
- end
506
-
507
- def members_uri
508
- members = @config[:replicas] || @config[:routers]
509
- members.collect{|node| "#{node[:host]}:#{node[:port]}"}.join(',')
510
- end
511
-
512
- def repl_set_name
513
- @config[:replicas].first[:replSet]
514
- end
515
-
516
- def member_names_by_state(state)
517
- states = Array(state)
518
- # Any status with a REMOVED node won't have the full cluster state
519
- status = repl_set_get_status.find {|status| status['members'].find {|m| m['state'] == 'REMOVED'}.nil?}
520
- status['members'].find_all{|member| states.index(member['state']) }.collect{|member| member['name']}
521
- end
522
-
523
- def primary_name
524
- member_names_by_state(1).first
525
- end
526
-
527
- def secondary_names
528
- member_names_by_state(2)
529
- end
530
-
531
- def replica_names
532
- member_names_by_state([1,2])
533
- end
534
-
535
- def arbiter_names
536
- member_names_by_state(7)
537
- end
538
-
539
- def members_by_name(names)
540
- names.collect do |name|
541
- member_by_name(name)
542
- end.compact
543
- end
544
-
545
- def member_by_name(name)
546
- servers.find{|server| server.host_port == name}
547
- end
548
-
549
- def primary
550
- members_by_name([primary_name]).first
551
- end
552
-
553
- def secondaries
554
- members_by_name(secondary_names)
555
- end
556
-
557
- def stop_primary
558
- primary.stop
559
- end
560
-
561
- def stop_secondary
562
- secondaries[rand(secondaries.length)].stop
563
- end
564
-
565
- def replicas
566
- members_by_name(replica_names)
567
- end
568
-
569
- def arbiters
570
- members_by_name(arbiter_names)
571
- end
572
-
573
- def config_names_by_kind(kind)
574
- @config[kind].collect{|conf| "#{conf[:host]}:#{conf[:port]}"}
575
- end
576
-
577
- def shards
578
- members_by_name(config_names_by_kind(:shards))
579
- end
580
-
581
- def repl_set_reconfig(new_config)
582
- new_config['version'] = repl_set_get_config['version'] + 1
583
- command( primary, 'admin', { :replSetReconfig => new_config } )
584
- repl_set_startup
585
- end
586
-
587
- def repl_set_remove_node(state = [1,2])
588
- names = member_names_by_state(state)
589
- name = names[rand(names.length)]
590
-
591
- @config[:replicas].delete_if{|node| "#{node[:host]}:#{node[:port]}" == name}
592
- repl_set_reconfig(repl_set_config)
593
- end
594
-
595
- def repl_set_add_node
596
- end
597
-
598
- def configs
599
- members_by_name(config_names_by_kind(:configs))
600
- end
601
-
602
- def routers
603
- members_by_name(config_names_by_kind(:routers))
604
- end
605
-
606
- def mongos_seeds
607
- config_names_by_kind(:routers)
608
- end
609
-
610
- def ismaster(servers)
611
- command( servers, 'admin', { :ismaster => 1 } )
612
- end
613
-
614
- def sharded_cluster_is_master
615
- ismaster(@config[:routers])
616
- end
617
-
618
- def repl_set_is_master
619
- ismaster(@config[:replicas])
620
- end
621
-
622
- def addshards(shards = @config[:shards])
623
- begin
624
- command( @config[:routers].first, 'admin', Array(shards).collect{|s| { :addshard => "#{s[:host]}:#{s[:port]}" } } )
625
- rescue Mongo::OperationFailure => ex
626
- # Because we cannot run the listshards command under the localhost
627
- # exception in > 2.7.1, we run the risk of attempting to add the same shard twice.
628
- # Our tests may add a local db to a shard, if the cluster is still up,
629
- # then we can ignore this.
630
- raise ex unless ex.message =~ /host already used/
631
- end
632
- end
633
-
634
- def listshards
635
- command( @config[:routers].first, 'admin', { :listshards => 1 } )
636
- end
637
-
638
- def enablesharding( dbname )
639
- command( @config[:routers].first, 'admin', { :enablesharding => dbname } )
640
- end
641
-
642
- def shardcollection( namespace, key, unique = false )
643
- command( @config[:routers].first, 'admin', { :shardcollection => namespace, :key => key, :unique => unique } )
644
- end
645
-
646
- def mongos_discover # can also do @config[:routers] find but only want mongos for connections
647
- (@config[:configs]).collect do |cmd_server|
648
- client = Mongo::MongoClient.new(cmd_server[:host], cmd_server[:port])
649
- result = client['config']['mongos'].find.to_a
650
- client.close
651
- result
652
- end
653
- end
654
-
655
- def start
656
- # Must start configs before mongos -- hash order not guaranteed on 1.8.X
657
- servers(:configs).each{|server| server.start}
658
- servers.each{|server| server.start}
659
- # TODO - sharded replica sets - pending
660
- if @config[:replicas]
661
- repl_set_initiate if repl_set_get_status.first['code'] == 94 ||
662
- (repl_set_get_status.first['startupStatus'] && repl_set_get_status.first['startupStatus'] == 3)
663
- repl_set_startup
664
- end
665
- if @config[:routers]
666
- addshards if listshards['shards'].size == 0
667
- end
668
- self
669
- end
670
- alias :restart :start
671
-
672
- def delete_users
673
- cmd_servers = replica_set? ? [ primary ] : routers
674
-
675
- cmd_servers.each do |cmd_server|
676
- next unless cmd_server
677
- begin
678
- client = Mongo::MongoClient.new(cmd_server.config[:host],
679
- cmd_server.config[:port])
680
- ensure_authenticated(client)
681
- db = client[TEST_DB]
682
-
683
- if client.server_version < '2.5'
684
- db['system.users'].remove
685
- else
686
- db.command(:dropAllUsersFromDatabase => 1)
687
- end
688
- break
689
- rescue Mongo::ConnectionFailure
690
- end
691
- end
692
- end
693
-
694
- def stop
695
- start
696
- delete_users
697
- servers.each{|server| server.stop}
698
- self
699
- end
700
-
701
- def clobber
702
- FileUtils.rm_rf @config[:dbpath]
703
- self
704
- end
705
- end
706
-
707
- end
708
- end