Change:
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>

Discussion:
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