Skip to content
148 changes: 148 additions & 0 deletions commands/pkg/update/cmdupdate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import (
internalgitutil "github.com/kptdev/kpt/internal/gitutil"
"github.com/kptdev/kpt/internal/testutil"
"github.com/kptdev/kpt/internal/testutil/pkgbuilder"
"github.com/kptdev/kpt/pkg/kptfile/kptfileutil"
"github.com/kptdev/kpt/pkg/printer/fake"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

Expand Down Expand Up @@ -132,6 +134,152 @@ func TestCmd_execute(t *testing.T) {
}
}

// TestCmd_subpkgVersions verifies that update is correctly invoked with an upstream 'mysql' package with multiple versions
func TestCmd_subpkgVersions(t *testing.T) {
// Setup version v1 of upstream package
g, w, clean := testutil.SetupRepoAndWorkspace(t, testutil.Content{
Data: testutil.Dataset1,
Branch: "master",
})
defer clean()

commitDs1, err := g.GetCommit()
if !assert.NoError(t, err) {
return
}
err = g.Tag("dataset1")
if !assert.NoError(t, err) {
t.FailNow()
}
// update the master branch
if !assert.NoError(t, g.ReplaceData(testutil.Dataset2)) {
return
}
_, err = g.Commit("modify upstream package -- ds2")
if !assert.NoError(t, err) {
return
}
err = g.Tag("dataset2")
if !assert.NoError(t, err) {
t.FailNow()
}

defer testutil.Chdir(t, w.WorkspaceDirectory)()

dest := filepath.Join(w.WorkspaceDirectory, "mysql")

// pkg get package version 'dataset1'
getCmd := get.NewRunner(fake.CtxWithDefaultPrinter(), "kpt")
getCmd.Command.SetArgs([]string{"file://" + g.RepoDirectory + ".git/mysql@dataset1", w.WorkspaceDirectory})
err = getCmd.Command.Execute()
if !assert.NoError(t, err) {
return
}
if !g.AssertEqual(t, filepath.Join(g.DatasetDirectory, testutil.Dataset1, "mysql"), dest, true) {
return
}

// Reference Kptfile for package version 'dataset1'
pkgDs1Kptfile, err := kptfileutil.ReadKptfile(filesys.FileSystemOrOnDisk{}, filepath.Join(g.DatasetDirectory, testutil.Dataset1, "mysql"))
if !assert.NoError(t, err) {
return
}
if !g.AssertKptfile(t, dest, kptfilev1.KptFile{
ResourceMeta: yaml.ResourceMeta{
ObjectMeta: yaml.ObjectMeta{
NameMeta: yaml.NameMeta{
Name: "mysql",
},
},
TypeMeta: yaml.TypeMeta{
APIVersion: kptfilev1.TypeMeta.APIVersion,
Kind: kptfilev1.TypeMeta.Kind},
},
Upstream: &kptfilev1.Upstream{
Type: kptfilev1.GitOrigin,
Git: &kptfilev1.Git{
Repo: "file://" + g.RepoDirectory,
Ref: "dataset1",
Directory: "/mysql",
},
UpdateStrategy: kptfilev1.ResourceMerge, // Defaulted
},
UpstreamLock: &kptfilev1.Locator{
Type: kptfilev1.GitOrigin,
Git: &kptfilev1.GitLock{
Repo: "file://" + g.RepoDirectory,
Ref: "dataset1",
Directory: "/mysql",
Commit: commitDs1,
},
},
Info: &kptfilev1.PackageInfo{
Description: pkgDs1Kptfile.Info.Description,
},
Pipeline: pkgDs1Kptfile.Pipeline,
}) {
return
}

// pkg update to version 'dataset2'
updateCmd := update.NewRunner(fake.CtxWithDefaultPrinter(), "kpt")
updateCmd.Command.SetArgs([]string{"mysql@dataset2", "--strategy", "fast-forward"})
if !assert.NoError(t, updateCmd.Command.Execute()) {
return
}
if !g.AssertEqual(t, filepath.Join(g.DatasetDirectory, testutil.Dataset2, "mysql"), dest, true) {
return
}

commitDs2, err := g.GetCommit()
if !assert.NoError(t, err) {
return
}

// Reference Kptfile for package version 'dataset2'
pkgDs2Kptfile, err := kptfileutil.ReadKptfile(filesys.FileSystemOrOnDisk{}, filepath.Join(g.DatasetDirectory, testutil.Dataset2, "mysql"))
if !assert.NoError(t, err) {
return
}

if !g.AssertKptfile(t, dest, kptfilev1.KptFile{
ResourceMeta: yaml.ResourceMeta{
ObjectMeta: yaml.ObjectMeta{
NameMeta: yaml.NameMeta{
Name: "mysql",
},
},
TypeMeta: yaml.TypeMeta{
APIVersion: kptfilev1.TypeMeta.APIVersion,
Kind: kptfilev1.TypeMeta.Kind},
},
Upstream: &kptfilev1.Upstream{
Type: kptfilev1.GitOrigin,
Git: &kptfilev1.Git{
Repo: "file://" + g.RepoDirectory,
Ref: "dataset2",
Directory: "/mysql",
},
UpdateStrategy: kptfilev1.FastForward,
},
UpstreamLock: &kptfilev1.Locator{
Type: kptfilev1.GitOrigin,
Git: &kptfilev1.GitLock{
Repo: "file://" + g.RepoDirectory,
Ref: "dataset2",
Directory: "/mysql",
Commit: commitDs2,
},
},
Info: &kptfilev1.PackageInfo{
Description: pkgDs2Kptfile.Info.Description,
},
Pipeline: pkgDs2Kptfile.Pipeline,
}) {
return
}
}

func TestCmd_successUnCommitted(t *testing.T) {
g, w, clean := testutil.SetupRepoAndWorkspace(t, testutil.Content{
Data: testutil.Dataset1,
Expand Down
16 changes: 16 additions & 0 deletions internal/testutil/testdata/dataset1/mysql/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: mysql
info:
description: kpt package for mysql
pipeline:
mutators:
- image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4.1
configMap:
namespace: example-ns
name: set namespace
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
color: orange
name: set color label
20 changes: 20 additions & 0 deletions internal/testutil/testdata/dataset2/mysql/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: mysql
info:
description: mysql package
pipeline:
mutators:
- image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4.1
configMap:
namespace: example-ns
name: set namespace
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
fruit: apple
name: set fruit label
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
color: orange
name: set color label
20 changes: 20 additions & 0 deletions internal/testutil/testdata/dataset3/mysql/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: mysql
info:
description: mysql package
pipeline:
mutators:
- image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4.1
configMap:
namespace: example-ns
name: set namespace
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
fruit: apple
name: set fruit label
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
color: orange
name: set color label
20 changes: 20 additions & 0 deletions internal/testutil/testdata/dataset4/mysql/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: mysql
info:
description: mysql package
pipeline:
mutators:
- image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4.1
configMap:
namespace: example-ns
name: set namespace
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
fruit: apple
name: set fruit label
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
color: orange
name: set color label
20 changes: 20 additions & 0 deletions internal/testutil/testdata/dataset5/mysql/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: mysql
info:
description: mysql package
pipeline:
mutators:
- image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4.1
configMap:
namespace: example-ns
name: set namespace
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
fruit: apple
name: set fruit label
- image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.2.0
configMap:
color: orange
name: set color label
29 changes: 20 additions & 9 deletions internal/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package testutil

import (
"bytes"
"fmt"
"os"
"os/exec"
Expand Down Expand Up @@ -47,10 +46,10 @@ const TmpDirPrefix = "test-kpt"

const (
Dataset1 = "dataset1"
Dataset2 = "dataset2"
Dataset2 = "dataset2" // Dataset2 is a replica of Dataset1 with workload spec changes (ports, replica count etc.) and a Kptfile mod
Dataset3 = "dataset3"
Dataset4 = "dataset4" // Dataset4 is replica of Dataset2 with different setter values
Dataset5 = "dataset5" // Dataset5 is replica of Dataset2 with additional non KRM files
Dataset4 = "dataset4" // Dataset4 is a replica of Dataset2 with different setter values
Dataset5 = "dataset5" // Dataset5 is a replica of Dataset2 with additional non KRM files
Dataset6 = "dataset6" // Dataset6 contains symlinks
DatasetMerged = "datasetmerged"
DiffOutput = "diff_output"
Expand Down Expand Up @@ -98,10 +97,22 @@ func (g *TestGitRepo) AssertEqual(t *testing.T, sourceDir, destDir string, addMe
if !assert.NoError(t, err) {
return false
}
diff = diff.Difference(KptfileSet)
diff = removeKptfiles(diff)
return assert.Empty(t, diff.List())
}

// removeKptfiles removes all Kptfile paths (at any depth) from the diff set,
// since Kptfile content is validated separately by AssertKptfile.
func removeKptfiles(s sets.String) sets.String {
result := sets.String{}
for _, item := range s.List() {
if filepath.Base(item) != kptfilev1.KptFileName {
result.Insert(item)
}
}
return result
}

// KptfileAwarePkgEqual compares two packages (including any subpackages)
// and has special handling of Kptfiles to handle fields that contain
// values which cannot easily be specified in the golden package.
Expand Down Expand Up @@ -273,12 +284,12 @@ func (g *TestGitRepo) AssertKptfile(t *testing.T, cloned string, kpkg kptfilev1.
if !assert.NoError(t, err) {
return false
}
var res bytes.Buffer
d := yaml.NewEncoder(&res)
if !assert.NoError(t, d.Encode(kpkg)) {
// This mirrors 'WriteFile' in pkg/kptfile/kptfileutil/util.go
res, err := yaml.MarshalWithOptions(kpkg, &yaml.EncoderOptions{SeqIndent: yaml.WideSequenceStyle})
if !assert.NoError(t, err) {
return false
}
return assert.Equal(t, res.String(), string(b))
return assert.Equal(t, string(res), string(b))
}

// CheckoutBranch checks out the git branch in the repo
Expand Down
Loading