Skip to content

Commit 7b8985d

Browse files
committed
add_test_cases
1 parent 75266db commit 7b8985d

File tree

2 files changed

+243
-2
lines changed

2 files changed

+243
-2
lines changed

pkg/scheduler/testing/wrappers.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
v1 "k8s.io/api/core/v1"
2424
resourceapi "k8s.io/api/resource/v1alpha3"
25+
storagev1 "k8s.io/api/storage/v1"
2526
"k8s.io/apimachinery/pkg/api/resource"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2728
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -1131,3 +1132,34 @@ func (wrapper *ResourceSliceWrapper) Device(name string, attrs map[resourceapi.Q
11311132
wrapper.Spec.Devices = append(wrapper.Spec.Devices, resourceapi.Device{Name: name, Basic: &resourceapi.BasicDevice{Attributes: attrs}})
11321133
return wrapper
11331134
}
1135+
1136+
// StorageClassWrapper wraps a StorageClass inside.
1137+
type StorageClassWrapper struct{ storagev1.StorageClass }
1138+
1139+
// MakeStorageClass creates a StorageClass wrapper.
1140+
func MakeStorageClass() *StorageClassWrapper {
1141+
return &StorageClassWrapper{}
1142+
}
1143+
1144+
// Obj returns the inner StorageClass.
1145+
func (s *StorageClassWrapper) Obj() *storagev1.StorageClass {
1146+
return &s.StorageClass
1147+
}
1148+
1149+
// Name sets `n` as the name of the inner StorageClass.
1150+
func (s *StorageClassWrapper) Name(n string) *StorageClassWrapper {
1151+
s.SetName(n)
1152+
return s
1153+
}
1154+
1155+
// VolumeBindingMode sets mode as the mode of the inner StorageClass.
1156+
func (s *StorageClassWrapper) VolumeBindingMode(mode storagev1.VolumeBindingMode) *StorageClassWrapper {
1157+
s.StorageClass.VolumeBindingMode = &mode
1158+
return s
1159+
}
1160+
1161+
// Provisoner sets p as the provisioner of the inner StorageClass.
1162+
func (s *StorageClassWrapper) Provisioner(p string) *StorageClassWrapper {
1163+
s.StorageClass.Provisioner = p
1164+
return s
1165+
}

test/integration/scheduler/queue_test.go

Lines changed: 211 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"time"
2424

2525
v1 "k8s.io/api/core/v1"
26+
storagev1 "k8s.io/api/storage/v1"
2627
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2728
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
2829
"k8s.io/apimachinery/pkg/api/errors"
@@ -800,7 +801,7 @@ func TestCoreResourceEnqueue(t *testing.T) {
800801
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
801802
Obj()
802803
if _, err := testCtx.ClientSet.CoreV1().PersistentVolumes().Create(testCtx.Ctx, pv2, metav1.CreateOptions{}); err != nil {
803-
return fmt.Errorf("failed to update pod1: %w", err)
804+
return fmt.Errorf("failed to create pv2: %w", err)
804805
}
805806
return nil
806807
},
@@ -855,13 +856,221 @@ func TestCoreResourceEnqueue(t *testing.T) {
855856
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
856857
Obj()
857858
if _, err := testCtx.ClientSet.CoreV1().PersistentVolumes().Update(testCtx.Ctx, pv2, metav1.UpdateOptions{}); err != nil {
858-
return fmt.Errorf("failed to update pod1: %w", err)
859+
return fmt.Errorf("failed to update pv2: %w", err)
860+
}
861+
return nil
862+
},
863+
wantRequeuedPods: sets.New("pod2"),
864+
enableSchedulingQueueHint: []bool{true},
865+
},
866+
{
867+
name: "Pod rejected with node by the VolumeZone plugin is requeued when the PVC is added",
868+
initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Label(v1.LabelTopologyZone, "us-west1-a").Obj()},
869+
initialPVs: []*v1.PersistentVolume{
870+
st.MakePersistentVolume().
871+
Name("pv1").
872+
Labels(map[string]string{v1.LabelTopologyZone: "us-west1-a"}).
873+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
874+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
875+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
876+
Obj(),
877+
st.MakePersistentVolume().
878+
Name("pv2").
879+
Labels(map[string]string{v1.LabelTopologyZone: "us-east1"}).
880+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
881+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
882+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
883+
Obj(),
884+
},
885+
initialPVCs: []*v1.PersistentVolumeClaim{
886+
st.MakePersistentVolumeClaim().
887+
Name("pvc1").
888+
Annotation(volume.AnnBindCompleted, "true").
889+
VolumeName("pv1").
890+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
891+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
892+
Obj(),
893+
},
894+
initialPods: []*v1.Pod{
895+
st.MakePod().Name("pod1").Container("image").PVC("pvc1").Node("fake-node").Obj(),
896+
},
897+
pods: []*v1.Pod{
898+
st.MakePod().Name("pod2").Container("image").PVC("pvc2").Obj(),
899+
},
900+
triggerFn: func(testCtx *testutils.TestContext) error {
901+
pvc2 := st.MakePersistentVolumeClaim().
902+
Name("pvc2").
903+
Annotation(volume.AnnBindCompleted, "true").
904+
VolumeName("pv2").
905+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
906+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
907+
Obj()
908+
if _, err := testCtx.ClientSet.CoreV1().PersistentVolumeClaims(testCtx.NS.Name).Create(testCtx.Ctx, pvc2, metav1.CreateOptions{}); err != nil {
909+
return fmt.Errorf("failed to add pvc2: %w", err)
859910
}
860911
return nil
861912
},
862913
wantRequeuedPods: sets.New("pod2"),
863914
enableSchedulingQueueHint: []bool{true},
864915
},
916+
{
917+
name: "Pod rejected with node by the VolumeZone plugin is requeued when the PVC is updated",
918+
initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Label(v1.LabelTopologyZone, "us-west1-a").Obj()},
919+
initialPVs: []*v1.PersistentVolume{
920+
st.MakePersistentVolume().
921+
Name("pv1").
922+
Labels(map[string]string{v1.LabelTopologyZone: "us-west1-a"}).
923+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
924+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
925+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
926+
Obj(),
927+
st.MakePersistentVolume().
928+
Name("pv2").
929+
Labels(map[string]string{v1.LabelTopologyZone: "us-east1"}).
930+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
931+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
932+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
933+
Obj(),
934+
},
935+
initialPVCs: []*v1.PersistentVolumeClaim{
936+
st.MakePersistentVolumeClaim().
937+
Name("pvc1").
938+
Annotation(volume.AnnBindCompleted, "true").
939+
VolumeName("pv1").
940+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
941+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
942+
Obj(),
943+
st.MakePersistentVolumeClaim().
944+
Name("pvc2").
945+
Annotation(volume.AnnBindCompleted, "true").
946+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
947+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
948+
Obj(),
949+
},
950+
initialPods: []*v1.Pod{
951+
st.MakePod().Name("pod1").Container("image").PVC("pvc1").Node("fake-node").Obj(),
952+
},
953+
pods: []*v1.Pod{
954+
st.MakePod().Name("pod2").Container("image").PVC("pvc2").Obj(),
955+
},
956+
triggerFn: func(testCtx *testutils.TestContext) error {
957+
pvc2 := st.MakePersistentVolumeClaim().
958+
Name("pvc2").
959+
Annotation(volume.AnnBindCompleted, "true").
960+
VolumeName("pv2").
961+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
962+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
963+
Obj()
964+
if _, err := testCtx.ClientSet.CoreV1().PersistentVolumeClaims(testCtx.NS.Name).Update(testCtx.Ctx, pvc2, metav1.UpdateOptions{}); err != nil {
965+
return fmt.Errorf("failed to update pvc2: %w", err)
966+
}
967+
return nil
968+
},
969+
wantRequeuedPods: sets.New("pod2"),
970+
enableSchedulingQueueHint: []bool{true},
971+
},
972+
{
973+
name: "Pod rejected with node by the VolumeZone plugin is requeued when the Storage class is added",
974+
initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Label(v1.LabelTopologyZone, "us-west1-a").Obj()},
975+
initialPVs: []*v1.PersistentVolume{
976+
st.MakePersistentVolume().
977+
Name("pv1").
978+
Labels(map[string]string{v1.LabelTopologyZone: "us-west1-a"}).
979+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
980+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
981+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
982+
Obj(),
983+
},
984+
initialPVCs: []*v1.PersistentVolumeClaim{
985+
st.MakePersistentVolumeClaim().
986+
Name("pvc1").
987+
Annotation(volume.AnnBindCompleted, "true").
988+
VolumeName("pv1").
989+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
990+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
991+
Obj(),
992+
st.MakePersistentVolumeClaim().
993+
Name("pvc2").
994+
Annotation(volume.AnnBindCompleted, "true").
995+
VolumeName("pv2").
996+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
997+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
998+
Obj(),
999+
},
1000+
initialPods: []*v1.Pod{
1001+
st.MakePod().Name("pod1").Container("image").PVC("pvc1").Node("fake-node").Obj(),
1002+
},
1003+
pods: []*v1.Pod{
1004+
st.MakePod().Name("pod2").Container("image").PVC("pvc2").Obj(),
1005+
},
1006+
triggerFn: func(testCtx *testutils.TestContext) error {
1007+
sc1 := st.MakeStorageClass().
1008+
Name("sc1").
1009+
VolumeBindingMode(storagev1.VolumeBindingWaitForFirstConsumer).
1010+
Provisioner("p").
1011+
Obj()
1012+
if _, err := testCtx.ClientSet.StorageV1().StorageClasses().Create(testCtx.Ctx, sc1, metav1.CreateOptions{}); err != nil {
1013+
return fmt.Errorf("failed to create sc1: %w", err)
1014+
}
1015+
return nil
1016+
},
1017+
wantRequeuedPods: sets.New("pod2"),
1018+
enableSchedulingQueueHint: []bool{true},
1019+
},
1020+
{
1021+
name: "Pod rejected with node by the VolumeZone plugin is not requeued when the unrelated label of PV is updated",
1022+
initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Label(v1.LabelTopologyZone, "us-west1-a").Obj()},
1023+
initialPVs: []*v1.PersistentVolume{
1024+
st.MakePersistentVolume().
1025+
Name("pv1").
1026+
Labels(map[string]string{v1.LabelTopologyZone: "us-west1-a"}).
1027+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
1028+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
1029+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
1030+
Obj(),
1031+
st.MakePersistentVolume().
1032+
Name("pv2").
1033+
Labels(map[string]string{v1.LabelTopologyZone: "us-east1"}).
1034+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
1035+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
1036+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
1037+
Obj(),
1038+
},
1039+
initialPVCs: []*v1.PersistentVolumeClaim{
1040+
st.MakePersistentVolumeClaim().
1041+
Name("pvc1").
1042+
Annotation(volume.AnnBindCompleted, "true").
1043+
VolumeName("pv1").
1044+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
1045+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
1046+
Obj(),
1047+
st.MakePersistentVolumeClaim().
1048+
Name("pvc2").
1049+
Annotation(volume.AnnBindCompleted, "true").
1050+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}).
1051+
Resources(v1.VolumeResourceRequirements{Requests: v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}}).
1052+
Obj(),
1053+
},
1054+
initialPods: []*v1.Pod{
1055+
st.MakePod().Name("pod1").Container("image").PVC("pvc1").Node("fake-node").Obj(),
1056+
},
1057+
pods: []*v1.Pod{
1058+
st.MakePod().Name("pod2").Container("image").PVC("pvc2").Obj(),
1059+
},
1060+
triggerFn: func(testCtx *testutils.TestContext) error {
1061+
pv2 := st.MakePersistentVolume().Name("pv2").Labels(map[string]string{v1.LabelTopologyZone: "us-east1"}).
1062+
AccessModes([]v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}).
1063+
Capacity(v1.ResourceList{v1.ResourceStorage: resource.MustParse("1Mi")}).
1064+
HostPathVolumeSource(&v1.HostPathVolumeSource{Path: "/tmp", Type: &volType}).
1065+
Obj()
1066+
if _, err := testCtx.ClientSet.CoreV1().PersistentVolumes().Update(testCtx.Ctx, pv2, metav1.UpdateOptions{}); err != nil {
1067+
return fmt.Errorf("failed to update pv2: %w", err)
1068+
}
1069+
return nil
1070+
},
1071+
wantRequeuedPods: sets.Set[string]{},
1072+
enableSchedulingQueueHint: []bool{true},
1073+
},
8651074
}
8661075

8671076
for _, tt := range tests {

0 commit comments

Comments
 (0)