1*6777b538SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker"""Provides a base class for test running.""" 5*6777b538SAndroid Build Coastguard Worker 6*6777b538SAndroid Build Coastguard Workerimport os 7*6777b538SAndroid Build Coastguard Workerimport subprocess 8*6777b538SAndroid Build Coastguard Worker 9*6777b538SAndroid Build Coastguard Workerfrom abc import ABC, abstractmethod 10*6777b538SAndroid Build Coastguard Workerfrom argparse import Namespace 11*6777b538SAndroid Build Coastguard Workerfrom typing import Dict, List, Optional 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Workerfrom common import read_package_paths 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Workerclass TestRunner(ABC): 17*6777b538SAndroid Build Coastguard Worker """Base class that handles running a test.""" 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker def __init__(self, 20*6777b538SAndroid Build Coastguard Worker out_dir: str, 21*6777b538SAndroid Build Coastguard Worker test_args: Namespace, 22*6777b538SAndroid Build Coastguard Worker packages: List[str], 23*6777b538SAndroid Build Coastguard Worker target_id: Optional[str], 24*6777b538SAndroid Build Coastguard Worker package_deps: Optional[List[str]] = None) -> None: 25*6777b538SAndroid Build Coastguard Worker self._target_id = target_id 26*6777b538SAndroid Build Coastguard Worker self._out_dir = out_dir 27*6777b538SAndroid Build Coastguard Worker self._test_args = test_args 28*6777b538SAndroid Build Coastguard Worker self._packages = packages 29*6777b538SAndroid Build Coastguard Worker self._package_deps = None 30*6777b538SAndroid Build Coastguard Worker if package_deps: 31*6777b538SAndroid Build Coastguard Worker self._package_deps = TestRunner._build_package_deps(package_deps) 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker # TODO(crbug.com/1256503): Remove when all tests are converted to CFv2. 34*6777b538SAndroid Build Coastguard Worker @staticmethod 35*6777b538SAndroid Build Coastguard Worker def is_cfv2() -> bool: 36*6777b538SAndroid Build Coastguard Worker """ 37*6777b538SAndroid Build Coastguard Worker Returns True if packages are CFv2, False otherwise. Subclasses can 38*6777b538SAndroid Build Coastguard Worker override this and return False if needed. 39*6777b538SAndroid Build Coastguard Worker """ 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker return True 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker @property 44*6777b538SAndroid Build Coastguard Worker def package_deps(self) -> Dict[str, str]: 45*6777b538SAndroid Build Coastguard Worker """ 46*6777b538SAndroid Build Coastguard Worker Returns: 47*6777b538SAndroid Build Coastguard Worker A dictionary of packages that |self._packages| depend on, with 48*6777b538SAndroid Build Coastguard Worker mapping from the package name to the local path to its far file. 49*6777b538SAndroid Build Coastguard Worker """ 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker if not self._package_deps: 52*6777b538SAndroid Build Coastguard Worker self._populate_package_deps() 53*6777b538SAndroid Build Coastguard Worker return self._package_deps 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker @staticmethod 56*6777b538SAndroid Build Coastguard Worker def _build_package_deps(package_paths: List[str]) -> Dict[str, str]: 57*6777b538SAndroid Build Coastguard Worker """Retrieve information for all packages listed in |package_paths|.""" 58*6777b538SAndroid Build Coastguard Worker package_deps = {} 59*6777b538SAndroid Build Coastguard Worker for path in package_paths: 60*6777b538SAndroid Build Coastguard Worker package_name = os.path.basename(path).replace('.far', '') 61*6777b538SAndroid Build Coastguard Worker if package_name in package_deps: 62*6777b538SAndroid Build Coastguard Worker assert path == package_deps[package_name] 63*6777b538SAndroid Build Coastguard Worker package_deps[package_name] = path 64*6777b538SAndroid Build Coastguard Worker return package_deps 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker def _populate_package_deps(self) -> None: 67*6777b538SAndroid Build Coastguard Worker """Retrieve information for all packages |self._packages| depend on. 68*6777b538SAndroid Build Coastguard Worker """ 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker package_paths = [] 71*6777b538SAndroid Build Coastguard Worker for package in self._packages: 72*6777b538SAndroid Build Coastguard Worker package_paths.extend(read_package_paths(self._out_dir, package)) 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker self._package_deps = TestRunner._build_package_deps(package_paths) 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker @abstractmethod 77*6777b538SAndroid Build Coastguard Worker def run_test(self) -> subprocess.Popen: 78*6777b538SAndroid Build Coastguard Worker """ 79*6777b538SAndroid Build Coastguard Worker Returns: 80*6777b538SAndroid Build Coastguard Worker A subprocess.Popen object that ran the test command. 81*6777b538SAndroid Build Coastguard Worker """ 82