diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py index c801c0ae5e0cf2e5a68415c856c19ad7bc42da07..021e1d9d27ccb8c2f24b978d40617adc333e2448 100755 --- a/qa/ganeti-qa.py +++ b/qa/ganeti-qa.py @@ -136,11 +136,19 @@ def main(): if qa_config.TestEnabled('instance-info'): RunTest(qa_instance.TestInstanceInfo, instance) - if qa_config.TestEnabled('instance-automatic-restart'): - RunTest(qa_daemon.TestInstanceAutomaticRestart, node, instance) + automatic_restart = \ + qa_config.TestEnabled('instance-automatic-restart') + consecutive_failures = \ + qa_config.TestEnabled('instance-consecutive-failures') - if qa_config.TestEnabled('instance-consecutive-failures'): - RunTest(qa_daemon.TestInstanceConsecutiveFailures, node, instance) + if automatic_restart or consecutive_failures: + qa_daemon.PrintCronWarning() + + if automatic_restart: + RunTest(qa_daemon.TestInstanceAutomaticRestart, node, instance) + + if consecutive_failures: + RunTest(qa_daemon.TestInstanceConsecutiveFailures, node, instance) if qa_config.TestEnabled('instance-export'): expnode = qa_config.AcquireNode(exclude=node) diff --git a/qa/qa_daemon.py b/qa/qa_daemon.py index e6e79fde6f070f3368f27ecc9b2800846367bd4f..8b40edf4823e4a090ecca7d038daa9a6f91bdb83 100644 --- a/qa/qa_daemon.py +++ b/qa/qa_daemon.py @@ -78,6 +78,15 @@ def _ResetWatcherDaemon(node): utils.ShellQuoteArgs(cmd)).wait(), 0) +def PrintCronWarning(): + """Shows a warning about the required cron job. + + """ + print + qa_utils.PrintWarning("The following tests require the cron script for" + " ganeti-watcher to be set up.") + + def TestInstanceAutomaticRestart(node, instance): """Test automatic restart of instance by ganeti-watcher. diff --git a/qa/qa_utils.py b/qa/qa_utils.py index 8e5a8fc6b2a0768bc3f993901a0f7424ddca089b..1ad596fb8deafc0dfbbdc1edaaab3571f3b89fb9 100644 --- a/qa/qa_utils.py +++ b/qa/qa_utils.py @@ -21,6 +21,7 @@ """ import os +import sys import subprocess from ganeti import utils @@ -29,6 +30,37 @@ import qa_config import qa_error +_INFO_SEQ = None +_WARNING_SEQ = None +_ERROR_SEQ = None +_RESET_SEQ = None + + +def _SetupColours(): + """Initializes the colour constants. + + """ + global _INFO_SEQ, _WARNING_SEQ, _ERROR_SEQ, _RESET_SEQ + + try: + import curses + except ImportError: + # Don't use colours if curses module can't be imported + return + + curses.setupterm() + + _RESET_SEQ = curses.tigetstr("op") + + setaf = curses.tigetstr("setaf") + _INFO_SEQ = curses.tparm(setaf, curses.COLOR_GREEN) + _WARNING_SEQ = curses.tparm(setaf, curses.COLOR_YELLOW) + _ERROR_SEQ = curses.tparm(setaf, curses.COLOR_RED) + + +_SetupColours() + + def AssertEqual(first, second, msg=None): """Raises an error when values aren't equal. @@ -113,3 +145,31 @@ def ResolveInstanceName(instance): AssertEqual(p.wait(), 0) return p.stdout.read().strip() + + +def _PrintWithColor(text, seq): + f = sys.stdout + + if not f.isatty(): + seq = None + + if seq: + f.write(seq) + + f.write(text) + f.write("\n") + + if seq: + f.write(_RESET_SEQ) + + +def PrintWarning(text): + return _PrintWithColor(text, _WARNING_SEQ) + + +def PrintError(f, text): + return _PrintWithColor(text, _ERROR_SEQ) + + +def PrintInfo(f, text): + return _PrintWithColor(text, _INFO_SEQ)