def test_runs_on_finish(executor, tmp_directory): hook.count = 0 hook_2.count = 0 hook_3.count = 0 hook_4.count = 0 dag = DAG(executor=executor) t = PythonCallable(fn, File('file1.txt'), dag, 't') t.on_finish = hook t.on_failure = hook_4 t2 = PythonCallable(touch_w_upstream, File('file2'), dag, 't2') t2.on_finish = hook_2 t3 = PythonCallable(fn, File('file3'), dag, 't3') t3.on_finish = hook_3 t >> t2 dag.build() assert hook.count == 1 assert hook_2.count == 1 assert hook_3.count == 1 assert hook_4.count == 0
def test_on_failure_exceptions_are_logged(executor, caplog): dag = DAG(executor='serial') t = PythonCallable(fn_that_fails, File('file.txt'), dag, name='t') t.on_failure = hook_crashing with caplog.at_level(logging.ERROR): with pytest.raises(DAGBuildError): dag.build() assert 'Exception when running on_failure for task "t"' in caplog.text
def test_runs_on_failure(tmp_directory): hook.count = 0 hook_2.count = 0 hook_3.count = 0 dag = DAG( executor=Serial(build_in_subprocess=False, catch_exceptions=True)) t = PythonCallable(fn_that_fails, File('file1.txt'), dag, 't') t.on_failure = hook t2 = PythonCallable(fn_that_fails, File('file2'), dag, 't2') t2.on_failure = hook_2 t2 = PythonCallable(fn_that_fails, File('file3'), dag, 't3') t2.on_failure = hook_3 try: dag.build() except DAGBuildError: pass assert hook.count == 1 assert hook_2.count == 1 assert hook_3.count == 1
def test_task_status_and_output_when_on_failure_crashes(tmp_directory): dag = DAG() t = PythonCallable(fn_that_fails, File('file'), dag) t.on_failure = hook_crashing t2 = PythonCallable(touch_w_upstream, File('file2'), dag) t >> t2 with pytest.raises(DAGBuildError) as excinfo: dag.build() assert t.exec_status == TaskStatus.Errored assert t2.exec_status == TaskStatus.Aborted assert ("PythonCallable: fn_that_fails -> File('file')" in str(excinfo.getrepr()))