xref: /aosp_15_r20/external/chromium-trace/catapult/devil/devil/android/md5sum_test.py (revision 1fa4b3da657c0e9ad43c0220bacf9731820715a5)
1#!/usr/bin/env python
2# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import os
7import unittest
8
9from devil import devil_env
10from devil.android import device_errors
11from devil.android import md5sum
12
13with devil_env.SysPath(devil_env.PYMOCK_PATH):
14  import mock  # pylint: disable=import-error
15
16TEST_OUT_DIR = os.path.join('test', 'out', 'directory')
17HOST_MD5_EXECUTABLE = os.path.join(TEST_OUT_DIR, 'md5sum_bin_host')
18MD5_DIST = os.path.join(TEST_OUT_DIR, 'md5sum_dist')
19
20
21class Md5SumTest(unittest.TestCase):
22  def setUp(self):
23    mocked_attrs = {
24        'md5sum_host': HOST_MD5_EXECUTABLE,
25        'md5sum_device': MD5_DIST,
26    }
27    self._patchers = [
28        mock.patch(
29            'devil.devil_env._Environment.FetchPath',
30            mock.Mock(side_effect=lambda a, device=None: mocked_attrs[a])),
31        mock.patch('os.path.exists', new=mock.Mock(return_value=True)),
32    ]
33    for p in self._patchers:
34      p.start()
35
36  def tearDown(self):
37    for p in self._patchers:
38      p.stop()
39
40  def testCalculateHostMd5Sums_singlePath(self):
41    test_path = '/test/host/file.dat'
42    mock_get_cmd_output = mock.Mock(
43        return_value='0123456789abcdef')
44    with mock.patch(
45        'devil.utils.cmd_helper.GetCmdOutput', new=mock_get_cmd_output):
46      out = md5sum.CalculateHostMd5Sums(test_path)
47      self.assertEquals(1, len(out))
48      self.assertTrue('/test/host/file.dat' in out)
49      self.assertEquals('0123456789abcdef', out['/test/host/file.dat'])
50      mock_get_cmd_output.assert_called_once_with(
51          [HOST_MD5_EXECUTABLE, "-gz", mock.ANY])
52
53  def testCalculateHostMd5Sums_list(self):
54    test_paths = ['/test/host/file0.dat', '/test/host/file1.dat']
55    mock_get_cmd_output = mock.Mock(
56        return_value='0123456789abcdef\n123456789abcdef0\n')
57    with mock.patch(
58        'devil.utils.cmd_helper.GetCmdOutput', new=mock_get_cmd_output):
59      out = md5sum.CalculateHostMd5Sums(test_paths)
60      self.assertEquals(2, len(out))
61      self.assertTrue('/test/host/file0.dat' in out)
62      self.assertEquals('0123456789abcdef', out['/test/host/file0.dat'])
63      self.assertTrue('/test/host/file1.dat' in out)
64      self.assertEquals('123456789abcdef0', out['/test/host/file1.dat'])
65      mock_get_cmd_output.assert_called_once_with(
66          [HOST_MD5_EXECUTABLE, "-gz", mock.ANY])
67
68  def testCalculateDeviceMd5Sums_noPaths(self):
69    device = mock.NonCallableMock()
70    device.RunShellCommand = mock.Mock(side_effect=Exception())
71
72    out = md5sum.CalculateDeviceMd5Sums([], device)
73    self.assertEquals(0, len(out))
74
75  def testCalculateDeviceMd5Sums_singlePath(self):
76    test_path = '/storage/emulated/legacy/test/file.dat'
77
78    device = mock.NonCallableMock()
79    device_md5sum_output = ['0123456789abcdef',]
80    device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
81
82    with mock.patch('os.path.getsize', return_value=1337):
83      out = md5sum.CalculateDeviceMd5Sums(test_path, device)
84      self.assertEquals(1, len(out))
85      self.assertTrue('/storage/emulated/legacy/test/file.dat' in out)
86      self.assertEquals('0123456789abcdef',
87                        out['/storage/emulated/legacy/test/file.dat'])
88      self.assertEquals(1, len(device.RunShellCommand.call_args_list))
89
90  def testCalculateDeviceMd5Sums_list(self):
91    test_path = [
92        '/storage/emulated/legacy/test/file0.dat',
93        '/storage/emulated/legacy/test/file1.dat'
94    ]
95    device = mock.NonCallableMock()
96    device_md5sum_output = [
97        '0123456789abcdef',
98        '123456789abcdef0',
99    ]
100    device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
101
102    with mock.patch('os.path.getsize', return_value=1337):
103      out = md5sum.CalculateDeviceMd5Sums(test_path, device)
104      self.assertEquals(2, len(out))
105      self.assertTrue('/storage/emulated/legacy/test/file0.dat' in out)
106      self.assertEquals('0123456789abcdef',
107                        out['/storage/emulated/legacy/test/file0.dat'])
108      self.assertTrue('/storage/emulated/legacy/test/file1.dat' in out)
109      self.assertEquals('123456789abcdef0',
110                        out['/storage/emulated/legacy/test/file1.dat'])
111      self.assertEquals(1, len(device.RunShellCommand.call_args_list))
112
113  def testCalculateDeviceMd5Sums_generator(self):
114    test_path = ('/storage/emulated/legacy/test/file%d.dat' % n
115                 for n in range(0, 2))
116
117    device = mock.NonCallableMock()
118    device_md5sum_output = [
119        '0123456789abcdef',
120        '123456789abcdef0',
121    ]
122    device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
123
124    with mock.patch('os.path.getsize', return_value=1337):
125      out = md5sum.CalculateDeviceMd5Sums(test_path, device)
126      self.assertEquals(2, len(out))
127      self.assertTrue('/storage/emulated/legacy/test/file0.dat' in out)
128      self.assertEquals('0123456789abcdef',
129                        out['/storage/emulated/legacy/test/file0.dat'])
130      self.assertTrue('/storage/emulated/legacy/test/file1.dat' in out)
131      self.assertEquals('123456789abcdef0',
132                        out['/storage/emulated/legacy/test/file1.dat'])
133      self.assertEquals(1, len(device.RunShellCommand.call_args_list))
134
135  def testCalculateDeviceMd5Sums_singlePath_linkerWarning(self):
136    # See crbug/479966
137    test_path = '/storage/emulated/legacy/test/file.dat'
138
139    device = mock.NonCallableMock()
140    device_md5sum_output = [
141        'WARNING: linker: /data/local/tmp/md5sum/md5sum_bin: '
142        'unused DT entry: type 0x1d arg 0x15db',
143        'THIS_IS_NOT_A_VALID_CHECKSUM_ZZZ some random text',
144        '0123456789abcdef',
145    ]
146    device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
147
148    with mock.patch('os.path.getsize', return_value=1337):
149      out = md5sum.CalculateDeviceMd5Sums(test_path, device)
150      self.assertEquals(1, len(out))
151      self.assertTrue('/storage/emulated/legacy/test/file.dat' in out)
152      self.assertEquals('0123456789abcdef',
153                        out['/storage/emulated/legacy/test/file.dat'])
154      self.assertEquals(1, len(device.RunShellCommand.call_args_list))
155
156  def testCalculateDeviceMd5Sums_list_fileMissing(self):
157    test_path = [
158        '/storage/emulated/legacy/test/file0.dat',
159        '/storage/emulated/legacy/test/file1.dat'
160    ]
161    device = mock.NonCallableMock()
162    device_md5sum_output = [
163        '0123456789abcdef',
164        '[0819/203513:ERROR:md5sum.cc(25)] Could not open file asdf',
165        '',
166    ]
167    device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
168
169    with mock.patch('os.path.getsize', return_value=1337):
170      out = md5sum.CalculateDeviceMd5Sums(test_path, device)
171      self.assertEquals(1, len(out))
172      self.assertTrue('/storage/emulated/legacy/test/file0.dat' in out)
173      self.assertEquals('0123456789abcdef',
174                        out['/storage/emulated/legacy/test/file0.dat'])
175      self.assertEquals(1, len(device.RunShellCommand.call_args_list))
176
177  def testCalculateDeviceMd5Sums_requiresBinary(self):
178    test_path = '/storage/emulated/legacy/test/file.dat'
179
180    device = mock.NonCallableMock()
181    device.adb = mock.NonCallableMock()
182    device.adb.Push = mock.Mock()
183    device_md5sum_output = [
184        'WARNING: linker: /data/local/tmp/md5sum/md5sum_bin: '
185        'unused DT entry: type 0x1d arg 0x15db',
186        'THIS_IS_NOT_A_VALID_CHECKSUM_ZZZ some random text',
187        '0123456789abcdef',
188    ]
189    error = device_errors.AdbShellCommandFailedError('cmd', 'out', 2)
190    device.RunShellCommand = mock.Mock(
191        side_effect=(error, '', device_md5sum_output))
192
193    with mock.patch(
194        'os.path.isdir', return_value=True), (mock.patch(
195            'os.path.getsize', return_value=1337)):
196      out = md5sum.CalculateDeviceMd5Sums(test_path, device)
197      self.assertEquals(1, len(out))
198      self.assertTrue('/storage/emulated/legacy/test/file.dat' in out)
199      self.assertEquals('0123456789abcdef',
200                        out['/storage/emulated/legacy/test/file.dat'])
201      self.assertEquals(3, len(device.RunShellCommand.call_args_list))
202      device.adb.Push.assert_called_once_with('test/out/directory/md5sum_dist',
203                                              '/data/local/tmp/md5sum')
204
205
206if __name__ == '__main__':
207  unittest.main(verbosity=2)
208