From c8250a29ffbac391cc880355255de9e857f26167 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sat, 13 Aug 2022 22:01:39 +0300 Subject: [PATCH 01/10] test: add session to all test tasks --- rocketry/test/condition/task/test_basic.py | 12 +- rocketry/test/condition/task/test_compare.py | 3 +- rocketry/test/condition/task/test_time.py | 15 +- .../condition/task/test_time_executable.py | 6 +- .../condition/task/test_time_optimized.py | 18 +- .../test/condition/task/test_time_runnable.py | 3 +- rocketry/test/condition/test_meta.py | 2 +- rocketry/test/schedule/process/test_core.py | 31 +- rocketry/test/schedule/test_conditions.py | 3 +- rocketry/test/schedule/test_core.py | 276 ++++++++-------- rocketry/test/schedule/test_failure.py | 12 +- rocketry/test/schedule/test_from_scripts.py | 3 +- rocketry/test/schedule/test_piping.py | 13 +- .../schedule/test_scheduler_conditions.py | 18 +- rocketry/test/schedule/test_terminate.py | 13 +- rocketry/test/schedule/test_traceback.py | 2 +- rocketry/test/session/params/test_func.py | 15 +- rocketry/test/session/params/test_params.py | 4 +- rocketry/test/session/params/test_return.py | 23 +- rocketry/test/session/test_core.py | 9 +- rocketry/test/session/test_run.py | 14 +- rocketry/test/session/test_utils.py | 8 +- rocketry/test/task/code/test_construct.py | 10 +- rocketry/test/task/command/test_run.py | 12 +- rocketry/test/task/func/test_construct.py | 174 +++++----- rocketry/test/task/func/test_logging.py | 297 +++++++++--------- rocketry/test/task/func/test_run.py | 168 +++++----- rocketry/test/task/func/test_run_delayed.py | 21 +- rocketry/test/task/misc/test_restart.py | 6 +- rocketry/test/task/misc/test_shutdown.py | 8 +- rocketry/test/task/test_core.py | 9 +- rocketry/test/task/test_pickle.py | 6 +- rocketry/test/test_hooks.py | 10 +- 33 files changed, 622 insertions(+), 602 deletions(-) diff --git a/rocketry/test/condition/task/test_basic.py b/rocketry/test/condition/task/test_basic.py index ea23df31..e8dbfb1d 100644 --- a/rocketry/test/condition/task/test_basic.py +++ b/rocketry/test/condition/task/test_basic.py @@ -134,13 +134,15 @@ def test_task_depend_fail(tmpdir, session, cls, expected): depend_task = FuncTask( run_task, name="prerequisite task", - execution="main" + execution="main", + session=session ) task = FuncTask( run_task, name="runned task", - execution="main" + execution="main", + session=session ) # ------------------------ t0 @@ -200,13 +202,15 @@ def test_task_depend_success(tmpdir, session, cls, expected): depend_task = FuncTask( run_task, name="prerequisite task", - execution="main" + execution="main", + session=session ) task = FuncTask( run_task, name="runned task", - execution="main" + execution="main", + session=session ) # ------------------------ t0 diff --git a/rocketry/test/condition/task/test_compare.py b/rocketry/test/condition/task/test_compare.py index 871da8ca..d7feccfb 100644 --- a/rocketry/test/condition/task/test_compare.py +++ b/rocketry/test/condition/task/test_compare.py @@ -18,7 +18,8 @@ def test_task_finish_compare(tmpdir, session): task = FuncTask( run_task, name="runned task", - execution="main" + execution="main", + session=session ) # Has not yet ran diff --git a/rocketry/test/condition/task/test_time.py b/rocketry/test/condition/task/test_time.py index ae9c103b..adc3f03c 100644 --- a/rocketry/test/condition/task/test_time.py +++ b/rocketry/test/condition/task/test_time.py @@ -21,7 +21,7 @@ from rocketry.tasks import FuncTask -def setup_task_state(mock_datetime_now, logs:List[Tuple[str, str]], time_after=None, task=None): +def setup_task_state(mock_datetime_now, logs:List[Tuple[str, str]], time_after=None, task=None, session=None): """A mock up that sets up a task to test the condition with given logs @@ -39,7 +39,8 @@ def setup_task_state(mock_datetime_now, logs:List[Tuple[str, str]], time_after=N task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) for log in logs: @@ -147,7 +148,7 @@ def setup_task_state(mock_datetime_now, logs:List[Tuple[str, str]], time_after=N ) def test_running(mock_datetime_now, logs, time_after, get_condition, outcome, session): session.config.force_status_from_logs = True - task = setup_task_state(mock_datetime_now, logs, time_after) + task = setup_task_state(mock_datetime_now, logs, time_after, session=session) cond = get_condition() if outcome: assert cond.observe(session=session) @@ -211,7 +212,7 @@ def test_running(mock_datetime_now, logs, time_after, get_condition, outcome, se ) def test_started(tmpdir, mock_datetime_now, logs, time_after, get_condition, outcome, session): session.config.force_status_from_logs = True - setup_task_state(mock_datetime_now, logs, time_after) + setup_task_state(mock_datetime_now, logs, time_after, session=session) cond = get_condition() if outcome: assert cond.observe(session=session) @@ -313,7 +314,7 @@ def test_started(tmpdir, mock_datetime_now, logs, time_after, get_condition, out ) def test_finish(tmpdir, mock_datetime_now, logs, time_after, get_condition, outcome, session): session.config.force_status_from_logs = True - setup_task_state(mock_datetime_now, logs, time_after) + setup_task_state(mock_datetime_now, logs, time_after, session=session) cond = get_condition() if outcome: assert cond.observe(session=session) @@ -409,7 +410,7 @@ def test_finish(tmpdir, mock_datetime_now, logs, time_after, get_condition, outc ) def test_success(tmpdir, mock_datetime_now, logs, time_after, get_condition, outcome, session): session.config.force_status_from_logs = True - setup_task_state(mock_datetime_now, logs, time_after) + setup_task_state(mock_datetime_now, logs, time_after, session=session) cond = get_condition() if outcome: assert cond.observe(session=session) @@ -505,7 +506,7 @@ def test_success(tmpdir, mock_datetime_now, logs, time_after, get_condition, out ) def test_fail(mock_datetime_now, logs, time_after, get_condition, outcome, session): session.config.force_status_from_logs = True - setup_task_state(mock_datetime_now, logs, time_after) + setup_task_state(mock_datetime_now, logs, time_after, session=session) cond = get_condition() if outcome: assert cond.observe(session=session) diff --git a/rocketry/test/condition/task/test_time_executable.py b/rocketry/test/condition/task/test_time_executable.py index 9312aaf9..7eed25ea 100644 --- a/rocketry/test/condition/task/test_time_executable.py +++ b/rocketry/test/condition/task/test_time_executable.py @@ -189,7 +189,8 @@ def to_epoch(dt): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) condition = get_condition() @@ -260,7 +261,8 @@ def test_periods(mock_datetime_now, logs, time_after, get_condition, outcome, se task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) condition = get_condition() diff --git a/rocketry/test/condition/task/test_time_optimized.py b/rocketry/test/condition/task/test_time_optimized.py index cb6b501b..acaf6b6b 100644 --- a/rocketry/test/condition/task/test_time_optimized.py +++ b/rocketry/test/condition/task/test_time_optimized.py @@ -35,7 +35,8 @@ def test_logs_not_used_false(session, cls, mock_datetime_now): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) logs = [ ("2021-01-01 12:00:00", state) @@ -56,7 +57,8 @@ def test_logs_not_used_true(session, cls, mock_datetime_now): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) for attr in ("last_run", "last_success", "last_fail", "last_inaction", "last_terminate"): setattr(task, attr, to_datetime("2000-01-01 12:00:00")) @@ -76,7 +78,8 @@ def test_logs_not_used_true_inside_period(session, cls, mock_datetime_now): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) for attr in ("last_run", "last_success", "last_fail", "last_inaction", "last_terminate"): setattr(task, attr, to_datetime("2000-01-01 12:00:00")) @@ -99,7 +102,8 @@ def test_logs_not_used_false_outside_period(session, cls, mock_datetime_now): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) for attr in ("last_run", "last_success", "last_fail", "last_inaction", "last_terminate"): setattr(task, attr, to_datetime("2000-01-01 05:00:00")) @@ -120,7 +124,8 @@ def test_logs_not_used_equal_zero(session, cls, mock_datetime_now): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) logs = [ ("2021-01-01 12:00:00", state) @@ -141,7 +146,8 @@ def test_logs_used(session, cls, mock_datetime_now): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) logs = [ ("2021-01-01 12:00:00", state) diff --git a/rocketry/test/condition/task/test_time_runnable.py b/rocketry/test/condition/task/test_time_runnable.py index 48e14244..a2c4837c 100644 --- a/rocketry/test/condition/task/test_time_runnable.py +++ b/rocketry/test/condition/task/test_time_runnable.py @@ -89,7 +89,8 @@ def to_epoch(dt): task = FuncTask( lambda:None, name="the task", - execution="main" + execution="main", + session=session ) condition = get_condition() diff --git a/rocketry/test/condition/test_meta.py b/rocketry/test/condition/test_meta.py index e1acce5b..438a67dd 100644 --- a/rocketry/test/condition/test_meta.py +++ b/rocketry/test/condition/test_meta.py @@ -24,7 +24,7 @@ def test_taskcond_true(session, execution): cond = TaskCond(syntax=re.compile(r"is foo (?P.+)"), start_cond="every 1 min", active_time="past 10 seconds", execution=execution, session=session) cond(is_foo) - task = FuncTask(lambda: None, start_cond="is foo true", name="a task", execution="main") + task = FuncTask(lambda: None, start_cond="is foo true", name="a task", execution="main", session=session) # Test that there is only one more cond parser assert len(session._cond_parsers) == N_PARSERS + 1 diff --git a/rocketry/test/schedule/process/test_core.py b/rocketry/test/schedule/process/test_core.py index 0fc78808..c666d268 100644 --- a/rocketry/test/schedule/process/test_core.py +++ b/rocketry/test/schedule/process/test_core.py @@ -14,21 +14,16 @@ def run_creating_child(): proc = multiprocessing.Process(target=run_succeeding, daemon=True) proc.start() -def test_creating_child(tmpdir, session): - with tmpdir.as_cwd() as old_dir: - - # To be confident the scheduler won't lie to us - # we test the task execution with a job that has - # actual measurable impact outside rocketry - FuncTask(run_creating_child, name="task_1", start_cond=AlwaysTrue()) - - session.config.tasks_as_daemon = False - session.config.shut_cond = (TaskStarted(task="task_1") >= 1) | ~SchedulerStarted(period=TimeDelta("1 second")) - - - session.start() - - logger = session.get_task("task_1").logger - assert 1 == logger.filter_by(action="run").count() - assert 1 == logger.filter_by(action="success").count() - assert 0 == logger.filter_by(action="fail").count() +def test_creating_child(session): + + FuncTask(run_creating_child, name="task_1", start_cond=AlwaysTrue(), session=session) + + session.config.tasks_as_daemon = False + session.config.shut_cond = (TaskStarted(task="task_1") >= 1) | ~SchedulerStarted(period=TimeDelta("1 second")) + + session.start() + + logger = session["task_1"].logger + assert 1 == logger.filter_by(action="run").count() + assert 1 == logger.filter_by(action="success").count() + assert 0 == logger.filter_by(action="fail").count() diff --git a/rocketry/test/schedule/test_conditions.py b/rocketry/test/schedule/test_conditions.py index 31048d48..034f99da 100644 --- a/rocketry/test/schedule/test_conditions.py +++ b/rocketry/test/schedule/test_conditions.py @@ -25,7 +25,8 @@ def is_true(): run_succeeding, start_cond=true & is_true, name="task success", - execution=execution + execution=execution, + session=session ) session.config.shut_cond = TaskStarted(task=task_success) >= 1 diff --git a/rocketry/test/schedule/test_core.py b/rocketry/test/schedule/test_core.py index 98425e64..c41bc08b 100644 --- a/rocketry/test/schedule/test_core.py +++ b/rocketry/test/schedule/test_core.py @@ -88,7 +88,7 @@ def test_task_execution(tmpdir, execution, func, session): # To be confident the scheduler won't lie to us # we test the task execution with a job that has # actual measurable impact outside rocketry - FuncTask(func, name="add line to file", start_cond=AlwaysTrue(), execution=execution), + FuncTask(func, name="add line to file", start_cond=AlwaysTrue(), execution=execution, session=session), session.config.shut_cond = (TaskStarted(task="add line to file") >= 3) | ~SchedulerStarted(period=TimeDelta("5 second")) @@ -129,59 +129,58 @@ def test_task_log(tmpdir, execution, task_func, run_count, fail_count, success_c issues with logging. """ - with tmpdir.as_cwd() as old_dir: - # Set session (and logging) - session = Session(config={"debug": True, "silence_task_prerun": False}) - rocketry.session = session - session.set_as_default() - - task_logger = logging.getLogger(session.config.task_logger_basename) - task_logger.handlers = [ - get_handler() - ] + # Set session (and logging) + session = Session(config={"debug": True, "silence_task_prerun": False}) + rocketry.session = session + session.set_as_default() - task = FuncTask(task_func, name="mytask", start_cond=AlwaysTrue(), execution=execution) + task_logger = logging.getLogger(session.config.task_logger_basename) + task_logger.handlers = [ + get_handler() + ] - session.config.shut_cond = (TaskStarted(task="mytask") >= run_count) | ~SchedulerStarted(period=TimeDelta("10 second")) - session.start() + task = FuncTask(task_func, name="mytask", start_cond=AlwaysTrue(), execution=execution, session=session) - assert (TaskStarted(task="mytask") >= run_count).observe(session=session) + session.config.shut_cond = (TaskStarted(task="mytask") >= run_count) | ~SchedulerStarted(period=TimeDelta("10 second")) + session.start() - # Test history - history = list(task.logger.get_records()) - logger = task.logger - assert run_count == logger.filter_by(action="run").count() - assert success_count == logger.filter_by(action="success").count() - assert fail_count == logger.filter_by(action="fail").count() - assert inact_count == logger.filter_by(action="inaction").count() - - # Test relevant log items - for record in history: - if not isinstance(record, dict): - record = record.dict() - assert record["task_name"] == "mytask" - assert isinstance(record["created"], float) - assert isinstance(record["start"], datetime.datetime) - if record["action"] != "run": - assert isinstance(record["end"], datetime.datetime) - assert isinstance(record["runtime"], datetime.timedelta) - - # Test traceback - if record["action"] == "fail": - assert re.match( - r'Traceback \(most recent call last\):\n File ".+", line [0-9]+, in [\s\S]+, in run_failing\n raise RuntimeError\("Task failed"\)\nRuntimeError: Task failed', - record["exc_text"] - ) - - # Test some other relevant APIs - assert history == list(task.logger.get_records()) - assert history[-1] == task.logger.get_latest() - assert history == list(session.get_task_log()) - - assert run_count == len(list(task.logger.get_records(action="run"))) - assert success_count == len(list(task.logger.get_records(action="success"))) - assert fail_count == len(list(task.logger.get_records(action="fail"))) - assert inact_count == len(list(task.logger.get_records(action="inaction"))) + assert (TaskStarted(task="mytask") >= run_count).observe(session=session) + + # Test history + history = list(task.logger.get_records()) + logger = task.logger + assert run_count == logger.filter_by(action="run").count() + assert success_count == logger.filter_by(action="success").count() + assert fail_count == logger.filter_by(action="fail").count() + assert inact_count == logger.filter_by(action="inaction").count() + + # Test relevant log items + for record in history: + if not isinstance(record, dict): + record = record.dict() + assert record["task_name"] == "mytask" + assert isinstance(record["created"], float) + assert isinstance(record["start"], datetime.datetime) + if record["action"] != "run": + assert isinstance(record["end"], datetime.datetime) + assert isinstance(record["runtime"], datetime.timedelta) + + # Test traceback + if record["action"] == "fail": + assert re.match( + r'Traceback \(most recent call last\):\n File ".+", line [0-9]+, in [\s\S]+, in run_failing\n raise RuntimeError\("Task failed"\)\nRuntimeError: Task failed', + record["exc_text"] + ) + + # Test some other relevant APIs + assert history == list(task.logger.get_records()) + assert history[-1] == task.logger.get_latest() + assert history == list(session.get_task_log()) + + assert run_count == len(list(task.logger.get_records(action="run"))) + assert success_count == len(list(task.logger.get_records(action="success"))) + assert fail_count == len(list(task.logger.get_records(action="fail"))) + assert inact_count == len(list(task.logger.get_records(action="inaction"))) @pytest.mark.parametrize("mode", ["use logs", "use cache"]) @pytest.mark.parametrize("func_type", ["sync", "async"]) @@ -194,28 +193,32 @@ def test_task_status(session, execution, func_type, mode): start_cond=true, name="task success", execution=execution, - priority=0 + priority=0, + session=session ) task_fail = FuncTask( run_failing if func_type == "sync" else run_failing_async, start_cond=true, name="task fail", execution=execution, - priority=0 + priority=0, + session=session ) task_inact = FuncTask( run_inacting if func_type == "sync" else run_inacting_async, start_cond=true, name="task inact", execution=execution, - priority=100 + priority=100, + session=session ) task_not_run = FuncTask( run_inacting if func_type == "sync" else run_inacting_async, start_cond=false, name="task not run", execution=execution, - priority=0 + priority=0, + session=session ) session.config.shut_cond = (TaskStarted(task="task inact") >= 3) | ~SchedulerStarted(period=TimeDelta("20 second")) session.start() @@ -259,24 +262,24 @@ def test_task_status(session, execution, func_type, mode): assert 3 == task_inact.logger.filter_by(action="inaction").count() @pytest.mark.parametrize("execution", ["main", "thread", "process"]) -def test_task_force_run(tmpdir, execution, session): - with tmpdir.as_cwd() as old_dir: - task = FuncTask( - run_succeeding, - start_cond=AlwaysFalse(), - name="task", - execution=execution - ) - task.force_run = True +def test_task_force_run(execution, session): + task = FuncTask( + run_succeeding, + start_cond=AlwaysFalse(), + name="task", + execution=execution, + session=session + ) + task.force_run = True - session.config.shut_cond = SchedulerCycles() >= 5 - session.start() + session.config.shut_cond = SchedulerCycles() >= 5 + session.start() - logger = task.logger - assert 1 == logger.filter_by(action="run").count() + logger = task.logger + assert 1 == logger.filter_by(action="run").count() - # The force_run should have reseted as it should have run once - assert not task.force_run + # The force_run should have reseted as it should have run once + assert not task.force_run @pytest.mark.parametrize("execution", ["main", "thread", "process"]) @@ -313,7 +316,8 @@ def test_task_force_disabled(tmpdir, execution, session): run_succeeding, start_cond=AlwaysFalse(), name="task", - execution=execution + execution=execution, + session=session ) task.disabled = True task.force_run = True @@ -329,47 +333,45 @@ def test_task_force_disabled(tmpdir, execution, session): assert not task.force_run # This should be reseted @pytest.mark.parametrize("execution", ["main", "thread", "process"]) -def test_priority(tmpdir, execution, session): - with tmpdir.as_cwd() as old_dir: +def test_priority(execution, session): - task_1 = FuncTask(run_succeeding, name="1", priority=100, start_cond=AlwaysTrue(), execution=execution) - task_3 = FuncTask(run_failing, name="3", priority=10, start_cond=AlwaysTrue(), execution=execution) - task_2 = FuncTask(run_failing, name="2", priority=50, start_cond=AlwaysTrue(), execution=execution) - task_4 = FuncTask(run_failing, name="4", start_cond=AlwaysTrue(), execution=execution) + task_1 = FuncTask(run_succeeding, name="1", priority=100, start_cond=AlwaysTrue(), execution=execution, session=session) + task_3 = FuncTask(run_failing, name="3", priority=10, start_cond=AlwaysTrue(), execution=execution, session=session) + task_2 = FuncTask(run_failing, name="2", priority=50, start_cond=AlwaysTrue(), execution=execution, session=session) + task_4 = FuncTask(run_failing, name="4", start_cond=AlwaysTrue(), execution=execution, session=session) - assert 0 == task_4.priority + assert 0 == task_4.priority - session.config.shut_cond = (SchedulerCycles() == 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) + session.config.shut_cond = (SchedulerCycles() == 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) - session.start() - assert session.scheduler.n_cycles == 1 + session.start() + assert session.scheduler.n_cycles == 1 - task_1_start = list(task_1.logger.get_records())[0].created - task_2_start = list(task_2.logger.get_records())[0].created - task_3_start = list(task_3.logger.get_records())[0].created - task_4_start = list(task_4.logger.get_records())[0].created - - assert task_1_start < task_2_start < task_3_start < task_4_start + task_1_start = list(task_1.logger.get_records())[0].created + task_2_start = list(task_2.logger.get_records())[0].created + task_3_start = list(task_3.logger.get_records())[0].created + task_4_start = list(task_4.logger.get_records())[0].created + + assert task_1_start < task_2_start < task_3_start < task_4_start @pytest.mark.parametrize("execution", ["main", "thread", "process"]) -def test_pass_params_as_global(tmpdir, execution, session): +def test_pass_params_as_global(execution, session): # thread-Parameters has been observed to fail rarely - with tmpdir.as_cwd() as old_dir: - task = FuncTask(run_with_param, name="parametrized", start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(run_with_param, name="parametrized", start_cond=AlwaysTrue(), execution=execution, session=session) - session.config.shut_cond = (TaskStarted(task="parametrized") >= 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) + session.config.shut_cond = (TaskStarted(task="parametrized") >= 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) - # Passing global parameters - session.parameters["int_5"] = 5 - session.parameters["extra_param"] = "something" + # Passing global parameters + session.parameters["int_5"] = 5 + session.parameters["extra_param"] = "something" - session.scheduler() + session.scheduler() - logger = task.logger - assert 1 == logger.filter_by(action="run").count() - assert 1 == logger.filter_by(action="success").count() - assert 0 == logger.filter_by(action="fail").count() + logger = task.logger + assert 1 == logger.filter_by(action="run").count() + assert 1 == logger.filter_by(action="success").count() + assert 0 == logger.filter_by(action="fail").count() @pytest.mark.parametrize("parameters", [ pytest.param({"int_5": 5}, id="dict"), @@ -377,48 +379,48 @@ def test_pass_params_as_global(tmpdir, execution, session): pytest.param(Parameters(int_5=Private(5)), id="Parameter with secret"), ]) @pytest.mark.parametrize("execution", ["main", "thread", "process"]) -def test_pass_params_as_local(tmpdir, execution, parameters, session): - with tmpdir.as_cwd() as old_dir: +def test_pass_params_as_local(execution, parameters, session): - task = FuncTask( - run_with_param, - name="parametrized", - parameters=parameters, - start_cond=AlwaysTrue(), - execution=execution - ) - session.config.shut_cond = (TaskStarted(task="parametrized") >= 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) + task = FuncTask( + run_with_param, + name="parametrized", + parameters=parameters, + start_cond=AlwaysTrue(), + execution=execution, + session=session + ) + session.config.shut_cond = (TaskStarted(task="parametrized") >= 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) - session.start() + session.start() - logger = task.logger - assert 1 == logger.filter_by(action="run").count() - assert 1 == logger.filter_by(action="success").count() - assert 0 == logger.filter_by(action="fail").count() + logger = task.logger + assert 1 == logger.filter_by(action="run").count() + assert 1 == logger.filter_by(action="success").count() + assert 0 == logger.filter_by(action="fail").count() @pytest.mark.parametrize("execution", ["main", "thread", "process"]) -def test_pass_params_as_local_and_global(tmpdir, execution, session): - with tmpdir.as_cwd() as old_dir: +def test_pass_params_as_local_and_global(execution, session): - task = FuncTask( - run_with_param, - name="parametrized", - parameters={"int_5": 5}, - start_cond=AlwaysTrue(), - execution=execution - ) + task = FuncTask( + run_with_param, + name="parametrized", + parameters={"int_5": 5}, + start_cond=AlwaysTrue(), + execution=execution, + session=session + ) - session.config.shut_cond = (TaskStarted(task="parametrized") >= 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) + session.config.shut_cond = (TaskStarted(task="parametrized") >= 1) | ~SchedulerStarted(period=TimeDelta("2 seconds")) - # Additional parameters - session.parameters["extra_param"] = "something" + # Additional parameters + session.parameters["extra_param"] = "something" - session.start() + session.start() - logger = task.logger - assert 1 == logger.filter_by(action="run").count() - assert 1 == logger.filter_by(action="success").count() - assert 0 == logger.filter_by(action="fail").count() + logger = task.logger + assert 1 == logger.filter_by(action="run").count() + assert 1 == logger.filter_by(action="success").count() + assert 0 == logger.filter_by(action="fail").count() # Only needed for testing start up and shutdown @@ -434,8 +436,8 @@ def create_line_to_shutdown(): def test_startup_shutdown(tmpdir, execution, session): with tmpdir.as_cwd() as old_dir: - FuncTask(create_line_to_startup_file, name="startup", on_startup=True, execution=execution) - FuncTask(create_line_to_shutdown, name="shutdown", on_shutdown=True, execution=execution) + FuncTask(create_line_to_startup_file, name="startup", on_startup=True, execution=execution, session=session) + FuncTask(create_line_to_shutdown, name="shutdown", on_shutdown=True, execution=execution, session=session) session.config.shut_cond = AlwaysTrue() @@ -472,10 +474,10 @@ def test_logging_repo(tmpdir, execution): with tmpdir.as_cwd() as old_dir: - task_1 = FuncTask(run_succeeding, name="1", priority=100, start_cond=AlwaysTrue(), execution=execution) - task_3 = FuncTask(run_failing, name="3", priority=10, start_cond=AlwaysTrue(), execution=execution) - task_2 = FuncTask(run_failing, name="2", priority=50, start_cond=AlwaysTrue(), execution=execution) - task_4 = FuncTask(run_failing, name="4", start_cond=AlwaysTrue(), execution=execution) + task_1 = FuncTask(run_succeeding, name="1", priority=100, start_cond=AlwaysTrue(), execution=execution, session=session) + task_3 = FuncTask(run_failing, name="3", priority=10, start_cond=AlwaysTrue(), execution=execution, session=session) + task_2 = FuncTask(run_failing, name="2", priority=50, start_cond=AlwaysTrue(), execution=execution, session=session) + task_4 = FuncTask(run_failing, name="4", start_cond=AlwaysTrue(), execution=execution, session=session) assert 0 == task_4.priority @@ -497,7 +499,7 @@ def test_instant_shutdown(execution, session): func = {"async": run_slow_async, "thread": run_slow_thread, "process": run_slow}[execution] - task = FuncTask(func, execution=execution, start_cond=true, end_cond=SchedulerCycles() == 2) + task = FuncTask(func, execution=execution, start_cond=true, end_cond=SchedulerCycles() == 2, session=session) session.config.shut_cond = SchedulerCycles() == 2 diff --git a/rocketry/test/schedule/test_failure.py b/rocketry/test/schedule/test_failure.py index 02da2bd3..b86aa09c 100644 --- a/rocketry/test/schedule/test_failure.py +++ b/rocketry/test/schedule/test_failure.py @@ -56,7 +56,7 @@ def do_stuff_with_arg(arg): ) def test_param_failure(tmpdir, execution, session, fail_in): session.config.silence_task_prerun = True # Prod setting - task = FuncTask(do_stuff_with_arg, name="a task", parameters={"arg": FailingArgument(fail_in)}, start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(do_stuff_with_arg, name="a task", parameters={"arg": FailingArgument(fail_in)}, start_cond=AlwaysTrue(), execution=execution, session=session) session.config.shut_cond = (TaskStarted(task="a task") >= 1) | ~SchedulerStarted(period=TimeDelta("5 second")) session.start() @@ -80,7 +80,7 @@ def test_session_param_failure(tmpdir, execution, session, fail_in): session.config.silence_task_prerun = True # Prod setting session.parameters["arg"] = FailingArgument(fail_in) - task = FuncTask(do_stuff_with_arg, name="a task", start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(do_stuff_with_arg, name="a task", start_cond=AlwaysTrue(), execution=execution, session=session) session.config.shut_cond = (TaskStarted(task="a task") >= 1) | ~SchedulerStarted(period=TimeDelta("5 second")) session.start() @@ -104,7 +104,7 @@ def test_session_param_failure(tmpdir, execution, session, fail_in): ) def test_raise_param_failure(execution, session, fail_in): session.config.silence_task_prerun = False - task = FuncTask(do_stuff_with_arg, name="a task", parameters={"arg": FailingArgument(fail_in)}, start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(do_stuff_with_arg, name="a task", parameters={"arg": FailingArgument(fail_in)}, start_cond=AlwaysTrue(), execution=execution, session=session) session.config.shut_cond = (TaskStarted(task="a task") >= 1) | ~SchedulerStarted(period=TimeDelta("5 second")) with pytest.raises(RuntimeError): @@ -113,7 +113,7 @@ def test_raise_param_failure(execution, session, fail_in): @pytest.mark.parametrize("execution", ["main", "thread", "process"]) def test_raise_task_cond_failure(execution, session): session.config.silence_cond_check = False - task = FuncTask(do_stuff, name="a task", start_cond=FailingCondition(), execution=execution) + task = FuncTask(do_stuff, name="a task", start_cond=FailingCondition(), execution=execution, session=session) session.config.shut_cond = ~SchedulerStarted(period=TimeDelta("5 second")) @@ -124,7 +124,7 @@ def test_raise_task_cond_failure(execution, session): @pytest.mark.parametrize("execution", ["main", "thread", "process"]) def test_raise_sched_cond_failure(execution, session): session.config.silence_cond_check = False - task = FuncTask(do_stuff, name="a task", execution=execution) + task = FuncTask(do_stuff, name="a task", execution=execution, session=session) session.config.shut_cond = FailingCondition() @@ -146,7 +146,7 @@ def test_silence_task_cond_failure(execution, session): def test_silence_sched_cond_failure(execution, session): # Failing shut_cond crashes also with silence_cond_check = True session.config.silence_cond_check = True - task = FuncTask(do_stuff, name="a task", execution=execution) + task = FuncTask(do_stuff, name="a task", execution=execution, session=session) session.config.shut_cond = FailingCondition() with pytest.raises(RuntimeError): diff --git a/rocketry/test/schedule/test_from_scripts.py b/rocketry/test/schedule/test_from_scripts.py index 428a1116..e675c5a3 100644 --- a/rocketry/test/schedule/test_from_scripts.py +++ b/rocketry/test/schedule/test_from_scripts.py @@ -42,7 +42,8 @@ def test_run(tmpdir, script_files, script_path, expected_outcome, exc_cls, execu path=script_path, name="a task", start_cond=AlwaysTrue(), - execution=execution + execution=execution, + session=session ) session.config.shut_cond = (TaskStarted(task="a task") >= 3) | ~SchedulerStarted(period=TimeDelta("15 seconds")) diff --git a/rocketry/test/schedule/test_piping.py b/rocketry/test/schedule/test_piping.py index 45baa9df..5148cf72 100644 --- a/rocketry/test/schedule/test_piping.py +++ b/rocketry/test/schedule/test_piping.py @@ -28,26 +28,29 @@ def test_dependent(tmpdir, execution, session): with tmpdir.as_cwd() as old_dir: # Running the master tasks only once - task_a = FuncTask(run_succeeding, name="A", start_cond=~TaskStarted(), execution=execution) - task_b = FuncTask(run_succeeding, name="B", start_cond=~TaskStarted(), execution=execution) + task_a = FuncTask(run_succeeding, name="A", start_cond=~TaskStarted(), execution=execution, session=session) + task_b = FuncTask(run_succeeding, name="B", start_cond=~TaskStarted(), execution=execution, session=session) task_after_a = FuncTask( run_succeeding, name="After A", start_cond=DependSuccess(depend_task="A"), - execution=execution + execution=execution, + session=session ) task_after_b = FuncTask( run_succeeding, name="After B", start_cond=DependSuccess(depend_task="B"), - execution=execution + execution=execution, + session=session ) task_after_all = FuncTask( run_succeeding, name="After all", start_cond=DependSuccess(depend_task="After A") & DependSuccess(depend_task="After B"), - execution=execution + execution=execution, + session=session ) session.config.shut_cond = (TaskStarted(task="After all") >= 1) | ~SchedulerStarted(period=TimeDelta("10 seconds")) diff --git a/rocketry/test/schedule/test_scheduler_conditions.py b/rocketry/test/schedule/test_scheduler_conditions.py index 762c7a93..c8006310 100644 --- a/rocketry/test/schedule/test_scheduler_conditions.py +++ b/rocketry/test/schedule/test_scheduler_conditions.py @@ -3,18 +3,16 @@ from rocketry.time import TimeDelta from rocketry.conditions import SchedulerCycles, SchedulerStarted -def test_scheduler_started(tmpdir, session): - with tmpdir.as_cwd() as old_dir: +def test_scheduler_started(session): - session.config.shut_cond = ~SchedulerStarted(period=TimeDelta("1 second")) - session.start() + session.config.shut_cond = ~SchedulerStarted(period=TimeDelta("1 second")) + session.start() - assert session.scheduler.n_cycles > 1 + assert session.scheduler.n_cycles > 1 -def test_scheduler_cycles(tmpdir, session): - with tmpdir.as_cwd() as old_dir: +def test_scheduler_cycles(session): - session.config.shut_cond = SchedulerCycles() >= 4 - session.start() + session.config.shut_cond = SchedulerCycles() >= 4 + session.start() - assert session.scheduler.n_cycles == 4 \ No newline at end of file + assert session.scheduler.n_cycles == 4 \ No newline at end of file diff --git a/rocketry/test/schedule/test_terminate.py b/rocketry/test/schedule/test_terminate.py index ad27c138..e3b0f09e 100644 --- a/rocketry/test/schedule/test_terminate.py +++ b/rocketry/test/schedule/test_terminate.py @@ -44,11 +44,10 @@ def get_slow_func(execution): @pytest.mark.parametrize("execution", ["async", "thread", "process"]) def test_without_timeout(tmpdir, execution, session): """Test the task.timeout is respected overt scheduler.timeout""" - # TODO: There is probably better ways to test this with tmpdir.as_cwd() as old_dir: func_run_slow = get_slow_func(execution) - task = FuncTask(func_run_slow, name="slow task but passing", start_cond=AlwaysTrue(), timeout="never", execution=execution) + task = FuncTask(func_run_slow, name="slow task but passing", start_cond=AlwaysTrue(), timeout="never", execution=execution, session=session) session.config.shut_cond = (TaskFinished(task="slow task but passing") >= 2) | ~SchedulerStarted(period=TimeDelta("5 seconds")) session.config.timeout = 0.1 @@ -71,7 +70,7 @@ def test_task_timeout_set_in_session(tmpdir, execution, session): func_run_slow = get_slow_func(execution) - task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), execution=execution, session=session) session.config.shut_cond = (TaskStarted(task="slow task") >= 2) | ~SchedulerStarted(period=TimeDelta("5 seconds")) session.config.timeout = 0.1 @@ -93,7 +92,7 @@ def test_task_timeout_set_in_task(tmpdir, execution, session): func_run_slow = get_slow_func(execution) - task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), timeout="0.1 sec", execution=execution) + task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), timeout="0.1 sec", execution=execution, session=session) session.config.shut_cond = (TaskStarted(task="slow task") >= 2) | ~SchedulerStarted(period=TimeDelta("5 seconds")) assert task.timeout == datetime.timedelta(milliseconds=100) @@ -117,9 +116,9 @@ def terminate_task(session=Session()): with tmpdir.as_cwd() as old_dir: func_run_slow = get_slow_func(execution) - task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), execution=execution, session=session) - FuncTask(terminate_task, name="terminator", start_cond=TaskStarted(task="slow task"), execution="main") + FuncTask(terminate_task, name="terminator", start_cond=TaskStarted(task="slow task"), execution="main", session=session) session.config.shut_cond = (TaskStarted(task="slow task") >= 2) | ~SchedulerStarted(period=TimeDelta("5 seconds")) session.start() @@ -143,7 +142,7 @@ def test_task_terminate_end_cond(tmpdir, execution, session): func_run_slow = get_slow_func(execution) - task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), end_cond=TaskStarted(task='slow task'), execution=execution) + task = FuncTask(func_run_slow, name="slow task", start_cond=AlwaysTrue(), end_cond=TaskStarted(task='slow task'), execution=execution, session=session) session.config.shut_cond = (TaskTerminated(task="slow task") >= 1) | ~SchedulerStarted(period=TimeDelta("5 seconds")) session.start() diff --git a/rocketry/test/schedule/test_traceback.py b/rocketry/test/schedule/test_traceback.py index 2921a373..5142f591 100644 --- a/rocketry/test/schedule/test_traceback.py +++ b/rocketry/test/schedule/test_traceback.py @@ -27,7 +27,7 @@ def test_task_fail_traceback(tmpdir, execution, session): task_logger.handlers = [ RepoHandler(repo=MemoryRepo(model=LogRecord)) ] - task = FuncTask(run_failing, name="task", start_cond=AlwaysTrue(), execution=execution) + task = FuncTask(run_failing, name="task", start_cond=AlwaysTrue(), execution=execution, session=session) session.config.shut_cond = (TaskStarted(task="task") >= 3) | ~SchedulerStarted(period=TimeDelta("5 seconds")) session.start() diff --git a/rocketry/test/session/params/test_func.py b/rocketry/test/session/params/test_func.py index f6df5891..19fdc247 100644 --- a/rocketry/test/session/params/test_func.py +++ b/rocketry/test/session/params/test_func.py @@ -32,7 +32,8 @@ def test_simple(session, execution): parameters={"myparam": FuncArg(get_x)}, execution=execution, name="a task", - start_cond=AlwaysTrue() + start_cond=AlwaysTrue(), + session=session ) session.config.shut_cond = (TaskStarted(task="a task") >= 1) @@ -50,7 +51,8 @@ def test_session(session, execution): func_x_with_arg, execution=execution, name="a task", - start_cond=AlwaysTrue() + start_cond=AlwaysTrue(), + session=session ) session.config.shut_cond = (TaskStarted(task="a task") >= 1) @@ -69,7 +71,8 @@ def test_session_with_arg(session, execution): execution=execution, name="a task", parameters={"myparam": Arg('a_param')}, - start_cond=AlwaysTrue() + start_cond=AlwaysTrue(), + session=session ) session.config.shut_cond = (TaskStarted(task="a task") >= 1) @@ -91,7 +94,8 @@ def test_nested(session, execution, materialize, config_mater): func_x_with_arg, execution=execution, name="a task", - start_cond=AlwaysTrue() + start_cond=AlwaysTrue(), + session=session ) session.config.shut_cond = (TaskStarted(task="a task") >= 1) @@ -121,7 +125,8 @@ def test_unpicklable(session, execution): parameters={"myparam": FuncArg(get_unpicklable)}, execution=execution, name="a task", - start_cond=AlwaysTrue() + start_cond=AlwaysTrue(), + session=session ) session.config.shut_cond = (TaskStarted(task="a task") >= 1) diff --git a/rocketry/test/session/params/test_params.py b/rocketry/test/session/params/test_params.py index 2abb99bd..289479af 100644 --- a/rocketry/test/session/params/test_params.py +++ b/rocketry/test/session/params/test_params.py @@ -28,7 +28,7 @@ def test_parametrization_private(session): session.parameters.update({"secret": Private("psst"), "public": "hello", "secret_list": Private([1,2,3])}) - task = FuncTask(run_task, name="a task", execution="main", parameters={"task_secret": Private("hsss"), "task_public": "world"}, force_run=True) + task = FuncTask(run_task, name="a task", execution="main", parameters={"task_secret": Private("hsss"), "task_public": "world"}, force_run=True, session=session) session.config.shut_cond = TaskStarted(task="a task") >= 1 session.start() @@ -41,7 +41,7 @@ def test_params_failure(session): def get_value(): raise RuntimeError("Not working") - task = FuncTask(simple_task_func, parameters={'value': FuncArg(get_value)}, name="a task", execution="main", force_run=True) + task = FuncTask(simple_task_func, parameters={'value': FuncArg(get_value)}, name="a task", execution="main", force_run=True, session=session) assert task.status is None diff --git a/rocketry/test/session/params/test_return.py b/rocketry/test/session/params/test_return.py index 79eab008..53808edc 100644 --- a/rocketry/test/session/params/test_return.py +++ b/rocketry/test/session/params/test_return.py @@ -28,14 +28,16 @@ def test_normal(session, execution): name="return task", start_cond="~has started", execution=execution, - force_run=True + force_run=True, + session=session ) task = FuncTask( func_x_with_arg, name="a task", start_cond="after task 'return task'", parameters={"myparam": Return('return task')}, - execution=execution + execution=execution, + session=session ) assert task.status is None @@ -55,14 +57,16 @@ def test_normal_pass_task(session, execution): name="return task", start_cond="~has started", execution=execution, - force_run=True + force_run=True, + session=session ) task = FuncTask( func_x_with_arg, name="a task", start_cond="after task 'return task'", parameters={"myparam": Return(task_return)}, - execution=execution + execution=execution, + session=session ) assert task.status is None @@ -81,7 +85,8 @@ def test_normal_pass_func(session, execution): name="return task", start_cond="~has started", execution="main", - force_run=True + force_run=True, + session=session ) def func_with_arg_local(): return 'x' @@ -91,7 +96,8 @@ def func_with_arg_local(): name="a task", start_cond="after task 'return task'", parameters={"myparam": Return(func_with_arg_local)}, - execution=execution + execution=execution, + session=session, ) assert task.status is None @@ -113,7 +119,8 @@ def test_missing(session, execution): parameters={"myparam": Return('return task')}, name="a task", force_run=True, - execution=execution + execution=execution, + session=session ) assert task.status is None @@ -127,6 +134,7 @@ def test_default(session, execution): task = FuncTask( func_with_arg, name="return task", + session=session ) task = FuncTask( func_x_with_arg, @@ -134,6 +142,7 @@ def test_default(session, execution): name="a task", execution=execution, force_run=True, + session=session ) assert task.status is None diff --git a/rocketry/test/session/test_core.py b/rocketry/test/session/test_core.py index b31a3d25..ff28c8e4 100644 --- a/rocketry/test/session/test_core.py +++ b/rocketry/test/session/test_core.py @@ -85,7 +85,8 @@ def test_get_task(session): task = FuncTask( lambda : None, name="example", - execution="main" + execution="main", + session=session ) # By string @@ -105,12 +106,14 @@ def test_clear(session): task1 = FuncTask( lambda : None, name="example 1", - execution="main" + execution="main", + session=session ) task2 = FuncTask( lambda : None, name="example 2", - execution="main" + execution="main", + session=session ) session.parameters["x"] = 1 diff --git a/rocketry/test/session/test_run.py b/rocketry/test/session/test_run.py index 0db6cf71..e3aa7b8f 100644 --- a/rocketry/test/session/test_run.py +++ b/rocketry/test/session/test_run.py @@ -5,29 +5,33 @@ def test_run(tmpdir, session): task1 = FuncTask( lambda : None, name="example 1", - execution="main" + execution="main", + session=session, ) task2 = FuncTask( lambda : None, name="example 2", - execution="main" + execution="main", + session=session, ) session.run("example 2") assert task1.status is None assert task2.status == "success" -def test_run_obey_cond(tmpdir, session): +def test_run_obey_cond(session): task1 = FuncTask( lambda : None, name="example 1", - execution="main" + execution="main", + session=session, ) task2 = FuncTask( lambda : None, name="example 2", - execution="main" + execution="main", + session=session, ) session.run("example 2", obey_cond=True) assert task1.status is None diff --git a/rocketry/test/session/test_utils.py b/rocketry/test/session/test_utils.py index a5700986..bf11ed33 100644 --- a/rocketry/test/session/test_utils.py +++ b/rocketry/test/session/test_utils.py @@ -9,10 +9,10 @@ from rocketry.utils.dependencies import Dependencies, Link def test_dependency(session): - ta = FuncTask(lambda: None, name="a", start_cond="daily", execution="main") - tb = FuncTask(lambda: None, name="b", start_cond="after task 'a'", execution="main") - tc = FuncTask(lambda: None, name="c", start_cond="after task 'a' & after task 'b' failed", execution="main") - td = FuncTask(lambda: None, name="d", start_cond="after task 'a' | after task 'b'", execution="main") + ta = FuncTask(lambda: None, name="a", start_cond="daily", execution="main", session=session) + tb = FuncTask(lambda: None, name="b", start_cond="after task 'a'", execution="main", session=session) + tc = FuncTask(lambda: None, name="c", start_cond="after task 'a' & after task 'b' failed", execution="main", session=session) + td = FuncTask(lambda: None, name="d", start_cond="after task 'a' | after task 'b'", execution="main", session=session) te = FuncTask(lambda: None, name="no link", start_cond="daily", execution="main") diff --git a/rocketry/test/task/code/test_construct.py b/rocketry/test/task/code/test_construct.py index 3463178a..2a951cdf 100644 --- a/rocketry/test/task/code/test_construct.py +++ b/rocketry/test/task/code/test_construct.py @@ -16,7 +16,7 @@ def test_construct(session): def main(): ... main() - """), start_cond="daily", name="mytask") + """), start_cond="daily", name="mytask", session=session) assert task.name == "mytask" assert "mytask" in session @@ -26,7 +26,7 @@ def test_construct_missing_name(session): def main(): ... main() - """)) + """), session=session) @pytest.mark.parametrize('execution', ['main', 'thread', 'process']) def test_run_success(session, execution): @@ -36,7 +36,7 @@ def main(): return 'myvalue' return_value = main() - """), execution=execution, name="mytask") + """), execution=execution, name="mytask", session=session) task.force_run = True session.config.shut_cond = TaskStarted(task='mytask') >= 1 @@ -52,7 +52,7 @@ def main(param): return 'myvalue' + param return_value = main(myparam) - """), name="mytask", execution=execution, parameters={'myparam': ' + myparam'}) + """), name="mytask", execution=execution, parameters={'myparam': ' + myparam'}, session=session) task.force_run = True session.config.shut_cond = TaskStarted(task='mytask') >= 1 @@ -74,7 +74,7 @@ def main(): raise RuntimeError('Failed') return_value = main() - """), execution=execution, name="mytask") + """), execution=execution, name="mytask", session=session) task.force_run = True session.config.shut_cond = TaskStarted(task='mytask') >= 1 diff --git a/rocketry/test/task/command/test_run.py b/rocketry/test/task/command/test_run.py index ee9b01b3..f9c339c3 100644 --- a/rocketry/test/task/command/test_run.py +++ b/rocketry/test/task/command/test_run.py @@ -38,7 +38,8 @@ def test_success_command(tmpdir, session, cmd, params, systems,shell, execution) shell=shell, execution="main", parameters=params, - argform="short" + argform="short", + session=session ) assert task.status is None @@ -61,7 +62,8 @@ def test_fail_command(tmpdir, execution, session): command=["python", "--not_an_arg"], name="a task", shell=False, - execution=execution + execution=execution, + session=session ) assert task.status is None @@ -95,7 +97,8 @@ def test_success_bat_file(tmpdir, execution, session): command=["my_command.bat"], name="a task", shell=False, - execution="main" + execution="main", + session=session ) assert task.status is None @@ -120,7 +123,8 @@ def test_success_bash_file(tmpdir, session): command=["/bin/bash", "my_command.sh"], name="a task", shell=False, - execution="main" + execution="main", + session=session ) assert task.status is None diff --git a/rocketry/test/task/func/test_construct.py b/rocketry/test/task/func/test_construct.py index 22041af8..904f3e8f 100644 --- a/rocketry/test/task/func/test_construct.py +++ b/rocketry/test/task/func/test_construct.py @@ -36,7 +36,7 @@ def __call__(self): # Going to tempdir to dump the log files there with tmpdir.as_cwd() as old_dir: # This should always be picklable - task = FuncTask(MyClass(), execution=execution) + task = FuncTask(MyClass(), execution=execution, session=session) assert not task.is_delayed() assert task.status is None assert task.name.endswith("test_construct:MyClass") @@ -51,12 +51,12 @@ def myfunc(): ... assert task.description is None - task = FuncTask(lambda x: x, name="no desc 2", execution="main") + task = FuncTask(lambda x: x, name="no desc 2", execution="main", session=session) assert task.description is None # Test description from doc (decorated) - task = FuncTask(name="has desc 1") + task = FuncTask(name="has desc 1", session=session) @task def myfunc(): "This is func" @@ -65,91 +65,76 @@ def myfunc(): # Test description from doc (normal) def myfunc(): "This is func" - task = FuncTask(myfunc, name="has desc 2") + task = FuncTask(myfunc, name="has desc 2", session=session) assert task.description == "This is func" # Test the description is respected if doc is found def myfunc(): "This is func" - task = FuncTask(myfunc, name="has desc 3", description="But this is preferred") + task = FuncTask(myfunc, name="has desc 3", description="But this is preferred", session=session) assert task.description == "But this is preferred" # Test the description is respected if doc missing def myfunc(): ... - task = FuncTask(myfunc, name="has desc 4", description="This is func") + task = FuncTask(myfunc, name="has desc 4", description="This is func", session=session) assert task.description == "This is func" @pytest.mark.parametrize("execution", ["main", "thread", "process"]) -def test_construct_delayed(tmpdir, session, execution): - - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - task = FuncTask(func_name="myfunc", path="myfile.py", execution=execution) - assert task.status is None - assert task.is_delayed() - assert task.func_name == "myfunc" - assert task.path == Path("myfile.py") - assert task.func is None - -def test_construct_decorate(tmpdir, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - - @FuncTask(start_cond=AlwaysTrue(), name="mytask", execution="main") - def do_stuff(): - pass - - assert isinstance(do_stuff, types.FunctionType) - - do_stuff_task = session["mytask"] - assert isinstance(do_stuff_task, FuncTask) - assert do_stuff_task.status is None - assert do_stuff_task.start_cond == AlwaysTrue() - assert do_stuff_task.name == "mytask" - - assert {do_stuff_task} == session.tasks - -def test_construct_decorate_minimal(tmpdir, session): +def test_construct_delayed(session, execution): + + task = FuncTask(func_name="myfunc", path="myfile.py", execution=execution, session=session) + assert task.status is None + assert task.is_delayed() + assert task.func_name == "myfunc" + assert task.path == Path("myfile.py") + assert task.func is None + +def test_construct_decorate(session): + @FuncTask(start_cond=AlwaysTrue(), name="mytask", execution="main", session=session) + def do_stuff(): + pass + + assert isinstance(do_stuff, types.FunctionType) + + do_stuff_task = session["mytask"] + assert isinstance(do_stuff_task, FuncTask) + assert do_stuff_task.status is None + assert do_stuff_task.start_cond == AlwaysTrue() + assert do_stuff_task.name == "mytask" + + assert {do_stuff_task} == session.tasks + +def test_construct_decorate_minimal(session): """This is an exception when FuncTask returns itself (__init__ cannot return anything else)""" # Going to tempdir to dump the log files there orig_default_exec = session.config.task_execution session.config.task_execution = 'main' try: - with tmpdir.as_cwd() as old_dir: - + with pytest.warns(UserWarning): @FuncTask def do_stuff(): pass - assert isinstance(do_stuff, FuncTask) - assert do_stuff.status is None - assert do_stuff.start_cond == AlwaysFalse() - assert do_stuff.name.endswith(":do_stuff") - - assert {do_stuff} == session.tasks + assert set() == session.tasks finally: session.config.task_execution = orig_default_exec -def test_construct_decorate_default_name(tmpdir, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - +def test_construct_decorate_default_name(session): - @FuncTask(start_cond=AlwaysTrue(), execution="main") - def do_stuff(): - pass - - assert isinstance(do_stuff, types.FunctionType) - do_stuff_task = list(session.tasks)[-1] - assert isinstance(do_stuff_task, FuncTask) - assert do_stuff_task.status is None - assert do_stuff_task.start_cond == AlwaysTrue() - assert do_stuff_task.name.endswith(":do_stuff") + @FuncTask(start_cond=AlwaysTrue(), execution="main", session=session) + def do_stuff(): + pass + + assert isinstance(do_stuff, types.FunctionType) + do_stuff_task = list(session.tasks)[-1] + assert isinstance(do_stuff_task, FuncTask) + assert do_stuff_task.status is None + assert do_stuff_task.start_cond == AlwaysTrue() + assert do_stuff_task.name.endswith(":do_stuff") - assert [do_stuff_task] == list(session.tasks) + assert [do_stuff_task] == list(session.tasks) @pytest.mark.parametrize( "start_cond,depend,expected", @@ -161,18 +146,16 @@ def do_stuff(): id="AlwaysTrue"), ], ) -def test_set_start_condition(tmpdir, start_cond, depend, expected, session): +def test_set_start_condition(start_cond, depend, expected, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task = FuncTask( - lambda : None, - name="task", - start_cond=start_cond, - execution="main", - ) - assert expected == task.start_cond + task = FuncTask( + lambda : None, + name="task", + start_cond=start_cond, + execution="main", + session=session + ) + assert expected == task.start_cond @pytest.mark.parametrize( @@ -184,29 +167,26 @@ def test_set_start_condition(tmpdir, start_cond, depend, expected, session): ) def test_set_start_condition_str(tmpdir, start_cond_str, start_cond, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task = FuncTask( - lambda : None, - name="task", - start_cond=start_cond_str, - execution="main", - ) - assert start_cond() == task.start_cond + task = FuncTask( + lambda : None, + name="task", + start_cond=start_cond_str, + execution="main", + ) + assert start_cond() == task.start_cond - assert str(task.start_cond) == start_cond_str + assert str(task.start_cond) == start_cond_str @pytest.mark.parametrize( "get_task,exc", [ pytest.param( - lambda: FuncTask(lambda : None, name="task", start_cond="this is not valid", execution="main"), + lambda s: FuncTask(lambda : None, name="task", start_cond="this is not valid", execution="main", session=s), ParserError, id="invalid start_cond" ), pytest.param( - lambda: FuncTask(lambda : None, name="task", execution="not valid"), + lambda s: FuncTask(lambda : None, name="task", execution="not valid", session=s), ValueError, id="invalid execution" ), @@ -214,12 +194,12 @@ def test_set_start_condition_str(tmpdir, start_cond_str, start_cond, session): ) def test_failure(session, exc, get_task): with pytest.raises(exc): - get_task() + get_task(session) assert session.tasks == set() def test_rename(session): - task1 = FuncTask(lambda : None, name="a task 1", execution="main") - task2 = FuncTask(lambda : None, name="a task 2", execution="main") + task1 = FuncTask(lambda : None, name="a task 1", execution="main", session=session) + task2 = FuncTask(lambda : None, name="a task 2", execution="main", session=session) assert session.tasks == {task1, task2} assert 'renamed task' not in session assert 'a task 1' in session @@ -231,8 +211,8 @@ def test_rename(session): assert 'a task 1' not in session def test_rename_conflict(session): - task1 = FuncTask(lambda : None, name="a task 1", execution="main") - task2 = FuncTask(lambda : None, name="a task 2", execution="main") + task1 = FuncTask(lambda : None, name="a task 1", execution="main", session=session) + task2 = FuncTask(lambda : None, name="a task 2", execution="main", session=session) assert session.tasks == {task1, task2} assert 'renamed task' not in session assert 'a task 1' in session @@ -246,28 +226,28 @@ def test_rename_conflict(session): def test_existing_raise(session): assert session.config.task_pre_exist == 'raise' - task1 = FuncTask(lambda : None, name="a task", execution="main") + task1 = FuncTask(lambda : None, name="a task", execution="main", session=session) with pytest.raises(ValueError): - task2 = FuncTask(lambda : None, name="a task", execution="main") + task2 = FuncTask(lambda : None, name="a task", execution="main", session=session) assert session.tasks == {task1} def test_existing_ignore(session): session.config.task_pre_exist = 'ignore' - task1 = FuncTask(lambda : None, name="a task", execution="main") - task2 = FuncTask(lambda : None, name="a task", execution="main") + task1 = FuncTask(lambda : None, name="a task", execution="main", session=session) + task2 = FuncTask(lambda : None, name="a task", execution="main", session=session) assert session.tasks == {task1} @pytest.mark.skip(reason="No support for this yet") def test_existing_replace(session): session.config.task_pre_exist = 'replace' - task1 = FuncTask(lambda : None, name="a task", execution="main") - task2 = FuncTask(lambda : None, name="a task", execution="main") + task1 = FuncTask(lambda : None, name="a task", execution="main", session=session) + task2 = FuncTask(lambda : None, name="a task", execution="main", session=session) assert session.tasks == {"a task": task2} def test_existing_rename(session): session.config.task_pre_exist = 'rename' - task1 = FuncTask(lambda : None, name="a task", execution="main") - task2 = FuncTask(lambda : None, name="a task", execution="main") + task1 = FuncTask(lambda : None, name="a task", execution="main", session=session) + task2 = FuncTask(lambda : None, name="a task", execution="main", session=session) assert session.tasks == {task1, task2} assert task2.name == 'a task - 1' diff --git a/rocketry/test/task/func/test_logging.py b/rocketry/test/task/func/test_logging.py index f070a01a..ce5b13bc 100644 --- a/rocketry/test/task/func/test_logging.py +++ b/rocketry/test/task/func/test_logging.py @@ -66,60 +66,54 @@ def test_set_cached_in_init(session, optimized, last_status): else: assert task.status == last_status -def test_running(tmpdir, session): +def test_running(session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task = FuncTask( - lambda : None, - execution="main" - ) - task.log_running() - assert "run" == task.status - assert task.is_running + task = FuncTask( + lambda : None, + execution="main", + session=session + ) + task.log_running() + assert "run" == task.status + assert task.is_running def test_success(tmpdir, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task = FuncTask( - lambda : None, - execution="main" - ) - task.log_running() - task.log_success() - assert "success" == task.status - assert not task.is_running + task = FuncTask( + lambda : None, + execution="main", + session=session + ) + task.log_running() + task.log_success() + assert "success" == task.status + assert not task.is_running def test_fail(tmpdir, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - task = FuncTask( - lambda : None, - execution="main" - ) - task.log_running() - task.log_failure() - assert "fail" == task.status - assert not task.is_running + task = FuncTask( + lambda : None, + execution="main", + session=session + ) + task.log_running() + task.log_failure() + assert "fail" == task.status + assert not task.is_running def test_without_running(tmpdir, session): "An edge case if for mysterious reason the task did not log running. Logging should still not crash" - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - task = FuncTask( - lambda : None, - execution="main" - ) - task.log_failure() - assert "fail" == task.status - assert not task.is_running + task = FuncTask( + lambda : None, + execution="main", + session=session + ) + task.log_failure() + assert "fail" == task.status + assert not task.is_running -def test_handle(tmpdir, session): +def test_handle(session): def create_record(action, task_name): # Util func to create a LogRecord @@ -137,39 +131,37 @@ def create_record(action, task_name): record.task_name = task_name return record - # Tests Task.handle (used in process tasks) - with tmpdir.as_cwd() as old_dir: + task = FuncTask( + lambda : None, + execution="main", + name="a task", + session=session + ) + # Creating the run log + record_run = create_record("run", task_name="a task") - task = FuncTask( - lambda : None, - execution="main", - name="a task" - ) - # Creating the run log - record_run = create_record("run", task_name="a task") - - # Creating the outcome log - record_finish = create_record("success", task_name="a task") - - task.log_record(record_run) - assert "run" == task.status - assert task.is_running - - task.log_record(record_finish) - assert "success" == task.status - assert not task.is_running - - records = session.get_task_log() - records = [ - record.dict(exclude={"created"}) - for record in records - ] - assert [ - {"task_name": "a task", "action": "run"}, - {"task_name": "a task", "action": "success"}, - ] == records - -def test_without_handlers(tmpdir, session): + # Creating the outcome log + record_finish = create_record("success", task_name="a task") + + task.log_record(record_run) + assert "run" == task.status + assert task.is_running + + task.log_record(record_finish) + assert "success" == task.status + assert not task.is_running + + records = session.get_task_log() + records = [ + record.dict(exclude={"created"}) + for record in records + ] + assert [ + {"task_name": "a task", "action": "run"}, + {"task_name": "a task", "action": "success"}, + ] == records + +def test_without_handlers(session): session.config.force_status_from_logs = True session.config.task_logger_basename = 'hdlr_test.task' @@ -184,7 +176,8 @@ def test_without_handlers(tmpdir, session): name="task 1", start_cond="always true", #logger="rocketry.task.test", - execution="main", + execution="main", + session=session ) # Test warnings @@ -198,7 +191,7 @@ def test_without_handlers(tmpdir, session): assert len(logger.handlers) == 1 assert isinstance(logger.handlers[0], RepoHandler) -def test_without_handlers_status_warnings(tmpdir, session): +def test_without_handlers_status_warnings(session): session.config.force_status_from_logs = True logger = logging.getLogger("rocketry.task") @@ -213,6 +206,7 @@ def test_without_handlers_status_warnings(tmpdir, session): start_cond="always true", logger_name="rocketry.task.test", execution="main", + session=session ) # Removing the handlers that were added @@ -253,6 +247,7 @@ def test_without_handlers_status_warnings(tmpdir, session): start_cond="always true", logger="rocketry.task.test", execution="main", + session=session ) assert list(str(w.message) for w in warns) == [ 'Logger rocketry.task cannot be read. Logging is set to memory. To supress this warning, please set a handler that can be read (redbird.logging.RepoHandler)' @@ -273,91 +268,89 @@ def test_without_handlers_status_warnings(tmpdir, session): ) def test_action_start(tmpdir, method, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task = FuncTask( - lambda : None, - execution="main", - ) - task.log_running() - getattr(task, method)() + task = FuncTask( + lambda : None, + execution="main", + session=session + ) + task.log_running() + getattr(task, method)() - records = list(map(lambda e: e.dict(), session.get_task_log())) - assert len(records) == 2 + records = list(map(lambda e: e.dict(), session.get_task_log())) + assert len(records) == 2 - # First should not have "end" - first = records[0] - assert first['created'] >= datetime.datetime(2000, 1, 1).timestamp() + # First should not have "end" + first = records[0] + assert first['created'] >= datetime.datetime(2000, 1, 1).timestamp() - # Second should and that should be datetime - last = records[1] - assert first['created'] <= last['created'] - assert last['created'] < datetime.datetime(2200, 1, 1).timestamp() + # Second should and that should be datetime + last = records[1] + assert first['created'] <= last['created'] + assert last['created'] < datetime.datetime(2200, 1, 1).timestamp() -def test_process_no_double_logging(tmpdir, session): +def test_process_no_double_logging(session): # 2021-02-27 there is a bug that Raspbian logs process task logs twice # while this is not occuring on Windows. This tests the bug. #!NOTE: This test requires there are two handlers in # rocketry.task logger (Memory and Stream in this order) expected_actions = ["run", "success"] - with tmpdir.as_cwd() as old_dir: - task = FuncTask( - run_success, - name="a task", - execution="process" - ) + task = FuncTask( + run_success, + name="a task", + execution="process", + session=session + ) - log_queue = multiprocessing.Queue(-1) - - # Start the process - proc = multiprocessing.Process(target=task._run_as_process, args=(None, None, log_queue, session.config, []), daemon=None) - proc.start() - - # Do the logging manually (copied from the method) - actual_actions = [] - records = [] - while True: - try: - record = log_queue.get(block=True, timeout=3) - except Empty: - break - else: - records.append(record) - # task.log_record(record) - actual_actions.append(record.action) - - # If fails here, double logging caused by creating too many records - # Obseved to fail rarely with py36 (c2f0368ffa56c5b8933f1afa2917f2be1555fb7a) - assert len(records) >= 2 # Testing not too few records (else not double logging bug) - assert ( - ["run", "success"] == [rec.action for rec in records] - ), "Double logging. Caused by creating multiple records (Task.log_running & Task.log_success) to the queue." - - # Testing there is no log records yet in the log - # (as the records should not been handled yet) - recs = list(session.get_task_log()) - assert len(recs) == 0, "Double logging. The log file is not empty before handling the records. Process bypasses the queue." - - for record in records: - task.log_record(record) - - # If fails here, double logging caused by multiple handlers - handlers = task.logger.logger.handlers - handlers[0] # Checking it has atleast 2 - handlers[1] # Checking it has atleast 2 - assert ( - isinstance(handlers[1], logging.StreamHandler) - and isinstance(handlers[0], RepoHandler) - and len(handlers) == 2 - ), f"Double logging. Too many handlers: {handlers}" - - # If fails here, double logging caused by Task.log_record - n_run = len(list(session.get_task_log(task_name="a task", action="run"))) - n_success = len(list(session.get_task_log(task_name="a task", action="success"))) - - assert n_run > 0 and n_success > 0, "No log records formed to log." - - assert n_run == 1 and n_success == 1, "Double logging. Bug in Task.log_record probably." \ No newline at end of file + log_queue = multiprocessing.Queue(-1) + + # Start the process + proc = multiprocessing.Process(target=task._run_as_process, args=(None, None, log_queue, session.config, []), daemon=None) + proc.start() + + # Do the logging manually (copied from the method) + actual_actions = [] + records = [] + while True: + try: + record = log_queue.get(block=True, timeout=3) + except Empty: + break + else: + records.append(record) + # task.log_record(record) + actual_actions.append(record.action) + + # If fails here, double logging caused by creating too many records + # Obseved to fail rarely with py36 (c2f0368ffa56c5b8933f1afa2917f2be1555fb7a) + assert len(records) >= 2 # Testing not too few records (else not double logging bug) + assert ( + ["run", "success"] == [rec.action for rec in records] + ), "Double logging. Caused by creating multiple records (Task.log_running & Task.log_success) to the queue." + + # Testing there is no log records yet in the log + # (as the records should not been handled yet) + recs = list(session.get_task_log()) + assert len(recs) == 0, "Double logging. The log file is not empty before handling the records. Process bypasses the queue." + + for record in records: + task.log_record(record) + + # If fails here, double logging caused by multiple handlers + handlers = task.logger.logger.handlers + handlers[0] # Checking it has atleast 2 + handlers[1] # Checking it has atleast 2 + assert ( + isinstance(handlers[1], logging.StreamHandler) + and isinstance(handlers[0], RepoHandler) + and len(handlers) == 2 + ), f"Double logging. Too many handlers: {handlers}" + + # If fails here, double logging caused by Task.log_record + n_run = len(list(session.get_task_log(task_name="a task", action="run"))) + n_success = len(list(session.get_task_log(task_name="a task", action="success"))) + + assert n_run > 0 and n_success > 0, "No log records formed to log." + + assert n_run == 1 and n_success == 1, "Double logging. Bug in Task.log_record probably." \ No newline at end of file diff --git a/rocketry/test/task/func/test_run.py b/rocketry/test/task/func/test_run.py index 97bab3e4..c6f4e6ad 100644 --- a/rocketry/test/task/func/test_run.py +++ b/rocketry/test/task/func/test_run.py @@ -59,7 +59,8 @@ def test_run(task_func, expected_outcome, exc_cls, execution, session): task = FuncTask( task_func, name="a task", - execution=execution + execution=execution, + session=session ) try: @@ -104,7 +105,8 @@ def test_run_async(task_func, expected_outcome, execution, session): task = FuncTask( task_func, name="a task", - execution=execution + execution=execution, + session=session ) try: @@ -125,106 +127,104 @@ def test_run_async(task_func, expected_outcome, execution, session): {"task_name": "a task", "action": expected_outcome}, ] == records -def test_force_run(tmpdir, session): +def test_force_run(session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task = FuncTask( - run_successful_func, - name="task", - start_cond=AlwaysFalse(), - execution="main" - ) - task.force_run = True + task = FuncTask( + run_successful_func, + name="task", + start_cond=AlwaysFalse(), + execution="main", + session=session + ) + task.force_run = True - assert bool(task) - assert bool(task) + assert bool(task) + assert bool(task) - task() - assert not task.force_run + task() + assert not task.force_run def test_dependency(tmpdir, session): - # Going to tempdir to dump the log files there - with tmpdir.as_cwd() as old_dir: - - task_a = FuncTask( - run_successful_func, - name="task_a", - start_cond=AlwaysTrue(), - execution="main" - ) - task_b = FuncTask( - run_successful_func, - name="task_b", - start_cond=AlwaysTrue(), - execution="main" - ) - task_dependent = FuncTask( - run_successful_func, - name="task_dependent", - start_cond="after task 'task_a' & after task 'task_b'", - execution="main" - ) - assert not bool(task_dependent) - task_a() - assert not bool(task_dependent) - task_b() - assert bool(task_dependent) + task_a = FuncTask( + run_successful_func, + name="task_a", + start_cond=AlwaysTrue(), + execution="main", + session=session + ) + task_b = FuncTask( + run_successful_func, + name="task_b", + start_cond=AlwaysTrue(), + execution="main", + session=session + ) + task_dependent = FuncTask( + run_successful_func, + name="task_dependent", + start_cond="after task 'task_a' & after task 'task_b'", + execution="main", + session=session + ) + assert not bool(task_dependent) + task_a() + assert not bool(task_dependent) + task_b() + assert bool(task_dependent) # Parametrization -def test_parametrization_runtime(tmpdir, session): - with tmpdir.as_cwd() as old_dir: +def test_parametrization_runtime(session): - task = FuncTask( - run_parametrized, - name="a task", - execution="main" - ) + task = FuncTask( + run_parametrized, + name="a task", + execution="main", + session=session + ) - task(params={"integer": 1, "string": "X", "optional_float": 1.1, "extra_parameter": "Should not be passed"}) + task(params={"integer": 1, "string": "X", "optional_float": 1.1, "extra_parameter": "Should not be passed"}) - records = list(map(lambda e: e.dict(exclude={'created'}), session.get_task_log())) - assert [ - {"task_name": "a task", "action": "run"}, - {"task_name": "a task", "action": "success"}, - ] == records + records = list(map(lambda e: e.dict(exclude={'created'}), session.get_task_log())) + assert [ + {"task_name": "a task", "action": "run"}, + {"task_name": "a task", "action": "success"}, + ] == records -def test_parametrization_local(tmpdir, session): - with tmpdir.as_cwd() as old_dir: +def test_parametrization_local(session): - task = FuncTask( - run_parametrized, - name="a task", - parameters={"integer": 1, "string": "X", "optional_float": 1.1}, - execution="main" - ) + task = FuncTask( + run_parametrized, + name="a task", + parameters={"integer": 1, "string": "X", "optional_float": 1.1}, + execution="main", + session=session + ) - task() + task() - records = list(map(lambda e: e.dict(exclude={'created'}), session.get_task_log())) - assert [ - {"task_name": "a task", "action": "run"}, - {"task_name": "a task", "action": "success"}, - ] == records + records = list(map(lambda e: e.dict(exclude={'created'}), session.get_task_log())) + assert [ + {"task_name": "a task", "action": "run"}, + {"task_name": "a task", "action": "success"}, + ] == records -def test_parametrization_kwargs(tmpdir, session): - with tmpdir.as_cwd() as old_dir: +def test_parametrization_kwargs(session): - task = FuncTask( - run_parametrized_kwargs, - name="a task", - parameters={"integer": 1, "string": "X", "optional_float": 1.1}, - execution="main" - ) + task = FuncTask( + run_parametrized_kwargs, + name="a task", + parameters={"integer": 1, "string": "X", "optional_float": 1.1}, + execution="main", + session=session + ) - task() + task() - records = list(map(lambda e: e.dict(exclude={'created'}), session.get_task_log())) - assert [ - {"task_name": "a task", "action": "run"}, - {"task_name": "a task", "action": "success"}, - ] == records \ No newline at end of file + records = list(map(lambda e: e.dict(exclude={'created'}), session.get_task_log())) + assert [ + {"task_name": "a task", "action": "run"}, + {"task_name": "a task", "action": "success"}, + ] == records \ No newline at end of file diff --git a/rocketry/test/task/func/test_run_delayed.py b/rocketry/test/task/func/test_run_delayed.py index c147df32..b4fb6017 100644 --- a/rocketry/test/task/func/test_run_delayed.py +++ b/rocketry/test/task/func/test_run_delayed.py @@ -69,7 +69,8 @@ def myfunc(): func_name="myfunc", path="mytasks/myfile.py", name="a task", - execution="main" + execution="main", + session=session ) task() @@ -98,7 +99,8 @@ def main(): func_name="main", path="mytasks/myfile.py", name="a task", - execution="main" + execution="main", + session=session ) task() @@ -131,7 +133,8 @@ def main(): func_name="main", path="mypkg6574/subpkg/myfile.py", name="a task", - execution="main" + execution="main", + session=session ) task() @@ -192,7 +195,8 @@ def main(val_5, optional=None): path="mytasks/myfile.py", name="a task", execution="main", - sys_paths=["mytasks/subfolder/another"] + sys_paths=["mytasks/subfolder/another"], + session=session ) task(params={"val_5":5}) @@ -210,7 +214,8 @@ def test_parametrization_runtime(tmpdir, script_files, session): func_name="main", path="scripts/parameterized_script.py", name="a task", - execution="main" + execution="main", + session=session ) task(params={"integer": 1, "string": "X", "optional_float": 1.1, "extra_parameter": "Should not be passed"}) @@ -229,7 +234,8 @@ def test_parametrization_local(tmpdir, script_files, session): path="scripts/parameterized_script.py", name="a task", parameters={"integer": 1, "string": "X", "optional_float": 1.1}, - execution="main" + execution="main", + session=session ) task() @@ -248,7 +254,8 @@ def test_parametrization_kwargs(tmpdir, script_files, session): path="scripts/parameterized_kwargs_script.py", name="a task", parameters={"integer": 1, "string": "X", "optional_float": 1.1}, - execution="main" + execution="main", + session=session ) task() diff --git a/rocketry/test/task/misc/test_restart.py b/rocketry/test/task/misc/test_restart.py index 8aa4891b..96011652 100644 --- a/rocketry/test/task/misc/test_restart.py +++ b/rocketry/test/task/misc/test_restart.py @@ -22,10 +22,10 @@ def test_scheduler_restart(tmpdir, session): with tmpdir.as_cwd() as old_dir: - FuncTask(write_file, parameters={"text": "Started"}, on_startup=True, name="startup", execution="main") - FuncTask(write_file, parameters={"text": "Shut"}, on_shutdown=True, name="shutdown", execution="main") + FuncTask(write_file, parameters={"text": "Started"}, on_startup=True, name="startup", execution="main", session=session) + FuncTask(write_file, parameters={"text": "Shut"}, on_shutdown=True, name="shutdown", execution="main", session=session) - task = Restart() + task = Restart(session=session) task.force_run = True diff --git a/rocketry/test/task/misc/test_shutdown.py b/rocketry/test/task/misc/test_shutdown.py index 28332a47..4a92191e 100644 --- a/rocketry/test/task/misc/test_shutdown.py +++ b/rocketry/test/task/misc/test_shutdown.py @@ -12,7 +12,7 @@ def write_file(text): f.write(text) def test_restart_raises(session): - task = ShutDown() + task = ShutDown(session=session) with pytest.raises(SchedulerExit): task() @@ -20,10 +20,10 @@ def test_scheduler_shutdown(tmpdir, session): with tmpdir.as_cwd() as old_dir: - FuncTask(write_file, parameters={"text": "Started"}, on_startup=True, name="write_startup", execution="main") - FuncTask(write_file, parameters={"text": "Shut"}, on_shutdown=True, name="write_shutdown", execution="main") + FuncTask(write_file, parameters={"text": "Started"}, on_startup=True, name="write_startup", execution="main", session=session) + FuncTask(write_file, parameters={"text": "Shut"}, on_shutdown=True, name="write_shutdown", execution="main", session=session) - task = ShutDown() + task = ShutDown(session=session) task.force_run = True diff --git a/rocketry/test/task/test_core.py b/rocketry/test/task/test_core.py index f71cddf4..94a85395 100644 --- a/rocketry/test/task/test_core.py +++ b/rocketry/test/task/test_core.py @@ -8,6 +8,7 @@ from rocketry.core.condition.base import AlwaysFalse, AlwaysTrue, BaseCondition from rocketry.args import Arg, Session, Task from rocketry.log import MinimalRecord +from rocketry import Session as SessionClass class DummyTask(BaseTask): @@ -15,7 +16,7 @@ def execute(self, *args, **kwargs): return def test_defaults(session): - task = DummyTask(name="mytest") + task = DummyTask(name="mytest", session=session) assert task.name == "mytest" assert isinstance(task.start_cond, AlwaysFalse) assert isinstance(task.end_cond, AlwaysFalse) @@ -31,18 +32,18 @@ def test_set_timeout(session): assert task.timeout == datetime.timedelta(seconds=20) def test_delete(session): - task = DummyTask(name="mytest") + task = DummyTask(name="mytest", session=session) assert session.tasks == {task} task.delete() assert session.tasks == set() def test_set_invalid_status(session): - task = DummyTask(name="mytest") + task = DummyTask(name="mytest", session=session) with pytest.raises(ValueError): task.status = "not valid" def test_pickle(session): - task_1 = DummyTask(name="mytest") + task_1 = DummyTask(name="mytest", session=session) pkl_obj = pickle.dumps(task_1) task_2 = pickle.loads(pkl_obj) assert task_1.name == task_2.name diff --git a/rocketry/test/task/test_pickle.py b/rocketry/test/task/test_pickle.py index d460b646..e3591167 100644 --- a/rocketry/test/task/test_pickle.py +++ b/rocketry/test/task/test_pickle.py @@ -61,8 +61,8 @@ def func_nested(): def test_unpicklable_session(self, session): def func_nested(): pass - unpkl_task = FuncTask(func_nested, execution="thread", name="unpicklable") - task = FuncTask(func_on_main_level, execution="process", name="picklable") + unpkl_task = FuncTask(func_nested, execution="thread", name="unpicklable", session=session) + task = FuncTask(func_on_main_level, execution="process", name="picklable", session=session) assert session.tasks == {unpkl_task, task} @@ -75,7 +75,7 @@ def func_nested(): def test_unpicklable_session_params(self, session): session.parameters["unpicklable"] = FuncTask(lambda:None, execution="main", name="unpicklable") session.parameters["picklable"] = "myval" - task = FuncTask(func_on_main_level, execution="process", name="picklable") + task = FuncTask(func_on_main_level, execution="process", name="picklable", session=session) pick_task = pickle_dump_read(task) assert pick_task.session is None diff --git a/rocketry/test/test_hooks.py b/rocketry/test/test_hooks.py index 664fb35f..ef7331e3 100644 --- a/rocketry/test/test_hooks.py +++ b/rocketry/test/test_hooks.py @@ -94,10 +94,10 @@ def my_shutdown_hook_generator(sched): timeline.append("ran hook (shutdown, generator second)") - FuncTask(lambda: timeline.append("ran TASK (startup)"), name="start", on_startup=True, execution="main") - task1 = FuncTask(lambda: timeline.append("ran TASK (normal 1)"), name="1", execution="main", start_cond=true, priority=1) - task2 = FuncTask(lambda: timeline.append("ran TASK (normal 2)"), name="2", execution="main", start_cond=DependSuccess(depend_task=task1), priority=0) - FuncTask(lambda: timeline.append("ran TASK (shutdown)"), name="shut", on_shutdown=True, execution="main") + FuncTask(lambda: timeline.append("ran TASK (startup)"), name="start", on_startup=True, execution="main", session=session) + task1 = FuncTask(lambda: timeline.append("ran TASK (normal 1)"), name="1", execution="main", start_cond=true, priority=1, session=session) + task2 = FuncTask(lambda: timeline.append("ran TASK (normal 2)"), name="2", execution="main", start_cond=DependSuccess(depend_task=task1), priority=0, session=session) + FuncTask(lambda: timeline.append("ran TASK (shutdown)"), name="shut", on_shutdown=True, execution="main", session=session) session.config.shut_cond = SchedulerCycles() == 2 session.start() @@ -158,7 +158,7 @@ def test_task_execute(session, execution, tmpdir, func, exc_type, exc): with open(file, "w") as f: f.write("\nStarting\n") - task = FuncTask(func, execution=execution, parameters={"testfile": str(file)}, start_cond="true", name="mytask") + task = FuncTask(func, execution=execution, parameters={"testfile": str(file)}, start_cond="true", name="mytask", session=session) session.config.shut_cond = TaskStarted(task="mytask") >= 1 session.start() with open(file) as f: From 627ce894e7a6dc1e9951e7825515c9aee4dc11c8 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sat, 13 Aug 2022 22:04:41 +0300 Subject: [PATCH 02/10] upd: now creates session for task if not specified --- rocketry/core/task.py | 11 ++++++++--- rocketry/test/task/test_core.py | 7 +++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/rocketry/core/task.py b/rocketry/core/task.py index 7049b3ba..7ba52c18 100644 --- a/rocketry/core/task.py +++ b/rocketry/core/task.py @@ -41,6 +41,11 @@ _IS_WINDOWS = platform.system() +def _create_session(): + # To avoid circular imports + from rocketry import Session + return Session() + class Task(RedBase, BaseModel): """Base class for Tasks. @@ -116,8 +121,7 @@ class Task(RedBase, BaseModel): Logger of the task. Typically not needed to be set. session : rocketry.session.Session, optional - Session the task is binded to, - by default default session + Session the task is binded to. Attributes @@ -253,7 +257,8 @@ def __init__(self, **kwargs): hooker.prerun(self) if kwargs.get("session") is None: - kwargs['session'] = self.session + warnings.warn("Task's session not defined. Creating new.", UserWarning) + kwargs['session'] = _create_session() kwargs['name'] = self._get_name(**kwargs) super().__init__(**kwargs) diff --git a/rocketry/test/task/test_core.py b/rocketry/test/task/test_core.py index 94a85395..2e01d1f8 100644 --- a/rocketry/test/task/test_core.py +++ b/rocketry/test/task/test_core.py @@ -21,6 +21,13 @@ def test_defaults(session): assert isinstance(task.start_cond, AlwaysFalse) assert isinstance(task.end_cond, AlwaysFalse) +def test_defaults_no_session(session): + with pytest.warns(UserWarning): + task = DummyTask(name="mytest") + assert task.session is not session + assert isinstance(task.session, SessionClass) + assert task.session.tasks == {task} + def test_set_timeout(session): task = DummyTask(timeout="1 hour 20 min", session=session, name="1") assert task.timeout == datetime.timedelta(hours=1, minutes=20) From b77a356ca51009703801721bb1dbf6d9f981eb8b Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sat, 13 Aug 2022 22:13:21 +0300 Subject: [PATCH 03/10] depr: deprecated session.get_task getitem should be used instead. --- rocketry/core/schedule.py | 2 +- rocketry/core/task.py | 6 +++--- rocketry/session.py | 5 ++++- rocketry/test/session/test_core.py | 14 ++++++++------ rocketry/utils/dependencies.py | 4 ++-- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/rocketry/core/schedule.py b/rocketry/core/schedule.py index f19c6b96..5cbf0693 100644 --- a/rocketry/core/schedule.py +++ b/rocketry/core/schedule.py @@ -330,7 +330,7 @@ def handle_logs(self): break else: self.logger.debug(f"Inserting record for '{record.task_name}' ({record.action})") - task = self.session.get_task(record.task_name) + task = self.session[record.task_name] if record.action == "fail": # There is a caveat in logging # https://github.com/python/cpython/blame/fad6af2744c0b022568f7f4a8afc93fed056d4db/Lib/logging/handlers.py#L1383 diff --git a/rocketry/core/task.py b/rocketry/core/task.py index 7ba52c18..8adbdc67 100644 --- a/rocketry/core/task.py +++ b/rocketry/core/task.py @@ -816,7 +816,7 @@ def _lock_to_run_log(self, log_queue): else: #self.logger.debug(f"Inserting record for '{record.task_name}' ({record.action})") - task = self.session.get_task(record.task_name) + task = self.session[record.task_name] task.log_record(record) action = record.action @@ -1070,13 +1070,13 @@ def period(self) -> TimePeriod: session = self.session if isinstance(cond, (TaskSucceeded, TaskFinished)): - if session.get_task(cond.kwargs["task"]) is self: + if session[cond.kwargs["task"]] is self: return cond.period elif isinstance(cond, All): task_periods = [] for sub_stmt in cond: - if isinstance(sub_stmt, (TaskFinished, TaskFinished)) and session.get_task(sub_stmt.kwargs["task"]) is self: + if isinstance(sub_stmt, (TaskFinished, TaskFinished)) and session[sub_stmt.kwargs["task"]] is self: task_periods.append(sub_stmt.period) if task_periods: return AllTime(*task_periods) diff --git a/rocketry/session.py b/rocketry/session.py index 2ed473b7..3e695fcf 100644 --- a/rocketry/session.py +++ b/rocketry/session.py @@ -338,7 +338,10 @@ def get_tasks(self) -> list: return self.tasks def get_task(self, task): - #! TODO: Do we need this? + warnings.warn(( + "Method get_task will be removed in the future version." + "Please use instead: session['task name']" + ), DeprecationWarning) return self[task] def get_cond_parsers(self): diff --git a/rocketry/test/session/test_core.py b/rocketry/test/session/test_core.py index ff28c8e4..0b37068a 100644 --- a/rocketry/test/session/test_core.py +++ b/rocketry/test/session/test_core.py @@ -89,13 +89,15 @@ def test_get_task(session): session=session ) - # By string - t = session.get_task(task.name) - assert t is task + with pytest.warns(DeprecationWarning): + # By string + t = session.get_task(task.name) + assert t is task - # By task (returns itself) - t = session.get_task(task) - assert t is task + with pytest.warns(DeprecationWarning): + # By task (returns itself) + t = session.get_task(task) + assert t is task def test_clear(session): diff --git a/rocketry/utils/dependencies.py b/rocketry/utils/dependencies.py index 848bba99..1b421adb 100644 --- a/rocketry/utils/dependencies.py +++ b/rocketry/utils/dependencies.py @@ -64,11 +64,11 @@ def _get_links(self, task:Task) -> Union[Any, All]: for subcond in cond: if isinstance(subcond, (DependFinish, DependSuccess, DependFailure)): req_task = subcond.depend_task - req_task = self.session.get_task(req_task) + req_task = self.session[req_task] yield Link(parent=req_task, child=task, relation=type(subcond), type=type(cond)) elif isinstance(cond, (DependFinish, DependSuccess, DependFailure)): req_task = cond.depend_task - req_task = self.session.get_task(req_task) + req_task = self.session[req_task] yield Link(req_task, task, relation=type(cond)) From de959f6d10b1a013962f4170f70d021f3b9014e3 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sat, 13 Aug 2022 23:09:12 +0300 Subject: [PATCH 04/10] add: session.remove_task, create_task and add_task --- rocketry/application.py | 15 ++------ rocketry/session.py | 21 +++++++++++ rocketry/test/session/test_core.py | 57 ++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/rocketry/application.py b/rocketry/application.py index ff4d51fd..01c62440 100644 --- a/rocketry/application.py +++ b/rocketry/application.py @@ -19,20 +19,9 @@ class _AppMixin: - def task(self, start_cond=None, name=None, *, command=None, path=None, **kwargs): + def task(self, start_cond=None, name=None, **kwargs): "Create a task" - - kwargs['session'] = self.session - kwargs['start_cond'] = start_cond - kwargs['name'] = name - - if command is not None: - return CommandTask(command=command, **kwargs) - elif path is not None: - # Non-wrapped FuncTask - return FuncTask(path=path, **kwargs) - else: - return FuncTask(name_include_module=False, _name_template='{func_name}', **kwargs) + return self.session.create_task(start_cond=start_cond, name=name, **kwargs) def param(self, name:Optional[str]=None): "Set one session parameter (decorator)" diff --git a/rocketry/session.py b/rocketry/session.py index 3e695fcf..4e8f35e8 100644 --- a/rocketry/session.py +++ b/rocketry/session.py @@ -348,6 +348,22 @@ def get_cond_parsers(self): "Used by the actual string condition parser" return self._cond_parsers + def create_task(self, *, command=None, path=None, **kwargs): + "Create a task and put it to the session" + + # To avoid circular imports + from rocketry.tasks import CommandTask, FuncTask + + kwargs['session'] = self + + if command is not None: + return CommandTask(command=command, **kwargs) + elif path is not None: + # Non-wrapped FuncTask + return FuncTask(path=path, **kwargs) + else: + return FuncTask(name_include_module=False, _name_template='{func_name}', **kwargs) + def add_task(self, task: 'Task'): "Add the task to the session" if_exists = self.config.task_pre_exist @@ -363,6 +379,11 @@ def add_task(self, task: 'Task'): else: self.tasks.add(task) + def remove_task(self, task: Union['Task', str]): + if isinstance(task, str): + task = self[task] + self.session.tasks.remove(task) + def task_exists(self, task: 'Task'): warnings.warn(( "Method task_exists will be removed in the future version." diff --git a/rocketry/test/session/test_core.py b/rocketry/test/session/test_core.py index 0b37068a..350ae1ef 100644 --- a/rocketry/test/session/test_core.py +++ b/rocketry/test/session/test_core.py @@ -32,6 +32,9 @@ def test_get_repo(session): # Test the one used in the task logging is also the same assert session.get_repo() is TaskAdapter(logger, task=None)._get_repo() +# Manipulate +# ---------- + def test_getitem(session): task_1 = FuncTask( @@ -65,6 +68,57 @@ def do_things_2(): with pytest.raises(KeyError): session["non existing"] +def test_add(session): + task = FuncTask( + lambda : None, + name="task 1", + execution="main", + session=None + ) + + assert session.tasks == set() + session.add_task(task) + + assert session.tasks == {task} + +def test_create(session): + + assert session.tasks == set() + session.create_task(name="do_command", start_cond="daily", command="echo 'hello world'") + + @session.create_task(name="do_func", start_cond="daily") + def do_things(): + ... + assert session.tasks == {session['do_func'], session['do_command']} + +def test_remove(session): + task_1 = FuncTask( + lambda : None, + name="task 1", + execution="main", + session=session + ) + task_2 = FuncTask( + lambda : None, + name="task 2", + execution="main", + session=session + ) + task_3 = FuncTask( + lambda : None, + name="task 3", + execution="main", + session=session + ) + assert session.tasks == {task_1, task_2, task_3} + session.remove_task(task_3) + assert session.tasks == {task_1, task_2} + session.remove_task("task 2") + assert session.tasks == {task_1} + +# Old interface +# ------------- + def test_task_exists(session): task_1 = FuncTask( lambda : None, @@ -77,9 +131,6 @@ def test_task_exists(session): assert not session.task_exists("task not exists") assert session.task_exists(task_1) -# Old interface -# ------------- - def test_get_task(session): task = FuncTask( From 88cad4ddfff3aef321ed09148cd93b39355adbdb Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sun, 14 Aug 2022 00:57:39 +0300 Subject: [PATCH 05/10] add: task groups --- rocketry/__init__.py | 2 +- rocketry/application.py | 48 ++++++++-- rocketry/test/app/test_grouper.py | 140 ++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 rocketry/test/app/test_grouper.py diff --git a/rocketry/__init__.py b/rocketry/__init__.py index 5a37c75b..96e8e7e9 100644 --- a/rocketry/__init__.py +++ b/rocketry/__init__.py @@ -16,7 +16,7 @@ session = Session() session.set_as_default() -from .application import Rocketry +from .application import Rocketry, Grouper from . import _version __version__ = _version.get_versions()['version'] diff --git a/rocketry/application.py b/rocketry/application.py index 01c62440..5c019985 100644 --- a/rocketry/application.py +++ b/rocketry/application.py @@ -27,6 +27,24 @@ def param(self, name:Optional[str]=None): "Set one session parameter (decorator)" return FuncParam(name, session=self.session) + def cond(self, syntax: Union[str, Pattern, List[Union[str, Pattern]]]=None): + "Create a condition (decorator)" + return FuncCond(syntax=syntax, session=self.session, decor_return_func=False) + + def params(self, **kwargs): + "Set session parameters" + self.session.parameters.update(kwargs) + + def include_grouper(self, group:'Grouper'): + for task in group.session.tasks: + if group.prefix: + task.name = group.prefix + task.name + if group.start_cond is not None: + task.start_cond = task.start_cond & group.start_cond + task.execution = group.execution if task.execution is None else task.execution + + self.session.add_task(task) + self.session.parameters.update(group.session.parameters) class Rocketry(_AppMixin): """Rocketry scheduling application""" @@ -55,14 +73,6 @@ async def serve(self, debug=False): self.session.set_as_default() await self.session.serve() - def cond(self, syntax: Union[str, Pattern, List[Union[str, Pattern]]]=None): - "Create a condition (decorator)" - return FuncCond(syntax=syntax, session=self.session, decor_return_func=False) - - def params(self, **kwargs): - "Set session parameters" - self.session.parameters.update(kwargs) - def set_logger(self): warnings.warn(( "set_logger is deprecated and will be removed in the future. " @@ -92,3 +102,25 @@ def _get_repo(self, repo:str): return CSVFileRepo(filename=filepath, model=LogRecord) else: raise NotImplementedError(f"Repo creation for {repo} not implemented") + +class Grouper(_AppMixin): + + def __init__(self, prefix:str=None, start_cond=None, execution=None): + self.prefix = prefix + self.start_cond = start_cond + self.execution = execution + + self.session = Session() + + def disable(self): + "Disable all tasks in the group" + self.set_task_attr("disabled", True) + + def enabled(self): + "Disable all tasks in the group" + self.set_task_attr("disabled", False) + + def set_task_attr(self, attr, value): + "Set attribute in all tasks" + for task in self.session.tasks: + setattr(task, attr, value) \ No newline at end of file diff --git a/rocketry/test/app/test_grouper.py b/rocketry/test/app/test_grouper.py new file mode 100644 index 00000000..0403b01f --- /dev/null +++ b/rocketry/test/app/test_grouper.py @@ -0,0 +1,140 @@ + +import asyncio +import logging + +from rocketry import Rocketry, Grouper +from rocketry.conds import daily, time_of_day +from rocketry.args import Return, Arg, FuncArg +from redbird.logging import RepoHandler +from redbird.repos import MemoryRepo, CSVFileRepo + +from rocketry import Session +from rocketry.tasks import CommandTask +from rocketry.tasks import FuncTask +from rocketry.conds import false, true + +def set_logging_defaults(): + task_logger = logging.getLogger("rocketry.task") + task_logger.handlers = [] + task_logger.setLevel(logging.WARNING) + +def test_simple(session): + set_logging_defaults() + + app = Rocketry() + + @app.task(daily) + def do_things(): + ... + + group = Grouper() + + @group.task(daily) + def do_other_things(): + ... + + assert app.session.tasks == {app.session["do_things"]} + + app.include_grouper(group) + assert app.session.tasks == {app.session["do_things"], app.session["do_other_things"]} + assert app.session["do_other_things"].start_cond == daily + +def test_prefix(session): + set_logging_defaults() + + app = Rocketry() + + @app.task(daily) + def do_things(): + ... + + group = Grouper(prefix="mytests.") + + @group.task(daily) + def do_things(): + ... + + app.include_grouper(group) + assert app.session.tasks == {app.session["do_things"], app.session["mytests.do_things"]} + +def test_start_cond(session): + set_logging_defaults() + + app = Rocketry() + group = Grouper(start_cond=time_of_day.between("10:00", "18:00")) + + @group.task(daily) + def do_things(): + ... + + app.include_grouper(group) + task = app.session[do_things] + assert task.start_cond == daily & time_of_day.between("10:00", "18:00") + +def test_execution(session): + set_logging_defaults() + + app = Rocketry(config=dict(task_execution="process")) + group = Grouper(execution="main") + + @group.task(daily, execution="thread") + def do_things(): + ... + + @group.task(daily) + def do_things_2(): + ... + + app.include_grouper(group) + assert app.session[do_things].execution == "thread" + assert app.session[do_things_2].execution == "main" + +def test_custom_condition(session): + set_logging_defaults() + + app = Rocketry() + + @app.cond() + def is_foo(): + return True + + group = Grouper() + + @group.cond() + def is_bar(): + return True + + @group.task(is_foo & is_bar) + def do_things(): + ... + + app.include_grouper(group) + assert app.session.tasks == {app.session["do_things"]} + +def test_params(session): + set_logging_defaults() + + app = Rocketry() + app.params(x="hello", z="world") + + group = Grouper() + group.params(x="hi", y="universe") + + app.include_grouper(group) + assert dict(app.session.parameters) == {"x": "hi", "y": "universe", "z": "world"} + +def test_func_param(session): + set_logging_defaults() + + app = Rocketry() + @app.param("x") + def get_x(): + return "hello" + + group = Grouper() + @group.param("y") + def get_x(): + return "world" + + app.include_grouper(group) + assert list(app.session.parameters.keys()) == ["x", "y"] \ No newline at end of file From e7dd67d9daeb4817dda50d874ddd6c107184ccf6 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sun, 14 Aug 2022 09:37:55 +0300 Subject: [PATCH 06/10] fix: session in add_task --- rocketry/session.py | 3 +++ rocketry/test/app/test_grouper.py | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/rocketry/session.py b/rocketry/session.py index 4e8f35e8..98778f98 100644 --- a/rocketry/session.py +++ b/rocketry/session.py @@ -378,6 +378,9 @@ def add_task(self, task: 'Task'): raise KeyError(f"Task '{task.name}' already exists") else: self.tasks.add(task) + + # Adding the session to the task + task.session = self def remove_task(self, task: Union['Task', str]): if isinstance(task, str): diff --git a/rocketry/test/app/test_grouper.py b/rocketry/test/app/test_grouper.py index 0403b01f..cd84be96 100644 --- a/rocketry/test/app/test_grouper.py +++ b/rocketry/test/app/test_grouper.py @@ -3,6 +3,7 @@ import logging from rocketry import Rocketry, Grouper +from rocketry.conditions import TaskStarted from rocketry.conds import daily, time_of_day from rocketry.args import Return, Arg, FuncArg from redbird.logging import RepoHandler @@ -137,4 +138,29 @@ def get_x(): return "world" app.include_grouper(group) - assert list(app.session.parameters.keys()) == ["x", "y"] \ No newline at end of file + assert list(app.session.parameters.keys()) == ["x", "y"] + + +def test_run(session): + set_logging_defaults() + + app = Rocketry(config={"task_execution": "main"}) + + @app.task(daily) + def do_things(): + ... + + group = Grouper() + + @group.task(daily) + def do_other_things(): + ... + + assert app.session.tasks == {app.session["do_things"]} + + app.include_grouper(group) + + app.session.config.shut_cond = TaskStarted(task=do_other_things) + app.run() + logger = app.session[do_other_things].logger + assert logger.filter_by(action="success").count() == 1 \ No newline at end of file From 80b3d426df59a60a4fd1f58d43bddc2727c17576 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sun, 14 Aug 2022 09:47:11 +0300 Subject: [PATCH 07/10] rem: removed additional group features These are possibly implemented later --- rocketry/application.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/rocketry/application.py b/rocketry/application.py index 5c019985..49f7772a 100644 --- a/rocketry/application.py +++ b/rocketry/application.py @@ -111,16 +111,3 @@ def __init__(self, prefix:str=None, start_cond=None, execution=None): self.execution = execution self.session = Session() - - def disable(self): - "Disable all tasks in the group" - self.set_task_attr("disabled", True) - - def enabled(self): - "Disable all tasks in the group" - self.set_task_attr("disabled", False) - - def set_task_attr(self, attr, value): - "Set attribute in all tasks" - for task in self.session.tasks: - setattr(task, attr, value) \ No newline at end of file From 5b377403992ef1742eff13ee00852a525325cec6 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sun, 14 Aug 2022 10:06:25 +0300 Subject: [PATCH 08/10] docs: add type hint --- rocketry/application.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rocketry/application.py b/rocketry/application.py index 49f7772a..49475ffa 100644 --- a/rocketry/application.py +++ b/rocketry/application.py @@ -18,6 +18,8 @@ from rocketry import Session class _AppMixin: + + session: Session def task(self, start_cond=None, name=None, **kwargs): "Create a task" From 78d85216cb060908ee59c618d71ec55802eb6611 Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sun, 14 Aug 2022 11:45:29 +0300 Subject: [PATCH 09/10] test: add more tests --- rocketry/test/app/test_app.py | 45 ++++++++++++++++++++++++++++++- rocketry/test/app/test_grouper.py | 21 +++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/rocketry/test/app/test_app.py b/rocketry/test/app/test_app.py index 43403f13..3244cc94 100644 --- a/rocketry/test/app/test_app.py +++ b/rocketry/test/app/test_app.py @@ -101,6 +101,36 @@ def do_daily(arg=Arg('arg_3')): logger = app.session['do_daily'].logger assert logger.filter_by(action="success").count() == 1 +def test_nested_args_from_func_arg(): + set_logging_defaults() + + # Creating app + app = Rocketry(config={'task_execution': 'main'}) + + @app.param('arg_1') + def my_arg_1(): + return 'arg 1' + + def my_func_2(arg=Arg('arg_1')): + assert arg == "arg 1" + return 'arg 2' + + def my_func_3(arg_1=Arg('arg_1'), arg_2=FuncArg(my_func_2)): + assert arg_1 == "arg 1" + assert arg_2 == "arg 2" + return 'arg 3' + + # Creating a task to test this + @app.task(true) + def do_daily(arg=FuncArg(my_func_3)): + ... + assert arg == "arg 3" + + app.session.config.shut_cond = TaskStarted(task='do_daily') + app.run() + logger = app.session['do_daily'].logger + assert logger.filter_by(action="success").count() == 1 + def test_arg_ref(): set_logging_defaults() @@ -203,4 +233,17 @@ def do_never(arg_1): task_example = session['never done'] assert task_example.execution == 'process' assert task_example.name == 'never done' - assert dict(task_example.parameters) == {'arg_1': 'something'} \ No newline at end of file + assert dict(task_example.parameters) == {'arg_1': 'something'} + + +def test_task_name(): + set_logging_defaults() + + app = Rocketry(config={'task_execution': 'main'}) + + @app.task() + def do_func(): + ... + return 'return value' + + assert app.session[do_func].name == "do_func" \ No newline at end of file diff --git a/rocketry/test/app/test_grouper.py b/rocketry/test/app/test_grouper.py index cd84be96..eae107b6 100644 --- a/rocketry/test/app/test_grouper.py +++ b/rocketry/test/app/test_grouper.py @@ -163,4 +163,25 @@ def do_other_things(): app.session.config.shut_cond = TaskStarted(task=do_other_things) app.run() logger = app.session[do_other_things].logger + assert logger.filter_by(action="success").count() == 1 + +def test_run_cond_elsewhere(session): + set_logging_defaults() + + app = Rocketry(config={"task_execution": "main"}) + group = Grouper() + + @group.cond() + def is_foo(): + return True + + @app.task(is_foo) + def do_things(): + ... + + # We don't include the group + + app.session.config.shut_cond = TaskStarted(task=do_things) + app.run() + logger = app.session[do_things].logger assert logger.filter_by(action="success").count() == 1 \ No newline at end of file From 9168608ee2a1c17359ec3012502703820a1bf60a Mon Sep 17 00:00:00 2001 From: Mikael Koli Date: Sun, 14 Aug 2022 12:17:56 +0300 Subject: [PATCH 10/10] docs: update versions --- docs/versions.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/versions.rst b/docs/versions.rst index 15143234..7d60ab8d 100644 --- a/docs/versions.rst +++ b/docs/versions.rst @@ -5,11 +5,14 @@ Version history - ``2.3.0`` - Add: Cron style scheduling + - Add: Task groups (``Grouper``) to support bigger applications - Add: New condition, ``TaskRunnable`` + - Add: New methods to session (``remove_task`` & ``create_task``) - Add: ``always`` time period - Fix: Various bugs related to ``Any``, ``All`` and ``StaticInterval`` time periods - Fix: Integers as start and end in time periods - Upd: Now time periods are immutable + - Upd: Now if session is not specified, tasks create new one. - ``2.2.0``