k8s.io/client-go@v0.31.1/rest/transport_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 rest 18 19 import ( 20 "context" 21 "net" 22 "strings" 23 "sync" 24 "testing" 25 26 clientcmdapi "k8s.io/client-go/tools/clientcmd/api" 27 ) 28 29 // TestTransportForThreadSafe is meant to be run with the race detector 30 // to detect that the Transport generation for client-go is safe to 31 // call from multiple goroutines. 32 func TestTransportForThreadSafe(t *testing.T) { 33 const ( 34 rootCACert = `-----BEGIN CERTIFICATE----- 35 MIIC4DCCAcqgAwIBAgIBATALBgkqhkiG9w0BAQswIzEhMB8GA1UEAwwYMTAuMTMu 36 MTI5LjEwNkAxNDIxMzU5MDU4MB4XDTE1MDExNTIxNTczN1oXDTE2MDExNTIxNTcz 37 OFowIzEhMB8GA1UEAwwYMTAuMTMuMTI5LjEwNkAxNDIxMzU5MDU4MIIBIjANBgkq 38 hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunDRXGwsiYWGFDlWH6kjGun+PshDGeZX 39 xtx9lUnL8pIRWH3wX6f13PO9sktaOWW0T0mlo6k2bMlSLlSZgG9H6og0W6gLS3vq 40 s4VavZ6DbXIwemZG2vbRwsvR+t4G6Nbwelm6F8RFnA1Fwt428pavmNQ/wgYzo+T1 41 1eS+HiN4ACnSoDSx3QRWcgBkB1g6VReofVjx63i0J+w8Q/41L9GUuLqquFxu6ZnH 42 60vTB55lHgFiDLjA1FkEz2dGvGh/wtnFlRvjaPC54JH2K1mPYAUXTreoeJtLJKX0 43 ycoiyB24+zGCniUmgIsmQWRPaOPircexCp1BOeze82BT1LCZNTVaxQIDAQABoyMw 44 ITAOBgNVHQ8BAf8EBAMCAKQwDwYDVR0TAQH/BAUwAwEB/zALBgkqhkiG9w0BAQsD 45 ggEBADMxsUuAFlsYDpF4fRCzXXwrhbtj4oQwcHpbu+rnOPHCZupiafzZpDu+rw4x 46 YGPnCb594bRTQn4pAu3Ac18NbLD5pV3uioAkv8oPkgr8aUhXqiv7KdDiaWm6sbAL 47 EHiXVBBAFvQws10HMqMoKtO8f1XDNAUkWduakR/U6yMgvOPwS7xl0eUTqyRB6zGb 48 K55q2dejiFWaFqB/y78txzvz6UlOZKE44g2JAVoJVM6kGaxh33q8/FmrL4kuN3ut 49 W+MmJCVDvd4eEqPwbp7146ZWTqpIJ8lvA6wuChtqV8lhAPka2hD/LMqY8iXNmfXD 50 uml0obOEy+ON91k+SWTJ3ggmF/U= 51 -----END CERTIFICATE-----` 52 authPluginName = "auth-plugin-tr" 53 ) 54 55 err := RegisterAuthProviderPlugin(authPluginName, pluginAProvider) 56 // the plugins are stored in a global variable that fails if the test 57 // runs with the flag -count N, with N > 1 58 if err != nil && !strings.Contains(err.Error(), "was registered twice") { 59 t.Errorf("Unexpected error: failed to register pluginA: %v", err) 60 } 61 62 configurations := []struct { 63 name string 64 config *Config 65 }{ 66 { 67 name: "simple config", 68 config: &Config{ 69 Host: "localhost:8080", 70 Username: "gopher", 71 Password: "g0ph3r", 72 }, 73 }, 74 { 75 name: "not cacheable config", 76 config: &Config{ 77 Host: "localhost:8080", 78 Username: "gopher", 79 Password: "g0ph3r", 80 Dial: func(ctx context.Context, network, address string) (net.Conn, error) { 81 return nil, nil 82 }, 83 }, 84 }, 85 { 86 name: "with TLS config", 87 config: &Config{ 88 Host: "localhost:8080", 89 Username: "gopher", 90 Password: "g0ph3r", 91 TLSClientConfig: TLSClientConfig{ 92 CAData: []byte(rootCACert), 93 }, 94 }, 95 }, 96 { 97 name: "with auth provider", 98 config: &Config{ 99 Host: "localhost:8080", 100 Username: "gopher", 101 Password: "g0ph3r", 102 TLSClientConfig: TLSClientConfig{ 103 CAData: []byte(rootCACert), 104 }, 105 AuthProvider: &clientcmdapi.AuthProviderConfig{ 106 Name: authPluginName, 107 Config: map[string]string{"secret": "s3cr3t"}, 108 }, 109 }, 110 }, 111 { 112 name: "with exec provider", 113 config: &Config{ 114 Host: "localhost:8080", 115 Username: "gopher", 116 Password: "g0ph3r", 117 TLSClientConfig: TLSClientConfig{ 118 CAData: []byte(rootCACert), 119 }, 120 ExecProvider: &clientcmdapi.ExecConfig{ 121 Args: []string{"secret"}, 122 Env: []clientcmdapi.ExecEnvVar{{Name: "secret", Value: "s3cr3t"}}, 123 APIVersion: "client.authentication.k8s.io/v1beta1", 124 }, 125 }, 126 }, 127 } 128 var wg sync.WaitGroup 129 130 for _, tt := range configurations { 131 tt := tt 132 wg.Add(1) 133 go func() { 134 defer wg.Done() 135 for i := 1; i <= 50; i++ { 136 wg.Add(1) 137 go func() { 138 defer wg.Done() 139 _, err := TransportFor(tt.config) 140 if err != nil { 141 t.Errorf("Config: %s TransportFor() error = %v", tt.name, err) 142 } 143 }() 144 } 145 146 }() 147 } 148 wg.Wait() 149 }