|
|
|
|
# Lint as: python3
|
|
|
|
|
#
|
|
|
|
|
# Copyright 2020, The Android Open Source Project
|
|
|
|
|
#
|
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
|
#
|
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
#
|
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
|
# limitations under the License.
|
|
|
|
|
"""CSuite-specific automated unit test functionality."""
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import sys
|
|
|
|
|
from typing import Any, Sequence, Text
|
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
|
|
# Export the TestCase class to reduce the number of imports tests have to list.
|
|
|
|
|
TestCase = unittest.TestCase
|
|
|
|
|
|
|
|
|
|
_DEVICE_SERIAL = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_device_serial() -> Text:
|
|
|
|
|
"""Returns the serial of the connected device."""
|
|
|
|
|
if not _DEVICE_SERIAL:
|
|
|
|
|
raise RuntimeError(
|
|
|
|
|
'Device serial is unset, did you call main in your test?')
|
|
|
|
|
return _DEVICE_SERIAL
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_arg_parser(add_help: bool = False) -> argparse.ArgumentParser:
|
|
|
|
|
"""Creates a new parser that can handle the default command-line flags.
|
|
|
|
|
|
|
|
|
|
The object returned by this function can be used by other modules that want to
|
|
|
|
|
add their own command-line flags. The returned parser is intended to be passed
|
|
|
|
|
to the 'parents' argument of ArgumentParser and extend the set of default
|
|
|
|
|
flags with additional ones.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
add_help: whether to add an option which simply displays the parser’s help
|
|
|
|
|
message; this is typically false when used from other modules that want to
|
|
|
|
|
use the returned parser as a parent argument parser.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
A new arg parser that can handle the default flags expected by this module.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# The below flags are passed in by the TF Python test runner.
|
|
|
|
|
parser = argparse.ArgumentParser(add_help=add_help)
|
|
|
|
|
|
|
|
|
|
parser.add_argument('-s', '--serial', help='the device serial')
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
'--test-output-file',
|
|
|
|
|
help='the file in which to store the test results',
|
|
|
|
|
required=True)
|
|
|
|
|
|
|
|
|
|
return parser
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_tests(args: Any, unittest_argv: Sequence[Text]) -> None:
|
|
|
|
|
"""Executes a set of Python unit tests.
|
|
|
|
|
|
|
|
|
|
This function is typically used by modules that extend command-line flags.
|
|
|
|
|
Callers create their own argument parser with this module's parser as a parent
|
|
|
|
|
and parse the command-line. The resulting object is will contain the
|
|
|
|
|
attributes expected by this module and is used to call this method.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
args: an object that contains at least the set of attributes defined in
|
|
|
|
|
objects returned when using the default argument parser.
|
|
|
|
|
unittest_argv: the list of command-line arguments to forward to
|
|
|
|
|
unittest.main.
|
|
|
|
|
"""
|
|
|
|
|
global _DEVICE_SERIAL
|
|
|
|
|
|
|
|
|
|
_DEVICE_SERIAL = args.serial
|
|
|
|
|
|
|
|
|
|
with open(args.test_output_file, 'w') as test_output_file:
|
|
|
|
|
|
|
|
|
|
# Note that we use a type and not an instance for 'testRunner' since
|
|
|
|
|
# TestProgram forwards its constructor arguments when creating an instance
|
|
|
|
|
# of the runner type. Not doing so would require us to make sure that the
|
|
|
|
|
# parameters passed to TestProgram are aligned with those for creating a
|
|
|
|
|
# runner instance.
|
|
|
|
|
class TestRunner(unittest.TextTestRunner):
|
|
|
|
|
"""A test runner that writes test results to the TF-provided file."""
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super(TestRunner, self).__init__(
|
|
|
|
|
stream=test_output_file, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
# Setting verbosity is required to generate output that the TradeFed test
|
|
|
|
|
# runner can parse.
|
|
|
|
|
unittest.TestProgram(verbosity=3, testRunner=TestRunner, argv=unittest_argv)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
"""Executes a set of Python unit tests."""
|
|
|
|
|
args, unittest_argv = create_arg_parser(add_help=True).parse_known_args(
|
|
|
|
|
sys.argv)
|
|
|
|
|
run_tests(args, unittest_argv)
|