summaryrefslogtreecommitdiffstats
path: root/chromium/build/fuchsia/emu_target.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/build/fuchsia/emu_target.py')
-rw-r--r--chromium/build/fuchsia/emu_target.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/chromium/build/fuchsia/emu_target.py b/chromium/build/fuchsia/emu_target.py
new file mode 100644
index 00000000000..1aa6e420d05
--- /dev/null
+++ b/chromium/build/fuchsia/emu_target.py
@@ -0,0 +1,92 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Implements commands for running/interacting with Fuchsia on an emulator."""
+
+import boot_data
+import logging
+import os
+import subprocess
+import sys
+import target
+import tempfile
+
+class EmuTarget(target.Target):
+ def __init__(self, output_dir, target_cpu, system_log_file):
+ """output_dir: The directory which will contain the files that are
+ generated to support the emulator deployment.
+ target_cpu: The emulated target CPU architecture.
+ Can be 'x64' or 'arm64'."""
+ super(EmuTarget, self).__init__(output_dir, target_cpu)
+ self._emu_process = None
+ self._system_log_file = system_log_file
+
+ def __enter__(self):
+ return self
+
+ def _GetEmulatorName(self):
+ pass
+
+ def _BuildCommand(self):
+ """Build the command that will be run to start Fuchsia in the emulator."""
+ pass
+
+ # Used by the context manager to ensure that the emulator is killed when
+ # the Python process exits.
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.Shutdown();
+
+ def Start(self):
+ emu_command = self._BuildCommand()
+
+ # We pass a separate stdin stream. Sharing stdin across processes
+ # leads to flakiness due to the OS prematurely killing the stream and the
+ # Python script panicking and aborting.
+ # The precise root cause is still nebulous, but this fix works.
+ # See crbug.com/741194.
+ logging.debug('Launching %s.' % (self._GetEmulatorName()))
+ logging.debug(' '.join(emu_command))
+
+ # Zircon sends debug logs to serial port (see kernel.serial=legacy flag
+ # above). Serial port is redirected to a file through emulator stdout.
+ # Unless a |_system_log_file| is explicitly set, we output the kernel serial
+ # log to a temporary file, and print that out if we are unable to connect to
+ # the emulator guest, to make it easier to diagnose connectivity issues.
+ temporary_system_log_file = None
+ if self._system_log_file:
+ stdout = self._system_log_file
+ stderr = subprocess.STDOUT
+ else:
+ temporary_system_log_file = tempfile.NamedTemporaryFile('w')
+ stdout = temporary_system_log_file
+ stderr = sys.stderr
+
+ self._emu_process = subprocess.Popen(emu_command, stdin=open(os.devnull),
+ stdout=stdout, stderr=stderr)
+
+ try:
+ self._WaitUntilReady();
+ except target.FuchsiaTargetException:
+ if temporary_system_log_file:
+ logging.info('Kernel logs:\n' +
+ open(temporary_system_log_file.name, 'r').read())
+ raise
+
+ def Shutdown(self):
+ if self._IsEmuStillRunning():
+ logging.info('Shutting down %s' % (self._GetEmulatorName()))
+ self._emu_process.kill()
+
+ def _IsEmuStillRunning(self):
+ if not self._emu_process:
+ return False
+ return os.waitpid(self._emu_process.pid, os.WNOHANG)[0] == 0
+
+ def _GetEndpoint(self):
+ if not self._IsEmuStillRunning():
+ raise Exception('%s quit unexpectedly.' % (self._GetEmulatorName()))
+ return ('localhost', self._host_ssh_port)
+
+ def _GetSshConfigPath(self):
+ return boot_data.GetSSHConfigPath(self._output_dir) \ No newline at end of file