def setup(self): """Setup before each method""" self._app = AppIntegration(AppConfig(get_valid_config_dict('duo_admin')))
class TestAppIntegration(object): """Test class for the AppIntegration""" @patch.object(AppIntegration, 'type', Mock(return_value='type')) def __init__(self): self._app = None # Remove all abstractmethods so we can instantiate AppIntegration for testing # Also patch some abstractproperty attributes @patch.object(AppIntegration, '__abstractmethods__', frozenset()) def setup(self): """Setup before each method""" self._app = AppIntegration(AppConfig(get_valid_config_dict('duo_admin'))) @patch('logging.Logger.debug') def test_no_sleep(self, log_mock): """App Integration - App Base, No Sleep on First Poll""" self._app._sleep() log_mock.assert_called_with('Skipping sleep for first poll') @patch('time.sleep') @patch('app_integrations.apps.app_base.AppIntegration._sleep_seconds', Mock(return_value=1)) def test_sleep(self, time_mock): """App Integration - App Base, Sleep""" self._app._poll_count = 1 self._app._sleep() time_mock.assert_called_with(1) def test_validate_auth_(self): """App Integration - Validate Authentication Info""" assert_is_none(self._app._validate_auth()) @raises(AppIntegrationConfigError) def test_validate_auth_empty(self): """App Integration - Validate Authentication Info, No Config Exception""" self._app._config.clear() self._app._validate_auth() @raises(AppIntegrationConfigError) def test_validate_auth_no_auth(self): """App Integration - Validate Authentication Info, No Auth Exception""" del self._app._config['auth'] self._app._validate_auth() @raises(AppIntegrationConfigError) def test_validate_auth_missing_auth(self): """App Integration - Validate Authentication Info, Missing Auth Key Exception""" with patch.object(AppIntegration, 'required_auth_info') as auth_keys_mock: auth_keys_mock.return_value = {'new_auth_key'} self._app._validate_auth() def test_check_http_response_good(self): """App Integration - Check HTTP Response, Success""" response = Mock(status_code=200) assert_true(self._app._check_http_response(response)) @patch('logging.Logger.error') def test_check_http_response_bad(self, log_mock): """App Integration - Check HTTP Response, Failure""" response = Mock(status_code=404, json=Mock(side_effect=[{'message': 'hey'}])) # Check to make sure this resulted in a return of False assert_false(self._app._check_http_response(response)) # Make sure the logger was called with the proper info log_mock.assert_called_with('HTTP request failed for service \'%s\': [%d] %s', 'type', 404, 'hey') def test_initialize(self): """App Integration - Initialize, Valid""" assert_true(self._app._initialize()) @patch('logging.Logger.error') def test_initialize_running(self, log_mock): """App Integration - Initialize, Already Running""" self._app._config['current_state'] = 'running' assert_false(self._app._initialize()) log_mock.assert_called_with('App already running for service \'%s\'.', 'type') def test_finalize(self): """App Integration - Finalize, Valid""" test_new_time = 50000000 self._app._last_timestamp = test_new_time self._app._finalize() assert_equal(self._app._config.last_timestamp, test_new_time) @patch('logging.Logger.error') def test_finalize_zero_time(self, log_mock): """App Integration - Finalize, Zero Time Error""" self._app._finalize() log_mock.assert_called_with('Ending last timestamp is 0. This should not happen and ' 'is likely due to the subclass not setting this value.') @patch('logging.Logger.error') def test_finalize_same_time(self, log_mock): """App Integration - Finalize, Same Time Error""" self._app._last_timestamp = self._app._config.start_last_timestamp self._app._finalize() log_mock.assert_called_with('Ending last timestamp is the same as ' 'the beginning last timestamp') @patch('logging.Logger.debug') def test_gather_success(self, log_mock): """App Integration - Gather, Success""" with patch.object(AppIntegration, '_gather_logs') as subclass_gather_mock: subclass_gather_mock.return_value = ['log01', 'log02', 'log03'] self._app._gather() log_mock.assert_called() assert_equal(log_mock.call_args_list[-1][0][0], 'Gather process for \'%s\' executed in %f seconds.') @patch('logging.Logger.error') def test_gather_no_logs(self, log_mock): """App Integration - Gather, Success""" with patch.object(AppIntegration, '_gather_logs') as subclass_gather_mock: subclass_gather_mock.return_value = [] self._app._gather() log_mock.assert_called_with('Gather process for service \'%s\' was not able ' 'to poll any logs', 'type') @patch('app_integrations.apps.app_base.AppIntegration._finalize') @patch('app_integrations.apps.app_base.AppIntegration._sleep_seconds', Mock(return_value=1)) @patch('app_integrations.config.AppConfig.remaining_ms', Mock(return_value=5000)) def test_gather_entry(self, finalize_mock): """App Integration - Gather, Entry Point""" self._app.gather() finalize_mock.assert_called() @patch('app_integrations.apps.app_base.AppIntegration._gather') @patch('app_integrations.apps.app_base.AppIntegration._sleep_seconds', Mock(return_value=1)) @patch('app_integrations.config.AppConfig.remaining_ms', Mock(side_effect=[5000, 2000])) def test_gather_multiple(self, gather_mock): """App Integration - Gather, Entry Point, Multiple Calls""" # 3 == number of 'seconds' this ran for. This is compared against the remaining_ms mock gather_mock.side_effect = [3, 3] self._app._more_to_poll = True self._app.gather() assert_equal(gather_mock.call_count, 2) @patch('app_integrations.apps.app_base.AppIntegration._finalize') def test_gather_running(self, finalize_mock): """App Integration - Gather, Entry Point, Already Running""" self._app._config['current_state'] = 'running' self._app.gather() finalize_mock.assert_not_called()