def test_start_and_stop(self, get_timestamp_mock, stop_proc_mock, start_proc_mock, create_dir_mock, FastbootProxy, MockAdbProxy): """Verifies the steps of collecting adb logcat on an AndroidDevice object, including various function calls and the expected behaviors of the calls. """ mock_serial = '1' get_timestamp_mock.return_value = '123' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service.start() # Verify start did the correct operations. self.assertTrue(logcat_service._adb_logcat_process) expected_log_path = os.path.join( logging.log_path, 'AndroidDevice%s' % ad.serial, 'logcat,%s,fakemodel,123.txt' % ad.serial) create_dir_mock.assert_called_with(os.path.dirname(expected_log_path)) adb_cmd = '"adb" -s %s logcat -v threadtime >> %s' start_proc_mock.assert_called_with( adb_cmd % (ad.serial, '"%s"' % expected_log_path), shell=True) self.assertEqual(logcat_service.adb_logcat_file_path, expected_log_path) expected_msg = ( 'Logcat thread is already running, cannot start another' ' one.') # Expect error if start is called back to back. with self.assertRaisesRegex(logcat.Error, expected_msg): logcat_service.start() # Verify stop did the correct operations. logcat_service.stop() stop_proc_mock.assert_called_with('process') self.assertIsNone(logcat_service._adb_logcat_process) self.assertEqual(logcat_service.adb_logcat_file_path, expected_log_path)
def test__enable_logpersist_with_missing_logpersist_stop( self, MockFastboot, MockAdbProxy): def adb_shell_helper(command): if command == 'logpersist.stop --clear': raise MOCK_LOGPERSIST_STOP_MISSING_ADB_ERROR else: return b'' mock_serial = '1' mock_adb_proxy = MockAdbProxy.return_value mock_adb_proxy.getprops.return_value = { 'ro.build.id': 'AB42', 'ro.build.type': 'userdebug', 'ro.debuggable': '1', } mock_adb_proxy.has_shell_command.side_effect = lambda command: { 'logpersist.start': True, 'logpersist.stop': False, }[command] mock_adb_proxy.shell.side_effect = adb_shell_helper ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._enable_logpersist() mock_adb_proxy.shell.assert_has_calls([ mock.call('logpersist.stop --clear'), ])
def test_cat_adb_log_with_unicode(self, mock_timestamp_getter, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy): """Verifies that AndroidDevice.cat_adb_log loads the correct adb log file, locates the correct adb log lines within the given time range, and writes the lines to the correct output file. """ mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._enable_logpersist() # Direct the log path of the ad to a temp dir to avoid racing. logcat_service._ad._log_path = self.tmp_dir # Expect error if attempted to cat adb log before starting adb logcat. expected_msg = ('.* Attempting to cat adb log when none' ' has been collected.') with self.assertRaisesRegex(logcat.Error, expected_msg): logcat_service.cat_adb_log('some_test', MOCK_ADB_LOGCAT_BEGIN_TIME) logcat_service.start() utils.create_dir(ad.log_path) mock_adb_log_path = logcat_service.adb_logcat_file_path with io.open(mock_adb_log_path, 'w', encoding='utf-8') as f: f.write(MOCK_ADB_UNICODE_LOGCAT) cat_file_path = logcat_service.cat_adb_log('some_test', MOCK_ADB_LOGCAT_BEGIN_TIME) with io.open(cat_file_path, 'r', encoding='utf-8') as f: actual_cat = f.read() self.assertEqual(actual_cat, ''.join(MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT)) # Stops adb logcat. logcat_service.stop()
def test_take_logcat_with_extra_params(self, get_timestamp_mock, stop_proc_mock, start_proc_mock, create_dir_mock, FastbootProxy, MockAdbProxy): """Verifies the steps of collecting adb logcat on an AndroidDevice object, including various function calls and the expected behaviors of the calls. """ mock_serial = '1' get_timestamp_mock.return_value = '123' ad = android_device.AndroidDevice(serial=mock_serial) configs = logcat.Config() configs.logcat_params = '-b radio' logcat_service = logcat.Logcat(ad, configs) logcat_service.start() # Verify start did the correct operations. self.assertTrue(logcat_service._adb_logcat_process) expected_log_path = os.path.join( logging.log_path, 'AndroidDevice%s' % ad.serial, 'logcat,%s,fakemodel,123.txt' % ad.serial) create_dir_mock.assert_called_with(os.path.dirname(expected_log_path)) adb_cmd = '"adb" -s %s logcat -v threadtime -b radio >> %s' start_proc_mock.assert_called_with( adb_cmd % (ad.serial, '"%s"' % expected_log_path), shell=True) self.assertEqual(logcat_service.adb_logcat_file_path, expected_log_path)
def test_clear_adb_log(self, MockFastboot, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) ad.adb.logcat = mock.MagicMock() ad.adb.logcat.side_effect = adb.AdbError( cmd='cmd', stdout=b'', stderr=b'failed to clear "main" log', ret_code=1) logcat_service = logcat.Logcat(ad) logcat_service.clear_adb_log()
def test_instantiation(self, MockFastboot, MockAdbProxy): """Verifies the AndroidDevice object's basic attributes are correctly set after instantiation. """ mock_serial = 1 ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) self.assertIsNone(logcat_service._adb_logcat_process) self.assertIsNone(logcat_service.adb_logcat_file_path)
def test_update_config_while_running(self, stop_proc_mock, start_proc_mock, create_dir_mock, FastbootProxy, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service.start() new_config = logcat.Config(logcat_params='-blah', output_file_path='some/path/file.txt') with self.assertRaisesRegex( logcat.Error, 'Logcat thread is already running, cannot start another one'): logcat_service.update_config(new_config) self.assertTrue(logcat_service.is_alive)
def test_logcat_service_create_output_excerpts(self, clear_adb_mock, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._start() # Generate logs before the file pointer is created. # This message will not be captured in the excerpt. NOT_IN_EXCERPT = 'Not in excerpt.\n' with open(logcat_service.adb_logcat_file_path, 'a') as f: f.write(NOT_IN_EXCERPT) # With the file pointer created, generate logs and make an excerpt. logcat_service._open_logcat_file() FILE_CONTENT = 'Some log.\n' with open(logcat_service.adb_logcat_file_path, 'a') as f: f.write(FILE_CONTENT) test_output_dir = os.path.join(self.tmp_dir, 'test_foo') mock_record = mock.MagicMock() mock_record.begin_time = 123 test_run_info = runtime_test_info.RuntimeTestInfo( 'test_foo', test_output_dir, mock_record) actual_path1 = logcat_service.create_output_excerpts(test_run_info)[0] expected_path1 = os.path.join(test_output_dir, 'test_foo-123', 'logcat,1,fakemodel,test_foo-123.txt') self.assertEqual(actual_path1, expected_path1) self.assertTrue(os.path.exists(expected_path1)) self.AssertFileContains(FILE_CONTENT, expected_path1) self.AssertFileDoesNotContain(NOT_IN_EXCERPT, expected_path1) # Generate some new logs and do another excerpt. FILE_CONTENT = 'Some more logs!!!\n' with open(logcat_service.adb_logcat_file_path, 'a') as f: f.write(FILE_CONTENT) test_output_dir = os.path.join(self.tmp_dir, 'test_bar') mock_record = mock.MagicMock() mock_record.begin_time = 456 test_run_info = runtime_test_info.RuntimeTestInfo( 'test_bar', test_output_dir, mock_record) actual_path2 = logcat_service.create_output_excerpts(test_run_info)[0] expected_path2 = os.path.join(test_output_dir, 'test_bar-456', 'logcat,1,fakemodel,test_bar-456.txt') self.assertEqual(actual_path2, expected_path2) self.assertTrue(os.path.exists(expected_path2)) self.AssertFileContains(FILE_CONTENT, expected_path2) self.AssertFileDoesNotContain(FILE_CONTENT, expected_path1) logcat_service.stop()
def test__enable_logpersist_with_logpersist(self, MockFastboot, MockAdbProxy): mock_serial = '1' mock_adb_proxy = MockAdbProxy.return_value # Set getprop to return '1' to indicate the device is rootable. mock_adb_proxy.getprop.return_value = '1' mock_adb_proxy.has_shell_command.side_effect = lambda command: { 'logpersist.start': True, 'logpersist.stop': True, }[command] ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._enable_logpersist() mock_adb_proxy.shell.assert_has_calls([ mock.call('logpersist.stop --clear'), mock.call('logpersist.start'), ])
def test__enable_logpersist_with_user_build_device(self, MockFastboot, MockAdbProxy): mock_serial = '1' mock_adb_proxy = MockAdbProxy.return_value mock_adb_proxy.getprops.return_value = { 'ro.build.id': 'AB42', 'ro.build.type': 'user', 'ro.debuggable': '0', } mock_adb_proxy.has_shell_command.side_effect = lambda command: { 'logpersist.start': True, 'logpersist.stop': True, }[command] ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._enable_logpersist() mock_adb_proxy.shell.assert_not_called()
def test_pause_and_resume(self, clear_adb_mock, stop_proc_mock, start_proc_mock, create_dir_mock, FastbootProxy, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad, logcat.Config(clear_log=True)) logcat_service.start() clear_adb_mock.assert_called_once_with() self.assertTrue(logcat_service.is_alive) logcat_service.pause() self.assertFalse(logcat_service.is_alive) stop_proc_mock.assert_called_with('process') self.assertIsNone(logcat_service._adb_logcat_process) clear_adb_mock.reset_mock() logcat_service.resume() self.assertTrue(logcat_service.is_alive) clear_adb_mock.assert_not_called()
def test__enable_logpersist_with_missing_logpersist_start( self, MockFastboot, MockAdbProxy): def adb_shell_helper(command): if command == 'logpersist.start': raise MOCK_LOGPERSIST_START_MISSING_ADB_ERROR else: return '' mock_serial = '1' mock_adb_proxy = MockAdbProxy.return_value mock_adb_proxy.getprop.return_value = 'userdebug' mock_adb_proxy.has_shell_command.side_effect = lambda command: { 'logpersist.start': False, 'logpersist.stop': True, }[command] mock_adb_proxy.shell.side_effect = adb_shell_helper ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._enable_logpersist()
def test_update_config(self, stop_proc_mock, start_proc_mock, create_dir_mock, FastbootProxy, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service.start() logcat_service.stop() new_log_params = '-a -b -c' new_file_path = 'some/path/log.txt' new_config = logcat.Config(logcat_params=new_log_params, output_file_path=new_file_path) logcat_service.update_config(new_config) logcat_service.start() self.assertTrue(logcat_service._adb_logcat_process) create_dir_mock.assert_has_calls([mock.call('some/path')]) expected_adb_cmd = ('"adb" -s 1 logcat -v threadtime -a -b -c >> ' '"some/path/log.txt"') start_proc_mock.assert_called_with(expected_adb_cmd, shell=True) self.assertEqual(logcat_service.adb_logcat_file_path, 'some/path/log.txt')
def test_logcat_service_create_output_excerpts(self, clear_adb_mock, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service.start() FILE_CONTENT = 'Some log.\n' with open(logcat_service.adb_logcat_file_path, 'w') as f: f.write(FILE_CONTENT) test_output_dir = os.path.join(self.tmp_dir, 'test_foo') mock_record = mock.MagicMock() mock_record.begin_time = 123 test_run_info = runtime_test_info.RuntimeTestInfo( 'test_foo', test_output_dir, mock_record) actual_path1 = logcat_service.create_output_excerpts(test_run_info)[0] expected_path1 = os.path.join(test_output_dir, 'test_foo-123', 'adblog,fakemodel,1.txt') self.assertTrue(os.path.exists(expected_path1)) self.assertEqual(actual_path1, expected_path1) self.AssertFileContains(FILE_CONTENT, expected_path1) self.assertFalse(os.path.exists(logcat_service.adb_logcat_file_path)) # Generate some new logs and do another excerpt. FILE_CONTENT = 'Some more logs!!!\n' with open(logcat_service.adb_logcat_file_path, 'w') as f: f.write(FILE_CONTENT) test_output_dir = os.path.join(self.tmp_dir, 'test_bar') mock_record = mock.MagicMock() mock_record.begin_time = 456 test_run_info = runtime_test_info.RuntimeTestInfo( 'test_bar', test_output_dir, mock_record) actual_path2 = logcat_service.create_output_excerpts(test_run_info)[0] expected_path2 = os.path.join(test_output_dir, 'test_bar-456', 'adblog,fakemodel,1.txt') self.assertTrue(os.path.exists(expected_path2)) self.assertEqual(actual_path2, expected_path2) self.AssertFileContains(FILE_CONTENT, expected_path2) self.AssertFileDoesNotContain(FILE_CONTENT, expected_path1) self.assertFalse(os.path.exists(logcat_service.adb_logcat_file_path))
def test_logcat_service_create_output_excerpts(self, clear_adb_mock, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy): mock_serial = '1' ad = android_device.AndroidDevice(serial=mock_serial) logcat_service = logcat.Logcat(ad) logcat_service._start() def _write_logcat_file_and_assert_excerpts_exists( logcat_file_content, test_begin_time, test_name): with open(logcat_service.adb_logcat_file_path, 'a') as f: f.write(logcat_file_content) test_output_dir = os.path.join(self.tmp_dir, test_name) mock_record = records.TestResultRecord(test_name) mock_record.begin_time = test_begin_time mock_record.signature = f'{test_name}-{test_begin_time}' test_run_info = runtime_test_info.RuntimeTestInfo( test_name, test_output_dir, mock_record) actual_path = logcat_service.create_output_excerpts( test_run_info)[0] expected_path = os.path.join( test_output_dir, '{test_name}-{test_begin_time}'.format( test_name=test_name, test_begin_time=test_begin_time), 'logcat,{mock_serial},fakemodel,{test_name}-{test_begin_time}.txt' .format(mock_serial=mock_serial, test_name=test_name, test_begin_time=test_begin_time)) self.assertEqual(actual_path, expected_path) self.assertTrue(os.path.exists(expected_path)) return expected_path # Generate logs before the file pointer is created. # This message will not be captured in the excerpt. NOT_IN_EXCERPT = 'Not in excerpt.\n' with open(logcat_service.adb_logcat_file_path, 'a') as f: f.write(NOT_IN_EXCERPT) # With the file pointer created, generate logs and make an excerpt. logcat_service._open_logcat_file() FILE_CONTENT = 'Some log.\n' expected_path1 = _write_logcat_file_and_assert_excerpts_exists( logcat_file_content=FILE_CONTENT, test_begin_time=123, test_name='test_foo', ) self.AssertFileContains(FILE_CONTENT, expected_path1) self.AssertFileDoesNotContain(NOT_IN_EXCERPT, expected_path1) # Generate some new logs and do another excerpt. FILE_CONTENT = 'Some more logs!!!\n' expected_path2 = _write_logcat_file_and_assert_excerpts_exists( logcat_file_content=FILE_CONTENT, test_begin_time=456, test_name='test_bar', ) self.AssertFileContains(FILE_CONTENT, expected_path2) self.AssertFileDoesNotContain(FILE_CONTENT, expected_path1) # Simulate devices accidentally go offline, logcat service stopped. logcat_service.stop() FILE_CONTENT = 'Whatever logs\n' expected_path3 = _write_logcat_file_and_assert_excerpts_exists( logcat_file_content=FILE_CONTENT, test_begin_time=789, test_name='test_offline', ) self.assertEqual(os.stat(expected_path3).st_size, 0)