# Copyright (C) 2013 10gen Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'test_helper' class ReplicaSetRefreshTest < Test::Unit::TestCase def setup ensure_cluster(:rs) end def test_connect_and_manual_refresh_with_secondary_down num_secondaries = @rs.secondaries.size client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :refresh_mode => false) assert_equal num_secondaries, client.secondaries.size assert client.connected? assert_equal client.read_pool, client.primary_pool old_refresh_version = client.refresh_version @rs.stop_secondary client.refresh assert_equal num_secondaries - 1, client.secondaries.size assert client.connected? assert_equal client.read_pool, client.primary_pool assert client.refresh_version > old_refresh_version old_refresh_version = client.refresh_version # Test no changes after restart until manual refresh @rs.restart assert_equal num_secondaries - 1, client.secondaries.size assert client.connected? assert_equal client.read_pool, client.primary_pool assert_equal client.refresh_version, old_refresh_version # Refresh and ensure state client.refresh assert_equal num_secondaries, client.secondaries.size assert client.connected? assert_equal client.read_pool, client.primary_pool assert client.refresh_version > old_refresh_version end def test_automated_refresh_with_secondary_down num_secondaries = @rs.secondaries.size client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :refresh_interval => 1, :refresh_mode => :sync, :read => :secondary_preferred) # Ensure secondaries are all recognized by client and client is connected assert_equal num_secondaries, client.secondaries.size assert client.connected? assert client.secondary_pools.include?(client.read_pool) pool = client.read_pool @rs.member_by_name(pool.host_string).stop sleep(2) old_refresh_version = client.refresh_version # Trigger synchronous refresh client['foo']['bar'].find_one assert client.connected? assert client.refresh_version > old_refresh_version assert_equal num_secondaries - 1, client.secondaries.size assert client.secondary_pools.include?(client.read_pool) assert_not_equal pool, client.read_pool # Restart nodes and ensure refresh interval has passed @rs.restart sleep(2) old_refresh_version = client.refresh_version # Trigger synchronous refresh client['foo']['bar'].find_one assert client.connected? assert client.refresh_version > old_refresh_version, "Refresh version hasn't changed." assert_equal num_secondaries, client.secondaries.size "No secondaries have been added." assert_equal num_secondaries, client.secondary_pools.size end def test_concurrent_refreshes factor = 5 nthreads = factor * 10 threads = [] client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :refresh_mode => :sync, :refresh_interval => 1) nthreads.times do |i| threads << Thread.new do # force a connection failure every couple of threads that causes a refresh if i % factor == 0 cursor = client['foo']['bar'].find cursor.stubs(:checkout_socket_from_connection).raises(ConnectionFailure) begin cursor.next rescue => ex raise ex unless ex.class == ConnectionFailure next end else # synchronous refreshes will happen every couple of find_ones cursor = client['foo']['bar'].find_one end end end threads.each do |t| t.join end end =begin def test_automated_refresh_with_removed_node client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :refresh_interval => 1, :refresh_mode => :sync) num_secondaries = client.secondary_pools.length old_refresh_version = client.refresh_version n = @rs.repl_set_remove_node(2) sleep(2) rescue_connection_failure do client['foo']['bar'].find_one end assert client.refresh_version > old_refresh_version, "Refresh version hasn't changed." assert_equal num_secondaries - 1, client.secondaries.length assert_equal num_secondaries - 1, client.secondary_pools.length #@rs.add_node(n) end def test_adding_and_removing_nodes client = MongoReplicaSetClient.new(build_seeds(3), :refresh_interval => 2, :refresh_mode => :sync) @rs.add_node sleep(4) client['foo']['bar'].find_one @conn2 = MongoReplicaSetClient.new(build_seeds(3), :refresh_interval => 2, :refresh_mode => :sync) assert @conn2.secondaries.sort == client.secondaries.sort, "Second connection secondaries not equal to first." assert_equal 3, client.secondary_pools.length assert_equal 3, client.secondaries.length config = client['admin'].command({:ismaster => 1}) @rs.remove_secondary_node sleep(4) config = client['admin'].command({:ismaster => 1}) assert_equal 2, client.secondary_pools.length assert_equal 2, client.secondaries.length end =end end