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  }