import argparse import datetime import pytest from feed_ingestion.flows._anyexec import exec # noqa:A004 from feed_ingestion.util import exec_utils from tests.testing_utils import (parametrize_by_dicts, raises_optionally) class TestFlowExec: @pytest.fixture(autouse=True) def setup(self, clear_os_environ): self.flow_exec = exec.FlowExec() def test_prepare_parser(self): parser = self.flow_exec.prepare_parser() expected_args = { 'flow', 'start_date', 'end_date', 'reload', 'check_status', 'max_concurrent_flows', 'concurrency_strategy', } args = {action.dest for action in parser._actions} assert expected_args.issubset(args), expected_args.difference(args) def test_concurrency_control_settings(self): """Test that the ConcurrencyControlMixin settings are correct.""" mro = type(self.flow_exec).mro() assert mro.index(exec_utils.CheckStatusMixin) < mro.index( exec_utils.ConcurrencyControlMixin) assert self.flow_exec.TIMEOUT_SECONDS == 60 * 60 parser = self.flow_exec.prepare_parser() actions = {action.dest: action for action in parser._actions} assert actions['concurrency_strategy'].default == 'WAIT' assert actions['max_concurrent_flows'].default == 15 @parametrize_by_dicts( 'cli, env, expected, raises', [ dict( case='by command line', cli='--flow apple_music_streams --start-date 2024-11-01', env={}, expected=dict( flow='apple_music_streams', start_date=datetime.date(2024, 11, 1), ) ), dict( case='by env', cli='', env={'FLOW': 'spotify', 'START_DATE': '2024-11-01'}, expected=dict( flow='spotify', start_date=datetime.date(2024, 11, 1), ), ), dict( case='wrong flow by command line', cli='--flow not_exists --start-date 2024-11-01', env={}, raises=SystemExit ), dict( case='wrong flow by ENV', env={'FLOW': 'not_exists', 'START_DATE': '2024-11-01'}, raises=SystemExit ), dict( case='no flow', cli='--start-date 2024-11-01', env={}, raises=SystemExit ), ] ) def test_parse_args( self, cli, env, expected, raises, monkeypatch): cli = cli or '' argv = cli.split() if env: monkeypatch.setattr('os.environ', env) with raises_optionally(raises): parser = self.flow_exec.prepare_parser() args = parser.parse_args(argv) for key, value in expected.items(): assert getattr(args, key) == value @pytest.mark.parametrize( 'case_name, args, expected', [ ( 'single date', argparse.Namespace( flow='apple_music_streams', start_date=datetime.date(2024, 11, 1), end_date=None, ), [ datetime.date(2024, 11, 1), ] ), ( 'few dates', argparse.Namespace( flow='apple_music_streams', start_date=datetime.date(2024, 11, 1), end_date=datetime.date(2024, 11, 3), ), [ datetime.date(2024, 11, 1), datetime.date(2024, 11, 2), datetime.date(2024, 11, 3), ] ), ( 'many dates, close to limit', argparse.Namespace( flow='apple_music_streams', start_date=datetime.date(2024, 11, 1), end_date=datetime.date(2024, 11, 5), ), [ datetime.date(2024, 11, 1), datetime.date(2024, 11, 2), datetime.date(2024, 11, 3), datetime.date(2024, 11, 4), datetime.date(2024, 11, 5), ] ), ( 'end_date before date', argparse.Namespace( flow='apple_music_streams', start_date=datetime.date(2024, 11, 2), end_date=datetime.date(2024, 11, 1), ), [ datetime.date(2024, 11, 2), datetime.date(2024, 11, 1), ] ), ] ) def test_generate_dates(self, case_name, args, expected): try: self.flow_exec.args = args dates = list(self.flow_exec.generate_dates()) assert dates == expected except BaseException as e: if not (isinstance(expected, type) and isinstance(e, expected)): raise