Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
run_tests.py
Go to the documentation of this file.
1#!/usr/bin/env vpython3
2
3# [VPYTHON:BEGIN]
4# python_version: "3.8"
5# wheel <
6# name: "infra/python/wheels/pyyaml/${platform}_${py_python}_${py_abi}"
7# version: "version:5.4.1.chromium.1"
8# >
9# [VPYTHON:END]
10
11# Copyright (c) 2013, the Flutter project authors. All rights reserved.
12# Use of this source code is governed by a BSD-style license that can be found
13# in the LICENSE file.
14
15import argparse
16import logging
17import os
18import sys
19
20from subprocess import CompletedProcess
21from typing import Any, Iterable, List, Mapping, NamedTuple, Set
22
23# The import is coming from vpython wheel and pylint cannot find it.
24import yaml # pylint: disable=import-error
25
26# The imports are coming from fuchsia/test_scripts and pylint cannot find them
27# without setting a global init-hook which is less favorable.
28# But this file will be executed as part of the CI, its correctness of importing
29# is guaranteed.
30
31sys.path.insert(
32 0, os.path.join(os.path.dirname(__file__), '../../tools/fuchsia/test_scripts/test/')
33)
34
35# pylint: disable=import-error, wrong-import-position
36import run_test
37from common import DIR_SRC_ROOT
38from run_executable_test import ExecutableTestRunner
39from test_runner import TestRunner
40
41if len(sys.argv) == 2:
42 VARIANT = sys.argv[1]
43 sys.argv.pop()
44elif len(sys.argv) == 1:
45 VARIANT = 'fuchsia_debug_x64'
46else:
47 assert False, 'Expect only one parameter as the compile output directory.'
48OUT_DIR = os.path.join(DIR_SRC_ROOT, 'out', VARIANT)
49
50
51# Visible for testing
52class TestCase(NamedTuple):
53 package: str
54 args: str = ''
55
56
58
59 # private, use bundled_test_runner_of function instead.
60 def __init__(self, target_id: str, package_deps: Set[str], tests: List[TestCase], logs_dir: str):
61 super().__init__(OUT_DIR, [], None, target_id, list(package_deps))
62 self.tests = tests
63 self.logs_dir = logs_dir
64
65 def run_test(self) -> CompletedProcess:
66 returncode = 0
67 for test in self.tests:
68 assert test.package.endswith('.cm')
69 test_runner = ExecutableTestRunner(
70 OUT_DIR, test.args.split(), test.package, self._target_id, None, self.logs_dir, [], None
71 )
72 # pylint: disable=protected-access
73 test_runner._package_deps = self._package_deps
74 result = test_runner.run_test().returncode
75 logging.info('Result of test %s is %s', test, result)
76 if result != 0:
77 returncode = result
78 return CompletedProcess(args='', returncode=returncode)
79
80
81# Visible for testing
82def resolve_packages(tests: Iterable[Mapping[str, Any]]) -> Set[str]:
83 packages = set()
84 for test in tests:
85 if 'package' in test:
86 packages.add(test['package'])
87 else:
88 assert 'packages' in test, \
89 'Expect either one package or a list of packages'
90 packages.update(test['packages'])
91 resolved_packages = set()
92 for package in packages:
93 if package.endswith('-0.far'):
94 # Make a symbolic link to match the name of the package itself without the
95 # '-0.far' suffix.
96 new_package = os.path.join(OUT_DIR, package.replace('-0.far', '.far'))
97 try:
98 # Remove the old one if it exists, usually happen on the devbox, so
99 # ignore the FileNotFoundError.
100 os.remove(new_package)
101 except FileNotFoundError:
102 pass
103 os.symlink(package, new_package)
104 resolved_packages.add(new_package)
105 else:
106 resolved_packages.add(os.path.join(OUT_DIR, package))
107 return resolved_packages
108
109
110# Visible for testing
111def build_test_cases(tests: Iterable[Mapping[str, Any]]) -> List[TestCase]:
112 test_cases = []
113 for test in [t['test_command'] for t in tests]:
114 assert test.startswith('test run ')
115 test = test[len('test run '):]
116 if ' -- ' in test:
117 package, args = test.split(' -- ', 1)
118 test_cases.append(TestCase(package=package, args=args))
119 else:
120 test_cases.append(TestCase(package=test))
121 return test_cases
122
123
124def _bundled_test_runner_of(target_id: str) -> _BundledTestRunner:
125 log_dir = os.environ.get('FLUTTER_LOGS_DIR', '/tmp/log')
126 with open(os.path.join(os.path.dirname(__file__), 'test_suites.yaml'), 'r') as file:
127 tests = yaml.safe_load(file)
128 # TODO(zijiehe-google-com): Run all tests in release build,
129 # https://github.com/flutter/flutter/issues/140179.
130 def variant(test) -> bool:
131 return 'variant' not in test or test['variant'] in VARIANT
132
133 tests = [t for t in tests if variant(t)]
134 return _BundledTestRunner(target_id, resolve_packages(tests), build_test_cases(tests), log_dir)
135
136
137def _get_test_runner(runner_args: argparse.Namespace, *_) -> TestRunner:
138 return _bundled_test_runner_of(runner_args.target_id)
139
140
141if __name__ == '__main__':
142 logging.basicConfig(level=logging.INFO)
143 logging.info('Running tests in %s', OUT_DIR)
144 sys.argv.append('--out-dir=' + OUT_DIR)
145 if VARIANT.endswith('_arm64') or VARIANT.endswith('_arm64_tester'):
146 sys.argv.append('--product=terminal.qemu-arm64')
147 # The 'flutter-test-type' is a place holder and has no specific meaning; the
148 # _get_test_runner is overrided.
149 sys.argv.append('flutter-test-type')
150 run_test._get_test_runner = _get_test_runner # pylint: disable=protected-access
151 sys.exit(run_test.main())
__init__(self, str target_id, Set[str] package_deps, List[TestCase] tests, str logs_dir)
Definition run_tests.py:60
_BundledTestRunner _bundled_test_runner_of(str target_id)
Definition run_tests.py:124
Set[str] resolve_packages(Iterable[Mapping[str, Any]] tests)
Definition run_tests.py:82
List[TestCase] build_test_cases(Iterable[Mapping[str, Any]] tests)
Definition run_tests.py:111