436 lines
19 KiB
Go
436 lines
19 KiB
Go
/*
|
|
Copyright 2024 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package podinjection
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
appsv1 "k8s.io/api/apps/v1"
|
|
batchv1 "k8s.io/api/batch/v1"
|
|
apiv1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/autoscaler/cluster-autoscaler/context"
|
|
podinjectionbackoff "k8s.io/autoscaler/cluster-autoscaler/processors/podinjection/backoff"
|
|
"k8s.io/autoscaler/cluster-autoscaler/simulator/clustersnapshot/store"
|
|
"k8s.io/autoscaler/cluster-autoscaler/simulator/clustersnapshot/testsnapshot"
|
|
"k8s.io/autoscaler/cluster-autoscaler/simulator/fake"
|
|
"k8s.io/autoscaler/cluster-autoscaler/simulator/framework"
|
|
"k8s.io/autoscaler/cluster-autoscaler/utils/kubernetes"
|
|
. "k8s.io/autoscaler/cluster-autoscaler/utils/test"
|
|
)
|
|
|
|
func TestTargetCountInjectionPodListProcessor(t *testing.T) {
|
|
node := BuildTestNode("node1", 100, 0)
|
|
|
|
replicaSet1 := createTestReplicaSet("rep-set-1", "default", 5)
|
|
scheduledPodRep1Copy1 := buildTestPod("default", "-scheduled-pod-rep1-1", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID), WithNodeName(node.Name))
|
|
podRep1Copy1 := buildTestPod("default", "pod-rep1-1", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID))
|
|
podRep1Copy2 := buildTestPod("default", "pod-rep1-2", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID))
|
|
|
|
job1 := createTestJob("job-1", "default", 10, 10, 0)
|
|
scheduledPodJob1Copy1 := buildTestPod("default", "scheduled-pod-job1-1", WithControllerOwnerRef(job1.Name, "Job", job1.UID), WithNodeName(node.Name))
|
|
podJob1Copy1 := buildTestPod("default", "pod-job1-1", WithControllerOwnerRef(job1.Name, "Job", job1.UID))
|
|
podJob1Copy2 := buildTestPod("default", "pod-job1-2", WithControllerOwnerRef(job1.Name, "Job", job1.UID))
|
|
|
|
parallelStatefulset := createTestStatefulset("parallel-statefulset-1", "default", appsv1.ParallelPodManagement, 10)
|
|
scheduledParallelStatefulsetPod := buildTestPod("default", "parallel-scheduled-pod-statefulset-1", WithControllerOwnerRef(parallelStatefulset.Name, "StatefulSet", parallelStatefulset.UID), WithNodeName(node.Name))
|
|
parallelStatefulsetPodCopy1 := buildTestPod("default", "parallel-pod-statefulset1-1", WithControllerOwnerRef(parallelStatefulset.Name, "StatefulSet", parallelStatefulset.UID))
|
|
parallelStatefulsetPodCopy2 := buildTestPod("default", "parallel-pod-statefulset1-2", WithControllerOwnerRef(parallelStatefulset.Name, "StatefulSet", parallelStatefulset.UID))
|
|
|
|
sequentialStatefulset := createTestStatefulset("sequential-statefulset-1", "default", appsv1.OrderedReadyPodManagement, 10)
|
|
scheduledSequentialStatefulsetPod := buildTestPod("default", "sequential-scheduled-pod-statefulset-1", WithControllerOwnerRef(sequentialStatefulset.Name, "StatefulSet", sequentialStatefulset.UID), WithNodeName(node.Name))
|
|
sequentialStatefulsetPodCopy1 := buildTestPod("default", "sequential-pod-statefulset1-1", WithControllerOwnerRef(sequentialStatefulset.Name, "StatefulSet", sequentialStatefulset.UID))
|
|
sequentialStatefulsetPodCopy2 := buildTestPod("default", "sequential-pod-statefulset1-2", WithControllerOwnerRef(sequentialStatefulset.Name, "StatefulSet", sequentialStatefulset.UID))
|
|
|
|
replicaSetLister, err := kubernetes.NewTestReplicaSetLister([]*appsv1.ReplicaSet{&replicaSet1})
|
|
assert.NoError(t, err)
|
|
jobLister, err := kubernetes.NewTestJobLister([]*batchv1.Job{&job1})
|
|
assert.NoError(t, err)
|
|
statefulsetLister, err := kubernetes.NewTestStatefulSetLister([]*appsv1.StatefulSet{¶llelStatefulset, &sequentialStatefulset})
|
|
assert.NoError(t, err)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
scheduledPods []*apiv1.Pod
|
|
unschedulablePods []*apiv1.Pod
|
|
wantPods []*apiv1.Pod
|
|
}{
|
|
{
|
|
name: "ReplicaSet",
|
|
scheduledPods: []*apiv1.Pod{scheduledPodRep1Copy1},
|
|
unschedulablePods: []*apiv1.Pod{podRep1Copy1, podRep1Copy2},
|
|
wantPods: append([]*apiv1.Pod{podRep1Copy1, podRep1Copy2}, makeFakePods(replicaSet1.UID, scheduledPodRep1Copy1, 2)...),
|
|
},
|
|
{
|
|
name: "Job",
|
|
scheduledPods: []*apiv1.Pod{scheduledPodJob1Copy1},
|
|
unschedulablePods: []*apiv1.Pod{podJob1Copy1, podJob1Copy2},
|
|
wantPods: append([]*apiv1.Pod{podJob1Copy1, podJob1Copy2}, makeFakePods(job1.UID, scheduledPodJob1Copy1, 7)...),
|
|
},
|
|
{
|
|
name: "Statefulset - Parallel pod management policy",
|
|
scheduledPods: []*apiv1.Pod{scheduledParallelStatefulsetPod},
|
|
unschedulablePods: []*apiv1.Pod{parallelStatefulsetPodCopy1, parallelStatefulsetPodCopy2},
|
|
wantPods: append([]*apiv1.Pod{parallelStatefulsetPodCopy1, parallelStatefulsetPodCopy2}, makeFakePods(parallelStatefulset.UID, scheduledParallelStatefulsetPod, 7)...),
|
|
},
|
|
{
|
|
name: "Statefulset - sequential pod management policy",
|
|
scheduledPods: []*apiv1.Pod{scheduledSequentialStatefulsetPod},
|
|
unschedulablePods: []*apiv1.Pod{sequentialStatefulsetPodCopy1, sequentialStatefulsetPodCopy2},
|
|
wantPods: []*apiv1.Pod{sequentialStatefulsetPodCopy1, sequentialStatefulsetPodCopy2},
|
|
},
|
|
{
|
|
name: "Mix of controllers",
|
|
scheduledPods: []*apiv1.Pod{scheduledPodRep1Copy1, scheduledPodJob1Copy1, scheduledParallelStatefulsetPod},
|
|
unschedulablePods: []*apiv1.Pod{podRep1Copy1, podRep1Copy2, podJob1Copy1, podJob1Copy2, parallelStatefulsetPodCopy1, parallelStatefulsetPodCopy2},
|
|
wantPods: append(
|
|
append(
|
|
append(
|
|
[]*apiv1.Pod{podRep1Copy1, podRep1Copy2, podJob1Copy1, podJob1Copy2, parallelStatefulsetPodCopy1, parallelStatefulsetPodCopy2},
|
|
makeFakePods(replicaSet1.UID, scheduledPodRep1Copy1, 2)...),
|
|
makeFakePods(job1.UID, scheduledPodJob1Copy1, 7)...),
|
|
makeFakePods(parallelStatefulset.UID, scheduledParallelStatefulsetPod, 7)...,
|
|
),
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
p := NewPodInjectionPodListProcessor(podinjectionbackoff.NewFakePodControllerRegistry())
|
|
clusterSnapshot := testsnapshot.NewCustomTestSnapshotOrDie(t, store.NewDeltaSnapshotStore(16))
|
|
err := clusterSnapshot.AddNodeInfo(framework.NewTestNodeInfo(node, tc.scheduledPods...))
|
|
assert.NoError(t, err)
|
|
ctx := context.AutoscalingContext{
|
|
AutoscalingKubeClients: context.AutoscalingKubeClients{
|
|
ListerRegistry: kubernetes.NewListerRegistry(nil, nil, nil, nil, nil, nil, nil, jobLister, replicaSetLister, statefulsetLister),
|
|
},
|
|
ClusterSnapshot: clusterSnapshot,
|
|
}
|
|
pods, err := p.Process(&ctx, tc.unschedulablePods)
|
|
assert.NoError(t, err)
|
|
assert.ElementsMatch(t, tc.wantPods, pods)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGroupPods(t *testing.T) {
|
|
noControllerPod := buildTestPod("default", "pod-no-podGroup")
|
|
|
|
replicaSet1 := createTestReplicaSet("rep-set-1", "default", 10)
|
|
podRep1Copy1 := buildTestPod("default", "pod-rep1-1", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID))
|
|
podRep1Copy2 := buildTestPod("default", "pod-rep1-2", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID))
|
|
podRep1ScheduledCopy1 := buildTestPod("default", "pod-rep1-3", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID), WithNodeName("n1"))
|
|
podRep1ScheduledCopy2 := buildTestPod("default", "pod-rep1-4", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID), WithNodeName("n1"))
|
|
timestamp := time.Date(2025, 3, 19, 12, 0, 0, 0, time.UTC)
|
|
podRep1OlderCopy := buildTestPod(
|
|
"default",
|
|
"pod-rep1-5",
|
|
WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID),
|
|
WithNodeName("n1"),
|
|
WithCreationTimestamp(timestamp),
|
|
)
|
|
podRep1NewerCopy := buildTestPod(
|
|
"default",
|
|
"pod-rep1-6",
|
|
WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID),
|
|
WithNodeName("n1"),
|
|
WithCreationTimestamp(timestamp.Add(1*time.Minute)),
|
|
)
|
|
|
|
replicaSet2 := createTestReplicaSet("rep-set-2", "default", 10)
|
|
podRep2Copy1 := buildTestPod("default", "pod-rep2-1", WithControllerOwnerRef(replicaSet2.Name, "ReplicaSet", replicaSet2.UID))
|
|
podRep2ScheduledCopy1 := buildTestPod("default", "pod-rep2-1", WithControllerOwnerRef(replicaSet2.Name, "ReplicaSet", replicaSet2.UID), WithNodeName("n1"))
|
|
|
|
replicaSet3 := createTestReplicaSet("rep-set-3", "default", 10)
|
|
podRep3Copy1 := buildTestPod("default", "pod-rep3-1", WithControllerOwnerRef(replicaSet3.Name, "ReplicaSet", replicaSet3.UID))
|
|
|
|
job1 := createTestJob("job-1", "default", 10, 10, 0)
|
|
podJob1Copy1 := buildTestPod("default", "pod-job1-1", WithControllerOwnerRef(job1.Name, "Job", job1.UID))
|
|
podJob1Copy2 := buildTestPod("default", "pod-job1-2", WithControllerOwnerRef(job1.Name, "Job", job1.UID))
|
|
|
|
job2 := createTestJob("job-2", "default", 10, 10, 0)
|
|
podJob2Copy1 := buildTestPod("default", "pod-job-2", WithControllerOwnerRef(job2.Name, "Job", job2.UID))
|
|
|
|
statefulset1 := createTestStatefulset("statefulset-1", "default", appsv1.ParallelPodManagement, 10)
|
|
statefulset1Copy1 := buildTestPod("default", "pod-statefulset1-1", WithControllerOwnerRef(statefulset1.Name, "StatefulSet", statefulset1.UID))
|
|
statefulset1Copy2 := buildTestPod("default", "pod-statefulset1-2", WithControllerOwnerRef(statefulset1.Name, "StatefulSet", statefulset1.UID))
|
|
|
|
statefulset2 := createTestStatefulset("statefulset-2", "default", appsv1.ParallelPodManagement, 10)
|
|
statefulset2Copy1 := buildTestPod("default", "pod-statefulset2-1", WithControllerOwnerRef(statefulset2.Name, "StatefulSet", statefulset2.UID))
|
|
|
|
testCases := []struct {
|
|
name string
|
|
unscheduledPods []*apiv1.Pod
|
|
scheduledPods []*apiv1.Pod
|
|
replicaSets []*appsv1.ReplicaSet
|
|
jobs []*batchv1.Job
|
|
statefulsets []*appsv1.StatefulSet
|
|
wantGroupedPods map[types.UID]podGroup
|
|
}{
|
|
{
|
|
name: "no pods",
|
|
replicaSets: []*appsv1.ReplicaSet{&replicaSet1, &replicaSet2},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
replicaSet1.UID: {podCount: 0, desiredReplicas: 10, sample: nil},
|
|
replicaSet2.UID: {podCount: 0, desiredReplicas: 10, sample: nil},
|
|
},
|
|
},
|
|
{
|
|
name: "no unschedulable pods",
|
|
scheduledPods: []*apiv1.Pod{podRep1ScheduledCopy1, podRep1ScheduledCopy2, podRep2ScheduledCopy1},
|
|
replicaSets: []*appsv1.ReplicaSet{&replicaSet1, &replicaSet2},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
replicaSet1.UID: {podCount: 2, desiredReplicas: 10, sample: podRep1ScheduledCopy1, ownerUid: replicaSet1.UID},
|
|
replicaSet2.UID: {podCount: 1, desiredReplicas: 10, sample: podRep2ScheduledCopy1, ownerUid: replicaSet2.UID},
|
|
},
|
|
},
|
|
{
|
|
name: "scheduled and unschedulable pods",
|
|
scheduledPods: []*apiv1.Pod{podRep1ScheduledCopy2},
|
|
unscheduledPods: []*apiv1.Pod{podRep1Copy1, podRep2Copy1},
|
|
replicaSets: []*appsv1.ReplicaSet{&replicaSet1, &replicaSet2},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
replicaSet1.UID: {podCount: 2, desiredReplicas: 10, sample: podRep1ScheduledCopy2, ownerUid: replicaSet1.UID},
|
|
replicaSet2.UID: {podCount: 1, desiredReplicas: 10, sample: podRep2Copy1, ownerUid: replicaSet2.UID},
|
|
},
|
|
},
|
|
{
|
|
name: "pods without a controller are ignored",
|
|
unscheduledPods: []*apiv1.Pod{noControllerPod},
|
|
wantGroupedPods: map[types.UID]podGroup{},
|
|
},
|
|
{
|
|
name: "unable to retrieve a controller - pods are ignored",
|
|
unscheduledPods: []*apiv1.Pod{podRep3Copy1},
|
|
wantGroupedPods: map[types.UID]podGroup{},
|
|
},
|
|
{
|
|
name: "pods form multiple replicaSets",
|
|
unscheduledPods: []*apiv1.Pod{podRep1Copy1, podRep1Copy2, podRep2Copy1},
|
|
replicaSets: []*appsv1.ReplicaSet{&replicaSet1, &replicaSet2},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
replicaSet1.UID: {podCount: 2, desiredReplicas: 10, sample: podRep1Copy1, ownerUid: replicaSet1.UID},
|
|
replicaSet2.UID: {podCount: 1, desiredReplicas: 10, sample: podRep2Copy1, ownerUid: replicaSet2.UID},
|
|
},
|
|
},
|
|
{
|
|
name: "pods form multiple jobs",
|
|
unscheduledPods: []*apiv1.Pod{podJob1Copy1, podJob1Copy2, podJob2Copy1},
|
|
jobs: []*batchv1.Job{&job1, &job2},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
job1.UID: {podCount: 2, desiredReplicas: 10, sample: podJob1Copy1, ownerUid: job1.UID},
|
|
job2.UID: {podCount: 1, desiredReplicas: 10, sample: podJob2Copy1, ownerUid: job2.UID},
|
|
},
|
|
},
|
|
{
|
|
name: "pods form multiple statefulsets",
|
|
unscheduledPods: []*apiv1.Pod{statefulset1Copy1, statefulset1Copy2, statefulset2Copy1},
|
|
statefulsets: []*appsv1.StatefulSet{&statefulset1, &statefulset2},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
statefulset1.UID: {podCount: 2, desiredReplicas: 10, sample: statefulset1Copy1, ownerUid: statefulset1.UID},
|
|
statefulset2.UID: {podCount: 1, desiredReplicas: 10, sample: statefulset2Copy1, ownerUid: statefulset2.UID},
|
|
},
|
|
},
|
|
{
|
|
name: "unscheduledPods from multiple different controllers",
|
|
unscheduledPods: []*apiv1.Pod{podRep1Copy1, podRep1Copy2, podRep2Copy1, podJob1Copy1, statefulset1Copy1},
|
|
replicaSets: []*appsv1.ReplicaSet{&replicaSet1, &replicaSet2},
|
|
jobs: []*batchv1.Job{&job1},
|
|
statefulsets: []*appsv1.StatefulSet{&statefulset1},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
replicaSet1.UID: {podCount: 2, desiredReplicas: 10, sample: podRep1Copy1, ownerUid: replicaSet1.UID},
|
|
replicaSet2.UID: {podCount: 1, desiredReplicas: 10, sample: podRep2Copy1, ownerUid: replicaSet2.UID},
|
|
job1.UID: {podCount: 1, desiredReplicas: 10, sample: podJob1Copy1, ownerUid: job1.UID},
|
|
statefulset1.UID: {podCount: 1, desiredReplicas: 10, sample: statefulset1Copy1, ownerUid: statefulset1.UID},
|
|
},
|
|
},
|
|
{
|
|
name: "newest pod as a sample",
|
|
unscheduledPods: []*apiv1.Pod{podRep1Copy1},
|
|
scheduledPods: []*apiv1.Pod{podRep1NewerCopy, podRep1OlderCopy},
|
|
replicaSets: []*appsv1.ReplicaSet{&replicaSet1},
|
|
wantGroupedPods: map[types.UID]podGroup{
|
|
replicaSet1.UID: {podCount: 3, desiredReplicas: 10, sample: podRep1NewerCopy, ownerUid: replicaSet1.UID},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
replicaSetLister, err := kubernetes.NewTestReplicaSetLister(tc.replicaSets)
|
|
assert.NoError(t, err)
|
|
jobLister, err := kubernetes.NewTestJobLister(tc.jobs)
|
|
assert.NoError(t, err)
|
|
statefulsetLister, err := kubernetes.NewTestStatefulSetLister(tc.statefulsets)
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.AutoscalingContext{
|
|
AutoscalingKubeClients: context.AutoscalingKubeClients{
|
|
ListerRegistry: kubernetes.NewListerRegistry(nil, nil, nil, nil, nil, nil, nil, jobLister, replicaSetLister, statefulsetLister),
|
|
},
|
|
}
|
|
controllers := listControllers(&ctx)
|
|
groupedPods := groupPods(append(tc.scheduledPods, tc.unscheduledPods...), controllers)
|
|
assert.Equal(t, tc.wantGroupedPods, groupedPods)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUpdatePodGroups(t *testing.T) {
|
|
replicaSet1 := createTestReplicaSet("rep-set-1", "default", 10)
|
|
podRep1Copy1 := buildTestPod("default", "pod-rep1-1", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID))
|
|
podRep1Copy2 := buildTestPod("default", "pod-rep1-2", WithControllerOwnerRef(replicaSet1.Name, "ReplicaSet", replicaSet1.UID))
|
|
samplePodGroups := map[types.UID]podGroup{replicaSet1.UID: makePodGroup(10)}
|
|
sampleFalse := false
|
|
sampleTrue := true
|
|
|
|
testCases := []struct {
|
|
name string
|
|
pod *apiv1.Pod
|
|
ownerRef metav1.OwnerReference
|
|
podGroups map[types.UID]podGroup
|
|
wantPodGroup map[types.UID]podGroup
|
|
}{
|
|
{
|
|
name: "owner ref nil controller",
|
|
pod: podRep1Copy1,
|
|
ownerRef: metav1.OwnerReference{},
|
|
podGroups: samplePodGroups,
|
|
wantPodGroup: samplePodGroups,
|
|
},
|
|
{
|
|
name: "owner ref controller set to false",
|
|
pod: podRep1Copy1,
|
|
ownerRef: metav1.OwnerReference{Controller: &sampleFalse},
|
|
podGroups: samplePodGroups,
|
|
wantPodGroup: samplePodGroups,
|
|
},
|
|
{
|
|
name: "owner ref controller not found",
|
|
pod: podRep1Copy1,
|
|
ownerRef: metav1.OwnerReference{Controller: &sampleTrue, UID: types.UID("not found uid")},
|
|
podGroups: samplePodGroups,
|
|
wantPodGroup: samplePodGroups,
|
|
},
|
|
{
|
|
name: "sample pod added and count updated",
|
|
pod: podRep1Copy1,
|
|
ownerRef: podRep1Copy1.OwnerReferences[0],
|
|
podGroups: samplePodGroups,
|
|
wantPodGroup: map[types.UID]podGroup{replicaSet1.UID: {
|
|
podCount: 1,
|
|
desiredReplicas: 10,
|
|
sample: podRep1Copy1,
|
|
ownerUid: replicaSet1.UID,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "only count updated",
|
|
pod: podRep1Copy2,
|
|
ownerRef: podRep1Copy1.OwnerReferences[0],
|
|
podGroups: map[types.UID]podGroup{replicaSet1.UID: {
|
|
podCount: 1,
|
|
desiredReplicas: 10,
|
|
sample: podRep1Copy1,
|
|
ownerUid: replicaSet1.UID,
|
|
},
|
|
},
|
|
wantPodGroup: map[types.UID]podGroup{replicaSet1.UID: {
|
|
podCount: 2,
|
|
desiredReplicas: 10,
|
|
sample: podRep1Copy1,
|
|
ownerUid: replicaSet1.UID,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
podGroups := updatePodGroups(tc.pod, tc.ownerRef, tc.podGroups)
|
|
assert.Equal(t, tc.wantPodGroup, podGroups)
|
|
})
|
|
}
|
|
}
|
|
func TestMakeFakePods(t *testing.T) {
|
|
samplePod := buildTestPod("default", "test-pod", WithNodeName("test-node"))
|
|
// Test case: Positive fake pod count
|
|
fakePodCount := 5
|
|
ownerUid := types.UID("sample uid")
|
|
fakePods := makeFakePods(ownerUid, samplePod, fakePodCount)
|
|
assert.Equal(t, fakePodCount, len(fakePods))
|
|
for idx, fakePod := range fakePods {
|
|
assert.Equal(t, fakePod.Name, fmt.Sprintf("%s-copy-%d", samplePod.Name, idx+1))
|
|
assert.Equal(t, fakePod.UID, types.UID(fmt.Sprintf("%s-%d", string(ownerUid), idx+1)))
|
|
assert.Equal(t, "", fakePod.Spec.NodeName)
|
|
assert.True(t, fake.IsFake(fakePod))
|
|
}
|
|
|
|
// Test case: Zero fake pod count
|
|
fakePodCount = 0
|
|
fakePods = makeFakePods(ownerUid, samplePod, fakePodCount)
|
|
assert.Nil(t, fakePods)
|
|
}
|
|
|
|
func createTestReplicaSet(uid, namespace string, targetReplicaCount int32) appsv1.ReplicaSet {
|
|
return appsv1.ReplicaSet{
|
|
ObjectMeta: metav1.ObjectMeta{UID: types.UID(uid), Name: uid, Namespace: namespace},
|
|
Spec: appsv1.ReplicaSetSpec{
|
|
Replicas: &targetReplicaCount,
|
|
},
|
|
}
|
|
}
|
|
|
|
func createTestJob(uid, namespace string, parallelism, completions, succeeded int32) batchv1.Job {
|
|
return batchv1.Job{
|
|
ObjectMeta: metav1.ObjectMeta{UID: types.UID(uid), Name: uid, Namespace: namespace},
|
|
Spec: batchv1.JobSpec{
|
|
Parallelism: ¶llelism,
|
|
Completions: &completions,
|
|
},
|
|
Status: batchv1.JobStatus{
|
|
Succeeded: succeeded,
|
|
},
|
|
}
|
|
}
|
|
func createTestStatefulset(uid, namespace string, podManagementPolicy appsv1.PodManagementPolicyType, numReplicas int32) appsv1.StatefulSet {
|
|
return appsv1.StatefulSet{
|
|
ObjectMeta: metav1.ObjectMeta{UID: types.UID(uid), Name: uid, Namespace: namespace},
|
|
Spec: appsv1.StatefulSetSpec{
|
|
Replicas: &numReplicas,
|
|
PodManagementPolicy: podManagementPolicy,
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildTestPod(namespace, name string, opts ...podOption) *apiv1.Pod {
|
|
pod := BuildTestPod(name, 10, 10)
|
|
pod.Namespace = namespace
|
|
for _, opt := range opts {
|
|
opt(pod)
|
|
}
|
|
return pod
|
|
}
|
|
|
|
type podOption func(*apiv1.Pod)
|