Skip to content

Commit

Permalink
unit tests for the new interface methods
Browse files Browse the repository at this point in the history
  • Loading branch information
prameshj committed Jan 9, 2020
1 parent 1043bdc commit dee780b
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 30 deletions.
209 changes: 209 additions & 0 deletions pkg/neg/syncers/endpoints_calculator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*
Copyright 2020 The Kubernetes 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 syncers

import (
"fmt"
"reflect"
"testing"

"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
listers "k8s.io/client-go/listers/core/v1"
negtypes "k8s.io/ingress-gce/pkg/neg/types"
"k8s.io/legacy-cloud-providers/gce"
)

// TestLocalGetEndpointSet verifies the GetEndpointSet method implemented by the LocalL4ILBEndpointsCalculator.
// The L7 implementation is tested in TestToZoneNetworkEndpointMapUtil.
func TestLocalGetEndpointSet(t *testing.T) {
t.Parallel()
_, transactionSyncer := newL4ILBTestTransactionSyncer(negtypes.NewAdapter(gce.NewFakeGCECloud(gce.DefaultTestClusterValues())), false)
nodeNames := []string{testInstance1, testInstance2, testInstance3, testInstance4, testInstance5, testInstance6}
for i := 0; i < len(nodeNames); i++ {
err := transactionSyncer.nodeLister.Add(&v1.Node{
ObjectMeta: metav1.ObjectMeta{
//Namespace: testServiceNamespace,
Name: nodeNames[i],
},
Status: v1.NodeStatus{
Addresses: []v1.NodeAddress{
{
Type: v1.NodeInternalIP,
Address: fmt.Sprintf("1.2.3.%d", i+1),
},
},
Conditions: []v1.NodeCondition{
{
Type: v1.NodeReady,
Status: v1.ConditionTrue,
},
},
},
})
if err != nil {
t.Errorf("Failed to add node %s to syncer's nodeLister, err %v", nodeNames[i], err)
}
}
zoneGetter := negtypes.NewFakeZoneGetter()
nodeLister := listers.NewNodeLister(transactionSyncer.nodeLister)

testCases := []struct {
desc string
endpoints *v1.Endpoints
endpointSets map[string]negtypes.NetworkEndpointSet
networkEndpointType negtypes.NetworkEndpointType
}{
{
desc: "default endpoints",
endpoints: getDefaultEndpoint(),
// only 4 out of 6 nodes are picked since there are > 4 endpoints, but they are found only on 4 nodes.
endpointSets: map[string]negtypes.NetworkEndpointSet{
negtypes.TestZone1: negtypes.NewNetworkEndpointSet(negtypes.NetworkEndpoint{IP: "1.2.3.1", Node: testInstance1}, negtypes.NetworkEndpoint{IP: "1.2.3.2", Node: testInstance2}),
negtypes.TestZone2: negtypes.NewNetworkEndpointSet(negtypes.NetworkEndpoint{IP: "1.2.3.3", Node: testInstance3}, negtypes.NetworkEndpoint{IP: "1.2.3.4", Node: testInstance4}),
},
networkEndpointType: negtypes.VmPrimaryIpEndpointType,
},
{
desc: "no endpoints",
endpoints: &v1.Endpoints{},
// No nodes are picked as there are no service endpoints.
endpointSets: nil,
networkEndpointType: negtypes.VmPrimaryIpEndpointType,
},
}
svcKey := fmt.Sprintf("%s/%s", testServiceName, testServiceNamespace)
ec := NewLocalL4ILBEndpointsCalculator(nodeLister, zoneGetter, svcKey)
for _, tc := range testCases {
retSet, _, err := ec.CalculateEndpoints(tc.endpoints, nil)
if err != nil {
t.Errorf("For case %q, expect nil error, but got %v.", tc.desc, err)
}
if !reflect.DeepEqual(retSet, tc.endpointSets) {
t.Errorf("For case %q, expecting endpoint set %v, but got %v.", tc.desc, tc.endpointSets, retSet)
}
}
}

// TestClusterGetEndpointSet verifies the GetEndpointSet method implemented by the ClusterL4ILBEndpointsCalculator.
func TestClusterGetEndpointSet(t *testing.T) {
t.Parallel()
_, transactionSyncer := newL4ILBTestTransactionSyncer(negtypes.NewAdapter(gce.NewFakeGCECloud(gce.DefaultTestClusterValues())), true)
nodeNames := []string{testInstance1, testInstance2, testInstance3, testInstance4, testInstance5, testInstance6}
for i := 0; i < len(nodeNames); i++ {
err := transactionSyncer.nodeLister.Add(&v1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: nodeNames[i],
},
Status: v1.NodeStatus{
Addresses: []v1.NodeAddress{
{
Type: v1.NodeInternalIP,
Address: fmt.Sprintf("1.2.3.%d", i+1),
},
},
Conditions: []v1.NodeCondition{
{
Type: v1.NodeReady,
Status: v1.ConditionTrue,
},
},
},
})
if err != nil {
t.Errorf("Failed to add node %s to syncer's nodeLister, err %v", nodeNames[i], err)
}
}
zoneGetter := negtypes.NewFakeZoneGetter()
nodeLister := listers.NewNodeLister(transactionSyncer.nodeLister)
testCases := []struct {
desc string
endpoints *v1.Endpoints
endpointSets map[string]negtypes.NetworkEndpointSet
networkEndpointType negtypes.NetworkEndpointType
}{
{
desc: "default endpoints",
endpoints: getDefaultEndpoint(),
// all nodes are picked since, in this mode, endpoints running do not need to run on the selected node.
endpointSets: map[string]negtypes.NetworkEndpointSet{
negtypes.TestZone1: negtypes.NewNetworkEndpointSet(negtypes.NetworkEndpoint{IP: "1.2.3.1", Node: testInstance1}, negtypes.NetworkEndpoint{IP: "1.2.3.2", Node: testInstance2}),
negtypes.TestZone2: negtypes.NewNetworkEndpointSet(negtypes.NetworkEndpoint{IP: "1.2.3.3", Node: testInstance3}, negtypes.NetworkEndpoint{IP: "1.2.3.4", Node: testInstance4},
negtypes.NetworkEndpoint{IP: "1.2.3.5", Node: testInstance5}, negtypes.NetworkEndpoint{IP: "1.2.3.6", Node: testInstance6}),
},
networkEndpointType: negtypes.VmPrimaryIpEndpointType,
},
{
desc: "no endpoints",
// all nodes are picked since, in this mode, endpoints running do not need to run on the selected node.
// Even when there are no service endpoints, nodes are selected at random.
endpoints: &v1.Endpoints{},
endpointSets: map[string]negtypes.NetworkEndpointSet{
negtypes.TestZone1: negtypes.NewNetworkEndpointSet(negtypes.NetworkEndpoint{IP: "1.2.3.1", Node: testInstance1}, negtypes.NetworkEndpoint{IP: "1.2.3.2", Node: testInstance2}),
negtypes.TestZone2: negtypes.NewNetworkEndpointSet(negtypes.NetworkEndpoint{IP: "1.2.3.3", Node: testInstance3}, negtypes.NetworkEndpoint{IP: "1.2.3.4", Node: testInstance4},
negtypes.NetworkEndpoint{IP: "1.2.3.5", Node: testInstance5}, negtypes.NetworkEndpoint{IP: "1.2.3.6", Node: testInstance6}),
},
networkEndpointType: negtypes.VmPrimaryIpEndpointType,
},
}
svcKey := fmt.Sprintf("%s/%s", testServiceName, testServiceNamespace)
ec := NewClusterL4ILBEndpointsCalculator(nodeLister, zoneGetter, svcKey)
for _, tc := range testCases {
retSet, _, err := ec.CalculateEndpoints(tc.endpoints, nil)
if err != nil {
t.Errorf("For case %q, expect nil error, but got %v.", tc.desc, err)
}
if !reflect.DeepEqual(retSet, tc.endpointSets) {
t.Errorf("For case %q, expecting endpoint set %v, but got %v.", tc.desc, tc.endpointSets, retSet)
}
}
}

// TestGetPerZoneSubsetCount verifies the perZoneSubsetCount method.
func TestGetPerZoneSubsetCount(t *testing.T) {
t.Parallel()
zoneCount := 3
result := 0
tcs := []struct {
desc string
randomize bool
startCount int
endCount int
expectedCount int
}{
{desc: "start with endpoints, drop to none", startCount: 5, endCount: 0, expectedCount: 0},
{desc: "no endpoints", startCount: 0, endCount: 0, expectedCount: 0},
{desc: "valid endpoints increase", startCount: 5, endCount: 10, expectedCount: 10 / zoneCount},
// If total number of nodes is less than the number of zones, per zone count will be 1.
{desc: "valid endpoints decrease", startCount: 5, endCount: 2, expectedCount: 1},
{desc: "valid endpoints > limit", startCount: 5, endCount: 258, expectedCount: maxSubsetSizeLocal / zoneCount},
{desc: "start with endpoints, drop to none, random true", randomize: true, startCount: 5, endCount: 0, expectedCount: maxSubsetSizeDefault / zoneCount},
{desc: "no endpoints, random true", randomize: true, startCount: 0, endCount: 0, expectedCount: maxSubsetSizeDefault / zoneCount},
{desc: "valid endpoints increase, random true", randomize: true, startCount: 5, endCount: 10, expectedCount: maxSubsetSizeDefault / zoneCount},
{desc: "valid endpoints decrease, random true", randomize: true, startCount: 5, endCount: 2, expectedCount: maxSubsetSizeDefault / zoneCount},
}
for _, tc := range tcs {
if tc.randomize {
result = NewClusterL4ILBEndpointsCalculator(nil, nil, "test").getPerZoneSubsetCount(zoneCount, tc.endCount)
} else {
result = NewLocalL4ILBEndpointsCalculator(nil, nil, "test").getPerZoneSubsetCount(zoneCount, tc.endCount)
}
if result != tc.expectedCount {
t.Errorf("For test case '%s', expected subsetCount of %d, but got %d", tc.desc, tc.expectedCount, result)
}
}
}
27 changes: 0 additions & 27 deletions pkg/neg/syncers/subsets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,33 +117,6 @@ func TestNoRemovals(t *testing.T) {
}
}

func TestGetSubsetCount(t *testing.T) {
t.Parallel()
zoneCount := 3
tcs := []struct {
desc string
randomize bool
startCount int
endCount int
expectedCount int
}{
{desc: "start with endpoints, drop to none", startCount: 5, endCount: 0, expectedCount: zoneCount},
{desc: "no endpoints", startCount: 0, endCount: 0, expectedCount: zoneCount},
{desc: "valid endpoints increase", startCount: 5, endCount: 10, expectedCount: 10},
{desc: "valid endpoints decrease", startCount: 5, endCount: 2, expectedCount: 2},
{desc: "start with endpoints, drop to none, random true", randomize: true, startCount: 5, endCount: 0, expectedCount: 5},
{desc: "no endpoints, random true", randomize: true, startCount: 0, endCount: 0, expectedCount: zoneCount},
{desc: "valid endpoints increase, random true", randomize: true, startCount: 5, endCount: 10, expectedCount: 10},
{desc: "valid endpoints decrease, random true", randomize: true, startCount: 5, endCount: 2, expectedCount: 5},
}
for _, tc := range tcs {
result := getSubsetCount(tc.startCount, tc.endCount, zoneCount, tc.randomize)
if result != tc.expectedCount {
t.Errorf("For test case '%s', expected subsetCount of %d, but got %d", tc.desc, tc.expectedCount, result)
}
}
}

func validateSubset(subset []*v1.Node, nodes []*v1.Node) bool {
for _, val := range subset {
found := false
Expand Down
2 changes: 2 additions & 0 deletions pkg/neg/syncers/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const (
testZone2 = "zone2"
testInstance3 = "instance3"
testInstance4 = "instance4"
testInstance5 = "instance5"
testInstance6 = "instance6"
testNamespace = "ns"
testService = "svc"
)
Expand Down
4 changes: 2 additions & 2 deletions pkg/neg/syncers/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
listers "k8s.io/client-go/listers/core/v1"
"k8s.io/ingress-gce/pkg/composite"
negtypes "k8s.io/ingress-gce/pkg/neg/types"
"k8s.io/legacy-cloud-providers/gce"
Expand Down Expand Up @@ -386,6 +385,7 @@ func TestEnsureNetworkEndpointGroup(t *testing.T) {
}
}

/*
func TestToZonePrimaryIPNetworkEndpointMapUtil(t *testing.T) {
t.Parallel()
// Syncer for externalTrafficPolicy: Local case
Expand Down Expand Up @@ -444,7 +444,7 @@ func TestToZonePrimaryIPNetworkEndpointMapUtil(t *testing.T) {
t.Errorf("For case %q, expecting endpoint set %v, but got %v.", tc.desc, tc.endpointSets, retSet)
}
}
}
}*/

func TestToZoneNetworkEndpointMapUtil(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion pkg/neg/types/fakes.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const (
TestInstance2 = "instance2"
TestInstance3 = "instance3"
TestInstance4 = "instance4"
TestInstance5 = "instance5"
TestInstance6 = "instance6"
)

type fakeZoneGetter struct {
Expand All @@ -44,7 +46,7 @@ func NewFakeZoneGetter() *fakeZoneGetter {
return &fakeZoneGetter{
zoneInstanceMap: map[string]sets.String{
TestZone1: sets.NewString(TestInstance1, TestInstance2),
TestZone2: sets.NewString(TestInstance3, TestInstance4),
TestZone2: sets.NewString(TestInstance3, TestInstance4, TestInstance5, TestInstance6),
},
}
}
Expand Down

0 comments on commit dee780b

Please sign in to comment.