From 60afdc3050a7323d55da52c98fa1f4e392959ee5 Mon Sep 17 00:00:00 2001 From: Ken Sipe Date: Wed, 15 Jan 2020 08:24:51 -0600 Subject: [PATCH] Document and tests for how package name, operator version and app version is resolved. (#1277) Signed-off-by: Ken Sipe --- pkg/kudoctl/cmd/repo_index_test.go | 2 +- pkg/kudoctl/util/repo/resolver_repo.go | 11 ++- pkg/kudoctl/util/repo/resolver_repo_test.go | 84 +++++++++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 pkg/kudoctl/util/repo/resolver_repo_test.go diff --git a/pkg/kudoctl/cmd/repo_index_test.go b/pkg/kudoctl/cmd/repo_index_test.go index 4ee14a2c5..071f44e39 100644 --- a/pkg/kudoctl/cmd/repo_index_test.go +++ b/pkg/kudoctl/cmd/repo_index_test.go @@ -113,6 +113,6 @@ func TestRepoIndexCmd_MergeIndex(t *testing.T) { } // local operator takes precedence - o, _ := indexFile.GetByNameAndVersion("mysql", "5.7", "0.1.0") + o, _ := indexFile.FindFirstMatch("mysql", "5.7", "0.1.0") assert.Equal(t, o.Maintainers[0].Name, "Ken Sipe") } diff --git a/pkg/kudoctl/util/repo/resolver_repo.go b/pkg/kudoctl/util/repo/resolver_repo.go index 906b74778..fb1c06322 100644 --- a/pkg/kudoctl/util/repo/resolver_repo.go +++ b/pkg/kudoctl/util/repo/resolver_repo.go @@ -44,7 +44,7 @@ func (c *Client) GetPackageBytes(name string, appVersion string, operatorVersion return nil, fmt.Errorf("could not download repository index file: %w", err) } - pkgVersion, err := indexFile.GetByNameAndVersion(name, appVersion, operatorVersion) + pkgVersion, err := indexFile.FindFirstMatch(name, appVersion, operatorVersion) if err != nil { return nil, fmt.Errorf("getting %s in index file: %w", name, err) } @@ -80,10 +80,15 @@ func (c *Client) getPackageBytesByURL(packageURL string) (*bytes.Buffer, error) return resp, nil } -// GetByNameAndVersion returns the operator of given name and version. +// FindFirstMatch returns the operator of given name and version. // If no specific version is required, pass an empty string as version and the // the latest version will be returned. -func (i IndexFile) GetByNameAndVersion(name string, appVersion string, operatorVersion string) (*PackageVersion, error) { +// Possible package options include: foo-1.0.0.tgz, foo-2.0.0_1.0.1.tgz and foo-3.0.0_1.0.1.tgz +// The Entries are sorted by AppVersion first, then OpVersion. Entries with no appVersion are later in the sort order than +// entries with appVersion. Given a search for an opVersion = 1.0.1 (without appVersion) given the above foo options, +// foo-3.0.0-1.0.1 (the latest app version for this opVersion) +// appVersion could be arbitrary. if appVersion is "bar" than foo-var_1.0.1.tgz +func (i IndexFile) FindFirstMatch(name string, appVersion string, operatorVersion string) (*PackageVersion, error) { vs, ok := i.Entries[name] if !ok || len(vs) == 0 { return nil, fmt.Errorf("no operator found for: %s", name) diff --git a/pkg/kudoctl/util/repo/resolver_repo_test.go b/pkg/kudoctl/util/repo/resolver_repo_test.go new file mode 100644 index 000000000..dcfa43a97 --- /dev/null +++ b/pkg/kudoctl/util/repo/resolver_repo_test.go @@ -0,0 +1,84 @@ +package repo + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +// Testing findfirst for the following combo +// foo-2.0.0_1.0.1.tgz # app version semver +// foo-3.0.0_1.0.1.tgz # app version semver +// foo-bar_1.0.1.tgz # app version not semver +// foo-1.0.0.tgz, # no app version +// the rules are semver takes ordered precedence +// non semver takes order from position in index file (first is highest) +func TestIndexFile_FindFirstMatch(t *testing.T) { + + index := createTestIndexFile() + + // first operator version should be the latest app version + pv, _ := index.FindFirstMatch("Foo", "", "1.0.1") + assert.Equal(t, "3.0.0", pv.AppVersion) + + // first buzz operator version is the one without an app version + pv, _ = index.FindFirstMatch("Buzz", "", "1.0.1") + assert.Equal(t, "", pv.AppVersion) + assert.Equal(t, "1.0.1", pv.OperatorVersion) + + // buzz search without app or op version should have the latest buzz + pv, _ = index.FindFirstMatch("Buzz", "", "") + assert.Equal(t, "1.0.2", pv.OperatorVersion) + + // specific app version should have the app version + pv, _ = index.FindFirstMatch("Foo", "2.0.0", "") + assert.Equal(t, "2.0.0", pv.AppVersion) + assert.Equal(t, "1.0.1", pv.OperatorVersion) + + // same search but specific for app and op versions + pv, _ = index.FindFirstMatch("Foo", "2.0.0", "1.0.1") + assert.Equal(t, "2.0.0", pv.AppVersion) + assert.Equal(t, "1.0.1", pv.OperatorVersion) + +} + +func createTestIndexFile() *IndexFile { + + index := &IndexFile{} + + pv := createPackageVersion("Foo", "2.0.0", "1.0.1") + addToIndex(index, pv) + pv = createPackageVersion("Foo", "3.0.0", "1.0.1") + addToIndex(index, pv) + pv = createPackageVersion("Foo", "", "1.0.1") + addToIndex(index, pv) + pv = createPackageVersion("Foo", "bar", "1.0.1") + addToIndex(index, pv) + pv = createPackageVersion("Buzz", "", "1.0.1") + addToIndex(index, pv) + pv = createPackageVersion("Buzz", "", "1.0.2") + addToIndex(index, pv) + + index.sortPackages() + return index +} + +func addToIndex(index *IndexFile, pv PackageVersion) { + err := index.AddPackageVersion(&pv) + if err != nil { + fmt.Printf("err in test %v", err) + } +} + +func createPackageVersion(name, appVersion, operatorVersion string) PackageVersion { + + m := Metadata{ + Name: name, + OperatorVersion: operatorVersion, + AppVersion: appVersion, + } + return PackageVersion{ + Metadata: &m, + } +}