1#!/usr/bin/env python3 2# 3# Copyright (C) 2020 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import argparse 19import errno 20import logging 21import os 22import sys 23import tempfile 24import time 25 26from mobly import base_test 27from mobly import test_runner 28from mobly.controllers import android_device 29 30 31SINGLE_DEVICE_TEST_CONFIG_FORMAT = """ 32TestBeds: 33- Name: SampleTestBed 34 Controllers: 35 AndroidDevice: 36 - serial: {serial} 37MoblyParams: {{LogPath: {log_path}}} 38""" 39 40TEST_CONFIG_FILE_NAME = 'mobly_test_config.yaml' 41DEFAULT_TESTBED_NAME = 'localDevTestBed' 42MOBLY_LOG_DIR_NAME = 'mobly' 43 44def _create_config_file(args): 45 """Create the test configuration file on local host. 46 47 Args: 48 args: Populated argument object, including attributes: device_serial, 49 log_path. 50 51 Returns: 52 String of created configuration file absolute path. 53 """ 54 mobly_dir = os.path.join(_get_default_log_root_path(), DEFAULT_TESTBED_NAME, 55 str(time.time())) 56 mobly_config_file_path = os.path.join(mobly_dir, TEST_CONFIG_FILE_NAME) 57 log_path = args.log_path if args.log_path else mobly_dir 58 config_text = SINGLE_DEVICE_TEST_CONFIG_FORMAT.format( 59 serial=args.device_serial, 60 log_path=log_path) 61 if not os.path.exists(os.path.dirname(mobly_config_file_path)): 62 try: 63 os.makedirs(os.path.dirname(mobly_config_file_path)) 64 except OSError as os_error: 65 if os_error.errno != errno.EEXIST: 66 raise 67 with open(mobly_config_file_path, 'w') as config_file: 68 config_file.write(config_text) 69 return mobly_config_file_path 70 71 72def _get_default_log_root_path(): 73 return os.path.join( 74 os.environ.get('TEST_UNDECLARED_OUTPUTS_DIR', 75 os.environ.get('GOOGLE_LOG_DIR', tempfile.gettempdir())), 76 MOBLY_LOG_DIR_NAME) 77 78 79def _parse_arguments(argv=None): 80 """Parse command line arguments. 81 82 Args: 83 argv: List of arguments, if none, get from sys.argv. 84 85 Returns: 86 A three item tuple containing the populated argument objects and 87 the list of remaining argument strings. 88 89 Raises: 90 Exception: If no '--' exists in arguments passed in. 91 """ 92 logging.info('arguments: %s', argv) 93 94 if not argv: 95 argv = sys.argv[1:] 96 if '--' not in argv: 97 raise ValueError(""" 98 Usage exception: 99 Arguments should be parsed in after '--'. 100 For example: 101 <python_binary> -- --config=<config_file> --test_bed=<testbed_name> 102 """) 103 index = argv.index('--') 104 # Parse arguments for this script only. It is better to not use the 105 # abbreviated (single character) version of the arguments to avoid conflict 106 # with mobly. 107 # Exception is the device_serial, since it is a convention. 108 local_parser = argparse.ArgumentParser(description='Mobly Hello World Test.') 109 local_parser.add_argument( 110 '-s', 111 '--device_serial', 112 type=str, 113 help='Device serial number to run tests.') 114 local_parser.add_argument('--log_path', type=str, help='Test log file path.') 115 local_args, other_args = local_parser.parse_known_args(argv[index + 1:]) 116 logging.info('Parsed local arguments: %s; Not parsed arguments: %s', 117 local_args, other_args) 118 filtered_argv = argv[:index + 1] + other_args # Remove all local arguments. 119 120 # The following arguments are the same as mobly test_runner. 121 parser = argparse.ArgumentParser(description='Mobly Hello World Test.') 122 parser.add_argument( 123 '-c', 124 '--config', 125 nargs=1, 126 type=str, 127 metavar='<PATH>', 128 help='Path to the test configuration file.') 129 args, unrec_argv = parser.parse_known_args(other_args) 130 logging.info('Parsed arguments: %s; Not parsed arguments: %s', args, 131 unrec_argv) 132 return local_args, args, filtered_argv 133 134 135class HelloWorldTest(base_test.BaseTestClass): 136 137 def setup_class(self): 138 # Registering android_device controller module declares the test's 139 # dependency on Android device hardware. By default, we expect at least one 140 # object is created from this. 141 self.ads = self.register_controller(android_device) 142 self.dut = self.ads[0] 143 144 def test_hello(self): 145 pass 146 147 148if __name__ == '__main__': 149 local_args, args, filtered_argv = _parse_arguments(sys.argv[1:]) 150 sys.argv = sys.argv[:1] 151 if not args.config: 152 logging.info('Mobly test config file was not provided. Creating one.') 153 config_file = _create_config_file(local_args) 154 sys.argv.append('--config=%s' % config_file) 155 logging.info('Mobly test config file: %s', config_file) 156 logging.info('Sys args: %s', sys.argv) 157 test_runner.main() 158