Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cartotest supplychains #1265

Merged
merged 50 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
067cd87
Turn cartotest Expectation into an interface
waciumawanjohi Jun 7, 2023
298b744
SupplyChain interface for Cartotest
waciumawanjohi Jun 8, 2023
9c85699
Supply a set of supply chain file paths
waciumawanjohi Jun 8, 2023
ed109da
Split large file
waciumawanjohi Jun 8, 2023
b4e6411
Refactor replaceIfFound
waciumawanjohi Jun 8, 2023
b24c62c
Update cli suite expected locating
waciumawanjohi Jun 8, 2023
b13eabd
Change cartotesting workload to an interface
waciumawanjohi Jun 8, 2023
3cab13e
Turn Givens.Template into an interface
waciumawanjohi Jun 9, 2023
998b205
Rename interface
waciumawanjohi Jun 9, 2023
a8bacbb
Rename supplychain interface
waciumawanjohi Jun 9, 2023
261b150
BlueprintParams as an interface
waciumawanjohi Jun 9, 2023
902170d
Move functions
waciumawanjohi Jun 9, 2023
1aea4f5
Change method to function
waciumawanjohi Jun 9, 2023
fb752a2
Change BlueprintInputs into an interface
waciumawanjohi Jun 9, 2023
4f6f036
Blueprint Params and Inputs nested under MockSupplyChain
waciumawanjohi Jun 9, 2023
b5a55a9
Move method
waciumawanjohi Jun 9, 2023
7feb8ad
Change pointers on methods
waciumawanjohi Jun 9, 2023
a902068
Move functions
waciumawanjohi Jun 9, 2023
6567cc8
Turn SupplyChain into an interface implemented by mock and actual sup…
waciumawanjohi Jun 9, 2023
0bc65ed
Rename Expectations and Given
waciumawanjohi Jun 9, 2023
3d12655
Rename SupplyChainFileSet
waciumawanjohi Jun 9, 2023
e7e0c89
Add fields to supply chain set
waciumawanjohi Jun 9, 2023
a5b685c
Rename Expectation interface implementations
waciumawanjohi Jun 9, 2023
98f2b09
Rename Expectation fields
waciumawanjohi Jun 9, 2023
5e834a9
First passing actual supply chain test
waciumawanjohi Jun 9, 2023
713eb92
Change specification of ytt file for cli cartotests
waciumawanjohi Jun 9, 2023
437bd78
Nest template cli fields as they are in new template struct
waciumawanjohi Jun 9, 2023
95333e0
Nest mockSupplyChain CLI fields
waciumawanjohi Jun 9, 2023
537abe1
Nest metadata and givens in CLI info file
waciumawanjohi Jun 9, 2023
b63fcc1
Test CLI tests with go test
waciumawanjohi Jun 9, 2023
851d01e
Begin moving CLI TestCase Population to functions
waciumawanjohi Jun 9, 2023
e23ee7c
CLI TestCase Population in function
waciumawanjohi Jun 9, 2023
7dc01bf
Split cli-suite-builder file into suite and case
waciumawanjohi Jun 9, 2023
3ee3500
Rename variables
waciumawanjohi Jun 9, 2023
0974f5e
Refactor populate testCase template
waciumawanjohi Jun 9, 2023
6f381ba
Further refactor populate testCase template
waciumawanjohi Jun 9, 2023
0a1abe1
Rename function
waciumawanjohi Jun 9, 2023
02712a8
Even further refactor populate testCase template
waciumawanjohi Jun 9, 2023
355c723
populate TestCase SupplyChain function
waciumawanjohi Jun 9, 2023
4edca4f
Working cartotest cli with actual supply chain
waciumawanjohi Jun 9, 2023
7eb9da4
Create Comparison Option Field
waciumawanjohi Jun 9, 2023
5a32138
CompareOptions yields cmp.Options
waciumawanjohi Jun 9, 2023
66ce6ba
Cartotest CLI uses compareOptions
waciumawanjohi Jun 9, 2023
46b8456
Reorder yaml files
waciumawanjohi Jun 9, 2023
ecec9d6
Lint
waciumawanjohi Jun 9, 2023
aa778d8
Cartotest CLI can leverage number conversion function
waciumawanjohi Jun 9, 2023
1922538
Simplify cartotest cli
waciumawanjohi Jun 13, 2023
d121031
Ensure targetResource references provided template
waciumawanjohi Jun 13, 2023
c38f2f9
Simplify language
waciumawanjohi Jun 14, 2023
ec306e0
Convert Blueprint params/inputs to SupplyChain params/inputs
waciumawanjohi Jun 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ test-cartotest: test-cartotest-go test-cartotest-cli

.PHONY: test-cartotest-cli
test-cartotest-cli:
go run ./cmd/cartotest/main.go templates --directory ./tests/templates/
go run ./cmd/cartotest/main.go ./tests/templates/

.PHONY: test-cartotest-go
test-cartotest-go:
Expand Down
10 changes: 5 additions & 5 deletions pkg/controllers/workload_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (r *WorkloadReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
}

contextGenerator := realizer.NewContextGenerator(workload, workload.Spec.Params, supplyChain.Spec.Params)
resourceRealizer, err := r.ResourceRealizerBuilder(saToken, workload, contextGenerator, r.Repo, buildWorkloadResourceLabeler(workload, supplyChain))
resourceRealizer, err := r.ResourceRealizerBuilder(saToken, workload, contextGenerator, r.Repo, BuildWorkloadResourceLabeler(workload, supplyChain))
if err != nil {
conditionManager.AddPositive(conditions.ResourceRealizerBuilderErrorCondition(err))
log.Error(err, "failed to build resource realizer")
Expand Down Expand Up @@ -228,7 +228,7 @@ func (r *WorkloadReconciler) isSupplyChainReady(supplyChain *v1alpha1.ClusterSup
return supplyChainReadyCondition.Status == "True"
}

func buildWorkloadResourceLabeler(owner, blueprint client.Object) realizer.ResourceLabeler {
func BuildWorkloadResourceLabeler(owner, blueprint client.Object) realizer.ResourceLabeler {
return func(resource realizer.OwnerResource, reader templates.Reader) templates.Labels {
return templates.Labels{
"carto.run/workload-name": owner.GetName(),
Expand Down Expand Up @@ -278,9 +278,9 @@ func (r *WorkloadReconciler) getSupplyChainsForWorkload(ctx context.Context, wor
if len(supplyChains) > 1 {
conditionManager.AddPositive(conditions.TooManySupplyChainMatchesCondition())
log.Info("more than one supply chain selected for workload",
"supply chains", getSupplyChainNames(supplyChains))
"supply chains", GetSupplyChainNames(supplyChains))
return nil, fmt.Errorf("more than one supply chain selected for workload [%s/%s]: %+v",
workload.Namespace, workload.Name, getSupplyChainNames(supplyChains))
workload.Namespace, workload.Name, GetSupplyChainNames(supplyChains))
}

log.V(logger.DEBUG).Info("supply chain matched for workload", "supply chain", supplyChains[0].Name)
Expand Down Expand Up @@ -388,7 +388,7 @@ func (r *WorkloadReconciler) cleanupOrphanedObjects(ctx context.Context, previou
return nil
}

func getSupplyChainNames(objs []*v1alpha1.ClusterSupplyChain) []string {
func GetSupplyChainNames(objs []*v1alpha1.ClusterSupplyChain) []string {
var names []string
for _, obj := range objs {
names = append(names, obj.GetName())
Expand Down
15 changes: 13 additions & 2 deletions pkg/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,21 @@ func (r *repository) GetSupplyChainsForWorkload(ctx context.Context, workload *v
return nil, fmt.Errorf("unable to list supply chains from api server: %w", err)
}

var selectorGetters []SelectingObject
var supplyChains []*v1alpha1.ClusterSupplyChain

for _, item := range list.Items {
itemValue := item
selectorGetters = append(selectorGetters, &itemValue)
supplyChains = append(supplyChains, &itemValue)
}

return GetSelectedSupplyChain(supplyChains, workload, log)
}

func GetSelectedSupplyChain(allSupplyChains []*v1alpha1.ClusterSupplyChain, workload *v1alpha1.Workload, log logr.Logger) ([]*v1alpha1.ClusterSupplyChain, error) {
var selectorGetters []SelectingObject
for _, item := range allSupplyChains {
itemValue := item
selectorGetters = append(selectorGetters, itemValue)
}

var supplyChains []*v1alpha1.ClusterSupplyChain
Expand Down
113 changes: 113 additions & 0 deletions pkg/testing/case.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2021 VMware
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package testing

import (
"context"
"errors"
"fmt"

"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"github.com/vmware-tanzu/cartographer/pkg/templates"
)

// Test is an individual template test.
// Given and Expect values must be provided.
// Fields in the expected object's metadata may be ignored
// When run as part of a Suite, an individual case(s) may be focused.
// This will exercise the individual test(s).
// Note that the overall suite will fail (preventing focused tests from passing CI).
type Test struct {
Given Given
Expect Expectation
CompareOptions *CompareOptions
Focus bool
}

// Given must specify a Template and a Workload.
// SupplyChain is optional
type Given struct {
Template Template
Workload Workload
SupplyChain SupplyChain
}

func (c *Test) Run() error {
expectedObject, err := c.Expect.getExpected()
if err != nil {
return fmt.Errorf("failed to get expected object: %w", err)
}

actualObject, err := c.Given.getActualObject()
if errors.Is(err, yttNotFound) {
return fmt.Errorf("test requires ytt, but ytt was not found in path")
} else if err != nil {
return fmt.Errorf("failed to get actual object: %w", err)
}

c.stripIgnoredFields(expectedObject, actualObject)

var opts cmp.Options
if c.CompareOptions != nil && c.CompareOptions.CMPOption != nil {
opts, err = c.CompareOptions.CMPOption()
if err != nil {
return fmt.Errorf("get compare options: %w", err)
}
}

if diff := cmp.Diff(expectedObject.Object, actualObject.Object, opts); diff != "" {
return fmt.Errorf("expected does not equal actual: (-expected +actual):\n%s", diff)
}

return nil
}

func (i *Given) getActualObject() (*unstructured.Unstructured, error) {
ctx := context.Background()

workload, err := i.Workload.GetWorkload()
if err != nil {
return nil, fmt.Errorf("get workload failed: %w", err)
}

apiTemplate, err := i.Template.GetTemplate()
if err != nil {
return nil, fmt.Errorf("get populated template failed: %w", err)
}

if err = (*apiTemplate).ValidateCreate(); err != nil {
return nil, fmt.Errorf("template validation failed: %w", err)
}

template, err := templates.NewReaderFromAPI(*apiTemplate)
if err != nil {
return nil, fmt.Errorf("failed to get cluster template")
}

if template.IsYTTTemplate() {
err = ensureYTTAvailable(ctx)
if err != nil {
return nil, fmt.Errorf("ensure YTT available: %w", err)
}
}

if i.SupplyChain == nil {
i.SupplyChain = &MockSupplyChain{}
}

return i.SupplyChain.stamp(ctx, workload, *apiTemplate, template)
}
Loading