test_job_timeout.py 6.9 KB
Newer Older
1
import glob
2 3 4
import os
import tempfile
import shutil
5
import xml.dom.minidom
6
import unittest
7

8
from avocado.core import exit_codes
9
from avocado.utils import genio
10 11 12 13
from avocado.utils import process
from avocado.utils import script


14
basedir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..')
15 16
basedir = os.path.abspath(basedir)

17 18
AVOCADO = os.environ.get("UNITTEST_AVOCADO_CMD", "./scripts/avocado")

19 20 21 22 23 24 25

SCRIPT_CONTENT = """#!/bin/bash
sleep 2
"""

PYTHON_CONTENT = """#!/usr/bin/env python
import time
26
from avocado import Test
27

28
class Dummy(Test):
29
    def test00sleep(self):
30
        time.sleep(10)
31 32 33 34 35 36 37
    def test01pass(self):
        pass
    def test02pass(self):
        pass
"""


38 39 40 41
class ParseXMLError(Exception):
    pass


42 43 44 45 46 47 48 49 50 51 52 53 54
class JobTimeOutTest(unittest.TestCase):

    def setUp(self):
        self.script = script.TemporaryScript(
            'sleep.sh',
            SCRIPT_CONTENT,
            'avocado_timeout_functional')
        self.script.save()
        self.py = script.TemporaryScript(
            'sleep_test.py',
            PYTHON_CONTENT,
            'avocado_timeout_functional')
        self.py.save()
55
        self.tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
56 57
        os.chdir(basedir)

58 59 60 61 62 63 64 65 66 67
    def run_and_check(self, cmd_line, e_rc, e_ntests, e_nerrors, e_nfailures,
                      e_nskip):
        os.chdir(basedir)
        result = process.run(cmd_line, ignore_status=True)
        xml_output = result.stdout
        self.assertEqual(result.exit_status, e_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (e_rc, result))
        try:
            xunit_doc = xml.dom.minidom.parseString(xml_output)
68
        except Exception as detail:
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
            raise ParseXMLError("Failed to parse content: %s\n%s" %
                                (detail, xml_output))

        testsuite_list = xunit_doc.getElementsByTagName('testsuite')
        self.assertEqual(len(testsuite_list), 1, 'More than one testsuite tag')

        testsuite_tag = testsuite_list[0]
        self.assertEqual(len(testsuite_tag.attributes), 7,
                         'The testsuite tag does not have 7 attributes. '
                         'XML:\n%s' % xml_output)

        n_tests = int(testsuite_tag.attributes['tests'].value)
        self.assertEqual(n_tests, e_ntests,
                         "Unexpected number of executed tests, "
                         "XML:\n%s" % xml_output)

        n_errors = int(testsuite_tag.attributes['errors'].value)
        self.assertEqual(n_errors, e_nerrors,
                         "Unexpected number of test errors, "
                         "XML:\n%s" % xml_output)

        n_failures = int(testsuite_tag.attributes['failures'].value)
        self.assertEqual(n_failures, e_nfailures,
                         "Unexpected number of test failures, "
                         "XML:\n%s" % xml_output)

95
        n_skip = int(testsuite_tag.attributes['skipped'].value)
96 97 98 99
        self.assertEqual(n_skip, e_nskip,
                         "Unexpected number of test skips, "
                         "XML:\n%s" % xml_output)

100 101
    def _check_timeout_msg(self, idx):
        res_dir = os.path.join(self.tmpdir, "latest", "test-results")
102 103
        debug_log_paths = glob.glob(os.path.join(res_dir, "%s-*" % idx, "debug.log"))
        debug_log = genio.read_file(debug_log_paths[0])
104 105 106
        self.assertIn("Runner error occurred: Timeout reached", debug_log,
                      "Runner error occurred: Timeout reached message not "
                      "in the %sst test's debug.log:\n%s"
107 108 109 110 111
                      % (idx, debug_log))
        self.assertIn("Traceback (most recent call last)", debug_log,
                      "Traceback not present in the %sst test's debug.log:\n%s"
                      % (idx, debug_log))

112
    def test_sleep_longer_timeout(self):
113
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
114
                    '--xunit - --job-timeout=5 %s examples/tests/passtest.py' %
115
                    (AVOCADO, self.tmpdir, self.script.path))
116
        self.run_and_check(cmd_line, 0, 2, 0, 0, 0)
117 118

    def test_sleep_short_timeout(self):
119
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
120
                    '--xunit - --job-timeout=1 %s examples/tests/passtest.py' %
121
                    (AVOCADO, self.tmpdir, self.script.path))
122 123
        self.run_and_check(cmd_line, exit_codes.AVOCADO_JOB_INTERRUPTED,
                           2, 1, 0, 1)
124
        self._check_timeout_msg(1)
125 126

    def test_sleep_short_timeout_with_test_methods(self):
127
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
128
                    '--xunit - --job-timeout=1 %s' %
129
                    (AVOCADO, self.tmpdir, self.py.path))
130 131
        self.run_and_check(cmd_line, exit_codes.AVOCADO_JOB_INTERRUPTED,
                           3, 1, 0, 2)
132
        self._check_timeout_msg(1)
133 134

    def test_invalid_values(self):
135 136 137
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
                    '--job-timeout=1,5 examples/tests/passtest.py'
                    % (AVOCADO, self.tmpdir))
138
        result = process.run(cmd_line, ignore_status=True)
139
        self.assertEqual(result.exit_status, exit_codes.AVOCADO_FAIL)
140
        self.assertIn('Invalid value', result.stderr)
141 142 143
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
                    '--job-timeout=123x examples/tests/passtest.py'
                    % (AVOCADO, self.tmpdir))
144
        result = process.run(cmd_line, ignore_status=True)
145
        self.assertEqual(result.exit_status, exit_codes.AVOCADO_FAIL)
146
        self.assertIn('Invalid value', result.stderr)
147 148

    def test_valid_values(self):
149 150 151
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
                    '--job-timeout=123 examples/tests/passtest.py'
                    % (AVOCADO, self.tmpdir))
152
        result = process.run(cmd_line, ignore_status=True)
153
        self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
154 155 156
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
                    '--job-timeout=123s examples/tests/passtest.py'
                    % (AVOCADO, self.tmpdir))
157
        result = process.run(cmd_line, ignore_status=True)
158
        self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
159 160 161
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
                    '--job-timeout=123m examples/tests/passtest.py'
                    % (AVOCADO, self.tmpdir))
162
        result = process.run(cmd_line, ignore_status=True)
163
        self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
164 165 166
        cmd_line = ('%s run --job-results-dir %s --sysinfo=off '
                    '--job-timeout=123h examples/tests/passtest.py'
                    % (AVOCADO, self.tmpdir))
167
        result = process.run(cmd_line, ignore_status=True)
168
        self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
169 170 171 172 173 174

    def tearDown(self):
        self.script.remove()
        self.py.remove()
        shutil.rmtree(self.tmpdir)

L
Lukáš Doktor 已提交
175

176 177
if __name__ == '__main__':
    unittest.main()