Revision 2f4b4f78
b/qa/qa_cluster.py | ||
---|---|---|
32 | 32 |
import qa_utils |
33 | 33 |
import qa_error |
34 | 34 |
|
35 |
from qa_utils import AssertEqual, AssertNotEqual, StartSSH
|
|
35 |
from qa_utils import AssertEqual, AssertCommand
|
|
36 | 36 |
|
37 | 37 |
|
38 | 38 |
def _RemoveFileFromAllNodes(filename): |
39 | 39 |
"""Removes a file from all nodes. |
40 | 40 |
|
41 | 41 |
""" |
42 |
for node in qa_config.get('nodes'): |
|
43 |
cmd = ['rm', '-f', filename] |
|
44 |
AssertEqual(StartSSH(node['primary'], |
|
45 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
42 |
for node in qa_config.get("nodes"): |
|
43 |
AssertCommand(["rm", "-f", filename], node=node) |
|
46 | 44 |
|
47 | 45 |
|
48 | 46 |
def _CheckFileOnAllNodes(filename, content): |
... | ... | |
50 | 48 |
|
51 | 49 |
""" |
52 | 50 |
cmd = utils.ShellQuoteArgs(["cat", filename]) |
53 |
for node in qa_config.get('nodes'): |
|
54 |
AssertEqual(qa_utils.GetCommandOutput(node['primary'], cmd), |
|
55 |
content) |
|
51 |
for node in qa_config.get("nodes"): |
|
52 |
AssertEqual(qa_utils.GetCommandOutput(node["primary"], cmd), content) |
|
56 | 53 |
|
57 | 54 |
|
58 | 55 |
def TestClusterInit(rapi_user, rapi_secret): |
... | ... | |
67 | 64 |
|
68 | 65 |
tmpru = qa_utils.UploadFile(master["primary"], fh.name) |
69 | 66 |
try: |
70 |
cmd = ["mv", tmpru, constants.RAPI_USERS_FILE] |
|
71 |
AssertEqual(StartSSH(master["primary"], |
|
72 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
67 |
AssertCommand(["mv", tmpru, constants.RAPI_USERS_FILE]) |
|
73 | 68 |
finally: |
74 |
cmd = ["rm", "-f", tmpru] |
|
75 |
AssertEqual(StartSSH(master["primary"], |
|
76 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
69 |
AssertCommand(["rm", "-f", tmpru]) |
|
77 | 70 |
finally: |
78 | 71 |
fh.close() |
79 | 72 |
|
... | ... | |
97 | 90 |
|
98 | 91 |
cmd.append(qa_config.get('name')) |
99 | 92 |
|
100 |
AssertEqual(StartSSH(master['primary'], |
|
101 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
93 |
AssertCommand(cmd) |
|
102 | 94 |
|
103 | 95 |
|
104 | 96 |
def TestClusterRename(): |
105 | 97 |
"""gnt-cluster rename""" |
106 |
master = qa_config.GetMasterNode() |
|
107 |
|
|
108 | 98 |
cmd = ['gnt-cluster', 'rename', '-f'] |
109 | 99 |
|
110 | 100 |
original_name = qa_config.get('name') |
... | ... | |
113 | 103 |
print qa_utils.FormatError('"rename" entry is missing') |
114 | 104 |
return |
115 | 105 |
|
116 |
cmd_1 = cmd + [rename_target] |
|
117 |
cmd_2 = cmd + [original_name] |
|
118 |
|
|
119 | 106 |
cmd_verify = ['gnt-cluster', 'verify'] |
120 | 107 |
|
121 |
AssertEqual(StartSSH(master['primary'], |
|
122 |
utils.ShellQuoteArgs(cmd_1)).wait(), 0) |
|
123 |
|
|
124 |
AssertEqual(StartSSH(master['primary'], |
|
125 |
utils.ShellQuoteArgs(cmd_verify)).wait(), 0) |
|
126 |
|
|
127 |
AssertEqual(StartSSH(master['primary'], |
|
128 |
utils.ShellQuoteArgs(cmd_2)).wait(), 0) |
|
129 |
|
|
130 |
AssertEqual(StartSSH(master['primary'], |
|
131 |
utils.ShellQuoteArgs(cmd_verify)).wait(), 0) |
|
108 |
for data in [ |
|
109 |
cmd + [rename_target], |
|
110 |
cmd_verify, |
|
111 |
cmd + [original_name], |
|
112 |
cmd_verify, |
|
113 |
]: |
|
114 |
AssertCommand(data) |
|
132 | 115 |
|
133 | 116 |
|
134 | 117 |
def TestClusterVerify(): |
135 | 118 |
"""gnt-cluster verify""" |
136 |
master = qa_config.GetMasterNode() |
|
137 |
|
|
138 |
cmd = ['gnt-cluster', 'verify'] |
|
139 |
AssertEqual(StartSSH(master['primary'], |
|
140 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
119 |
AssertCommand(["gnt-cluster", "verify"]) |
|
141 | 120 |
|
142 | 121 |
|
143 | 122 |
def TestJobqueue(): |
144 | 123 |
"""gnt-debug test-jobqueue""" |
145 |
master = qa_config.GetMasterNode() |
|
146 |
|
|
147 |
cmd = ["gnt-debug", "test-jobqueue"] |
|
148 |
AssertEqual(StartSSH(master["primary"], |
|
149 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
124 |
AssertCommand(["gnt-debug", "test-jobqueue"]) |
|
150 | 125 |
|
151 | 126 |
|
152 | 127 |
def TestClusterReservedLvs(): |
153 | 128 |
"""gnt-cluster reserved lvs""" |
154 |
master = qa_config.GetMasterNode() |
|
155 |
CVERIFY = ['gnt-cluster', 'verify'] |
|
156 |
for rcode, cmd in [ |
|
157 |
(0, CVERIFY), |
|
158 |
(0, ['gnt-cluster', 'modify', '--reserved-lvs', '']), |
|
159 |
(0, ['lvcreate', '-L1G', '-nqa-test', 'xenvg']), |
|
160 |
(1, CVERIFY), |
|
161 |
(0, ['gnt-cluster', 'modify', '--reserved-lvs', 'qa-test,other-test']), |
|
162 |
(0, CVERIFY), |
|
163 |
(0, ['gnt-cluster', 'modify', '--reserved-lvs', 'qa-.*']), |
|
164 |
(0, CVERIFY), |
|
165 |
(0, ['gnt-cluster', 'modify', '--reserved-lvs', '']), |
|
166 |
(1, CVERIFY), |
|
167 |
(0, ['lvremove', '-f', 'xenvg/qa-test']), |
|
168 |
(0, CVERIFY), |
|
129 |
CVERIFY = ["gnt-cluster", "verify"] |
|
130 |
for fail, cmd in [ |
|
131 |
(False, CVERIFY), |
|
132 |
(False, ["gnt-cluster", "modify", "--reserved-lvs", ""]), |
|
133 |
(False, ["lvcreate", "-L1G", "-nqa-test", "xenvg"]), |
|
134 |
(True, CVERIFY), |
|
135 |
(False, ["gnt-cluster", "modify", "--reserved-lvs", "qa-test,other-test"]), |
|
136 |
(False, CVERIFY), |
|
137 |
(False, ["gnt-cluster", "modify", "--reserved-lvs", "qa-.*"]), |
|
138 |
(False, CVERIFY), |
|
139 |
(False, ["gnt-cluster", "modify", "--reserved-lvs", ""]), |
|
140 |
(True, CVERIFY), |
|
141 |
(False, ["lvremove", "-f", "xenvg/qa-test"]), |
|
142 |
(False, CVERIFY), |
|
169 | 143 |
]: |
170 |
AssertEqual(StartSSH(master['primary'], |
|
171 |
utils.ShellQuoteArgs(cmd)).wait(), rcode) |
|
144 |
AssertCommand(cmd, fail=fail) |
|
172 | 145 |
|
173 | 146 |
|
174 | 147 |
def TestClusterModifyBe(): |
175 | 148 |
"""gnt-cluster modify -B""" |
176 |
master = qa_config.GetMasterNode() |
|
177 |
|
|
178 |
for rcode, cmd in [ |
|
149 |
for fail, cmd in [ |
|
179 | 150 |
# mem |
180 |
(0, ["gnt-cluster", "modify", "-B", "memory=256"]),
|
|
181 |
(0, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 256$'"]),
|
|
182 |
(1, ["gnt-cluster", "modify", "-B", "memory=a"]),
|
|
183 |
(0, ["gnt-cluster", "modify", "-B", "memory=128"]),
|
|
184 |
(0, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 128$'"]),
|
|
151 |
(False, ["gnt-cluster", "modify", "-B", "memory=256"]),
|
|
152 |
(False, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 256$'"]),
|
|
153 |
(True, ["gnt-cluster", "modify", "-B", "memory=a"]),
|
|
154 |
(False, ["gnt-cluster", "modify", "-B", "memory=128"]),
|
|
155 |
(False, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 128$'"]),
|
|
185 | 156 |
# vcpus |
186 |
(0, ["gnt-cluster", "modify", "-B", "vcpus=4"]),
|
|
187 |
(0, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 4$'"]),
|
|
188 |
(1, ["gnt-cluster", "modify", "-B", "vcpus=a"]),
|
|
189 |
(0, ["gnt-cluster", "modify", "-B", "vcpus=1"]),
|
|
190 |
(0, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 1$'"]),
|
|
157 |
(False, ["gnt-cluster", "modify", "-B", "vcpus=4"]),
|
|
158 |
(False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 4$'"]),
|
|
159 |
(True, ["gnt-cluster", "modify", "-B", "vcpus=a"]),
|
|
160 |
(False, ["gnt-cluster", "modify", "-B", "vcpus=1"]),
|
|
161 |
(False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 1$'"]),
|
|
191 | 162 |
# auto_balance |
192 |
(0, ["gnt-cluster", "modify", "-B", "auto_balance=False"]),
|
|
193 |
(0, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: False$'"]),
|
|
194 |
(1, ["gnt-cluster", "modify", "-B", "auto_balance=1"]),
|
|
195 |
(0, ["gnt-cluster", "modify", "-B", "auto_balance=True"]),
|
|
196 |
(0, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: True$'"]),
|
|
163 |
(False, ["gnt-cluster", "modify", "-B", "auto_balance=False"]),
|
|
164 |
(False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: False$'"]),
|
|
165 |
(True, ["gnt-cluster", "modify", "-B", "auto_balance=1"]),
|
|
166 |
(False, ["gnt-cluster", "modify", "-B", "auto_balance=True"]),
|
|
167 |
(False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: True$'"]),
|
|
197 | 168 |
]: |
198 |
AssertEqual(StartSSH(master['primary'], |
|
199 |
utils.ShellQuoteArgs(cmd)).wait(), rcode) |
|
169 |
AssertCommand(cmd, fail=fail) |
|
200 | 170 |
|
201 | 171 |
|
202 | 172 |
def TestClusterInfo(): |
203 | 173 |
"""gnt-cluster info""" |
204 |
master = qa_config.GetMasterNode() |
|
205 |
|
|
206 |
cmd = ['gnt-cluster', 'info'] |
|
207 |
AssertEqual(StartSSH(master['primary'], |
|
208 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
174 |
AssertCommand(["gnt-cluster", "info"]) |
|
209 | 175 |
|
210 | 176 |
|
211 | 177 |
def TestClusterGetmaster(): |
212 | 178 |
"""gnt-cluster getmaster""" |
213 |
master = qa_config.GetMasterNode() |
|
214 |
|
|
215 |
cmd = ['gnt-cluster', 'getmaster'] |
|
216 |
AssertEqual(StartSSH(master['primary'], |
|
217 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
179 |
AssertCommand(["gnt-cluster", "getmaster"]) |
|
218 | 180 |
|
219 | 181 |
|
220 | 182 |
def TestClusterVersion(): |
221 | 183 |
"""gnt-cluster version""" |
222 |
master = qa_config.GetMasterNode() |
|
223 |
|
|
224 |
cmd = ['gnt-cluster', 'version'] |
|
225 |
AssertEqual(StartSSH(master['primary'], |
|
226 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
184 |
AssertCommand(["gnt-cluster", "version"]) |
|
227 | 185 |
|
228 | 186 |
|
229 | 187 |
def TestClusterRenewCrypto(): |
... | ... | |
238 | 196 |
["--new-cluster-domain-secret", "--cluster-domain-secret=/dev/null"], |
239 | 197 |
] |
240 | 198 |
for i in conflicting: |
241 |
AssertNotEqual(StartSSH(master["primary"], |
|
242 |
utils.ShellQuoteArgs(cmd + i)).wait(), 0) |
|
199 |
AssertCommand(cmd+i, fail=True) |
|
243 | 200 |
|
244 | 201 |
# Invalid RAPI certificate |
245 | 202 |
cmd = ["gnt-cluster", "renew-crypto", "--force", |
246 | 203 |
"--rapi-certificate=/dev/null"] |
247 |
AssertNotEqual(StartSSH(master["primary"], |
|
248 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
204 |
AssertCommand(cmd, fail=True) |
|
249 | 205 |
|
250 | 206 |
rapi_cert_backup = qa_utils.BackupFile(master["primary"], |
251 | 207 |
constants.RAPI_CERT_FILE) |
... | ... | |
260 | 216 |
|
261 | 217 |
tmpcert = qa_utils.UploadFile(master["primary"], fh.name) |
262 | 218 |
try: |
263 |
cmd = ["gnt-cluster", "renew-crypto", "--force", |
|
264 |
"--rapi-certificate=%s" % tmpcert] |
|
265 |
AssertEqual(StartSSH(master["primary"], |
|
266 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
219 |
AssertCommand(["gnt-cluster", "renew-crypto", "--force", |
|
220 |
"--rapi-certificate=%s" % tmpcert]) |
|
267 | 221 |
finally: |
268 |
cmd = ["rm", "-f", tmpcert] |
|
269 |
AssertEqual(StartSSH(master["primary"], |
|
270 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
222 |
AssertCommand(["rm", "-f", tmpcert]) |
|
271 | 223 |
|
272 | 224 |
# Custom cluster domain secret |
273 | 225 |
cds_fh = tempfile.NamedTemporaryFile() |
... | ... | |
277 | 229 |
|
278 | 230 |
tmpcds = qa_utils.UploadFile(master["primary"], cds_fh.name) |
279 | 231 |
try: |
280 |
cmd = ["gnt-cluster", "renew-crypto", "--force", |
|
281 |
"--cluster-domain-secret=%s" % tmpcds] |
|
282 |
AssertEqual(StartSSH(master["primary"], |
|
283 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
232 |
AssertCommand(["gnt-cluster", "renew-crypto", "--force", |
|
233 |
"--cluster-domain-secret=%s" % tmpcds]) |
|
284 | 234 |
finally: |
285 |
cmd = ["rm", "-f", tmpcds] |
|
286 |
AssertEqual(StartSSH(master["primary"], |
|
287 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
235 |
AssertCommand(["rm", "-f", tmpcds]) |
|
288 | 236 |
|
289 | 237 |
# Normal case |
290 |
cmd = ["gnt-cluster", "renew-crypto", "--force", |
|
291 |
"--new-cluster-certificate", "--new-confd-hmac-key", |
|
292 |
"--new-rapi-certificate", "--new-cluster-domain-secret"] |
|
293 |
AssertEqual(StartSSH(master["primary"], |
|
294 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
238 |
AssertCommand(["gnt-cluster", "renew-crypto", "--force", |
|
239 |
"--new-cluster-certificate", "--new-confd-hmac-key", |
|
240 |
"--new-rapi-certificate", "--new-cluster-domain-secret"]) |
|
295 | 241 |
|
296 | 242 |
# Restore RAPI certificate |
297 |
cmd = ["gnt-cluster", "renew-crypto", "--force", |
|
298 |
"--rapi-certificate=%s" % rapi_cert_backup] |
|
299 |
AssertEqual(StartSSH(master["primary"], |
|
300 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
243 |
AssertCommand(["gnt-cluster", "renew-crypto", "--force", |
|
244 |
"--rapi-certificate=%s" % rapi_cert_backup]) |
|
301 | 245 |
finally: |
302 |
cmd = ["rm", "-f", rapi_cert_backup] |
|
303 |
AssertEqual(StartSSH(master["primary"], |
|
304 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
246 |
AssertCommand(["rm", "-f", rapi_cert_backup]) |
|
305 | 247 |
|
306 | 248 |
|
307 | 249 |
def TestClusterBurnin(): |
... | ... | |
349 | 291 |
else: |
350 | 292 |
cmd.append('--reboot-types=%s' % ",".join(reboot_types)) |
351 | 293 |
cmd += [inst['name'] for inst in instances] |
352 |
AssertEqual(StartSSH(master['primary'], |
|
353 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
294 |
AssertCommand(cmd) |
|
354 | 295 |
finally: |
355 |
cmd = ['rm', '-f', script] |
|
356 |
AssertEqual(StartSSH(master['primary'], |
|
357 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
296 |
AssertCommand(["rm", "-f", script]) |
|
297 |
|
|
358 | 298 |
finally: |
359 | 299 |
for inst in instances: |
360 | 300 |
qa_config.ReleaseInstance(inst) |
... | ... | |
363 | 303 |
def TestClusterMasterFailover(): |
364 | 304 |
"""gnt-cluster master-failover""" |
365 | 305 |
master = qa_config.GetMasterNode() |
366 |
|
|
367 | 306 |
failovermaster = qa_config.AcquireNode(exclude=master) |
368 |
try: |
|
369 |
cmd = ['gnt-cluster', 'master-failover'] |
|
370 |
AssertEqual(StartSSH(failovermaster['primary'], |
|
371 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
372 | 307 |
|
373 |
cmd = ['gnt-cluster', 'master-failover'] |
|
374 |
AssertEqual(StartSSH(master['primary'], |
|
375 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
308 |
cmd = ["gnt-cluster", "master-failover"] |
|
309 |
try: |
|
310 |
AssertCommand(cmd, node=failovermaster) |
|
311 |
AssertCommand(cmd, node=master) |
|
376 | 312 |
finally: |
377 | 313 |
qa_config.ReleaseNode(failovermaster) |
378 | 314 |
|
... | ... | |
393 | 329 |
testname = qa_utils.UploadFile(master['primary'], f.name) |
394 | 330 |
try: |
395 | 331 |
# Copy file to all nodes |
396 |
cmd = ['gnt-cluster', 'copyfile', testname] |
|
397 |
AssertEqual(StartSSH(master['primary'], |
|
398 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
332 |
AssertCommand(["gnt-cluster", "copyfile", testname]) |
|
399 | 333 |
_CheckFileOnAllNodes(testname, uniqueid) |
400 | 334 |
finally: |
401 | 335 |
_RemoveFileFromAllNodes(testname) |
... | ... | |
403 | 337 |
|
404 | 338 |
def TestClusterCommand(): |
405 | 339 |
"""gnt-cluster command""" |
406 |
master = qa_config.GetMasterNode() |
|
407 |
|
|
408 | 340 |
uniqueid = utils.NewUUID() |
409 | 341 |
rfile = "/tmp/gnt%s" % utils.NewUUID() |
410 | 342 |
rcmd = utils.ShellQuoteArgs(['echo', '-n', uniqueid]) |
... | ... | |
412 | 344 |
"%s >%s" % (rcmd, rfile)]) |
413 | 345 |
|
414 | 346 |
try: |
415 |
AssertEqual(StartSSH(master['primary'], cmd).wait(), 0)
|
|
347 |
AssertCommand(cmd)
|
|
416 | 348 |
_CheckFileOnAllNodes(rfile, uniqueid) |
417 | 349 |
finally: |
418 | 350 |
_RemoveFileFromAllNodes(rfile) |
... | ... | |
420 | 352 |
|
421 | 353 |
def TestClusterDestroy(): |
422 | 354 |
"""gnt-cluster destroy""" |
423 |
master = qa_config.GetMasterNode() |
|
424 |
|
|
425 |
cmd = ['gnt-cluster', 'destroy', '--yes-do-it'] |
|
426 |
AssertEqual(StartSSH(master['primary'], |
|
427 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
355 |
AssertCommand(["gnt-cluster", "destroy", "--yes-do-it"]) |
b/qa/qa_daemon.py | ||
---|---|---|
32 | 32 |
import qa_utils |
33 | 33 |
import qa_error |
34 | 34 |
|
35 |
from qa_utils import AssertEqual, AssertMatch, StartSSH, GetCommandOutput
|
|
35 |
from qa_utils import AssertMatch, AssertCommand, StartSSH, GetCommandOutput
|
|
36 | 36 |
|
37 | 37 |
|
38 | 38 |
def _InstanceRunning(node, name): |
39 | 39 |
"""Checks whether an instance is running. |
40 | 40 |
|
41 |
Args:
|
|
42 |
node: Node the instance runs on
|
|
43 |
name: Full name of Xen instance |
|
41 |
@param node: node the instance runs on
|
|
42 |
@param name: full name of the Xen instance
|
|
43 |
|
|
44 | 44 |
""" |
45 | 45 |
cmd = utils.ShellQuoteArgs(['xm', 'list', name]) + ' >/dev/null' |
46 | 46 |
ret = StartSSH(node['primary'], cmd).wait() |
... | ... | |
50 | 50 |
def _XmShutdownInstance(node, name): |
51 | 51 |
"""Shuts down instance using "xm" and waits for completion. |
52 | 52 |
|
53 |
Args: |
|
54 |
node: Node the instance runs on |
|
55 |
name: Full name of Xen instance |
|
56 |
""" |
|
57 |
master = qa_config.GetMasterNode() |
|
53 |
@param node: node the instance runs on |
|
54 |
@param name: full name of Xen instance |
|
58 | 55 |
|
59 |
cmd = ['xm', 'shutdown', name] |
|
60 |
AssertEqual(StartSSH(node['primary'], |
|
61 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
56 |
""" |
|
57 |
AssertCommand(["xm", "shutdown", name], node=node) |
|
62 | 58 |
|
63 | 59 |
# Wait up to a minute |
64 | 60 |
end = time.time() + 60 |
... | ... | |
73 | 69 |
def _ResetWatcherDaemon(): |
74 | 70 |
"""Removes the watcher daemon's state file. |
75 | 71 |
|
76 |
Args: |
|
77 |
node: Node to be reset |
|
78 | 72 |
""" |
79 |
master = qa_config.GetMasterNode() |
|
80 |
|
|
81 |
cmd = ['rm', '-f', constants.WATCHER_STATEFILE] |
|
82 |
AssertEqual(StartSSH(master['primary'], |
|
83 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
73 |
AssertCommand(["rm", "-f", constants.WATCHER_STATEFILE]) |
|
84 | 74 |
|
85 | 75 |
|
86 | 76 |
def _RunWatcherDaemon(): |
87 | 77 |
"""Runs the ganeti-watcher daemon on the master node. |
88 | 78 |
|
89 | 79 |
""" |
90 |
master = qa_config.GetMasterNode() |
|
91 |
|
|
92 |
cmd = ["ganeti-watcher", "-d", "--ignore-pause"] |
|
93 |
AssertEqual(StartSSH(master["primary"], |
|
94 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
80 |
AssertCommand(["ganeti-watcher", "-d", "--ignore-pause"]) |
|
95 | 81 |
|
96 | 82 |
|
97 | 83 |
def TestPauseWatcher(): |
... | ... | |
100 | 86 |
""" |
101 | 87 |
master = qa_config.GetMasterNode() |
102 | 88 |
|
103 |
cmd = ["gnt-cluster", "watcher", "pause", "4h"] |
|
104 |
AssertEqual(StartSSH(master["primary"], |
|
105 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
89 |
AssertCommand(["gnt-cluster", "watcher", "pause", "4h"]) |
|
106 | 90 |
|
107 | 91 |
cmd = ["gnt-cluster", "watcher", "info"] |
108 | 92 |
output = GetCommandOutput(master["primary"], |
... | ... | |
116 | 100 |
""" |
117 | 101 |
master = qa_config.GetMasterNode() |
118 | 102 |
|
119 |
cmd = ["gnt-cluster", "watcher", "continue"] |
|
120 |
AssertEqual(StartSSH(master["primary"], |
|
121 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
103 |
AssertCommand(["gnt-cluster", "watcher", "continue"]) |
|
122 | 104 |
|
123 | 105 |
cmd = ["gnt-cluster", "watcher", "info"] |
124 | 106 |
output = GetCommandOutput(master["primary"], |
... | ... | |
130 | 112 |
"""Test automatic restart of instance by ganeti-watcher. |
131 | 113 |
|
132 | 114 |
""" |
133 |
master = qa_config.GetMasterNode() |
|
134 | 115 |
inst_name = qa_utils.ResolveInstanceName(instance["name"]) |
135 | 116 |
|
136 | 117 |
_ResetWatcherDaemon() |
... | ... | |
142 | 123 |
if not _InstanceRunning(node, inst_name): |
143 | 124 |
raise qa_error.Error("Daemon didn't restart instance") |
144 | 125 |
|
145 |
cmd = ['gnt-instance', 'info', inst_name] |
|
146 |
AssertEqual(StartSSH(master['primary'], |
|
147 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
126 |
AssertCommand(["gnt-instance", "info", inst_name]) |
|
148 | 127 |
|
149 | 128 |
|
150 | 129 |
def TestInstanceConsecutiveFailures(node, instance): |
151 | 130 |
"""Test five consecutive instance failures. |
152 | 131 |
|
153 | 132 |
""" |
154 |
master = qa_config.GetMasterNode() |
|
155 | 133 |
inst_name = qa_utils.ResolveInstanceName(instance["name"]) |
156 | 134 |
|
157 | 135 |
_ResetWatcherDaemon() |
... | ... | |
168 | 146 |
msg = "Instance started when it shouldn't" |
169 | 147 |
raise qa_error.Error(msg) |
170 | 148 |
|
171 |
cmd = ['gnt-instance', 'info', inst_name] |
|
172 |
AssertEqual(StartSSH(master['primary'], |
|
173 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
149 |
AssertCommand(["gnt-instance", "info", inst_name]) |
b/qa/qa_env.py | ||
---|---|---|
26 | 26 |
from ganeti import utils |
27 | 27 |
|
28 | 28 |
import qa_config |
29 |
import qa_utils |
|
30 | 29 |
|
31 |
from qa_utils import AssertEqual, StartSSH
|
|
30 |
from qa_utils import AssertCommand
|
|
32 | 31 |
|
33 | 32 |
|
34 | 33 |
def TestSshConnection(): |
35 | 34 |
"""Test SSH connection. |
36 | 35 |
|
37 | 36 |
""" |
38 |
for node in qa_config.get('nodes'):
|
|
39 |
AssertEqual(StartSSH(node['primary'], 'exit').wait(), 0)
|
|
37 |
for node in qa_config.get("nodes"):
|
|
38 |
AssertCommand("exit", node=node)
|
|
40 | 39 |
|
41 | 40 |
|
42 | 41 |
def TestGanetiCommands(): |
... | ... | |
60 | 59 |
cmd = ' && '.join([utils.ShellQuoteArgs(i) for i in cmds]) |
61 | 60 |
|
62 | 61 |
for node in qa_config.get('nodes'): |
63 |
AssertEqual(StartSSH(node['primary'], cmd).wait(), 0)
|
|
62 |
AssertCommand(cmd, node=node)
|
|
64 | 63 |
|
65 | 64 |
|
66 | 65 |
def TestIcmpPing(): |
... | ... | |
74 | 73 |
if qa_config.get("primary_ip_version") == 6: |
75 | 74 |
pingprimary = "ping6" |
76 | 75 |
|
77 |
for node in nodes: |
|
78 |
check = [] |
|
79 |
for i in nodes: |
|
80 |
cmd = [pingprimary] + pingargs + [i['primary']] |
|
76 |
check = [] |
|
77 |
for i in nodes: |
|
78 |
cmd = [pingprimary] + pingargs + [i["primary"]] |
|
79 |
check.append(utils.ShellQuoteArgs(cmd)) |
|
80 |
if i.has_key("secondary"): |
|
81 |
cmd = ["ping"] + pingargs + [i["secondary"]] |
|
81 | 82 |
check.append(utils.ShellQuoteArgs(cmd)) |
82 |
if i.has_key('secondary'): |
|
83 |
cmd = ["ping"] + pingargs + [i["secondary"]] |
|
84 |
check.append(utils.ShellQuoteArgs(cmd)) |
|
83 |
cmdall = " && ".join(check) |
|
85 | 84 |
|
86 |
cmdall = ' && '.join(check) |
|
87 |
AssertEqual(StartSSH(node['primary'], cmdall).wait(), 0) |
|
85 |
for node in nodes: |
|
86 |
AssertCommand(cmdall, node=node) |
b/qa/qa_instance.py | ||
---|---|---|
33 | 33 |
import qa_utils |
34 | 34 |
import qa_error |
35 | 35 |
|
36 |
from qa_utils import AssertEqual, AssertNotEqual, AssertIn, StartSSH
|
|
36 |
from qa_utils import AssertIn, AssertCommand
|
|
37 | 37 |
|
38 | 38 |
|
39 | 39 |
def _GetDiskStatePath(disk): |
... | ... | |
48 | 48 |
|
49 | 49 |
|
50 | 50 |
def _DiskTest(node, disk_template): |
51 |
master = qa_config.GetMasterNode() |
|
52 |
|
|
53 | 51 |
instance = qa_config.AcquireInstance() |
54 | 52 |
try: |
55 | 53 |
cmd = (['gnt-instance', 'add', |
... | ... | |
59 | 57 |
_GetGenericAddParameters()) |
60 | 58 |
cmd.append(instance['name']) |
61 | 59 |
|
62 |
AssertEqual(StartSSH(master['primary'], |
|
63 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
60 |
AssertCommand(cmd) |
|
64 | 61 |
|
65 | 62 |
_CheckSsconfInstanceList(instance["name"]) |
66 | 63 |
|
... | ... | |
83 | 80 |
|
84 | 81 |
def TestInstanceRemove(instance): |
85 | 82 |
"""gnt-instance remove""" |
86 |
master = qa_config.GetMasterNode() |
|
87 |
|
|
88 |
cmd = ['gnt-instance', 'remove', '-f', instance['name']] |
|
89 |
AssertEqual(StartSSH(master['primary'], |
|
90 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
83 |
AssertCommand(["gnt-instance", "remove", "-f", instance["name"]]) |
|
91 | 84 |
|
92 | 85 |
qa_config.ReleaseInstance(instance) |
93 | 86 |
|
94 | 87 |
|
95 | 88 |
def TestInstanceStartup(instance): |
96 | 89 |
"""gnt-instance startup""" |
97 |
master = qa_config.GetMasterNode() |
|
98 |
|
|
99 |
cmd = ['gnt-instance', 'startup', instance['name']] |
|
100 |
AssertEqual(StartSSH(master['primary'], |
|
101 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
90 |
AssertCommand(["gnt-instance", "startup", instance["name"]]) |
|
102 | 91 |
|
103 | 92 |
|
104 | 93 |
def TestInstanceShutdown(instance): |
105 | 94 |
"""gnt-instance shutdown""" |
106 |
master = qa_config.GetMasterNode() |
|
107 |
|
|
108 |
cmd = ['gnt-instance', 'shutdown', instance['name']] |
|
109 |
AssertEqual(StartSSH(master['primary'], |
|
110 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
95 |
AssertCommand(["gnt-instance", "shutdown", instance["name"]]) |
|
111 | 96 |
|
112 | 97 |
|
113 | 98 |
def TestInstanceReboot(instance): |
114 | 99 |
"""gnt-instance reboot""" |
115 |
master = qa_config.GetMasterNode() |
|
116 |
|
|
117 | 100 |
options = qa_config.get('options', {}) |
118 | 101 |
reboot_types = options.get("reboot-types", constants.REBOOT_TYPES) |
119 |
|
|
102 |
name = instance["name"] |
|
120 | 103 |
for rtype in reboot_types: |
121 |
cmd = ['gnt-instance', 'reboot', '--type=%s' % rtype, instance['name']] |
|
122 |
AssertEqual(StartSSH(master['primary'], |
|
123 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
104 |
AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name]) |
|
124 | 105 |
|
125 | 106 |
|
126 | 107 |
def TestInstanceReinstall(instance): |
127 | 108 |
"""gnt-instance reinstall""" |
128 |
master = qa_config.GetMasterNode() |
|
129 |
|
|
130 |
cmd = ['gnt-instance', 'reinstall', '-f', instance['name']] |
|
131 |
AssertEqual(StartSSH(master['primary'], |
|
132 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
109 |
AssertCommand(["gnt-instance", "reinstall", "-f", instance["name"]]) |
|
133 | 110 |
|
134 | 111 |
|
135 | 112 |
def _ReadSsconfInstanceList(): |
... | ... | |
158 | 135 |
|
159 | 136 |
def TestInstanceRename(instance, rename_target): |
160 | 137 |
"""gnt-instance rename""" |
161 |
master = qa_config.GetMasterNode() |
|
162 |
|
|
163 | 138 |
rename_source = instance['name'] |
164 | 139 |
|
165 | 140 |
for name1, name2 in [(rename_source, rename_target), |
166 | 141 |
(rename_target, rename_source)]: |
167 | 142 |
_CheckSsconfInstanceList(name1) |
168 |
cmd = ['gnt-instance', 'rename', name1, name2] |
|
169 |
AssertEqual(StartSSH(master['primary'], |
|
170 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
143 |
AssertCommand(["gnt-instance", "rename", name1, name2]) |
|
171 | 144 |
_CheckSsconfInstanceList(name2) |
172 | 145 |
|
173 | 146 |
|
174 | 147 |
def TestInstanceFailover(instance): |
175 | 148 |
"""gnt-instance failover""" |
176 |
master = qa_config.GetMasterNode() |
|
177 |
|
|
178 | 149 |
cmd = ['gnt-instance', 'failover', '--force', instance['name']] |
179 |
AssertEqual(StartSSH(master['primary'], |
|
180 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
181 |
|
|
150 |
# failover ... |
|
151 |
AssertCommand(cmd) |
|
182 | 152 |
# ... and back |
183 |
cmd = ['gnt-instance', 'failover', '--force', instance['name']] |
|
184 |
AssertEqual(StartSSH(master['primary'], |
|
185 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
153 |
AssertCommand(cmd) |
|
186 | 154 |
|
187 | 155 |
|
188 | 156 |
def TestInstanceMigrate(instance): |
189 | 157 |
"""gnt-instance migrate""" |
190 |
master = qa_config.GetMasterNode() |
|
191 |
|
|
192 | 158 |
cmd = ["gnt-instance", "migrate", "--force", instance["name"]] |
193 |
AssertEqual(StartSSH(master["primary"], |
|
194 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
195 |
|
|
159 |
# migrate ... |
|
160 |
AssertCommand(cmd) |
|
196 | 161 |
# ... and back |
197 |
cmd = ["gnt-instance", "migrate", "--force", instance["name"]] |
|
198 |
AssertEqual(StartSSH(master["primary"], |
|
199 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
162 |
AssertCommand(cmd) |
|
200 | 163 |
|
201 | 164 |
|
202 | 165 |
def TestInstanceInfo(instance): |
203 | 166 |
"""gnt-instance info""" |
204 |
master = qa_config.GetMasterNode() |
|
205 |
|
|
206 |
cmd = ['gnt-instance', 'info', instance['name']] |
|
207 |
AssertEqual(StartSSH(master['primary'], |
|
208 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
167 |
AssertCommand(["gnt-instance", "info", instance["name"]]) |
|
209 | 168 |
|
210 | 169 |
|
211 | 170 |
def TestInstanceModify(instance): |
212 | 171 |
"""gnt-instance modify""" |
213 |
master = qa_config.GetMasterNode() |
|
214 |
|
|
215 | 172 |
# Assume /sbin/init exists on all systems |
216 | 173 |
test_kernel = "/sbin/init" |
217 | 174 |
test_initrd = test_kernel |
218 | 175 |
|
219 | 176 |
orig_memory = qa_config.get('mem') |
220 |
orig_bridge = qa_config.get('bridge', 'xen-br0')
|
|
177 |
#orig_bridge = qa_config.get("bridge", "xen-br0")
|
|
221 | 178 |
args = [ |
222 | 179 |
["-B", "%s=128" % constants.BE_MEMORY], |
223 | 180 |
["-B", "%s=%s" % (constants.BE_MEMORY, orig_memory)], |
... | ... | |
240 | 197 |
#["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)], |
241 | 198 |
] |
242 | 199 |
for alist in args: |
243 |
cmd = ['gnt-instance', 'modify'] + alist + [instance['name']] |
|
244 |
AssertEqual(StartSSH(master['primary'], |
|
245 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
200 |
AssertCommand(["gnt-instance", "modify"] + alist + [instance["name"]]) |
|
246 | 201 |
|
247 | 202 |
# check no-modify |
248 |
cmd = ['gnt-instance', 'modify', instance['name']] |
|
249 |
AssertNotEqual(StartSSH(master['primary'], |
|
250 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
203 |
AssertCommand(["gnt-instance", "modify", instance["name"]], fail=True) |
|
251 | 204 |
|
252 | 205 |
|
253 | 206 |
def TestInstanceConvertDisk(instance, snode): |
254 | 207 |
"""gnt-instance modify -t""" |
255 |
master = qa_config.GetMasterNode() |
|
256 |
cmd = ['gnt-instance', 'modify', '-t', 'plain', instance['name']] |
|
257 |
AssertEqual(StartSSH(master['primary'], |
|
258 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
259 |
cmd = ['gnt-instance', 'modify', '-t', 'drbd', '-n', snode['primary'], |
|
260 |
instance['name']] |
|
261 |
AssertEqual(StartSSH(master['primary'], |
|
262 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
208 |
name = instance["name"] |
|
209 |
AssertCommand(["gnt-instance", "modify", "-t", "plain", name]) |
|
210 |
AssertCommand(["gnt-instance", "modify", "-t", "drbd", |
|
211 |
"-n", snode["primary"], name]) |
|
263 | 212 |
|
264 | 213 |
|
265 | 214 |
def TestInstanceList(): |
266 | 215 |
"""gnt-instance list""" |
267 |
master = qa_config.GetMasterNode() |
|
268 |
|
|
269 |
cmd = ['gnt-instance', 'list'] |
|
270 |
AssertEqual(StartSSH(master['primary'], |
|
271 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
216 |
AssertCommand(["gnt-instance", "list"]) |
|
272 | 217 |
|
273 | 218 |
|
274 | 219 |
def TestInstanceConsole(instance): |
275 | 220 |
"""gnt-instance console""" |
276 |
master = qa_config.GetMasterNode() |
|
277 |
|
|
278 |
cmd = ['gnt-instance', 'console', '--show-cmd', instance['name']] |
|
279 |
AssertEqual(StartSSH(master['primary'], |
|
280 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
221 |
AssertCommand(["gnt-instance", "console", "--show-cmd", instance["name"]]) |
|
281 | 222 |
|
282 | 223 |
|
283 | 224 |
def TestReplaceDisks(instance, pnode, snode, othernode): |
284 | 225 |
"""gnt-instance replace-disks""" |
285 |
master = qa_config.GetMasterNode() |
|
286 |
|
|
287 | 226 |
def buildcmd(args): |
288 | 227 |
cmd = ['gnt-instance', 'replace-disks'] |
289 | 228 |
cmd.extend(args) |
290 | 229 |
cmd.append(instance["name"]) |
291 | 230 |
return cmd |
292 | 231 |
|
293 |
cmd = buildcmd(["-p"]) |
|
294 |
AssertEqual(StartSSH(master['primary'], |
|
295 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
296 |
|
|
297 |
cmd = buildcmd(["-s"]) |
|
298 |
AssertEqual(StartSSH(master['primary'], |
|
299 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
300 |
|
|
301 |
cmd = buildcmd(["--new-secondary=%s" % othernode["primary"]]) |
|
302 |
AssertEqual(StartSSH(master['primary'], |
|
303 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
304 |
|
|
305 |
# Restore |
|
306 |
cmd = buildcmd(["--new-secondary=%s" % snode["primary"]]) |
|
307 |
AssertEqual(StartSSH(master['primary'], |
|
308 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
232 |
for data in [ |
|
233 |
["-p"], |
|
234 |
["-s"], |
|
235 |
["--new-secondary=%s" % othernode["primary"]], |
|
236 |
# and restore |
|
237 |
["--new-secondary=%s" % snode["primary"]], |
|
238 |
]: |
|
239 |
AssertCommand(buildcmd(data)) |
|
309 | 240 |
|
310 | 241 |
|
311 | 242 |
def TestInstanceExport(instance, node): |
312 | 243 |
"""gnt-backup export -n ...""" |
313 |
master = qa_config.GetMasterNode() |
|
314 |
|
|
315 |
cmd = ['gnt-backup', 'export', '-n', node['primary'], instance['name']] |
|
316 |
AssertEqual(StartSSH(master['primary'], |
|
317 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
318 |
|
|
319 |
return qa_utils.ResolveInstanceName(instance["name"]) |
|
244 |
name = instance["name"] |
|
245 |
AssertCommand(["gnt-backup", "export", "-n", node["primary"], name]) |
|
246 |
return qa_utils.ResolveInstanceName(name) |
|
320 | 247 |
|
321 | 248 |
|
322 | 249 |
def TestInstanceExportWithRemove(instance, node): |
323 | 250 |
"""gnt-backup export --remove-instance""" |
324 |
master = qa_config.GetMasterNode() |
|
325 |
|
|
326 |
cmd = ['gnt-backup', 'export', '-n', node['primary'], "--remove-instance", |
|
327 |
instance['name']] |
|
328 |
AssertEqual(StartSSH(master['primary'], |
|
329 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
251 |
AssertCommand(["gnt-backup", "export", "-n", node["primary"], |
|
252 |
"--remove-instance", instance["name"]]) |
|
330 | 253 |
|
331 | 254 |
|
332 | 255 |
def TestInstanceExportNoTarget(instance): |
333 | 256 |
"""gnt-backup export (without target node, should fail)""" |
334 |
master = qa_config.GetMasterNode() |
|
335 |
|
|
336 |
cmd = ["gnt-backup", "export", instance["name"]] |
|
337 |
AssertNotEqual(StartSSH(master['primary'], |
|
338 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
257 |
AssertCommand(["gnt-backup", "export", instance["name"]], fail=True) |
|
339 | 258 |
|
340 | 259 |
|
341 | 260 |
def TestInstanceImport(node, newinst, expnode, name): |
342 | 261 |
"""gnt-backup import""" |
343 |
master = qa_config.GetMasterNode() |
|
344 |
|
|
345 | 262 |
cmd = (['gnt-backup', 'import', |
346 | 263 |
'--disk-template=plain', |
347 | 264 |
'--no-ip-check', |
... | ... | |
351 | 268 |
'--node=%s' % node['primary']] + |
352 | 269 |
_GetGenericAddParameters()) |
353 | 270 |
cmd.append(newinst['name']) |
354 |
AssertEqual(StartSSH(master['primary'], |
|
355 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
271 |
AssertCommand(cmd) |
|
356 | 272 |
|
357 | 273 |
|
358 | 274 |
def TestBackupList(expnode): |
359 | 275 |
"""gnt-backup list""" |
360 |
master = qa_config.GetMasterNode() |
|
361 |
|
|
362 |
cmd = ['gnt-backup', 'list', '--node=%s' % expnode['primary']] |
|
363 |
AssertEqual(StartSSH(master['primary'], |
|
364 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
276 |
AssertCommand(["gnt-backup", "list", "--node=%s" % expnode["primary"]]) |
|
365 | 277 |
|
366 | 278 |
|
367 | 279 |
def _TestInstanceDiskFailure(instance, node, node2, onmaster): |
... | ... | |
390 | 302 |
|
391 | 303 |
m = re_disk.match(phys) |
392 | 304 |
if not m: |
393 |
raise qa_error.Error("Unknown disk name format: %s" % disk)
|
|
305 |
raise qa_error.Error("Unknown disk name format: %s" % phys)
|
|
394 | 306 |
|
395 | 307 |
name = m.group(1) |
396 | 308 |
if name not in node2disk[node_name]: |
... | ... | |
406 | 318 |
cmds = [] |
407 | 319 |
for disk in disks: |
408 | 320 |
cmds.append(sq(["test", "-f", _GetDiskStatePath(disk)])) |
409 |
AssertEqual(StartSSH(node_name, ' && '.join(cmds)).wait(), 0)
|
|
321 |
AssertCommand(" && ".join(cmds), node=node_name)
|
|
410 | 322 |
|
411 | 323 |
print qa_utils.FormatInfo("Getting device paths") |
412 | 324 |
cmd = ['gnt-instance', 'activate-disks', instance['name']] |
... | ... | |
432 | 344 |
for name in node2disk[[node2_full, node_full][int(onmaster)]]: |
433 | 345 |
halted_disks.append(name) |
434 | 346 |
cmds.append(sq(["echo", "offline"]) + " >%s" % _GetDiskStatePath(name)) |
435 |
AssertEqual(StartSSH([node2, node][int(onmaster)]['primary'], |
|
436 |
' && '.join(cmds)).wait(), 0) |
|
347 |
AssertCommand(" && ".join(cmds), node=[node2, node][int(onmaster)]) |
|
437 | 348 |
|
438 | 349 |
print qa_utils.FormatInfo("Write to disks and give some time to notice" |
439 | 350 |
" to notice the problem") |
... | ... | |
442 | 353 |
cmds.append(sq(["dd", "count=1", "bs=512", "conv=notrunc", |
443 | 354 |
"if=%s" % disk, "of=%s" % disk])) |
444 | 355 |
for _ in (0, 1, 2): |
445 |
AssertEqual(StartSSH(node['primary'], ' && '.join(cmds)).wait(), 0)
|
|
356 |
AssertCommand(" && ".join(cmds), node=node)
|
|
446 | 357 |
time.sleep(3) |
447 | 358 |
|
448 | 359 |
print qa_utils.FormatInfo("Debugging info") |
449 | 360 |
for name in drbddevs: |
450 |
cmd = ['drbdsetup', name, 'show'] |
|
451 |
AssertEqual(StartSSH(node['primary'], sq(cmd)).wait(), 0) |
|
361 |
AssertCommand(["drbdsetup", name, "show"], node=node) |
|
452 | 362 |
|
453 |
cmd = ['gnt-instance', 'info', instance['name']] |
|
454 |
AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0) |
|
363 |
AssertCommand(["gnt-instance", "info", instance["name"]]) |
|
455 | 364 |
|
456 | 365 |
finally: |
457 | 366 |
print qa_utils.FormatInfo("Activating disks again") |
458 | 367 |
cmds = [] |
459 | 368 |
for name in halted_disks: |
460 | 369 |
cmds.append(sq(["echo", "running"]) + " >%s" % _GetDiskStatePath(name)) |
461 |
AssertEqual(StartSSH([node2, node][int(onmaster)]['primary'], |
|
462 |
'; '.join(cmds)).wait(), 0) |
|
370 |
AssertCommand("; ".join(cmds), node=[node2, node][int(onmaster)]) |
|
463 | 371 |
|
464 | 372 |
if onmaster: |
465 | 373 |
for name in drbddevs: |
466 |
cmd = ['drbdsetup', name, 'detach'] |
|
467 |
AssertEqual(StartSSH(node['primary'], sq(cmd)).wait(), 0) |
|
374 |
AssertCommand(["drbdsetup", name, "detach"], node=node) |
|
468 | 375 |
else: |
469 | 376 |
for name in drbddevs: |
470 |
cmd = ['drbdsetup', name, 'disconnect'] |
|
471 |
AssertEqual(StartSSH(node2['primary'], sq(cmd)).wait(), 0) |
|
377 |
AssertCommand(["drbdsetup", name, "disconnect"], node=node2) |
|
472 | 378 |
|
473 | 379 |
# TODO |
474 |
#cmd = ['vgs'] |
|
475 |
#AssertEqual(StartSSH([node2, node][int(onmaster)]['primary'], |
|
476 |
# sq(cmd)).wait(), 0) |
|
380 |
#AssertCommand(["vgs"], [node2, node][int(onmaster)]) |
|
477 | 381 |
|
478 | 382 |
print qa_utils.FormatInfo("Making sure disks are up again") |
479 |
cmd = ['gnt-instance', 'replace-disks', instance['name']] |
|
480 |
AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0) |
|
383 |
AssertCommand(["gnt-instance", "replace-disks", instance["name"]]) |
|
481 | 384 |
|
482 | 385 |
print qa_utils.FormatInfo("Restarting instance") |
483 |
cmd = ['gnt-instance', 'shutdown', instance['name']] |
|
484 |
AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0) |
|
485 |
|
|
486 |
cmd = ['gnt-instance', 'startup', instance['name']] |
|
487 |
AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0) |
|
386 |
AssertCommand(["gnt-instance", "shutdown", instance["name"]]) |
|
387 |
AssertCommand(["gnt-instance", "startup", instance["name"]]) |
|
488 | 388 |
|
489 |
cmd = ['gnt-cluster', 'verify'] |
|
490 |
AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0) |
|
389 |
AssertCommand(["gnt-cluster", "verify"]) |
|
491 | 390 |
|
492 | 391 |
|
493 | 392 |
def TestInstanceMasterDiskFailure(instance, node, node2): |
b/qa/qa_node.py | ||
---|---|---|
26 | 26 |
import qa_error |
27 | 27 |
import qa_utils |
28 | 28 |
|
29 |
from qa_utils import AssertEqual, AssertNotEqual, StartSSH
|
|
29 |
from qa_utils import AssertCommand
|
|
30 | 30 |
|
31 | 31 |
|
32 | 32 |
def _NodeAdd(node, readd=False): |
33 |
master = qa_config.GetMasterNode() |
|
34 |
|
|
35 | 33 |
if not readd and node.get('_added', False): |
36 | 34 |
raise qa_error.Error("Node %s already in cluster" % node['primary']) |
37 | 35 |
elif readd and not node.get('_added', False): |
... | ... | |
43 | 41 |
if readd: |
44 | 42 |
cmd.append('--readd') |
45 | 43 |
cmd.append(node['primary']) |
46 |
AssertEqual(StartSSH(master['primary'], |
|
47 |
utils.ShellQuoteArgs(cmd)).wait(), 0)
|
|
44 |
|
|
45 |
AssertCommand(cmd)
|
|
48 | 46 |
|
49 | 47 |
node['_added'] = True |
50 | 48 |
|
51 | 49 |
|
52 | 50 |
def _NodeRemove(node): |
53 |
master = qa_config.GetMasterNode() |
|
54 |
|
|
55 |
cmd = ['gnt-node', 'remove', node['primary']] |
|
56 |
AssertEqual(StartSSH(master['primary'], |
|
57 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
51 |
AssertCommand(["gnt-node", "remove", node["primary"]]) |
|
58 | 52 |
node['_added'] = False |
59 | 53 |
|
60 | 54 |
|
... | ... | |
93 | 87 |
|
94 | 88 |
def TestNodeInfo(): |
95 | 89 |
"""gnt-node info""" |
96 |
master = qa_config.GetMasterNode() |
|
97 |
|
|
98 |
cmd = ['gnt-node', 'info'] |
|
99 |
AssertEqual(StartSSH(master['primary'], |
|
100 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
90 |
AssertCommand(["gnt-node", "info"]) |
|
101 | 91 |
|
102 | 92 |
|
103 | 93 |
def TestNodeVolumes(): |
104 | 94 |
"""gnt-node volumes""" |
105 |
master = qa_config.GetMasterNode() |
|
106 |
|
|
107 |
cmd = ['gnt-node', 'volumes'] |
|
108 |
AssertEqual(StartSSH(master['primary'], |
|
109 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
95 |
AssertCommand(["gnt-node", "volumes"]) |
|
110 | 96 |
|
111 | 97 |
|
112 | 98 |
def TestNodeStorage(): |
... | ... | |
115 | 101 |
|
116 | 102 |
for storage_type in constants.VALID_STORAGE_TYPES: |
117 | 103 |
# Test simple list |
118 |
cmd = ["gnt-node", "list-storage", "--storage-type", storage_type] |
|
119 |
AssertEqual(StartSSH(master["primary"], |
|
120 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
104 |
AssertCommand(["gnt-node", "list-storage", "--storage-type", storage_type]) |
|
121 | 105 |
|
122 | 106 |
# Test all storage fields |
123 | 107 |
cmd = ["gnt-node", "list-storage", "--storage-type", storage_type, |
124 | 108 |
"--output=%s" % ",".join(list(constants.VALID_STORAGE_FIELDS) + |
125 | 109 |
[constants.SF_NODE, constants.SF_TYPE])] |
126 |
AssertEqual(StartSSH(master["primary"], |
|
127 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
110 |
AssertCommand(cmd) |
|
128 | 111 |
|
129 | 112 |
# Get list of valid storage devices |
130 | 113 |
cmd = ["gnt-node", "list-storage", "--storage-type", storage_type, |
... | ... | |
141 | 124 |
|
142 | 125 |
# Dummy modification without any changes |
143 | 126 |
cmd = ["gnt-node", "modify-storage", node_name, storage_type, st_name] |
144 |
AssertEqual(StartSSH(master["primary"], |
|
145 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
127 |
AssertCommand(cmd) |
|
146 | 128 |
|
147 | 129 |
# Make sure we end up with the same value as before |
148 | 130 |
if st_allocatable.lower() == "y": |
... | ... | |
150 | 132 |
else: |
151 | 133 |
test_allocatable = ["yes", "no"] |
152 | 134 |
|
153 |
if (constants.SF_ALLOCATABLE in |
|
154 |
constants.MODIFIABLE_STORAGE_FIELDS.get(storage_type, [])): |
|
155 |
assert_fn = AssertEqual |
|
156 |
else: |
|
157 |
assert_fn = AssertNotEqual |
|
135 |
fail = (constants.SF_ALLOCATABLE not in |
|
136 |
constants.MODIFIABLE_STORAGE_FIELDS.get(storage_type, [])) |
|
158 | 137 |
|
159 | 138 |
for i in test_allocatable: |
160 |
cmd = ["gnt-node", "modify-storage", "--allocatable", i, |
|
161 |
node_name, storage_type, st_name] |
|
162 |
assert_fn(StartSSH(master["primary"], |
|
163 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
139 |
AssertCommand(["gnt-node", "modify-storage", "--allocatable", i, |
|
140 |
node_name, storage_type, st_name], fail=fail) |
|
164 | 141 |
|
165 | 142 |
# Test repair functionality |
166 |
cmd = ["gnt-node", "repair-storage", node_name, storage_type, st_name] |
|
167 |
|
|
168 |
if (constants.SO_FIX_CONSISTENCY in |
|
169 |
constants.VALID_STORAGE_OPERATIONS.get(storage_type, [])): |
|
170 |
assert_fn = AssertEqual |
|
171 |
else: |
|
172 |
assert_fn = AssertNotEqual |
|
173 |
|
|
174 |
assert_fn(StartSSH(master["primary"], |
|
175 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
143 |
fail = (constants.SO_FIX_CONSISTENCY not in |
|
144 |
constants.VALID_STORAGE_OPERATIONS.get(storage_type, [])) |
|
145 |
AssertCommand(["gnt-node", "repair-storage", node_name, |
|
146 |
storage_type, st_name], fail=fail) |
|
176 | 147 |
|
177 | 148 |
|
178 | 149 |
def TestNodeFailover(node, node2): |
179 | 150 |
"""gnt-node failover""" |
180 |
master = qa_config.GetMasterNode() |
|
181 |
|
|
182 | 151 |
if qa_utils.GetNodeInstances(node2, secondaries=False): |
183 | 152 |
raise qa_error.UnusableNodeError("Secondary node has at least one" |
184 | 153 |
" primary instance. This test requires" |
185 | 154 |
" it to have no primary instances.") |
186 | 155 |
|
187 | 156 |
# Fail over to secondary node |
188 |
cmd = ['gnt-node', 'failover', '-f', node['primary']] |
|
189 |
AssertEqual(StartSSH(master['primary'], |
|
190 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
157 |
AssertCommand(["gnt-node", "failover", "-f", node["primary"]]) |
|
191 | 158 |
|
192 | 159 |
# ... and back again. |
193 |
cmd = ['gnt-node', 'failover', '-f', node2['primary']] |
|
194 |
AssertEqual(StartSSH(master['primary'], |
|
195 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
160 |
AssertCommand(["gnt-node", "failover", "-f", node2["primary"]]) |
|
196 | 161 |
|
197 | 162 |
|
198 | 163 |
def TestNodeEvacuate(node, node2): |
199 | 164 |
"""gnt-node evacuate""" |
200 |
master = qa_config.GetMasterNode() |
|
201 |
|
|
202 | 165 |
node3 = qa_config.AcquireNode(exclude=[node, node2]) |
203 | 166 |
try: |
204 | 167 |
if qa_utils.GetNodeInstances(node3, secondaries=True): |
... | ... | |
207 | 170 |
" it to have no secondary instances.") |
208 | 171 |
|
209 | 172 |
# Evacuate all secondary instances |
210 |
cmd = ['gnt-node', 'evacuate', '-f', |
|
211 |
"--new-secondary=%s" % node3['primary'], node2['primary']] |
|
212 |
AssertEqual(StartSSH(master['primary'], |
|
213 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
173 |
AssertCommand(["gnt-node", "evacuate", "-f", |
|
174 |
"--new-secondary=%s" % node3["primary"], node2["primary"]]) |
|
214 | 175 |
|
215 | 176 |
# ... and back again. |
216 |
cmd = ['gnt-node', 'evacuate', '-f', |
|
217 |
"--new-secondary=%s" % node2['primary'], node3['primary']] |
|
218 |
AssertEqual(StartSSH(master['primary'], |
|
219 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
177 |
AssertCommand(["gnt-node", "evacuate", "-f", |
|
178 |
"--new-secondary=%s" % node2["primary"], node3["primary"]]) |
|
220 | 179 |
finally: |
221 | 180 |
qa_config.ReleaseNode(node3) |
222 | 181 |
|
223 | 182 |
|
224 | 183 |
def TestNodeModify(node): |
225 | 184 |
"""gnt-node modify""" |
226 |
master = qa_config.GetMasterNode() |
|
227 |
|
|
228 | 185 |
for flag in ["master-candidate", "drained", "offline"]: |
229 | 186 |
for value in ["yes", "no"]: |
230 |
cmd = ["gnt-node", "modify", "--force", |
|
231 |
"--%s=%s" % (flag, value), node["primary"]] |
|
232 |
AssertEqual(StartSSH(master["primary"], |
|
233 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
234 |
|
|
235 |
cmd = ["gnt-node", "modify", "--master-candidate=yes", "--auto-promote", |
|
236 |
node["primary"]] |
|
237 |
AssertEqual(StartSSH(master["primary"], |
|
238 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
187 |
AssertCommand(["gnt-node", "modify", "--force", |
|
188 |
"--%s=%s" % (flag, value), node["primary"]]) |
|
189 |
|
|
190 |
AssertCommand(["gnt-node", "modify", "--master-candidate=yes", |
|
191 |
"--auto-promote", node["primary"]]) |
b/qa/qa_os.py | ||
---|---|---|
32 | 32 |
import qa_config |
33 | 33 |
import qa_utils |
34 | 34 |
|
35 |
from qa_utils import AssertEqual, StartSSH
|
|
35 |
from qa_utils import AssertCommand
|
|
36 | 36 |
|
37 | 37 |
|
38 | 38 |
_TEMP_OS_NAME = "TEMP-Ganeti-QA-OS" |
... | ... | |
41 | 41 |
|
42 | 42 |
def TestOsList(): |
43 | 43 |
"""gnt-os list""" |
44 |
master = qa_config.GetMasterNode() |
|
45 |
|
|
46 |
cmd = ['gnt-os', 'list'] |
|
47 |
AssertEqual(StartSSH(master['primary'], |
|
48 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
44 |
AssertCommand(["gnt-os", "list"]) |
|
49 | 45 |
|
50 | 46 |
|
51 | 47 |
def TestOsDiagnose(): |
52 | 48 |
"""gnt-os diagnose""" |
53 |
master = qa_config.GetMasterNode() |
|
54 |
|
|
55 |
cmd = ['gnt-os', 'diagnose'] |
|
56 |
AssertEqual(StartSSH(master['primary'], |
|
57 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
49 |
AssertCommand(["gnt-os", "diagnose"]) |
|
58 | 50 |
|
59 | 51 |
|
60 |
def _TestOsModify(hvp_dict, expected_result=0):
|
|
52 |
def _TestOsModify(hvp_dict, fail=False):
|
|
61 | 53 |
"""gnt-os modify""" |
62 |
master = qa_config.GetMasterNode() |
|
63 |
|
|
64 | 54 |
cmd = ['gnt-os', 'modify'] |
65 | 55 |
|
66 | 56 |
for hv_name, hv_params in hvp_dict.items(): |
... | ... | |
71 | 61 |
cmd.append('%s:%s' % (hv_name, ','.join(options))) |
72 | 62 |
|
73 | 63 |
cmd.append(_TEMP_OS_NAME) |
74 |
AssertEqual(StartSSH(master['primary'], |
|
75 |
utils.ShellQuoteArgs(cmd)).wait(), expected_result) |
|
64 |
AssertCommand(cmd, fail=fail) |
|
76 | 65 |
|
77 | 66 |
|
78 | 67 |
def _TestOsStates(): |
79 | 68 |
"""gnt-os modify, more stuff""" |
80 |
master = qa_config.GetMasterNode() |
|
81 |
|
|
82 | 69 |
cmd = ["gnt-os", "modify"] |
83 | 70 |
|
84 | 71 |
for param in ["hidden", "blacklisted"]: |
85 | 72 |
for val in ["yes", "no"]: |
86 | 73 |
new_cmd = cmd + ["--%s" % param, val, _TEMP_OS_NAME] |
87 |
AssertEqual(StartSSH(master["primary"], |
|
88 |
utils.ShellQuoteArgs(new_cmd)).wait(), 0) |
|
74 |
AssertCommand(new_cmd) |
|
89 | 75 |
# check that double-running the command is OK |
90 |
AssertEqual(StartSSH(master["primary"], |
|
91 |
utils.ShellQuoteArgs(new_cmd)).wait(), 0) |
|
76 |
AssertCommand(new_cmd) |
|
92 | 77 |
|
93 | 78 |
|
94 | 79 |
def _SetupTempOs(node, dir, valid): |
... | ... | |
115 | 100 |
(node["primary"], |
116 | 101 |
["an invalid", "a valid"][int(valid)])) |
117 | 102 |
|
118 |
AssertEqual(StartSSH(node['primary'], cmd).wait(), 0)
|
|
103 |
AssertCommand(cmd, node=node)
|
|
119 | 104 |
|
120 | 105 |
|
121 | 106 |
def _RemoveTempOs(node, dir): |
122 | 107 |
"""Removes a temporary OS definition. |
123 | 108 |
|
124 | 109 |
""" |
125 |
cmd = ['rm', '-rf', dir] |
|
126 |
AssertEqual(StartSSH(node['primary'], |
|
127 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
110 |
AssertCommand(["rm", "-rf", dir], node=node) |
|
128 | 111 |
|
129 | 112 |
|
130 | 113 |
def _TestOs(mode): |
131 | 114 |
"""Generic function for OS definition testing |
132 | 115 |
|
133 | 116 |
""" |
134 |
master = qa_config.GetMasterNode() |
|
135 | 117 |
dir = _TEMP_OS_PATH |
136 | 118 |
|
137 | 119 |
nodes = [] |
138 | 120 |
try: |
139 |
i = 0 |
|
140 |
for node in qa_config.get('nodes'): |
|
121 |
for i, node in enumerate(qa_config.get("nodes")): |
|
141 | 122 |
nodes.append(node) |
142 | 123 |
if mode == 0: |
143 | 124 |
valid = False |
... | ... | |
146 | 127 |
else: |
147 | 128 |
valid = bool(i % 2) |
148 | 129 |
_SetupTempOs(node, dir, valid) |
149 |
i += 1 |
|
150 |
|
|
151 |
cmd = ['gnt-os', 'diagnose'] |
|
152 |
result = StartSSH(master['primary'], |
|
153 |
utils.ShellQuoteArgs(cmd)).wait() |
|
154 |
if mode == 1: |
|
155 |
AssertEqual(result, 0) |
|
156 |
else: |
|
157 |
AssertEqual(result, 1) |
|
130 |
|
|
131 |
AssertCommand(["gnt-os", "diagnose"], fail=not mode==1) |
|
158 | 132 |
finally: |
159 | 133 |
for node in nodes: |
160 | 134 |
_RemoveTempOs(node, dir) |
... | ... | |
196 | 170 |
"blahblahblubb": {"bar": ""}, |
197 | 171 |
} |
198 | 172 |
|
199 |
return _TestOsModify(hv_dict, 1)
|
|
173 |
return _TestOsModify(hv_dict, fail=True)
|
|
200 | 174 |
|
201 | 175 |
|
202 | 176 |
def TestOsStates(): |
b/qa/qa_tags.py | ||
---|---|---|
20 | 20 |
|
21 | 21 |
""" |
22 | 22 |
|
23 |
from ganeti import utils |
|
24 | 23 |
from ganeti import constants |
25 | 24 |
|
26 |
import qa_config |
|
27 |
import qa_utils |
|
28 | 25 |
import qa_rapi |
29 | 26 |
|
30 |
from qa_utils import AssertEqual, StartSSH
|
|
27 |
from qa_utils import AssertCommand
|
|
31 | 28 |
|
32 | 29 |
|
33 | 30 |
_TEMP_TAG_NAMES = ["TEMP-Ganeti-QA-Tag%d" % i for i in range(3)] |
... | ... | |
44 | 41 |
"""Generic function for add-tags. |
45 | 42 |
|
46 | 43 |
""" |
47 |
master = qa_config.GetMasterNode() |
|
48 |
|
|
49 | 44 |
def cmdfn(subcmd): |
50 | 45 |
cmd = [_KIND_TO_COMMAND[kind], subcmd] |
51 | 46 |
|
... | ... | |
54 | 49 |
|
55 | 50 |
return cmd |
56 | 51 |
|
57 |
cmd = cmdfn('add-tags') + _TEMP_TAG_NAMES |
|
58 |
AssertEqual(StartSSH(master['primary'], |
|
59 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
60 |
|
|
61 |
cmd = cmdfn('list-tags') |
|
62 |
AssertEqual(StartSSH(master['primary'], |
|
63 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
64 |
|
|
65 |
cmd = ['gnt-cluster', 'search-tags', _TEMP_TAG_RE] |
|
66 |
AssertEqual(StartSSH(master['primary'], |
|
67 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
68 |
|
|
69 |
cmd = cmdfn('remove-tags') + _TEMP_TAG_NAMES |
|
70 |
AssertEqual(StartSSH(master['primary'], |
|
71 |
utils.ShellQuoteArgs(cmd)).wait(), 0) |
|
52 |
for cmd in [ |
|
53 |
cmdfn("add-tags") + _TEMP_TAG_NAMES, |
|
54 |
cmdfn("list-tags"), |
|
55 |
["gnt-cluster", "search-tags", _TEMP_TAG_RE], |
|
56 |
cmdfn("remove-tags") + _TEMP_TAG_NAMES, |
|
57 |
]: |
|
58 |
AssertCommand(cmd) |
|
72 | 59 |
|
73 | 60 |
if qa_rapi.Enabled(): |
74 | 61 |
qa_rapi.TestTags(kind, name, _TEMP_TAG_NAMES) |
b/qa/qa_utils.py | ||
---|---|---|
101 | 101 |
raise qa_error.Error("%r doesn't match /%r/" % (string, pattern)) |
102 | 102 |
|
103 | 103 |
|
104 |
def AssertCommand(cmd, fail=False, node=None): |
|
105 |
"""Checks that a remote command succeeds. |
|
106 |
|
|
107 |
@param cmd: either a string (the command to execute) or a list (to |
|
108 |
be converted using L{utils.ShellQuoteArgs} into a string) |
|
109 |
@type fail: boolean |
|
110 |
@param fail: if the command is expected to fail instead of succeeding |
|
111 |
@param node: if passed, it should be the node on which the command |
|
112 |
should be executed, instead of the master node (can be either a |
|
113 |
dict or a string) |
|
114 |
|
|
115 |
""" |
|
116 |
if node is None: |
|
117 |
node = qa_config.GetMasterNode() |
|
118 |
|
|
119 |
if isinstance(node, basestring): |
|
120 |
nodename = node |
|
121 |
else: |
|
122 |
nodename = node["primary"] |
|
123 |
|
|
124 |
if isinstance(cmd, basestring): |
|
125 |
cmdstr = cmd |
|
126 |
else: |
|
127 |
cmdstr = utils.ShellQuoteArgs(cmd) |
|
128 |
|
|
129 |
rcode = StartSSH(nodename, cmdstr).wait() |
|
130 |
|
|
131 |
if fail: |
|
132 |
if rcode == 0: |
|
133 |
raise qa_error.Error("Command '%s' on node %s was expected to fail but" |
|
134 |
" didn't" % (cmdstr, nodename)) |
|
135 |
else: |
|
136 |
if rcode != 0: |
|
137 |
raise qa_error.Error("Command '%s' on node %s failed, exit code %s" % |
|
138 |
(cmdstr, nodename, rcode)) |
|
139 |
|
|
140 |
|
|
104 | 141 |
def GetSSHCommand(node, cmd, strict=True): |
105 | 142 |
"""Builds SSH command to be executed. |
106 | 143 |
|
Also available in: Unified diff