Statistics
| Branch: | Tag: | Revision:

root / test / py / cmdlib / cluster_unittest.py @ ac156ecd

History | View | Annotate | Download (75.4 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 4256f8fe Sebastian Gebhard
  NEW_IP = "203.0.113.100"
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 0c5f1b13 Thomas Thrainer
  def _SetUpInstanceSingleDisk(self, dev_type=constants.DT_PLAIN):
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 0c5f1b13 Thomas Thrainer
    self._SetUpInstanceSingleDisk(dev_type=constants.DT_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 0c5f1b13 Thomas Thrainer
    (_, disk) = self._SetUpInstanceSingleDisk(dev_type=constants.DT_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 f41b569f Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netmask=26)
423 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
424 f41b569f Thomas Thrainer
    self.assertEqual(26, 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 9b9e088c Raffa Santi
                       {constants.DT_DRBD8: {constants.RBD_POOL: "pool"}},
429 9b9e088c Raffa Santi
                       {constants.DT_DRBD8: {constants.RBD_ACCESS: "bunny"}}]:
430 a794b8d7 Thomas Thrainer
      self.ResetMocks()
431 a794b8d7 Thomas Thrainer
      op = opcodes.OpClusterSetParams(diskparams=diskparams)
432 a794b8d7 Thomas Thrainer
      self.ExecOpCodeExpectOpPrereqError(op, "verify diskparams")
433 a794b8d7 Thomas Thrainer
434 a794b8d7 Thomas Thrainer
  def testValidDiskparams(self):
435 9b9e088c Raffa Santi
    diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool",
436 9b9e088c Raffa Santi
                                     constants.RBD_ACCESS: "kernelspace"}}
437 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(diskparams=diskparams)
438 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
439 a794b8d7 Thomas Thrainer
    self.assertEqual(diskparams[constants.DT_RBD],
440 a794b8d7 Thomas Thrainer
                     self.cluster.diskparams[constants.DT_RBD])
441 a794b8d7 Thomas Thrainer
442 a794b8d7 Thomas Thrainer
  def testMinimalDiskparams(self):
443 a794b8d7 Thomas Thrainer
    diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
444 a794b8d7 Thomas Thrainer
    self.cluster.diskparams = {}
445 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(diskparams=diskparams)
446 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
447 a794b8d7 Thomas Thrainer
    self.assertEqual(diskparams, self.cluster.diskparams)
448 a794b8d7 Thomas Thrainer
449 537dba0c Raffa Santi
  def testValidDiskparamsAccess(self):
450 537dba0c Raffa Santi
    for value in constants.DISK_VALID_ACCESS_MODES:
451 537dba0c Raffa Santi
      self.ResetMocks()
452 537dba0c Raffa Santi
      op = opcodes.OpClusterSetParams(diskparams={
453 537dba0c Raffa Santi
        constants.DT_RBD: {constants.RBD_ACCESS: value}
454 537dba0c Raffa Santi
      })
455 537dba0c Raffa Santi
      self.ExecOpCode(op)
456 537dba0c Raffa Santi
      got = self.cluster.diskparams[constants.DT_RBD][constants.RBD_ACCESS]
457 537dba0c Raffa Santi
      self.assertEqual(value, got)
458 537dba0c Raffa Santi
459 537dba0c Raffa Santi
  def testInvalidDiskparamsAccess(self):
460 537dba0c Raffa Santi
    for value in ["default", "pinky_bunny"]:
461 537dba0c Raffa Santi
      self.ResetMocks()
462 537dba0c Raffa Santi
      op = opcodes.OpClusterSetParams(diskparams={
463 537dba0c Raffa Santi
        constants.DT_RBD: {constants.RBD_ACCESS: value}
464 537dba0c Raffa Santi
      })
465 537dba0c Raffa Santi
      self.ExecOpCodeExpectOpPrereqError(op, "Invalid value of 'rbd:access'")
466 537dba0c Raffa Santi
467 a794b8d7 Thomas Thrainer
  def testUnsetDrbdHelperWithDrbdDisks(self):
468 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(disks=[
469 0c5f1b13 Thomas Thrainer
      self.cfg.CreateDisk(dev_type=constants.DT_DRBD8, create_nodes=True)])
470 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="")
471 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable drbd helper")
472 a794b8d7 Thomas Thrainer
473 a794b8d7 Thomas Thrainer
  def testFileStorageDir(self):
474 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(file_storage_dir="/random/path")
475 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
476 a794b8d7 Thomas Thrainer
477 a794b8d7 Thomas Thrainer
  def testSetFileStorageDirToCurrentValue(self):
478 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
479 a794b8d7 Thomas Thrainer
           file_storage_dir=self.cluster.file_storage_dir)
480 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
481 a794b8d7 Thomas Thrainer
482 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("file storage dir already set to value")
483 a794b8d7 Thomas Thrainer
484 70e8dd0a Helga Velroyen
  def testUnsetFileStorageDirFileStorageEnabled(self):
485 70e8dd0a Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_FILE])
486 70e8dd0a Helga Velroyen
    op = opcodes.OpClusterSetParams(file_storage_dir='')
487 70e8dd0a Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(op, "Unsetting the 'file' storage")
488 70e8dd0a Helga Velroyen
489 70e8dd0a Helga Velroyen
  def testUnsetFileStorageDirFileStorageDisabled(self):
490 70e8dd0a Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_PLAIN])
491 70e8dd0a Helga Velroyen
    op = opcodes.OpClusterSetParams(file_storage_dir='')
492 70e8dd0a Helga Velroyen
    self.ExecOpCode(op)
493 70e8dd0a Helga Velroyen
494 70e8dd0a Helga Velroyen
  def testSetFileStorageDirFileStorageDisabled(self):
495 70e8dd0a Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_PLAIN])
496 70e8dd0a Helga Velroyen
    op = opcodes.OpClusterSetParams(file_storage_dir='/some/path/')
497 70e8dd0a Helga Velroyen
    self.ExecOpCode(op)
498 70e8dd0a Helga Velroyen
    self.mcpu.assertLogContainsRegex("although file storage is not enabled")
499 70e8dd0a Helga Velroyen
500 a794b8d7 Thomas Thrainer
  def testValidDrbdHelper(self):
501 a794b8d7 Thomas Thrainer
    node1 = self.cfg.AddNewNode()
502 a794b8d7 Thomas Thrainer
    node1.offline = True
503 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
504 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
505 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, "/bin/true") \
506 a794b8d7 Thomas Thrainer
        .AddOfflineNode(node1) \
507 a794b8d7 Thomas Thrainer
        .Build()
508 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
509 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
510 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Not checking drbd helper on offline node")
511 a794b8d7 Thomas Thrainer
512 a794b8d7 Thomas Thrainer
  def testDrbdHelperFailingNode(self):
513 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
514 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
515 a794b8d7 Thomas Thrainer
        .AddFailedNode(self.master) \
516 a794b8d7 Thomas Thrainer
        .Build()
517 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
518 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Error checking drbd helper")
519 a794b8d7 Thomas Thrainer
520 a794b8d7 Thomas Thrainer
  def testInvalidDrbdHelper(self):
521 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
522 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
523 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, "/bin/false") \
524 a794b8d7 Thomas Thrainer
        .Build()
525 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper="/bin/true")
526 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "drbd helper is /bin/false")
527 a794b8d7 Thomas Thrainer
528 a794b8d7 Thomas Thrainer
  def testDrbdHelperWithoutDrbdDiskTemplate(self):
529 a794b8d7 Thomas Thrainer
    drbd_helper = "/bin/random_helper"
530 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
531 a794b8d7 Thomas Thrainer
    self.rpc.call_drbd_helper.return_value = \
532 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
533 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, drbd_helper) \
534 a794b8d7 Thomas Thrainer
        .Build()
535 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
536 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
537 a794b8d7 Thomas Thrainer
538 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("but did not enable")
539 a794b8d7 Thomas Thrainer
540 31ccfc0e Helga Velroyen
  def testResetDrbdHelperDrbdDisabled(self):
541 a794b8d7 Thomas Thrainer
    drbd_helper = ""
542 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
543 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
544 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
545 a794b8d7 Thomas Thrainer
546 a794b8d7 Thomas Thrainer
    self.assertEqual(None, self.cluster.drbd_usermode_helper)
547 a794b8d7 Thomas Thrainer
548 31ccfc0e Helga Velroyen
  def testResetDrbdHelperDrbdEnabled(self):
549 31ccfc0e Helga Velroyen
    drbd_helper = ""
550 31ccfc0e Helga Velroyen
    self.cluster.enabled_disk_templates = [constants.DT_DRBD8]
551 31ccfc0e Helga Velroyen
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
552 31ccfc0e Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(
553 31ccfc0e Helga Velroyen
        op, "Cannot disable drbd helper while DRBD is enabled.")
554 31ccfc0e Helga Velroyen
555 31ccfc0e Helga Velroyen
  def testEnableDrbdNoHelper(self):
556 31ccfc0e Helga Velroyen
    self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
557 31ccfc0e Helga Velroyen
    self.cluster.drbd_usermode_helper = None
558 31ccfc0e Helga Velroyen
    enabled_disk_templates = [constants.DT_DRBD8]
559 31ccfc0e Helga Velroyen
    op = opcodes.OpClusterSetParams(
560 31ccfc0e Helga Velroyen
        enabled_disk_templates=enabled_disk_templates)
561 31ccfc0e Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(
562 31ccfc0e Helga Velroyen
        op, "Cannot enable DRBD without a DRBD usermode helper set")
563 31ccfc0e Helga Velroyen
564 31ccfc0e Helga Velroyen
  def testEnableDrbdHelperSet(self):
565 31ccfc0e Helga Velroyen
    drbd_helper = "/bin/random_helper"
566 31ccfc0e Helga Velroyen
    self.rpc.call_drbd_helper.return_value = \
567 31ccfc0e Helga Velroyen
      self.RpcResultsBuilder() \
568 31ccfc0e Helga Velroyen
        .AddSuccessfulNode(self.master, drbd_helper) \
569 31ccfc0e Helga Velroyen
        .Build()
570 31ccfc0e Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
571 31ccfc0e Helga Velroyen
    self.cluster.drbd_usermode_helper = drbd_helper
572 31ccfc0e Helga Velroyen
    enabled_disk_templates = [constants.DT_DRBD8]
573 31ccfc0e Helga Velroyen
    op = opcodes.OpClusterSetParams(
574 31ccfc0e Helga Velroyen
        enabled_disk_templates=enabled_disk_templates,
575 31ccfc0e Helga Velroyen
        ipolicy={constants.IPOLICY_DTS: enabled_disk_templates})
576 31ccfc0e Helga Velroyen
    self.ExecOpCode(op)
577 31ccfc0e Helga Velroyen
578 31ccfc0e Helga Velroyen
    self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper)
579 31ccfc0e Helga Velroyen
580 7c577910 Helga Velroyen
  def testDrbdHelperAlreadySet(self):
581 7c577910 Helga Velroyen
    drbd_helper = "/bin/true"
582 7c577910 Helga Velroyen
    self.rpc.call_drbd_helper.return_value = \
583 7c577910 Helga Velroyen
      self.RpcResultsBuilder() \
584 7c577910 Helga Velroyen
        .AddSuccessfulNode(self.master, "/bin/true") \
585 7c577910 Helga Velroyen
        .Build()
586 31ccfc0e Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
587 7c577910 Helga Velroyen
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
588 7c577910 Helga Velroyen
    self.ExecOpCode(op)
589 7c577910 Helga Velroyen
590 7c577910 Helga Velroyen
    self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper)
591 7c577910 Helga Velroyen
    self.mcpu.assertLogContainsRegex("DRBD helper already in desired state")
592 7c577910 Helga Velroyen
593 7c577910 Helga Velroyen
  def testSetDrbdHelper(self):
594 7c577910 Helga Velroyen
    drbd_helper = "/bin/true"
595 7c577910 Helga Velroyen
    self.rpc.call_drbd_helper.return_value = \
596 7c577910 Helga Velroyen
      self.RpcResultsBuilder() \
597 7c577910 Helga Velroyen
        .AddSuccessfulNode(self.master, "/bin/true") \
598 7c577910 Helga Velroyen
        .Build()
599 7c577910 Helga Velroyen
    self.cluster.drbd_usermode_helper = "/bin/false"
600 31ccfc0e Helga Velroyen
    self.cfg.SetEnabledDiskTemplates([constants.DT_DRBD8])
601 7c577910 Helga Velroyen
    op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper)
602 7c577910 Helga Velroyen
    self.ExecOpCode(op)
603 7c577910 Helga Velroyen
604 7c577910 Helga Velroyen
    self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper)
605 7c577910 Helga Velroyen
606 a794b8d7 Thomas Thrainer
  def testBeparams(self):
607 a794b8d7 Thomas Thrainer
    beparams = {constants.BE_VCPUS: 32}
608 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(beparams=beparams)
609 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
610 a794b8d7 Thomas Thrainer
    self.assertEqual(32, self.cluster
611 a794b8d7 Thomas Thrainer
                           .beparams[constants.PP_DEFAULT][constants.BE_VCPUS])
612 a794b8d7 Thomas Thrainer
613 a794b8d7 Thomas Thrainer
  def testNdparams(self):
614 a794b8d7 Thomas Thrainer
    ndparams = {constants.ND_EXCLUSIVE_STORAGE: True}
615 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ndparams=ndparams)
616 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
617 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster
618 a794b8d7 Thomas Thrainer
                             .ndparams[constants.ND_EXCLUSIVE_STORAGE])
619 a794b8d7 Thomas Thrainer
620 a794b8d7 Thomas Thrainer
  def testNdparamsResetOobProgram(self):
621 a794b8d7 Thomas Thrainer
    ndparams = {constants.ND_OOB_PROGRAM: ""}
622 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ndparams=ndparams)
623 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
624 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.NDC_DEFAULTS[constants.ND_OOB_PROGRAM],
625 a794b8d7 Thomas Thrainer
                     self.cluster.ndparams[constants.ND_OOB_PROGRAM])
626 a794b8d7 Thomas Thrainer
627 a794b8d7 Thomas Thrainer
  def testHvState(self):
628 a794b8d7 Thomas Thrainer
    hv_state = {constants.HT_FAKE: {constants.HVST_CPU_TOTAL: 8}}
629 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hv_state=hv_state)
630 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
631 a794b8d7 Thomas Thrainer
    self.assertEqual(8, self.cluster.hv_state_static
632 a794b8d7 Thomas Thrainer
                          [constants.HT_FAKE][constants.HVST_CPU_TOTAL])
633 a794b8d7 Thomas Thrainer
634 a794b8d7 Thomas Thrainer
  def testDiskState(self):
635 a794b8d7 Thomas Thrainer
    disk_state = {
636 0c5f1b13 Thomas Thrainer
      constants.DT_PLAIN: {
637 a794b8d7 Thomas Thrainer
        "mock_vg": {constants.DS_DISK_TOTAL: 10}
638 a794b8d7 Thomas Thrainer
      }
639 a794b8d7 Thomas Thrainer
    }
640 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(disk_state=disk_state)
641 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
642 a794b8d7 Thomas Thrainer
    self.assertEqual(10, self.cluster
643 0c5f1b13 Thomas Thrainer
                           .disk_state_static[constants.DT_PLAIN]["mock_vg"]
644 a794b8d7 Thomas Thrainer
                             [constants.DS_DISK_TOTAL])
645 a794b8d7 Thomas Thrainer
646 a794b8d7 Thomas Thrainer
  def testDefaultIPolicy(self):
647 a794b8d7 Thomas Thrainer
    ipolicy = constants.IPOLICY_DEFAULTS
648 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ipolicy=ipolicy)
649 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
650 a794b8d7 Thomas Thrainer
651 a794b8d7 Thomas Thrainer
  def testIPolicyNewViolation(self):
652 a794b8d7 Thomas Thrainer
    import ganeti.constants as C
653 a794b8d7 Thomas Thrainer
    ipolicy = C.IPOLICY_DEFAULTS
654 a794b8d7 Thomas Thrainer
    ipolicy[C.ISPECS_MINMAX][0][C.ISPECS_MIN][C.ISPEC_MEM_SIZE] = 128
655 a794b8d7 Thomas Thrainer
    ipolicy[C.ISPECS_MINMAX][0][C.ISPECS_MAX][C.ISPEC_MEM_SIZE] = 128
656 a794b8d7 Thomas Thrainer
657 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(beparams={C.BE_MINMEM: 512, C.BE_MAXMEM: 512})
658 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(ipolicy=ipolicy)
659 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
660 a794b8d7 Thomas Thrainer
661 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("instances violate them")
662 a794b8d7 Thomas Thrainer
663 a794b8d7 Thomas Thrainer
  def testNicparamsNoInstance(self):
664 a794b8d7 Thomas Thrainer
    nicparams = {
665 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
666 a794b8d7 Thomas Thrainer
    }
667 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
668 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
669 a794b8d7 Thomas Thrainer
670 a794b8d7 Thomas Thrainer
    self.assertEqual("mock_bridge",
671 a794b8d7 Thomas Thrainer
                     self.cluster.nicparams
672 a794b8d7 Thomas Thrainer
                       [constants.PP_DEFAULT][constants.NIC_LINK])
673 a794b8d7 Thomas Thrainer
674 a794b8d7 Thomas Thrainer
  def testNicparamsInvalidConf(self):
675 a794b8d7 Thomas Thrainer
    nicparams = {
676 850be460 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
677 850be460 Thomas Thrainer
      constants.NIC_LINK: ""
678 a794b8d7 Thomas Thrainer
    }
679 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
680 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectException(op, errors.ConfigurationError, "NIC link")
681 a794b8d7 Thomas Thrainer
682 a794b8d7 Thomas Thrainer
  def testNicparamsInvalidInstanceConf(self):
683 a794b8d7 Thomas Thrainer
    nicparams = {
684 a794b8d7 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
685 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
686 a794b8d7 Thomas Thrainer
    }
687 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(nics=[
688 a794b8d7 Thomas Thrainer
      self.cfg.CreateNic(nicparams={constants.NIC_LINK: None})])
689 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
690 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Missing bridged NIC link")
691 a794b8d7 Thomas Thrainer
692 a794b8d7 Thomas Thrainer
  def testNicparamsMissingIp(self):
693 a794b8d7 Thomas Thrainer
    nicparams = {
694 a794b8d7 Thomas Thrainer
      constants.NIC_MODE: constants.NIC_MODE_ROUTED
695 a794b8d7 Thomas Thrainer
    }
696 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance()
697 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
698 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "routed NIC with no ip address")
699 a794b8d7 Thomas Thrainer
700 a794b8d7 Thomas Thrainer
  def testNicparamsWithInstance(self):
701 a794b8d7 Thomas Thrainer
    nicparams = {
702 a794b8d7 Thomas Thrainer
      constants.NIC_LINK: "mock_bridge"
703 a794b8d7 Thomas Thrainer
    }
704 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance()
705 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(nicparams=nicparams)
706 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
707 a794b8d7 Thomas Thrainer
708 a794b8d7 Thomas Thrainer
  def testDefaultHvparams(self):
709 a794b8d7 Thomas Thrainer
    hvparams = constants.HVC_DEFAULTS
710 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hvparams=hvparams)
711 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
712 a794b8d7 Thomas Thrainer
713 a794b8d7 Thomas Thrainer
    self.assertEqual(hvparams, self.cluster.hvparams)
714 a794b8d7 Thomas Thrainer
715 a794b8d7 Thomas Thrainer
  def testMinimalHvparams(self):
716 a794b8d7 Thomas Thrainer
    hvparams = {
717 a794b8d7 Thomas Thrainer
      constants.HT_FAKE: {
718 a794b8d7 Thomas Thrainer
        constants.HV_MIGRATION_MODE: constants.HT_MIGRATION_NONLIVE
719 a794b8d7 Thomas Thrainer
      }
720 a794b8d7 Thomas Thrainer
    }
721 a794b8d7 Thomas Thrainer
    self.cluster.hvparams = {}
722 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hvparams=hvparams)
723 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
724 a794b8d7 Thomas Thrainer
725 a794b8d7 Thomas Thrainer
    self.assertEqual(hvparams, self.cluster.hvparams)
726 a794b8d7 Thomas Thrainer
727 a794b8d7 Thomas Thrainer
  def testOsHvp(self):
728 a794b8d7 Thomas Thrainer
    os_hvp = {
729 a794b8d7 Thomas Thrainer
      "mocked_os": {
730 a794b8d7 Thomas Thrainer
        constants.HT_FAKE: {
731 a794b8d7 Thomas Thrainer
          constants.HV_MIGRATION_MODE: constants.HT_MIGRATION_NONLIVE
732 a794b8d7 Thomas Thrainer
        }
733 a794b8d7 Thomas Thrainer
      },
734 a794b8d7 Thomas Thrainer
      "other_os": constants.HVC_DEFAULTS
735 a794b8d7 Thomas Thrainer
    }
736 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
737 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
738 a794b8d7 Thomas Thrainer
739 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HT_MIGRATION_NONLIVE,
740 a794b8d7 Thomas Thrainer
                     self.cluster.os_hvp["mocked_os"][constants.HT_FAKE]
741 a794b8d7 Thomas Thrainer
                       [constants.HV_MIGRATION_MODE])
742 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HVC_DEFAULTS, self.cluster.os_hvp["other_os"])
743 a794b8d7 Thomas Thrainer
744 a794b8d7 Thomas Thrainer
  def testRemoveOsHvp(self):
745 a794b8d7 Thomas Thrainer
    os_hvp = {"mocked_os": {constants.HT_FAKE: None}}
746 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
747 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
748 a794b8d7 Thomas Thrainer
749 a794b8d7 Thomas Thrainer
    assert constants.HT_FAKE not in self.cluster.os_hvp["mocked_os"]
750 a794b8d7 Thomas Thrainer
751 a794b8d7 Thomas Thrainer
  def testDefaultOsHvp(self):
752 a794b8d7 Thomas Thrainer
    os_hvp = {"mocked_os": constants.HVC_DEFAULTS.copy()}
753 a794b8d7 Thomas Thrainer
    self.cluster.os_hvp = {"mocked_os": {}}
754 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(os_hvp=os_hvp)
755 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
756 a794b8d7 Thomas Thrainer
757 a794b8d7 Thomas Thrainer
    self.assertEqual(os_hvp, self.cluster.os_hvp)
758 a794b8d7 Thomas Thrainer
759 a794b8d7 Thomas Thrainer
  def testOsparams(self):
760 a794b8d7 Thomas Thrainer
    osparams = {
761 a794b8d7 Thomas Thrainer
      "mocked_os": {
762 a794b8d7 Thomas Thrainer
        "param1": "value1",
763 a794b8d7 Thomas Thrainer
        "param2": None
764 a794b8d7 Thomas Thrainer
      },
765 a794b8d7 Thomas Thrainer
      "other_os": {
766 a794b8d7 Thomas Thrainer
        "param1": None
767 a794b8d7 Thomas Thrainer
      }
768 a794b8d7 Thomas Thrainer
    }
769 a794b8d7 Thomas Thrainer
    self.cluster.osparams = {"other_os": {"param1": "value1"}}
770 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(osparams=osparams)
771 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
772 a794b8d7 Thomas Thrainer
773 a794b8d7 Thomas Thrainer
    self.assertEqual({"mocked_os": {"param1": "value1"}}, self.cluster.osparams)
774 a794b8d7 Thomas Thrainer
775 a794b8d7 Thomas Thrainer
  def testEnabledHypervisors(self):
776 a794b8d7 Thomas Thrainer
    enabled_hypervisors = [constants.HT_XEN_HVM, constants.HT_XEN_PVM]
777 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(enabled_hypervisors=enabled_hypervisors)
778 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
779 a794b8d7 Thomas Thrainer
780 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_hypervisors, self.cluster.enabled_hypervisors)
781 a794b8d7 Thomas Thrainer
782 a794b8d7 Thomas Thrainer
  def testEnabledHypervisorsWithoutHypervisorParams(self):
783 a794b8d7 Thomas Thrainer
    enabled_hypervisors = [constants.HT_FAKE]
784 a794b8d7 Thomas Thrainer
    self.cluster.hvparams = {}
785 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(enabled_hypervisors=enabled_hypervisors)
786 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
787 a794b8d7 Thomas Thrainer
788 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_hypervisors, self.cluster.enabled_hypervisors)
789 a794b8d7 Thomas Thrainer
    self.assertEqual(constants.HVC_DEFAULTS[constants.HT_FAKE],
790 a794b8d7 Thomas Thrainer
                     self.cluster.hvparams[constants.HT_FAKE])
791 a794b8d7 Thomas Thrainer
792 a794b8d7 Thomas Thrainer
  @testutils.patch_object(utils, "FindFile")
793 a794b8d7 Thomas Thrainer
  def testValidDefaultIallocator(self, find_file_mock):
794 a794b8d7 Thomas Thrainer
    find_file_mock.return_value = "/random/path"
795 a794b8d7 Thomas Thrainer
    default_iallocator = "/random/path"
796 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(default_iallocator=default_iallocator)
797 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
798 a794b8d7 Thomas Thrainer
799 a794b8d7 Thomas Thrainer
    self.assertEqual(default_iallocator, self.cluster.default_iallocator)
800 a794b8d7 Thomas Thrainer
801 a794b8d7 Thomas Thrainer
  @testutils.patch_object(utils, "FindFile")
802 a794b8d7 Thomas Thrainer
  def testInvalidDefaultIallocator(self, find_file_mock):
803 a794b8d7 Thomas Thrainer
    find_file_mock.return_value = None
804 a794b8d7 Thomas Thrainer
    default_iallocator = "/random/path"
805 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(default_iallocator=default_iallocator)
806 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Invalid default iallocator script")
807 a794b8d7 Thomas Thrainer
808 a794b8d7 Thomas Thrainer
  def testEnabledDiskTemplates(self):
809 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_DISKLESS, constants.DT_PLAIN]
810 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
811 1583d0e4 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates,
812 1583d0e4 Thomas Thrainer
           ipolicy={constants.IPOLICY_DTS: enabled_disk_templates})
813 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
814 a794b8d7 Thomas Thrainer
815 a794b8d7 Thomas Thrainer
    self.assertEqual(enabled_disk_templates,
816 a794b8d7 Thomas Thrainer
                     self.cluster.enabled_disk_templates)
817 a794b8d7 Thomas Thrainer
818 5859dad6 Helga Velroyen
  def testEnabledDiskTemplatesVsIpolicy(self):
819 5859dad6 Helga Velroyen
    enabled_disk_templates = [constants.DT_DISKLESS, constants.DT_PLAIN]
820 5859dad6 Helga Velroyen
    op = opcodes.OpClusterSetParams(
821 5859dad6 Helga Velroyen
           enabled_disk_templates=enabled_disk_templates,
822 5859dad6 Helga Velroyen
           ipolicy={constants.IPOLICY_DTS: [constants.DT_FILE]})
823 5859dad6 Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(op, "but not enabled on the cluster")
824 5859dad6 Helga Velroyen
825 916c0e6f Helga Velroyen
  def testDisablingDiskTemplatesOfInstances(self):
826 916c0e6f Helga Velroyen
    old_disk_templates = [constants.DT_DISKLESS, constants.DT_PLAIN]
827 916c0e6f Helga Velroyen
    self.cfg.SetEnabledDiskTemplates(old_disk_templates)
828 916c0e6f Helga Velroyen
    self.cfg.AddNewInstance(
829 916c0e6f Helga Velroyen
      disks=[self.cfg.CreateDisk(dev_type=constants.DT_PLAIN)])
830 916c0e6f Helga Velroyen
    new_disk_templates = [constants.DT_DISKLESS, constants.DT_DRBD8]
831 916c0e6f Helga Velroyen
    op = opcodes.OpClusterSetParams(
832 916c0e6f Helga Velroyen
           enabled_disk_templates=new_disk_templates,
833 916c0e6f Helga Velroyen
           ipolicy={constants.IPOLICY_DTS: new_disk_templates})
834 916c0e6f Helga Velroyen
    self.ExecOpCodeExpectOpPrereqError(op, "least one instance using it")
835 916c0e6f Helga Velroyen
836 a794b8d7 Thomas Thrainer
  def testEnabledDiskTemplatesWithoutVgName(self):
837 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_PLAIN]
838 a794b8d7 Thomas Thrainer
    self.cluster.volume_group_name = None
839 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
840 a794b8d7 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates)
841 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "specify a volume group")
842 a794b8d7 Thomas Thrainer
843 a794b8d7 Thomas Thrainer
  def testDisableDiskTemplateWithExistingInstance(self):
844 a794b8d7 Thomas Thrainer
    enabled_disk_templates = [constants.DT_DISKLESS]
845 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(
846 0c5f1b13 Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.DT_PLAIN)])
847 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(
848 1583d0e4 Thomas Thrainer
           enabled_disk_templates=enabled_disk_templates,
849 1583d0e4 Thomas Thrainer
           ipolicy={constants.IPOLICY_DTS: enabled_disk_templates})
850 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot disable disk template")
851 a794b8d7 Thomas Thrainer
852 a794b8d7 Thomas Thrainer
  def testVgNameNoLvmDiskTemplateEnabled(self):
853 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
854 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
855 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
856 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
857 a794b8d7 Thomas Thrainer
858 a794b8d7 Thomas Thrainer
    self.assertEqual(vg_name, self.cluster.volume_group_name)
859 1583d0e4 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
860 a794b8d7 Thomas Thrainer
861 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithLvmDiskTemplateEnabled(self):
862 a794b8d7 Thomas Thrainer
    vg_name = ""
863 a794b8d7 Thomas Thrainer
    self.cluster.enabled_disk_templates = [constants.DT_PLAIN]
864 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
865 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot unset volume group")
866 a794b8d7 Thomas Thrainer
867 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithLvmInstance(self):
868 a794b8d7 Thomas Thrainer
    vg_name = ""
869 a794b8d7 Thomas Thrainer
    self.cfg.AddNewInstance(
870 0c5f1b13 Thomas Thrainer
      disks=[self.cfg.CreateDisk(dev_type=constants.DT_PLAIN)])
871 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
872 1583d0e4 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "Cannot unset volume group")
873 a794b8d7 Thomas Thrainer
874 a794b8d7 Thomas Thrainer
  def testUnsetVgNameWithNoLvmDiskTemplateEnabled(self):
875 a794b8d7 Thomas Thrainer
    vg_name = ""
876 1583d0e4 Thomas Thrainer
    self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
877 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
878 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
879 a794b8d7 Thomas Thrainer
880 a794b8d7 Thomas Thrainer
    self.assertEqual(None, self.cluster.volume_group_name)
881 a794b8d7 Thomas Thrainer
882 a794b8d7 Thomas Thrainer
  def testVgNameToOldName(self):
883 a794b8d7 Thomas Thrainer
    vg_name = self.cluster.volume_group_name
884 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
885 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
886 a794b8d7 Thomas Thrainer
887 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("already in desired state")
888 a794b8d7 Thomas Thrainer
889 a794b8d7 Thomas Thrainer
  def testVgNameWithFailingNode(self):
890 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
891 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
892 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
893 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
894 a794b8d7 Thomas Thrainer
        .AddFailedNode(self.master) \
895 a794b8d7 Thomas Thrainer
        .Build()
896 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
897 a794b8d7 Thomas Thrainer
898 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Error while gathering data on node")
899 a794b8d7 Thomas Thrainer
900 a794b8d7 Thomas Thrainer
  def testVgNameWithValidNode(self):
901 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
902 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
903 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
904 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
905 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, {vg_name: 1024 * 1024}) \
906 a794b8d7 Thomas Thrainer
        .Build()
907 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
908 a794b8d7 Thomas Thrainer
909 a794b8d7 Thomas Thrainer
  def testVgNameWithTooSmallNode(self):
910 a794b8d7 Thomas Thrainer
    vg_name = "test_vg"
911 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(vg_name=vg_name)
912 a794b8d7 Thomas Thrainer
    self.rpc.call_vg_list.return_value = \
913 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
914 a794b8d7 Thomas Thrainer
        .AddSuccessfulNode(self.master, {vg_name: 1}) \
915 a794b8d7 Thomas Thrainer
        .Build()
916 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpPrereqError(op, "too small")
917 a794b8d7 Thomas Thrainer
918 a794b8d7 Thomas Thrainer
  def testMiscParameters(self):
919 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(candidate_pool_size=123,
920 a794b8d7 Thomas Thrainer
                                    maintain_node_health=True,
921 a794b8d7 Thomas Thrainer
                                    modify_etc_hosts=True,
922 a794b8d7 Thomas Thrainer
                                    prealloc_wipe_disks=True,
923 a794b8d7 Thomas Thrainer
                                    reserved_lvs=["/dev/mock_lv"],
924 a794b8d7 Thomas Thrainer
                                    use_external_mip_script=True)
925 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
926 a794b8d7 Thomas Thrainer
927 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogIsEmpty()
928 a794b8d7 Thomas Thrainer
    self.assertEqual(123, self.cluster.candidate_pool_size)
929 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.maintain_node_health)
930 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.modify_etc_hosts)
931 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.prealloc_wipe_disks)
932 a794b8d7 Thomas Thrainer
    self.assertEqual(["/dev/mock_lv"], self.cluster.reserved_lvs)
933 a794b8d7 Thomas Thrainer
    self.assertEqual(True, self.cluster.use_external_mip_script)
934 a794b8d7 Thomas Thrainer
935 a794b8d7 Thomas Thrainer
  def testAddHiddenOs(self):
936 a794b8d7 Thomas Thrainer
    self.cluster.hidden_os = ["hidden1", "hidden2"]
937 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(hidden_os=[(constants.DDM_ADD, "hidden2"),
938 a794b8d7 Thomas Thrainer
                                               (constants.DDM_ADD, "hidden3")])
939 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
940 a794b8d7 Thomas Thrainer
941 a794b8d7 Thomas Thrainer
    self.assertEqual(["hidden1", "hidden2", "hidden3"], self.cluster.hidden_os)
942 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("OS hidden2 already")
943 a794b8d7 Thomas Thrainer
944 a794b8d7 Thomas Thrainer
  def testRemoveBlacklistedOs(self):
945 a794b8d7 Thomas Thrainer
    self.cluster.blacklisted_os = ["blisted1", "blisted2"]
946 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(blacklisted_os=[
947 a794b8d7 Thomas Thrainer
                                      (constants.DDM_REMOVE, "blisted2"),
948 a794b8d7 Thomas Thrainer
                                      (constants.DDM_REMOVE, "blisted3")])
949 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
950 a794b8d7 Thomas Thrainer
951 a794b8d7 Thomas Thrainer
    self.assertEqual(["blisted1"], self.cluster.blacklisted_os)
952 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("OS blisted3 not found")
953 a794b8d7 Thomas Thrainer
954 a794b8d7 Thomas Thrainer
  def testMasterNetdev(self):
955 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
956 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev)
957 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
958 a794b8d7 Thomas Thrainer
959 a794b8d7 Thomas Thrainer
    self.assertEqual(master_netdev, self.cluster.master_netdev)
960 a794b8d7 Thomas Thrainer
961 a794b8d7 Thomas Thrainer
  def testMasterNetdevFailNoForce(self):
962 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
963 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev)
964 a794b8d7 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
965 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
966 a794b8d7 Thomas Thrainer
        .CreateFailedNodeResult(self.master)
967 a794b8d7 Thomas Thrainer
    self.ExecOpCodeExpectOpExecError(op, "Could not disable the master ip")
968 a794b8d7 Thomas Thrainer
969 a794b8d7 Thomas Thrainer
  def testMasterNetdevFailForce(self):
970 a794b8d7 Thomas Thrainer
    master_netdev = "test_dev"
971 a794b8d7 Thomas Thrainer
    op = opcodes.OpClusterSetParams(master_netdev=master_netdev,
972 a794b8d7 Thomas Thrainer
                                    force=True)
973 a794b8d7 Thomas Thrainer
    self.rpc.call_node_deactivate_master_ip.return_value = \
974 a794b8d7 Thomas Thrainer
      self.RpcResultsBuilder() \
975 a794b8d7 Thomas Thrainer
        .CreateFailedNodeResult(self.master)
976 a794b8d7 Thomas Thrainer
    self.ExecOpCode(op)
977 a794b8d7 Thomas Thrainer
978 a794b8d7 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Could not disable the master ip")
979 a794b8d7 Thomas Thrainer
980 a794b8d7 Thomas Thrainer
981 c60f7675 Thomas Thrainer
class TestLUClusterVerify(CmdlibTestCase):
982 c60f7675 Thomas Thrainer
  def testVerifyAllGroups(self):
983 c60f7675 Thomas Thrainer
    op = opcodes.OpClusterVerify()
984 c60f7675 Thomas Thrainer
    result = self.ExecOpCode(op)
985 c60f7675 Thomas Thrainer
986 c60f7675 Thomas Thrainer
    self.assertEqual(2, len(result["jobs"]))
987 c60f7675 Thomas Thrainer
988 c60f7675 Thomas Thrainer
  def testVerifyDefaultGroups(self):
989 c60f7675 Thomas Thrainer
    op = opcodes.OpClusterVerify(group_name="default")
990 c60f7675 Thomas Thrainer
    result = self.ExecOpCode(op)
991 c60f7675 Thomas Thrainer
992 c60f7675 Thomas Thrainer
    self.assertEqual(1, len(result["jobs"]))
993 c60f7675 Thomas Thrainer
994 850be460 Thomas Thrainer
995 850be460 Thomas Thrainer
class TestLUClusterVerifyConfig(CmdlibTestCase):
996 850be460 Thomas Thrainer
997 850be460 Thomas Thrainer
  def setUp(self):
998 850be460 Thomas Thrainer
    super(TestLUClusterVerifyConfig, self).setUp()
999 850be460 Thomas Thrainer
1000 850be460 Thomas Thrainer
    self._load_cert_patcher = testutils \
1001 850be460 Thomas Thrainer
      .patch_object(OpenSSL.crypto, "load_certificate")
1002 850be460 Thomas Thrainer
    self._load_cert_mock = self._load_cert_patcher.start()
1003 850be460 Thomas Thrainer
    self._verify_cert_patcher = testutils \
1004 850be460 Thomas Thrainer
      .patch_object(utils, "VerifyX509Certificate")
1005 850be460 Thomas Thrainer
    self._verify_cert_mock = self._verify_cert_patcher.start()
1006 850be460 Thomas Thrainer
    self._read_file_patcher = testutils.patch_object(utils, "ReadFile")
1007 850be460 Thomas Thrainer
    self._read_file_mock = self._read_file_patcher.start()
1008 850be460 Thomas Thrainer
    self._can_read_patcher = testutils.patch_object(utils, "CanRead")
1009 850be460 Thomas Thrainer
    self._can_read_mock = self._can_read_patcher.start()
1010 850be460 Thomas Thrainer
1011 850be460 Thomas Thrainer
    self._can_read_mock.return_value = True
1012 850be460 Thomas Thrainer
    self._read_file_mock.return_value = True
1013 850be460 Thomas Thrainer
    self._verify_cert_mock.return_value = (None, "")
1014 850be460 Thomas Thrainer
    self._load_cert_mock.return_value = True
1015 850be460 Thomas Thrainer
1016 850be460 Thomas Thrainer
  def tearDown(self):
1017 850be460 Thomas Thrainer
    super(TestLUClusterVerifyConfig, self).tearDown()
1018 850be460 Thomas Thrainer
1019 850be460 Thomas Thrainer
    self._can_read_patcher.stop()
1020 850be460 Thomas Thrainer
    self._read_file_patcher.stop()
1021 850be460 Thomas Thrainer
    self._verify_cert_patcher.stop()
1022 850be460 Thomas Thrainer
    self._load_cert_patcher.stop()
1023 850be460 Thomas Thrainer
1024 850be460 Thomas Thrainer
  def testSuccessfulRun(self):
1025 850be460 Thomas Thrainer
    self.cfg.AddNewInstance()
1026 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
1027 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
1028 850be460 Thomas Thrainer
1029 850be460 Thomas Thrainer
    self.assertTrue(result)
1030 850be460 Thomas Thrainer
1031 850be460 Thomas Thrainer
  def testDanglingNode(self):
1032 850be460 Thomas Thrainer
    node = self.cfg.AddNewNode()
1033 850be460 Thomas Thrainer
    self.cfg.AddNewInstance(primary_node=node)
1034 850be460 Thomas Thrainer
    node.group = "invalid"
1035 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
1036 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
1037 850be460 Thomas Thrainer
1038 850be460 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1039 850be460 Thomas Thrainer
      "following nodes \(and their instances\) belong to a non existing group")
1040 850be460 Thomas Thrainer
    self.assertFalse(result)
1041 850be460 Thomas Thrainer
1042 850be460 Thomas Thrainer
  def testDanglingInstance(self):
1043 850be460 Thomas Thrainer
    inst = self.cfg.AddNewInstance()
1044 850be460 Thomas Thrainer
    inst.primary_node = "invalid"
1045 850be460 Thomas Thrainer
    op = opcodes.OpClusterVerifyConfig()
1046 850be460 Thomas Thrainer
    result = self.ExecOpCode(op)
1047 850be460 Thomas Thrainer
1048 850be460 Thomas Thrainer
    self.mcpu.assertLogContainsRegex(
1049 850be460 Thomas Thrainer
      "following instances have a non-existing primary-node")
1050 850be460 Thomas Thrainer
    self.assertFalse(result)
1051 850be460 Thomas Thrainer
1052 850be460 Thomas Thrainer
1053 b8f45292 Thomas Thrainer
class TestLUClusterVerifyGroup(CmdlibTestCase):
1054 b8f45292 Thomas Thrainer
  def testEmptyNodeGroup(self):
1055 b8f45292 Thomas Thrainer
    group = self.cfg.AddNewNodeGroup()
1056 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name=group.name, verbose=True)
1057 b8f45292 Thomas Thrainer
1058 b8f45292 Thomas Thrainer
    result = self.ExecOpCode(op)
1059 b8f45292 Thomas Thrainer
1060 b8f45292 Thomas Thrainer
    self.assertTrue(result)
1061 b8f45292 Thomas Thrainer
    self.mcpu.assertLogContainsRegex("Empty node group, skipping verification")
1062 b8f45292 Thomas Thrainer
1063 b8f45292 Thomas Thrainer
  def testSimpleInvocation(self):
1064 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1065 9fdb10be Thomas Thrainer
1066 9fdb10be Thomas Thrainer
    self.ExecOpCode(op)
1067 9fdb10be Thomas Thrainer
1068 9fdb10be Thomas Thrainer
  def testSimpleInvocationWithInstance(self):
1069 9fdb10be Thomas Thrainer
    self.cfg.AddNewInstance(disks=[])
1070 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1071 9fdb10be Thomas Thrainer
1072 9fdb10be Thomas Thrainer
    self.ExecOpCode(op)
1073 9fdb10be Thomas Thrainer
1074 9fdb10be Thomas Thrainer
  def testGhostNode(self):
1075 9fdb10be Thomas Thrainer
    group = self.cfg.AddNewNodeGroup()
1076 9fdb10be Thomas Thrainer
    node = self.cfg.AddNewNode(group=group.uuid, offline=True)
1077 9fdb10be Thomas Thrainer
    self.master.offline = True
1078 9fdb10be Thomas Thrainer
    self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
1079 9fdb10be Thomas Thrainer
                            primary_node=self.master,
1080 9fdb10be Thomas Thrainer
                            secondary_node=node)
1081 9fdb10be Thomas Thrainer
1082 9fdb10be Thomas Thrainer
    self.rpc.call_blockdev_getmirrorstatus_multi.return_value = \
1083 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
1084 9fdb10be Thomas Thrainer
        .AddOfflineNode(self.master) \
1085 9fdb10be Thomas Thrainer
        .Build()
1086 9fdb10be Thomas Thrainer
1087 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1088 9fdb10be Thomas Thrainer
1089 9fdb10be Thomas Thrainer
    self.ExecOpCode(op)
1090 9fdb10be Thomas Thrainer
1091 9fdb10be Thomas Thrainer
  def testValidRpcResult(self):
1092 9fdb10be Thomas Thrainer
    self.cfg.AddNewInstance(disks=[])
1093 9fdb10be Thomas Thrainer
1094 9fdb10be Thomas Thrainer
    self.rpc.call_node_verify.return_value = \
1095 9fdb10be Thomas Thrainer
      RpcResultsBuilder() \
1096 9fdb10be Thomas Thrainer
        .AddSuccessfulNode(self.master, {}) \
1097 9fdb10be Thomas Thrainer
        .Build()
1098 9fdb10be Thomas Thrainer
1099 9fdb10be Thomas Thrainer
    op = opcodes.OpClusterVerifyGroup(group_name="default", verbose=True)
1100 b8f45292 Thomas Thrainer
1101 b8f45292 Thomas Thrainer
    self.ExecOpCode(op)
1102 b8f45292 Thomas Thrainer
1103 b8f45292 Thomas Thrainer
1104 b8f45292 Thomas Thrainer
class TestLUClusterVerifyGroupMethods(CmdlibTestCase):
1105 b8f45292 Thomas Thrainer
  """Base class for testing individual methods in LUClusterVerifyGroup.
1106 b8f45292 Thomas Thrainer

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