apiserver/storage: decrease running time of RunWatchSemantics

This commit is contained in:
Lukasz Szaszkiewicz 2024-06-26 10:49:20 +02:00
parent e07314860c
commit c6ef512b5b

View File

@ -28,6 +28,7 @@ import (
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
@ -1236,6 +1237,7 @@ func RunSendInitialEventsBackwardCompatibility(ctx context.Context, t *testing.T
// - false indicates the value of the param was set to "false" by a test case // - false indicates the value of the param was set to "false" by a test case
// - true indicates the value of the param was set to "true" by a test case // - true indicates the value of the param was set to "true" by a test case
func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interface) { func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interface) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WatchList, true)
trueVal, falseVal := true, false trueVal, falseVal := true, false
addEventsFromCreatedPods := func(createdInitialPods []*example.Pod) []watch.Event { addEventsFromCreatedPods := func(createdInitialPods []*example.Pod) []watch.Event {
var ret []watch.Event var ret []watch.Event
@ -1244,8 +1246,8 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
} }
return ret return ret
} }
initialEventsEndFromLastCreatedPod := func(createdInitialPods []*example.Pod) []watch.Event { initialEventsEndFromLastCreatedPod := func(createdInitialPods []*example.Pod) watch.Event {
return []watch.Event{{ return watch.Event{
Type: watch.Bookmark, Type: watch.Bookmark,
Object: &example.Pod{ Object: &example.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -1253,7 +1255,7 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
Annotations: map[string]string{metav1.InitialEventsAnnotationKey: "true"}, Annotations: map[string]string{metav1.InitialEventsAnnotationKey: "true"},
}, },
}, },
}} }
} }
scenarios := []struct { scenarios := []struct {
name string name string
@ -1267,19 +1269,19 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
initialPods []*example.Pod initialPods []*example.Pod
podsAfterEstablishingWatch []*example.Pod podsAfterEstablishingWatch []*example.Pod
expectedInitialEvents func(createdInitialPods []*example.Pod) []watch.Event expectedInitialEvents func(createdInitialPods []*example.Pod) []watch.Event
expectedInitialEventsBookmark func(createdInitialPods []*example.Pod) []watch.Event expectedInitialEventsBookmarkWithMinimalRV func(createdInitialPods []*example.Pod) watch.Event
expectedEventsAfterEstablishingWatch func(createdPodsAfterWatch []*example.Pod) []watch.Event expectedEventsAfterEstablishingWatch func(createdPodsAfterWatch []*example.Pod) []watch.Event
}{ }{
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=unset", name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=unset",
allowWatchBookmarks: true, allowWatchBookmarks: true,
sendInitialEvents: &trueVal, sendInitialEvents: &trueVal,
initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")}, initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")},
expectedInitialEvents: addEventsFromCreatedPods, expectedInitialEvents: addEventsFromCreatedPods,
expectedInitialEventsBookmark: initialEventsEndFromLastCreatedPod, expectedInitialEventsBookmarkWithMinimalRV: initialEventsEndFromLastCreatedPod,
podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")}, podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")},
expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods, expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods,
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=unset", name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=unset",
@ -1306,15 +1308,15 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=0", name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=0",
allowWatchBookmarks: true, allowWatchBookmarks: true,
sendInitialEvents: &trueVal, sendInitialEvents: &trueVal,
resourceVersion: "0", resourceVersion: "0",
initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")}, initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")},
expectedInitialEvents: addEventsFromCreatedPods, expectedInitialEvents: addEventsFromCreatedPods,
expectedInitialEventsBookmark: initialEventsEndFromLastCreatedPod, expectedInitialEventsBookmarkWithMinimalRV: initialEventsEndFromLastCreatedPod,
podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")}, podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")},
expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods, expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods,
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=0", name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=0",
@ -1344,15 +1346,15 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=1", name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=1",
allowWatchBookmarks: true, allowWatchBookmarks: true,
sendInitialEvents: &trueVal, sendInitialEvents: &trueVal,
resourceVersion: "1", resourceVersion: "1",
initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")}, initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")},
expectedInitialEvents: addEventsFromCreatedPods, expectedInitialEvents: addEventsFromCreatedPods,
expectedInitialEventsBookmark: initialEventsEndFromLastCreatedPod, expectedInitialEventsBookmarkWithMinimalRV: initialEventsEndFromLastCreatedPod,
podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")}, podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")},
expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods, expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods,
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=1", name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=1",
@ -1384,15 +1386,15 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=useCurrentRV", name: "allowWatchBookmarks=true, sendInitialEvents=true, RV=useCurrentRV",
allowWatchBookmarks: true, allowWatchBookmarks: true,
sendInitialEvents: &trueVal, sendInitialEvents: &trueVal,
useCurrentRV: true, useCurrentRV: true,
initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")}, initialPods: []*example.Pod{makePod("1"), makePod("2"), makePod("3")},
expectedInitialEvents: addEventsFromCreatedPods, expectedInitialEvents: addEventsFromCreatedPods,
expectedInitialEventsBookmark: initialEventsEndFromLastCreatedPod, expectedInitialEventsBookmarkWithMinimalRV: initialEventsEndFromLastCreatedPod,
podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")}, podsAfterEstablishingWatch: []*example.Pod{makePod("4"), makePod("5")},
expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods, expectedEventsAfterEstablishingWatch: addEventsFromCreatedPods,
}, },
{ {
name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=useCurrentRV", name: "allowWatchBookmarks=true, sendInitialEvents=false, RV=useCurrentRV",
@ -1439,14 +1441,11 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
} }
for idx, scenario := range scenarios { for idx, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) { t.Run(scenario.name, func(t *testing.T) {
t.Parallel()
// set up env // set up env
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WatchList, true)
if scenario.expectedInitialEvents == nil { if scenario.expectedInitialEvents == nil {
scenario.expectedInitialEvents = func(_ []*example.Pod) []watch.Event { return nil } scenario.expectedInitialEvents = func(_ []*example.Pod) []watch.Event { return nil }
} }
if scenario.expectedInitialEventsBookmark == nil {
scenario.expectedInitialEventsBookmark = func(_ []*example.Pod) []watch.Event { return nil }
}
if scenario.expectedEventsAfterEstablishingWatch == nil { if scenario.expectedEventsAfterEstablishingWatch == nil {
scenario.expectedEventsAfterEstablishingWatch = func(_ []*example.Pod) []watch.Event { return nil } scenario.expectedEventsAfterEstablishingWatch = func(_ []*example.Pod) []watch.Event { return nil }
} }
@ -1480,7 +1479,25 @@ func RunWatchSemantics(ctx context.Context, t *testing.T, store storage.Interfac
// make sure we only get initial events // make sure we only get initial events
testCheckResultsInStrictOrder(t, w, scenario.expectedInitialEvents(createdPods)) testCheckResultsInStrictOrder(t, w, scenario.expectedInitialEvents(createdPods))
testCheckResultsInStrictOrder(t, w, scenario.expectedInitialEventsBookmark(createdPods))
// make sure that the actual bookmark has at least RV >= to the expected one
if scenario.expectedInitialEventsBookmarkWithMinimalRV != nil {
testCheckResultFunc(t, w, func(actualEvent watch.Event) {
expectedBookmarkEventWithMinRV := scenario.expectedInitialEventsBookmarkWithMinimalRV(createdPods)
expectedObj, err := meta.Accessor(expectedBookmarkEventWithMinRV.Object)
require.NoError(t, err)
actualObj, err := meta.Accessor(actualEvent.Object)
require.NoError(t, err)
require.GreaterOrEqual(t, actualObj.GetResourceVersion(), expectedObj.GetResourceVersion())
// once we know that the RV is at least >= the expected one
// rewrite it so that we can compare the objs
expectedObj.SetResourceVersion(actualObj.GetResourceVersion())
expectNoDiff(t, "incorrect event", expectedBookmarkEventWithMinRV, actualEvent)
})
}
createdPods = []*example.Pod{} createdPods = []*example.Pod{}
// add a pod that is greater than the storage's RV when the watch was started // add a pod that is greater than the storage's RV when the watch was started