| Index: build/android/pylib/device/device_utils_test.py | 
| diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py | 
| index 65547d420950ee7e661d4a820c6455fed4a2a935..8d78b2d3f99b72ee9cd9751bec37cdfee06da706 100755 | 
| --- a/build/android/pylib/device/device_utils_test.py | 
| +++ b/build/android/pylib/device/device_utils_test.py | 
| @@ -67,6 +67,19 @@ 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 | 
| @@ -215,9 +228,14 @@ class DeviceUtilsOldImplTest(unittest.TestCase): | 
| return type(self).AndroidCommandsCalls(self, cmd_ret, comp) | 
|  | 
| def setUp(self): | 
| +    self._get_adb_path_patch = mock.patch('pylib.constants.GetAdbPath', | 
| +                                          mock.Mock(return_value='adb')) | 
| +    self._get_adb_path_patch.start() | 
| self.device = device_utils.DeviceUtils( | 
| '0123456789abcdef', default_timeout=1, default_retries=0) | 
|  | 
| +  def tearDown(self): | 
| +    self._get_adb_path_patch.stop() | 
|  | 
| class DeviceUtilsNewImplTest(mock_calls.TestCase): | 
|  | 
| @@ -497,9 +515,6 @@ class DeviceUtilsInstallTest(DeviceUtilsOldImplTest): | 
| def mockGetFilesChanged(host_path, device_path, ignore_filenames): | 
| return [(host_path, device_path)] | 
|  | 
| -    # Pylint raises a false positive "operator not preceded by a space" | 
| -    # warning below. | 
| -    # pylint: disable=C0322 | 
| with mock.patch('os.path.isfile', return_value=True), ( | 
| mock.patch('os.path.exists', return_value=True)), ( | 
| mock.patch('pylib.utils.apk_helper.GetPackageName', | 
| @@ -508,7 +523,6 @@ class DeviceUtilsInstallTest(DeviceUtilsOldImplTest): | 
| return_value='/fake/test/out')), ( | 
| mock.patch('pylib.android_commands.AndroidCommands.GetFilesChanged', | 
| side_effect=mockGetFilesChanged)): | 
| -    # pylint: enable=C0322 | 
| with self.assertCallsSequence([ | 
| ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'", | 
| 'package:/fake/data/app/this.is.a.test.package.apk\r\n'), | 
| @@ -523,9 +537,6 @@ class DeviceUtilsInstallTest(DeviceUtilsOldImplTest): | 
| def mockGetFilesChanged(host_path, device_path, ignore_filenames): | 
| return [(host_path, device_path)] | 
|  | 
| -    # Pylint raises a false positive "operator not preceded by a space" | 
| -    # warning below. | 
| -    # pylint: disable=C0322 | 
| with mock.patch('os.path.isfile', return_value=True), ( | 
| mock.patch('pylib.utils.apk_helper.GetPackageName', | 
| return_value='this.is.a.test.package')), ( | 
| @@ -533,7 +544,6 @@ class DeviceUtilsInstallTest(DeviceUtilsOldImplTest): | 
| return_value='/fake/test/out')), ( | 
| mock.patch('pylib.android_commands.AndroidCommands.GetFilesChanged', | 
| side_effect=mockGetFilesChanged)): | 
| -    # pylint: enable=C0322 | 
| with self.assertCallsSequence([ | 
| ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'", | 
| 'package:/fake/data/app/this.is.a.test.package.apk\r\n'), | 
| @@ -614,7 +624,7 @@ class DeviceUtilsRunShellCommandTest(DeviceUtilsNewImplTest): | 
| def testRunShellCommand_withSu(self): | 
| with self.assertCalls( | 
| (self.call.device.NeedsSU(), True), | 
| -        (self.call.adb.Shell('su -c setprop service.adb.root 0'), '')): | 
| +        (self.call.adb.Shell("su -c sh -c 'setprop service.adb.root 0'"), '')): | 
| self.device.RunShellCommand('setprop service.adb.root 0', as_root=True) | 
|  | 
| def testRunShellCommand_manyLines(self): | 
| @@ -714,7 +724,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 kill -9 1234'), '')): | 
| +        (self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')): | 
| self.assertEquals(1, | 
| self.device.KillAll('some.process', as_root=True)) | 
|  | 
| @@ -1190,134 +1200,67 @@ class DeviceUtilsReadFileTest(DeviceUtilsOldImplTest): | 
| as_root=True) | 
|  | 
|  | 
| -class DeviceUtilsWriteFileTest(DeviceUtilsOldImplTest): | 
| - | 
| -  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_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 | 
| - | 
| -    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_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 | 
| - | 
| -    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_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) | 
| - | 
| +class DeviceUtilsWriteFileTest(DeviceUtilsNewImplTest): | 
|  | 
| -class DeviceUtilsWriteTextFileTest(DeviceUtilsNewImplTest): | 
| +  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_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_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) | 
| + | 
| +  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 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 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') | 
|  | 
| -  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 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 testWriteTextFileTest_withSU(self): | 
| +  def testWriteFile_withEchoAndSU(self): | 
| with self.assertCalls( | 
| (self.call.device.NeedsSU(), True), | 
| -        (self.call.adb.Shell('su -c echo string > /test/file'), '')): | 
| -      self.device.WriteTextFile('/test/file', 'string', as_root=True) | 
| +        (self.call.adb.Shell("su -c sh -c 'echo -n contents > /test/file'"), | 
| +         '')): | 
| +      self.device.WriteFile('/test/file', 'contents', as_root=True) | 
|  | 
|  | 
| class DeviceUtilsLsTest(DeviceUtilsOldImplTest): | 
|  |