我已经实现了用于运行单个dag的测试用例,但是它在1.9中似乎不起作用,可能是由于气流1.8中引入了更严格的存储池 。 我正在尝试在测试用例下运行:
from airflow import DAG
from airflow.operators.dummy_operator import DummyOperator
from airflow.operators.python_operator import PythonOperator
class DAGTest(unittest.TestCase):
def make_tasks(self):
dag = DAG('test_dag', description='a test',
schedule_interval='@once',
start_date=datetime(2018, 6, 26),
catchup=False)
du1 = DummyOperator(task_id='dummy1', dag=dag)
du2 = DummyOperator(task_id='dummy2', dag=dag)
du3 = DummyOperator(task_id='dummy3', dag=dag)
du1 >> du2 >> du3
dag.run()
def test_execute(self):
self.make_tasks()
Dependencies not met for <TaskInstance: test_dag.dummy3 2018-06-26 00:00:00 [upstream_failed]>, dependency 'Trigger Rule' FAILED: Task's trigger rule 'all_success' requires all
upstream tasks to have succeeded, but found 1 non-success(es).
upstream_tasks_state={'skipped': 0L, 'successes': 0L, 'failed': 0L,'upstream_failed': 1L, 'done': 1L, 'total': 1}, upstream_task_ids=['dummy2']
我做错了什么? 我已经尝试过LocalExecutor和SequentialExecutor
环境:
Python 2.7
Airflow 1.9
我相信它正在尝试同时执行所有任务而又不遵守依赖关系。 注意:在Airflow 1.7中使用类似的代码
答案 0 :(得分:1)
我不熟悉Airflow 1.7,但我想它没有与Airflow1.8及更高版本相同的“ DagBag”概念。
您无法运行这样创建的DAG,因为dag.run()
启动了一个新的python进程,它将必须从它在磁盘上解析的dag文件夹中找到DAG-但它不能。这已作为消息包含在输出中(但您没有包括完整的错误消息/输出)
您要通过在测试文件中创建dag来测试什么?它是自定义运算符吗?那么您最好直接进行测试。例如,这是我如何独立测试自定义运算符的方法:
class MyPluginTest(unittest.TestCase)
def setUp(self):
dag = DAG(TEST_DAG_ID, schedule_interval='* * * * Thu', default_args={'start_date': DEFAULT_DATE})
self.dag = dag
self.op = myplugin.FindTriggerFileForExecutionPeriod(
dag=dag,
task_id='test',
prefix='s3://bucket/some/prefix',
)
self.ti = TaskInstance(task=self.op, execution_date=DEFAULT_DATE)
# Other S3 setup here, specific to my test
def test_execute_no_trigger(self):
with self.assertRaises(RuntimeError):
self.ti.run(ignore_ti_state=True)
# It shouldn't have anything in XCom
self.assertEqual(
self.ti.xcom_pull(task_ids=self.op.task_id),
None
)
答案 1 :(得分:0)
这是可以在pytest
测试用例中使用的功能,该功能将按顺序运行DAG的任务。
from datetime import timedelta
import pytest
from unittest import TestCase
@pytest.fixture
def test_dag(dag):
dag._schedule_interval = timedelta(days=1) # override cuz @once gets skipped
done = set([])
def run(key):
task = dag.task_dict[key]
for k in task._upstream_task_ids:
run(k)
if key not in done:
print(f'running task {key}...')
date = dag.default_args['start_date']
task.run(date, date, ignore_ti_state=True)
done.add(key)
for k, _ in dag.task_dict.items():
run(k)
然后可以在测试中使用test_dag(dag)代替dag.run()
。
您需要确保登录自定义运算符时使用的是self.log.info()
而不是logging.info()
或print()
,否则它们不会显示。
您可能还需要使用python -m pytest -s test_my_dag.py
运行测试,因为如果没有-s
标志,将不会捕获到气流的标准输出。
我仍在设法弄清DAG之间的依赖性。