Flutter Engine
The Flutter Engine
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())
def __init__(self, str target_id, Set[str] package_deps, List[TestCase] tests, str logs_dir)
Definition: run_tests.py:60
CompletedProcess run_test(self)
Definition: run_tests.py:65
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
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