我们正在将Google Composer(托管的Airflow服务)与airflow v1.10和Python 3.6.8结合使用。 要部署DAGS,我们采用打包DAG(https://airflow.apache.org/concepts.html?highlight=zip#packaged-dags)方法。
从cmd行创建zip文件时一切正常
zip -r dag_under_test.zip test_dag.py
但是,当我尝试从pytest固定装置执行此操作时,因此我在DagBag中加载并测试DAG的完整性,气流完全无法识别此zip文件。这是我的pytest固定装置的代码
@fixture
def setup(config):
os.system("zip -r dag_under_test.zip test_zip.py")
def test_import_dags(setup):
dagbag = DagBag(include_examples=False)
noOfDags = len(dagbag.dags)
dagbag.process_file("dag_under_test.zip")
assert len(dagbag.dags) == noOfDags + 1, 'DAG import failures. Errors: {}'.format(dagbag.import_errors)
我将此zip文件复制到DAGs文件夹,但是气流根本无法识别它,没有错误消息。 但是用cmdline的相同命令构建的zip文件正在被气流加载!似乎我在这里缺少明显的东西,无法弄清楚。
答案 0 :(得分:0)
在这种情况下,似乎os.system
的工作目录与DagBag加载程序正在查找的目录之间不匹配。如果您检查airflow/dagbag.py
的代码,则process_file
接受的路径将传递到os.path.isfile
:
def process_file(self, filepath, only_if_updated=True, safe_mode=True):
if filepath is None or not os.path.isfile(filepath):
...
这意味着在测试中,您可能可以进行一些测试以确保所有这些匹配:
# Make sure this works
os.path.isfile(filepath)
# Make sure these are equal
os.system('pwd')
os.getcwd()
答案 1 :(得分:0)
因此,事实证明,我在哪里创建zip文件很重要。在这种情况下,我要从测试文件夹创建zip文件,然后将文件归档到src文件夹中。尽管最终的zip文件看起来非常适合肉眼,但是气流却拒绝了它。 我尝试在zip命令中添加“ -j”(以破坏目录名),然后我的测试开始工作。
zip -r -j dag_under_test_metrics.zip ../src/metricsDAG.py
我还有另一个更大的问题,即在我的DAG项目中有完整的文件夹结构时测试相同的情况。顶层的dag文件引用了项目中的许多python模块。我无法通过上述技巧使此工作正常,但提出了解决方法。我创建了一个小的shell脚本,该脚本执行zip部分,就像这样。
SCRIPT_PATH=${0%/*/*}
cd $SCRIPT_PATH
zip -r -q test/dag_under_test.zip DagRunner.py
zip -r -q test/dag_under_test.zip tasks dag common resources
此shell脚本将currentdir更改为project home并从此处存档。我正在从pytest固定装置中调用此外壳程序,
@fixture
def setup():
os.system('rm {}'.format(DAG_UNDER_TEST))
os.system('sh {}'.format(PACKAGE_SCRIPT))
yield
print("-------- clean up -----------")
os.system('rm {}'.format(DAG_UNDER_TEST))
这非常适合我的集成测试。
def test_conversionDAG(setup):
configuration.load_test_config()
dagbag = DagBag(include_examples=False)
noOfDags = len(dagbag.dags)
dagbag.process_file(DAG_UNDER_TEST)
assert len(dagbag.dags) == noOfDags + 1, 'DAG import failures. Errors: {}'.format(dagbag.import_errors)
assert dagbag.get_dag("name of the dag")