1# Copyright 2022 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4"""Provides a base class for test running.""" 5 6import os 7import subprocess 8 9from abc import ABC, abstractmethod 10from typing import Dict, List, Optional, Union 11 12from common import read_package_paths 13 14 15class TestRunner(ABC): 16 """Base class that handles running a test.""" 17 18 def __init__(self, 19 out_dir: str, 20 test_args: List[str], 21 packages: List[str], 22 target_id: Optional[str], 23 package_deps: Union[Dict[str, str], List[str]] = None): 24 self._out_dir = out_dir 25 self._test_args = test_args 26 self._packages = packages 27 self._target_id = target_id 28 if package_deps: 29 if isinstance(package_deps, list): 30 self._package_deps = self._build_package_deps(package_deps) 31 elif isinstance(package_deps, dict): 32 self._package_deps = package_deps 33 else: 34 assert False, 'Unsupported package_deps ' + package_deps 35 else: 36 self._package_deps = self._populate_package_deps() 37 38 @property 39 def package_deps(self) -> Dict[str, str]: 40 """ 41 Returns: 42 A dictionary of packages that |self._packages| depend on, with 43 mapping from the package name to the local path to its far file. 44 """ 45 46 return self._package_deps 47 48 def _build_package_deps(self, package_paths: List[str]) -> Dict[str, str]: 49 """Retrieve information for all packages listed in |package_paths|.""" 50 package_deps = {} 51 for path in package_paths: 52 path = os.path.join(self._out_dir, path) 53 package_name = os.path.basename(path).replace('.far', '') 54 if package_name in package_deps: 55 assert path == package_deps[package_name] 56 package_deps[package_name] = path 57 return package_deps 58 59 def _populate_package_deps(self) -> None: 60 """Retrieve information for all packages |self._packages| depend on. 61 Note, this function expects the packages to be built with chromium 62 specified build rules and placed in certain locations. 63 """ 64 65 package_paths = [] 66 for package in self._packages: 67 package_paths.extend(read_package_paths(self._out_dir, package)) 68 69 return self._build_package_deps(package_paths) 70 71 @abstractmethod 72 def run_test(self) -> subprocess.Popen: 73 """ 74 Returns: 75 A subprocess.Popen object that ran the test command. 76 """ 77