Repository: kubernetes/kubernetes
File: test/integration/scheduler/preemption/preemption_test.go (Go)

Code before:
		t.Fatalf("Timed out waiting for victim to reach WaitOnPermit")
	}

	// 3. Add small node
	smallNodeRes := map[v1.ResourceName]string{
		v1.ResourceCPU:    "1",
		v1.ResourceMemory: "1Gi",
	}
	smallNode := st.MakeNode().Name("small-node").Capacity(smallNodeRes).Obj()
	if _, err := createNode(cs, smallNode); err != nil {
		t.Fatalf("Error creating node: %v", err)
	}

	// 4. Run preemptor
	t.Logf("Creating preemptor pod")
	_, err = cs.CoreV1().Pods(testCtx.NS.Name).Create(testCtx.Ctx, preemptor, metav1.CreateOptions{})
	if err != nil {
		t.Fatalf("Error creating preemptor: %v", err)
	}

	// 5. Wait for preemptor to be scheduled and victim to be rescheduled
	// Preemptor should eventually be scheduled or cause victim preemption.
	// Since victim is in WaitingOnPermit, Preemptor's preemption logic (PostFilter) should find it.
	// It should call PreemptPod() on waiting victim.

	// The plugin returns error on preemption, so the pod scheduling fails.
	// The pod should NOT be deleted from API server.
	// Instead the Pod should go to the backoff queue and rescheduled eventually.
	t.Logf("Waiting for preemptor to be scheduled")
	err = wait.PollUntilContextTimeout(testCtx.Ctx, 100*time.Millisecond, 15*time.Second, false, func(ctx context.Context) (bool, error) {
		// Check if victim is deleted
		_, err := cs.CoreV1().Pods(testCtx.NS.Name).Get(ctx, victim.Name, metav1.GetOptions{})
		if err != nil {
			if apierrors.IsNotFound(err) {
				return false, fmt.Errorf("victim pod was deleted")
			}
			return false, err
		}
		// Check if preemptor was scheduled
		p, err := cs.CoreV1().Pods(testCtx.NS.Name).Get(ctx, preemptor.Name, metav1.GetOptions{})
		if err != nil {
			if apierrors.IsNotFound(err) {
				return false, fmt.Errorf("victim pod was deleted")
			}
			return false, err
		}
		_, cond := podutil.GetPodCondition(&p.Status, v1.PodScheduled)
		if cond != nil && cond.Status == v1.ConditionTrue {
			return true, nil
		}
		return false, nil

Review comment (bug):
```suggestion
	// The plugin returns error on preemption, so the victim pod scheduling fails.
	// The victim pod should NOT be deleted from API server.
	// Instead the victim pod should go to the backoff queue and rescheduled eventually.
```

Code after:
		v1.ResourceCPU:    "1",
		v1.ResourceMemory: "1Gi",
	}
	smallNode := st.MakeNode().Name("small-node").Capacity(smallNodeRes).Obj()
	if _, err := createNode(cs, smallNode); err != nil {
		t.Fatalf("Error creating node: %v", err)
	}

	t.Logf("Creating preemptor pod")
	_, err = cs.CoreV1().Pods(testCtx.NS.Name).Create(testCtx.Ctx, preemptor, metav1.CreateOptions{})
	if err != nil {
		t.Fatalf("Error creating preemptor: %v", err)
	}

	// Preemptor should eventually be scheduled or cause victim preemption.
	// Since victim is in WaitingOnPermit, Preemptor's preemption logic (PostFilter) should find it.
	// It should call PreemptPod() on waiting victim.
	// The plugin returns error on preemption, so the victim scheduling fails.
	// The victim should NOT be deleted from API server.
	// Instead the victim  should go to the backoff queue and get rescheduled eventually.
	t.Logf("Waiting for preemptor to be scheduled")
	err = wait.PollUntilContextTimeout(testCtx.Ctx, 100*time.Millisecond, 15*time.Second, false, func(ctx context.Context) (bool, error) {
		// Ensure that victim is not deleted
		_, err := cs.CoreV1().Pods(testCtx.NS.Name).Get(ctx, victim.Name, metav1.GetOptions{})
		if err != nil {
			if apierrors.IsNotFound(err) {
				return false, fmt.Errorf("victim pod was deleted")
			}
			return false, err
		}
		// Check if preemptor was scheduled
		p, err := cs.CoreV1().Pods(testCtx.NS.Name).Get(ctx, preemptor.Name, metav1.GetOptions{})
		if err != nil {
			if apierrors.IsNotFound(err) {
				return false, fmt.Errorf("preemptor pod was deleted")
			}
			return false, err
		}
		return p.Spec.NodeName != "", nil
	})
	if err != nil {
		t.Fatalf("Failed waiting for preemptor validation: %v", err)
	}

	t.Logf("waiting for victim to be rescheduled")
	err = wait.PollUntilContextTimeout(testCtx.Ctx, 100*time.Millisecond, 15*time.Second, false, func(ctx context.Context) (bool, error) {
		v, err := cs.CoreV1().Pods(testCtx.NS.Name).Get(ctx, victim.Name, metav1.GetOptions{})
		if err != nil {
			return false, err
		}
		return v.Spec.NodeName != "", nil