~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/mongo/dbtests/replica_set_monitor_test.cpp

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 * ReplicaSetMonitor::selectNode and TagSet
20
20
 */
21
21
 
22
 
#include <vector>
23
 
 
 
22
#include "mongo/client/connpool.h"
 
23
#include "mongo/client/dbclientinterface.h"
24
24
#include "mongo/client/dbclient_rs.h"
 
25
#include "mongo/dbtests/mock/mock_conn_registry.h"
 
26
#include "mongo/dbtests/mock/mock_replica_set.h"
25
27
#include "mongo/unittest/unittest.h"
26
28
 
27
 
namespace {
28
 
    using std::vector;
29
 
    using boost::scoped_ptr;
30
 
 
31
 
    using mongo::BSONObj;
32
 
    using mongo::BSONArray;
33
 
    using mongo::BSONArrayBuilder;
34
 
    using mongo::ReplicaSetMonitor;
35
 
    using mongo::HostAndPort;
36
 
    using mongo::ReadPreference;
37
 
    using mongo::TagSet;
38
 
 
 
29
#include <vector>
 
30
 
 
31
using std::vector;
 
32
using std::string;
 
33
using boost::scoped_ptr;
 
34
 
 
35
using mongo::BSONObj;
 
36
using mongo::BSONObjBuilder;
 
37
using mongo::BSONArray;
 
38
using mongo::BSONArrayBuilder;
 
39
using mongo::BSONElement;
 
40
using mongo::ConnectionString;
 
41
using mongo::HostAndPort;
 
42
using mongo::MockReplicaSet;
 
43
using mongo::ReadPreference;
 
44
using mongo::ReplicaSetMonitor;
 
45
using mongo::ReplicaSetMonitorPtr;
 
46
using mongo::ScopedDbConnection;
 
47
using mongo::TagSet;
 
48
 
 
49
namespace mongo_test {
39
50
    const BSONObj SampleIsMasterDoc = BSON("tags"
40
51
                                            << BSON("dc" << "NYC"
41
52
                                                    << "p" << "2"
1403
1414
        ASSERT_EQUALS("b", lastHost.host());
1404
1415
    }
1405
1416
 
 
1417
    TEST(TagSet, CopyConstructor) {
 
1418
        TagSet* copy;
 
1419
 
 
1420
        {
 
1421
            BSONArrayBuilder builder;
 
1422
            builder.append(BSON("dc" << "nyc"));
 
1423
            builder.append(BSON("priority" << "1"));
 
1424
            TagSet original(builder.arr());
 
1425
 
 
1426
            original.next();
 
1427
 
 
1428
            copy = new TagSet(original);
 
1429
        }
 
1430
 
 
1431
        ASSERT_FALSE(copy->isExhausted());
 
1432
        ASSERT(copy->getCurrentTag().equal(BSON("dc" << "nyc")));
 
1433
        copy->next();
 
1434
 
 
1435
        ASSERT_FALSE(copy->isExhausted());
 
1436
        ASSERT(copy->getCurrentTag().equal(BSON("priority" << "1")));
 
1437
        copy->next();
 
1438
 
 
1439
        ASSERT(copy->isExhausted());
 
1440
 
 
1441
        delete copy;
 
1442
    }
 
1443
 
1406
1444
    TEST(TagSet, NearestMultiTagsNoMatch) {
1407
1445
        vector<ReplicaSetMonitor::Node> nodes =
1408
1446
                NodeSetFixtures::getThreeMemberWithTags();
1475
1513
        ASSERT_THROWS(tags.getCurrentTag(), mongo::AssertionException);
1476
1514
#endif
1477
1515
    }
 
1516
 
 
1517
    // TODO: Port these existing tests here: replmonitor_bad_seed.js, repl_monitor_refresh.js
 
1518
 
 
1519
    /**
 
1520
     * Warning: Tests running this fixture cannot be run in parallel with other tests
 
1521
     * that uses ConnectionString::setConnectionHook
 
1522
     */
 
1523
    class ReplicaSetMonitorTest: public mongo::unittest::Test {
 
1524
    protected:
 
1525
        void setUp() {
 
1526
            _replSet.reset(new MockReplicaSet("test", 3));
 
1527
            _originalConnectionHook = ConnectionString::getConnectionHook();
 
1528
            ConnectionString::setConnectionHook(
 
1529
                    mongo::MockConnRegistry::get()->getConnStrHook());
 
1530
        }
 
1531
 
 
1532
        void tearDown() {
 
1533
            ConnectionString::setConnectionHook(_originalConnectionHook);
 
1534
            ReplicaSetMonitor::remove(_replSet->getSetName(), true);
 
1535
            _replSet.reset();
 
1536
            mongo::ScopedDbConnection::clearPool();
 
1537
        }
 
1538
 
 
1539
        MockReplicaSet* getReplSet() {
 
1540
            return _replSet.get();
 
1541
        }
 
1542
 
 
1543
    private:
 
1544
        ConnectionString::ConnectionHook* _originalConnectionHook;
 
1545
        boost::scoped_ptr<MockReplicaSet> _replSet;
 
1546
    };
 
1547
 
 
1548
    TEST_F(ReplicaSetMonitorTest, SeedWithPriOnlySecDown) {
 
1549
        // Test to make sure that the monitor doesn't crash when
 
1550
        // ConnectionString::connect returns NULL
 
1551
        MockReplicaSet* replSet = getReplSet();
 
1552
        replSet->kill(replSet->getSecondaries());
 
1553
 
 
1554
        // Create a monitor with primary as the only seed list and the two secondaries
 
1555
        // down so a NULL connection object will be stored for these secondaries in
 
1556
        // the _nodes vector.
 
1557
        const string replSetName(replSet->getSetName());
 
1558
        vector<HostAndPort> seedList;
 
1559
        seedList.push_back(HostAndPort(replSet->getPrimary()));
 
1560
        ReplicaSetMonitor::createIfNeeded(replSetName, seedList);
 
1561
 
 
1562
        replSet->kill(replSet->getPrimary());
 
1563
 
 
1564
        ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(replSet->getSetName());
 
1565
        // Trigger calls to Node::getConnWithRefresh
 
1566
        monitor->check(true);
 
1567
    }
 
1568
 
 
1569
    // Stress test case for a node that is previously a primary being removed from the set.
 
1570
    // This test goes through configurations with different positions for the primary node
 
1571
    // in the host list returned from the isMaster command. The test here is to make sure
 
1572
    // that the ReplicaSetMonitor will not crash under these situations.
 
1573
    TEST(ReplicaSetMonitorTest, PrimaryRemovedFromSetStress) {
 
1574
        const size_t NODE_COUNT = 5;
 
1575
        MockReplicaSet replSet("test", NODE_COUNT);
 
1576
        ConnectionString::ConnectionHook* originalConnHook =
 
1577
                ConnectionString::getConnectionHook();
 
1578
        ConnectionString::setConnectionHook(mongo::MockConnRegistry::get()->getConnStrHook());
 
1579
 
 
1580
        const string replSetName(replSet.getSetName());
 
1581
        vector<HostAndPort> seedList;
 
1582
        seedList.push_back(HostAndPort(replSet.getPrimary()));
 
1583
        ReplicaSetMonitor::createIfNeeded(replSetName, seedList);
 
1584
 
 
1585
        const MockReplicaSet::ReplConfigMap origConfig = replSet.getReplConfig();
 
1586
        mongo::ReplicaSetMonitorPtr replMonitor = ReplicaSetMonitor::get(replSetName);
 
1587
 
 
1588
        for (size_t idxToRemove = 0; idxToRemove < NODE_COUNT; idxToRemove++) {
 
1589
            MockReplicaSet::ReplConfigMap newConfig = origConfig;
 
1590
 
 
1591
            replSet.setConfig(origConfig);
 
1592
            replMonitor->check(true); // Make sure the monitor sees the change
 
1593
 
 
1594
            string hostToRemove;
 
1595
            {
 
1596
                BSONObjBuilder monitorStateBuilder;
 
1597
                replMonitor->appendInfo(monitorStateBuilder);
 
1598
                BSONObj monitorState = monitorStateBuilder.done();
 
1599
 
 
1600
                BSONElement hostsElem = monitorState["hosts"];
 
1601
                BSONElement addrElem = hostsElem[mongo::str::stream() << idxToRemove]["addr"];
 
1602
                hostToRemove = addrElem.String();
 
1603
            }
 
1604
 
 
1605
            replSet.setPrimary(hostToRemove);
 
1606
            replMonitor->check(true); // Make sure the monitor sees the new primary
 
1607
 
 
1608
            newConfig.erase(hostToRemove);
 
1609
            replSet.setConfig(newConfig);
 
1610
            replSet.setPrimary(newConfig.begin()->first);
 
1611
            replMonitor->check(true); // Force refresh -> should not crash
 
1612
        }
 
1613
 
 
1614
        ReplicaSetMonitor::remove(replSet.getSetName(), true);
 
1615
        ConnectionString::setConnectionHook(originalConnHook);
 
1616
        mongo::ScopedDbConnection::clearPool();
 
1617
    }
1478
1618
}