mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Use generics in scheduling queue's heap
This commit is contained in:
		@@ -147,9 +147,7 @@ func (sched *Scheduler) addPodToSchedulingQueue(obj interface{}) {
 | 
				
			|||||||
	logger := sched.logger
 | 
						logger := sched.logger
 | 
				
			||||||
	pod := obj.(*v1.Pod)
 | 
						pod := obj.(*v1.Pod)
 | 
				
			||||||
	logger.V(3).Info("Add event for unscheduled pod", "pod", klog.KObj(pod))
 | 
						logger.V(3).Info("Add event for unscheduled pod", "pod", klog.KObj(pod))
 | 
				
			||||||
	if err := sched.SchedulingQueue.Add(logger, pod); err != nil {
 | 
						sched.SchedulingQueue.Add(logger, pod)
 | 
				
			||||||
		utilruntime.HandleError(fmt.Errorf("unable to queue %T: %v", obj, err))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (sched *Scheduler) updatePodInSchedulingQueue(oldObj, newObj interface{}) {
 | 
					func (sched *Scheduler) updatePodInSchedulingQueue(oldObj, newObj interface{}) {
 | 
				
			||||||
@@ -172,9 +170,7 @@ func (sched *Scheduler) updatePodInSchedulingQueue(oldObj, newObj interface{}) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logger.V(4).Info("Update event for unscheduled pod", "pod", klog.KObj(newPod))
 | 
						logger.V(4).Info("Update event for unscheduled pod", "pod", klog.KObj(newPod))
 | 
				
			||||||
	if err := sched.SchedulingQueue.Update(logger, oldPod, newPod); err != nil {
 | 
						sched.SchedulingQueue.Update(logger, oldPod, newPod)
 | 
				
			||||||
		utilruntime.HandleError(fmt.Errorf("unable to update %T: %v", newObj, err))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (sched *Scheduler) deletePodFromSchedulingQueue(obj interface{}) {
 | 
					func (sched *Scheduler) deletePodFromSchedulingQueue(obj interface{}) {
 | 
				
			||||||
@@ -199,9 +195,7 @@ func (sched *Scheduler) deletePodFromSchedulingQueue(obj interface{}) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logger.V(3).Info("Delete event for unscheduled pod", "pod", klog.KObj(pod))
 | 
						logger.V(3).Info("Delete event for unscheduled pod", "pod", klog.KObj(pod))
 | 
				
			||||||
	if err := sched.SchedulingQueue.Delete(pod); err != nil {
 | 
						sched.SchedulingQueue.Delete(pod)
 | 
				
			||||||
		utilruntime.HandleError(fmt.Errorf("unable to dequeue %T: %v", obj, err))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fwk, err := sched.frameworkForPod(pod)
 | 
						fwk, err := sched.frameworkForPod(pod)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		// This shouldn't happen, because we only accept for scheduling the pods
 | 
							// This shouldn't happen, because we only accept for scheduling the pods
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,29 +24,28 @@ import (
 | 
				
			|||||||
	"container/heap"
 | 
						"container/heap"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/client-go/tools/cache"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/metrics"
 | 
						"k8s.io/kubernetes/pkg/scheduler/metrics"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// KeyFunc is a function type to get the key from an object.
 | 
					// KeyFunc is a function type to get the key from an object.
 | 
				
			||||||
type KeyFunc func(obj interface{}) (string, error)
 | 
					type KeyFunc[T any] func(obj T) string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type heapItem struct {
 | 
					type heapItem[T any] struct {
 | 
				
			||||||
	obj   interface{} // The object which is stored in the heap.
 | 
						obj   T   // The object which is stored in the heap.
 | 
				
			||||||
	index int         // The index of the object's key in the Heap.queue.
 | 
						index int // The index of the object's key in the Heap.queue.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type itemKeyValue struct {
 | 
					type itemKeyValue[T any] struct {
 | 
				
			||||||
	key string
 | 
						key string
 | 
				
			||||||
	obj interface{}
 | 
						obj T
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// data is an internal struct that implements the standard heap interface
 | 
					// data is an internal struct that implements the standard heap interface
 | 
				
			||||||
// and keeps the data stored in the heap.
 | 
					// and keeps the data stored in the heap.
 | 
				
			||||||
type data struct {
 | 
					type data[T any] struct {
 | 
				
			||||||
	// items is a map from key of the objects to the objects and their index.
 | 
						// items is a map from key of the objects to the objects and their index.
 | 
				
			||||||
	// We depend on the property that items in the map are in the queue and vice versa.
 | 
						// We depend on the property that items in the map are in the queue and vice versa.
 | 
				
			||||||
	items map[string]*heapItem
 | 
						items map[string]*heapItem[T]
 | 
				
			||||||
	// queue implements a heap data structure and keeps the order of elements
 | 
						// queue implements a heap data structure and keeps the order of elements
 | 
				
			||||||
	// according to the heap invariant. The queue keeps the keys of objects stored
 | 
						// according to the heap invariant. The queue keeps the keys of objects stored
 | 
				
			||||||
	// in "items".
 | 
						// in "items".
 | 
				
			||||||
@@ -54,18 +53,18 @@ type data struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// keyFunc is used to make the key used for queued item insertion and retrieval, and
 | 
						// keyFunc is used to make the key used for queued item insertion and retrieval, and
 | 
				
			||||||
	// should be deterministic.
 | 
						// should be deterministic.
 | 
				
			||||||
	keyFunc KeyFunc
 | 
						keyFunc KeyFunc[T]
 | 
				
			||||||
	// lessFunc is used to compare two objects in the heap.
 | 
						// lessFunc is used to compare two objects in the heap.
 | 
				
			||||||
	lessFunc lessFunc
 | 
						lessFunc LessFunc[T]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	_ = heap.Interface(&data{}) // heapData is a standard heap
 | 
						_ = heap.Interface(&data[any]{}) // heapData is a standard heap
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Less compares two objects and returns true if the first one should go
 | 
					// Less compares two objects and returns true if the first one should go
 | 
				
			||||||
// in front of the second one in the heap.
 | 
					// in front of the second one in the heap.
 | 
				
			||||||
func (h *data) Less(i, j int) bool {
 | 
					func (h *data[T]) Less(i, j int) bool {
 | 
				
			||||||
	if i > len(h.queue) || j > len(h.queue) {
 | 
						if i > len(h.queue) || j > len(h.queue) {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -81,11 +80,11 @@ func (h *data) Less(i, j int) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Len returns the number of items in the Heap.
 | 
					// Len returns the number of items in the Heap.
 | 
				
			||||||
func (h *data) Len() int { return len(h.queue) }
 | 
					func (h *data[T]) Len() int { return len(h.queue) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Swap implements swapping of two elements in the heap. This is a part of standard
 | 
					// Swap implements swapping of two elements in the heap. This is a part of standard
 | 
				
			||||||
// heap interface and should never be called directly.
 | 
					// heap interface and should never be called directly.
 | 
				
			||||||
func (h *data) Swap(i, j int) {
 | 
					func (h *data[T]) Swap(i, j int) {
 | 
				
			||||||
	h.queue[i], h.queue[j] = h.queue[j], h.queue[i]
 | 
						h.queue[i], h.queue[j] = h.queue[j], h.queue[i]
 | 
				
			||||||
	item := h.items[h.queue[i]]
 | 
						item := h.items[h.queue[i]]
 | 
				
			||||||
	item.index = i
 | 
						item.index = i
 | 
				
			||||||
@@ -93,16 +92,16 @@ func (h *data) Swap(i, j int) {
 | 
				
			|||||||
	item.index = j
 | 
						item.index = j
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Push is supposed to be called by heap.Push only.
 | 
					// Push is supposed to be called by container/heap.Push only.
 | 
				
			||||||
func (h *data) Push(kv interface{}) {
 | 
					func (h *data[T]) Push(kv interface{}) {
 | 
				
			||||||
	keyValue := kv.(*itemKeyValue)
 | 
						keyValue := kv.(*itemKeyValue[T])
 | 
				
			||||||
	n := len(h.queue)
 | 
						n := len(h.queue)
 | 
				
			||||||
	h.items[keyValue.key] = &heapItem{keyValue.obj, n}
 | 
						h.items[keyValue.key] = &heapItem[T]{keyValue.obj, n}
 | 
				
			||||||
	h.queue = append(h.queue, keyValue.key)
 | 
						h.queue = append(h.queue, keyValue.key)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Pop is supposed to be called by heap.Pop only.
 | 
					// Pop is supposed to be called by container/heap.Pop only.
 | 
				
			||||||
func (h *data) Pop() interface{} {
 | 
					func (h *data[T]) Pop() interface{} {
 | 
				
			||||||
	key := h.queue[len(h.queue)-1]
 | 
						key := h.queue[len(h.queue)-1]
 | 
				
			||||||
	h.queue = h.queue[0 : len(h.queue)-1]
 | 
						h.queue = h.queue[0 : len(h.queue)-1]
 | 
				
			||||||
	item, ok := h.items[key]
 | 
						item, ok := h.items[key]
 | 
				
			||||||
@@ -114,56 +113,44 @@ func (h *data) Pop() interface{} {
 | 
				
			|||||||
	return item.obj
 | 
						return item.obj
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Peek is supposed to be called by heap.Peek only.
 | 
					// Peek returns the head of the heap without removing it.
 | 
				
			||||||
func (h *data) Peek() interface{} {
 | 
					func (h *data[T]) Peek() (T, bool) {
 | 
				
			||||||
	if len(h.queue) > 0 {
 | 
						if len(h.queue) > 0 {
 | 
				
			||||||
		return h.items[h.queue[0]].obj
 | 
							return h.items[h.queue[0]].obj, true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						var zero T
 | 
				
			||||||
 | 
						return zero, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Heap is a producer/consumer queue that implements a heap data structure.
 | 
					// Heap is a producer/consumer queue that implements a heap data structure.
 | 
				
			||||||
// It can be used to implement priority queues and similar data structures.
 | 
					// It can be used to implement priority queues and similar data structures.
 | 
				
			||||||
type Heap struct {
 | 
					type Heap[T any] struct {
 | 
				
			||||||
	// data stores objects and has a queue that keeps their ordering according
 | 
						// data stores objects and has a queue that keeps their ordering according
 | 
				
			||||||
	// to the heap invariant.
 | 
						// to the heap invariant.
 | 
				
			||||||
	data *data
 | 
						data *data[T]
 | 
				
			||||||
	// metricRecorder updates the counter when elements of a heap get added or
 | 
						// metricRecorder updates the counter when elements of a heap get added or
 | 
				
			||||||
	// removed, and it does nothing if it's nil
 | 
						// removed, and it does nothing if it's nil
 | 
				
			||||||
	metricRecorder metrics.MetricRecorder
 | 
						metricRecorder metrics.MetricRecorder
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Add inserts an item, and puts it in the queue. The item is updated if it
 | 
					// AddOrUpdate inserts an item, and puts it in the queue. The item is updated if it
 | 
				
			||||||
// already exists.
 | 
					// already exists.
 | 
				
			||||||
func (h *Heap) Add(obj interface{}) error {
 | 
					func (h *Heap[T]) AddOrUpdate(obj T) {
 | 
				
			||||||
	key, err := h.data.keyFunc(obj)
 | 
						key := h.data.keyFunc(obj)
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return cache.KeyError{Obj: obj, Err: err}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, exists := h.data.items[key]; exists {
 | 
						if _, exists := h.data.items[key]; exists {
 | 
				
			||||||
		h.data.items[key].obj = obj
 | 
							h.data.items[key].obj = obj
 | 
				
			||||||
		heap.Fix(h.data, h.data.items[key].index)
 | 
							heap.Fix(h.data, h.data.items[key].index)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		heap.Push(h.data, &itemKeyValue{key, obj})
 | 
							heap.Push(h.data, &itemKeyValue[T]{key, obj})
 | 
				
			||||||
		if h.metricRecorder != nil {
 | 
							if h.metricRecorder != nil {
 | 
				
			||||||
			h.metricRecorder.Inc()
 | 
								h.metricRecorder.Inc()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Update is the same as Add in this implementation. When the item does not
 | 
					 | 
				
			||||||
// exist, it is added.
 | 
					 | 
				
			||||||
func (h *Heap) Update(obj interface{}) error {
 | 
					 | 
				
			||||||
	return h.Add(obj)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Delete removes an item.
 | 
					// Delete removes an item.
 | 
				
			||||||
func (h *Heap) Delete(obj interface{}) error {
 | 
					func (h *Heap[T]) Delete(obj T) error {
 | 
				
			||||||
	key, err := h.data.keyFunc(obj)
 | 
						key := h.data.keyFunc(obj)
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return cache.KeyError{Obj: obj, Err: err}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if item, ok := h.data.items[key]; ok {
 | 
						if item, ok := h.data.items[key]; ok {
 | 
				
			||||||
		heap.Remove(h.data, item.index)
 | 
							heap.Remove(h.data, item.index)
 | 
				
			||||||
		if h.metricRecorder != nil {
 | 
							if h.metricRecorder != nil {
 | 
				
			||||||
@@ -175,43 +162,48 @@ func (h *Heap) Delete(obj interface{}) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Peek returns the head of the heap without removing it.
 | 
					// Peek returns the head of the heap without removing it.
 | 
				
			||||||
func (h *Heap) Peek() interface{} {
 | 
					func (h *Heap[T]) Peek() (T, bool) {
 | 
				
			||||||
	return h.data.Peek()
 | 
						return h.data.Peek()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Pop returns the head of the heap and removes it.
 | 
					// Pop returns the head of the heap and removes it.
 | 
				
			||||||
func (h *Heap) Pop() (interface{}, error) {
 | 
					func (h *Heap[T]) Pop() (T, error) {
 | 
				
			||||||
	obj := heap.Pop(h.data)
 | 
						obj := heap.Pop(h.data)
 | 
				
			||||||
	if obj != nil {
 | 
						if obj != nil {
 | 
				
			||||||
		if h.metricRecorder != nil {
 | 
							if h.metricRecorder != nil {
 | 
				
			||||||
			h.metricRecorder.Dec()
 | 
								h.metricRecorder.Dec()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return obj, nil
 | 
							return obj.(T), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, fmt.Errorf("object was removed from heap data")
 | 
						var zero T
 | 
				
			||||||
 | 
						return zero, fmt.Errorf("heap is empty")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Get returns the requested item, or sets exists=false.
 | 
					// Get returns the requested item, or sets exists=false.
 | 
				
			||||||
func (h *Heap) Get(obj interface{}) (interface{}, bool, error) {
 | 
					func (h *Heap[T]) Get(obj T) (T, bool) {
 | 
				
			||||||
	key, err := h.data.keyFunc(obj)
 | 
						key := h.data.keyFunc(obj)
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, false, cache.KeyError{Obj: obj, Err: err}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return h.GetByKey(key)
 | 
						return h.GetByKey(key)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetByKey returns the requested item, or sets exists=false.
 | 
					// GetByKey returns the requested item, or sets exists=false.
 | 
				
			||||||
func (h *Heap) GetByKey(key string) (interface{}, bool, error) {
 | 
					func (h *Heap[T]) GetByKey(key string) (T, bool) {
 | 
				
			||||||
	item, exists := h.data.items[key]
 | 
						item, exists := h.data.items[key]
 | 
				
			||||||
	if !exists {
 | 
						if !exists {
 | 
				
			||||||
		return nil, false, nil
 | 
							var zero T
 | 
				
			||||||
 | 
							return zero, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return item.obj, true, nil
 | 
						return item.obj, true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Heap[T]) Has(obj T) bool {
 | 
				
			||||||
 | 
						key := h.data.keyFunc(obj)
 | 
				
			||||||
 | 
						_, ok := h.GetByKey(key)
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// List returns a list of all the items.
 | 
					// List returns a list of all the items.
 | 
				
			||||||
func (h *Heap) List() []interface{} {
 | 
					func (h *Heap[T]) List() []T {
 | 
				
			||||||
	list := make([]interface{}, 0, len(h.data.items))
 | 
						list := make([]T, 0, len(h.data.items))
 | 
				
			||||||
	for _, item := range h.data.items {
 | 
						for _, item := range h.data.items {
 | 
				
			||||||
		list = append(list, item.obj)
 | 
							list = append(list, item.obj)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -219,20 +211,20 @@ func (h *Heap) List() []interface{} {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Len returns the number of items in the heap.
 | 
					// Len returns the number of items in the heap.
 | 
				
			||||||
func (h *Heap) Len() int {
 | 
					func (h *Heap[T]) Len() int {
 | 
				
			||||||
	return len(h.data.queue)
 | 
						return len(h.data.queue)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// New returns a Heap which can be used to queue up items to process.
 | 
					// New returns a Heap which can be used to queue up items to process.
 | 
				
			||||||
func New(keyFn KeyFunc, lessFn lessFunc) *Heap {
 | 
					func New[T any](keyFn KeyFunc[T], lessFn LessFunc[T]) *Heap[T] {
 | 
				
			||||||
	return NewWithRecorder(keyFn, lessFn, nil)
 | 
						return NewWithRecorder(keyFn, lessFn, nil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewWithRecorder wraps an optional metricRecorder to compose a Heap object.
 | 
					// NewWithRecorder wraps an optional metricRecorder to compose a Heap object.
 | 
				
			||||||
func NewWithRecorder(keyFn KeyFunc, lessFn lessFunc, metricRecorder metrics.MetricRecorder) *Heap {
 | 
					func NewWithRecorder[T any](keyFn KeyFunc[T], lessFn LessFunc[T], metricRecorder metrics.MetricRecorder) *Heap[T] {
 | 
				
			||||||
	return &Heap{
 | 
						return &Heap[T]{
 | 
				
			||||||
		data: &data{
 | 
							data: &data[T]{
 | 
				
			||||||
			items:    map[string]*heapItem{},
 | 
								items:    map[string]*heapItem[T]{},
 | 
				
			||||||
			queue:    []string{},
 | 
								queue:    []string{},
 | 
				
			||||||
			keyFunc:  keyFn,
 | 
								keyFunc:  keyFn,
 | 
				
			||||||
			lessFunc: lessFn,
 | 
								lessFunc: lessFn,
 | 
				
			||||||
@@ -241,6 +233,6 @@ func NewWithRecorder(keyFn KeyFunc, lessFn lessFunc, metricRecorder metrics.Metr
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// lessFunc is a function that receives two items and returns true if the first
 | 
					// LessFunc is a function that receives two items and returns true if the first
 | 
				
			||||||
// item should be placed before the second one when the list is sorted.
 | 
					// item should be placed before the second one when the list is sorted.
 | 
				
			||||||
type lessFunc = func(item1, item2 interface{}) bool
 | 
					type LessFunc[T any] func(item1, item2 T) bool
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,8 +23,8 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func testHeapObjectKeyFunc(obj interface{}) (string, error) {
 | 
					func testHeapObjectKeyFunc(obj testHeapObject) string {
 | 
				
			||||||
	return obj.(testHeapObject).name, nil
 | 
						return obj.name
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type testHeapObject struct {
 | 
					type testHeapObject struct {
 | 
				
			||||||
@@ -56,9 +56,9 @@ func mkHeapObj(name string, val interface{}) testHeapObject {
 | 
				
			|||||||
	return testHeapObject{name: name, val: val}
 | 
						return testHeapObject{name: name, val: val}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func compareInts(val1 interface{}, val2 interface{}) bool {
 | 
					func compareInts(val1 testHeapObject, val2 testHeapObject) bool {
 | 
				
			||||||
	first := val1.(testHeapObject).val.(int)
 | 
						first := val1.val.(int)
 | 
				
			||||||
	second := val2.(testHeapObject).val.(int)
 | 
						second := val2.val.(int)
 | 
				
			||||||
	return first < second
 | 
						return first < second
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -67,17 +67,18 @@ func TestHeapBasic(t *testing.T) {
 | 
				
			|||||||
	h := New(testHeapObjectKeyFunc, compareInts)
 | 
						h := New(testHeapObjectKeyFunc, compareInts)
 | 
				
			||||||
	const amount = 500
 | 
						const amount = 500
 | 
				
			||||||
	var i int
 | 
						var i int
 | 
				
			||||||
 | 
						var zero testHeapObject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// empty queue
 | 
						// empty queue
 | 
				
			||||||
	if item := h.Peek(); item != nil {
 | 
						if item, ok := h.Peek(); ok || item != zero {
 | 
				
			||||||
		t.Errorf("expected nil object but got %v", item)
 | 
							t.Errorf("expected nil object but got %v", item)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i = amount; i > 0; i-- {
 | 
						for i = amount; i > 0; i-- {
 | 
				
			||||||
		h.Add(mkHeapObj(string([]rune{'a', rune(i)}), i))
 | 
							h.AddOrUpdate(mkHeapObj(string([]rune{'a', rune(i)}), i))
 | 
				
			||||||
		// Retrieve head without removing it
 | 
							// Retrieve head without removing it
 | 
				
			||||||
		head := h.Peek()
 | 
							head, ok := h.Peek()
 | 
				
			||||||
		if e, a := i, head.(testHeapObject).val; a != e {
 | 
							if e, a := i, head.val; !ok || a != e {
 | 
				
			||||||
			t.Errorf("expected %d, got %d", e, a)
 | 
								t.Errorf("expected %d, got %d", e, a)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -85,41 +86,44 @@ func TestHeapBasic(t *testing.T) {
 | 
				
			|||||||
	// Make sure that the numbers are popped in ascending order.
 | 
						// Make sure that the numbers are popped in ascending order.
 | 
				
			||||||
	prevNum := 0
 | 
						prevNum := 0
 | 
				
			||||||
	for i := 0; i < amount; i++ {
 | 
						for i := 0; i < amount; i++ {
 | 
				
			||||||
		obj, err := h.Pop()
 | 
							item, err := h.Pop()
 | 
				
			||||||
		num := obj.(testHeapObject).val.(int)
 | 
							num := item.val.(int)
 | 
				
			||||||
		// All the items must be sorted.
 | 
							// All the items must be sorted.
 | 
				
			||||||
		if err != nil || prevNum > num {
 | 
							if err != nil || prevNum > num {
 | 
				
			||||||
			t.Errorf("got %v out of order, last was %v", obj, prevNum)
 | 
								t.Errorf("got %v out of order, last was %v", item, prevNum)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		prevNum = num
 | 
							prevNum = num
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests Heap.Add and ensures that heap invariant is preserved after adding items.
 | 
					// TestHeap_AddOrUpdate_Add tests add capabilities of Heap.AddOrUpdate
 | 
				
			||||||
func TestHeap_Add(t *testing.T) {
 | 
					// and ensures that heap invariant is preserved after adding items.
 | 
				
			||||||
 | 
					func TestHeap_AddOrUpdate_Add(t *testing.T) {
 | 
				
			||||||
	h := New(testHeapObjectKeyFunc, compareInts)
 | 
						h := New(testHeapObjectKeyFunc, compareInts)
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 10))
 | 
						h.AddOrUpdate(mkHeapObj("foo", 10))
 | 
				
			||||||
	h.Add(mkHeapObj("bar", 1))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 1))
 | 
				
			||||||
	h.Add(mkHeapObj("baz", 11))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 11))
 | 
				
			||||||
	h.Add(mkHeapObj("zab", 30))
 | 
						h.AddOrUpdate(mkHeapObj("zab", 30))
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 13)) // This updates "foo".
 | 
						h.AddOrUpdate(mkHeapObj("foo", 13)) // This updates "foo".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	item, err := h.Pop()
 | 
						item, err := h.Pop()
 | 
				
			||||||
	if e, a := 1, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 1, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	item, err = h.Pop()
 | 
						item, err = h.Pop()
 | 
				
			||||||
	if e, a := 11, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 11, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	h.Delete(mkHeapObj("baz", 11)) // Nothing is deleted.
 | 
						if err := h.Delete(mkHeapObj("baz", 11)); err == nil { // Nothing is deleted.
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 14))    // foo is updated.
 | 
							t.Fatalf("nothing should be deleted from the heap")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						h.AddOrUpdate(mkHeapObj("foo", 14)) // foo is updated.
 | 
				
			||||||
	item, err = h.Pop()
 | 
						item, err = h.Pop()
 | 
				
			||||||
	if e, a := 14, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 14, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	item, err = h.Pop()
 | 
						item, err = h.Pop()
 | 
				
			||||||
	if e, a := 30, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 30, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -128,21 +132,21 @@ func TestHeap_Add(t *testing.T) {
 | 
				
			|||||||
// preserved after deleting items.
 | 
					// preserved after deleting items.
 | 
				
			||||||
func TestHeap_Delete(t *testing.T) {
 | 
					func TestHeap_Delete(t *testing.T) {
 | 
				
			||||||
	h := New(testHeapObjectKeyFunc, compareInts)
 | 
						h := New(testHeapObjectKeyFunc, compareInts)
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 10))
 | 
						h.AddOrUpdate(mkHeapObj("foo", 10))
 | 
				
			||||||
	h.Add(mkHeapObj("bar", 1))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 1))
 | 
				
			||||||
	h.Add(mkHeapObj("bal", 31))
 | 
						h.AddOrUpdate(mkHeapObj("bal", 31))
 | 
				
			||||||
	h.Add(mkHeapObj("baz", 11))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 11))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Delete head. Delete should work with "key" and doesn't care about the value.
 | 
						// Delete head. Delete should work with "key" and doesn't care about the value.
 | 
				
			||||||
	if err := h.Delete(mkHeapObj("bar", 200)); err != nil {
 | 
						if err := h.Delete(mkHeapObj("bar", 200)); err != nil {
 | 
				
			||||||
		t.Fatalf("Failed to delete head.")
 | 
							t.Fatalf("Failed to delete head.")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	item, err := h.Pop()
 | 
						item, err := h.Pop()
 | 
				
			||||||
	if e, a := 10, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 10, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	h.Add(mkHeapObj("zab", 30))
 | 
						h.AddOrUpdate(mkHeapObj("zab", 30))
 | 
				
			||||||
	h.Add(mkHeapObj("faz", 30))
 | 
						h.AddOrUpdate(mkHeapObj("faz", 30))
 | 
				
			||||||
	len := h.data.Len()
 | 
						len := h.data.Len()
 | 
				
			||||||
	// Delete non-existing item.
 | 
						// Delete non-existing item.
 | 
				
			||||||
	if err = h.Delete(mkHeapObj("non-existent", 10)); err == nil || len != h.data.Len() {
 | 
						if err = h.Delete(mkHeapObj("non-existent", 10)); err == nil || len != h.data.Len() {
 | 
				
			||||||
@@ -157,11 +161,11 @@ func TestHeap_Delete(t *testing.T) {
 | 
				
			|||||||
		t.Fatalf("Failed to delete item.")
 | 
							t.Fatalf("Failed to delete item.")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	item, err = h.Pop()
 | 
						item, err = h.Pop()
 | 
				
			||||||
	if e, a := 11, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 11, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	item, err = h.Pop()
 | 
						item, err = h.Pop()
 | 
				
			||||||
	if e, a := 30, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 30, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if h.data.Len() != 0 {
 | 
						if h.data.Len() != 0 {
 | 
				
			||||||
@@ -169,26 +173,26 @@ func TestHeap_Delete(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TestHeap_Update tests Heap.Update and ensures that heap invariant is
 | 
					// TestHeap_AddOrUpdate_Update tests update capabilities of Heap.Update
 | 
				
			||||||
// preserved after adding items.
 | 
					// and ensures that heap invariant is preserved after adding items.
 | 
				
			||||||
func TestHeap_Update(t *testing.T) {
 | 
					func TestHeap_AddOrUpdate_Update(t *testing.T) {
 | 
				
			||||||
	h := New(testHeapObjectKeyFunc, compareInts)
 | 
						h := New(testHeapObjectKeyFunc, compareInts)
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 10))
 | 
						h.AddOrUpdate(mkHeapObj("foo", 10))
 | 
				
			||||||
	h.Add(mkHeapObj("bar", 1))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 1))
 | 
				
			||||||
	h.Add(mkHeapObj("bal", 31))
 | 
						h.AddOrUpdate(mkHeapObj("bal", 31))
 | 
				
			||||||
	h.Add(mkHeapObj("baz", 11))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 11))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update an item to a value that should push it to the head.
 | 
						// Update an item to a value that should push it to the head.
 | 
				
			||||||
	h.Update(mkHeapObj("baz", 0))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 0))
 | 
				
			||||||
	if h.data.queue[0] != "baz" || h.data.items["baz"].index != 0 {
 | 
						if h.data.queue[0] != "baz" || h.data.items["baz"].index != 0 {
 | 
				
			||||||
		t.Fatalf("expected baz to be at the head")
 | 
							t.Fatalf("expected baz to be at the head")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	item, err := h.Pop()
 | 
						item, err := h.Pop()
 | 
				
			||||||
	if e, a := 0, item.(testHeapObject).val; err != nil || a != e {
 | 
						if e, a := 0, item.val; err != nil || a != e {
 | 
				
			||||||
		t.Fatalf("expected %d, got %d", e, a)
 | 
							t.Fatalf("expected %d, got %d", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Update bar to push it farther back in the queue.
 | 
						// Update bar to push it farther back in the queue.
 | 
				
			||||||
	h.Update(mkHeapObj("bar", 100))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 100))
 | 
				
			||||||
	if h.data.queue[0] != "foo" || h.data.items["foo"].index != 0 {
 | 
						if h.data.queue[0] != "foo" || h.data.items["foo"].index != 0 {
 | 
				
			||||||
		t.Fatalf("expected foo to be at the head")
 | 
							t.Fatalf("expected foo to be at the head")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -197,19 +201,19 @@ func TestHeap_Update(t *testing.T) {
 | 
				
			|||||||
// TestHeap_Get tests Heap.Get.
 | 
					// TestHeap_Get tests Heap.Get.
 | 
				
			||||||
func TestHeap_Get(t *testing.T) {
 | 
					func TestHeap_Get(t *testing.T) {
 | 
				
			||||||
	h := New(testHeapObjectKeyFunc, compareInts)
 | 
						h := New(testHeapObjectKeyFunc, compareInts)
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 10))
 | 
						h.AddOrUpdate(mkHeapObj("foo", 10))
 | 
				
			||||||
	h.Add(mkHeapObj("bar", 1))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 1))
 | 
				
			||||||
	h.Add(mkHeapObj("bal", 31))
 | 
						h.AddOrUpdate(mkHeapObj("bal", 31))
 | 
				
			||||||
	h.Add(mkHeapObj("baz", 11))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 11))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get works with the key.
 | 
						// Get works with the key.
 | 
				
			||||||
	obj, exists, err := h.Get(mkHeapObj("baz", 0))
 | 
						item, exists := h.Get(mkHeapObj("baz", 0))
 | 
				
			||||||
	if err != nil || exists == false || obj.(testHeapObject).val != 11 {
 | 
						if !exists || item.val != 11 {
 | 
				
			||||||
		t.Fatalf("unexpected error in getting element")
 | 
							t.Fatalf("unexpected error in getting element")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Get non-existing object.
 | 
						// Get non-existing object.
 | 
				
			||||||
	_, exists, err = h.Get(mkHeapObj("non-existing", 0))
 | 
						_, exists = h.Get(mkHeapObj("non-existing", 0))
 | 
				
			||||||
	if err != nil || exists {
 | 
						if exists {
 | 
				
			||||||
		t.Fatalf("didn't expect to get any object")
 | 
							t.Fatalf("didn't expect to get any object")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -217,18 +221,18 @@ func TestHeap_Get(t *testing.T) {
 | 
				
			|||||||
// TestHeap_GetByKey tests Heap.GetByKey and is very similar to TestHeap_Get.
 | 
					// TestHeap_GetByKey tests Heap.GetByKey and is very similar to TestHeap_Get.
 | 
				
			||||||
func TestHeap_GetByKey(t *testing.T) {
 | 
					func TestHeap_GetByKey(t *testing.T) {
 | 
				
			||||||
	h := New(testHeapObjectKeyFunc, compareInts)
 | 
						h := New(testHeapObjectKeyFunc, compareInts)
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 10))
 | 
						h.AddOrUpdate(mkHeapObj("foo", 10))
 | 
				
			||||||
	h.Add(mkHeapObj("bar", 1))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 1))
 | 
				
			||||||
	h.Add(mkHeapObj("bal", 31))
 | 
						h.AddOrUpdate(mkHeapObj("bal", 31))
 | 
				
			||||||
	h.Add(mkHeapObj("baz", 11))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 11))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	obj, exists, err := h.GetByKey("baz")
 | 
						item, exists := h.GetByKey("baz")
 | 
				
			||||||
	if err != nil || !exists || obj.(testHeapObject).val != 11 {
 | 
						if !exists || item.val != 11 {
 | 
				
			||||||
		t.Fatalf("unexpected error in getting element")
 | 
							t.Fatalf("unexpected error in getting element")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Get non-existing object.
 | 
						// Get non-existing object.
 | 
				
			||||||
	_, exists, err = h.GetByKey("non-existing")
 | 
						_, exists = h.GetByKey("non-existing")
 | 
				
			||||||
	if err != nil || exists {
 | 
						if exists {
 | 
				
			||||||
		t.Fatalf("didn't expect to get any object")
 | 
							t.Fatalf("didn't expect to get any object")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -249,14 +253,13 @@ func TestHeap_List(t *testing.T) {
 | 
				
			|||||||
		"faz": 30,
 | 
							"faz": 30,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for k, v := range items {
 | 
						for k, v := range items {
 | 
				
			||||||
		h.Add(mkHeapObj(k, v))
 | 
							h.AddOrUpdate(mkHeapObj(k, v))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	list = h.List()
 | 
						list = h.List()
 | 
				
			||||||
	if len(list) != len(items) {
 | 
						if len(list) != len(items) {
 | 
				
			||||||
		t.Errorf("expected %d items, got %d", len(items), len(list))
 | 
							t.Errorf("expected %d items, got %d", len(items), len(list))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, obj := range list {
 | 
						for _, heapObj := range list {
 | 
				
			||||||
		heapObj := obj.(testHeapObject)
 | 
					 | 
				
			||||||
		v, ok := items[heapObj.name]
 | 
							v, ok := items[heapObj.name]
 | 
				
			||||||
		if !ok || v != heapObj.val {
 | 
							if !ok || v != heapObj.val {
 | 
				
			||||||
			t.Errorf("unexpected item in the list: %v", heapObj)
 | 
								t.Errorf("unexpected item in the list: %v", heapObj)
 | 
				
			||||||
@@ -267,10 +270,10 @@ func TestHeap_List(t *testing.T) {
 | 
				
			|||||||
func TestHeapWithRecorder(t *testing.T) {
 | 
					func TestHeapWithRecorder(t *testing.T) {
 | 
				
			||||||
	metricRecorder := new(testMetricRecorder)
 | 
						metricRecorder := new(testMetricRecorder)
 | 
				
			||||||
	h := NewWithRecorder(testHeapObjectKeyFunc, compareInts, metricRecorder)
 | 
						h := NewWithRecorder(testHeapObjectKeyFunc, compareInts, metricRecorder)
 | 
				
			||||||
	h.Add(mkHeapObj("foo", 10))
 | 
						h.AddOrUpdate(mkHeapObj("foo", 10))
 | 
				
			||||||
	h.Add(mkHeapObj("bar", 1))
 | 
						h.AddOrUpdate(mkHeapObj("bar", 1))
 | 
				
			||||||
	h.Add(mkHeapObj("baz", 100))
 | 
						h.AddOrUpdate(mkHeapObj("baz", 100))
 | 
				
			||||||
	h.Add(mkHeapObj("qux", 11))
 | 
						h.AddOrUpdate(mkHeapObj("qux", 11))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if *metricRecorder != 4 {
 | 
						if *metricRecorder != 4 {
 | 
				
			||||||
		t.Errorf("expected count to be 4 but got %d", *metricRecorder)
 | 
							t.Errorf("expected count to be 4 but got %d", *metricRecorder)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,7 +93,7 @@ type PreEnqueueCheck func(pod *v1.Pod) bool
 | 
				
			|||||||
// makes it easy to use those data structures as a SchedulingQueue.
 | 
					// makes it easy to use those data structures as a SchedulingQueue.
 | 
				
			||||||
type SchedulingQueue interface {
 | 
					type SchedulingQueue interface {
 | 
				
			||||||
	framework.PodNominator
 | 
						framework.PodNominator
 | 
				
			||||||
	Add(logger klog.Logger, pod *v1.Pod) error
 | 
						Add(logger klog.Logger, pod *v1.Pod)
 | 
				
			||||||
	// Activate moves the given pods to activeQ iff they're in unschedulablePods or backoffQ.
 | 
						// Activate moves the given pods to activeQ iff they're in unschedulablePods or backoffQ.
 | 
				
			||||||
	// The passed-in pods are originally compiled from plugins that want to activate Pods,
 | 
						// The passed-in pods are originally compiled from plugins that want to activate Pods,
 | 
				
			||||||
	// by injecting the pods through a reserved CycleState struct (PodsToActivate).
 | 
						// by injecting the pods through a reserved CycleState struct (PodsToActivate).
 | 
				
			||||||
@@ -112,8 +112,8 @@ type SchedulingQueue interface {
 | 
				
			|||||||
	// Done must be called for pod returned by Pop. This allows the queue to
 | 
						// Done must be called for pod returned by Pop. This allows the queue to
 | 
				
			||||||
	// keep track of which pods are currently being processed.
 | 
						// keep track of which pods are currently being processed.
 | 
				
			||||||
	Done(types.UID)
 | 
						Done(types.UID)
 | 
				
			||||||
	Update(logger klog.Logger, oldPod, newPod *v1.Pod) error
 | 
						Update(logger klog.Logger, oldPod, newPod *v1.Pod)
 | 
				
			||||||
	Delete(pod *v1.Pod) error
 | 
						Delete(pod *v1.Pod)
 | 
				
			||||||
	// TODO(sanposhiho): move all PreEnqueueCheck to Requeue and delete it from this parameter eventually.
 | 
						// TODO(sanposhiho): move all PreEnqueueCheck to Requeue and delete it from this parameter eventually.
 | 
				
			||||||
	// Some PreEnqueueCheck include event filtering logic based on some in-tree plugins
 | 
						// Some PreEnqueueCheck include event filtering logic based on some in-tree plugins
 | 
				
			||||||
	// and it affect badly to other plugins.
 | 
						// and it affect badly to other plugins.
 | 
				
			||||||
@@ -212,10 +212,10 @@ type PriorityQueue struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// activeQ is heap structure that scheduler actively looks at to find pods to
 | 
						// activeQ is heap structure that scheduler actively looks at to find pods to
 | 
				
			||||||
	// schedule. Head of heap is the highest priority pod. It should be protected by activeQLock.
 | 
						// schedule. Head of heap is the highest priority pod. It should be protected by activeQLock.
 | 
				
			||||||
	activeQ *heap.Heap
 | 
						activeQ *heap.Heap[*framework.QueuedPodInfo]
 | 
				
			||||||
	// podBackoffQ is a heap ordered by backoff expiry. Pods which have completed backoff
 | 
						// podBackoffQ is a heap ordered by backoff expiry. Pods which have completed backoff
 | 
				
			||||||
	// are popped from this heap before the scheduler looks at activeQ
 | 
						// are popped from this heap before the scheduler looks at activeQ
 | 
				
			||||||
	podBackoffQ *heap.Heap
 | 
						podBackoffQ *heap.Heap[*framework.QueuedPodInfo]
 | 
				
			||||||
	// unschedulablePods holds pods that have been tried and determined unschedulable.
 | 
						// unschedulablePods holds pods that have been tried and determined unschedulable.
 | 
				
			||||||
	unschedulablePods *UnschedulablePods
 | 
						unschedulablePods *UnschedulablePods
 | 
				
			||||||
	// schedulingCycle represents sequence number of scheduling cycle and is incremented
 | 
						// schedulingCycle represents sequence number of scheduling cycle and is incremented
 | 
				
			||||||
@@ -382,19 +382,13 @@ func NewPriorityQueue(
 | 
				
			|||||||
		opt(&options)
 | 
							opt(&options)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	comp := func(podInfo1, podInfo2 interface{}) bool {
 | 
					 | 
				
			||||||
		pInfo1 := podInfo1.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
		pInfo2 := podInfo2.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
		return lessFn(pInfo1, pInfo2)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pq := &PriorityQueue{
 | 
						pq := &PriorityQueue{
 | 
				
			||||||
		clock:                             options.clock,
 | 
							clock:                             options.clock,
 | 
				
			||||||
		stop:                              make(chan struct{}),
 | 
							stop:                              make(chan struct{}),
 | 
				
			||||||
		podInitialBackoffDuration:         options.podInitialBackoffDuration,
 | 
							podInitialBackoffDuration:         options.podInitialBackoffDuration,
 | 
				
			||||||
		podMaxBackoffDuration:             options.podMaxBackoffDuration,
 | 
							podMaxBackoffDuration:             options.podMaxBackoffDuration,
 | 
				
			||||||
		podMaxInUnschedulablePodsDuration: options.podMaxInUnschedulablePodsDuration,
 | 
							podMaxInUnschedulablePodsDuration: options.podMaxInUnschedulablePodsDuration,
 | 
				
			||||||
		activeQ:                           heap.NewWithRecorder(podInfoKeyFunc, comp, metrics.NewActivePodsRecorder()),
 | 
							activeQ:                           heap.NewWithRecorder(podInfoKeyFunc, heap.LessFunc[*framework.QueuedPodInfo](lessFn), metrics.NewActivePodsRecorder()),
 | 
				
			||||||
		unschedulablePods:                 newUnschedulablePods(metrics.NewUnschedulablePodsRecorder(), metrics.NewGatedPodsRecorder()),
 | 
							unschedulablePods:                 newUnschedulablePods(metrics.NewUnschedulablePodsRecorder(), metrics.NewGatedPodsRecorder()),
 | 
				
			||||||
		inFlightPods:                      make(map[types.UID]*list.Element),
 | 
							inFlightPods:                      make(map[types.UID]*list.Element),
 | 
				
			||||||
		inFlightEvents:                    list.New(),
 | 
							inFlightEvents:                    list.New(),
 | 
				
			||||||
@@ -603,7 +597,7 @@ func (p *PriorityQueue) runPreEnqueuePlugin(ctx context.Context, pl framework.Pr
 | 
				
			|||||||
// It returns 2 parameters:
 | 
					// It returns 2 parameters:
 | 
				
			||||||
// 1. a boolean flag to indicate whether the pod is added successfully.
 | 
					// 1. a boolean flag to indicate whether the pod is added successfully.
 | 
				
			||||||
// 2. an error for the caller to act on.
 | 
					// 2. an error for the caller to act on.
 | 
				
			||||||
func (p *PriorityQueue) moveToActiveQ(logger klog.Logger, pInfo *framework.QueuedPodInfo, event string) (bool, error) {
 | 
					func (p *PriorityQueue) moveToActiveQ(logger klog.Logger, pInfo *framework.QueuedPodInfo, event string) bool {
 | 
				
			||||||
	gatedBefore := pInfo.Gated
 | 
						gatedBefore := pInfo.Gated
 | 
				
			||||||
	pInfo.Gated = !p.runPreEnqueuePlugins(context.Background(), pInfo)
 | 
						pInfo.Gated = !p.runPreEnqueuePlugins(context.Background(), pInfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -611,24 +605,21 @@ func (p *PriorityQueue) moveToActiveQ(logger klog.Logger, pInfo *framework.Queue
 | 
				
			|||||||
	defer p.activeQLock.Unlock()
 | 
						defer p.activeQLock.Unlock()
 | 
				
			||||||
	if pInfo.Gated {
 | 
						if pInfo.Gated {
 | 
				
			||||||
		// Add the Pod to unschedulablePods if it's not passing PreEnqueuePlugins.
 | 
							// Add the Pod to unschedulablePods if it's not passing PreEnqueuePlugins.
 | 
				
			||||||
		if _, exists, _ := p.activeQ.Get(pInfo); exists {
 | 
							if p.activeQ.Has(pInfo) {
 | 
				
			||||||
			return false, nil
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if _, exists, _ := p.podBackoffQ.Get(pInfo); exists {
 | 
							if p.podBackoffQ.Has(pInfo) {
 | 
				
			||||||
			return false, nil
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		p.unschedulablePods.addOrUpdate(pInfo)
 | 
							p.unschedulablePods.addOrUpdate(pInfo)
 | 
				
			||||||
		return false, nil
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if pInfo.InitialAttemptTimestamp == nil {
 | 
						if pInfo.InitialAttemptTimestamp == nil {
 | 
				
			||||||
		now := p.clock.Now()
 | 
							now := p.clock.Now()
 | 
				
			||||||
		pInfo.InitialAttemptTimestamp = &now
 | 
							pInfo.InitialAttemptTimestamp = &now
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := p.activeQ.Add(pInfo); err != nil {
 | 
						p.activeQ.AddOrUpdate(pInfo)
 | 
				
			||||||
		logger.Error(err, "Error adding pod to the active queue", "pod", klog.KObj(pInfo.Pod))
 | 
					 | 
				
			||||||
		return false, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p.unschedulablePods.delete(pInfo.Pod, gatedBefore)
 | 
						p.unschedulablePods.delete(pInfo.Pod, gatedBefore)
 | 
				
			||||||
	_ = p.podBackoffQ.Delete(pInfo) // Don't need to react when pInfo is not found.
 | 
						_ = p.podBackoffQ.Delete(pInfo) // Don't need to react when pInfo is not found.
 | 
				
			||||||
@@ -638,22 +629,19 @@ func (p *PriorityQueue) moveToActiveQ(logger klog.Logger, pInfo *framework.Queue
 | 
				
			|||||||
		p.AddNominatedPod(logger, pInfo.PodInfo, nil)
 | 
							p.AddNominatedPod(logger, pInfo.PodInfo, nil)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true, nil
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Add adds a pod to the active queue. It should be called only when a new pod
 | 
					// Add adds a pod to the active queue. It should be called only when a new pod
 | 
				
			||||||
// is added so there is no chance the pod is already in active/unschedulable/backoff queues
 | 
					// is added so there is no chance the pod is already in active/unschedulable/backoff queues
 | 
				
			||||||
func (p *PriorityQueue) Add(logger klog.Logger, pod *v1.Pod) error {
 | 
					func (p *PriorityQueue) Add(logger klog.Logger, pod *v1.Pod) {
 | 
				
			||||||
	p.lock.Lock()
 | 
						p.lock.Lock()
 | 
				
			||||||
	defer p.lock.Unlock()
 | 
						defer p.lock.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pInfo := p.newQueuedPodInfo(pod)
 | 
						pInfo := p.newQueuedPodInfo(pod)
 | 
				
			||||||
	if added, err := p.moveToActiveQ(logger, pInfo, framework.PodAdd); !added {
 | 
						if added := p.moveToActiveQ(logger, pInfo, framework.PodAdd); added {
 | 
				
			||||||
		return err
 | 
							p.cond.Broadcast()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	p.cond.Broadcast()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Activate moves the given pods to activeQ iff they're in unschedulablePods or backoffQ.
 | 
					// Activate moves the given pods to activeQ iff they're in unschedulablePods or backoffQ.
 | 
				
			||||||
@@ -676,8 +664,7 @@ func (p *PriorityQueue) Activate(logger klog.Logger, pods map[string]*v1.Pod) {
 | 
				
			|||||||
func (p *PriorityQueue) existsInActiveQ(pInfo *framework.QueuedPodInfo) bool {
 | 
					func (p *PriorityQueue) existsInActiveQ(pInfo *framework.QueuedPodInfo) bool {
 | 
				
			||||||
	p.activeQLock.RLock()
 | 
						p.activeQLock.RLock()
 | 
				
			||||||
	defer p.activeQLock.RUnlock()
 | 
						defer p.activeQLock.RUnlock()
 | 
				
			||||||
	_, exists, _ := p.activeQ.Get(pInfo)
 | 
						return p.activeQ.Has(pInfo)
 | 
				
			||||||
	return exists
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *PriorityQueue) activate(logger klog.Logger, pod *v1.Pod) bool {
 | 
					func (p *PriorityQueue) activate(logger klog.Logger, pod *v1.Pod) bool {
 | 
				
			||||||
@@ -686,10 +673,10 @@ func (p *PriorityQueue) activate(logger klog.Logger, pod *v1.Pod) bool {
 | 
				
			|||||||
	if pInfo = p.unschedulablePods.get(pod); pInfo == nil {
 | 
						if pInfo = p.unschedulablePods.get(pod); pInfo == nil {
 | 
				
			||||||
		// If the pod doesn't belong to unschedulablePods or backoffQ, don't activate it.
 | 
							// If the pod doesn't belong to unschedulablePods or backoffQ, don't activate it.
 | 
				
			||||||
		// The pod can be already in activeQ.
 | 
							// The pod can be already in activeQ.
 | 
				
			||||||
		if obj, exists, _ := p.podBackoffQ.Get(newQueuedPodInfoForLookup(pod)); !exists {
 | 
							var exists bool
 | 
				
			||||||
 | 
							pInfo, exists = p.podBackoffQ.Get(newQueuedPodInfoForLookup(pod))
 | 
				
			||||||
 | 
							if !exists {
 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			pInfo = obj.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -699,8 +686,7 @@ func (p *PriorityQueue) activate(logger klog.Logger, pod *v1.Pod) bool {
 | 
				
			|||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	added, _ := p.moveToActiveQ(logger, pInfo, framework.ForceActivate)
 | 
						return p.moveToActiveQ(logger, pInfo, framework.ForceActivate)
 | 
				
			||||||
	return added
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isPodBackingoff returns true if a pod is still waiting for its backoff timer.
 | 
					// isPodBackingoff returns true if a pod is still waiting for its backoff timer.
 | 
				
			||||||
@@ -820,9 +806,7 @@ func (p *PriorityQueue) addUnschedulableWithoutQueueingHint(logger klog.Logger,
 | 
				
			|||||||
		// - No unschedulable plugins are associated with this Pod,
 | 
							// - No unschedulable plugins are associated with this Pod,
 | 
				
			||||||
		//   meaning something unusual (a temporal failure on kube-apiserver, etc) happened and this Pod gets moved back to the queue.
 | 
							//   meaning something unusual (a temporal failure on kube-apiserver, etc) happened and this Pod gets moved back to the queue.
 | 
				
			||||||
		//   In this case, we should retry scheduling it because this Pod may not be retried until the next flush.
 | 
							//   In this case, we should retry scheduling it because this Pod may not be retried until the next flush.
 | 
				
			||||||
		if err := p.podBackoffQ.Add(pInfo); err != nil {
 | 
							p.podBackoffQ.AddOrUpdate(pInfo)
 | 
				
			||||||
			return fmt.Errorf("error adding pod %v to the backoff queue: %v", klog.KObj(pod), err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pod), "event", framework.ScheduleAttemptFailure, "queue", backoffQ)
 | 
							logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pod), "event", framework.ScheduleAttemptFailure, "queue", backoffQ)
 | 
				
			||||||
		metrics.SchedulerQueueIncomingPods.WithLabelValues("backoff", framework.ScheduleAttemptFailure).Inc()
 | 
							metrics.SchedulerQueueIncomingPods.WithLabelValues("backoff", framework.ScheduleAttemptFailure).Inc()
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@@ -853,7 +837,7 @@ func (p *PriorityQueue) AddUnschedulableIfNotPresent(logger klog.Logger, pInfo *
 | 
				
			|||||||
	if p.existsInActiveQ(pInfo) {
 | 
						if p.existsInActiveQ(pInfo) {
 | 
				
			||||||
		return fmt.Errorf("Pod %v is already present in the active queue", klog.KObj(pod))
 | 
							return fmt.Errorf("Pod %v is already present in the active queue", klog.KObj(pod))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, exists, _ := p.podBackoffQ.Get(pInfo); exists {
 | 
						if p.podBackoffQ.Has(pInfo) {
 | 
				
			||||||
		return fmt.Errorf("Pod %v is already present in the backoff queue", klog.KObj(pod))
 | 
							return fmt.Errorf("Pod %v is already present in the backoff queue", klog.KObj(pod))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -892,11 +876,10 @@ func (p *PriorityQueue) flushBackoffQCompleted(logger klog.Logger) {
 | 
				
			|||||||
	defer p.lock.Unlock()
 | 
						defer p.lock.Unlock()
 | 
				
			||||||
	activated := false
 | 
						activated := false
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		rawPodInfo := p.podBackoffQ.Peek()
 | 
							pInfo, ok := p.podBackoffQ.Peek()
 | 
				
			||||||
		if rawPodInfo == nil {
 | 
							if !ok || pInfo == nil {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		pInfo := rawPodInfo.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
		pod := pInfo.Pod
 | 
							pod := pInfo.Pod
 | 
				
			||||||
		if p.isPodBackingoff(pInfo) {
 | 
							if p.isPodBackingoff(pInfo) {
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
@@ -906,7 +889,7 @@ func (p *PriorityQueue) flushBackoffQCompleted(logger klog.Logger) {
 | 
				
			|||||||
			logger.Error(err, "Unable to pop pod from backoff queue despite backoff completion", "pod", klog.KObj(pod))
 | 
								logger.Error(err, "Unable to pop pod from backoff queue despite backoff completion", "pod", klog.KObj(pod))
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if added, _ := p.moveToActiveQ(logger, pInfo, framework.BackoffComplete); added {
 | 
							if added := p.moveToActiveQ(logger, pInfo, framework.BackoffComplete); added {
 | 
				
			||||||
			activated = true
 | 
								activated = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -954,11 +937,10 @@ func (p *PriorityQueue) Pop(logger klog.Logger) (*framework.QueuedPodInfo, error
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		p.cond.Wait()
 | 
							p.cond.Wait()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	obj, err := p.activeQ.Pop()
 | 
						pInfo, err := p.activeQ.Pop()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pInfo := obj.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
	pInfo.Attempts++
 | 
						pInfo.Attempts++
 | 
				
			||||||
	p.schedulingCycle++
 | 
						p.schedulingCycle++
 | 
				
			||||||
	// In flight, no concurrent events yet.
 | 
						// In flight, no concurrent events yet.
 | 
				
			||||||
@@ -1039,22 +1021,23 @@ func isPodUpdated(oldPod, newPod *v1.Pod) bool {
 | 
				
			|||||||
	return !reflect.DeepEqual(strip(oldPod), strip(newPod))
 | 
						return !reflect.DeepEqual(strip(oldPod), strip(newPod))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *PriorityQueue) updateInActiveQueue(logger klog.Logger, oldPod, newPod *v1.Pod, oldPodInfo *framework.QueuedPodInfo) (bool, error) {
 | 
					func (p *PriorityQueue) updateInActiveQueue(logger klog.Logger, oldPod, newPod *v1.Pod, oldPodInfo *framework.QueuedPodInfo) bool {
 | 
				
			||||||
	p.activeQLock.Lock()
 | 
						p.activeQLock.Lock()
 | 
				
			||||||
	defer p.activeQLock.Unlock()
 | 
						defer p.activeQLock.Unlock()
 | 
				
			||||||
	if oldPodInfo, exists, _ := p.activeQ.Get(oldPodInfo); exists {
 | 
						if pInfo, exists := p.activeQ.Get(oldPodInfo); exists {
 | 
				
			||||||
		pInfo := updatePod(oldPodInfo, newPod)
 | 
							_ = pInfo.Update(newPod)
 | 
				
			||||||
		p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo)
 | 
							p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo)
 | 
				
			||||||
		return true, p.activeQ.Update(pInfo)
 | 
							p.activeQ.AddOrUpdate(pInfo)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false, nil
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Update updates a pod in the active or backoff queue if present. Otherwise, it removes
 | 
					// Update updates a pod in the active or backoff queue if present. Otherwise, it removes
 | 
				
			||||||
// the item from the unschedulable queue if pod is updated in a way that it may
 | 
					// the item from the unschedulable queue if pod is updated in a way that it may
 | 
				
			||||||
// become schedulable and adds the updated one to the active queue.
 | 
					// become schedulable and adds the updated one to the active queue.
 | 
				
			||||||
// If pod is not present in any of the queues, it is added to the active queue.
 | 
					// If pod is not present in any of the queues, it is added to the active queue.
 | 
				
			||||||
func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) error {
 | 
					func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) {
 | 
				
			||||||
	p.lock.Lock()
 | 
						p.lock.Lock()
 | 
				
			||||||
	defer p.lock.Unlock()
 | 
						defer p.lock.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1075,7 +1058,7 @@ func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) error
 | 
				
			|||||||
			})
 | 
								})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			p.activeQLock.Unlock()
 | 
								p.activeQLock.Unlock()
 | 
				
			||||||
			return nil
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		p.activeQLock.Unlock()
 | 
							p.activeQLock.Unlock()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1083,79 +1066,72 @@ func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) error
 | 
				
			|||||||
	if oldPod != nil {
 | 
						if oldPod != nil {
 | 
				
			||||||
		oldPodInfo := newQueuedPodInfoForLookup(oldPod)
 | 
							oldPodInfo := newQueuedPodInfoForLookup(oldPod)
 | 
				
			||||||
		// If the pod is already in the active queue, just update it there.
 | 
							// If the pod is already in the active queue, just update it there.
 | 
				
			||||||
		if exists, err := p.updateInActiveQueue(logger, oldPod, newPod, oldPodInfo); exists {
 | 
							if exists := p.updateInActiveQueue(logger, oldPod, newPod, oldPodInfo); exists {
 | 
				
			||||||
			return err
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If the pod is in the backoff queue, update it there.
 | 
							// If the pod is in the backoff queue, update it there.
 | 
				
			||||||
		if oldPodInfo, exists, _ := p.podBackoffQ.Get(oldPodInfo); exists {
 | 
							if pInfo, exists := p.podBackoffQ.Get(oldPodInfo); exists {
 | 
				
			||||||
			pInfo := updatePod(oldPodInfo, newPod)
 | 
								_ = pInfo.Update(newPod)
 | 
				
			||||||
			p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo)
 | 
								p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo)
 | 
				
			||||||
			return p.podBackoffQ.Update(pInfo)
 | 
								p.podBackoffQ.AddOrUpdate(pInfo)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If the pod is in the unschedulable queue, updating it may make it schedulable.
 | 
						// If the pod is in the unschedulable queue, updating it may make it schedulable.
 | 
				
			||||||
	if usPodInfo := p.unschedulablePods.get(newPod); usPodInfo != nil {
 | 
						if pInfo := p.unschedulablePods.get(newPod); pInfo != nil {
 | 
				
			||||||
		pInfo := updatePod(usPodInfo, newPod)
 | 
							_ = pInfo.Update(newPod)
 | 
				
			||||||
		p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo)
 | 
							p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo)
 | 
				
			||||||
		gated := usPodInfo.Gated
 | 
							gated := pInfo.Gated
 | 
				
			||||||
		if p.isSchedulingQueueHintEnabled {
 | 
							if p.isSchedulingQueueHintEnabled {
 | 
				
			||||||
			// When unscheduled Pods are updated, we check with QueueingHint
 | 
								// When unscheduled Pods are updated, we check with QueueingHint
 | 
				
			||||||
			// whether the update may make the pods schedulable.
 | 
								// whether the update may make the pods schedulable.
 | 
				
			||||||
			// Plugins have to implement a QueueingHint for Pod/Update event
 | 
								// Plugins have to implement a QueueingHint for Pod/Update event
 | 
				
			||||||
			// if the rejection from them could be resolved by updating unscheduled Pods itself.
 | 
								// if the rejection from them could be resolved by updating unscheduled Pods itself.
 | 
				
			||||||
 | 
					 | 
				
			||||||
			events := framework.PodSchedulingPropertiesChange(newPod, oldPod)
 | 
								events := framework.PodSchedulingPropertiesChange(newPod, oldPod)
 | 
				
			||||||
			for _, evt := range events {
 | 
								for _, evt := range events {
 | 
				
			||||||
				hint := p.isPodWorthRequeuing(logger, pInfo, evt, oldPod, newPod)
 | 
									hint := p.isPodWorthRequeuing(logger, pInfo, evt, oldPod, newPod)
 | 
				
			||||||
				queue := p.requeuePodViaQueueingHint(logger, pInfo, hint, framework.UnscheduledPodUpdate.Label)
 | 
									queue := p.requeuePodViaQueueingHint(logger, pInfo, hint, framework.UnscheduledPodUpdate.Label)
 | 
				
			||||||
				if queue != unschedulablePods {
 | 
									if queue != unschedulablePods {
 | 
				
			||||||
					logger.V(5).Info("Pod moved to an internal scheduling queue because the Pod is updated", "pod", klog.KObj(newPod), "event", framework.PodUpdate, "queue", queue)
 | 
										logger.V(5).Info("Pod moved to an internal scheduling queue because the Pod is updated", "pod", klog.KObj(newPod), "event", framework.PodUpdate, "queue", queue)
 | 
				
			||||||
					p.unschedulablePods.delete(usPodInfo.Pod, gated)
 | 
										p.unschedulablePods.delete(pInfo.Pod, gated)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if queue == activeQ {
 | 
									if queue == activeQ {
 | 
				
			||||||
					p.cond.Broadcast()
 | 
										p.cond.Broadcast()
 | 
				
			||||||
					break
 | 
										break
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if isPodUpdated(oldPod, newPod) {
 | 
							if isPodUpdated(oldPod, newPod) {
 | 
				
			||||||
 | 
								if p.isPodBackingoff(pInfo) {
 | 
				
			||||||
			if p.isPodBackingoff(usPodInfo) {
 | 
									p.podBackoffQ.AddOrUpdate(pInfo)
 | 
				
			||||||
				if err := p.podBackoffQ.Add(pInfo); err != nil {
 | 
									p.unschedulablePods.delete(pInfo.Pod, gated)
 | 
				
			||||||
					return err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				p.unschedulablePods.delete(usPodInfo.Pod, gated)
 | 
					 | 
				
			||||||
				logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", framework.PodUpdate, "queue", backoffQ)
 | 
									logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", framework.PodUpdate, "queue", backoffQ)
 | 
				
			||||||
				return nil
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if added, err := p.moveToActiveQ(logger, pInfo, framework.BackoffComplete); !added {
 | 
								if added := p.moveToActiveQ(logger, pInfo, framework.BackoffComplete); added {
 | 
				
			||||||
				return err
 | 
									p.cond.Broadcast()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			p.cond.Broadcast()
 | 
								return
 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Pod update didn't make it schedulable, keep it in the unschedulable queue.
 | 
							// Pod update didn't make it schedulable, keep it in the unschedulable queue.
 | 
				
			||||||
		p.unschedulablePods.addOrUpdate(pInfo)
 | 
							p.unschedulablePods.addOrUpdate(pInfo)
 | 
				
			||||||
		return nil
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// If pod is not in any of the queues, we put it in the active queue.
 | 
						// If pod is not in any of the queues, we put it in the active queue.
 | 
				
			||||||
	pInfo := p.newQueuedPodInfo(newPod)
 | 
						pInfo := p.newQueuedPodInfo(newPod)
 | 
				
			||||||
	if added, err := p.moveToActiveQ(logger, pInfo, framework.PodUpdate); !added {
 | 
						if added := p.moveToActiveQ(logger, pInfo, framework.PodUpdate); added {
 | 
				
			||||||
		return err
 | 
							p.cond.Broadcast()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	p.cond.Broadcast()
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Delete deletes the item from either of the two queues. It assumes the pod is
 | 
					// Delete deletes the item from either of the two queues. It assumes the pod is
 | 
				
			||||||
// only in one queue.
 | 
					// only in one queue.
 | 
				
			||||||
func (p *PriorityQueue) Delete(pod *v1.Pod) error {
 | 
					func (p *PriorityQueue) Delete(pod *v1.Pod) {
 | 
				
			||||||
	p.lock.Lock()
 | 
						p.lock.Lock()
 | 
				
			||||||
	defer p.lock.Unlock()
 | 
						defer p.lock.Unlock()
 | 
				
			||||||
	p.DeleteNominatedPodIfExists(pod)
 | 
						p.DeleteNominatedPodIfExists(pod)
 | 
				
			||||||
@@ -1169,7 +1145,6 @@ func (p *PriorityQueue) Delete(pod *v1.Pod) error {
 | 
				
			|||||||
			p.unschedulablePods.delete(pod, pInfo.Gated)
 | 
								p.unschedulablePods.delete(pod, pInfo.Gated)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AssignedPodAdded is called when a bound pod is added. Creation of this pod
 | 
					// AssignedPodAdded is called when a bound pod is added. Creation of this pod
 | 
				
			||||||
@@ -1241,25 +1216,14 @@ func (p *PriorityQueue) requeuePodViaQueueingHint(logger klog.Logger, pInfo *fra
 | 
				
			|||||||
		return unschedulablePods
 | 
							return unschedulablePods
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pod := pInfo.Pod
 | 
					 | 
				
			||||||
	if strategy == queueAfterBackoff && p.isPodBackingoff(pInfo) {
 | 
						if strategy == queueAfterBackoff && p.isPodBackingoff(pInfo) {
 | 
				
			||||||
		if err := p.podBackoffQ.Add(pInfo); err != nil {
 | 
							p.podBackoffQ.AddOrUpdate(pInfo)
 | 
				
			||||||
			logger.Error(err, "Error adding pod to the backoff queue, queue this Pod to unschedulable pod pool", "pod", klog.KObj(pod))
 | 
					 | 
				
			||||||
			p.unschedulablePods.addOrUpdate(pInfo)
 | 
					 | 
				
			||||||
			return unschedulablePods
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		metrics.SchedulerQueueIncomingPods.WithLabelValues("backoff", event).Inc()
 | 
							metrics.SchedulerQueueIncomingPods.WithLabelValues("backoff", event).Inc()
 | 
				
			||||||
		return backoffQ
 | 
							return backoffQ
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Reach here if schedulingHint is QueueImmediately, or schedulingHint is Queue but the pod is not backing off.
 | 
						// Reach here if schedulingHint is QueueImmediately, or schedulingHint is Queue but the pod is not backing off.
 | 
				
			||||||
 | 
						if added := p.moveToActiveQ(logger, pInfo, event); added {
 | 
				
			||||||
	added, err := p.moveToActiveQ(logger, pInfo, event)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		logger.Error(err, "Error adding pod to the active queue, queue this Pod to unschedulable pod pool", "pod", klog.KObj(pod))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if added {
 | 
					 | 
				
			||||||
		return activeQ
 | 
							return activeQ
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if pInfo.Gated {
 | 
						if pInfo.Gated {
 | 
				
			||||||
@@ -1368,7 +1332,7 @@ func (p *PriorityQueue) PodsInActiveQ() []*v1.Pod {
 | 
				
			|||||||
	defer p.activeQLock.RUnlock()
 | 
						defer p.activeQLock.RUnlock()
 | 
				
			||||||
	var result []*v1.Pod
 | 
						var result []*v1.Pod
 | 
				
			||||||
	for _, pInfo := range p.activeQ.List() {
 | 
						for _, pInfo := range p.activeQ.List() {
 | 
				
			||||||
		result = append(result, pInfo.(*framework.QueuedPodInfo).Pod)
 | 
							result = append(result, pInfo.Pod)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1384,7 +1348,7 @@ func (p *PriorityQueue) PendingPods() ([]*v1.Pod, string) {
 | 
				
			|||||||
	result := p.PodsInActiveQ()
 | 
						result := p.PodsInActiveQ()
 | 
				
			||||||
	activeQLen := len(result)
 | 
						activeQLen := len(result)
 | 
				
			||||||
	for _, pInfo := range p.podBackoffQ.List() {
 | 
						for _, pInfo := range p.podBackoffQ.List() {
 | 
				
			||||||
		result = append(result, pInfo.(*framework.QueuedPodInfo).Pod)
 | 
							result = append(result, pInfo.Pod)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, pInfo := range p.unschedulablePods.podInfoMap {
 | 
						for _, pInfo := range p.unschedulablePods.podInfoMap {
 | 
				
			||||||
		result = append(result, pInfo.Pod)
 | 
							result = append(result, pInfo.Pod)
 | 
				
			||||||
@@ -1397,20 +1361,18 @@ func (p *PriorityQueue) nominatedPodToInfo(np PodRef) *framework.PodInfo {
 | 
				
			|||||||
	pod := np.ToPod()
 | 
						pod := np.ToPod()
 | 
				
			||||||
	pInfoLookup := newQueuedPodInfoForLookup(pod)
 | 
						pInfoLookup := newQueuedPodInfoForLookup(pod)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	obj, exists, _ := p.activeQ.Get(pInfoLookup)
 | 
						queuedPodInfo, exists := p.activeQ.Get(pInfoLookup)
 | 
				
			||||||
	if exists {
 | 
						if exists {
 | 
				
			||||||
		queuedPodInfo := obj.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
		return queuedPodInfo.PodInfo
 | 
							return queuedPodInfo.PodInfo
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	queuedPodInfo := p.unschedulablePods.get(pod)
 | 
						queuedPodInfo = p.unschedulablePods.get(pod)
 | 
				
			||||||
	if queuedPodInfo != nil {
 | 
						if queuedPodInfo != nil {
 | 
				
			||||||
		return queuedPodInfo.PodInfo
 | 
							return queuedPodInfo.PodInfo
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	obj, exists, _ = p.podBackoffQ.Get(pInfoLookup)
 | 
						queuedPodInfo, exists = p.podBackoffQ.Get(pInfoLookup)
 | 
				
			||||||
	if exists {
 | 
						if exists {
 | 
				
			||||||
		queuedPodInfo := obj.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
		return queuedPodInfo.PodInfo
 | 
							return queuedPodInfo.PodInfo
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1469,9 +1431,7 @@ func (npm *nominator) NominatedPodsForNode(nodeName string) []*framework.PodInfo
 | 
				
			|||||||
	return npm.nominatedPodsToInfo(nominatedPods)
 | 
						return npm.nominatedPodsToInfo(nominatedPods)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *PriorityQueue) podsCompareBackoffCompleted(podInfo1, podInfo2 interface{}) bool {
 | 
					func (p *PriorityQueue) podsCompareBackoffCompleted(pInfo1, pInfo2 *framework.QueuedPodInfo) bool {
 | 
				
			||||||
	pInfo1 := podInfo1.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
	pInfo2 := podInfo2.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
	bo1 := p.getBackoffTime(pInfo1)
 | 
						bo1 := p.getBackoffTime(pInfo1)
 | 
				
			||||||
	bo2 := p.getBackoffTime(pInfo2)
 | 
						bo2 := p.getBackoffTime(pInfo2)
 | 
				
			||||||
	return bo1.Before(bo2)
 | 
						return bo1.Before(bo2)
 | 
				
			||||||
@@ -1512,12 +1472,6 @@ func (p *PriorityQueue) calculateBackoffDuration(podInfo *framework.QueuedPodInf
 | 
				
			|||||||
	return duration
 | 
						return duration
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func updatePod(oldPodInfo interface{}, newPod *v1.Pod) *framework.QueuedPodInfo {
 | 
					 | 
				
			||||||
	pInfo := oldPodInfo.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
	pInfo.Update(newPod)
 | 
					 | 
				
			||||||
	return pInfo
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnschedulablePods holds pods that cannot be scheduled. This data structure
 | 
					// UnschedulablePods holds pods that cannot be scheduled. This data structure
 | 
				
			||||||
// is used to implement unschedulablePods.
 | 
					// is used to implement unschedulablePods.
 | 
				
			||||||
type UnschedulablePods struct {
 | 
					type UnschedulablePods struct {
 | 
				
			||||||
@@ -1729,6 +1683,6 @@ func newPodNominator(podLister listersv1.PodLister, nominatedPodsToInfo func([]P
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func podInfoKeyFunc(obj interface{}) (string, error) {
 | 
					func podInfoKeyFunc(pInfo *framework.QueuedPodInfo) string {
 | 
				
			||||||
	return cache.MetaNamespaceKeyFunc(obj.(*framework.QueuedPodInfo).Pod)
 | 
						return cache.NewObjectName(pInfo.Pod.Namespace, pInfo.Pod.Name).String()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,15 +122,9 @@ func TestPriorityQueue_Add(t *testing.T) {
 | 
				
			|||||||
	ctx, cancel := context.WithCancel(ctx)
 | 
						ctx, cancel := context.WithCancel(ctx)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
						q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
				
			||||||
	if err := q.Add(logger, medPriorityPodInfo.Pod); err != nil {
 | 
						q.Add(logger, medPriorityPodInfo.Pod)
 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
						q.Add(logger, unschedulablePodInfo.Pod)
 | 
				
			||||||
	}
 | 
						q.Add(logger, highPriorityPodInfo.Pod)
 | 
				
			||||||
	if err := q.Add(logger, unschedulablePodInfo.Pod); err != nil {
 | 
					 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := q.Add(logger, highPriorityPodInfo.Pod); err != nil {
 | 
					 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	expectedNominatedPods := &nominator{
 | 
						expectedNominatedPods := &nominator{
 | 
				
			||||||
		nominatedPodToNode: map[types.UID]string{
 | 
							nominatedPodToNode: map[types.UID]string{
 | 
				
			||||||
			medPriorityPodInfo.Pod.UID:   "node1",
 | 
								medPriorityPodInfo.Pod.UID:   "node1",
 | 
				
			||||||
@@ -168,12 +162,8 @@ func TestPriorityQueue_AddWithReversePriorityLessFunc(t *testing.T) {
 | 
				
			|||||||
	ctx, cancel := context.WithCancel(ctx)
 | 
						ctx, cancel := context.WithCancel(ctx)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
						q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
				
			||||||
	if err := q.Add(logger, medPriorityPodInfo.Pod); err != nil {
 | 
						q.Add(logger, medPriorityPodInfo.Pod)
 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
						q.Add(logger, highPriorityPodInfo.Pod)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := q.Add(logger, highPriorityPodInfo.Pod); err != nil {
 | 
					 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -748,17 +738,17 @@ func Test_InFlightPods(t *testing.T) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if test.wantActiveQPodNames != nil {
 | 
								if test.wantActiveQPodNames != nil {
 | 
				
			||||||
				rawPodInfos := q.activeQ.List()
 | 
									podInfos := q.activeQ.List()
 | 
				
			||||||
				if len(rawPodInfos) != len(test.wantActiveQPodNames) {
 | 
									if len(podInfos) != len(test.wantActiveQPodNames) {
 | 
				
			||||||
					diff := cmp.Diff(test.wantActiveQPodNames, rawPodInfos, cmpopts.SortSlices(func(a, b interface{}) bool {
 | 
										diff := cmp.Diff(test.wantActiveQPodNames, podInfos, cmpopts.SortSlices(func(a, b interface{}) bool {
 | 
				
			||||||
						return a.(framework.PodInfo).Pod.Name < b.(framework.PodInfo).Pod.Name
 | 
											return a.(framework.PodInfo).Pod.Name < b.(framework.PodInfo).Pod.Name
 | 
				
			||||||
					}))
 | 
										}))
 | 
				
			||||||
					t.Fatalf("Length of activeQ is not expected. Got %v, want %v.\n%s", len(rawPodInfos), len(test.wantActiveQPodNames), diff)
 | 
										t.Fatalf("Length of activeQ is not expected. Got %v, want %v.\n%s", len(podInfos), len(test.wantActiveQPodNames), diff)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				wantPodNames := sets.New(test.wantActiveQPodNames...)
 | 
									wantPodNames := sets.New(test.wantActiveQPodNames...)
 | 
				
			||||||
				for _, rawPodInfo := range rawPodInfos {
 | 
									for _, podInfo := range podInfos {
 | 
				
			||||||
					podGotFromActiveQ := rawPodInfo.(*framework.QueuedPodInfo).Pod
 | 
										podGotFromActiveQ := podInfo.Pod
 | 
				
			||||||
					if !wantPodNames.Has(podGotFromActiveQ.Name) {
 | 
										if !wantPodNames.Has(podGotFromActiveQ.Name) {
 | 
				
			||||||
						t.Fatalf("Pod %v was not expected to be in the activeQ.", podGotFromActiveQ.Name)
 | 
											t.Fatalf("Pod %v was not expected to be in the activeQ.", podGotFromActiveQ.Name)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@@ -766,17 +756,17 @@ func Test_InFlightPods(t *testing.T) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if test.wantBackoffQPodNames != nil {
 | 
								if test.wantBackoffQPodNames != nil {
 | 
				
			||||||
				rawPodInfos := q.podBackoffQ.List()
 | 
									podInfos := q.podBackoffQ.List()
 | 
				
			||||||
				if len(rawPodInfos) != len(test.wantBackoffQPodNames) {
 | 
									if len(podInfos) != len(test.wantBackoffQPodNames) {
 | 
				
			||||||
					diff := cmp.Diff(test.wantBackoffQPodNames, rawPodInfos, cmpopts.SortSlices(func(a, b interface{}) bool {
 | 
										diff := cmp.Diff(test.wantBackoffQPodNames, podInfos, cmpopts.SortSlices(func(a, b interface{}) bool {
 | 
				
			||||||
						return a.(framework.PodInfo).Pod.Name < b.(framework.PodInfo).Pod.Name
 | 
											return a.(framework.PodInfo).Pod.Name < b.(framework.PodInfo).Pod.Name
 | 
				
			||||||
					}))
 | 
										}))
 | 
				
			||||||
					t.Fatalf("Length of backoffQ is not expected. Got %v, want %v.\n%s", len(rawPodInfos), len(test.wantBackoffQPodNames), diff)
 | 
										t.Fatalf("Length of backoffQ is not expected. Got %v, want %v.\n%s", len(podInfos), len(test.wantBackoffQPodNames), diff)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				wantPodNames := sets.New(test.wantBackoffQPodNames...)
 | 
									wantPodNames := sets.New(test.wantBackoffQPodNames...)
 | 
				
			||||||
				for _, rawPodInfo := range rawPodInfos {
 | 
									for _, podInfo := range podInfos {
 | 
				
			||||||
					podGotFromBackoffQ := rawPodInfo.(*framework.QueuedPodInfo).Pod
 | 
										podGotFromBackoffQ := podInfo.Pod
 | 
				
			||||||
					if !wantPodNames.Has(podGotFromBackoffQ.Name) {
 | 
										if !wantPodNames.Has(podGotFromBackoffQ.Name) {
 | 
				
			||||||
						t.Fatalf("Pod %v was not expected to be in the backoffQ.", podGotFromBackoffQ.Name)
 | 
											t.Fatalf("Pod %v was not expected to be in the backoffQ.", podGotFromBackoffQ.Name)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@@ -935,7 +925,7 @@ func TestPriorityQueue_AddUnschedulableIfNotPresent_Backoff(t *testing.T) {
 | 
				
			|||||||
	// Since there was a move request at the same cycle as "oldCycle", these pods
 | 
						// Since there was a move request at the same cycle as "oldCycle", these pods
 | 
				
			||||||
	// should be in the backoff queue.
 | 
						// should be in the backoff queue.
 | 
				
			||||||
	for i := 1; i < totalNum; i++ {
 | 
						for i := 1; i < totalNum; i++ {
 | 
				
			||||||
		if _, exists, _ := q.podBackoffQ.Get(newQueuedPodInfoForLookup(&expectedPods[i])); !exists {
 | 
							if !q.podBackoffQ.Has(newQueuedPodInfoForLookup(&expectedPods[i])) {
 | 
				
			||||||
			t.Errorf("Expected %v to be added to podBackoffQ.", expectedPods[i].Name)
 | 
								t.Errorf("Expected %v to be added to podBackoffQ.", expectedPods[i].Name)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1026,10 +1016,7 @@ func TestPriorityQueue_Update(t *testing.T) {
 | 
				
			|||||||
			name:  "When updating a pod that is already in activeQ, the pod should remain in activeQ after Update()",
 | 
								name:  "When updating a pod that is already in activeQ, the pod should remain in activeQ after Update()",
 | 
				
			||||||
			wantQ: activeQ,
 | 
								wantQ: activeQ,
 | 
				
			||||||
			prepareFunc: func(t *testing.T, logger klog.Logger, q *PriorityQueue) (oldPod, newPod *v1.Pod) {
 | 
								prepareFunc: func(t *testing.T, logger klog.Logger, q *PriorityQueue) (oldPod, newPod *v1.Pod) {
 | 
				
			||||||
				err := q.Update(logger, nil, highPriorityPodInfo.Pod)
 | 
									q.Update(logger, nil, highPriorityPodInfo.Pod)
 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					t.Errorf("add pod %s error: %v", highPriorityPodInfo.Pod.Name, err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return highPriorityPodInfo.Pod, highPriorityPodInfo.Pod
 | 
									return highPriorityPodInfo.Pod, highPriorityPodInfo.Pod
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			schedulingHintsEnablement: []bool{false, true},
 | 
								schedulingHintsEnablement: []bool{false, true},
 | 
				
			||||||
@@ -1039,9 +1026,7 @@ func TestPriorityQueue_Update(t *testing.T) {
 | 
				
			|||||||
			wantQ: backoffQ,
 | 
								wantQ: backoffQ,
 | 
				
			||||||
			prepareFunc: func(t *testing.T, logger klog.Logger, q *PriorityQueue) (oldPod, newPod *v1.Pod) {
 | 
								prepareFunc: func(t *testing.T, logger klog.Logger, q *PriorityQueue) (oldPod, newPod *v1.Pod) {
 | 
				
			||||||
				podInfo := q.newQueuedPodInfo(medPriorityPodInfo.Pod)
 | 
									podInfo := q.newQueuedPodInfo(medPriorityPodInfo.Pod)
 | 
				
			||||||
				if err := q.podBackoffQ.Add(podInfo); err != nil {
 | 
									q.podBackoffQ.AddOrUpdate(podInfo)
 | 
				
			||||||
					t.Errorf("adding pod to backoff queue error: %v", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return podInfo.Pod, podInfo.Pod
 | 
									return podInfo.Pod, podInfo.Pod
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			schedulingHintsEnablement: []bool{false, true},
 | 
								schedulingHintsEnablement: []bool{false, true},
 | 
				
			||||||
@@ -1088,10 +1073,7 @@ func TestPriorityQueue_Update(t *testing.T) {
 | 
				
			|||||||
			prepareFunc: func(t *testing.T, logger klog.Logger, q *PriorityQueue) (oldPod, newPod *v1.Pod) {
 | 
								prepareFunc: func(t *testing.T, logger klog.Logger, q *PriorityQueue) (oldPod, newPod *v1.Pod) {
 | 
				
			||||||
				podInfo := q.newQueuedPodInfo(medPriorityPodInfo.Pod)
 | 
									podInfo := q.newQueuedPodInfo(medPriorityPodInfo.Pod)
 | 
				
			||||||
				// We need to once add this Pod to activeQ and Pop() it so that this Pod is registered correctly in inFlightPods.
 | 
									// We need to once add this Pod to activeQ and Pop() it so that this Pod is registered correctly in inFlightPods.
 | 
				
			||||||
				err := q.activeQ.Add(podInfo)
 | 
									q.activeQ.AddOrUpdate(podInfo)
 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					t.Errorf("unexpected error from activeQ.Add: %v", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if p, err := q.Pop(logger); err != nil || p.Pod != medPriorityPodInfo.Pod {
 | 
									if p, err := q.Pop(logger); err != nil || p.Pod != medPriorityPodInfo.Pod {
 | 
				
			||||||
					t.Errorf("Expected: %v after Pop, but got: %v", medPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
										t.Errorf("Expected: %v after Pop, but got: %v", medPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -1115,25 +1097,23 @@ func TestPriorityQueue_Update(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				oldPod, newPod := tt.prepareFunc(t, logger, q)
 | 
									oldPod, newPod := tt.prepareFunc(t, logger, q)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if err := q.Update(logger, oldPod, newPod); err != nil {
 | 
									q.Update(logger, oldPod, newPod)
 | 
				
			||||||
					t.Fatalf("unexpected error from Update: %v", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var pInfo *framework.QueuedPodInfo
 | 
									var pInfo *framework.QueuedPodInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// validate expected queue
 | 
									// validate expected queue
 | 
				
			||||||
				if obj, exists, _ := q.podBackoffQ.Get(newQueuedPodInfoForLookup(newPod)); exists {
 | 
									if pInfoFromBackoff, exists := q.podBackoffQ.Get(newQueuedPodInfoForLookup(newPod)); exists {
 | 
				
			||||||
					if tt.wantQ != backoffQ {
 | 
										if tt.wantQ != backoffQ {
 | 
				
			||||||
						t.Errorf("expected pod %s not to be queued to backoffQ, but it was", newPod.Name)
 | 
											t.Errorf("expected pod %s not to be queued to backoffQ, but it was", newPod.Name)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					pInfo = obj.(*framework.QueuedPodInfo)
 | 
										pInfo = pInfoFromBackoff
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if obj, exists, _ := q.activeQ.Get(newQueuedPodInfoForLookup(newPod)); exists {
 | 
									if pInfoFromActive, exists := q.activeQ.Get(newQueuedPodInfoForLookup(newPod)); exists {
 | 
				
			||||||
					if tt.wantQ != activeQ {
 | 
										if tt.wantQ != activeQ {
 | 
				
			||||||
						t.Errorf("expected pod %s not to be queued to activeQ, but it was", newPod.Name)
 | 
											t.Errorf("expected pod %s not to be queued to activeQ, but it was", newPod.Name)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					pInfo = obj.(*framework.QueuedPodInfo)
 | 
										pInfo = pInfoFromActive
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if pInfoFromUnsched := q.unschedulablePods.get(newPod); pInfoFromUnsched != nil {
 | 
									if pInfoFromUnsched := q.unschedulablePods.get(newPod); pInfoFromUnsched != nil {
 | 
				
			||||||
@@ -1183,9 +1163,7 @@ func TestPriorityQueue_UpdateWhenInflight(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// test-pod is created and popped out from the queue
 | 
						// test-pod is created and popped out from the queue
 | 
				
			||||||
	testPod := st.MakePod().Name("test-pod").Namespace("test-ns").UID("test-uid").Obj()
 | 
						testPod := st.MakePod().Name("test-pod").Namespace("test-ns").UID("test-uid").Obj()
 | 
				
			||||||
	if err := q.Add(logger, testPod); err != nil {
 | 
						q.Add(logger, testPod)
 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != testPod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != testPod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", testPod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", testPod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1199,9 +1177,7 @@ func TestPriorityQueue_UpdateWhenInflight(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := q.Update(logger, testPod, updatedPod); err != nil {
 | 
						q.Update(logger, testPod, updatedPod)
 | 
				
			||||||
		t.Errorf("Error calling Update: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// test-pod got rejected by fakePlugin,
 | 
						// test-pod got rejected by fakePlugin,
 | 
				
			||||||
	// but the update event that it just got may change this scheduling result,
 | 
						// but the update event that it just got may change this scheduling result,
 | 
				
			||||||
	// and hence we should put this pod to activeQ/backoffQ.
 | 
						// and hence we should put this pod to activeQ/backoffQ.
 | 
				
			||||||
@@ -1210,11 +1186,9 @@ func TestPriorityQueue_UpdateWhenInflight(t *testing.T) {
 | 
				
			|||||||
		t.Fatalf("unexpected error from AddUnschedulableIfNotPresent: %v", err)
 | 
							t.Fatalf("unexpected error from AddUnschedulableIfNotPresent: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var pInfo *framework.QueuedPodInfo
 | 
						pInfo, exists := q.podBackoffQ.Get(newQueuedPodInfoForLookup(updatedPod))
 | 
				
			||||||
	if obj, exists, _ := q.podBackoffQ.Get(newQueuedPodInfoForLookup(updatedPod)); !exists {
 | 
						if !exists {
 | 
				
			||||||
		t.Fatalf("expected pod %s to be queued to backoffQ, but it wasn't.", updatedPod.Name)
 | 
							t.Fatalf("expected pod %s to be queued to backoffQ, but it wasn't.", updatedPod.Name)
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		pInfo = obj.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if diff := cmp.Diff(updatedPod, pInfo.PodInfo.Pod); diff != "" {
 | 
						if diff := cmp.Diff(updatedPod, pInfo.PodInfo.Pod); diff != "" {
 | 
				
			||||||
		t.Errorf("Unexpected updated pod diff (-want, +got): %s", diff)
 | 
							t.Errorf("Unexpected updated pod diff (-want, +got): %s", diff)
 | 
				
			||||||
@@ -1229,21 +1203,17 @@ func TestPriorityQueue_Delete(t *testing.T) {
 | 
				
			|||||||
	q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
						q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
				
			||||||
	q.Update(logger, highPriorityPodInfo.Pod, highPriNominatedPodInfo.Pod)
 | 
						q.Update(logger, highPriorityPodInfo.Pod, highPriNominatedPodInfo.Pod)
 | 
				
			||||||
	q.Add(logger, unschedulablePodInfo.Pod)
 | 
						q.Add(logger, unschedulablePodInfo.Pod)
 | 
				
			||||||
	if err := q.Delete(highPriNominatedPodInfo.Pod); err != nil {
 | 
						q.Delete(highPriNominatedPodInfo.Pod)
 | 
				
			||||||
		t.Errorf("delete failed: %v", err)
 | 
						if !q.activeQ.Has(newQueuedPodInfoForLookup(unschedulablePodInfo.Pod)) {
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, exists, _ := q.activeQ.Get(newQueuedPodInfoForLookup(unschedulablePodInfo.Pod)); !exists {
 | 
					 | 
				
			||||||
		t.Errorf("Expected %v to be in activeQ.", unschedulablePodInfo.Pod.Name)
 | 
							t.Errorf("Expected %v to be in activeQ.", unschedulablePodInfo.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, exists, _ := q.activeQ.Get(newQueuedPodInfoForLookup(highPriNominatedPodInfo.Pod)); exists {
 | 
						if q.activeQ.Has(newQueuedPodInfoForLookup(highPriNominatedPodInfo.Pod)) {
 | 
				
			||||||
		t.Errorf("Didn't expect %v to be in activeQ.", highPriorityPodInfo.Pod.Name)
 | 
							t.Errorf("Didn't expect %v to be in activeQ.", highPriorityPodInfo.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(q.nominator.nominatedPods) != 1 {
 | 
						if len(q.nominator.nominatedPods) != 1 {
 | 
				
			||||||
		t.Errorf("Expected nominatedPods to have only 'unschedulablePodInfo': %v", q.nominator.nominatedPods)
 | 
							t.Errorf("Expected nominatedPods to have only 'unschedulablePodInfo': %v", q.nominator.nominatedPods)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := q.Delete(unschedulablePodInfo.Pod); err != nil {
 | 
						q.Delete(unschedulablePodInfo.Pod)
 | 
				
			||||||
		t.Errorf("delete failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(q.nominator.nominatedPods) != 0 {
 | 
						if len(q.nominator.nominatedPods) != 0 {
 | 
				
			||||||
		t.Errorf("Expected nominatedPods to be empty: %v", q.nominator)
 | 
							t.Errorf("Expected nominatedPods to be empty: %v", q.nominator)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1293,7 +1263,7 @@ func TestPriorityQueue_Activate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// Prepare activeQ/unschedulablePods/podBackoffQ according to the table
 | 
								// Prepare activeQ/unschedulablePods/podBackoffQ according to the table
 | 
				
			||||||
			for _, qPodInfo := range tt.qPodInfoInActiveQ {
 | 
								for _, qPodInfo := range tt.qPodInfoInActiveQ {
 | 
				
			||||||
				q.activeQ.Add(qPodInfo)
 | 
									q.activeQ.AddOrUpdate(qPodInfo)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for _, qPodInfo := range tt.qPodInfoInUnschedulablePods {
 | 
								for _, qPodInfo := range tt.qPodInfoInUnschedulablePods {
 | 
				
			||||||
@@ -1301,7 +1271,7 @@ func TestPriorityQueue_Activate(t *testing.T) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for _, qPodInfo := range tt.qPodInfoInPodBackoffQ {
 | 
								for _, qPodInfo := range tt.qPodInfoInPodBackoffQ {
 | 
				
			||||||
				q.podBackoffQ.Add(qPodInfo)
 | 
									q.podBackoffQ.AddOrUpdate(qPodInfo)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Activate specific pod according to the table
 | 
								// Activate specific pod according to the table
 | 
				
			||||||
@@ -1314,7 +1284,7 @@ func TestPriorityQueue_Activate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// Check if the specific pod exists in activeQ
 | 
								// Check if the specific pod exists in activeQ
 | 
				
			||||||
			for _, want := range tt.want {
 | 
								for _, want := range tt.want {
 | 
				
			||||||
				if _, exist, _ := q.activeQ.Get(newQueuedPodInfoForLookup(want.PodInfo.Pod)); !exist {
 | 
									if !q.activeQ.Has(newQueuedPodInfoForLookup(want.PodInfo.Pod)) {
 | 
				
			||||||
					t.Errorf("podInfo not exist in activeQ: want %v", want.PodInfo.Pod.Name)
 | 
										t.Errorf("podInfo not exist in activeQ: want %v", want.PodInfo.Pod.Name)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -1393,7 +1363,7 @@ func TestPriorityQueue_addToActiveQ(t *testing.T) {
 | 
				
			|||||||
			m := map[string][]framework.PreEnqueuePlugin{"": tt.plugins}
 | 
								m := map[string][]framework.PreEnqueuePlugin{"": tt.plugins}
 | 
				
			||||||
			q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), []runtime.Object{tt.pod}, WithPreEnqueuePluginMap(m),
 | 
								q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), []runtime.Object{tt.pod}, WithPreEnqueuePluginMap(m),
 | 
				
			||||||
				WithPodInitialBackoffDuration(time.Second*30), WithPodMaxBackoffDuration(time.Second*60))
 | 
									WithPodInitialBackoffDuration(time.Second*30), WithPodMaxBackoffDuration(time.Second*60))
 | 
				
			||||||
			got, _ := q.moveToActiveQ(logger, q.newQueuedPodInfo(tt.pod), framework.PodAdd)
 | 
								got := q.moveToActiveQ(logger, q.newQueuedPodInfo(tt.pod), framework.PodAdd)
 | 
				
			||||||
			if got != tt.wantSuccess {
 | 
								if got != tt.wantSuccess {
 | 
				
			||||||
				t.Errorf("Unexpected result: want %v, but got %v", tt.wantSuccess, got)
 | 
									t.Errorf("Unexpected result: want %v, but got %v", tt.wantSuccess, got)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -1600,7 +1570,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueueWithQueueingHint(t *testing.
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			cl := testingclock.NewFakeClock(now)
 | 
								cl := testingclock.NewFakeClock(now)
 | 
				
			||||||
			q := NewTestQueue(ctx, newDefaultQueueSort(), WithQueueingHintMapPerProfile(m), WithClock(cl))
 | 
								q := NewTestQueue(ctx, newDefaultQueueSort(), WithQueueingHintMapPerProfile(m), WithClock(cl))
 | 
				
			||||||
			q.activeQ.Add(q.newQueuedPodInfo(test.podInfo.Pod))
 | 
								q.activeQ.AddOrUpdate(q.newQueuedPodInfo(test.podInfo.Pod))
 | 
				
			||||||
			if p, err := q.Pop(logger); err != nil || p.Pod != test.podInfo.Pod {
 | 
								if p, err := q.Pop(logger); err != nil || p.Pod != test.podInfo.Pod {
 | 
				
			||||||
				t.Errorf("Expected: %v after Pop, but got: %v", test.podInfo.Pod.Name, p.Pod.Name)
 | 
									t.Errorf("Expected: %v after Pop, but got: %v", test.podInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -1644,12 +1614,12 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueue(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
 | 
						q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
 | 
				
			||||||
	// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
						// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(unschedulablePodInfo.Pod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(unschedulablePodInfo.Pod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	expectInFlightPods(t, q, unschedulablePodInfo.Pod.UID)
 | 
						expectInFlightPods(t, q, unschedulablePodInfo.Pod.UID)
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(highPriorityPodInfo.Pod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(highPriorityPodInfo.Pod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1665,7 +1635,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueue(t *testing.T) {
 | 
				
			|||||||
	expectInFlightPods(t, q)
 | 
						expectInFlightPods(t, q)
 | 
				
			||||||
	// Construct a Pod, but don't associate its scheduler failure to any plugin
 | 
						// Construct a Pod, but don't associate its scheduler failure to any plugin
 | 
				
			||||||
	hpp1 := clonePod(highPriorityPodInfo.Pod, "hpp1")
 | 
						hpp1 := clonePod(highPriorityPodInfo.Pod, "hpp1")
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(hpp1))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(hpp1))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != hpp1 {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != hpp1 {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", hpp1, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", hpp1, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1678,7 +1648,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueue(t *testing.T) {
 | 
				
			|||||||
	expectInFlightPods(t, q)
 | 
						expectInFlightPods(t, q)
 | 
				
			||||||
	// Construct another Pod, and associate its scheduler failure to plugin "barPlugin".
 | 
						// Construct another Pod, and associate its scheduler failure to plugin "barPlugin".
 | 
				
			||||||
	hpp2 := clonePod(highPriorityPodInfo.Pod, "hpp2")
 | 
						hpp2 := clonePod(highPriorityPodInfo.Pod, "hpp2")
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(hpp2))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(hpp2))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != hpp2 {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != hpp2 {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", hpp2, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", hpp2, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1714,17 +1684,17 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueue(t *testing.T) {
 | 
				
			|||||||
	expectInFlightPods(t, q, medPriorityPodInfo.Pod.UID)
 | 
						expectInFlightPods(t, q, medPriorityPodInfo.Pod.UID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	q.schedulingCycle++
 | 
						q.schedulingCycle++
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(unschedulablePodInfo.Pod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(unschedulablePodInfo.Pod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	expectInFlightPods(t, q, medPriorityPodInfo.Pod.UID, unschedulablePodInfo.Pod.UID)
 | 
						expectInFlightPods(t, q, medPriorityPodInfo.Pod.UID, unschedulablePodInfo.Pod.UID)
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(highPriorityPodInfo.Pod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(highPriorityPodInfo.Pod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	expectInFlightPods(t, q, medPriorityPodInfo.Pod.UID, unschedulablePodInfo.Pod.UID, highPriorityPodInfo.Pod.UID)
 | 
						expectInFlightPods(t, q, medPriorityPodInfo.Pod.UID, unschedulablePodInfo.Pod.UID, highPriorityPodInfo.Pod.UID)
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(hpp1))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(hpp1))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != hpp1 {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != hpp1 {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", hpp1, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", hpp1, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1755,7 +1725,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueue(t *testing.T) {
 | 
				
			|||||||
			t.Errorf("Expected %v in the unschedulablePods", pod.Name)
 | 
								t.Errorf("Expected %v in the unschedulablePods", pod.Name)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, ok, _ := q.podBackoffQ.Get(hpp1QueuedPodInfo); !ok {
 | 
						if !q.podBackoffQ.Has(hpp1QueuedPodInfo) {
 | 
				
			||||||
		t.Errorf("Expected %v in the podBackoffQ", hpp1.Name)
 | 
							t.Errorf("Expected %v in the podBackoffQ", hpp1.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1792,9 +1762,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueueWithOutQueueingHint(t *testi
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
 | 
						q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
 | 
				
			||||||
	// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
						// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
				
			||||||
	if err := q.Add(logger, medPriorityPodInfo.Pod); err != nil {
 | 
						q.Add(logger, medPriorityPodInfo.Pod)
 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := q.AddUnschedulableIfNotPresent(logger, q.newQueuedPodInfo(unschedulablePodInfo.Pod, "fooPlugin"), q.SchedulingCycle())
 | 
						err := q.AddUnschedulableIfNotPresent(logger, q.newQueuedPodInfo(unschedulablePodInfo.Pod, "fooPlugin"), q.SchedulingCycle())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -1858,9 +1826,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueueWithOutQueueingHint(t *testi
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("unexpected error from AddUnschedulableIfNotPresent: %v", err)
 | 
							t.Fatalf("unexpected error from AddUnschedulableIfNotPresent: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err = q.Add(logger, medPriorityPodInfo.Pod); err != nil {
 | 
						q.Add(logger, medPriorityPodInfo.Pod)
 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// hpp1 will go to backoffQ because no failure plugin is associated with it.
 | 
						// hpp1 will go to backoffQ because no failure plugin is associated with it.
 | 
				
			||||||
	// All plugins other than hpp1 are enqueued to the unschedulable Pod pool.
 | 
						// All plugins other than hpp1 are enqueued to the unschedulable Pod pool.
 | 
				
			||||||
	for _, pod := range []*v1.Pod{unschedulablePodInfo.Pod, highPriorityPodInfo.Pod, hpp2} {
 | 
						for _, pod := range []*v1.Pod{unschedulablePodInfo.Pod, highPriorityPodInfo.Pod, hpp2} {
 | 
				
			||||||
@@ -1868,9 +1834,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueueWithOutQueueingHint(t *testi
 | 
				
			|||||||
			t.Errorf("Expected %v in the unschedulablePods", pod.Name)
 | 
								t.Errorf("Expected %v in the unschedulablePods", pod.Name)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, ok, _ := q.podBackoffQ.Get(hpp1QueuedPodInfo); !ok {
 | 
						q.podBackoffQ.Get(hpp1QueuedPodInfo)
 | 
				
			||||||
		t.Errorf("Expected %v in the podBackoffQ", hpp1.Name)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Move clock by podInitialBackoffDuration, so that pods in the unschedulablePods would pass the backing off,
 | 
						// Move clock by podInitialBackoffDuration, so that pods in the unschedulablePods would pass the backing off,
 | 
				
			||||||
	// and the pods will be moved into activeQ.
 | 
						// and the pods will be moved into activeQ.
 | 
				
			||||||
@@ -1990,9 +1954,7 @@ func TestPriorityQueue_AssignedPodAdded_(t *testing.T) {
 | 
				
			|||||||
			q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
 | 
								q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
								// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
				
			||||||
			if err := q.activeQ.Add(q.newQueuedPodInfo(tt.unschedPod)); err != nil {
 | 
								q.activeQ.AddOrUpdate(q.newQueuedPodInfo(tt.unschedPod))
 | 
				
			||||||
				t.Errorf("failed to add pod to activeQ: %v", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if p, err := q.Pop(logger); err != nil || p.Pod != tt.unschedPod {
 | 
								if p, err := q.Pop(logger); err != nil || p.Pod != tt.unschedPod {
 | 
				
			||||||
				t.Errorf("Expected: %v after Pop, but got: %v", tt.unschedPod.Name, p.Pod.Name)
 | 
									t.Errorf("Expected: %v after Pop, but got: %v", tt.unschedPod.Name, p.Pod.Name)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -2007,8 +1969,8 @@ func TestPriorityQueue_AssignedPodAdded_(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			q.AssignedPodAdded(logger, tt.updatedAssignedPod)
 | 
								q.AssignedPodAdded(logger, tt.updatedAssignedPod)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if _, exists, _ := q.activeQ.Get(newQueuedPodInfoForLookup(tt.unschedPod)); exists != tt.wantToRequeue {
 | 
								if q.activeQ.Has(newQueuedPodInfoForLookup(tt.unschedPod)) != tt.wantToRequeue {
 | 
				
			||||||
				t.Fatalf("unexpected Pod move: Pod should be requeued: %v. Pod is actually requeued: %v", tt.wantToRequeue, exists)
 | 
									t.Fatalf("unexpected Pod move: Pod should be requeued: %v. Pod is actually requeued: %v", tt.wantToRequeue, !tt.wantToRequeue)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -2107,11 +2069,11 @@ func TestPriorityQueue_PendingPods(t *testing.T) {
 | 
				
			|||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	q := NewTestQueue(ctx, newDefaultQueueSort())
 | 
						q := NewTestQueue(ctx, newDefaultQueueSort())
 | 
				
			||||||
	// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
						// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(unschedulablePodInfo.Pod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(unschedulablePodInfo.Pod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(highPriorityPodInfo.Pod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(highPriorityPodInfo.Pod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != highPriorityPodInfo.Pod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPodInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -2150,9 +2112,7 @@ func TestPriorityQueue_UpdateNominatedPodForNode(t *testing.T) {
 | 
				
			|||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	objs := []runtime.Object{medPriorityPodInfo.Pod, unschedulablePodInfo.Pod, highPriorityPodInfo.Pod, scheduledPodInfo.Pod}
 | 
						objs := []runtime.Object{medPriorityPodInfo.Pod, unschedulablePodInfo.Pod, highPriorityPodInfo.Pod, scheduledPodInfo.Pod}
 | 
				
			||||||
	q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
						q := NewTestQueueWithObjects(ctx, newDefaultQueueSort(), objs)
 | 
				
			||||||
	if err := q.Add(logger, medPriorityPodInfo.Pod); err != nil {
 | 
						q.Add(logger, medPriorityPodInfo.Pod)
 | 
				
			||||||
		t.Errorf("add failed: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Update unschedulablePodInfo on a different node than specified in the pod.
 | 
						// Update unschedulablePodInfo on a different node than specified in the pod.
 | 
				
			||||||
	q.AddNominatedPod(logger, mustNewTestPodInfo(t, unschedulablePodInfo.Pod),
 | 
						q.AddNominatedPod(logger, mustNewTestPodInfo(t, unschedulablePodInfo.Pod),
 | 
				
			||||||
		&framework.NominatingInfo{NominatingMode: framework.ModeOverride, NominatedNodeName: "node5"})
 | 
							&framework.NominatingInfo{NominatingMode: framework.ModeOverride, NominatedNodeName: "node5"})
 | 
				
			||||||
@@ -2459,7 +2419,7 @@ func TestPodFailedSchedulingMultipleTimesDoesNotBlockNewerPod(t *testing.T) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
						// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(unschedulablePod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(unschedulablePod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != unschedulablePod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -2597,11 +2557,11 @@ func TestHighPriorityFlushUnschedulablePodsLeftover(t *testing.T) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
						// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent()s below.
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(highPod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(highPod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != highPod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != highPod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", highPod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", highPod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	q.activeQ.Add(q.newQueuedPodInfo(midPod))
 | 
						q.activeQ.AddOrUpdate(q.newQueuedPodInfo(midPod))
 | 
				
			||||||
	if p, err := q.Pop(logger); err != nil || p.Pod != midPod {
 | 
						if p, err := q.Pop(logger); err != nil || p.Pod != midPod {
 | 
				
			||||||
		t.Errorf("Expected: %v after Pop, but got: %v", midPod.Name, p.Pod.Name)
 | 
							t.Errorf("Expected: %v after Pop, but got: %v", midPod.Name, p.Pod.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -2698,7 +2658,7 @@ func TestPriorityQueue_initPodMaxInUnschedulablePodsDuration(t *testing.T) {
 | 
				
			|||||||
				if pInfo, err := queue.activeQ.Pop(); err != nil {
 | 
									if pInfo, err := queue.activeQ.Pop(); err != nil {
 | 
				
			||||||
					t.Errorf("Error while popping the head of the queue: %v", err)
 | 
										t.Errorf("Error while popping the head of the queue: %v", err)
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					podInfoList = append(podInfoList, pInfo.(*framework.QueuedPodInfo))
 | 
										podInfoList = append(podInfoList, pInfo)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2713,17 +2673,13 @@ type operation func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInf
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	add = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
						add = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
				
			||||||
		if err := queue.Add(logger, pInfo.Pod); err != nil {
 | 
							queue.Add(logger, pInfo.Pod)
 | 
				
			||||||
			t.Fatalf("Unexpected error during Add: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	popAndRequeueAsUnschedulable = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
						popAndRequeueAsUnschedulable = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
				
			||||||
		// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
							// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
				
			||||||
		// UnschedulablePlugins will get cleared by Pop, so make a copy first.
 | 
							// UnschedulablePlugins will get cleared by Pop, so make a copy first.
 | 
				
			||||||
		unschedulablePlugins := pInfo.UnschedulablePlugins.Clone()
 | 
							unschedulablePlugins := pInfo.UnschedulablePlugins.Clone()
 | 
				
			||||||
		if err := queue.activeQ.Add(queue.newQueuedPodInfo(pInfo.Pod)); err != nil {
 | 
							queue.activeQ.AddOrUpdate(queue.newQueuedPodInfo(pInfo.Pod))
 | 
				
			||||||
			t.Fatalf("Unexpected error during Add: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		p, err := queue.Pop(logger)
 | 
							p, err := queue.Pop(logger)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Fatalf("Unexpected error during Pop: %v", err)
 | 
								t.Fatalf("Unexpected error during Pop: %v", err)
 | 
				
			||||||
@@ -2739,9 +2695,7 @@ var (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	popAndRequeueAsBackoff = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
						popAndRequeueAsBackoff = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
				
			||||||
		// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
							// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
				
			||||||
		if err := queue.activeQ.Add(queue.newQueuedPodInfo(pInfo.Pod)); err != nil {
 | 
							queue.activeQ.AddOrUpdate(queue.newQueuedPodInfo(pInfo.Pod))
 | 
				
			||||||
			t.Fatalf("Unexpected error during Add: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		p, err := queue.Pop(logger)
 | 
							p, err := queue.Pop(logger)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Fatalf("Unexpected error during Pop: %v", err)
 | 
								t.Fatalf("Unexpected error during Pop: %v", err)
 | 
				
			||||||
@@ -2755,10 +2709,7 @@ var (
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	addPodActiveQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
						addPodActiveQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
				
			||||||
		queue.activeQ.Add(pInfo)
 | 
							queue.activeQ.AddOrUpdate(pInfo)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	updatePodActiveQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
					 | 
				
			||||||
		queue.activeQ.Update(pInfo)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	addPodUnschedulablePods = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
						addPodUnschedulablePods = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
				
			||||||
		if !pInfo.Gated {
 | 
							if !pInfo.Gated {
 | 
				
			||||||
@@ -2781,7 +2732,7 @@ var (
 | 
				
			|||||||
		queue.Update(logger, pInfo.Pod, newPod)
 | 
							queue.Update(logger, pInfo.Pod, newPod)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	addPodBackoffQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
						addPodBackoffQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, pInfo *framework.QueuedPodInfo) {
 | 
				
			||||||
		queue.podBackoffQ.Add(pInfo)
 | 
							queue.podBackoffQ.AddOrUpdate(pInfo)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	moveAllToActiveOrBackoffQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, _ *framework.QueuedPodInfo) {
 | 
						moveAllToActiveOrBackoffQ = func(t *testing.T, logger klog.Logger, queue *PriorityQueue, _ *framework.QueuedPodInfo) {
 | 
				
			||||||
		queue.MoveAllToActiveOrBackoffQueue(logger, framework.UnschedulableTimeout, nil, nil, nil)
 | 
							queue.MoveAllToActiveOrBackoffQueue(logger, framework.UnschedulableTimeout, nil, nil, nil)
 | 
				
			||||||
@@ -2829,15 +2780,6 @@ func TestPodTimestamp(t *testing.T) {
 | 
				
			|||||||
			operands: []*framework.QueuedPodInfo{pInfo2, pInfo1},
 | 
								operands: []*framework.QueuedPodInfo{pInfo2, pInfo1},
 | 
				
			||||||
			expected: []*framework.QueuedPodInfo{pInfo1, pInfo2},
 | 
								expected: []*framework.QueuedPodInfo{pInfo1, pInfo2},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "update two pod to activeQ and sort them by the timestamp",
 | 
					 | 
				
			||||||
			operations: []operation{
 | 
					 | 
				
			||||||
				updatePodActiveQ,
 | 
					 | 
				
			||||||
				updatePodActiveQ,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			operands: []*framework.QueuedPodInfo{pInfo2, pInfo1},
 | 
					 | 
				
			||||||
			expected: []*framework.QueuedPodInfo{pInfo1, pInfo2},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name: "add two pod to unschedulablePods then move them to activeQ and sort them by the timestamp",
 | 
								name: "add two pod to unschedulablePods then move them to activeQ and sort them by the timestamp",
 | 
				
			||||||
			operations: []operation{
 | 
								operations: []operation{
 | 
				
			||||||
@@ -2883,7 +2825,7 @@ func TestPodTimestamp(t *testing.T) {
 | 
				
			|||||||
				if pInfo, err := queue.activeQ.Pop(); err != nil {
 | 
									if pInfo, err := queue.activeQ.Pop(); err != nil {
 | 
				
			||||||
					t.Errorf("Error while popping the head of the queue: %v", err)
 | 
										t.Errorf("Error while popping the head of the queue: %v", err)
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					podInfoList = append(podInfoList, pInfo.(*framework.QueuedPodInfo))
 | 
										podInfoList = append(podInfoList, pInfo)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3398,9 +3340,7 @@ func TestBackOffFlow(t *testing.T) {
 | 
				
			|||||||
		Namespace: pod.Namespace,
 | 
							Namespace: pod.Namespace,
 | 
				
			||||||
		Name:      pod.Name,
 | 
							Name:      pod.Name,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := q.Add(logger, pod); err != nil {
 | 
						q.Add(logger, pod)
 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, step := range steps {
 | 
						for i, step := range steps {
 | 
				
			||||||
		t.Run(fmt.Sprintf("step %d", i), func(t *testing.T) {
 | 
							t.Run(fmt.Sprintf("step %d", i), func(t *testing.T) {
 | 
				
			||||||
@@ -3421,7 +3361,7 @@ func TestBackOffFlow(t *testing.T) {
 | 
				
			|||||||
			// An event happens.
 | 
								// An event happens.
 | 
				
			||||||
			q.MoveAllToActiveOrBackoffQueue(logger, framework.UnschedulableTimeout, nil, nil, nil)
 | 
								q.MoveAllToActiveOrBackoffQueue(logger, framework.UnschedulableTimeout, nil, nil, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if _, ok, _ := q.podBackoffQ.Get(podInfo); !ok {
 | 
								if !q.podBackoffQ.Has(podInfo) {
 | 
				
			||||||
				t.Errorf("pod %v is not in the backoff queue", podID)
 | 
									t.Errorf("pod %v is not in the backoff queue", podID)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3436,13 +3376,13 @@ func TestBackOffFlow(t *testing.T) {
 | 
				
			|||||||
			cl.Step(time.Millisecond)
 | 
								cl.Step(time.Millisecond)
 | 
				
			||||||
			q.flushBackoffQCompleted(logger)
 | 
								q.flushBackoffQCompleted(logger)
 | 
				
			||||||
			// Still in backoff queue after an early flush.
 | 
								// Still in backoff queue after an early flush.
 | 
				
			||||||
			if _, ok, _ := q.podBackoffQ.Get(podInfo); !ok {
 | 
								if !q.podBackoffQ.Has(podInfo) {
 | 
				
			||||||
				t.Errorf("pod %v is not in the backoff queue", podID)
 | 
									t.Errorf("pod %v is not in the backoff queue", podID)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// Moved out of the backoff queue after timeout.
 | 
								// Moved out of the backoff queue after timeout.
 | 
				
			||||||
			cl.Step(backoff)
 | 
								cl.Step(backoff)
 | 
				
			||||||
			q.flushBackoffQCompleted(logger)
 | 
								q.flushBackoffQCompleted(logger)
 | 
				
			||||||
			if _, ok, _ := q.podBackoffQ.Get(podInfo); ok {
 | 
								if q.podBackoffQ.Has(podInfo) {
 | 
				
			||||||
				t.Errorf("pod %v is still in the backoff queue", podID)
 | 
									t.Errorf("pod %v is still in the backoff queue", podID)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
@@ -3513,7 +3453,7 @@ func TestMoveAllToActiveOrBackoffQueue_PreEnqueueChecks(t *testing.T) {
 | 
				
			|||||||
			q := NewTestQueue(ctx, newDefaultQueueSort())
 | 
								q := NewTestQueue(ctx, newDefaultQueueSort())
 | 
				
			||||||
			for i, podInfo := range tt.podInfos {
 | 
								for i, podInfo := range tt.podInfos {
 | 
				
			||||||
				// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
									// To simulate the pod is failed in scheduling in the real world, Pop() the pod from activeQ before AddUnschedulableIfNotPresent() below.
 | 
				
			||||||
				q.activeQ.Add(q.newQueuedPodInfo(podInfo.Pod))
 | 
									q.activeQ.AddOrUpdate(q.newQueuedPodInfo(podInfo.Pod))
 | 
				
			||||||
				if p, err := q.Pop(logger); err != nil || p.Pod != podInfo.Pod {
 | 
									if p, err := q.Pop(logger); err != nil || p.Pod != podInfo.Pod {
 | 
				
			||||||
					t.Errorf("Expected: %v after Pop, but got: %v", podInfo.Pod.Name, p.Pod.Name)
 | 
										t.Errorf("Expected: %v after Pop, but got: %v", podInfo.Pod.Name, p.Pod.Name)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -3532,14 +3472,10 @@ func TestMoveAllToActiveOrBackoffQueue_PreEnqueueChecks(t *testing.T) {
 | 
				
			|||||||
			q.MoveAllToActiveOrBackoffQueue(logger, tt.event, nil, nil, tt.preEnqueueCheck)
 | 
								q.MoveAllToActiveOrBackoffQueue(logger, tt.event, nil, nil, tt.preEnqueueCheck)
 | 
				
			||||||
			var got []string
 | 
								var got []string
 | 
				
			||||||
			for q.podBackoffQ.Len() != 0 {
 | 
								for q.podBackoffQ.Len() != 0 {
 | 
				
			||||||
				obj, err := q.podBackoffQ.Pop()
 | 
									queuedPodInfo, err := q.podBackoffQ.Pop()
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					t.Fatalf("Fail to pop pod from backoffQ: %v", err)
 | 
										t.Fatalf("Fail to pop pod from backoffQ: %v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				queuedPodInfo, ok := obj.(*framework.QueuedPodInfo)
 | 
					 | 
				
			||||||
				if !ok {
 | 
					 | 
				
			||||||
					t.Fatalf("Fail to convert popped obj (type %T) to *framework.QueuedPodInfo", obj)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				got = append(got, queuedPodInfo.Pod.Name)
 | 
									got = append(got, queuedPodInfo.Pod.Name)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if diff := cmp.Diff(tt.want, got); diff != "" {
 | 
								if diff := cmp.Diff(tt.want, got); diff != "" {
 | 
				
			||||||
@@ -3912,9 +3848,7 @@ func Test_queuedPodInfo_gatedSetUponCreationAndUnsetUponUpdate(t *testing.T) {
 | 
				
			|||||||
	q := NewTestQueue(ctx, newDefaultQueueSort(), WithPreEnqueuePluginMap(m))
 | 
						q := NewTestQueue(ctx, newDefaultQueueSort(), WithPreEnqueuePluginMap(m))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gatedPod := st.MakePod().SchedulingGates([]string{"hello world"}).Obj()
 | 
						gatedPod := st.MakePod().SchedulingGates([]string{"hello world"}).Obj()
 | 
				
			||||||
	if err := q.Add(logger, gatedPod); err != nil {
 | 
						q.Add(logger, gatedPod)
 | 
				
			||||||
		t.Errorf("Error while adding gated pod: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !q.unschedulablePods.get(gatedPod).Gated {
 | 
						if !q.unschedulablePods.get(gatedPod).Gated {
 | 
				
			||||||
		t.Error("Expected pod to be gated")
 | 
							t.Error("Expected pod to be gated")
 | 
				
			||||||
@@ -3922,9 +3856,7 @@ func Test_queuedPodInfo_gatedSetUponCreationAndUnsetUponUpdate(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ungatedPod := gatedPod.DeepCopy()
 | 
						ungatedPod := gatedPod.DeepCopy()
 | 
				
			||||||
	ungatedPod.Spec.SchedulingGates = nil
 | 
						ungatedPod.Spec.SchedulingGates = nil
 | 
				
			||||||
	if err := q.Update(logger, gatedPod, ungatedPod); err != nil {
 | 
						q.Update(logger, gatedPod, ungatedPod)
 | 
				
			||||||
		t.Errorf("Error while updating pod to ungated: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ungatedPodInfo, _ := q.Pop(logger)
 | 
						ungatedPodInfo, _ := q.Pop(logger)
 | 
				
			||||||
	if ungatedPodInfo.Gated {
 | 
						if ungatedPodInfo.Gated {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -287,9 +287,7 @@ func TestFailureHandler(t *testing.T) {
 | 
				
			|||||||
			queue := internalqueue.NewPriorityQueue(nil, informerFactory, internalqueue.WithClock(testingclock.NewFakeClock(time.Now())))
 | 
								queue := internalqueue.NewPriorityQueue(nil, informerFactory, internalqueue.WithClock(testingclock.NewFakeClock(time.Now())))
 | 
				
			||||||
			schedulerCache := internalcache.New(ctx, 30*time.Second)
 | 
								schedulerCache := internalcache.New(ctx, 30*time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := queue.Add(logger, testPod); err != nil {
 | 
								queue.Add(logger, testPod)
 | 
				
			||||||
				t.Fatalf("Add failed: %v", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if _, err := queue.Pop(logger); err != nil {
 | 
								if _, err := queue.Pop(logger); err != nil {
 | 
				
			||||||
				t.Fatalf("Pop failed: %v", err)
 | 
									t.Fatalf("Pop failed: %v", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -314,13 +314,7 @@ func TestCoreResourceEnqueue(t *testing.T) {
 | 
				
			|||||||
				newPod = oldPod.DeepCopy()
 | 
									newPod = oldPod.DeepCopy()
 | 
				
			||||||
				newPod.Status.Conditions[0].Message = "injected message"
 | 
									newPod.Status.Conditions[0].Message = "injected message"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if err := testCtx.Scheduler.SchedulingQueue.Update(
 | 
									testCtx.Scheduler.SchedulingQueue.Update(klog.FromContext(testCtx.Ctx), oldPod, newPod)
 | 
				
			||||||
					klog.FromContext(testCtx.Ctx),
 | 
					 | 
				
			||||||
					oldPod,
 | 
					 | 
				
			||||||
					newPod,
 | 
					 | 
				
			||||||
				); err != nil {
 | 
					 | 
				
			||||||
					return fmt.Errorf("failed to update the pod: %w", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			wantRequeuedPods: sets.Set[string]{},
 | 
								wantRequeuedPods: sets.Set[string]{},
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user