mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
fuchsia: Remove run_tests.py functionality
This removes the rotted functionality for running tests on Fuchsia. It had previously been broken by other platform changes. Other tools are from previous SDKs being removed too; this approach is no longer going to work. The preferred way is to connect via SSH to the device, however, that requires using the femu.sh from the SDK, which in turn requires `sudo` to create a network device, so it won't directly work on bots anyway. I started trying to update the to use femu.sh, fserve.sh, & fpublish.sh, but that requires building a .far, which uses GN templates which differ from the in-tree versions, and don't seem (?) to support packaging resources into the package. So, for now because it was confusing people (see linked bug) give up and delete the code for the time being. Bug: fuchsia:54031 Change-Id: Iac7af80094b150d11e71474cba4bd93eb8e80639 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2354160 Commit-Queue: Scott Graham <scottmg@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
7547d0aa87
commit
b472408135
20
DEPS
20
DEPS
@ -81,26 +81,6 @@ deps = {
|
|||||||
'condition': 'checkout_fuchsia and host_os == "linux"',
|
'condition': 'checkout_fuchsia and host_os == "linux"',
|
||||||
'dep_type': 'cipd'
|
'dep_type': 'cipd'
|
||||||
},
|
},
|
||||||
'crashpad/third_party/fuchsia/qemu/mac-amd64': {
|
|
||||||
'packages': [
|
|
||||||
{
|
|
||||||
'package': 'fuchsia/qemu/mac-amd64',
|
|
||||||
'version': 'latest'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'condition': 'checkout_fuchsia and host_os == "mac"',
|
|
||||||
'dep_type': 'cipd'
|
|
||||||
},
|
|
||||||
'crashpad/third_party/fuchsia/qemu/linux-amd64': {
|
|
||||||
'packages': [
|
|
||||||
{
|
|
||||||
'package': 'fuchsia/qemu/linux-amd64',
|
|
||||||
'version': 'latest'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'condition': 'checkout_fuchsia and host_os == "linux"',
|
|
||||||
'dep_type': 'cipd'
|
|
||||||
},
|
|
||||||
'crashpad/third_party/fuchsia/sdk/mac-amd64': {
|
'crashpad/third_party/fuchsia/sdk/mac-amd64': {
|
||||||
'packages': [
|
'packages': [
|
||||||
{
|
{
|
||||||
|
@ -1,145 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# Copyright 2017 The Crashpad Authors. All rights reserved.
|
|
||||||
#
|
|
||||||
# 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 script to [re]start or stop a helper Fuchsia QEMU instance to be used
|
|
||||||
for running tests without a device.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import getpass
|
|
||||||
import os
|
|
||||||
import random
|
|
||||||
import signal
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import tempfile
|
|
||||||
import time
|
|
||||||
|
|
||||||
try:
|
|
||||||
from subprocess import DEVNULL
|
|
||||||
except ImportError:
|
|
||||||
DEVNULL = open(os.devnull, 'r+b')
|
|
||||||
|
|
||||||
CRASHPAD_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
|
||||||
os.pardir)
|
|
||||||
|
|
||||||
|
|
||||||
def _Stop(pid_file):
|
|
||||||
if os.path.isfile(pid_file):
|
|
||||||
with open(pid_file, 'rb') as f:
|
|
||||||
pid = int(f.read().strip())
|
|
||||||
try:
|
|
||||||
os.kill(pid, signal.SIGTERM)
|
|
||||||
except:
|
|
||||||
print('Unable to kill pid %d, continuing' % pid, file=sys.stderr)
|
|
||||||
os.unlink(pid_file)
|
|
||||||
|
|
||||||
|
|
||||||
def _CheckForTun():
|
|
||||||
"""Check for networking. TODO(scottmg): Currently, this is Linux-specific.
|
|
||||||
"""
|
|
||||||
returncode = subprocess.call(
|
|
||||||
['tunctl', '-b', '-u',
|
|
||||||
getpass.getuser(), '-t', 'qemu'],
|
|
||||||
stdout=DEVNULL,
|
|
||||||
stderr=DEVNULL)
|
|
||||||
if returncode != 0:
|
|
||||||
print('To use QEMU with networking on Linux, configure TUN/TAP. See:',
|
|
||||||
file=sys.stderr)
|
|
||||||
print(
|
|
||||||
' https://fuchsia.googlesource.com/zircon/+/HEAD/docs/qemu.md#enabling-networking-under-qemu-x86_64-only',
|
|
||||||
file=sys.stderr)
|
|
||||||
return 2
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def _Start(pid_file):
|
|
||||||
tun_result = _CheckForTun()
|
|
||||||
if tun_result != 0:
|
|
||||||
return tun_result
|
|
||||||
|
|
||||||
arch = 'mac-amd64' if sys.platform == 'darwin' else 'linux-amd64'
|
|
||||||
fuchsia_dir = os.path.join(CRASHPAD_ROOT, 'third_party', 'fuchsia')
|
|
||||||
qemu_path = os.path.join(fuchsia_dir, 'qemu', arch, 'bin',
|
|
||||||
'qemu-system-x86_64')
|
|
||||||
kernel_data_dir = os.path.join(fuchsia_dir, 'sdk', arch, 'target', 'x86_64')
|
|
||||||
kernel_path = os.path.join(kernel_data_dir, 'zircon.bin')
|
|
||||||
initrd_path = os.path.join(kernel_data_dir, 'bootdata.bin')
|
|
||||||
|
|
||||||
mac_tail = ':'.join('%02x' % random.randint(0, 255) for x in range(3))
|
|
||||||
instance_name = (
|
|
||||||
'crashpad_qemu_' +
|
|
||||||
''.join(chr(random.randint(ord('A'), ord('Z'))) for x in range(8)))
|
|
||||||
|
|
||||||
# These arguments are from the Fuchsia repo in zircon/scripts/run-zircon.
|
|
||||||
|
|
||||||
# yapf: disable
|
|
||||||
popen = subprocess.Popen([
|
|
||||||
qemu_path,
|
|
||||||
'-m', '2048',
|
|
||||||
'-nographic',
|
|
||||||
'-kernel', kernel_path,
|
|
||||||
'-initrd', initrd_path,
|
|
||||||
'-smp', '4',
|
|
||||||
'-serial', 'stdio',
|
|
||||||
'-monitor', 'none',
|
|
||||||
'-machine', 'q35',
|
|
||||||
'-cpu', 'host,migratable=no,+invtsc',
|
|
||||||
'-enable-kvm',
|
|
||||||
'-netdev', 'type=tap,ifname=qemu,script=no,downscript=no,id=net0',
|
|
||||||
'-device', 'e1000,netdev=net0,mac=52:54:00:' + mac_tail,
|
|
||||||
'-append', 'TERM=dumb zircon.nodename=' + instance_name,
|
|
||||||
],
|
|
||||||
stdin=DEVNULL,
|
|
||||||
stdout=DEVNULL,
|
|
||||||
stderr=DEVNULL)
|
|
||||||
# yapf: enable
|
|
||||||
|
|
||||||
with open(pid_file, 'wb') as f:
|
|
||||||
f.write('%d\n' % popen.pid)
|
|
||||||
|
|
||||||
for i in range(10):
|
|
||||||
netaddr_path = os.path.join(fuchsia_dir, 'sdk', arch, 'tools',
|
|
||||||
'netaddr')
|
|
||||||
if subprocess.call([netaddr_path, '--nowait', instance_name],
|
|
||||||
stdout=open(os.devnull),
|
|
||||||
stderr=open(os.devnull)) == 0:
|
|
||||||
break
|
|
||||||
time.sleep(.5)
|
|
||||||
else:
|
|
||||||
print('instance did not respond after start', file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
if len(args) != 1 or args[0] not in ('start', 'stop'):
|
|
||||||
print('usage: run_fuchsia_qemu.py start|stop', file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
command = args[0]
|
|
||||||
|
|
||||||
pid_file = os.path.join(tempfile.gettempdir(), 'crashpad_fuchsia_qemu_pid')
|
|
||||||
_Stop(pid_file)
|
|
||||||
if command == 'start':
|
|
||||||
return _Start(pid_file)
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main(sys.argv[1:]))
|
|
@ -313,144 +313,6 @@ def _RunOnAndroidTarget(binary_dir, test, android_device, extra_command_line):
|
|||||||
_adb_shell(['rm', '-rf', device_temp_dir])
|
_adb_shell(['rm', '-rf', device_temp_dir])
|
||||||
|
|
||||||
|
|
||||||
def _GetFuchsiaSDKRoot():
|
|
||||||
arch = 'mac-amd64' if sys.platform == 'darwin' else 'linux-amd64'
|
|
||||||
return os.path.join(CRASHPAD_DIR, 'third_party', 'fuchsia', 'sdk', arch)
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateFuchsiaRuntimeDepsFiles(binary_dir, tests):
|
|
||||||
"""Ensures a <binary_dir>/<test>.runtime_deps file exists for each test."""
|
|
||||||
targets_file = os.path.join(binary_dir, 'targets.txt')
|
|
||||||
with open(targets_file, 'wb') as f:
|
|
||||||
f.write('//:' + '\n//:'.join(tests) + '\n')
|
|
||||||
gn_path = _FindGNFromBinaryDir(binary_dir)
|
|
||||||
subprocess.check_call([
|
|
||||||
gn_path, '--root=' + CRASHPAD_DIR, 'gen', binary_dir,
|
|
||||||
'--runtime-deps-list-file=' + targets_file
|
|
||||||
])
|
|
||||||
|
|
||||||
# Run again so that --runtime-deps-list-file isn't in the regen rule. See
|
|
||||||
# https://crbug.com/814816.
|
|
||||||
subprocess.check_call(
|
|
||||||
[gn_path, '--root=' + CRASHPAD_DIR, 'gen', binary_dir])
|
|
||||||
|
|
||||||
|
|
||||||
def _HandleOutputFromFuchsiaLogListener(process, done_message):
|
|
||||||
"""Pass through the output from |process| (which should be an instance of
|
|
||||||
Fuchsia's loglistener) until a special termination |done_message| is
|
|
||||||
encountered.
|
|
||||||
|
|
||||||
Also attempts to determine if any tests failed by inspecting the log output,
|
|
||||||
and returns False if there were failures.
|
|
||||||
"""
|
|
||||||
success = True
|
|
||||||
while True:
|
|
||||||
line = process.stdout.readline().rstrip()
|
|
||||||
if 'FAILED TEST' in line:
|
|
||||||
success = False
|
|
||||||
elif done_message in line and 'echo ' not in line:
|
|
||||||
break
|
|
||||||
print(line)
|
|
||||||
return success
|
|
||||||
|
|
||||||
|
|
||||||
def _RunOnFuchsiaTarget(binary_dir, test, device_name, extra_command_line):
|
|
||||||
"""Runs the given Fuchsia |test| executable on the given |device_name|. The
|
|
||||||
device must already be booted.
|
|
||||||
|
|
||||||
Copies the executable and its runtime dependencies as specified by GN to the
|
|
||||||
target in /tmp using `netcp`, runs the binary on the target, and logs output
|
|
||||||
back to stdout on this machine via `loglistener`.
|
|
||||||
"""
|
|
||||||
sdk_root = _GetFuchsiaSDKRoot()
|
|
||||||
|
|
||||||
# Run loglistener and filter the output to know when the test is done.
|
|
||||||
loglistener_process = subprocess.Popen(
|
|
||||||
[os.path.join(sdk_root, 'tools', 'loglistener'), device_name],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stdin=open(os.devnull),
|
|
||||||
stderr=open(os.devnull))
|
|
||||||
|
|
||||||
runtime_deps_file = os.path.join(binary_dir, test + '.runtime_deps')
|
|
||||||
with open(runtime_deps_file, 'rb') as f:
|
|
||||||
runtime_deps = f.read().splitlines()
|
|
||||||
|
|
||||||
def netruncmd(*args):
|
|
||||||
"""Runs a list of commands on the target device. Each command is escaped
|
|
||||||
by using pipes.quote(), and then each command is chained by shell ';'.
|
|
||||||
"""
|
|
||||||
netruncmd_path = os.path.join(sdk_root, 'tools', 'netruncmd')
|
|
||||||
final_args = ' ; '.join(
|
|
||||||
' '.join(pipes.quote(x) for x in command) for command in args)
|
|
||||||
subprocess.check_call([netruncmd_path, device_name, final_args])
|
|
||||||
|
|
||||||
try:
|
|
||||||
unique_id = uuid.uuid4().hex
|
|
||||||
test_root = '/tmp/%s_%s' % (test, unique_id)
|
|
||||||
tmp_root = test_root + '/tmp'
|
|
||||||
staging_root = test_root + '/pkg'
|
|
||||||
|
|
||||||
# Make a staging directory tree on the target.
|
|
||||||
directories_to_create = [
|
|
||||||
tmp_root,
|
|
||||||
'%s/bin' % staging_root,
|
|
||||||
'%s/assets' % staging_root
|
|
||||||
]
|
|
||||||
netruncmd(['mkdir', '-p'] + directories_to_create)
|
|
||||||
|
|
||||||
def netcp(local_path):
|
|
||||||
"""Uses `netcp` to copy a file or directory to the device. Files
|
|
||||||
located inside the build dir are stored to /pkg/bin, otherwise to
|
|
||||||
/pkg/assets. .so files are stored somewhere completely different,
|
|
||||||
into /boot/lib (!). This is because the loader service does not yet
|
|
||||||
correctly handle the namespace in which the caller is being run, and
|
|
||||||
so can only load .so files from a couple hardcoded locations, the
|
|
||||||
only writable one of which is /boot/lib, so we copy all .so files
|
|
||||||
there. This bug is filed upstream as ZX-1619.
|
|
||||||
"""
|
|
||||||
in_binary_dir = local_path.startswith(binary_dir + '/')
|
|
||||||
if in_binary_dir:
|
|
||||||
if local_path.endswith('.so'):
|
|
||||||
target_path = os.path.join('/boot/lib',
|
|
||||||
local_path[len(binary_dir) + 1:])
|
|
||||||
else:
|
|
||||||
target_path = os.path.join(staging_root, 'bin',
|
|
||||||
local_path[len(binary_dir) + 1:])
|
|
||||||
else:
|
|
||||||
relative_path = os.path.relpath(local_path, CRASHPAD_DIR)
|
|
||||||
target_path = os.path.join(staging_root, 'assets',
|
|
||||||
relative_path)
|
|
||||||
netcp_path = os.path.join(sdk_root, 'tools', 'netcp')
|
|
||||||
subprocess.check_call(
|
|
||||||
[netcp_path, local_path, device_name + ':' + target_path],
|
|
||||||
stderr=open(os.devnull))
|
|
||||||
|
|
||||||
# Copy runtime deps into the staging tree.
|
|
||||||
for dep in runtime_deps:
|
|
||||||
local_path = os.path.normpath(os.path.join(binary_dir, dep))
|
|
||||||
if os.path.isdir(local_path):
|
|
||||||
for root, dirs, files in os.walk(local_path):
|
|
||||||
for f in files:
|
|
||||||
netcp(os.path.join(root, f))
|
|
||||||
else:
|
|
||||||
netcp(local_path)
|
|
||||||
|
|
||||||
done_message = 'TERMINATED: ' + unique_id
|
|
||||||
namespace_command = [
|
|
||||||
'namespace', '/pkg=' + staging_root, '/tmp=' + tmp_root,
|
|
||||||
'/svc=/svc', '--replace-child-argv0=/pkg/bin/' + test, '--',
|
|
||||||
staging_root + '/bin/' + test
|
|
||||||
] + extra_command_line
|
|
||||||
netruncmd(namespace_command, ['echo', done_message])
|
|
||||||
|
|
||||||
success = _HandleOutputFromFuchsiaLogListener(loglistener_process,
|
|
||||||
done_message)
|
|
||||||
if not success:
|
|
||||||
raise subprocess.CalledProcessError(1, test)
|
|
||||||
finally:
|
|
||||||
netruncmd(['rm', '-rf', test_root])
|
|
||||||
|
|
||||||
|
|
||||||
def _RunOnIOSTarget(binary_dir, test, is_xcuitest=False):
|
def _RunOnIOSTarget(binary_dir, test, is_xcuitest=False):
|
||||||
"""Runs the given iOS |test| app on iPhone 8 with the default OS version."""
|
"""Runs the given iOS |test| app on iPhone 8 with the default OS version."""
|
||||||
|
|
||||||
@ -544,7 +406,6 @@ def main(args):
|
|||||||
|
|
||||||
target_os = _BinaryDirTargetOS(args.binary_dir)
|
target_os = _BinaryDirTargetOS(args.binary_dir)
|
||||||
is_android = target_os == 'android'
|
is_android = target_os == 'android'
|
||||||
is_fuchsia = target_os == 'fuchsia'
|
|
||||||
is_ios = target_os == 'ios'
|
is_ios = target_os == 'ios'
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
@ -575,21 +436,6 @@ def main(args):
|
|||||||
return 2
|
return 2
|
||||||
android_device = devices[0]
|
android_device = devices[0]
|
||||||
print('Using autodetected Android device:', android_device)
|
print('Using autodetected Android device:', android_device)
|
||||||
elif is_fuchsia:
|
|
||||||
zircon_nodename = os.environ.get('ZIRCON_NODENAME')
|
|
||||||
if not zircon_nodename:
|
|
||||||
netls = os.path.join(_GetFuchsiaSDKRoot(), 'tools', 'netls')
|
|
||||||
popen = subprocess.Popen([netls, '--nowait'],
|
|
||||||
stdout=subprocess.PIPE)
|
|
||||||
devices = popen.communicate()[0].splitlines()
|
|
||||||
if popen.returncode != 0 or len(devices) != 1:
|
|
||||||
print("Please set ZIRCON_NODENAME to your device's hostname",
|
|
||||||
file=sys.stderr)
|
|
||||||
return 2
|
|
||||||
zircon_nodename = devices[0].strip().split()[1]
|
|
||||||
print('Using autodetected Fuchsia device:', zircon_nodename)
|
|
||||||
_GenerateFuchsiaRuntimeDepsFiles(
|
|
||||||
args.binary_dir, [t for t in tests if not t.endswith('.py')])
|
|
||||||
elif is_ios:
|
elif is_ios:
|
||||||
tests.append('ios_crash_xcuitests')
|
tests.append('ios_crash_xcuitests')
|
||||||
elif IS_WINDOWS_HOST:
|
elif IS_WINDOWS_HOST:
|
||||||
@ -618,9 +464,6 @@ def main(args):
|
|||||||
if is_android:
|
if is_android:
|
||||||
_RunOnAndroidTarget(args.binary_dir, test, android_device,
|
_RunOnAndroidTarget(args.binary_dir, test, android_device,
|
||||||
extra_command_line)
|
extra_command_line)
|
||||||
elif is_fuchsia:
|
|
||||||
_RunOnFuchsiaTarget(args.binary_dir, test, zircon_nodename,
|
|
||||||
extra_command_line)
|
|
||||||
elif is_ios:
|
elif is_ios:
|
||||||
_RunOnIOSTarget(args.binary_dir,
|
_RunOnIOSTarget(args.binary_dir,
|
||||||
test,
|
test,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user