Simplify QA commands
authorIustin Pop <iustin@google.com>
Mon, 29 Nov 2010 02:34:57 +0000 (02:34 +0000)
committerIustin Pop <iustin@google.com>
Mon, 29 Nov 2010 13:37:51 +0000 (13:37 +0000)
Currently, 95% of the QA commands are executed in the same way: on the
master, based on a command list and with expectancies for succes:

    AssertEqual(StartSSH(master['primary'],
                         utils.ShellQuoteArgs(cmd)).wait(), 0)

The rest 5% are variations on this theme (maybe the command needs to
fail, or the node is different, etc.). Based on this, we can simplify
the code significantly if we abstract the common theme into a new
AssertCommand() function. This saves ~250 lines of code in the QA suite,
around 8% of the entire QA code size.

Additionally, the output was very cryptic before (the famous "QA error:
1 != 0" messages), whereas now we show a clear error message (node,
command, exit code and failure mode).

The patch replaces single quotes with double quotes in all the parts of
the code that I touch; let me know if that's not OK…

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

qa/qa_cluster.py
qa/qa_daemon.py
qa/qa_env.py
qa/qa_instance.py
qa/qa_node.py
qa/qa_os.py
qa/qa_tags.py
qa/qa_utils.py

index f615a73..596c573 100644 (file)
@@ -32,17 +32,15 @@ import qa_config
 import qa_utils
 import qa_error
 
-from qa_utils import AssertEqual, AssertNotEqual, StartSSH
+from qa_utils import AssertEqual, AssertCommand
 
 
 def _RemoveFileFromAllNodes(filename):
   """Removes a file from all nodes.
 
   """
-  for node in qa_config.get('nodes'):
-    cmd = ['rm', '-f', filename]
-    AssertEqual(StartSSH(node['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+  for node in qa_config.get("nodes"):
+    AssertCommand(["rm", "-f", filename], node=node)
 
 
 def _CheckFileOnAllNodes(filename, content):
@@ -50,9 +48,8 @@ def _CheckFileOnAllNodes(filename, content):
 
   """
   cmd = utils.ShellQuoteArgs(["cat", filename])
-  for node in qa_config.get('nodes'):
-    AssertEqual(qa_utils.GetCommandOutput(node['primary'], cmd),
-                content)
+  for node in qa_config.get("nodes"):
+    AssertEqual(qa_utils.GetCommandOutput(node["primary"], cmd), content)
 
 
 def TestClusterInit(rapi_user, rapi_secret):
@@ -67,13 +64,9 @@ def TestClusterInit(rapi_user, rapi_secret):
 
     tmpru = qa_utils.UploadFile(master["primary"], fh.name)
     try:
-      cmd = ["mv", tmpru, constants.RAPI_USERS_FILE]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["mv", tmpru, constants.RAPI_USERS_FILE])
     finally:
-      cmd = ["rm", "-f", tmpru]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["rm", "-f", tmpru])
   finally:
     fh.close()
 
@@ -97,14 +90,11 @@ def TestClusterInit(rapi_user, rapi_secret):
 
   cmd.append(qa_config.get('name'))
 
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(cmd)
 
 
 def TestClusterRename():
   """gnt-cluster rename"""
-  master = qa_config.GetMasterNode()
-
   cmd = ['gnt-cluster', 'rename', '-f']
 
   original_name = qa_config.get('name')
@@ -113,117 +103,85 @@ def TestClusterRename():
     print qa_utils.FormatError('"rename" entry is missing')
     return
 
-  cmd_1 = cmd + [rename_target]
-  cmd_2 = cmd + [original_name]
-
   cmd_verify = ['gnt-cluster', 'verify']
 
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd_1)).wait(), 0)
-
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd_verify)).wait(), 0)
-
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd_2)).wait(), 0)
-
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd_verify)).wait(), 0)
+  for data in [
+    cmd + [rename_target],
+    cmd_verify,
+    cmd + [original_name],
+    cmd_verify,
+    ]:
+    AssertCommand(data)
 
 
 def TestClusterVerify():
   """gnt-cluster verify"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-cluster', 'verify']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "verify"])
 
 
 def TestJobqueue():
   """gnt-debug test-jobqueue"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ["gnt-debug", "test-jobqueue"]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-debug", "test-jobqueue"])
 
 
 def TestClusterReservedLvs():
   """gnt-cluster reserved lvs"""
-  master = qa_config.GetMasterNode()
-  CVERIFY = ['gnt-cluster', 'verify']
-  for rcode, cmd in [
-    (0, CVERIFY),
-    (0, ['gnt-cluster', 'modify', '--reserved-lvs', '']),
-    (0, ['lvcreate', '-L1G', '-nqa-test', 'xenvg']),
-    (1, CVERIFY),
-    (0, ['gnt-cluster', 'modify', '--reserved-lvs', 'qa-test,other-test']),
-    (0, CVERIFY),
-    (0, ['gnt-cluster', 'modify', '--reserved-lvs', 'qa-.*']),
-    (0, CVERIFY),
-    (0, ['gnt-cluster', 'modify', '--reserved-lvs', '']),
-    (1, CVERIFY),
-    (0, ['lvremove', '-f', 'xenvg/qa-test']),
-    (0, CVERIFY),
+  CVERIFY = ["gnt-cluster", "verify"]
+  for fail, cmd in [
+    (False, CVERIFY),
+    (False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
+    (False, ["lvcreate", "-L1G", "-nqa-test", "xenvg"]),
+    (True,  CVERIFY),
+    (False, ["gnt-cluster", "modify", "--reserved-lvs", "qa-test,other-test"]),
+    (False, CVERIFY),
+    (False, ["gnt-cluster", "modify", "--reserved-lvs", "qa-.*"]),
+    (False, CVERIFY),
+    (False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
+    (True,  CVERIFY),
+    (False, ["lvremove", "-f", "xenvg/qa-test"]),
+    (False, CVERIFY),
     ]:
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), rcode)
+    AssertCommand(cmd, fail=fail)
 
 
 def TestClusterModifyBe():
   """gnt-cluster modify -B"""
-  master = qa_config.GetMasterNode()
-
-  for rcode, cmd in [
+  for fail, cmd in [
     # mem
-    (0, ["gnt-cluster", "modify", "-B", "memory=256"]),
-    (0, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 256$'"]),
-    (1, ["gnt-cluster", "modify", "-B", "memory=a"]),
-    (0, ["gnt-cluster", "modify", "-B", "memory=128"]),
-    (0, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 128$'"]),
+    (False, ["gnt-cluster", "modify", "-B", "memory=256"]),
+    (False, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 256$'"]),
+    (True,  ["gnt-cluster", "modify", "-B", "memory=a"]),
+    (False, ["gnt-cluster", "modify", "-B", "memory=128"]),
+    (False, ["sh", "-c", "gnt-cluster info|grep '^ *memory: 128$'"]),
     # vcpus
-    (0, ["gnt-cluster", "modify", "-B", "vcpus=4"]),
-    (0, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 4$'"]),
-    (1, ["gnt-cluster", "modify", "-B", "vcpus=a"]),
-    (0, ["gnt-cluster", "modify", "-B", "vcpus=1"]),
-    (0, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 1$'"]),
+    (False, ["gnt-cluster", "modify", "-B", "vcpus=4"]),
+    (False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 4$'"]),
+    (True,  ["gnt-cluster", "modify", "-B", "vcpus=a"]),
+    (False, ["gnt-cluster", "modify", "-B", "vcpus=1"]),
+    (False, ["sh", "-c", "gnt-cluster info|grep '^ *vcpus: 1$'"]),
     # auto_balance
-    (0, ["gnt-cluster", "modify", "-B", "auto_balance=False"]),
-    (0, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: False$'"]),
-    (1, ["gnt-cluster", "modify", "-B", "auto_balance=1"]),
-    (0, ["gnt-cluster", "modify", "-B", "auto_balance=True"]),
-    (0, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: True$'"]),
+    (False, ["gnt-cluster", "modify", "-B", "auto_balance=False"]),
+    (False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: False$'"]),
+    (True,  ["gnt-cluster", "modify", "-B", "auto_balance=1"]),
+    (False, ["gnt-cluster", "modify", "-B", "auto_balance=True"]),
+    (False, ["sh", "-c", "gnt-cluster info|grep '^ *auto_balance: True$'"]),
     ]:
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), rcode)
+    AssertCommand(cmd, fail=fail)
 
 
 def TestClusterInfo():
   """gnt-cluster info"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-cluster', 'info']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "info"])
 
 
 def TestClusterGetmaster():
   """gnt-cluster getmaster"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-cluster', 'getmaster']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "getmaster"])
 
 
 def TestClusterVersion():
   """gnt-cluster version"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-cluster', 'version']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "version"])
 
 
 def TestClusterRenewCrypto():
@@ -238,14 +196,12 @@ def TestClusterRenewCrypto():
     ["--new-cluster-domain-secret", "--cluster-domain-secret=/dev/null"],
     ]
   for i in conflicting:
-    AssertNotEqual(StartSSH(master["primary"],
-                            utils.ShellQuoteArgs(cmd + i)).wait(), 0)
+    AssertCommand(cmd+i, fail=True)
 
   # Invalid RAPI certificate
   cmd = ["gnt-cluster", "renew-crypto", "--force",
          "--rapi-certificate=/dev/null"]
-  AssertNotEqual(StartSSH(master["primary"],
-                          utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(cmd, fail=True)
 
   rapi_cert_backup = qa_utils.BackupFile(master["primary"],
                                          constants.RAPI_CERT_FILE)
@@ -260,14 +216,10 @@ def TestClusterRenewCrypto():
 
     tmpcert = qa_utils.UploadFile(master["primary"], fh.name)
     try:
-      cmd = ["gnt-cluster", "renew-crypto", "--force",
-             "--rapi-certificate=%s" % tmpcert]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
+                     "--rapi-certificate=%s" % tmpcert])
     finally:
-      cmd = ["rm", "-f", tmpcert]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["rm", "-f", tmpcert])
 
     # Custom cluster domain secret
     cds_fh = tempfile.NamedTemporaryFile()
@@ -277,31 +229,21 @@ def TestClusterRenewCrypto():
 
     tmpcds = qa_utils.UploadFile(master["primary"], cds_fh.name)
     try:
-      cmd = ["gnt-cluster", "renew-crypto", "--force",
-             "--cluster-domain-secret=%s" % tmpcds]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["gnt-cluster", "renew-crypto", "--force",
+                     "--cluster-domain-secret=%s" % tmpcds])
     finally:
-      cmd = ["rm", "-f", tmpcds]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["rm", "-f", tmpcds])
 
     # Normal case
-    cmd = ["gnt-cluster", "renew-crypto", "--force",
-           "--new-cluster-certificate", "--new-confd-hmac-key",
-           "--new-rapi-certificate", "--new-cluster-domain-secret"]
-    AssertEqual(StartSSH(master["primary"],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
+                   "--new-cluster-certificate", "--new-confd-hmac-key",
+                   "--new-rapi-certificate", "--new-cluster-domain-secret"])
 
     # Restore RAPI certificate
-    cmd = ["gnt-cluster", "renew-crypto", "--force",
-           "--rapi-certificate=%s" % rapi_cert_backup]
-    AssertEqual(StartSSH(master["primary"],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-cluster", "renew-crypto", "--force",
+                   "--rapi-certificate=%s" % rapi_cert_backup])
   finally:
-    cmd = ["rm", "-f", rapi_cert_backup]
-    AssertEqual(StartSSH(master["primary"],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["rm", "-f", rapi_cert_backup])
 
 
 def TestClusterBurnin():
@@ -349,12 +291,10 @@ def TestClusterBurnin():
       else:
         cmd.append('--reboot-types=%s' % ",".join(reboot_types))
       cmd += [inst['name'] for inst in instances]
-      AssertEqual(StartSSH(master['primary'],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(cmd)
     finally:
-      cmd = ['rm', '-f', script]
-      AssertEqual(StartSSH(master['primary'],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["rm", "-f", script])
+
   finally:
     for inst in instances:
       qa_config.ReleaseInstance(inst)
@@ -363,16 +303,12 @@ def TestClusterBurnin():
 def TestClusterMasterFailover():
   """gnt-cluster master-failover"""
   master = qa_config.GetMasterNode()
-
   failovermaster = qa_config.AcquireNode(exclude=master)
-  try:
-    cmd = ['gnt-cluster', 'master-failover']
-    AssertEqual(StartSSH(failovermaster['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
 
-    cmd = ['gnt-cluster', 'master-failover']
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+  cmd = ["gnt-cluster", "master-failover"]
+  try:
+    AssertCommand(cmd, node=failovermaster)
+    AssertCommand(cmd, node=master)
   finally:
     qa_config.ReleaseNode(failovermaster)
 
@@ -393,9 +329,7 @@ def TestClusterCopyfile():
   testname = qa_utils.UploadFile(master['primary'], f.name)
   try:
     # Copy file to all nodes
-    cmd = ['gnt-cluster', 'copyfile', testname]
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-cluster", "copyfile", testname])
     _CheckFileOnAllNodes(testname, uniqueid)
   finally:
     _RemoveFileFromAllNodes(testname)
@@ -403,8 +337,6 @@ def TestClusterCopyfile():
 
 def TestClusterCommand():
   """gnt-cluster command"""
-  master = qa_config.GetMasterNode()
-
   uniqueid = utils.NewUUID()
   rfile = "/tmp/gnt%s" % utils.NewUUID()
   rcmd = utils.ShellQuoteArgs(['echo', '-n', uniqueid])
@@ -412,7 +344,7 @@ def TestClusterCommand():
                               "%s >%s" % (rcmd, rfile)])
 
   try:
-    AssertEqual(StartSSH(master['primary'], cmd).wait(), 0)
+    AssertCommand(cmd)
     _CheckFileOnAllNodes(rfile, uniqueid)
   finally:
     _RemoveFileFromAllNodes(rfile)
@@ -420,8 +352,4 @@ def TestClusterCommand():
 
 def TestClusterDestroy():
   """gnt-cluster destroy"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-cluster', 'destroy', '--yes-do-it']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "destroy", "--yes-do-it"])
index a092803..1f47357 100644 (file)
@@ -32,15 +32,15 @@ import qa_config
 import qa_utils
 import qa_error
 
-from qa_utils import AssertEqual, AssertMatch, StartSSH, GetCommandOutput
+from qa_utils import AssertMatch, AssertCommand, StartSSH, GetCommandOutput
 
 
 def _InstanceRunning(node, name):
   """Checks whether an instance is running.
 
-  Args:
-    node: Node the instance runs on
-    name: Full name of Xen instance
+  @param node: node the instance runs on
+  @param name: full name of the Xen instance
+
   """
   cmd = utils.ShellQuoteArgs(['xm', 'list', name]) + ' >/dev/null'
   ret = StartSSH(node['primary'], cmd).wait()
@@ -50,15 +50,11 @@ def _InstanceRunning(node, name):
 def _XmShutdownInstance(node, name):
   """Shuts down instance using "xm" and waits for completion.
 
-  Args:
-    node: Node the instance runs on
-    name: Full name of Xen instance
-  """
-  master = qa_config.GetMasterNode()
+  @param node: node the instance runs on
+  @param name: full name of Xen instance
 
-  cmd = ['xm', 'shutdown', name]
-  AssertEqual(StartSSH(node['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  """
+  AssertCommand(["xm", "shutdown", name], node=node)
 
   # Wait up to a minute
   end = time.time() + 60
@@ -73,25 +69,15 @@ def _XmShutdownInstance(node, name):
 def _ResetWatcherDaemon():
   """Removes the watcher daemon's state file.
 
-  Args:
-    node: Node to be reset
   """
-  master = qa_config.GetMasterNode()
-
-  cmd = ['rm', '-f', constants.WATCHER_STATEFILE]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["rm", "-f", constants.WATCHER_STATEFILE])
 
 
 def _RunWatcherDaemon():
   """Runs the ganeti-watcher daemon on the master node.
 
   """
-  master = qa_config.GetMasterNode()
-
-  cmd = ["ganeti-watcher", "-d", "--ignore-pause"]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["ganeti-watcher", "-d", "--ignore-pause"])
 
 
 def TestPauseWatcher():
@@ -100,9 +86,7 @@ def TestPauseWatcher():
   """
   master = qa_config.GetMasterNode()
 
-  cmd = ["gnt-cluster", "watcher", "pause", "4h"]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "watcher", "pause", "4h"])
 
   cmd = ["gnt-cluster", "watcher", "info"]
   output = GetCommandOutput(master["primary"],
@@ -116,9 +100,7 @@ def TestResumeWatcher():
   """
   master = qa_config.GetMasterNode()
 
-  cmd = ["gnt-cluster", "watcher", "continue"]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "watcher", "continue"])
 
   cmd = ["gnt-cluster", "watcher", "info"]
   output = GetCommandOutput(master["primary"],
@@ -130,7 +112,6 @@ def TestInstanceAutomaticRestart(node, instance):
   """Test automatic restart of instance by ganeti-watcher.
 
   """
-  master = qa_config.GetMasterNode()
   inst_name = qa_utils.ResolveInstanceName(instance["name"])
 
   _ResetWatcherDaemon()
@@ -142,16 +123,13 @@ def TestInstanceAutomaticRestart(node, instance):
   if not _InstanceRunning(node, inst_name):
     raise qa_error.Error("Daemon didn't restart instance")
 
-  cmd = ['gnt-instance', 'info', inst_name]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "info", inst_name])
 
 
 def TestInstanceConsecutiveFailures(node, instance):
   """Test five consecutive instance failures.
 
   """
-  master = qa_config.GetMasterNode()
   inst_name = qa_utils.ResolveInstanceName(instance["name"])
 
   _ResetWatcherDaemon()
@@ -168,6 +146,4 @@ def TestInstanceConsecutiveFailures(node, instance):
         msg = "Instance started when it shouldn't"
       raise qa_error.Error(msg)
 
-  cmd = ['gnt-instance', 'info', inst_name]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "info", inst_name])
index dd53198..c0b0d1c 100644 (file)
 from ganeti import utils
 
 import qa_config
-import qa_utils
 
-from qa_utils import AssertEqual, StartSSH
+from qa_utils import AssertCommand
 
 
 def TestSshConnection():
   """Test SSH connection.
 
   """
-  for node in qa_config.get('nodes'):
-    AssertEqual(StartSSH(node['primary'], 'exit').wait(), 0)
+  for node in qa_config.get("nodes"):
+    AssertCommand("exit", node=node)
 
 
 def TestGanetiCommands():
@@ -60,7 +59,7 @@ def TestGanetiCommands():
   cmd = ' && '.join([utils.ShellQuoteArgs(i) for i in cmds])
 
   for node in qa_config.get('nodes'):
-    AssertEqual(StartSSH(node['primary'], cmd).wait(), 0)
+    AssertCommand(cmd, node=node)
 
 
 def TestIcmpPing():
@@ -74,14 +73,14 @@ def TestIcmpPing():
   if qa_config.get("primary_ip_version") == 6:
     pingprimary = "ping6"
 
-  for node in nodes:
-    check = []
-    for i in nodes:
-      cmd = [pingprimary] + pingargs + [i['primary']]
+  check = []
+  for i in nodes:
+    cmd = [pingprimary] + pingargs + [i["primary"]]
+    check.append(utils.ShellQuoteArgs(cmd))
+    if i.has_key("secondary"):
+      cmd = ["ping"] + pingargs + [i["secondary"]]
       check.append(utils.ShellQuoteArgs(cmd))
-      if i.has_key('secondary'):
-        cmd = ["ping"] + pingargs + [i["secondary"]]
-        check.append(utils.ShellQuoteArgs(cmd))
+  cmdall = " && ".join(check)
 
-    cmdall = ' && '.join(check)
-    AssertEqual(StartSSH(node['primary'], cmdall).wait(), 0)
+  for node in nodes:
+    AssertCommand(cmdall, node=node)
index 5b4b41a..a8bea2f 100644 (file)
@@ -33,7 +33,7 @@ import qa_config
 import qa_utils
 import qa_error
 
-from qa_utils import AssertEqual, AssertNotEqual, AssertIn, StartSSH
+from qa_utils import AssertIn, AssertCommand
 
 
 def _GetDiskStatePath(disk):
@@ -48,8 +48,6 @@ def _GetGenericAddParameters():
 
 
 def _DiskTest(node, disk_template):
-  master = qa_config.GetMasterNode()
-
   instance = qa_config.AcquireInstance()
   try:
     cmd = (['gnt-instance', 'add',
@@ -59,8 +57,7 @@ def _DiskTest(node, disk_template):
            _GetGenericAddParameters())
     cmd.append(instance['name'])
 
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(cmd)
 
     _CheckSsconfInstanceList(instance["name"])
 
@@ -83,53 +80,33 @@ def TestInstanceAddWithDrbdDisk(node, node2):
 
 def TestInstanceRemove(instance):
   """gnt-instance remove"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'remove', '-f', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "remove", "-f", instance["name"]])
 
   qa_config.ReleaseInstance(instance)
 
 
 def TestInstanceStartup(instance):
   """gnt-instance startup"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'startup', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "startup", instance["name"]])
 
 
 def TestInstanceShutdown(instance):
   """gnt-instance shutdown"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'shutdown', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
 
 
 def TestInstanceReboot(instance):
   """gnt-instance reboot"""
-  master = qa_config.GetMasterNode()
-
   options = qa_config.get('options', {})
   reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
-
+  name = instance["name"]
   for rtype in reboot_types:
-    cmd = ['gnt-instance', 'reboot', '--type=%s' % rtype, instance['name']]
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name])
 
 
 def TestInstanceReinstall(instance):
   """gnt-instance reinstall"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'reinstall', '-f', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "reinstall", "-f", instance["name"]])
 
 
 def _ReadSsconfInstanceList():
@@ -158,66 +135,46 @@ def _CheckSsconfInstanceList(instance):
 
 def TestInstanceRename(instance, rename_target):
   """gnt-instance rename"""
-  master = qa_config.GetMasterNode()
-
   rename_source = instance['name']
 
   for name1, name2 in [(rename_source, rename_target),
                        (rename_target, rename_source)]:
     _CheckSsconfInstanceList(name1)
-    cmd = ['gnt-instance', 'rename', name1, name2]
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-instance", "rename", name1, name2])
     _CheckSsconfInstanceList(name2)
 
 
 def TestInstanceFailover(instance):
   """gnt-instance failover"""
-  master = qa_config.GetMasterNode()
-
   cmd = ['gnt-instance', 'failover', '--force', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
+  # failover ...
+  AssertCommand(cmd)
   # ... and back
-  cmd = ['gnt-instance', 'failover', '--force', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(cmd)
 
 
 def TestInstanceMigrate(instance):
   """gnt-instance migrate"""
-  master = qa_config.GetMasterNode()
-
   cmd = ["gnt-instance", "migrate", "--force", instance["name"]]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
+  # migrate ...
+  AssertCommand(cmd)
   # ... and back
-  cmd = ["gnt-instance", "migrate", "--force", instance["name"]]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(cmd)
 
 
 def TestInstanceInfo(instance):
   """gnt-instance info"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'info', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "info", instance["name"]])
 
 
 def TestInstanceModify(instance):
   """gnt-instance modify"""
-  master = qa_config.GetMasterNode()
-
   # Assume /sbin/init exists on all systems
   test_kernel = "/sbin/init"
   test_initrd = test_kernel
 
   orig_memory = qa_config.get('mem')
-  orig_bridge = qa_config.get('bridge', 'xen-br0')
+  #orig_bridge = qa_config.get("bridge", "xen-br0")
   args = [
     ["-B", "%s=128" % constants.BE_MEMORY],
     ["-B", "%s=%s" % (constants.BE_MEMORY, orig_memory)],
@@ -240,108 +197,68 @@ def TestInstanceModify(instance):
     #["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
     ]
   for alist in args:
-    cmd = ['gnt-instance', 'modify'] + alist + [instance['name']]
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-instance", "modify"] + alist + [instance["name"]])
 
   # check no-modify
-  cmd = ['gnt-instance', 'modify', instance['name']]
-  AssertNotEqual(StartSSH(master['primary'],
-                          utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "modify", instance["name"]], fail=True)
 
 
 def TestInstanceConvertDisk(instance, snode):
   """gnt-instance modify -t"""
-  master = qa_config.GetMasterNode()
-  cmd = ['gnt-instance', 'modify', '-t', 'plain', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-  cmd = ['gnt-instance', 'modify', '-t', 'drbd', '-n', snode['primary'],
-         instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  name = instance["name"]
+  AssertCommand(["gnt-instance", "modify", "-t", "plain", name])
+  AssertCommand(["gnt-instance", "modify", "-t", "drbd",
+                 "-n", snode["primary"], name])
 
 
 def TestInstanceList():
   """gnt-instance list"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'list']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "list"])
 
 
 def TestInstanceConsole(instance):
   """gnt-instance console"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-instance', 'console', '--show-cmd', instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "console", "--show-cmd", instance["name"]])
 
 
 def TestReplaceDisks(instance, pnode, snode, othernode):
   """gnt-instance replace-disks"""
-  master = qa_config.GetMasterNode()
-
   def buildcmd(args):
     cmd = ['gnt-instance', 'replace-disks']
     cmd.extend(args)
     cmd.append(instance["name"])
     return cmd
 
-  cmd = buildcmd(["-p"])
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  cmd = buildcmd(["-s"])
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  cmd = buildcmd(["--new-secondary=%s" % othernode["primary"]])
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  # Restore
-  cmd = buildcmd(["--new-secondary=%s" % snode["primary"]])
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  for data in [
+    ["-p"],
+    ["-s"],
+    ["--new-secondary=%s" % othernode["primary"]],
+    # and restore
+    ["--new-secondary=%s" % snode["primary"]],
+    ]:
+    AssertCommand(buildcmd(data))
 
 
 def TestInstanceExport(instance, node):
   """gnt-backup export -n ..."""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-backup', 'export', '-n', node['primary'], instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  return qa_utils.ResolveInstanceName(instance["name"])
+  name = instance["name"]
+  AssertCommand(["gnt-backup", "export", "-n", node["primary"], name])
+  return qa_utils.ResolveInstanceName(name)
 
 
 def TestInstanceExportWithRemove(instance, node):
   """gnt-backup export --remove-instance"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-backup', 'export', '-n', node['primary'], "--remove-instance",
-         instance['name']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-backup", "export", "-n", node["primary"],
+                 "--remove-instance", instance["name"]])
 
 
 def TestInstanceExportNoTarget(instance):
   """gnt-backup export (without target node, should fail)"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ["gnt-backup", "export", instance["name"]]
-  AssertNotEqual(StartSSH(master['primary'],
-                          utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-backup", "export", instance["name"]], fail=True)
 
 
 def TestInstanceImport(node, newinst, expnode, name):
   """gnt-backup import"""
-  master = qa_config.GetMasterNode()
-
   cmd = (['gnt-backup', 'import',
           '--disk-template=plain',
           '--no-ip-check',
@@ -351,17 +268,12 @@ def TestInstanceImport(node, newinst, expnode, name):
           '--node=%s' % node['primary']] +
          _GetGenericAddParameters())
   cmd.append(newinst['name'])
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(cmd)
 
 
 def TestBackupList(expnode):
   """gnt-backup list"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-backup', 'list', '--node=%s' % expnode['primary']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode["primary"]])
 
 
 def _TestInstanceDiskFailure(instance, node, node2, onmaster):
@@ -390,7 +302,7 @@ def _TestInstanceDiskFailure(instance, node, node2, onmaster):
 
       m = re_disk.match(phys)
       if not m:
-        raise qa_error.Error("Unknown disk name format: %s" % disk)
+        raise qa_error.Error("Unknown disk name format: %s" % phys)
 
       name = m.group(1)
       if name not in node2disk[node_name]:
@@ -406,7 +318,7 @@ def _TestInstanceDiskFailure(instance, node, node2, onmaster):
     cmds = []
     for disk in disks:
       cmds.append(sq(["test", "-f", _GetDiskStatePath(disk)]))
-    AssertEqual(StartSSH(node_name, ' && '.join(cmds)).wait(), 0)
+    AssertCommand(" && ".join(cmds), node=node_name)
 
   print qa_utils.FormatInfo("Getting device paths")
   cmd = ['gnt-instance', 'activate-disks', instance['name']]
@@ -432,8 +344,7 @@ def _TestInstanceDiskFailure(instance, node, node2, onmaster):
     for name in node2disk[[node2_full, node_full][int(onmaster)]]:
       halted_disks.append(name)
       cmds.append(sq(["echo", "offline"]) + " >%s" % _GetDiskStatePath(name))
-    AssertEqual(StartSSH([node2, node][int(onmaster)]['primary'],
-                         ' && '.join(cmds)).wait(), 0)
+    AssertCommand(" && ".join(cmds), node=[node2, node][int(onmaster)])
 
     print qa_utils.FormatInfo("Write to disks and give some time to notice"
                               " to notice the problem")
@@ -442,52 +353,40 @@ def _TestInstanceDiskFailure(instance, node, node2, onmaster):
       cmds.append(sq(["dd", "count=1", "bs=512", "conv=notrunc",
                       "if=%s" % disk, "of=%s" % disk]))
     for _ in (0, 1, 2):
-      AssertEqual(StartSSH(node['primary'], ' && '.join(cmds)).wait(), 0)
+      AssertCommand(" && ".join(cmds), node=node)
       time.sleep(3)
 
     print qa_utils.FormatInfo("Debugging info")
     for name in drbddevs:
-      cmd = ['drbdsetup', name, 'show']
-      AssertEqual(StartSSH(node['primary'], sq(cmd)).wait(), 0)
+      AssertCommand(["drbdsetup", name, "show"], node=node)
 
-    cmd = ['gnt-instance', 'info', instance['name']]
-    AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0)
+    AssertCommand(["gnt-instance", "info", instance["name"]])
 
   finally:
     print qa_utils.FormatInfo("Activating disks again")
     cmds = []
     for name in halted_disks:
       cmds.append(sq(["echo", "running"]) + " >%s" % _GetDiskStatePath(name))
-    AssertEqual(StartSSH([node2, node][int(onmaster)]['primary'],
-                         '; '.join(cmds)).wait(), 0)
+    AssertCommand("; ".join(cmds), node=[node2, node][int(onmaster)])
 
   if onmaster:
     for name in drbddevs:
-      cmd = ['drbdsetup', name, 'detach']
-      AssertEqual(StartSSH(node['primary'], sq(cmd)).wait(), 0)
+      AssertCommand(["drbdsetup", name, "detach"], node=node)
   else:
     for name in drbddevs:
-      cmd = ['drbdsetup', name, 'disconnect']
-      AssertEqual(StartSSH(node2['primary'], sq(cmd)).wait(), 0)
+      AssertCommand(["drbdsetup", name, "disconnect"], node=node2)
 
   # TODO
-  #cmd = ['vgs']
-  #AssertEqual(StartSSH([node2, node][int(onmaster)]['primary'],
-  #                     sq(cmd)).wait(), 0)
+  #AssertCommand(["vgs"], [node2, node][int(onmaster)])
 
   print qa_utils.FormatInfo("Making sure disks are up again")
-  cmd = ['gnt-instance', 'replace-disks', instance['name']]
-  AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "replace-disks", instance["name"]])
 
   print qa_utils.FormatInfo("Restarting instance")
-  cmd = ['gnt-instance', 'shutdown', instance['name']]
-  AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0)
-
-  cmd = ['gnt-instance', 'startup', instance['name']]
-  AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0)
+  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
+  AssertCommand(["gnt-instance", "startup", instance["name"]])
 
-  cmd = ['gnt-cluster', 'verify']
-  AssertEqual(StartSSH(master['primary'], sq(cmd)).wait(), 0)
+  AssertCommand(["gnt-cluster", "verify"])
 
 
 def TestInstanceMasterDiskFailure(instance, node, node2):
index 15550f9..1c6a0cc 100644 (file)
@@ -26,12 +26,10 @@ import qa_config
 import qa_error
 import qa_utils
 
-from qa_utils import AssertEqual, AssertNotEqual, StartSSH
+from qa_utils import AssertCommand
 
 
 def _NodeAdd(node, readd=False):
-  master = qa_config.GetMasterNode()
-
   if not readd and node.get('_added', False):
     raise qa_error.Error("Node %s already in cluster" % node['primary'])
   elif readd and not node.get('_added', False):
@@ -43,18 +41,14 @@ def _NodeAdd(node, readd=False):
   if readd:
     cmd.append('--readd')
   cmd.append(node['primary'])
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+
+  AssertCommand(cmd)
 
   node['_added'] = True
 
 
 def _NodeRemove(node):
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-node', 'remove', node['primary']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-node", "remove", node["primary"]])
   node['_added'] = False
 
 
@@ -93,20 +87,12 @@ def TestNodeReadd(node):
 
 def TestNodeInfo():
   """gnt-node info"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-node', 'info']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-node", "info"])
 
 
 def TestNodeVolumes():
   """gnt-node volumes"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-node', 'volumes']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-node", "volumes"])
 
 
 def TestNodeStorage():
@@ -115,16 +101,13 @@ def TestNodeStorage():
 
   for storage_type in constants.VALID_STORAGE_TYPES:
     # Test simple list
-    cmd = ["gnt-node", "list-storage", "--storage-type", storage_type]
-    AssertEqual(StartSSH(master["primary"],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-node", "list-storage", "--storage-type", storage_type])
 
     # Test all storage fields
     cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
            "--output=%s" % ",".join(list(constants.VALID_STORAGE_FIELDS) +
                                     [constants.SF_NODE, constants.SF_TYPE])]
-    AssertEqual(StartSSH(master["primary"],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(cmd)
 
     # Get list of valid storage devices
     cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
@@ -141,8 +124,7 @@ def TestNodeStorage():
 
       # Dummy modification without any changes
       cmd = ["gnt-node", "modify-storage", node_name, storage_type, st_name]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(cmd)
 
       # Make sure we end up with the same value as before
       if st_allocatable.lower() == "y":
@@ -150,55 +132,36 @@ def TestNodeStorage():
       else:
         test_allocatable = ["yes", "no"]
 
-      if (constants.SF_ALLOCATABLE in
-          constants.MODIFIABLE_STORAGE_FIELDS.get(storage_type, [])):
-        assert_fn = AssertEqual
-      else:
-        assert_fn = AssertNotEqual
+      fail = (constants.SF_ALLOCATABLE not in
+              constants.MODIFIABLE_STORAGE_FIELDS.get(storage_type, []))
 
       for i in test_allocatable:
-        cmd = ["gnt-node", "modify-storage", "--allocatable", i,
-               node_name, storage_type, st_name]
-        assert_fn(StartSSH(master["primary"],
-                  utils.ShellQuoteArgs(cmd)).wait(), 0)
+        AssertCommand(["gnt-node", "modify-storage", "--allocatable", i,
+                       node_name, storage_type, st_name], fail=fail)
 
       # Test repair functionality
-      cmd = ["gnt-node", "repair-storage", node_name, storage_type, st_name]
-
-      if (constants.SO_FIX_CONSISTENCY in
-          constants.VALID_STORAGE_OPERATIONS.get(storage_type, [])):
-        assert_fn = AssertEqual
-      else:
-        assert_fn = AssertNotEqual
-
-      assert_fn(StartSSH(master["primary"],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+      fail = (constants.SO_FIX_CONSISTENCY not in
+              constants.VALID_STORAGE_OPERATIONS.get(storage_type, []))
+      AssertCommand(["gnt-node", "repair-storage", node_name,
+                     storage_type, st_name], fail=fail)
 
 
 def TestNodeFailover(node, node2):
   """gnt-node failover"""
-  master = qa_config.GetMasterNode()
-
   if qa_utils.GetNodeInstances(node2, secondaries=False):
     raise qa_error.UnusableNodeError("Secondary node has at least one"
                                      " primary instance. This test requires"
                                      " it to have no primary instances.")
 
   # Fail over to secondary node
-  cmd = ['gnt-node', 'failover', '-f', node['primary']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-node", "failover", "-f", node["primary"]])
 
   # ... and back again.
-  cmd = ['gnt-node', 'failover', '-f', node2['primary']]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-node", "failover", "-f", node2["primary"]])
 
 
 def TestNodeEvacuate(node, node2):
   """gnt-node evacuate"""
-  master = qa_config.GetMasterNode()
-
   node3 = qa_config.AcquireNode(exclude=[node, node2])
   try:
     if qa_utils.GetNodeInstances(node3, secondaries=True):
@@ -207,32 +170,22 @@ def TestNodeEvacuate(node, node2):
                                        " it to have no secondary instances.")
 
     # Evacuate all secondary instances
-    cmd = ['gnt-node', 'evacuate', '-f',
-           "--new-secondary=%s" % node3['primary'], node2['primary']]
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-node", "evacuate", "-f",
+                   "--new-secondary=%s" % node3["primary"], node2["primary"]])
 
     # ... and back again.
-    cmd = ['gnt-node', 'evacuate', '-f',
-           "--new-secondary=%s" % node2['primary'], node3['primary']]
-    AssertEqual(StartSSH(master['primary'],
-                         utils.ShellQuoteArgs(cmd)).wait(), 0)
+    AssertCommand(["gnt-node", "evacuate", "-f",
+                   "--new-secondary=%s" % node2["primary"], node3["primary"]])
   finally:
     qa_config.ReleaseNode(node3)
 
 
 def TestNodeModify(node):
   """gnt-node modify"""
-  master = qa_config.GetMasterNode()
-
   for flag in ["master-candidate", "drained", "offline"]:
     for value in ["yes", "no"]:
-      cmd = ["gnt-node", "modify", "--force",
-             "--%s=%s" % (flag, value), node["primary"]]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  cmd = ["gnt-node", "modify", "--master-candidate=yes", "--auto-promote",
-         node["primary"]]
-  AssertEqual(StartSSH(master["primary"],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+      AssertCommand(["gnt-node", "modify", "--force",
+                     "--%s=%s" % (flag, value), node["primary"]])
+
+  AssertCommand(["gnt-node", "modify", "--master-candidate=yes",
+                 "--auto-promote", node["primary"]])
index e6e259a..5669058 100644 (file)
@@ -32,7 +32,7 @@ from ganeti import constants
 import qa_config
 import qa_utils
 
-from qa_utils import AssertEqual, StartSSH
+from qa_utils import AssertCommand
 
 
 _TEMP_OS_NAME = "TEMP-Ganeti-QA-OS"
@@ -41,26 +41,16 @@ _TEMP_OS_PATH = os.path.join(constants.OS_SEARCH_PATH[0], _TEMP_OS_NAME)
 
 def TestOsList():
   """gnt-os list"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-os', 'list']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-os", "list"])
 
 
 def TestOsDiagnose():
   """gnt-os diagnose"""
-  master = qa_config.GetMasterNode()
-
-  cmd = ['gnt-os', 'diagnose']
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["gnt-os", "diagnose"])
 
 
-def _TestOsModify(hvp_dict, expected_result=0):
+def _TestOsModify(hvp_dict, fail=False):
   """gnt-os modify"""
-  master = qa_config.GetMasterNode()
-
   cmd = ['gnt-os', 'modify']
 
   for hv_name, hv_params in hvp_dict.items():
@@ -71,24 +61,19 @@ def _TestOsModify(hvp_dict, expected_result=0):
     cmd.append('%s:%s' % (hv_name, ','.join(options)))
 
   cmd.append(_TEMP_OS_NAME)
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), expected_result)
+  AssertCommand(cmd, fail=fail)
 
 
 def _TestOsStates():
   """gnt-os modify, more stuff"""
-  master = qa_config.GetMasterNode()
-
   cmd = ["gnt-os", "modify"]
 
   for param in ["hidden", "blacklisted"]:
     for val in ["yes", "no"]:
       new_cmd = cmd + ["--%s" % param, val, _TEMP_OS_NAME]
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(new_cmd)).wait(), 0)
+      AssertCommand(new_cmd)
       # check that double-running the command is OK
-      AssertEqual(StartSSH(master["primary"],
-                           utils.ShellQuoteArgs(new_cmd)).wait(), 0)
+      AssertCommand(new_cmd)
 
 
 def _SetupTempOs(node, dir, valid):
@@ -115,29 +100,25 @@ def _SetupTempOs(node, dir, valid):
                             (node["primary"],
                              ["an invalid", "a valid"][int(valid)]))
 
-  AssertEqual(StartSSH(node['primary'], cmd).wait(), 0)
+  AssertCommand(cmd, node=node)
 
 
 def _RemoveTempOs(node, dir):
   """Removes a temporary OS definition.
 
   """
-  cmd = ['rm', '-rf', dir]
-  AssertEqual(StartSSH(node['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  AssertCommand(["rm", "-rf", dir], node=node)
 
 
 def _TestOs(mode):
   """Generic function for OS definition testing
 
   """
-  master = qa_config.GetMasterNode()
   dir = _TEMP_OS_PATH
 
   nodes = []
   try:
-    i = 0
-    for node in qa_config.get('nodes'):
+    for i, node in enumerate(qa_config.get("nodes")):
       nodes.append(node)
       if mode == 0:
         valid = False
@@ -146,15 +127,8 @@ def _TestOs(mode):
       else:
         valid = bool(i % 2)
       _SetupTempOs(node, dir, valid)
-      i += 1
-
-    cmd = ['gnt-os', 'diagnose']
-    result = StartSSH(master['primary'],
-                      utils.ShellQuoteArgs(cmd)).wait()
-    if mode == 1:
-      AssertEqual(result, 0)
-    else:
-      AssertEqual(result, 1)
+
+    AssertCommand(["gnt-os", "diagnose"], fail=not mode==1)
   finally:
     for node in nodes:
       _RemoveTempOs(node, dir)
@@ -196,7 +170,7 @@ def TestOsModifyInvalid():
     "blahblahblubb": {"bar": ""},
     }
 
-  return _TestOsModify(hv_dict, 1)
+  return _TestOsModify(hv_dict, fail=True)
 
 
 def TestOsStates():
index d438ab9..9e48696 100644 (file)
 
 """
 
-from ganeti import utils
 from ganeti import constants
 
-import qa_config
-import qa_utils
 import qa_rapi
 
-from qa_utils import AssertEqual, StartSSH
+from qa_utils import AssertCommand
 
 
 _TEMP_TAG_NAMES = ["TEMP-Ganeti-QA-Tag%d" % i for i in range(3)]
@@ -44,8 +41,6 @@ def _TestTags(kind, name):
   """Generic function for add-tags.
 
   """
-  master = qa_config.GetMasterNode()
-
   def cmdfn(subcmd):
     cmd = [_KIND_TO_COMMAND[kind], subcmd]
 
@@ -54,21 +49,13 @@ def _TestTags(kind, name):
 
     return cmd
 
-  cmd = cmdfn('add-tags') + _TEMP_TAG_NAMES
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  cmd = cmdfn('list-tags')
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  cmd = ['gnt-cluster', 'search-tags', _TEMP_TAG_RE]
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
-
-  cmd = cmdfn('remove-tags') + _TEMP_TAG_NAMES
-  AssertEqual(StartSSH(master['primary'],
-                       utils.ShellQuoteArgs(cmd)).wait(), 0)
+  for cmd in [
+    cmdfn("add-tags") + _TEMP_TAG_NAMES,
+    cmdfn("list-tags"),
+    ["gnt-cluster", "search-tags", _TEMP_TAG_RE],
+    cmdfn("remove-tags") + _TEMP_TAG_NAMES,
+    ]:
+    AssertCommand(cmd)
 
   if qa_rapi.Enabled():
     qa_rapi.TestTags(kind, name, _TEMP_TAG_NAMES)
index de48794..0926f74 100644 (file)
@@ -101,6 +101,43 @@ def AssertMatch(string, pattern):
     raise qa_error.Error("%r doesn't match /%r/" % (string, pattern))
 
 
+def AssertCommand(cmd, fail=False, node=None):
+  """Checks that a remote command succeeds.
+
+  @param cmd: either a string (the command to execute) or a list (to
+      be converted using L{utils.ShellQuoteArgs} into a string)
+  @type fail: boolean
+  @param fail: if the command is expected to fail instead of succeeding
+  @param node: if passed, it should be the node on which the command
+      should be executed, instead of the master node (can be either a
+      dict or a string)
+
+  """
+  if node is None:
+    node = qa_config.GetMasterNode()
+
+  if isinstance(node, basestring):
+    nodename = node
+  else:
+    nodename = node["primary"]
+
+  if isinstance(cmd, basestring):
+    cmdstr = cmd
+  else:
+    cmdstr = utils.ShellQuoteArgs(cmd)
+
+  rcode = StartSSH(nodename, cmdstr).wait()
+
+  if fail:
+    if rcode == 0:
+      raise qa_error.Error("Command '%s' on node %s was expected to fail but"
+                           " didn't" % (cmdstr, nodename))
+  else:
+    if rcode != 0:
+      raise qa_error.Error("Command '%s' on node %s failed, exit code %s" %
+                           (cmdstr, nodename, rcode))
+
+
 def GetSSHCommand(node, cmd, strict=True):
   """Builds SSH command to be executed.