~ubuntu-branches/ubuntu/wily/pymongo/wily-proposed

« back to all changes in this revision

Viewing changes to test/test_replica_set_reconfig.py

  • Committer: Package Import Robot
  • Author(s): Federico Ceratto
  • Date: 2015-04-26 22:43:13 UTC
  • mfrom: (24.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20150426224313-0hga2jphvf0rrmfe
Tags: 3.0.1-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2013-2014 MongoDB, Inc.
 
1
# Copyright 2013-2015 MongoDB, Inc.
2
2
#
3
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
4
# you may not use this file except in compliance with the License.
15
15
"""Test clients and replica set configuration changes, using mocks."""
16
16
 
17
17
import sys
18
 
import unittest
19
18
 
20
19
sys.path[0:0] = [""]
21
20
 
22
 
from pymongo.errors import ConfigurationError, ConnectionFailure
 
21
from pymongo.errors import ConnectionFailure, AutoReconnect
23
22
from pymongo import ReadPreference
24
 
from test.pymongo_mocks import MockClient, MockReplicaSetClient
25
 
 
26
 
 
27
 
class TestSecondaryBecomesStandalone(unittest.TestCase):
 
23
from test import unittest, client_context, client_knobs, MockClientTest
 
24
from test.pymongo_mocks import MockClient
 
25
from test.utils import wait_until
 
26
 
 
27
 
 
28
@client_context.require_connection
 
29
def setUpModule():
 
30
    pass
 
31
 
 
32
 
 
33
class TestSecondaryBecomesStandalone(MockClientTest):
28
34
    # An administrator removes a secondary from a 3-node set and
29
35
    # brings it back up as standalone, without updating the other
30
36
    # members' config. Verify we don't continue using it.
34
40
            members=['a:1', 'b:2', 'c:3'],
35
41
            mongoses=[],
36
42
            host='a:1,b:2,c:3',
37
 
            replicaSet='rs')
 
43
            replicaSet='rs',
 
44
            serverSelectionTimeoutMS=100)
38
45
 
39
46
        # MongoClient connects to primary by default.
40
 
        self.assertEqual('a', c.host)
41
 
        self.assertEqual(1, c.port)
 
47
        wait_until(lambda: c.address is not None, 'connect to primary')
 
48
        self.assertEqual(c.address, ('a', 1))
42
49
 
43
50
        # C is brought up as a standalone.
44
51
        c.mock_members.remove('c:3')
49
56
        c.kill_host('b:2')
50
57
 
51
58
        # Force reconnect.
52
 
        c.disconnect()
53
 
 
54
 
        try:
55
 
            c.db.collection.find_one()
56
 
        except ConfigurationError, e:
57
 
            self.assertTrue('not a member of replica set' in str(e))
58
 
        else:
59
 
            self.fail("MongoClient didn't raise AutoReconnect")
60
 
 
61
 
        self.assertEqual(None, c.host)
62
 
        self.assertEqual(None, c.port)
 
59
        c.close()
 
60
 
 
61
        with self.assertRaises(AutoReconnect):
 
62
            c.db.command('ismaster')
 
63
 
 
64
        self.assertEqual(c.address, None)
63
65
 
64
66
    def test_replica_set_client(self):
65
 
        c = MockReplicaSetClient(
 
67
        c = MockClient(
66
68
            standalones=[],
67
69
            members=['a:1', 'b:2', 'c:3'],
68
70
            mongoses=[],
69
71
            host='a:1,b:2,c:3',
70
72
            replicaSet='rs')
71
73
 
72
 
        self.assertTrue(('b', 2) in c.secondaries)
73
 
        self.assertTrue(('c', 3) in c.secondaries)
 
74
        wait_until(lambda: ('b', 2) in c.secondaries,
 
75
                   'discover host "b"')
 
76
 
 
77
        wait_until(lambda: ('c', 3) in c.secondaries,
 
78
                   'discover host "c"')
74
79
 
75
80
        # C is brought up as a standalone.
76
81
        c.mock_members.remove('c:3')
77
82
        c.mock_standalones.append('c:3')
78
 
        c.refresh()
 
83
 
 
84
        wait_until(lambda: set([('b', 2)]) == c.secondaries,
 
85
                   'update the list of secondaries')
79
86
 
80
87
        self.assertEqual(('a', 1), c.primary)
81
 
        self.assertEqual(set([('b', 2)]), c.secondaries)
82
 
 
83
 
 
84
 
class TestSecondaryRemoved(unittest.TestCase):
 
88
 
 
89
 
 
90
class TestSecondaryRemoved(MockClientTest):
85
91
    # An administrator removes a secondary from a 3-node set *without*
86
92
    # restarting it as standalone.
87
93
    def test_replica_set_client(self):
88
 
        c = MockReplicaSetClient(
 
94
        c = MockClient(
89
95
            standalones=[],
90
96
            members=['a:1', 'b:2', 'c:3'],
91
97
            mongoses=[],
92
98
            host='a:1,b:2,c:3',
93
99
            replicaSet='rs')
94
100
 
95
 
        self.assertTrue(('b', 2) in c.secondaries)
96
 
        self.assertTrue(('c', 3) in c.secondaries)
 
101
        wait_until(lambda: ('b', 2) in c.secondaries, 'discover host "b"')
 
102
        wait_until(lambda: ('c', 3) in c.secondaries, 'discover host "c"')
97
103
 
98
104
        # C is removed.
99
105
        c.mock_ismaster_hosts.remove('c:3')
100
 
        c.refresh()
 
106
        wait_until(lambda: set([('b', 2)]) == c.secondaries,
 
107
                   'update list of secondaries')
101
108
 
102
109
        self.assertEqual(('a', 1), c.primary)
103
 
        self.assertEqual(set([('b', 2)]), c.secondaries)
104
 
 
105
 
 
106
 
class TestSocketError(unittest.TestCase):
 
110
 
 
111
 
 
112
class TestSocketError(MockClientTest):
107
113
    def test_socket_error_marks_member_down(self):
108
 
        c = MockReplicaSetClient(
109
 
            standalones=[],
110
 
            members=['a:1', 'b:2'],
111
 
            mongoses=[],
112
 
            host='a:1',
113
 
            replicaSet='rs')
114
 
 
115
 
        self.assertEqual(2, len(c._MongoReplicaSetClient__rs_state.members))
116
 
 
117
 
        # b now raises socket.error.
118
 
        c.mock_down_hosts.append('b:2')
119
 
        self.assertRaises(
120
 
            ConnectionFailure,
121
 
            c.db.collection.find_one, read_preference=ReadPreference.SECONDARY)
122
 
 
123
 
        self.assertEqual(1, len(c._MongoReplicaSetClient__rs_state.members))
124
 
 
125
 
 
126
 
class TestSecondaryAdded(unittest.TestCase):
 
114
        # Disable background refresh.
 
115
        with client_knobs(heartbeat_frequency=999999):
 
116
            c = MockClient(
 
117
                standalones=[],
 
118
                members=['a:1', 'b:2'],
 
119
                mongoses=[],
 
120
                host='a:1',
 
121
                replicaSet='rs')
 
122
 
 
123
            wait_until(lambda: len(c.nodes) == 2, 'discover both nodes')
 
124
 
 
125
            # b now raises socket.error.
 
126
            c.mock_down_hosts.append('b:2')
 
127
            self.assertRaises(
 
128
                ConnectionFailure,
 
129
                c.db.collection.with_options(
 
130
                    read_preference=ReadPreference.SECONDARY).find_one)
 
131
 
 
132
            self.assertEqual(1, len(c.nodes))
 
133
 
 
134
 
 
135
class TestSecondaryAdded(MockClientTest):
127
136
    def test_client(self):
128
137
        c = MockClient(
129
138
            standalones=[],
132
141
            host='a:1',
133
142
            replicaSet='rs')
134
143
 
 
144
        wait_until(lambda: len(c.nodes) == 2, 'discover both nodes')
 
145
 
135
146
        # MongoClient connects to primary by default.
136
 
        self.assertEqual('a', c.host)
137
 
        self.assertEqual(1, c.port)
 
147
        self.assertEqual(c.address, ('a', 1))
138
148
        self.assertEqual(set([('a', 1), ('b', 2)]), c.nodes)
139
149
 
140
150
        # C is added.
141
151
        c.mock_members.append('c:3')
142
152
        c.mock_ismaster_hosts.append('c:3')
143
153
 
144
 
        c.disconnect()
145
 
        c.db.collection.find_one()
146
 
 
147
 
        self.assertEqual('a', c.host)
148
 
        self.assertEqual(1, c.port)
149
 
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]), c.nodes)
 
154
        c.close()
 
155
        c.db.command('ismaster')
 
156
 
 
157
        self.assertEqual(c.address, ('a', 1))
 
158
 
 
159
        wait_until(lambda: set([('a', 1), ('b', 2), ('c', 3)]) == c.nodes,
 
160
                   'reconnect to both secondaries')
150
161
 
151
162
    def test_replica_set_client(self):
152
 
        c = MockReplicaSetClient(
 
163
        c = MockClient(
153
164
            standalones=[],
154
165
            members=['a:1', 'b:2'],
155
166
            mongoses=[],
156
167
            host='a:1',
157
168
            replicaSet='rs')
158
169
 
159
 
        self.assertEqual(('a', 1), c.primary)
160
 
        self.assertEqual(set([('b', 2)]), c.secondaries)
 
170
        wait_until(lambda: ('a', 1) == c.primary, 'discover the primary')
 
171
        wait_until(lambda: set([('b', 2)]) == c.secondaries,
 
172
                   'discover the secondary')
161
173
 
162
174
        # C is added.
163
175
        c.mock_members.append('c:3')
164
176
        c.mock_ismaster_hosts.append('c:3')
165
 
        c.refresh()
 
177
 
 
178
        wait_until(lambda: set([('b', 2), ('c', 3)]) == c.secondaries,
 
179
                   'discover the new secondary')
166
180
 
167
181
        self.assertEqual(('a', 1), c.primary)
168
 
        self.assertEqual(set([('b', 2), ('c', 3)]), c.secondaries)
169
182
 
170
183
 
171
184
if __name__ == "__main__":