diff --git a/commands/pkg/update/cmdupdate_test.go b/commands/pkg/update/cmdupdate_test.go index a788e4ca8e..fa893c8a7f 100644 --- a/commands/pkg/update/cmdupdate_test.go +++ b/commands/pkg/update/cmdupdate_test.go @@ -27,12 +27,14 @@ import ( "github.com/GoogleContainerTools/kpt/commands/pkg/get" "github.com/GoogleContainerTools/kpt/commands/pkg/update" "github.com/GoogleContainerTools/kpt/internal/gitutil" + "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/testutil" "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/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" ) @@ -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 := pkg.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.UpstreamLock{ + 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 := pkg.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.UpstreamLock{ + 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, diff --git a/internal/testutil/testdata/dataset1/mysql/Kptfile b/internal/testutil/testdata/dataset1/mysql/Kptfile new file mode 100644 index 0000000000..13b6ed5ca6 --- /dev/null +++ b/internal/testutil/testdata/dataset1/mysql/Kptfile @@ -0,0 +1,16 @@ +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: mysql +info: + description: kpt package for mysql +pipeline: + mutators: + - image: gcr.io/kpt-fn/set-namespace:v0.4.1 + configMap: + namespace: example-ns + name: set namespace + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + color: orange + name: set color label diff --git a/internal/testutil/testdata/dataset2/mysql/Kptfile b/internal/testutil/testdata/dataset2/mysql/Kptfile new file mode 100644 index 0000000000..cfd69cdac1 --- /dev/null +++ b/internal/testutil/testdata/dataset2/mysql/Kptfile @@ -0,0 +1,20 @@ +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: mysql +info: + description: mysql package +pipeline: + mutators: + - image: gcr.io/kpt-fn/set-namespace:v0.4.1 + configMap: + namespace: example-ns + name: set namespace + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + fruit: apple + name: set fruit label + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + color: orange + name: set color label diff --git a/internal/testutil/testdata/dataset4/mysql/Kptfile b/internal/testutil/testdata/dataset4/mysql/Kptfile new file mode 100644 index 0000000000..cfd69cdac1 --- /dev/null +++ b/internal/testutil/testdata/dataset4/mysql/Kptfile @@ -0,0 +1,20 @@ +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: mysql +info: + description: mysql package +pipeline: + mutators: + - image: gcr.io/kpt-fn/set-namespace:v0.4.1 + configMap: + namespace: example-ns + name: set namespace + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + fruit: apple + name: set fruit label + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + color: orange + name: set color label diff --git a/internal/testutil/testdata/dataset5/mysql/Kptfile b/internal/testutil/testdata/dataset5/mysql/Kptfile new file mode 100644 index 0000000000..cfd69cdac1 --- /dev/null +++ b/internal/testutil/testdata/dataset5/mysql/Kptfile @@ -0,0 +1,20 @@ +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: mysql +info: + description: mysql package +pipeline: + mutators: + - image: gcr.io/kpt-fn/set-namespace:v0.4.1 + configMap: + namespace: example-ns + name: set namespace + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + fruit: apple + name: set fruit label + - image: gcr.io/kpt-fn/set-labels:v0.2.0 + configMap: + color: orange + name: set color label diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go index 4a0c156391..6094b39b1b 100644 --- a/internal/testutil/testutil.go +++ b/internal/testutil/testutil.go @@ -15,7 +15,6 @@ package testutil import ( - "bytes" "fmt" "os" "os/exec" @@ -46,10 +45,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" @@ -272,12 +271,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