blob: b57a692a4ec95b94fbb998baa683499f6c2493e7 [file] [log] [blame]
// Copyright Istio Authors
//
// 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 util
import (
"fmt"
"reflect"
"testing"
)
import (
core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
xdsutil "github.com/envoyproxy/go-control-plane/pkg/wellknown"
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/testing/protocmp"
structpb "google.golang.org/protobuf/types/known/structpb"
wrappers "google.golang.org/protobuf/types/known/wrapperspb"
networking "istio.io/api/networking/v1alpha3"
)
import (
"github.com/apache/dubbo-go-pixiu/pilot/pkg/features"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
"github.com/apache/dubbo-go-pixiu/pkg/cluster"
"github.com/apache/dubbo-go-pixiu/pkg/config"
"github.com/apache/dubbo-go-pixiu/pkg/config/labels"
"github.com/apache/dubbo-go-pixiu/pkg/config/schema/collections"
"github.com/apache/dubbo-go-pixiu/pkg/network"
"github.com/apache/dubbo-go-pixiu/pkg/test"
)
var testCla = &endpoint.ClusterLoadAssignment{
ClusterName: "cluster",
Endpoints: []*endpoint.LocalityLbEndpoints{{
Locality: &core.Locality{Region: "foo", Zone: "bar"},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: &endpoint.LbEndpoint_Endpoint{Endpoint: &endpoint.Endpoint{Hostname: "foo", Address: BuildAddress("1.1.1.1", 80)}},
LoadBalancingWeight: &wrappers.UInt32Value{Value: 100},
},
{
HostIdentifier: &endpoint.LbEndpoint_Endpoint{Endpoint: &endpoint.Endpoint{Hostname: "foo", Address: BuildAddress("1.1.1.1", 80)}},
LoadBalancingWeight: &wrappers.UInt32Value{Value: 100},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{Value: 50},
Priority: 2,
}},
}
func BenchmarkCloneClusterLoadAssignment(b *testing.B) {
for i := 0; i < b.N; i++ {
cpy := CloneClusterLoadAssignment(testCla)
_ = cpy
}
}
func TestCloneClusterLoadAssignment(t *testing.T) {
cloned := CloneClusterLoadAssignment(testCla)
cloned2 := CloneClusterLoadAssignment(testCla)
if !cmp.Equal(testCla, cloned, protocmp.Transform()) {
t.Fatalf("expected %v to be the same as %v", testCla, cloned)
}
cloned.ClusterName = "foo"
cloned.Endpoints[0].LbEndpoints[0].LoadBalancingWeight.Value = 5
if cmp.Equal(testCla, cloned, protocmp.Transform()) {
t.Fatalf("expected %v to be the different from %v", testCla, cloned)
}
if !cmp.Equal(testCla, cloned2, protocmp.Transform()) {
t.Fatalf("expected %v to be the same as %v", testCla, cloned)
}
}
func TestConvertAddressToCidr(t *testing.T) {
tests := []struct {
name string
addr string
want *core.CidrRange
}{
{
"return nil when the address is empty",
"",
nil,
},
{
"success case with no PrefixLen",
"1.2.3.4",
&core.CidrRange{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
{
"success case with PrefixLen",
"1.2.3.4/16",
&core.CidrRange{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 16,
},
},
},
{
"ipv6",
"2001:db8::",
&core.CidrRange{
AddressPrefix: "2001:db8::",
PrefixLen: &wrappers.UInt32Value{
Value: 128,
},
},
},
{
"ipv6 with prefix",
"2001:db8::/64",
&core.CidrRange{
AddressPrefix: "2001:db8::",
PrefixLen: &wrappers.UInt32Value{
Value: 64,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ConvertAddressToCidr(tt.addr); !reflect.DeepEqual(got, tt.want) {
t.Errorf("ConvertAddressToCidr() = %v, want %v", got, tt.want)
}
})
}
}
func TestConvertLocality(t *testing.T) {
tests := []struct {
name string
locality string
want *core.Locality
reverse string
}{
{
name: "nil locality",
locality: "",
want: &core.Locality{},
},
{
name: "locality with only region",
locality: "region",
want: &core.Locality{
Region: "region",
},
},
{
name: "locality with region and zone",
locality: "region/zone",
want: &core.Locality{
Region: "region",
Zone: "zone",
},
},
{
name: "locality with region zone and subzone",
locality: "region/zone/subzone",
want: &core.Locality{
Region: "region",
Zone: "zone",
SubZone: "subzone",
},
},
{
name: "locality with region zone subzone and rack",
locality: "region/zone/subzone/rack",
want: &core.Locality{
Region: "region",
Zone: "zone",
SubZone: "subzone",
},
reverse: "region/zone/subzone",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ConvertLocality(tt.locality)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Expected locality %#v, but got %#v", tt.want, got)
}
// Verify we can reverse the conversion back to the original input
reverse := LocalityToString(got)
if tt.reverse != "" {
// Special case, reverse lookup is different than original input
if tt.reverse != reverse {
t.Errorf("Expected locality string %s, got %v", tt.reverse, reverse)
}
} else if tt.locality != reverse {
t.Errorf("Expected locality string %s, got %v", tt.locality, reverse)
}
})
}
}
func TestLocalityMatch(t *testing.T) {
tests := []struct {
name string
locality *core.Locality
rule string
match bool
}{
{
name: "wildcard matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
rule: "*",
match: true,
},
{
name: "wildcard matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
rule: "region1/*",
match: true,
},
{
name: "wildcard matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
rule: "region1/zone1/*",
match: true,
},
{
name: "wildcard not matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
rule: "region1/zone2/*",
match: false,
},
{
name: "region matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
rule: "region1",
match: true,
},
{
name: "region and zone matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
rule: "region1/zone1",
match: true,
},
{
name: "zubzone wildcard matching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
},
rule: "region1/zone1",
match: true,
},
{
name: "subzone mismatching",
locality: &core.Locality{
Region: "region1",
Zone: "zone1",
},
rule: "region1/zone1/subzone2",
match: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
match := LocalityMatch(tt.locality, tt.rule)
if match != tt.match {
t.Errorf("Expected matching result %v, but got %v", tt.match, match)
}
})
}
}
func TestIsLocalityEmpty(t *testing.T) {
tests := []struct {
name string
locality *core.Locality
want bool
}{
{
"non empty locality",
&core.Locality{
Region: "region",
},
false,
},
{
"empty locality",
&core.Locality{
Region: "",
},
true,
},
{
"nil locality",
nil,
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := IsLocalityEmpty(tt.locality)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Expected locality empty result %#v, but got %#v", tt.want, got)
}
})
}
}
func TestBuildConfigInfoMetadata(t *testing.T) {
cases := []struct {
name string
in config.Meta
want *core.Metadata
}{
{
"destination-rule",
config.Meta{
Name: "svcA",
Namespace: "default",
Domain: "svc.cluster.local",
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
},
},
},
},
},
}
for _, v := range cases {
t.Run(v.name, func(tt *testing.T) {
got := BuildConfigInfoMetadata(v.in)
if diff := cmp.Diff(got, v.want, protocmp.Transform()); diff != "" {
tt.Errorf("BuildConfigInfoMetadata(%v) produced incorrect result:\ngot: %v\nwant: %v\nDiff: %s", v.in, got, v.want, diff)
}
})
}
}
func TestAddConfigInfoMetadata(t *testing.T) {
cases := []struct {
name string
in config.Meta
meta *core.Metadata
want *core.Metadata
}{
{
"nil metadata",
config.Meta{
Name: "svcA",
Namespace: "default",
Domain: "svc.cluster.local",
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
},
nil,
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
},
},
},
},
},
{
"empty metadata",
config.Meta{
Name: "svcA",
Namespace: "default",
Domain: "svc.cluster.local",
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{},
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
},
},
},
},
},
{
"existing istio metadata",
config.Meta{
Name: "svcA",
Namespace: "default",
Domain: "svc.cluster.local",
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"other-config": {
Kind: &structpb.Value_StringValue{
StringValue: "other-config",
},
},
},
},
},
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"other-config": {
Kind: &structpb.Value_StringValue{
StringValue: "other-config",
},
},
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
},
},
},
},
},
{
"existing non-istio metadata",
config.Meta{
Name: "svcA",
Namespace: "default",
Domain: "svc.cluster.local",
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
"other-metadata": {
Fields: map[string]*structpb.Value{
"other-config": {
Kind: &structpb.Value_StringValue{
StringValue: "other-config",
},
},
},
},
},
},
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
"other-metadata": {
Fields: map[string]*structpb.Value{
"other-config": {
Kind: &structpb.Value_StringValue{
StringValue: "other-config",
},
},
},
},
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
},
},
},
},
},
}
for _, v := range cases {
t.Run(v.name, func(tt *testing.T) {
got := AddConfigInfoMetadata(v.meta, v.in)
if diff := cmp.Diff(got, v.want, protocmp.Transform()); diff != "" {
tt.Errorf("AddConfigInfoMetadata(%v) produced incorrect result:\ngot: %v\nwant: %v\nDiff: %s", v.in, got, v.want, diff)
}
})
}
}
func TestAddSubsetToMetadata(t *testing.T) {
cases := []struct {
name string
in *core.Metadata
subset string
want *core.Metadata
}{
{
"simple subset",
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
},
},
},
},
"test-subset",
&core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"config": {
Kind: &structpb.Value_StringValue{
StringValue: "/apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/svcA",
},
},
"subset": {
Kind: &structpb.Value_StringValue{
StringValue: "test-subset",
},
},
},
},
},
},
},
{
"no metadata",
&core.Metadata{},
"test-subset",
&core.Metadata{},
},
}
for _, v := range cases {
t.Run(v.name, func(tt *testing.T) {
AddSubsetToMetadata(v.in, v.subset)
got := v.in
if diff := cmp.Diff(got, v.want, protocmp.Transform()); diff != "" {
tt.Errorf("AddSubsetToMetadata(%v, %s) produced incorrect result:\ngot: %v\nwant: %v\nDiff: %s", v.in, v.subset, got, v.want, diff)
}
})
}
}
func TestIsHTTPFilterChain(t *testing.T) {
httpFilterChain := &listener.FilterChain{
Filters: []*listener.Filter{
{
Name: xdsutil.HTTPConnectionManager,
},
},
}
tcpFilterChain := &listener.FilterChain{
Filters: []*listener.Filter{
{
Name: xdsutil.TCPProxy,
},
},
}
if !IsHTTPFilterChain(httpFilterChain) {
t.Errorf("http Filter chain not detected properly")
}
if IsHTTPFilterChain(tcpFilterChain) {
t.Errorf("tcp filter chain detected as http filter chain")
}
}
func TestIsAllowAnyOutbound(t *testing.T) {
tests := []struct {
name string
node *model.Proxy
result bool
}{
{
name: "NilSidecarScope",
node: &model.Proxy{},
result: false,
},
{
name: "NilOutboundTrafficPolicy",
node: &model.Proxy{
SidecarScope: &model.SidecarScope{},
},
result: false,
},
{
name: "OutboundTrafficPolicyRegistryOnly",
node: &model.Proxy{
SidecarScope: &model.SidecarScope{
OutboundTrafficPolicy: &networking.OutboundTrafficPolicy{
Mode: networking.OutboundTrafficPolicy_REGISTRY_ONLY,
},
},
},
result: false,
},
{
name: "OutboundTrafficPolicyAllowAny",
node: &model.Proxy{
SidecarScope: &model.SidecarScope{
OutboundTrafficPolicy: &networking.OutboundTrafficPolicy{
Mode: networking.OutboundTrafficPolicy_ALLOW_ANY,
},
},
},
result: true,
},
}
for i := range tests {
t.Run(tests[i].name, func(t *testing.T) {
out := IsAllowAnyOutbound(tests[i].node)
if out != tests[i].result {
t.Errorf("Expected %t but got %t for test case: %v\n", tests[i].result, out, tests[i].node)
}
})
}
}
func TestBuildAddress(t *testing.T) {
testCases := []struct {
name string
addr string
port uint32
expected *core.Address
}{
{
name: "ipv4",
addr: "172.10.10.1",
port: 8080,
expected: &core.Address{
Address: &core.Address_SocketAddress{
SocketAddress: &core.SocketAddress{
Address: "172.10.10.1",
PortSpecifier: &core.SocketAddress_PortValue{
PortValue: 8080,
},
},
},
},
},
{
name: "ipv6",
addr: "fe80::10e7:52ff:fecd:198b",
port: 8080,
expected: &core.Address{
Address: &core.Address_SocketAddress{
SocketAddress: &core.SocketAddress{
Address: "fe80::10e7:52ff:fecd:198b",
PortSpecifier: &core.SocketAddress_PortValue{
PortValue: 8080,
},
},
},
},
},
{
name: "uds",
addr: "/var/run/test/socket",
port: 0,
expected: &core.Address{
Address: &core.Address_Pipe{
Pipe: &core.Pipe{
Path: "/var/run/test/socket",
},
},
},
},
{
name: "uds with unix prefix",
addr: "unix:///var/run/test/socket",
port: 0,
expected: &core.Address{
Address: &core.Address_Pipe{
Pipe: &core.Pipe{
Path: "/var/run/test/socket",
},
},
},
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
addr := BuildAddress(test.addr, test.port)
if !reflect.DeepEqual(addr, test.expected) {
t.Errorf("expected add %v, but got %v", test.expected, addr)
}
})
}
}
func TestCidrRangeSliceEqual(t *testing.T) {
tests := []struct {
name string
first []*core.CidrRange
second []*core.CidrRange
want bool
}{
{
"both nil",
nil,
nil,
true,
},
{
"unequal length",
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
{
AddressPrefix: "1.2.3.5",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
false,
},
{
"equal cidr",
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
true,
},
{
"equal cidr with different insignificant bits",
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 24,
},
},
},
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.5",
PrefixLen: &wrappers.UInt32Value{
Value: 24,
},
},
},
true,
},
{
"unequal cidr address prefix mismatch",
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.5",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
false,
},
{
"unequal cidr prefixlen mismatch",
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 32,
},
},
},
[]*core.CidrRange{
{
AddressPrefix: "1.2.3.4",
PrefixLen: &wrappers.UInt32Value{
Value: 16,
},
},
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CidrRangeSliceEqual(tt.first, tt.second); got != tt.want {
t.Errorf("Unexpected CidrRangeSliceEqual() = %v, want %v", got, tt.want)
}
})
}
}
func TestEndpointMetadata(t *testing.T) {
test.SetBoolForTest(t, &features.EndpointTelemetryLabel, true)
cases := []struct {
name string
network network.ID
tlsMode string
workloadName string
clusterID cluster.ID
namespace string
labels labels.Instance
want *core.Metadata
}{
{
name: "all empty",
tlsMode: model.DisabledTLSModeLabel,
network: "",
workloadName: "",
clusterID: "",
want: &core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"workload": {
Kind: &structpb.Value_StringValue{
StringValue: ";;;;",
},
},
},
},
},
},
},
{
name: "tls mode",
tlsMode: model.IstioMutualTLSModeLabel,
network: "",
workloadName: "",
clusterID: "",
want: &core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
EnvoyTransportSocketMetadataKey: {
Fields: map[string]*structpb.Value{
model.TLSModeLabelShortname: {
Kind: &structpb.Value_StringValue{
StringValue: model.IstioMutualTLSModeLabel,
},
},
},
},
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"workload": {
Kind: &structpb.Value_StringValue{
StringValue: ";;;;",
},
},
},
},
},
},
},
{
name: "network and tls mode",
tlsMode: model.IstioMutualTLSModeLabel,
network: "network",
workloadName: "",
clusterID: "",
want: &core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
EnvoyTransportSocketMetadataKey: {
Fields: map[string]*structpb.Value{
model.TLSModeLabelShortname: {
Kind: &structpb.Value_StringValue{
StringValue: model.IstioMutualTLSModeLabel,
},
},
},
},
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"workload": {
Kind: &structpb.Value_StringValue{
StringValue: ";;;;",
},
},
},
},
},
},
},
{
name: "all label",
tlsMode: model.IstioMutualTLSModeLabel,
network: "network",
workloadName: "workload",
clusterID: "cluster",
namespace: "default",
labels: labels.Instance{
model.IstioCanonicalServiceLabelName: "service",
model.IstioCanonicalServiceRevisionLabelName: "v1",
},
want: &core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
EnvoyTransportSocketMetadataKey: {
Fields: map[string]*structpb.Value{
model.TLSModeLabelShortname: {
Kind: &structpb.Value_StringValue{
StringValue: model.IstioMutualTLSModeLabel,
},
},
},
},
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"workload": {
Kind: &structpb.Value_StringValue{
StringValue: "workload;default;service;v1;cluster",
},
},
},
},
},
},
},
{
name: "miss pod label",
tlsMode: model.IstioMutualTLSModeLabel,
network: "network",
workloadName: "workload",
clusterID: "cluster",
namespace: "default",
want: &core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
EnvoyTransportSocketMetadataKey: {
Fields: map[string]*structpb.Value{
model.TLSModeLabelShortname: {
Kind: &structpb.Value_StringValue{
StringValue: model.IstioMutualTLSModeLabel,
},
},
},
},
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"workload": {
Kind: &structpb.Value_StringValue{
StringValue: "workload;default;;;cluster",
},
},
},
},
},
},
},
{
name: "miss workload name",
tlsMode: model.IstioMutualTLSModeLabel,
network: "network",
workloadName: "",
clusterID: "cluster",
namespace: "",
want: &core.Metadata{
FilterMetadata: map[string]*structpb.Struct{
EnvoyTransportSocketMetadataKey: {
Fields: map[string]*structpb.Value{
model.TLSModeLabelShortname: {
Kind: &structpb.Value_StringValue{
StringValue: model.IstioMutualTLSModeLabel,
},
},
},
},
IstioMetadataKey: {
Fields: map[string]*structpb.Value{
"workload": {
Kind: &structpb.Value_StringValue{
StringValue: ";;;;cluster",
},
},
},
},
},
},
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
if got := BuildLbEndpointMetadata(tt.network, tt.tlsMode, tt.workloadName, tt.namespace, tt.clusterID, tt.labels); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Unexpected Endpoint metadata got %v, want %v", got, tt.want)
}
})
}
}
func TestByteCount(t *testing.T) {
cases := []struct {
in int
out string
}{
{1, "1B"},
{1000, "1.0kB"},
{1_000_000, "1.0MB"},
{1_500_000, "1.5MB"},
}
for _, tt := range cases {
t.Run(fmt.Sprint(tt.in), func(t *testing.T) {
if got := ByteCount(tt.in); got != tt.out {
t.Fatalf("got %v wanted %v", got, tt.out)
}
})
}
}
func TestIPv6Compliant(t *testing.T) {
tests := []struct {
host string
match string
}{
{"localhost", "localhost"},
{"127.0.0.1", "127.0.0.1"},
{"::1", "[::1]"},
{"2001:4860:0:2001::68", "[2001:4860:0:2001::68]"},
}
for _, tt := range tests {
t.Run(fmt.Sprint(tt.host), func(t *testing.T) {
if got := IPv6Compliant(tt.host); got != tt.match {
t.Fatalf("got %v wanted %v", got, tt.match)
}
})
}
}
func TestDomainName(t *testing.T) {
tests := []struct {
host string
port int
match string
}{
{"localhost", 3000, "localhost:3000"},
{"127.0.0.1", 3000, "127.0.0.1:3000"},
{"::1", 3000, "[::1]:3000"},
{"2001:4860:0:2001::68", 3000, "[2001:4860:0:2001::68]:3000"},
}
for _, tt := range tests {
t.Run(fmt.Sprint(tt.host), func(t *testing.T) {
if got := DomainName(tt.host, tt.port); got != tt.match {
t.Fatalf("got %v wanted %v", got, tt.match)
}
})
}
}