1+ # Copyright 2009-2011 10gen, Inc.
2+ #
3+ # Licensed under the Apache License, Version 2.0 (the "License");
4+ # you may not use this file except in compliance with the License.
5+ # You may obtain a copy of the License at
6+ #
7+ # http://www.apache.org/licenses/LICENSE-2.0
8+ #
9+ # Unless required by applicable law or agreed to in writing, software
10+ # distributed under the License is distributed on an "AS IS" BASIS,
11+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ # See the License for the specific language governing permissions and
13+ # limitations under the License.
14+
15+ """Tools for testing PyMongo with a replica set."""
16+
117import os
218import random
319import shutil
2137
2238nodes = {}
2339
40+
2441def kill_members (members , sig ):
2542 for member in members :
2643 try :
@@ -31,14 +48,16 @@ def kill_members(members, sig):
3148 else :
3249 os .kill (proc .pid , sig )
3350 except OSError :
34- pass # already dead
51+ pass # already dead
52+
3553
3654def kill_all_members ():
3755 kill_members (nodes .keys (), 2 )
3856
57+
3958def wait_for (proc , port ):
4059 trys = 0
41- while proc .poll () is None and trys < 40 : # ~10 seconds
60+ while proc .poll () is None and trys < 40 : # ~10 seconds
4261 trys += 1
4362 s = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
4463 try :
@@ -53,6 +72,7 @@ def wait_for(proc, port):
5372 kill_all_members ()
5473 return False
5574
75+
5676def start_replica_set (num_members = 3 , with_arbiter = True , fresh = True ):
5777 if fresh :
5878 if os .path .exists (dbpath ):
@@ -110,48 +130,58 @@ def start_replica_set(num_members=3, with_arbiter=True, fresh=True):
110130 pass
111131 return primary , set_name
112132
133+
113134def get_members_in_state (state ):
114135 c = pymongo .Connection (nodes .keys (), slave_okay = True )
115136 status = c .admin .command ('replSetGetStatus' )
116137 members = status ['members' ]
117138 return [k ['name' ] for k in members if k ['state' ] == state ]
118139
140+
119141def get_primary ():
120142 return get_members_in_state (1 )
121143
144+
122145def get_random_secondary ():
123146 secondaries = get_members_in_state (2 )
124147 if len (secondaries ):
125148 return [secondaries [random .randrange (0 , len (secondaries ))]]
126149 return secondaries
127150
151+
128152def get_secondaries ():
129153 return get_members_in_state (2 )
130154
155+
131156def get_arbiters ():
132157 return get_members_in_state (7 )
133158
159+
134160def kill_primary (sig = 2 ):
135161 primary = get_primary ()
136162 kill_members (primary , sig )
137163 return primary
138164
165+
139166def kill_secondary (sig = 2 ):
140167 secondary = get_random_secondary ()
141168 kill_members (secondary , sig )
142169 return secondary
143170
171+
144172def kill_all_secondaries (sig = 2 ):
145173 secondaries = get_secondaries ()
146174 kill_members (secondaries , sig )
147175 return secondaries
148176
177+
149178def stepdown_primary ():
150179 primary = get_primary ()
151180 if primary :
152181 c = pymongo .Connection (primary )
153182 c .admin .command ('replSetStepDown' , 10 )
154183
184+
155185def restart_members (members ):
156186 restarted = []
157187 for member in members :
@@ -164,4 +194,3 @@ def restart_members(members):
164194 if res :
165195 restarted .append (member )
166196 return restarted
167-
0 commit comments