Make GetFilesChanged work with copied files.

BUG=358028

Review URL: https://codereview.chromium.org/219363006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261466 0039d316-1c4b-4281-b951-d872f2087c98
parent 999fe8c8
...@@ -964,31 +964,40 @@ class AndroidCommands(object): ...@@ -964,31 +964,40 @@ class AndroidCommands(object):
host_hash_tuples, device_hash_tuples = self._RunMd5Sum( host_hash_tuples, device_hash_tuples = self._RunMd5Sum(
real_host_path, real_device_path) real_host_path, real_device_path)
# Ignore extra files on the device.
if not ignore_filenames:
host_files = [os.path.relpath(os.path.normpath(p.path),
real_host_path) for p in host_hash_tuples]
def HostHas(fname):
return any(path in fname for path in host_files)
device_hash_tuples = [h for h in device_hash_tuples if HostHas(h.path)]
if len(host_hash_tuples) > len(device_hash_tuples): if len(host_hash_tuples) > len(device_hash_tuples):
logging.info('%s files do not exist on the device' % logging.info('%s files do not exist on the device' %
(len(host_hash_tuples) - len(device_hash_tuples))) (len(host_hash_tuples) - len(device_hash_tuples)))
# Constructs the target device path from a given host path. Don't use when host_rel = [(os.path.relpath(os.path.normpath(t.path), real_host_path),
# only a single file is given as the base name given in device_path may t.hash)
# differ from that in host_path. for t in host_hash_tuples]
def HostToDevicePath(host_file_path):
return os.path.join(device_path, os.path.relpath(host_file_path, if os.path.isdir(real_host_path):
real_host_path)) def RelToRealPaths(rel_path):
return (os.path.join(real_host_path, rel_path),
device_hashes = [h.hash for h in device_hash_tuples] os.path.join(real_device_path, rel_path))
return [(t.path, HostToDevicePath(t.path) if else:
os.path.isdir(real_host_path) else real_device_path) assert len(host_rel) == 1
for t in host_hash_tuples if t.hash not in device_hashes] def RelToRealPaths(_):
return (real_host_path, real_device_path)
if ignore_filenames:
# If we are ignoring file names, then we want to push any file for which
# a file with an equivalent MD5 sum does not exist on the device.
device_hashes = set([h.hash for h in device_hash_tuples])
ShouldPush = lambda p, h: h not in device_hashes
else:
# Otherwise, we want to push any file on the host for which a file with
# an equivalent MD5 sum does not exist at the same relative path on the
# device.
device_rel = dict([(os.path.relpath(os.path.normpath(t.path),
real_device_path),
t.hash)
for t in device_hash_tuples])
ShouldPush = lambda p, h: p not in device_rel or h != device_rel[p]
return [RelToRealPaths(path) for path, host_hash in host_rel
if ShouldPush(path, host_hash)]
def PushIfNeeded(self, host_path, device_path): def PushIfNeeded(self, host_path, device_path):
"""Pushes |host_path| to |device_path|. """Pushes |host_path| to |device_path|.
......
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import shutil
import sys
import unittest
sys.path.append(os.path.join(os.pardir, os.path.dirname(__file__)))
from pylib import android_commands
# pylint: disable=W0212,W0702
class TestGetFilesChanged(unittest.TestCase):
def setUp(self):
if not os.getenv('BUILDTYPE'):
os.environ['BUILDTYPE'] = 'Debug'
devices = android_commands.GetAttachedDevices()
self.assertGreater(len(devices), 0, 'No device attached!')
self.ac = android_commands.AndroidCommands(device=devices[0])
self.host_data_dir = os.path.realpath('test_push_data')
self.device_data_dir = '%s/test_push_data' % (
self.ac.RunShellCommand('realpath %s' %
self.ac.GetExternalStorage())[0])
os.mkdir(self.host_data_dir)
for i in xrange(1, 10):
with open('%s/%d.txt' % (self.host_data_dir, i), 'w') as f:
f.write('file #%d' % i)
self.ac.RunShellCommand('mkdir %s' % self.device_data_dir)
def testGetFilesChangedAllNeeded(self):
""" Tests GetFilesChanged when none of the files are on the device.
"""
expected = [('%s/%d.txt' % (self.host_data_dir, i),
'%s/%d.txt' % (self.device_data_dir, i))
for i in xrange(1, 10)]
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def testGetFilesChangedSomeIdentical(self):
""" Tests GetFilesChanged when some of the files are on the device.
"""
for i in xrange(1, 5):
self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
self.device_data_dir)
expected = [('%s/%d.txt' % (self.host_data_dir, i),
'%s/%d.txt' % (self.device_data_dir, i))
for i in xrange(5, 10)]
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def testGetFilesChangedAllIdentical(self):
""" Tests GetFilesChanged when all of the files are on the device.
"""
for i in xrange(1, 10):
self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
self.device_data_dir)
expected = []
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def testGetFilesChangedRename(self):
""" Tests GetFilesChanged when one of the files has been renamed.
This tests both with and without the ignore_filenames flag set.
"""
for i in xrange(5, 10):
self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
self.device_data_dir)
os.rename('%s/5.txt' % (self.host_data_dir),
'%s/99.txt' % (self.host_data_dir))
expected = [('%s/%d.txt' % (self.host_data_dir, i),
'%s/%d.txt' % (self.device_data_dir, i))
for i in xrange(1, 5)]
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir,
ignore_filenames=True)
self.assertSequenceEqual(expected, actual)
expected.append(('%s/99.txt' % self.host_data_dir,
'%s/99.txt' % self.device_data_dir))
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def testGetFilesChangedCopy(self):
""" Tests GetFilesChanged when one of the files has been copied.
This tests both with and without the ignore_filenames flag set.
"""
for i in xrange(5, 10):
self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
self.device_data_dir)
shutil.copy('%s/5.txt' % self.host_data_dir,
'%s/99.txt' % self.host_data_dir)
expected = [('%s/%d.txt' % (self.host_data_dir, i),
'%s/%d.txt' % (self.device_data_dir, i))
for i in xrange(1, 5)]
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir,
ignore_filenames=True)
self.assertSequenceEqual(expected, actual)
expected.append(('%s/99.txt' % self.host_data_dir,
'%s/99.txt' % self.device_data_dir))
actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def testGetFilesChangedIndividual(self):
""" Tests GetFilesChanged when provided one file.
"""
expected = [('%s/1.txt' % self.host_data_dir,
'%s/1.txt' % self.device_data_dir)]
actual = self.ac.GetFilesChanged('%s/1.txt' % self.host_data_dir,
'%s/1.txt' % self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def testGetFilesChangedFileToDirectory(self):
""" Tests GetFilesChanged when provided a file from the host and a
directory on the device.
"""
expected = [('%s/1.txt' % self.host_data_dir,
'%s' % self.device_data_dir)]
actual = self.ac.GetFilesChanged('%s/1.txt' % self.host_data_dir,
'%s' % self.device_data_dir)
self.assertSequenceEqual(expected, actual)
def tearDown(self):
try:
shutil.rmtree(self.host_data_dir)
self.ac.RunShellCommand('rm -rf %s' % self.device_data_dir)
except:
pass
if __name__ == '__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment