From 21995e9fc2d794ce53a299065705a7876df12694 Mon Sep 17 00:00:00 2001 From: Lucas Rodriguez Date: Wed, 22 May 2024 13:42:02 -0500 Subject: [PATCH] chore: add unit tests for creator.LoadPackageDefinition (#2531) Relates to #2512 --- src/pkg/packager/create.go | 5 -- src/pkg/packager/creator/creator.go | 2 +- src/pkg/packager/creator/normal.go | 10 +++- src/pkg/packager/creator/normal_test.go | 43 +++++++++++++++ src/pkg/packager/creator/skeleton.go | 10 +++- src/pkg/packager/creator/skeleton_test.go | 55 +++++++++++++++++++ .../creator/testdata/invalid/zarf.yaml | 4 ++ .../packager/creator/testdata/valid/zarf.yaml | 6 ++ src/types/validate.go | 5 ++ 9 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 src/pkg/packager/creator/skeleton_test.go create mode 100644 src/pkg/packager/creator/testdata/invalid/zarf.yaml create mode 100644 src/pkg/packager/creator/testdata/valid/zarf.yaml diff --git a/src/pkg/packager/create.go b/src/pkg/packager/create.go index bc10fe8d73..bad88d5d4e 100755 --- a/src/pkg/packager/create.go +++ b/src/pkg/packager/create.go @@ -39,11 +39,6 @@ func (p *Packager) Create() (err error) { return err } - // Perform early package validation. - if err := p.cfg.Pkg.Validate(); err != nil { - return fmt.Errorf("unable to validate package: %w", err) - } - if !p.confirmAction(config.ZarfCreateStage) { return fmt.Errorf("package creation canceled") } diff --git a/src/pkg/packager/creator/creator.go b/src/pkg/packager/creator/creator.go index 5b0f3c27b1..5e34fd46c1 100644 --- a/src/pkg/packager/creator/creator.go +++ b/src/pkg/packager/creator/creator.go @@ -11,7 +11,7 @@ import ( // Creator is an interface for creating Zarf packages. type Creator interface { - LoadPackageDefinition(dst *layout.PackagePaths) (pkg types.ZarfPackage, warnings []string, err error) + LoadPackageDefinition(src *layout.PackagePaths) (pkg types.ZarfPackage, warnings []string, err error) Assemble(dst *layout.PackagePaths, components []types.ZarfComponent, arch string) error Output(dst *layout.PackagePaths, pkg *types.ZarfPackage) error } diff --git a/src/pkg/packager/creator/normal.go b/src/pkg/packager/creator/normal.go index 0cb5c7d921..7747cfdd4d 100644 --- a/src/pkg/packager/creator/normal.go +++ b/src/pkg/packager/creator/normal.go @@ -61,8 +61,8 @@ func NewPackageCreator(createOpts types.ZarfCreateOptions, cwd string) *PackageC } // LoadPackageDefinition loads and configures a zarf.yaml file during package create. -func (pc *PackageCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg types.ZarfPackage, warnings []string, err error) { - pkg, warnings, err = dst.ReadZarfYAML() +func (pc *PackageCreator) LoadPackageDefinition(src *layout.PackagePaths) (pkg types.ZarfPackage, warnings []string, err error) { + pkg, warnings, err = src.ReadZarfYAML() if err != nil { return types.ZarfPackage{}, nil, err } @@ -86,7 +86,7 @@ func (pc *PackageCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg t warnings = append(warnings, templateWarnings...) // After templates are filled process any create extensions - pkg.Components, err = pc.processExtensions(pkg.Components, dst, pkg.Metadata.YOLO) + pkg.Components, err = pc.processExtensions(pkg.Components, src, pkg.Metadata.YOLO) if err != nil { return types.ZarfPackage{}, nil, err } @@ -119,6 +119,10 @@ func (pc *PackageCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg t } } + if err := pkg.Validate(); err != nil { + return types.ZarfPackage{}, nil, err + } + return pkg, warnings, nil } diff --git a/src/pkg/packager/creator/normal_test.go b/src/pkg/packager/creator/normal_test.go index 9a4830cb1f..95998ba1ca 100644 --- a/src/pkg/packager/creator/normal_test.go +++ b/src/pkg/packager/creator/normal_test.go @@ -8,6 +8,8 @@ import ( "path/filepath" "testing" + "github.com/defenseunicorns/zarf/src/pkg/layout" + "github.com/defenseunicorns/zarf/src/types" "github.com/stretchr/testify/require" ) @@ -56,3 +58,44 @@ func TestDifferentialPackagePathSetCorrectly(t *testing.T) { }) } } + +func TestLoadPackageDefinition(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + testDir string + expectedErr string + }{ + { + name: "valid package definition", + testDir: "valid", + expectedErr: "", + }, + { + name: "invalid package definition", + testDir: "invalid", + expectedErr: "package must have at least 1 component", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + src := layout.New(filepath.Join("testdata", tt.testDir)) + pc := NewPackageCreator(types.ZarfCreateOptions{}, "") + pkg, _, err := pc.LoadPackageDefinition(src) + + if tt.expectedErr == "" { + require.NoError(t, err) + require.NotEmpty(t, pkg) + return + } + + require.EqualError(t, err, tt.expectedErr) + require.Empty(t, pkg) + }) + } +} diff --git a/src/pkg/packager/creator/skeleton.go b/src/pkg/packager/creator/skeleton.go index 74dc19fd35..b6e5498322 100644 --- a/src/pkg/packager/creator/skeleton.go +++ b/src/pkg/packager/creator/skeleton.go @@ -42,8 +42,8 @@ func NewSkeletonCreator(createOpts types.ZarfCreateOptions, publishOpts types.Za } // LoadPackageDefinition loads and configure a zarf.yaml file when creating and publishing a skeleton package. -func (sc *SkeletonCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg types.ZarfPackage, warnings []string, err error) { - pkg, warnings, err = dst.ReadZarfYAML() +func (sc *SkeletonCreator) LoadPackageDefinition(src *layout.PackagePaths) (pkg types.ZarfPackage, warnings []string, err error) { + pkg, warnings, err = src.ReadZarfYAML() if err != nil { return types.ZarfPackage{}, nil, err } @@ -60,7 +60,7 @@ func (sc *SkeletonCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg warnings = append(warnings, composeWarnings...) - pkg.Components, err = sc.processExtensions(pkg.Components, dst) + pkg.Components, err = sc.processExtensions(pkg.Components, src) if err != nil { return types.ZarfPackage{}, nil, err } @@ -69,6 +69,10 @@ func (sc *SkeletonCreator) LoadPackageDefinition(dst *layout.PackagePaths) (pkg message.Warn(warning) } + if err := pkg.Validate(); err != nil { + return types.ZarfPackage{}, nil, err + } + return pkg, warnings, nil } diff --git a/src/pkg/packager/creator/skeleton_test.go b/src/pkg/packager/creator/skeleton_test.go new file mode 100644 index 0000000000..1fed6f985d --- /dev/null +++ b/src/pkg/packager/creator/skeleton_test.go @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package creator contains functions for creating Zarf packages. +package creator + +import ( + "path/filepath" + "testing" + + "github.com/defenseunicorns/zarf/src/pkg/layout" + "github.com/defenseunicorns/zarf/src/types" + "github.com/stretchr/testify/require" +) + +func TestSkeletonLoadPackageDefinition(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + testDir string + expectedErr string + }{ + { + name: "valid package definition", + testDir: "valid", + expectedErr: "", + }, + { + name: "invalid package definition", + testDir: "invalid", + expectedErr: "package must have at least 1 component", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + src := layout.New(filepath.Join("testdata", tt.testDir)) + sc := NewSkeletonCreator(types.ZarfCreateOptions{}, types.ZarfPublishOptions{}) + pkg, _, err := sc.LoadPackageDefinition(src) + + if tt.expectedErr == "" { + require.NoError(t, err) + require.NotEmpty(t, pkg) + return + } + + require.EqualError(t, err, tt.expectedErr) + require.Empty(t, pkg) + }) + } +} diff --git a/src/pkg/packager/creator/testdata/invalid/zarf.yaml b/src/pkg/packager/creator/testdata/invalid/zarf.yaml new file mode 100644 index 0000000000..ae4c915b6e --- /dev/null +++ b/src/pkg/packager/creator/testdata/invalid/zarf.yaml @@ -0,0 +1,4 @@ +kind: ZarfPackageConfig +metadata: + name: minimal-invalid + description: Must have at least 1 component diff --git a/src/pkg/packager/creator/testdata/valid/zarf.yaml b/src/pkg/packager/creator/testdata/valid/zarf.yaml new file mode 100644 index 0000000000..a9b00bb04d --- /dev/null +++ b/src/pkg/packager/creator/testdata/valid/zarf.yaml @@ -0,0 +1,6 @@ +kind: ZarfPackageConfig +metadata: + name: minimal-valid + description: Minimal valid package +components: + - name: component1 diff --git a/src/types/validate.go b/src/types/validate.go index ae6236227f..fbef1dab65 100644 --- a/src/types/validate.go +++ b/src/types/validate.go @@ -5,6 +5,7 @@ package types import ( + "errors" "fmt" "path/filepath" "regexp" @@ -47,6 +48,10 @@ func (pkg ZarfPackage) Validate() error { return fmt.Errorf(lang.PkgValidateErrPkgName, pkg.Metadata.Name) } + if len(pkg.Components) == 0 { + return errors.New("package must have at least 1 component") + } + for _, variable := range pkg.Variables { if err := variable.Validate(); err != nil { return fmt.Errorf(lang.PkgValidateErrVariable, err)