def test_get_env_var_missing(self): env_var_key = 'SOME_ENV_VAR' with self.assertRaises(ValueError) as context_manager: Config._get_env_var(env_var_key) expected = ('Lambda configuration error: ' f'missing environment variable {env_var_key}') self.assertEqual(str(context_manager.exception), expected)
def set_up(args): config = Config(args.config) db = Database(config.get_database_uri()) db.create_tables() aggregator = Aggregator(db) slack = Slack(people=config.get_people(), slack_config=config.get_slack_config(), aggregator=aggregator) fixer = Fixer() logger = get_logger(args.debug) return config, db, slack, fixer, logger
def test_load_yaml_invalid(self): yaml_input = 'foo:\n - \'bar"' config_name = 'test' with self.assertRaises(Exception) as context_manager: result = Config._load_yaml(yaml_input, config_name=config_name) expected = f'There was an error when attempting to load {config_name}' self.assertTrue(str(context_manager.exception).startswith(expected))
def test_thresholds_setter_empty_list(self): thresholds = {'notify_user_only': [], 'notify_admins_too': [100.0]} with self.assertRaises(Exception) as context_manager: Config().thresholds = thresholds expected = "{'notify_user_only': ['min length is 1']}" print(str(context_manager.exception)) self.assertTrue(expected in str(context_manager.exception))
def test_init(self): account_id = '012345678901' topic_arn = 'arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE' end_user_role_name = 'SomeRoleName' parentdir = Path(__file__).parent budget_rules = ('teams:\n' ' \'3412821\':\n' ' amount: \'10\'\n' ' period: ANNUALLY\n' ' unit: USD\n' ' community_manager_emails:\n' ' - [email protected]') thresholds = ('notify_user_only: [25.0, 50.0, 80.0]\n' 'notify_admins_too: [90.0, 100.0, 110.0]') with patch.dict( 'os.environ', { 'AWS_ACCOUNT_ID': account_id, 'NOTIFICATION_TOPIC_ARN': topic_arn, 'BUDGET_RULES': budget_rules, 'THRESHOLDS': thresholds, 'END_USER_ROLE_NAME': end_user_role_name }): config = Config() self.assertEqual(config.account_id, account_id) self.assertEqual(config.notification_topic_arn, topic_arn) self.assertEqual(config.end_user_role_name, end_user_role_name) expected_budget_rules = yaml.safe_load(budget_rules) expected_thresholds = yaml.safe_load(thresholds) self.assertDictEqual(config.budget_rules, expected_budget_rules) self.assertDictEqual(config.thresholds, expected_thresholds)
def test_get_env_var_present(self): env_var_value = 'some_value' env_var_key = 'SOME_ENV_VAR' with patch('os.getenv', MagicMock(return_value=env_var_value)) as mock: result = Config._get_env_var(env_var_key) expected = env_var_value self.assertEqual(result, expected) mock.assert_called_once_with(env_var_key)
def test_budget_rules_setter_empty(self): # empty test budget_rules = {} with self.assertRaises(Exception) as context_manager: Config().budget_rules = budget_rules expected = (f'There was a configuration validation error: ' "{'teams': ['required field']}. " f'Configuration submitted: {budget_rules}') self.assertEqual(str(context_manager.exception), expected)
def test_thresholds_setter_all_empty(self): thresholds = {} with self.assertRaises(Exception) as context_manager: Config().thresholds = thresholds expected = ( "{'notify_admins_too': ['required field'], 'notify_user_only': " "['required field']}") print(str(context_manager.exception)) self.assertTrue(expected in str(context_manager.exception))
def test_budget_rules_setter_empty_team(self): budget_rules = {'teams': {'3412821': {}}} with self.assertRaises(Exception) as context_manager: Config().budget_rules = budget_rules expected = ("[{'amount': ['required field'], " "'community_manager_emails': ['required field'], " "'period': ['required field'], " "'unit': ['required field']}]") print(str(context_manager.exception)) self.assertTrue(expected in str(context_manager.exception))
def test_budget_rules_setter_happy(self): # happy path -- the setter will throw an error if the rules don't validate budget_rules = { 'teams': { '3412821': { 'amount': '10', 'period': 'ANNUALLY', 'unit': 'USD', 'community_manager_emails': ['*****@*****.**'] } } } Config().budget_rules = budget_rules
def test_budget_rules_setter_missing_manager(self): budget_rules = { 'teams': { '3412821': { 'amount': '10', 'period': 'ANNUALLY', 'unit': 'USD', 'community_manager_emails': [] } } } with self.assertRaises(Exception) as context_manager: Config().budget_rules = budget_rules expected = "{'community_manager_emails': ['min length is 1']}" print(str(context_manager.exception)) self.assertTrue(expected in str(context_manager.exception))
def lambda_handler(event, context): '''Lambda event handler''' log.debug(f'Event received: {json.dumps(event)}') try: global configuration configuration = Config() log.debug(f'Lambda configuration: {configuration}') # get users teams = configuration.budget_rules['teams'].keys() teams_by_user_id = get_users(teams) # verify that no users appear in multiple teams duplicates = check_user_duplicates(teams_by_user_id) if duplicates: log.warn(f'One or more duplicate team memberships was found.\n{duplicates}') # check which user ids need a budget, and which budgets should be removed user_ids_without_budget, budgets_to_remove = compare_budgets_and_users( teams_by_user_id.keys() ) # create budgets, if applicable budgets_created_message = create_budgets(user_ids_without_budget, teams_by_user_id) # remove budgets, if applicable budgets_removed_message = delete_budgets(budgets_to_remove) success_message = 'Budget maker run complete' if budgets_created_message: success_message = f'{success_message}; {budgets_created_message}' if budgets_removed_message: success_message = f'{success_message}; {budgets_removed_message}' log.info(success_message) return { 'message': success_message } except Exception as e: log.error(e, exc_info=True) return { 'error': str(e) }
def test_load_yaml_happy(self): yaml_input = 'foo:\n - bar' result = Config._load_yaml(yaml_input) expected = {'foo': ['bar']} self.assertDictEqual(result, expected)
def test_thresholds_setter_happy(self): thresholds = {'notify_user_only': [50.0], 'notify_admins_too': [100.0]} Config().thresholds = thresholds
) args_parser.add_argument("--debug", help="Increase verbosity", action="store_true") args_parser.add_argument( "--user-email", help="Pre-authenticated user e-mail", ) return args_parser.parse_args() app = Flask(__name__, static_url_path='/static') args = parse_arguments() config = Config(args.config) db = Database(config.get_database_uri()) aggregator = Aggregator(db) if args.user_email: config.pre_authenticated_user = args.user_email google_client_id, google_client_secret = config.get_google_auth_credentials() app.config.update(SECRET_KEY=google_client_secret, GOOGLE_LOGIN_REDIRECT_SCHEME="https", GOOGLE_LOGIN_CLIENT_ID=google_client_id, GOOGLE_LOGIN_CLIENT_SECRET=google_client_secret) login_manager = LoginManager(app) google_login = GoogleLogin(app)