github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/cmd/helm/repo_add_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 main 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "os" 23 "path/filepath" 24 "strings" 25 "sync" 26 "testing" 27 28 "sigs.k8s.io/yaml" 29 30 "github.com/stefanmcshane/helm/internal/test/ensure" 31 "github.com/stefanmcshane/helm/pkg/helmpath" 32 "github.com/stefanmcshane/helm/pkg/helmpath/xdg" 33 "github.com/stefanmcshane/helm/pkg/repo" 34 "github.com/stefanmcshane/helm/pkg/repo/repotest" 35 ) 36 37 func TestRepoAddCmd(t *testing.T) { 38 srv, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") 39 if err != nil { 40 t.Fatal(err) 41 } 42 defer srv.Stop() 43 44 // A second test server is setup to verify URL changing 45 srv2, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") 46 if err != nil { 47 t.Fatal(err) 48 } 49 defer srv2.Stop() 50 51 tmpdir := filepath.Join(ensure.TempDir(t), "path-component.yaml/data") 52 err = os.MkdirAll(tmpdir, 0777) 53 if err != nil { 54 t.Fatal(err) 55 } 56 repoFile := filepath.Join(tmpdir, "repositories.yaml") 57 58 tests := []cmdTestCase{ 59 { 60 name: "add a repository", 61 cmd: fmt.Sprintf("repo add test-name %s --repository-config %s --repository-cache %s", srv.URL(), repoFile, tmpdir), 62 golden: "output/repo-add.txt", 63 }, 64 { 65 name: "add repository second time", 66 cmd: fmt.Sprintf("repo add test-name %s --repository-config %s --repository-cache %s", srv.URL(), repoFile, tmpdir), 67 golden: "output/repo-add2.txt", 68 }, 69 { 70 name: "add repository different url", 71 cmd: fmt.Sprintf("repo add test-name %s --repository-config %s --repository-cache %s", srv2.URL(), repoFile, tmpdir), 72 wantError: true, 73 }, 74 { 75 name: "add repository second time", 76 cmd: fmt.Sprintf("repo add test-name %s --repository-config %s --repository-cache %s --force-update", srv2.URL(), repoFile, tmpdir), 77 golden: "output/repo-add.txt", 78 }, 79 } 80 81 runTestCmd(t, tests) 82 } 83 84 func TestRepoAdd(t *testing.T) { 85 ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") 86 if err != nil { 87 t.Fatal(err) 88 } 89 defer ts.Stop() 90 91 rootDir := ensure.TempDir(t) 92 repoFile := filepath.Join(rootDir, "repositories.yaml") 93 94 const testRepoName = "test-name" 95 96 o := &repoAddOptions{ 97 name: testRepoName, 98 url: ts.URL(), 99 forceUpdate: false, 100 deprecatedNoUpdate: true, 101 repoFile: repoFile, 102 } 103 os.Setenv(xdg.CacheHomeEnvVar, rootDir) 104 105 if err := o.run(ioutil.Discard); err != nil { 106 t.Error(err) 107 } 108 109 f, err := repo.LoadFile(repoFile) 110 if err != nil { 111 t.Fatal(err) 112 } 113 114 if !f.Has(testRepoName) { 115 t.Errorf("%s was not successfully inserted into %s", testRepoName, repoFile) 116 } 117 118 idx := filepath.Join(helmpath.CachePath("repository"), helmpath.CacheIndexFile(testRepoName)) 119 if _, err := os.Stat(idx); os.IsNotExist(err) { 120 t.Errorf("Error cache index file was not created for repository %s", testRepoName) 121 } 122 idx = filepath.Join(helmpath.CachePath("repository"), helmpath.CacheChartsFile(testRepoName)) 123 if _, err := os.Stat(idx); os.IsNotExist(err) { 124 t.Errorf("Error cache charts file was not created for repository %s", testRepoName) 125 } 126 127 o.forceUpdate = true 128 129 if err := o.run(ioutil.Discard); err != nil { 130 t.Errorf("Repository was not updated: %s", err) 131 } 132 133 if err := o.run(ioutil.Discard); err != nil { 134 t.Errorf("Duplicate repository name was added") 135 } 136 } 137 138 func TestRepoAddCheckLegalName(t *testing.T) { 139 ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") 140 if err != nil { 141 t.Fatal(err) 142 } 143 defer ts.Stop() 144 defer resetEnv()() 145 146 const testRepoName = "test-hub/test-name" 147 148 rootDir := ensure.TempDir(t) 149 repoFile := filepath.Join(ensure.TempDir(t), "repositories.yaml") 150 151 o := &repoAddOptions{ 152 name: testRepoName, 153 url: ts.URL(), 154 forceUpdate: false, 155 deprecatedNoUpdate: true, 156 repoFile: repoFile, 157 } 158 os.Setenv(xdg.CacheHomeEnvVar, rootDir) 159 160 wantErrorMsg := fmt.Sprintf("repository name (%s) contains '/', please specify a different name without '/'", testRepoName) 161 162 if err := o.run(ioutil.Discard); err != nil { 163 if wantErrorMsg != err.Error() { 164 t.Fatalf("Actual error %s, not equal to expected error %s", err, wantErrorMsg) 165 } 166 } else { 167 t.Fatalf("expect reported an error.") 168 } 169 } 170 171 func TestRepoAddConcurrentGoRoutines(t *testing.T) { 172 const testName = "test-name" 173 repoFile := filepath.Join(ensure.TempDir(t), "repositories.yaml") 174 repoAddConcurrent(t, testName, repoFile) 175 } 176 177 func TestRepoAddConcurrentDirNotExist(t *testing.T) { 178 const testName = "test-name-2" 179 repoFile := filepath.Join(ensure.TempDir(t), "foo", "repositories.yaml") 180 repoAddConcurrent(t, testName, repoFile) 181 } 182 183 func TestRepoAddConcurrentNoFileExtension(t *testing.T) { 184 const testName = "test-name-3" 185 repoFile := filepath.Join(ensure.TempDir(t), "repositories") 186 repoAddConcurrent(t, testName, repoFile) 187 } 188 189 func TestRepoAddConcurrentHiddenFile(t *testing.T) { 190 const testName = "test-name-4" 191 repoFile := filepath.Join(ensure.TempDir(t), ".repositories") 192 repoAddConcurrent(t, testName, repoFile) 193 } 194 195 func repoAddConcurrent(t *testing.T, testName, repoFile string) { 196 ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") 197 if err != nil { 198 t.Fatal(err) 199 } 200 defer ts.Stop() 201 202 var wg sync.WaitGroup 203 wg.Add(3) 204 for i := 0; i < 3; i++ { 205 go func(name string) { 206 defer wg.Done() 207 o := &repoAddOptions{ 208 name: name, 209 url: ts.URL(), 210 deprecatedNoUpdate: true, 211 forceUpdate: false, 212 repoFile: repoFile, 213 } 214 if err := o.run(ioutil.Discard); err != nil { 215 t.Error(err) 216 } 217 }(fmt.Sprintf("%s-%d", testName, i)) 218 } 219 wg.Wait() 220 221 b, err := ioutil.ReadFile(repoFile) 222 if err != nil { 223 t.Error(err) 224 } 225 226 var f repo.File 227 if err := yaml.Unmarshal(b, &f); err != nil { 228 t.Error(err) 229 } 230 231 var name string 232 for i := 0; i < 3; i++ { 233 name = fmt.Sprintf("%s-%d", testName, i) 234 if !f.Has(name) { 235 t.Errorf("%s was not successfully inserted into %s: %s", name, repoFile, f.Repositories[0]) 236 } 237 } 238 } 239 240 func TestRepoAddFileCompletion(t *testing.T) { 241 checkFileCompletion(t, "repo add", false) 242 checkFileCompletion(t, "repo add reponame", false) 243 checkFileCompletion(t, "repo add reponame https://example.com", false) 244 } 245 246 func TestRepoAddWithPasswordFromStdin(t *testing.T) { 247 srv := repotest.NewTempServerWithCleanupAndBasicAuth(t, "testdata/testserver/*.*") 248 defer srv.Stop() 249 250 defer resetEnv()() 251 252 in, err := os.Open("testdata/password") 253 if err != nil { 254 t.Errorf("unexpected error, got '%v'", err) 255 } 256 257 tmpdir := ensure.TempDir(t) 258 repoFile := filepath.Join(tmpdir, "repositories.yaml") 259 260 store := storageFixture() 261 262 const testName = "test-name" 263 const username = "username" 264 cmd := fmt.Sprintf("repo add %s %s --repository-config %s --repository-cache %s --username %s --password-stdin", testName, srv.URL(), repoFile, tmpdir, username) 265 var result string 266 _, result, err = executeActionCommandStdinC(store, in, cmd) 267 if err != nil { 268 t.Errorf("unexpected error, got '%v'", err) 269 } 270 271 if !strings.Contains(result, fmt.Sprintf("\"%s\" has been added to your repositories", testName)) { 272 t.Errorf("Repo was not successfully added. Output: %s", result) 273 } 274 }