-
Notifications
You must be signed in to change notification settings - Fork 551
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add EMULATED_ANDROID platform (#2267)
* add EMULATED_ANDROID platform This allows downloading an emulator bundle (from the ANDROID_EMULATOR_BUCKET_PATH variable) and running it (using the ANDROID_EMULATOR_SCRIPT_PATH variable) before fuzzing. The emulated Android instance is controlled using 'adb', just as a physical Android device would. The new EmulatedAndroidLibFuzzerRunner shares most logic with the existing AndroidLibFuzzerRunner. * fix import order * fix formatting using 'butler.py format' * fix lint errors * resolve first round of feedback * change execute_command() to run_command() for 'adb devices' call * move emulator startup to build_manager.py This also scans the stdout of the emulator process to get the expected device serial, which is determined at runtime. This allows us to set the ANDROID_SERIAL environment variable. * fix test errors from unused imports * wait for emulated device to come online * bail out early from functions when using emulated Android device * add case to wait_until_fully_booted() for emulators * fix lint error - unused import * clean up platform check, check for correct env var
- Loading branch information
Showing
10 changed files
with
147 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# Copyright 2021 Google LLC | ||
# | ||
# 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. | ||
"""Helper functions for running commands on emulated Android devices.""" | ||
|
||
import os | ||
import re | ||
import subprocess | ||
import tempfile | ||
|
||
from google_cloud_utils import storage | ||
from metrics import logs | ||
from platforms.android import adb | ||
from system import archive | ||
from system import environment | ||
from system import new_process | ||
from system import shell | ||
|
||
# Output pattern to parse stdout for serial number | ||
DEVICE_SERIAL_RE = re.compile(r'DEVICE_SERIAL: (.+)') | ||
|
||
|
||
class EmulatorError(Exception): | ||
"""Error for errors handling the Android emulator.""" | ||
|
||
|
||
class EmulatorProcess(object): | ||
"""A EmulatorProcess encapsulates the creation, running, and destruction | ||
of Android emulator processes.""" | ||
|
||
def __init__(self): | ||
self.process_runner = None | ||
self.process = None | ||
self.logfile = None | ||
|
||
log_path = os.path.join(tempfile.gettempdir(), 'android-emulator.log') | ||
self.logfile = open(log_path, 'wb') | ||
|
||
def create(self): | ||
"""Configures a emulator process which can subsequently be `run`.""" | ||
# Download emulator image. | ||
if not environment.get_value('ANDROID_EMULATOR_BUCKET_PATH'): | ||
logs.log_error('ANDROID_EMULATOR_BUCKET_PATH is not set.') | ||
return | ||
temp_directory = environment.get_value('BOT_TMPDIR') | ||
archive_src_path = environment.get_value('ANDROID_EMULATOR_BUCKET_PATH') | ||
archive_dst_path = os.path.join(temp_directory, 'emulator_bundle.zip') | ||
storage.copy_file_from(archive_src_path, archive_dst_path) | ||
|
||
# Extract emulator image. | ||
self.emulator_path = os.path.join(temp_directory, 'emulator') | ||
archive.unpack(archive_dst_path, self.emulator_path) | ||
shell.remove_file(archive_dst_path) | ||
|
||
# Run emulator. | ||
script_path = os.path.join(self.emulator_path, 'run') | ||
self.process_runner = new_process.ProcessRunner(script_path) | ||
|
||
def run(self): | ||
"""Actually runs a emulator, assuming `create` has already been called.""" | ||
if not self.process_runner: | ||
raise EmulatorError('Attempted to `run` emulator before calling `create`') | ||
|
||
logs.log('Starting emulator.') | ||
self.process = self.process_runner.run( | ||
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
|
||
device_serial = None | ||
while not device_serial: | ||
line = self.process.popen.stdout.readline().decode() | ||
match = DEVICE_SERIAL_RE.match(line) | ||
if match: | ||
device_serial = match.group(1) | ||
|
||
logs.log('Found serial ID: %s.' % device_serial) | ||
environment.set_value('ANDROID_SERIAL', device_serial) | ||
|
||
logs.log('Waiting on device') | ||
adb.wait_until_fully_booted() | ||
logs.log('Device is online') | ||
|
||
def kill(self): | ||
""" Kills the currently-running emulator, if there is one. """ | ||
if self.process: | ||
logs.log('Stopping emulator.') | ||
self.process.kill() | ||
self.process = None | ||
|
||
if self.logfile: | ||
self.logfile.close() | ||
self.logfile = None | ||
|
||
if self.emulator_path: | ||
shell.remove_directory(self.emulator_path) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters