Change:
What would you like to be : is used at the beginning of some e2e scheduler tests to wait until the cluster is in a stable state. It currently waits until all existing pods are scheduled, but it should also wait until pods from previous tests are actually deleted. We can do this by assuming that pods should exist only in the kube-system namespace, and so WaitForStableCluster should wait until there are no pods in any other namespace. Why is this needed: /help /sig testing /sig scheduling
/milestone v1.17 /priority critical-urgent
/cc
I'll take this one, can't figure out how to get ci bot to assign to me...
/assign
/remove-help

Discussion:
return stdout, stderr, err } <del> // WaitForStableCluster waits until all existing pods are scheduled and returns their amount. func WaitForStableCluster(c clientset.Interface, masterNodes sets.String) int { timeout := 10 * time.Minute startTime := time.Now() allPods, err := c.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{}) ExpectNoError(err) // API server returns also Pods that succeeded. We need to filter them out. currentPods := make([]v1.Pod, 0, len(allPods.Items)) for _, pod := range allPods.Items { if pod.Status.Phase != v1.PodSucceeded && pod.Status.Phase != v1.PodFailed { currentPods = append(currentPods, pod) } } allPods.Items = currentPods scheduledPods, currentlyNotScheduledPods := e2epod.GetPodsScheduled(masterNodes, allPods) for len(currentlyNotScheduledPods) != 0 { time.Sleep(2 * time.Second) allPods, err := c.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{}) ExpectNoError(err) scheduledPods, currentlyNotScheduledPods = e2epod.GetPodsScheduled(masterNodes, allPods) if startTime.Add(timeout).Before(time.Now()) { Failf("Timed out after %v waiting for stable cluster.", timeout) break } } return len(scheduledPods) } </del> // E2ETestNodePreparer implements testutils.TestNodePreparer interface, which is used // to create/modify Nodes before running a test. type E2ETestNodePreparer struct {

package scheduling <del> import "github.com/onsi/ginkgo" </del> <ins> import ( "time" "github.com/onsi/ginkgo" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" ) </ins> // SIGDescribe annotates the test with the SIG label. func SIGDescribe(text string, body func()) bool { return ginkgo.Describe("[sig-scheduling] "+text, body) } <ins> // WaitForStableCluster waits until all existing pods are scheduled and returns their amount. func WaitForStableCluster(c clientset.Interface, masterNodes sets.String) int { timeout := 10 * time.Minute startTime := time.Now() allPods := getAllPods(c) scheduledSystemPods, currentlyNotScheduledSystemPods := getSystemPods(c) systemPods := scheduledSystemPods + currentlyNotScheduledSystemPods // Wait for system pods to be scheduled, and for pods in all other namespaces to be deleted for currentlyNotScheduledSystemPods != 0 || systemPods != allPods { time.Sleep(2 * time.Second) scheduledSystemPods, currentlyNotScheduledSystemPods := getSystemPods(c) systemPods = scheduledSystemPods + currentlyNotScheduledSystemPods allPods = getAllPods(c) if startTime.Add(timeout).Before(time.Now()) { framework.Failf("Timed out after %v waiting for stable cluster.", timeout) break } } return scheduledSystemPods } // getAllPods lists all pods in the cluster, with succeeded and failed pods filtered out and returns the count func getAllPods(c clientset.Interface) int { allPods, err := c.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{}) framework.ExpectNoError(err, "listing all pods in kube-system namespace while waiting for stable cluster") // API server returns also Pods that succeeded. We need to filter them out. currentPods := make([]v1.Pod, 0, len(allPods.Items)) for _, pod := range allPods.Items { if pod.Status.Phase != v1.PodSucceeded && pod.Status.Phase != v1.PodFailed { currentPods = append(currentPods, pod) } } allPods.Items = currentPods return len(allPods.Items) } // getSystemPods lists the pods in the kube-system namespace and returns the number of scheduled and unscheduled pods func getSystemPods(c clientset.Interface) (int, int) { systemPods, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(metav1.ListOptions{}) framework.ExpectNoError(err, "listing all pods in kube-system namespace while waiting for stable cluster") scheduledSystemPods, currentlyNotScheduledSystemPods := e2epod.GetPodsScheduled(masterNodes, systemPods) return len(scheduledSystemPods), len(currentlyNotScheduledSystemPods) } </ins>

totalPodCapacity += podCapacity.Value() } <del> currentlyScheduledPods := framework.WaitForStableCluster(cs, masterNodes) </del> <ins> currentlyScheduledPods := WaitForStableCluster(cs, masterNodes) </ins> podsNeededForSaturation := int(totalPodCapacity) - currentlyScheduledPods ginkgo.By(fmt.Sprintf("Starting additional %v Pods to fully saturate the cluster max pods and trying to start another one", podsNeededForSaturation))

nodeMaxAllocatable = allocatable.Value() } } <del> framework.WaitForStableCluster(cs, masterNodes) </del> <ins> WaitForStableCluster(cs, masterNodes) </ins> pods, err := cs.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{}) framework.ExpectNoError(err)

Description: Scheduling Pods MUST fail if the resource limits exceed Machine capacity. */ framework.ConformanceIt("validates resource limits of pods that are allowed to run ", func() { <del> framework.WaitForStableCluster(cs, masterNodes) </del> <ins> WaitForStableCluster(cs, masterNodes) </ins> nodeMaxAllocatable := int64(0) nodeToAllocatableMap := make(map[string]int64) for _, node := range nodeList.Items {

ginkgo.By("Trying to schedule Pod with nonempty NodeSelector.") podName := "restricted-pod" <del> framework.WaitForStableCluster(cs, masterNodes) </del> <ins> WaitForStableCluster(cs, masterNodes) </ins> conf := pausePodConfig{ Name:   podName,

ginkgo.By("Trying to schedule Pod with nonempty NodeSelector.") podName := "restricted-pod" <del> framework.WaitForStableCluster(cs, masterNodes) </del> <ins> WaitForStableCluster(cs, masterNodes) </ins> conf := pausePodConfig{ Name: podName,