Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Copyright 2026. Huawei Technologies Co.,Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package server
import (
"testing"
"github.com/stretchr/testify/assert"
)
type parseEndpointTestCase struct {
Name string
Endpoint string
ExpectError bool
ExpectedProtocol string
ExpectedAddr string
}
func buildParseEndpointTestCases() []parseEndpointTestCase {
return []parseEndpointTestCase{
{
Name: "01-unix socket endpoint, should parse successfully",
Endpoint: "unix:///tmp/s1.sock",
ExpectedProtocol: "unix",
ExpectedAddr: "/tmp/s1.sock",
},
{
Name: "02-tcp endpoint, should parse successfully",
Endpoint: "tcp://localhost:15880",
ExpectedProtocol: "tcp",
ExpectedAddr: "localhost:15880",
},
{
Name: "03-unsupported protocol, should return error",
Endpoint: "npipe://./pipe/mypipe",
ExpectedProtocol: "npipe",
ExpectError: true,
},
{
Name: "04-invalid protocol prefix, should return error",
Endpoint: "tcp1://abc",
ExpectedProtocol: "tcp1",
ExpectError: true,
},
{
Name: "05-malformed endpoint with spaces, should return error",
Endpoint: "a b c",
ExpectError: true,
},
{
Name: "06-empty scheme endpoint, should return deprecated error",
Endpoint: "/tmp/s1.sock",
ExpectError: true,
},
}
}
func TestParseEndpoint(t *testing.T) {
testCases := buildParseEndpointTestCases()
for _, tt := range testCases {
t.Run(tt.Name, func(t *testing.T) {
protocol, addr, err := parseEndpoint(tt.Endpoint)
assert.Equal(t, tt.ExpectedProtocol, protocol)
if tt.ExpectError {
assert.NotNil(t, err, "expected error during parsing %q", tt.Endpoint)
return
}
assert.Nil(t, err, "expected no error during parsing %q", tt.Endpoint)
assert.Equal(t, tt.ExpectedAddr, addr)
})
}
}
type parseEndpointWithFallbackProtocolTestCase struct {
Name string
Endpoint string
FallbackProtocol string
ExpectError bool
ExpectedProtocol string
ExpectedAddr string
}
func buildParseEndpointWithFallbackProtocolTestCases() []parseEndpointWithFallbackProtocolTestCase {
return []parseEndpointWithFallbackProtocolTestCase{
{
Name: "01-unix endpoint, should parse without fallback",
Endpoint: "unix:///tmp/s1.sock",
FallbackProtocol: "unix",
ExpectedProtocol: "unix",
ExpectedAddr: "/tmp/s1.sock",
},
{
Name: "02-bare path, should fallback to unix protocol",
Endpoint: "/tmp/s1.sock",
FallbackProtocol: "unix",
ExpectedProtocol: "unix",
ExpectedAddr: "/tmp/s1.sock",
},
{
Name: "03-tcp endpoint, should parse without fallback",
Endpoint: "tcp://localhost:9090",
FallbackProtocol: "unix",
ExpectedProtocol: "tcp",
ExpectedAddr: "localhost:9090",
},
{
Name: "04-unsupported protocol with non-empty scheme, should not fallback",
Endpoint: "npipe://./pipe/mypipe",
FallbackProtocol: "unix",
ExpectedProtocol: "npipe",
ExpectError: true,
},
}
}
func TestParseEndpointWithFallbackProtocol(t *testing.T) {
testCases := buildParseEndpointWithFallbackProtocolTestCases()
for _, tt := range testCases {
t.Run(tt.Name, func(t *testing.T) {
protocol, addr, err := parseEndpointWithFallbackProtocol(tt.Endpoint, tt.FallbackProtocol)
assert.Equal(t, tt.ExpectedProtocol, protocol)
if tt.ExpectError {
assert.NotNil(t, err, "expected error during parsing %q", tt.Endpoint)
return
}
assert.Nil(t, err, "expected no error during parsing %q", tt.Endpoint)
assert.Equal(t, tt.ExpectedAddr, addr)
})
}
}
type getAddressAndDialerTestCase struct {
Name string
Endpoint string
ExpectError bool
ExpectedAddr string
}
func buildGetAddressAndDialerTestCases() []getAddressAndDialerTestCase {
return []getAddressAndDialerTestCase{
{
Name: "01-unix socket endpoint, should return address and dialer",
Endpoint: "unix:///tmp/s1.sock",
ExpectedAddr: "/tmp/s1.sock",
},
{
Name: "02-unix socket with different path, should return address and dialer",
Endpoint: "unix:///tmp/f6.sock",
ExpectedAddr: "/tmp/f6.sock",
},
{
Name: "03-bare path endpoint, should fallback to unix and return address and dialer",
Endpoint: "/var/lib/kubelet/pod-resources/kubelet.sock",
ExpectedAddr: "/var/lib/kubelet/pod-resources/kubelet.sock",
},
{
Name: "04-tcp endpoint, should return only support unix error",
Endpoint: "tcp://localhost:9090",
ExpectError: true,
},
{
Name: "05-http endpoint, should return unsupported protocol error",
Endpoint: "http://www.test-web.com/",
ExpectError: true,
},
{
Name: "06-https endpoint, should return unsupported protocol error",
Endpoint: "https://www.test-web.com/",
ExpectError: true,
},
{
Name: "07-invalid protocol, should return error",
Endpoint: "htta://test-web.com",
ExpectError: true,
},
}
}
func TestGetAddressAndDialer(t *testing.T) {
testCases := buildGetAddressAndDialerTestCases()
for _, tt := range testCases {
t.Run(tt.Name, func(t *testing.T) {
addr, dialer, err := getAddressAndDialer(tt.Endpoint)
if tt.ExpectError {
assert.NotNil(t, err, "expected error during parsing %s", tt.Endpoint)
return
}
assert.Nil(t, err, "expected no error during parsing %s", tt.Endpoint)
assert.Equal(t, tt.ExpectedAddr, addr)
assert.NotNil(t, dialer, "expected non-nil dialer")
})
}
}