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