diff options
Diffstat (limited to 'avatar/__init__.py')
-rw-r--r-- | avatar/__init__.py | 103 |
1 files changed, 100 insertions, 3 deletions
diff --git a/avatar/__init__.py b/avatar/__init__.py index e5a1cf2..abc4653 100644 --- a/avatar/__init__.py +++ b/avatar/__init__.py @@ -17,21 +17,26 @@ Avatar is a scalable multi-platform Bluetooth testing tool capable of running any Bluetooth test cases virtually and physically. """ -__version__ = "0.0.2" +__version__ = "0.0.4" +import argparse import enum import functools import grpc import grpc.aio import importlib import logging +import pathlib from avatar import pandora_server from avatar.aio import asynchronous from avatar.metrics import trace -from avatar.pandora_client import BumblePandoraClient as BumblePandoraDevice, PandoraClient as PandoraDevice +from avatar.pandora_client import BumblePandoraClient as BumblePandoraDevice +from avatar.pandora_client import PandoraClient as PandoraDevice from avatar.pandora_server import PandoraServer +from avatar.runner import SuiteRunner from mobly import base_test +from mobly import signals from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Sized, Tuple, Type, TypeVar # public symbols @@ -105,7 +110,13 @@ class PandoraDevices(Sized, Iterable[PandoraDevice]): # Register the controller and load its Pandora servers. logging.info('Starting %s(s) for %s', server_cls.__name__, controller) - devices: Optional[List[Any]] = test.register_controller(server_cls.MOBLY_CONTROLLER_MODULE) # type: ignore + try: + devices: Optional[List[Any]] = test.register_controller( # type: ignore + server_cls.MOBLY_CONTROLLER_MODULE + ) + except Exception: + logging.exception('abort: failed to register controller') + raise signals.TestAbortAll("") assert devices for device in devices: # type: ignore self._servers.append(server_cls(device)) @@ -215,3 +226,89 @@ def rpc_except( return wrapper return wrap + + +def args_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description='Avatar test runner.') + parser.add_argument( + 'input', + type=str, + nargs='*', + metavar='<PATH>', + help='Lits of folder or test file to run', + default=[], + ) + parser.add_argument('-c', '--config', type=str, metavar='<PATH>', help='Path to the test configuration file.') + parser.add_argument( + '-l', + '--list', + '--list_tests', # For backward compatibility with tradefed `MoblyBinaryHostTest` + action='store_true', + help='Print the names of the tests defined in a script without ' 'executing them.', + ) + parser.add_argument( + '-o', + '--log-path', + '--log_path', # For backward compatibility with tradefed `MoblyBinaryHostTest` + type=str, + metavar='<PATH>', + help='Path to the test configuration file.', + ) + parser.add_argument( + '-t', + '--tests', + nargs='+', + type=str, + metavar='[ClassA[.test_a] ClassB[.test_b] ...]', + help='A list of test classes and optional tests to execute.', + ) + parser.add_argument( + '-b', + '--test-beds', + '--test_bed', # For backward compatibility with tradefed `MoblyBinaryHostTest` + nargs='+', + type=str, + metavar='[<TEST BED NAME1> <TEST BED NAME2> ...]', + help='Specify which test beds to run tests on.', + ) + parser.add_argument('-v', '--verbose', action='store_true', help='Set console logger level to DEBUG') + parser.add_argument('-x', '--no-default-cases', action='store_true', help='Dot no include default test cases') + return parser + + +# Avatar default entry point +def main(args: Optional[argparse.Namespace] = None) -> None: + import sys + + # Create an Avatar suite runner. + runner = SuiteRunner() + + # Parse arguments. + argv = args or args_parser().parse_args() + if argv.input: + for path in argv.input: + runner.add_path(pathlib.Path(path)) + if argv.config: + runner.add_config_file(pathlib.Path(argv.config)) + if argv.log_path: + runner.set_logs_dir(pathlib.Path(argv.log_path)) + if argv.tests: + runner.add_test_filters(argv.tests) + if argv.test_beds: + runner.add_test_beds(argv.test_beds) + if argv.verbose: + runner.set_logs_verbose() + if not argv.no_default_cases: + runner.add_path(pathlib.Path(__file__).resolve().parent / 'cases') + + # List tests to standard output. + if argv.list: + for _, (tag, test_names) in runner.included_tests.items(): + for name in test_names: + print(f"{tag}.{name}") + sys.exit(0) + + # Run the test suite. + logging.basicConfig(level=logging.INFO) + if not runner.run(): + sys.exit(1) |