sigs.k8s.io/cluster-api@v1.7.1/cmd/clusterctl/client/repository/repository_gitlab_test.go (about) 1 /* 2 Copyright 2022 The Kubernetes 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 repository 18 19 import ( 20 "context" 21 "fmt" 22 "net/http" 23 "net/http/httptest" 24 "testing" 25 26 . "github.com/onsi/gomega" 27 28 clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3" 29 "sigs.k8s.io/cluster-api/cmd/clusterctl/client/config" 30 "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test" 31 goproxytest "sigs.k8s.io/cluster-api/internal/goproxy/test" 32 ) 33 34 func Test_gitLabRepository_newGitLabRepository(t *testing.T) { 35 type field struct { 36 providerConfig config.Provider 37 variableClient config.VariablesClient 38 } 39 tests := []struct { 40 name string 41 field field 42 want *gitLabRepository 43 wantedErr string 44 }{ 45 { 46 name: "can create a new GitLab repo", 47 field: field{ 48 providerConfig: config.NewProvider("test", "https://gitlab.example.org/api/v4/projects/group%2Fproject/packages/generic/my-package/v1.0/path", clusterctlv1.CoreProviderType), 49 variableClient: test.NewFakeVariableClient(), 50 }, 51 want: &gitLabRepository{ 52 providerConfig: config.NewProvider("test", "https://gitlab.example.org/api/v4/projects/group%2Fproject/packages/generic/my-package/v1.0/path", clusterctlv1.CoreProviderType), 53 configVariablesClient: test.NewFakeVariableClient(), 54 httpClient: http.DefaultClient, 55 host: "gitlab.example.org", 56 projectSlug: "group%2Fproject", 57 packageName: "my-package", 58 defaultVersion: "v1.0", 59 rootPath: ".", 60 componentsPath: "path", 61 }, 62 wantedErr: "", 63 }, 64 { 65 name: "missing variableClient", 66 field: field{ 67 providerConfig: config.NewProvider("test", "https://gitlab.example.org/api/v4/projects/group%2Fproject/packages/generic/my-package/v1.0/path", clusterctlv1.CoreProviderType), 68 variableClient: nil, 69 }, 70 want: nil, 71 wantedErr: "invalid arguments: configVariablesClient can't be nil", 72 }, 73 { 74 name: "provider url is not valid", 75 field: field{ 76 providerConfig: config.NewProvider("test", "%gh&%ij", clusterctlv1.CoreProviderType), 77 variableClient: test.NewFakeVariableClient(), 78 }, 79 want: nil, 80 wantedErr: "invalid url: parse \"%gh&%ij\": invalid URL escape \"%gh\"", 81 }, 82 { 83 name: "provider url should be in https", 84 field: field{ 85 providerConfig: config.NewProvider("test", "http://gitlab.example.org/api/v4/projects/group%2Fproject/packages/generic/my-package/v1.0/path", clusterctlv1.CoreProviderType), 86 variableClient: test.NewFakeVariableClient(), 87 }, 88 want: nil, 89 wantedErr: "invalid url: a GitLab repository url should be in the form https://{host}/api/v4/projects/{projectSlug}/packages/generic/{packageName}/{defaultVersion}/{componentsPath}", 90 }, 91 { 92 name: "provider url should have the correct number of parts", 93 field: field{ 94 providerConfig: config.NewProvider("test", "https://gitlab.example.org/api/v4/projects/group%2Fproject/packages/generic/my-package/v1.0/path/grrr", clusterctlv1.CoreProviderType), 95 variableClient: test.NewFakeVariableClient(), 96 }, 97 want: &gitLabRepository{}, 98 wantedErr: "invalid url: a GitLab repository url should be in the form https://{host}/api/v4/projects/{projectSlug}/packages/generic/{packageName}/{defaultVersion}/{componentsPath}", 99 }, 100 { 101 name: "provider url should have the correct prefix", 102 field: field{ 103 providerConfig: config.NewProvider("test", "https://gitlab.example.org/subpath/api/v4/projects/group%2Fproject/packages/generic/my-package/v1.0/path", clusterctlv1.CoreProviderType), 104 variableClient: test.NewFakeVariableClient(), 105 }, 106 want: &gitLabRepository{}, 107 wantedErr: "invalid url: a GitLab repository url should be in the form https://{host}/api/v4/projects/{projectSlug}/packages/generic/{packageName}/{defaultVersion}/{componentsPath}", 108 }, 109 { 110 name: "provider url should have the packages part", 111 field: field{ 112 providerConfig: config.NewProvider("test", "https://gitlab.example.org/api/v4/projects/group%2Fproject/packages-invalid/generic/my-package/v1.0/path", clusterctlv1.CoreProviderType), 113 variableClient: test.NewFakeVariableClient(), 114 }, 115 want: nil, 116 wantedErr: "invalid url: a GitLab repository url should be in the form https://{host}/api/v4/projects/{projectSlug}/packages/generic/{packageName}/{defaultVersion}/{componentsPath}", 117 }, 118 { 119 name: "provider url should have the generic part", 120 field: field{ 121 providerConfig: config.NewProvider("test", "https://gitlab.example.org/api/v4/projects/group%2Fproject/packages/generic-invalid/my-package/v1.0/path", clusterctlv1.CoreProviderType), 122 variableClient: test.NewFakeVariableClient(), 123 }, 124 want: nil, 125 wantedErr: "invalid url: a GitLab repository url should be in the form https://{host}/api/v4/projects/{projectSlug}/packages/generic/{packageName}/{defaultVersion}/{componentsPath}", 126 }, 127 } 128 129 for _, tt := range tests { 130 t.Run(tt.name, func(t *testing.T) { 131 g := NewWithT(t) 132 resetCaches() 133 134 gitLab, err := NewGitLabRepository(tt.field.providerConfig, tt.field.variableClient) 135 if tt.wantedErr != "" { 136 g.Expect(err).To(MatchError(tt.wantedErr)) 137 return 138 } 139 140 g.Expect(err).ToNot(HaveOccurred()) 141 g.Expect(gitLab).To(Equal(tt.want)) 142 }) 143 } 144 } 145 146 func Test_gitLabRepository_getFile(t *testing.T) { 147 mux := http.NewServeMux() 148 server := httptest.NewTLSServer(mux) 149 defer server.Close() 150 client := server.Client() 151 152 providerURL := fmt.Sprintf("%s/api/v4/projects/group%%2Fproject/packages/generic/my-package/v0.4.1/file.yaml", server.URL) 153 providerConfig := config.NewProvider("test", providerURL, clusterctlv1.CoreProviderType) 154 155 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 156 goproxytest.HTTPTestMethod(t, r, "GET") 157 if r.URL.RawPath == "/api/v4/projects/group%2Fproject/packages/generic/my-package/v0.4.1/file.yaml" { 158 w.Header().Set("Content-Type", "application/octet-stream") 159 w.Header().Set("Content-Disposition", "attachment; filename=file.yaml") 160 fmt.Fprint(w, "content") 161 return 162 } 163 http.NotFound(w, r) 164 }) 165 166 configVariablesClient := test.NewFakeVariableClient() 167 168 tests := []struct { 169 name string 170 version string 171 fileName string 172 want []byte 173 wantErr bool 174 }{ 175 { 176 name: "Release and file exist", 177 version: "v0.4.1", 178 fileName: "file.yaml", 179 want: []byte("content"), 180 wantErr: false, 181 }, 182 { 183 name: "File does not exist", 184 version: "v0.4.1", 185 fileName: "404.file", 186 want: nil, 187 wantErr: true, 188 }, 189 } 190 191 for _, tt := range tests { 192 t.Run(tt.name, func(t *testing.T) { 193 g := NewWithT(t) 194 resetCaches() 195 196 gitLab, err := NewGitLabRepository(providerConfig, configVariablesClient) 197 gitLab.(*gitLabRepository).httpClient = client 198 g.Expect(err).ToNot(HaveOccurred()) 199 200 got, err := gitLab.GetFile(context.Background(), tt.version, tt.fileName) 201 if tt.wantErr { 202 g.Expect(err).To(HaveOccurred()) 203 return 204 } 205 206 g.Expect(err).ToNot(HaveOccurred()) 207 g.Expect(got).To(Equal(tt.want)) 208 }) 209 } 210 }