summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/mock/mock_replica_set.h
blob: 8fb98255123b3370a4ae7c1e2a2cc59351dec16d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*    Copyright 2012 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.
 */

#pragma once

#include "mongo/dbtests/mock/mock_remote_db_server.h"
#include "mongo/db/repl/rs_config.h"

#include <string>
#include <map>
#include <vector>

namespace mongo_test {
    /**
     * This is a helper class for managing a replica set consisting of
     * MockRemoteDBServer instances.
     *
     * Warning: Not thread-safe
     */
    class MockReplicaSet {
    public:
        /**
         * Creates a mock replica set and automatically mocks the isMaster
         * and replSetGetStatus commands based on the default replica set
         * configuration.
         *
         * @param setName The name for this replica set
         * @param nodes The initial number of nodes for this replica set
         */
        MockReplicaSet(const std::string& setName, size_t nodes);
        ~MockReplicaSet();

        //
        // getters
        //

        std::string getSetName() const;
        std::string getConnectionString() const;
        std::vector<mongo::HostAndPort> getHosts() const;
        mongo::ConnectionString::ConnectionHook* getConnectionHook();
        const std::vector<mongo::ReplSetConfig::MemberCfg>& getReplConfig() const;
        std::string getPrimary() const;
        const std::vector<std::string>& getSecondaries() const;

        /**
         * Sets the configuration for this replica sets. This also has a side effect
         * of mocking the ismaster and replSetGetStatus command responses based on
         * the new config.
         */
        void setConfig(const std::vector<mongo::ReplSetConfig::MemberCfg>& newConfig);

        /**
         * @return pointer to the mocked remote server with the given hostName.
         *     NULL if host doesn't exists.
         */
        MockRemoteDBServer* getNode(const std::string& hostName);

        /**
         * Kills a node belonging to this set.
         *
         * @param hostName the name of the replica node to kill.
         */
        void kill(const std::string& hostName);

        /**
         * Kills a set of host belonging to this set.
         *
         * @param hostList the list of host names of the servers to kill.
         */
        void kill(const std::vector<std::string>& hostList);

        /**
         * Reboots a node.
         *
         * @param hostName the name of the host to reboot.
         */
        void restore(const std::string& hostName);

    private:
        class ReplSetConnHook: public mongo::ConnectionString::ConnectionHook {
        public:
            /**
             * Creates a new connection hook for the ConnectionString class that
             * can create mock connections to mock replica set members using their
             * pseudo host names.
             *
             * @param replSet the mock replica set. Caller is responsible for managing
             *     replSet and making sure that it lives longer than this object.
             */
            ReplSetConnHook(MockReplicaSet* replSet);
            ~ReplSetConnHook();

            mongo::DBClientBase* connect(
                    const mongo::ConnectionString& connString,
                    std::string& errmsg, double socketTimeout);

        private:
            MockReplicaSet* _replSet;
        };

        /**
         * Mocks the ismaster command based on the information on the current
         * replica set configuration.
         */
        void mockIsMasterCmd();

        /**
         * Mocks the replSetGetStatus command based on the current states of the
         * mocked servers.
         */
        void mockReplSetGetStatusCmd();

        /**
         * @return the replica set state of the given host
         */
        int getState(const std::string& host) const;

        const std::string _setName;
        std::map<std::string, MockRemoteDBServer*> _nodeMap;
        ReplSetConnHook _connStringHook;
        std::vector<mongo::ReplSetConfig::MemberCfg> _replConfig;

        std::string _primaryHost;
        std::vector<std::string> _secondaryHosts;
    };
}