xref: /aosp_15_r20/external/autotest/client/bin/local_host_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li#!/usr/bin/python3
2*9c5db199SXin Li
3*9c5db199SXin Liimport os
4*9c5db199SXin Liimport six
5*9c5db199SXin Liimport unittest
6*9c5db199SXin Lifrom unittest import mock
7*9c5db199SXin Li
8*9c5db199SXin Liimport common
9*9c5db199SXin Lifrom autotest_lib.client.common_lib import autotemp
10*9c5db199SXin Lifrom autotest_lib.client.common_lib import error
11*9c5db199SXin Lifrom autotest_lib.client.bin import local_host
12*9c5db199SXin Li
13*9c5db199SXin Li
14*9c5db199SXin Liclass test_local_host_class(unittest.TestCase):
15*9c5db199SXin Li    def setUp(self):
16*9c5db199SXin Li        self.tmpdir = autotemp.tempdir(unique_id='localhost_unittest')
17*9c5db199SXin Li        self.addCleanup(self.tmpdir.clean)
18*9c5db199SXin Li
19*9c5db199SXin Li
20*9c5db199SXin Li    @mock.patch('autotest_lib.client.bin.local_host.platform.node')
21*9c5db199SXin Li    def test_init_default_hostname(self, mock_node):
22*9c5db199SXin Li        mock_node.return_value = 'foo'
23*9c5db199SXin Li        host = local_host.LocalHost()
24*9c5db199SXin Li        self.assertEqual(host.hostname, 'foo')
25*9c5db199SXin Li
26*9c5db199SXin Li
27*9c5db199SXin Li    @mock.patch('autotest_lib.client.bin.local_host.platform.node')
28*9c5db199SXin Li    def test_init_with_hostname(self, mock_node):
29*9c5db199SXin Li        mock_node.return_value = 'foo'
30*9c5db199SXin Li        host = local_host.LocalHost(hostname='bar')
31*9c5db199SXin Li        self.assertEqual(host.hostname, 'bar')
32*9c5db199SXin Li
33*9c5db199SXin Li
34*9c5db199SXin Li    def test_wait_up(self):
35*9c5db199SXin Li        # just test that wait_up always works
36*9c5db199SXin Li        host = local_host.LocalHost()
37*9c5db199SXin Li        host.wait_up(1)
38*9c5db199SXin Li
39*9c5db199SXin Li
40*9c5db199SXin Li    @mock.patch('autotest_lib.client.bin.local_host.utils.run')
41*9c5db199SXin Li    def test_run_success(self, mock_run):
42*9c5db199SXin Li        result = local_host.utils.CmdResult(
43*9c5db199SXin Li                command='yes',
44*9c5db199SXin Li                stdout='y',
45*9c5db199SXin Li                stderr='',
46*9c5db199SXin Li                exit_status=0,
47*9c5db199SXin Li                duration=1,
48*9c5db199SXin Li        )
49*9c5db199SXin Li        mock_run.return_value = result
50*9c5db199SXin Li
51*9c5db199SXin Li        host = local_host.LocalHost()
52*9c5db199SXin Li        got = host.run(
53*9c5db199SXin Li                'yes',
54*9c5db199SXin Li                timeout=123,
55*9c5db199SXin Li                ignore_status=True,
56*9c5db199SXin Li                stdout_tee=local_host.utils.TEE_TO_LOGS,
57*9c5db199SXin Li                stderr_tee=local_host.utils.TEE_TO_LOGS,
58*9c5db199SXin Li                stdin=None,
59*9c5db199SXin Li        )
60*9c5db199SXin Li
61*9c5db199SXin Li        self.assertEqual(got, result)
62*9c5db199SXin Li        mock_run.assert_called_once_with(
63*9c5db199SXin Li                result.command,
64*9c5db199SXin Li                timeout=123,
65*9c5db199SXin Li                ignore_status=True,
66*9c5db199SXin Li                stdout_tee=local_host.utils.TEE_TO_LOGS,
67*9c5db199SXin Li                stderr_tee=local_host.utils.TEE_TO_LOGS,
68*9c5db199SXin Li                stdin=None,
69*9c5db199SXin Li                ignore_timeout=False,
70*9c5db199SXin Li                args=(),
71*9c5db199SXin Li        )
72*9c5db199SXin Li
73*9c5db199SXin Li
74*9c5db199SXin Li    @mock.patch('autotest_lib.client.bin.local_host.utils.run')
75*9c5db199SXin Li    def test_run_cmd_failure_raised(self, mock_run):
76*9c5db199SXin Li        mock_result = mock.MagicMock()
77*9c5db199SXin Li        mock_run.side_effect = error.CmdError('yes', mock_result)
78*9c5db199SXin Li
79*9c5db199SXin Li        host = local_host.LocalHost()
80*9c5db199SXin Li        with self.assertRaises(error.AutotestHostRunCmdError) as exc_cm:
81*9c5db199SXin Li            host.run('yes', timeout=123)
82*9c5db199SXin Li
83*9c5db199SXin Li        self.assertEqual(exc_cm.exception.result_obj, mock_result)
84*9c5db199SXin Li        mock_run.assert_called_once_with(
85*9c5db199SXin Li                'yes',
86*9c5db199SXin Li                timeout=123,
87*9c5db199SXin Li                ignore_status=False,
88*9c5db199SXin Li                stdout_tee=local_host.utils.TEE_TO_LOGS,
89*9c5db199SXin Li                stderr_tee=local_host.utils.TEE_TO_LOGS,
90*9c5db199SXin Li                stdin=None,
91*9c5db199SXin Li                ignore_timeout=False,
92*9c5db199SXin Li                args=(),
93*9c5db199SXin Li        )
94*9c5db199SXin Li
95*9c5db199SXin Li
96*9c5db199SXin Li    @mock.patch('autotest_lib.client.bin.local_host.utils.run')
97*9c5db199SXin Li    def test_run_cmd_timeout_raised(self, mock_run):
98*9c5db199SXin Li        mock_result = mock.MagicMock()
99*9c5db199SXin Li        mock_run.side_effect = error.CmdTimeoutError('yes', mock_result)
100*9c5db199SXin Li
101*9c5db199SXin Li        host = local_host.LocalHost()
102*9c5db199SXin Li        with self.assertRaises(error.AutotestHostRunTimeoutError) as exc_cm:
103*9c5db199SXin Li            host.run('yes', timeout=123)
104*9c5db199SXin Li
105*9c5db199SXin Li        self.assertEqual(exc_cm.exception.result_obj, mock_result)
106*9c5db199SXin Li        mock_run.assert_called_once_with(
107*9c5db199SXin Li                'yes',
108*9c5db199SXin Li                timeout=123,
109*9c5db199SXin Li                ignore_status=False,
110*9c5db199SXin Li                stdout_tee=local_host.utils.TEE_TO_LOGS,
111*9c5db199SXin Li                stderr_tee=local_host.utils.TEE_TO_LOGS,
112*9c5db199SXin Li                stdin=None,
113*9c5db199SXin Li                ignore_timeout=False,
114*9c5db199SXin Li                args=(),
115*9c5db199SXin Li        )
116*9c5db199SXin Li
117*9c5db199SXin Li
118*9c5db199SXin Li    @mock.patch('autotest_lib.client.bin.local_host.utils.run')
119*9c5db199SXin Li    def test_run_failure_ignored(self, mock_run):
120*9c5db199SXin Li        result = local_host.utils.CmdResult(
121*9c5db199SXin Li                command='yes',
122*9c5db199SXin Li                stdout='',
123*9c5db199SXin Li                stderr='err',
124*9c5db199SXin Li                exit_status=1,
125*9c5db199SXin Li                duration=1,
126*9c5db199SXin Li        )
127*9c5db199SXin Li        mock_run.return_value = result
128*9c5db199SXin Li
129*9c5db199SXin Li        host = local_host.LocalHost()
130*9c5db199SXin Li        got = host.run('yes', timeout=123, ignore_status=True)
131*9c5db199SXin Li
132*9c5db199SXin Li        self.assertEqual(got, result)
133*9c5db199SXin Li        mock_run.assert_called_once_with(
134*9c5db199SXin Li                result.command,
135*9c5db199SXin Li                timeout=123,
136*9c5db199SXin Li                ignore_status=True,
137*9c5db199SXin Li                stdout_tee=local_host.utils.TEE_TO_LOGS,
138*9c5db199SXin Li                stderr_tee=local_host.utils.TEE_TO_LOGS,
139*9c5db199SXin Li                stdin=None,
140*9c5db199SXin Li                ignore_timeout=False,
141*9c5db199SXin Li                args=(),
142*9c5db199SXin Li        )
143*9c5db199SXin Li
144*9c5db199SXin Li
145*9c5db199SXin Li    def test_list_files_glob(self):
146*9c5db199SXin Li        host = local_host.LocalHost()
147*9c5db199SXin Li
148*9c5db199SXin Li        files = (os.path.join(self.tmpdir.name, 'file1'),
149*9c5db199SXin Li                 os.path.join(self.tmpdir.name, 'file2'))
150*9c5db199SXin Li
151*9c5db199SXin Li        # create some files in tmpdir
152*9c5db199SXin Li        open(files[0], 'w').close()
153*9c5db199SXin Li        open(files[1], 'w').close()
154*9c5db199SXin Li        if six.PY2:
155*9c5db199SXin Li            self.assertItemsEqual(
156*9c5db199SXin Li                    files,
157*9c5db199SXin Li                    host.list_files_glob(os.path.join(self.tmpdir.name, '*')))
158*9c5db199SXin Li        else:
159*9c5db199SXin Li            self.assertCountEqual(
160*9c5db199SXin Li                    files,
161*9c5db199SXin Li                    host.list_files_glob(os.path.join(self.tmpdir.name, '*')))
162*9c5db199SXin Li
163*9c5db199SXin Li
164*9c5db199SXin Li    def test_symlink_closure_does_not_add_existent_file(self):
165*9c5db199SXin Li        host = local_host.LocalHost()
166*9c5db199SXin Li
167*9c5db199SXin Li        # create a file and a symlink to it
168*9c5db199SXin Li        fname = os.path.join(self.tmpdir.name, 'file')
169*9c5db199SXin Li        sname = os.path.join(self.tmpdir.name, 'sym')
170*9c5db199SXin Li        open(fname, 'w').close()
171*9c5db199SXin Li        os.symlink(fname, sname)
172*9c5db199SXin Li
173*9c5db199SXin Li        # test that when the symlinks point to already know files
174*9c5db199SXin Li        # nothing is added
175*9c5db199SXin Li        if six.PY2:
176*9c5db199SXin Li            self.assertItemsEqual([fname, sname],
177*9c5db199SXin Li                                  host.symlink_closure([fname, sname]))
178*9c5db199SXin Li        else:
179*9c5db199SXin Li            self.assertCountEqual([fname, sname],
180*9c5db199SXin Li                                  host.symlink_closure([fname, sname]))
181*9c5db199SXin Li
182*9c5db199SXin Li
183*9c5db199SXin Li    def test_symlink_closure_adds_missing_files(self):
184*9c5db199SXin Li        host = local_host.LocalHost()
185*9c5db199SXin Li
186*9c5db199SXin Li        # create a file and a symlink to it
187*9c5db199SXin Li        fname = os.path.join(self.tmpdir.name, 'file')
188*9c5db199SXin Li        sname = os.path.join(self.tmpdir.name, 'sym')
189*9c5db199SXin Li        open(fname, 'w').close()
190*9c5db199SXin Li        os.symlink(fname, sname)
191*9c5db199SXin Li
192*9c5db199SXin Li        # test that when the symlinks point to unknown files they are added
193*9c5db199SXin Li        if six.PY2:
194*9c5db199SXin Li            self.assertItemsEqual([fname, sname],
195*9c5db199SXin Li                                  host.symlink_closure([sname]))
196*9c5db199SXin Li        else:
197*9c5db199SXin Li            self.assertCountEqual([fname, sname],
198*9c5db199SXin Li                                  host.symlink_closure([sname]))
199*9c5db199SXin Li
200*9c5db199SXin Li
201*9c5db199SXin Li    def test_get_file(self):
202*9c5db199SXin Li        """Tests get_file() copying a regular file."""
203*9c5db199SXin Li        host = local_host.LocalHost()
204*9c5db199SXin Li
205*9c5db199SXin Li        source_file = os.path.join(self.tmpdir.name, 'file')
206*9c5db199SXin Li        open(os.path.join(source_file), 'w').close()
207*9c5db199SXin Li
208*9c5db199SXin Li        dest_file = os.path.join(self.tmpdir.name, 'dest')
209*9c5db199SXin Li
210*9c5db199SXin Li        host.get_file(source_file, dest_file)
211*9c5db199SXin Li        self.assertTrue(os.path.isfile(dest_file))
212*9c5db199SXin Li
213*9c5db199SXin Li
214*9c5db199SXin Li    def test_get_directory_into_new_directory(self):
215*9c5db199SXin Li        """Tests get_file() copying a directory into a new dir."""
216*9c5db199SXin Li        host = local_host.LocalHost()
217*9c5db199SXin Li
218*9c5db199SXin Li        source_dir = os.path.join(self.tmpdir.name, 'dir')
219*9c5db199SXin Li        os.mkdir(source_dir)
220*9c5db199SXin Li        open(os.path.join(source_dir, 'file'), 'w').close()
221*9c5db199SXin Li
222*9c5db199SXin Li        dest_dir = os.path.join(self.tmpdir.name, 'dest')
223*9c5db199SXin Li
224*9c5db199SXin Li        host.get_file(source_dir, dest_dir)
225*9c5db199SXin Li
226*9c5db199SXin Li        self.assertTrue(os.path.isfile(os.path.join(dest_dir, 'dir', 'file')))
227*9c5db199SXin Li
228*9c5db199SXin Li
229*9c5db199SXin Li    def test_get_directory_into_existing_directory(self):
230*9c5db199SXin Li        """Tests get_file() copying a directory into an existing dir."""
231*9c5db199SXin Li        host = local_host.LocalHost()
232*9c5db199SXin Li
233*9c5db199SXin Li        source_dir = os.path.join(self.tmpdir.name, 'dir')
234*9c5db199SXin Li        os.mkdir(source_dir)
235*9c5db199SXin Li        open(os.path.join(source_dir, 'file'), 'w').close()
236*9c5db199SXin Li
237*9c5db199SXin Li        dest_dir = os.path.join(self.tmpdir.name, 'dest')
238*9c5db199SXin Li        os.mkdir(dest_dir)
239*9c5db199SXin Li
240*9c5db199SXin Li        host.get_file(source_dir, dest_dir)
241*9c5db199SXin Li
242*9c5db199SXin Li        self.assertTrue(os.path.isfile(os.path.join(dest_dir, 'dir', 'file')))
243*9c5db199SXin Li
244*9c5db199SXin Li
245*9c5db199SXin Li    def test_get_directory_delete_dest(self):
246*9c5db199SXin Li        """Tests get_file() replacing a dir."""
247*9c5db199SXin Li        host = local_host.LocalHost()
248*9c5db199SXin Li
249*9c5db199SXin Li        source_dir = os.path.join(self.tmpdir.name, 'dir')
250*9c5db199SXin Li        os.mkdir(source_dir)
251*9c5db199SXin Li        open(os.path.join(source_dir, 'file'), 'w').close()
252*9c5db199SXin Li
253*9c5db199SXin Li        dest_dir = os.path.join(self.tmpdir.name, 'dest')
254*9c5db199SXin Li        os.mkdir(dest_dir)
255*9c5db199SXin Li        os.mkdir(os.path.join(dest_dir, 'dir'))
256*9c5db199SXin Li        open(os.path.join(dest_dir, 'dir', 'file2'), 'w').close()
257*9c5db199SXin Li
258*9c5db199SXin Li        host.get_file(source_dir, dest_dir, delete_dest=True)
259*9c5db199SXin Li
260*9c5db199SXin Li        self.assertTrue(os.path.isfile(os.path.join(dest_dir, 'dir', 'file')))
261*9c5db199SXin Li        self.assertFalse(os.path.isfile(os.path.join(dest_dir, 'dir', 'file2')))
262*9c5db199SXin Li
263*9c5db199SXin Li
264*9c5db199SXin Li    def test_get_directory_contents_into_new_directory(self):
265*9c5db199SXin Li        """Tests get_file() copying dir contents to a new dir."""
266*9c5db199SXin Li        host = local_host.LocalHost()
267*9c5db199SXin Li
268*9c5db199SXin Li        source_dir = os.path.join(self.tmpdir.name, 'dir')
269*9c5db199SXin Li        os.mkdir(source_dir)
270*9c5db199SXin Li        open(os.path.join(source_dir, 'file'), 'w').close()
271*9c5db199SXin Li
272*9c5db199SXin Li        dest_dir = os.path.join(self.tmpdir.name, 'dest')
273*9c5db199SXin Li
274*9c5db199SXin Li        # End the source with '/' to copy the contents only.
275*9c5db199SXin Li        host.get_file(os.path.join(source_dir, ''), dest_dir)
276*9c5db199SXin Li
277*9c5db199SXin Li        self.assertTrue(os.path.isfile(os.path.join(dest_dir, 'file')))
278*9c5db199SXin Li
279*9c5db199SXin Li
280*9c5db199SXin Li    def test_get_directory_contents_into_existing_directory(self):
281*9c5db199SXin Li        """Tests get_file() copying dir contents into an existing dir."""
282*9c5db199SXin Li        host = local_host.LocalHost()
283*9c5db199SXin Li
284*9c5db199SXin Li        source_dir = os.path.join(self.tmpdir.name, 'dir')
285*9c5db199SXin Li        os.mkdir(source_dir)
286*9c5db199SXin Li        open(os.path.join(source_dir, 'file'), 'w').close()
287*9c5db199SXin Li
288*9c5db199SXin Li        dest_dir = os.path.join(self.tmpdir.name, 'dest')
289*9c5db199SXin Li        os.mkdir(dest_dir)
290*9c5db199SXin Li
291*9c5db199SXin Li        # End the source with '/' to copy the contents only.
292*9c5db199SXin Li        host.get_file(os.path.join(source_dir, ''), dest_dir)
293*9c5db199SXin Li
294*9c5db199SXin Li        self.assertTrue(os.path.isfile(os.path.join(dest_dir, 'file')))
295*9c5db199SXin Li
296*9c5db199SXin Li
297*9c5db199SXin Li    def test_get_directory_contents_delete_dest(self):
298*9c5db199SXin Li        """Tests get_file() replacing contents of a dir."""
299*9c5db199SXin Li        host = local_host.LocalHost()
300*9c5db199SXin Li
301*9c5db199SXin Li        source_dir = os.path.join(self.tmpdir.name, 'dir')
302*9c5db199SXin Li        os.mkdir(source_dir)
303*9c5db199SXin Li        open(os.path.join(source_dir, 'file'), 'w').close()
304*9c5db199SXin Li
305*9c5db199SXin Li        dest_dir = os.path.join(self.tmpdir.name, 'dest')
306*9c5db199SXin Li        os.mkdir(dest_dir)
307*9c5db199SXin Li        open(os.path.join(dest_dir, 'file2'), 'w').close()
308*9c5db199SXin Li
309*9c5db199SXin Li        # End the source with '/' to copy the contents only.
310*9c5db199SXin Li        host.get_file(os.path.join(source_dir, ''), dest_dir, delete_dest=True)
311*9c5db199SXin Li
312*9c5db199SXin Li        self.assertTrue(os.path.isfile(os.path.join(dest_dir, 'file')))
313*9c5db199SXin Li        self.assertFalse(os.path.isfile(os.path.join(dest_dir, 'file2')))
314*9c5db199SXin Li
315*9c5db199SXin Li
316*9c5db199SXin Liif __name__ == "__main__":
317*9c5db199SXin Li    unittest.main()
318