k8s.io/client-go@v0.31.1/transport/cache_test.go (about) 1 /* 2 Copyright 2015 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 transport 18 19 import ( 20 "context" 21 "crypto/tls" 22 "net" 23 "net/http" 24 "net/url" 25 "reflect" 26 "testing" 27 ) 28 29 func TestTLSConfigKey(t *testing.T) { 30 // Make sure config fields that don't affect the tls config don't affect the cache key 31 identicalConfigurations := map[string]*Config{ 32 "empty": {}, 33 "basic": {Username: "bob", Password: "password"}, 34 "bearer": {BearerToken: "token"}, 35 "user agent": {UserAgent: "useragent"}, 36 "transport": {Transport: http.DefaultTransport}, 37 "wrap transport": {WrapTransport: func(http.RoundTripper) http.RoundTripper { return nil }}, 38 } 39 for nameA, valueA := range identicalConfigurations { 40 for nameB, valueB := range identicalConfigurations { 41 keyA, canCache, err := tlsConfigKey(valueA) 42 if err != nil { 43 t.Errorf("Unexpected error for %q: %v", nameA, err) 44 continue 45 } 46 if !canCache { 47 t.Errorf("Unexpected canCache=false") 48 continue 49 } 50 keyB, canCache, err := tlsConfigKey(valueB) 51 if err != nil { 52 t.Errorf("Unexpected error for %q: %v", nameB, err) 53 continue 54 } 55 if !canCache { 56 t.Errorf("Unexpected canCache=false") 57 continue 58 } 59 if keyA != keyB { 60 t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB) 61 continue 62 } 63 if keyA != (tlsCacheKey{}) { 64 t.Errorf("Expected empty cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB) 65 continue 66 } 67 } 68 } 69 70 // Make sure config fields that affect the tls config affect the cache key 71 dialer := net.Dialer{} 72 getCert := &GetCertHolder{GetCert: func() (*tls.Certificate, error) { return nil, nil }} 73 uniqueConfigurations := map[string]*Config{ 74 "proxy": {Proxy: func(request *http.Request) (*url.URL, error) { return nil, nil }}, 75 "no tls": {}, 76 "dialer": {DialHolder: &DialHolder{Dial: dialer.DialContext}}, 77 "dialer2": {DialHolder: &DialHolder{Dial: func(ctx context.Context, network, address string) (net.Conn, error) { return nil, nil }}}, 78 "insecure": {TLS: TLSConfig{Insecure: true}}, 79 "cadata 1": {TLS: TLSConfig{CAData: []byte{1}}}, 80 "cadata 2": {TLS: TLSConfig{CAData: []byte{2}}}, 81 "cert 1, key 1": { 82 TLS: TLSConfig{ 83 CertData: []byte{1}, 84 KeyData: []byte{1}, 85 }, 86 }, 87 "cert 1, key 1, servername 1": { 88 TLS: TLSConfig{ 89 CertData: []byte{1}, 90 KeyData: []byte{1}, 91 ServerName: "1", 92 }, 93 }, 94 "cert 1, key 1, servername 2": { 95 TLS: TLSConfig{ 96 CertData: []byte{1}, 97 KeyData: []byte{1}, 98 ServerName: "2", 99 }, 100 }, 101 "cert 1, key 2": { 102 TLS: TLSConfig{ 103 CertData: []byte{1}, 104 KeyData: []byte{2}, 105 }, 106 }, 107 "cert 2, key 1": { 108 TLS: TLSConfig{ 109 CertData: []byte{2}, 110 KeyData: []byte{1}, 111 }, 112 }, 113 "cert 2, key 2": { 114 TLS: TLSConfig{ 115 CertData: []byte{2}, 116 KeyData: []byte{2}, 117 }, 118 }, 119 "cadata 1, cert 1, key 1": { 120 TLS: TLSConfig{ 121 CAData: []byte{1}, 122 CertData: []byte{1}, 123 KeyData: []byte{1}, 124 }, 125 }, 126 "getCert1": { 127 TLS: TLSConfig{ 128 KeyData: []byte{1}, 129 GetCertHolder: getCert, 130 }, 131 }, 132 "getCert2": { 133 TLS: TLSConfig{ 134 KeyData: []byte{1}, 135 GetCertHolder: &GetCertHolder{GetCert: func() (*tls.Certificate, error) { return nil, nil }}, 136 }, 137 }, 138 "getCert1, key 2": { 139 TLS: TLSConfig{ 140 KeyData: []byte{2}, 141 GetCertHolder: getCert, 142 }, 143 }, 144 "http2, http1.1": {TLS: TLSConfig{NextProtos: []string{"h2", "http/1.1"}}}, 145 "http1.1-only": {TLS: TLSConfig{NextProtos: []string{"http/1.1"}}}, 146 } 147 for nameA, valueA := range uniqueConfigurations { 148 for nameB, valueB := range uniqueConfigurations { 149 keyA, canCacheA, err := tlsConfigKey(valueA) 150 if err != nil { 151 t.Errorf("Unexpected error for %q: %v", nameA, err) 152 continue 153 } 154 keyB, canCacheB, err := tlsConfigKey(valueB) 155 if err != nil { 156 t.Errorf("Unexpected error for %q: %v", nameB, err) 157 continue 158 } 159 160 shouldCacheA := valueA.Proxy == nil 161 if shouldCacheA != canCacheA { 162 t.Errorf("Unexpected canCache=false for " + nameA) 163 } 164 165 configIsNotEmpty := !reflect.DeepEqual(*valueA, Config{}) 166 if keyA == (tlsCacheKey{}) && shouldCacheA && configIsNotEmpty { 167 t.Errorf("Expected non-empty cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB) 168 continue 169 } 170 171 // Make sure we get the same key on the same config 172 if nameA == nameB { 173 if keyA != keyB { 174 t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB) 175 } 176 if canCacheA != canCacheB { 177 t.Errorf("Expected identical canCache %q and %q, got:\n\t%v\n\t%v", nameA, nameB, canCacheA, canCacheB) 178 } 179 continue 180 } 181 182 if canCacheA && canCacheB { 183 if keyA == keyB { 184 t.Errorf("Expected unique cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB) 185 continue 186 } 187 } 188 } 189 } 190 }