Add more Endpoints vs EndpointsSlices reconciler tests

This commit is contained in:
Dan Winship 2022-01-28 16:44:05 -05:00
parent 07de59ab60
commit 80e9d948e3
3 changed files with 188 additions and 10 deletions

View File

@ -32,7 +32,7 @@ import (
) )
func TestEndpointsAdapterGet(t *testing.T) { func TestEndpointsAdapterGet(t *testing.T) {
endpoints1, _ := generateEndpointsAndSlice("foo", "testing", []int{80, 443}, []string{"10.1.2.3", "10.1.2.4"}) endpoints1, epSlice1 := generateEndpointsAndSlice("foo", "testing", []int{80, 443}, []string{"10.1.2.3", "10.1.2.4"})
testCases := map[string]struct { testCases := map[string]struct {
expectedError error expectedError error
@ -42,23 +42,37 @@ func TestEndpointsAdapterGet(t *testing.T) {
nameParam string nameParam string
}{ }{
"single-existing-endpoints": { "single-existing-endpoints": {
expectedError: nil,
expectedEndpoints: endpoints1,
initialState: []runtime.Object{endpoints1, epSlice1},
namespaceParam: "testing",
nameParam: "foo",
},
"endpoints exists, endpointslice does not": {
expectedError: nil, expectedError: nil,
expectedEndpoints: endpoints1, expectedEndpoints: endpoints1,
initialState: []runtime.Object{endpoints1}, initialState: []runtime.Object{endpoints1},
namespaceParam: "testing", namespaceParam: "testing",
nameParam: "foo", nameParam: "foo",
}, },
"endpointslice exists, endpoints does not": {
expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "foo"),
expectedEndpoints: nil,
initialState: []runtime.Object{epSlice1},
namespaceParam: "testing",
nameParam: "foo",
},
"wrong-namespace": { "wrong-namespace": {
expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "foo"), expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "foo"),
expectedEndpoints: nil, expectedEndpoints: nil,
initialState: []runtime.Object{endpoints1}, initialState: []runtime.Object{endpoints1, epSlice1},
namespaceParam: "foo", namespaceParam: "foo",
nameParam: "foo", nameParam: "foo",
}, },
"wrong-name": { "wrong-name": {
expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "bar"), expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "bar"),
expectedEndpoints: nil, expectedEndpoints: nil,
initialState: []runtime.Object{endpoints1}, initialState: []runtime.Object{endpoints1, epSlice1},
namespaceParam: "testing", namespaceParam: "testing",
nameParam: "bar", nameParam: "bar",
}, },
@ -128,7 +142,7 @@ func TestEndpointsAdapterCreate(t *testing.T) {
namespaceParam: endpoints3.Namespace, namespaceParam: endpoints3.Namespace,
endpointsParam: endpoints3, endpointsParam: endpoints3,
}, },
"existing-endpoint": { "existing-endpoints": {
expectedError: errors.NewAlreadyExists(schema.GroupResource{Group: "", Resource: "endpoints"}, "foo"), expectedError: errors.NewAlreadyExists(schema.GroupResource{Group: "", Resource: "endpoints"}, "foo"),
expectedResult: nil, expectedResult: nil,
initialState: []runtime.Object{endpoints1, epSlice1}, initialState: []runtime.Object{endpoints1, epSlice1},
@ -138,6 +152,27 @@ func TestEndpointsAdapterCreate(t *testing.T) {
// We expect the create to be attempted, we just also expect it to fail // We expect the create to be attempted, we just also expect it to fail
expectCreate: []runtime.Object{endpoints1}, expectCreate: []runtime.Object{endpoints1},
}, },
"existing-endpointslice-incorrect": {
// No error when we need to create the Endpoints but the correct
// EndpointSlice already exists
expectedError: nil,
expectedResult: endpoints1,
expectCreate: []runtime.Object{endpoints1},
initialState: []runtime.Object{epSlice1},
namespaceParam: endpoints1.Namespace,
endpointsParam: endpoints1,
},
"existing-endpointslice-correct": {
// No error when we need to create the Endpoints but an incorrect
// EndpointSlice already exists
expectedError: nil,
expectedResult: endpoints2,
expectCreate: []runtime.Object{endpoints2},
expectUpdate: []runtime.Object{epSlice2},
initialState: []runtime.Object{epSlice1},
namespaceParam: endpoints2.Namespace,
endpointsParam: endpoints2,
},
} }
for name, testCase := range testCases { for name, testCase := range testCases {
@ -155,7 +190,7 @@ func TestEndpointsAdapterCreate(t *testing.T) {
t.Errorf("Expected endpoints: %v, got: %v", testCase.expectedResult, endpoints) t.Errorf("Expected endpoints: %v, got: %v", testCase.expectedResult, endpoints)
} }
err = verifyCreatesAndUpdates(client, testCase.expectCreate, nil) err = verifyCreatesAndUpdates(client, testCase.expectCreate, testCase.expectUpdate)
if err != nil { if err != nil {
t.Errorf("unexpected error in side effects: %v", err) t.Errorf("unexpected error in side effects: %v", err)
} }
@ -216,6 +251,30 @@ func TestEndpointsAdapterUpdate(t *testing.T) {
namespaceParam: "testing", namespaceParam: "testing",
endpointsParam: endpoints2, endpointsParam: endpoints2,
}, },
"endpoints-correct-endpointslice-wrong": {
expectedError: nil,
expectedResult: endpoints2,
expectUpdate: []runtime.Object{endpoints2, epSlice2},
initialState: []runtime.Object{endpoints2, epSlice1},
namespaceParam: "testing",
endpointsParam: endpoints2,
},
"endpointslice-correct-endpoints-wrong": {
expectedError: nil,
expectedResult: endpoints2,
expectUpdate: []runtime.Object{endpoints2},
initialState: []runtime.Object{endpoints1, epSlice2},
namespaceParam: "testing",
endpointsParam: endpoints2,
},
"wrong-endpoints": {
expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "bar"),
expectedResult: nil,
expectUpdate: []runtime.Object{endpoints3},
initialState: []runtime.Object{endpoints1, epSlice1},
namespaceParam: "testing",
endpointsParam: endpoints3,
},
"missing-endpoints": { "missing-endpoints": {
expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "bar"), expectedError: errors.NewNotFound(schema.GroupResource{Group: "", Resource: "endpoints"}, "bar"),
expectedResult: nil, expectedResult: nil,
@ -226,6 +285,17 @@ func TestEndpointsAdapterUpdate(t *testing.T) {
// We expect the update to be attempted, we just also expect it to fail // We expect the update to be attempted, we just also expect it to fail
expectUpdate: []runtime.Object{endpoints3}, expectUpdate: []runtime.Object{endpoints3},
}, },
"missing-endpointslice": {
// No error when we need to update the Endpoints but the
// EndpointSlice doesn't exist
expectedError: nil,
expectedResult: endpoints1,
expectUpdate: []runtime.Object{endpoints1},
expectCreate: []runtime.Object{epSlice1},
initialState: []runtime.Object{endpoints2},
namespaceParam: "testing",
endpointsParam: endpoints1,
},
} }
for name, testCase := range testCases { for name, testCase := range testCases {
@ -252,10 +322,12 @@ func TestEndpointsAdapterUpdate(t *testing.T) {
} }
func generateEndpointsAndSlice(name, namespace string, ports []int, addresses []string) (*corev1.Endpoints, *discovery.EndpointSlice) { func generateEndpointsAndSlice(name, namespace string, ports []int, addresses []string) (*corev1.Endpoints, *discovery.EndpointSlice) {
objectMeta := metav1.ObjectMeta{Name: name, Namespace: namespace}
trueBool := true trueBool := true
epSlice := &discovery.EndpointSlice{ObjectMeta: objectMeta, AddressType: discovery.AddressTypeIPv4} epSlice := &discovery.EndpointSlice{
ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace},
AddressType: discovery.AddressTypeIPv4,
}
epSlice.Labels = map[string]string{discovery.LabelServiceName: name} epSlice.Labels = map[string]string{discovery.LabelServiceName: name}
subset := corev1.EndpointSubset{} subset := corev1.EndpointSubset{}
@ -292,12 +364,18 @@ func generateEndpointsAndSlice(name, namespace string, ports []int, addresses []
} }
return &corev1.Endpoints{ return &corev1.Endpoints{
ObjectMeta: objectMeta, ObjectMeta: metav1.ObjectMeta{
Subsets: []corev1.EndpointSubset{subset}, Name: name,
Namespace: namespace,
Labels: map[string]string{
discovery.LabelSkipMirror: "true",
},
},
Subsets: []corev1.EndpointSubset{subset},
}, epSlice }, epSlice
} }
func TestEndpointsAdapterEnsureEndpointSliceFromEndpoints(t *testing.T) { func TestEndpointManagerEnsureEndpointSliceFromEndpoints(t *testing.T) {
endpoints1, epSlice1 := generateEndpointsAndSlice("foo", "testing", []int{80, 443}, []string{"10.1.2.3", "10.1.2.4"}) endpoints1, epSlice1 := generateEndpointsAndSlice("foo", "testing", []int{80, 443}, []string{"10.1.2.3", "10.1.2.4"})
endpoints2, epSlice2 := generateEndpointsAndSlice("foo", "testing", []int{80, 443}, []string{"10.1.2.3", "10.1.2.4", "10.1.2.5"}) endpoints2, epSlice2 := generateEndpointsAndSlice("foo", "testing", []int{80, 443}, []string{"10.1.2.3", "10.1.2.4", "10.1.2.5"})

View File

@ -51,6 +51,56 @@ func TestMasterCountEndpointReconciler(t *testing.T) {
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: makeEndpointsArray("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}), initialState: makeEndpointsArray("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
}, },
{
testName: "existing endpoints satisfy, no endpointslice",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectCreate: []runtime.Object{
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{
testName: "existing endpointslice satisfies, no endpoints",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectCreate: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{
testName: "existing endpoints satisfy, endpointslice is wrong",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
makeEndpointSlice("foo", []string{"4.3.2.1"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectUpdate: []runtime.Object{
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{
testName: "existing endpointslice satisfies, endpoints is wrong",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpoints("foo", []string{"4.3.2.1"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectUpdate: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{ {
testName: "existing endpoints satisfy but too many", testName: "existing endpoints satisfy but too many",
serviceName: "foo", serviceName: "foo",

View File

@ -104,6 +104,56 @@ func TestLeaseEndpointReconciler(t *testing.T) {
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: makeEndpointsArray("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}), initialState: makeEndpointsArray("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
}, },
{
testName: "existing endpoints satisfy, no endpointslice",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectCreate: []runtime.Object{
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{
testName: "existing endpointslice satisfies, no endpoints",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectCreate: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{
testName: "existing endpoints satisfy, endpointslice is wrong",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
makeEndpointSlice("foo", []string{"4.3.2.1"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectUpdate: []runtime.Object{
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{
testName: "existing endpointslice satisfies, endpoints is wrong",
serviceName: "foo",
ip: "1.2.3.4",
endpointPorts: []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
initialState: []runtime.Object{
makeEndpoints("foo", []string{"4.3.2.1"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
makeEndpointSlice("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
expectUpdate: []runtime.Object{
makeEndpoints("foo", []string{"1.2.3.4"}, []corev1.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}}),
},
},
{ {
testName: "existing endpoints satisfy + refresh existing key", testName: "existing endpoints satisfy + refresh existing key",
serviceName: "foo", serviceName: "foo",