Ian Zerny | dcb172e | 2022-02-22 15:36:45 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Morten Krogh-Jespersen | cd55f81 | 2020-11-04 09:13:31 +0100 | [diff] [blame] | 2 | # Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file |
| 3 | # for details. All rights reserved. Use of this source code is governed by a |
| 4 | # BSD-style license that can be found in the LICENSE file. |
| 5 | |
| 6 | import subprocess |
| 7 | import time |
| 8 | import utils |
| 9 | |
Morten Krogh-Jespersen | cd55f81 | 2020-11-04 09:13:31 +0100 | [diff] [blame] | 10 | def install_apk_on_emulator(apk, emulator_id, quiet=False): |
| 11 | cmd = ['adb', '-s', emulator_id, 'install', '-r', '-d', apk] |
| 12 | if quiet: |
| 13 | subprocess.check_output(cmd) |
| 14 | else: |
| 15 | subprocess.check_call(cmd) |
| 16 | |
| 17 | |
| 18 | def uninstall_apk_on_emulator(app_id, emulator_id): |
| 19 | process = subprocess.Popen( |
| 20 | ['adb', '-s', emulator_id, 'uninstall', app_id], |
| 21 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 22 | stdout, stderr = process.communicate() |
Morten Krogh-Jespersen | 235d754 | 2021-03-02 15:30:44 +0100 | [diff] [blame] | 23 | stdout = stdout.decode('UTF-8') |
| 24 | stderr = stderr.decode('UTF-8') |
Morten Krogh-Jespersen | cd55f81 | 2020-11-04 09:13:31 +0100 | [diff] [blame] | 25 | |
| 26 | if stdout.strip() == 'Success': |
| 27 | # Successfully uninstalled |
| 28 | return |
| 29 | |
| 30 | if 'Unknown package: {}'.format(app_id) in stderr: |
| 31 | # Application not installed |
| 32 | return |
| 33 | |
| 34 | # Check if the app is listed in packages |
| 35 | packages = subprocess.check_output(['adb', 'shell', 'pm', 'list', 'packages']) |
| 36 | if not 'package:' + app_id in packages: |
| 37 | return |
| 38 | |
| 39 | raise Exception( |
| 40 | 'Unexpected result from `adb uninstall {}\nStdout: {}\nStderr: {}'.format( |
| 41 | app_id, stdout, stderr)) |
| 42 | |
| 43 | |
| 44 | def wait_for_emulator(emulator_id): |
Morten Krogh-Jespersen | 235d754 | 2021-03-02 15:30:44 +0100 | [diff] [blame] | 45 | stdout = subprocess.check_output(['adb', 'devices']).decode('UTF-8') |
Morten Krogh-Jespersen | cd55f81 | 2020-11-04 09:13:31 +0100 | [diff] [blame] | 46 | if '{}\tdevice'.format(emulator_id) in stdout: |
| 47 | return True |
| 48 | |
| 49 | print('Emulator \'{}\' not connected; waiting for connection'.format( |
| 50 | emulator_id)) |
| 51 | |
| 52 | time_waited = 0 |
| 53 | while True: |
| 54 | time.sleep(10) |
| 55 | time_waited += 10 |
Morten Krogh-Jespersen | 235d754 | 2021-03-02 15:30:44 +0100 | [diff] [blame] | 56 | stdout = subprocess.check_output(['adb', 'devices']).decode('UTF-8') |
Morten Krogh-Jespersen | cd55f81 | 2020-11-04 09:13:31 +0100 | [diff] [blame] | 57 | if '{}\tdevice'.format(emulator_id) not in stdout: |
| 58 | print('... still waiting for connection') |
| 59 | if time_waited >= 5 * 60: |
| 60 | return False |
| 61 | else: |
| 62 | return True |
| 63 | |
| 64 | |
| 65 | def run_monkey(app_id, emulator_id, apk, monkey_events, quiet, enable_logging): |
| 66 | if not wait_for_emulator(emulator_id): |
| 67 | return False |
| 68 | |
| 69 | install_apk_on_emulator(apk, emulator_id, quiet) |
| 70 | |
| 71 | # Intentionally using a constant seed such that the monkey generates the same |
| 72 | # event sequence for each shrinker. |
| 73 | random_seed = 42 |
| 74 | |
| 75 | cmd = ['adb', '-s', emulator_id, 'shell', 'monkey', '-p', app_id, |
| 76 | '-s', str(random_seed), str(monkey_events)] |
| 77 | |
| 78 | try: |
| 79 | stdout = utils.RunCmd(cmd, quiet=quiet, logging=enable_logging) |
| 80 | succeeded = ('Events injected: {}'.format(monkey_events) in stdout) |
| 81 | except subprocess.CalledProcessError as e: |
| 82 | succeeded = False |
| 83 | |
| 84 | uninstall_apk_on_emulator(app_id, emulator_id) |
| 85 | |
| 86 | return succeeded |
Morten Krogh-Jespersen | 51a1635 | 2020-11-04 09:31:15 +0100 | [diff] [blame] | 87 | |
| 88 | |
| 89 | def run_instrumented(app_id, test_id, emulator_id, apk, test_apk, quiet, |
| 90 | enable_logging, |
| 91 | test_runner='androidx.test.runner.AndroidJUnitRunner'): |
| 92 | if not wait_for_emulator(emulator_id): |
| 93 | return None |
| 94 | |
| 95 | install_apk_on_emulator(apk, emulator_id, quiet) |
| 96 | install_apk_on_emulator(test_apk, emulator_id, quiet) |
| 97 | |
| 98 | cmd = ['adb', '-s', emulator_id, 'shell', 'am', 'instrument', '-w', |
| 99 | '{}/{}'.format(test_id, test_runner)] |
| 100 | |
| 101 | try: |
| 102 | stdout = utils.RunCmd(cmd, quiet=quiet, logging=enable_logging) |
| 103 | # The runner will print OK (X tests) if completed succesfully |
| 104 | succeeded = any("OK (" in s for s in stdout) |
| 105 | except subprocess.CalledProcessError as e: |
| 106 | succeeded = False |
| 107 | |
| 108 | uninstall_apk_on_emulator(test_id, emulator_id) |
| 109 | uninstall_apk_on_emulator(app_id, emulator_id) |
| 110 | |
| 111 | return succeeded |