首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用提供的工具而不是规则构建的工具来编写Bazel测试规则?

如何使用提供的工具而不是规则构建的工具来编写Bazel测试规则?
EN

Stack Overflow用户
提问于 2019-10-06 01:39:56
回答 1查看 1.4K关注 0票数 1

我有一个测试工具(粗略地说,是一个不同的工具),它接受两个输入,并返回一个输出(两个输入之间的差异)和一个返回代码(如果两个输入匹配,返回代码为0,否则为1)。它建在科特林,可在//java/fr/enoent/phosphorus在我的回购。

我想要编写一条规则,测试由某物生成的文件是否与存储库中已经存在的引用文件相同。我用ctx.actions.run尝试了一些东西,问题是我的规则,有test = True设置,需要返回由该规则构建的可执行文件(所以不是为规则提供的工具)。然后,我尝试将它封装在示例后面的shell脚本中,如下所示:

代码语言:javascript
运行
复制
def _phosphorus_test_impl(ctx):
    output = ctx.actions.declare_file("{name}.phs".format(name = ctx.label.name))
    script = phosphorus_compare(
        ctx,
        reference = ctx.file.reference,
        comparison = ctx.file.comparison,
        out = output,
    )

    ctx.actions.write(
        output = ctx.outputs.executable,
        content = script,
    )

    runfiles = ctx.runfiles(files = [ctx.executable._phosphorus_tool, ctx.file.reference, ctx.file.comparison])
    return [DefaultInfo(runfiles = runfiles)]

phosphorus_test = rule(
    _phosphorus_test_impl,
    attrs = {
        "comparison": attr.label(
            allow_single_file = [".phs"],
            doc = "File to compare to the reference",
            mandatory = True,
        ),
        "reference": attr.label(
            allow_single_file = [".phs"],
            doc = "Reference file",
            mandatory = True,
        ),
        "_phosphorus_tool": attr.label(
            default = "//java/fr/enoent/phosphorus",
            executable = True,
            cfg = "host",
        ),
    },
    doc = "Compares two files, and fails if they are different.",
    test = True,
)

(phosphorus_compare只是一个生成实际命令的宏。)

然而,这种方法有两个问题:

  • 输出不能以这种方式声明。它与任何行动都没有关联(巴泽尔也在抱怨)。也许我真的不需要为测试声明一个输出?当测试失败时,Bazel是否使测试文件夹中的任何内容可用?
  • 运行该工具所需的运行文件在测试运行时似乎不可用:java/fr/enoent/phosphorus/phosphorus: line 359: /home/kernald/.cache/bazel/_bazel_kernald/58c025fbb926eac6827117ef80f7d2fa/sandbox/linux-sandbox/1979/execroot/fr_enoent/bazel-out/k8-fastbuild/bin/tools/phosphorus/tests/should_pass.runfiles/remotejdk11_linux/bin/java: No such file or directory

总的来说,我觉得使用shell脚本只是添加了一个不必要的间接方向,并且失去了一些上下文(例如,工具的runfiles)。理想情况下,我只需要使用ctx.actions.run并依赖于它的返回代码,但它似乎不是一个选项,因为测试显然需要生成一个可执行文件。写这样一条规则的正确方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-09 08:02:55

事实证明,生成脚本是正确的方法,(据我所知)不可能返回指向ctx.actions.run的某种指针。测试规则需要有一个可执行的输出。

关于工具正在生成的输出文件:根本不需要声明它。我只需要确保它是在$TEST_UNDECLARED_OUTPUTS_DIR中生成的。这个目录中的每个文件都将被Bazel添加到一个名为output.zip的存档中。这是(部分)文档化的这里

关于runfile,我有这个工具的二进制文件,但没有它自己的runfile。这是一个固定的规则:

代码语言:javascript
运行
复制
def _phosphorus_test_impl(ctx):
    script = phosphorus_compare(
        ctx,
        reference = ctx.file.reference,
        comparison = ctx.file.comparison,
        out = "%s.phs" % ctx.label.name,
    )

    ctx.actions.write(
        output = ctx.outputs.executable,
        content = script,
    )

    return [
        DefaultInfo(
            runfiles = ctx.runfiles(
                files = [
                    ctx.executable._phosphorus_tool,
                    ctx.file.reference,
                    ctx.file.comparison,
                ],
            ).merge(ctx.attr._phosphorus_tool[DefaultInfo].default_runfiles),
            executable = ctx.outputs.executable,
        ),
    ]

def phosphorus_test(size = "small", **kwargs):
    _phosphorus_test(size = size, **kwargs)

_phosphorus_test = rule(
    _phosphorus_test_impl,
    attrs = {
        "comparison": attr.label(
            allow_single_file = [".phs"],
            doc = "File to compare to the reference",
            mandatory = True,
        ),
        "reference": attr.label(
            allow_single_file = [".phs"],
            doc = "Reference file",
            mandatory = True,
        ),
        "_phosphorus_tool": attr.label(
            default = "//java/fr/enoent/phosphorus",
            executable = True,
            cfg = "target",
        ),
    },
    doc = "Compares two files, and fails if they are different.",
    test = True,
)

关键部分是返回的.merge(ctx.attr._phosphorus_tool[DefaultInfo].default_runfiles)中的DefaultInfo

我还犯了一个关于配置的小错误,因为这个测试的目的是在目标配置上运行,而不是在主机上运行,因此已经相应地修复了它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58253616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档