sawchain

package module
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

README

Sawchain

Go Reference Go Report Card Code Coverage

Go library for K8s YAML-driven testing—powered by Chainsaw

Sawchain

Documentation

Examples

Contributions

Please read the contributing guide for details on how to contribute.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Sawchain

type Sawchain struct {
	// contains filtered or unexported fields
}

Sawchain provides utilities for K8s YAML-driven testing—powered by Chainsaw. It includes helpers to reliably create/update/delete test resources, Gomega-friendly APIs to simplify assertions, and more.

Use New to create a Sawchain instance.

More documentation is available at https://github.com/guidewire-oss/sawchain/tree/main/docs.

func New

func New(t testing.TB, c client.Client, args ...any) *Sawchain

New creates a new Sawchain instance with the provided global settings, using an internal Gomega instance for assertions.

The testing.TB is used for test helper marking, logging, and Gomega assertions. The client.Client is used for all K8s API operations.

Arguments

The following arguments may be provided in any order (unless noted otherwise) after t and c:

  • Bindings (map[string]any): Optional. Global bindings to be used in all Chainsaw template operations. If multiple maps are provided, they will be merged in natural order.

  • Timeout (string or time.Duration): Optional. Defaults to 5s. Default timeout for eventual assertions. If provided, must be before interval.

  • Interval (string or time.Duration): Optional. Defaults to 1s. Default polling interval for eventual assertions. If provided, must be after timeout.

Notes

  • Invalid input will result in immediate test failure.

  • Sawchain's timeout and interval settings control all internal eventual assertions. Gomega global or instance-level duration defaults are ignored within Sawchain operations.

  • Use NewWithGomega if you need to provide a custom Gomega instance with a custom fail handler.

Examples

Initialize Sawchain with the default settings:

sc := sawchain.New(t, k8sClient)

Initialize Sawchain with global bindings:

sc := sawchain.New(t, k8sClient, map[string]any{"namespace", "test"})

Initialize Sawchain with custom timeout and interval settings:

sc := sawchain.New(t, k8sClient, "10s", "2s")

func NewWithGomega added in v0.2.0

func NewWithGomega(t testing.TB, g gomega.Gomega, c client.Client, args ...any) *Sawchain

NewWithGomega creates a new Sawchain instance with a custom Gomega instance and provided global settings.

All assertions performed by Sawchain (including input validation) will use the provided Gomega instance. This is useful for registering custom fail handlers or maintaining consistent Gomega configuration across multiple Sawchain instances.

The testing.TB is used for test helper marking and logging. The client.Client is used for all K8s API operations.

Arguments

The following arguments may be provided in any order (unless noted otherwise) after t, g, and c:

  • Bindings (map[string]any): Optional. Global bindings to be used in all Chainsaw template operations. If multiple maps are provided, they will be merged in natural order.

  • Timeout (string or time.Duration): Optional. Defaults to 5s. Default timeout for eventual assertions. If provided, must be before interval.

  • Interval (string or time.Duration): Optional. Defaults to 1s. Default polling interval for eventual assertions. If provided, must be after timeout.

Notes

  • Invalid input will result in immediate test failure.

  • Sawchain's timeout and interval settings control all internal eventual assertions. Gomega global or instance-level duration defaults are ignored within Sawchain operations.

Examples

Initialize Sawchain with a custom fail handler:

customFailHandler := func(message string, callerSkip ...int) {
    isTestFailed = true
    Fail(message, callerSkip...)
}
g := gomega.NewGomega(customFailHandler)
sc := sawchain.NewWithGomega(t, g, k8sClient)

Initialize Sawchain with a custom Gomega instance and global bindings:

g := gomega.NewGomega(customFailHandler)
sc := sawchain.NewWithGomega(t, g, k8sClient, map[string]any{"namespace": "test"})

Initialize Sawchain with a custom Gomega instance and custom timeout settings:

g := gomega.NewGomega(customFailHandler)
sc := sawchain.NewWithGomega(t, g, k8sClient, "10s", "2s")

func (*Sawchain) Check

func (s *Sawchain) Check(ctx context.Context, args ...any) error

Check searches the cluster for resources matching YAML expectations defined in a template and optionally saves found matches to objects for type-safe access. If no match is found, a detailed error will be returned.

Arguments

The following arguments may be provided in any order after the context:

  • Template (string): Required. File path or content of a static manifest or Chainsaw template containing type metadata and expectations of resources to check. If provided with an object, must contain exactly one resource expectation document matching the type of the object. If provided with a slice of objects, must contain resource expectation documents exactly matching the count, order, and types of the objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

  • Object (client.Object): Typed or unstructured object to populate with the state of the first match (if found) for the expected resource defined in the template. Only valid with a single-document template.

  • Objects ([]client.Object): Slice of typed or unstructured objects to populate with the states of the first matches (if found) for each expected resource defined in the template.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • A "check" for one resource is equivalent to a Chainsaw assert resource operation without polling, including full support for Chainsaw JMESPath expressions.

  • Because Chainsaw performs partial/subset matching on resource fields (expected fields must exist, extras are allowed), template expectations only have to include fields of interest, not necessarily complete resource definitions.

  • Use CheckFunc if you need to create a Check function for polling.

Examples

Check with a file:

err := sc.Check(ctx, "path/to/expectation.yaml")

Check for a ConfigMap with specific name, namespace, and data:

err := sc.Check(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: test-cm
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"namespace": "default"})

Check for a ConfigMap with specific data and save the first match to an object:

configMap := &corev1.ConfigMap{}
err := sc.Check(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  data:
    foo: bar
    (length(bar) >= `3`): true
`)

Check for multiple resources with labels and save the first matches to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
err := sc.Check(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    namespace: ($namespace)
    labels:
      foo: bar
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    namespace: ($namespace)
    labels:
      bar: baz
  `, map[string]any{"namespace": "default"})

For more Chainsaw examples, see https://github.com/guidewire-oss/sawchain/blob/main/docs/chainsaw-cheatsheet.md.

func (*Sawchain) CheckFunc

func (s *Sawchain) CheckFunc(ctx context.Context, args ...any) func() error

CheckFunc returns a function that searches the cluster for resources matching YAML expectations defined in a template and optionally saves found matches to objects for type-safe access.

The returned function performs the same operations as Check, but is particularly useful for polling scenarios where resources might not be immediately available.

For details on arguments, examples, and behavior, see the documentation for Check.

func (*Sawchain) Create

func (s *Sawchain) Create(ctx context.Context, args ...any) error

Create creates resources with objects, a manifest, or a Chainsaw template, and returns an error if any client Create operations fail.

Arguments

The following arguments may be provided in any order after the context:

  • Object (client.Object): Typed or unstructured object for reading/writing the state of a single resource. If provided without a template, resource state will be read from the object for creation. If provided with a template, resource state will be read from the template and written to the object.

  • Objects ([]client.Object): Slice of typed or unstructured objects for reading/writing the states of multiple resources. If provided without a template, resource states will be read from the objects for creation. If provided with a template, resource states will be read from the template and written to the objects.

  • Template (string): File path or content of a static manifest or Chainsaw template containing complete resource definitions to be read for creation. If provided with an object, must contain exactly one resource definition matching the type of the object. If provided with a slice of objects, must contain resource definitions exactly matching the count, order, and types of the objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When running tests in parallel, ensure resource names or namespaces are unique per process to prevent collisions. See docs/parallel-tests.md for isolation strategies.

  • Use CreateAndWait instead of Create if you need to ensure creation is successful and the client cache is synced.

Examples

Create a single resource with an object:

err := sc.Create(ctx, obj)

Create multiple resources with objects:

err := sc.Create(ctx, []client.Object{obj1, obj2, obj3})

Create resources with a manifest file:

err := sc.Create(ctx, "path/to/resources.yaml")

Create a single resource with a Chainsaw template and bindings:

err := sc.Create(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Create a single resource with a Chainsaw template and save the resource's state to an object:

configMap := &corev1.ConfigMap{}
err := sc.Create(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Create multiple resources with a Chainsaw template and bindings:

err := sc.Create(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Create multiple resources with a Chainsaw template and save the resources' states to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
err := sc.Create(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) CreateAndWait

func (s *Sawchain) CreateAndWait(ctx context.Context, args ...any)

CreateAndWait creates resources with objects, a manifest, or a Chainsaw template, and ensures client Get operations for all resources succeed within a configurable duration before returning. If testing with a cached client, this ensures the client cache is synced and it is safe to make assertions on the resources immediately after execution.

Arguments

The following arguments may be provided in any order (unless noted otherwise) after the context:

  • Object (client.Object): Typed or unstructured object for reading/writing the state of a single resource. If provided without a template, resource state will be read from the object for creation. If provided with a template, resource state will be read from the template and written to the object.

  • Objects ([]client.Object): Slice of typed or unstructured objects for reading/writing the states of multiple resources. If provided without a template, resource states will be read from the objects for creation. If provided with a template, resource states will be read from the template and written to the objects.

  • Template (string): File path or content of a static manifest or Chainsaw template containing complete resource definitions to be read for creation. If provided with an object, must contain exactly one resource definition matching the type of the object. If provided with a slice of objects, must contain resource definitions exactly matching the count, order, and types of the objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

  • Timeout (string or time.Duration): Duration within which client Get operations for all resources should succeed after creation. If provided, must be before interval. Defaults to Sawchain's global timeout value.

  • Interval (string or time.Duration): Polling interval for checking the resources after creation. If provided, must be after timeout. Defaults to Sawchain's global interval value.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together. All other arguments are optional.

Notes

  • Invalid input, client errors, and timeout errors will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When running tests in parallel, ensure resource names or namespaces are unique per process to prevent collisions. See docs/parallel-tests.md for isolation strategies.

  • Use Create instead of CreateAndWait if you need to create resources without ensuring success.

Examples

Create a single resource with an object:

sc.CreateAndWait(ctx, obj)

Create multiple resources with objects:

sc.CreateAndWait(ctx, []client.Object{obj1, obj2, obj3})

Create resources with a manifest file and override duration settings:

sc.CreateAndWait(ctx, "path/to/resources.yaml", "10s", "2s")

Create a single resource with a Chainsaw template and bindings:

sc.CreateAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Create a single resource with a Chainsaw template and save the resource's state to an object:

configMap := &corev1.ConfigMap{}
sc.CreateAndWait(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Create multiple resources with a Chainsaw template and bindings:

sc.CreateAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Create multiple resources with a Chainsaw template and save the resources' states to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
sc.CreateAndWait(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) Delete

func (s *Sawchain) Delete(ctx context.Context, args ...any) error

Delete deletes resources with objects, a manifest, or a Chainsaw template, and returns an error if any client Delete operations fail.

Arguments

The following arguments may be provided in any order after the context:

  • Object (client.Object): Typed or unstructured object representing a single resource to be deleted. If provided with a template, the template will take precedence and the object will be ignored.

  • Objects ([]client.Object): Slice of typed or unstructured objects representing multiple resources to be deleted. If provided with a template, the template will take precedence and the objects will be ignored.

  • Template (string): File path or content of a static manifest or Chainsaw template containing the identifiers of the resources to be deleted. Takes precedence over objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together.

Notes

  • Invalid input will result in immediate test failure.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When running tests in parallel, ensure resource names or namespaces are unique per process to prevent collisions. See docs/parallel-tests.md for isolation strategies.

  • Use DeleteAndWait instead of Delete if you need to ensure deletion is successful and the client cache is synced.

Examples

Delete a single resource with an object:

err := sc.Delete(ctx, obj)

Delete multiple resources with objects:

err := sc.Delete(ctx, []client.Object{obj1, obj2, obj3})

Delete resources with a manifest file:

err := sc.Delete(ctx, "path/to/resources.yaml")

Delete a single resource with a Chainsaw template and bindings:

err := sc.Delete(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Delete multiple resources with a Chainsaw template and bindings:

err := sc.Delete(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) DeleteAndWait

func (s *Sawchain) DeleteAndWait(ctx context.Context, args ...any)

DeleteAndWait deletes resources with objects, a manifest, or a Chainsaw template, and ensures client Get operations for all resources reflect the deletion (resources not found) within a configurable duration before returning. If testing with a cached client, this ensures the client cache is synced and it is safe to make assertions on the resources' absence immediately after execution.

Arguments

The following arguments may be provided in any order (unless noted otherwise) after the context:

  • Object (client.Object): Typed or unstructured object representing a single resource to be deleted. If provided with a template, the template will take precedence and the object will be ignored.

  • Objects ([]client.Object): Slice of typed or unstructured objects representing multiple resources to be deleted. If provided with a template, the template will take precedence and the objects will be ignored.

  • Template (string): File path or content of a static manifest or Chainsaw template containing the identifiers of the resources to be deleted. Takes precedence over objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

  • Timeout (string or time.Duration): Duration within which client Get operations for all resources should reflect deletion. If provided, must be before interval. Defaults to Sawchain's global timeout value.

  • Interval (string or time.Duration): Polling interval for checking the resources after deletion. If provided, must be after timeout. Defaults to Sawchain's global interval value.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together. All other arguments are optional.

Notes

  • Invalid input, client errors, and timeout errors will result in immediate test failure.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When running tests in parallel, ensure resource names or namespaces are unique per process to prevent collisions. See docs/parallel-tests.md for isolation strategies.

  • Use Delete instead of DeleteAndWait if you need to delete resources without ensuring success.

Examples

Delete a single resource with an object:

sc.DeleteAndWait(ctx, obj)

Delete multiple resources with objects:

sc.DeleteAndWait(ctx, []client.Object{obj1, obj2, obj3})

Delete resources with a manifest file and override duration settings:

sc.DeleteAndWait(ctx, "path/to/resources.yaml", "10s", "2s")

Delete a single resource with a Chainsaw template and bindings:

sc.DeleteAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Delete multiple resources with a Chainsaw template and bindings:

sc.DeleteAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) FetchMultiple

func (s *Sawchain) FetchMultiple(ctx context.Context, args ...any) []client.Object

FetchMultiple retrieves multiple resources with objects, a manifest, or a Chainsaw template, saves their states to the objects (if provided), and returns the objects. This is especially useful for assertions on resource states when the resources are expected to already exist.

Arguments

The following arguments may be provided in any order after the context:

  • Objects ([]client.Object): Slice of typed or unstructured objects for reading/writing resource states. If provided without a template, resource states will be read from the objects for identification and written back to the objects. If provided with a template, resource states will be read from the template for identification and written to the objects.

  • Template (string): File path or content of a static manifest or Chainsaw template containing resource identifiers to be read for retrieval. Must contain resource identifiers exactly matching the count, order, and types of the objects (if provided).

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

A template or objects must be provided.

Notes

  • Invalid input and client errors will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When no input objects are provided and objects must be returned, FetchMultiple attempts to return typed objects. If typed objects cannot be created (i.e., if the client scheme does not support the necessary types), unstructured objects will be returned instead.

  • Use FetchMultipleFunc if you need to create a FetchMultiple function for polling.

Examples

Fetch resources with objects:

fetchedObjs := sc.FetchMultiple(ctx, []client.Object{configMap, secret})

Fetch resources with a manifest file:

fetchedObjs := sc.FetchMultiple(ctx, "path/to/resources.yaml")

Fetch resources with a Chainsaw template and bindings:

fetchedObjs := sc.FetchMultiple(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  `, map[string]any{"prefix": "test", "namespace": "default"})

Fetch resources with a Chainsaw template and save their states to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
fetchedObjs := sc.FetchMultiple(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) FetchMultipleFunc

func (s *Sawchain) FetchMultipleFunc(ctx context.Context, args ...any) func() []client.Object

FetchMultipleFunc returns a function that retrieves multiple resources with objects, a manifest, or a Chainsaw template, saves their states to the objects (if provided), and returns the objects.

The returned function performs the same operations as FetchMultiple, but is particularly useful for polling scenarios where resources might not immediately reflect the desired state.

For details on arguments, examples, and behavior, see the documentation for FetchMultiple.

func (*Sawchain) FetchSingle

func (s *Sawchain) FetchSingle(ctx context.Context, args ...any) client.Object

FetchSingle retrieves a single resource with an object, a manifest, or a Chainsaw template, saves its state to the object (if provided), and returns the object. This is especially useful for assertions on resource state when the resource is expected to already exist.

Arguments

The following arguments may be provided in any order after the context:

  • Object (client.Object): Typed or unstructured object for reading/writing resource state. If provided without a template, resource state will be read from the object for identification and written back to the object. If provided with a template, resource state will be read from the template for identification and written to the object.

  • Template (string): File path or content of a static manifest or Chainsaw template containing a resource identifier to be read for retrieval. Must contain exactly one resource identifier matching the type of the object (if provided).

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

A template or an object must be provided.

Notes

  • Invalid input and client errors will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When no input object is provided and an object must be returned, FetchSingle attempts to return a typed object. If a typed object cannot be created (i.e., if the client scheme does not support the necessary type), an unstructured object will be returned instead.

  • Use FetchSingleFunc if you need to create a FetchSingle function for polling.

Examples

Fetch a resource with an object:

fetched := sc.FetchSingle(ctx, obj)

Fetch a resource with a manifest file:

fetched := sc.FetchSingle(ctx, "path/to/configmap.yaml")

Fetch a resource with a Chainsaw template and bindings:

fetched := sc.FetchSingle(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Fetch a resource with a Chainsaw template and save the resource's state to an object:

configMap := &corev1.ConfigMap{}
fetched := sc.FetchSingle(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  `, map[string]any{"name": "test-cm", "namespace": "default"})

func (*Sawchain) FetchSingleFunc

func (s *Sawchain) FetchSingleFunc(ctx context.Context, args ...any) func() client.Object

FetchSingleFunc returns a function that retrieves a single resource with an object, a manifest, or a Chainsaw template, saves its state to the object (if provided), and returns the object.

The returned function performs the same operations as FetchSingle, but is particularly useful for polling scenarios where resources might not immediately reflect the desired state.

For details on arguments, examples, and behavior, see the documentation for FetchSingle.

func (*Sawchain) Get

func (s *Sawchain) Get(ctx context.Context, args ...any) error

Get retrieves resources with objects, a manifest, or a Chainsaw template, and returns an error if any client Get operations fail. This is especially useful for assertions on resource existence.

Arguments

The following arguments may be provided in any order after the context:

  • Object (client.Object): Typed or unstructured object for reading/writing the state of a single resource. If provided without a template, resource state will be read from the object for identification and written back to the object. If provided with a template, resource state will be read from the template for identification and written to the object.

  • Objects ([]client.Object): Slice of typed or unstructured objects for reading/writing the states of multiple resources. If provided without a template, resource states will be read from the objects for identification and written back to the objects. If provided with a template, resource states will be read from the template for identification and written to the objects.

  • Template (string): File path or content of a static manifest or Chainsaw template containing resource identifiers to be read for retrieval. If provided with an object, must contain exactly one resource identifier matching the type of the object. If provided with a slice of objects, must contain resource identifiers exactly matching the count, order, and types of the objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • Use GetFunc if you need to create a Get function for polling.

Examples

Get a single resource with an object:

err := sc.Get(ctx, obj)

Get multiple resources with objects:

err := sc.Get(ctx, []client.Object{obj1, obj2, obj3})

Get resources with a manifest file:

err := sc.Get(ctx, "path/to/resources.yaml")

Get a single resource with a Chainsaw template and bindings:

err := sc.Get(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Get a single resource with a Chainsaw template and save the resource's state to an object:

configMap := &corev1.ConfigMap{}
err := sc.Get(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Get multiple resources with a Chainsaw template and bindings:

err := sc.Get(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  `, map[string]any{"prefix": "test", "namespace": "default"})

Get multiple resources with a Chainsaw template and save the resources' states to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
err := sc.Get(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) GetFunc

func (s *Sawchain) GetFunc(ctx context.Context, args ...any) func() error

GetFunc returns a function that retrieves resources with objects, a manifest, or a Chainsaw template, and returns an error if any client Get operations fail.

The returned function performs the same operations as Get, but is particularly useful for polling scenarios where resources might not be immediately available.

For details on arguments, examples, and behavior, see the documentation for Get.

func (*Sawchain) HaveStatusCondition

func (s *Sawchain) HaveStatusCondition(conditionType, expectedStatus string) types.GomegaMatcher

HaveStatusCondition returns a Gomega matcher that uses Chainsaw matching to check if a client.Object has a specific status condition.

Arguments

  • ConditionType (string): The type of the status condition to check for.

  • ExpectedStatus (string): The expected status value of the condition.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • For optimal failure output, use individual assertions in a for-loop rather than collection matchers (e.g., HaveEach, ContainElement). Collection matchers work correctly but provide limited error details due to Gomega limitations. If collection matchers are necessary, enable format.UseStringerRepresentation for slightly better output.

Examples

Check if a Deployment has condition Available=True:

Expect(deployment).To(sc.HaveStatusCondition("Available", "True"))

Check if a Pod has condition Ready=True:

Expect(pod).To(sc.HaveStatusCondition("Ready", "True"))

Check if multiple resources have condition Ready=True:

for _, obj := range objs {
    Expect(obj).To(sc.HaveStatusCondition("Ready", "True"))
}

func (*Sawchain) List added in v0.3.0

func (s *Sawchain) List(ctx context.Context, template string, bindings ...map[string]any) []client.Object

List retrieves all resources matching YAML expectations defined in a template, enabling assertions on counts and collective properties. Returns an empty slice (not an error) when no matches are found.

Arguments

  • Template (string): Required. File path or content of a static manifest or Chainsaw template containing type metadata and expectations of resources to list. Must contain exactly one resource expectation document.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

Notes

  • Invalid input will result in immediate test failure.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When the scheme supports the resource type, typed objects are returned. Otherwise, unstructured objects are returned.

  • Use ListFunc if you need to create a List function for polling.

Examples

List all ConfigMaps cluster-wide:

matches := sc.List(ctx, `
  apiVersion: v1
  kind: ConfigMap
`)

List ConfigMaps with specific labels and data fields:

matches := sc.List(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    labels:
      app: myapp
  data:
    environment: ($env)
  `, map[string]any{"env": "production"})

Assert on count with a file:

Expect(sc.List(ctx, "path/to/expectation.yaml")).To(HaveLen(3))

Wait for all Pods in a namespace to be Ready:

Eventually(sc.ListFunc(ctx, `
  apiVersion: v1
  kind: Pod
  metadata:
    namespace: default
`)).Should(HaveEach(sc.HaveStatusCondition("Ready", "True")))

func (*Sawchain) ListFunc added in v0.3.0

func (s *Sawchain) ListFunc(ctx context.Context, template string, bindings ...map[string]any) func() []client.Object

ListFunc returns a function that retrieves all resources matching YAML expectations defined in a template.

The returned function performs the same operations as List, but is particularly useful for polling scenarios where resources might not be immediately available.

For details on arguments, examples, and behavior, see the documentation for List.

func (*Sawchain) MatchYAML

func (s *Sawchain) MatchYAML(template string, bindings ...map[string]any) types.GomegaMatcher

MatchYAML returns a Gomega matcher that checks if a client.Object matches YAML expectations defined in a template, including full support for Chainsaw JMESPath expressions, as well as multi-document matching with "match any document" semantics.

Arguments

  • Template (string): File path or content of a static manifest or Chainsaw template containing the type metadata and expectations to match against.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • Multi-document templates use "match any document" semantics: the matcher succeeds if the object matches at least one of the documents in the template.

  • Because Chainsaw performs partial/subset matching on resource fields (expected fields must exist, extras are allowed), template expectations only have to include fields of interest, not necessarily complete resource definitions.

  • For optimal failure output, use individual assertions in a for-loop rather than collection matchers (e.g., HaveEach, ContainElement). Collection matchers work correctly but provide limited error details due to Gomega limitations. If collection matchers are necessary, enable format.UseStringerRepresentation for slightly better output.

Examples

Match an object with a template and bindings:

Expect(configMap).To(sc.MatchYAML(`
  apiVersion: v1
  kind: ConfigMap
  data:
    key1: ($value1)
    key2: ($value2)
  `, map[string]any{"value1": "foo", "value2": "bar"}))

Match a Deployment's replica count using a JMESPath expression:

Expect(deployment).To(sc.MatchYAML(`
  apiVersion: apps/v1
  kind: Deployment
  spec:
    (replicas > `1` && replicas < `4`): true
`))

Match multiple objects with a multi-document template file:

for _, obj := range objs {
    Expect(obj).To(sc.MatchYAML("path/to/expected-outputs.yaml"))
}

For more Chainsaw examples, see https://github.com/guidewire-oss/sawchain/blob/main/docs/chainsaw-cheatsheet.md.

func (*Sawchain) RenderMultiple

func (s *Sawchain) RenderMultiple(args ...any) []client.Object

RenderMultiple renders a multi-resource Chainsaw template (or unmarshals a static manifest) into a slice of objects and returns it.

Arguments

The following arguments may be provided in any order:

  • Template (string): Required. File path or content of a static manifest or Chainsaw template to render. Must contain complete resource definitions exactly matching the count, order, and types of the objects (if provided).

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

  • Objects ([]client.Object): Slice of typed or unstructured objects to render into.

When no objects are provided, RenderMultiple attempts to return typed objects. If typed objects cannot be created (i.e., if the client scheme does not support the necessary types), unstructured objects will be returned instead.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • RenderMultiple supports two usage modes: returning a slice of client.Object for use in generic worklows, or populating a slice of provided client.Object pointers for type-safe access (without needing type assertions).

  • With populate mode, the provided objects will also be returned.

Examples

Render a template with bindings (return mode, generic):

objs := sc.RenderMultiple(`
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Render a template with bindings (populate mode, type-safe):

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
sc.RenderMultiple([]client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Unmarshal a static manifest file (populate mode, type-safe):

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
sc.RenderMultiple([]client.Object{configMap, secret}, "path/to/resources.yaml")

func (*Sawchain) RenderSingle

func (s *Sawchain) RenderSingle(args ...any) client.Object

RenderSingle renders a single-resource Chainsaw template (or unmarshals a static manifest) into an object and returns it.

Arguments

The following arguments may be provided in any order:

  • Template (string): Required. File path or content of a static manifest or Chainsaw template to render. Must contain exactly one complete resource definition matching the type of the object (if provided).

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

  • Object (client.Object): Typed or unstructured object to render into.

When no object is provided, RenderSingle attempts to return a typed object. If a typed object cannot be created (i.e., if the client scheme does not support the necessary type), an unstructured object will be returned instead.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • RenderSingle supports two usage modes: returning a client.Object for use in generic worklows, or populating a provided client.Object pointer for type-safe access (without needing type assertions).

  • With populate mode, the provided object will also be returned.

Examples

Render a template with bindings (return mode, generic):

obj := sc.RenderSingle(`
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Render a template with bindings (populate mode, type-safe):

configMap := &corev1.ConfigMap{}
sc.RenderSingle(configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Unmarshal a static manifest file (populate mode, type-safe):

configMap := &corev1.ConfigMap{}
sc.RenderSingle(configMap, "path/to/configmap.yaml")

func (*Sawchain) RenderToFile

func (s *Sawchain) RenderToFile(filepath, template string, bindings ...map[string]any)

RenderToFile renders a Chainsaw template with optional bindings and writes it to a file.

Arguments

  • Filepath (string): The file path where the rendered YAML will be written.

  • Template (string): File path or content of a Chainsaw template to render.

  • Bindings (map[string]any): Bindings to be applied to the template in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

Notes

  • Invalid input, marshaling errors, and I/O errors will result in immediate test failure.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When running tests in parallel, use unique file paths per process to prevent write collisions. See docs/parallel-tests.md for isolation strategies.

Examples

Render a template to a file:

sc.RenderToFile("output.yaml", `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Render a template file to another file:

sc.RenderToFile("output.yaml", "path/to/template.yaml",
  map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) RenderToString

func (s *Sawchain) RenderToString(template string, bindings ...map[string]any) string

RenderToString renders a Chainsaw template with optional bindings into a YAML string.

Arguments

  • Template (string): File path or content of a Chainsaw template to render.

  • Bindings (map[string]any): Bindings to be applied to the template in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

Notes

  • Invalid input and marshaling errors will result in immediate test failure.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

Examples

Render a template with bindings:

yaml := sc.RenderToString(`
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  type: Opaque
  stringData:
    username: admin
    password: secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Render a template file with bindings:

yaml := sc.RenderToString("path/to/template.yaml",
  map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) Update

func (s *Sawchain) Update(ctx context.Context, args ...any) error

Update updates resources with objects, a manifest, or a Chainsaw template, and returns an error if any client Update operations fail.

Arguments

The following arguments may be provided in any order after the context:

  • Object (client.Object): Typed or unstructured object for reading/writing the state of a single resource. If provided without a template, resource state will be read from the object for update. If provided with a template, resource state will be read from the template and written to the object.

  • Objects ([]client.Object): Slice of typed or unstructured objects for reading/writing the states of multiple resources. If provided without a template, resource states will be read from the objects for update. If provided with a template, resource states will be read from the template and written to the objects.

  • Template (string): File path or content of a static manifest or Chainsaw template containing resource definitions to be merged as patches for update. Template documents are used as JSON merge patches (RFC 7386) and only need to contain identifying metadata and fields to be updated. If provided with an object, must contain exactly one resource definition matching the type of the object. If provided with a slice of objects, must contain resource definitions exactly matching the count, order, and types of the objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together.

Notes

  • Invalid input will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When using a template, each document is used as a JSON merge patch (RFC 7386) to update the corresponding resource. This means fields not specified in the template are preserved, and explicit null values in the template will delete the corresponding fields in the resource.

  • When running tests in parallel, ensure resource names or namespaces are unique per process to prevent collisions. See docs/parallel-tests.md for isolation strategies.

  • Use UpdateAndWait instead of Update if you need to ensure updates are successful and the client cache is synced.

Examples

Update a single resource with an object:

err := sc.Update(ctx, obj)

Update multiple resources with objects:

err := sc.Update(ctx, []client.Object{obj1, obj2, obj3})

Update resources with a manifest file:

err := sc.Update(ctx, "path/to/resources.yaml")

Update a single resource with a Chainsaw template and bindings:

err := sc.Update(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: updated-value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Update a single resource with a Chainsaw template that removes a field (using null):

err := sc.Update(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: test-cm
    namespace: default
  data:
    key-to-remove: null
    new-key: new-value
`)

Update a single resource with a Chainsaw template and save the resource's state to an object:

configMap := &corev1.ConfigMap{}
err := sc.Update(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: updated-value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Update multiple resources with a Chainsaw template and bindings:

err := sc.Update(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: updated-value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  stringData:
    password: updated-secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Update multiple resources with a Chainsaw template and save the resources' states to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
err := sc.Update(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: updated-value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  stringData:
    password: updated-secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

func (*Sawchain) UpdateAndWait

func (s *Sawchain) UpdateAndWait(ctx context.Context, args ...any)

UpdateAndWait updates resources with objects, a manifest, or a Chainsaw template, and ensures client Get operations for all resources reflect the updates within a configurable duration before returning. If testing with a cached client, this ensures the client cache is synced and it is safe to make assertions on the updated resources immediately after execution.

Arguments

The following arguments may be provided in any order (unless noted otherwise) after the context:

  • Object (client.Object): Typed or unstructured object for reading/writing the state of a single resource. If provided without a template, resource state will be read from the object for update. If provided with a template, resource state will be read from the template and written to the object.

  • Objects ([]client.Object): Slice of typed or unstructured objects for reading/writing the states of multiple resources. If provided without a template, resource states will be read from the objects for update. If provided with a template, resource states will be read from the template and written to the objects.

  • Template (string): File path or content of a static manifest or Chainsaw template containing resource definitions to be merged as patches for update. Template documents are used as JSON merge patches (RFC 7386) and only need to contain identifying metadata and fields to be updated. If provided with an object, must contain exactly one resource definition matching the type of the object. If provided with a slice of objects, must contain resource definitions exactly matching the count, order, and types of the objects.

  • Bindings (map[string]any): Bindings to be applied to the Chainsaw template (if provided) in addition to (or overriding) Sawchain's global bindings. If multiple maps are provided, they will be merged in natural order.

  • Timeout (string or time.Duration): Duration within which client Get operations for all resources should reflect the updates. If provided, must be before interval. Defaults to Sawchain's global timeout value.

  • Interval (string or time.Duration): Polling interval for checking the resources after updating. If provided, must be after timeout. Defaults to Sawchain's global interval value.

A template, an object, or a slice of objects must be provided. However, an object and a slice of objects may not be provided together. All other arguments are optional.

Notes

  • Invalid input, client errors, and timeout errors will result in immediate test failure.

  • When dealing with typed objects, the client scheme will be used for internal conversions.

  • Templates will be sanitized before use, including de-indenting (removing any common leading whitespace prefix from non-empty lines) and pruning empty documents.

  • When using a template, each document is used as a JSON merge patch (RFC 7386) to update the corresponding resource. This means fields not specified in the template are preserved, and explicit null values in the template will delete the corresponding fields in the resource.

  • When running tests in parallel, ensure resource names or namespaces are unique per process to prevent collisions. See docs/parallel-tests.md for isolation strategies.

  • Use Update instead of UpdateAndWait if you need to update resources without ensuring success.

Examples

Update a single resource with an object:

sc.UpdateAndWait(ctx, obj)

Update multiple resources with objects:

sc.UpdateAndWait(ctx, []client.Object{obj1, obj2, obj3})

Update resources with a manifest file and override duration settings:

sc.UpdateAndWait(ctx, "path/to/resources.yaml", "10s", "2s")

Update a single resource with a Chainsaw template and bindings:

sc.UpdateAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: updated-value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Update a single resource with a Chainsaw template that removes a field (using null):

sc.UpdateAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: test-cm
    namespace: default
  data:
    key-to-remove: null
    new-key: new-value
`)

Update a single resource with a Chainsaw template and save the resource's updated state to an object:

configMap := &corev1.ConfigMap{}
sc.UpdateAndWait(ctx, configMap, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: ($name)
    namespace: ($namespace)
  data:
    key: updated-value
  `, map[string]any{"name": "test-cm", "namespace": "default"})

Update multiple resources with a Chainsaw template and bindings:

sc.UpdateAndWait(ctx, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: updated-value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  stringData:
    password: updated-secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Update multiple resources with a Chainsaw template and save the resources' updated states to objects:

configMap := &corev1.ConfigMap{}
secret := &corev1.Secret{}
sc.UpdateAndWait(ctx, []client.Object{configMap, secret}, `
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: (concat($prefix, '-cm'))
    namespace: ($namespace)
  data:
    key: updated-value
  ---
  apiVersion: v1
  kind: Secret
  metadata:
    name: (concat($prefix, '-secret'))
    namespace: ($namespace)
  stringData:
    password: updated-secret
  `, map[string]any{"prefix": "test", "namespace": "default"})

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL