diff --git a/Makefile.am b/Makefile.am index 6c4b2c62c30056b16c434b0e4a6c49a2c3cc5f7a..38efd06aa36847080c1f16ad4755badec770da33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,7 +30,6 @@ DIRS = \ lib/rapi \ man \ qa \ - qa/hooks \ scripts \ test \ test/data \ @@ -51,7 +50,6 @@ CLEANFILES = \ man/*.[78] \ man/*.in \ qa/*.py[co] \ - qa/hooks/*.py[co] \ test/*.py[co] \ stamp-directories \ $(nodist_pkgpython_PYTHON) @@ -141,8 +139,6 @@ EXTRA_DIST = \ doc/examples/ganeti.initd.in \ doc/examples/ganeti.cron.in \ doc/examples/dumb-allocator \ - qa/hooks/datehook.py \ - qa/hooks/loghook.py \ test/testutils.py \ test/mocks.py \ $(dist_TESTS) \ diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py index f38ca337ddf94283c77f87f45477b29d25f18fc6..c4573ce3a435a0029d04feb0c73f404c867bf624 100755 --- a/qa/ganeti-qa.py +++ b/qa/ganeti-qa.py @@ -263,7 +263,6 @@ def main(): sys.exit(1) qa_config.Load(config_file) - qa_utils.LoadHooks() RunTest(qa_other.UploadKnownHostsFile, known_hosts_file) diff --git a/qa/hooks/datehook.py b/qa/hooks/datehook.py deleted file mode 100644 index 590bc855691e466a9c9e9668e80da3b4b86da978..0000000000000000000000000000000000000000 --- a/qa/hooks/datehook.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2007 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - - -"""Example QA hook. - -""" - -from ganeti import utils - -import qa_utils -import qa_config - -from qa_utils import AssertEqual, StartSSH - - -class DateHook: - def run(self, ctx): - if ctx.name == 'cluster-init' and ctx.phase == 'pre': - self._CallDate(ctx) - - def _CallDate(self, ctx): - for node in qa_config.get('nodes'): - cmd = ['date'] - AssertEqual(StartSSH(node['primary'], - utils.ShellQuoteArgs(cmd)).wait(), 0) - -hook = DateHook diff --git a/qa/hooks/loghook.py b/qa/hooks/loghook.py deleted file mode 100644 index 4b86542ffc3998598588f9ee0d58c8230fe3c661..0000000000000000000000000000000000000000 --- a/qa/hooks/loghook.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (C) 2007 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - - -"""QA hook to log all function calls. - -""" - -from ganeti import utils - -import qa_utils -import qa_config - -from qa_utils import AssertEqual, StartSSH - - -class LogHook: - def __init__(self): - file_name = qa_config.get('options', {}).get('hook-logfile', None) - if file_name: - self.log = open(file_name, "a+") - else: - self.log = None - - def __del__(self): - if self.log: - self.log.close() - - def run(self, ctx): - if not self.log: - return - - msg = "%s-%s" % (ctx.phase, ctx.name) - if ctx.phase == 'post': - msg += " success=%s" % ctx.success - if ctx.args: - msg += " %s" % repr(ctx.args) - if ctx.kwargs: - msg += " %s" % repr(ctx.kwargs) - if ctx.phase == 'pre': - self.log.write("---\n") - self.log.write(msg) - self.log.write("\n") - self.log.flush() - - -hook = LogHook diff --git a/qa/qa-sample.yaml b/qa/qa-sample.yaml index 38b2fa6922e501c2c5e94003a874f40a622f2352..e1457c78fbeca6e6c2c166e894d5b3359dc20592 100644 --- a/qa/qa-sample.yaml +++ b/qa/qa-sample.yaml @@ -83,9 +83,3 @@ tests: options: burnin-instances: 2 burnin-disk-template: drbd - - # Directory containing QA hooks - #hooks-dir: hooks/ - - # Logfile for loghook.py - hook-logfile: /tmp/qa.log diff --git a/qa/qa_cluster.py b/qa/qa_cluster.py index 24c9a8872828274a8b0ed6b92518d8d646f49509..bf4095fdb95a06386b88b6102b51db6e189a4a80 100644 --- a/qa/qa_cluster.py +++ b/qa/qa_cluster.py @@ -54,7 +54,6 @@ def _CheckFileOnAllNodes(filename, content): content) -@qa_utils.DefineHook('cluster-init') def TestClusterInit(): """gnt-cluster init""" master = qa_config.GetMasterNode() @@ -79,7 +78,6 @@ def TestClusterInit(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('cluster-rename') def TestClusterRename(): """gnt-cluster rename""" master = qa_config.GetMasterNode() @@ -110,7 +108,6 @@ def TestClusterRename(): utils.ShellQuoteArgs(cmd_verify)).wait(), 0) -@qa_utils.DefineHook('cluster-verify') def TestClusterVerify(): """gnt-cluster verify""" master = qa_config.GetMasterNode() @@ -120,7 +117,6 @@ def TestClusterVerify(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('cluster-info') def TestClusterInfo(): """gnt-cluster info""" master = qa_config.GetMasterNode() @@ -130,7 +126,6 @@ def TestClusterInfo(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('cluster-getmaster') def TestClusterGetmaster(): """gnt-cluster getmaster""" master = qa_config.GetMasterNode() @@ -140,7 +135,6 @@ def TestClusterGetmaster(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('cluster-version') def TestClusterVersion(): """gnt-cluster version""" master = qa_config.GetMasterNode() @@ -150,7 +144,6 @@ def TestClusterVersion(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('cluster-burnin') def TestClusterBurnin(): """Burnin""" master = qa_config.GetMasterNode() @@ -191,7 +184,6 @@ def TestClusterBurnin(): qa_config.ReleaseInstance(inst) -@qa_utils.DefineHook('cluster-master-failover') def TestClusterMasterFailover(): """gnt-cluster masterfailover""" master = qa_config.GetMasterNode() @@ -209,7 +201,6 @@ def TestClusterMasterFailover(): qa_config.ReleaseNode(failovermaster) -@qa_utils.DefineHook('cluster-copyfile') def TestClusterCopyfile(): """gnt-cluster copyfile""" master = qa_config.GetMasterNode() @@ -234,7 +225,6 @@ def TestClusterCopyfile(): _RemoveFileFromAllNodes(testname) -@qa_utils.DefineHook('cluster-command') def TestClusterCommand(): """gnt-cluster command""" master = qa_config.GetMasterNode() @@ -252,7 +242,6 @@ def TestClusterCommand(): _RemoveFileFromAllNodes(rfile) -@qa_utils.DefineHook('cluster-destroy') def TestClusterDestroy(): """gnt-cluster destroy""" master = qa_config.GetMasterNode() diff --git a/qa/qa_daemon.py b/qa/qa_daemon.py index 30bb657e61a96c4a33ad8312c67b9d4aa0b71206..4817bfef078a877885a5cd25fbb168f006966a9b 100644 --- a/qa/qa_daemon.py +++ b/qa/qa_daemon.py @@ -104,7 +104,6 @@ def PrintCronWarning(): print qa_utils.FormatWarning(msg) -@qa_utils.DefineHook('daemon-automatic-restart') def TestInstanceAutomaticRestart(node, instance): """Test automatic restart of instance by ganeti-watcher. @@ -126,7 +125,6 @@ def TestInstanceAutomaticRestart(node, instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('daemon-consecutive-failures') def TestInstanceConsecutiveFailures(node, instance): """Test five consecutive instance failures. diff --git a/qa/qa_env.py b/qa/qa_env.py index 540363d3a071d767cd7b18ced582e898e1f919ba..b2dff2e09066df5d1c98a8035996384efd50dd10 100644 --- a/qa/qa_env.py +++ b/qa/qa_env.py @@ -31,7 +31,6 @@ import qa_utils from qa_utils import AssertEqual, StartSSH -@qa_utils.DefineHook('env-ssh-connection') def TestSshConnection(): """Test SSH connection. @@ -40,7 +39,6 @@ def TestSshConnection(): AssertEqual(StartSSH(node['primary'], 'exit').wait(), 0) -@qa_utils.DefineHook('env-ganeti-commands') def TestGanetiCommands(): """Test availibility of Ganeti commands. @@ -59,7 +57,6 @@ def TestGanetiCommands(): AssertEqual(StartSSH(node['primary'], cmd).wait(), 0) -@qa_utils.DefineHook('env-icmp-ping') def TestIcmpPing(): """ICMP ping each node. diff --git a/qa/qa_instance.py b/qa/qa_instance.py index b2e8f4604d904eaa6ef6fcc4cd26148b347aebcd..cf749d77dd59712d498d50066095e95d0c637112 100644 --- a/qa/qa_instance.py +++ b/qa/qa_instance.py @@ -66,20 +66,17 @@ def _DiskTest(node, disk_template): raise -@qa_utils.DefineHook('instance-add-plain-disk') def TestInstanceAddWithPlainDisk(node): """gnt-instance add -t plain""" return _DiskTest(node['primary'], 'plain') -@qa_utils.DefineHook('instance-add-drbd-disk') def TestInstanceAddWithDrbdDisk(node, node2): """gnt-instance add -t drbd""" return _DiskTest("%s:%s" % (node['primary'], node2['primary']), 'drbd') -@qa_utils.DefineHook('instance-remove') def TestInstanceRemove(instance): """gnt-instance remove""" master = qa_config.GetMasterNode() @@ -91,7 +88,6 @@ def TestInstanceRemove(instance): qa_config.ReleaseInstance(instance) -@qa_utils.DefineHook('instance-startup') def TestInstanceStartup(instance): """gnt-instance startup""" master = qa_config.GetMasterNode() @@ -101,7 +97,6 @@ def TestInstanceStartup(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-shutdown') def TestInstanceShutdown(instance): """gnt-instance shutdown""" master = qa_config.GetMasterNode() @@ -111,7 +106,6 @@ def TestInstanceShutdown(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-reboot') def TestInstanceReboot(instance): """gnt-instance reboot""" master = qa_config.GetMasterNode() @@ -123,7 +117,6 @@ def TestInstanceReboot(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-reinstall') def TestInstanceReinstall(instance): """gnt-instance reinstall""" master = qa_config.GetMasterNode() @@ -133,7 +126,6 @@ def TestInstanceReinstall(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-failover') def TestInstanceFailover(instance): """gnt-instance failover""" master = qa_config.GetMasterNode() @@ -148,7 +140,6 @@ def TestInstanceFailover(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-info') def TestInstanceInfo(instance): """gnt-instance info""" master = qa_config.GetMasterNode() @@ -158,7 +149,6 @@ def TestInstanceInfo(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-modify') def TestInstanceModify(instance): """gnt-instance modify""" master = qa_config.GetMasterNode() @@ -191,7 +181,6 @@ def TestInstanceModify(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-list') def TestInstanceList(): """gnt-instance list""" master = qa_config.GetMasterNode() @@ -201,7 +190,6 @@ def TestInstanceList(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-console') def TestInstanceConsole(instance): """gnt-instance console""" master = qa_config.GetMasterNode() @@ -211,7 +199,6 @@ def TestInstanceConsole(instance): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('instance-replace-disks') def TestReplaceDisks(instance, pnode, snode, othernode): """gnt-instance replace-disks""" master = qa_config.GetMasterNode() @@ -240,7 +227,6 @@ def TestReplaceDisks(instance, pnode, snode, othernode): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('backup-export') def TestInstanceExport(instance, node): """gnt-backup export""" master = qa_config.GetMasterNode() @@ -252,7 +238,6 @@ def TestInstanceExport(instance, node): return qa_utils.ResolveInstanceName(instance) -@qa_utils.DefineHook('backup-import') def TestInstanceImport(node, newinst, expnode, name): """gnt-backup import""" master = qa_config.GetMasterNode() @@ -269,7 +254,6 @@ def TestInstanceImport(node, newinst, expnode, name): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('backup-list') def TestBackupList(expnode): """gnt-backup list""" master = qa_config.GetMasterNode() diff --git a/qa/qa_node.py b/qa/qa_node.py index f337734e5f5ddfcd3388d53a33d5e674dfef42b9..9899762e44707135ef63d477ab77b25c7d748d6f 100644 --- a/qa/qa_node.py +++ b/qa/qa_node.py @@ -28,7 +28,6 @@ import qa_utils from qa_utils import AssertEqual, StartSSH -@qa_utils.DefineHook('node-add') def _NodeAdd(node, readd=False): master = qa_config.GetMasterNode() @@ -49,7 +48,6 @@ def _NodeAdd(node, readd=False): node['_added'] = True -@qa_utils.DefineHook('node-remove') def _NodeRemove(node): master = qa_config.GetMasterNode() @@ -75,13 +73,11 @@ def TestNodeRemoveAll(): _NodeRemove(node) -@qa_utils.DefineHook('node-readd') def TestNodeReadd(node): """gnt-node add --readd""" _NodeAdd(node, readd=True) -@qa_utils.DefineHook('node-info') def TestNodeInfo(): """gnt-node info""" master = qa_config.GetMasterNode() @@ -91,7 +87,6 @@ def TestNodeInfo(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('node-volumes') def TestNodeVolumes(): """gnt-node volumes""" master = qa_config.GetMasterNode() @@ -101,7 +96,6 @@ def TestNodeVolumes(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('node-failover') def TestNodeFailover(node, node2): """gnt-node failover""" master = qa_config.GetMasterNode() @@ -122,7 +116,6 @@ def TestNodeFailover(node, node2): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('node-evacuate') def TestNodeEvacuate(node, node2): """gnt-node evacuate""" master = qa_config.GetMasterNode() diff --git a/qa/qa_os.py b/qa/qa_os.py index fbdaa27e631657bc06ff759ee6ead1c1973a3322..b39e3ca3917c3e420e96980fddd0951227ca40bb 100644 --- a/qa/qa_os.py +++ b/qa/qa_os.py @@ -39,7 +39,6 @@ _TEMP_OS_NAME = "TEMP-Ganeti-QA-OS" _TEMP_OS_PATH = os.path.join(constants.OS_SEARCH_PATH[0], _TEMP_OS_NAME) -@qa_utils.DefineHook('os-list') def TestOsList(): """gnt-os list""" master = qa_config.GetMasterNode() @@ -49,7 +48,6 @@ def TestOsList(): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('os-diagnose') def TestOsDiagnose(): """gnt-os diagnose""" master = qa_config.GetMasterNode() @@ -128,19 +126,16 @@ def _TestOs(mode): _RemoveTempOs(node, dir) -@qa_utils.DefineHook('os-valid') def TestOsValid(): """Testing valid OS definition""" return _TestOs(1) -@qa_utils.DefineHook('os-invalid') def TestOsInvalid(): """Testing invalid OS definition""" return _TestOs(0) -@qa_utils.DefineHook('os-partially-valid') def TestOsPartiallyValid(): """Testing partially valid OS definition""" return _TestOs(2) diff --git a/qa/qa_rapi.py b/qa/qa_rapi.py index 0f9054fc676280b48387cbade47de8d7e45f5ef7..f45f6c4d744303968b28e2a6e26c34d95b039c02 100644 --- a/qa/qa_rapi.py +++ b/qa/qa_rapi.py @@ -97,7 +97,6 @@ def _DoTests(uris): AssertEqual(data, verify) -@qa_utils.DefineHook('rapi-version') def TestVersion(): """Testing remote API version. @@ -107,7 +106,6 @@ def TestVersion(): ]) -@qa_utils.DefineHook('rapi-empty-cluster') def TestEmptyCluster(): """Testing remote API on an empty cluster. @@ -143,7 +141,6 @@ def TestEmptyCluster(): ]) -@qa_utils.DefineHook('rapi-instance') def TestInstance(instance): """Testing getting instance(s) info via remote API. @@ -168,7 +165,6 @@ def TestInstance(instance): ]) -@qa_utils.DefineHook('rapi-node') def TestNode(node): """Testing getting node(s) info via remote API. diff --git a/qa/qa_tags.py b/qa/qa_tags.py index 7cccced6f7a20da1761aa439bc46025cb368686d..ae19f2e31539d7488b57f6b034c71e3ecbad1f47 100644 --- a/qa/qa_tags.py +++ b/qa/qa_tags.py @@ -74,19 +74,16 @@ def _TestTags(kind, name): utils.ShellQuoteArgs(cmd)).wait(), 0) -@qa_utils.DefineHook('tags-cluster') def TestClusterTags(): """gnt-cluster tags""" _TestTags(constants.TAG_CLUSTER, "") -@qa_utils.DefineHook('tags-node') def TestNodeTags(node): """gnt-node tags""" _TestTags(constants.TAG_NODE, node["primary"]) -@qa_utils.DefineHook('tags-instance') def TestInstanceTags(instance): """gnt-instance tags""" _TestTags(constants.TAG_INSTANCE, instance["name"]) diff --git a/qa/qa_utils.py b/qa/qa_utils.py index 2005634351dcf59a916897cc25dcd6bb7a6c124e..bbf667cc46809bf9c30382068a760d9967c4a523 100644 --- a/qa/qa_utils.py +++ b/qa/qa_utils.py @@ -39,10 +39,6 @@ _ERROR_SEQ = None _RESET_SEQ = None -# List of all hooks -_hooks = [] - - def _SetupColours(): """Initializes the colour constants. @@ -225,87 +221,3 @@ def _FormatWithColor(text, seq): FormatWarning = lambda text: _FormatWithColor(text, _WARNING_SEQ) FormatError = lambda text: _FormatWithColor(text, _ERROR_SEQ) FormatInfo = lambda text: _FormatWithColor(text, _INFO_SEQ) - - -def LoadHooks(): - """Load all QA hooks. - - """ - hooks_dir = qa_config.get('options', {}).get('hooks-dir', None) - if not hooks_dir: - return - if hooks_dir not in sys.path: - sys.path.insert(0, hooks_dir) - for name in utils.ListVisibleFiles(hooks_dir): - if name.endswith('.py'): - # Load and instanciate hook - print "Loading hook %s" % name - _hooks.append(__import__(name[:-3], None, None, ['']).hook()) - - -class QaHookContext: - """Definition of context passed to hooks. - - """ - name = None - phase = None - success = None - args = None - kwargs = None - - -def _CallHooks(ctx): - """Calls all hooks with the given context. - - """ - if not _hooks: - return - - name = "%s-%s" % (ctx.phase, ctx.name) - if ctx.success is not None: - msg = "%s (success=%s)" % (name, ctx.success) - else: - msg = name - print FormatInfo("Begin %s" % msg) - for hook in _hooks: - hook.run(ctx) - print FormatInfo("End %s" % name) - - -def DefineHook(name): - """Wraps a function with calls to hooks. - - Usage: prefix function with @qa_utils.DefineHook(...) - - This is based on PEP 318, "Decorators for Functions and Methods". - - """ - def wrapper(fn): - def new_f(*args, **kwargs): - # Create context - ctx = QaHookContext() - ctx.name = name - ctx.phase = 'pre' - ctx.args = args - ctx.kwargs = kwargs - - _CallHooks(ctx) - try: - ctx.phase = 'post' - ctx.success = True - try: - # Call real function - return fn(*args, **kwargs) - except: - ctx.success = False - raise - finally: - _CallHooks(ctx) - - # Override function metadata - new_f.func_name = fn.func_name - new_f.func_doc = fn.func_doc - - return new_f - - return wrapper