def _start(self, pixel_tests, per_test_args): if not self._android_devices.is_device_prepared(self._device.serial): raise driver.DeviceFailure("%s is not prepared in _start()" % self._device.serial) for retries in range(3): try: if self._start_once(pixel_tests, per_test_args): return except ScriptError as e: self._abort('ScriptError("%s") in _start()' % str(e)) self._log_error('Failed to start the content_shell application. Retries=%d. Log:%s' % (retries, self._get_logcat())) self.stop() time.sleep(2) self._abort('Failed to start the content_shell application multiple times. Giving up.')
def _start(self): if self._proc: raise ValueError('%s already running' % self._name) self._reset() # Fuchsia doesn't support stdin stream for packaged applications, so the # stdin stream for content_shell is routed through a separate TCP # socket. Open a local socket and then pass the address with the port as # --stdin-redirect parameter. content_shell will connect to this address # and will use that connection as its stdin stream. listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listen_socket.bind(('127.0.0.1', 0)) listen_socket.listen(1) stdin_port = listen_socket.getsockname()[1] command = ['%s=%s' % (k, v) for k, v in self._env.items()] + \ self._cmd + \ ['--stdin-redirect=%s:%s' % (qemu_target.HOST_IP_ADDRESS, stdin_port)] proc = self._port.get_target_host().run_command(command) # Wait for incoming connection from content_shell. fd = listen_socket.fileno() read_fds, _, _ = select.select([fd], [], [], PROCESS_START_TIMEOUT) if fd not in read_fds: listen_socket.close() proc.kill() raise driver.DeviceFailure( 'Timed out waiting connection from content_shell.') # Python's interfaces for sockets and pipes are different. To masquerade # the socket as a pipe dup() the file descriptor and pass it to # os.fdopen(). stdin_socket, _ = listen_socket.accept() fd = stdin_socket.fileno() # pylint: disable=no-member stdin_pipe = os.fdopen(os.dup(fd), "w", 0) stdin_socket.close() proc.stdin.close() proc.stdin = stdin_pipe self._set_proc(proc)
def _abort(self, message): self._device_failed = True raise driver.DeviceFailure('[%s] %s' % (self._device.serial, message))