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

Side by Side Diff: build/android/pylib/device/device_utils.py

Issue 1167693002: remove stale test data on the device (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove stale data from device Created 5 years, 6 months 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 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Provides a variety of device interactions based on adb. 5 """Provides a variety of device interactions based on adb.
6 6
7 Eventually, this will be based on adb_wrapper. 7 Eventually, this will be based on adb_wrapper.
8 """ 8 """
9 # pylint: disable=unused-argument 9 # pylint: disable=unused-argument
10 10
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 retries: number of retries 456 retries: number of retries
457 457
458 Raises: 458 Raises:
459 CommandFailedError if the installation fails. 459 CommandFailedError if the installation fails.
460 CommandTimeoutError if the installation times out. 460 CommandTimeoutError if the installation times out.
461 DeviceUnreachableError on missing device. 461 DeviceUnreachableError on missing device.
462 """ 462 """
463 package_name = apk_helper.GetPackageName(apk_path) 463 package_name = apk_helper.GetPackageName(apk_path)
464 device_path = self.GetApplicationPath(package_name) 464 device_path = self.GetApplicationPath(package_name)
465 if device_path is not None: 465 if device_path is not None:
466 should_install = bool(self._GetChangedFilesImpl(apk_path, device_path)) 466 (files_to_push, _) = self._GetChangedAndStaleFiles(
467 apk_path, device_path)
468 should_install = bool(files_to_push)
467 if should_install and not reinstall: 469 if should_install and not reinstall:
468 self.adb.Uninstall(package_name) 470 self.adb.Uninstall(package_name)
469 else: 471 else:
470 should_install = True 472 should_install = True
471 if should_install: 473 if should_install:
472 self.adb.Install(apk_path, reinstall=reinstall) 474 self.adb.Install(apk_path, reinstall=reinstall)
473 475
474 @decorators.WithTimeoutAndRetriesFromInstance() 476 @decorators.WithTimeoutAndRetriesFromInstance()
475 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None, 477 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None,
476 as_root=False, single_line=False, large_output=False, 478 as_root=False, single_line=False, large_output=False,
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 self.RunShellCommand(['input', 'keyevent', format(keycode, 'd')], 805 self.RunShellCommand(['input', 'keyevent', format(keycode, 'd')],
804 check_return=True) 806 check_return=True)
805 807
806 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT 808 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
807 PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES 809 PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES
808 810
809 @decorators.WithTimeoutAndRetriesDefaults( 811 @decorators.WithTimeoutAndRetriesDefaults(
810 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT, 812 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT,
811 PUSH_CHANGED_FILES_DEFAULT_RETRIES) 813 PUSH_CHANGED_FILES_DEFAULT_RETRIES)
812 def PushChangedFiles(self, host_device_tuples, timeout=None, 814 def PushChangedFiles(self, host_device_tuples, timeout=None,
813 retries=None): 815 retries=None, delete_device_stale=False):
814 """Push files to the device, skipping files that don't need updating. 816 """Push files to the device, skipping files that don't need updating.
817 If delete_device_stale option is True, delete stale files on device.
perezju 2015/06/10 09:24:23 Maybe explain in a bit more detail: When pushing
Menglin 2015/06/10 21:22:16 Done.
815 818
816 Args: 819 Args:
817 host_device_tuples: A list of (host_path, device_path) tuples, where 820 host_device_tuples: A list of (host_path, device_path) tuples, where
818 |host_path| is an absolute path of a file or directory on the host 821 |host_path| is an absolute path of a file or directory on the host
819 that should be minimially pushed to the device, and |device_path| is 822 that should be minimially pushed to the device, and |device_path| is
820 an absolute path of the destination on the device. 823 an absolute path of the destination on the device.
821 timeout: timeout in seconds 824 timeout: timeout in seconds
822 retries: number of retries 825 retries: number of retries
826 delete_device_stale: option to delete stale files on device
823 827
824 Raises: 828 Raises:
825 CommandFailedError on failure. 829 CommandFailedError on failure.
826 CommandTimeoutError on timeout. 830 CommandTimeoutError on timeout.
827 DeviceUnreachableError on missing device. 831 DeviceUnreachableError on missing device.
828 """ 832 """
829 833
830 files = [] 834 files = []
835 stale_files_on_device = []
831 for h, d in host_device_tuples: 836 for h, d in host_device_tuples:
832 if os.path.isdir(h): 837 if os.path.isdir(h):
833 self.RunShellCommand(['mkdir', '-p', d], check_return=True) 838 self.RunShellCommand(['mkdir', '-p', d], check_return=True)
834 files += self._GetChangedFilesImpl(h, d) 839 (file_tuples_to_push, stale_files) = self._GetChangedAndStaleFiles(h, d)
840 files += file_tuples_to_push
841 stale_files_on_device += stale_files
perezju 2015/06/10 09:24:23 nit: maybe rename these variables to something lik
Menglin 2015/06/10 21:22:15 Done.
842
843 if delete_device_stale:
844 self._DeleteStaleFiles(stale_files_on_device)
835 845
836 if not files: 846 if not files:
837 return 847 return
838 848
849 self._PushFilesImpl(host_device_tuples, files)
850
851 def _GetChangedAndStaleFiles(self, host_path, device_path):
852 """Get files to push and delete
853
854 Args:
855 host_path: an absolute path of a file or directory on the host
856 device_path: an absolute path of a file or directory on the device
857
858 Returns:
859 a two-element tuple
860 1st element: a list of (host_files_path, device_files_path) tuples to push
861 2nd element: a list of stale files under device_path
862 """
863 real_host_path = os.path.realpath(host_path)
864 try:
865 real_device_path = self.RunShellCommand(
866 ['realpath', device_path], single_line=True, check_return=True)
867 except device_errors.CommandFailedError:
868 real_device_path = None
869 if not real_device_path:
870 return ([(host_path, device_path)], [])
871
872 try:
873 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
874 device_checksums = md5sum.CalculateDeviceMd5Sums(
875 [real_device_path], self)
876 except EnvironmentError as e:
877 logging.warning('Error calculating md5: %s', e)
878 return ([(host_path, device_path)], [])
879
880 if os.path.isfile(host_path):
881 host_checksum = host_checksums.get(real_host_path)
882 device_checksum = device_checksums.get(real_device_path)
883 if host_checksum != device_checksum:
884 return ([(host_path, device_path)], [])
885 else:
886 return ([], [])
887 else:
888 to_push = []
889 to_delete = []
890 for host_abs_path, host_checksum in host_checksums.iteritems():
891 device_abs_path = '%s/%s' % (
892 real_device_path, os.path.relpath(host_abs_path, real_host_path))
893 device_checksum = device_checksums.get(device_abs_path)
894 if device_abs_path in device_checksums:
895 del device_checksums[device_abs_path]
perezju 2015/06/10 09:24:22 I think you can replace the last three lines with:
Menglin 2015/06/10 21:22:15 Done.
896 if ((device_checksum) != host_checksum):
perezju 2015/06/10 09:24:23 nit: drop all the parentheses
Menglin 2015/06/10 21:22:15 Done.
897 to_push.append((host_abs_path, device_abs_path))
898 to_delete = [p for p in device_checksums.iterkeys()]
perezju 2015/06/10 09:24:22 nit: to_delete = device_checksums.keys()
Menglin 2015/06/10 21:22:15 Done.
899 return (to_push, to_delete)
900
901 def _PushFilesImpl(self, host_device_tuples, files):
839 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) 902 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
840 file_count = len(files) 903 file_count = len(files)
841 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) 904 dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
842 for h, _ in host_device_tuples) 905 for h, _ in host_device_tuples)
843 dir_file_count = 0 906 dir_file_count = 0
844 for h, _ in host_device_tuples: 907 for h, _ in host_device_tuples:
845 if os.path.isdir(h): 908 if os.path.isdir(h):
846 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h)) 909 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h))
847 else: 910 else:
848 dir_file_count += 1 911 dir_file_count += 1
(...skipping 10 matching lines...) Expand all
859 dir_push_duration < zip_duration or not self._commands_installed): 922 dir_push_duration < zip_duration or not self._commands_installed):
860 self._PushChangedFilesIndividually(host_device_tuples) 923 self._PushChangedFilesIndividually(host_device_tuples)
861 elif push_duration < zip_duration or not self._commands_installed: 924 elif push_duration < zip_duration or not self._commands_installed:
862 self._PushChangedFilesIndividually(files) 925 self._PushChangedFilesIndividually(files)
863 else: 926 else:
864 self._PushChangedFilesZipped(files) 927 self._PushChangedFilesZipped(files)
865 self.RunShellCommand( 928 self.RunShellCommand(
866 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], 929 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
867 as_root=True, check_return=True) 930 as_root=True, check_return=True)
868 931
869 def _GetChangedFilesImpl(self, host_path, device_path): 932 def _DeleteStaleFiles(self, stale_files):
870 real_host_path = os.path.realpath(host_path) 933 for stale_file_path in stale_files:
871 try: 934 self.RunShellCommand(['rm', stale_file_path])
perezju 2015/06/10 09:24:22 do we really need this method? maybe just inline w
Menglin 2015/06/10 21:22:15 Done.
872 real_device_path = self.RunShellCommand(
873 ['realpath', device_path], single_line=True, check_return=True)
874 except device_errors.CommandFailedError:
875 real_device_path = None
876 if not real_device_path:
877 return [(host_path, device_path)]
878
879 try:
880 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
881 device_paths_to_md5 = (
882 real_device_path if os.path.isfile(real_host_path)
883 else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path))
884 for p in host_checksums.iterkeys()))
885 device_checksums = md5sum.CalculateDeviceMd5Sums(
886 device_paths_to_md5, self)
887 except EnvironmentError as e:
888 logging.warning('Error calculating md5: %s', e)
889 return [(host_path, device_path)]
890
891 if os.path.isfile(host_path):
892 host_checksum = host_checksums.get(real_host_path)
893 device_checksum = device_checksums.get(real_device_path)
894 if host_checksum != device_checksum:
895 return [(host_path, device_path)]
896 else:
897 return []
898 else:
899 to_push = []
900 for host_abs_path, host_checksum in host_checksums.iteritems():
901 device_abs_path = '%s/%s' % (
902 real_device_path, os.path.relpath(host_abs_path, real_host_path))
903 if (device_checksums.get(device_abs_path) != host_checksum):
904 to_push.append((host_abs_path, device_abs_path))
905 return to_push
906 935
907 def _InstallCommands(self): 936 def _InstallCommands(self):
908 if self._commands_installed is None: 937 if self._commands_installed is None:
909 try: 938 try:
910 if not install_commands.Installed(self): 939 if not install_commands.Installed(self):
911 install_commands.InstallCommands(self) 940 install_commands.InstallCommands(self)
912 self._commands_installed = True 941 self._commands_installed = True
913 except Exception as e: 942 except Exception as e:
914 logging.warning('unzip not available: %s' % str(e)) 943 logging.warning('unzip not available: %s' % str(e))
915 self._commands_installed = False 944 self._commands_installed = False
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 blacklist = device_blacklist.ReadBlacklist() 1608 blacklist = device_blacklist.ReadBlacklist()
1580 def blacklisted(adb): 1609 def blacklisted(adb):
1581 if adb.GetDeviceSerial() in blacklist: 1610 if adb.GetDeviceSerial() in blacklist:
1582 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial()) 1611 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial())
1583 return True 1612 return True
1584 return False 1613 return False
1585 1614
1586 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices() 1615 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices()
1587 if not blacklisted(adb)] 1616 if not blacklisted(adb)]
1588 1617
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698