Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py

Issue 2540603004: [Android] Redirect std{in,out,err} to sockets for layout tests. (Closed)
Patch Set: peter comments 2 Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (C) 2012 Google Inc. All rights reserved. 1 # Copyright (C) 2012 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the 11 # in the documentation and/or other materials provided with the
12 # distribution. 12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from 14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission. 15 # this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import itertools
29 import logging 30 import logging
30 import os 31 import os
31 import re 32 import re
32 import sys 33 import sys
33 import threading 34 import threading
34 import time 35 import time
35 36
36 from multiprocessing.pool import ThreadPool 37 from multiprocessing.pool import ThreadPool
37 38
38 from webkitpy.common.system.executive import ScriptError 39 from webkitpy.common.system.executive import ScriptError
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 261
261 BUILD_REQUIREMENTS_URL = 'https://www.chromium.org/developers/how-tos/androi d-build-instructions' 262 BUILD_REQUIREMENTS_URL = 'https://www.chromium.org/developers/how-tos/androi d-build-instructions'
262 263
263 def __init__(self, host, port_name, **kwargs): 264 def __init__(self, host, port_name, **kwargs):
264 super(AndroidPort, self).__init__(host, port_name, **kwargs) 265 super(AndroidPort, self).__init__(host, port_name, **kwargs)
265 266
266 self._operating_system = 'android' 267 self._operating_system = 'android'
267 self._version = 'icecreamsandwich' 268 self._version = 'icecreamsandwich'
268 269
269 self._host_port = factory.PortFactory(host).get(**kwargs) 270 self._host_port = factory.PortFactory(host).get(**kwargs)
270 self._server_process_constructor = self._android_server_process_construc tor 271 self.server_process_constructor = self._android_server_process_construct or
271 272
272 if not self.get_option('disable_breakpad'): 273 if not self.get_option('disable_breakpad'):
273 self._dump_reader = DumpReaderAndroid(host, self._build_path()) 274 self._dump_reader = DumpReaderAndroid(host, self._build_path())
274 275
275 if self.driver_name() != self.CONTENT_SHELL_NAME: 276 if self.driver_name() != self.CONTENT_SHELL_NAME:
276 raise AssertionError('Layout tests on Android only support content_s hell as the driver.') 277 raise AssertionError('Layout tests on Android only support content_s hell as the driver.')
277 278
278 self._driver_details = ContentShellDriverDetails() 279 self._driver_details = ContentShellDriverDetails()
279 280
280 # Initialize the AndroidDevices class which tracks available devices. 281 # Initialize the AndroidDevices class which tracks available devices.
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 603
603 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l inux' 604 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l inux'
604 _log.debug("To view the full profile, run:") 605 _log.debug("To view the full profile, run:")
605 _log.debug(' '.join([perfhost_display_patch] + perfhost_report_command)) 606 _log.debug(' '.join([perfhost_display_patch] + perfhost_report_command))
606 607
607 608
608 class ChromiumAndroidDriver(driver.Driver): 609 class ChromiumAndroidDriver(driver.Driver):
609 610
610 def __init__(self, port, worker_number, pixel_tests, driver_details, android _devices, no_timeout=False): 611 def __init__(self, port, worker_number, pixel_tests, driver_details, android _devices, no_timeout=False):
611 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t ests, no_timeout) 612 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t ests, no_timeout)
612 self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fif o' 613 self._write_stdin_process = None
613 self._out_fifo_path = driver_details.device_fifo_directory() + 'test.fif o'
614 self._err_fifo_path = driver_details.device_fifo_directory() + 'stderr.f ifo'
615 self._read_stdout_process = None 614 self._read_stdout_process = None
616 self._read_stderr_process = None 615 self._read_stderr_process = None
617 self._original_kptr_restrict = None 616 self._original_kptr_restrict = None
618 617
619 self._android_devices = android_devices 618 self._android_devices = android_devices
620 self._device = android_devices.get_device(port._executive, worker_number ) # pylint: disable=protected-access 619 self._device = android_devices.get_device(port._executive, worker_number ) # pylint: disable=protected-access
621 self._driver_details = driver_details 620 self._driver_details = driver_details
622 self._debug_logging = self._port._debug_logging 621 self._debug_logging = self._port._debug_logging
623 self._created_cmd_line = False 622 self._created_cmd_line = False
624 self._device_failed = False 623 self._device_failed = False
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 return '' 818 return ''
820 819
821 # Use Android tool vendor/google/tools/stack to convert the raw 820 # Use Android tool vendor/google/tools/stack to convert the raw
822 # stack trace into a human readable format, if needed. 821 # stack trace into a human readable format, if needed.
823 # It takes a long time, so don't do it here. 822 # It takes a long time, so don't do it here.
824 tombstone_contents = self._device.ReadFile( 823 tombstone_contents = self._device.ReadFile(
825 '/data/tombstones/%s' % last_tombstone[6]) 824 '/data/tombstones/%s' % last_tombstone[6])
826 return '%s\n%s' % (' '.join(last_tombstone), tombstone_contents) 825 return '%s\n%s' % (' '.join(last_tombstone), tombstone_contents)
827 826
828 def _get_logcat(self): 827 def _get_logcat(self):
829 return list(self._device.adb.Logcat(dump=True, logcat_format='threadtime ')) 828 return '\n'.join(self._device.adb.Logcat(dump=True, logcat_format='threa dtime'))
830 829
831 def _setup_performance(self): 830 def _setup_performance(self):
832 # Disable CPU scaling and drop ram cache to reduce noise in tests 831 # Disable CPU scaling and drop ram cache to reduce noise in tests
833 perf_control.PerfControl(self._device).SetPerfProfilingMode() 832 perf_control.PerfControl(self._device).SetPerfProfilingMode()
834 833
835 def _teardown_performance(self): 834 def _teardown_performance(self):
836 perf_control.PerfControl(self._device).SetDefaultPerfMode() 835 perf_control.PerfControl(self._device).SetDefaultPerfMode()
837 836
838 def _get_crash_log(self, stdout, stderr, newer_than): 837 def _get_crash_log(self, stdout, stderr, newer_than):
839 if not stdout: 838 if not stdout:
(...skipping 30 matching lines...) Expand all
870 return driver.Driver.cmd_line(self, pixel_tests, per_test_args) 869 return driver.Driver.cmd_line(self, pixel_tests, per_test_args)
871 870
872 @staticmethod 871 @staticmethod
873 def _loop_with_timeout(condition, timeout_secs): 872 def _loop_with_timeout(condition, timeout_secs):
874 deadline = time.time() + timeout_secs 873 deadline = time.time() + timeout_secs
875 while time.time() < deadline: 874 while time.time() < deadline:
876 if condition(): 875 if condition():
877 return True 876 return True
878 return False 877 return False
879 878
880 def _all_pipes_created(self):
881 return self._device.PathExists(
882 [self._in_fifo_path, self._out_fifo_path, self._err_fifo_path])
883
884 def _remove_all_pipes(self):
885 self._device.RunShellCommand(
886 ['rm', '-f', self._in_fifo_path, self._out_fifo_path, self._err_fifo _path],
887 check_return=True)
888 return (not self._device.PathExists(self._in_fifo_path) and
889 not self._device.PathExists(self._out_fifo_path) and
890 not self._device.PathExists(self._err_fifo_path))
891
892 def start(self, pixel_tests, per_test_args, deadline): 879 def start(self, pixel_tests, per_test_args, deadline):
893 # We override the default start() so that we can call _android_driver_cm d_line() 880 # We override the default start() so that we can call _android_driver_cm d_line()
894 # instead of cmd_line(). 881 # instead of cmd_line().
895 new_cmd_line = self._android_driver_cmd_line(pixel_tests, per_test_args) 882 new_cmd_line = self._android_driver_cmd_line(pixel_tests, per_test_args)
896 883
897 # Since _android_driver_cmd_line() is different than cmd_line() we need to provide 884 # Since _android_driver_cmd_line() is different than cmd_line() we need to provide
898 # our own mechanism for detecting when the process should be stopped. 885 # our own mechanism for detecting when the process should be stopped.
899 if self._current_cmd_line is None: 886 if self._current_cmd_line is None:
900 self._current_android_cmd_line = None 887 self._current_android_cmd_line = None
901 if new_cmd_line != self._current_android_cmd_line: 888 if new_cmd_line != self._current_android_cmd_line:
902 self.stop() 889 self.stop()
903 self._current_android_cmd_line = new_cmd_line 890 self._current_android_cmd_line = new_cmd_line
904 891
905 super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args, dea dline) 892 super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args, dea dline)
906 893
907 def _start(self, pixel_tests, per_test_args): 894 def _start(self, pixel_tests, per_test_args):
908 if not self._android_devices.is_device_prepared(self._device.serial): 895 if not self._android_devices.is_device_prepared(self._device.serial):
909 raise driver.DeviceFailure("%s is not prepared in _start()" % self._ device.serial) 896 raise driver.DeviceFailure("%s is not prepared in _start()" % self._ device.serial)
910 897
911 for retries in range(3): 898 for retries in range(3):
912 try: 899 try:
913 if self._start_once(pixel_tests, per_test_args): 900 if self._start_once(pixel_tests, per_test_args):
914 return 901 return
915 except ScriptError as e: 902 except ScriptError as e:
916 self._abort('ScriptError("%s") in _start()' % str(e)) 903 self._abort('ScriptError("%s") in _start()' % str(e))
917 904
918 self._log_error('Failed to start the content_shell application. Retr ies=%d. Log:%s' % (retries, self._get_logcat())) 905 self._log_error('Failed to start the content_shell application. Retr ies=%d. Log:\n%s' % (retries, self._get_logcat()))
919 self.stop() 906 self.stop()
920 time.sleep(2) 907 time.sleep(2)
921 self._abort('Failed to start the content_shell application multiple time s. Giving up.') 908 self._abort('Failed to start the content_shell application multiple time s. Giving up.')
922 909
923 def _start_once(self, pixel_tests, per_test_args): 910 def _start_once(self, pixel_tests, per_test_args):
924 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa it_for_ready=False) 911 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa it_for_ready=False)
925 912
913 self._device.adb.Logcat(clear=True)
914
915 self._device.RunShellCommand(
916 ['rm', '-rf', self._driver_details.device_crash_dumps_directory()],
917 check_return=True)
918 self._device.RunShellCommand(
919 ['mkdir', self._driver_details.device_crash_dumps_directory()],
920 check_return=True)
921 self._device.RunShellCommand(
922 ['chmod', '-R', '777', self._driver_details.device_crash_dumps_direc tory()],
923 check_return=True)
qyearsley 2016/12/15 19:21:01 Maybe some parts of this large function would be e
jbudorick 2016/12/21 00:55:16 Done.
924
925 # Read back the shell prompt to ensure adb shell is ready.
926 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS
927 self._server_process.start()
qyearsley 2016/12/15 19:21:02 What process does self._server_process refer to?
jbudorick 2016/12/21 00:55:16 For Android, it's basically a host proxy process f
928 self._read_prompt(deadline)
929 self._log_debug('Interactive shell started')
930
931 # Start a netcat process to which the test driver will connect to write stdout.
932 self._read_stdout_process, stdout_port = self._start_netcat(
933 'ReadStdout', read_from_stdin=False)
934 self._log_debug('Redirecting stdout to port %d' % stdout_port)
935
936 # Start a netcat process to which the test driver will connect to write stderr.
937 self._read_stderr_process, stderr_port = self._start_netcat(
938 'ReadStderr', first_port=stdout_port + 1, read_from_stdin=False)
939 self._log_debug('Redirecting stderr to port %d' % stderr_port)
940
941 # Start a netcat process to which the test driver will connect to read s tdin.
942 self._write_stdin_process, stdin_port = self._start_netcat(
943 'WriteStdin', first_port=stderr_port + 1)
944 self._log_debug('Redirecting stdin to port %d' % stdin_port)
945
946 # Combine the stdin, stdout, and stderr pipes into self._server_process.
947 self._replace_server_process_streams()
948
926 # We delay importing forwarder as long as possible because it uses fcntl , 949 # We delay importing forwarder as long as possible because it uses fcntl ,
927 # which isn't available on windows. 950 # which isn't available on windows.
928 from devil.android import forwarder 951 from devil.android import forwarder
929 952
930 self._log_debug('Starting forwarder') 953 self._log_debug('Starting forwarder')
931 forwarder.Forwarder.Map( 954 forwarder.Forwarder.Map(
932 [(p, p) for p in FORWARD_PORTS.split()], 955 [(p, p) for p in FORWARD_PORTS.split()],
933 self._device) 956 self._device)
qyearsley 2016/12/15 19:21:02 What happens when you "start the forwarder"? Does
jbudorick 2016/12/21 00:55:16 It starts a host_forwarder client process which th
934 957 forwarder.Forwarder.Map(
935 self._device.adb.Logcat(clear=True) 958 [(0, stdout_port), (0, stderr_port), (0, stdin_port)],
959 self._device)
qyearsley 2016/12/15 19:21:02 It's not obvious from here that 0 means that a por
jbudorick 2016/12/21 00:55:16 That or a constant in forwarder.py: https://codere
qyearsley 2017/01/04 19:00:32 I agree, that is good :-)
936 960
937 cmd_line_file_path = self._driver_details.command_line_file() 961 cmd_line_file_path = self._driver_details.command_line_file()
938 original_cmd_line_file_path = cmd_line_file_path + '.orig' 962 original_cmd_line_file_path = cmd_line_file_path + '.orig'
939 if (self._device.PathExists(cmd_line_file_path) 963 if (self._device.PathExists(cmd_line_file_path)
940 and not self._device.PathExists(original_cmd_line_file_path)): 964 and not self._device.PathExists(original_cmd_line_file_path)):
941 # We check for both the normal path and the backup because we do not want to step 965 # We check for both the normal path and the backup because we do not want to step
942 # on the backup. Otherwise, we'd clobber the backup whenever we chan ged the 966 # on the backup. Otherwise, we'd clobber the backup whenever we chan ged the
943 # command line during the run. 967 # command line during the run.
944 self._device.RunShellCommand( 968 self._device.RunShellCommand(
945 ['mv', cmd_line_file_path, original_cmd_line_file_path], 969 ['mv', cmd_line_file_path, original_cmd_line_file_path],
946 check_return=True) 970 check_return=True)
947 971
972 stream_port_args = [
973 '--android-stderr-port=%s' % forwarder.Forwarder.DevicePortForHostPo rt(stderr_port),
974 '--android-stdin-port=%s' % forwarder.Forwarder.DevicePortForHostPor t(stdin_port),
975 '--android-stdout-port=%s' % forwarder.Forwarder.DevicePortForHostPo rt(stdout_port),
976 ]
977 cmd_line_contents = self._android_driver_cmd_line(pixel_tests, per_test_ args + stream_port_args)
948 self._device.WriteFile( 978 self._device.WriteFile(
949 self._driver_details.command_line_file(), 979 self._driver_details.command_line_file(),
950 ' '.join(self._android_driver_cmd_line(pixel_tests, per_test_args))) 980 ' '.join(cmd_line_contents))
981 self._log_debug('Command-line file contents: %s' % ' '.join(cmd_line_con tents))
951 self._created_cmd_line = True 982 self._created_cmd_line = True
952 983
953 self._device.RunShellCommand(
954 ['rm', '-rf', self._driver_details.device_crash_dumps_directory()],
955 check_return=True)
956 self._device.RunShellCommand(
957 ['mkdir', self._driver_details.device_crash_dumps_directory()],
958 check_return=True)
959 self._device.RunShellCommand(
960 ['chmod', '-R', '777', self._driver_details.device_crash_dumps_direc tory()],
961 check_return=True)
962
963 try: 984 try:
964 self._device.StartActivity( 985 self._device.StartActivity(
965 intent.Intent( 986 intent.Intent(
966 component=self._driver_details.activity_name(), 987 component=self._driver_details.activity_name(),
967 extras={'RunInSubThread': None})) 988 extras={'RunInSubThread': None}))
968 except device_errors.CommandFailedError as exc: 989 except device_errors.CommandFailedError as exc:
969 self._log_error('Failed to start the content_shell application. Exce ption:\n' + str(exc)) 990 self._log_error('Failed to start the content_shell application. Exce ption:\n' + str(exc))
970 return False 991 return False
971 992
972 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created, DRIVER_START_STOP_TIMEOUT_SECS): 993 # The test driver might crash during startup.
973 return False
974
975 # Read back the shell prompt to ensure adb shell ready.
976 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS
977 self._server_process.start()
978 self._read_prompt(deadline)
979 self._log_debug('Interactive shell started')
980
981 # Start a process to read from the stdout fifo of the test driver and pr int to stdout.
982 self._log_debug('Redirecting stdout to ' + self._out_fifo_path)
983 self._read_stdout_process = self._port._server_process_constructor(
984 self._port, 'ReadStdout',
985 [self._device.adb.GetAdbPath(), '-s', self._device.serial, 'shell', 'cat', self._out_fifo_path])
986 self._read_stdout_process.start()
987
988 # Start a process to read from the stderr fifo of the test driver and pr int to stdout.
989 self._log_debug('Redirecting stderr to ' + self._err_fifo_path)
990 self._read_stderr_process = self._port._server_process_constructor(
991 self._port, 'ReadStderr',
992 [self._device.adb.GetAdbPath(), '-s', self._device.serial, 'shell', 'cat', self._err_fifo_path])
993 self._read_stderr_process.start()
994
995 self._log_debug('Redirecting stdin to ' + self._in_fifo_path)
996 self._server_process.write('cat >%s\n' % self._in_fifo_path)
997
998 # Combine the stdout and stderr pipes into self._server_process.
999 self._server_process.replace_outputs(self._read_stdout_process._proc.std out, self._read_stderr_process._proc.stdout)
1000
1001 def deadlock_detector(processes, normal_startup_event):
1002 if not ChromiumAndroidDriver._loop_with_timeout(lambda: normal_start up_event.is_set(), DRIVER_START_STOP_TIMEOUT_SECS):
1003 # If normal_startup_event is not set in time, the main thread mu st be blocked at
1004 # reading/writing the fifo. Kill the fifo reading/writing proces ses to let the
1005 # main thread escape from the deadlocked state. After that, the main thread will
1006 # treat this as a crash.
1007 self._log_error('Deadlock detected. Processes killed.')
1008 for i in processes:
1009 i.kill()
1010
1011 # Start a thread to kill the pipe reading/writing processes on deadlock of the fifos during startup.
1012 normal_startup_event = threading.Event()
1013 threading.Thread(
1014 name='DeadlockDetector',
1015 target=deadlock_detector,
1016 args=([self._server_process, self._read_stdout_process, self._read_s tderr_process], normal_startup_event)).start()
1017
1018 # The test driver might crash during startup or when the deadlock detect or hits
1019 # a deadlock and kills the fifo reading/writing processes.
1020 if not self._wait_for_server_process_output(self._server_process, deadli ne, '#READY'): 994 if not self._wait_for_server_process_output(self._server_process, deadli ne, '#READY'):
1021 return False 995 return False
1022 996
1023 # Inform the deadlock detector that the startup is successful without de adlock.
1024 normal_startup_event.set()
1025 self._log_debug("content_shell is ready") 997 self._log_debug("content_shell is ready")
1026 return True 998 return True
1027 999
1000 def _start_netcat(self, server_name, first_port=10201, read_from_stdin=True) :
qyearsley 2016/12/15 19:21:02 Server name must always be one of {"ReadStderr", "
jbudorick 2016/12/21 00:55:16 The three call sites provide those, but there's no
qyearsley 2017/01/04 19:00:32 Optionally, if you think it makes it clearer, we c
jbudorick 2017/01/04 19:50:15 I think it helps for the port and have added a con
1001 for i in itertools.count(first_port, 65536):
1002 nc_cmd = ['nc', '-l', str(i)]
1003 if not read_from_stdin:
1004 nc_cmd.append('-d')
1005 proc = self._port.server_process_constructor(self._port, server_name , nc_cmd)
1006 proc.start()
1007 self._port.host.executive.wait_limited(proc.pid(), limit_in_seconds= 1)
1008 if self._port.host.executive.check_running_pid(proc.pid()):
1009 return (proc, i)
qyearsley 2016/12/15 19:21:02 What would happen hypothetically if this loop exit
jbudorick 2016/12/21 00:55:16 hmm, this would return None and we'd get a confusi
qyearsley 2017/01/04 19:00:32 SGTM
1010
1011 def _replace_server_process_streams(self):
1012 # pylint: disable=protected-access
1013 self._server_process.replace_input(
1014 self._write_stdin_process._proc.stdin)
1015 self._server_process.replace_outputs(
1016 self._read_stdout_process._proc.stdout,
1017 self._read_stderr_process._proc.stdout)
1018
1028 def _pid_on_target(self): 1019 def _pid_on_target(self):
1029 pids = self._device.GetPids(self._driver_details.package_name()) 1020 pids = self._device.GetPids(self._driver_details.package_name())
1030 return pids.get(self._driver_details.package_name()) 1021 return pids.get(self._driver_details.package_name())
1031 1022
1032 def stop(self): 1023 def stop(self):
1033 if not self._device_failed: 1024 if not self._device_failed:
1034 # Do not try to stop the application if there's something wrong with the device; adb may hang. 1025 # Do not try to stop the application if there's something wrong with the device; adb may hang.
1035 # FIXME: crbug.com/305040. Figure out if it's really hanging (and wh y). 1026 # FIXME: crbug.com/305040. Figure out if it's really hanging (and wh y).
1036 self._device.ForceStop(self._driver_details.package_name()) 1027 self._device.ForceStop(self._driver_details.package_name())
1037 1028
1029 if self._write_stdin_process:
1030 self._write_stdin_process.kill()
1031 self._write_stdin_process = None
1032
1038 if self._read_stdout_process: 1033 if self._read_stdout_process:
1039 self._read_stdout_process.kill() 1034 self._read_stdout_process.kill()
1040 self._read_stdout_process = None 1035 self._read_stdout_process = None
1041 1036
1042 if self._read_stderr_process: 1037 if self._read_stderr_process:
1043 self._read_stderr_process.kill() 1038 self._read_stderr_process.kill()
1044 self._read_stderr_process = None 1039 self._read_stderr_process = None
1045 1040
1046 # We delay importing forwarder as long as possible because it uses fcntl , 1041 # We delay importing forwarder as long as possible because it uses fcntl ,
1047 # which isn't available on windows. 1042 # which isn't available on windows.
1048 from devil.android import forwarder 1043 from devil.android import forwarder
1049 1044
1050 forwarder.Forwarder.KillDevice(self._device) 1045 forwarder.Forwarder.KillDevice(self._device)
1051 forwarder.Forwarder.KillHost() 1046 forwarder.Forwarder.KillHost()
1052 1047
1053 super(ChromiumAndroidDriver, self).stop() 1048 super(ChromiumAndroidDriver, self).stop()
1054 1049
1055 if self._android_devices.is_device_prepared(self._device.serial):
1056 if not ChromiumAndroidDriver._loop_with_timeout(self._remove_all_pip es, DRIVER_START_STOP_TIMEOUT_SECS):
1057 self._abort('Failed to remove fifo files. May be locked.')
1058
1059 self._clean_up_cmd_line() 1050 self._clean_up_cmd_line()
1060 1051
1061 def _pull_crash_dumps_from_device(self): 1052 def _pull_crash_dumps_from_device(self):
1062 result = [] 1053 result = []
1063 if not self._device.PathExists(self._driver_details.device_crash_dumps_d irectory()): 1054 if not self._device.PathExists(self._driver_details.device_crash_dumps_d irectory()):
1064 return result 1055 return result
1065 dumps = self._device.ListDirectory( 1056 dumps = self._device.ListDirectory(
1066 self._driver_details.device_crash_dumps_directory()) 1057 self._driver_details.device_crash_dumps_directory())
1067 for dump in dumps: 1058 for dump in dumps:
1068 device_dump = '%s/%s' % (self._driver_details.device_crash_dumps_dir ectory(), dump) 1059 device_dump = '%s/%s' % (self._driver_details.device_crash_dumps_dir ectory(), dump)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 return command 1100 return command
1110 1101
1111 def _read_prompt(self, deadline): 1102 def _read_prompt(self, deadline):
1112 last_char = '' 1103 last_char = ''
1113 while True: 1104 while True:
1114 current_char = self._server_process.read_stdout(deadline, 1) 1105 current_char = self._server_process.read_stdout(deadline, 1)
1115 if current_char == ' ': 1106 if current_char == ' ':
1116 if last_char in ('#', '$'): 1107 if last_char in ('#', '$'):
1117 return 1108 return
1118 last_char = current_char 1109 last_char = current_char
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698