aboutsummaryrefslogtreecommitdiff
path: root/avatar/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'avatar/__init__.py')
-rw-r--r--avatar/__init__.py103
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)