test_loader.py 7.5 KB
Newer Older
1
import os
2
import subprocess
3
import time
4
import stat
5 6
import tempfile
import shutil
7
import signal
8
import unittest
9

10
from avocado.core import exit_codes
11 12 13 14
from avocado.utils import script
from avocado.utils import process


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

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

20

21
AVOCADO_TEST_OK = """#!/usr/bin/env python
22
from avocado import Test
23
from avocado import main
24

25
class PassTest(Test):
26
    def test(self):
27 28 29
        pass

if __name__ == "__main__":
30
    main()
31 32
"""

33

34
AVOCADO_TEST_SLEEP_ELEVEN = """#!/usr/bin/env python
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
import time

from avocado import Test
from avocado import main

class SleepEleven(Test):
    def test(self):
        time.sleep(10)
    def test_2(self):
        time.sleep(1)

time.sleep(11)

if __name__ == "__main__":
    main()
"""


53
AVOCADO_TEST_MULTIPLE_CLASSES = """#!/usr/bin/env python
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
import time

from avocado import Test
from avocado import main

class First(Test):
    def test(self):
        pass

class Second(Test):
    def test(self):
        pass

if __name__ == "__main__":
    main()
"""

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
AVOCADO_TEST_MULTIPLE_METHODS_SAME_NAME = """#!/usr/bin/env python
from avocado import Test
from avocado import main

class Multiple(Test):
    def test(self):
        raise

    def test(self):
        pass

if __name__ == "__main__":
    main()
"""

86 87
NOT_A_TEST = """
def hello():
88
    print('Hello World!')
89 90
"""

91
PY_SIMPLE_TEST = """#!/usr/bin/env python
92
def hello():
93
    print('Hello World!')
94 95 96 97 98 99 100 101 102

if __name__ == "__main__":
    hello()
"""

SIMPLE_TEST = """#!/bin/sh
true
"""

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
AVOCADO_SIMPLE_PYTHON_LIKE_MULTIPLE_FILES = """#!/usr/bin/env python
# A simple test (executable bit set when saved to file) that looks like
# an Avocado instrumented test, with base class on separate file
from avocado import Test
from avocado import main
from test2 import *

class BasicTestSuite(SuperTest):

    def test1(self):
        self.xxx()
        self.assertTrue(True)

if __name__ == '__main__':
    main()
"""

AVOCADO_SIMPLE_PYTHON_LIKE_MULTIPLE_FILES_LIB = """
#!/usr/bin/python

from avocado import Test

class SuperTest(Test):
    def xxx(self):
        print "ahoj"
"""

AVOCADO_TEST_SIMPLE_USING_MAIN = """#!/usr/bin/env python
from avocado import main

if __name__ == "__main__":
    main()
"""

137 138 139

class LoaderTestFunctional(unittest.TestCase):

140 141 142 143 144 145 146 147
    MODE_0664 = (stat.S_IRUSR | stat.S_IWUSR |
                 stat.S_IRGRP | stat.S_IWGRP |
                 stat.S_IROTH)

    MODE_0775 = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
                 stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP |
                 stat.S_IROTH | stat.S_IXOTH)

148
    def setUp(self):
149
        os.chdir(basedir)
150
        self.tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
151

152
    def _test(self, name, content, exp_str, mode=MODE_0664, count=1):
153 154 155 156
        test_script = script.TemporaryScript(name, content,
                                             'avocado_loader_test',
                                             mode=mode)
        test_script.save()
157
        cmd_line = ('%s list -V %s' % (AVOCADO, test_script.path))
158
        result = process.run(cmd_line)
159
        self.assertIn('%s: %s' % (exp_str, count), result.stdout)
160 161
        test_script.remove()

162 163 164 165
    def _run_with_timeout(self, cmd_line, timeout):
        current_time = time.time()
        deadline = current_time + timeout
        test_process = subprocess.Popen(cmd_line, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
166
                                        preexec_fn=os.setsid, shell=True)
167 168 169 170 171 172 173
        while not test_process.poll():
            if time.time() > deadline:
                os.killpg(os.getpgid(test_process.pid), signal.SIGKILL)
                self.fail("Failed to run test under %s seconds" % timeout)
            time.sleep(0.05)
        self.assertEquals(test_process.returncode, exit_codes.AVOCADO_TESTS_FAIL)

174
    def test_simple(self):
175
        self._test('simpletest.sh', SIMPLE_TEST, 'SIMPLE', self.MODE_0775)
176 177

    def test_simple_not_exec(self):
178
        self._test('simpletest.sh', SIMPLE_TEST, 'NOT_A_TEST')
179 180

    def test_pass(self):
181
        self._test('passtest.py', AVOCADO_TEST_OK, 'INSTRUMENTED')
182

183 184 185 186 187 188 189 190
    def test_sleep_a_lot(self):
        """
        Verifies that the test loader, at list time, does not load the Python
        module and thus executes its contents.
        """
        test_script = script.TemporaryScript('sleepeleven.py',
                                             AVOCADO_TEST_SLEEP_ELEVEN,
                                             'avocado_loader_test',
191
                                             mode=self.MODE_0664)
192
        test_script.save()
193
        cmd_line = ('%s list -V %s' % (AVOCADO, test_script.path))
194 195 196 197 198 199 200 201 202 203
        initial_time = time.time()
        result = process.run(cmd_line, ignore_status=True)
        test_script.remove()
        actual_time = time.time() - initial_time
        self.assertLess(actual_time, 3.0,
                        ("Took more than 3 seconds to list tests. Loader "
                         "probably loaded/executed Python code and slept for "
                         "eleven seconds."))
        self.assertIn('INSTRUMENTED: 2', result.stdout)

204 205
    def test_multiple_class(self):
        self._test('multipleclasses.py', AVOCADO_TEST_MULTIPLE_CLASSES,
206
                   'INSTRUMENTED', self.MODE_0664, 2)
207

208 209 210 211
    def test_multiple_methods_same_name(self):
        self._test('multiplemethods.py', AVOCADO_TEST_MULTIPLE_METHODS_SAME_NAME,
                   'INSTRUMENTED', 0664, 1)

212
    def test_load_not_a_test(self):
213
        self._test('notatest.py', NOT_A_TEST, 'SIMPLE', self.MODE_0775)
214 215

    def test_load_not_a_test_not_exec(self):
216
        self._test('notatest.py', NOT_A_TEST, 'NOT_A_TEST')
217

218 219 220
    @unittest.skipIf(os.environ.get("AVOCADO_CHECK_FULL") != "1",
                     "Skipping test that take a long time to run, are "
                     "resource intensive or time sensitve")
221 222 223 224 225 226 227 228 229 230 231 232
    def test_runner_simple_python_like_multiple_files(self):
        mylib = script.TemporaryScript(
            'test2.py',
            AVOCADO_SIMPLE_PYTHON_LIKE_MULTIPLE_FILES_LIB,
            'avocado_simpletest_functional',
            0644)
        mylib.save()
        mytest = script.Script(
            os.path.join(os.path.dirname(mylib.path), 'test.py'),
            AVOCADO_SIMPLE_PYTHON_LIKE_MULTIPLE_FILES)
        os.chdir(basedir)
        mytest.save()
233
        cmd_line = "%s list -V %s" % (AVOCADO, mytest)
234 235 236 237
        result = process.run(cmd_line)
        self.assertIn('SIMPLE: 1', result.stdout)
        # job should be able to finish under 5 seconds. If this fails, it's
        # possible that we hit the "simple test fork bomb" bug
238 239
        cmd_line = ("%s run --sysinfo=off --job-results-dir '%s' -- '%s'"
                    % (AVOCADO, self.tmpdir, mytest))
240 241 242 243 244 245 246 247 248 249
        self._run_with_timeout(cmd_line, 5)

    def test_simple_using_main(self):
        mytest = script.TemporaryScript("simple_using_main.py",
                                        AVOCADO_TEST_SIMPLE_USING_MAIN,
                                        'avocado_simpletest_functional')
        mytest.save()
        os.chdir(basedir)
        # job should be able to finish under 5 seconds. If this fails, it's
        # possible that we hit the "simple test fork bomb" bug
250 251
        cmd_line = ("%s run --sysinfo=off --job-results-dir '%s' -- '%s'"
                    % (AVOCADO, self.tmpdir, mytest))
252 253
        self._run_with_timeout(cmd_line, 5)

254 255 256 257
    def tearDown(self):
        shutil.rmtree(self.tmpdir)


258 259
if __name__ == '__main__':
    unittest.main()