Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test_gyp.py261 linesDownload Raw Back to gyp
1#!/usr/bin/env python3
2# Copyright (c) 2012 Google Inc. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""gyptest.py -- test runner for GYP tests."""
7
8import argparse
9import os
10import platform
11import subprocess
12import sys
13import time
14
15
16def is_test_name(f):
17    return f.startswith("gyptest") and f.endswith(".py")
18
19
20def find_all_gyptest_files(directory):
21    result = []
22    for root, dirs, files in os.walk(directory):
23        result.extend([os.path.join(root, f) for f in files if is_test_name(f)])
24    result.sort()
25    return result
26
27
28def main(argv=None):
29    if argv is None:
30        argv = sys.argv
31
32    parser = argparse.ArgumentParser()
33    parser.add_argument("-a", "--all", action="store_true", help="run all tests")
34    parser.add_argument("-C", "--chdir", action="store", help="change to directory")
35    parser.add_argument(
36        "-f",
37        "--format",
38        action="store",
39        default="",
40        help="run tests with the specified formats",
41    )
42    parser.add_argument(
43        "-G",
44        "--gyp_option",
45        action="append",
46        default=[],
47        help="Add -G options to the gyp command line",
48    )
49    parser.add_argument(
50        "-l", "--list", action="store_true", help="list available tests and exit"
51    )
52    parser.add_argument(
53        "-n",
54        "--no-exec",
55        action="store_true",
56        help="no execute, just print the command line",
57    )
58    parser.add_argument(
59        "--path", action="append", default=[], help="additional $PATH directory"
60    )
61    parser.add_argument(
62        "-q",
63        "--quiet",
64        action="store_true",
65        help="quiet, don't print anything unless there are failures",
66    )
67    parser.add_argument(
68        "-v",
69        "--verbose",
70        action="store_true",
71        help="print configuration info and test results.",
72    )
73    parser.add_argument("tests", nargs="*")
74    args = parser.parse_args(argv[1:])
75
76    if args.chdir:
77        os.chdir(args.chdir)
78
79    if args.path:
80        extra_path = [os.path.abspath(p) for p in args.path]
81        extra_path = os.pathsep.join(extra_path)
82        os.environ["PATH"] = extra_path + os.pathsep + os.environ["PATH"]
83
84    if not args.tests:
85        if not args.all:
86            sys.stderr.write("Specify -a to get all tests.\n")
87            return 1
88        args.tests = ["test"]
89
90    tests = []
91    for arg in args.tests:
92        if os.path.isdir(arg):
93            tests.extend(find_all_gyptest_files(os.path.normpath(arg)))
94        else:
95            if not is_test_name(os.path.basename(arg)):
96                print(arg, "is not a valid gyp test name.", file=sys.stderr)
97                sys.exit(1)
98            tests.append(arg)
99
100    if args.list:
101        for test in tests:
102            print(test)
103        sys.exit(0)
104
105    os.environ["PYTHONPATH"] = os.path.abspath("test/lib")
106
107    if args.verbose:
108        print_configuration_info()
109
110    if args.gyp_option and not args.quiet:
111        print("Extra Gyp options: %s\n" % args.gyp_option)
112
113    if args.format:
114        format_list = args.format.split(",")
115    else:
116        format_list = {
117            "aix5": ["make"],
118            "os400": ["make"],
119            "freebsd7": ["make"],
120            "freebsd8": ["make"],
121            "openbsd5": ["make"],
122            "cygwin": ["msvs"],
123            "win32": ["msvs", "ninja"],
124            "linux": ["make", "ninja"],
125            "linux2": ["make", "ninja"],
126            "linux3": ["make", "ninja"],
127            # TODO: Re-enable xcode-ninja.
128            # https://bugs.chromium.org/p/gyp/issues/detail?id=530
129            # 'darwin':   ['make', 'ninja', 'xcode', 'xcode-ninja'],
130            "darwin": ["make", "ninja", "xcode"],
131        }[sys.platform]
132
133    gyp_options = []
134    for option in args.gyp_option:
135        gyp_options += ["-G", option]
136
137    runner = Runner(format_list, tests, gyp_options, args.verbose)
138    runner.run()
139
140    if not args.quiet:
141        runner.print_results()
142
143    return 1 if runner.failures else 0
144
145
146def print_configuration_info():
147    print("Test configuration:")
148    if sys.platform == "darwin":
149        sys.path.append(os.path.abspath("test/lib"))
150        import TestMac  # noqa: PLC0415
151
152        print(f"  Mac {platform.mac_ver()[0]} {platform.mac_ver()[2]}")
153        print(f"  Xcode {TestMac.Xcode.Version()}")
154    elif sys.platform == "win32":
155        sys.path.append(os.path.abspath("pylib"))
156        import gyp.MSVSVersion  # noqa: PLC0415
157
158        print("  Win %s %s\n" % platform.win32_ver()[0:2])
159        print("  MSVS %s" % gyp.MSVSVersion.SelectVisualStudioVersion().Description())
160    elif sys.platform in ("linux", "linux2"):
161        print("  Linux %s" % " ".join(platform.linux_distribution()))
162    print(f"  Python {platform.python_version()}")
163    print(f"  PYTHONPATH={os.environ['PYTHONPATH']}")
164    print()
165
166
167class Runner:
168    def __init__(self, formats, tests, gyp_options, verbose):
169        self.formats = formats
170        self.tests = tests
171        self.verbose = verbose
172        self.gyp_options = gyp_options
173        self.failures = []
174        self.num_tests = len(formats) * len(tests)
175        num_digits = len(str(self.num_tests))
176        self.fmt_str = "[%%%dd/%%%dd] (%%s) %%s" % (num_digits, num_digits)
177        self.isatty = sys.stdout.isatty() and not self.verbose
178        self.env = os.environ.copy()
179        self.hpos = 0
180
181    def run(self):
182        run_start = time.time()
183
184        i = 1
185        for fmt in self.formats:
186            for test in self.tests:
187                self.run_test(test, fmt, i)
188                i += 1
189
190        if self.isatty:
191            self.erase_current_line()
192
193        self.took = time.time() - run_start
194
195    def run_test(self, test, fmt, i):
196        if self.isatty:
197            self.erase_current_line()
198
199        msg = self.fmt_str % (i, self.num_tests, fmt, test)
200        self.print_(msg)
201
202        start = time.time()
203        cmd = [sys.executable, test] + self.gyp_options
204        self.env["TESTGYP_FORMAT"] = fmt
205        proc = subprocess.Popen(
206            cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=self.env
207        )
208        proc.wait()
209        took = time.time() - start
210
211        stdout = proc.stdout.read().decode("utf8")
212        if proc.returncode == 2:
213            res = "skipped"
214        elif proc.returncode:
215            res = "failed"
216            self.failures.append(f"({test}) {fmt}")
217        else:
218            res = "passed"
219        res_msg = f" {res} {took:.3f}s"
220        self.print_(res_msg)
221
222        if stdout and not stdout.endswith(("PASSED\n", "NO RESULT\n")):
223            print()
224            print("\n".join(f"    {line}" for line in stdout.splitlines()))
225        elif not self.isatty:
226            print()
227
228    def print_(self, msg):
229        print(msg, end="")
230        index = msg.rfind("\n")
231        if index == -1:
232            self.hpos += len(msg)
233        else:
234            self.hpos = len(msg) - index
235        sys.stdout.flush()
236
237    def erase_current_line(self):
238        print("\b" * self.hpos + " " * self.hpos + "\b" * self.hpos, end="")
239        sys.stdout.flush()
240        self.hpos = 0
241
242    def print_results(self):
243        num_failures = len(self.failures)
244        if num_failures:
245            print()
246            if num_failures == 1:
247                print("Failed the following test:")
248            else:
249                print("Failed the following %d tests:" % num_failures)
250            print("\t" + "\n\t".join(sorted(self.failures)))
251            print()
252        print(
253            "Ran %d tests in %.3fs, %d failed."
254            % (self.num_tests, self.took, num_failures)
255        )
256        print()
257
258
259if __name__ == "__main__":
260    sys.exit(main())
261 
codekingpro/portable-devtools · Team Ai