Documentation
Cartotest Go Framework
cartotest
is a go test framework to assert that your Cartographer templates behave as you expect.
Quick Start
Dependency
Users may define templates that use ytt. Testing such templates requires installing ytt.
Run
Clone the Cartographer repository:
git clone git@github.com:vmware-tanzu/cartographer.git
cd cartographer
Run the example template tests:
go test ./tests/templates/template_test.go -v
You should see
=== RUN TestTemplateExample
=== RUN TestTemplateExample/clustertemplate_uses_ytt_field
=== RUN TestTemplateExample/template_requires_ytt_preprocessing,_data_supplied_in_files
=== RUN TestTemplateExample/providing_a_supply_chain_input_file
=== RUN TestTemplateExample/template,_workload_and_expected_defined_in_files
=== RUN TestTemplateExample/workload_defined_as_an_object
=== RUN TestTemplateExample/expected_defined_as_an_object
=== RUN TestTemplateExample/expected_defined_as_an_unstructured
=== RUN TestTemplateExample/actual_supply_chain
=== RUN TestTemplateExample/template_defined_as_an_object
=== RUN TestTemplateExample/blueprints_defined_as_a_file
=== RUN TestTemplateExample/template_requires_ytt_preprocessing,_data_supplied_in_object
=== RUN TestTemplateExample/template_that_requires_a_supply_chain_input
--- PASS: TestTemplateExample (0.16s)
--- PASS: TestTemplateExample/clustertemplate_uses_ytt_field (0.04s)
--- PASS: TestTemplateExample/template_requires_ytt_preprocessing,_data_supplied_in_files (0.05s)
--- PASS: TestTemplateExample/providing_a_supply_chain_input_file (0.00s)
--- PASS: TestTemplateExample/template,_workload_and_expected_defined_in_files (0.01s)
--- PASS: TestTemplateExample/workload_defined_as_an_object (0.00s)
--- PASS: TestTemplateExample/expected_defined_as_an_object (0.00s)
--- PASS: TestTemplateExample/expected_defined_as_an_unstructured (0.00s)
--- PASS: TestTemplateExample/actual_supply_chain (0.00s)
--- PASS: TestTemplateExample/template_defined_as_an_object (0.00s)
--- PASS: TestTemplateExample/blueprints_defined_as_a_file (0.00s)
--- PASS: TestTemplateExample/template_requires_ytt_preprocessing,_data_supplied_in_object (0.04s)
--- PASS: TestTemplateExample/template_that_requires_a_supply_chain_input (0.00s)
PASS
Great, a passing test!
Creating A Test
To use the cartotest framework, you’ll create a cartotesting.Suite
. The suite will map test names to
cartotesting.Test
s. After defining the suite, call the suite’s Run
function.
cartotesting.Test
s have 4 high level fields:
- Given: The inputs to the test
- Expect: The object expected to be created
- CompareOptions: Methods to simplify the comparison, for example by excluding some metadata fields
- Focus: a boolean flag to focus the suite on the flagged test
Given
Given is one of the top level fields of a cartotest Test. The Given field must define a Template and a Workload. They may define a SupplyChain. Each of these is an interface with multiple implementations, generally allowing provision as a go object or as a yaml file.
Template Interface
Template is one of the fields in Given. There are two implementations of the template interface:
- TemplateFile, which specifies the filepath of a yaml file of a Cartographer Template. It may also specify the YttFiles and YttValues fields. Example: # TODO: point to example
- TemplateObject, which provides a go instance of one of the cartographer template classes. Example: # TODO: point to example
Workload Interface
Workload is one of the fields in Given. There are two implementations of the workload interface:
- WorkloadFile, which specifies the filepath of a yaml file of a Cartographer Workload. Example: # TODO: point to example
- WorkloadObject, which provides a go cartographer workload object. Example: # TODO: point to example
SupplyChain Interface
SupplyChain is one of the fields in Given. There are two implementations of the supply-chain interface:
SupplyChainFileSet
SupplyChainFileSet is an implementation of SupplyChain.
The SupplyChainFileSet allows users to specify a Supply Chain yaml file. Users specify which stage/resource in the supply chain the test focuses on (e.g. which resource points to the template under test). Users can mock out the outputs of earlier stages/resources that the template consumes.
Fields of SupplyChainFileSet:
- Paths: a list of filepaths. Each may be either the path of a supplychain yaml file. Or they may be a path to a directory containing only supplychain yaml files. Given multiple supply chains, the test will use Cartographer’s selector rules to determine which supply chain will be paired with the given workload. This allows validation of the selectors on the supply chain set and the labels on the workload.
- TargetResourceName: A supplychain defines a set of resources (stages) which each point to a template. The name of the resource under test must be specified.
- PreviousOutputs: Previous resources in a supply chain will create outputs. This field allows users to mock these outputs. See an example here of creating an output and specifying it as belonging to a previous resource named “build-image”. # TODO: link to getActualSupplyChainOutputs in example
- YttFiles: See YTT Templating.
- YttValues: See YTT Templating.
MockSupplyChain
MockSupplyChain is an implementation of SupplyChain.
MockSupplyChains allow mocking out the two types of values that a supply chain supplies to stamping: params and outputs of previous resources/stages. Each of these can be specified by pointing to a yaml file, or by creating a go object.
- Inputs
- SupplyChainInputsObject: Define an inputs object. See example #TODO
- SupplyChainInputsFile: Provide the path of a yaml file defining inputs. See example
- Params
- SupplyChainParamsFile: Provide the path of a yaml file defining params. See example
- SupplyChainParamsObject: Provide a params object. To simplify this process, Cartotest provides the [BuildSupplyChainStringParams](# TODO) function. Example usage
Inputs vs Outputs
It is important to note that inputs and outputs are slightly different:
- SupplyChainFileSet PreviousOutputs: provide the name of the previous resource that created the output. The supply chain spec will rename this input. Read more about that in the tutorials.
- MockSupplyChain Inputs: As we are mocking out the supply chain, we need not specify the previous resource’s name. Instead we specify the name of the input as it is referred to in the template. Read more in the templating documentation
Expect
Expect is one of the top level fields of a cartotest Test. This field accepts an Expectation. Expectation is an interface with multiple implementations. This allows definition of the expected object as:
- a yaml file. Create a
cartotesting.ExpectedFile
whosePath
field is the location of the file. - a go object. Create a
cartotesting.ExpectedObject
whoseObject
field is the object. - a kubernetes
unstructured.Unstructured. Create
a
cartotesting.ExpectedUnstructured
whoseUnstructured
field is the unstructured object.
Note on implementation: All implementations are converted into an unstructured.Unstructured
when compared to the
object stamped by Cartographer.
CompareOptions
CompareOptions is one of the top level fields of a cartotest Test.
CompareOptions allows two behaviors: to ignore certain fields in the metadata of the stamped object, and to transform the comparison function.
There are 4 fields related to ignoring the metadata:
IgnoreMetadata
: a boolean flag to ignore the entire metadata fieldIgnoreOwnerRefs
: a boolean flag to ignore the ownerRefs of the stamped objectIgnoreLabels
: a boolean flag to ignore the labels of the stamped objectIgnoreMetadataFields
: a list of names of fields in the metadata that should be ignored
The CMPOption
field accepts a function that returns
cmp.Options, which can be used to change the comparison
between the expected and the actual object stamped. Cartotest provides one such function,
ConvertNumbersToFloatsDuringComparison, which coerces all numbers to be of the same type. # TODO link to function
definition.
YTT Templating
When defining objects using a yaml file, that file may be written expecting ytt templating, including configuration from additional values specified in another file.
Values may be provided either from:
- YttFiles: a set of yaml files using the ytt
#@data/values
tag. Example: # TODO - YttValues: a go map. Example # TODO
If the same value is provided by a YttFile and a YttValue, the YttValue will be respected. # TODO: verify