Update ESIPP validation and service registry unit tests

This commit is contained in:
Zihong Zheng 2017-05-02 21:20:16 -07:00
parent 79ca71708a
commit 12277a0ad4
4 changed files with 1131 additions and 51 deletions

View File

@ -19,10 +19,15 @@ package service
import (
"testing"
"fmt"
"reflect"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
"github.com/davecgh/go-spew/spew"
)
func TestGetLoadBalancerSourceRanges(t *testing.T) {
@ -129,3 +134,385 @@ func TestAllowAll(t *testing.T) {
checkAllowAll(true, "192.168.0.0/0")
checkAllowAll(true, "192.168.0.1/32", "0.0.0.0/0")
}
func TestRequestsOnlyLocalTraffic(t *testing.T) {
checkRequestsOnlyLocalTraffic := func(requestsOnlyLocalTraffic bool, service *api.Service) {
res := RequestsOnlyLocalTraffic(service)
if res != requestsOnlyLocalTraffic {
t.Errorf("Expected requests OnlyLocal traffic = %v, got %v",
requestsOnlyLocalTraffic, res)
}
}
checkRequestsOnlyLocalTraffic(false, &api.Service{})
checkRequestsOnlyLocalTraffic(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
})
checkRequestsOnlyLocalTraffic(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
},
})
checkRequestsOnlyLocalTraffic(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkRequestsOnlyLocalTraffic(true, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
},
})
checkRequestsOnlyLocalTraffic(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkRequestsOnlyLocalTraffic(true, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
},
})
}
func TestNeedsHealthCheck(t *testing.T) {
checkNeedsHealthCheck := func(needsHealthCheck bool, service *api.Service) {
res := NeedsHealthCheck(service)
if res != needsHealthCheck {
t.Errorf("Expected needs health check = %v, got %v",
needsHealthCheck, res)
}
}
checkNeedsHealthCheck(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
})
checkNeedsHealthCheck(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkNeedsHealthCheck(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
},
})
checkNeedsHealthCheck(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkNeedsHealthCheck(true, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
},
})
checkNeedsHealthCheck(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: "invalid",
},
},
})
checkNeedsHealthCheck(false, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
})
checkNeedsHealthCheck(true, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
})
}
func TestGetServiceHealthCheckNodePort(t *testing.T) {
checkGetServiceHealthCheckNodePort := func(healthCheckNodePort int32, service *api.Service) {
res := GetServiceHealthCheckNodePort(service)
if res != healthCheckNodePort {
t.Errorf("Expected health check node port = %v, got %v",
healthCheckNodePort, res)
}
}
checkGetServiceHealthCheckNodePort(0, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
})
checkGetServiceHealthCheckNodePort(0, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkGetServiceHealthCheckNodePort(0, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkGetServiceHealthCheckNodePort(34567, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
HealthCheckNodePort: int32(34567),
},
})
checkGetServiceHealthCheckNodePort(34567, &api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
BetaAnnotationHealthCheckNodePort: "34567",
},
},
})
}
func TestSetDefaultExternalTrafficPolicyIfNeeded(t *testing.T) {
testCases := []struct {
inputService *api.Service
expectedService *api.Service
}{
// First class fields cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
},
},
// Beta annotations cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
},
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
},
}
for i, tc := range testCases {
SetDefaultExternalTrafficPolicyIfNeeded(tc.inputService)
if !reflect.DeepEqual(tc.inputService, tc.expectedService) {
t.Errorf("%v: got unexpected service", i)
spew.Dump(tc)
}
}
}
func TestClearExternalTrafficPolicy(t *testing.T) {
testCases := []struct {
inputService *api.Service
}{
// First class fields cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
// Beta annotations cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
},
},
}
for i, tc := range testCases {
ClearExternalTrafficPolicy(tc.inputService)
if _, ok := tc.inputService.Annotations[BetaAnnotationExternalTraffic]; ok ||
tc.inputService.Spec.ExternalTrafficPolicy != "" {
t.Errorf("%v: failed to clear ExternalTrafficPolicy", i)
spew.Dump(tc)
}
}
}
func TestSetServiceHealthCheckNodePort(t *testing.T) {
testCases := []struct {
inputService *api.Service
hcNodePort int32
beta bool
}{
// First class fields cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
30012,
false,
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
0,
false,
},
// Beta annotations cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
30012,
true,
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
0,
true,
},
}
for i, tc := range testCases {
SetServiceHealthCheckNodePort(tc.inputService, tc.hcNodePort)
if !tc.beta {
if tc.inputService.Spec.HealthCheckNodePort != tc.hcNodePort {
t.Errorf("%v: got HealthCheckNodePort %v, want %v", i, tc.inputService.Spec.HealthCheckNodePort, tc.hcNodePort)
}
} else {
l, ok := tc.inputService.Annotations[BetaAnnotationHealthCheckNodePort]
if tc.hcNodePort == 0 {
if ok {
t.Errorf("%v: HealthCheckNodePort set, want it to be cleared", i)
}
} else {
if !ok {
t.Errorf("%v: HealthCheckNodePort unset, want %v", i, tc.hcNodePort)
} else if l != fmt.Sprintf("%v", tc.hcNodePort) {
t.Errorf("%v: got HealthCheckNodePort %v, want %v", i, l, tc.hcNodePort)
}
}
}
}
}

View File

@ -19,10 +19,15 @@ package service
import (
"testing"
"fmt"
"reflect"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api/v1"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
"github.com/davecgh/go-spew/spew"
)
func TestGetLoadBalancerSourceRanges(t *testing.T) {
@ -129,3 +134,385 @@ func TestAllowAll(t *testing.T) {
checkAllowAll(true, "192.168.0.0/0")
checkAllowAll(true, "192.168.0.1/32", "0.0.0.0/0")
}
func TestRequestsOnlyLocalTraffic(t *testing.T) {
checkRequestsOnlyLocalTraffic := func(requestsOnlyLocalTraffic bool, service *v1.Service) {
res := RequestsOnlyLocalTraffic(service)
if res != requestsOnlyLocalTraffic {
t.Errorf("Expected requests OnlyLocal traffic = %v, got %v",
requestsOnlyLocalTraffic, res)
}
}
checkRequestsOnlyLocalTraffic(false, &v1.Service{})
checkRequestsOnlyLocalTraffic(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
})
checkRequestsOnlyLocalTraffic(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
},
})
checkRequestsOnlyLocalTraffic(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkRequestsOnlyLocalTraffic(true, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
},
})
checkRequestsOnlyLocalTraffic(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkRequestsOnlyLocalTraffic(true, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
},
})
}
func TestNeedsHealthCheck(t *testing.T) {
checkNeedsHealthCheck := func(needsHealthCheck bool, service *v1.Service) {
res := NeedsHealthCheck(service)
if res != needsHealthCheck {
t.Errorf("Expected needs health check = %v, got %v",
needsHealthCheck, res)
}
}
checkNeedsHealthCheck(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
})
checkNeedsHealthCheck(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkNeedsHealthCheck(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
},
})
checkNeedsHealthCheck(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkNeedsHealthCheck(true, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
},
})
checkNeedsHealthCheck(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: "invalid",
},
},
})
checkNeedsHealthCheck(false, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
})
checkNeedsHealthCheck(true, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
})
}
func TestGetServiceHealthCheckNodePort(t *testing.T) {
checkGetServiceHealthCheckNodePort := func(healthCheckNodePort int32, service *v1.Service) {
res := GetServiceHealthCheckNodePort(service)
if res != healthCheckNodePort {
t.Errorf("Expected health check node port = %v, got %v",
healthCheckNodePort, res)
}
}
checkGetServiceHealthCheckNodePort(0, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
})
checkGetServiceHealthCheckNodePort(0, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkGetServiceHealthCheckNodePort(0, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
})
checkGetServiceHealthCheckNodePort(34567, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
HealthCheckNodePort: int32(34567),
},
})
checkGetServiceHealthCheckNodePort(34567, &v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
BetaAnnotationHealthCheckNodePort: "34567",
},
},
})
}
func TestSetDefaultExternalTrafficPolicyIfNeeded(t *testing.T) {
testCases := []struct {
inputService *v1.Service
expectedService *v1.Service
}{
// First class fields cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
},
},
// Beta annotations cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
},
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
},
}
for i, tc := range testCases {
SetDefaultExternalTrafficPolicyIfNeeded(tc.inputService)
if !reflect.DeepEqual(tc.inputService, tc.expectedService) {
t.Errorf("%v: got unexpected service", i)
spew.Dump(tc)
}
}
}
func TestClearExternalTrafficPolicy(t *testing.T) {
testCases := []struct {
inputService *v1.Service
}{
// First class fields cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
// Beta annotations cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficLocal,
},
},
},
},
}
for i, tc := range testCases {
ClearExternalTrafficPolicy(tc.inputService)
if _, ok := tc.inputService.Annotations[BetaAnnotationExternalTraffic]; ok ||
tc.inputService.Spec.ExternalTrafficPolicy != "" {
t.Errorf("%v: failed to clear ExternalTrafficPolicy", i)
spew.Dump(tc)
}
}
}
func TestSetServiceHealthCheckNodePort(t *testing.T) {
testCases := []struct {
inputService *v1.Service
hcNodePort int32
beta bool
}{
// First class fields cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
30012,
false,
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
0,
false,
},
// Beta annotations cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
30012,
true,
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
BetaAnnotationExternalTraffic: AnnotationValueExternalTrafficGlobal,
},
},
},
0,
true,
},
}
for i, tc := range testCases {
SetServiceHealthCheckNodePort(tc.inputService, tc.hcNodePort)
if !tc.beta {
if tc.inputService.Spec.HealthCheckNodePort != tc.hcNodePort {
t.Errorf("%v: got HealthCheckNodePort %v, want %v", i, tc.inputService.Spec.HealthCheckNodePort, tc.hcNodePort)
}
} else {
l, ok := tc.inputService.Annotations[BetaAnnotationHealthCheckNodePort]
if tc.hcNodePort == 0 {
if ok {
t.Errorf("%v: HealthCheckNodePort set, want it to be cleared", i)
}
} else {
if !ok {
t.Errorf("%v: HealthCheckNodePort unset, want %v", i, tc.hcNodePort)
} else if l != fmt.Sprintf("%v", tc.hcNodePort) {
t.Errorf("%v: got HealthCheckNodePort %v, want %v", i, l, tc.hcNodePort)
}
}
}
}
}

View File

@ -5656,9 +5656,19 @@ func TestValidateService(t *testing.T) {
numErrs: 1,
},
{
name: "LoadBalancer allows onlyLocal alpha annotations",
name: "invalid node port with clusterIP None",
tweakSvc: func(s *api.Service) {
s.Annotations[service.AlphaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
s.Spec.Type = api.ServiceTypeNodePort
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "q", Port: 1, Protocol: "TCP", NodePort: 1, TargetPort: intstr.FromInt(1)})
s.Spec.ClusterIP = "None"
},
numErrs: 1,
},
// ESIPP section begins.
{
name: "LoadBalancer allows onlyLocal beta annotations",
tweakSvc: func(s *api.Service) {
s.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
},
numErrs: 0,
},
@ -5689,14 +5699,68 @@ func TestValidateService(t *testing.T) {
numErrs: 1,
},
{
name: "invalid node port with clusterIP None",
name: "valid healthCheckNodePort beta annotation",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeNodePort
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "q", Port: 1, Protocol: "TCP", NodePort: 1, TargetPort: intstr.FromInt(1)})
s.Spec.ClusterIP = "None"
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
s.Annotations[service.BetaAnnotationHealthCheckNodePort] = "31100"
},
numErrs: 0,
},
{
name: "invalid externalTraffic field",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Spec.ExternalTrafficPolicy = "invalid"
},
numErrs: 1,
},
{
name: "nagative healthCheckNodePort field",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
s.Spec.HealthCheckNodePort = -1
},
numErrs: 1,
},
{
name: "nagative healthCheckNodePort field",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
s.Spec.HealthCheckNodePort = 31100
},
numErrs: 0,
},
{
name: "disallows use ExternalTraffic beta annotation with first class field",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
s.Spec.HealthCheckNodePort = 3001
},
numErrs: 1,
},
{
name: "disallows duplicated ExternalTraffic beta annotation with first class field",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
},
numErrs: 1,
},
{
name: "disallows use HealthCheckNodePort beta annotation with first class field",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
s.Annotations[service.BetaAnnotationHealthCheckNodePort] = "3001"
},
numErrs: 1,
},
// ESIPP section ends.
}
for _, tc := range testCases {
@ -5709,6 +5773,75 @@ func TestValidateService(t *testing.T) {
}
}
func TestValidateServiceExternalTrafficFieldsCombination(t *testing.T) {
testCases := []struct {
name string
tweakSvc func(svc *api.Service) // Given a basic valid service, each test case can customize it.
numErrs int
}{
{
name: "valid loadBalancer service with externalTrafficPolicy and healthCheckNodePort set",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
s.Spec.HealthCheckNodePort = 34567
},
numErrs: 0,
},
{
name: "valid nodePort service with externalTrafficPolicy set",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeNodePort
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
},
numErrs: 0,
},
{
name: "valid clusterIP service with none of externalTrafficPolicy and healthCheckNodePort set",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeClusterIP
},
numErrs: 0,
},
{
name: "cannot set healthCheckNodePort field on loadBalancer service with externalTrafficPolicy!=Local",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeLoadBalancer
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeGlobal
s.Spec.HealthCheckNodePort = 34567
},
numErrs: 1,
},
{
name: "cannot set healthCheckNodePort field on nodePort service",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeNodePort
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
s.Spec.HealthCheckNodePort = 34567
},
numErrs: 1,
},
{
name: "cannot set externalTrafficPolicy or healthCheckNodePort fields on clusterIP service",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeClusterIP
s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
s.Spec.HealthCheckNodePort = 34567
},
numErrs: 2,
},
}
for _, tc := range testCases {
svc := makeValidService()
tc.tweakSvc(&svc)
errs := ValidateServiceExternalTrafficFieldsCombination(&svc)
if len(errs) != tc.numErrs {
t.Errorf("Unexpected error list for case %q: %v", tc.name, errs.ToAggregate())
}
}
}
func TestValidateReplicationControllerStatus(t *testing.T) {
tests := []struct {
name string
@ -7088,40 +7221,46 @@ func TestValidateServiceUpdate(t *testing.T) {
numErrs: 1,
},
{
name: "Service allows removing onlyLocal alpha annotations",
name: "Service allows removing onlyLocal beta annotations",
tweakSvc: func(oldSvc, newSvc *api.Service) {
oldSvc.Annotations[service.AlphaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort] = "3001"
oldSvc.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = "3001"
},
numErrs: 0,
},
{
name: "Service allows modifying onlyLocal alpha annotations",
name: "Service allows modifying onlyLocal beta annotations",
tweakSvc: func(oldSvc, newSvc *api.Service) {
oldSvc.Annotations[service.AlphaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort] = "3001"
newSvc.Annotations[service.AlphaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficGlobal
newSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort] = oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort]
},
numErrs: 0,
},
{
name: "Service disallows promoting one of the onlyLocal pair to beta",
tweakSvc: func(oldSvc, newSvc *api.Service) {
oldSvc.Annotations[service.AlphaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort] = "3001"
oldSvc.Spec.Type = api.ServiceTypeLoadBalancer
oldSvc.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = "3001"
newSvc.Spec.Type = api.ServiceTypeLoadBalancer
newSvc.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficGlobal
newSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort] = oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort]
newSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = oldSvc.Annotations[service.BetaAnnotationHealthCheckNodePort]
},
numErrs: 0,
},
{
name: "Service disallows promoting one of the onlyLocal pair to GA",
tweakSvc: func(oldSvc, newSvc *api.Service) {
oldSvc.Spec.Type = api.ServiceTypeLoadBalancer
oldSvc.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = "3001"
newSvc.Spec.Type = api.ServiceTypeLoadBalancer
newSvc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
newSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = oldSvc.Annotations[service.BetaAnnotationHealthCheckNodePort]
},
numErrs: 1,
},
{
name: "Service allows changing both onlyLocal annotations from alpha to beta",
name: "Service allows changing both onlyLocal annotations from beta to GA",
tweakSvc: func(oldSvc, newSvc *api.Service) {
oldSvc.Annotations[service.AlphaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort] = "3001"
newSvc.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
newSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = oldSvc.Annotations[service.AlphaAnnotationHealthCheckNodePort]
oldSvc.Spec.Type = api.ServiceTypeLoadBalancer
oldSvc.Annotations[service.BetaAnnotationExternalTraffic] = service.AnnotationValueExternalTrafficLocal
oldSvc.Annotations[service.BetaAnnotationHealthCheckNodePort] = "3001"
newSvc.Spec.Type = api.ServiceTypeLoadBalancer
newSvc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal
newSvc.Spec.HealthCheckNodePort = 3001
},
numErrs: 0,
},

View File

@ -959,13 +959,48 @@ func TestUpdateServiceWithConflictingNamespace(t *testing.T) {
}
}
// Validate allocation of a nodePort when the externalTraffic=OnlyLocal annotation is set
// and type is LoadBalancer
func TestServiceRegistryExternalTrafficAnnotationHealthCheckNodePortAllocation(t *testing.T) {
// Validate allocation of a nodePort when ExternalTrafficPolicy is set to Local
// and type is LoadBalancer.
func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp",
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeLoadBalancer,
Ports: []api.ServicePort{{
Port: 6502,
Protocol: api.ProtocolTCP,
TargetPort: intstr.FromInt(6502),
}},
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
},
}
created_svc, err := storage.Create(ctx, svc)
if created_svc == nil || err != nil {
t.Errorf("Unexpected failure creating service %v", err)
}
created_service := created_svc.(*api.Service)
if !service.NeedsHealthCheck(created_service) {
t.Errorf("Expecting health check needed, returned health check not needed instead")
}
port := service.GetServiceHealthCheckNodePort(created_service)
if port == 0 {
t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort")
}
}
// Validate allocation of a nodePort when ExternalTraffic beta annotation is set to OnlyLocal
// and type is LoadBalancer.
func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocationBeta(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "external-lb-esipp",
Annotations: map[string]string{
service.BetaAnnotationExternalTraffic: service.AnnotationValueExternalTrafficLocal,
},
@ -987,22 +1022,60 @@ func TestServiceRegistryExternalTrafficAnnotationHealthCheckNodePortAllocation(t
}
created_service := created_svc.(*api.Service)
if !service.NeedsHealthCheck(created_service) {
t.Errorf("Unexpected missing annotation %s", service.BetaAnnotationExternalTraffic)
t.Errorf("Expecting health check needed, returned health check not needed instead")
}
port := service.GetServiceHealthCheckNodePort(created_service)
if port == 0 {
t.Errorf("Failed to allocate and create the health check node port annotation %s", service.BetaAnnotationHealthCheckNodePort)
t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort")
}
}
// Validate using the user specified nodePort when the externalTraffic=OnlyLocal annotation is set
// and type is LoadBalancer
func TestServiceRegistryExternalTrafficBetaAnnotationHealthCheckNodePortUserAllocation(t *testing.T) {
// Validate using the user specified nodePort when ExternalTrafficPolicy is set to Local
// and type is LoadBalancer.
func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp",
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeLoadBalancer,
Ports: []api.ServicePort{{
Port: 6502,
Protocol: api.ProtocolTCP,
TargetPort: intstr.FromInt(6502),
}},
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
HealthCheckNodePort: int32(30200),
},
}
created_svc, err := storage.Create(ctx, svc)
if created_svc == nil || err != nil {
t.Fatalf("Unexpected failure creating service :%v", err)
}
created_service := created_svc.(*api.Service)
if !service.NeedsHealthCheck(created_service) {
t.Errorf("Expecting health check needed, returned health check not needed instead")
}
port := service.GetServiceHealthCheckNodePort(created_service)
if port == 0 {
t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort")
}
if port != 30200 {
t.Errorf("Failed to allocate requested nodePort expected 30200, got %d", port)
}
}
// Validate using the user specified nodePort when ExternalTraffic beta annotation is set to OnlyLocal
// and type is LoadBalancer.
func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocationBeta(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "external-lb-esipp",
Annotations: map[string]string{
service.BetaAnnotationExternalTraffic: service.AnnotationValueExternalTrafficLocal,
service.BetaAnnotationHealthCheckNodePort: "30200",
@ -1021,27 +1094,54 @@ func TestServiceRegistryExternalTrafficBetaAnnotationHealthCheckNodePortUserAllo
}
created_svc, err := storage.Create(ctx, svc)
if created_svc == nil || err != nil {
t.Fatalf("Unexpected failure creating service: %v", err)
t.Fatalf("Unexpected failure creating service :%v", err)
}
created_service := created_svc.(*api.Service)
if !service.NeedsHealthCheck(created_service) {
t.Errorf("Unexpected missing annotation %s", service.BetaAnnotationExternalTraffic)
t.Errorf("Expecting health check needed, returned health check not needed instead")
}
port := service.GetServiceHealthCheckNodePort(created_service)
if port == 0 {
t.Errorf("Failed to allocate and create the health check node port annotation %s", service.BetaAnnotationHealthCheckNodePort)
t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort")
}
if port != 30200 {
t.Errorf("Failed to allocate requested nodePort expected 30200, got %d", port)
}
}
// Validate that the service creation fails when the requested port number is -1
func TestServiceRegistryExternalTrafficAnnotationNegative(t *testing.T) {
// Validate that the service creation fails when the requested port number is -1.
func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp",
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeLoadBalancer,
Ports: []api.ServicePort{{
Port: 6502,
Protocol: api.ProtocolTCP,
TargetPort: intstr.FromInt(6502),
}},
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
HealthCheckNodePort: int32(-1),
},
}
created_svc, err := storage.Create(ctx, svc)
if created_svc == nil || err != nil {
return
}
t.Errorf("Unexpected creation of service with invalid HealthCheckNodePort specified")
}
// Validate that the service creation fails when the requested port number in beta annotation is -1.
func TestServiceRegistryExternalTrafficHealthCheckNodePortNegativeBeta(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "external-lb-esipp",
Annotations: map[string]string{
service.BetaAnnotationExternalTraffic: service.AnnotationValueExternalTrafficLocal,
service.BetaAnnotationHealthCheckNodePort: "-1",
@ -1062,15 +1162,49 @@ func TestServiceRegistryExternalTrafficAnnotationNegative(t *testing.T) {
if created_svc == nil || err != nil {
return
}
t.Errorf("Unexpected creation of service with invalid healthCheckNodePort specified")
t.Errorf("Unexpected creation of service with invalid HealthCheckNodePort specified")
}
// Validate that the health check nodePort is not allocated when the externalTraffic annotation is !"OnlyLocal"
func TestServiceRegistryExternalTrafficAnnotationGlobal(t *testing.T) {
// Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global.
func TestServiceRegistryExternalTrafficGlobal(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp",
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeLoadBalancer,
Ports: []api.ServicePort{{
Port: 6502,
Protocol: api.ProtocolTCP,
TargetPort: intstr.FromInt(6502),
}},
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
}
created_svc, err := storage.Create(ctx, svc)
if created_svc == nil || err != nil {
t.Errorf("Unexpected failure creating service %v", err)
}
created_service := created_svc.(*api.Service)
if service.NeedsHealthCheck(created_service) {
t.Errorf("Expecting health check not needed, returned health check needed instead")
}
// Make sure the service does not have the health check node port allocated
port := service.GetServiceHealthCheckNodePort(created_service)
if port != 0 {
t.Errorf("Unexpected allocation of health check node port: %v", port)
}
}
// Validate that the health check nodePort is not allocated when ExternalTraffic beta annotation is set to Global.
func TestServiceRegistryExternalTrafficGlobalBeta(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "external-lb-esipp",
Annotations: map[string]string{
service.BetaAnnotationExternalTraffic: service.AnnotationValueExternalTrafficGlobal,
},
@ -1091,14 +1225,47 @@ func TestServiceRegistryExternalTrafficAnnotationGlobal(t *testing.T) {
t.Errorf("Unexpected failure creating service %v", err)
}
created_service := created_svc.(*api.Service)
// Make sure the service does not have the annotation
if service.NeedsHealthCheck(created_service) {
t.Errorf("Unexpected value for annotation %s", service.BetaAnnotationExternalTraffic)
t.Errorf("Expecting health check not needed, returned health check needed instead")
}
// Make sure the service does not have the health check node port allocated
port := service.GetServiceHealthCheckNodePort(created_service)
if port != 0 {
t.Errorf("Unexpected allocation of health check node port annotation %s", service.BetaAnnotationHealthCheckNodePort)
t.Errorf("Unexpected allocation of health check node port: %v", port)
}
}
// Validate that ExternalTraffic is default to Global for loadBalancer service.
func TestServiceRegistryExternalTrafficDefaultGlobal(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
storage, _ := NewTestREST(t, nil)
svc := &api.Service{
ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"},
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeLoadBalancer,
Ports: []api.ServicePort{{
Port: 6502,
Protocol: api.ProtocolTCP,
TargetPort: intstr.FromInt(6502),
}},
},
}
created_svc, err := storage.Create(ctx, svc)
if created_svc == nil || err != nil {
t.Errorf("Unexpected failure creating service %v", err)
}
created_service := created_svc.(*api.Service)
if service.NeedsHealthCheck(created_service) {
t.Errorf("Expecting health check not needed, returned health check needed instead")
}
// Make sure the service does not have the health check node port allocated
if port := service.GetServiceHealthCheckNodePort(created_service); port != 0 {
t.Errorf("Unexpected allocation of health check node port: %v", port)
}
if created_service.Spec.ExternalTrafficPolicy != api.ServiceExternalTrafficPolicyTypeGlobal {
t.Errorf("Expecting externalTraffic to be %v, got:%v", api.ServiceExternalTrafficPolicyTypeGlobal, created_service.Spec.ExternalTrafficPolicy)
}
}