Move PodPriorityResolution e2e to integration

This commit is contained in:
Mike Dame
2019-07-31 16:17:03 -04:00
parent 001f2cd2b5
commit ca18b48151
6 changed files with 134 additions and 65 deletions

View File

@@ -221,43 +221,6 @@ var _ = SIGDescribe("SchedulerPreemption [Serial]", func() {
})
})
var _ = SIGDescribe("PodPriorityResolution [Serial]", func() {
var cs clientset.Interface
var ns string
f := framework.NewDefaultFramework("sched-pod-priority")
ginkgo.BeforeEach(func() {
cs = f.ClientSet
ns = f.Namespace.Name
err := framework.CheckTestingNSDeletedExcept(cs, ns)
framework.ExpectNoError(err)
})
// This test verifies that system critical priorities are created automatically and resolved properly.
ginkgo.It("validates critical system priorities are created and resolved", func() {
// Create pods that use system critical priorities and
ginkgo.By("Create pods that use critical system priorities.")
systemPriorityClasses := []string{
scheduling.SystemNodeCritical, scheduling.SystemClusterCritical,
}
for i, spc := range systemPriorityClasses {
pod := createPausePod(f, pausePodConfig{
Name: fmt.Sprintf("pod%d-%v", i, spc),
Namespace: metav1.NamespaceSystem,
PriorityClassName: spc,
})
defer func() {
// Clean-up the pod.
err := f.ClientSet.CoreV1().Pods(pod.Namespace).Delete(pod.Name, metav1.NewDeleteOptions(0))
framework.ExpectNoError(err)
}()
gomega.Expect(pod.Spec.Priority).NotTo(gomega.BeNil())
framework.Logf("Created pod: %v", pod.Name)
}
})
})
// construct a fakecpu so as to set it to status of Node object
// otherwise if we update CPU/Memory/etc, those values will be corrected back by kubelet
var fakecpu v1.ResourceName = "example.com/fakecpu"

View File

@@ -24,6 +24,7 @@ go_test(
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/v1/pod:go_default_library",
"//pkg/apis/scheduling:go_default_library",
"//pkg/controller/nodelifecycle:go_default_library",
"//pkg/features:go_default_library",
"//pkg/scheduler:go_default_library",
@@ -37,6 +38,7 @@ go_test(
"//pkg/scheduler/testing:go_default_library",
"//plugin/pkg/admission/podtolerationrestriction:go_default_library",
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library",
"//plugin/pkg/admission/priority:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",

View File

@@ -27,12 +27,18 @@ import (
policy "k8s.io/api/policy/v1beta1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/apis/scheduling"
_ "k8s.io/kubernetes/pkg/scheduler/algorithmprovider"
"k8s.io/kubernetes/plugin/pkg/admission/priority"
testutils "k8s.io/kubernetes/test/utils"
"k8s.io/klog"
@@ -366,6 +372,102 @@ func TestDisablePreemption(t *testing.T) {
}
}
// This test verifies that system critical priorities are created automatically and resolved properly.
func TestPodPriorityResolution(t *testing.T) {
admission := priority.NewPlugin()
context := initTestScheduler(t, initTestMaster(t, "preemption", admission), true, nil)
defer cleanupTest(t, context)
cs := context.clientSet
// Build clientset and informers for controllers.
externalClientset := kubernetes.NewForConfigOrDie(&restclient.Config{
QPS: -1,
Host: context.httpServer.URL,
ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}})
externalInformers := informers.NewSharedInformerFactory(externalClientset, time.Second)
admission.SetExternalKubeClientSet(externalClientset)
admission.SetExternalKubeInformerFactory(externalInformers)
externalInformers.Start(context.stopCh)
externalInformers.WaitForCacheSync(context.stopCh)
tests := []struct {
Name string
PriorityClass string
Pod *v1.Pod
ExpectedPriority int32
ExpectedError error
}{
{
Name: "SystemNodeCritical priority class",
PriorityClass: scheduling.SystemNodeCritical,
ExpectedPriority: scheduling.SystemCriticalPriority + 1000,
Pod: initPausePod(cs, &pausePodConfig{
Name: fmt.Sprintf("pod1-%v", scheduling.SystemNodeCritical),
Namespace: metav1.NamespaceSystem,
PriorityClassName: scheduling.SystemNodeCritical,
}),
},
{
Name: "SystemClusterCritical priority class",
PriorityClass: scheduling.SystemClusterCritical,
ExpectedPriority: scheduling.SystemCriticalPriority,
Pod: initPausePod(cs, &pausePodConfig{
Name: fmt.Sprintf("pod2-%v", scheduling.SystemClusterCritical),
Namespace: metav1.NamespaceSystem,
PriorityClassName: scheduling.SystemClusterCritical,
}),
},
{
Name: "Invalid priority class should result in error",
PriorityClass: "foo",
ExpectedPriority: scheduling.SystemCriticalPriority,
Pod: initPausePod(cs, &pausePodConfig{
Name: fmt.Sprintf("pod3-%v", scheduling.SystemClusterCritical),
Namespace: metav1.NamespaceSystem,
PriorityClassName: "foo",
}),
ExpectedError: fmt.Errorf("Error creating pause pod: pods \"pod3-system-cluster-critical\" is forbidden: no PriorityClass with name foo was found"),
},
}
// Create a node with some resources and a label.
nodeRes := &v1.ResourceList{
v1.ResourcePods: *resource.NewQuantity(32, resource.DecimalSI),
v1.ResourceCPU: *resource.NewMilliQuantity(500, resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(500, resource.DecimalSI),
}
_, err := createNode(context.clientSet, "node1", nodeRes)
if err != nil {
t.Fatalf("Error creating nodes: %v", err)
}
pods := make([]*v1.Pod, 0, len(tests))
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
pod, err := runPausePod(cs, test.Pod)
if err != nil {
if test.ExpectedError == nil {
t.Fatalf("Test [PodPriority/%v]: Error running pause pod: %v", test.PriorityClass, err)
}
if err.Error() != test.ExpectedError.Error() {
t.Fatalf("Test [PodPriority/%v]: Expected error %v but got error %v", test.PriorityClass, test.ExpectedError, err)
}
return
}
pods = append(pods, pod)
if pod.Spec.Priority != nil {
if *pod.Spec.Priority != test.ExpectedPriority {
t.Errorf("Expected pod %v to have priority %v but was %v", pod.Name, test.ExpectedPriority, pod.Spec.Priority)
}
} else {
t.Errorf("Expected pod %v to have priority %v but was nil", pod.Name, test.PriorityClass)
}
})
}
cleanupPods(cs, t, pods)
cleanupNodes(cs, t)
}
func mkPriorityPodWithGrace(tc *testContext, name string, priority int32, grace int64) *v1.Pod {
defaultPodRes := &v1.ResourceRequirements{Requests: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI),

View File

@@ -462,6 +462,7 @@ type pausePodConfig struct {
NodeName string
SchedulerName string
Priority *int32
PriorityClassName string
}
// initPausePod initializes a pod API object from the given config. It is used
@@ -483,10 +484,11 @@ func initPausePod(cs clientset.Interface, conf *pausePodConfig) *v1.Pod {
Image: imageutils.GetPauseImageName(),
},
},
Tolerations: conf.Tolerations,
NodeName: conf.NodeName,
SchedulerName: conf.SchedulerName,
Priority: conf.Priority,
Tolerations: conf.Tolerations,
NodeName: conf.NodeName,
SchedulerName: conf.SchedulerName,
Priority: conf.Priority,
PriorityClassName: conf.PriorityClassName,
},
}
if conf.Resources != nil {