From 065517ac2900359683a27f7b5d129ed22e5f2a34 Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Mon, 2 Aug 2010 18:19:54 -0400 Subject: [PATCH] Fixed test bug; better replication ack tests; deprecated DB#error and DB#last_status for DB#get_last_error --- Rakefile | 5 ++ lib/mongo/db.rb | 31 ++++++++-- test/collection_test.rb | 18 ------ test/cursor_test.rb | 10 ++-- test/db_test.rb | 18 ------ test/replica_sets/replication_ack_test.rb | 71 +++++++++++++++++++++++ test/test_helper.rb | 2 + 7 files changed, 108 insertions(+), 47 deletions(-) create mode 100644 test/replica_sets/replication_ack_test.rb diff --git a/Rakefile b/Rakefile index 78ae0a9..9d21c22 100644 --- a/Rakefile +++ b/Rakefile @@ -98,6 +98,11 @@ namespace :test do t.verbose = true end + Rake::TestTask.new(:replica_set_ack) do |t| + t.test_files = FileList['test/replica_sets/replication_ack_test.rb'] + t.verbose = true + end + Rake::TestTask.new(:auto_reconnect) do |t| t.test_files = FileList['test/auxillary/autoreconnect_test.rb'] t.verbose = true diff --git a/lib/mongo/db.rb b/lib/mongo/db.rb index fc8de83..b78a914 100644 --- a/lib/mongo/db.rb +++ b/lib/mongo/db.rb @@ -276,6 +276,8 @@ module Mongo ok?(command(:drop => name)) end + # @deprecated + # # Get the error message from the most recently executed database # operation for this connection. # @@ -286,19 +288,36 @@ module Mongo # @return [String, Nil] either the text describing an error or nil if no # error has occurred. def error(opts={}) + warn "DB#error is deprecated. Please use DB#get_last_error instead" opts.assert_valid_keys(:w, :wtimeout, :fsync) - cmd = BSON::OrderedHash.new - cmd[:getlasterror] = 1 - cmd.merge!(opts) unless opts.empty? - doc = command(cmd, :check_response => false) - raise MongoDBError, "error retrieving last error: #{doc.inspect}" unless ok?(doc) - doc['err'] + get_last_error(opts)['err'] end + # Run the getlasterror command with the specified replication options. + # + # @option opts [Boolean] :fsync (false) + # @option opts [Integer] :w (nil) + # @option opts [Integer] :wtimeout (nil) + # + # @return [Hash] the entire response to getlasterror. + # + # @raise [MongoDBError] if the operation fails. + def get_last_error(opts={}) + cmd = BSON::OrderedHash.new + cmd[:getlasterror] = 1 + cmd.merge!(opts) + doc = command(cmd, :check_response => false) + raise MongoDBError, "error retrieving last error: #{doc.inspect}" unless ok?(doc) + doc + end + + # @deprecated + # # Get status information from the last operation on this connection. # # @return [Hash] a hash representing the status of the last db op. def last_status + warn "DB#last_status is deprecated. Please use the equivalent DB#get_last_error instead" command(:getlasterror => 1) end diff --git a/test/collection_test.rb b/test/collection_test.rb index 18f1ff2..8636498 100644 --- a/test/collection_test.rb +++ b/test/collection_test.rb @@ -139,24 +139,6 @@ class TestCollection < Test::Unit::TestCase @@test.remove({:foo => 2}, :safe => {:w => 2, :wtime => 1, :fsync => true}) end end - - def test_safe_mode_with_w_failure - assert_raise_error OperationFailure, "timed out waiting for slaves" do - @@test.insert({:foo => 1}, :safe => {:w => 2, :wtimeout => 1, :fsync => true}) - end - assert_raise_error OperationFailure, "timed out waiting for slaves" do - @@test.update({:foo => 1}, {:foo => 2}, :safe => {:w => 2, :wtimeout => 1, :fsync => true}) - end - assert_raise_error OperationFailure, "timed out waiting for slaves" do - @@test.remove({:foo => 2}, :safe => {:w => 2, :wtimeout => 1, :fsync => true}) - end - end - - def test_safe_mode_with_write_and_fsync - assert @@test.insert({:foo => 1}, :safe => {:w => 1, :wtimeout => 1, :fsync => true}) - assert @@test.update({:foo => 1}, {:foo => 2}, :safe => {:w => 1, :wtimeout => 1, :fsync => true}) - assert @@test.remove({:foo => 2}, :safe => {:w => 1, :wtimeout => 1, :fsync => true}) - end end def test_update diff --git a/test/cursor_test.rb b/test/cursor_test.rb index 4aab1ad..6ce8fa8 100644 --- a/test/cursor_test.rb +++ b/test/cursor_test.rb @@ -399,18 +399,18 @@ class CursorTest < Test::Unit::TestCase def test_cursor_invalid @@coll.remove - 1000.times do |n| + 10000.times do |n| @@coll.insert({:a => n}) end cursor = @@coll.find({}) - cursor.next_document - cursor.close - assert_raise_error(Mongo::OperationFailure, "CURSOR_NOT_FOUND") do - 999.times do + assert_raise_error Mongo::OperationFailure, "CURSOR_NOT_FOUND" do + 9999.times do cursor.next_document + cursor.instance_variable_set(:@cursor_id, 1234567890) end end end + end diff --git a/test/db_test.rb b/test/db_test.rb index dfeacaa..26adcf2 100644 --- a/test/db_test.rb +++ b/test/db_test.rb @@ -191,24 +191,6 @@ class DBTest < Test::Unit::TestCase assert_nil @@db.previous_error end - if @@version >= "1.5.1" - def test_failing_error_params - assert_raise_error Mongo::MongoDBError, "timed out waiting for slaves" do - @@db.error(:w => 2, :wtimeout => 10, :fsync => true) - end - end - - def test_passing_error_params - assert_nil @@db.error(:w => 1, :wtimeout => 10, :fsync => true) - end - - def test_invalid_error_params - assert_raise_error ArgumentError, "Unknown key(s): z" do - @@db.error(:z => 1, :wtimeout => 10, :fsync => true) - end - end - end - def test_check_command_response command = {:forceerror => 1} assert_raise OperationFailure do diff --git a/test/replica_sets/replication_ack_test.rb b/test/replica_sets/replication_ack_test.rb new file mode 100644 index 0000000..4d34582 --- /dev/null +++ b/test/replica_sets/replication_ack_test.rb @@ -0,0 +1,71 @@ +$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) +require 'mongo' +require 'test/unit' +require 'test/test_helper' + +# NOTE: This test expects a replica set of three nodes to be running on local host. +class ReplicaSetAckTest < Test::Unit::TestCase + include Mongo + + def setup + @conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]]) + + master = [@conn.host, @conn.port] + @slaves = @conn.nodes - master + + @slave1 = Mongo::Connection.new(@slaves[0][0], @slaves[0][1], :slave_ok => true) + @slave2 = Mongo::Connection.new(@slaves[1][0], @slaves[1][1], :slave_ok => true) + + @db = @conn.db(MONGO_TEST_DB) + @db.drop_collection("test-sets") + @col = @db.collection("test-sets") + end + + def test_safe_mode_with_w_failure + assert_raise_error OperationFailure, "timed out waiting for slaves" do + @col.insert({:foo => 1}, :safe => {:w => 4, :wtimeout => 1, :fsync => true}) + end + assert_raise_error OperationFailure, "timed out waiting for slaves" do + @col.update({:foo => 1}, {:foo => 2}, :safe => {:w => 4, :wtimeout => 1, :fsync => true}) + end + assert_raise_error OperationFailure, "timed out waiting for slaves" 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 => 1000}) + + assert @col.insert({:foo => "0" * 10000}, :safe => {:w => 3, :wtimeout => 1000}) + assert_equal 2, @slave1[MONGO_TEST_DB]["test-sets"].count + assert_equal 2, @slave2[MONGO_TEST_DB]["test-sets"].count + + + assert @col.update({:baz => "bar"}, {:baz => "foo"}, :safe => {:w => 3, :wtimeout => 1000}) + assert @slave1[MONGO_TEST_DB]["test-sets"].find_one({:baz => "foo"}) + assert @slave2[MONGO_TEST_DB]["test-sets"].find_one({:baz => "foo"}) + + assert @col.remove({}, :safe => {:w => 3, :wtimeout => 1000}) + assert_equal 0, @slave1[MONGO_TEST_DB]["test-sets"].count + assert_equal 0, @slave2[MONGO_TEST_DB]["test-sets"].count + end + + def test_last_error_responses + 20.times { @col.insert({:baz => "bar"}) } + response = @db.get_last_error(:w => 3, :wtimeout => 10000) + assert response['ok'] == 1 + assert response['lastOp'] + + @col.update({}, {:baz => "foo"}, :multi => true) + response = @db.get_last_error(:w => 3, :wtimeout => 1000) + assert response['ok'] == 1 + assert response['lastOp'] + + @col.remove({}) + response = @db.get_last_error(:w => 3, :wtimeout => 1000) + assert response['ok'] == 1 + assert response['n'] == 20 + assert response['lastOp'] + end + +end diff --git a/test/test_helper.rb b/test/test_helper.rb index fccca2d..60d0187 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -48,6 +48,8 @@ class Test::Unit::TestCase 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