aboutsummaryrefslogtreecommitdiff
path: root/run_single_test.py
blob: c6018d5a34919f2826dd8da540a3d8aaf2c29dec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env python3
# SPDX-license-identifier: Apache-2.0
# Copyright © 2021 Intel Corporation

"""Script for running a single project test.

This script is meant for Meson developers who want to run a single project
test, with all of the rules from the test.json file loaded.
"""

import argparse
import pathlib
import shutil
import typing as T

from mesonbuild import environment
from mesonbuild import mlog
from mesonbuild import mesonlib
from run_project_tests import TestDef, load_test_json, run_test, BuildStep, skippable
from run_tests import get_backend_commands, guess_backend, get_fake_options

if T.TYPE_CHECKING:
    try:
        from typing import Protocol
    except ImportError:
        # Mypy gets grump about this even though it's fine
        from typing_extensions import Protocol  # type: ignore

    class ArgumentType(Protocol):

        """Typing information for command line arguments."""

        case: pathlib.Path
        subtests: T.List[int]
        backend: str


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('case', type=pathlib.Path, help='The test case to run')
    parser.add_argument('--subtest', type=int, action='append', dest='subtests', help='which subtests to run')
    parser.add_argument('--backend', action='store', help="Which backend to use")
    args = T.cast('ArgumentType', parser.parse_args())

    test = TestDef(args.case, args.case.stem, [])
    tests = load_test_json(test, False)
    if args.subtests:
        tests = [t for i, t in enumerate(tests) if i in args.subtests]

    with mesonlib.TemporaryDirectoryWinProof() as build_dir:
        fake_opts = get_fake_options('/')
        env = environment.Environment(None, build_dir, fake_opts)
        try:
            comp = env.compiler_from_language('c', mesonlib.MachineChoice.HOST).get_id()
        except mesonlib.MesonException:
            raise RuntimeError('Could not detect C compiler')

    backend, backend_args = guess_backend(args.backend, shutil.which('msbuild'))
    _cmds = get_backend_commands(backend, False)
    commands = (_cmds[0], _cmds[1], _cmds[3], _cmds[4])

    results = [run_test(t, t.args, comp, backend, backend_args, commands, False, True) for t in tests]
    failed = False
    for test, result in zip(tests, results):
        if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(str(args.case.parent), test.path.as_posix()))):
            msg = mlog.yellow('SKIP:')
        elif result.msg:
            msg = mlog.red('FAIL:')
            failed = True
        else:
            msg = mlog.green('PASS:')
        mlog.log(msg, test.display_name())
        if result.msg and 'MESON_SKIP_TEST' not in result.stdo:
            mlog.log('reason:', result.msg)
            if result.step is BuildStep.configure:
                # For configure failures, instead of printing stdout,
                # print the meson log if available since it's a superset
                # of stdout and often has very useful information.
                mlog.log(result.mlog)
            else:
                mlog.log(result.stdo)
            for cmd_res in result.cicmds:
                mlog.log(cmd_res)
            mlog.log(result.stde)

    exit(1 if failed else 0)

if __name__ == "__main__":
    main()