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