// Copyright 2021 The Sigstore Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package client import ( "log" "net/http" "os" "testing" "github.com/google/go-cmp/cmp" ) func TestMakeOptions(t *testing.T) { customLogger := log.New(os.Stdout, "", log.LstdFlags) tests := []struct { desc string opts []Option want *options }{{ desc: "no opts", want: &options{RetryCount: DefaultRetryCount}, }, { desc: "WithUserAgent", opts: []Option{WithUserAgent("test user agent")}, want: &options{UserAgent: "test user agent", RetryCount: DefaultRetryCount}, }, { desc: "WithRetryCount", opts: []Option{WithRetryCount(2)}, want: &options{UserAgent: "", RetryCount: 2}, }, { desc: "WithLogger", opts: []Option{WithLogger(customLogger)}, want: &options{UserAgent: "", RetryCount: DefaultRetryCount, Logger: customLogger}, }, { desc: "WithLoggerNil", opts: []Option{WithLogger(nil)}, want: &options{UserAgent: "", RetryCount: DefaultRetryCount}, }, { desc: "WithInsecureTLSEnabled", opts: []Option{WithInsecureTLS(true)}, want: &options{UserAgent: "", RetryCount: DefaultRetryCount, InsecureTLS: true}, }, { desc: "WithInsecureTLSDisabled", opts: []Option{WithInsecureTLS(false)}, want: &options{UserAgent: "", RetryCount: DefaultRetryCount, InsecureTLS: false}, }} for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { got := makeOptions(tc.opts...) if d := cmp.Diff(tc.want, got, cmp.Comparer(func(a, b *log.Logger) bool { return a == b })); d != "" { t.Errorf("makeOptions(%v) returned unexpected result (-want +got): %s", tc.desc, d) } }) } } type mockRoundTripper struct { gotReqs []*http.Request resp *http.Response err error } // RoundTrip implements `http.RoundTripper` func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { m.gotReqs = append(m.gotReqs, req) return m.resp, m.err } func TestCreateRoundTripper(t *testing.T) { t.Run("always returns non-nil", func(t *testing.T) { got := createRoundTripper(nil, &options{}) if got == nil { t.Errorf("createRoundTripper() should never return a nil `http.RoundTripper`") } }) testReq, err := http.NewRequest("GET", "http://www.example.com/test", nil) if err != nil { t.Fatalf("http.NewRequest() failed: %v", err) } testResp := &http.Response{ Status: "OK", StatusCode: 200, Request: testReq, } expectedUserAgent := "test UserAgent" m := &mockRoundTripper{} rt := createRoundTripper(m, &options{ UserAgent: expectedUserAgent, }) m.resp = testResp gotResp, err := rt.RoundTrip(testReq) if err != nil { t.Errorf("RoundTrip() returned error: %v", err) } if len(m.gotReqs) < 1 { t.Fatalf("inner RoundTripper.RoundTrip() was not called") } gotReq := m.gotReqs[0] gotReqUserAgent := gotReq.UserAgent() if gotReqUserAgent != expectedUserAgent { t.Errorf("rt.RoundTrip() did not set the User-Agent properly. Wanted: %q, got: %q", expectedUserAgent, gotReqUserAgent) } if testResp != gotResp { t.Errorf("roundTripper.RoundTrip() should have returned exactly the response of the inner RoundTripper. Wanted %v, got %v", testResp, gotResp) } }