github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/action/list_test.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package action 18 19 import ( 20 "testing" 21 22 "github.com/stretchr/testify/assert" 23 24 "github.com/stefanmcshane/helm/pkg/release" 25 "github.com/stefanmcshane/helm/pkg/storage" 26 ) 27 28 func TestListStates(t *testing.T) { 29 for input, expect := range map[string]ListStates{ 30 "deployed": ListDeployed, 31 "uninstalled": ListUninstalled, 32 "uninstalling": ListUninstalling, 33 "superseded": ListSuperseded, 34 "failed": ListFailed, 35 "pending-install": ListPendingInstall, 36 "pending-rollback": ListPendingRollback, 37 "pending-upgrade": ListPendingUpgrade, 38 "unknown": ListUnknown, 39 "totally made up key": ListUnknown, 40 } { 41 if expect != expect.FromName(input) { 42 t.Errorf("Expected %d for %s", expect, input) 43 } 44 // This is a cheap way to verify that ListAll actually allows everything but Unknown 45 if got := expect.FromName(input); got != ListUnknown && got&ListAll == 0 { 46 t.Errorf("Expected %s to match the ListAll filter", input) 47 } 48 } 49 50 filter := ListDeployed | ListPendingRollback 51 if status := filter.FromName("deployed"); filter&status == 0 { 52 t.Errorf("Expected %d to match mask %d", status, filter) 53 } 54 if status := filter.FromName("failed"); filter&status != 0 { 55 t.Errorf("Expected %d to fail to match mask %d", status, filter) 56 } 57 } 58 59 func TestList_Empty(t *testing.T) { 60 lister := NewList(actionConfigFixture(t)) 61 list, err := lister.Run() 62 assert.NoError(t, err) 63 assert.Len(t, list, 0) 64 } 65 66 func newListFixture(t *testing.T) *List { 67 return NewList(actionConfigFixture(t)) 68 } 69 70 func TestList_OneNamespace(t *testing.T) { 71 is := assert.New(t) 72 lister := newListFixture(t) 73 makeMeSomeReleases(lister.cfg.Releases, t) 74 list, err := lister.Run() 75 is.NoError(err) 76 is.Len(list, 3) 77 } 78 79 func TestList_AllNamespaces(t *testing.T) { 80 is := assert.New(t) 81 lister := newListFixture(t) 82 makeMeSomeReleases(lister.cfg.Releases, t) 83 lister.AllNamespaces = true 84 lister.SetStateMask() 85 list, err := lister.Run() 86 is.NoError(err) 87 is.Len(list, 3) 88 } 89 90 func TestList_Sort(t *testing.T) { 91 is := assert.New(t) 92 lister := newListFixture(t) 93 lister.Sort = ByNameDesc // Other sorts are tested elsewhere 94 makeMeSomeReleases(lister.cfg.Releases, t) 95 list, err := lister.Run() 96 is.NoError(err) 97 is.Len(list, 3) 98 is.Equal("two", list[0].Name) 99 is.Equal("three", list[1].Name) 100 is.Equal("one", list[2].Name) 101 } 102 103 func TestList_Limit(t *testing.T) { 104 is := assert.New(t) 105 lister := newListFixture(t) 106 lister.Limit = 2 107 makeMeSomeReleases(lister.cfg.Releases, t) 108 list, err := lister.Run() 109 is.NoError(err) 110 is.Len(list, 2) 111 // Lex order means one, three, two 112 is.Equal("one", list[0].Name) 113 is.Equal("three", list[1].Name) 114 } 115 116 func TestList_BigLimit(t *testing.T) { 117 is := assert.New(t) 118 lister := newListFixture(t) 119 lister.Limit = 20 120 makeMeSomeReleases(lister.cfg.Releases, t) 121 list, err := lister.Run() 122 is.NoError(err) 123 is.Len(list, 3) 124 125 // Lex order means one, three, two 126 is.Equal("one", list[0].Name) 127 is.Equal("three", list[1].Name) 128 is.Equal("two", list[2].Name) 129 } 130 131 func TestList_LimitOffset(t *testing.T) { 132 is := assert.New(t) 133 lister := newListFixture(t) 134 lister.Limit = 2 135 lister.Offset = 1 136 makeMeSomeReleases(lister.cfg.Releases, t) 137 list, err := lister.Run() 138 is.NoError(err) 139 is.Len(list, 2) 140 141 // Lex order means one, three, two 142 is.Equal("three", list[0].Name) 143 is.Equal("two", list[1].Name) 144 } 145 146 func TestList_LimitOffsetOutOfBounds(t *testing.T) { 147 is := assert.New(t) 148 lister := newListFixture(t) 149 lister.Limit = 2 150 lister.Offset = 3 // Last item is index 2 151 makeMeSomeReleases(lister.cfg.Releases, t) 152 list, err := lister.Run() 153 is.NoError(err) 154 is.Len(list, 0) 155 156 lister.Limit = 10 157 lister.Offset = 1 158 list, err = lister.Run() 159 is.NoError(err) 160 is.Len(list, 2) 161 } 162 163 func TestList_StateMask(t *testing.T) { 164 is := assert.New(t) 165 lister := newListFixture(t) 166 makeMeSomeReleases(lister.cfg.Releases, t) 167 one, err := lister.cfg.Releases.Get("one", 1) 168 is.NoError(err) 169 one.SetStatus(release.StatusUninstalled, "uninstalled") 170 err = lister.cfg.Releases.Update(one) 171 is.NoError(err) 172 173 res, err := lister.Run() 174 is.NoError(err) 175 is.Len(res, 2) 176 is.Equal("three", res[0].Name) 177 is.Equal("two", res[1].Name) 178 179 lister.StateMask = ListUninstalled 180 res, err = lister.Run() 181 is.NoError(err) 182 is.Len(res, 1) 183 is.Equal("one", res[0].Name) 184 185 lister.StateMask |= ListDeployed 186 res, err = lister.Run() 187 is.NoError(err) 188 is.Len(res, 3) 189 } 190 191 func TestList_StateMaskWithStaleRevisions(t *testing.T) { 192 is := assert.New(t) 193 lister := newListFixture(t) 194 lister.StateMask = ListFailed 195 196 makeMeSomeReleasesWithStaleFailure(lister.cfg.Releases, t) 197 198 res, err := lister.Run() 199 200 is.NoError(err) 201 is.Len(res, 1) 202 203 // "dirty" release should _not_ be present as most recent 204 // release is deployed despite failed release in past 205 is.Equal("failed", res[0].Name) 206 } 207 208 func makeMeSomeReleasesWithStaleFailure(store *storage.Storage, t *testing.T) { 209 t.Helper() 210 one := namedReleaseStub("clean", release.StatusDeployed) 211 one.Namespace = "default" 212 one.Version = 1 213 214 two := namedReleaseStub("dirty", release.StatusDeployed) 215 two.Namespace = "default" 216 two.Version = 1 217 218 three := namedReleaseStub("dirty", release.StatusFailed) 219 three.Namespace = "default" 220 three.Version = 2 221 222 four := namedReleaseStub("dirty", release.StatusDeployed) 223 four.Namespace = "default" 224 four.Version = 3 225 226 five := namedReleaseStub("failed", release.StatusFailed) 227 five.Namespace = "default" 228 five.Version = 1 229 230 for _, rel := range []*release.Release{one, two, three, four, five} { 231 if err := store.Create(rel); err != nil { 232 t.Fatal(err) 233 } 234 } 235 236 all, err := store.ListReleases() 237 assert.NoError(t, err) 238 assert.Len(t, all, 5, "sanity test: five items added") 239 } 240 241 func TestList_Filter(t *testing.T) { 242 is := assert.New(t) 243 lister := newListFixture(t) 244 lister.Filter = "th." 245 makeMeSomeReleases(lister.cfg.Releases, t) 246 247 res, err := lister.Run() 248 is.NoError(err) 249 is.Len(res, 1) 250 is.Equal("three", res[0].Name) 251 } 252 253 func TestList_FilterFailsCompile(t *testing.T) { 254 is := assert.New(t) 255 lister := newListFixture(t) 256 lister.Filter = "t[h.{{{" 257 makeMeSomeReleases(lister.cfg.Releases, t) 258 259 _, err := lister.Run() 260 is.Error(err) 261 } 262 263 func makeMeSomeReleases(store *storage.Storage, t *testing.T) { 264 t.Helper() 265 one := releaseStub() 266 one.Name = "one" 267 one.Namespace = "default" 268 one.Version = 1 269 two := releaseStub() 270 two.Name = "two" 271 two.Namespace = "default" 272 two.Version = 2 273 three := releaseStub() 274 three.Name = "three" 275 three.Namespace = "default" 276 three.Version = 3 277 278 for _, rel := range []*release.Release{one, two, three} { 279 if err := store.Create(rel); err != nil { 280 t.Fatal(err) 281 } 282 } 283 284 all, err := store.ListReleases() 285 assert.NoError(t, err) 286 assert.Len(t, all, 3, "sanity test: three items added") 287 } 288 289 func TestFilterLatestReleases(t *testing.T) { 290 t.Run("should filter old versions of the same release", func(t *testing.T) { 291 r1 := releaseStub() 292 r1.Name = "r" 293 r1.Version = 1 294 r2 := releaseStub() 295 r2.Name = "r" 296 r2.Version = 2 297 another := releaseStub() 298 another.Name = "another" 299 another.Version = 1 300 301 filteredList := filterLatestReleases([]*release.Release{r1, r2, another}) 302 expectedFilteredList := []*release.Release{r2, another} 303 304 assert.ElementsMatch(t, expectedFilteredList, filteredList) 305 }) 306 307 t.Run("should not filter out any version across namespaces", func(t *testing.T) { 308 r1 := releaseStub() 309 r1.Name = "r" 310 r1.Namespace = "default" 311 r1.Version = 1 312 r2 := releaseStub() 313 r2.Name = "r" 314 r2.Namespace = "testing" 315 r2.Version = 2 316 317 filteredList := filterLatestReleases([]*release.Release{r1, r2}) 318 expectedFilteredList := []*release.Release{r1, r2} 319 320 assert.ElementsMatch(t, expectedFilteredList, filteredList) 321 }) 322 } 323 324 func TestSelectorList(t *testing.T) { 325 r1 := releaseStub() 326 r1.Name = "r1" 327 r1.Version = 1 328 r1.Labels = map[string]string{"key": "value1"} 329 r2 := releaseStub() 330 r2.Name = "r2" 331 r2.Version = 1 332 r2.Labels = map[string]string{"key": "value2"} 333 r3 := releaseStub() 334 r3.Name = "r3" 335 r3.Version = 1 336 r3.Labels = map[string]string{} 337 338 lister := newListFixture(t) 339 for _, rel := range []*release.Release{r1, r2, r3} { 340 if err := lister.cfg.Releases.Create(rel); err != nil { 341 t.Fatal(err) 342 } 343 } 344 345 t.Run("should fail selector parsing", func(t *testing.T) { 346 is := assert.New(t) 347 lister.Selector = "a?=b" 348 349 _, err := lister.Run() 350 is.Error(err) 351 }) 352 353 t.Run("should select one release with matching label", func(t *testing.T) { 354 lister.Selector = "key==value1" 355 res, _ := lister.Run() 356 357 expectedFilteredList := []*release.Release{r1} 358 assert.ElementsMatch(t, expectedFilteredList, res) 359 }) 360 361 t.Run("should select two releases with non matching label", func(t *testing.T) { 362 lister.Selector = "key!=value1" 363 res, _ := lister.Run() 364 365 expectedFilteredList := []*release.Release{r2, r3} 366 assert.ElementsMatch(t, expectedFilteredList, res) 367 }) 368 }