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
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