Revision 47cce79a
b/test/py/cmdlib/node_unittest.py | ||
---|---|---|
25 | 25 |
|
26 | 26 |
from collections import defaultdict |
27 | 27 |
|
28 |
from ganeti import compat |
|
28 | 29 |
from ganeti import constants |
29 | 30 |
from ganeti import objects |
30 | 31 |
from ganeti import opcodes |
32 |
from ganeti import errors |
|
31 | 33 |
|
32 | 34 |
from testsupport import * |
33 | 35 |
|
34 | 36 |
import testutils |
35 | 37 |
|
38 |
# pylint: disable=W0613 |
|
39 |
def _TcpPingFailSecondary(cfg, mock_fct, target, port, timeout=None, |
|
40 |
live_port_needed=None, source=None): |
|
41 |
# This will return True if target is in 192.0.2.0/24 (primary range) |
|
42 |
# and False if not. |
|
43 |
return "192.0.2." in target |
|
36 | 44 |
|
37 | 45 |
class TestLUNodeAdd(CmdlibTestCase): |
38 | 46 |
def setUp(self): |
... | ... | |
131 | 139 |
self.assertEqual(ndparams[constants.ND_OVS_LINK], |
132 | 140 |
created_node.ndparams.get(constants.ND_OVS_LINK, None)) |
133 | 141 |
|
142 |
def testReaddingMaster(self): |
|
143 |
op = opcodes.OpNodeAdd(node_name=self.cfg.GetMasterNodeName(), |
|
144 |
readd=True) |
|
145 |
|
|
146 |
self.ExecOpCodeExpectOpPrereqError(op, "Cannot readd the master node") |
|
147 |
|
|
148 |
def testReaddNotVmCapableNode(self): |
|
149 |
self.cfg.AddNewInstance(primary_node=self.node_readd) |
|
150 |
self.netutils_mod.GetHostname.return_value = \ |
|
151 |
HostnameMock(self.node_readd.name, self.node_readd.primary_ip) |
|
152 |
|
|
153 |
op = self.CopyOpCode(self.op_readd, vm_capable=False) |
|
154 |
|
|
155 |
self.ExecOpCodeExpectOpPrereqError(op, "Node .* being re-added with" |
|
156 |
" vm_capable flag set to false, but it" |
|
157 |
" already holds instances") |
|
158 |
|
|
159 |
def testReaddAndPassNodeGroup(self): |
|
160 |
op = self.CopyOpCode(self.op_readd,group="groupname") |
|
161 |
|
|
162 |
self.ExecOpCodeExpectOpPrereqError(op, "Cannot pass a node group when a" |
|
163 |
" node is being readded") |
|
164 |
|
|
165 |
def testPrimaryIPv6(self): |
|
166 |
self.master.secondary_ip = self.master.primary_ip |
|
167 |
|
|
168 |
op = self.CopyOpCode(self.op_add, primary_ip="2001:DB8::1", |
|
169 |
secondary_ip=self.REMOVE) |
|
170 |
|
|
171 |
self.ExecOpCode(op) |
|
172 |
|
|
173 |
def testInvalidSecondaryIP(self): |
|
174 |
op = self.CopyOpCode(self.op_add, secondary_ip="333.444.555.777") |
|
175 |
|
|
176 |
self.ExecOpCodeExpectOpPrereqError(op, "Secondary IP .* needs to be a valid" |
|
177 |
" IPv4 address") |
|
178 |
|
|
179 |
def testNodeAlreadyInCluster(self): |
|
180 |
op = self.CopyOpCode(self.op_readd, readd=False) |
|
181 |
|
|
182 |
self.ExecOpCodeExpectOpPrereqError(op, "Node %s is already in the" |
|
183 |
" configuration" % self.node_readd.name) |
|
184 |
|
|
185 |
def testReaddNodeNotInConfiguration(self): |
|
186 |
op = self.CopyOpCode(self.op_add, readd=True) |
|
187 |
|
|
188 |
self.ExecOpCodeExpectOpPrereqError(op, "Node %s is not in the" |
|
189 |
" configuration" % self.node_add.name) |
|
190 |
|
|
191 |
def testPrimaryIpConflict(self): |
|
192 |
# In LUNodeAdd, DNS will resolve the node name to an IP address, that is |
|
193 |
# used to overwrite any given primary_ip value! |
|
194 |
# Thus we need to mock this DNS resolver here! |
|
195 |
self.netutils_mod.GetHostname.return_value = \ |
|
196 |
HostnameMock(self.node_add.name, self.node_readd.primary_ip) |
|
197 |
|
|
198 |
op = self.CopyOpCode(self.op_add) |
|
199 |
|
|
200 |
self.ExecOpCodeExpectOpPrereqError(op, "New node ip address.* conflict with" |
|
201 |
" existing node") |
|
202 |
|
|
203 |
def testSecondaryIpConflict(self): |
|
204 |
op = self.CopyOpCode(self.op_add, secondary_ip=self.node_readd.secondary_ip) |
|
205 |
|
|
206 |
self.ExecOpCodeExpectOpPrereqError(op, "New node ip address.* conflict with" |
|
207 |
" existing node") |
|
208 |
|
|
209 |
def testReaddWithDifferentIP(self): |
|
210 |
op = self.CopyOpCode(self.op_readd, primary_ip="192.0.2.100", |
|
211 |
secondary_ip="230.0.113.100") |
|
212 |
|
|
213 |
self.ExecOpCodeExpectOpPrereqError(op, "Readded node doesn't have the same" |
|
214 |
" IP address configuration as before") |
|
215 |
|
|
216 |
|
|
217 |
def testNodeHasSecondaryIpButNotMaster(self): |
|
218 |
self.master.secondary_ip = self.master.primary_ip |
|
219 |
|
|
220 |
self.ExecOpCodeExpectOpPrereqError(self.op_add, "The master has no" |
|
221 |
" secondary ip but the new node has one") |
|
222 |
|
|
223 |
def testMasterHasSecondaryIpButNotNode(self): |
|
224 |
op = self.CopyOpCode(self.op_add, secondary_ip=None) |
|
225 |
|
|
226 |
self.ExecOpCodeExpectOpPrereqError(op, "The master has a secondary ip but" |
|
227 |
" the new node doesn't have one") |
|
228 |
|
|
229 |
def testNodeNotReachableByPing(self): |
|
230 |
self.netutils_mod.TcpPing.return_value = False |
|
231 |
|
|
232 |
op = self.CopyOpCode(self.op_add) |
|
233 |
|
|
234 |
self.ExecOpCodeExpectOpPrereqError(op, "Node not reachable by ping") |
|
235 |
|
|
236 |
def testNodeNotReachableByPingOnSecondary(self): |
|
237 |
self.netutils_mod.GetHostname.return_value = \ |
|
238 |
HostnameMock(self.node_add.name, self.node_add.primary_ip) |
|
239 |
self.netutils_mod.TcpPing.side_effect = \ |
|
240 |
compat.partial(_TcpPingFailSecondary, self.cfg, self.netutils_mod.TcpPing) |
|
241 |
|
|
242 |
op = self.CopyOpCode(self.op_add) |
|
243 |
|
|
244 |
self.ExecOpCodeExpectOpPrereqError(op, "Node secondary ip not reachable by" |
|
245 |
" TCP based ping to node daemon port") |
|
246 |
|
|
247 |
def testCantGetVersion(self): |
|
248 |
self.mocked_dns_rpc.call_version.return_value = \ |
|
249 |
self.RpcResultsBuilder(use_node_names=True) \ |
|
250 |
.AddErrorNode(self.node_add) \ |
|
251 |
.Build() |
|
252 |
|
|
253 |
op = self.CopyOpCode(self.op_add) |
|
254 |
self.ExecOpCodeExpectOpExecError(op, "Can't get version information from" |
|
255 |
" node %s" % self.node_add.name) |
|
256 |
|
|
134 | 257 |
if __name__ == "__main__": |
135 | 258 |
testutils.GanetiTestProgram() |
Also available in: Unified diff