QA: use a persistent SSH connection to the master
[ganeti-local] / qa / ganeti-qa.py
index 027c065..6dc909d 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/python -u
 #
 
-# Copyright (C) 2007, 2008, 2009, 2010 Google Inc.
+# Copyright (C) 2007, 2008, 2009, 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@ import qa_utils
 
 from ganeti import utils
 from ganeti import rapi
+from ganeti import constants
 
 import ganeti.rapi.client
 
@@ -121,6 +122,11 @@ def SetupCluster(rapi_user, rapi_secret):
   """
   RunTestIf("create-cluster", qa_cluster.TestClusterInit,
             rapi_user, rapi_secret)
+
+  # Test on empty cluster
+  RunTestIf("node-list", qa_node.TestNodeList)
+  RunTestIf("instance-list", qa_instance.TestInstanceList)
+
   RunTestIf("create-cluster", qa_node.TestNodeAddAll)
   if not qa_config.TestEnabled("create-cluster"):
     # consider the nodes are already there
@@ -131,6 +137,12 @@ def SetupCluster(rapi_user, rapi_secret):
   # enable the watcher (unconditionally)
   RunTest(qa_daemon.TestResumeWatcher)
 
+  RunTestIf("node-list", qa_node.TestNodeList)
+
+  # Test listing fields
+  RunTestIf("node-list", qa_node.TestNodeListFields)
+  RunTestIf("instance-list", qa_instance.TestInstanceListFields)
+
   RunTestIf("node-info", qa_node.TestNodeInfo)
 
 
@@ -152,6 +164,7 @@ def RunClusterTests():
     ("cluster-command", qa_cluster.TestClusterCommand),
     ("cluster-burnin", qa_cluster.TestClusterBurnin),
     ("cluster-master-failover", qa_cluster.TestClusterMasterFailover),
+    ("cluster-oob", qa_cluster.TestClusterOob),
     ("rapi", qa_rapi.TestVersion),
     ("rapi", qa_rapi.TestEmptyCluster),
     ]:
@@ -204,19 +217,27 @@ def RunCommonInstanceTests(instance):
     RunTest(qa_instance.TestInstanceShutdown, instance)
     # perform instance rename to the same name
     RunTest(qa_instance.TestInstanceRename, rename_source, rename_source)
-    RunTestIf("rapi", qa_rapi.TestRapiInstanceRename, rename_source, rename_source)
+    RunTestIf("rapi", qa_rapi.TestRapiInstanceRename,
+              rename_source, rename_source)
     if rename_target is not None:
       # perform instance rename to a different name, if we have one configured
       RunTest(qa_instance.TestInstanceRename, rename_source, rename_target)
       RunTest(qa_instance.TestInstanceRename, rename_target, rename_source)
-      RunTestIf("rapi", qa_rapi.TestRapiInstanceRename, rename_source, rename_target)
-      RunTestIf("rapi", qa_rapi.TestRapiInstanceRename, rename_target, rename_source)
+      RunTestIf("rapi", qa_rapi.TestRapiInstanceRename,
+                rename_source, rename_target)
+      RunTestIf("rapi", qa_rapi.TestRapiInstanceRename,
+                rename_target, rename_source)
     RunTest(qa_instance.TestInstanceStartup, instance)
 
   RunTestIf("tags", qa_tags.TestInstanceTags, instance)
 
+  RunTestIf("cluster-verify", qa_cluster.TestClusterVerify)
+
   RunTestIf("rapi", qa_rapi.TestInstance, instance)
 
+  # Lists instances, too
+  RunTestIf("node-list", qa_node.TestNodeList)
+
 
 def RunCommonNodeTests():
   """Run a few common node tests.
@@ -224,14 +245,15 @@ def RunCommonNodeTests():
   """
   RunTestIf("node-volumes", qa_node.TestNodeVolumes)
   RunTestIf("node-storage", qa_node.TestNodeStorage)
+  RunTestIf("node-oob", qa_node.TestOutOfBand)
 
 
 def RunGroupListTests():
   """Run tests for listing node groups.
 
   """
-  RunTestIf("group-list", qa_group.TestGroupListDefaultFields)
-  RunTestIf("group-list", qa_group.TestGroupListAllFields)
+  RunTestIf("group-list", qa_group.TestGroupList)
+  RunTestIf("group-list", qa_group.TestGroupListFields)
 
 
 def RunGroupRwTests():
@@ -239,6 +261,10 @@ def RunGroupRwTests():
 
   """
   RunTestIf("group-rwops", qa_group.TestGroupAddRemoveRename)
+  RunTestIf("group-rwops", qa_group.TestGroupAddWithOptions)
+  RunTestIf("group-rwops", qa_group.TestGroupModify)
+  RunTestIf("rapi", qa_rapi.TestRapiNodeGroups)
+
 
 def RunExportImportTests(instance, pnode, snode):
   """Tries to export and import the instance.
@@ -328,30 +354,10 @@ def RunHardwareFailureTests(instance, pnode, snode):
             pnode, snode)
 
 
-@rapi.client.UsesRapiClient
-def main():
-  """Main program.
+def RunQa():
+  """Main QA body.
 
   """
-  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
-  parser.add_option('--yes-do-it', dest='yes_do_it',
-      action="store_true",
-      help="Really execute the tests")
-  (qa_config.options, args) = parser.parse_args()
-
-  if len(args) == 1:
-    (config_file, ) = args
-  else:
-    parser.error("Wrong number of arguments.")
-
-  if not qa_config.options.yes_do_it:
-    print ("Executing this script irreversibly destroys any Ganeti\n"
-           "configuration on all nodes involved. If you really want\n"
-           "to start testing, supply the --yes-do-it option.")
-    sys.exit(1)
-
-  qa_config.Load(config_file)
-
   rapi_user = "ganeti-qa"
   rapi_secret = utils.GenerateSecret()
 
@@ -411,9 +417,11 @@ def main():
         snode = qa_config.AcquireNode(exclude=pnode)
         try:
           instance = RunTest(func, pnode, snode)
-          RunTestIf("cluster-verify", qa_cluster.TestClusterVerify)
           RunCommonInstanceTests(instance)
           RunGroupListTests()
+          RunTest(qa_group.TestAssignNodesIncludingSplit,
+                  constants.INITIAL_NODE_GROUP_NAME,
+                  pnode["primary"], snode["primary"])
           if qa_config.TestEnabled('instance-convert-disk'):
             RunTest(qa_instance.TestInstanceShutdown, instance)
             RunTest(qa_instance.TestInstanceConvertDisk, instance, snode)
@@ -448,5 +456,35 @@ def main():
   RunTestIf("cluster-destroy", qa_cluster.TestClusterDestroy)
 
 
+@rapi.client.UsesRapiClient
+def main():
+  """Main program.
+
+  """
+  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
+  parser.add_option('--yes-do-it', dest='yes_do_it',
+      action="store_true",
+      help="Really execute the tests")
+  (qa_config.options, args) = parser.parse_args()
+
+  if len(args) == 1:
+    (config_file, ) = args
+  else:
+    parser.error("Wrong number of arguments.")
+
+  if not qa_config.options.yes_do_it:
+    print ("Executing this script irreversibly destroys any Ganeti\n"
+           "configuration on all nodes involved. If you really want\n"
+           "to start testing, supply the --yes-do-it option.")
+    sys.exit(1)
+
+  qa_config.Load(config_file)
+
+  qa_utils.StartMultiplexer(qa_config.GetMasterNode()["primary"])
+  try:
+    RunQa()
+  finally:
+    qa_utils.CloseMultiplexers()
+
 if __name__ == '__main__':
   main()