mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-27 23:48:30 +00:00
client-go/tools/cache/reflector_data_consistency_detector: refactor unit tests
Kubernetes-commit: 18837d60ae12ac70380ce5cf21cfd8e0d221263a
This commit is contained in:
parent
0123e78ef6
commit
00036b79c4
@ -26,8 +26,6 @@ import (
|
|||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
|
||||||
"k8s.io/utils/ptr"
|
"k8s.io/utils/ptr"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,8 +33,8 @@ func TestDataConsistencyChecker(t *testing.T) {
|
|||||||
scenarios := []struct {
|
scenarios := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
||||||
podList *v1.PodList
|
listResponse *v1.PodList
|
||||||
storeContent []*v1.Pod
|
retrievedItems []*v1.Pod
|
||||||
requestOptions metav1.ListOptions
|
requestOptions metav1.ListOptions
|
||||||
|
|
||||||
expectedRequestOptions []metav1.ListOptions
|
expectedRequestOptions []metav1.ListOptions
|
||||||
@ -45,12 +43,12 @@ func TestDataConsistencyChecker(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "data consistency check won't panic when data is consistent",
|
name: "data consistency check won't panic when data is consistent",
|
||||||
podList: &v1.PodList{
|
listResponse: &v1.PodList{
|
||||||
ListMeta: metav1.ListMeta{ResourceVersion: "2"},
|
ListMeta: metav1.ListMeta{ResourceVersion: "2"},
|
||||||
Items: []v1.Pod{*makePod("p1", "1"), *makePod("p2", "2")},
|
Items: []v1.Pod{*makePod("p1", "1"), *makePod("p2", "2")},
|
||||||
},
|
},
|
||||||
requestOptions: metav1.ListOptions{TimeoutSeconds: ptr.To(int64(39))},
|
requestOptions: metav1.ListOptions{TimeoutSeconds: ptr.To(int64(39))},
|
||||||
storeContent: []*v1.Pod{makePod("p1", "1"), makePod("p2", "2")},
|
retrievedItems: []*v1.Pod{makePod("p1", "1"), makePod("p2", "2")},
|
||||||
expectedListRequests: 1,
|
expectedListRequests: 1,
|
||||||
expectedRequestOptions: []metav1.ListOptions{
|
expectedRequestOptions: []metav1.ListOptions{
|
||||||
{
|
{
|
||||||
@ -63,7 +61,7 @@ func TestDataConsistencyChecker(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
name: "data consistency check won't panic when there is no data",
|
name: "data consistency check won't panic when there is no data",
|
||||||
podList: &v1.PodList{
|
listResponse: &v1.PodList{
|
||||||
ListMeta: metav1.ListMeta{ResourceVersion: "2"},
|
ListMeta: metav1.ListMeta{ResourceVersion: "2"},
|
||||||
},
|
},
|
||||||
requestOptions: metav1.ListOptions{TimeoutSeconds: ptr.To(int64(39))},
|
requestOptions: metav1.ListOptions{TimeoutSeconds: ptr.To(int64(39))},
|
||||||
@ -79,12 +77,12 @@ func TestDataConsistencyChecker(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
name: "data consistency panics when data is inconsistent",
|
name: "data consistency panics when data is inconsistent",
|
||||||
podList: &v1.PodList{
|
listResponse: &v1.PodList{
|
||||||
ListMeta: metav1.ListMeta{ResourceVersion: "2"},
|
ListMeta: metav1.ListMeta{ResourceVersion: "2"},
|
||||||
Items: []v1.Pod{*makePod("p1", "1"), *makePod("p2", "2"), *makePod("p3", "3")},
|
Items: []v1.Pod{*makePod("p1", "1"), *makePod("p2", "2"), *makePod("p3", "3")},
|
||||||
},
|
},
|
||||||
requestOptions: metav1.ListOptions{TimeoutSeconds: ptr.To(int64(39))},
|
requestOptions: metav1.ListOptions{TimeoutSeconds: ptr.To(int64(39))},
|
||||||
storeContent: []*v1.Pod{makePod("p1", "1"), makePod("p2", "2")},
|
retrievedItems: []*v1.Pod{makePod("p1", "1"), makePod("p2", "2")},
|
||||||
expectedListRequests: 1,
|
expectedListRequests: 1,
|
||||||
expectedRequestOptions: []metav1.ListOptions{
|
expectedRequestOptions: []metav1.ListOptions{
|
||||||
{
|
{
|
||||||
@ -99,23 +97,22 @@ func TestDataConsistencyChecker(t *testing.T) {
|
|||||||
|
|
||||||
for _, scenario := range scenarios {
|
for _, scenario := range scenarios {
|
||||||
t.Run(scenario.name, func(t *testing.T) {
|
t.Run(scenario.name, func(t *testing.T) {
|
||||||
listWatcher, store, _, stopCh := testData()
|
ctx := context.TODO()
|
||||||
ctx := wait.ContextForChannel(stopCh)
|
fakeLister := &listWrapper{response: scenario.listResponse}
|
||||||
for _, obj := range scenario.storeContent {
|
retrievedItemsFunc := func() []*v1.Pod {
|
||||||
require.NoError(t, store.Add(obj))
|
return scenario.retrievedItems
|
||||||
}
|
}
|
||||||
listWatcher.customListResponse = scenario.podList
|
|
||||||
|
|
||||||
if scenario.expectPanic {
|
if scenario.expectPanic {
|
||||||
require.Panics(t, func() {
|
require.Panics(t, func() {
|
||||||
checkDataConsistency(ctx, "", scenario.podList.ResourceVersion, wrapListFuncWithContext(listWatcher.List), scenario.requestOptions, store.List)
|
checkDataConsistency(ctx, "", scenario.listResponse.ResourceVersion, fakeLister.List, scenario.requestOptions, retrievedItemsFunc)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
checkDataConsistency(ctx, "", scenario.podList.ResourceVersion, wrapListFuncWithContext(listWatcher.List), scenario.requestOptions, store.List)
|
checkDataConsistency(ctx, "", scenario.listResponse.ResourceVersion, fakeLister.List, scenario.requestOptions, retrievedItemsFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyListCounter(t, listWatcher, scenario.expectedListRequests)
|
require.Equal(t, fakeLister.counter, scenario.expectedListRequests)
|
||||||
verifyRequestOptions(t, listWatcher, scenario.expectedRequestOptions)
|
require.Equal(t, fakeLister.requestOptions, scenario.expectedRequestOptions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,14 +123,15 @@ func TestDriveWatchLisConsistencyIfRequired(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDataConsistencyCheckerRetry(t *testing.T) {
|
func TestDataConsistencyCheckerRetry(t *testing.T) {
|
||||||
store := NewStore(MetaNamespaceKeyFunc)
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
retrievedItemsFunc := func() []*v1.Pod {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
stopListErrorAfter := 5
|
stopListErrorAfter := 5
|
||||||
errLister := &errorLister{stopErrorAfter: stopListErrorAfter}
|
fakeErrLister := &errorLister{stopErrorAfter: stopListErrorAfter}
|
||||||
|
|
||||||
checkDataConsistency(ctx, "", "", wrapListFuncWithContext(errLister.List), metav1.ListOptions{}, store.List)
|
checkDataConsistency(ctx, "", "", fakeErrLister.List, metav1.ListOptions{}, retrievedItemsFunc)
|
||||||
require.Equal(t, errLister.listCounter, errLister.stopErrorAfter)
|
require.Equal(t, fakeErrLister.listCounter, fakeErrLister.stopErrorAfter)
|
||||||
}
|
}
|
||||||
|
|
||||||
type errorLister struct {
|
type errorLister struct {
|
||||||
@ -141,7 +139,7 @@ type errorLister struct {
|
|||||||
stopErrorAfter int
|
stopErrorAfter int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lw *errorLister) List(_ metav1.ListOptions) (runtime.Object, error) {
|
func (lw *errorLister) List(_ context.Context, _ metav1.ListOptions) (runtime.Object, error) {
|
||||||
lw.listCounter++
|
lw.listCounter++
|
||||||
if lw.listCounter == lw.stopErrorAfter {
|
if lw.listCounter == lw.stopErrorAfter {
|
||||||
return &v1.PodList{}, nil
|
return &v1.PodList{}, nil
|
||||||
@ -149,6 +147,14 @@ func (lw *errorLister) List(_ metav1.ListOptions) (runtime.Object, error) {
|
|||||||
return nil, fmt.Errorf("nasty error")
|
return nil, fmt.Errorf("nasty error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lw *errorLister) Watch(_ metav1.ListOptions) (watch.Interface, error) {
|
type listWrapper struct {
|
||||||
panic("not implemented")
|
counter int
|
||||||
|
requestOptions []metav1.ListOptions
|
||||||
|
response *v1.PodList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lw *listWrapper) List(_ context.Context, opts metav1.ListOptions) (*v1.PodList, error) {
|
||||||
|
lw.counter++
|
||||||
|
lw.requestOptions = append(lw.requestOptions, opts)
|
||||||
|
return lw.response, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user