From d781784c44c49b32f349218d252be01b30d92c8b Mon Sep 17 00:00:00 2001 From: aavarghese Date: Fri, 15 Oct 2021 11:00:53 -0400 Subject: [PATCH] Moving Placeable type and new Scheduler to eventing core Signed-off-by: aavarghese --- pkg/apis/sources/v1beta1/kafka_scheduling.go | 2 +- .../sources/v1beta1/kafka_scheduling_test.go | 2 +- pkg/apis/sources/v1beta1/kafka_types.go | 2 +- pkg/common/constants/constants.go | 4 - pkg/common/scheduler/OWNERS | 3 - pkg/common/scheduler/placement_test.go | 156 --- .../availability_node_priority_test.go | 228 ----- .../availability_zone_priority_test.go | 231 ----- .../evenpodspread/even_pod_spread_test.go | 198 ---- .../lowest_ordinal_priority_test.go | 114 --- .../pod_fits_resources_test.go | 96 -- ...ve_with_availability_node_priority_test.go | 231 ----- ...ve_with_availability_zone_priority_test.go | 231 ----- ...move_with_even_pod_spread_priority_test.go | 166 ---- ...move_with_highest_ordinal_priority_test.go | 113 --- .../no_max_resource_count_test.go | 146 --- pkg/common/scheduler/state/interface_test.go | 87 -- pkg/common/scheduler/state/state_test.go | 541 ----------- .../scheduler/statefulset/autoscaler_test.go | 893 ------------------ .../scheduler/statefulset/scheduler_test.go | 745 --------------- pkg/common/scheduler/testing/client.go | 53 -- pkg/common/scheduler/testing/store.go | 42 - pkg/common/scheduler/testing/vpod.go | 219 ----- pkg/source/mtadapter/adapter.go | 2 +- pkg/source/mtadapter/adapter_test.go | 2 +- pkg/source/reconciler/mtsource/controller.go | 9 +- pkg/source/reconciler/mtsource/kafkasource.go | 2 +- .../eventing/pkg}/apis/duck/v1alpha1/doc.go | 0 .../apis/duck/v1alpha1/placement_types.go | 0 .../pkg}/apis/duck/v1alpha1/register.go | 0 .../duck/v1alpha1/zz_generated.deepcopy.go | 0 .../eventing/pkg}/scheduler/README.md | 0 .../eventing/pkg}/scheduler/doc.go | 0 .../pkg}/scheduler/factory/registry.go | 2 +- .../eventing/pkg}/scheduler/placement.go | 2 +- .../availability_node_priority.go | 4 +- .../availability_zone_priority.go | 4 +- .../core/evenpodspread/even_pod_spread.go | 4 +- .../lowest_ordinal_priority.go | 4 +- .../podfitsresources/pod_fits_resources.go | 4 +- .../remove_with_availability_node_priority.go | 4 +- .../remove_with_availability_zone_priority.go | 4 +- .../remove_with_even_pod_spread_priority.go | 4 +- .../remove_with_highest_ordinal_priority.go | 4 +- .../no_max_resource_count.go | 4 +- .../eventing/pkg}/scheduler/scheduler.go | 6 +- .../eventing/pkg}/scheduler/state/helpers.go | 3 +- .../pkg}/scheduler/state/interface.go | 0 .../eventing/pkg}/scheduler/state/state.go | 5 +- .../pkg}/scheduler/statefulset/autoscaler.go | 4 +- .../pkg}/scheduler/statefulset/scheduler.go | 39 +- .../apps/v1/statefulset/fake/fake.go | 40 - vendor/modules.txt | 16 +- 53 files changed, 80 insertions(+), 4595 deletions(-) delete mode 100644 pkg/common/scheduler/OWNERS delete mode 100644 pkg/common/scheduler/placement_test.go delete mode 100644 pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread_test.go delete mode 100644 pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources_test.go delete mode 100644 pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority_test.go delete mode 100644 pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count_test.go delete mode 100644 pkg/common/scheduler/state/interface_test.go delete mode 100644 pkg/common/scheduler/state/state_test.go delete mode 100644 pkg/common/scheduler/statefulset/autoscaler_test.go delete mode 100644 pkg/common/scheduler/statefulset/scheduler_test.go delete mode 100644 pkg/common/scheduler/testing/client.go delete mode 100644 pkg/common/scheduler/testing/store.go delete mode 100644 pkg/common/scheduler/testing/vpod.go rename {pkg => vendor/knative.dev/eventing/pkg}/apis/duck/v1alpha1/doc.go (100%) rename {pkg => vendor/knative.dev/eventing/pkg}/apis/duck/v1alpha1/placement_types.go (100%) rename {pkg => vendor/knative.dev/eventing/pkg}/apis/duck/v1alpha1/register.go (100%) rename {pkg => vendor/knative.dev/eventing/pkg}/apis/duck/v1alpha1/zz_generated.deepcopy.go (100%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/README.md (100%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/doc.go (100%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/factory/registry.go (97%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/placement.go (95%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go (97%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go (97%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/evenpodspread/even_pod_spread.go (97%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go (93%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/podfitsresources/pod_fits_resources.go (93%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go (96%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go (97%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go (96%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go (94%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go (95%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/scheduler.go (92%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/state/helpers.go (97%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/state/interface.go (100%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/state/state.go (98%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/statefulset/autoscaler.go (98%) rename {pkg/common => vendor/knative.dev/eventing/pkg}/scheduler/statefulset/scheduler.go (95%) delete mode 100644 vendor/knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake/fake.go diff --git a/pkg/apis/sources/v1beta1/kafka_scheduling.go b/pkg/apis/sources/v1beta1/kafka_scheduling.go index 404b1a90b9..8dfdf606d0 100644 --- a/pkg/apis/sources/v1beta1/kafka_scheduling.go +++ b/pkg/apis/sources/v1beta1/kafka_scheduling.go @@ -18,7 +18,7 @@ package v1beta1 import ( "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" + "knative.dev/eventing/pkg/apis/duck/v1alpha1" ) func (k *KafkaSource) GetKey() types.NamespacedName { diff --git a/pkg/apis/sources/v1beta1/kafka_scheduling_test.go b/pkg/apis/sources/v1beta1/kafka_scheduling_test.go index 9892b59b44..d224a27a9f 100644 --- a/pkg/apis/sources/v1beta1/kafka_scheduling_test.go +++ b/pkg/apis/sources/v1beta1/kafka_scheduling_test.go @@ -23,7 +23,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/pointer" - "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" + "knative.dev/eventing/pkg/apis/duck/v1alpha1" ) func TestScheduling(t *testing.T) { diff --git a/pkg/apis/sources/v1beta1/kafka_types.go b/pkg/apis/sources/v1beta1/kafka_types.go index 058095df90..7c50e50b60 100644 --- a/pkg/apis/sources/v1beta1/kafka_types.go +++ b/pkg/apis/sources/v1beta1/kafka_types.go @@ -19,7 +19,7 @@ package v1beta1 import ( "fmt" - "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" + "knative.dev/eventing/pkg/apis/duck/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index c6349e9e97..615679d8b5 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -73,8 +73,4 @@ const ( // KafkaTopicConfigRetentionMs is the key in the Sarama TopicDetail ConfigEntries map for retention time (in ms) KafkaTopicConfigRetentionMs = "retention.ms" - - // PodAnnotationKey is an annotation used by the scheduler to be informed of pods - // being evicted and not use it for placing vreplicas - PodAnnotationKey = "eventing.knative.dev/unschedulable" ) diff --git a/pkg/common/scheduler/OWNERS b/pkg/common/scheduler/OWNERS deleted file mode 100644 index 671657b792..0000000000 --- a/pkg/common/scheduler/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -approvers: -- eventing-kafka-mtsource-approvers - diff --git a/pkg/common/scheduler/placement_test.go b/pkg/common/scheduler/placement_test.go deleted file mode 100644 index 9534b13e39..0000000000 --- a/pkg/common/scheduler/placement_test.go +++ /dev/null @@ -1,156 +0,0 @@ -/* -Copyright 2020 The Knative 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 scheduler - -import ( - "testing" - - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" -) - -func TestGetTotalVReplicas(t *testing.T) { - testCases := []struct { - name string - placements []duckv1alpha1.Placement - vreplicas int - }{ - { - name: "nil placements", - placements: nil, - vreplicas: 0, - }, - { - name: "empty placements", - placements: []duckv1alpha1.Placement{}, - vreplicas: 0, - }, - { - name: "one placement", - placements: []duckv1alpha1.Placement{{PodName: "d", VReplicas: 2}}, - vreplicas: 2, - }, - { - name: "many placements", - placements: []duckv1alpha1.Placement{ - {PodName: "d", VReplicas: 2}, - {PodName: "d", VReplicas: 6}, - {PodName: "d", VReplicas: 0}}, - vreplicas: 8, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - vreplicas := GetTotalVReplicas(tc.placements) - if vreplicas != int32(tc.vreplicas) { - t.Errorf("got %d, want %d", vreplicas, tc.vreplicas) - } - }) - } -} - -func TestGetPlacementForPod(t *testing.T) { - ps1 := []duckv1alpha1.Placement{{PodName: "p", VReplicas: 2}} - ps2 := []duckv1alpha1.Placement{{PodName: "p", VReplicas: 2}, {PodName: "p2", VReplicas: 4}} - testCases := []struct { - name string - podName string - placements []duckv1alpha1.Placement - expected *duckv1alpha1.Placement - }{ - { - name: "nil placements", - podName: "p", - placements: nil, - expected: nil, - }, - { - name: "empty placements", - podName: "p", - placements: []duckv1alpha1.Placement{}, - expected: nil, - }, - { - name: "one placement", - placements: ps1, - podName: "p", - expected: &ps1[0], - }, { - name: "mayne placements", - placements: ps2, - podName: "p2", - expected: &ps2[1], - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got := GetPlacementForPod(tc.placements, tc.podName) - if got != tc.expected { - t.Errorf("got %v, want %v", got, tc.expected) - } - }) - } -} -func TestPodCount(t *testing.T) { - testCases := []struct { - name string - placements []duckv1alpha1.Placement - expected int - }{ - { - name: "nil placements", - placements: nil, - expected: 0, - }, - { - name: "empty placements", - placements: []duckv1alpha1.Placement{}, - expected: 0, - }, - { - name: "one pod", - placements: []duckv1alpha1.Placement{{PodName: "d", VReplicas: 2}}, - expected: 1, - }, - { - name: "two pods", - placements: []duckv1alpha1.Placement{ - {PodName: "p1", VReplicas: 2}, - {PodName: "p2", VReplicas: 6}, - {PodName: "p1", VReplicas: 6}}, - expected: 2, - }, - { - name: "three pods, one with no vreplicas", - placements: []duckv1alpha1.Placement{ - {PodName: "p1", VReplicas: 2}, - {PodName: "p2", VReplicas: 6}, - {PodName: "p1", VReplicas: 0}}, - expected: 2, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got := GetPodCount(tc.placements) - if got != tc.expected { - t.Errorf("got %v, want %v", got, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority_test.go b/pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority_test.go deleted file mode 100644 index b4b84d80df..0000000000 --- a/pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority_test.go +++ /dev/null @@ -1,228 +0,0 @@ -/* -Copyright 2021 The Knative 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 availabilitynodepriority - -import ( - "fmt" - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" - listers "knative.dev/eventing/pkg/reconciler/testing/v1" - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" -) - -const ( - testNs = "test-ns" - sfsName = "statefulset-name" - vpodName = "source-name" - vpodNamespace = "source-namespace" - numNodes = 3 -) - -func TestScore(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - replicas int32 - podID int32 - expected *state.Status - expScore uint64 - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - NodeSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - expScore: 0, - args: "{\"MaxSkewness\": 2}", - }, - { - name: "no vpods, no pods, no resource", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 1, - expected: state.NewStatus(state.Error, ErrReasonNoResource), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, one zone, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 12, - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, one zone, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNamespace + "-1"}: { - "node1": 4, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 12, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, two zones, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 2, NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - "node1": 5, - "node2": 3, - }, - }}, - replicas: 2, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 4, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, three zones, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 3, NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - "node1": 4, - "node2": 3, - }, - }}, - replicas: 3, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 2, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 5, NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 8, - "node1": 4, - "node2": 3, - }, - }}, - replicas: 5, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 11, - args: "{\"MaxSkew\": 2}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &AvailabilityNodePriority{} - - name := plugin.Name() - assert.Equal(t, name, state.AvailabilityNodePriority) - - nodelist := make([]*v1.Node, 0) - podlist := make([]runtime.Object, 0) - - for i := int32(0); i < numNodes; i++ { - nodeName := "node" + fmt.Sprint(i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - nodeToZoneMap := make(map[string]string) - for i := 0; i < len(nodelist); i++ { - node := nodelist[i] - zoneName, ok := node.GetLabels()[scheduler.ZoneLabel] - if !ok { - continue //ignore node that doesn't have zone info (maybe a test setup or control node) - } - nodeToZoneMap[node.Name] = zoneName - } - - lsp := listers.NewListers(podlist) - tc.state.PodLister = lsp.GetPodLister().Pods(testNs) - tc.state.NodeToZoneMap = nodeToZoneMap - - score, status := plugin.Score(ctx, tc.args, tc.state, tc.state.SchedulablePods, tc.vpod, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority_test.go b/pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority_test.go deleted file mode 100644 index 71109bee19..0000000000 --- a/pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority_test.go +++ /dev/null @@ -1,231 +0,0 @@ -/* -Copyright 2021 The Knative 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 availabilityzonepriority - -import ( - "fmt" - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" - listers "knative.dev/eventing/pkg/reconciler/testing/v1" - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" -) - -const ( - testNs = "test-ns" - sfsName = "statefulset-name" - vpodName = "source-name" - vpodNamespace = "source-namespace" - numZones = 3 - numNodes = 6 -) - -func TestScore(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - replicas int32 - podID int32 - expected *state.Status - expScore uint64 - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - expScore: 0, - args: "{\"MaxSkewness\": 2}", - }, - { - name: "no vpods, no pods, no resource", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 1, - expected: state.NewStatus(state.Error, ErrReasonNoResource), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, one zone, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 12, - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, one zone, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNamespace + "-1"}: { - "zone1": 4, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 12, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, two zones, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 2, ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - "zone1": 5, - "zone2": 3, - }, - }}, - replicas: 2, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 4, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, three zones, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 3, ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - "zone1": 4, - "zone2": 3, - }, - }}, - replicas: 3, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 2, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 5, ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 8, - "zone1": 4, - "zone2": 3, - }, - }}, - replicas: 5, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 11, - args: "{\"MaxSkew\": 2}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &AvailabilityZonePriority{} - - name := plugin.Name() - assert.Equal(t, name, state.AvailabilityZonePriority) - - nodelist := make([]*v1.Node, 0) - podlist := make([]runtime.Object, 0) - - for i := int32(0); i < numZones; i++ { - for j := int32(0); j < numNodes/numZones; j++ { - nodeName := "node" + fmt.Sprint((j*((numNodes/numZones)+1))+i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - } - - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - nodeToZoneMap := make(map[string]string) - for i := 0; i < len(nodelist); i++ { - node := nodelist[i] - zoneName, ok := node.GetLabels()[scheduler.ZoneLabel] - if !ok { - continue //ignore node that doesn't have zone info (maybe a test setup or control node) - } - nodeToZoneMap[node.Name] = zoneName - } - - lsp := listers.NewListers(podlist) - tc.state.PodLister = lsp.GetPodLister().Pods(testNs) - tc.state.NodeToZoneMap = nodeToZoneMap - - score, status := plugin.Score(ctx, tc.args, tc.state, tc.state.SchedulablePods, tc.vpod, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread_test.go b/pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread_test.go deleted file mode 100644 index 174a4662ee..0000000000 --- a/pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread_test.go +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright 2021 The Knative 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 evenpodspread - -import ( - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -func TestFilter(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - podID int32 - expScore uint64 - expected *state.Status - onlyFilter bool - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 0, PodSpread: map[types.NamespacedName]map[string]int32{}}, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 0, PodSpread: map[types.NamespacedName]map[string]int32{}}, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - expScore: 0, - args: "{\"MaxSkewness\": 2}", - }, - { - name: "one vpod, one pod, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 1, - SchedulablePods: []int32{int32(0)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - }, - }, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64, - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, one pod, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 1, - SchedulablePods: []int32{int32(0)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - {Name: "vpod-name-1", Namespace: "vpod-ns-1"}: { - "pod-name-0": 4, - }, - }, - }, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, two pods,same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 2, - SchedulablePods: []int32{int32(0), int32(1)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - "pod-name-1": 5, - }, - }}, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 1, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 5, - SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3), int32(4)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - "pod-name-1": 4, - "pod-name-2": 3, - "pod-name-3": 4, - "pod-name-4": 5, - }, - }}, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 3, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter unschedulable", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 5, - SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3), int32(4)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 7, - "pod-name-1": 4, - "pod-name-2": 3, - "pod-name-3": 4, - "pod-name-4": 5, - }, - }}, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonUnschedulable), - onlyFilter: true, - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, two pods, one pod full", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 2, - SchedulablePods: []int32{int32(0), int32(1)}, - FreeCap: []int32{int32(3), int32(0)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - {Name: "vpod-name-1", Namespace: "vpod-ns-1"}: { - "pod-name-0": 2, - "pod-name-1": 10, - }, - }, - }, - podID: 0, - expected: state.NewStatus(state.Success), - onlyFilter: true, - args: "{\"MaxSkew\": 2}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &EvenPodSpread{} - - name := plugin.Name() - assert.Equal(t, name, state.EvenPodSpread) - - status := plugin.Filter(ctx, tc.args, tc.state, tc.vpod, tc.podID) - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - - if !tc.onlyFilter { - score, status := plugin.Score(ctx, tc.args, tc.state, tc.state.SchedulablePods, tc.vpod, tc.podID) - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected state, got %v, want %v", status, tc.expected) - } - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority_test.go b/pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority_test.go deleted file mode 100644 index 9e5fa3990f..0000000000 --- a/pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority_test.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright 2021 The Knative 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 lowestordinalpriority - -import ( - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -func TestScore(t *testing.T) { - testCases := []struct { - name string - state *state.State - podID int32 - expScore uint64 - expected *state.Status - }{ - { - name: "no vpods", - state: &state.State{LastOrdinal: -1}, - podID: 0, - expScore: math.MaxUint64, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods free", - state: &state.State{LastOrdinal: 0}, - podID: 0, - expScore: math.MaxUint64, - expected: state.NewStatus(state.Success), - }, - { - name: "two vpods free", - state: &state.State{LastOrdinal: 0}, - podID: 1, - expScore: math.MaxUint64 - 1, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods not free", - state: &state.State{LastOrdinal: 1}, - podID: 0, - expScore: math.MaxUint64, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods not free", - state: &state.State{LastOrdinal: 1}, - podID: 1, - expScore: math.MaxUint64 - 1, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, no gaps", - state: &state.State{LastOrdinal: 1}, - podID: 2, - expScore: math.MaxUint64 - 2, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, with gaps", - state: &state.State{LastOrdinal: 2}, - podID: 0, - expScore: math.MaxUint64, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, with gaps", - state: &state.State{LastOrdinal: 2}, - podID: 1000, - expScore: math.MaxUint64 - 1000, - expected: state.NewStatus(state.Success), - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &LowestOrdinalPriority{} - var args interface{} - - name := plugin.Name() - assert.Equal(t, name, state.LowestOrdinalPriority) - - score, status := plugin.Score(ctx, args, tc.state, tc.state.SchedulablePods, types.NamespacedName{}, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources_test.go b/pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources_test.go deleted file mode 100644 index e743ba9c38..0000000000 --- a/pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources_test.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2021 The Knative 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 podfitsresources - -import ( - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -func TestFilter(t *testing.T) { - testCases := []struct { - name string - state *state.State - podID int32 - expected *state.Status - err error - }{ - { - name: "no vpods", - state: &state.State{Capacity: 10, FreeCap: []int32{}, LastOrdinal: -1}, - podID: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods free", - state: &state.State{Capacity: 10, FreeCap: []int32{int32(9)}, LastOrdinal: 0}, - podID: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods free", - state: &state.State{Capacity: 10, FreeCap: []int32{int32(10)}, LastOrdinal: 0}, - podID: 1, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods not free", - state: &state.State{Capacity: 10, FreeCap: []int32{int32(0)}, LastOrdinal: 0}, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonUnschedulable), - }, - { - name: "many vpods, no gaps", - state: &state.State{Capacity: 10, FreeCap: []int32{int32(0), int32(5), int32(5)}, LastOrdinal: 2}, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonUnschedulable), - }, - { - name: "many vpods, with gaps", - state: &state.State{Capacity: 10, FreeCap: []int32{int32(9), int32(10), int32(5), int32(10)}, LastOrdinal: 2}, - podID: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, with gaps and reserved vreplicas", - state: &state.State{Capacity: 10, FreeCap: []int32{int32(4), int32(10), int32(5), int32(0)}, LastOrdinal: 2}, - podID: 3, - expected: state.NewStatus(state.Unschedulable, ErrReasonUnschedulable), - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &PodFitsResources{} - var args interface{} - - name := plugin.Name() - assert.Equal(t, name, state.PodFitsResources) - - status := plugin.Filter(ctx, args, tc.state, types.NamespacedName{}, tc.podID) - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected state, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority_test.go b/pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority_test.go deleted file mode 100644 index e6d7fd94cf..0000000000 --- a/pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority_test.go +++ /dev/null @@ -1,231 +0,0 @@ -/* -Copyright 2021 The Knative 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 removewithavailabilitynodepriority - -import ( - "fmt" - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" - listers "knative.dev/eventing/pkg/reconciler/testing/v1" - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" -) - -const ( - testNs = "test-ns" - sfsName = "statefulset-name" - vpodName = "source-name" - vpodNamespace = "source-namespace" - numZones = 3 - numNodes = 6 -) - -func TestScore(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - replicas int32 - podID int32 - expected *state.Status - expScore uint64 - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - NodeSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - NodeSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - expScore: 0, - args: "{\"MaxSkewness\": 2}", - }, - { - name: "no vpods, no pods, no resource", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - NodeSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 1, - expected: state.NewStatus(state.Error, ErrReasonNoResource), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, one node, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64, - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, one node, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNamespace + "-1"}: { - "node1": 4, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, two nodes, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 2, NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - "node1": 5, - "node2": 3, - }, - }}, - replicas: 2, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 2, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, three nodes, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 3, NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 5, - "node1": 4, - "node2": 3, - }, - }}, - replicas: 3, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 2, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 5, NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "node0": 8, - "node1": 4, - "node2": 3, - }, - }}, - replicas: 5, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 7, - args: "{\"MaxSkew\": 2}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &RemoveWithAvailabilityNodePriority{} - - name := plugin.Name() - assert.Equal(t, name, state.RemoveWithAvailabilityNodePriority) - - nodelist := make([]*v1.Node, 0) - podlist := make([]runtime.Object, 0) - - for i := int32(0); i < numZones; i++ { - for j := int32(0); j < numNodes/numZones; j++ { - nodeName := "node" + fmt.Sprint((j*((numNodes/numZones)+1))+i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - } - - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - nodeToZoneMap := make(map[string]string) - for i := 0; i < len(nodelist); i++ { - node := nodelist[i] - zoneName, ok := node.GetLabels()[scheduler.ZoneLabel] - if !ok { - continue //ignore node that doesn't have zone info (maybe a test setup or control node) - } - nodeToZoneMap[node.Name] = zoneName - } - - lsp := listers.NewListers(podlist) - tc.state.PodLister = lsp.GetPodLister().Pods(testNs) - tc.state.NodeToZoneMap = nodeToZoneMap - - score, status := plugin.Score(ctx, tc.args, tc.state, tc.state.SchedulablePods, tc.vpod, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority_test.go b/pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority_test.go deleted file mode 100644 index 10f90faaad..0000000000 --- a/pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority_test.go +++ /dev/null @@ -1,231 +0,0 @@ -/* -Copyright 2021 The Knative 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 removewithavailabilityzonepriority - -import ( - "fmt" - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" - listers "knative.dev/eventing/pkg/reconciler/testing/v1" - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" -) - -const ( - testNs = "test-ns" - sfsName = "statefulset-name" - vpodName = "source-name" - vpodNamespace = "source-namespace" - numZones = 3 - numNodes = 6 -) - -func TestScore(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - replicas int32 - podID int32 - expected *state.Status - expScore uint64 - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 0, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - expScore: 0, - args: "{\"MaxSkewness\": 2}", - }, - { - name: "no vpods, no pods, no resource", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{}}, - replicas: 0, - podID: 1, - expected: state.NewStatus(state.Error, ErrReasonNoResource), - expScore: 0, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, one zone, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64, - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, one zone, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 1, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNamespace + "-1"}: { - "zone1": 4, - }, - }, - }, - replicas: 1, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, two zones, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 2, ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - "zone1": 5, - "zone2": 3, - }, - }}, - replicas: 2, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 2, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, three zones, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 3, ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 5, - "zone1": 4, - "zone2": 3, - }, - }}, - replicas: 3, - podID: 1, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 2, - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}, - state: &state.State{StatefulSetName: sfsName, Replicas: 5, ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNamespace + "-0"}: { - "zone0": 8, - "zone1": 4, - "zone2": 3, - }, - }}, - replicas: 5, - podID: 0, - expected: state.NewStatus(state.Success), - expScore: math.MaxUint64 - 7, - args: "{\"MaxSkew\": 2}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &RemoveWithAvailabilityZonePriority{} - - name := plugin.Name() - assert.Equal(t, name, state.RemoveWithAvailabilityZonePriority) - - nodelist := make([]*v1.Node, 0) - podlist := make([]runtime.Object, 0) - - for i := int32(0); i < numZones; i++ { - for j := int32(0); j < numNodes/numZones; j++ { - nodeName := "node" + fmt.Sprint((j*((numNodes/numZones)+1))+i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - } - - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - nodeToZoneMap := make(map[string]string) - for i := 0; i < len(nodelist); i++ { - node := nodelist[i] - zoneName, ok := node.GetLabels()[scheduler.ZoneLabel] - if !ok { - continue //ignore node that doesn't have zone info (maybe a test setup or control node) - } - nodeToZoneMap[node.Name] = zoneName - } - - lsp := listers.NewListers(podlist) - tc.state.PodLister = lsp.GetPodLister().Pods(testNs) - tc.state.NodeToZoneMap = nodeToZoneMap - - score, status := plugin.Score(ctx, tc.args, tc.state, tc.state.SchedulablePods, tc.vpod, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority_test.go b/pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority_test.go deleted file mode 100644 index abf5a18124..0000000000 --- a/pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority_test.go +++ /dev/null @@ -1,166 +0,0 @@ -/* -Copyright 2021 The Knative 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 removewithevenpodspreadpriority - -import ( - "math" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -func TestFilter(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - podID int32 - expected *state.Status - expScore uint64 - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 0, PodSpread: map[types.NamespacedName]map[string]int32{}}, - podID: 0, - expScore: 0, - expected: state.NewStatus(state.Success), - args: "{\"MaxSkew\": 2}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 0, PodSpread: map[types.NamespacedName]map[string]int32{}}, - podID: 0, - expScore: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - args: "{\"MaxSkewness\": 2}", - }, - { - name: "one vpod, one pod, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 1, - SchedulablePods: []int32{int32(0)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - }, - }, - podID: 0, - expScore: math.MaxUint64, - expected: state.NewStatus(state.Success), - args: "{\"MaxSkew\": 2}", - }, - { - name: "two vpods, one pod, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 1, - SchedulablePods: []int32{int32(0)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - {Name: "vpod-name-1", Namespace: "vpod-ns-1"}: { - "pod-name-0": 4, - }, - }, - }, - podID: 0, - expScore: math.MaxUint64, - expected: state.NewStatus(state.Success), - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, two pods,same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 2, - SchedulablePods: []int32{int32(0), int32(1)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - "pod-name-1": 5, - }, - }}, - podID: 1, - expScore: math.MaxUint64 - 1, - expected: state.NewStatus(state.Success), - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 5, - SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3), int32(4)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - "pod-name-1": 4, - "pod-name-2": 3, - "pod-name-3": 4, - "pod-name-4": 5, - }, - }}, - podID: 1, - expScore: math.MaxUint64 - 5, - expected: state.NewStatus(state.Success), - args: "{\"MaxSkew\": 2}", - }, - { - name: "one vpod, five pods, same pod filter diff pod", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", Replicas: 6, - SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3), int32(4), int32(5)}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 10, - "pod-name-1": 4, - "pod-name-2": 3, - "pod-name-3": 4, - "pod-name-4": 5, - }, - }}, - podID: 0, - expScore: math.MaxUint64 - 20, - expected: state.NewStatus(state.Success), - args: "{\"MaxSkew\": 2}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &RemoveWithEvenPodSpreadPriority{} - - name := plugin.Name() - assert.Equal(t, name, state.RemoveWithEvenPodSpreadPriority) - - score, status := plugin.Score(ctx, tc.args, tc.state, tc.state.SchedulablePods, tc.vpod, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority_test.go b/pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority_test.go deleted file mode 100644 index 0b8bea909f..0000000000 --- a/pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority_test.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2021 The Knative 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 removewithhighestordinalpriority - -import ( - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -func TestScore(t *testing.T) { - testCases := []struct { - name string - state *state.State - podID int32 - expScore uint64 - expected *state.Status - }{ - { - name: "no vpods", - state: &state.State{LastOrdinal: -1}, - podID: 0, - expScore: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods free", - state: &state.State{LastOrdinal: 0}, - podID: 0, - expScore: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "two vpods free", - state: &state.State{LastOrdinal: 0}, - podID: 1, - expScore: 1, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods not free", - state: &state.State{LastOrdinal: 1}, - podID: 0, - expScore: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "one vpods not free", - state: &state.State{LastOrdinal: 1}, - podID: 1, - expScore: 01, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, no gaps", - state: &state.State{LastOrdinal: 1}, - podID: 2, - expScore: 2, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, with gaps", - state: &state.State{LastOrdinal: 2}, - podID: 0, - expScore: 0, - expected: state.NewStatus(state.Success), - }, - { - name: "many vpods, with gaps", - state: &state.State{LastOrdinal: 2}, - podID: 1000, - expScore: 1000, - expected: state.NewStatus(state.Success), - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &RemoveWithHighestOrdinalPriority{} - var args interface{} - - name := plugin.Name() - assert.Equal(t, name, state.RemoveWithHighestOrdinalPriority) - - score, status := plugin.Score(ctx, args, tc.state, tc.state.SchedulablePods, types.NamespacedName{}, tc.podID) - if score != tc.expScore { - t.Errorf("unexpected score, got %v, want %v", score, tc.expScore) - } - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected status, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count_test.go b/pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count_test.go deleted file mode 100644 index a219674e17..0000000000 --- a/pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count_test.go +++ /dev/null @@ -1,146 +0,0 @@ -/* -Copyright 2021 The Knative 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 nomaxresourcecount - -import ( - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -func TestFilter(t *testing.T) { - testCases := []struct { - name string - state *state.State - vpod types.NamespacedName - podID int32 - expected *state.Status - args interface{} - }{ - { - name: "no vpods, no pods", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: -1, PodSpread: map[types.NamespacedName]map[string]int32{}}, - podID: 0, - expected: state.NewStatus(state.Success), - args: "{\"NumPartitions\": 5}", - }, - { - name: "no vpods, no pods, bad arg", - vpod: types.NamespacedName{}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: -1, PodSpread: map[types.NamespacedName]map[string]int32{}}, - podID: 0, - expected: state.NewStatus(state.Unschedulable, ErrReasonInvalidArg), - args: "{\"NumParts\": 5}", - }, - { - name: "one vpod, one pod, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: 0, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - }, - }, - podID: 0, - expected: state.NewStatus(state.Success), - args: "{\"NumPartitions\": 5}", - }, - { - name: "two vpods, one pod, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: 0, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - }, - {Name: "vpod-name-1", Namespace: "vpod-ns-1"}: { - "pod-name-0": 4, - }, - }, - }, - podID: 0, - expected: state.NewStatus(state.Success), - args: "{\"NumPartitions\": 5}", - }, - { - name: "one vpod, two pods,same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: 1, PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - "pod-name-1": 5, - }, - }}, - podID: 1, - expected: state.NewStatus(state.Success), - args: "{\"NumPartitions\": 5}", - }, - { - name: "one vpod, five pods, same pod filter", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: 4, PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 5, - "pod-name-1": 4, - "pod-name-2": 3, - "pod-name-3": 4, - "pod-name-4": 5, - }, - }}, - podID: 1, - expected: state.NewStatus(state.Success), - args: "{\"NumPartitions\": 5}", - }, - { - name: "one vpod, five pods, same pod filter unschedulable", - vpod: types.NamespacedName{Name: "vpod-name-0", Namespace: "vpod-ns-0"}, - state: &state.State{StatefulSetName: "pod-name", LastOrdinal: 2, PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "pod-name-0": 7, - "pod-name-1": 4, - "pod-name-2": 3, - "pod-name-3": 4, - "pod-name-4": 5, - }, - }}, - podID: 5, - expected: state.NewStatus(state.Unschedulable, ErrReasonUnschedulable), - args: "{\"NumPartitions\": 5}", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - var plugin = &NoMaxResourceCount{} - - name := plugin.Name() - assert.Equal(t, name, state.NoMaxResourceCount) - - status := plugin.Filter(ctx, tc.args, tc.state, tc.vpod, tc.podID) - if !reflect.DeepEqual(status, tc.expected) { - t.Errorf("unexpected state, got %v, want %v", status, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/state/interface_test.go b/pkg/common/scheduler/state/interface_test.go deleted file mode 100644 index 550377d62a..0000000000 --- a/pkg/common/scheduler/state/interface_test.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2020 The Knative 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 state - -import ( - "errors" - "testing" -) - -func TestStatus(t *testing.T) { - testCases := []struct { - name string - status *Status - code Code - err error - }{ - { - name: "success", - status: NewStatus(Success), - }, - { - name: "error", - status: NewStatus(Error), - code: Error, - }, - { - name: "error as status", - status: AsStatus(errors.New("invalid arguments")), - code: Error, - }, - { - name: "unschedulable", - status: NewStatus(Unschedulable, "invalid arguments"), - code: Unschedulable, - err: NewStatus(Unschedulable, "invalid arguments").AsError(), - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if tc.status.IsSuccess() && tc.status.Code() != tc.code && tc.status.AsError() != tc.err { - t.Errorf("unexpected code, got %v, want %v", tc.status.code, tc.code) - } else if tc.status.IsUnschedulable() && tc.status.Code() != tc.code && tc.status.AsError() != tc.err { - t.Errorf("unexpected code/msg, got %v, want %v, got %v, want %v", tc.status.code, tc.code, tc.status.AsError().Error(), tc.err.Error()) - } else if tc.status.IsError() && tc.status.Code() != tc.code && tc.status.AsError() != tc.err { - t.Errorf("unexpected code/msg, got %v, want %v, got %v, want %v", tc.status.code, tc.code, tc.status.AsError().Error(), tc.err.Error()) - } - }) - } -} - -func TestStatusMerge(t *testing.T) { - ps := PluginToStatus{"A": NewStatus(Success), "B": NewStatus(Success)} - if !ps.Merge().IsSuccess() { - t.Errorf("unexpected status from merge") - } - - ps = PluginToStatus{"A": NewStatus(Success), "B": NewStatus(Error)} - if !ps.Merge().IsError() { - t.Errorf("unexpected status from merge") - } - - ps = PluginToStatus{"A": NewStatus(Unschedulable), "B": NewStatus(Error)} - if !ps.Merge().IsError() { - t.Errorf("unexpected status from merge") - } - - ps = PluginToStatus{"A": NewStatus(Unschedulable), "B": NewStatus(Success)} - if !ps.Merge().IsUnschedulable() { - t.Errorf("unexpected status from merge") - } - -} diff --git a/pkg/common/scheduler/state/state_test.go b/pkg/common/scheduler/state/state_test.go deleted file mode 100644 index cdeafee060..0000000000 --- a/pkg/common/scheduler/state/state_test.go +++ /dev/null @@ -1,541 +0,0 @@ -/* -Copyright 2020 The Knative 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 state - -import ( - "fmt" - "reflect" - "testing" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" - "knative.dev/eventing-kafka/pkg/common/scheduler" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" - listers "knative.dev/eventing/pkg/reconciler/testing/v1" - kubeclient "knative.dev/pkg/client/injection/kube/client" -) - -const ( - testNs = "test-ns" - sfsName = "statefulset-name" - vpodName = "vpod-name" - vpodNs = "vpod-ns" -) - -func TestStateBuilder(t *testing.T) { - testCases := []struct { - name string - replicas int32 - vpods [][]duckv1alpha1.Placement - expected State - freec int32 - schedulerPolicyType scheduler.SchedulerPolicyType - schedulerPolicy *scheduler.SchedulerPolicy - deschedulerPolicy *scheduler.SchedulerPolicy - reserved map[types.NamespacedName]map[string]int32 - nodes []*v1.Node - err error - }{ - { - name: "no vpods", - replicas: int32(0), - vpods: [][]duckv1alpha1.Placement{}, - expected: State{Capacity: 10, FreeCap: []int32{}, SchedulablePods: []int32{}, LastOrdinal: -1, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName}, - freec: int32(0), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "one vpods", - replicas: int32(1), - vpods: [][]duckv1alpha1.Placement{{{PodName: "statefulset-name-0", VReplicas: 1}}}, - expected: State{Capacity: 10, FreeCap: []int32{int32(9)}, SchedulablePods: []int32{int32(0)}, LastOrdinal: 0, Replicas: 1, NumNodes: 1, NumZones: 1, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - }, - }, - }, - freec: int32(9), - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0")}, - }, - { - name: "many vpods, no gaps", - replicas: int32(3), - vpods: [][]duckv1alpha1.Placement{ - {{PodName: "statefulset-name-0", VReplicas: 1}, {PodName: "statefulset-name-2", VReplicas: 5}}, - {{PodName: "statefulset-name-1", VReplicas: 2}}, - {{PodName: "statefulset-name-1", VReplicas: 3}, {PodName: "statefulset-name-0", VReplicas: 1}}, - }, - expected: State{Capacity: 10, FreeCap: []int32{int32(8), int32(5), int32(5)}, SchedulablePods: []int32{int32(0), int32(1), int32(2)}, LastOrdinal: 2, Replicas: 3, NumNodes: 3, NumZones: 3, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0", "node-1": "zone-1", "node-2": "zone-2"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - "statefulset-name-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "statefulset-name-1": 2, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "statefulset-name-0": 1, - "statefulset-name-1": 3, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - "node-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "node-1": 2, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "node-0": 1, - "node-1": 3, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - "zone-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "zone-1": 2, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "zone-0": 1, - "zone-1": 3, - }, - }, - }, - freec: int32(18), - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0"), tscheduler.MakeNode("node-1", "zone-1"), tscheduler.MakeNode("node-2", "zone-2")}, - }, - { - name: "many vpods, with gaps", - replicas: int32(4), - vpods: [][]duckv1alpha1.Placement{ - {{PodName: "statefulset-name-0", VReplicas: 1}, {PodName: "statefulset-name-2", VReplicas: 5}}, - {{PodName: "statefulset-name-1", VReplicas: 0}}, - {{PodName: "statefulset-name-1", VReplicas: 0}, {PodName: "statefulset-name-3", VReplicas: 0}}, - }, - expected: State{Capacity: 10, FreeCap: []int32{int32(9), int32(10), int32(5), int32(10)}, SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3)}, LastOrdinal: 2, Replicas: 4, NumNodes: 4, NumZones: 3, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0", "node-1": "zone-1", "node-2": "zone-2", "node-3": "zone-0"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - "statefulset-name-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "statefulset-name-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "statefulset-name-1": 0, - "statefulset-name-3": 0, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - "node-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "node-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "node-1": 0, - "node-3": 0, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - "zone-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "zone-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "zone-0": 0, - "zone-1": 0, - }, - }, - }, - freec: int32(34), - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0"), tscheduler.MakeNode("node-1", "zone-1"), tscheduler.MakeNode("node-2", "zone-2"), tscheduler.MakeNode("node-3", "zone-0")}, - }, - { - name: "many vpods, with gaps and reserved vreplicas", - replicas: int32(4), - vpods: [][]duckv1alpha1.Placement{ - {{PodName: "statefulset-name-0", VReplicas: 1}, {PodName: "statefulset-name-2", VReplicas: 5}}, - {{PodName: "statefulset-name-1", VReplicas: 0}}, - {{PodName: "statefulset-name-1", VReplicas: 0}, {PodName: "statefulset-name-3", VReplicas: 0}}, - }, - expected: State{Capacity: 10, FreeCap: []int32{int32(3), int32(10), int32(5), int32(10)}, SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3)}, LastOrdinal: 2, Replicas: 4, NumNodes: 4, NumZones: 3, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0", "node-1": "zone-1", "node-2": "zone-2", "node-3": "zone-0"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 2, - "statefulset-name-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "statefulset-name-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "statefulset-name-1": 0, - "statefulset-name-3": 0, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 2, - "node-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "node-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "node-1": 0, - "node-3": 0, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 2, - "zone-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "zone-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "zone-0": 0, - "zone-1": 0, - }, - }, - }, - freec: int32(28), - reserved: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 2, - "statefulset-name-2": 5, - }, - {Name: vpodName + "-3", Namespace: vpodNs + "-3"}: { - "statefulset-name-0": 5, - }, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0"), tscheduler.MakeNode("node-1", "zone-1"), tscheduler.MakeNode("node-2", "zone-2"), tscheduler.MakeNode("node-3", "zone-0")}, - }, - { - name: "many vpods, with gaps and reserved vreplicas on existing and new placements, fully committed", - replicas: int32(4), - vpods: [][]duckv1alpha1.Placement{ - {{PodName: "statefulset-name-0", VReplicas: 1}, {PodName: "statefulset-name-2", VReplicas: 5}}, - {{PodName: "statefulset-name-1", VReplicas: 0}}, - {{PodName: "statefulset-name-1", VReplicas: 0}, {PodName: "statefulset-name-3", VReplicas: 0}}, - }, - expected: State{Capacity: 10, FreeCap: []int32{int32(4), int32(7), int32(5), int32(10), int32(5)}, SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3)}, LastOrdinal: 4, Replicas: 4, NumNodes: 4, NumZones: 3, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0", "node-1": "zone-1", "node-2": "zone-2", "node-3": "zone-0"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - "statefulset-name-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "statefulset-name-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "statefulset-name-1": 0, - "statefulset-name-3": 0, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - "node-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "node-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "node-1": 0, - "node-3": 0, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - "zone-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "zone-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "zone-0": 0, - "zone-1": 0, - }, - }, - }, - freec: int32(26), - reserved: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-3", Namespace: "vpod-ns-3"}: { - "statefulset-name-4": 5, - }, - {Name: "vpod-name-4", Namespace: "vpod-ns-4"}: { - "statefulset-name-0": 5, - "statefulset-name-1": 3, - }, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0"), tscheduler.MakeNode("node-1", "zone-1"), tscheduler.MakeNode("node-2", "zone-2"), tscheduler.MakeNode("node-3", "zone-0")}, - }, - { - name: "many vpods, with gaps and reserved vreplicas on existing and new placements, partially committed", - replicas: int32(5), - vpods: [][]duckv1alpha1.Placement{ - {{PodName: "statefulset-name-0", VReplicas: 1}, {PodName: "statefulset-name-2", VReplicas: 5}}, - {{PodName: "statefulset-name-1", VReplicas: 0}}, - {{PodName: "statefulset-name-1", VReplicas: 0}, {PodName: "statefulset-name-3", VReplicas: 0}}, - }, - expected: State{Capacity: 10, FreeCap: []int32{int32(4), int32(7), int32(5), int32(10), int32(2)}, SchedulablePods: []int32{int32(0), int32(1), int32(2), int32(3), int32(4)}, LastOrdinal: 4, Replicas: 5, NumNodes: 5, NumZones: 3, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0", "node-1": "zone-1", "node-2": "zone-2", "node-3": "zone-0", "node-4": "zone-1"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - "statefulset-name-2": 5, - "statefulset-name-4": 8, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "statefulset-name-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "statefulset-name-1": 0, - "statefulset-name-3": 0, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - "node-2": 5, - "node-4": 8, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "node-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "node-1": 0, - "node-3": 0, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - "zone-1": 8, - "zone-2": 5, - }, - {Name: vpodName + "-1", Namespace: vpodNs + "-1"}: { - "zone-1": 0, - }, - {Name: vpodName + "-2", Namespace: vpodNs + "-2"}: { - "zone-0": 0, - "zone-1": 0, - }, - }, - }, - freec: int32(28), - reserved: map[types.NamespacedName]map[string]int32{ - {Name: "vpod-name-0", Namespace: "vpod-ns-0"}: { - "statefulset-name-4": 8, - }, - {Name: "vpod-name-4", Namespace: "vpod-ns-4"}: { - "statefulset-name-0": 5, - "statefulset-name-1": 3, - }, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0"), tscheduler.MakeNode("node-1", "zone-1"), tscheduler.MakeNode("node-2", "zone-2"), tscheduler.MakeNode("node-3", "zone-0"), tscheduler.MakeNode("node-4", "zone-1")}, - }, - { - name: "three vpods but one tainted and one wit no zoen label", - replicas: int32(1), - vpods: [][]duckv1alpha1.Placement{{{PodName: "statefulset-name-0", VReplicas: 1}}}, - expected: State{Capacity: 10, FreeCap: []int32{int32(9)}, SchedulablePods: []int32{int32(0)}, LastOrdinal: 0, Replicas: 1, NumNodes: 1, NumZones: 1, SchedulerPolicy: scheduler.MAXFILLUP, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - }, - }, - }, - freec: int32(9), - schedulerPolicyType: scheduler.MAXFILLUP, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0"), tscheduler.MakeNodeNoLabel("node-1"), tscheduler.MakeNodeTainted("node-2", "zone-2")}, - }, - { - name: "one vpod (HA)", - replicas: int32(1), - vpods: [][]duckv1alpha1.Placement{{{PodName: "statefulset-name-0", VReplicas: 1}}}, - expected: State{Capacity: 10, FreeCap: []int32{int32(9)}, SchedulablePods: []int32{int32(0)}, LastOrdinal: 0, Replicas: 1, NumNodes: 1, NumZones: 1, SchedPolicy: &scheduler.SchedulerPolicy{}, DeschedPolicy: &scheduler.SchedulerPolicy{}, StatefulSetName: sfsName, - NodeToZoneMap: map[string]string{"node-0": "zone-0"}, - PodSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "statefulset-name-0": 1, - }, - }, - NodeSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "node-0": 1, - }, - }, - ZoneSpread: map[types.NamespacedName]map[string]int32{ - {Name: vpodName + "-0", Namespace: vpodNs + "-0"}: { - "zone-0": 1, - }, - }, - }, - freec: int32(9), - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityNodePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - nodes: []*v1.Node{tscheduler.MakeNode("node-0", "zone-0")}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - vpodClient := tscheduler.NewVPodClient() - nodelist := make([]runtime.Object, 0, len(tc.nodes)) - podlist := make([]runtime.Object, 0, tc.replicas) - - for i, placements := range tc.vpods { - vpodName := fmt.Sprint(vpodName+"-", i) - vpodNamespace := fmt.Sprint(vpodNs+"-", i) - - vpodC := vpodClient.Create(vpodNamespace, vpodName, 1, placements) - - lsvp, err := vpodClient.List() - if err != nil { - t.Fatal("unexpected error", err) - } - vpodG := GetVPod(types.NamespacedName{Name: vpodName, Namespace: vpodNamespace}, lsvp) - if !reflect.DeepEqual(vpodC, vpodG) { - t.Errorf("unexpected vpod, got %v, want %v", vpodG, vpodC) - } - } - - for i := 0; i < len(tc.nodes); i++ { - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tc.nodes[i], metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node-" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - _, err := kubeclient.Get(ctx).AppsV1().StatefulSets(testNs).Create(ctx, tscheduler.MakeStatefulset(testNs, sfsName, tc.replicas), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - - lsp := listers.NewListers(podlist) - lsn := listers.NewListers(nodelist) - - stateBuilder := NewStateBuilder(ctx, testNs, sfsName, vpodClient.List, int32(10), tc.schedulerPolicyType, &scheduler.SchedulerPolicy{}, &scheduler.SchedulerPolicy{}, lsp.GetPodLister().Pods(testNs), lsn.GetNodeLister()) - state, err := stateBuilder.State(tc.reserved) - if err != nil { - t.Fatal("unexpected error", err) - } - - tc.expected.PodLister = lsp.GetPodLister().Pods(testNs) - if tc.expected.FreeCap == nil { - tc.expected.FreeCap = make([]int32, 0, 256) - } - if tc.expected.PodSpread == nil { - tc.expected.PodSpread = make(map[types.NamespacedName]map[string]int32) - } - if tc.expected.NodeSpread == nil { - tc.expected.NodeSpread = make(map[types.NamespacedName]map[string]int32) - } - if tc.expected.ZoneSpread == nil { - tc.expected.ZoneSpread = make(map[types.NamespacedName]map[string]int32) - } - if tc.expected.NodeToZoneMap == nil { - tc.expected.NodeToZoneMap = make(map[string]string) - } - if !reflect.DeepEqual(*state, tc.expected) { - t.Errorf("unexpected state, got %v, want %v", *state, tc.expected) - } - - if state.FreeCapacity() != tc.freec { - t.Errorf("unexpected free capacity, got %d, want %d", state.FreeCapacity(), tc.freec) - } - - if tc.schedulerPolicy != nil && !SatisfyZoneAvailability(state.SchedulablePods, state) { - t.Errorf("unexpected state, got %v, want %v", *state, tc.expected) - } - - if tc.schedulerPolicy != nil && !SatisfyNodeAvailability(state.SchedulablePods, state) { - t.Errorf("unexpected state, got %v, want %v", *state, tc.expected) - } - }) - } -} diff --git a/pkg/common/scheduler/statefulset/autoscaler_test.go b/pkg/common/scheduler/statefulset/autoscaler_test.go deleted file mode 100644 index 83dac3f955..0000000000 --- a/pkg/common/scheduler/statefulset/autoscaler_test.go +++ /dev/null @@ -1,893 +0,0 @@ -/* -Copyright 2020 The Knative 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 statefulset - -import ( - "fmt" - "math" - "reflect" - "testing" - "time" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - v1 "k8s.io/client-go/listers/core/v1" - gtesting "k8s.io/client-go/testing" - - listers "knative.dev/eventing/pkg/reconciler/testing/v1" - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" - _ "knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake" - - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" - "knative.dev/eventing-kafka/pkg/common/scheduler" - "knative.dev/eventing-kafka/pkg/common/scheduler/state" - st "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" -) - -const ( - testNs = "test-ns" -) - -func TestAutoscaler(t *testing.T) { - testCases := []struct { - name string - replicas int32 - vpods []scheduler.VPod - pendings int32 - scaleDown bool - wantReplicas int32 - schedulerPolicyType scheduler.SchedulerPolicyType - schedulerPolicy *scheduler.SchedulerPolicy - deschedulerPolicy *scheduler.SchedulerPolicy - }{ - { - name: "no replicas, no placements, no pending", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 0, nil), - }, - pendings: int32(0), - wantReplicas: int32(0), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "no replicas, no placements, with pending", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 5, nil), - }, - pendings: int32(5), - wantReplicas: int32(1), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "no replicas, with placements, no pending", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(0), - wantReplicas: int32(2), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "no replicas, with placements, with pending, enough capacity", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(3), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "no replicas, with placements, with pending, not enough capacity", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(8), - wantReplicas: int32(3), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, no placements, no pending, scale down", - replicas: int32(3), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 0, nil), - }, - pendings: int32(0), - scaleDown: true, - wantReplicas: int32(0), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, no placements, with pending, scale down", - replicas: int32(3), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 5, nil), - }, - pendings: int32(5), - scaleDown: true, - wantReplicas: int32(1), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, no placements, with pending, scale down disabled", - replicas: int32(3), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 5, nil), - }, - pendings: int32(5), - scaleDown: false, - wantReplicas: int32(3), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, no placements, with pending, scale up", - replicas: int32(3), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 5, nil), - }, - pendings: int32(40), - wantReplicas: int32(4), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, with placements, no pending, no change", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(0), - wantReplicas: int32(2), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, with placements, no pending, scale down", - replicas: int32(5), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(0), - scaleDown: true, - wantReplicas: int32(2), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, with placements, with pending, enough capacity", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(3), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, with placements, with pending, not enough capacity", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(8), - wantReplicas: int32(3), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, with placements, no pending, round up capacity", - replicas: int32(5), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}, - {PodName: "statefulset-name-2", VReplicas: int32(1)}, - {PodName: "statefulset-name-3", VReplicas: int32(1)}, - {PodName: "statefulset-name-4", VReplicas: int32(1)}}), - }, - pendings: int32(0), - wantReplicas: int32(5), - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "with replicas, with placements, with pending, enough capacity, with Predicates and Zone Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(5), - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - }, - { - name: "with replicas, with placements, with pending, enough capacity, with Predicates and Node Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(8), - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityNodePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - }, - { - name: "with replicas, with placements, with pending, enough capacity, with Pod Predicates and Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(4), - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - }, - { - name: "with replicas, with placements, with pending, enough capacity, with Pod Predicates and Zone Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(5), - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - }, - { - name: "with replicas, with placements, with pending, enough capacity, with Pod Predicates and Node Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - pendings: int32(3), - wantReplicas: int32(8), - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityNodePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - - nodelist := make([]runtime.Object, 0, numZones) - podlist := make([]runtime.Object, 0, tc.replicas) - vpodClient := tscheduler.NewVPodClient() - - for i := int32(0); i < numZones; i++ { - for j := int32(0); j < numNodes/numZones; j++ { - nodeName := "node" + fmt.Sprint((j*((numNodes/numZones)+1))+i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - } - - for i := int32(0); i < int32(math.Max(float64(tc.wantReplicas), float64(tc.replicas))); i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - var lspp v1.PodNamespaceLister - var lsnn v1.NodeLister - if len(podlist) != 0 { - lsp := listers.NewListers(podlist) - lspp = lsp.GetPodLister().Pods(testNs) - } - if len(nodelist) != 0 { - lsn := listers.NewListers(nodelist) - lsnn = lsn.GetNodeLister() - } - - stateAccessor := state.NewStateBuilder(ctx, testNs, sfsName, vpodClient.List, 10, tc.schedulerPolicyType, tc.schedulerPolicy, tc.deschedulerPolicy, lspp, lsnn) - - sfsClient := kubeclient.Get(ctx).AppsV1().StatefulSets(testNs) - _, err := sfsClient.Create(ctx, tscheduler.MakeStatefulset(testNs, sfsName, tc.replicas), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - - noopEvictor := func(pod *corev1.Pod, vpod scheduler.VPod, from *duckv1alpha1.Placement) error { - return nil - } - - autoscaler := NewAutoscaler(ctx, testNs, sfsName, vpodClient.List, stateAccessor, noopEvictor, 10*time.Second, int32(10)).(*autoscaler) - - for _, vpod := range tc.vpods { - vpodClient.Append(vpod) - } - - err = autoscaler.doautoscale(ctx, tc.scaleDown, tc.pendings) - if err != nil { - t.Fatal("unexpected error", err) - } - - scale, err := sfsClient.GetScale(ctx, sfsName, metav1.GetOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - if scale.Spec.Replicas != tc.wantReplicas { - t.Errorf("unexpected number of replicas, got %d, want %d", scale.Spec.Replicas, tc.wantReplicas) - } - - }) - } -} - -func TestAutoscalerScaleDownToZero(t *testing.T) { - ctx, cancel := tscheduler.SetupFakeContext(t) - - afterUpdate := make(chan bool) - kubeclient.Get(ctx).PrependReactor("update", "statefulsets", func(action gtesting.Action) (handled bool, ret runtime.Object, err error) { - if action.GetSubresource() == "scale" { - afterUpdate <- true - } - return false, nil, nil - }) - - vpodClient := tscheduler.NewVPodClient() - ls := listers.NewListers(nil) - stateAccessor := state.NewStateBuilder(ctx, testNs, sfsName, vpodClient.List, 10, scheduler.MAXFILLUP, &scheduler.SchedulerPolicy{}, &scheduler.SchedulerPolicy{}, nil, ls.GetNodeLister()) - - sfsClient := kubeclient.Get(ctx).AppsV1().StatefulSets(testNs) - _, err := sfsClient.Create(ctx, tscheduler.MakeStatefulset(testNs, sfsName, 10), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - - noopEvictor := func(pod *corev1.Pod, vpod scheduler.VPod, from *duckv1alpha1.Placement) error { - return nil - } - - autoscaler := NewAutoscaler(ctx, testNs, sfsName, vpodClient.List, stateAccessor, noopEvictor, 2*time.Second, int32(10)).(*autoscaler) - - done := make(chan bool) - go func() { - autoscaler.Start(ctx) - done <- true - }() - - select { - case <-afterUpdate: - case <-time.After(4 * time.Second): - t.Fatal("timeout waiting for scale subresource to be updated") - - } - - sfs, err := sfsClient.Get(ctx, sfsName, metav1.GetOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - if *sfs.Spec.Replicas != 0 { - t.Errorf("unexpected number of replicas, got %d, want 3", *sfs.Spec.Replicas) - } - - cancel() - - select { - case <-done: - case <-time.After(1 * time.Second): - t.Fatal("timeout waiting for autoscaler to stop") - } -} - -func TestCompactor(t *testing.T) { - testCases := []struct { - name string - replicas int32 - vpods []scheduler.VPod - schedulerPolicyType scheduler.SchedulerPolicyType - wantEvictions map[types.NamespacedName][]duckv1alpha1.Placement - schedulerPolicy *scheduler.SchedulerPolicy - deschedulerPolicy *scheduler.SchedulerPolicy - }{ - { - name: "no replicas, no placements, no pending", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 0, nil), - }, - schedulerPolicyType: scheduler.MAXFILLUP, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, compacted", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - schedulerPolicyType: scheduler.MAXFILLUP, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, compacted edge", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 11, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(3)}}), - }, - schedulerPolicyType: scheduler.MAXFILLUP, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, not compacted", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 10, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(2)}}), - }, - schedulerPolicyType: scheduler.MAXFILLUP, - wantEvictions: map[types.NamespacedName][]duckv1alpha1.Placement{ - {Name: "vpod-1", Namespace: testNs}: {{PodName: "statefulset-name-1", VReplicas: int32(2)}}, - }, - }, - { - name: "multiple vpods, with placements in multiple pods, compacted", - replicas: int32(3), - // pod-0:6, pod-1:8, pod-2:7 - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 12, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(4)}, - {PodName: "statefulset-name-1", VReplicas: int32(8)}}), - tscheduler.NewVPod(testNs, "vpod-2", 9, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(7)}}), - }, - schedulerPolicyType: scheduler.MAXFILLUP, - wantEvictions: nil, - }, - { - name: "multiple vpods, with placements in multiple pods, not compacted", - replicas: int32(3), - // pod-0:6, pod-1:7, pod-2:7 - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 6, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(4)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - tscheduler.NewVPod(testNs, "vpod-2", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(7)}}), - }, - schedulerPolicyType: scheduler.MAXFILLUP, - wantEvictions: map[types.NamespacedName][]duckv1alpha1.Placement{ - {Name: "vpod-2", Namespace: testNs}: {{PodName: "statefulset-name-2", VReplicas: int32(7)}}, - }, - }, - { - name: "no replicas, no placements, no pending, with Predicates and Priorities", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 0, nil), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, compacted, with Predicates and Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, compacted edge, with Predicates and Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 11, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(3)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, not compacted, with Predicates and Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 10, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(2)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: map[types.NamespacedName][]duckv1alpha1.Placement{ - {Name: "vpod-1", Namespace: testNs}: {{PodName: "statefulset-name-1", VReplicas: int32(2)}}, - }, - }, - { - name: "multiple vpods, with placements in multiple pods, compacted, with Predicates and Priorities", - replicas: int32(3), - // pod-0:6, pod-1:8, pod-2:7 - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 12, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(4)}, - {PodName: "statefulset-name-1", VReplicas: int32(8)}}), - tscheduler.NewVPod(testNs, "vpod-2", 9, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(7)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "multiple vpods, with placements in multiple pods, not compacted, with Predicates and Priorities", - replicas: int32(3), - // pod-0:6, pod-1:7, pod-2:7 - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 6, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(4)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - tscheduler.NewVPod(testNs, "vpod-2", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(7)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: map[types.NamespacedName][]duckv1alpha1.Placement{ - {Name: "vpod-2", Namespace: testNs}: {{PodName: "statefulset-name-2", VReplicas: int32(7)}}, - }, - }, - { - name: "no replicas, no placements, no pending, with Predicates and HA Priorities", - replicas: int32(0), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 0, nil), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, compacted, with Predicates and HA Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 15, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(7)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 2 pods, compacted edge, with Predicates and HA Priorities", - replicas: int32(2), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 11, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(3)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "one vpod, with placements in 3 pods, compacted, with Predicates and HA Priorities", - replicas: int32(3), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 14, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(8)}, - {PodName: "statefulset-name-1", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(4)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "multiple vpods, with placements in multiple pods, compacted, with Predicates and HA Priorities", - replicas: int32(3), - // pod-0:6, pod-1:8, pod-2:7 - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 12, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(4)}, - {PodName: "statefulset-name-1", VReplicas: int32(8)}}), - tscheduler.NewVPod(testNs, "vpod-2", 9, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(7)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityNodePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: nil, - }, - { - name: "multiple vpods, with placements in multiple pods, not compacted, with Predicates and HA Priorities", - replicas: int32(6), - vpods: []scheduler.VPod{ - tscheduler.NewVPod(testNs, "vpod-1", 16, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(4)}, - {PodName: "statefulset-name-1", VReplicas: int32(2)}, - {PodName: "statefulset-name-2", VReplicas: int32(2)}, - {PodName: "statefulset-name-3", VReplicas: int32(2)}, - {PodName: "statefulset-name-4", VReplicas: int32(3)}, - {PodName: "statefulset-name-5", VReplicas: int32(3)}}), - tscheduler.NewVPod(testNs, "vpod-2", 11, []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: int32(2)}, - {PodName: "statefulset-name-1", VReplicas: int32(4)}, - {PodName: "statefulset-name-2", VReplicas: int32(5)}}), - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - wantEvictions: map[types.NamespacedName][]duckv1alpha1.Placement{ - {Name: "vpod-1", Namespace: testNs}: {{PodName: "statefulset-name-5", VReplicas: int32(3)}, {PodName: "statefulset-name-4", VReplicas: int32(3)}, {PodName: "statefulset-name-3", VReplicas: int32(2)}}, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - - nodelist := make([]runtime.Object, 0, numZones) - podlist := make([]runtime.Object, 0, tc.replicas) - vpodClient := tscheduler.NewVPodClient() - - for i := int32(0); i < numZones; i++ { - for j := int32(0); j < numNodes/numZones; j++ { - nodeName := "node" + fmt.Sprint((j*((numNodes/numZones)+1))+i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - } - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - _, err := kubeclient.Get(ctx).AppsV1().StatefulSets(testNs).Create(ctx, tscheduler.MakeStatefulset(testNs, sfsName, tc.replicas), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - - lsp := listers.NewListers(podlist) - lsn := listers.NewListers(nodelist) - stateAccessor := state.NewStateBuilder(ctx, testNs, sfsName, vpodClient.List, 10, tc.schedulerPolicyType, tc.schedulerPolicy, tc.deschedulerPolicy, lsp.GetPodLister().Pods(testNs), lsn.GetNodeLister()) - - evictions := make(map[types.NamespacedName][]duckv1alpha1.Placement) - recordEviction := func(pod *corev1.Pod, vpod scheduler.VPod, from *duckv1alpha1.Placement) error { - evictions[vpod.GetKey()] = append(evictions[vpod.GetKey()], *from) - return nil - } - - autoscaler := NewAutoscaler(ctx, testNs, sfsName, vpodClient.List, stateAccessor, recordEviction, 10*time.Second, int32(10)).(*autoscaler) - - for _, vpod := range tc.vpods { - vpodClient.Append(vpod) - } - - state, err := stateAccessor.State(nil) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - var scaleUpFactor int32 - if tc.schedulerPolicy != nil && contains(nil, tc.schedulerPolicy.Priorities, st.AvailabilityZonePriority) { //HA scaling across zones - scaleUpFactor = state.NumZones - } else if tc.schedulerPolicy != nil && contains(nil, tc.schedulerPolicy.Priorities, st.AvailabilityNodePriority) { //HA scalingacross nodes - scaleUpFactor = state.NumNodes - } else { - scaleUpFactor = 1 // Non-HA scaling - } - - autoscaler.mayCompact(state, scaleUpFactor) - - if tc.wantEvictions == nil && len(evictions) != 0 { - t.Fatalf("unexpected evictions: %v", evictions) - - } - for key, placements := range tc.wantEvictions { - got, ok := evictions[key] - if !ok { - t.Fatalf("unexpected %v to be evicted but was not", key) - } - - if !reflect.DeepEqual(placements, got) { - t.Fatalf("expected evicted placement to be %v, but got %v", placements, got) - } - - delete(evictions, key) - } - - if len(evictions) != 0 { - t.Fatalf("unexpected evictions %v", evictions) - } - }) - } -} diff --git a/pkg/common/scheduler/statefulset/scheduler_test.go b/pkg/common/scheduler/statefulset/scheduler_test.go deleted file mode 100644 index 1da28e2a80..0000000000 --- a/pkg/common/scheduler/statefulset/scheduler_test.go +++ /dev/null @@ -1,745 +0,0 @@ -/* -Copyright 2020 The Knative 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 statefulset - -import ( - "fmt" - "reflect" - "testing" - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" - _ "knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake" - - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" - "knative.dev/eventing-kafka/pkg/common/scheduler" - "knative.dev/eventing-kafka/pkg/common/scheduler/state" - tscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/testing" - listers "knative.dev/eventing/pkg/reconciler/testing/v1" -) - -const ( - sfsName = "statefulset-name" - vpodName = "source-name" - vpodNamespace = "source-namespace" - numZones = 3 - numNodes = 6 -) - -func TestStatefulsetScheduler(t *testing.T) { - testCases := []struct { - name string - vreplicas int32 - replicas int32 - placements []duckv1alpha1.Placement - expected []duckv1alpha1.Placement - err error - schedulerPolicyType scheduler.SchedulerPolicyType - schedulerPolicy *scheduler.SchedulerPolicy - deschedulerPolicy *scheduler.SchedulerPolicy - pending map[types.NamespacedName]int32 - }{ - { - name: "no replicas, no vreplicas", - vreplicas: 0, - replicas: int32(0), - expected: nil, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "no replicas, 1 vreplicas, fail.", - vreplicas: 1, - replicas: int32(0), - err: scheduler.ErrNotEnoughReplicas, - expected: []duckv1alpha1.Placement{}, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "one replica, one vreplicas", - vreplicas: 1, - replicas: int32(1), - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 1}}, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "one replica, 3 vreplicas", - vreplicas: 3, - replicas: int32(1), - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 3}}, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "one replica, 15 vreplicas, unschedulable", - vreplicas: 15, - replicas: int32(1), - err: scheduler.ErrNotEnoughReplicas, - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 10}}, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "two replicas, 15 vreplicas, scheduled", - vreplicas: 15, - replicas: int32(2), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "two replicas, 15 vreplicas, already scheduled", - vreplicas: 15, - replicas: int32(2), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "two replicas, 20 vreplicas, scheduling", - vreplicas: 20, - replicas: int32(2), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "two replicas, 15 vreplicas, too much scheduled (scale down)", - vreplicas: 15, - replicas: int32(2), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - schedulerPolicyType: scheduler.MAXFILLUP, - }, - { - name: "no replicas, no vreplicas with Predicates and Priorities", - vreplicas: 0, - replicas: int32(0), - expected: nil, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "no replicas, 1 vreplicas, fail with Predicates and Priorities", - vreplicas: 1, - replicas: int32(0), - err: scheduler.ErrNotEnoughReplicas, - expected: []duckv1alpha1.Placement{}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "one replica, one vreplicas with Predicates and Priorities", - vreplicas: 1, - replicas: int32(1), - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 1}}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "one replica, 3 vreplicas with Predicates and Priorities", - vreplicas: 3, - replicas: int32(1), - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 3}}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "one replica, 15 vreplicas, unschedulable with Predicates and Priorities", - vreplicas: 15, - replicas: int32(1), - err: scheduler.ErrNotEnoughReplicas, - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 10}}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "two replicas, 12 vreplicas, scheduled with Predicates and no Priorities", - vreplicas: 12, - replicas: int32(2), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 6}, - {PodName: "statefulset-name-1", VReplicas: 6}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - }, - }, - { - name: "two replicas, 15 vreplicas, scheduled with Predicates and Priorities", - vreplicas: 15, - replicas: int32(2), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "two replicas, 15 vreplicas, already scheduled with Predicates and Priorities", - vreplicas: 15, - replicas: int32(2), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "two replicas, 20 vreplicas, scheduling with Predicates and Priorities", - vreplicas: 20, - replicas: int32(2), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 1}, - }, - }, - }, - { - name: "no replicas, no vreplicas with two Predicates and two Priorities", - vreplicas: 0, - replicas: int32(0), - expected: nil, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", - Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "no replicas, 1 vreplicas, fail with two Predicates and two Priorities", - vreplicas: 1, - replicas: int32(0), - err: scheduler.ErrNotEnoughReplicas, - expected: []duckv1alpha1.Placement{}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "three replicas, one vreplica, with two Predicates and two Priorities (HA)", - vreplicas: 1, - replicas: int32(3), - expected: []duckv1alpha1.Placement{{PodName: "statefulset-name-0", VReplicas: 1}}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "three replicas, three vreplicas, with two Predicates and two Priorities (HA)", - vreplicas: 3, - replicas: int32(3), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 1}, - {PodName: "statefulset-name-1", VReplicas: 1}, - {PodName: "statefulset-name-2", VReplicas: 1}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "one replica, 15 vreplicas, with two Predicates and two Priorities (HA)", - vreplicas: 15, - replicas: int32(1), - err: scheduler.ErrNotEnoughReplicas, - expected: []duckv1alpha1.Placement{}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "three replicas, 15 vreplicas, scheduled, with two Predicates and two Priorities (HA)", - vreplicas: 15, - replicas: int32(3), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - {PodName: "statefulset-name-2", VReplicas: 5}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "three replicas, 15 vreplicas, already scheduled, with two Predicates and two Priorities (HA)", - vreplicas: 15, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 5}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "three replicas, 30 vreplicas, with two Predicates and two Priorities (HA)", - vreplicas: 30, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - {PodName: "statefulset-name-2", VReplicas: 10}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - {PodName: "statefulset-name-2", VReplicas: 10}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 5}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 5}"}, - }, - }, - }, - { - name: "three replicas, 15 vreplicas, with two Predicates and two Priorities (HA)", - vreplicas: 15, - replicas: int32(3), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - {PodName: "statefulset-name-2", VReplicas: 5}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "three replicas, 20 vreplicas, with two Predicates and two Priorities (HA)", - vreplicas: 20, - replicas: int32(3), - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 7}, - {PodName: "statefulset-name-1", VReplicas: 7}, - {PodName: "statefulset-name-2", VReplicas: 6}, - }, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 2}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "LowestOrdinalPriority", Weight: 2}, - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - }, - }, - }, - { - name: "one replica, 8 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 8, - replicas: int32(1), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 8}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithEvenPodSpreadPriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "two replicas, 15 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 15, - replicas: int32(2), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 8}, - {PodName: "statefulset-name-1", VReplicas: 7}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithEvenPodSpreadPriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "three replicas, 15 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 15, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - {PodName: "statefulset-name-2", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - {PodName: "statefulset-name-2", VReplicas: 5}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithAvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "three replicas, 2 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 2, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 1}, - {PodName: "statefulset-name-1", VReplicas: 1}, - {PodName: "statefulset-name-2", VReplicas: 1}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 1}, - {PodName: "statefulset-name-1", VReplicas: 1}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithEvenPodSpreadPriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "three replicas, 2 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 2, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 1}, - {PodName: "statefulset-name-1", VReplicas: 1}, - {PodName: "statefulset-name-2", VReplicas: 1}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 1}, - {PodName: "statefulset-name-1", VReplicas: 1}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithAvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "three replicas, 3 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 3, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 2}, - {PodName: "statefulset-name-1", VReplicas: 2}, - {PodName: "statefulset-name-2", VReplicas: 2}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 1}, - {PodName: "statefulset-name-1", VReplicas: 1}, - {PodName: "statefulset-name-2", VReplicas: 1}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithEvenPodSpreadPriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "three replicas, 6 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 7, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - {PodName: "statefulset-name-1", VReplicas: 10}, - {PodName: "statefulset-name-2", VReplicas: 5}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 3}, - {PodName: "statefulset-name-1", VReplicas: 2}, - {PodName: "statefulset-name-2", VReplicas: 2}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithEvenPodSpreadPriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "four replicas, 7 vreplicas, too much scheduled (scale down), with two desched Priorities", - vreplicas: 7, - replicas: int32(4), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 4}, - {PodName: "statefulset-name-1", VReplicas: 3}, - {PodName: "statefulset-name-2", VReplicas: 4}, - {PodName: "statefulset-name-3", VReplicas: 3}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 2}, - {PodName: "statefulset-name-1", VReplicas: 2}, - {PodName: "statefulset-name-2", VReplicas: 2}, - {PodName: "statefulset-name-3", VReplicas: 1}, - }, - deschedulerPolicy: &scheduler.SchedulerPolicy{ - Priorities: []scheduler.PriorityPolicy{ - {Name: "RemoveWithEvenPodSpreadPriority", Weight: 10, Args: "{\"MaxSkew\": 2}"}, - {Name: "RemoveWithHighestOrdinalPriority", Weight: 2}, - }, - }, - }, - { - name: "three replicas, 15 vreplicas with Predicates and Priorities and non-zero pending for rebalancing", - vreplicas: 15, - replicas: int32(3), - placements: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 10}, - }, - expected: []duckv1alpha1.Placement{ - {PodName: "statefulset-name-0", VReplicas: 5}, - {PodName: "statefulset-name-1", VReplicas: 5}, - {PodName: "statefulset-name-2", VReplicas: 5}, - }, - pending: map[types.NamespacedName]int32{{Name: vpodName, Namespace: vpodNamespace}: 5}, - schedulerPolicy: &scheduler.SchedulerPolicy{ - Predicates: []scheduler.PredicatePolicy{ - {Name: "PodFitsResources"}, - {Name: "EvenPodSpread", Args: "{\"MaxSkew\": 1}"}, - }, - Priorities: []scheduler.PriorityPolicy{ - {Name: "AvailabilityZonePriority", Weight: 10, Args: "{\"MaxSkew\": 1}"}, - {Name: "LowestOrdinalPriority", Weight: 5}, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ctx, _ := tscheduler.SetupFakeContext(t) - nodelist := make([]runtime.Object, 0, numZones) - podlist := make([]runtime.Object, 0, tc.replicas) - vpodClient := tscheduler.NewVPodClient() - - for i := int32(0); i < numZones; i++ { - for j := int32(0); j < numNodes/numZones; j++ { - nodeName := "node" + fmt.Sprint((j*((numNodes/numZones)+1))+i) - zoneName := "zone" + fmt.Sprint(i) - node, err := kubeclient.Get(ctx).CoreV1().Nodes().Create(ctx, tscheduler.MakeNode(nodeName, zoneName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - nodelist = append(nodelist, node) - } - } - for i := int32(0); i < tc.replicas; i++ { - nodeName := "node" + fmt.Sprint(i) - podName := sfsName + "-" + fmt.Sprint(i) - pod, err := kubeclient.Get(ctx).CoreV1().Pods(testNs).Create(ctx, tscheduler.MakePod(testNs, podName, nodeName), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - podlist = append(podlist, pod) - } - - _, err := kubeclient.Get(ctx).AppsV1().StatefulSets(testNs).Create(ctx, tscheduler.MakeStatefulset(testNs, sfsName, tc.replicas), metav1.CreateOptions{}) - if err != nil { - t.Fatal("unexpected error", err) - } - lsp := listers.NewListers(podlist) - lsn := listers.NewListers(nodelist) - sa := state.NewStateBuilder(ctx, testNs, sfsName, vpodClient.List, 10, tc.schedulerPolicyType, tc.schedulerPolicy, tc.deschedulerPolicy, lsp.GetPodLister().Pods(testNs), lsn.GetNodeLister()) - s := NewStatefulSetScheduler(ctx, testNs, sfsName, vpodClient.List, sa, nil, lsp.GetPodLister().Pods(testNs)).(*StatefulSetScheduler) - if tc.pending != nil { - s.pending = tc.pending - } - // Give some time for the informer to notify the scheduler and set the number of replicas - time.Sleep(200 * time.Millisecond) - - func() { - s.lock.Lock() - defer s.lock.Unlock() - if s.replicas != tc.replicas { - t.Fatalf("expected number of statefulset replica to be %d (got %d)", tc.replicas, s.replicas) - } - }() - - vpod := vpodClient.Create(vpodNamespace, vpodName, tc.vreplicas, tc.placements) - placements, err := s.Schedule(vpod) - - if tc.err == nil && err != nil { - t.Fatal("unexpected error", err) - } - - if tc.err != nil && err == nil { - t.Fatal("expected error, got none") - } - - if !reflect.DeepEqual(placements, tc.expected) { - t.Errorf("got %v, want %v", placements, tc.expected) - } - - }) - } -} diff --git a/pkg/common/scheduler/testing/client.go b/pkg/common/scheduler/testing/client.go deleted file mode 100644 index d72c54bf35..0000000000 --- a/pkg/common/scheduler/testing/client.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2020 The Knative 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 testing - -import ( - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" - "knative.dev/eventing-kafka/pkg/common/scheduler" -) - -type VPodClient struct { - store *VPodStore - lister scheduler.VPodLister -} - -func NewVPodClient() *VPodClient { - store := newVPodStore() - return &VPodClient{ - store: store, - lister: newVPodLister(store), - } -} - -func (s *VPodClient) Create(ns, name string, vreplicas int32, placements []duckv1alpha1.Placement) scheduler.VPod { - vpod := NewVPod(ns, name, vreplicas, placements) - s.store.lock.Lock() - defer s.store.lock.Unlock() - s.store.vpods = append(s.store.vpods, vpod) - return vpod -} - -func (s *VPodClient) Append(vpod scheduler.VPod) { - s.store.lock.Lock() - defer s.store.lock.Unlock() - s.store.vpods = append(s.store.vpods, vpod) -} - -func (s *VPodClient) List() ([]scheduler.VPod, error) { - return s.lister() -} diff --git a/pkg/common/scheduler/testing/store.go b/pkg/common/scheduler/testing/store.go deleted file mode 100644 index ecd28ad2ca..0000000000 --- a/pkg/common/scheduler/testing/store.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2020 The Knative 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 testing - -import ( - "sync" - - "knative.dev/eventing-kafka/pkg/common/scheduler" -) - -type VPodStore struct { - vpods []scheduler.VPod - lock sync.Mutex -} - -func newVPodStore() *VPodStore { - return &VPodStore{} -} - -func newVPodLister(store *VPodStore) scheduler.VPodLister { - return func() ([]scheduler.VPod, error) { - store.lock.Lock() - defer store.lock.Unlock() - dst := make([]scheduler.VPod, len(store.vpods)) - copy(dst, store.vpods) - return dst, nil - } -} diff --git a/pkg/common/scheduler/testing/vpod.go b/pkg/common/scheduler/testing/vpod.go deleted file mode 100644 index 20e8b620e6..0000000000 --- a/pkg/common/scheduler/testing/vpod.go +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright 2020 The Knative 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 testing - -import ( - "context" - "testing" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" - "knative.dev/eventing-kafka/pkg/common/scheduler" - "knative.dev/pkg/controller" - - appsv1 "k8s.io/api/apps/v1" - autoscalingv1 "k8s.io/api/autoscaling/v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gtesting "k8s.io/client-go/testing" - - kubeclient "knative.dev/pkg/client/injection/kube/client/fake" - _ "knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake" - rectesting "knative.dev/pkg/reconciler/testing" -) - -type sampleVPod struct { - key types.NamespacedName - vreplicas int32 - placements []duckv1alpha1.Placement - rsrcversion string -} - -func NewVPod(ns, name string, vreplicas int32, placements []duckv1alpha1.Placement) *sampleVPod { - return &sampleVPod{ - key: types.NamespacedName{ - Namespace: ns, - Name: name, - }, - vreplicas: vreplicas, - placements: placements, - rsrcversion: "12345", - } -} - -func (d *sampleVPod) GetKey() types.NamespacedName { - return d.key -} - -func (d *sampleVPod) GetVReplicas() int32 { - return d.vreplicas -} - -func (d *sampleVPod) GetPlacements() []duckv1alpha1.Placement { - return d.placements -} - -func (d *sampleVPod) GetResourceVersion() string { - return d.rsrcversion -} - -func MakeNode(name, zonename string) *v1.Node { - obj := &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - scheduler.ZoneLabel: zonename, - }, - }, - } - return obj -} - -func MakeNodeNoLabel(name string) *v1.Node { - obj := &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - } - return obj -} - -func MakeNodeTainted(name, zonename string) *v1.Node { - obj := &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - scheduler.ZoneLabel: zonename, - }, - }, - Spec: v1.NodeSpec{ - Taints: []v1.Taint{ - {Key: "node.kubernetes.io/unreachable", Effect: v1.TaintEffectNoExecute}, - {Key: "node.kubernetes.io/unreachable", Effect: v1.TaintEffectNoSchedule}, - }, - }, - } - return obj -} - -func MakeStatefulset(ns, name string, replicas int32) *appsv1.StatefulSet { - obj := &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: ns, - }, - Spec: appsv1.StatefulSetSpec{ - Replicas: &replicas, - }, - Status: appsv1.StatefulSetStatus{ - Replicas: replicas, - }, - } - - return obj -} - -func MakePod(ns, name, nodename string) *v1.Pod { - obj := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: ns, - }, - Spec: v1.PodSpec{ - NodeName: nodename, - }, - } - return obj -} - -func SetupFakeContext(t *testing.T) (context.Context, context.CancelFunc) { - ctx, cancel, informers := rectesting.SetupFakeContextWithCancel(t) - err := controller.StartInformers(ctx.Done(), informers...) - if err != nil { - t.Fatal("unexpected error", err) - } - - kc := kubeclient.Get(ctx) - kc.PrependReactor("create", "statefulsets", func(action gtesting.Action) (handled bool, ret runtime.Object, err error) { - createAction := action.(gtesting.CreateActionImpl) - sfs := createAction.GetObject().(*appsv1.StatefulSet) - scale := &autoscalingv1.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: sfs.Name, - Namespace: sfs.Namespace, - }, - Spec: autoscalingv1.ScaleSpec{ - Replicas: func() int32 { - if sfs.Spec.Replicas == nil { - return 1 - } - return *sfs.Spec.Replicas - }(), - }, - } - kc.Tracker().Add(scale) - return false, nil, nil - }) - - kc.PrependReactor("get", "statefulsets", func(action gtesting.Action) (handled bool, ret runtime.Object, err error) { - getAction := action.(gtesting.GetAction) - if action.GetSubresource() == "scale" { - scale, err := kc.Tracker().Get(autoscalingv1.SchemeGroupVersion.WithResource("scales"), getAction.GetNamespace(), getAction.GetName()) - return true, scale, err - - } - return false, nil, nil - }) - - kc.PrependReactor("update", "statefulsets", func(action gtesting.Action) (handled bool, ret runtime.Object, err error) { - updateAction := action.(gtesting.UpdateActionImpl) - if action.GetSubresource() == "scale" { - scale := updateAction.GetObject().(*autoscalingv1.Scale) - - err := kc.Tracker().Update(autoscalingv1.SchemeGroupVersion.WithResource("scales"), scale, scale.GetNamespace()) - if err != nil { - return true, nil, err - } - - meta, err := meta.Accessor(updateAction.GetObject()) - if err != nil { - return true, nil, err - } - - obj, err := kc.Tracker().Get(appsv1.SchemeGroupVersion.WithResource("statefulsets"), meta.GetNamespace(), meta.GetName()) - if err != nil { - return true, nil, err - } - - sfs := obj.(*appsv1.StatefulSet) - sfs.Spec.Replicas = &scale.Spec.Replicas - - err = kc.Tracker().Update(appsv1.SchemeGroupVersion.WithResource("statefulsets"), sfs, sfs.GetNamespace()) - if err != nil { - return true, nil, err - } - - return true, scale, nil - - } - return false, nil, nil - }) - - return ctx, cancel -} diff --git a/pkg/source/mtadapter/adapter.go b/pkg/source/mtadapter/adapter.go index 5824ab4615..d5ce7476fe 100644 --- a/pkg/source/mtadapter/adapter.go +++ b/pkg/source/mtadapter/adapter.go @@ -36,9 +36,9 @@ import ( "knative.dev/pkg/logging" "knative.dev/eventing-kafka/pkg/apis/sources/v1beta1" - "knative.dev/eventing-kafka/pkg/common/scheduler" stadapter "knative.dev/eventing-kafka/pkg/source/adapter" "knative.dev/eventing-kafka/pkg/source/client" + "knative.dev/eventing/pkg/scheduler" ) type AdapterConfig struct { diff --git a/pkg/source/mtadapter/adapter_test.go b/pkg/source/mtadapter/adapter_test.go index 2adfa178ad..6bca3245c2 100644 --- a/pkg/source/mtadapter/adapter_test.go +++ b/pkg/source/mtadapter/adapter_test.go @@ -34,8 +34,8 @@ import ( "knative.dev/eventing/pkg/kncloudevents" bindingsv1beta1 "knative.dev/eventing-kafka/pkg/apis/bindings/v1beta1" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" sourcesv1beta1 "knative.dev/eventing-kafka/pkg/apis/sources/v1beta1" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" ) var ( diff --git a/pkg/source/reconciler/mtsource/controller.go b/pkg/source/reconciler/mtsource/controller.go index 9cffb9282e..198e6f42f8 100644 --- a/pkg/source/reconciler/mtsource/controller.go +++ b/pkg/source/reconciler/mtsource/controller.go @@ -37,14 +37,13 @@ import ( "knative.dev/eventing/pkg/reconciler/source" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" sourcesv1beta1 "knative.dev/eventing-kafka/pkg/apis/sources/v1beta1" kafkaclient "knative.dev/eventing-kafka/pkg/client/injection/client" kafkainformer "knative.dev/eventing-kafka/pkg/client/injection/informers/sources/v1beta1/kafkasource" "knative.dev/eventing-kafka/pkg/client/injection/reconciler/sources/v1beta1/kafkasource" - "knative.dev/eventing-kafka/pkg/common/constants" - "knative.dev/eventing-kafka/pkg/common/scheduler" - stsscheduler "knative.dev/eventing-kafka/pkg/common/scheduler/statefulset" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + scheduler "knative.dev/eventing/pkg/scheduler" + stsscheduler "knative.dev/eventing/pkg/scheduler/statefulset" ) type envConfig struct { @@ -95,7 +94,7 @@ func NewController( if annots == nil { annots = make(map[string]string) } - annots[constants.PodAnnotationKey] = "true" //scheduling disabled + annots[scheduler.PodAnnotationKey] = "true" //scheduling disabled newPod.ObjectMeta.Annotations = annots updated, err := kubeclient.Get(ctx).CoreV1().Pods(newPod.ObjectMeta.Namespace).Update(ctx, newPod, metav1.UpdateOptions{}) diff --git a/pkg/source/reconciler/mtsource/kafkasource.go b/pkg/source/reconciler/mtsource/kafkasource.go index 2965e394b4..abd286f13e 100644 --- a/pkg/source/reconciler/mtsource/kafkasource.go +++ b/pkg/source/reconciler/mtsource/kafkasource.go @@ -45,9 +45,9 @@ import ( reconcilerkafkasource "knative.dev/eventing-kafka/pkg/client/injection/reconciler/sources/v1beta1/kafkasource" listers "knative.dev/eventing-kafka/pkg/client/listers/sources/v1beta1" "knative.dev/eventing-kafka/pkg/common/kafka/offset" - "knative.dev/eventing-kafka/pkg/common/scheduler" "knative.dev/eventing-kafka/pkg/source/client" "knative.dev/eventing-kafka/pkg/source/reconciler/common" + "knative.dev/eventing/pkg/scheduler" ) const ( diff --git a/pkg/apis/duck/v1alpha1/doc.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/doc.go similarity index 100% rename from pkg/apis/duck/v1alpha1/doc.go rename to vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/doc.go diff --git a/pkg/apis/duck/v1alpha1/placement_types.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/placement_types.go similarity index 100% rename from pkg/apis/duck/v1alpha1/placement_types.go rename to vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/placement_types.go diff --git a/pkg/apis/duck/v1alpha1/register.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/register.go similarity index 100% rename from pkg/apis/duck/v1alpha1/register.go rename to vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/register.go diff --git a/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go similarity index 100% rename from pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go rename to vendor/knative.dev/eventing/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go diff --git a/pkg/common/scheduler/README.md b/vendor/knative.dev/eventing/pkg/scheduler/README.md similarity index 100% rename from pkg/common/scheduler/README.md rename to vendor/knative.dev/eventing/pkg/scheduler/README.md diff --git a/pkg/common/scheduler/doc.go b/vendor/knative.dev/eventing/pkg/scheduler/doc.go similarity index 100% rename from pkg/common/scheduler/doc.go rename to vendor/knative.dev/eventing/pkg/scheduler/doc.go diff --git a/pkg/common/scheduler/factory/registry.go b/vendor/knative.dev/eventing/pkg/scheduler/factory/registry.go similarity index 97% rename from pkg/common/scheduler/factory/registry.go rename to vendor/knative.dev/eventing/pkg/scheduler/factory/registry.go index e14792fcc3..518a910567 100644 --- a/pkg/common/scheduler/factory/registry.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/factory/registry.go @@ -19,7 +19,7 @@ package factory import ( "fmt" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + state "knative.dev/eventing/pkg/scheduler/state" ) // RegistryFP is a collection of all available filter plugins. diff --git a/pkg/common/scheduler/placement.go b/vendor/knative.dev/eventing/pkg/scheduler/placement.go similarity index 95% rename from pkg/common/scheduler/placement.go rename to vendor/knative.dev/eventing/pkg/scheduler/placement.go index 86dd89f4ab..e0aaab0da2 100644 --- a/pkg/common/scheduler/placement.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/placement.go @@ -18,7 +18,7 @@ package scheduler import ( "k8s.io/apimachinery/pkg/util/sets" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" ) // GetTotalVReplicas returns the total number of placed virtual replicas diff --git a/pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go similarity index 97% rename from pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go index fc012ec081..7c83d43df4 100644 --- a/pkg/common/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/availabilitynodepriority/availability_node_priority.go @@ -23,8 +23,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go similarity index 97% rename from pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go index 600444ca27..bcefa1d376 100644 --- a/pkg/common/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/availabilityzonepriority/availability_zone_priority.go @@ -23,8 +23,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/evenpodspread/even_pod_spread.go similarity index 97% rename from pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/evenpodspread/even_pod_spread.go index fe16ce1764..edba306372 100644 --- a/pkg/common/scheduler/plugins/core/evenpodspread/even_pod_spread.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/evenpodspread/even_pod_spread.go @@ -23,8 +23,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go similarity index 93% rename from pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go index 3f3e0587d5..3068d55263 100644 --- a/pkg/common/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/lowestordinalpriority/lowest_ordinal_priority.go @@ -21,8 +21,8 @@ import ( "math" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" ) // LowestOrdinalPriority is a score plugin that favors pods that have a lower ordinal diff --git a/pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/podfitsresources/pod_fits_resources.go similarity index 93% rename from pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/podfitsresources/pod_fits_resources.go index 4a182d84c1..e5fc2e6192 100644 --- a/pkg/common/scheduler/plugins/core/podfitsresources/pod_fits_resources.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/podfitsresources/pod_fits_resources.go @@ -20,8 +20,8 @@ import ( "context" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go similarity index 96% rename from pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go index 7c5dab88d0..10f4e778cf 100644 --- a/pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilitynodepriority/remove_with_availability_node_priority.go @@ -23,8 +23,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go similarity index 97% rename from pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go index 22312c573c..9ac6d2774a 100644 --- a/pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilityzonepriority/remove_with_availability_zone_priority.go @@ -23,8 +23,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go similarity index 96% rename from pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go index d4fb90d537..8c7692d663 100644 --- a/pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithevenpodspreadpriority/remove_with_even_pod_spread_priority.go @@ -23,8 +23,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go similarity index 94% rename from pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go index fb54331a30..9a390977f2 100644 --- a/pkg/common/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/core/removewithhighestordinalpriority/remove_with_highest_ordinal_priority.go @@ -20,8 +20,8 @@ import ( "context" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" ) // RemoveWithHighestOrdinalPriority is a score plugin that favors pods that have a higher ordinal diff --git a/pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go b/vendor/knative.dev/eventing/pkg/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go similarity index 95% rename from pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go rename to vendor/knative.dev/eventing/pkg/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go index 7380589f0c..301d29293e 100644 --- a/pkg/common/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/plugins/kafka/nomaxresourcecount/no_max_resource_count.go @@ -22,8 +22,8 @@ import ( "strings" "k8s.io/apimachinery/pkg/types" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - state "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler/factory" + state "knative.dev/eventing/pkg/scheduler/state" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/scheduler.go b/vendor/knative.dev/eventing/pkg/scheduler/scheduler.go similarity index 92% rename from pkg/common/scheduler/scheduler.go rename to vendor/knative.dev/eventing/pkg/scheduler/scheduler.go index 7c37864b2a..1e63719862 100644 --- a/pkg/common/scheduler/scheduler.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/scheduler.go @@ -22,7 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" ) var ( @@ -34,6 +34,10 @@ type SchedulerPolicyType string const ( // MAXFILLUP policy type adds vreplicas to existing pods to fill them up before adding to new pods MAXFILLUP SchedulerPolicyType = "MAXFILLUP" + + // PodAnnotationKey is an annotation used by the scheduler to be informed of pods + // being evicted and not use it for placing vreplicas + PodAnnotationKey = "eventing.knative.dev/unschedulable" ) const ( diff --git a/pkg/common/scheduler/state/helpers.go b/vendor/knative.dev/eventing/pkg/scheduler/state/helpers.go similarity index 97% rename from pkg/common/scheduler/state/helpers.go rename to vendor/knative.dev/eventing/pkg/scheduler/state/helpers.go index 3ab274add0..56ca82b8d4 100644 --- a/pkg/common/scheduler/state/helpers.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/state/helpers.go @@ -13,6 +13,7 @@ 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 state import ( @@ -23,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - "knative.dev/eventing-kafka/pkg/common/scheduler" + "knative.dev/eventing/pkg/scheduler" ) func PodNameFromOrdinal(name string, ordinal int32) string { diff --git a/pkg/common/scheduler/state/interface.go b/vendor/knative.dev/eventing/pkg/scheduler/state/interface.go similarity index 100% rename from pkg/common/scheduler/state/interface.go rename to vendor/knative.dev/eventing/pkg/scheduler/state/interface.go diff --git a/pkg/common/scheduler/state/state.go b/vendor/knative.dev/eventing/pkg/scheduler/state/state.go similarity index 98% rename from pkg/common/scheduler/state/state.go rename to vendor/knative.dev/eventing/pkg/scheduler/state/state.go index 6d3e653086..f3b7f12fb4 100644 --- a/pkg/common/scheduler/state/state.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/state/state.go @@ -32,8 +32,7 @@ import ( clientappsv1 "k8s.io/client-go/kubernetes/typed/apps/v1" corev1 "k8s.io/client-go/listers/core/v1" - "knative.dev/eventing-kafka/pkg/common/constants" - "knative.dev/eventing-kafka/pkg/common/scheduler" + scheduler "knative.dev/eventing/pkg/scheduler" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/logging" ) @@ -237,7 +236,7 @@ func (s *stateBuilder) State(reserved map[types.NamespacedName]map[string]int32) if pod != nil { var unschedulable bool - annotVal, ok := pod.ObjectMeta.Annotations[constants.PodAnnotationKey] //Pod is marked for eviction - CANNOT SCHEDULE VREPS on this pod + annotVal, ok := pod.ObjectMeta.Annotations[scheduler.PodAnnotationKey] //Pod is marked for eviction - CANNOT SCHEDULE VREPS on this pod if ok { unschedulable, _ = strconv.ParseBool(annotVal) } diff --git a/pkg/common/scheduler/statefulset/autoscaler.go b/vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go similarity index 98% rename from pkg/common/scheduler/statefulset/autoscaler.go rename to vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go index 5ba3508f26..fb5da1c9c5 100644 --- a/pkg/common/scheduler/statefulset/autoscaler.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/statefulset/autoscaler.go @@ -28,8 +28,8 @@ import ( "k8s.io/apimachinery/pkg/util/wait" clientappsv1 "k8s.io/client-go/kubernetes/typed/apps/v1" - "knative.dev/eventing-kafka/pkg/common/scheduler" - st "knative.dev/eventing-kafka/pkg/common/scheduler/state" + "knative.dev/eventing/pkg/scheduler" + st "knative.dev/eventing/pkg/scheduler/state" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/logging" ) diff --git a/pkg/common/scheduler/statefulset/scheduler.go b/vendor/knative.dev/eventing/pkg/scheduler/statefulset/scheduler.go similarity index 95% rename from pkg/common/scheduler/statefulset/scheduler.go rename to vendor/knative.dev/eventing/pkg/scheduler/statefulset/scheduler.go index dc64f7cce9..274547275b 100644 --- a/pkg/common/scheduler/statefulset/scheduler.go +++ b/vendor/knative.dev/eventing/pkg/scheduler/statefulset/scheduler.go @@ -18,8 +18,9 @@ package statefulset import ( "context" + "crypto/rand" "fmt" - "math/rand" + "math/big" "sort" "sync" "time" @@ -37,22 +38,22 @@ import ( "knative.dev/pkg/controller" "knative.dev/pkg/logging" - duckv1alpha1 "knative.dev/eventing-kafka/pkg/apis/duck/v1alpha1" - "knative.dev/eventing-kafka/pkg/common/scheduler" - "knative.dev/eventing-kafka/pkg/common/scheduler/factory" - st "knative.dev/eventing-kafka/pkg/common/scheduler/state" + duckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" + "knative.dev/eventing/pkg/scheduler" + "knative.dev/eventing/pkg/scheduler/factory" + st "knative.dev/eventing/pkg/scheduler/state" podinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/pod" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/availabilitynodepriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/availabilityzonepriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/evenpodspread" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/lowestordinalpriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/podfitsresources" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/removewithavailabilitynodepriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/removewithavailabilityzonepriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/removewithevenpodspreadpriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/core/removewithhighestordinalpriority" - _ "knative.dev/eventing-kafka/pkg/common/scheduler/plugins/kafka/nomaxresourcecount" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/availabilitynodepriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/availabilityzonepriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/evenpodspread" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/lowestordinalpriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/podfitsresources" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilitynodepriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilityzonepriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/removewithevenpodspreadpriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/core/removewithhighestordinalpriority" + _ "knative.dev/eventing/pkg/scheduler/plugins/kafka/nomaxresourcecount" ) // NewScheduler creates a new scheduler with pod autoscaling enabled. @@ -485,7 +486,7 @@ func (s *StatefulSetScheduler) selectPod(podScoreList st.PodScoreList) (int32, e maxScore := podScoreList[0].Score selected := podScoreList[0].ID - cntOfMaxScore := 1 + cntOfMaxScore := int64(1) for _, ps := range podScoreList[1:] { if ps.Score > maxScore { maxScore = ps.Score @@ -493,7 +494,11 @@ func (s *StatefulSetScheduler) selectPod(podScoreList st.PodScoreList) (int32, e cntOfMaxScore = 1 } else if ps.Score == maxScore { //if equal scores, randomly picks one cntOfMaxScore++ - if rand.Intn(cntOfMaxScore) == 0 { + randNum, err := rand.Int(rand.Reader, big.NewInt(cntOfMaxScore)) + if err != nil { + return -1, fmt.Errorf("failed to generate random number") + } + if randNum.Int64() == int64(0) { selected = ps.ID } } diff --git a/vendor/knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake/fake.go b/vendor/knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake/fake.go deleted file mode 100644 index 518d654ecf..0000000000 --- a/vendor/knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake/fake.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2021 The Knative 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. -*/ - -// Code generated by injection-gen. DO NOT EDIT. - -package fake - -import ( - context "context" - - statefulset "knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset" - fake "knative.dev/pkg/client/injection/kube/informers/factory/fake" - controller "knative.dev/pkg/controller" - injection "knative.dev/pkg/injection" -) - -var Get = statefulset.Get - -func init() { - injection.Fake.RegisterInformer(withInformer) -} - -func withInformer(ctx context.Context) (context.Context, controller.Informer) { - f := fake.Get(ctx) - inf := f.Apps().V1().StatefulSets() - return context.WithValue(ctx, statefulset.Key{}, inf), inf.Informer() -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0a8a9c6117..32cd5d0a63 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1127,6 +1127,7 @@ knative.dev/eventing/pkg/adapter/v2/util/crstatusevent knative.dev/eventing/pkg/apis/config knative.dev/eventing/pkg/apis/duck knative.dev/eventing/pkg/apis/duck/v1 +knative.dev/eventing/pkg/apis/duck/v1alpha1 knative.dev/eventing/pkg/apis/duck/v1beta1 knative.dev/eventing/pkg/apis/eventing knative.dev/eventing/pkg/apis/eventing/v1 @@ -1194,6 +1195,20 @@ knative.dev/eventing/pkg/reconciler/sugar knative.dev/eventing/pkg/reconciler/testing knative.dev/eventing/pkg/reconciler/testing/scheme knative.dev/eventing/pkg/reconciler/testing/v1 +knative.dev/eventing/pkg/scheduler +knative.dev/eventing/pkg/scheduler/factory +knative.dev/eventing/pkg/scheduler/plugins/core/availabilitynodepriority +knative.dev/eventing/pkg/scheduler/plugins/core/availabilityzonepriority +knative.dev/eventing/pkg/scheduler/plugins/core/evenpodspread +knative.dev/eventing/pkg/scheduler/plugins/core/lowestordinalpriority +knative.dev/eventing/pkg/scheduler/plugins/core/podfitsresources +knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilitynodepriority +knative.dev/eventing/pkg/scheduler/plugins/core/removewithavailabilityzonepriority +knative.dev/eventing/pkg/scheduler/plugins/core/removewithevenpodspreadpriority +knative.dev/eventing/pkg/scheduler/plugins/core/removewithhighestordinalpriority +knative.dev/eventing/pkg/scheduler/plugins/kafka/nomaxresourcecount +knative.dev/eventing/pkg/scheduler/state +knative.dev/eventing/pkg/scheduler/statefulset knative.dev/eventing/pkg/tracing knative.dev/eventing/pkg/utils knative.dev/eventing/test @@ -1273,7 +1288,6 @@ knative.dev/pkg/client/injection/kube/informers/admissionregistration/v1/validat knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment/fake knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset -knative.dev/pkg/client/injection/kube/informers/apps/v1/statefulset/fake knative.dev/pkg/client/injection/kube/informers/core/v1/endpoints knative.dev/pkg/client/injection/kube/informers/core/v1/namespace knative.dev/pkg/client/injection/kube/informers/core/v1/node