diff --git a/labgrid/config/BUILD.bazel b/labgrid/config/BUILD.bazel index 52f77d0ef22cdc74e1d6d61e194cb53966a31f2a..f4c3b1f997c67bb96913145c503825167e8eeb01 100644 --- a/labgrid/config/BUILD.bazel +++ b/labgrid/config/BUILD.bazel @@ -3,6 +3,7 @@ load(":data.bzl", "data") load(":deps.bzl", "deps") load(":env.bzl", "env") load(":managers.bzl", "managers") +load(":tests.bzl", "suite") load(":tools.bzl", "tools") env( @@ -60,3 +61,8 @@ bzl_library( visibility = ["//visibility:public"], deps = ["//labgrid/cfg:unstore"], ) + +suite( + name = "suite", + visibility = ["//visibility:private"], +) diff --git a/labgrid/config/rule.bzl b/labgrid/config/rule.bzl index 3205d9f3316aabcf69dc8f6a09d3e6d1d4930db1..50b3fb309520af876faaff7c50ce289ee622a3ba 100644 --- a/labgrid/config/rule.bzl +++ b/labgrid/config/rule.bzl @@ -61,30 +61,40 @@ ATTRS = { doc = "The labgrid configuration Python dependencies.", providers = [[DefaultInfo, PyInfo]], cfg = "exec", + default = [], ), "env": attr.string_dict( doc = "The environment variables to set for the configuration. Subject to `$(location)` and \"Make\" variable substitution.", + default = {}, + ), + "place_tags": attr.string_dict( + doc = "The tags to use when reserving a place.", + default = {}, ), "state": attr.label( doc = "The states to transition the configuration strategy to.", providers = [LabgridStateInfo], + default = "//labgrid/state", ), "data": attr.label_list( allow_files = True, doc = "The data files to use in the configuration.", providers = [DefaultInfo], cfg = "target", + default = [], ), "tools": attr.label_list( allow_files = True, doc = "The tools to use in the configuration.", providers = [DefaultInfo], cfg = "exec", + default = [], ), "managers": attr.label_list( doc = "A list of Python context managers to customize the setup of the labgrid environment.", providers = [[DefaultInfo, PyInfo]], cfg = "exec", + default = [], ), } @@ -135,7 +145,14 @@ def _forward_runfiles(ctx, targets): runfiles = runfiles.merge_all([d.default_runfiles for d in targets]) return DefaultInfo(files = files, runfiles = runfiles) -def _state_env(state): +def _src_env(ctx): + src = ctx.attr.src.label + return { + "LG_ENV": "$(location {})".format(src), + } + +def _state_env(ctx): + state = ctx.attr.state[LabgridStateInfo] tuples = [ ("LG_INITIAL_STATE", state.initial), ("LG_STATE", state.desired), @@ -143,10 +160,16 @@ def _state_env(state): ] return {k: v for k, v in tuples if v} +def _place_tags_env(ctx): + place_tags = ctx.attr.place_tags + if place_tags: + return {"BZL_LG_TAGS": " ".join(["{}={}".format(k, v) for k, v in place_tags.items()])} + return {} + def implementation(ctx): data = ctx.attr.data + [ctx.attr.src] tools = ctx.attr.tools + ctx.attr.toolchains - env = {k: _expand(ctx, data, v) for k, v in ctx.attr.env.items()} | _state_env(ctx.attr.state[LabgridStateInfo]) + env = {k: _expand(ctx, data, v) for k, v in (ctx.attr.env | _src_env(ctx) | _state_env(ctx) | _place_tags_env(ctx)).items()} default = DefaultInfo(files = depset([ctx.file.src])) toolchain = platform_common.ToolchainInfo( src = ctx.file.src, diff --git a/labgrid/config/tests.bzl b/labgrid/config/tests.bzl new file mode 100644 index 0000000000000000000000000000000000000000..95a6a4087ac8219589bfe861e4b80b08d88afb44 --- /dev/null +++ b/labgrid/config/tests.bzl @@ -0,0 +1,111 @@ +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@bazel_skylib//rules:write_file.bzl", "write_file") +load("//labgrid/state:defs.bzl", "labgrid_state") +load(":rule.bzl", "labgrid_config") + +def _test_src_env(name): + src = "{}.yml".format(name) + + write_file( + name = "{}.file".format(name), + out = src, + ) + + labgrid_config( + name = "{}.config".format(name), + src = src, + ) + + env_contains_test( + name = name, + target_under_test = "{}.config".format(name), + subset = { + "LG_ENV": "$(rlocationpath {})".format(src), + }, + data = [src], + ) + +def _test_state_env(name): + state = "{}.state".format(name) + + write_file( + name = "{}.file".format(name), + out = "{}.yml".format(name), + ) + + labgrid_state( + name = state, + initial = "one", + desired = "two", + final = "three", + ) + + labgrid_config( + name = "{}.config".format(name), + src = "{}.yml".format(name), + state = state, + ) + + env_contains_test( + name = name, + target_under_test = "{}.config".format(name), + subset = { + "LG_INITIAL_STATE": "one", + "LG_STATE": "two", + "BZL_LG_FINAL_STATE": "three", + }, + ) + +def _test_place_tags_env(name): + write_file( + name = "{}.file".format(name), + out = "{}.yml".format(name), + ) + + labgrid_config( + name = "{}.config".format(name), + src = "{}.yml".format(name), + place_tags = { + "ONE": "1", + "TWO": "2", + }, + ) + + env_contains_test( + name = name, + target_under_test = "{}.config".format(name), + subset = { + "BZL_LG_TAGS": "ONE=1 TWO=2", + }, + ) + +def suite(name, **kwargs): + _test_src_env("src-env-test") + _test_state_env("state-env-test") + _test_place_tags_env("place-tags-env-test") + + native.test_suite( + name = name, + tests = [ + ":src-env-test", + ":state-env-test", + ":place-tags-env-test", + ], + **kwargs + ) + +def _env_contains_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + subset = {k: ctx.expand_location(v, ctx.attr.data) for k, v in ctx.attr.subset.items()} + for k, v in subset.items(): + asserts.equals(env, v, target[platform_common.ToolchainInfo].env.get(k, None)) + return analysistest.end(env) + +env_contains_test = analysistest.make( + impl = _env_contains_impl, + attrs = { + "subset": attr.string_dict(), + "data": attr.label_list(allow_files = True), + }, +) diff --git a/labgrid/config/toolchain/macro.bzl b/labgrid/config/toolchain/macro.bzl index ed2cb81097843063fa25b21d37876a3e21becd4d..69179127bf2b790c14bba1bdc5b8121c9f530911 100644 --- a/labgrid/config/toolchain/macro.bzl +++ b/labgrid/config/toolchain/macro.bzl @@ -2,7 +2,7 @@ load("@rules_labgrid//labgrid/config:defs.bzl", "labgrid_config") visibility("//...") -def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatible_with = [], state = "@rules_labgrid//labgrid/state", managers = [], deps = [], env = {}, data = [], tools = [], toolchains = []): +def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatible_with = [], managers = [], deps = [], **kwargs): """Registers a labgrid configuration as a toolchain of type `@rules_labgrid//labgrid/toolchain/config:type`. Args: @@ -10,27 +10,17 @@ def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatib src: The labgrid configuration YAML. target_compatible_with: The constraints to set for the target. exec_compatible_with: The constraints to set for the exec. - state: The states to transition the configuration strategy to managers: A list of Python context managers to customize the setup of the labgrid environment. deps: The labgrid configuration Python dependencies. - env: The environment variables to set for the configuration. `LG_ENV` is always set to the path of `src`. Subject to `$(location)` and \"Make\" variable substitution. - data: The data files to use in the configuration. - tools: The tools to use in the configuration. - toolchains: The toolchains to use in the configuration. + **kwargs: Extra attributes to pass to `labgrid_config` """ src = native.package_relative_label(src) labgrid_config( name = "{}-config".format(name), src = src, deps = [native.package_relative_label(d) for d in deps], - env = env | { - "LG_ENV": "$(location {})".format(src), - }, - state = state, - data = data, - tools = tools, - toolchains = toolchains, managers = [native.package_relative_label(m) for m in managers], + **kwargs ) target_constraints = [native.package_relative_label(c) for c in target_compatible_with]