Skip to content

Latest commit

 

History

History
126 lines (91 loc) · 6.25 KB

test.md

File metadata and controls

126 lines (91 loc) · 6.25 KB

Public API for testing container images.

load("@rules_img//img:test.bzl", "image_size_test", "image_structure_test")

image_size_test

load("@rules_img//img:test.bzl", "image_size_test")

image_size_test(name, image, max_duplicated_bytes, max_wasted_bytes)

Budgets the wasted and duplicated bytes an image ships across its layers.

image_size_test replays the image's per-layer mtrees in layer order -- the test itself never reads a layer blob -- and fails when a budget is exceeded:

  • Wasted bytes (max_wasted_bytes): file bytes shipped in a layer that a later layer shadows with an overwrite, a whiteout (.wh.<name>), or an opaque whiteout (.wh..wh..opq). They are pulled with every image but are unreachable in the final filesystem.
  • Duplicated bytes (max_duplicated_bytes): identical file content (by sha256digest) live at multiple paths, counted once per extra copy. A hardlink group ships its content once however many names point at it, and symlinks carry no file bytes, so neither inflates the count.

Both are counted in uncompressed tar entry sizes, so they are larger than the compressed bytes a registry reports for the same layers. At least one budget must be set. On failure the test lists the largest offenders, each attributed to the layer that wrote the bytes and the layer that shadowed them (with the producing target where the layer history records it).

The image must be a rules_img image_manifest or image_index; for an index, every single-platform child image is checked.

Every layer must expose its filesystem content, otherwise the test fails with an "incomplete layer metadata" error rather than silently passing on a subset of the image. In particular a base image pulled with the default layer_handling = "shallow" never fetches its layer blobs, so it has no mtree to replay: pull it with layer_handling = "eager" to make an image on top of it measurable.

Example:

load("@rules_img//img:test.bzl", "image_size_test")

image_size_test(
    name = "app_size_test",
    image = ":app",
    max_wasted_bytes = "10MiB",
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
image Image to check: a rules_img image_manifest or image_index. Label required
max_duplicated_bytes Budget for duplicated bytes (identical file content live at multiple paths, counted once per extra copy).

A byte count, optionally with a KiB/MiB/GiB/TiB suffix (e.g. "10000000", "512MiB"). Empty (the default) leaves duplicated bytes unchecked; the measured value is still reported.
String optional ""
max_wasted_bytes Budget for wasted bytes (shipped file bytes shadowed by a later layer).

A byte count, optionally with a KiB/MiB/GiB/TiB suffix (e.g. "10000000", "512MiB"). Empty (the default) leaves wasted bytes unchecked; the measured value is still reported.
String optional ""

image_structure_test

load("@rules_img//img:test.bzl", "image_structure_test")

image_structure_test(name, configs, image)

Validates a container image's structure using its config JSON and mtree.

image_structure_test is a lightweight, hermetic analogue of container-structure-test: it accepts the same YAML/JSON config files, but validates the image using only its image config JSON and its mtree filesystem listing -- it never materializes the layer blobs into the test. Because of that, checks that require a running container or file contents are not supported and cause a clear failure (so a migrated config tells you exactly what won't port):

  • Supported (metadataTest): env / envVars, labels, entrypoint, cmd, exposedPorts, volumes, workdir, user -- validated against the image config JSON.
  • Supported (fileExistenceTests): path, shouldExist, permissions, uid, gid, isExecutableBy -- validated against the image mtree.
  • Rejected: commandTests (require running the container), fileContentTests (require file bytes), licenseTests (require scanning a running container).

The image may be a rules_img image_manifest or image_index, a target that exposes prebuilt mtree and oci_image_config output groups (paired positionally in sorted order), or an OCI image layout directory (a tree artifact, e.g. a rules_oci oci_image). For a multi-platform image_index, every config is validated against each single-platform image.

Example:

load("@rules_img//img:test.bzl", "image_structure_test")

image_structure_test(
    name = "hello_test",
    configs = ["testdata/hello.yaml"],
    image = ":hello",
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
configs container-structure-test config files (YAML or JSON). List of labels required
image Image to validate: a rules_img image_manifest/image_index, a target exposing mtree + oci_image_config output groups, or an OCI image layout directory (rules_oci). Label required