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

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.
837 839
840 When a directory is pushed, it is traversed recursively on the host and
841 all files in it are pushed to the device as needed.
842 Additionally, if delete_device_stale option is True,
843 files that exist on the device but don't exist on the host are deleted.
844
838 Args: 845 Args:
839 host_device_tuples: A list of (host_path, device_path) tuples, where 846 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 847 |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 848 that should be minimially pushed to the device, and |device_path| is
842 an absolute path of the destination on the device. 849 an absolute path of the destination on the device.
843 timeout: timeout in seconds 850 timeout: timeout in seconds
844 retries: number of retries 851 retries: number of retries
852 delete_device_stale: option to delete stale files on device
845 853
846 Raises: 854 Raises:
847 CommandFailedError on failure. 855 CommandFailedError on failure.
848 CommandTimeoutError on timeout. 856 CommandTimeoutError on timeout.
849 DeviceUnreachableError on missing device. 857 DeviceUnreachableError on missing device.
850 """ 858 """
851 859
852 files = [] 860 all_changed_files = []
861 all_stale_files = []
853 for h, d in host_device_tuples: 862 for h, d in host_device_tuples:
854 if os.path.isdir(h): 863 if os.path.isdir(h):
855 self.RunShellCommand(['mkdir', '-p', d], check_return=True) 864 self.RunShellCommand(['mkdir', '-p', d], check_return=True)
856 files += self._GetChangedFilesImpl(h, d) 865 (changed_files, stale_files) = self._GetChangedAndStaleFiles(h, d)
866 all_changed_files += changed_files
867 all_stale_files += stale_files
857 868
858 if not files: 869 if delete_device_stale:
870 self.RunShellCommand(['rm', '-f'] + all_stale_files,
871 check_return=True)
872
873 if not all_changed_files:
859 return 874 return
860 875
876 self._PushFilesImpl(host_device_tuples, all_changed_files)
877
878 def _GetChangedAndStaleFiles(self, host_path, device_path):
879 """Get files to push and delete
880
881 Args:
882 host_path: an absolute path of a file or directory on the host
883 device_path: an absolute path of a file or directory on the device
884
885 Returns:
886 a two-element tuple
887 1st element: a list of (host_files_path, device_files_path) tuples to push
888 2nd element: a list of stale files under device_path
889 """
890 real_host_path = os.path.realpath(host_path)
891 try:
892 real_device_path = self.RunShellCommand(
893 ['realpath', device_path], single_line=True, check_return=True)
894 except device_errors.CommandFailedError:
895 real_device_path = None
896 if not real_device_path:
897 return ([(host_path, device_path)], [])
898
899 try:
900 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
901 device_checksums = md5sum.CalculateDeviceMd5Sums(
902 [real_device_path], self)
903 except EnvironmentError as e:
904 logging.warning('Error calculating md5: %s', e)
905 return ([(host_path, device_path)], [])
906
907 if os.path.isfile(host_path):
908 host_checksum = host_checksums.get(real_host_path)
909 device_checksum = device_checksums.get(real_device_path)
910 if host_checksum != device_checksum:
911 return ([(host_path, device_path)], [])
912 else:
913 return ([], [])
914 else:
915 to_push = []
916 for host_abs_path, host_checksum in host_checksums.iteritems():
917 device_abs_path = '%s/%s' % (
918 real_device_path, os.path.relpath(host_abs_path, real_host_path))
919 device_checksum = device_checksums.pop(device_abs_path, None)
920 if device_checksum != host_checksum:
921 to_push.append((host_abs_path, device_abs_path))
922 to_delete = device_checksums.keys()
923 return (to_push, to_delete)
924
925 def _PushFilesImpl(self, host_device_tuples, files):
861 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) 926 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
862 file_count = len(files) 927 file_count = len(files)
863 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) 928 dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
864 for h, _ in host_device_tuples) 929 for h, _ in host_device_tuples)
865 dir_file_count = 0 930 dir_file_count = 0
866 for h, _ in host_device_tuples: 931 for h, _ in host_device_tuples:
867 if os.path.isdir(h): 932 if os.path.isdir(h):
868 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h)) 933 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h))
869 else: 934 else:
870 dir_file_count += 1 935 dir_file_count += 1
(...skipping 10 matching lines...) Expand all
881 dir_push_duration < zip_duration or not self._commands_installed): 946 dir_push_duration < zip_duration or not self._commands_installed):
882 self._PushChangedFilesIndividually(host_device_tuples) 947 self._PushChangedFilesIndividually(host_device_tuples)
883 elif push_duration < zip_duration or not self._commands_installed: 948 elif push_duration < zip_duration or not self._commands_installed:
884 self._PushChangedFilesIndividually(files) 949 self._PushChangedFilesIndividually(files)
885 else: 950 else:
886 self._PushChangedFilesZipped(files) 951 self._PushChangedFilesZipped(files)
887 self.RunShellCommand( 952 self.RunShellCommand(
888 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], 953 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
889 as_root=True, check_return=True) 954 as_root=True, check_return=True)
890 955
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): 956 def _InstallCommands(self):
930 if self._commands_installed is None: 957 if self._commands_installed is None:
931 try: 958 try:
932 if not install_commands.Installed(self): 959 if not install_commands.Installed(self):
933 install_commands.InstallCommands(self) 960 install_commands.InstallCommands(self)
934 self._commands_installed = True 961 self._commands_installed = True
935 except Exception as e: 962 except Exception as e:
936 logging.warning('unzip not available: %s' % str(e)) 963 logging.warning('unzip not available: %s' % str(e))
937 self._commands_installed = False 964 self._commands_installed = False
938 965
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 blacklist = device_blacklist.ReadBlacklist() 1628 blacklist = device_blacklist.ReadBlacklist()
1602 def blacklisted(adb): 1629 def blacklisted(adb):
1603 if adb.GetDeviceSerial() in blacklist: 1630 if adb.GetDeviceSerial() in blacklist:
1604 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial()) 1631 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial())
1605 return True 1632 return True
1606 return False 1633 return False
1607 1634
1608 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices() 1635 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices()
1609 if not blacklisted(adb)] 1636 if not blacklisted(adb)]
1610 1637
OLDNEW
« no previous file with comments | « build/android/pylib/base/base_setup.py ('k') | build/android/pylib/device/device_utils_device_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698