""" All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or its licensors. For complete copyright and license terms please see the LICENSE at the root of this distribution (the "License"). All use of this software is governed by the License, or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ import argparse import itertools import logging import os from run_launcher_tests import PlatformDriver import subprocess import time logger = logging.getLogger(__name__) class AndroidDriver(PlatformDriver): def read_package_name(self): project_data = self.read_json_data(self.project_json_path) return project_data['android_settings']['package_name'] def run_test(self, test_name, map, dynamic_slice, timeout, pass_string, fail_string): package = self.read_package_name() project = self.read_project_name() package_and_activity = "{}/{}.{}Activity".format(package, package, project) # clear any old logcat command_line = ['adb', 'logcat', '-c'] p = subprocess.Popen(command_line) p.communicate() # increase ring buffer size because we are going to be printing a large amount of data in a short time. command_line = ['adb', 'logcat', '-G', '10m'] p = subprocess.Popen(command_line) p.communicate() # Start the process and pass in the test args logger.info("Start the activity {} ...".format(package_and_activity)) command_line = ['adb', 'shell', 'am', 'start', '-a', 'android.intent.action.MAIN', '-n', package_and_activity] command_line += ['-e', 'ltest_map', map] command_line += ['-e', 'ltest_slice', dynamic_slice] p = subprocess.Popen(command_line) p.communicate() # Get the pid of the app to use in the logcat monitoring. If we don't # do this we might get residual output from previous test run. Even # though we do a clear. for _ in itertools.repeat(None, 10): command_line = ['adb', 'shell', 'pidof', package] p = subprocess.Popen(command_line, stdout=subprocess.PIPE) stdoutdata, stderrdata = p.communicate() pid = stdoutdata.strip() if pid: logger.info("Get pid of {}".format(pid)) break else: logger.info('Failed to get pid, waiting 1 second to retry ...') time.sleep(1) if not pid: raise Exception('Unable to determin the pid of the process.') command_line = ['adb', '-d', 'logcat', "--pid={}".format(pid), 'LMBR:I', '*:S'] test_result = self.monitor_process_output(test_name, command_line, pass_string, fail_string, timeout) logger.info("Kill the app ...") p = subprocess.Popen(['adb', 'shell', 'am', 'force-stop', package]) p.communicate() # Stop here if we failed. if not test_result: raise Exception("Test failed.") def take_screenshot(self, output_path_no_ext): # Create the output folder if it is not there output_folder = os.path.dirname(output_path_no_ext) if not os.path.exists(output_folder): os.makedirs(output_folder) # Take the screenshot p = subprocess.Popen(['adb', 'shell', 'screencap', '-p', '/sdcard/screen.png']) p.communicate() # copy it off of the device p = subprocess.Popen(['adb', 'pull', '/sdcard/screen.png', "{}.png".format(output_path_no_ext)]) p.communicate() def main(): parser = argparse.ArgumentParser(description='Sets up and runs Android Launcher Tests.') parser.add_argument('--project-json-path', required=True, help='Path to the project.json project settings file.') parser.add_argument('--project-launcher-tests-folder', required=True, help='Path to the LauncherTests folder in a Project.') parser.add_argument('--test-names', nargs='+', help='A list of test names to run, default runs all tests.') parser.add_argument('--screenshots-folder', default="./temp/Android/screenshots", help='Output folder for screenshots.') parser.add_argument('--screenshots-interval', default=5, help='Time interval between taking screenshots in seconds.') args = parser.parse_args() logging.basicConfig(level=logging.DEBUG) logger.info("Running Launcher tests at {} ...".format(args.project_launcher_tests_folder)) driver = AndroidDriver(args.project_json_path, args.project_launcher_tests_folder, args.test_names, args.screenshots_folder, args.screenshots_interval) driver.run_launcher_tests() if __name__== "__main__": main()