github.com/felipejfc/helm@v2.1.2+incompatible/pkg/repo/index_test.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 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 repo 18 19 import ( 20 "io/ioutil" 21 "net/http" 22 "net/http/httptest" 23 "os" 24 "path/filepath" 25 "testing" 26 27 "k8s.io/helm/pkg/proto/hapi/chart" 28 ) 29 30 const ( 31 testfile = "testdata/local-index.yaml" 32 testRepo = "test-repo" 33 ) 34 35 func TestIndexFile(t *testing.T) { 36 i := NewIndexFile() 37 i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890") 38 i.Add(&chart.Metadata{Name: "cutter", Version: "0.1.1"}, "cutter-0.1.1.tgz", "http://example.com/charts", "sha256:1234567890abc") 39 i.Add(&chart.Metadata{Name: "cutter", Version: "0.1.0"}, "cutter-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890abc") 40 i.Add(&chart.Metadata{Name: "cutter", Version: "0.2.0"}, "cutter-0.2.0.tgz", "http://example.com/charts", "sha256:1234567890abc") 41 i.SortEntries() 42 43 if i.APIVersion != APIVersionV1 { 44 t.Error("Expected API version v1") 45 } 46 47 if len(i.Entries) != 2 { 48 t.Errorf("Expected 2 charts. Got %d", len(i.Entries)) 49 } 50 51 if i.Entries["clipper"][0].Name != "clipper" { 52 t.Errorf("Expected clipper, got %s", i.Entries["clipper"][0].Name) 53 } 54 55 if len(i.Entries["cutter"]) != 3 { 56 t.Error("Expected two cutters.") 57 } 58 59 // Test that the sort worked. 0.2 should be at the first index for Cutter. 60 if v := i.Entries["cutter"][0].Version; v != "0.2.0" { 61 t.Errorf("Unexpected first version: %s", v) 62 } 63 } 64 65 func TestLoadIndex(t *testing.T) { 66 b, err := ioutil.ReadFile(testfile) 67 if err != nil { 68 t.Fatal(err) 69 } 70 i, err := LoadIndex(b) 71 if err != nil { 72 t.Fatal(err) 73 } 74 verifyLocalIndex(t, i) 75 } 76 77 func TestLoadIndexFile(t *testing.T) { 78 i, err := LoadIndexFile(testfile) 79 if err != nil { 80 t.Fatal(err) 81 } 82 verifyLocalIndex(t, i) 83 } 84 85 func TestMerge(t *testing.T) { 86 ind1 := NewIndexFile() 87 ind1.Add(&chart.Metadata{ 88 Name: "dreadnought", 89 Version: "0.1.0", 90 }, "dreadnought-0.1.0.tgz", "http://example.com", "aaaa") 91 92 ind2 := NewIndexFile() 93 ind2.Add(&chart.Metadata{ 94 Name: "dreadnought", 95 Version: "0.2.0", 96 }, "dreadnought-0.2.0.tgz", "http://example.com", "aaaabbbb") 97 ind2.Add(&chart.Metadata{ 98 Name: "doughnut", 99 Version: "0.2.0", 100 }, "doughnut-0.2.0.tgz", "http://example.com", "ccccbbbb") 101 102 ind1.Merge(ind2) 103 104 if len(ind1.Entries) != 2 { 105 t.Errorf("Expected 2 entries, got %d", len(ind1.Entries)) 106 vs := ind1.Entries["dreadnaught"] 107 if len(vs) != 2 { 108 t.Errorf("Expected 2 versions, got %d", len(vs)) 109 } 110 v := vs[0] 111 if v.Version != "0.2.0" { 112 t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version) 113 } 114 } 115 116 } 117 118 func TestDownloadIndexFile(t *testing.T) { 119 fileBytes, err := ioutil.ReadFile("testdata/local-index.yaml") 120 if err != nil { 121 t.Fatal(err) 122 } 123 124 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 125 w.Write(fileBytes) 126 })) 127 defer srv.Close() 128 129 dirName, err := ioutil.TempDir("", "tmp") 130 if err != nil { 131 t.Fatal(err) 132 } 133 defer os.RemoveAll(dirName) 134 135 path := filepath.Join(dirName, testRepo+"-index.yaml") 136 if err := DownloadIndexFile(testRepo, srv.URL, path); err != nil { 137 t.Errorf("%#v", err) 138 } 139 140 if _, err := os.Stat(path); err != nil { 141 t.Errorf("error finding created index file: %#v", err) 142 } 143 144 b, err := ioutil.ReadFile(path) 145 if err != nil { 146 t.Errorf("error reading index file: %#v", err) 147 } 148 149 i, err := LoadIndex(b) 150 if err != nil { 151 t.Errorf("Index %q failed to parse: %s", testfile, err) 152 return 153 } 154 155 verifyLocalIndex(t, i) 156 } 157 158 func verifyLocalIndex(t *testing.T, i *IndexFile) { 159 numEntries := len(i.Entries) 160 if numEntries != 2 { 161 t.Errorf("Expected 2 entries in index file but got %d", numEntries) 162 } 163 164 alpine, ok := i.Entries["alpine"] 165 if !ok { 166 t.Errorf("'alpine' section not found.") 167 return 168 } 169 170 if l := len(alpine); l != 1 { 171 t.Errorf("'alpine' should have 1 chart, got %d", l) 172 return 173 } 174 175 nginx, ok := i.Entries["nginx"] 176 if !ok || len(nginx) != 2 { 177 t.Error("Expected 2 nginx entries") 178 return 179 } 180 181 expects := []*ChartVersion{ 182 { 183 Metadata: &chart.Metadata{ 184 Name: "alpine", 185 Description: "string", 186 Version: "1.0.0", 187 Keywords: []string{"linux", "alpine", "small", "sumtin"}, 188 Home: "https://github.com/something", 189 }, 190 URLs: []string{ 191 "https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz", 192 "http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz", 193 }, 194 Digest: "sha256:1234567890abcdef", 195 }, 196 { 197 Metadata: &chart.Metadata{ 198 Name: "nginx", 199 Description: "string", 200 Version: "0.2.0", 201 Keywords: []string{"popular", "web server", "proxy"}, 202 Home: "https://github.com/something/else", 203 }, 204 URLs: []string{ 205 "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz", 206 }, 207 Digest: "sha256:1234567890abcdef", 208 }, 209 { 210 Metadata: &chart.Metadata{ 211 Name: "nginx", 212 Description: "string", 213 Version: "0.1.0", 214 Keywords: []string{"popular", "web server", "proxy"}, 215 Home: "https://github.com/something", 216 }, 217 URLs: []string{ 218 "https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz", 219 }, 220 Digest: "sha256:1234567890abcdef", 221 }, 222 } 223 tests := []*ChartVersion{alpine[0], nginx[0], nginx[1]} 224 225 for i, tt := range tests { 226 expect := expects[i] 227 if tt.Name != expect.Name { 228 t.Errorf("Expected name %q, got %q", expect.Name, tt.Name) 229 } 230 if tt.Description != expect.Description { 231 t.Errorf("Expected description %q, got %q", expect.Description, tt.Description) 232 } 233 if tt.Version != expect.Version { 234 t.Errorf("Expected version %q, got %q", expect.Version, tt.Version) 235 } 236 if tt.Digest != expect.Digest { 237 t.Errorf("Expected digest %q, got %q", expect.Digest, tt.Digest) 238 } 239 if tt.Home != expect.Home { 240 t.Errorf("Expected home %q, got %q", expect.Home, tt.Home) 241 } 242 243 for i, url := range tt.URLs { 244 if url != expect.URLs[i] { 245 t.Errorf("Expected URL %q, got %q", expect.URLs[i], url) 246 } 247 } 248 for i, kw := range tt.Keywords { 249 if kw != expect.Keywords[i] { 250 t.Errorf("Expected keywords %q, got %q", expect.Keywords[i], kw) 251 } 252 } 253 } 254 } 255 256 func TestIndexDirectory(t *testing.T) { 257 dir := "testdata/repository" 258 index, err := IndexDirectory(dir, "http://localhost:8080") 259 if err != nil { 260 t.Fatal(err) 261 } 262 263 if l := len(index.Entries); l != 2 { 264 t.Fatalf("Expected 2 entries, got %d", l) 265 } 266 267 // Other things test the entry generation more thoroughly. We just test a 268 // few fields. 269 cname := "frobnitz" 270 frobs, ok := index.Entries[cname] 271 if !ok { 272 t.Fatalf("Could not read chart %s", cname) 273 } 274 275 frob := frobs[0] 276 if len(frob.Digest) == 0 { 277 t.Errorf("Missing digest of file %s.", frob.Name) 278 } 279 if frob.URLs[0] != "http://localhost:8080/frobnitz-1.2.3.tgz" { 280 t.Errorf("Unexpected URLs: %v", frob.URLs) 281 } 282 if frob.Name != "frobnitz" { 283 t.Errorf("Expected frobnitz, got %q", frob.Name) 284 } 285 } 286 287 func TestLoadUnversionedIndex(t *testing.T) { 288 data, err := ioutil.ReadFile("testdata/unversioned-index.yaml") 289 if err != nil { 290 t.Fatal(err) 291 } 292 293 ind, err := loadUnversionedIndex(data) 294 if err != nil { 295 t.Fatal(err) 296 } 297 298 if l := len(ind.Entries); l != 2 { 299 t.Fatalf("Expected 2 entries, got %d", l) 300 } 301 302 if l := len(ind.Entries["mysql"]); l != 3 { 303 t.Fatalf("Expected 3 mysql versions, got %d", l) 304 } 305 } 306 307 func TestIndexAdd(t *testing.T) { 308 309 i := NewIndexFile() 310 i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890") 311 312 if i.Entries["clipper"][0].URLs[0] != "http://example.com/charts/clipper-0.1.0.tgz" { 313 t.Errorf("Expected http://example.com/charts/clipper-0.1.0.tgz, got %s", i.Entries["clipper"][0].URLs[0]) 314 } 315 316 i.Add(&chart.Metadata{Name: "alpine", Version: "0.1.0"}, "/home/charts/alpine-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890") 317 318 if i.Entries["alpine"][0].URLs[0] != "http://example.com/charts/alpine-0.1.0.tgz" { 319 t.Errorf("Expected http://example.com/charts/alpine-0.1.0.tgz, got %s", i.Entries["alpine"][0].URLs[0]) 320 } 321 322 i.Add(&chart.Metadata{Name: "deis", Version: "0.1.0"}, "/home/charts/deis-0.1.0.tgz", "http://example.com/charts/", "sha256:1234567890") 323 324 if i.Entries["deis"][0].URLs[0] != "http://example.com/charts/deis-0.1.0.tgz" { 325 t.Errorf("Expected http://example.com/charts/deis-0.1.0.tgz, got %s", i.Entries["deis"][0].URLs[0]) 326 } 327 } 328 329 func TestUrlJoin(t *testing.T) { 330 tests := []struct { 331 name, url, expect string 332 paths []string 333 }{ 334 {name: "URL, one path", url: "http://example.com", paths: []string{"hello"}, expect: "http://example.com/hello"}, 335 {name: "Long URL, one path", url: "http://example.com/but/first", paths: []string{"slurm"}, expect: "http://example.com/but/first/slurm"}, 336 {name: "URL, two paths", url: "http://example.com", paths: []string{"hello", "world"}, expect: "http://example.com/hello/world"}, 337 {name: "URL, no paths", url: "http://example.com", paths: []string{}, expect: "http://example.com"}, 338 {name: "basepath, two paths", url: "../example.com", paths: []string{"hello", "world"}, expect: "../example.com/hello/world"}, 339 } 340 341 for _, tt := range tests { 342 if got, err := urlJoin(tt.url, tt.paths...); err != nil { 343 t.Errorf("%s: error %q", tt.name, err) 344 } else if got != tt.expect { 345 t.Errorf("%s: expected %q, got %q", tt.name, tt.expect, got) 346 } 347 } 348 }