Permalink
Browse files

Merge branch 'dev'

  • Loading branch information...
2 parents 9d2034d + cf6781c commit 287ddafc2fa26d5361b0e15b276cfedbaed08664 @brandonblack brandonblack committed Oct 11, 2012
Showing with 925 additions and 693 deletions.
  1. +1 −0 .gitignore
  2. +3 −0 Gemfile
  3. +12 −0 README.md
  4. +27 −50 Rakefile
  5. 0 {test/load/unicorn → docs/load/thin}/config.ru
  6. 0 {test → docs}/load/thin/config.yml.template
  7. 0 {test → docs}/load/thin/load.rb
  8. 0 {test/load/thin → docs/load/unicorn}/config.ru
  9. 0 {test → docs}/load/unicorn/load.rb
  10. 0 {test → docs}/load/unicorn/unicorn.rb.template
  11. BIN lib/bson_ext/cbson.so
  12. +1 −0 lib/mongo/repl_set_connection.rb
  13. +23 −0 lib/mongo/util/pool.rb
  14. +1 −1 lib/mongo/util/pool_manager.rb
  15. +2 −3 test/auxillary/1.4_features.rb
  16. +1 −3 test/auxillary/authentication_test.rb
  17. +1 −3 test/auxillary/autoreconnect_test.rb
  18. +1 −3 test/auxillary/fork_test.rb
  19. +2 −4 test/auxillary/repl_set_auth_test.rb
  20. +2 −1 test/auxillary/slave_connection_test.rb
  21. +1 −3 test/auxillary/threaded_authentication_test.rb
  22. +1 −1 test/bson/binary_test.rb
  23. +1 −1 test/bson/bson_test.rb
  24. +1 −1 test/bson/byte_buffer_test.rb
  25. +2 −2 test/bson/hash_with_indifferent_access_test.rb
  26. +1 −2 test/bson/json_test.rb
  27. +1 −2 test/bson/object_id_test.rb
  28. +1 −1 test/bson/ordered_hash_test.rb
  29. +0 −29 test/bson/test_helper.rb
  30. +1 −1 test/bson/timestamp_test.rb
  31. +1 −1 test/{ → functional}/collection_test.rb
  32. +1 −1 test/{ → functional}/connection_test.rb
  33. +1 −1 test/{ → functional}/conversions_test.rb
  34. +1 −1 test/{ → functional}/cursor_fail_test.rb
  35. +1 −1 test/{ → functional}/cursor_message_test.rb
  36. +1 −1 test/{ → functional}/cursor_test.rb
  37. +1 −1 test/{ → functional}/db_api_test.rb
  38. +1 −1 test/{ → functional}/db_connection_test.rb
  39. +1 −1 test/{ → functional}/db_test.rb
  40. +1 −1 test/{ → functional}/grid_file_system_test.rb
  41. +3 −3 test/{ → functional}/grid_io_test.rb
  42. +9 −9 test/{ → functional}/grid_test.rb
  43. +1 −1 test/{ → functional}/pool_test.rb
  44. +1 −1 test/{ → functional}/safe_test.rb
  45. +1 −1 test/{ → functional}/support_test.rb
  46. +1 −1 test/{ → functional}/threading_test.rb
  47. +1 −1 test/{ → functional}/timeout_test.rb
  48. +1 −1 test/{ → functional}/uri_test.rb
  49. +127 −0 test/replica_set/basic_test.rb
  50. +62 −0 test/replica_set/complex_connect_test.rb
  51. +112 −0 test/replica_set/connect_test.rb
  52. +46 −0 test/replica_set/count_test.rb
  53. +75 −0 test/replica_set/cursor_test.rb
  54. +55 −0 test/replica_set/insert_test.rb
  55. 0 test/{replica_sets → replica_set/old}/basic_test.rb
  56. 0 test/{replica_sets → replica_set/old}/complex_connect_test.rb
  57. 0 test/{replica_sets → replica_set/old}/complex_read_preference_test.rb
  58. 0 test/{replica_sets → replica_set/old}/connect_test.rb
  59. 0 test/{replica_sets → replica_set/old}/count_test.rb
  60. 0 test/{replica_sets → replica_set/old}/cursor_test.rb
  61. 0 test/{replica_sets → replica_set/old}/insert_test.rb
  62. 0 test/{replica_sets → replica_set/old}/pooled_insert_test.rb
  63. 0 test/{replica_sets → replica_set/old}/query_test.rb
  64. 0 test/{replica_sets → replica_set/old}/read_preference_test.rb
  65. 0 test/{replica_sets → replica_set/old}/refresh_test.rb
  66. 0 test/{replica_sets → replica_set/old}/refresh_with_threads_test.rb
  67. 0 test/{replica_sets → replica_set/old}/replication_ack_test.rb
  68. 0 test/{replica_sets → replica_set/old}/rs_test_helper.rb
  69. +53 −0 test/replica_set/query_test.rb
  70. +71 −0 test/replica_set/replication_ack_test.rb
  71. +5 −24 test/sharded_cluster/basic_test.rb
  72. +0 −39 test/sharded_cluster/sc_test_helper.rb
  73. +49 −4 test/test_helper.rb
  74. +1 −1 test/threading/threading_with_large_pool_test.rb
  75. +142 −39 test/tools/mongo_config.rb
  76. +2 −19 test/{sharded_cluster → tools}/mongo_config_test.rb
  77. +0 −418 test/tools/repl_set_manager.rb
  78. +1 −1 test/unit/collection_test.rb
  79. +1 −1 test/unit/connection_test.rb
  80. +1 −1 test/unit/cursor_test.rb
  81. +1 −1 test/unit/db_test.rb
  82. +1 −1 test/unit/grid_test.rb
  83. +1 −1 test/unit/node_test.rb
  84. +1 −1 test/unit/pool_manager_test.rb
  85. +1 −1 test/unit/pool_test.rb
  86. +1 −1 test/unit/read_test.rb
  87. +1 −1 test/unit/safe_test.rb
View
1 .gitignore
@@ -7,6 +7,7 @@ ydoc
nbproject
*.bundle
*.o
+*.so
ext/cbson/Makefile
lib/mongo_ext/Makefile
lib/bson_ext
View
3 Gemfile
@@ -12,11 +12,14 @@ group :development, :test do
gem "yard"
# Testing
+ gem "test-unit"
gem "mocha"
gem "shoulda"
gem "ci_reporter"
gem "ruby-prof" unless RUBY_PLATFORM =~ /java/
gem "rake-compiler"
+ # posix-spawn: XCode 4.4 - brew install apple-gcc42 && export CC=/usr/local/bin/gcc-4.2 && bundle install
+ gem "posix-spawn" if RUBY_PLATFORM =~ /java/
# Java
platforms :jruby do
View
12 README.md
@@ -331,6 +331,18 @@ If you want to test replica set, you can run the following task:
$ rake test:rs
+To run a single test at the top level, add -Itest since we no longer modify LOAD_PATH:
+
+ $ ruby -Itest -Ilib test/bson/bson_test.rb
+
+To run a single test from the test directory, add -I. since we no longer modify LOAD_PATH:
+
+ $ ruby -I. -I../lib bson/bson_test.rb
+
+To run a single test from its subdirectory, add -I.. since we no longer modify LOAD_PATH:
+
+ $ ruby -I.. -I../../lib bson_test.rb
+
# Release Notes
See HISTORY.
View
77 Rakefile
@@ -1,19 +1,13 @@
# -*- mode: ruby; -*-
-if RUBY_VERSION < '1.9.0'
- require 'rubygems'
- require 'rubygems/specification'
-end
-
-require 'fileutils'
require 'rake'
+require 'fileutils'
require 'rake/testtask'
require 'rake/extensiontask'
require 'rake/javaextensiontask'
begin
require 'git'
require 'devkit'
- require 'ci/reporter/rake/test_unit'
rescue LoadError
end
@@ -62,11 +56,10 @@ task :test do
end
task :path do
- $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
end
namespace :test do
-
desc "Test the driver with the C extension enabled."
task :c => :path do
ENV['C_EXT'] = 'TRUE'
@@ -76,7 +69,7 @@ namespace :test do
Rake::Task['test:unit'].invoke
Rake::Task['test:functional'].invoke
Rake::Task['test:bson'].invoke
- Rake::Task['test:pooled_threading'].invoke
+ #Rake::Task['test:pooled_threading'].invoke
Rake::Task['test:drop_databases'].invoke
end
ENV['C_EXT'] = nil
@@ -91,61 +84,76 @@ namespace :test do
Rake::Task['test:unit'].invoke
Rake::Task['test:functional'].invoke
Rake::Task['test:bson'].invoke
- Rake::Task['test:pooled_threading'].invoke
+ #Rake::Task['test:pooled_threading'].invoke
Rake::Task['test:drop_databases'].invoke
end
end
desc "Run the replica set test suite"
Rake::TestTask.new(:rs) do |t|
- t.test_files = FileList['test/replica_sets/*_test.rb']
- t.ruby_opts << '-w'
- end
-
- desc "Run the replica set test suite"
- Rake::TestTask.new(:rs_no_threads) do |t|
- t.test_files = FileList['test/replica_sets/*_test.rb'] - ["test/replica_sets/refresh_with_threads_test.rb"]
+ t.test_files = FileList['test/replica_set/*_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
desc "Run the sharded cluster test suite"
Rake::TestTask.new(:sc) do |t|
t.test_files = FileList['test/sharded_cluster/*_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:unit) do |t|
t.test_files = FileList['test/unit/*_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:functional) do |t|
- t.test_files = FileList['test/*_test.rb'] - ["test/db_api_test.rb"]
+ t.test_files = FileList['test/functional/*_test.rb'] - [
+ "test/functional/db_api_test.rb",
+ "test/functional/pool_test.rb",
+ "test/functional/threading_test.rb",
+ "test/functional/grid_io_test.rb",
+ "test/functional/grid_test.rb"
+ ]
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:pooled_threading) do |t|
t.test_files = FileList['test/threading/*_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:auto_reconnect) do |t|
t.test_files = FileList['test/auxillary/autoreconnect_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:authentication) do |t|
t.test_files = FileList['test/auxillary/authentication_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:new_features) do |t|
t.test_files = FileList['test/auxillary/1.4_features.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
Rake::TestTask.new(:bson) do |t|
t.test_files = FileList['test/bson/*_test.rb']
+ t.libs << 'test'
+ t.ruby_opts << '-w'
+ end
+
+ Rake::TestTask.new(:config) do |t|
+ t.test_files = FileList['test/tools/mongo_config_test.rb']
+ t.libs << 'test'
t.ruby_opts << '-w'
end
@@ -176,27 +184,6 @@ task :ydoc do
system "yardoc -o #{out} --title MongoRuby-#{Mongo::VERSION}"
end
-namespace :jenkins do
- task :ci_reporter do
- begin
- require 'ci/reporter/rake/test_unit'
- rescue LoadError
- warn "Warning: Unable to load ci_reporter gem."
- end
- end
-
- namespace :test do
- task :ruby do
- Rake::Task['test:ruby'].invoke
- end
-
- task :c do
- Rake::Task['gem:install_extensions'].invoke
- Rake::Task['test:c'].invoke
- end
- end
-end
-
namespace :gem do
desc "Install the gem locally"
task :install do
@@ -223,16 +210,6 @@ namespace :gem do
end
end
-namespace :ci do
- namespace :test do
- task :c => :path do
- Rake::Task['gem:install'].invoke
- Rake::Task['gem:install_extensions'].invoke
- Rake::Task['test:c'].invoke
- end
- end
-end
-
# Deployment
VERSION_FILES = %w(lib/bson/version.rb lib/mongo/version.rb ext/cbson/version.h)
GEMSPECS = %w(bson.gemspec bson.java.gemspec bson_ext.gemspec mongo.gemspec)
View
0 test/load/unicorn/config.ru → docs/load/thin/config.ru
File renamed without changes.
View
0 test/load/thin/config.yml.template → docs/load/thin/config.yml.template
File renamed without changes.
View
0 test/load/thin/load.rb → docs/load/thin/load.rb
File renamed without changes.
View
0 test/load/thin/config.ru → docs/load/unicorn/config.ru
File renamed without changes.
View
0 test/load/unicorn/load.rb → docs/load/unicorn/load.rb
File renamed without changes.
View
0 test/load/unicorn/unicorn.rb.template → docs/load/unicorn/unicorn.rb.template
File renamed without changes.
View
BIN lib/bson_ext/cbson.so
Binary file not shown.
View
1 lib/mongo/repl_set_connection.rb
@@ -96,6 +96,7 @@ class ReplSetConnection < Connection
def initialize(*args)
opts = args.last.is_a?(Hash) ? args.pop : {}
nodes = args
+ nodes = nodes.flatten(1) if nodes.first.is_a?(Array) && nodes.first.first.is_a?(Array)
if nodes.empty? and ENV.has_key?('MONGODB_URI')
parser = URIParser.new ENV['MONGODB_URI']
View
23 lib/mongo/util/pool.rb
@@ -85,6 +85,29 @@ def closed?
@closed
end
+ def up?
+ !@closed
+ end
+
+ def matches_mode(mode)
+ if mode == :primary && @node.secondary? ||
+ mode == :secondary && @node.primary?
+ false
+ else
+ true
+ end
+ end
+
+ def matches_tag_set(tag_set)
+ tag_set.all? do |tag, value|
+ tags.has_key?(tag) && tags[tag] == value
+ end
+ end
+
+ def matches_tag_sets(tag_sets)
+ tag_sets.all? {|set| matches_tag_set(set)}
+ end
+
def inspect
"#<Mongo::Pool:0x#{self.object_id.to_s(16)} @host=#{@host} @port=#{port} " +
"@ping_time=#{@ping_time} #{@checked_out.size}/#{@size} sockets available " +
View
2 lib/mongo/util/pool_manager.rb
@@ -107,7 +107,7 @@ def read_pool(mode=@connection.read_preference, tags=@connection.tag_sets,
end
pinned = @pinned_pools[Thread.current]
- if mode && pinned && select_pool([pinned], tags, acceptable_latency) && !pinned.closed?
+ if pinned && pinned.matches_mode(mode) && pinned.matches_tag_sets(tags) && pinned.up?
pool = pinned
else
pool = case mode
View
5 test/auxillary/1.4_features.rb
@@ -1,7 +1,6 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'test_helper'
require 'mongo'
-require 'test/unit'
-require File.expand_path("../../test_helper", __FILE__)
+
# Demonstrate features in MongoDB 1.4
class Features14Test < Test::Unit::TestCase
View
4 test/auxillary/authentication_test.rb
@@ -1,7 +1,5 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'test_helper'
require 'mongo'
-require 'test/unit'
-require File.expand_path("../../test_helper", __FILE__)
# NOTE: This test requires bouncing the server.
# It also requires that a user exists on the admin database.
View
4 test/auxillary/autoreconnect_test.rb
@@ -1,7 +1,5 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'test_helper'
require 'mongo'
-require 'test/unit'
-require File.expand_path("../../test_helper", __FILE__)
# NOTE: This test requires bouncing the server
class AutoreconnectTest < Test::Unit::TestCase
View
4 test/auxillary/fork_test.rb
@@ -1,7 +1,5 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'test_helper'
require 'mongo'
-require 'test/unit'
-require File.expand_path("../../test_helper", __FILE__)
class ForkTest < Test::Unit::TestCase
include Mongo
View
6 test/auxillary/repl_set_auth_test.rb
@@ -1,7 +1,5 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
-require File.expand_path("../../test_helper", __FILE__)
-require './test/tools/auth_repl_set_manager'
-require './test/replica_sets/rs_test_helper'
+require 'test_helper'
+require 'mongo'
class AuthTest < Test::Unit::TestCase
include Mongo
View
3 test/auxillary/slave_connection_test.rb
@@ -1,4 +1,5 @@
-require File.expand_path("../../test_helper", __FILE__)
+require 'test_helper'
+require 'mongo'
# NOTE: these tests are run only if we can connect to a single MongoDB in slave mode.
class SlaveConnectionTest < Test::Unit::TestCase
View
4 test/auxillary/threaded_authentication_test.rb
@@ -1,8 +1,6 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'test_helper'
require 'mongo'
require 'thread'
-require 'test/unit'
-require File.expand_path("../../test_helper", __FILE__)
# NOTE: This test requires bouncing the server.
# It also requires that a user exists on the admin database.
View
2 test/bson/binary_test.rb
@@ -1,5 +1,5 @@
# encoding:utf-8
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class BinaryTest < Test::Unit::TestCase
def setup
View
2 test/bson/bson_test.rb
@@ -1,5 +1,5 @@
# encoding:utf-8
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'set'
if RUBY_VERSION < '1.9'
View
2 test/bson/byte_buffer_test.rb
@@ -1,5 +1,5 @@
# encoding: binary
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class ByteBufferTest < Test::Unit::TestCase
include BSON
View
4 test/bson/hash_with_indifferent_access_test.rb
@@ -1,6 +1,6 @@
# encoding:utf-8
-require File.expand_path("../test_helper", __FILE__)
-require './test/support/hash_with_indifferent_access'
+require 'test_helper'
+require 'support/hash_with_indifferent_access'
class HashWithIndifferentAccessTest < Test::Unit::TestCase
include BSON
View
3 test/bson/json_test.rb
@@ -1,5 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
-require 'rubygems'
+require 'test_helper'
require 'json'
class JSONTest < Test::Unit::TestCase
View
3 test/bson/object_id_test.rb
@@ -1,5 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
-require 'rubygems'
+require 'test_helper'
require 'json'
class ObjectIdTest < Test::Unit::TestCase
View
2 test/bson/ordered_hash_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class OrderedHashTest < Test::Unit::TestCase
View
29 test/bson/test_helper.rb
@@ -1,29 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'bson')
-require 'rubygems' if RUBY_VERSION < '1.9.0'
-require 'test/unit'
-
-def silently
- warn_level = $VERBOSE
- $VERBOSE = nil
- result = yield
- $VERBOSE = warn_level
- result
-end
-
-require 'bson_ext/cbson' if !(RUBY_PLATFORM =~ /java/) && ENV['C_EXT']
-
-class Test::Unit::TestCase
- include BSON
-
- def assert_raise_error(klass, message)
- begin
- yield
- rescue => e
- assert_equal klass, e.class
- assert e.message.include?(message), "#{e.message} does not include #{message}."
- else
- flunk "Expected assertion #{klass} but none was raised."
- end
- end
-
-end
View
2 test/bson/timestamp_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class TimestampTest < Test::Unit::TestCase
View
2 test/collection_test.rb → test/functional/collection_test.rb
@@ -1,5 +1,5 @@
-require File.expand_path("../test_helper", __FILE__)
require 'rbconfig'
+require 'test_helper'
class TestCollection < Test::Unit::TestCase
@@connection ||= standard_connection(:op_timeout => 10)
View
2 test/connection_test.rb → test/functional/connection_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'logger'
require 'stringio'
require 'thread'
View
2 test/conversions_test.rb → test/functional/conversions_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'mongo/exceptions'
require 'mongo/util/conversions'
View
2 test/cursor_fail_test.rb → test/functional/cursor_fail_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'logger'
class CursorFailTest < Test::Unit::TestCase
View
2 test/cursor_message_test.rb → test/functional/cursor_message_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'logger'
class CursorMessageTest < Test::Unit::TestCase
View
2 test/cursor_test.rb → test/functional/cursor_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'logger'
class CursorTest < Test::Unit::TestCase
View
2 test/db_api_test.rb → test/functional/db_api_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class DBAPITest < Test::Unit::TestCase
include Mongo
View
2 test/db_connection_test.rb → test/functional/db_connection_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class DBConnectionTest < Test::Unit::TestCase
View
2 test/db_test.rb → test/functional/db_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'digest/md5'
require 'stringio'
require 'logger'
View
2 test/grid_file_system_test.rb → test/functional/grid_file_system_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class GridFileSystemTest < Test::Unit::TestCase
context "GridFileSystem:" do
View
6 test/grid_io_test.rb → test/functional/grid_io_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class GridIOTest < Test::Unit::TestCase
@@ -193,15 +193,15 @@ class GridIOTest < Test::Unit::TestCase
end
should "validate with a large file" do
- io = File.open(File.join(File.dirname(__FILE__), 'data', 'sample_file.pdf'), 'r')
+ io = File.open(File.join(TEST_DATA, 'sample_file.pdf'), 'r')
file = GridIO.new(@files, @chunks, 'bigfile', 'w', :safe => true)
file.write(io)
assert file.close
assert_equal file.server_md5, file.client_md5
end
should "raise an exception when check fails" do
- io = File.open(File.join(File.dirname(__FILE__), 'data', 'sample_file.pdf'), 'r')
+ io = File.open(File.join(TEST_DATA, 'sample_file.pdf'), 'r')
@db.stubs(:command).returns({'md5' => '12345'})
file = GridIO.new(@files, @chunks, 'bigfile', 'w', :safe => true)
file.write(io)
View
18 test/grid_test.rb → test/functional/grid_test.rb
@@ -1,8 +1,8 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
include Mongo
def read_and_write_stream(filename, read_length, opts={})
- io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r+b')
+ io = File.open(File.join(TEST_DATA, filename), 'r+b')
id = @grid.put(io, opts.merge!(:filename => filename + read_length.to_s))
file = @grid.get(id)
io.rewind
@@ -59,11 +59,11 @@ class GridTest < Test::Unit::TestCase
assert_equal 'sample', file['filename']
end
- should "not be able to overwrite an exising file" do
- assert_raise GridError do
- @grid.put(@data, :filename => 'sample', :_id => @id, :safe => true)
- end
- end
+ #should "not be able to overwrite an exising file" do
+ # assert_raise GridError do
+ # @grid.put(@data, :filename => 'sample', :_id => @id, :safe => true)
+ # end
+ #end
should "return nil if it doesn't exist" do
assert_nil @grid.exist?(:metadata => 'foo')
@@ -170,7 +170,7 @@ class GridTest < Test::Unit::TestCase
setup do
@grid = Grid.new(@db, 'test-fs')
filename = 'sample_data'
- @io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
+ @io = File.open(File.join(TEST_DATA, filename), 'r')
id = @grid.put(@io, :filename => filename)
@file = @grid.get(id)
@io.rewind
@@ -203,7 +203,7 @@ class GridTest < Test::Unit::TestCase
setup do
@grid = Grid.new(@db, 'test-fs')
filename = 'empty_data'
- @io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
+ @io = File.open(File.join(TEST_DATA, filename), 'r')
id = silently do
@grid.put(@io, :filename => filename)
end
View
2 test/pool_test.rb → test/functional/pool_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
require 'thread'
class PoolTest < Test::Unit::TestCase
View
2 test/safe_test.rb → test/functional/safe_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
include Mongo
class SafeTest < Test::Unit::TestCase
View
2 test/support_test.rb → test/functional/support_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class SupportTest < Test::Unit::TestCase
View
2 test/threading_test.rb → test/functional/threading_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class TestThreading < Test::Unit::TestCase
View
2 test/timeout_test.rb → test/functional/timeout_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class TestTimeout < Test::Unit::TestCase
def test_op_timeout
View
2 test/uri_test.rb → test/functional/uri_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../test_helper", __FILE__)
+require 'test_helper'
class URITest < Test::Unit::TestCase
include Mongo
View
127 test/replica_set/basic_test.rb
@@ -0,0 +1,127 @@
+require 'test_helper'
+
+class BasicTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ # To reset after (test) failure
+ # $ killall mongod; rm -fr rs
+
+ def test_connect
+ conn = Mongo::ReplSetConnection.new(@rs.repl_set_seeds, :name => @rs.repl_set_name)
+ assert conn.connected?
+ assert_equal @rs.primary_name, conn.primary.join(':')
+ assert_equal @rs.secondary_names.sort, conn.secondaries.collect{|s| s.join(':')}.sort
+ assert_equal @rs.arbiter_names.sort, conn.arbiters.collect{|s| s.join(':')}.sort
+ conn.close
+
+ silently do
+ conn = Mongo::ReplSetConnection.new(@rs.repl_set_seeds_old, :name => @rs.repl_set_name)
+ end
+
+ assert conn.connected?
+ conn.close
+ end
+
+ def test_multiple_concurrent_replica_set_connection
+ conn1 = ReplSetConnection.new(@rs.repl_set_seeds, :name => @rs.repl_set_name)
+ conn2 = ReplSetConnection.new(@rs.repl_set_seeds, :name => @rs.repl_set_name)
+ assert conn1.connected?
+ assert conn2.connected?
+ assert conn1.manager != conn2.manager
+ assert conn1.local_manager != conn2.local_manager
+ conn1.close
+ conn2.close
+ end
+
+ def test_cache_original_seed_nodes
+ host = @rs.servers.first.host
+ seeds = @rs.repl_set_seeds << "#{host}:19356"
+ conn = ReplSetConnection.new(seeds, :name => @rs.repl_set_name)
+ assert conn.connected?
+ assert conn.seeds.include?([host, 19356]), "Original seed nodes not cached!"
+ assert_equal [host, 19356], conn.seeds.last, "Original seed nodes not cached!"
+ conn.close
+ end
+
+ def test_accessors
+ seeds = @rs.repl_set_seeds
+ args = {:name => @rs.repl_set_name}
+ conn = ReplSetConnection.new(seeds, args)
+ assert_equal @rs.primary_name, [conn.host, conn.port].join(':')
+ assert_equal conn.host, conn.primary_pool.host
+ assert_equal conn.port, conn.primary_pool.port
+ assert_equal 2, conn.secondaries.length
+ assert_equal 2, conn.arbiters.length
+ assert_equal 2, conn.secondary_pools.length
+ assert_equal @rs.repl_set_name, conn.replica_set_name
+ assert conn.secondary_pools.include?(conn.read_pool(:secondary))
+ assert_equal 90, conn.refresh_interval
+ assert_equal conn.refresh_mode, false
+ conn.close
+ end
+
+ context "Socket pools" do
+ context "checking out writers" do
+ setup do
+ seeds = @rs.repl_set_seeds
+ args = {:name => @rs.repl_set_name}
+ @con = ReplSetConnection.new(seeds, args)
+ @coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
+ end
+
+ should "close the connection on send_message for major exceptions" do
+ @con.expects(:checkout_writer).raises(SystemStackError)
+ @con.expects(:close)
+ begin
+ @coll.insert({:foo => "bar"})
+ rescue SystemStackError
+ end
+ end
+
+ should "close the connection on send_message_with_safe_check for major exceptions" do
+ @con.expects(:checkout_writer).raises(SystemStackError)
+ @con.expects(:close)
+ begin
+ @coll.insert({:foo => "bar"}, :safe => true)
+ rescue SystemStackError
+ end
+ end
+
+ should "close the connection on receive_message for major exceptions" do
+ @con.expects(:checkout_reader).raises(SystemStackError)
+ @con.expects(:close)
+ begin
+ @coll.find({}, :read => :primary).next
+ rescue SystemStackError
+ end
+ end
+ end
+
+ context "checking out readers" do
+ setup do
+ seeds = @rs.repl_set_seeds
+ args = {:name => @rs.repl_set_name}
+ @con = ReplSetConnection.new(seeds, args)
+ @coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
+ end
+
+ should "close the connection on receive_message for major exceptions" do
+ @con.expects(:checkout_reader).raises(SystemStackError)
+ @con.expects(:close)
+ begin
+ @coll.find({}, :read => :secondary).next
+ rescue SystemStackError
+ end
+ end
+ end
+ end
+
+end
View
62 test/replica_set/complex_connect_test.rb
@@ -0,0 +1,62 @@
+require 'test_helper'
+
+class ComplexConnectTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ def teardown
+ @conn.close if defined?(@conn) && @conn
+ end
+
+ def test_complex_connect
+ host = @rs.servers.first.host
+ primary = Connection.new(host, @rs.primary.port)
+
+ @conn = ReplSetConnection.new([
+ @rs.servers[2].host_port,
+ @rs.servers[1].host_port,
+ @rs.servers[0].host_port
+ ])
+
+ version = @conn.server_version
+
+ @conn['test']['foo'].insert({:a => 1})
+ assert @conn['test']['foo'].find_one
+
+ config = primary['local']['system.replset'].find_one
+ config['version'] += 1
+ port_to_delete = @rs.servers.collect(&:port).find{|port| port != primary.port}.to_s # eliminate exception: can't find self in new replset config
+ config['members'].delete_if do |member|
+ member['host'].include?(port_to_delete)
+ end
+
+ assert_raise ConnectionFailure do
+ primary['admin'].command({:replSetReconfig => config})
+ end
+ @rs.start
+
+ force_stepdown = BSON::OrderedHash.new
+ force_stepdown[:replSetStepDown] = 1
+ force_stepdown[:force] = true
+
+ assert_raise ConnectionFailure do
+ primary['admin'].command(force_stepdown)
+ end
+
+ # isMaster is currently broken in 2.1+ when called on removed nodes
+ if version < "2.1"
+ rescue_connection_failure do
+ assert @conn['test']['foo'].find_one
+ end
+
+ assert @conn['test']['foo'].find_one
+ end
+ end
+end
View
112 test/replica_set/connect_test.rb
@@ -0,0 +1,112 @@
+require 'test_helper'
+
+class ConnectTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ # To reset after (test) failure
+ # $ killall mongod; rm -fr rs
+
+ def step_down_command
+ # Adding force=true to avoid 'no secondaries within 10 seconds of my optime' errors
+ step_down_command = BSON::OrderedHash.new
+ step_down_command[:replSetStepDown] = 60
+ step_down_command[:force] = true
+ step_down_command
+ end
+
+ # TODO: test connect timeout.
+
+ def test_connect_with_deprecated_multi
+ host = @rs.servers.first.host
+ @conn = Connection.multi([
+ # guaranteed to have one data-holding member
+ [host, @rs.servers[0].port],
+ [host, @rs.servers[1].port],
+ [host, @rs.servers[2].port],
+ ], :name => @rs.repl_set_name)
+ assert @conn.is_a?(ReplSetConnection)
+ assert @conn.connected?
+ @conn.close
+ end
+
+ def test_connect_bad_name
+ assert_raise_error(ReplicaSetConnectionError, "-wrong") do
+ @conn = ReplSetConnection.new(@rs.repl_set_seeds, :name => @rs.repl_set_name + "-wrong")
+ end
+ end
+
+ def test_connect_with_first_secondary_node_terminated
+ @rs.secondaries.first.stop
+
+ rescue_connection_failure do
+ @conn = ReplSetConnection.new @rs.repl_set_seeds
+ end
+ assert @conn.connected?
+ @conn.close
+ end
+
+ #def test_connect_with_last_secondary_node_terminated
+ # @rs.secondaries.last.stop
+ #
+ # rescue_connection_failure do
+ # @conn = ReplSetConnection.new @rs.repl_set_seeds
+ # end
+ # assert @conn.connected?
+ # @conn.close
+ #end
+
+ #def test_connect_with_primary_stepped_down
+ # @conn = ReplSetConnection.new @rs.repl_set_seeds
+ # @conn[MONGO_TEST_DB]['bar'].save({:a => 1}, {:safe => {:w => 3}})
+ # assert @conn[MONGO_TEST_DB]['bar'].find_one
+ #
+ # primary = Mongo::Connection.new(@conn.primary_pool.host, @conn.primary_pool.port)
+ # assert_raise Mongo::ConnectionFailure do
+ # primary['admin'].command(step_down_command)
+ # end
+ # assert @conn.connected?
+ #
+ # rescue_connection_failure do
+ # @conn[MONGO_TEST_DB]['bar'].find_one
+ # end
+ # @conn.close
+ #end
+
+ #def test_connect_with_primary_killed
+ # @conn = ReplSetConnection.new @rs.repl_set_seeds
+ # assert @conn.connected?
+ # @conn[MONGO_TEST_DB]['bar'].save({:a => 1}, {:safe => {:w => 3}})
+ # assert @conn[MONGO_TEST_DB]['bar'].find_one
+ #
+ # @rs.primary.kill(Signal.list['KILL'])
+ #
+ # rescue_connection_failure do
+ # @conn[MONGO_TEST_DB]['bar'].find_one
+ # end
+ # @conn.close
+ #end
+
+ #def test_save_with_primary_stepped_down
+ # @conn = ReplSetConnection.new @rs.repl_set_seeds
+ # assert @conn.connected?
+ #
+ # primary = Mongo::Connection.new(@conn.primary_pool.host, @conn.primary_pool.port)
+ # assert_raise Mongo::ConnectionFailure do
+ # primary['admin'].command(step_down_command)
+ # end
+ #
+ # rescue_connection_failure do
+ # @conn[MONGO_TEST_DB]['bar'].save({:a => 1}, {:safe => {:w => 3}})
+ # end
+ # @conn.close
+ #end
+
+end
View
46 test/replica_set/count_test.rb
@@ -0,0 +1,46 @@
+require 'test_helper'
+
+class ReplicaSetCountTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ @conn = ReplSetConnection.new(@rs.repl_set_seeds, :read => :primary_preferred)
+ assert @conn.primary_pool
+ @primary = Connection.new(@conn.primary_pool.host, @conn.primary_pool.port)
+ @db = @conn.db(MONGO_TEST_DB)
+ @db.drop_collection("test-sets")
+ @coll = @db.collection("test-sets")
+ end
+
+ def teardown
+ @conn.close if @conn
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ def test_correct_count_after_insertion_reconnect
+ @coll.insert({:a => 20}, :safe => {:w => 2, :wtimeout => 10000})
+ assert_equal 1, @coll.count
+
+ # Kill the current master node
+ @rs.primary.stop
+
+ rescue_connection_failure do
+ @coll.insert({:a => 30}, :safe => true)
+ end
+
+ @coll.insert({:a => 40}, :safe => true)
+ assert_equal 3, @coll.count, "Second count failed"
+ end
+
+ def test_count_command_sent_to_primary
+ @coll.insert({:a => 20}, :safe => {:w => 2, :wtimeout => 10000})
+ count_before = @primary['admin'].command({:serverStatus => 1})['opcounters']['command']
+ assert_equal 1, @coll.count
+ count_after = @primary['admin'].command({:serverStatus => 1})['opcounters']['command']
+ assert_equal 2, count_after - count_before
+ end
+end
View
75 test/replica_set/cursor_test.rb
@@ -0,0 +1,75 @@
+require 'test_helper'
+
+class ReplicaSetCursorTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ def test_cursors_get_closed
+ setup_connection
+ assert_cursor_count
+ end
+
+ def test_cursors_get_closed_secondary
+ setup_connection(:secondary)
+ assert_cursor_count
+ end
+
+ private
+
+ def setup_connection(read=:primary)
+ # Setup ReplicaSet Connection
+ @replconn = Mongo::ReplSetConnection.new(
+ @rs.repl_set_seeds,
+ :read => read
+ )
+
+ @db = @replconn.db(MONGO_TEST_DB)
+ @db.drop_collection("cursor_tests")
+ @coll = @db.collection("cursor_tests")
+
+ @coll.insert({:a => 1}, :safe => true, :w => 3)
+ @coll.insert({:b => 2}, :safe => true, :w => 3)
+ @coll.insert({:c => 3}, :safe => true, :w => 3)
+
+ # Pin reader
+ @coll.find_one
+
+ # Setup Direct Connections
+ @primary = Mongo::Connection.new(*@replconn.manager.primary)
+ @read = Mongo::Connection.new(*@replconn.manager.read)
+ end
+
+ def cursor_count(connection)
+ connection['cursor_tests'].command({:cursorInfo => 1})['totalOpen']
+ end
+
+ def query_count(connection)
+ connection['admin'].command({:serverStatus => 1})['opcounters']['query']
+ end
+
+ def assert_cursor_count
+ before_primary = cursor_count(@primary)
+ before_read = cursor_count(@read)
+ before_query = query_count(@read)
+
+ @coll.find.limit(2).to_a
+ sleep(1)
+
+ after_primary = cursor_count(@primary)
+ after_read = cursor_count(@read)
+ after_query = query_count(@read)
+
+ assert_equal before_primary, after_primary
+ assert_equal before_read, after_read
+ assert_equal 1, after_query - before_query
+ end
+
+end
+
View
55 test/replica_set/insert_test.rb
@@ -0,0 +1,55 @@
+require 'test_helper'
+
+class ReplicaSetInsertTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ @conn = ReplSetConnection.new @rs.repl_set_seeds
+ @db = @conn.db(MONGO_TEST_DB)
+ @db.drop_collection("test-sets")
+ @coll = @db.collection("test-sets")
+ end
+
+ def teardown
+ @conn.close if @conn
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ def test_insert
+ @coll.save({:a => 20}, :safe => {:w => 2})
+
+ @rs.primary.stop
+
+ rescue_connection_failure do
+ @coll.save({:a => 30}, :safe => {:w => 2})
+ end
+
+ @coll.save({:a => 40}, :safe => {:w => 2})
+ @coll.save({:a => 50}, :safe => {:w => 2})
+ @coll.save({:a => 60}, :safe => {:w => 2})
+ @coll.save({:a => 70}, :safe => {:w => 2})
+
+ # Restart the old master and wait for sync
+ @rs.start
+ sleep(5)
+ results = []
+
+ rescue_connection_failure do
+ @coll.find.each {|r| results << r}
+ [20, 30, 40, 50, 60, 70].each do |a|
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
+ end
+ end
+
+ @coll.save({:a => 80}, :safe => {:w => 2})
+ @coll.find.each {|r| results << r}
+ [20, 30, 40, 50, 60, 70, 80].each do |a|
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a} on second find"
+ end
+ end
+
+end
View
0 test/replica_sets/basic_test.rb → test/replica_set/old/basic_test.rb
File renamed without changes.
View
0 test/replica_sets/complex_connect_test.rb → test/replica_set/old/complex_connect_test.rb
File renamed without changes.
View
0 ...lica_sets/complex_read_preference_test.rb → ...a_set/old/complex_read_preference_test.rb
File renamed without changes.
View
0 test/replica_sets/connect_test.rb → test/replica_set/old/connect_test.rb
File renamed without changes.
View
0 test/replica_sets/count_test.rb → test/replica_set/old/count_test.rb
File renamed without changes.
View
0 test/replica_sets/cursor_test.rb → test/replica_set/old/cursor_test.rb
File renamed without changes.
View
0 test/replica_sets/insert_test.rb → test/replica_set/old/insert_test.rb
File renamed without changes.
View
0 test/replica_sets/pooled_insert_test.rb → test/replica_set/old/pooled_insert_test.rb
File renamed without changes.
View
0 test/replica_sets/query_test.rb → test/replica_set/old/query_test.rb
File renamed without changes.
View
0 test/replica_sets/read_preference_test.rb → test/replica_set/old/read_preference_test.rb
File renamed without changes.
View
0 test/replica_sets/refresh_test.rb → test/replica_set/old/refresh_test.rb
File renamed without changes.
View
0 ...replica_sets/refresh_with_threads_test.rb → ...lica_set/old/refresh_with_threads_test.rb
File renamed without changes.
View
0 test/replica_sets/replication_ack_test.rb → test/replica_set/old/replication_ack_test.rb
File renamed without changes.
View
0 test/replica_sets/rs_test_helper.rb → test/replica_set/old/rs_test_helper.rb
File renamed without changes.
View
53 test/replica_set/query_test.rb
@@ -0,0 +1,53 @@
+require 'test_helper'
+
+class ReplicaSetQueryTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ @conn = ReplSetConnection.new @rs.repl_set_seeds
+ @db = @conn.db(MONGO_TEST_DB)
+ @db.drop_collection("test-sets")
+ @coll = @db.collection("test-sets")
+ end
+
+ def teardown
+ @conn.close if @conn
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ def test_query
+ @coll.save({:a => 20}, :safe => {:w => 3})
+ @coll.save({:a => 30}, :safe => {:w => 3})
+ @coll.save({:a => 40}, :safe => {:w => 3})
+ results = []
+ @coll.find.each {|r| results << r}
+ [20, 30, 40].each do |a|
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
+ end
+
+ #puts "Benchmark before failover: #{benchmark_queries}"
+
+ @rs.primary.stop
+
+ results = []
+ rescue_connection_failure do
+ @coll.find.each {|r| results << r}
+ [20, 30, 40].each do |a|
+ assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
+ end
+
+ #puts "Benchmark after failover: #{benchmark_queries}"
+ end
+ end
+
+ def benchmark_queries
+ t1 = Time.now
+ 10000.times { @coll.find_one }
+ Time.now - t1
+ end
+
+end
View
71 test/replica_set/replication_ack_test.rb
@@ -0,0 +1,71 @@
+require 'test_helper'
+
+class ReplicaSetAckTest < Test::Unit::TestCase
+
+ def setup
+ ensure_cluster(:rs)
+ @conn = ReplSetConnection.new(@rs.repl_set_seeds)
+
+ @slave1 = Connection.new(@conn.secondary_pools[0].host,
+ @conn.secondary_pools[0].port, :slave_ok => true)
+
+ assert !@slave1.read_primary?
+
+ @db = @conn.db(MONGO_TEST_DB)
+ @db.drop_collection("test-sets")
+ @col = @db.collection("test-sets")
+ end
+
+ def teardown
+ @conn.close if @conn
+ end
+
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
+ end
+
+ def test_safe_mode_with_w_failure
+ assert_raise_error OperationFailure, "timeout" do
+ @col.insert({:foo => 1}, :safe => {:w => 4, :wtimeout => 1, :fsync => true})
+ end
+ assert_raise_error OperationFailure, "timeout" do
+ @col.update({:foo => 1}, {:foo => 2}, :safe => {:w => 4, :wtimeout => 1, :fsync => true})
+ end
+ assert_raise_error OperationFailure, "timeout" do
+ @col.remove({:foo => 2}, :safe => {:w => 4, :wtimeout => 1, :fsync => true})
+ end
+ end
+
+ def test_safe_mode_replication_ack
+ @col.insert({:baz => "bar"}, :safe => {:w => 3, :wtimeout => 5000})
+
+ assert @col.insert({:foo => "0" * 5000}, :safe => {:w => 3, :wtimeout => 5000})
+ assert_equal 2, @slave1[MONGO_TEST_DB]["test-sets"].count
+
+ assert @col.update({:baz => "bar"}, {:baz => "foo"}, :safe => {:w => 3, :wtimeout => 5000})
+ assert @slave1[MONGO_TEST_DB]["test-sets"].find_one({:baz => "foo"})
+
+ assert @col.remove({}, :safe => {:w => 3, :wtimeout => 5000})
+ assert_equal 0, @slave1[MONGO_TEST_DB]["test-sets"].count
+ end
+
+ def test_last_error_responses
+ 20.times { @col.insert({:baz => "bar"}) }
+ response = @db.get_last_error(:w => 2, :wtimeout => 5000)
+ assert response['ok'] == 1
+ assert response['lastOp']
+
+ @col.update({}, {:baz => "foo"}, :multi => true)
+ response = @db.get_last_error(:w => 2, :wtimeout => 5000)
+ assert response['ok'] == 1
+ assert response['lastOp']
+
+ @col.remove({})
+ response = @db.get_last_error(:w => 2, :wtimeout => 5000)
+ assert response['ok'] == 1
+ assert response['n'] == 20
+ assert response['lastOp']
+ end
+
+end
View
29 test/sharded_cluster/basic_test.rb
@@ -1,32 +1,13 @@
-$:.unshift(File.expand_path('../..', File.dirname(__FILE__)))
-require 'test/sharded_cluster/sc_test_helper'
-require 'test/tools/mongo_config'
+require 'test_helper'
class BasicTest < Test::Unit::TestCase
-
- def self.suite
- s = super
- def s.setup
-
- end
- def s.teardown
- @@sc.stop
- @@sc.clobber
- end
- def s.run(*args)
- setup
- super
- teardown
- end
- s
- end
-
def setup
- ensure_sc
+ ensure_cluster(:sc)
end
- def teardown
-
+ def self.shutdown
+ @@cluster.stop
+ @@cluster.clobber
end
# TODO member.primary? ==> true
View
39 test/sharded_cluster/sc_test_helper.rb
@@ -1,39 +0,0 @@
-$:.unshift(File.expand_path('../../lib', File.dirname(__FILE__)))
-require File.expand_path("../../test_helper", __FILE__)
-require 'test/tools/mongo_config'
-
-class Test::Unit::TestCase
- # Ensure sharded cluster is available as an instance variable and that
- # a new set is spun up for each TestCase class
- def ensure_sc
- if defined?(@@current_class) and @@current_class == self.class
- @@sc.start
- else
- @@current_class = self.class
- dbpath = 'sc'
- opts = Mongo::Config::DEFAULT_SHARDED_SIMPLE.merge(:dbpath => dbpath).merge(:routers => 4)
- #debug 1, opts
- config = Mongo::Config.cluster(opts)
- #debug 1, config
- @@sc = Mongo::Config::ClusterManager.new(config)
- @@sc.start
- end
- @sc = @@sc
- end
-
- # Generic code for rescuing connection failures and retrying operations.
- # This could be combined with some timeout functionality.
- def rescue_connection_failure(max_retries=30)
- retries = 0
- begin
- yield
- rescue Mongo::ConnectionFailure => ex
- #puts "Rescue attempt #{retries}: from #{ex}"
- retries += 1
- raise ex if retries > max_retries
- sleep(2)
- retry
- end
- end
-
-end
View
53 test/test_helper.rb
@@ -1,7 +1,53 @@
-$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
-require 'mongo'
-require 'rubygems' if RUBY_VERSION < '1.9.0'
+require 'rubygems'
+gem 'test-unit'
require 'test/unit'
+require 'tools/mongo_config'
+
+TEST_DATA = File.join(File.dirname(__FILE__), 'data')
+
+class Test::Unit::TestCase
+
+ def ensure_cluster(kind=nil)
+ if defined?(@@current_class) and @@current_class == self.class
+ @@cluster.start
+ else
+ @@current_class = self.class
+
+ if kind == :rs
+ opts = Mongo::Config::DEFAULT_REPLICA_SET
+ opts.merge!(:arbiters => 2)
+ else
+ opts = Mongo::Config::DEFAULT_SHARDED_SIMPLE
+ opts.merge!(:routers => 4)
+ end
+
+ dbpath = ENV['DBPATH'] || 'data'
+ opts.merge!(:dbpath => dbpath)
+
+ #debug 1, opts
+ config = Mongo::Config.cluster(opts)
+ #debug 1, config
+ @@cluster = Mongo::Config::ClusterManager.new(config)
+ @@cluster.start
+ end
+ instance_variable_set("@#{kind}", @@cluster)
+ end
+
+ # Generic code for rescuing connection failures and retrying operations.
+ # This could be combined with some timeout functionality.
+ def rescue_connection_failure(max_retries=30)
+ retries = 0
+ begin
+ yield
+ rescue Mongo::ConnectionFailure => ex
+ #puts "Rescue attempt #{retries}: from #{ex}"
+ retries += 1
+ raise ex if retries > max_retries
+ sleep(2)
+ retry
+ end
+ end
+end
def silently
warn_level = $VERBOSE
@@ -15,7 +61,6 @@ def silently
end
begin
- require 'rubygems' if RUBY_VERSION < "1.9.0" && !ENV['C_EXT']
silently { require 'shoulda' }
silently { require 'mocha' }
rescue LoadError
View
2 test/threading/threading_with_large_pool_test.rb
@@ -1,4 +1,4 @@
-require File.expand_path("../../test_helper", __FILE__)
+require 'test_helper'
# Essentialy the same as test_threading.rb but with an expanded pool for
# testing multiple connections.
View
181 test/tools/mongo_config.rb
@@ -1,15 +1,12 @@
#!/usr/bin/env ruby
-
require 'socket'
require 'fileutils'
+require 'mongo'
+require 'posix/spawn' if RUBY_PLATFORM == 'java'
$debug_level = 2
STDOUT.sync = true
-unless defined? Mongo
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
-end
-
def debug(level, arg)
if level <= $debug_level
file_line = caller[0][/(.*:\d+):/, 1]
@@ -18,19 +15,28 @@ def debug(level, arg)
end
end
+#
+# Design Notes
+# Configuration and Cluster Management are modularized with the concept that the Cluster Manager
+# can be supplied with any configuration to run.
+# A configuration can be edited, modified, copied into a test file, and supplied to a cluster manager
+# as a parameter.
+#
module Mongo
class Config
- DEFAULT_BASE_OPTS = { :host => 'localhost', :logpath => 'data/log', :dbpath => 'data' }
+ DEFAULT_BASE_OPTS = { :host => 'localhost', :dbpath => 'data' }
DEFAULT_REPLICA_SET = DEFAULT_BASE_OPTS.merge( :replicas => 3 )
DEFAULT_SHARDED_SIMPLE = DEFAULT_BASE_OPTS.merge( :shards => 2, :configs => 1, :routers => 2 )
DEFAULT_SHARDED_REPLICA = DEFAULT_SHARDED_SIMPLE.merge( :replicas => 3 )
SERVER_PRELUDE_KEYS = [:host, :command]
SHARDING_OPT_KEYS = [:shards, :configs, :routers]
- REPLICA_OPT_KEYS = [:replicas]
+ REPLICA_OPT_KEYS = [:replicas, :arbiters]
MONGODS_OPT_KEYS = [:mongods]
CLUSTER_OPT_KEYS = SHARDING_OPT_KEYS + REPLICA_OPT_KEYS + MONGODS_OPT_KEYS
+ FLAGS = [:noprealloc, :nojournal, :smallfiles, :logappend]
+
DEFAULT_VERIFIES = 60
BASE_PORT = 3000
@@port = BASE_PORT
@@ -40,25 +46,50 @@ def self.configdb(config)
end
def self.cluster(opts = DEFAULT_SHARDED_SIMPLE)
+ mongod = ENV['MONGOD'] || 'mongod'
+ mongos = ENV['MONGOS'] || 'mongos'
+
+ dbpath = opts[:dbpath]
+ replSet = opts[:replSet] || 'ruby-driver-test'
+ oplog_size = opts[:oplog_size] || 10
+ nojournal = opts[:nojournal] || nil
+ noprealloc = opts[:noprealloc] || true
+ smallfiles = opts[:smallfiles] || true
+ logappend = opts[:logappend] || true
+
raise "missing required option" if [:host, :dbpath].any?{|k| !opts[k]}
- config = opts.reject{|k,v| CLUSTER_OPT_KEYS.include?(k)}
- keys = SHARDING_OPT_KEYS.any?{|k| opts[k]} ? SHARDING_OPT_KEYS : nil
- keys ||= REPLICA_OPT_KEYS.any?{|k| opts[k]} ? REPLICA_OPT_KEYS : nil
- keys ||= MONGODS_OPT_KEYS
- keys.each do |key|
- config[key] = opts.fetch(key,1).times.collect do |i| #default to 1 of whatever
- server_base = key.to_s.chop
- dbpath = "#{opts[:dbpath]}/#{server_base}#{i}"
- logpath = "#{dbpath}/#{server_base}.log"
- if key == :shards && opts[:replicas]
- self.cluster(opts.reject{|k,v| SHARDING_OPT_KEYS.include?(k)}.merge(:dbpath => dbpath))
+
+ config = opts.reject {|k,v| CLUSTER_OPT_KEYS.include?(k)}
+ kinds = opts.keys.select {|k| CLUSTER_OPT_KEYS.include?(k)}
+
+ kinds.each do |kind|
+ config[kind] = opts.fetch(kind,1).times.collect do |i| #default to 1 of whatever
+
+ server_base = kind.to_s.chop
+ path = "#{dbpath}/#{server_base}#{i}"
+ logpath = "#{path}/#{server_base}.log"
+
+ if kind == :shards && opts[:replicas]
+ self.cluster(opts.reject{|k,v| SHARDING_OPT_KEYS.include?(k)}.merge(:dbpath => path))
else
- server_params = { :host => opts[:host], :port => self.get_available_port, :logpath => logpath }
- case key
- when :replicas; server_params.merge!( :command => 'mongod', :dbpath => dbpath, :replSet => File.basename(opts[:dbpath]) )
- when :configs; server_params.merge!( :command => 'mongod', :dbpath => dbpath, :configsvr => nil )
- when :routers; server_params.merge!( :command => 'mongos', :configdb => self.configdb(config) ) # mongos, NO dbpath
- else server_params.merge!( :command => 'mongod', :dbpath => dbpath ) # :mongods, :shards
+ server_params = {
+ :host => opts[:host],
+ :port => self.get_available_port,
+ :logpath => logpath,
+ :logappend => logappend
+ }
+ #TODO: make this not awful
+ case kind
+ when :replicas
+ server_params.merge!( :command => mongod, :dbpath => path, :replSet => replSet, :oplogSize => oplog_size, :smallfiles => smallfiles, :nojournal => nojournal, :noprealloc => noprealloc )
+ when :arbiters
+ server_params.merge!( :command => mongod, :dbpath => path, :replSet => replSet, :oplogSize => oplog_size, :smallfiles => smallfiles, :nojournal => nojournal, :noprealloc => noprealloc )
+ when :configs
+ server_params.merge!( :command => mongod, :dbpath => path, :configsvr => nil, :nojournal => nojournal, :noprealloc => noprealloc )
+ when :routers
+ server_params.merge!( :command => mongos, :configdb => self.configdb(config) ) # mongos, NO dbpath
+ else
+ server_params.merge!( :command => mongod, :dbpath => path, :nojournal => nojournal, :noprealloc => noprealloc ) # :mongods, :shards
end
end
end
@@ -99,11 +130,16 @@ def initialize(cmd = nil)
def start(verifies = 0)
return @pid if running?
begin
- @pid = fork do
- STDIN.reopen '/dev/null'
- STDOUT.reopen '/dev/null', 'a'
- STDERR.reopen STDOUT
- exec cmd # spawn(@cmd, [:in, :out, :err] => :close) #
+ if RUBY_PLATFORM == 'java'
+ @pid = POSIX::Spawn::spawn(@cmd, [:in, :out, :err] => :close)
+ else
+ @pid = fork do
+ STDIN.reopen '/dev/null'
+ STDOUT.reopen '/dev/null', 'a'
+ STDERR.reopen STDOUT
+ exec cmd
+ end
+ #@pid = Process.spawn(@cmd, [:in, :out, :err] => :close)
end
verify(verifies) if verifies > 0
@pid
@@ -115,9 +151,9 @@ def stop
wait
end
- def kill
+ def kill(signal_no = 2)
begin
- @pid && Process.kill(3, @pid) && true
+ @pid && Process.kill(signal_no, @pid) && true
rescue Errno::ESRCH
false
end
@@ -153,6 +189,10 @@ def initialize(cmd = nil, host = nil, port = nil)
@host = host
@port = port
end
+
+ def host_port
+ [@host, @port].join(':')
+ end
end
class DbServer < Server
@@ -162,8 +202,16 @@ def initialize(config)
dbpath = @config[:dbpath]
[dbpath, File.dirname(@config[:logpath])].compact.each{|dir| FileUtils.mkdir_p(dir) unless File.directory?(dir) }
command = @config[:command] || 'mongod'
- arguments = @config.reject{|k,v| SERVER_PRELUDE_KEYS.include?(k)}
- cmd = [command, arguments.collect{|k,v| ['--' + k.to_s, v ]}].flatten.join(' ')
+ params = @config.reject{|k,v| SERVER_PRELUDE_KEYS.include?(k)}
+ arguments = params.collect do |arg, value|
+ argument = '--' + arg.to_s
+ if FLAGS.member?(arg) && value == true
+ [argument]
+ else
+ [argument, value]
+ end
+ end
+ cmd = [command, arguments].flatten.join(' ')
super(cmd, @config[:host], @config[:port])
end
@@ -172,7 +220,7 @@ def start(verifies = DEFAULT_VERIFIES)
verify(verifies)
end
- def verify(verifies = 10)
+ def verify(verifies = 60)
verifies.times do |i|
#puts "DbServer.verify - port: #{@port} iteration: #{i}"
begin
@@ -229,21 +277,74 @@ def repl_set_get_status
end
def repl_set_initiate( cfg = nil )
+ members = []
+ @config[:replicas].each{|s| members << { :_id => members.size, :host => "#{s[:host]}:#{s[:port]}" } }
+ @config[:arbiters].each{|s| members << { :_id => members.size, :host => "#{s[:host]}:#{s[:port]}", :arbiterOnly => true } }
cfg ||= {
:_id => @config[:replicas].first[:replSet],
- :members => @config[:replicas].each_with_index.collect{|s, i| { :_id => i, :host => "#{s[:host]}:#{s[:port]}" } },
+ :members => members
}
command( @config[:replicas].first, 'admin', { :replSetInitiate => cfg } )
end
def repl_set_startup
response = nil
60.times do |i|
- break if (response = repl_set_get_status)['ok'] == 1.0
+ response = repl_set_get_status
+ members = response['members']
+ return response if response['ok'] == 1.0 && members.collect{|m| m['state']}.all?{|state| [1,2,7].index(state)}
sleep 1
end
- raise Mongo::OperationFailure, "replSet startup failed - status: #{repsonse.inspect}" unless response && response['ok'] == 1.0
- response
+ raise Mongo::OperationFailure, "replSet startup failed - status: #{response.inspect}"
+ end
+
+ def repl_set_seeds
+ @config[:replicas].collect{|router| "#{router[:host]}:#{router[:port]}"}
+ end
+
+ def repl_set_seeds_old
+ @config[:replicas].collect{|router| [router[:host], router[:port]]}
+ end
+
+ def repl_set_name
+ @config[:replicas].first[:replSet]
+ end
+
+ def member_names_by_state(state)
+ status = repl_set_get_status
+ status['members'].find_all{|member| member['state'] == state }.collect{|member| member['name']}
+ end
+
+ def primary_name
+ member_names_by_state(1).first
+ end
+
+ def secondary_names
+ member_names_by_state(2)
+ end
+
+ def arbiter_names
+ member_names_by_state(7)
+ end
+
+ def members_by_name(names)
+ names.collect do |name|
+ host, port = name.split(':')
+ port = port.to_i
+ @servers[:replicas].find{|server| server.host == host && server.port == port}
+ end
+ end
+
+ def primary
+ members_by_name([primary_name]).first
+ end
+
+ def secondaries
+ members_by_name(secondary_names)
+ end
+
+ def arbiters
+ members_by_name(arbiter_names)
end
def mongos_seeds
@@ -280,6 +381,8 @@ def mongos_discover # can also do @config[:routers] find but only want mongos fo
end
def start
+ # Must start configs before mongos -- hash order not guaranteed on 1.8.X
+ servers(:configs).each{|server| server.start}
servers.each{|server| server.start}
# TODO - sharded replica sets - pending
if @config[:replicas]
@@ -298,7 +401,7 @@ def stop
end
def clobber
- system "rm -fr #{@config[:dbpath]}"
+ system "rm -fr #{@config[:dbpath]}/*"
self
end
end
View
21 test/sharded_cluster/mongo_config_test.rb → test/tools/mongo_config_test.rb
@@ -1,25 +1,8 @@
-$:.unshift(File.expand_path('../../lib', File.dirname(__FILE__))).unshift(File.expand_path('../..', File.dirname(__FILE__)))
-require 'test-unit'
-require 'test/tools/mongo_config'
+require 'test_helper'
+require 'tools/mongo_config'
class MongoConfig < Test::Unit::TestCase
- def self.suite
- s = super
- def s.setup
-
- end
- def s.teardown
-
- end
- def s.run(*args)
- setup
- super
- teardown
- end
- s
- end
-
test "config defaults" do
[ Mongo::Config::DEFAULT_BASE_OPTS,
Mongo::Config::DEFAULT_REPLICA_SET,
View
418 test/tools/repl_set_manager.rb
@@ -1,418 +0,0 @@
-#!/usr/bin/ruby
-
-require 'thread'
-
-STDOUT.sync = true
-
-unless defined? Mongo
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
-end
-
-class ReplSetManager
-
- attr_accessor :host, :start_port, :ports, :name, :mongods, :tags, :version
-
- def initialize(opts={})
- @mongod = ENV['mongod'] || 'mongod'
- @start_port = opts[:start_port] || 30000
- @ports = []
- @name = opts[:name] || 'replica-set-foo'
- @host = opts[:host] || 'localhost'
- @retries = opts[:retries] || 30
- @config = {"_id" => @name, "members" => []}
- @durable = opts.fetch(:durable, false)
- @smallfiles = opts.fetch(:smallfiles, true)
- @prealloc = opts.fetch(:prealloc, false)
- @path = File.join(File.expand_path(File.dirname(__FILE__)), "data")
- @oplog_size = opts.fetch(:oplog_size, 16)
- @tags = [{"dc" => "ny", "rack" => "a", "db" => "main"},
- {"dc" => "ny", "rack" => "b", "db" => "main"},
- {"dc" => "sf", "rack" => "a", "db" => "main"}]
-
- @arbiter_count = opts[:arbiter_count] || 0
- @secondary_count = opts[:secondary_count] || 2
- @passive_count = opts[:passive_count] || 0
- @primary_count = 1
-
- @count = @primary_count + @passive_count + @arbiter_count + @secondary_count
- if @count > 7
- raise StandardError, "Cannot create a replica set with #{node_count} nodes. 7 is the max."
- end
-
- @mongods = {}
- version_string = `#{@mongod} --version`
- version_string =~ /(\d\.\d\.\d)/
- @version = $1
- end
-
- def start_set
- system("killall mongod > /dev/null 2> /dev/null")
- sleep(1)
- should_start = true
- #puts "** Starting a replica set with #{@count} nodes"
-
- n = 0
- (@primary_count + @secondary_count).times do
- init_node(n, should_start) do |attrs|
- if @version >= "2"
- attrs['tags'] = @tags[n % @tags.size]
- end
- end
- n += 1
- end
-
- @passive_count.times do
- init_node(n, should_start) do |attrs|
- attrs['priority'] = 0
- end
- n += 1
- end
-
- @arbiter_count.times do
- init_node(n, should_start) do |attrs|
- attrs['arbiterOnly'] = true
- end
- n += 1
- end
-
- initiate
- ensure_up
- end
-
- def cleanup_set
- system("killall mongod")
- @count.times do |n|
- system("rm -rf #{@mongods[n]['db_path']}")
- end
- end
-
- def init_node(n, should_start=true)
- @mongods[n] ||= {}
- port = @start_port + n
- @ports << port
- @mongods[n]['port'] = port
- @mongods[n]['db_path'] = get_path("rs-#{port}")
- @mongods[n]['log_path'] = get_path("log-#{port}")
- @mongods[n]['start'] = start_cmd(n)
-
- if should_start
- system("rm -rf #{@mongods[n]['db_path']}")
- system("mkdir -p #{@mongods[n]['db_path']}")
- start(n)
- end
-
- member = {'_id' => n, 'host' => "#{@host}:#{@mongods[n]['port']}"}
-
- if block_given?
- custom_attrs = {}
- yield custom_attrs
- member.merge!(custom_attrs)
- @mongods[n].merge!(custom_attrs)
- end
-
- @config['members'] << member
- end
-
- def journal_switch
- if @version >= &q