|
|
|
|
@ -18,6 +18,7 @@ package registry
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"crypto/tls"
|
|
|
|
|
"errors"
|
|
|
|
|
"io"
|
|
|
|
|
"net/http"
|
|
|
|
|
@ -25,6 +26,8 @@ import (
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
"oras.land/oras-go/v2/registry/remote/auth"
|
|
|
|
|
"oras.land/oras-go/v2/registry/remote/retry"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var errMockRead = errors.New("mock read error")
|
|
|
|
|
@ -35,6 +38,24 @@ func (e *errorReader) Read(_ []byte) (n int, err error) {
|
|
|
|
|
return 0, errMockRead
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nonClonableTransport stands in for a RoundTripper an imported package replaced
|
|
|
|
|
// http.DefaultTransport with: DefaultTransport is a variable of interface type, so
|
|
|
|
|
// it does not always hold an *http.Transport.
|
|
|
|
|
type nonClonableTransport struct{}
|
|
|
|
|
|
|
|
|
|
func (*nonClonableTransport) RoundTrip(*http.Request) (*http.Response, error) {
|
|
|
|
|
return nil, errors.New("never called")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// baseTransport unwraps the transport NewTransport built the retry transport from.
|
|
|
|
|
func baseTransport(t *testing.T, transport *retry.Transport) http.RoundTripper {
|
|
|
|
|
t.Helper()
|
|
|
|
|
if logged, ok := transport.Base.(*LoggingTransport); ok {
|
|
|
|
|
return logged.RoundTripper
|
|
|
|
|
}
|
|
|
|
|
return transport.Base
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Test_isPrintableContentType(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
@ -384,3 +405,47 @@ func Test_containsCredentials(t *testing.T) {
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Test_NewTransport(t *testing.T) {
|
|
|
|
|
defer func(orig http.RoundTripper) { http.DefaultTransport = orig }(http.DefaultTransport)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
debug bool
|
|
|
|
|
installed http.RoundTripper
|
|
|
|
|
}{
|
|
|
|
|
{name: "clonable default transport", installed: &http.Transport{}},
|
|
|
|
|
{name: "replaced default transport", installed: &nonClonableTransport{}},
|
|
|
|
|
{name: "clonable default transport, debug", debug: true, installed: &http.Transport{}},
|
|
|
|
|
{name: "replaced default transport, debug", debug: true, installed: &nonClonableTransport{}},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
http.DefaultTransport = tt.installed
|
|
|
|
|
|
|
|
|
|
transport := NewTransport(tt.debug)
|
|
|
|
|
base := baseTransport(t, transport)
|
|
|
|
|
|
|
|
|
|
if tt.debug {
|
|
|
|
|
_, ok := transport.Base.(*LoggingTransport)
|
|
|
|
|
require.True(t, ok, "expected the transport to be wrapped for debug output, got %T", transport.Base)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert.NotSame(t, tt.installed, base, "the process-wide default transport must not be handed out")
|
|
|
|
|
|
|
|
|
|
httpTransport, ok := base.(*http.Transport)
|
|
|
|
|
require.True(t, ok, "TLS settings can only be applied to an *http.Transport, got %T", base)
|
|
|
|
|
|
|
|
|
|
conf := &tls.Config{InsecureSkipVerify: true}
|
|
|
|
|
_, err := ensureTLSConfig(&auth.Client{Client: &http.Client{Transport: transport}}, conf)
|
|
|
|
|
require.NoError(t, err, "TLS settings should be applicable to a Helm registry transport")
|
|
|
|
|
assert.Same(t, conf, httpTransport.TLSClientConfig)
|
|
|
|
|
|
|
|
|
|
if shared, ok := tt.installed.(*http.Transport); ok {
|
|
|
|
|
assert.NotSame(t, conf, shared.TLSClientConfig,
|
|
|
|
|
"configuring Helm's transport must not reach the process-wide default transport")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|