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  }