Statistics
| Branch: | Tag: | Revision:

root / test / py / cmdlib / cluster_unittest.py @ 31ccfc0e

History | View | Annotate | Download (73 kB)

1 19830e88 Thomas Thrainer
#!/usr/bin/python
2 19830e88 Thomas Thrainer
#
3 19830e88 Thomas Thrainer
4 0e1b5262 Thomas Thrainer
# Copyright (C) 2008, 2011, 2012, 2013 Google Inc.
5 19830e88 Thomas Thrainer
#
6 19830e88 Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 19830e88 Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 19830e88 Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 19830e88 Thomas Thrainer
# (at your option) any later version.
10 19830e88 Thomas Thrainer
#
11 19830e88 Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 19830e88 Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 19830e88 Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 19830e88 Thomas Thrainer
# General Public License for more details.
15 19830e88 Thomas Thrainer
#
16 19830e88 Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 19830e88 Thomas Thrainer
# along with this program; if not, write to the Free Software
18 19830e88 Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 19830e88 Thomas Thrainer
# 02110-1301, USA.
20 19830e88 Thomas Thrainer
21 19830e88 Thomas Thrainer
22 19830e88 Thomas Thrainer
"""Tests for LUCluster*
23 19830e88 Thomas Thrainer

24 19830e88 Thomas Thrainer
"""
25 19830e88 Thomas Thrainer
26 850be460 Thomas Thrainer
import OpenSSL
27 850be460 Thomas Thrainer
28 0e1b5262 Thomas Thrainer
import unittest
29 0e1b5262 Thomas Thrainer
import operator
30 0e1b5262 Thomas Thrainer
import os
31 0e1b5262 Thomas Thrainer
import tempfile
32 0e1b5262 Thomas Thrainer
import shutil
33 0e1b5262 Thomas Thrainer
34 0e1b5262 Thomas Thrainer
from ganeti import constants
35 a794b8d7 Thomas Thrainer
from ganeti import errors
36 b730e2a7 Thomas Thrainer
from ganeti import netutils
37 0e1b5262 Thomas Thrainer
from ganeti import objects
38 19830e88 Thomas Thrainer
from ganeti import opcodes
39 0e1b5262 Thomas Thrainer
from ganeti import utils
40 0e1b5262 Thomas Thrainer
from ganeti import pathutils
41 eb172e55 Thomas Thrainer
from ganeti import query
42 0e1b5262 Thomas Thrainer
from ganeti.cmdlib import cluster
43 0e1b5262 Thomas Thrainer
from ganeti.hypervisor import hv_xen
44 19830e88 Thomas Thrainer
45 19830e88 Thomas Thrainer
from testsupport import *
46 19830e88 Thomas Thrainer
47 19830e88 Thomas Thrainer
import testutils
48 0e1b5262 Thomas Thrainer
49 0e1b5262 Thomas Thrainer
50 0e1b5262 Thomas Thrainer
class TestCertVerification(testutils.GanetiTestCase):
51 0e1b5262 Thomas Thrainer
  def setUp(self):
52 0e1b5262 Thomas Thrainer
    testutils.GanetiTestCase.setUp(self)
53 0e1b5262 Thomas Thrainer
54 0e1b5262 Thomas Thrainer
    self.tmpdir = tempfile.mkdtemp()
55 0e1b5262 Thomas Thrainer
56 0e1b5262 Thomas Thrainer
  def tearDown(self):
57 0e1b5262 Thomas Thrainer
    shutil.rmtree(self.tmpdir)
58 0e1b5262 Thomas Thrainer
59 0e1b5262 Thomas Thrainer
  def testVerifyCertificate(self):
60 0e1b5262 Thomas Thrainer
    cluster._VerifyCertificate(testutils.TestDataFilename("cert1.pem"))
61 0e1b5262 Thomas Thrainer
62 0e1b5262 Thomas Thrainer
    nonexist_filename = os.path.join(self.tmpdir, "does-not-exist")
63 0e1b5262 Thomas Thrainer
64 0e1b5262 Thomas Thrainer
    (errcode, msg) = cluster._VerifyCertificate(nonexist_filename)
65 0e1b5262 Thomas Thrainer
    self.assertEqual(errcode, cluster.LUClusterVerifyConfig.ETYPE_ERROR)
66 0e1b5262 Thomas Thrainer
67 0e1b5262 Thomas Thrainer
    # Try to load non-certificate file
68 0e1b5262 Thomas Thrainer
    invalid_cert = testutils.TestDataFilename("bdev-net.txt")
69 0e1b5262 Thomas Thrainer
    (errcode, msg) = cluster._VerifyCertificate(invalid_cert)
70 0e1b5262 Thomas Thrainer
    self.assertEqual(errcode, cluster.LUClusterVerifyConfig.ETYPE_ERROR)
71 0e1b5262 Thomas Thrainer
72 0e1b5262 Thomas Thrainer
73 0e1b5262 Thomas Thrainer
class TestClusterVerifySsh(unittest.TestCase):
74 0e1b5262 Thomas Thrainer
  def testMultipleGroups(self):
75 0e1b5262 Thomas Thrainer
    fn = cluster.LUClusterVerifyGroup._SelectSshCheckNodes
76 0e1b5262 Thomas Thrainer
    mygroupnodes = [
77 0e1b5262 Thomas Thrainer
      objects.Node(name="node20", group="my", offline=False),
78 0e1b5262 Thomas Thrainer
      objects.Node(name="node21", group="my", offline=False),
79 0e1b5262 Thomas Thrainer
      objects.Node(name="node22", group="my", offline=False),
80 0e1b5262 Thomas Thrainer
      objects.Node(name="node23", group="my", offline=False),
81 0e1b5262 Thomas Thrainer
      objects.Node(name="node24", group="my", offline=False),
82 0e1b5262 Thomas Thrainer
      objects.Node(name="node25", group="my", offline=False),
83 0e1b5262 Thomas Thrainer
      objects.Node(name="node26", group="my", offline=True),
84 0e1b5262 Thomas Thrainer
      ]
85 0e1b5262 Thomas Thrainer
    nodes = [
86 0e1b5262 Thomas Thrainer
      objects.Node(name="node1", group="g1", offline=True),
87 0e1b5262 Thomas Thrainer
      objects.Node(name="node2", group="g1", offline=False),
88 0e1b5262 Thomas Thrainer
      objects.Node(name="node3", group="g1", offline=False),
89 0e1b5262 Thomas Thrainer
      objects.Node(name="node4", group="g1", offline=True),
90 0e1b5262 Thomas Thrainer
      objects.Node(name="node5", group="g1", offline=False),
91 0e1b5262 Thomas Thrainer
      objects.Node(name="node10", group="xyz", offline=False),
92 0e1b5262 Thomas Thrainer
      objects.Node(name="node11", group="xyz", offline=False),
93 0e1b5262 Thomas Thrainer
      objects.Node(name="node40", group="alloff", offline=True),
94 0e1b5262 Thomas Thrainer
      objects.Node(name="node41", group="alloff", offline=True),
95 0e1b5262 Thomas Thrainer
      objects.Node(name="node50", group="aaa", offline=False),
96 0e1b5262 Thomas Thrainer
      ] + mygroupnodes
97 0e1b5262 Thomas Thrainer
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
98 0e1b5262 Thomas Thrainer
99 0e1b5262 Thomas Thrainer
    (online, perhost) = fn(mygroupnodes, "my", nodes)
100 0e1b5262 Thomas Thrainer
    self.assertEqual(online, ["node%s" % i for i in range(20, 26)])
101 0e1b5262 Thomas Thrainer
    self.assertEqual(set(perhost.keys()), set(online))
102 0e1b5262 Thomas Thrainer
103 0e1b5262 Thomas Thrainer
    self.assertEqual(perhost, {
104 0e1b5262 Thomas Thrainer
      "node20": ["node10", "node2", "node50"],
105 0e1b5262 Thomas Thrainer
      "node21": ["node11", "node3", "node50"],
106 0e1b5262 Thomas Thrainer
      "node22": ["node10", "node5", "node50"],
107 0e1b5262 Thomas Thrainer
      "node23": ["node11", "node2", "node50"],
108 0e1b5262 Thomas Thrainer
      "node24": ["node10", "node3", "node50"],
109 0e1b5262 Thomas Thrainer
      "node25": ["node11", "node5", "node50"],
110 0e1b5262 Thomas Thrainer
      })
111 0e1b5262 Thomas Thrainer
112 0e1b5262 Thomas Thrainer
  def testSingleGroup(self):
113 0e1b5262 Thomas Thrainer
    fn = cluster.LUClusterVerifyGroup._SelectSshCheckNodes
114 0e1b5262 Thomas Thrainer
    nodes = [
115 0e1b5262 Thomas Thrainer
      objects.Node(name="node1", group="default", offline=True),
116 0e1b5262 Thomas Thrainer
      objects.Node(name="node2", group="default", offline=False),
117 0e1b5262 Thomas Thrainer
      objects.Node(name="node3", group="default", offline=False),
118 0e1b5262 Thomas Thrainer
      objects.Node(name="node4", group="default", offline=True),
119 0e1b5262 Thomas Thrainer
      ]
120 0e1b5262 Thomas Thrainer
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
121 0e1b5262 Thomas Thrainer
122 0e1b5262 Thomas Thrainer
    (online, perhost) = fn(nodes, "default", nodes)
123 0e1b5262 Thomas Thrainer
    self.assertEqual(online, ["node2", "node3"])
124 0e1b5262 Thomas Thrainer
    self.assertEqual(set(perhost.keys()), set(online))
125 0e1b5262 Thomas Thrainer
126 0e1b5262 Thomas Thrainer
    self.assertEqual(perhost, {
127 0e1b5262 Thomas Thrainer
      "node2": [],
128 0e1b5262 Thomas Thrainer
      "node3": [],
129 0e1b5262 Thomas Thrainer
      })
130 0e1b5262 Thomas Thrainer
131 0e1b5262 Thomas Thrainer
132 19830e88 Thomas Thrainer
class TestLUClusterActivateMasterIp(CmdlibTestCase):
133 19830e88 Thomas Thrainer
  def testSuccess(self):
134 19830e88 Thomas Thrainer
    op = opcodes.OpClusterActivateMasterIp()
135 19830e88 Thomas Thrainer
136 19830e88 Thomas Thrainer
    self.rpc.call_node_activate_master_ip.return_value = \
137 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
138 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master)
139 19830e88 Thomas Thrainer
140 19830e88 Thomas Thrainer
    self.ExecOpCode(op)
141 19830e88 Thomas Thrainer
142 19830e88 Thomas Thrainer
    self.rpc.call_node_activate_master_ip.assert_called_once_with(
143 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
144 19830e88 Thomas Thrainer
145 19830e88 Thomas Thrainer
  def testFailure(self):
146 19830e88 Thomas Thrainer
    op = opcodes.OpClusterActivateMasterIp()
147 19830e88 Thomas Thrainer
148 19830e88 Thomas Thrainer
    self.rpc.call_node_activate_master_ip.return_value = \
149 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
150 f02733cc Thomas Thrainer
        .CreateFailedNodeResult(self.master) \
151 19830e88 Thomas Thrainer
152 19830e88 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op)
153 19830e88 Thomas Thrainer
154 19830e88 Thomas Thrainer
155 e0b8df13 Thomas Thrainer
class TestLUClusterDeactivateMasterIp(CmdlibTestCase):
156 e0b8df13 Thomas Thrainer
  def testSuccess(self):
157 e0b8df13 Thomas Thrainer
    op = opcodes.OpClusterDeactivateMasterIp()
158 e0b8df13 Thomas Thrainer
159 e0b8df13 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
160 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
161 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master)
162 e0b8df13 Thomas Thrainer
163 e0b8df13 Thomas Thrainer
    self.ExecOpCode(op)
164 e0b8df13 Thomas Thrainer
165 e0b8df13 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.assert_called_once_with(
166 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
167 e0b8df13 Thomas Thrainer
168 e0b8df13 Thomas Thrainer
  def testFailure(self):
169 e0b8df13 Thomas Thrainer
    op = opcodes.OpClusterDeactivateMasterIp()
170 e0b8df13 Thomas Thrainer
171 e0b8df13 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
172 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
173 f02733cc Thomas Thrainer
        .CreateFailedNodeResult(self.master) \
174 e0b8df13 Thomas Thrainer
175 e0b8df13 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op)
176 e0b8df13 Thomas Thrainer
177 e0b8df13 Thomas Thrainer
178 eb172e55 Thomas Thrainer
class TestLUClusterConfigQuery(CmdlibTestCase):
179 eb172e55 Thomas Thrainer
  def testInvalidField(self):
180 eb172e55 Thomas Thrainer
    op = opcodes.OpClusterConfigQuery(output_fields=["pinky_bunny"])
181 eb172e55 Thomas Thrainer
182 eb172e55 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "pinky_bunny")
183 eb172e55 Thomas Thrainer
184 eb172e55 Thomas Thrainer
  def testAllFields(self):
185 eb172e55 Thomas Thrainer
    op = opcodes.OpClusterConfigQuery(output_fields=query.CLUSTER_FIELDS.keys())
186 eb172e55 Thomas Thrainer
187 eb172e55 Thomas Thrainer
    self.rpc.call_get_watcher_pause.return_value = \
188 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
189 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master, -1)
190 eb172e55 Thomas Thrainer
191 eb172e55 Thomas Thrainer
    ret = self.ExecOpCode(op)
192 eb172e55 Thomas Thrainer
193 eb172e55 Thomas Thrainer
    self.assertEqual(1, self.rpc.call_get_watcher_pause.call_count)
194 eb172e55 Thomas Thrainer
    self.assertEqual(len(ret), len(query.CLUSTER_FIELDS))
195 eb172e55 Thomas Thrainer
196 eb172e55 Thomas Thrainer
  def testEmpytFields(self):
197 eb172e55 Thomas Thrainer
    op = opcodes.OpClusterConfigQuery(output_fields=[])
198 eb172e55 Thomas Thrainer
199 eb172e55 Thomas Thrainer
    self.ExecOpCode(op)
200 eb172e55 Thomas Thrainer
201 eb172e55 Thomas Thrainer
    self.assertFalse(self.rpc.call_get_watcher_pause.called)
202 eb172e55 Thomas Thrainer
203 eb172e55 Thomas Thrainer
204 bd6fb93b Thomas Thrainer
class TestLUClusterDestroy(CmdlibTestCase):
205 bd6fb93b Thomas Thrainer
  def testExistingNodes(self):
206 bd6fb93b Thomas Thrainer
    op = opcodes.OpClusterDestroy()
207 bd6fb93b Thomas Thrainer
208 bd6fb93b Thomas Thrainer
    self.cfg.AddNewNode()
209 bd6fb93b Thomas Thrainer
    self.cfg.AddNewNode()
210 bd6fb93b Thomas Thrainer
211 bd6fb93b Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "still 2 node\(s\)")
212 bd6fb93b Thomas Thrainer
213 bd6fb93b Thomas Thrainer
  def testExistingInstances(self):
214 bd6fb93b Thomas Thrainer
    op = opcodes.OpClusterDestroy()
215 bd6fb93b Thomas Thrainer
216 bd6fb93b Thomas Thrainer
    self.cfg.AddNewInstance()
217 bd6fb93b Thomas Thrainer
    self.cfg.AddNewInstance()
218 bd6fb93b Thomas Thrainer
219 bd6fb93b Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "still 2 instance\(s\)")
220 bd6fb93b Thomas Thrainer
221 bd6fb93b Thomas Thrainer
  def testEmptyCluster(self):
222 bd6fb93b Thomas Thrainer
    op = opcodes.OpClusterDestroy()
223 bd6fb93b Thomas Thrainer
224 bd6fb93b Thomas Thrainer
    self.ExecOpCode(op)
225 bd6fb93b Thomas Thrainer
226 f02733cc Thomas Thrainer
    self.assertSingleHooksCall([self.master.name],
227 812e07ab Thomas Thrainer
                               "cluster-destroy",
228 812e07ab Thomas Thrainer
                               constants.HOOKS_PHASE_POST)
229 bd6fb93b Thomas Thrainer
230 bd6fb93b Thomas Thrainer
231 812e07ab Thomas Thrainer
class TestLUClusterPostInit(CmdlibTestCase):
232 812e07ab Thomas Thrainer
  def testExecuion(self):
233 812e07ab Thomas Thrainer
    op = opcodes.OpClusterPostInit()
234 812e07ab Thomas Thrainer
235 812e07ab Thomas Thrainer
    self.ExecOpCode(op)
236 812e07ab Thomas Thrainer
237 f02733cc Thomas Thrainer
    self.assertSingleHooksCall([self.master.name],
238 812e07ab Thomas Thrainer
                               "cluster-init",
239 812e07ab Thomas Thrainer
                               constants.HOOKS_PHASE_POST)
240 812e07ab Thomas Thrainer
241 b730e2a7 Thomas Thrainer
242 b730e2a7 Thomas Thrainer
class TestLUClusterQuery(CmdlibTestCase):
243 b730e2a7 Thomas Thrainer
  def testSimpleInvocation(self):
244 b730e2a7 Thomas Thrainer
    op = opcodes.OpClusterQuery()
245 b730e2a7 Thomas Thrainer
246 b730e2a7 Thomas Thrainer
    self.ExecOpCode(op)
247 b730e2a7 Thomas Thrainer
248 b730e2a7 Thomas Thrainer
  def testIPv6Cluster(self):
249 b730e2a7 Thomas Thrainer
    op = opcodes.OpClusterQuery()
250 b730e2a7 Thomas Thrainer
251 f02733cc Thomas Thrainer
    self.cluster.primary_ip_family = netutils.IP6Address.family
252 b730e2a7 Thomas Thrainer
253 b730e2a7 Thomas Thrainer
    self.ExecOpCode(op)
254 b730e2a7 Thomas Thrainer
255 b730e2a7 Thomas Thrainer
256 6aac41fa Thomas Thrainer
class TestLUClusterRedistConf(CmdlibTestCase):
257 6aac41fa Thomas Thrainer
  def testSimpleInvocation(self):
258 6aac41fa Thomas Thrainer
    op = opcodes.OpClusterRedistConf()
259 6aac41fa Thomas Thrainer
260 6aac41fa Thomas Thrainer
    self.ExecOpCode(op)
261 6aac41fa Thomas Thrainer
262 6aac41fa Thomas Thrainer
263 08cef8fc Thomas Thrainer
class TestLUClusterRename(CmdlibTestCase):
264 08cef8fc Thomas Thrainer
  NEW_NAME = "new-name.example.com"
265 08cef8fc Thomas Thrainer
  NEW_IP = "1.2.3.4"
266 08cef8fc Thomas Thrainer
267 08cef8fc Thomas Thrainer
  def testNoChanges(self):
268 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.cfg.GetClusterName())
269 08cef8fc Thomas Thrainer
270 08cef8fc Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "name nor the IP address")
271 08cef8fc Thomas Thrainer
272 08cef8fc Thomas Thrainer
  def testReachableIp(self):
273 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.NEW_NAME)
274 08cef8fc Thomas Thrainer
275 08cef8fc Thomas Thrainer
    self.netutils_mod.GetHostname.return_value = \
276 08cef8fc Thomas Thrainer
      HostnameMock(self.NEW_NAME, self.NEW_IP)
277 08cef8fc Thomas Thrainer
    self.netutils_mod.TcpPing.return_value = True
278 08cef8fc Thomas Thrainer
279 08cef8fc Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "is reachable on the network")
280 08cef8fc Thomas Thrainer
281 08cef8fc Thomas Thrainer
  def testValidRename(self):
282 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.NEW_NAME)
283 08cef8fc Thomas Thrainer
284 08cef8fc Thomas Thrainer
    self.netutils_mod.GetHostname.return_value = \
285 08cef8fc Thomas Thrainer
      HostnameMock(self.NEW_NAME, self.NEW_IP)
286 08cef8fc Thomas Thrainer
287 08cef8fc Thomas Thrainer
    self.ExecOpCode(op)
288 08cef8fc Thomas Thrainer
289 08cef8fc Thomas Thrainer
    self.assertEqual(1, self.ssh_mod.WriteKnownHostsFile.call_count)
290 08cef8fc Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.assert_called_once_with(
291 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
292 08cef8fc Thomas Thrainer
    self.rpc.call_node_activate_master_ip.assert_called_once_with(
293 f02733cc Thomas Thrainer
      self.master_uuid, self.cfg.GetMasterNetworkParameters(), False)
294 08cef8fc Thomas Thrainer
295 08cef8fc Thomas Thrainer
  def testRenameOfflineMaster(self):
296 08cef8fc Thomas Thrainer
    op = opcodes.OpClusterRename(name=self.NEW_NAME)
297 08cef8fc Thomas Thrainer
298 f02733cc Thomas Thrainer
    self.master.offline = True
299 08cef8fc Thomas Thrainer
    self.netutils_mod.GetHostname.return_value = \
300 08cef8fc Thomas Thrainer
      HostnameMock(self.NEW_NAME, self.NEW_IP)
301 08cef8fc Thomas Thrainer
302 08cef8fc Thomas Thrainer
    self.ExecOpCode(op)
303 08cef8fc Thomas Thrainer
304 08cef8fc Thomas Thrainer
305 c487ae24 Thomas Thrainer
class TestLUClusterRepairDiskSizes(CmdlibTestCase):
306 c487ae24 Thomas Thrainer
  def testNoInstances(self):
307 c487ae24 Thomas Thrainer
    op = opcodes.OpClusterRepairDiskSizes()
308 c487ae24 Thomas Thrainer
309 c487ae24 Thomas Thrainer
    self.ExecOpCode(op)
310 c487ae24 Thomas Thrainer
311 c487ae24 Thomas Thrainer
  def _SetUpInstanceSingleDisk(self, dev_type=constants.LD_LV):
312 f02733cc Thomas Thrainer
    pnode = self.master
313 c487ae24 Thomas Thrainer
    snode = self.cfg.AddNewNode()
314 c487ae24 Thomas Thrainer
315 c487ae24 Thomas Thrainer
    disk = self.cfg.CreateDisk(dev_type=dev_type,
316 c487ae24 Thomas Thrainer
                               primary_node=pnode,
317 c487ae24 Thomas Thrainer
                               secondary_node=snode)
318 a794b8d7 Thomas Thrainer
    inst = self.cfg.AddNewInstance(disks=[disk])
319 c487ae24 Thomas Thrainer
320 c487ae24 Thomas Thrainer
    return (inst, disk)
321 c487ae24 Thomas Thrainer
322 c487ae24 Thomas Thrainer
  def testSingleInstanceOnFailingNode(self):
323 c487ae24 Thomas Thrainer
    (inst, _) = self._SetUpInstanceSingleDisk()
324 c487ae24 Thomas Thrainer
    op = opcodes.OpClusterRepairDiskSizes(instances=[inst.name])
325 c487ae24 Thomas Thrainer
326 c487ae24 Thomas Thrainer
    self.rpc.call_blockdev_getdimensions.return_value = \
327 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
328 f02733cc Thomas Thrainer
        .CreateFailedNodeResult(self.master)
329 c487ae24 Thomas Thrainer
330 c487ae24 Thomas Thrainer
    self.ExecOpCode(op)
331 c487ae24 Thomas Thrainer
332 c487ae24 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Failure in blockdev_getdimensions")
333 c487ae24 Thomas Thrainer
334 c487ae24 Thomas Thrainer
  def _ExecOpClusterRepairDiskSizes(self, node_data):
335 c487ae24 Thomas Thrainer
    # not specifying instances repairs all
336 c487ae24 Thomas Thrainer
    op = opcodes.OpClusterRepairDiskSizes()
337 c487ae24 Thomas Thrainer
338 c487ae24 Thomas Thrainer
    self.rpc.call_blockdev_getdimensions.return_value = \
339 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
340 f02733cc Thomas Thrainer
        .CreateSuccessfulNodeResult(self.master, node_data)
341 c487ae24 Thomas Thrainer
342 c487ae24 Thomas Thrainer
    return self.ExecOpCode(op)
343 c487ae24 Thomas Thrainer
344 c487ae24 Thomas Thrainer
  def testInvalidResultData(self):
345 c487ae24 Thomas Thrainer
    for data in [[], [None], ["invalid"], [("still", "invalid")]]:
346 c487ae24 Thomas Thrainer
      self.ResetMocks()
347 c487ae24 Thomas Thrainer
348 c487ae24 Thomas Thrainer
      self._SetUpInstanceSingleDisk()
349 c487ae24 Thomas Thrainer
      self._ExecOpClusterRepairDiskSizes(data)
350 c487ae24 Thomas Thrainer
351 c487ae24 Thomas Thrainer
      self.mcpu.assertLogContainsRegex("ignoring")
352 c487ae24 Thomas Thrainer
353 c487ae24 Thomas Thrainer
  def testCorrectSize(self):
354 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
355 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
356 c487ae24 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
357 c487ae24 Thomas Thrainer
    self.assertEqual(0, len(changed))
358 c487ae24 Thomas Thrainer
359 c487ae24 Thomas Thrainer
  def testWrongSize(self):
360 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
361 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(512 * 1024 * 1024, None)])
362 c487ae24 Thomas Thrainer
    self.assertEqual(1, len(changed))
363 c487ae24 Thomas Thrainer
364 c487ae24 Thomas Thrainer
  def testCorrectDRBD(self):
365 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk(dev_type=constants.LD_DRBD8)
366 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
367 c487ae24 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
368 c487ae24 Thomas Thrainer
    self.assertEqual(0, len(changed))
369 c487ae24 Thomas Thrainer
370 c487ae24 Thomas Thrainer
  def testWrongDRBDChild(self):
371 c487ae24 Thomas Thrainer
    (_, disk) = self._SetUpInstanceSingleDisk(dev_type=constants.LD_DRBD8)
372 c487ae24 Thomas Thrainer
    disk.children[0].size = 512
373 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
374 c487ae24 Thomas Thrainer
    self.assertEqual(1, len(changed))
375 c487ae24 Thomas Thrainer
376 c487ae24 Thomas Thrainer
  def testExclusiveStorageInvalidResultData(self):
377 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
378 f02733cc Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
379 c487ae24 Thomas Thrainer
    self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, None)])
380 c487ae24 Thomas Thrainer
381 c487ae24 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
382 c487ae24 Thomas Thrainer
      "did not return valid spindles information")
383 c487ae24 Thomas Thrainer
384 c487ae24 Thomas Thrainer
  def testExclusiveStorageCorrectSpindles(self):
385 c487ae24 Thomas Thrainer
    (_, disk) = self._SetUpInstanceSingleDisk()
386 c487ae24 Thomas Thrainer
    disk.spindles = 1
387 f02733cc Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
388 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, 1)])
389 c487ae24 Thomas Thrainer
    self.assertEqual(0, len(changed))
390 c487ae24 Thomas Thrainer
391 c487ae24 Thomas Thrainer
  def testExclusiveStorageWrongSpindles(self):
392 c487ae24 Thomas Thrainer
    self._SetUpInstanceSingleDisk()
393 f02733cc Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
394 c487ae24 Thomas Thrainer
    changed = self._ExecOpClusterRepairDiskSizes([(1024 * 1024 * 1024, 1)])
395 c487ae24 Thomas Thrainer
    self.assertEqual(1, len(changed))
396 c487ae24 Thomas Thrainer
397 c487ae24 Thomas Thrainer
398 a794b8d7 Thomas Thrainer
class TestLUClusterSetParams(CmdlibTestCase):
399 a794b8d7 Thomas Thrainer
  UID_POOL = [(10, 1000)]
400 a794b8d7 Thomas Thrainer
401 a794b8d7 Thomas Thrainer
  def testUidPool(self):
402 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(uid_pool=self.UID_POOL)
403 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
404 a794b8d7 Thomas Thrainer
    self.assertEqual(self.UID_POOL, self.cluster.uid_pool)
405 a794b8d7 Thomas Thrainer
406 a794b8d7 Thomas Thrainer
  def testAddUids(self):
407 a794b8d7 Thomas Thrainer
    old_pool = [(1, 9)]
408 a794b8d7 Thomas Thrainer
    self.cluster.uid_pool = list(old_pool)
409 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(add_uids=self.UID_POOL)
410 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
411 a794b8d7 Thomas Thrainer
    self.assertEqual(set(self.UID_POOL + old_pool),
412 a794b8d7 Thomas Thrainer
                     set(self.cluster.uid_pool))
413 a794b8d7 Thomas Thrainer
414 a794b8d7 Thomas Thrainer
  def testRemoveUids(self):
415 a794b8d7 Thomas Thrainer
    additional_pool = [(1, 9)]
416 a794b8d7 Thomas Thrainer
    self.cluster.uid_pool = self.UID_POOL + additional_pool
417 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(remove_uids=self.UID_POOL)
418 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
419 a794b8d7 Thomas Thrainer
    self.assertEqual(additional_pool, self.cluster.uid_pool)
420 a794b8d7 Thomas Thrainer
421 a794b8d7 Thomas Thrainer
  def testMasterNetmask(self):
422 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netmask=0xFFFF0000)
423 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
424 a794b8d7 Thomas Thrainer
    self.assertEqual(0xFFFF0000, self.cluster.master_netmask)
425 a794b8d7 Thomas Thrainer
426 a794b8d7 Thomas Thrainer
  def testInvalidDiskparams(self):
427 a794b8d7 Thomas Thrainer
    for diskparams in [{constants.DT_DISKLESS: {constants.LV_STRIPES: 0}},
428 a794b8d7 Thomas Thrainer
                       {constants.DT_DRBD8: {constants.RBD_POOL: "pool"}}]:
429 a794b8d7 Thomas Thrainer
      self.ResetMocks()
430 a794b8d7 Thomas Thrainer
      op = opcodes.OpClusterSetParams(diskparams=diskparams)
431 a794b8d7 Thomas Thrainer
      self.ExecOpCodeExpectOpPrereqError(op, "verify diskparams")
432 a794b8d7 Thomas Thrainer
433 a794b8d7 Thomas Thrainer
  def testValidDiskparams(self):
434 a794b8d7 Thomas Thrainer
    diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
435 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(diskparams=diskparams)
436 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
437 a794b8d7 Thomas Thrainer
    self.assertEqual(diskparams[constants.DT_RBD],
438 a794b8d7 Thomas Thrainer
                     self.cluster.diskparams[constants.DT_RBD])
439 a794b8d7 Thomas Thrainer
440 a794b8d7 Thomas Thrainer
  def testMinimalDiskparams(self):
441 a794b8d7 Thomas Thrainer
    diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
442 a794b8d7 Thomas Thrainer
    self.cluster.diskparams = {}
443 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(diskparams=diskparams)
444 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
445 a794b8d7 Thomas Thrainer
    self.assertEqual(diskparams, self.cluster.diskparams)
446 a794b8d7 Thomas Thrainer
447 a794b8d7 Thomas Thrainer
  def testUnsetDrbdHelperWithDrbdDisks(self):
448 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(disks=[
449 a794b8d7 Thomas Thrainer
      self.cfg.CreateDisk(dev_type=constants.LD_DRBD8, create_nodes=True)])
450 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="")
451 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable drbd helper")
452 a794b8d7 Thomas Thrainer
453 a794b8d7 Thomas Thrainer
  def testFileStorageDir(self):
454 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(file_storage_dir="/random/path")
455 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
456 a794b8d7 Thomas Thrainer
457 a794b8d7 Thomas Thrainer
  def testSetFileStorageDirToCurrentValue(self):
458 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
459 a794b8d7 Thomas Thrainer
           file_storage_dir=self.cluster.file_storage_dir)
460 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
461 a794b8d7 Thomas Thrainer
462 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("file storage dir already set to value")
463 a794b8d7 Thomas Thrainer
464 a794b8d7 Thomas Thrainer
  def testValidDrbdHelper(self):
465 a794b8d7 Thomas Thrainer
    node1 = self.cfg.AddNewNode()
466 a794b8d7 Thomas Thrainer
    node1.offline = True
467 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
468 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
469 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, "/bin/true") \
470 a794b8d7 Thomas Thrainer
        .AddOfflineNode(node1) \
471 a794b8d7 Thomas Thrainer
        .Build()
472 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
473 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
474 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Not checking drbd helper on offline node")
475 a794b8d7 Thomas Thrainer
476 a794b8d7 Thomas Thrainer
  def testDrbdHelperFailingNode(self):
477 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
478 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
479 a794b8d7 Thomas Thrainer
        .AddFailedNode(self.master) \
480 a794b8d7 Thomas Thrainer
        .Build()
481 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
482 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Error checking drbd helper")
483 a794b8d7 Thomas Thrainer
484 a794b8d7 Thomas Thrainer
  def testInvalidDrbdHelper(self):
485 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
486 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
487 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, "/bin/false") \
488 a794b8d7 Thomas Thrainer
        .Build()
489 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
490 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "drbd helper is /bin/false")
491 a794b8d7 Thomas Thrainer
492 a794b8d7 Thomas Thrainer
  def testDrbdHelperWithoutDrbdDiskTemplate(self):
493 a794b8d7 Thomas Thrainer
    drbd_helper = "/bin/random_helper"
494 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
495 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
496 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
497 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, drbd_helper) \
498 a794b8d7 Thomas Thrainer
        .Build()
499 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
500 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
501 a794b8d7 Thomas Thrainer
502 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("but did not enable")
503 a794b8d7 Thomas Thrainer
504 31ccfc0e Helga Velroyen
  def testResetDrbdHelperDrbdDisabled(self):
505 a794b8d7 Thomas Thrainer
    drbd_helper = ""
506 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
507 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
508 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
509 a794b8d7 Thomas Thrainer
510 a794b8d7 Thomas Thrainer
    self.assertEqual(None, self.cluster.drbd_usermode_helper)
511 a794b8d7 Thomas Thrainer
512 31ccfc0e Helga Velroyen
  def testResetDrbdHelperDrbdEnabled(self):
513 31ccfc0e Helga Velroyen
    drbd_helper = ""
514 31ccfc0e Helga Velroyen
    self.cluster.enabled_disk_templates = [constants.DT_DRBD8]
515 31ccfc0e Helga Velroyen
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
516 31ccfc0e Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(
517 31ccfc0e Helga Velroyen
        op, "Cannot disable drbd helper while DRBD is enabled.")
518 31ccfc0e Helga Velroyen
519 31ccfc0e Helga Velroyen
  def testEnableDrbdNoHelper(self):
520 31ccfc0e Helga Velroyen
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
521 31ccfc0e Helga Velroyen
    self.cluster.drbd_usermode_helper = None
522 31ccfc0e Helga Velroyen
    enabled_disk_templates = [constants.DT_DRBD8]
523 31ccfc0e Helga Velroyen
    op = opcodes.OpClusterSetParams(
524 31ccfc0e Helga Velroyen
        enabled_disk_templates=enabled_disk_templates)
525 31ccfc0e Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(
526 31ccfc0e Helga Velroyen
        op, "Cannot enable DRBD without a DRBD usermode helper set")
527 31ccfc0e Helga Velroyen
528 31ccfc0e Helga Velroyen
  def testEnableDrbdHelperSet(self):
529 31ccfc0e Helga Velroyen
    drbd_helper = "/bin/random_helper"
530 31ccfc0e Helga Velroyen
    self.rpc.call_drbd_helper.return_value = \
531 31ccfc0e Helga Velroyen
      self.RpcResultsBuilder() \
532 31ccfc0e Helga Velroyen
        .AddSuccessfulNode(self.master, drbd_helper) \
533 31ccfc0e Helga Velroyen
        .Build()
534 31ccfc0e Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
535 31ccfc0e Helga Velroyen
    self.cluster.drbd_usermode_helper = drbd_helper
536 31ccfc0e Helga Velroyen
    enabled_disk_templates = [constants.DT_DRBD8]
537 31ccfc0e Helga Velroyen
    op = opcodes.OpClusterSetParams(
538 31ccfc0e Helga Velroyen
        enabled_disk_templates=enabled_disk_templates,
539 31ccfc0e Helga Velroyen
        ipolicy={constants.IPOLICY_DTS: enabled_disk_templates})
540 31ccfc0e Helga Velroyen
    self.ExecOpCode(op)
541 31ccfc0e Helga Velroyen
542 31ccfc0e Helga Velroyen
    self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper)
543 31ccfc0e Helga Velroyen
544 7c577910 Helga Velroyen
  def testDrbdHelperAlreadySet(self):
545 7c577910 Helga Velroyen
    drbd_helper = "/bin/true"
546 7c577910 Helga Velroyen
    self.rpc.call_drbd_helper.return_value = \
547 7c577910 Helga Velroyen
      self.RpcResultsBuilder() \
548 7c577910 Helga Velroyen
        .AddSuccessfulNode(self.master, "/bin/true") \
549 7c577910 Helga Velroyen
        .Build()
550 31ccfc0e Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
551 7c577910 Helga Velroyen
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
552 7c577910 Helga Velroyen
    self.ExecOpCode(op)
553 7c577910 Helga Velroyen
554 7c577910 Helga Velroyen
    self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper)
555 7c577910 Helga Velroyen
    self.mcpu.assertLogContainsRegex("DRBD helper already in desired state")
556 7c577910 Helga Velroyen
557 7c577910 Helga Velroyen
  def testSetDrbdHelper(self):
558 7c577910 Helga Velroyen
    drbd_helper = "/bin/true"
559 7c577910 Helga Velroyen
    self.rpc.call_drbd_helper.return_value = \
560 7c577910 Helga Velroyen
      self.RpcResultsBuilder() \
561 7c577910 Helga Velroyen
        .AddSuccessfulNode(self.master, "/bin/true") \
562 7c577910 Helga Velroyen
        .Build()
563 7c577910 Helga Velroyen
    self.cluster.drbd_usermode_helper = "/bin/false"
564 31ccfc0e Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_DRBD8])
565 7c577910 Helga Velroyen
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
566 7c577910 Helga Velroyen
    self.ExecOpCode(op)
567 7c577910 Helga Velroyen
568 7c577910 Helga Velroyen
    self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper)
569 7c577910 Helga Velroyen
570 a794b8d7 Thomas Thrainer
  def testBeparams(self):
571 a794b8d7 Thomas Thrainer
    beparams = {constants.BE_VCPUS: 32}
572 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(beparams=beparams)
573 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
574 a794b8d7 Thomas Thrainer
    self.assertEqual(32, self.cluster
575 a794b8d7 Thomas Thrainer
                           .beparams[constants.PP_DEFAULT][constants.BE_VCPUS])
576 a794b8d7 Thomas Thrainer
577 a794b8d7 Thomas Thrainer
  def testNdparams(self):
578 a794b8d7 Thomas Thrainer
    ndparams = {constants.ND_EXCLUSIVE_STORAGE: True}
579 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ndparams=ndparams)
580 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
581 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster
582 a794b8d7 Thomas Thrainer
                             .ndparams[constants.ND_EXCLUSIVE_STORAGE])
583 a794b8d7 Thomas Thrainer
584 a794b8d7 Thomas Thrainer
  def testNdparamsResetOobProgram(self):
585 a794b8d7 Thomas Thrainer
    ndparams = {constants.ND_OOB_PROGRAM: ""}
586 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ndparams=ndparams)
587 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
588 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.NDC_DEFAULTS[constants.ND_OOB_PROGRAM],
589 a794b8d7 Thomas Thrainer
                     self.cluster.ndparams[constants.ND_OOB_PROGRAM])
590 a794b8d7 Thomas Thrainer
591 a794b8d7 Thomas Thrainer
  def testHvState(self):
592 a794b8d7 Thomas Thrainer
    hv_state = {constants.HT_FAKE: {constants.HVST_CPU_TOTAL: 8}}
593 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hv_state=hv_state)
594 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
595 a794b8d7 Thomas Thrainer
    self.assertEqual(8, self.cluster.hv_state_static
596 a794b8d7 Thomas Thrainer
                          [constants.HT_FAKE][constants.HVST_CPU_TOTAL])
597 a794b8d7 Thomas Thrainer
598 a794b8d7 Thomas Thrainer
  def testDiskState(self):
599 a794b8d7 Thomas Thrainer
    disk_state = {
600 a794b8d7 Thomas Thrainer
      constants.LD_LV: {
601 a794b8d7 Thomas Thrainer
        "mock_vg": {constants.DS_DISK_TOTAL: 10}
602 a794b8d7 Thomas Thrainer
      }
603 a794b8d7 Thomas Thrainer
    }
604 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(disk_state=disk_state)
605 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
606 a794b8d7 Thomas Thrainer
    self.assertEqual(10, self.cluster
607 a794b8d7 Thomas Thrainer
                           .disk_state_static[constants.LD_LV]["mock_vg"]
608 a794b8d7 Thomas Thrainer
                             [constants.DS_DISK_TOTAL])
609 a794b8d7 Thomas Thrainer
610 a794b8d7 Thomas Thrainer
  def testDefaultIPolicy(self):
611 a794b8d7 Thomas Thrainer
    ipolicy = constants.IPOLICY_DEFAULTS
612 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ipolicy=ipolicy)
613 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
614 a794b8d7 Thomas Thrainer
615 a794b8d7 Thomas Thrainer
  def testIPolicyNewViolation(self):
616 a794b8d7 Thomas Thrainer
    import ganeti.constants as C
617 a794b8d7 Thomas Thrainer
    ipolicy = C.IPOLICY_DEFAULTS
618 a794b8d7 Thomas Thrainer
    ipolicy[C.ISPECS_MINMAX][0][C.ISPECS_MIN][C.ISPEC_MEM_SIZE] = 128
619 a794b8d7 Thomas Thrainer
    ipolicy[C.ISPECS_MINMAX][0][C.ISPECS_MAX][C.ISPEC_MEM_SIZE] = 128
620 a794b8d7 Thomas Thrainer
621 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(beparams={C.BE_MINMEM: 512, C.BE_MAXMEM: 512})
622 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ipolicy=ipolicy)
623 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
624 a794b8d7 Thomas Thrainer
625 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instances violate them")
626 a794b8d7 Thomas Thrainer
627 a794b8d7 Thomas Thrainer
  def testNicparamsNoInstance(self):
628 a794b8d7 Thomas Thrainer
    nicparams = {
629 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
630 a794b8d7 Thomas Thrainer
    }
631 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
632 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
633 a794b8d7 Thomas Thrainer
634 a794b8d7 Thomas Thrainer
    self.assertEqual("mock_bridge",
635 a794b8d7 Thomas Thrainer
                     self.cluster.nicparams
636 a794b8d7 Thomas Thrainer
                       [constants.PP_DEFAULT][constants.NIC_LINK])
637 a794b8d7 Thomas Thrainer
638 a794b8d7 Thomas Thrainer
  def testNicparamsInvalidConf(self):
639 a794b8d7 Thomas Thrainer
    nicparams = {
640 850be460 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
641 850be460 Thomas Thrainer
      constants.NIC_LINK: ""
642 a794b8d7 Thomas Thrainer
    }
643 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
644 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectException(op, errors.ConfigurationError, "NIC link")
645 a794b8d7 Thomas Thrainer
646 a794b8d7 Thomas Thrainer
  def testNicparamsInvalidInstanceConf(self):
647 a794b8d7 Thomas Thrainer
    nicparams = {
648 a794b8d7 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
649 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
650 a794b8d7 Thomas Thrainer
    }
651 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(nics=[
652 a794b8d7 Thomas Thrainer
      self.cfg.CreateNic(nicparams={constants.NIC_LINK: None})])
653 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
654 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Missing bridged NIC link")
655 a794b8d7 Thomas Thrainer
656 a794b8d7 Thomas Thrainer
  def testNicparamsMissingIp(self):
657 a794b8d7 Thomas Thrainer
    nicparams = {
658 a794b8d7 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_ROUTED
659 a794b8d7 Thomas Thrainer
    }
660 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance()
661 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
662 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "routed NIC with no ip address")
663 a794b8d7 Thomas Thrainer
664 a794b8d7 Thomas Thrainer
  def testNicparamsWithInstance(self):
665 a794b8d7 Thomas Thrainer
    nicparams = {
666 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
667 a794b8d7 Thomas Thrainer
    }
668 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance()
669 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
670 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
671 a794b8d7 Thomas Thrainer
672 a794b8d7 Thomas Thrainer
  def testDefaultHvparams(self):
673 a794b8d7 Thomas Thrainer
    hvparams = constants.HVC_DEFAULTS
674 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hvparams=hvparams)
675 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
676 a794b8d7 Thomas Thrainer
677 a794b8d7 Thomas Thrainer
    self.assertEqual(hvparams, self.cluster.hvparams)
678 a794b8d7 Thomas Thrainer
679 a794b8d7 Thomas Thrainer
  def testMinimalHvparams(self):
680 a794b8d7 Thomas Thrainer
    hvparams = {
681 a794b8d7 Thomas Thrainer
      constants.HT_FAKE: {
682 a794b8d7 Thomas Thrainer
        constants.HV_MIGRATION_MODE: constants.HT_MIGRATION_NONLIVE
683 a794b8d7 Thomas Thrainer
      }
684 a794b8d7 Thomas Thrainer
    }
685 a794b8d7 Thomas Thrainer
    self.cluster.hvparams = {}
686 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hvparams=hvparams)
687 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
688 a794b8d7 Thomas Thrainer
689 a794b8d7 Thomas Thrainer
    self.assertEqual(hvparams, self.cluster.hvparams)
690 a794b8d7 Thomas Thrainer
691 a794b8d7 Thomas Thrainer
  def testOsHvp(self):
692 a794b8d7 Thomas Thrainer
    os_hvp = {
693 a794b8d7 Thomas Thrainer
      "mocked_os": {
694 a794b8d7 Thomas Thrainer
        constants.HT_FAKE: {
695 a794b8d7 Thomas Thrainer
          constants.HV_MIGRATION_MODE: constants.HT_MIGRATION_NONLIVE
696 a794b8d7 Thomas Thrainer
        }
697 a794b8d7 Thomas Thrainer
      },
698 a794b8d7 Thomas Thrainer
      "other_os": constants.HVC_DEFAULTS
699 a794b8d7 Thomas Thrainer
    }
700 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
701 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
702 a794b8d7 Thomas Thrainer
703 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HT_MIGRATION_NONLIVE,
704 a794b8d7 Thomas Thrainer
                     self.cluster.os_hvp["mocked_os"][constants.HT_FAKE]
705 a794b8d7 Thomas Thrainer
                       [constants.HV_MIGRATION_MODE])
706 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HVC_DEFAULTS, self.cluster.os_hvp["other_os"])
707 a794b8d7 Thomas Thrainer
708 a794b8d7 Thomas Thrainer
  def testRemoveOsHvp(self):
709 a794b8d7 Thomas Thrainer
    os_hvp = {"mocked_os": {constants.HT_FAKE: None}}
710 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
711 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
712 a794b8d7 Thomas Thrainer
713 a794b8d7 Thomas Thrainer
    assert constants.HT_FAKE not in self.cluster.os_hvp["mocked_os"]
714 a794b8d7 Thomas Thrainer
715 a794b8d7 Thomas Thrainer
  def testDefaultOsHvp(self):
716 a794b8d7 Thomas Thrainer
    os_hvp = {"mocked_os": constants.HVC_DEFAULTS.copy()}
717 a794b8d7 Thomas Thrainer
    self.cluster.os_hvp = {"mocked_os": {}}
718 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
719 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
720 a794b8d7 Thomas Thrainer
721 a794b8d7 Thomas Thrainer
    self.assertEqual(os_hvp, self.cluster.os_hvp)
722 a794b8d7 Thomas Thrainer
723 a794b8d7 Thomas Thrainer
  def testOsparams(self):
724 a794b8d7 Thomas Thrainer
    osparams = {
725 a794b8d7 Thomas Thrainer
      "mocked_os": {
726 a794b8d7 Thomas Thrainer
        "param1": "value1",
727 a794b8d7 Thomas Thrainer
        "param2": None
728 a794b8d7 Thomas Thrainer
      },
729 a794b8d7 Thomas Thrainer
      "other_os": {
730 a794b8d7 Thomas Thrainer
        "param1": None
731 a794b8d7 Thomas Thrainer
      }
732 a794b8d7 Thomas Thrainer
    }
733 a794b8d7 Thomas Thrainer
    self.cluster.osparams = {"other_os": {"param1": "value1"}}
734 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(osparams=osparams)
735 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
736 a794b8d7 Thomas Thrainer
737 a794b8d7 Thomas Thrainer
    self.assertEqual({"mocked_os": {"param1": "value1"}}, self.cluster.osparams)
738 a794b8d7 Thomas Thrainer
739 a794b8d7 Thomas Thrainer
  def testEnabledHypervisors(self):
740 a794b8d7 Thomas Thrainer
    enabled_hypervisors = [constants.HT_XEN_HVM, constants.HT_XEN_PVM]
741 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(enabled_hypervisors=enabled_hypervisors)
742 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
743 a794b8d7 Thomas Thrainer
744 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_hypervisors, self.cluster.enabled_hypervisors)
745 a794b8d7 Thomas Thrainer
746 a794b8d7 Thomas Thrainer
  def testEnabledHypervisorsWithoutHypervisorParams(self):
747 a794b8d7 Thomas Thrainer
    enabled_hypervisors = [constants.HT_FAKE]
748 a794b8d7 Thomas Thrainer
    self.cluster.hvparams = {}
749 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(enabled_hypervisors=enabled_hypervisors)
750 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
751 a794b8d7 Thomas Thrainer
752 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_hypervisors, self.cluster.enabled_hypervisors)
753 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HVC_DEFAULTS[constants.HT_FAKE],
754 a794b8d7 Thomas Thrainer
                     self.cluster.hvparams[constants.HT_FAKE])
755 a794b8d7 Thomas Thrainer
756 a794b8d7 Thomas Thrainer
  @testutils.patch_object(utils, "FindFile")
757 a794b8d7 Thomas Thrainer
  def testValidDefaultIallocator(self, find_file_mock):
758 a794b8d7 Thomas Thrainer
    find_file_mock.return_value = "/random/path"
759 a794b8d7 Thomas Thrainer
    default_iallocator = "/random/path"
760 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(default_iallocator=default_iallocator)
761 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
762 a794b8d7 Thomas Thrainer
763 a794b8d7 Thomas Thrainer
    self.assertEqual(default_iallocator, self.cluster.default_iallocator)
764 a794b8d7 Thomas Thrainer
765 a794b8d7 Thomas Thrainer
  @testutils.patch_object(utils, "FindFile")
766 a794b8d7 Thomas Thrainer
  def testInvalidDefaultIallocator(self, find_file_mock):
767 a794b8d7 Thomas Thrainer
    find_file_mock.return_value = None
768 a794b8d7 Thomas Thrainer
    default_iallocator = "/random/path"
769 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(default_iallocator=default_iallocator)
770 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Invalid default iallocator script")
771 a794b8d7 Thomas Thrainer
772 a794b8d7 Thomas Thrainer
  def testEnabledDiskTemplates(self):
773 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_DISKLESS, constants.DT_PLAIN]
774 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
775 1583d0e4 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates,
776 1583d0e4 Thomas Thrainer
           ipolicy={constants.IPOLICY_DTS: enabled_disk_templates})
777 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
778 a794b8d7 Thomas Thrainer
779 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_disk_templates,
780 a794b8d7 Thomas Thrainer
                     self.cluster.enabled_disk_templates)
781 a794b8d7 Thomas Thrainer
782 a794b8d7 Thomas Thrainer
  def testEnabledDiskTemplatesWithoutVgName(self):
783 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_PLAIN]
784 a794b8d7 Thomas Thrainer
    self.cluster.volume_group_name = None
785 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
786 a794b8d7 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates)
787 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "specify a volume group")
788 a794b8d7 Thomas Thrainer
789 a794b8d7 Thomas Thrainer
  def testDisableDiskTemplateWithExistingInstance(self):
790 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_DISKLESS]
791 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(
792 a794b8d7 Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.LD_LV)])
793 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
794 1583d0e4 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates,
795 1583d0e4 Thomas Thrainer
           ipolicy={constants.IPOLICY_DTS: enabled_disk_templates})
796 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable disk template")
797 a794b8d7 Thomas Thrainer
798 a794b8d7 Thomas Thrainer
  def testVgNameNoLvmDiskTemplateEnabled(self):
799 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
800 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
801 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
802 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
803 a794b8d7 Thomas Thrainer
804 a794b8d7 Thomas Thrainer
    self.assertEqual(vg_name, self.cluster.volume_group_name)
805 1583d0e4 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
806 a794b8d7 Thomas Thrainer
807 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithLvmDiskTemplateEnabled(self):
808 a794b8d7 Thomas Thrainer
    vg_name = ""
809 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_PLAIN]
810 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
811 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot unset volume group")
812 a794b8d7 Thomas Thrainer
813 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithLvmInstance(self):
814 a794b8d7 Thomas Thrainer
    vg_name = ""
815 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(
816 a794b8d7 Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.LD_LV)])
817 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
818 1583d0e4 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot unset volume group")
819 a794b8d7 Thomas Thrainer
820 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithNoLvmDiskTemplateEnabled(self):
821 a794b8d7 Thomas Thrainer
    vg_name = ""
822 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
823 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
824 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
825 a794b8d7 Thomas Thrainer
826 a794b8d7 Thomas Thrainer
    self.assertEqual(None, self.cluster.volume_group_name)
827 a794b8d7 Thomas Thrainer
828 a794b8d7 Thomas Thrainer
  def testVgNameToOldName(self):
829 a794b8d7 Thomas Thrainer
    vg_name = self.cluster.volume_group_name
830 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
831 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
832 a794b8d7 Thomas Thrainer
833 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("already in desired state")
834 a794b8d7 Thomas Thrainer
835 a794b8d7 Thomas Thrainer
  def testVgNameWithFailingNode(self):
836 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
837 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
838 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
839 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
840 a794b8d7 Thomas Thrainer
        .AddFailedNode(self.master) \
841 a794b8d7 Thomas Thrainer
        .Build()
842 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
843 a794b8d7 Thomas Thrainer
844 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Error while gathering data on node")
845 a794b8d7 Thomas Thrainer
846 a794b8d7 Thomas Thrainer
  def testVgNameWithValidNode(self):
847 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
848 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
849 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
850 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
851 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, {vg_name: 1024 * 1024}) \
852 a794b8d7 Thomas Thrainer
        .Build()
853 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
854 a794b8d7 Thomas Thrainer
855 a794b8d7 Thomas Thrainer
  def testVgNameWithTooSmallNode(self):
856 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
857 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
858 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
859 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
860 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, {vg_name: 1}) \
861 a794b8d7 Thomas Thrainer
        .Build()
862 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "too small")
863 a794b8d7 Thomas Thrainer
864 a794b8d7 Thomas Thrainer
  def testMiscParameters(self):
865 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(candidate_pool_size=123,
866 a794b8d7 Thomas Thrainer
                                    maintain_node_health=True,
867 a794b8d7 Thomas Thrainer
                                    modify_etc_hosts=True,
868 a794b8d7 Thomas Thrainer
                                    prealloc_wipe_disks=True,
869 a794b8d7 Thomas Thrainer
                                    reserved_lvs=["/dev/mock_lv"],
870 a794b8d7 Thomas Thrainer
                                    use_external_mip_script=True)
871 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
872 a794b8d7 Thomas Thrainer
873 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
874 a794b8d7 Thomas Thrainer
    self.assertEqual(123, self.cluster.candidate_pool_size)
875 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.maintain_node_health)
876 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.modify_etc_hosts)
877 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.prealloc_wipe_disks)
878 a794b8d7 Thomas Thrainer
    self.assertEqual(["/dev/mock_lv"], self.cluster.reserved_lvs)
879 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.use_external_mip_script)
880 a794b8d7 Thomas Thrainer
881 a794b8d7 Thomas Thrainer
  def testAddHiddenOs(self):
882 a794b8d7 Thomas Thrainer
    self.cluster.hidden_os = ["hidden1", "hidden2"]
883 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hidden_os=[(constants.DDM_ADD, "hidden2"),
884 a794b8d7 Thomas Thrainer
                                               (constants.DDM_ADD, "hidden3")])
885 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
886 a794b8d7 Thomas Thrainer
887 a794b8d7 Thomas Thrainer
    self.assertEqual(["hidden1", "hidden2", "hidden3"], self.cluster.hidden_os)
888 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("OS hidden2 already")
889 a794b8d7 Thomas Thrainer
890 a794b8d7 Thomas Thrainer
  def testRemoveBlacklistedOs(self):
891 a794b8d7 Thomas Thrainer
    self.cluster.blacklisted_os = ["blisted1", "blisted2"]
892 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(blacklisted_os=[
893 a794b8d7 Thomas Thrainer
                                      (constants.DDM_REMOVE, "blisted2"),
894 a794b8d7 Thomas Thrainer
                                      (constants.DDM_REMOVE, "blisted3")])
895 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
896 a794b8d7 Thomas Thrainer
897 a794b8d7 Thomas Thrainer
    self.assertEqual(["blisted1"], self.cluster.blacklisted_os)
898 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("OS blisted3 not found")
899 a794b8d7 Thomas Thrainer
900 a794b8d7 Thomas Thrainer
  def testMasterNetdev(self):
901 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
902 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev)
903 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
904 a794b8d7 Thomas Thrainer
905 a794b8d7 Thomas Thrainer
    self.assertEqual(master_netdev, self.cluster.master_netdev)
906 a794b8d7 Thomas Thrainer
907 a794b8d7 Thomas Thrainer
  def testMasterNetdevFailNoForce(self):
908 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
909 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev)
910 a794b8d7 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
911 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
912 a794b8d7 Thomas Thrainer
        .CreateFailedNodeResult(self.master)
913 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op, "Could not disable the master ip")
914 a794b8d7 Thomas Thrainer
915 a794b8d7 Thomas Thrainer
  def testMasterNetdevFailForce(self):
916 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
917 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev,
918 a794b8d7 Thomas Thrainer
                                    force=True)
919 a794b8d7 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
920 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
921 a794b8d7 Thomas Thrainer
        .CreateFailedNodeResult(self.master)
922 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
923 a794b8d7 Thomas Thrainer
924 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Could not disable the master ip")
925 a794b8d7 Thomas Thrainer
926 a794b8d7 Thomas Thrainer
927 c60f7675 Thomas Thrainer
class TestLUClusterVerify(CmdlibTestCase):
928 c60f7675 Thomas Thrainer
  def testVerifyAllGroups(self):
929 c60f7675 Thomas Thrainer
    op = opcodes.OpClusterVerify()
930 c60f7675 Thomas Thrainer
    result = self.ExecOpCode(op)
931 c60f7675 Thomas Thrainer
932 c60f7675 Thomas Thrainer
    self.assertEqual(2, len(result["jobs"]))
933 c60f7675 Thomas Thrainer
934 c60f7675 Thomas Thrainer
  def testVerifyDefaultGroups(self):
935 c60f7675 Thomas Thrainer
    op = opcodes.OpClusterVerify(group_name="default")
936 c60f7675 Thomas Thrainer
    result = self.ExecOpCode(op)
937 c60f7675 Thomas Thrainer
938 c60f7675 Thomas Thrainer
    self.assertEqual(1, len(result["jobs"]))
939 c60f7675 Thomas Thrainer
940 850be460 Thomas Thrainer
941 850be460 Thomas Thrainer
class TestLUClusterVerifyConfig(CmdlibTestCase):
942 850be460 Thomas Thrainer
943 850be460 Thomas Thrainer
  def setUp(self):
944 850be460 Thomas Thrainer
    super(TestLUClusterVerifyConfig, self).setUp()
945 850be460 Thomas Thrainer
946 850be460 Thomas Thrainer
    self._load_cert_patcher = testutils \
947 850be460 Thomas Thrainer
      .patch_object(OpenSSL.crypto, "load_certificate")
948 850be460 Thomas Thrainer
    self._load_cert_mock = self._load_cert_patcher.start()
949 850be460 Thomas Thrainer
    self._verify_cert_patcher = testutils \
950 850be460 Thomas Thrainer
      .patch_object(utils, "VerifyX509Certificate")
951 850be460 Thomas Thrainer
    self._verify_cert_mock = self._verify_cert_patcher.start()
952 850be460 Thomas Thrainer
    self._read_file_patcher = testutils.patch_object(utils, "ReadFile")
953 850be460 Thomas Thrainer
    self._read_file_mock = self._read_file_patcher.start()
954 850be460 Thomas Thrainer
    self._can_read_patcher = testutils.patch_object(utils, "CanRead")
955 850be460 Thomas Thrainer
    self._can_read_mock = self._can_read_patcher.start()
956 850be460 Thomas Thrainer
957 850be460 Thomas Thrainer
    self._can_read_mock.return_value = True
958 850be460 Thomas Thrainer
    self._read_file_mock.return_value = True
959 850be460 Thomas Thrainer
    self._verify_cert_mock.return_value = (None, "")
960 850be460 Thomas Thrainer
    self._load_cert_mock.return_value = True
961 850be460 Thomas Thrainer
962 850be460 Thomas Thrainer
  def tearDown(self):
963 850be460 Thomas Thrainer
    super(TestLUClusterVerifyConfig, self).tearDown()
964 850be460 Thomas Thrainer
965 850be460 Thomas Thrainer
    self._can_read_patcher.stop()
966 850be460 Thomas Thrainer
    self._read_file_patcher.stop()
967 850be460 Thomas Thrainer
    self._verify_cert_patcher.stop()
968 850be460 Thomas Thrainer
    self._load_cert_patcher.stop()
969 850be460 Thomas Thrainer
970 850be460 Thomas Thrainer
  def testSuccessfulRun(self):
971 850be460 Thomas Thrainer
    self.cfg.AddNewInstance()
972 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
973 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
974 850be460 Thomas Thrainer
975 850be460 Thomas Thrainer
    self.assertTrue(result)
976 850be460 Thomas Thrainer
977 850be460 Thomas Thrainer
  def testDanglingNode(self):
978 850be460 Thomas Thrainer
    node = self.cfg.AddNewNode()
979 850be460 Thomas Thrainer
    self.cfg.AddNewInstance(primary_node=node)
980 850be460 Thomas Thrainer
    node.group = "invalid"
981 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
982 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
983 850be460 Thomas Thrainer
984 850be460 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
985 850be460 Thomas Thrainer
      "following nodes \(and their instances\) belong to a non existing group")
986 850be460 Thomas Thrainer
    self.assertFalse(result)
987 850be460 Thomas Thrainer
988 850be460 Thomas Thrainer
  def testDanglingInstance(self):
989 850be460 Thomas Thrainer
    inst = self.cfg.AddNewInstance()
990 850be460 Thomas Thrainer
    inst.primary_node = "invalid"
991 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
992 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
993 850be460 Thomas Thrainer
994 850be460 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
995 850be460 Thomas Thrainer
      "following instances have a non-existing primary-node")
996 850be460 Thomas Thrainer
    self.assertFalse(result)
997 850be460 Thomas Thrainer
998 850be460 Thomas Thrainer
999 b8f45292 Thomas Thrainer
class TestLUClusterVerifyGroup(CmdlibTestCase):
1000 b8f45292 Thomas Thrainer
  def testEmptyNodeGroup(self):
1001 b8f45292 Thomas Thrainer
    group = self.cfg.AddNewNodeGroup()
1002 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name=group.name, verbose=True)
1003 b8f45292 Thomas Thrainer
1004 b8f45292 Thomas Thrainer
    result = self.ExecOpCode(op)
1005 b8f45292 Thomas Thrainer
1006 b8f45292 Thomas Thrainer
    self.assertTrue(result)
1007 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Empty node group, skipping verification")
1008 b8f45292 Thomas Thrainer
1009 b8f45292 Thomas Thrainer
  def testSimpleInvocation(self):
1010 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1011 9fdb10be Thomas Thrainer
1012 9fdb10be Thomas Thrainer
    self.ExecOpCode(op)
1013 9fdb10be Thomas Thrainer
1014 9fdb10be Thomas Thrainer
  def testSimpleInvocationWithInstance(self):
1015 9fdb10be Thomas Thrainer
    self.cfg.AddNewInstance(disks=[])
1016 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1017 9fdb10be Thomas Thrainer
1018 9fdb10be Thomas Thrainer
    self.ExecOpCode(op)
1019 9fdb10be Thomas Thrainer
1020 9fdb10be Thomas Thrainer
  def testGhostNode(self):
1021 9fdb10be Thomas Thrainer
    group = self.cfg.AddNewNodeGroup()
1022 9fdb10be Thomas Thrainer
    node = self.cfg.AddNewNode(group=group.uuid, offline=True)
1023 9fdb10be Thomas Thrainer
    self.master.offline = True
1024 9fdb10be Thomas Thrainer
    self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
1025 9fdb10be Thomas Thrainer
                            primary_node=self.master,
1026 9fdb10be Thomas Thrainer
                            secondary_node=node)
1027 9fdb10be Thomas Thrainer
1028 9fdb10be Thomas Thrainer
    self.rpc.call_blockdev_getmirrorstatus_multi.return_value = \
1029 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
1030 9fdb10be Thomas Thrainer
        .AddOfflineNode(self.master) \
1031 9fdb10be Thomas Thrainer
        .Build()
1032 9fdb10be Thomas Thrainer
1033 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1034 9fdb10be Thomas Thrainer
1035 9fdb10be Thomas Thrainer
    self.ExecOpCode(op)
1036 9fdb10be Thomas Thrainer
1037 9fdb10be Thomas Thrainer
  def testValidRpcResult(self):
1038 9fdb10be Thomas Thrainer
    self.cfg.AddNewInstance(disks=[])
1039 9fdb10be Thomas Thrainer
1040 9fdb10be Thomas Thrainer
    self.rpc.call_node_verify.return_value = \
1041 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
1042 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.master, {}) \
1043 9fdb10be Thomas Thrainer
        .Build()
1044 9fdb10be Thomas Thrainer
1045 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1046 b8f45292 Thomas Thrainer
1047 b8f45292 Thomas Thrainer
    self.ExecOpCode(op)
1048 b8f45292 Thomas Thrainer
1049 b8f45292 Thomas Thrainer
1050 b8f45292 Thomas Thrainer
class TestLUClusterVerifyGroupMethods(CmdlibTestCase):
1051 b8f45292 Thomas Thrainer
  """Base class for testing individual methods in LUClusterVerifyGroup.
1052 b8f45292 Thomas Thrainer

1053 b8f45292 Thomas Thrainer
  """
1054 b8f45292 Thomas Thrainer
  def setUp(self):
1055 b8f45292 Thomas Thrainer
    super(TestLUClusterVerifyGroupMethods, self).setUp()
1056 b8f45292 Thomas Thrainer
    self.op = opcodes.OpClusterVerifyGroup(group_name="default")
1057 b8f45292 Thomas Thrainer
1058 9fdb10be Thomas Thrainer
  def PrepareLU(self, lu):
1059 9fdb10be Thomas Thrainer
    lu._exclusive_storage = False
1060 9fdb10be Thomas Thrainer
    lu.master_node = self.master_uuid
1061 9fdb10be Thomas Thrainer
    lu.group_info = self.group
1062 9fdb10be Thomas Thrainer
    cluster.LUClusterVerifyGroup.all_node_info = \
1063 9fdb10be Thomas Thrainer
      property(fget=lambda _: self.cfg.GetAllNodesInfo())
1064 9fdb10be Thomas Thrainer
1065 b8f45292 Thomas Thrainer
1066 b8f45292 Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNode(TestLUClusterVerifyGroupMethods):
1067 b8f45292 Thomas Thrainer
  @withLockedLU
1068 b8f45292 Thomas Thrainer
  def testInvalidNodeResult(self, lu):
1069 b8f45292 Thomas Thrainer
    self.assertFalse(lu._VerifyNode(self.master, None))
1070 b8f45292 Thomas Thrainer
    self.assertFalse(lu._VerifyNode(self.master, ""))
1071 b8f45292 Thomas Thrainer
1072 b8f45292 Thomas Thrainer
  @withLockedLU
1073 b8f45292 Thomas Thrainer
  def testInvalidVersion(self, lu):
1074 b8f45292 Thomas Thrainer
    self.assertFalse(lu._VerifyNode(self.master, {"version": None}))
1075 b8f45292 Thomas Thrainer
    self.assertFalse(lu._VerifyNode(self.master, {"version": ""}))
1076 b8f45292 Thomas Thrainer
    self.assertFalse(lu._VerifyNode(self.master, {
1077 b8f45292 Thomas Thrainer
      "version": (constants.PROTOCOL_VERSION - 1, constants.RELEASE_VERSION)
1078 b8f45292 Thomas Thrainer
    }))
1079 b8f45292 Thomas Thrainer
1080 b8f45292 Thomas Thrainer
    self.mcpu.ClearLogMessages()
1081 b8f45292 Thomas Thrainer
    self.assertTrue(lu._VerifyNode(self.master, {
1082 b8f45292 Thomas Thrainer
      "version": (constants.PROTOCOL_VERSION, constants.RELEASE_VERSION + "x")
1083 b8f45292 Thomas Thrainer
    }))
1084 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("software version mismatch")
1085 b8f45292 Thomas Thrainer
1086 b8f45292 Thomas Thrainer
  def _GetValidNodeResult(self, additional_fields):
1087 b8f45292 Thomas Thrainer
    ret = {
1088 b8f45292 Thomas Thrainer
      "version": (constants.PROTOCOL_VERSION, constants.RELEASE_VERSION),
1089 b8f45292 Thomas Thrainer
      constants.NV_NODESETUP: []
1090 b8f45292 Thomas Thrainer
    }
1091 b8f45292 Thomas Thrainer
    ret.update(additional_fields)
1092 b8f45292 Thomas Thrainer
    return ret
1093 b8f45292 Thomas Thrainer
1094 b8f45292 Thomas Thrainer
  @withLockedLU
1095 b8f45292 Thomas Thrainer
  def testHypervisor(self, lu):
1096 b8f45292 Thomas Thrainer
    lu._VerifyNode(self.master, self._GetValidNodeResult({
1097 b8f45292 Thomas Thrainer
      constants.NV_HYPERVISOR: {
1098 b8f45292 Thomas Thrainer
        constants.HT_XEN_PVM: None,
1099 b8f45292 Thomas Thrainer
        constants.HT_XEN_HVM: "mock error"
1100 b8f45292 Thomas Thrainer
      }
1101 b8f45292 Thomas Thrainer
    }))
1102 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(constants.HT_XEN_HVM)
1103 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("mock error")
1104 b8f45292 Thomas Thrainer
1105 b8f45292 Thomas Thrainer
  @withLockedLU
1106 b8f45292 Thomas Thrainer
  def testHvParams(self, lu):
1107 b8f45292 Thomas Thrainer
    lu._VerifyNode(self.master, self._GetValidNodeResult({
1108 b8f45292 Thomas Thrainer
      constants.NV_HVPARAMS: [("mock item", constants.HT_XEN_HVM, "mock error")]
1109 b8f45292 Thomas Thrainer
    }))
1110 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(constants.HT_XEN_HVM)
1111 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("mock item")
1112 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("mock error")
1113 b8f45292 Thomas Thrainer
1114 b8f45292 Thomas Thrainer
  @withLockedLU
1115 b8f45292 Thomas Thrainer
  def testSuccessfulResult(self, lu):
1116 b8f45292 Thomas Thrainer
    self.assertTrue(lu._VerifyNode(self.master, self._GetValidNodeResult({})))
1117 b8f45292 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1118 b8f45292 Thomas Thrainer
1119 b8f45292 Thomas Thrainer
1120 b8f45292 Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNodeTime(TestLUClusterVerifyGroupMethods):
1121 b8f45292 Thomas Thrainer
  @withLockedLU
1122 b8f45292 Thomas Thrainer
  def testInvalidNodeResult(self, lu):
1123 b8f45292 Thomas Thrainer
    for ndata in [{}, {constants.NV_TIME: "invalid"}]:
1124 b8f45292 Thomas Thrainer
      self.mcpu.ClearLogMessages()
1125 b8f45292 Thomas Thrainer
      lu._VerifyNodeTime(self.master, ndata, None, None)
1126 b8f45292 Thomas Thrainer
1127 b8f45292 Thomas Thrainer
      self.mcpu.assertLogContainsRegex("Node returned invalid time")
1128 b8f45292 Thomas Thrainer
1129 b8f45292 Thomas Thrainer
  @withLockedLU
1130 b8f45292 Thomas Thrainer
  def testNodeDiverges(self, lu):
1131 b8f45292 Thomas Thrainer
    for ntime in [(0, 0), (2000, 0)]:
1132 b8f45292 Thomas Thrainer
      self.mcpu.ClearLogMessages()
1133 b8f45292 Thomas Thrainer
      lu._VerifyNodeTime(self.master, {constants.NV_TIME: ntime}, 1000, 1005)
1134 b8f45292 Thomas Thrainer
1135 b8f45292 Thomas Thrainer
      self.mcpu.assertLogContainsRegex("Node time diverges")
1136 b8f45292 Thomas Thrainer
1137 b8f45292 Thomas Thrainer
  @withLockedLU
1138 b8f45292 Thomas Thrainer
  def testSuccessfulResult(self, lu):
1139 b8f45292 Thomas Thrainer
    lu._VerifyNodeTime(self.master, {constants.NV_TIME: (0, 0)}, 0, 5)
1140 b8f45292 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1141 b8f45292 Thomas Thrainer
1142 9fdb10be Thomas Thrainer
1143 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupUpdateVerifyNodeLVM(
1144 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1145 9fdb10be Thomas Thrainer
  def setUp(self):
1146 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupUpdateVerifyNodeLVM, self).setUp()
1147 9fdb10be Thomas Thrainer
    self.VALID_NRESULT = {
1148 9fdb10be Thomas Thrainer
      constants.NV_VGLIST: {"mock_vg": 30000},
1149 9fdb10be Thomas Thrainer
      constants.NV_PVLIST: [
1150 9fdb10be Thomas Thrainer
        {
1151 9fdb10be Thomas Thrainer
          "name": "mock_pv",
1152 9fdb10be Thomas Thrainer
          "vg_name": "mock_vg",
1153 9fdb10be Thomas Thrainer
          "size": 5000,
1154 9fdb10be Thomas Thrainer
          "free": 2500,
1155 9fdb10be Thomas Thrainer
          "attributes": [],
1156 9fdb10be Thomas Thrainer
          "lv_list": []
1157 9fdb10be Thomas Thrainer
        }
1158 9fdb10be Thomas Thrainer
      ]
1159 9fdb10be Thomas Thrainer
    }
1160 9fdb10be Thomas Thrainer
1161 9fdb10be Thomas Thrainer
  @withLockedLU
1162 9fdb10be Thomas Thrainer
  def testNoVgName(self, lu):
1163 9fdb10be Thomas Thrainer
    lu._UpdateVerifyNodeLVM(self.master, {}, None, None)
1164 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1165 9fdb10be Thomas Thrainer
1166 9fdb10be Thomas Thrainer
  @withLockedLU
1167 9fdb10be Thomas Thrainer
  def testEmptyNodeResult(self, lu):
1168 9fdb10be Thomas Thrainer
    lu._UpdateVerifyNodeLVM(self.master, {}, "mock_vg", None)
1169 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("unable to check volume groups")
1170 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Can't get PV list from node")
1171 9fdb10be Thomas Thrainer
1172 9fdb10be Thomas Thrainer
  @withLockedLU
1173 9fdb10be Thomas Thrainer
  def testValidNodeResult(self, lu):
1174 9fdb10be Thomas Thrainer
    lu._UpdateVerifyNodeLVM(self.master, self.VALID_NRESULT, "mock_vg", None)
1175 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1176 9fdb10be Thomas Thrainer
1177 9fdb10be Thomas Thrainer
  @withLockedLU
1178 9fdb10be Thomas Thrainer
  def testValidNodeResultExclusiveStorage(self, lu):
1179 9fdb10be Thomas Thrainer
    lu._exclusive_storage = True
1180 9fdb10be Thomas Thrainer
    lu._UpdateVerifyNodeLVM(self.master, self.VALID_NRESULT, "mock_vg",
1181 9fdb10be Thomas Thrainer
                            cluster.LUClusterVerifyGroup.NodeImage())
1182 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1183 9fdb10be Thomas Thrainer
1184 9fdb10be Thomas Thrainer
1185 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyGroupDRBDVersion(
1186 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1187 9fdb10be Thomas Thrainer
  @withLockedLU
1188 9fdb10be Thomas Thrainer
  def testEmptyNodeResult(self, lu):
1189 9fdb10be Thomas Thrainer
    lu._VerifyGroupDRBDVersion({})
1190 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1191 9fdb10be Thomas Thrainer
1192 9fdb10be Thomas Thrainer
  @withLockedLU
1193 9fdb10be Thomas Thrainer
  def testValidNodeResult(self, lu):
1194 9fdb10be Thomas Thrainer
    lu._VerifyGroupDRBDVersion(
1195 9fdb10be Thomas Thrainer
      RpcResultsBuilder()
1196 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.master, {
1197 9fdb10be Thomas Thrainer
          constants.NV_DRBDVERSION: "8.3.0"
1198 9fdb10be Thomas Thrainer
        })
1199 9fdb10be Thomas Thrainer
        .Build())
1200 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1201 9fdb10be Thomas Thrainer
1202 9fdb10be Thomas Thrainer
  @withLockedLU
1203 9fdb10be Thomas Thrainer
  def testDifferentVersions(self, lu):
1204 9fdb10be Thomas Thrainer
    node1 = self.cfg.AddNewNode()
1205 9fdb10be Thomas Thrainer
    lu._VerifyGroupDRBDVersion(
1206 9fdb10be Thomas Thrainer
      RpcResultsBuilder()
1207 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.master, {
1208 9fdb10be Thomas Thrainer
          constants.NV_DRBDVERSION: "8.3.0"
1209 9fdb10be Thomas Thrainer
        })
1210 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(node1, {
1211 9fdb10be Thomas Thrainer
          constants.NV_DRBDVERSION: "8.4.0"
1212 9fdb10be Thomas Thrainer
        })
1213 9fdb10be Thomas Thrainer
        .Build())
1214 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("DRBD version mismatch: 8.3.0")
1215 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("DRBD version mismatch: 8.4.0")
1216 9fdb10be Thomas Thrainer
1217 9fdb10be Thomas Thrainer
1218 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyGroupLVM(TestLUClusterVerifyGroupMethods):
1219 9fdb10be Thomas Thrainer
  @withLockedLU
1220 9fdb10be Thomas Thrainer
  def testNoVgName(self, lu):
1221 9fdb10be Thomas Thrainer
    lu._VerifyGroupLVM(None, None)
1222 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1223 9fdb10be Thomas Thrainer
1224 9fdb10be Thomas Thrainer
  @withLockedLU
1225 9fdb10be Thomas Thrainer
  def testNoExclusiveStorage(self, lu):
1226 9fdb10be Thomas Thrainer
    lu._VerifyGroupLVM(None, "mock_vg")
1227 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1228 9fdb10be Thomas Thrainer
1229 9fdb10be Thomas Thrainer
  @withLockedLU
1230 9fdb10be Thomas Thrainer
  def testNoPvInfo(self, lu):
1231 9fdb10be Thomas Thrainer
    lu._exclusive_storage = True
1232 9fdb10be Thomas Thrainer
    nimg = cluster.LUClusterVerifyGroup.NodeImage()
1233 9fdb10be Thomas Thrainer
    lu._VerifyGroupLVM({self.master.uuid: nimg}, "mock_vg")
1234 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1235 9fdb10be Thomas Thrainer
1236 9fdb10be Thomas Thrainer
  @withLockedLU
1237 9fdb10be Thomas Thrainer
  def testValidPvInfos(self, lu):
1238 9fdb10be Thomas Thrainer
    lu._exclusive_storage = True
1239 9fdb10be Thomas Thrainer
    node2 = self.cfg.AddNewNode()
1240 9fdb10be Thomas Thrainer
    nimg1 = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master.uuid)
1241 9fdb10be Thomas Thrainer
    nimg1.pv_min = 10000
1242 9fdb10be Thomas Thrainer
    nimg1.pv_max = 10010
1243 9fdb10be Thomas Thrainer
    nimg2 = cluster.LUClusterVerifyGroup.NodeImage(uuid=node2.uuid)
1244 9fdb10be Thomas Thrainer
    nimg2.pv_min = 9998
1245 9fdb10be Thomas Thrainer
    nimg2.pv_max = 10005
1246 9fdb10be Thomas Thrainer
    lu._VerifyGroupLVM({self.master.uuid: nimg1, node2.uuid: nimg2}, "mock_vg")
1247 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1248 9fdb10be Thomas Thrainer
1249 9fdb10be Thomas Thrainer
1250 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNodeBridges(
1251 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1252 9fdb10be Thomas Thrainer
  @withLockedLU
1253 9fdb10be Thomas Thrainer
  def testNoBridges(self, lu):
1254 9fdb10be Thomas Thrainer
    lu._VerifyNodeBridges(None, None, None)
1255 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1256 9fdb10be Thomas Thrainer
1257 9fdb10be Thomas Thrainer
  @withLockedLU
1258 9fdb10be Thomas Thrainer
  def testInvalidBridges(self, lu):
1259 9fdb10be Thomas Thrainer
    for ndata in [{}, {constants.NV_BRIDGES: ""}]:
1260 9fdb10be Thomas Thrainer
      self.mcpu.ClearLogMessages()
1261 9fdb10be Thomas Thrainer
      lu._VerifyNodeBridges(self.master, ndata, ["mock_bridge"])
1262 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsRegex("not return valid bridge information")
1263 9fdb10be Thomas Thrainer
1264 9fdb10be Thomas Thrainer
    self.mcpu.ClearLogMessages()
1265 9fdb10be Thomas Thrainer
    lu._VerifyNodeBridges(self.master, {constants.NV_BRIDGES: ["mock_bridge"]},
1266 9fdb10be Thomas Thrainer
                          ["mock_bridge"])
1267 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("missing bridge")
1268 9fdb10be Thomas Thrainer
1269 9fdb10be Thomas Thrainer
1270 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNodeUserScripts(
1271 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1272 9fdb10be Thomas Thrainer
  @withLockedLU
1273 9fdb10be Thomas Thrainer
  def testNoUserScripts(self, lu):
1274 9fdb10be Thomas Thrainer
    lu._VerifyNodeUserScripts(self.master, {})
1275 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("did not return user scripts information")
1276 9fdb10be Thomas Thrainer
1277 9fdb10be Thomas Thrainer
  @withLockedLU
1278 9fdb10be Thomas Thrainer
  def testBrokenUserScripts(self, lu):
1279 9fdb10be Thomas Thrainer
    lu._VerifyNodeUserScripts(self.master,
1280 9fdb10be Thomas Thrainer
                              {constants.NV_USERSCRIPTS: ["script"]})
1281 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("scripts not present or not executable")
1282 9fdb10be Thomas Thrainer
1283 9fdb10be Thomas Thrainer
1284 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNodeNetwork(
1285 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1286 9fdb10be Thomas Thrainer
1287 9fdb10be Thomas Thrainer
  def setUp(self):
1288 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupVerifyNodeNetwork, self).setUp()
1289 9fdb10be Thomas Thrainer
    self.VALID_NRESULT = {
1290 9fdb10be Thomas Thrainer
      constants.NV_NODELIST: {},
1291 9fdb10be Thomas Thrainer
      constants.NV_NODENETTEST: {},
1292 9fdb10be Thomas Thrainer
      constants.NV_MASTERIP: True
1293 9fdb10be Thomas Thrainer
    }
1294 9fdb10be Thomas Thrainer
1295 9fdb10be Thomas Thrainer
  @withLockedLU
1296 9fdb10be Thomas Thrainer
  def testEmptyNodeResult(self, lu):
1297 9fdb10be Thomas Thrainer
    lu._VerifyNodeNetwork(self.master, {})
1298 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1299 9fdb10be Thomas Thrainer
      "node hasn't returned node ssh connectivity data")
1300 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1301 9fdb10be Thomas Thrainer
      "node hasn't returned node tcp connectivity data")
1302 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1303 9fdb10be Thomas Thrainer
      "node hasn't returned node master IP reachability data")
1304 9fdb10be Thomas Thrainer
1305 9fdb10be Thomas Thrainer
  @withLockedLU
1306 9fdb10be Thomas Thrainer
  def testValidResult(self, lu):
1307 9fdb10be Thomas Thrainer
    lu._VerifyNodeNetwork(self.master, self.VALID_NRESULT)
1308 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1309 9fdb10be Thomas Thrainer
1310 9fdb10be Thomas Thrainer
  @withLockedLU
1311 9fdb10be Thomas Thrainer
  def testSshProblem(self, lu):
1312 9fdb10be Thomas Thrainer
    self.VALID_NRESULT.update({
1313 9fdb10be Thomas Thrainer
      constants.NV_NODELIST: {
1314 9fdb10be Thomas Thrainer
        "mock_node": "mock_error"
1315 9fdb10be Thomas Thrainer
      }
1316 9fdb10be Thomas Thrainer
    })
1317 9fdb10be Thomas Thrainer
    lu._VerifyNodeNetwork(self.master, self.VALID_NRESULT)
1318 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("ssh communication with node 'mock_node'")
1319 9fdb10be Thomas Thrainer
1320 9fdb10be Thomas Thrainer
  @withLockedLU
1321 9fdb10be Thomas Thrainer
  def testTcpProblem(self, lu):
1322 9fdb10be Thomas Thrainer
    self.VALID_NRESULT.update({
1323 9fdb10be Thomas Thrainer
      constants.NV_NODENETTEST: {
1324 9fdb10be Thomas Thrainer
        "mock_node": "mock_error"
1325 9fdb10be Thomas Thrainer
      }
1326 9fdb10be Thomas Thrainer
    })
1327 9fdb10be Thomas Thrainer
    lu._VerifyNodeNetwork(self.master, self.VALID_NRESULT)
1328 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("tcp communication with node 'mock_node'")
1329 9fdb10be Thomas Thrainer
1330 9fdb10be Thomas Thrainer
  @withLockedLU
1331 9fdb10be Thomas Thrainer
  def testMasterIpNotReachable(self, lu):
1332 9fdb10be Thomas Thrainer
    self.VALID_NRESULT.update({
1333 9fdb10be Thomas Thrainer
      constants.NV_MASTERIP: False
1334 9fdb10be Thomas Thrainer
    })
1335 9fdb10be Thomas Thrainer
    node1 = self.cfg.AddNewNode()
1336 9fdb10be Thomas Thrainer
    lu._VerifyNodeNetwork(self.master, self.VALID_NRESULT)
1337 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1338 9fdb10be Thomas Thrainer
      "the master node cannot reach the master IP")
1339 9fdb10be Thomas Thrainer
1340 9fdb10be Thomas Thrainer
    self.mcpu.ClearLogMessages()
1341 9fdb10be Thomas Thrainer
    lu._VerifyNodeNetwork(node1, self.VALID_NRESULT)
1342 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("cannot reach the master IP")
1343 9fdb10be Thomas Thrainer
1344 9fdb10be Thomas Thrainer
1345 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyInstance(TestLUClusterVerifyGroupMethods):
1346 9fdb10be Thomas Thrainer
  def setUp(self):
1347 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupVerifyInstance, self).setUp()
1348 9fdb10be Thomas Thrainer
1349 9fdb10be Thomas Thrainer
    self.node1 = self.cfg.AddNewNode()
1350 9fdb10be Thomas Thrainer
    self.drbd_inst = self.cfg.AddNewInstance(
1351 9fdb10be Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.LD_DRBD8,
1352 9fdb10be Thomas Thrainer
                                 primary_node=self.master,
1353 9fdb10be Thomas Thrainer
                                 secondary_node=self.node1)])
1354 9fdb10be Thomas Thrainer
    self.running_inst = self.cfg.AddNewInstance(
1355 9fdb10be Thomas Thrainer
      admin_state=constants.ADMINST_UP, disks_active=True)
1356 9fdb10be Thomas Thrainer
    self.diskless_inst = self.cfg.AddNewInstance(disks=[])
1357 9fdb10be Thomas Thrainer
1358 9fdb10be Thomas Thrainer
    self.master_img = \
1359 9fdb10be Thomas Thrainer
      cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1360 9fdb10be Thomas Thrainer
    self.master_img.volumes = ["/".join(disk.logical_id)
1361 9fdb10be Thomas Thrainer
                               for inst in [self.running_inst,
1362 9fdb10be Thomas Thrainer
                                            self.diskless_inst]
1363 9fdb10be Thomas Thrainer
                               for disk in inst.disks]
1364 9fdb10be Thomas Thrainer
    self.master_img.volumes.extend(
1365 9fdb10be Thomas Thrainer
      ["/".join(disk.logical_id) for disk in self.drbd_inst.disks[0].children])
1366 9fdb10be Thomas Thrainer
    self.master_img.instances = [self.running_inst.uuid]
1367 9fdb10be Thomas Thrainer
    self.node1_img = \
1368 9fdb10be Thomas Thrainer
      cluster.LUClusterVerifyGroup.NodeImage(uuid=self.node1.uuid)
1369 9fdb10be Thomas Thrainer
    self.node1_img.volumes = \
1370 9fdb10be Thomas Thrainer
      ["/".join(disk.logical_id) for disk in self.drbd_inst.disks[0].children]
1371 9fdb10be Thomas Thrainer
    self.node_imgs = {
1372 9fdb10be Thomas Thrainer
      self.master_uuid: self.master_img,
1373 9fdb10be Thomas Thrainer
      self.node1.uuid: self.node1_img
1374 9fdb10be Thomas Thrainer
    }
1375 9fdb10be Thomas Thrainer
    self.diskstatus = {
1376 9fdb10be Thomas Thrainer
      self.master_uuid: [
1377 9fdb10be Thomas Thrainer
        (True, objects.BlockDevStatus(ldisk_status=constants.LDS_OKAY))
1378 9fdb10be Thomas Thrainer
        for _ in self.running_inst.disks
1379 9fdb10be Thomas Thrainer
      ]
1380 9fdb10be Thomas Thrainer
    }
1381 9fdb10be Thomas Thrainer
1382 9fdb10be Thomas Thrainer
  @withLockedLU
1383 9fdb10be Thomas Thrainer
  def testDisklessInst(self, lu):
1384 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.diskless_inst, self.node_imgs, {})
1385 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1386 9fdb10be Thomas Thrainer
1387 9fdb10be Thomas Thrainer
  @withLockedLU
1388 9fdb10be Thomas Thrainer
  def testOfflineNode(self, lu):
1389 9fdb10be Thomas Thrainer
    self.master_img.offline = True
1390 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.drbd_inst, self.node_imgs, {})
1391 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1392 9fdb10be Thomas Thrainer
1393 9fdb10be Thomas Thrainer
  @withLockedLU
1394 9fdb10be Thomas Thrainer
  def testRunningOnOfflineNode(self, lu):
1395 9fdb10be Thomas Thrainer
    self.master_img.offline = True
1396 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, {})
1397 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1398 9fdb10be Thomas Thrainer
      "instance is marked as running and lives on offline node")
1399 9fdb10be Thomas Thrainer
1400 9fdb10be Thomas Thrainer
  @withLockedLU
1401 9fdb10be Thomas Thrainer
  def testMissingVolume(self, lu):
1402 9fdb10be Thomas Thrainer
    self.master_img.volumes = []
1403 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, {})
1404 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("volume .* missing")
1405 9fdb10be Thomas Thrainer
1406 9fdb10be Thomas Thrainer
  @withLockedLU
1407 9fdb10be Thomas Thrainer
  def testRunningInstanceOnWrongNode(self, lu):
1408 9fdb10be Thomas Thrainer
    self.master_img.instances = []
1409 9fdb10be Thomas Thrainer
    self.diskless_inst.admin_state = constants.ADMINST_UP
1410 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, {})
1411 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instance not running on its primary node")
1412 9fdb10be Thomas Thrainer
1413 9fdb10be Thomas Thrainer
  @withLockedLU
1414 9fdb10be Thomas Thrainer
  def testRunningInstanceOnRightNode(self, lu):
1415 9fdb10be Thomas Thrainer
    self.master_img.instances = [self.running_inst.uuid]
1416 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, {})
1417 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1418 9fdb10be Thomas Thrainer
1419 9fdb10be Thomas Thrainer
  @withLockedLU
1420 9fdb10be Thomas Thrainer
  def testValidDiskStatus(self, lu):
1421 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, self.diskstatus)
1422 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1423 9fdb10be Thomas Thrainer
1424 9fdb10be Thomas Thrainer
  @withLockedLU
1425 9fdb10be Thomas Thrainer
  def testDegradedDiskStatus(self, lu):
1426 9fdb10be Thomas Thrainer
    self.diskstatus[self.master_uuid][0][1].is_degraded = True
1427 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, self.diskstatus)
1428 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instance .* is degraded")
1429 9fdb10be Thomas Thrainer
1430 9fdb10be Thomas Thrainer
  @withLockedLU
1431 9fdb10be Thomas Thrainer
  def testNotOkayDiskStatus(self, lu):
1432 9fdb10be Thomas Thrainer
    self.diskstatus[self.master_uuid][0][1].ldisk_status = constants.LDS_FAULTY
1433 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, self.diskstatus)
1434 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instance .* state is 'faulty'")
1435 9fdb10be Thomas Thrainer
1436 9fdb10be Thomas Thrainer
  @withLockedLU
1437 9fdb10be Thomas Thrainer
  def testExclusiveStorageWithInvalidInstance(self, lu):
1438 9fdb10be Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
1439 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.drbd_inst, self.node_imgs, self.diskstatus)
1440 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1441 9fdb10be Thomas Thrainer
      "instance has template drbd, which is not supported")
1442 9fdb10be Thomas Thrainer
1443 9fdb10be Thomas Thrainer
  @withLockedLU
1444 9fdb10be Thomas Thrainer
  def testExclusiveStorageWithValidInstance(self, lu):
1445 9fdb10be Thomas Thrainer
    self.master.ndparams[constants.ND_EXCLUSIVE_STORAGE] = True
1446 9fdb10be Thomas Thrainer
    self.running_inst.disks[0].spindles = 1
1447 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.running_inst, self.node_imgs, self.diskstatus)
1448 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1449 9fdb10be Thomas Thrainer
1450 9fdb10be Thomas Thrainer
  @withLockedLU
1451 9fdb10be Thomas Thrainer
  def testDrbdInTwoGroups(self, lu):
1452 9fdb10be Thomas Thrainer
    group = self.cfg.AddNewNodeGroup()
1453 9fdb10be Thomas Thrainer
    self.node1.group = group.uuid
1454 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.drbd_inst, self.node_imgs, self.diskstatus)
1455 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1456 9fdb10be Thomas Thrainer
      "instance has primary and secondary nodes in different groups")
1457 9fdb10be Thomas Thrainer
1458 9fdb10be Thomas Thrainer
  @withLockedLU
1459 9fdb10be Thomas Thrainer
  def testOfflineSecondary(self, lu):
1460 9fdb10be Thomas Thrainer
    self.node1_img.offline = True
1461 9fdb10be Thomas Thrainer
    lu._VerifyInstance(self.drbd_inst, self.node_imgs, self.diskstatus)
1462 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instance has offline secondary node\(s\)")
1463 9fdb10be Thomas Thrainer
1464 9fdb10be Thomas Thrainer
1465 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyOrphanVolumes(
1466 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1467 9fdb10be Thomas Thrainer
  @withLockedLU
1468 9fdb10be Thomas Thrainer
  def testOrphanedVolume(self, lu):
1469 9fdb10be Thomas Thrainer
    master_img = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1470 9fdb10be Thomas Thrainer
    master_img.volumes = ["mock_vg/disk_0", "mock_vg/disk_1", "mock_vg/disk_2"]
1471 9fdb10be Thomas Thrainer
    node_imgs = {
1472 9fdb10be Thomas Thrainer
      self.master_uuid: master_img
1473 9fdb10be Thomas Thrainer
    }
1474 9fdb10be Thomas Thrainer
    node_vol_should = {
1475 9fdb10be Thomas Thrainer
      self.master_uuid: ["mock_vg/disk_0"]
1476 9fdb10be Thomas Thrainer
    }
1477 9fdb10be Thomas Thrainer
1478 9fdb10be Thomas Thrainer
    lu._VerifyOrphanVolumes(node_vol_should, node_imgs,
1479 9fdb10be Thomas Thrainer
                            utils.FieldSet("mock_vg/disk_2"))
1480 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("volume mock_vg/disk_1 is unknown")
1481 9fdb10be Thomas Thrainer
    self.mcpu.assertLogDoesNotContainRegex("volume mock_vg/disk_0 is unknown")
1482 9fdb10be Thomas Thrainer
    self.mcpu.assertLogDoesNotContainRegex("volume mock_vg/disk_2 is unknown")
1483 9fdb10be Thomas Thrainer
1484 9fdb10be Thomas Thrainer
1485 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNPlusOneMemory(
1486 9fdb10be Thomas Thrainer
        TestLUClusterVerifyGroupMethods):
1487 9fdb10be Thomas Thrainer
  @withLockedLU
1488 9fdb10be Thomas Thrainer
  def testN1Failure(self, lu):
1489 9fdb10be Thomas Thrainer
    group1 = self.cfg.AddNewNodeGroup()
1490 9fdb10be Thomas Thrainer
1491 9fdb10be Thomas Thrainer
    node1 = self.cfg.AddNewNode()
1492 9fdb10be Thomas Thrainer
    node2 = self.cfg.AddNewNode(group=group1)
1493 9fdb10be Thomas Thrainer
    node3 = self.cfg.AddNewNode()
1494 9fdb10be Thomas Thrainer
1495 9fdb10be Thomas Thrainer
    inst1 = self.cfg.AddNewInstance()
1496 9fdb10be Thomas Thrainer
    inst2 = self.cfg.AddNewInstance()
1497 9fdb10be Thomas Thrainer
    inst3 = self.cfg.AddNewInstance()
1498 9fdb10be Thomas Thrainer
1499 9fdb10be Thomas Thrainer
    node1_img = cluster.LUClusterVerifyGroup.NodeImage(uuid=node1.uuid)
1500 9fdb10be Thomas Thrainer
    node1_img.sbp = {
1501 9fdb10be Thomas Thrainer
      self.master_uuid: [inst1.uuid, inst2.uuid, inst3.uuid]
1502 9fdb10be Thomas Thrainer
    }
1503 9fdb10be Thomas Thrainer
1504 9fdb10be Thomas Thrainer
    node2_img = cluster.LUClusterVerifyGroup.NodeImage(uuid=node2.uuid)
1505 9fdb10be Thomas Thrainer
1506 9fdb10be Thomas Thrainer
    node3_img = cluster.LUClusterVerifyGroup.NodeImage(uuid=node3.uuid)
1507 9fdb10be Thomas Thrainer
    node3_img.offline = True
1508 9fdb10be Thomas Thrainer
1509 9fdb10be Thomas Thrainer
    node_imgs = {
1510 9fdb10be Thomas Thrainer
      node1.uuid: node1_img,
1511 9fdb10be Thomas Thrainer
      node2.uuid: node2_img,
1512 9fdb10be Thomas Thrainer
      node3.uuid: node3_img
1513 9fdb10be Thomas Thrainer
    }
1514 9fdb10be Thomas Thrainer
1515 9fdb10be Thomas Thrainer
    lu._VerifyNPlusOneMemory(node_imgs, self.cfg.GetAllInstancesInfo())
1516 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1517 9fdb10be Thomas Thrainer
      "not enough memory to accomodate instance failovers")
1518 9fdb10be Thomas Thrainer
1519 9fdb10be Thomas Thrainer
    self.mcpu.ClearLogMessages()
1520 9fdb10be Thomas Thrainer
    node1_img.mfree = 1000
1521 9fdb10be Thomas Thrainer
    lu._VerifyNPlusOneMemory(node_imgs, self.cfg.GetAllInstancesInfo())
1522 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1523 9fdb10be Thomas Thrainer
1524 9fdb10be Thomas Thrainer
1525 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyFiles(TestLUClusterVerifyGroupMethods):
1526 9fdb10be Thomas Thrainer
  @withLockedLU
1527 9fdb10be Thomas Thrainer
  def test(self, lu):
1528 9fdb10be Thomas Thrainer
    node1 = self.cfg.AddNewNode(master_candidate=False, offline=False,
1529 9fdb10be Thomas Thrainer
                                vm_capable=True)
1530 9fdb10be Thomas Thrainer
    node2 = self.cfg.AddNewNode(master_candidate=True, vm_capable=False)
1531 9fdb10be Thomas Thrainer
    node3 = self.cfg.AddNewNode(master_candidate=False, offline=False,
1532 9fdb10be Thomas Thrainer
                                vm_capable=True)
1533 9fdb10be Thomas Thrainer
    node4 = self.cfg.AddNewNode(master_candidate=False, offline=False,
1534 9fdb10be Thomas Thrainer
                                vm_capable=True)
1535 9fdb10be Thomas Thrainer
    node5 = self.cfg.AddNewNode(master_candidate=False, offline=True)
1536 9fdb10be Thomas Thrainer
1537 9fdb10be Thomas Thrainer
    nodeinfo = [self.master, node1, node2, node3, node4, node5]
1538 9fdb10be Thomas Thrainer
    files_all = set([
1539 9fdb10be Thomas Thrainer
      pathutils.CLUSTER_DOMAIN_SECRET_FILE,
1540 9fdb10be Thomas Thrainer
      pathutils.RAPI_CERT_FILE,
1541 9fdb10be Thomas Thrainer
      pathutils.RAPI_USERS_FILE,
1542 9fdb10be Thomas Thrainer
      ])
1543 9fdb10be Thomas Thrainer
    files_opt = set([
1544 9fdb10be Thomas Thrainer
      pathutils.RAPI_USERS_FILE,
1545 9fdb10be Thomas Thrainer
      hv_xen.XL_CONFIG_FILE,
1546 9fdb10be Thomas Thrainer
      pathutils.VNC_PASSWORD_FILE,
1547 9fdb10be Thomas Thrainer
      ])
1548 9fdb10be Thomas Thrainer
    files_mc = set([
1549 9fdb10be Thomas Thrainer
      pathutils.CLUSTER_CONF_FILE,
1550 9fdb10be Thomas Thrainer
      ])
1551 9fdb10be Thomas Thrainer
    files_vm = set([
1552 9fdb10be Thomas Thrainer
      hv_xen.XEND_CONFIG_FILE,
1553 9fdb10be Thomas Thrainer
      hv_xen.XL_CONFIG_FILE,
1554 9fdb10be Thomas Thrainer
      pathutils.VNC_PASSWORD_FILE,
1555 9fdb10be Thomas Thrainer
      ])
1556 9fdb10be Thomas Thrainer
    nvinfo = RpcResultsBuilder() \
1557 9fdb10be Thomas Thrainer
      .AddSuccessfulNode(self.master, {
1558 9fdb10be Thomas Thrainer
        constants.NV_FILELIST: {
1559 9fdb10be Thomas Thrainer
          pathutils.CLUSTER_CONF_FILE: "82314f897f38b35f9dab2f7c6b1593e0",
1560 9fdb10be Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "babbce8f387bc082228e544a2146fee4",
1561 9fdb10be Thomas Thrainer
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
1562 9fdb10be Thomas Thrainer
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
1563 9fdb10be Thomas Thrainer
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
1564 9fdb10be Thomas Thrainer
        }}) \
1565 9fdb10be Thomas Thrainer
      .AddSuccessfulNode(node1, {
1566 9fdb10be Thomas Thrainer
        constants.NV_FILELIST: {
1567 9fdb10be Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
1568 9fdb10be Thomas Thrainer
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
1569 9fdb10be Thomas Thrainer
          }
1570 9fdb10be Thomas Thrainer
        }) \
1571 9fdb10be Thomas Thrainer
      .AddSuccessfulNode(node2, {
1572 9fdb10be Thomas Thrainer
        constants.NV_FILELIST: {
1573 9fdb10be Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
1574 9fdb10be Thomas Thrainer
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
1575 9fdb10be Thomas Thrainer
          }
1576 9fdb10be Thomas Thrainer
        }) \
1577 9fdb10be Thomas Thrainer
      .AddSuccessfulNode(node3, {
1578 9fdb10be Thomas Thrainer
        constants.NV_FILELIST: {
1579 9fdb10be Thomas Thrainer
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
1580 9fdb10be Thomas Thrainer
          pathutils.CLUSTER_CONF_FILE: "conf-a6d4b13e407867f7a7b4f0f232a8f527",
1581 9fdb10be Thomas Thrainer
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
1582 9fdb10be Thomas Thrainer
          pathutils.RAPI_USERS_FILE: "rapiusers-ea3271e8d810ef3",
1583 9fdb10be Thomas Thrainer
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
1584 9fdb10be Thomas Thrainer
          }
1585 9fdb10be Thomas Thrainer
        }) \
1586 9fdb10be Thomas Thrainer
      .AddSuccessfulNode(node4, {}) \
1587 9fdb10be Thomas Thrainer
      .AddOfflineNode(node5) \
1588 9fdb10be Thomas Thrainer
      .Build()
1589 9fdb10be Thomas Thrainer
    assert set(nvinfo.keys()) == set(map(operator.attrgetter("uuid"), nodeinfo))
1590 9fdb10be Thomas Thrainer
1591 9fdb10be Thomas Thrainer
    lu._VerifyFiles(nodeinfo, self.master_uuid, nvinfo,
1592 9fdb10be Thomas Thrainer
                    (files_all, files_opt, files_mc, files_vm))
1593 9fdb10be Thomas Thrainer
1594 9fdb10be Thomas Thrainer
    expected_msgs = [
1595 9fdb10be Thomas Thrainer
      "File %s found with 2 different checksums (variant 1 on"
1596 9fdb10be Thomas Thrainer
        " %s, %s, %s; variant 2 on %s)" %
1597 9fdb10be Thomas Thrainer
        (pathutils.RAPI_CERT_FILE, node1.name, node2.name, node3.name,
1598 9fdb10be Thomas Thrainer
         self.master.name),
1599 9fdb10be Thomas Thrainer
      "File %s is missing from node(s) %s" %
1600 9fdb10be Thomas Thrainer
        (pathutils.CLUSTER_DOMAIN_SECRET_FILE, node1.name),
1601 9fdb10be Thomas Thrainer
      "File %s should not exist on node(s) %s" %
1602 9fdb10be Thomas Thrainer
        (pathutils.CLUSTER_CONF_FILE, node3.name),
1603 9fdb10be Thomas Thrainer
      "File %s is missing from node(s) %s" %
1604 9fdb10be Thomas Thrainer
        (hv_xen.XEND_CONFIG_FILE, node3.name),
1605 9fdb10be Thomas Thrainer
      "File %s is missing from node(s) %s" %
1606 9fdb10be Thomas Thrainer
        (pathutils.CLUSTER_CONF_FILE, node2.name),
1607 9fdb10be Thomas Thrainer
      "File %s found with 2 different checksums (variant 1 on"
1608 9fdb10be Thomas Thrainer
        " %s; variant 2 on %s)" %
1609 9fdb10be Thomas Thrainer
        (pathutils.CLUSTER_CONF_FILE, self.master.name, node3.name),
1610 9fdb10be Thomas Thrainer
      "File %s is optional, but it must exist on all or no nodes (not"
1611 9fdb10be Thomas Thrainer
        " found on %s, %s, %s)" %
1612 9fdb10be Thomas Thrainer
        (pathutils.RAPI_USERS_FILE, self.master.name, node1.name, node2.name),
1613 9fdb10be Thomas Thrainer
      "File %s is optional, but it must exist on all or no nodes (not"
1614 9fdb10be Thomas Thrainer
        " found on %s)" % (hv_xen.XL_CONFIG_FILE, node1.name),
1615 9fdb10be Thomas Thrainer
      "Node did not return file checksum data",
1616 9fdb10be Thomas Thrainer
      ]
1617 9fdb10be Thomas Thrainer
1618 9fdb10be Thomas Thrainer
    self.assertEqual(len(self.mcpu.GetLogMessages()), len(expected_msgs))
1619 9fdb10be Thomas Thrainer
    for expected_msg in expected_msgs:
1620 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsInLine(expected_msg)
1621 9fdb10be Thomas Thrainer
1622 9fdb10be Thomas Thrainer
1623 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNodeDrbd(TestLUClusterVerifyGroupMethods):
1624 9fdb10be Thomas Thrainer
  def setUp(self):
1625 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupVerifyNodeDrbd, self).setUp()
1626 9fdb10be Thomas Thrainer
1627 9fdb10be Thomas Thrainer
    self.node1 = self.cfg.AddNewNode()
1628 9fdb10be Thomas Thrainer
    self.node2 = self.cfg.AddNewNode()
1629 9fdb10be Thomas Thrainer
    self.inst = self.cfg.AddNewInstance(
1630 9fdb10be Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.LD_DRBD8,
1631 9fdb10be Thomas Thrainer
                                 primary_node=self.node1,
1632 9fdb10be Thomas Thrainer
                                 secondary_node=self.node2)],
1633 9fdb10be Thomas Thrainer
      admin_state=constants.ADMINST_UP)
1634 9fdb10be Thomas Thrainer
1635 9fdb10be Thomas Thrainer
  @withLockedLU
1636 9fdb10be Thomas Thrainer
  def testNoDrbdHelper(self, lu):
1637 9fdb10be Thomas Thrainer
    lu._VerifyNodeDrbd(self.master, {}, self.cfg.GetAllInstancesInfo(), None,
1638 9fdb10be Thomas Thrainer
                       self.cfg.ComputeDRBDMap())
1639 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1640 9fdb10be Thomas Thrainer
1641 9fdb10be Thomas Thrainer
  @withLockedLU
1642 9fdb10be Thomas Thrainer
  def testDrbdHelperInvalidNodeResult(self, lu):
1643 9fdb10be Thomas Thrainer
    for ndata, expected in [({}, "no drbd usermode helper returned"),
1644 9fdb10be Thomas Thrainer
                            ({constants.NV_DRBDHELPER: (False, "")},
1645 9fdb10be Thomas Thrainer
                             "drbd usermode helper check unsuccessful"),
1646 9fdb10be Thomas Thrainer
                            ({constants.NV_DRBDHELPER: (True, "/bin/false")},
1647 9fdb10be Thomas Thrainer
                             "wrong drbd usermode helper")]:
1648 9fdb10be Thomas Thrainer
      self.mcpu.ClearLogMessages()
1649 9fdb10be Thomas Thrainer
      lu._VerifyNodeDrbd(self.master, ndata, self.cfg.GetAllInstancesInfo(),
1650 9fdb10be Thomas Thrainer
                         "/bin/true", self.cfg.ComputeDRBDMap())
1651 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsRegex(expected)
1652 9fdb10be Thomas Thrainer
1653 9fdb10be Thomas Thrainer
  @withLockedLU
1654 9fdb10be Thomas Thrainer
  def testNoNodeResult(self, lu):
1655 9fdb10be Thomas Thrainer
    lu._VerifyNodeDrbd(self.node1, {}, self.cfg.GetAllInstancesInfo(),
1656 9fdb10be Thomas Thrainer
                         None, self.cfg.ComputeDRBDMap())
1657 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("drbd minor 1 of .* is not active")
1658 9fdb10be Thomas Thrainer
1659 9fdb10be Thomas Thrainer
  @withLockedLU
1660 9fdb10be Thomas Thrainer
  def testInvalidNodeResult(self, lu):
1661 9fdb10be Thomas Thrainer
    lu._VerifyNodeDrbd(self.node1, {constants.NV_DRBDLIST: ""},
1662 9fdb10be Thomas Thrainer
                       self.cfg.GetAllInstancesInfo(), None,
1663 9fdb10be Thomas Thrainer
                       self.cfg.ComputeDRBDMap())
1664 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("cannot parse drbd status file")
1665 9fdb10be Thomas Thrainer
1666 9fdb10be Thomas Thrainer
  @withLockedLU
1667 9fdb10be Thomas Thrainer
  def testWrongMinorInUse(self, lu):
1668 9fdb10be Thomas Thrainer
    lu._VerifyNodeDrbd(self.node1, {constants.NV_DRBDLIST: [2]},
1669 9fdb10be Thomas Thrainer
                       self.cfg.GetAllInstancesInfo(), None,
1670 9fdb10be Thomas Thrainer
                       self.cfg.ComputeDRBDMap())
1671 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("drbd minor 1 of .* is not active")
1672 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("unallocated drbd minor 2 is in use")
1673 9fdb10be Thomas Thrainer
1674 9fdb10be Thomas Thrainer
  @withLockedLU
1675 9fdb10be Thomas Thrainer
  def testValidResult(self, lu):
1676 9fdb10be Thomas Thrainer
    lu._VerifyNodeDrbd(self.node1, {constants.NV_DRBDLIST: [1]},
1677 9fdb10be Thomas Thrainer
                       self.cfg.GetAllInstancesInfo(), None,
1678 9fdb10be Thomas Thrainer
                       self.cfg.ComputeDRBDMap())
1679 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1680 9fdb10be Thomas Thrainer
1681 9fdb10be Thomas Thrainer
1682 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyNodeOs(TestLUClusterVerifyGroupMethods):
1683 9fdb10be Thomas Thrainer
  @withLockedLU
1684 9fdb10be Thomas Thrainer
  def testUpdateNodeOsInvalidNodeResult(self, lu):
1685 9fdb10be Thomas Thrainer
    for ndata in [{}, {constants.NV_OSLIST: ""}, {constants.NV_OSLIST: [""]},
1686 9fdb10be Thomas Thrainer
                  {constants.NV_OSLIST: [["1", "2"]]}]:
1687 9fdb10be Thomas Thrainer
      self.mcpu.ClearLogMessages()
1688 9fdb10be Thomas Thrainer
      nimage = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1689 9fdb10be Thomas Thrainer
      lu._UpdateNodeOS(self.master, ndata, nimage)
1690 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsRegex("node hasn't returned valid OS data")
1691 9fdb10be Thomas Thrainer
1692 9fdb10be Thomas Thrainer
  @withLockedLU
1693 9fdb10be Thomas Thrainer
  def testUpdateNodeOsValidNodeResult(self, lu):
1694 9fdb10be Thomas Thrainer
    ndata = {
1695 9fdb10be Thomas Thrainer
      constants.NV_OSLIST: [
1696 9fdb10be Thomas Thrainer
        ["mock_OS", "/mocked/path", True, "", ["default"], [],
1697 9fdb10be Thomas Thrainer
         [constants.OS_API_V20]],
1698 9fdb10be Thomas Thrainer
        ["Another_Mock", "/random", True, "", ["var1", "var2"],
1699 9fdb10be Thomas Thrainer
         [{"param1": "val1"}, {"param2": "val2"}], constants.OS_API_VERSIONS]
1700 9fdb10be Thomas Thrainer
      ]
1701 9fdb10be Thomas Thrainer
    }
1702 9fdb10be Thomas Thrainer
    nimage = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1703 9fdb10be Thomas Thrainer
    lu._UpdateNodeOS(self.master, ndata, nimage)
1704 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1705 9fdb10be Thomas Thrainer
1706 9fdb10be Thomas Thrainer
  @withLockedLU
1707 9fdb10be Thomas Thrainer
  def testVerifyNodeOs(self, lu):
1708 9fdb10be Thomas Thrainer
    node = self.cfg.AddNewNode()
1709 9fdb10be Thomas Thrainer
    nimg_root = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1710 9fdb10be Thomas Thrainer
    nimg = cluster.LUClusterVerifyGroup.NodeImage(uuid=node.uuid)
1711 9fdb10be Thomas Thrainer
1712 9fdb10be Thomas Thrainer
    nimg_root.os_fail = False
1713 9fdb10be Thomas Thrainer
    nimg_root.oslist = {
1714 9fdb10be Thomas Thrainer
      "mock_os": [("/mocked/path", True, "", set(["default"]), set(),
1715 9fdb10be Thomas Thrainer
                   set([constants.OS_API_V20]))],
1716 9fdb10be Thomas Thrainer
      "broken_base_os": [("/broken", False, "", set(), set(),
1717 9fdb10be Thomas Thrainer
                         set([constants.OS_API_V20]))],
1718 9fdb10be Thomas Thrainer
      "only_on_root": [("/random", True, "", set(), set(), set())],
1719 9fdb10be Thomas Thrainer
      "diffing_os": [("/pinky", True, "", set(["var1", "var2"]),
1720 9fdb10be Thomas Thrainer
                      set([("param1", "val1"), ("param2", "val2")]),
1721 9fdb10be Thomas Thrainer
                      set([constants.OS_API_V20]))]
1722 9fdb10be Thomas Thrainer
    }
1723 9fdb10be Thomas Thrainer
    nimg.os_fail = False
1724 9fdb10be Thomas Thrainer
    nimg.oslist = {
1725 9fdb10be Thomas Thrainer
      "mock_os": [("/mocked/path", True, "", set(["default"]), set(),
1726 9fdb10be Thomas Thrainer
                   set([constants.OS_API_V20]))],
1727 9fdb10be Thomas Thrainer
      "only_on_test": [("/random", True, "", set(), set(), set())],
1728 9fdb10be Thomas Thrainer
      "diffing_os": [("/bunny", True, "", set(["var1", "var3"]),
1729 9fdb10be Thomas Thrainer
                      set([("param1", "val1"), ("param3", "val3")]),
1730 9fdb10be Thomas Thrainer
                      set([constants.OS_API_V15]))],
1731 9fdb10be Thomas Thrainer
      "broken_os": [("/broken", False, "", set(), set(),
1732 9fdb10be Thomas Thrainer
                     set([constants.OS_API_V20]))],
1733 9fdb10be Thomas Thrainer
      "multi_entries": [
1734 9fdb10be Thomas Thrainer
        ("/multi1", True, "", set(), set(), set([constants.OS_API_V20])),
1735 9fdb10be Thomas Thrainer
        ("/multi2", True, "", set(), set(), set([constants.OS_API_V20]))]
1736 9fdb10be Thomas Thrainer
    }
1737 9fdb10be Thomas Thrainer
1738 9fdb10be Thomas Thrainer
    lu._VerifyNodeOS(node, nimg, nimg_root)
1739 9fdb10be Thomas Thrainer
1740 9fdb10be Thomas Thrainer
    expected_msgs = [
1741 9fdb10be Thomas Thrainer
      "Extra OS only_on_test not present on reference node",
1742 9fdb10be Thomas Thrainer
      "OSes present on reference node .* but missing on this node:" +
1743 9fdb10be Thomas Thrainer
        " only_on_root",
1744 9fdb10be Thomas Thrainer
      "OS API version for diffing_os differs",
1745 9fdb10be Thomas Thrainer
      "OS variants list for diffing_os differs",
1746 9fdb10be Thomas Thrainer
      "OS parameters for diffing_os differs",
1747 9fdb10be Thomas Thrainer
      "Invalid OS broken_os",
1748 9fdb10be Thomas Thrainer
      "Extra OS broken_os not present on reference node",
1749 9fdb10be Thomas Thrainer
      "OS 'multi_entries' has multiple entries",
1750 9fdb10be Thomas Thrainer
      "Extra OS multi_entries not present on reference node"
1751 9fdb10be Thomas Thrainer
    ]
1752 9fdb10be Thomas Thrainer
1753 9fdb10be Thomas Thrainer
    self.assertEqual(len(expected_msgs), len(self.mcpu.GetLogMessages()))
1754 9fdb10be Thomas Thrainer
    for expected_msg in expected_msgs:
1755 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsRegex(expected_msg)
1756 9fdb10be Thomas Thrainer
1757 9fdb10be Thomas Thrainer
1758 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyAcceptedFileStoragePaths(
1759 9fdb10be Thomas Thrainer
  TestLUClusterVerifyGroupMethods):
1760 9fdb10be Thomas Thrainer
  @withLockedLU
1761 9fdb10be Thomas Thrainer
  def testNotMaster(self, lu):
1762 9fdb10be Thomas Thrainer
    lu._VerifyAcceptedFileStoragePaths(self.master, {}, False)
1763 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1764 9fdb10be Thomas Thrainer
1765 9fdb10be Thomas Thrainer
  @withLockedLU
1766 9fdb10be Thomas Thrainer
  def testNotMasterButRetunedValue(self, lu):
1767 9fdb10be Thomas Thrainer
    lu._VerifyAcceptedFileStoragePaths(
1768 9fdb10be Thomas Thrainer
      self.master, {constants.NV_ACCEPTED_STORAGE_PATHS: []}, False)
1769 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1770 9fdb10be Thomas Thrainer
      "Node should not have returned forbidden file storage paths")
1771 9fdb10be Thomas Thrainer
1772 9fdb10be Thomas Thrainer
  @withLockedLU
1773 9fdb10be Thomas Thrainer
  def testMasterInvalidNodeResult(self, lu):
1774 9fdb10be Thomas Thrainer
    lu._VerifyAcceptedFileStoragePaths(self.master, {}, True)
1775 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1776 9fdb10be Thomas Thrainer
      "Node did not return forbidden file storage paths")
1777 9fdb10be Thomas Thrainer
1778 9fdb10be Thomas Thrainer
  @withLockedLU
1779 9fdb10be Thomas Thrainer
  def testMasterForbiddenPaths(self, lu):
1780 9fdb10be Thomas Thrainer
    lu._VerifyAcceptedFileStoragePaths(
1781 9fdb10be Thomas Thrainer
      self.master, {constants.NV_ACCEPTED_STORAGE_PATHS: ["/forbidden"]}, True)
1782 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Found forbidden file storage paths")
1783 9fdb10be Thomas Thrainer
1784 9fdb10be Thomas Thrainer
  @withLockedLU
1785 9fdb10be Thomas Thrainer
  def testMasterSuccess(self, lu):
1786 9fdb10be Thomas Thrainer
    lu._VerifyAcceptedFileStoragePaths(
1787 9fdb10be Thomas Thrainer
      self.master, {constants.NV_ACCEPTED_STORAGE_PATHS: []}, True)
1788 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1789 9fdb10be Thomas Thrainer
1790 9fdb10be Thomas Thrainer
1791 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyStoragePaths(
1792 9fdb10be Thomas Thrainer
  TestLUClusterVerifyGroupMethods):
1793 9fdb10be Thomas Thrainer
  @withLockedLU
1794 9fdb10be Thomas Thrainer
  def testVerifyFileStoragePathsSuccess(self, lu):
1795 9fdb10be Thomas Thrainer
    lu._VerifyFileStoragePaths(self.master, {})
1796 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1797 9fdb10be Thomas Thrainer
1798 9fdb10be Thomas Thrainer
  @withLockedLU
1799 9fdb10be Thomas Thrainer
  def testVerifyFileStoragePathsFailure(self, lu):
1800 9fdb10be Thomas Thrainer
    lu._VerifyFileStoragePaths(self.master,
1801 9fdb10be Thomas Thrainer
                               {constants.NV_FILE_STORAGE_PATH: "/fail/path"})
1802 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1803 9fdb10be Thomas Thrainer
      "The configured file storage path is unusable")
1804 9fdb10be Thomas Thrainer
1805 9fdb10be Thomas Thrainer
  @withLockedLU
1806 9fdb10be Thomas Thrainer
  def testVerifySharedFileStoragePathsSuccess(self, lu):
1807 9fdb10be Thomas Thrainer
    lu._VerifySharedFileStoragePaths(self.master, {})
1808 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1809 9fdb10be Thomas Thrainer
1810 9fdb10be Thomas Thrainer
  @withLockedLU
1811 9fdb10be Thomas Thrainer
  def testVerifySharedFileStoragePathsFailure(self, lu):
1812 9fdb10be Thomas Thrainer
    lu._VerifySharedFileStoragePaths(
1813 9fdb10be Thomas Thrainer
      self.master, {constants.NV_SHARED_FILE_STORAGE_PATH: "/fail/path"})
1814 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1815 9fdb10be Thomas Thrainer
      "The configured sharedfile storage path is unusable")
1816 9fdb10be Thomas Thrainer
1817 9fdb10be Thomas Thrainer
1818 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupVerifyOob(TestLUClusterVerifyGroupMethods):
1819 9fdb10be Thomas Thrainer
  @withLockedLU
1820 9fdb10be Thomas Thrainer
  def testEmptyResult(self, lu):
1821 9fdb10be Thomas Thrainer
    lu._VerifyOob(self.master, {})
1822 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1823 9fdb10be Thomas Thrainer
1824 9fdb10be Thomas Thrainer
  @withLockedLU
1825 9fdb10be Thomas Thrainer
  def testErrorResults(self, lu):
1826 9fdb10be Thomas Thrainer
    lu._VerifyOob(self.master, {constants.NV_OOB_PATHS: ["path1", "path2"]})
1827 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("path1")
1828 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("path2")
1829 9fdb10be Thomas Thrainer
1830 9fdb10be Thomas Thrainer
1831 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupUpdateNodeVolumes(
1832 9fdb10be Thomas Thrainer
  TestLUClusterVerifyGroupMethods):
1833 9fdb10be Thomas Thrainer
  def setUp(self):
1834 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupUpdateNodeVolumes, self).setUp()
1835 9fdb10be Thomas Thrainer
    self.nimg = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1836 9fdb10be Thomas Thrainer
1837 9fdb10be Thomas Thrainer
  @withLockedLU
1838 9fdb10be Thomas Thrainer
  def testNoVgName(self, lu):
1839 9fdb10be Thomas Thrainer
    lu._UpdateNodeVolumes(self.master, {}, self.nimg, None)
1840 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1841 9fdb10be Thomas Thrainer
    self.assertTrue(self.nimg.lvm_fail)
1842 9fdb10be Thomas Thrainer
1843 9fdb10be Thomas Thrainer
  @withLockedLU
1844 9fdb10be Thomas Thrainer
  def testErrorMessage(self, lu):
1845 9fdb10be Thomas Thrainer
    lu._UpdateNodeVolumes(self.master, {constants.NV_LVLIST: "mock error"},
1846 9fdb10be Thomas Thrainer
                          self.nimg, "mock_vg")
1847 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("LVM problem on node: mock error")
1848 9fdb10be Thomas Thrainer
    self.assertTrue(self.nimg.lvm_fail)
1849 9fdb10be Thomas Thrainer
1850 9fdb10be Thomas Thrainer
  @withLockedLU
1851 9fdb10be Thomas Thrainer
  def testInvalidNodeResult(self, lu):
1852 9fdb10be Thomas Thrainer
    lu._UpdateNodeVolumes(self.master, {constants.NV_LVLIST: [1, 2, 3]},
1853 9fdb10be Thomas Thrainer
                          self.nimg, "mock_vg")
1854 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("rpc call to node failed")
1855 9fdb10be Thomas Thrainer
    self.assertTrue(self.nimg.lvm_fail)
1856 9fdb10be Thomas Thrainer
1857 9fdb10be Thomas Thrainer
  @withLockedLU
1858 9fdb10be Thomas Thrainer
  def testValidNodeResult(self, lu):
1859 9fdb10be Thomas Thrainer
    lu._UpdateNodeVolumes(self.master, {constants.NV_LVLIST: {}},
1860 9fdb10be Thomas Thrainer
                          self.nimg, "mock_vg")
1861 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1862 9fdb10be Thomas Thrainer
    self.assertFalse(self.nimg.lvm_fail)
1863 9fdb10be Thomas Thrainer
1864 9fdb10be Thomas Thrainer
1865 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupUpdateNodeInstances(
1866 9fdb10be Thomas Thrainer
  TestLUClusterVerifyGroupMethods):
1867 9fdb10be Thomas Thrainer
  def setUp(self):
1868 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupUpdateNodeInstances, self).setUp()
1869 9fdb10be Thomas Thrainer
    self.nimg = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1870 9fdb10be Thomas Thrainer
1871 9fdb10be Thomas Thrainer
  @withLockedLU
1872 9fdb10be Thomas Thrainer
  def testInvalidNodeResult(self, lu):
1873 9fdb10be Thomas Thrainer
    lu._UpdateNodeInstances(self.master, {}, self.nimg)
1874 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("rpc call to node failed")
1875 9fdb10be Thomas Thrainer
1876 9fdb10be Thomas Thrainer
  @withLockedLU
1877 9fdb10be Thomas Thrainer
  def testValidNodeResult(self, lu):
1878 9fdb10be Thomas Thrainer
    inst = self.cfg.AddNewInstance()
1879 9fdb10be Thomas Thrainer
    lu._UpdateNodeInstances(self.master,
1880 9fdb10be Thomas Thrainer
                            {constants.NV_INSTANCELIST: [inst.name]},
1881 9fdb10be Thomas Thrainer
                            self.nimg)
1882 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1883 9fdb10be Thomas Thrainer
1884 9fdb10be Thomas Thrainer
1885 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupUpdateNodeInfo(TestLUClusterVerifyGroupMethods):
1886 9fdb10be Thomas Thrainer
  def setUp(self):
1887 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupUpdateNodeInfo, self).setUp()
1888 9fdb10be Thomas Thrainer
    self.nimg = cluster.LUClusterVerifyGroup.NodeImage(uuid=self.master_uuid)
1889 9fdb10be Thomas Thrainer
    self.valid_hvresult = {constants.NV_HVINFO: {"memory_free": 1024}}
1890 9fdb10be Thomas Thrainer
1891 9fdb10be Thomas Thrainer
  @withLockedLU
1892 9fdb10be Thomas Thrainer
  def testInvalidHvNodeResult(self, lu):
1893 9fdb10be Thomas Thrainer
    for ndata in [{}, {constants.NV_HVINFO: ""}]:
1894 9fdb10be Thomas Thrainer
      self.mcpu.ClearLogMessages()
1895 9fdb10be Thomas Thrainer
      lu._UpdateNodeInfo(self.master, ndata, self.nimg, None)
1896 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsRegex("rpc call to node failed")
1897 9fdb10be Thomas Thrainer
1898 9fdb10be Thomas Thrainer
  @withLockedLU
1899 9fdb10be Thomas Thrainer
  def testInvalidMemoryFreeHvNodeResult(self, lu):
1900 9fdb10be Thomas Thrainer
    lu._UpdateNodeInfo(self.master,
1901 9fdb10be Thomas Thrainer
                       {constants.NV_HVINFO: {"memory_free": "abc"}},
1902 9fdb10be Thomas Thrainer
                       self.nimg, None)
1903 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1904 9fdb10be Thomas Thrainer
      "node returned invalid nodeinfo, check hypervisor")
1905 9fdb10be Thomas Thrainer
1906 9fdb10be Thomas Thrainer
  @withLockedLU
1907 9fdb10be Thomas Thrainer
  def testValidHvNodeResult(self, lu):
1908 9fdb10be Thomas Thrainer
    lu._UpdateNodeInfo(self.master, self.valid_hvresult, self.nimg, None)
1909 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1910 9fdb10be Thomas Thrainer
1911 9fdb10be Thomas Thrainer
  @withLockedLU
1912 9fdb10be Thomas Thrainer
  def testInvalidVgNodeResult(self, lu):
1913 9fdb10be Thomas Thrainer
    for vgdata in [[], ""]:
1914 9fdb10be Thomas Thrainer
      self.mcpu.ClearLogMessages()
1915 9fdb10be Thomas Thrainer
      ndata = {constants.NV_VGLIST: vgdata}
1916 9fdb10be Thomas Thrainer
      ndata.update(self.valid_hvresult)
1917 9fdb10be Thomas Thrainer
      lu._UpdateNodeInfo(self.master, ndata, self.nimg, "mock_vg")
1918 9fdb10be Thomas Thrainer
      self.mcpu.assertLogContainsRegex(
1919 9fdb10be Thomas Thrainer
        "node didn't return data for the volume group 'mock_vg'")
1920 9fdb10be Thomas Thrainer
1921 9fdb10be Thomas Thrainer
  @withLockedLU
1922 9fdb10be Thomas Thrainer
  def testInvalidDiskFreeVgNodeResult(self, lu):
1923 9fdb10be Thomas Thrainer
    self.valid_hvresult.update({
1924 9fdb10be Thomas Thrainer
      constants.NV_VGLIST: {"mock_vg": "abc"}
1925 9fdb10be Thomas Thrainer
    })
1926 9fdb10be Thomas Thrainer
    lu._UpdateNodeInfo(self.master, self.valid_hvresult, self.nimg, "mock_vg")
1927 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1928 9fdb10be Thomas Thrainer
      "node returned invalid LVM info, check LVM status")
1929 9fdb10be Thomas Thrainer
1930 9fdb10be Thomas Thrainer
  @withLockedLU
1931 9fdb10be Thomas Thrainer
  def testValidVgNodeResult(self, lu):
1932 9fdb10be Thomas Thrainer
    self.valid_hvresult.update({
1933 9fdb10be Thomas Thrainer
      constants.NV_VGLIST: {"mock_vg": 10000}
1934 9fdb10be Thomas Thrainer
    })
1935 9fdb10be Thomas Thrainer
    lu._UpdateNodeInfo(self.master, self.valid_hvresult, self.nimg, "mock_vg")
1936 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1937 9fdb10be Thomas Thrainer
1938 9fdb10be Thomas Thrainer
1939 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupCollectDiskInfo(TestLUClusterVerifyGroupMethods):
1940 9fdb10be Thomas Thrainer
  def setUp(self):
1941 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupCollectDiskInfo, self).setUp()
1942 9fdb10be Thomas Thrainer
1943 9fdb10be Thomas Thrainer
    self.node1 = self.cfg.AddNewNode()
1944 9fdb10be Thomas Thrainer
    self.node2 = self.cfg.AddNewNode()
1945 9fdb10be Thomas Thrainer
    self.node3 = self.cfg.AddNewNode()
1946 9fdb10be Thomas Thrainer
1947 9fdb10be Thomas Thrainer
    self.diskless_inst = \
1948 9fdb10be Thomas Thrainer
      self.cfg.AddNewInstance(primary_node=self.node1,
1949 9fdb10be Thomas Thrainer
                              disk_template=constants.DT_DISKLESS)
1950 9fdb10be Thomas Thrainer
    self.plain_inst = \
1951 9fdb10be Thomas Thrainer
      self.cfg.AddNewInstance(primary_node=self.node2,
1952 9fdb10be Thomas Thrainer
                              disk_template=constants.DT_PLAIN)
1953 9fdb10be Thomas Thrainer
    self.drbd_inst = \
1954 9fdb10be Thomas Thrainer
      self.cfg.AddNewInstance(primary_node=self.node3,
1955 9fdb10be Thomas Thrainer
                              secondary_node=self.node2,
1956 9fdb10be Thomas Thrainer
                              disk_template=constants.DT_DRBD8)
1957 9fdb10be Thomas Thrainer
1958 9fdb10be Thomas Thrainer
    self.node1_img = cluster.LUClusterVerifyGroup.NodeImage(
1959 9fdb10be Thomas Thrainer
                       uuid=self.node1.uuid)
1960 9fdb10be Thomas Thrainer
    self.node1_img.pinst = [self.diskless_inst.uuid]
1961 9fdb10be Thomas Thrainer
    self.node1_img.sinst = []
1962 9fdb10be Thomas Thrainer
    self.node2_img = cluster.LUClusterVerifyGroup.NodeImage(
1963 9fdb10be Thomas Thrainer
                       uuid=self.node2.uuid)
1964 9fdb10be Thomas Thrainer
    self.node2_img.pinst = [self.plain_inst.uuid]
1965 9fdb10be Thomas Thrainer
    self.node2_img.sinst = [self.drbd_inst.uuid]
1966 9fdb10be Thomas Thrainer
    self.node3_img = cluster.LUClusterVerifyGroup.NodeImage(
1967 9fdb10be Thomas Thrainer
                       uuid=self.node3.uuid)
1968 9fdb10be Thomas Thrainer
    self.node3_img.pinst = [self.drbd_inst.uuid]
1969 9fdb10be Thomas Thrainer
    self.node3_img.sinst = []
1970 9fdb10be Thomas Thrainer
1971 9fdb10be Thomas Thrainer
    self.node_images = {
1972 9fdb10be Thomas Thrainer
      self.node1.uuid: self.node1_img,
1973 9fdb10be Thomas Thrainer
      self.node2.uuid: self.node2_img,
1974 9fdb10be Thomas Thrainer
      self.node3.uuid: self.node3_img
1975 9fdb10be Thomas Thrainer
    }
1976 9fdb10be Thomas Thrainer
1977 9fdb10be Thomas Thrainer
    self.node_uuids = [self.node1.uuid, self.node2.uuid, self.node3.uuid]
1978 9fdb10be Thomas Thrainer
1979 9fdb10be Thomas Thrainer
  @withLockedLU
1980 9fdb10be Thomas Thrainer
  def testSuccessfulRun(self, lu):
1981 9fdb10be Thomas Thrainer
    self.rpc.call_blockdev_getmirrorstatus_multi.return_value = \
1982 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
1983 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.node2, [(True, ""), (True, "")]) \
1984 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.node3, [(True, "")]) \
1985 9fdb10be Thomas Thrainer
        .Build()
1986 9fdb10be Thomas Thrainer
1987 9fdb10be Thomas Thrainer
    lu._CollectDiskInfo(self.node_uuids, self.node_images,
1988 9fdb10be Thomas Thrainer
                        self.cfg.GetAllInstancesInfo())
1989 9fdb10be Thomas Thrainer
1990 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
1991 9fdb10be Thomas Thrainer
1992 9fdb10be Thomas Thrainer
  @withLockedLU
1993 9fdb10be Thomas Thrainer
  def testOfflineAndFailingNodes(self, lu):
1994 9fdb10be Thomas Thrainer
    self.rpc.call_blockdev_getmirrorstatus_multi.return_value = \
1995 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
1996 9fdb10be Thomas Thrainer
        .AddOfflineNode(self.node2) \
1997 9fdb10be Thomas Thrainer
        .AddFailedNode(self.node3) \
1998 9fdb10be Thomas Thrainer
        .Build()
1999 9fdb10be Thomas Thrainer
2000 9fdb10be Thomas Thrainer
    lu._CollectDiskInfo(self.node_uuids, self.node_images,
2001 9fdb10be Thomas Thrainer
                        self.cfg.GetAllInstancesInfo())
2002 9fdb10be Thomas Thrainer
2003 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("while getting disk information")
2004 9fdb10be Thomas Thrainer
2005 9fdb10be Thomas Thrainer
  @withLockedLU
2006 9fdb10be Thomas Thrainer
  def testInvalidNodeResult(self, lu):
2007 9fdb10be Thomas Thrainer
    self.rpc.call_blockdev_getmirrorstatus_multi.return_value = \
2008 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
2009 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.node2, [(True,), (False,)]) \
2010 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.node3, [""]) \
2011 9fdb10be Thomas Thrainer
        .Build()
2012 9fdb10be Thomas Thrainer
2013 9fdb10be Thomas Thrainer
    lu._CollectDiskInfo(self.node_uuids, self.node_images,
2014 9fdb10be Thomas Thrainer
                        self.cfg.GetAllInstancesInfo())
2015 9fdb10be Thomas Thrainer
    # logging is not performed through mcpu
2016 9fdb10be Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
2017 9fdb10be Thomas Thrainer
2018 9fdb10be Thomas Thrainer
2019 9fdb10be Thomas Thrainer
class TestLUClusterVerifyGroupHooksCallBack(TestLUClusterVerifyGroupMethods):
2020 9fdb10be Thomas Thrainer
  def setUp(self):
2021 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupHooksCallBack, self).setUp()
2022 9fdb10be Thomas Thrainer
2023 9fdb10be Thomas Thrainer
    self.feedback_fn = lambda _: None
2024 9fdb10be Thomas Thrainer
2025 9fdb10be Thomas Thrainer
  def PrepareLU(self, lu):
2026 9fdb10be Thomas Thrainer
    super(TestLUClusterVerifyGroupHooksCallBack, self).PrepareLU(lu)
2027 9fdb10be Thomas Thrainer
2028 9fdb10be Thomas Thrainer
    lu.my_node_uuids = list(self.cfg.GetAllNodesInfo().keys())
2029 9fdb10be Thomas Thrainer
2030 9fdb10be Thomas Thrainer
  @withLockedLU
2031 9fdb10be Thomas Thrainer
  def testEmptyGroup(self, lu):
2032 9fdb10be Thomas Thrainer
    lu.my_node_uuids = []
2033 9fdb10be Thomas Thrainer
    lu.HooksCallBack(constants.HOOKS_PHASE_POST, None, self.feedback_fn, None)
2034 9fdb10be Thomas Thrainer
2035 9fdb10be Thomas Thrainer
  @withLockedLU
2036 9fdb10be Thomas Thrainer
  def testFailedResult(self, lu):
2037 9fdb10be Thomas Thrainer
    lu.HooksCallBack(constants.HOOKS_PHASE_POST,
2038 9fdb10be Thomas Thrainer
                     RpcResultsBuilder(use_node_names=True)
2039 9fdb10be Thomas Thrainer
                       .AddFailedNode(self.master).Build(),
2040 9fdb10be Thomas Thrainer
                     self.feedback_fn,
2041 9fdb10be Thomas Thrainer
                     None)
2042 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Communication failure in hooks execution")
2043 9fdb10be Thomas Thrainer
2044 9fdb10be Thomas Thrainer
  @withLockedLU
2045 9fdb10be Thomas Thrainer
  def testOfflineNode(self, lu):
2046 9fdb10be Thomas Thrainer
    lu.HooksCallBack(constants.HOOKS_PHASE_POST,
2047 9fdb10be Thomas Thrainer
                     RpcResultsBuilder(use_node_names=True)
2048 9fdb10be Thomas Thrainer
                       .AddOfflineNode(self.master).Build(),
2049 9fdb10be Thomas Thrainer
                     self.feedback_fn,
2050 9fdb10be Thomas Thrainer
                     None)
2051 9fdb10be Thomas Thrainer
2052 9fdb10be Thomas Thrainer
  @withLockedLU
2053 9fdb10be Thomas Thrainer
  def testValidResult(self, lu):
2054 9fdb10be Thomas Thrainer
    lu.HooksCallBack(constants.HOOKS_PHASE_POST,
2055 9fdb10be Thomas Thrainer
                     RpcResultsBuilder(use_node_names=True)
2056 9fdb10be Thomas Thrainer
                       .AddSuccessfulNode(self.master,
2057 9fdb10be Thomas Thrainer
                                          [("mock_script",
2058 9fdb10be Thomas Thrainer
                                            constants.HKR_SUCCESS,
2059 9fdb10be Thomas Thrainer
                                            "mock output")])
2060 9fdb10be Thomas Thrainer
                       .Build(),
2061 9fdb10be Thomas Thrainer
                     self.feedback_fn,
2062 9fdb10be Thomas Thrainer
                     None)
2063 9fdb10be Thomas Thrainer
2064 9fdb10be Thomas Thrainer
  @withLockedLU
2065 9fdb10be Thomas Thrainer
  def testFailedScriptResult(self, lu):
2066 9fdb10be Thomas Thrainer
    lu.HooksCallBack(constants.HOOKS_PHASE_POST,
2067 9fdb10be Thomas Thrainer
                     RpcResultsBuilder(use_node_names=True)
2068 9fdb10be Thomas Thrainer
                       .AddSuccessfulNode(self.master,
2069 9fdb10be Thomas Thrainer
                                          [("mock_script",
2070 9fdb10be Thomas Thrainer
                                            constants.HKR_FAIL,
2071 9fdb10be Thomas Thrainer
                                            "mock output")])
2072 9fdb10be Thomas Thrainer
                       .Build(),
2073 9fdb10be Thomas Thrainer
                     self.feedback_fn,
2074 9fdb10be Thomas Thrainer
                     None)
2075 9fdb10be Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Script mock_script failed")
2076 9fdb10be Thomas Thrainer
2077 9fdb10be Thomas Thrainer
2078 570b6322 Thomas Thrainer
class TestLUClusterVerifyDisks(CmdlibTestCase):
2079 570b6322 Thomas Thrainer
  def testVerifyDisks(self):
2080 570b6322 Thomas Thrainer
    op = opcodes.OpClusterVerifyDisks()
2081 570b6322 Thomas Thrainer
    result = self.ExecOpCode(op)
2082 570b6322 Thomas Thrainer
2083 570b6322 Thomas Thrainer
    self.assertEqual(1, len(result["jobs"]))
2084 570b6322 Thomas Thrainer
2085 570b6322 Thomas Thrainer
2086 19830e88 Thomas Thrainer
if __name__ == "__main__":
2087 19830e88 Thomas Thrainer
  testutils.GanetiTestProgram()