气流无法识别pytest固定装置内置的zip文件DAG

时间:2019-05-16 10:25:24

标签: python zip airflow google-cloud-composer

我们正在将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文件正在被气流加载!似乎我在这里缺少明显的东西,无法弄清楚。

2 个答案:

答案 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")