The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#
#  Copyright 2009-2013 MongoDB, 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.
#


use strict;
use warnings;
use Test::More;
use Test::Exception;
use Test::Warn;

use MongoDB;

use lib "t/lib";
use MongoDBTest '$conn';

plan tests => 11;

my $rs;

SKIP: {
    skip 'requires running replica set', 11 unless exists $ENV{MONGOTEST_PATH};

    $rs = MongoDBTest::ReplicaSet->new(
        mongo_path => $ENV{MONGOTEST_PATH},
        logpath => '/data/db',
        name => 'testset',
        port => 27020,
        set_size => 3,
        priorities => [1, 1, 2]
    );

    # set up replica set tags, and wait for reconfig
    $rs->add_tags({disk => 'ssd', use => 'production', rack => 'f'},
                  {disk => 'ssd', use => 'production', rack => 'k'},
                  {disk => 'spinning', use => 'reporting', mem => '32'});
    sleep 5;

    my $rsconn = $rs->client;
    my $db = $rsconn->get_database('test_database');
    my $collection = $db->get_collection('test_collection');

    $rsconn->read_preference(MongoDB::MongoClient->SECONDARY_PREFERRED, [{rack => 'f'}]);
    my $pinhost = $rsconn->_readpref_pinned->host;
    is($pinhost, 'mongodb://localhost:27020', 'secondary pinned');

    # the host list should have three members
    ok($rsconn->_servers->{'localhost:27020'}, 'localhost:27020 in host list');
    ok($rsconn->_servers->{'localhost:27021'}, 'localhost:27021 in host list');
    ok($rsconn->_servers->{'localhost:27022'}, 'localhost:27022 in host list');
    is(keys %{$rsconn->_servers}, 3, 'no other hosts are in RS config');

    # reconfig so that the replica set only has two members
    my $replcoll = $rsconn->get_database('local')->get_collection('system.replset');
    my $rsconf = $replcoll->find_one();

    ($rsconf->{'version'})++;
    shift @{$rsconf->{'members'}};

    # reconfig will cause connection to be reset,
    # and throw a connection error
    eval {
        $rsconn->get_database('admin')->run_command({'replSetReconfig' => $rsconf});
    };

    # sleep for long enough that rs refresh will take place
    sleep 6;
    lives_ok { $collection->find()->next; } 'repin safely';

    # the host list should now have three members
    ok(!$rsconn->_servers->{'localhost:27020'}, 'localhost:27020 not in host list');
    ok($rsconn->_servers->{'localhost:27021'}, 'localhost:27021 in host list');
    ok($rsconn->_servers->{'localhost:27022'}, 'localhost:27022 in host list');
    is(keys %{$rsconn->_servers}, 2, 'no other hosts are in RS config');

    $pinhost = $rsconn->_readpref_pinned->host;
    is($pinhost, 'mongodb://localhost:27022', 'primary pinned after reconfig');
}

END {
    if ($conn) {
        $conn->get_database('test_database')->drop();
    }
    if ($rs) {
        $rs->shutdown();
    }
}