fix list showing multiple revisions of release

Signed-off-by: Karuppiah Natarajan <karuppiah7890@gmail.com>
pull/6391/head
Karuppiah Natarajan 6 years ago
parent d285097f58
commit 0c2ab7f3d1
No known key found for this signature in database
GPG Key ID: C674A28337662A96

@ -54,6 +54,16 @@ func TestListCmd(t *testing.T) {
Name: "starlord",
Version: 2,
Namespace: defaultNamespace,
Info: &release.Info{
LastDeployed: timestamp1,
Status: release.StatusFailed,
},
Chart: chartInfo,
},
{
Name: "starlord",
Version: 3,
Namespace: defaultNamespace,
Info: &release.Info{
LastDeployed: timestamp1,
Status: release.StatusDeployed,

@ -5,6 +5,5 @@ groot default 1 2016-01-16 00:00:01 +0000 UTC uninstalled chi
hummingbird default 1 2016-01-16 00:00:03 +0000 UTC deployed chickadee-1.0.0
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
starlord default 1 2016-01-16 00:00:01 +0000 UTC superseded chickadee-1.0.0
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
thanos default 1 2016-01-16 00:00:01 +0000 UTC pending-install chickadee-1.0.0

@ -2,4 +2,4 @@ NAME NAMESPACE REVISION UPDATED STATUS CHART
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0
hummingbird default 1 2016-01-16 00:00:03 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0

@ -1,5 +1,5 @@
NAME NAMESPACE REVISION UPDATED STATUS CHART
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
hummingbird default 1 2016-01-16 00:00:03 +0000 UTC deployed chickadee-1.0.0
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0

@ -2,4 +2,4 @@ NAME NAMESPACE REVISION UPDATED STATUS CHART
hummingbird default 1 2016-01-16 00:00:03 +0000 UTC deployed chickadee-1.0.0
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0

@ -1,4 +1,4 @@
NAME NAMESPACE REVISION UPDATED STATUS CHART
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0

@ -1,5 +1,5 @@
NAME NAMESPACE REVISION UPDATED STATUS CHART
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0
hummingbird default 1 2016-01-16 00:00:03 +0000 UTC deployed chickadee-1.0.0

@ -1,3 +1,2 @@
NAME NAMESPACE REVISION UPDATED STATUS CHART
gamora default 1 2016-01-16 00:00:01 +0000 UTC superseded chickadee-1.0.0
starlord default 1 2016-01-16 00:00:01 +0000 UTC superseded chickadee-1.0.0
NAME NAMESPACE REVISION UPDATED STATUS CHART
gamora default 1 2016-01-16 00:00:01 +0000 UTC superseded chickadee-1.0.0

@ -2,4 +2,4 @@ NAME NAMESPACE REVISION UPDATED STATUS CHART
hummingbird default 1 2016-01-16 00:00:03 +0000 UTC deployed chickadee-1.0.0
iguana default 2 2016-01-16 00:00:04 +0000 UTC deployed chickadee-1.0.0
rocket default 1 2016-01-16 00:00:02 +0000 UTC failed chickadee-1.0.0
starlord default 2 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0
starlord default 3 2016-01-16 00:00:01 +0000 UTC deployed chickadee-1.0.0

@ -163,7 +163,7 @@ func TestList_StateMask(t *testing.T) {
is := assert.New(t)
lister := newListFixture(t)
makeMeSomeReleases(lister.cfg.Releases, t)
one, err := lister.cfg.Releases.Get("one", 1)
one, err := lister.cfg.Releases.Get("one", 3)
is.NoError(err)
one.SetStatus(release.StatusUninstalled, "uninstalled")
lister.cfg.Releases.Update(one)
@ -210,10 +210,20 @@ func TestList_FilterFailsCompile(t *testing.T) {
func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
t.Helper()
oldOne := releaseStub()
oldOne.Namespace = "default"
oldOne.Name = "one"
oldOne.Version = 1
oldOne.Info.Status = release.StatusSuperseded
anotherOldOne := releaseStub()
anotherOldOne.Namespace = oldOne.Namespace
anotherOldOne.Name = oldOne.Name
anotherOldOne.Version = 2
anotherOldOne.Info.Status = release.StatusFailed
one := releaseStub()
one.Name = "one"
one.Namespace = "default"
one.Version = 1
one.Name = oldOne.Name
one.Namespace = oldOne.Namespace
one.Version = 3
two := releaseStub()
two.Name = "two"
two.Namespace = "default"
@ -222,13 +232,8 @@ func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
three.Name = "three"
three.Namespace = "default"
three.Version = 3
four := releaseStub()
four.Name = "four"
four.Namespace = "default"
four.Version = 4
four.Info.Status = release.StatusSuperseded
for _, rel := range []*release.Release{one, two, three} {
for _, rel := range []*release.Release{oldOne, anotherOldOne, one, two, three} {
if err := store.Create(rel); err != nil {
t.Fatal(err)
}
@ -236,5 +241,5 @@ func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
all, err := store.ListReleases()
assert.NoError(t, err)
assert.Len(t, all, 3, "sanity test: three items added")
assert.Len(t, all, 3, "sanity test: three latest releases present")
}

@ -81,7 +81,7 @@ func (cfgmaps *ConfigMaps) Get(key string) (*rspb.Release, error) {
return r, nil
}
// List fetches all releases and returns the list releases such
// List fetches all latest releases and returns the list releases such
// that filter(release) == true. An error is returned if the
// configmap fails to retrieve the releases.
func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
@ -94,7 +94,7 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
return nil, err
}
var results []*rspb.Release
releases := make([]*rspb.Release, 0, len(list.Items))
// iterate over the configmaps object list
// and decode each release
@ -104,6 +104,13 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
cfgmaps.Log("list: failed to decode release: %v: %s", item, err)
continue
}
releases = append(releases, rls)
}
latestReleases := getLatestReleases(releases)
results := make([]*rspb.Release, 0, len(latestReleases))
for _, rls := range latestReleases {
if filter(rls) {
results = append(results, rls)
}

@ -87,7 +87,9 @@ func TestConfigMapList(t *testing.T) {
cfgmaps := newTestFixtureCfgMaps(t, []*rspb.Release{
releaseStub("key-1", 1, "default", rspb.StatusUninstalled),
releaseStub("key-2", 1, "default", rspb.StatusUninstalled),
releaseStub("key-3", 1, "default", rspb.StatusDeployed),
releaseStub("key-3", 1, "default", rspb.StatusSuperseded),
releaseStub("key-3", 2, "default", rspb.StatusFailed),
releaseStub("key-3", 3, "default", rspb.StatusDeployed),
releaseStub("key-4", 1, "default", rspb.StatusDeployed),
releaseStub("key-5", 1, "default", rspb.StatusSuperseded),
releaseStub("key-6", 1, "default", rspb.StatusSuperseded),
@ -128,6 +130,18 @@ func TestConfigMapList(t *testing.T) {
if len(ssd) != 2 {
t.Errorf("Expected 2 superseded, got %d", len(ssd))
}
// list all deployed or failed releases
dplAndFail, err := cfgmaps.List(func(rel *rspb.Release) bool {
return rel.Info.Status == rspb.StatusDeployed || rel.Info.Status == rspb.StatusFailed
})
// check
if err != nil {
t.Errorf("Failed to list deployed/failed: %s", err)
}
if len(dplAndFail) != 2 {
t.Errorf("Expected 2 deployed/failed, got %d", len(dplAndFail))
}
}
func TestConfigMapCreate(t *testing.T) {

@ -66,19 +66,28 @@ func (mem *Memory) Get(key string) (*rspb.Release, error) {
}
}
// List returns the list of all releases such that filter(release) == true
// List returns the list of all latest releases such that filter(release) == true
func (mem *Memory) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
defer unlock(mem.rlock())
var ls []*rspb.Release
var releases []*rspb.Release
for _, recs := range mem.cache {
recs.Iter(func(_ int, rec *record) bool {
if filter(rec.rls) {
ls = append(ls, rec.rls)
}
rls := rec.rls
releases = append(releases, rls)
return true
})
}
latestReleases := getLatestReleases(releases)
var ls = make([]*rspb.Release, 0, len(latestReleases))
for _, rls := range latestReleases {
if filter(rls) {
ls = append(ls, rls)
}
}
return ls, nil
}

@ -194,3 +194,31 @@ func TestMemoryDelete(t *testing.T) {
}
}
func TestMemory_List(t *testing.T) {
var tests = []struct {
desc string
xlen int
filterFunc func(*rspb.Release) bool
}{
{
desc: "should be 2 list results",
xlen: 2,
filterFunc: func(rls *rspb.Release) bool {
return true
},
},
}
ts := tsFixtureMemory(t)
for _, tt := range tests {
l, err := ts.List(tt.filterFunc)
if err != nil {
t.Fatalf("Failed to list: %s\n", err)
}
if tt.xlen != len(l) {
t.Fatalf("Expected %d results, actual %d\n", tt.xlen, len(l))
}
}
}

@ -46,13 +46,13 @@ func tsFixtureMemory(t *testing.T) *Memory {
// rls-a
releaseStub("rls-a", 4, "default", rspb.StatusDeployed),
releaseStub("rls-a", 1, "default", rspb.StatusSuperseded),
releaseStub("rls-a", 3, "default", rspb.StatusSuperseded),
releaseStub("rls-a", 3, "default", rspb.StatusFailed),
releaseStub("rls-a", 2, "default", rspb.StatusSuperseded),
// rls-b
releaseStub("rls-b", 4, "default", rspb.StatusDeployed),
releaseStub("rls-b", 1, "default", rspb.StatusSuperseded),
releaseStub("rls-b", 3, "default", rspb.StatusSuperseded),
releaseStub("rls-b", 2, "default", rspb.StatusSuperseded),
releaseStub("rls-b", 2, "default", rspb.StatusFailed),
}
mem := NewMemory()

@ -74,7 +74,7 @@ func (secrets *Secrets) Get(key string) (*rspb.Release, error) {
return r, errors.Wrapf(err, "get: failed to decode data %q", key)
}
// List fetches all releases and returns the list releases such
// List fetches all the latest releases and returns the list releases such
// that filter(release) == true. An error is returned if the
// secret fails to retrieve the releases.
func (secrets *Secrets) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
@ -86,7 +86,7 @@ func (secrets *Secrets) List(filter func(*rspb.Release) bool) ([]*rspb.Release,
return nil, errors.Wrap(err, "list: failed to list")
}
var results []*rspb.Release
releases := make([]*rspb.Release, 0, len(list.Items))
// iterate over the secrets object list
// and decode each release
@ -96,6 +96,13 @@ func (secrets *Secrets) List(filter func(*rspb.Release) bool) ([]*rspb.Release,
secrets.Log("list: failed to decode release: %v: %s", item, err)
continue
}
releases = append(releases, rls)
}
latestReleases := getLatestReleases(releases)
results := make([]*rspb.Release, 0, len(latestReleases))
for _, rls := range latestReleases {
if filter(rls) {
results = append(results, rls)
}

@ -51,7 +51,7 @@ func TestSecretGet(t *testing.T) {
}
}
func TestUNcompressedSecretGet(t *testing.T) {
func TestUncompressedSecretGet(t *testing.T) {
vers := 1
name := "smug-pigeon"
namespace := "default"
@ -87,7 +87,9 @@ func TestSecretList(t *testing.T) {
secrets := newTestFixtureSecrets(t, []*rspb.Release{
releaseStub("key-1", 1, "default", rspb.StatusUninstalled),
releaseStub("key-2", 1, "default", rspb.StatusUninstalled),
releaseStub("key-3", 1, "default", rspb.StatusDeployed),
releaseStub("key-3", 1, "default", rspb.StatusSuperseded),
releaseStub("key-3", 2, "default", rspb.StatusFailed),
releaseStub("key-3", 3, "default", rspb.StatusDeployed),
releaseStub("key-4", 1, "default", rspb.StatusDeployed),
releaseStub("key-5", 1, "default", rspb.StatusSuperseded),
releaseStub("key-6", 1, "default", rspb.StatusSuperseded),
@ -128,6 +130,18 @@ func TestSecretList(t *testing.T) {
if len(ssd) != 2 {
t.Errorf("Expected 2 superseded, got %d", len(ssd))
}
// list all deployed or failed releases
dplAndFail, err := secrets.List(func(rel *rspb.Release) bool {
return rel.Info.Status == rspb.StatusDeployed || rel.Info.Status == rspb.StatusFailed
})
// check
if err != nil {
t.Errorf("Failed to list deployed/failed: %s", err)
}
if len(dplAndFail) != 2 {
t.Errorf("Expected 2 deployed/failed, got %d", len(dplAndFail))
}
}
func TestSecretCreate(t *testing.T) {

@ -83,3 +83,21 @@ func decodeRelease(data string) (*rspb.Release, error) {
}
return &rls, nil
}
// getLatestReleases returns the latest releases from the list of releases
func getLatestReleases(releases []*rspb.Release) []*rspb.Release {
latestReleases := make(map[string]*rspb.Release)
for _, rls := range releases {
if latestRelease, exists := latestReleases[rls.Name]; exists && latestRelease.Version > rls.Version {
continue
}
latestReleases[rls.Name] = rls
}
var list = make([]*rspb.Release, 0, len(latestReleases))
for _, rls := range latestReleases {
list = append(list, rls)
}
return list
}

@ -75,14 +75,14 @@ func (s *Storage) Delete(name string, version int) (*rspb.Release, error) {
return s.Driver.Delete(makeKey(name, version))
}
// ListReleases returns all releases from storage. An error is returned if the
// ListReleases returns all latest releases from storage. An error is returned if the
// storage backend fails to retrieve the releases.
func (s *Storage) ListReleases() ([]*rspb.Release, error) {
s.Log("listing all releases in storage")
s.Log("listing all latest releases in storage")
return s.Driver.List(func(_ *rspb.Release) bool { return true })
}
// ListUninstalled returns all releases with Status == UNINSTALLED. An error is returned
// ListUninstalled returns all latest releases with Status == UNINSTALLED. An error is returned
// if the storage backend fails to retrieve the releases.
func (s *Storage) ListUninstalled() ([]*rspb.Release, error) {
s.Log("listing uninstalled releases in storage")
@ -91,10 +91,10 @@ func (s *Storage) ListUninstalled() ([]*rspb.Release, error) {
})
}
// ListDeployed returns all releases with Status == DEPLOYED. An error is returned
// ListDeployed returns all latest releases with Status == DEPLOYED. An error is returned
// if the storage backend fails to retrieve the releases.
func (s *Storage) ListDeployed() ([]*rspb.Release, error) {
s.Log("listing all deployed releases in storage")
s.Log("listing all latest deployed releases in storage")
return s.Driver.List(func(rls *rspb.Release) bool {
return relutil.StatusFilter(rspb.StatusDeployed).Check(rls)
})

@ -126,9 +126,10 @@ func TestStorageList(t *testing.T) {
rls1 := ReleaseTestData{Name: "livid-human", Status: rspb.StatusSuperseded}.ToRelease()
rls2 := ReleaseTestData{Name: "relaxed-cat", Status: rspb.StatusSuperseded}.ToRelease()
rls3 := ReleaseTestData{Name: "hungry-hippo", Status: rspb.StatusDeployed}.ToRelease()
rls4 := ReleaseTestData{Name: "angry-beaver", Status: rspb.StatusDeployed}.ToRelease()
rls5 := ReleaseTestData{Name: "opulent-frog", Status: rspb.StatusUninstalled}.ToRelease()
rls6 := ReleaseTestData{Name: "happy-liger", Status: rspb.StatusUninstalled}.ToRelease()
rls4 := ReleaseTestData{Name: "angry-beaver", Version: 1, Status: rspb.StatusFailed}.ToRelease()
rls5 := ReleaseTestData{Name: "angry-beaver", Version: 2, Status: rspb.StatusDeployed}.ToRelease()
rls6 := ReleaseTestData{Name: "opulent-frog", Status: rspb.StatusUninstalled}.ToRelease()
rls7 := ReleaseTestData{Name: "happy-liger", Status: rspb.StatusUninstalled}.ToRelease()
// create the release records in the storage
assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'rls0'")
@ -138,6 +139,7 @@ func TestStorageList(t *testing.T) {
assertErrNil(t.Fatal, storage.Create(rls4), "Storing release 'rls4'")
assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'rls5'")
assertErrNil(t.Fatal, storage.Create(rls6), "Storing release 'rls6'")
assertErrNil(t.Fatal, storage.Create(rls7), "Storing release 'rls7'")
}
var listTests = []struct {

Loading…
Cancel
Save