diff options
| author | Joshua Harlow <harlowja@yahoo-inc.com> | 2012-09-14 14:32:31 -0700 | 
|---|---|---|
| committer | Joshua Harlow <harlowja@yahoo-inc.com> | 2012-09-14 14:32:31 -0700 | 
| commit | 2899c638c04907461024dff0d32c1cc57ae4b6d4 (patch) | |
| tree | 44ac16aa27e4b8e50124cd6229cc3587dae78347 | |
| parent | 0f385445522cf8fe76391c0c0c855b6fa7ad9f50 (diff) | |
| download | vyos-cloud-init-2899c638c04907461024dff0d32c1cc57ae4b6d4.tar.gz vyos-cloud-init-2899c638c04907461024dff0d32c1cc57ae4b6d4.zip | |
Add a basic signal test and write out all
the signal information in one block instead of many.
| -rw-r--r-- | cloudinit/signal_handler.py | 28 | ||||
| -rw-r--r-- | tests/unittests/test_signal.py | 46 | 
2 files changed, 68 insertions, 6 deletions
| diff --git a/cloudinit/signal_handler.py b/cloudinit/signal_handler.py index 96b618f3..b6ea592b 100644 --- a/cloudinit/signal_handler.py +++ b/cloudinit/signal_handler.py @@ -24,10 +24,14 @@ import sys  from StringIO import StringIO +from cloudinit import log as logging  from cloudinit import util  from cloudinit import version as vr +LOG = logging.getLogger(__name__) + +BACK_FRAME_TRACE_DEPTH = 3  EXIT_FOR = {      signal.SIGINT: ('Cloud-init %(version)s interrupted, exiting...', 1),      signal.SIGTERM: ('Cloud-init %(version)s terminated, exiting...', 1), @@ -37,24 +41,36 @@ EXIT_FOR = {  } -def _pprint_frame(frame, depth=1, max_depth=3): +def _pprint_frame(frame, depth, max_depth, contents):      if depth > max_depth or not frame:          return      frame_info = inspect.getframeinfo(frame)      prefix = " " * (depth * 2) -    contents = StringIO()      contents.write("%sFilename: %s\n" % (prefix, frame_info.filename))      contents.write("%sFunction: %s\n" % (prefix, frame_info.function))      contents.write("%sLine number: %s\n" % (prefix, frame_info.lineno)) -    util.multi_log(contents.getvalue()) -    _pprint_frame(frame.f_back, depth + 1, max_depth) +    _pprint_frame(frame.f_back, depth + 1, max_depth, contents)  def _handle_exit(signum, frame):      (msg, rc) = EXIT_FOR[signum] +    # Reset logging so that only the basic logging +    # is active since the state of syslog or other +    # logging processes is unknown if we are being +    # signaled by a reboot process which is external and +    # killing other processes while this process is being +    # finished off... +    try: +        logging.resetLogging() +        logging.setupBasicLogging() +    except: +        pass      msg = msg % ({'version': vr.version()}) -    util.multi_log("%s\n" % (msg)) -    _pprint_frame(frame) +    contents = StringIO() +    contents.write("%s\n" % (msg)) +    _pprint_frame(frame, 1, BACK_FRAME_TRACE_DEPTH, contents) +    util.multi_log(contents.getvalue(), +                   console=True, stderr=False, log=LOG)      sys.exit(rc) diff --git a/tests/unittests/test_signal.py b/tests/unittests/test_signal.py new file mode 100644 index 00000000..02fd1ef1 --- /dev/null +++ b/tests/unittests/test_signal.py @@ -0,0 +1,46 @@ +"""Tests for handling of signals within cloud init.""" + +import os +import subprocess +import sys +import time + +from StringIO import StringIO + +from mocker import MockerTestCase + + +class TestSignal(MockerTestCase): + +    def test_signal_output(self): + +        # This is done since nose/unittest is actually setting up +        # output capturing, signal handling itself, and its easier +        # to just call out to cloudinit with a loop and see what the result is +        run_what = [sys.executable,  +                    '-c', ('import time; from cloudinit import signal_handler;' +                           'signal_handler.attach_handlers(); time.sleep(120)')] + +        pc_info = subprocess.Popen(run_what, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + +        # Let it start up +        time.sleep(0.5) +        dead = None +        while dead is None: +            pc_info.terminate() +            # Ok not dead yet. try again +            time.sleep(0.5) +            dead = pc_info.poll() + +        outputs = StringIO() +        if pc_info.stdout: +            outputs.write(pc_info.stdout.read()) +        if pc_info.stderr: +            outputs.write(pc_info.stderr.read()) +        val = outputs.getvalue() +        print val + +        # Check some of the outputs that should of happened +        self.assertEquals(1, pc_info.wait()) +        self.assertTrue(len(val) != 0) +        self.assertTrue(val.find("terminated") != -1) | 
