test_test.py 12.7 KB
Newer Older
1 2 3
import os
import shutil
import tempfile
4
import unittest
5

6
from flexmock import flexmock, flexmock_teardown
7

8
from avocado.core import test, exceptions
9
from avocado.utils import script
10 11 12 13 14 15 16 17 18 19

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

FAIL_SCRIPT_CONTENTS = """#!/bin/sh
false
"""


20 21
class TestClassTestUnit(unittest.TestCase):

22 23 24 25
    class DummyTest(test.Test):
        def test(self):
            pass

26 27 28 29
    def setUp(self):
        self.tmpdir = tempfile.mkdtemp(prefix="avocado_" + __name__)

    def tearDown(self):
30
        flexmock_teardown()
31 32
        shutil.rmtree(self.tmpdir)

33
    def test_ugly_name(self):
34 35
        def run(name, path_name):
            """ Initialize test and check the dirs were created """
36
            tst = self.DummyTest("test", test.TestID(1, name),
37
                                 base_logdir=self.tmpdir)
38 39 40
            self.assertEqual(os.path.basename(tst.logdir), path_name)
            self.assertTrue(os.path.exists(tst.logdir))
            self.assertEqual(os.path.dirname(os.path.dirname(tst.logdir)),
41 42
                             self.tmpdir)

43 44
        run("/absolute/path", "1-_absolute_path")
        run("./relative/path", "1-._relative_path")
45
        run("../../multi_level/relative/path",
46
            "1-.._.._multi_level_relative_path")
47 48
        # Greek word 'kosme'
        run("\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5",
49
            "1-\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5")
50 51 52 53 54 55 56
        # Particularly problematic noncharacters in 16-bit applications
        name = ("\xb7\x95\xef\xb7\x96\xef\xb7\x97\xef\xb7\x98\xef\xb7\x99"
                "\xef\xb7\x9a\xef\xb7\x9b\xef\xb7\x9c\xef\xb7\x9d\xef\xb7"
                "\x9e\xef\xb7\x9f\xef\xb7\xa0\xef\xb7\xa1\xef\xb7\xa2\xef"
                "\xb7\xa3\xef\xb7\xa4\xef\xb7\xa5\xef\xb7\xa6\xef\xb7\xa7"
                "\xef\xb7\xa8\xef\xb7\xa9\xef\xb7\xaa\xef\xb7\xab\xef\xb7"
                "\xac\xef\xb7\xad\xef\xb7\xae\xef\xb7\xaf")
57
        run(name, "1-" + name)
58

59
    def test_long_name(self):
60
        def check(uid, name, variant, exp_logdir):
61
            tst = self.DummyTest("test", test.TestID(uid, name, variant),
62
                                 base_logdir=self.tmpdir)
63 64 65 66 67
            self.assertEqual(os.path.basename(tst.logdir), exp_logdir)
            return tst

        # Everything fits
        check(1, "a" * 253, None, "1-" + ("a" * 253))
68 69
        check(2, "a" * 251, {"variant_id": 1}, "2-" + ("a" * 251) + "+1")
        check(99, "a" * 249, {"variant_id": 88}, "99-" + ("a" * 249) + "+88")
70
        # Shrink name
71
        check(3, "a" * 252, {"variant_id": 1}, "3-" + ('a' * 251) + "+1")
72
        # Shrink variant
73 74
        check("a" * 253, "whatever", {"variant_id": 99}, "a" * 253 + "+9")
        check("a" * 254, "whatever", {"variant_id": 99}, "a" * 254 + "+")
75
        # No variant
76 77
        tst = check("a" * 255, "whatever", {"variant_id": "whatever-else"},
                    "a" * 255)
78
        # Impossible to store (uid does not fit
79 80
        self.assertRaises(AssertionError, check, "a" * 256, "whatever",
                          {"variant_id": "else"}, None)
81 82 83 84 85 86

        self.assertEqual(os.path.basename(tst.workdir),
                         os.path.basename(tst.logdir))
        flexmock(tst)
        tst.should_receive('filename').and_return(os.path.join(self.tmpdir,
                                                               "a"*250))
87
        self.assertEqual(os.path.join(self.tmpdir, "a"*250 + ".data"),
88 89 90 91 92 93 94
                         tst.datadir)
        tst.should_receive('filename').and_return("a"*251)
        self.assertFalse(tst.datadir)
        tst._record_reference_stdout       # Should does nothing
        tst._record_reference_stderr       # Should does nothing
        tst._record_reference_stdout()
        tst._record_reference_stderr()
95

96
    def test_all_dirs_exists_no_hang(self):
97
        flexmock(os.path)
98
        os.path.should_receive('exists').and_return(True)
99
        self.assertRaises(exceptions.TestSetupFail, self.DummyTest, "test",
100
                          test.TestID(1, "name"), base_logdir=self.tmpdir)
101

102
    def test_try_override_test_variable(self):
103 104 105 106
        test = self.DummyTest(base_logdir=self.tmpdir)
        self.assertRaises(AttributeError, setattr, test, "name", "whatever")
        self.assertRaises(AttributeError, setattr, test, "status", "whatever")

107

108 109 110
class TestClassTest(unittest.TestCase):

    def setUp(self):
111 112
        class AvocadoPass(test.Test):

113
            def test(self):
114 115 116 117
                variable = True
                self.assertTrue(variable)
                self.whiteboard = 'foo'

118
        self.base_logdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
119 120 121
        self.tst_instance_pass = AvocadoPass(base_logdir=self.base_logdir)
        self.tst_instance_pass.run_avocado()

122
    def test_class_attributes_name(self):
123
        self.assertEqual(self.tst_instance_pass.name, '0-AvocadoPass')
124

125
    def test_class_attributes_status(self):
126 127
        self.assertEqual(self.tst_instance_pass.status, 'PASS')

128
    def test_class_attributes_time_elapsed(self):
129 130
        self.assertIsInstance(self.tst_instance_pass.time_elapsed, float)

131
    def test_whiteboard_save(self):
132 133
        whiteboard_file = os.path.join(
            self.tst_instance_pass.logdir, 'whiteboard')
134 135 136 137 138
        self.assertTrue(os.path.isfile(whiteboard_file))
        with open(whiteboard_file, 'r') as whiteboard_file_obj:
            whiteboard_contents = whiteboard_file_obj.read().strip()
            self.assertTrue(whiteboard_contents, 'foo')

139
    def test_running_test_twice_with_the_same_uid_failure(self):
140 141 142 143 144 145 146
        class AvocadoPass(test.Test):

            def test(self):
                pass

        self.assertRaises(exceptions.TestSetupFail, AvocadoPass,
                          base_logdir=self.base_logdir)
147 148

    def tearDown(self):
149
        shutil.rmtree(self.base_logdir)
150 151


152
class SimpleTestClassTest(unittest.TestCase):
153 154

    def setUp(self):
155
        self.tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
156 157 158
        self.pass_script = script.TemporaryScript(
            'avocado_pass.sh',
            PASS_SCRIPT_CONTENTS,
159
            'avocado_simpletest_unittest')
160 161 162 163 164
        self.pass_script.save()

        self.fail_script = script.TemporaryScript(
            'avocado_fail.sh',
            FAIL_SCRIPT_CONTENTS,
165
            'avocado_simpletest_unittest')
166 167
        self.fail_script.save()

168
        self.tst_instance_pass = test.SimpleTest(
169
            name=test.TestID(1, self.pass_script.path),
170
            base_logdir=self.tmpdir)
171 172
        self.tst_instance_pass.run_avocado()

173
        self.tst_instance_fail = test.SimpleTest(
174
            name=test.TestID(1, self.fail_script.path),
175
            base_logdir=self.tmpdir)
176 177
        self.tst_instance_fail.run_avocado()

178
    def test_simple_test_pass_status(self):
179 180
        self.assertEqual(self.tst_instance_pass.status, 'PASS')

181
    def test_simple_test_fail_status(self):
182 183 184
        self.assertEqual(self.tst_instance_fail.status, 'FAIL')

    def tearDown(self):
185 186
        self.pass_script.remove()
        self.fail_script.remove()
187
        shutil.rmtree(self.tmpdir)
188

189

190
class MockingTest(unittest.TestCase):
191 192 193 194 195 196

    def setUp(self):
        self.tests = []

    def test_init(self):
        # No params
197
        self.tests.append(test.MockingTest())
198
        # Positional
199
        self.tests.append(test.MockingTest("test", test.TestID(1, "my_name"),
200 201 202
                                           {}, None, "1",
                                           None, None, "extra_param1",
                                           "extra_param2"))
203
        self.assertEqual(self.tests[-1].name, "1-my_name")
204
        # Kwargs
205
        self.tests.append(test.MockingTest(methodName="test",
206
                                           name=test.TestID(1, "my_name2"),
207 208 209 210
                                           params={}, base_logdir=None,
                                           tag="a", job=None, runner_queue=None,
                                           extra1="extra_param1",
                                           extra2="extra_param2"))
211
        self.assertEqual(self.tests[-1].name, "1-my_name2")
212 213
        # both (theoretically impossible in python, but valid for nasty tests)
        # keyword args are used as they explicitly represent what they mean
214 215 216 217
        self.tests.append(test.MockingTest("not used", "who cares", {}, None, "0",
                                           None, None, "extra_param1",
                                           "extra_param2",
                                           methodName="test",
218
                                           name=test.TestID(1, "my_name3"),
219 220 221 222
                                           params={}, base_logdir=None,
                                           tag="3", job=None, runner_queue=None,
                                           extra1="extra_param3",
                                           extra2="extra_param4"))
223
        self.assertEqual(self.tests[-1].name, "1-my_name3")
224
        # combination
225
        self.tests.append(test.MockingTest("test", test.TestID(1, "my_name4"),
226 227
                                           tag="321",
                                           other_param="Whatever"))
228
        self.assertEqual(self.tests[-1].name, "1-my_name4")
229 230 231 232 233 234
        # ugly combination (positional argument overrides kwargs, this only
        # happens when the substituted class reorders the positional arguments.
        # We try to first match keyword args and then fall-back to positional
        # ones.
        name = "positional_method_name_becomes_test_name"
        tag = "positional_base_logdir_becomes_tag"
235
        self.tests.append(test.MockingTest(test.TestID(1, name), None, None, tag,
236 237
                                           methodName="test",
                                           other_param="Whatever"))
238
        self.assertEqual(self.tests[-1].name, "1-" + name)
239 240 241 242

    def tearDown(self):
        for tst in self.tests:
            try:
243
                shutil.rmtree(os.path.dirname(os.path.dirname(tst.logdir)))
244 245 246
            except Exception:
                pass

L
Lukáš Doktor 已提交
247

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
class TestID(unittest.TestCase):

    def test_uid_name(self):
        uid = 1
        name = 'file.py:klass.test_method'
        test_id = test.TestID(uid, name)
        self.assertEqual(test_id.uid, 1)
        self.assertEqual(test_id.str_uid, '1')
        self.assertEqual(test_id.str_filesystem, '%s-%s' % (uid, name))
        self.assertIs(test_id.variant, None)
        self.assertIs(test_id.str_variant, '')

    def test_uid_name_no_digits(self):
        uid = 1
        name = 'file.py:klass.test_method'
        test_id = test.TestID(uid, name, no_digits=2)
        self.assertEqual(test_id.uid, 1)
        self.assertEqual(test_id.str_uid, '01')
        self.assertEqual(test_id.str_filesystem, '%s-%s' % ('01', name))
        self.assertIs(test_id.variant, None)
        self.assertIs(test_id.str_variant, '')

    def test_uid_name_large_digits(self):
        """
        Tests that when the filesystem can only cope with the size of
        the Test ID, that's the only thing that will be kept.
        """
        uid = 1
        name = 'test'
        test_id = test.TestID(uid, name, no_digits=255)
        self.assertEqual(test_id.uid, 1)
        self.assertEqual(test_id.str_uid, '%0255i' % uid)
        self.assertEqual(test_id.str_filesystem, '%0255i' % uid)
        self.assertIs(test_id.variant, None)
        self.assertIs(test_id.str_variant, '')

284
    def test_uid_name_uid_too_large_digits(self):
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
        """
        Tests that when the filesystem can not cope with the size of
        the Test ID, not even the test uid, an exception will be
        raised.
        """
        test_id = test.TestID(1, 'test', no_digits=256)
        self.assertRaises(AssertionError, lambda: test_id.str_filesystem)

    def test_uid_large_name(self):
        """
        Tests that when the filesystem can not cope with the size of
        the Test ID, the name will be shortened.
        """
        uid = 1
        name = 'test_' * 51     # 255 characters
        test_id = test.TestID(uid, name)
        self.assertEqual(test_id.uid, 1)
        # only 253 can fit for the test name
        self.assertEqual(test_id.str_filesystem, '%s-%s' % (uid, name[:253]))
        self.assertIs(test_id.variant, None)
        self.assertIs(test_id.str_variant, "")

    def test_uid_name_large_variant(self):
        """
        Tests that when the filesystem can not cope with the size of
        the Test ID, and a variant name is present, the name will be
        removed.
        """
        uid = 1
        name = 'test'
        variant_id = 'fast_' * 51    # 255 characters
        variant = {'variant_id': variant_id}
        test_id = test.TestID(uid, name, variant=variant)
        self.assertEqual(test_id.uid, 1)
319
        self.assertEqual(test_id.str_filesystem, '%s+%s' % (uid, variant_id[:253]))
320
        self.assertIs(test_id.variant, variant_id)
321
        self.assertEqual(test_id.str_variant, "+%s" % variant_id)
322 323


324 325
if __name__ == '__main__':
    unittest.main()