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