Revert of Migrate device utils WriteFile to AdbWrapper (patchset #5 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:
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()
|
||||
|
Reference in New Issue
Block a user