test_output.py 14.8 KB
Newer Older
1 2
import json
import tempfile
3
import os
4
import re
5
import sys
6
import shutil
7
from xml.dom import minidom
8

9 10 11 12 13
if sys.version_info[:2] == (2, 6):
    import unittest2 as unittest
else:
    import unittest

14
from avocado.core import exit_codes
15
from avocado.core.output import TermSupport
16
from avocado.utils import process
17

18 19 20 21
basedir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..')
basedir = os.path.abspath(basedir)


22 23 24 25 26 27 28 29
def image_output_uncapable():
    try:
        import PIL
        return False
    except ImportError:
        return True


30 31
class OutputTest(unittest.TestCase):

32
    def setUp(self):
33
        self.tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
34

35 36
    def test_output_doublefree(self):
        os.chdir(basedir)
37
        cmd_line = './scripts/avocado run --job-results-dir %s --sysinfo=off doublefree' % self.tmpdir
38
        result = process.run(cmd_line, ignore_status=True)
39
        expected_rc = exit_codes.AVOCADO_ALL_OK
40 41 42 43 44 45 46 47 48
        output = result.stdout + result.stderr
        self.assertEqual(result.exit_status, expected_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (expected_rc, result))
        bad_string = 'double free or corruption'
        self.assertNotIn(bad_string, output,
                         "Libc double free can be seen in avocado "
                         "doublefree output:\n%s" % output)

49 50 51
    def tearDown(self):
        shutil.rmtree(self.tmpdir)

52

53 54
class OutputPluginTest(unittest.TestCase):

55
    def setUp(self):
56
        self.tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
57

58 59 60 61 62 63 64 65 66 67
    def check_output_files(self, debug_log):
        base_dir = os.path.dirname(debug_log)
        json_output = os.path.join(base_dir, 'results.json')
        self.assertTrue(os.path.isfile(json_output))
        with open(json_output, 'r') as fp:
            json.load(fp)
        xunit_output = os.path.join(base_dir, 'results.xml')
        self.assertTrue(os.path.isfile(json_output))
        minidom.parse(xunit_output)

68 69
    def test_output_incompatible_setup(self):
        os.chdir(basedir)
70
        cmd_line = './scripts/avocado run --job-results-dir %s --sysinfo=off --xunit - --json - passtest' % self.tmpdir
71
        result = process.run(cmd_line, ignore_status=True)
72
        expected_rc = exit_codes.AVOCADO_JOB_FAIL
73 74 75 76
        output = result.stdout + result.stderr
        self.assertEqual(result.exit_status, expected_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (expected_rc, result))
77 78 79 80
        error_regex = re.compile(r'Options ((--json --xunit)|(--xunit --json)) '
                                 'are trying to use stdout simultaneously')
        self.assertIsNotNone(error_regex.match(output),
                             "Missing error message from output:\n%s" % output)
81 82

    def test_output_incompatible_setup_2(self):
83
        os.chdir(basedir)
84
        cmd_line = './scripts/avocado run --job-results-dir %s --sysinfo=off --html - passtest' % self.tmpdir
85
        result = process.run(cmd_line, ignore_status=True)
86
        expected_rc = exit_codes.AVOCADO_JOB_FAIL
87 88 89 90 91 92 93 94
        output = result.stdout + result.stderr
        self.assertEqual(result.exit_status, expected_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (expected_rc, result))
        error_excerpt = "HTML to stdout not supported"
        self.assertIn(error_excerpt, output,
                      "Missing excerpt error message from output:\n%s" % output)

95 96 97
    def test_output_compatible_setup(self):
        tmpfile = tempfile.mktemp()
        os.chdir(basedir)
98 99
        cmd_line = ('./scripts/avocado run --job-results-dir %s --sysinfo=off --journal --xunit %s --json - passtest' %
                    (self.tmpdir, tmpfile))
100 101
        result = process.run(cmd_line, ignore_status=True)
        output = result.stdout + result.stderr
102
        expected_rc = exit_codes.AVOCADO_ALL_OK
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
        try:
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
            # Check if we are producing valid outputs
            json.loads(output)
            minidom.parse(tmpfile)
        finally:
            try:
                os.remove(tmpfile)
            except OSError:
                pass

    def test_output_compatible_setup_2(self):
        tmpfile = tempfile.mktemp()
        os.chdir(basedir)
119 120
        cmd_line = ('./scripts/avocado run --job-results-dir %s --sysinfo=off --xunit - --json %s passtest' %
                    (self.tmpdir, tmpfile))
121 122
        result = process.run(cmd_line, ignore_status=True)
        output = result.stdout + result.stderr
123
        expected_rc = exit_codes.AVOCADO_ALL_OK
124 125 126 127 128 129
        try:
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
            # Check if we are producing valid outputs
            with open(tmpfile, 'r') as fp:
130 131 132
                json_results = json.load(fp)
                debug_log = json_results['debuglog']
                self.check_output_files(debug_log)
133 134 135 136 137 138 139
            minidom.parseString(output)
        finally:
            try:
                os.remove(tmpfile)
            except OSError:
                pass

140
    def test_output_compatible_setup_3(self):
141 142 143
        tmpfile = tempfile.mktemp(prefix='avocado_' + __name__)
        tmpfile2 = tempfile.mktemp(prefix='avocado_' + __name__)
        tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__)
144
        tmpfile3 = tempfile.mktemp(dir=tmpdir)
145
        os.chdir(basedir)
146 147
        cmd_line = ('./scripts/avocado run --job-results-dir %s --sysinfo=off --xunit %s --json %s --html %s passtest' %
                    (self.tmpdir, tmpfile, tmpfile2, tmpfile3))
148 149
        result = process.run(cmd_line, ignore_status=True)
        output = result.stdout + result.stderr
150
        expected_rc = exit_codes.AVOCADO_ALL_OK
151 152 153
        tmpdir_contents = os.listdir(tmpdir)
        self.assertEqual(len(tmpdir_contents), 5,
                         'Not all resources dir were created: %s' % tmpdir_contents)
154 155 156 157
        try:
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
158
            self.assertNotEqual(output, "", "Output is empty")
159
            # Check if we are producing valid outputs
160 161 162 163 164 165 166 167 168
            with open(tmpfile2, 'r') as fp:
                json_results = json.load(fp)
                debug_log = json_results['debuglog']
                self.check_output_files(debug_log)
            minidom.parse(tmpfile)
        finally:
            try:
                os.remove(tmpfile)
                os.remove(tmpfile2)
169
                shutil.rmtree(tmpdir)
170 171 172 173 174 175 176
            except OSError:
                pass

    def test_output_compatible_setup_nooutput(self):
        tmpfile = tempfile.mktemp()
        tmpfile2 = tempfile.mktemp()
        os.chdir(basedir)
177 178
        # Verify --silent can be supplied as app argument
        cmd_line = ('./scripts/avocado --silent run --job-results-dir %s --sysinfo=off --xunit %s --json %s passtest' %
179
                    (self.tmpdir, tmpfile, tmpfile2))
180 181
        result = process.run(cmd_line, ignore_status=True)
        output = result.stdout + result.stderr
182
        expected_rc = exit_codes.AVOCADO_ALL_OK
183 184 185 186 187 188
        try:
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
            self.assertEqual(output, "", "Output is not empty:\n%s" % output)
            # Check if we are producing valid outputs
189
            with open(tmpfile2, 'r') as fp:
190 191 192
                json_results = json.load(fp)
                debug_log = json_results['debuglog']
                self.check_output_files(debug_log)
193 194 195 196 197 198 199 200
            minidom.parse(tmpfile)
        finally:
            try:
                os.remove(tmpfile)
                os.remove(tmpfile2)
            except OSError:
                pass

201 202
    def test_show_job_log(self):
        os.chdir(basedir)
203
        cmd_line = './scripts/avocado run --job-results-dir %s --sysinfo=off passtest --show-job-log' % self.tmpdir
204
        result = process.run(cmd_line, ignore_status=True)
205
        expected_rc = exit_codes.AVOCADO_ALL_OK
206 207 208
        self.assertEqual(result.exit_status, expected_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (expected_rc, result))
209
        job_id_list = re.findall('Job ID: (.*)', result.stdout,
210
                                 re.MULTILINE)
211 212
        self.assertTrue(job_id_list, 'No Job ID in stdout:\n%s' %
                        result.stdout)
213 214
        job_id = job_id_list[0]
        self.assertEqual(len(job_id), 40)
215 216 217

    def test_silent_trumps_show_job_log(self):
        os.chdir(basedir)
218 219
        # Also verify --silent can be supplied as run option
        cmd_line = ('./scripts/avocado run --silent --job-results-dir %s --sysinfo=off passtest --show-job-log' %
220
                    self.tmpdir)
221 222
        result = process.run(cmd_line, ignore_status=True)
        output = result.stdout + result.stderr
223
        expected_rc = exit_codes.AVOCADO_ALL_OK
224 225 226 227 228
        self.assertEqual(result.exit_status, expected_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (expected_rc, result))
        self.assertEqual(output, "")

229 230
    def test_default_enabled_plugins(self):
        os.chdir(basedir)
231
        cmd_line = './scripts/avocado run --job-results-dir %s --sysinfo=off passtest' % self.tmpdir
232 233
        result = process.run(cmd_line, ignore_status=True)
        output = result.stdout + result.stderr
234
        expected_rc = exit_codes.AVOCADO_ALL_OK
235 236 237 238
        self.assertEqual(result.exit_status, expected_rc,
                         "Avocado did not return rc %d:\n%s" %
                         (expected_rc, result))
        output_lines = output.splitlines()
C
Cleber Rosa 已提交
239 240 241 242 243
        # The current human output produces 6 lines when running a single test,
        # with an optional 7th line when the HTML report generation is enabled
        self.assertGreaterEqual(len(output_lines), 6,
                                ('Basic human interface did not produce the '
                                 'expect output. Output produced: "%s"' % output))
244 245
        second_line = output_lines[1]
        debug_log = second_line.split()[-1]
246 247
        self.check_output_files(debug_log)

248 249 250 251
    def test_verify_whiteboard_save(self):
        tmpfile = tempfile.mktemp()
        try:
            os.chdir(basedir)
252 253
            cmd_line = ('./scripts/avocado run --job-results-dir %s --sysinfo=off whiteboard --json %s' %
                        (self.tmpdir, tmpfile))
254
            result = process.run(cmd_line, ignore_status=True)
255
            expected_rc = exit_codes.AVOCADO_ALL_OK
256 257 258 259 260
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
            with open(tmpfile, 'r') as fp:
                json_results = json.load(fp)
261 262 263
                logfile = json_results['tests'][0]['logfile']
                debug_dir = os.path.dirname(logfile)
                whiteboard_path = os.path.join(debug_dir, 'whiteboard')
264 265 266 267 268 269 270
                self.assertTrue(os.path.exists(whiteboard_path),
                                'Missing whiteboard file %s' % whiteboard_path)
        finally:
            try:
                os.remove(tmpfile)
            except OSError:
                pass
271

272
    @unittest.skipIf(image_output_uncapable(),
273
                     "Uncapable of generating images with PIL library")
274 275 276 277 278 279 280 281
    def test_gendata(self):
        tmpfile = tempfile.mktemp()
        try:
            os.chdir(basedir)
            cmd_line = ("./scripts/avocado run --job-results-dir %s "
                        "--sysinfo=off gendata --json %s" %
                        (self.tmpdir, tmpfile))
            result = process.run(cmd_line, ignore_status=True)
282
            expected_rc = exit_codes.AVOCADO_ALL_OK
283 284 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
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
            with open(tmpfile, 'r') as fp:
                json_results = json.load(fp)
                bsod_dir = None
                json_dir = None
                for test in json_results['tests']:
                    if "test_bsod" in test['url']:
                        bsod_dir = test['logfile']
                    elif "test_json" in test['url']:
                        json_dir = test['logfile']
                self.assertTrue(bsod_dir, "Failed to get test_bsod output "
                                "directory")
                self.assertTrue(json_dir, "Failed to get test_json output "
                                "directory")
                bsod_dir = os.path.join(os.path.dirname(bsod_dir), "data",
                                        "bsod.png")
                json_dir = os.path.join(os.path.dirname(json_dir), "data",
                                        "test.json")
                self.assertTrue(os.path.exists(bsod_dir), "File %s produced by"
                                "test does not exist" % bsod_dir)
                self.assertTrue(os.path.exists(json_dir), "File %s produced by"
                                "test does not exist" % json_dir)
        finally:
            try:
                os.remove(tmpfile)
            except OSError:
                pass

313 314 315 316
    def test_redirect_output(self):
        redirected_output_path = tempfile.mktemp()
        try:
            os.chdir(basedir)
317 318
            cmd_line = ('./scripts/avocado run --job-results-dir %s --sysinfo=off passtest > %s' %
                        (self.tmpdir, redirected_output_path))
319 320
            result = process.run(cmd_line, ignore_status=True, shell=True)
            output = result.stdout + result.stderr
321
            expected_rc = exit_codes.AVOCADO_ALL_OK
322 323 324
            self.assertEqual(result.exit_status, expected_rc,
                             "Avocado did not return rc %d:\n%s" %
                             (expected_rc, result))
325 326
            self.assertEqual(output, '',
                             'After redirecting to file, output is not empty: %s' % output)
327 328 329
            with open(redirected_output_path, 'r') as redirected_output_file_obj:
                redirected_output = redirected_output_file_obj.read()
                for code in TermSupport.ESCAPE_CODES:
R
Rudá Moura 已提交
330
                    self.assertNotIn(code, redirected_output,
331 332 333 334 335 336 337 338
                                     'Found terminal support code %s in redirected output\n%s' %
                                     (code, redirected_output))
        finally:
            try:
                os.remove(redirected_output_path)
            except OSError:
                pass

339 340 341
    def tearDown(self):
        shutil.rmtree(self.tmpdir)

342

343 344
if __name__ == '__main__':
    unittest.main()