k8s.io/kubernetes@v1.29.3/pkg/kubelet/util/util_windows_test.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2018 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package util
    21  
    22  import (
    23  	"fmt"
    24  	"math/rand"
    25  	"net"
    26  	"os"
    27  	"reflect"
    28  	"runtime"
    29  	"sync"
    30  	"testing"
    31  	"time"
    32  
    33  	winio "github.com/Microsoft/go-winio"
    34  	"github.com/stretchr/testify/assert"
    35  	"github.com/stretchr/testify/require"
    36  )
    37  
    38  func TestGetAddressAndDialer(t *testing.T) {
    39  
    40  	// Compare dialer function by pointer
    41  	tcpDialPointer := reflect.ValueOf(tcpDial).Pointer()
    42  	npipeDialPointer := reflect.ValueOf(npipeDial).Pointer()
    43  	var nilDialPointer uintptr = 0x0
    44  
    45  	tests := []struct {
    46  		endpoint      string
    47  		expectedAddr  string
    48  		expectedDial  uintptr
    49  		expectedError bool
    50  	}{
    51  		{
    52  			endpoint:      "tcp://localhost:15880",
    53  			expectedAddr:  "localhost:15880",
    54  			expectedDial:  tcpDialPointer,
    55  			expectedError: false,
    56  		},
    57  		{
    58  			endpoint:      "npipe://./pipe/mypipe",
    59  			expectedAddr:  "//./pipe/mypipe",
    60  			expectedDial:  npipeDialPointer,
    61  			expectedError: false,
    62  		},
    63  		{
    64  			endpoint:      "npipe:\\\\.\\pipe\\mypipe",
    65  			expectedAddr:  "//./pipe/mypipe",
    66  			expectedDial:  npipeDialPointer,
    67  			expectedError: false,
    68  		},
    69  		{
    70  			endpoint:      "unix:///tmp/s1.sock",
    71  			expectedAddr:  "",
    72  			expectedDial:  nilDialPointer,
    73  			expectedError: true,
    74  		},
    75  		{
    76  			endpoint:      "tcp1://abc",
    77  			expectedAddr:  "",
    78  			expectedDial:  nilDialPointer,
    79  			expectedError: true,
    80  		},
    81  		{
    82  			endpoint:      "a b c",
    83  			expectedAddr:  "",
    84  			expectedDial:  nilDialPointer,
    85  			expectedError: true,
    86  		},
    87  	}
    88  
    89  	for _, test := range tests {
    90  		expectedDialerName := runtime.FuncForPC(test.expectedDial).Name()
    91  		if expectedDialerName == "" {
    92  			expectedDialerName = "nilDial"
    93  		}
    94  		t.Run(fmt.Sprintf("Endpoint is %s, addr is %s and dialer is %s",
    95  			test.endpoint, test.expectedAddr, expectedDialerName),
    96  			func(t *testing.T) {
    97  				address, dialer, err := GetAddressAndDialer(test.endpoint)
    98  
    99  				dialerPointer := reflect.ValueOf(dialer).Pointer()
   100  				actualDialerName := runtime.FuncForPC(dialerPointer).Name()
   101  				if actualDialerName == "" {
   102  					actualDialerName = "nilDial"
   103  				}
   104  
   105  				assert.Equalf(t, test.expectedDial, dialerPointer,
   106  					"Expected dialer %s, but get %s", expectedDialerName, actualDialerName)
   107  
   108  				assert.Equal(t, test.expectedAddr, address)
   109  
   110  				if test.expectedError {
   111  					assert.NotNil(t, err, "Expect error during parsing %q", test.endpoint)
   112  				} else {
   113  					assert.Nil(t, err, "Expect no error during parsing %q", test.endpoint)
   114  				}
   115  			})
   116  	}
   117  }
   118  
   119  func TestParseEndpoint(t *testing.T) {
   120  	tests := []struct {
   121  		endpoint         string
   122  		expectedError    bool
   123  		expectedProtocol string
   124  		expectedAddr     string
   125  	}{
   126  		{
   127  			endpoint:         "unix:///tmp/s1.sock",
   128  			expectedProtocol: "unix",
   129  			expectedError:    true,
   130  		},
   131  		{
   132  			endpoint:         "tcp://localhost:15880",
   133  			expectedProtocol: "tcp",
   134  			expectedAddr:     "localhost:15880",
   135  		},
   136  		{
   137  			endpoint:         "npipe://./pipe/mypipe",
   138  			expectedProtocol: "npipe",
   139  			expectedAddr:     "//./pipe/mypipe",
   140  		},
   141  		{
   142  			endpoint:         "npipe:////./pipe/mypipe2",
   143  			expectedProtocol: "npipe",
   144  			expectedAddr:     "//./pipe/mypipe2",
   145  		},
   146  		{
   147  			endpoint:         "npipe:/pipe/mypipe3",
   148  			expectedProtocol: "npipe",
   149  			expectedAddr:     "//./pipe/mypipe3",
   150  		},
   151  		{
   152  			endpoint:         "npipe:\\\\.\\pipe\\mypipe4",
   153  			expectedProtocol: "npipe",
   154  			expectedAddr:     "//./pipe/mypipe4",
   155  		},
   156  		{
   157  			endpoint:         "npipe:\\pipe\\mypipe5",
   158  			expectedProtocol: "npipe",
   159  			expectedAddr:     "//./pipe/mypipe5",
   160  		},
   161  		{
   162  			endpoint:         "tcp1://abc",
   163  			expectedProtocol: "tcp1",
   164  			expectedError:    true,
   165  		},
   166  		{
   167  			endpoint:      "a b c",
   168  			expectedError: true,
   169  		},
   170  	}
   171  
   172  	for _, test := range tests {
   173  		protocol, addr, err := parseEndpoint(test.endpoint)
   174  		assert.Equal(t, test.expectedProtocol, protocol)
   175  		if test.expectedError {
   176  			assert.NotNil(t, err, "Expect error during parsing %q", test.endpoint)
   177  			continue
   178  		}
   179  		require.Nil(t, err, "Expect no error during parsing %q", test.endpoint)
   180  		assert.Equal(t, test.expectedAddr, addr)
   181  	}
   182  
   183  }
   184  
   185  func TestNormalizePath(t *testing.T) {
   186  	tests := []struct {
   187  		originalpath   string
   188  		normalizedPath string
   189  	}{
   190  		{
   191  			originalpath:   "\\path\\to\\file",
   192  			normalizedPath: "c:\\path\\to\\file",
   193  		},
   194  		{
   195  			originalpath:   "/path/to/file",
   196  			normalizedPath: "c:\\path\\to\\file",
   197  		},
   198  		{
   199  			originalpath:   "/path/to/dir/",
   200  			normalizedPath: "c:\\path\\to\\dir\\",
   201  		},
   202  		{
   203  			originalpath:   "\\path\\to\\dir\\",
   204  			normalizedPath: "c:\\path\\to\\dir\\",
   205  		},
   206  		{
   207  			originalpath:   "/file",
   208  			normalizedPath: "c:\\file",
   209  		},
   210  		{
   211  			originalpath:   "\\file",
   212  			normalizedPath: "c:\\file",
   213  		},
   214  		{
   215  			originalpath:   "fileonly",
   216  			normalizedPath: "fileonly",
   217  		},
   218  	}
   219  
   220  	for _, test := range tests {
   221  		assert.Equal(t, test.normalizedPath, NormalizePath(test.originalpath))
   222  	}
   223  }
   224  
   225  func TestLocalEndpoint(t *testing.T) {
   226  	tests := []struct {
   227  		path             string
   228  		file             string
   229  		expectError      bool
   230  		expectedFullPath string
   231  	}{
   232  		{
   233  			path:             "/var/lib/kubelet/pod-resources",
   234  			file:             "kube.sock", // this is not the default, but it's not relevant here
   235  			expectError:      false,
   236  			expectedFullPath: `npipe://\\.\pipe\kubelet-pod-resources`,
   237  		},
   238  	}
   239  	for _, test := range tests {
   240  		fullPath, err := LocalEndpoint(test.path, test.file)
   241  		if test.expectError {
   242  			assert.NotNil(t, err, "expected error")
   243  			continue
   244  		}
   245  		assert.Nil(t, err, "expected no error")
   246  		assert.Equal(t, test.expectedFullPath, fullPath)
   247  	}
   248  }
   249  
   250  func TestLocalEndpointRoundTrip(t *testing.T) {
   251  	npipeDialPointer := reflect.ValueOf(npipeDial).Pointer()
   252  	expectedDialerName := runtime.FuncForPC(npipeDialPointer).Name()
   253  	expectedAddress := "//./pipe/kubelet-pod-resources"
   254  
   255  	fullPath, err := LocalEndpoint(`pod-resources`, "kubelet")
   256  	require.NoErrorf(t, err, "Failed to create the local endpoint path")
   257  
   258  	address, dialer, err := GetAddressAndDialer(fullPath)
   259  	require.NoErrorf(t, err, "Failed to parse the endpoint path and get back address and dialer (path=%q)", fullPath)
   260  
   261  	dialerPointer := reflect.ValueOf(dialer).Pointer()
   262  	actualDialerName := runtime.FuncForPC(dialerPointer).Name()
   263  
   264  	assert.Equalf(t, npipeDialPointer, dialerPointer,
   265  		"Expected dialer %s, but get %s", expectedDialerName, actualDialerName)
   266  
   267  	assert.Equal(t, expectedAddress, address)
   268  }