0

Revert of Migrate device utils WriteFile to AdbWrapper (patchset id:80001 of https://codereview.chromium.org/715853002/)

Reason for revert:
Looks like this broke most of the perf tests on Nexus 4. Example log:

http://build.chromium.org/p/chromium.perf/builders/Android%20Nexus4%20Perf/builds/1711/steps/rasterize_and_record_micro.polymer/logs/stdio

Original issue's description:
> Migrate device utils WriteFile to AdbWrapper
>
> Also merged the functionality of WriteFile and WriteTextFile into a
> single method.
>
> BUG=267773
>
> Committed: https://crrev.com/6de48323f78311342108fda8b2f59ba3848eea81
> Cr-Commit-Position: refs/heads/master@{#303902}

TBR=jbudorick@chromium.org,perezju@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=267773

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

Cr-Commit-Position: refs/heads/master@{#304017}
This commit is contained in:
skyostil
2014-11-13 04:00:59 -08:00
committed by Commit bot
parent 382c20799b
commit 1ce3031cf7
4 changed files with 165 additions and 99 deletions
build/android/pylib/device
tools/telemetry/telemetry/core/backends/chrome

@ -41,7 +41,7 @@ def InstallCommands(device):
shell_command = _SHELL_COMMAND_FORMAT % (
constants.TEST_EXECUTABLE_DIR, main_class)
shell_file = '%s/%s' % (BIN_DIR, command)
device.WriteFile(shell_file, shell_command)
device.WriteTextFile(shell_file, shell_command)
device.RunShellCommand(
['chmod', '755', shell_file], check_return=True)

@ -24,7 +24,6 @@ from pylib.device import decorators
from pylib.device import device_errors
from pylib.device.commands import install_commands
from pylib.utils import apk_helper
from pylib.utils import device_temp_file
from pylib.utils import host_utils
from pylib.utils import parallelizer
from pylib.utils import timeout_retry
@ -430,14 +429,13 @@ class DeviceUtils(object):
if not isinstance(cmd, basestring):
cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd)
if as_root and self.NeedsSU():
cmd = 'su -c %s' % cmd
if env:
env = ' '.join(env_quote(k, v) for k, v in env.iteritems())
cmd = '%s %s' % (env, cmd)
if cwd:
cmd = 'cd %s && %s' % (cmd_helper.SingleQuote(cwd), cmd)
if as_root and self.NeedsSU():
# "su -c sh -c" allows using shell features in |cmd|
cmd = 'su -c sh -c %s' % cmd_helper.SingleQuote(cmd)
if timeout is None:
timeout = self._default_timeout
@ -884,19 +882,16 @@ class DeviceUtils(object):
return self.old_interface.GetFileContents(device_path)
@decorators.WithTimeoutAndRetriesFromInstance()
def WriteFile(self, device_path, contents, as_root=False, force_push=False,
timeout=None, retries=None):
def WriteFile(self, device_path, contents, as_root=False, timeout=None,
retries=None):
"""Writes |contents| to a file on the device.
Args:
device_path: A string containing the absolute path to the file to write
on the device.
on the device.
contents: A string containing the data to write to the device.
as_root: A boolean indicating whether the write should be executed with
root privileges (if available).
force_push: A boolean indicating whether to force the operation to be
performed by pushing a file to the device. The default is, when the
contents are short, to pass the contents using a shell script instead.
root privileges.
timeout: timeout in seconds
retries: number of retries
@ -905,24 +900,39 @@ class DeviceUtils(object):
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
if len(contents) < 512 and not force_push:
cmd = 'echo -n %s > %s' % (cmd_helper.SingleQuote(contents),
cmd_helper.SingleQuote(device_path))
self.RunShellCommand(cmd, as_root=as_root, check_return=True)
if as_root:
if not self.old_interface.CanAccessProtectedFileContents():
raise device_errors.CommandFailedError(
'Cannot write to %s with root privileges.' % device_path)
self.old_interface.SetProtectedFileContents(device_path, contents)
else:
with tempfile.NamedTemporaryFile() as host_temp:
host_temp.write(contents)
host_temp.flush()
if as_root and self.NeedsSU():
with device_temp_file.DeviceTempFile(self) as device_temp:
self.adb.Push(host_temp.name, device_temp.name)
# Here we need 'cp' rather than 'mv' because the temp and
# destination files might be on different file systems (e.g.
# on internal storage and an external sd card)
self.RunShellCommand(['cp', device_temp.name, device_path],
as_root=True, check_return=True)
else:
self.adb.Push(host_temp.name, device_path)
self.old_interface.SetFileContents(device_path, contents)
@decorators.WithTimeoutAndRetriesFromInstance()
def WriteTextFile(self, device_path, text, as_root=False, timeout=None,
retries=None):
"""Writes |text| to a file on the device.
Assuming that |text| is a small string, this is typically more efficient
than |WriteFile|, as no files are pushed into the device.
Args:
device_path: A string containing the absolute path to the file to write
on the device.
text: A short string of text to write to the file on the device.
as_root: A boolean indicating whether the write should be executed with
root privileges.
timeout: timeout in seconds
retries: number of retries
Raises:
CommandFailedError if the file could not be written on the device.
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
cmd = 'echo %s > %s' % (cmd_helper.SingleQuote(text),
cmd_helper.SingleQuote(device_path))
self.RunShellCommand(cmd, as_root=as_root, check_return=True)
@decorators.WithTimeoutAndRetriesFromInstance()
def Ls(self, device_path, timeout=None, retries=None):

@ -67,19 +67,6 @@ class DeviceUtilsTest(unittest.TestCase):
self.assertIsNone(d.old_interface.GetDevice())
class MockTempFile(object):
def __init__(self, name='/tmp/some/file'):
self.file = mock.MagicMock(spec=file)
self.file.name = name
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
pass
class _PatchedFunction(object):
def __init__(self, patched=None, mocked=None):
self.patched = patched
@ -627,7 +614,7 @@ class DeviceUtilsRunShellCommandTest(DeviceUtilsNewImplTest):
def testRunShellCommand_withSu(self):
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'setprop service.adb.root 0'"), '')):
(self.call.adb.Shell('su -c setprop service.adb.root 0'), '')):
self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
def testRunShellCommand_manyLines(self):
@ -727,7 +714,7 @@ class DeviceUtilsKillAllTest(DeviceUtilsNewImplTest):
'USER PID PPID VSIZE RSS WCHAN PC NAME\n'
'u0_a1 1234 174 123456 54321 ffffffff 456789ab some.process\n'),
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')):
(self.call.adb.Shell('su -c kill -9 1234'), '')):
self.assertEquals(1,
self.device.KillAll('some.process', as_root=True))
@ -1203,67 +1190,134 @@ class DeviceUtilsReadFileTest(DeviceUtilsOldImplTest):
as_root=True)
class DeviceUtilsWriteFileTest(DeviceUtilsNewImplTest):
class DeviceUtilsWriteFileTest(DeviceUtilsOldImplTest):
def testWriteFile_withPush(self):
tmp_host = MockTempFile('/tmp/file/on.host')
contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(), tmp_host),
self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')):
self.device.WriteFile('/path/to/device/file', contents)
tmp_host.file.write.assert_called_once_with(contents)
def testWriteFile_basic(self):
mock_file = mock.MagicMock(spec=file)
mock_file.name = '/tmp/file/to.be.pushed'
mock_file.__enter__.return_value = mock_file
with mock.patch('tempfile.NamedTemporaryFile',
return_value=mock_file):
with self.assertCalls(
'adb -s 0123456789abcdef push '
'/tmp/file/to.be.pushed /test/file/written.to.device',
'100 B/s (100 bytes in 1.000s)\r\n'):
self.device.WriteFile('/test/file/written.to.device',
'new test file contents')
mock_file.write.assert_called_once_with('new test file contents')
def testWriteFile_withPushForced(self):
tmp_host = MockTempFile('/tmp/file/on.host')
contents = 'tiny contents'
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(), tmp_host),
self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')):
self.device.WriteFile('/path/to/device/file', contents, force_push=True)
tmp_host.file.write.assert_called_once_with(contents)
def testWriteFile_asRoot_withRoot(self):
self.device.old_interface._external_storage = '/fake/storage/path'
self.device.old_interface._privileged_command_runner = (
self.device.old_interface.RunShellCommand)
self.device.old_interface._protected_file_access_method_initialized = True
def testWriteFile_withPushAndSU(self):
tmp_host = MockTempFile('/tmp/file/on.host')
contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(), tmp_host),
(self.call.device.NeedsSU(), True),
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.device),
MockTempFile('/external/path/tmp/on.device')),
self.call.adb.Push('/tmp/file/on.host', '/external/path/tmp/on.device'),
self.call.device.RunShellCommand(
['cp', '/external/path/tmp/on.device', '/path/to/device/file'],
as_root=True, check_return=True)):
self.device.WriteFile('/path/to/device/file', contents, as_root=True)
tmp_host.file.write.assert_called_once_with(contents)
mock_file = mock.MagicMock(spec=file)
mock_file.name = '/tmp/file/to.be.pushed'
mock_file.__enter__.return_value = mock_file
with mock.patch('tempfile.NamedTemporaryFile',
return_value=mock_file):
with self.assertCallsSequence(
cmd_ret=[
# Create temporary contents file
(r"adb -s 0123456789abcdef shell "
"'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
"echo \$\?'",
'1\r\n'),
# Create temporary script file
(r"adb -s 0123456789abcdef shell "
"'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
"echo \$\?'",
'1\r\n'),
# Set contents file
(r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
'/fake/storage/path/temp_file-\d+\d+',
'100 B/s (100 bytes in 1.000s)\r\n'),
# Set script file
(r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
'/fake/storage/path/temp_file-\d+\d+',
'100 B/s (100 bytes in 1.000s)\r\n'),
# Call script
(r"adb -s 0123456789abcdef shell "
"'sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
# Remove device temporaries
(r"adb -s 0123456789abcdef shell "
"'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
(r"adb -s 0123456789abcdef shell "
"'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
comp=re.match):
self.device.WriteFile('/test/file/written.to.device',
'new test file contents', as_root=True)
def testWriteFile_withPush_rejected(self):
tmp_host = MockTempFile('/tmp/file/on.host')
contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
with self.assertCalls(
(mock.call.tempfile.NamedTemporaryFile(), tmp_host),
(self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file'),
self.CommandError())):
with self.assertRaises(device_errors.CommandFailedError):
self.device.WriteFile('/path/to/device/file', contents)
def testWriteFile_asRoot_withSu(self):
self.device.old_interface._external_storage = '/fake/storage/path'
self.device.old_interface._privileged_command_runner = (
self.device.old_interface.RunShellCommandWithSU)
self.device.old_interface._protected_file_access_method_initialized = True
def testWriteFile_withEcho(self):
with self.assertCall(self.call.adb.Shell(
"echo -n the.contents > /test/file/to.write"), ''):
self.device.WriteFile('/test/file/to.write', 'the.contents')
mock_file = mock.MagicMock(spec=file)
mock_file.name = '/tmp/file/to.be.pushed'
mock_file.__enter__.return_value = mock_file
with mock.patch('tempfile.NamedTemporaryFile',
return_value=mock_file):
with self.assertCallsSequence(
cmd_ret=[
# Create temporary contents file
(r"adb -s 0123456789abcdef shell "
"'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
"echo \$\?'",
'1\r\n'),
# Create temporary script file
(r"adb -s 0123456789abcdef shell "
"'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
"echo \$\?'",
'1\r\n'),
# Set contents file
(r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
'/fake/storage/path/temp_file-\d+\d+',
'100 B/s (100 bytes in 1.000s)\r\n'),
# Set script file
(r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
'/fake/storage/path/temp_file-\d+\d+',
'100 B/s (100 bytes in 1.000s)\r\n'),
# Call script
(r"adb -s 0123456789abcdef shell "
"'su -c sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
# Remove device temporaries
(r"adb -s 0123456789abcdef shell "
"'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
(r"adb -s 0123456789abcdef shell "
"'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
comp=re.match):
self.device.WriteFile('/test/file/written.to.device',
'new test file contents', as_root=True)
def testWriteFile_withEchoAndQuotes(self):
with self.assertCall(self.call.adb.Shell(
"echo -n 'the contents' > '/test/file/to write'"), ''):
self.device.WriteFile('/test/file/to write', 'the contents')
def testWriteFile_asRoot_rejected(self):
self.device.old_interface._privileged_command_runner = None
self.device.old_interface._protected_file_access_method_initialized = True
with self.assertRaises(device_errors.CommandFailedError):
self.device.WriteFile('/test/file/no.permissions.to.write',
'new test file contents', as_root=True)
def testWriteFile_withEchoAndSU(self):
class DeviceUtilsWriteTextFileTest(DeviceUtilsNewImplTest):
def testWriteTextFileTest_basic(self):
with self.assertCall(
self.call.adb.Shell('echo some.string > /test/file/to.write'), ''):
self.device.WriteTextFile('/test/file/to.write', 'some.string')
def testWriteTextFileTest_quoted(self):
with self.assertCall(
self.call.adb.Shell("echo 'some other string' > '/test/file/to write'"),
''):
self.device.WriteTextFile('/test/file/to write', 'some other string')
def testWriteTextFileTest_withSU(self):
with self.assertCalls(
(self.call.device.NeedsSU(), True),
(self.call.adb.Shell("su -c sh -c 'echo -n contents > /test/file'"),
'')):
self.device.WriteFile('/test/file', 'contents', as_root=True)
(self.call.adb.Shell('su -c echo string > /test/file'), '')):
self.device.WriteTextFile('/test/file', 'string', as_root=True)
class DeviceUtilsLsTest(DeviceUtilsOldImplTest):

@ -217,6 +217,7 @@ class AndroidBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
content = ' '.join(QuoteIfNeeded(arg) for arg in args)
cmdline_file = self._backend_settings.GetCommandLineFile(
self._adb.IsUserBuild())
as_root = self._adb.device().old_interface.CanAccessProtectedFileContents()
try:
# Save the current command line to restore later, except if it appears to
@ -226,7 +227,7 @@ class AndroidBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
self._saved_cmdline = ''.join(self._adb.device().ReadFile(cmdline_file))
if '--host-resolver-rules' in self._saved_cmdline:
self._saved_cmdline = ''
self._adb.device().WriteFile(cmdline_file, content, as_root=True)
self._adb.device().WriteTextFile(cmdline_file, content, as_root=as_root)
except device_errors.CommandFailedError:
logging.critical('Cannot set Chrome command line. '
'Fix this by flashing to a userdebug build.')
@ -235,8 +236,9 @@ class AndroidBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
def _RestoreCommandLine(self):
cmdline_file = self._backend_settings.GetCommandLineFile(
self._adb.IsUserBuild())
self._adb.device().WriteFile(cmdline_file, self._saved_cmdline,
as_root=True)
as_root = self._adb.device().old_interface.CanAccessProtectedFileContents()
self._adb.device().WriteTextFile(cmdline_file, self._saved_cmdline,
as_root=as_root)
def Start(self):
self._SetUpCommandLine()