@@ -26,6 +26,7 @@ import (
26
26
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
27
27
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
28
28
"k8s.io/apimachinery/pkg/api/errors"
29
+ "k8s.io/apimachinery/pkg/api/resource"
29
30
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30
31
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
31
32
"k8s.io/apimachinery/pkg/runtime"
@@ -38,6 +39,7 @@ import (
38
39
"k8s.io/client-go/dynamic"
39
40
"k8s.io/client-go/kubernetes"
40
41
featuregatetesting "k8s.io/component-base/featuregate/testing"
42
+ "k8s.io/component-helpers/storage/volume"
41
43
"k8s.io/klog/v2"
42
44
configv1 "k8s.io/kube-scheduler/config/v1"
43
45
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
@@ -186,6 +188,7 @@ func TestSchedulingGates(t *testing.T) {
186
188
// TestCoreResourceEnqueue verify Pods failed by in-tree default plugins can be
187
189
// moved properly upon their registered events.
188
190
func TestCoreResourceEnqueue (t * testing.T ) {
191
+ volType := v1 .HostPathDirectoryOrCreate
189
192
tests := []struct {
190
193
name string
191
194
// initialNodes is the list of Nodes to be created at first.
@@ -194,6 +197,12 @@ func TestCoreResourceEnqueue(t *testing.T) {
194
197
// Note that the scheduler won't schedule those Pods,
195
198
// meaning, those Pods should be already scheduled basically; they should have .spec.nodename.
196
199
initialPods []* v1.Pod
200
+ // initialPVCs are the list of PersistentVolumeClaims to be created at first.
201
+ // Note that PVs are automatically created following PVCs.
202
+ // Also, the namespace of pvcs is automatically filled in.
203
+ initialPVCs []* v1.PersistentVolumeClaim
204
+ // initialPVs are the list of PersistentVolume to be created at first.
205
+ initialPVs []* v1.PersistentVolume
197
206
// pods are the list of Pods to be created.
198
207
// All of them are expected to be unschedulable at first.
199
208
pods []* v1.Pod
@@ -748,7 +757,109 @@ func TestCoreResourceEnqueue(t *testing.T) {
748
757
}
749
758
return nil
750
759
},
751
- wantRequeuedPods : sets .New ("pod4" ),
760
+ wantRequeuedPods : sets .New ("pod4" ),
761
+ },
762
+ {
763
+ name : "Pod rejected with node by the VolumeZone plugin is requeued when the PV is added" ,
764
+ initialNodes : []* v1.Node {st .MakeNode ().Name ("fake-node" ).Label ("node" , "fake-node" ).Label (v1 .LabelTopologyZone , "us-west1-a" ).Obj ()},
765
+ initialPVs : []* v1.PersistentVolume {
766
+ st .MakePersistentVolume ().
767
+ Name ("pv1" ).
768
+ Labels (map [string ]string {v1 .LabelTopologyZone : "us-west1-a" }).
769
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadOnlyMany }).
770
+ Capacity (v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}).
771
+ HostPathVolumeSource (& v1.HostPathVolumeSource {Path : "/tmp" , Type : & volType }).
772
+ Obj (),
773
+ },
774
+ initialPVCs : []* v1.PersistentVolumeClaim {
775
+ st .MakePersistentVolumeClaim ().
776
+ Name ("pvc1" ).
777
+ Annotation (volume .AnnBindCompleted , "true" ).
778
+ VolumeName ("pv1" ).
779
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadWriteOncePod }).
780
+ Resources (v1.VolumeResourceRequirements {Requests : v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}}).
781
+ Obj (),
782
+ st .MakePersistentVolumeClaim ().
783
+ Name ("pvc2" ).
784
+ Annotation (volume .AnnBindCompleted , "true" ).
785
+ VolumeName ("pv2" ).
786
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadWriteOncePod }).
787
+ Resources (v1.VolumeResourceRequirements {Requests : v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}}).
788
+ Obj (),
789
+ },
790
+ initialPods : []* v1.Pod {
791
+ st .MakePod ().Name ("pod1" ).Container ("image" ).PVC ("pvc1" ).Node ("fake-node" ).Obj (),
792
+ },
793
+ pods : []* v1.Pod {
794
+ st .MakePod ().Name ("pod2" ).Container ("image" ).PVC ("pvc2" ).Obj (),
795
+ },
796
+ triggerFn : func (testCtx * testutils.TestContext ) error {
797
+ pv2 := st .MakePersistentVolume ().Name ("pv2" ).Label (v1 .LabelTopologyZone , "us-west1-a" ).
798
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadOnlyMany }).
799
+ Capacity (v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}).
800
+ HostPathVolumeSource (& v1.HostPathVolumeSource {Path : "/tmp" , Type : & volType }).
801
+ Obj ()
802
+ 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
+ }
805
+ return nil
806
+ },
807
+ wantRequeuedPods : sets .New ("pod2" ),
808
+ enableSchedulingQueueHint : []bool {true },
809
+ },
810
+ {
811
+ name : "Pod rejected with node by the VolumeZone plugin is requeued when the PV is updated" ,
812
+ initialNodes : []* v1.Node {st .MakeNode ().Name ("fake-node" ).Label ("node" , "fake-node" ).Label (v1 .LabelTopologyZone , "us-west1-a" ).Obj ()},
813
+ initialPVs : []* v1.PersistentVolume {
814
+ st .MakePersistentVolume ().
815
+ Name ("pv1" ).
816
+ Labels (map [string ]string {v1 .LabelTopologyZone : "us-west1-a" }).
817
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadOnlyMany }).
818
+ Capacity (v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}).
819
+ HostPathVolumeSource (& v1.HostPathVolumeSource {Path : "/tmp" , Type : & volType }).
820
+ Obj (),
821
+ st .MakePersistentVolume ().
822
+ Name ("pv2" ).
823
+ Labels (map [string ]string {v1 .LabelTopologyZone : "us-east1" }).
824
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadOnlyMany }).
825
+ Capacity (v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}).
826
+ HostPathVolumeSource (& v1.HostPathVolumeSource {Path : "/tmp" , Type : & volType }).
827
+ Obj (),
828
+ },
829
+ initialPVCs : []* v1.PersistentVolumeClaim {
830
+ st .MakePersistentVolumeClaim ().
831
+ Name ("pvc1" ).
832
+ Annotation (volume .AnnBindCompleted , "true" ).
833
+ VolumeName ("pv1" ).
834
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadWriteOncePod }).
835
+ Resources (v1.VolumeResourceRequirements {Requests : v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}}).
836
+ Obj (),
837
+ st .MakePersistentVolumeClaim ().
838
+ Name ("pvc2" ).
839
+ Annotation (volume .AnnBindCompleted , "true" ).
840
+ VolumeName ("pv2" ).
841
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadWriteOncePod }).
842
+ Resources (v1.VolumeResourceRequirements {Requests : v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}}).
843
+ Obj (),
844
+ },
845
+ initialPods : []* v1.Pod {
846
+ st .MakePod ().Name ("pod1" ).Container ("image" ).PVC ("pvc1" ).Node ("fake-node" ).Obj (),
847
+ },
848
+ pods : []* v1.Pod {
849
+ st .MakePod ().Name ("pod2" ).Container ("image" ).PVC ("pvc2" ).Obj (),
850
+ },
851
+ triggerFn : func (testCtx * testutils.TestContext ) error {
852
+ pv2 := st .MakePersistentVolume ().Name ("pv2" ).Label (v1 .LabelTopologyZone , "us-west1-a" ).
853
+ AccessModes ([]v1.PersistentVolumeAccessMode {v1 .ReadOnlyMany }).
854
+ Capacity (v1.ResourceList {v1 .ResourceStorage : resource .MustParse ("1Mi" )}).
855
+ HostPathVolumeSource (& v1.HostPathVolumeSource {Path : "/tmp" , Type : & volType }).
856
+ Obj ()
857
+ 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
+ }
860
+ return nil
861
+ },
862
+ wantRequeuedPods : sets .New ("pod2" ),
752
863
enableSchedulingQueueHint : []bool {true },
753
864
},
754
865
}
@@ -785,6 +896,19 @@ func TestCoreResourceEnqueue(t *testing.T) {
785
896
}
786
897
}
787
898
899
+ for _ , pv := range tt .initialPVs {
900
+ if _ , err := testutils .CreatePV (cs , pv ); err != nil {
901
+ t .Fatalf ("Failed to create a PV %q: %v" , pv .Name , err )
902
+ }
903
+ }
904
+
905
+ for _ , pvc := range tt .initialPVCs {
906
+ pvc .Namespace = ns
907
+ if _ , err := testutils .CreatePVC (cs , pvc ); err != nil {
908
+ t .Fatalf ("Failed to create a PVC %q: %v" , pvc .Name , err )
909
+ }
910
+ }
911
+
788
912
for _ , pod := range tt .initialPods {
789
913
if _ , err := cs .CoreV1 ().Pods (ns ).Create (ctx , pod , metav1.CreateOptions {}); err != nil {
790
914
t .Fatalf ("Failed to create an initial Pod %q: %v" , pod .Name , err )
0 commit comments