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

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: 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 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 retries: number of retries 478 retries: number of retries
479 479
480 Raises: 480 Raises:
481 CommandFailedError if the installation fails. 481 CommandFailedError if the installation fails.
482 CommandTimeoutError if the installation times out. 482 CommandTimeoutError if the installation times out.
483 DeviceUnreachableError on missing device. 483 DeviceUnreachableError on missing device.
484 """ 484 """
485 package_name = apk_helper.GetPackageName(apk_path) 485 package_name = apk_helper.GetPackageName(apk_path)
486 device_path = self.GetApplicationPath(package_name) 486 device_path = self.GetApplicationPath(package_name)
487 if device_path is not None: 487 if device_path is not None:
488 should_install = bool(self._GetChangedFilesImpl(apk_path, device_path)) 488 (files_to_push, _) = self._GetChangedAndStaleFiles(
489 apk_path, device_path)
490 should_install = bool(files_to_push)
489 if should_install and not reinstall: 491 if should_install and not reinstall:
490 self.adb.Uninstall(package_name) 492 self.adb.Uninstall(package_name)
491 else: 493 else:
492 should_install = True 494 should_install = True
493 if should_install: 495 if should_install:
494 self.adb.Install(apk_path, reinstall=reinstall) 496 self.adb.Install(apk_path, reinstall=reinstall)
495 497
496 @decorators.WithTimeoutAndRetriesFromInstance() 498 @decorators.WithTimeoutAndRetriesFromInstance()
497 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None, 499 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None,
498 as_root=False, single_line=False, large_output=False, 500 as_root=False, single_line=False, large_output=False,
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 self.RunShellCommand(['input', 'keyevent', format(keycode, 'd')], 827 self.RunShellCommand(['input', 'keyevent', format(keycode, 'd')],
826 check_return=True) 828 check_return=True)
827 829
828 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT 830 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
829 PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES 831 PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES
830 832
831 @decorators.WithTimeoutAndRetriesDefaults( 833 @decorators.WithTimeoutAndRetriesDefaults(
832 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT, 834 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT,
833 PUSH_CHANGED_FILES_DEFAULT_RETRIES) 835 PUSH_CHANGED_FILES_DEFAULT_RETRIES)
834 def PushChangedFiles(self, host_device_tuples, timeout=None, 836 def PushChangedFiles(self, host_device_tuples, timeout=None,
835 retries=None): 837 retries=None, delete_device_stale=False):
836 """Push files to the device, skipping files that don't need updating. 838 """Push files to the device, skipping files that don't need updating.
839 If delete_device_stale option is True, delete stale files on device.
perezju 2015/06/11 08:38:47 nit: remove that line, it's now explained below.
Menglin 2015/06/11 20:36:16 Done.
840
841 When a directory is pushed, it is traversed recursively on the host and
842 all files in it are pushed to the device as needed.
843 Additionally, if delete_device_stale option is True,
844 files that exist on the device but don't exist on the host are deleted.
837 845
838 Args: 846 Args:
839 host_device_tuples: A list of (host_path, device_path) tuples, where 847 host_device_tuples: A list of (host_path, device_path) tuples, where
840 |host_path| is an absolute path of a file or directory on the host 848 |host_path| is an absolute path of a file or directory on the host
841 that should be minimially pushed to the device, and |device_path| is 849 that should be minimially pushed to the device, and |device_path| is
842 an absolute path of the destination on the device. 850 an absolute path of the destination on the device.
843 timeout: timeout in seconds 851 timeout: timeout in seconds
844 retries: number of retries 852 retries: number of retries
853 delete_device_stale: option to delete stale files on device
845 854
846 Raises: 855 Raises:
847 CommandFailedError on failure. 856 CommandFailedError on failure.
848 CommandTimeoutError on timeout. 857 CommandTimeoutError on timeout.
849 DeviceUnreachableError on missing device. 858 DeviceUnreachableError on missing device.
850 """ 859 """
851 860
852 files = [] 861 all_changed_files = []
862 all_stale_files = []
853 for h, d in host_device_tuples: 863 for h, d in host_device_tuples:
854 if os.path.isdir(h): 864 if os.path.isdir(h):
855 self.RunShellCommand(['mkdir', '-p', d], check_return=True) 865 self.RunShellCommand(['mkdir', '-p', d], check_return=True)
856 files += self._GetChangedFilesImpl(h, d) 866 (changed_files, stale_files) = self._GetChangedAndStaleFiles(h, d)
867 all_changed_files += changed_files
868 all_stale_files += stale_files
857 869
858 if not files: 870 if delete_device_stale:
871 for stale_file_path in all_stale_files:
872 self.RunShellCommand(['rm', stale_file_path])
perezju 2015/06/11 08:38:47 add option '-f' to rm (just in case the file is go
Menglin 2015/06/11 20:36:16 Done.
873
874 if not all_changed_files:
859 return 875 return
860 876
877 self._PushFilesImpl(host_device_tuples, all_changed_files)
878
879 def _GetChangedAndStaleFiles(self, host_path, device_path):
880 """Get files to push and delete
881
882 Args:
883 host_path: an absolute path of a file or directory on the host
884 device_path: an absolute path of a file or directory on the device
885
886 Returns:
887 a two-element tuple
888 1st element: a list of (host_files_path, device_files_path) tuples to push
889 2nd element: a list of stale files under device_path
890 """
891 real_host_path = os.path.realpath(host_path)
892 try:
893 real_device_path = self.RunShellCommand(
894 ['realpath', device_path], single_line=True, check_return=True)
895 except device_errors.CommandFailedError:
896 real_device_path = None
897 if not real_device_path:
898 return ([(host_path, device_path)], [])
899
900 try:
901 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
902 device_checksums = md5sum.CalculateDeviceMd5Sums(
903 [real_device_path], self)
904 except EnvironmentError as e:
905 logging.warning('Error calculating md5: %s', e)
906 return ([(host_path, device_path)], [])
907
908 if os.path.isfile(host_path):
909 host_checksum = host_checksums.get(real_host_path)
910 device_checksum = device_checksums.get(real_device_path)
911 if host_checksum != device_checksum:
912 return ([(host_path, device_path)], [])
913 else:
914 return ([], [])
915 else:
916 to_push = []
917 to_delete = []
918 for host_abs_path, host_checksum in host_checksums.iteritems():
919 device_abs_path = '%s/%s' % (
920 real_device_path, os.path.relpath(host_abs_path, real_host_path))
921 device_checksum = device_checksums.pop(device_abs_path, None)
922 if device_checksum != host_checksum:
923 to_push.append((host_abs_path, device_abs_path))
924 to_delete = device_checksums.keys()
925 return (to_push, to_delete)
926
927 def _PushFilesImpl(self, host_device_tuples, files):
861 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) 928 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
862 file_count = len(files) 929 file_count = len(files)
863 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) 930 dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
864 for h, _ in host_device_tuples) 931 for h, _ in host_device_tuples)
865 dir_file_count = 0 932 dir_file_count = 0
866 for h, _ in host_device_tuples: 933 for h, _ in host_device_tuples:
867 if os.path.isdir(h): 934 if os.path.isdir(h):
868 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h)) 935 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h))
869 else: 936 else:
870 dir_file_count += 1 937 dir_file_count += 1
(...skipping 10 matching lines...) Expand all
881 dir_push_duration < zip_duration or not self._commands_installed): 948 dir_push_duration < zip_duration or not self._commands_installed):
882 self._PushChangedFilesIndividually(host_device_tuples) 949 self._PushChangedFilesIndividually(host_device_tuples)
883 elif push_duration < zip_duration or not self._commands_installed: 950 elif push_duration < zip_duration or not self._commands_installed:
884 self._PushChangedFilesIndividually(files) 951 self._PushChangedFilesIndividually(files)
885 else: 952 else:
886 self._PushChangedFilesZipped(files) 953 self._PushChangedFilesZipped(files)
887 self.RunShellCommand( 954 self.RunShellCommand(
888 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], 955 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
889 as_root=True, check_return=True) 956 as_root=True, check_return=True)
890 957
891 def _GetChangedFilesImpl(self, host_path, device_path):
892 real_host_path = os.path.realpath(host_path)
893 try:
894 real_device_path = self.RunShellCommand(
895 ['realpath', device_path], single_line=True, check_return=True)
896 except device_errors.CommandFailedError:
897 real_device_path = None
898 if not real_device_path:
899 return [(host_path, device_path)]
900
901 try:
902 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
903 device_paths_to_md5 = (
904 real_device_path if os.path.isfile(real_host_path)
905 else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path))
906 for p in host_checksums.iterkeys()))
907 device_checksums = md5sum.CalculateDeviceMd5Sums(
908 device_paths_to_md5, self)
909 except EnvironmentError as e:
910 logging.warning('Error calculating md5: %s', e)
911 return [(host_path, device_path)]
912
913 if os.path.isfile(host_path):
914 host_checksum = host_checksums.get(real_host_path)
915 device_checksum = device_checksums.get(real_device_path)
916 if host_checksum != device_checksum:
917 return [(host_path, device_path)]
918 else:
919 return []
920 else:
921 to_push = []
922 for host_abs_path, host_checksum in host_checksums.iteritems():
923 device_abs_path = '%s/%s' % (
924 real_device_path, os.path.relpath(host_abs_path, real_host_path))
925 if (device_checksums.get(device_abs_path) != host_checksum):
926 to_push.append((host_abs_path, device_abs_path))
927 return to_push
928
929 def _InstallCommands(self): 958 def _InstallCommands(self):
930 if self._commands_installed is None: 959 if self._commands_installed is None:
931 try: 960 try:
932 if not install_commands.Installed(self): 961 if not install_commands.Installed(self):
933 install_commands.InstallCommands(self) 962 install_commands.InstallCommands(self)
934 self._commands_installed = True 963 self._commands_installed = True
935 except Exception as e: 964 except Exception as e:
936 logging.warning('unzip not available: %s' % str(e)) 965 logging.warning('unzip not available: %s' % str(e))
937 self._commands_installed = False 966 self._commands_installed = False
938 967
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 blacklist = device_blacklist.ReadBlacklist() 1630 blacklist = device_blacklist.ReadBlacklist()
1602 def blacklisted(adb): 1631 def blacklisted(adb):
1603 if adb.GetDeviceSerial() in blacklist: 1632 if adb.GetDeviceSerial() in blacklist:
1604 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial()) 1633 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial())
1605 return True 1634 return True
1606 return False 1635 return False
1607 1636
1608 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices() 1637 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices()
1609 if not blacklisted(adb)] 1638 if not blacklisted(adb)]
1610 1639
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698