sigs.k8s.io/cluster-api@v1.6.3/internal/goproxy/goproxy_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 goproxy 18 19 import ( 20 "context" 21 "fmt" 22 "net/http" 23 "net/http/httptest" 24 "net/url" 25 "testing" 26 "time" 27 28 "github.com/blang/semver/v4" 29 . "github.com/onsi/gomega" 30 ) 31 32 func TestClient_GetVersions(t *testing.T) { 33 retryableOperationInterval = 200 * time.Millisecond 34 retryableOperationTimeout = 1 * time.Second 35 36 clientGoproxy, muxGoproxy, teardownGoproxy := NewFakeGoproxy() 37 defer teardownGoproxy() 38 39 // setup an handler for returning 2 fake releases 40 muxGoproxy.HandleFunc("/github.com/o/r1/@v/list", func(w http.ResponseWriter, r *http.Request) { 41 testMethod(t, r, "GET") 42 fmt.Fprint(w, "v1.1.0\n") 43 fmt.Fprint(w, "v0.2.0\n") 44 }) 45 46 // setup an handler for returning 2 fake releases for v1 47 muxGoproxy.HandleFunc("/github.com/o/r2/@v/list", func(w http.ResponseWriter, r *http.Request) { 48 testMethod(t, r, "GET") 49 fmt.Fprint(w, "v1.1.0\n") 50 fmt.Fprint(w, "v0.2.0\n") 51 }) 52 // setup an handler for returning 2 fake releases for v2 53 muxGoproxy.HandleFunc("/github.com/o/r2/v2/@v/list", func(w http.ResponseWriter, r *http.Request) { 54 testMethod(t, r, "GET") 55 fmt.Fprint(w, "v2.0.1\n") 56 fmt.Fprint(w, "v2.0.0\n") 57 }) 58 59 tests := []struct { 60 name string 61 gomodulePath string 62 want semver.Versions 63 wantErr bool 64 }{ 65 { 66 "No versions", 67 "github.com/o/doesntexist", 68 nil, 69 true, 70 }, 71 { 72 "Two versions < v2", 73 "github.com/o/r1", 74 semver.Versions{ 75 semver.MustParse("0.2.0"), 76 semver.MustParse("1.1.0"), 77 }, 78 false, 79 }, 80 { 81 "Multiple versiosn including > v1", 82 "github.com/o/r2", 83 semver.Versions{ 84 semver.MustParse("0.2.0"), 85 semver.MustParse("1.1.0"), 86 semver.MustParse("2.0.0"), 87 semver.MustParse("2.0.1"), 88 }, 89 false, 90 }, 91 } 92 for _, tt := range tests { 93 t.Run(tt.name, func(t *testing.T) { 94 ctx := context.Background() 95 g := NewWithT(t) 96 97 got, err := clientGoproxy.GetVersions(ctx, tt.gomodulePath) 98 if tt.wantErr { 99 g.Expect(err).To(HaveOccurred()) 100 return 101 } 102 g.Expect(err).ToNot(HaveOccurred()) 103 104 g.Expect(got).To(BeEquivalentTo(tt.want)) 105 }) 106 } 107 } 108 109 func Test_GetGoproxyHost(t *testing.T) { 110 retryableOperationInterval = 200 * time.Millisecond 111 retryableOperationTimeout = 1 * time.Second 112 113 tests := []struct { 114 name string 115 envvar string 116 wantScheme string 117 wantHost string 118 wantErr bool 119 }{ 120 { 121 name: "defaulting", 122 envvar: "", 123 wantScheme: "https", 124 wantHost: "proxy.golang.org", 125 wantErr: false, 126 }, 127 { 128 name: "direct falls back to empty strings", 129 envvar: "direct", 130 wantScheme: "", 131 wantHost: "", 132 wantErr: false, 133 }, 134 { 135 name: "off falls back to empty strings", 136 envvar: "off", 137 wantScheme: "", 138 wantHost: "", 139 wantErr: false, 140 }, 141 { 142 name: "other goproxy", 143 envvar: "foo.bar.de", 144 wantScheme: "https", 145 wantHost: "foo.bar.de", 146 wantErr: false, 147 }, 148 { 149 name: "other goproxy comma separated, return first", 150 envvar: "foo.bar,foobar.barfoo", 151 wantScheme: "https", 152 wantHost: "foo.bar", 153 wantErr: false, 154 }, 155 { 156 name: "other goproxy including https scheme", 157 envvar: "https://foo.bar", 158 wantScheme: "https", 159 wantHost: "foo.bar", 160 wantErr: false, 161 }, 162 { 163 name: "other goproxy including http scheme", 164 envvar: "http://foo.bar", 165 wantScheme: "http", 166 wantHost: "foo.bar", 167 wantErr: false, 168 }, 169 } 170 for _, tt := range tests { 171 t.Run(tt.name, func(t *testing.T) { 172 g := NewWithT(t) 173 gotScheme, gotHost, err := GetSchemeAndHost(tt.envvar) 174 if tt.wantErr { 175 g.Expect(err).To(HaveOccurred()) 176 return 177 } 178 g.Expect(err).ToNot(HaveOccurred()) 179 180 g.Expect(gotScheme).To(Equal(tt.wantScheme)) 181 g.Expect(gotHost).To(Equal(tt.wantHost)) 182 }) 183 } 184 } 185 186 // NewFakeGoproxy sets up a test HTTP server along with a github.Client that is 187 // configured to talk to that test server. Tests should register handlers on 188 // mux which provide mock responses for the API method being tested. 189 func NewFakeGoproxy() (client *Client, mux *http.ServeMux, teardown func()) { 190 // mux is the HTTP request multiplexer used with the test server. 191 mux = http.NewServeMux() 192 193 apiHandler := http.NewServeMux() 194 apiHandler.Handle("/", mux) 195 196 // server is a test HTTP server used to provide mock API responses. 197 server := httptest.NewServer(apiHandler) 198 199 // client is the GitHub client being tested and is configured to use test server. 200 url, _ := url.Parse(server.URL + "/") 201 return NewClient(url.Scheme, url.Host), mux, server.Close 202 } 203 204 func testMethod(t *testing.T, r *http.Request, want string) { 205 t.Helper() 206 207 if got := r.Method; got != want { 208 t.Errorf("Request method: %v, want %v", got, want) 209 } 210 }