mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Cover get equivalence cache in core
Fix testing method
This commit is contained in:
		@@ -18,6 +18,7 @@ package predicates
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
						"k8s.io/api/core/v1"
 | 
				
			||||||
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/labels"
 | 
						"k8s.io/apimachinery/pkg/labels"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,3 +65,27 @@ func CreateSelectorFromLabels(aL map[string]string) labels.Selector {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return labels.Set(aL).AsSelector()
 | 
						return labels.Set(aL).AsSelector()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetEquivalencePod returns a EquivalencePod which contains a group of pod attributes which can be reused.
 | 
				
			||||||
 | 
					func GetEquivalencePod(pod *v1.Pod) interface{} {
 | 
				
			||||||
 | 
						// For now we only consider pods:
 | 
				
			||||||
 | 
						// 1. OwnerReferences is Controller
 | 
				
			||||||
 | 
						// 2. with same OwnerReferences
 | 
				
			||||||
 | 
						// to be equivalent
 | 
				
			||||||
 | 
						if len(pod.OwnerReferences) != 0 {
 | 
				
			||||||
 | 
							for _, ref := range pod.OwnerReferences {
 | 
				
			||||||
 | 
								if *ref.Controller {
 | 
				
			||||||
 | 
									// a pod can only belongs to one controller
 | 
				
			||||||
 | 
									return &EquivalencePod{
 | 
				
			||||||
 | 
										ControllerRef: ref,
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EquivalencePod is a group of pod attributes which can be reused as equivalence to schedule other pods.
 | 
				
			||||||
 | 
					type EquivalencePod struct {
 | 
				
			||||||
 | 
						ControllerRef metav1.OwnerReference
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,6 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
					 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
					 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
 | 
						"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
 | 
				
			||||||
	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
 | 
						"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
 | 
				
			||||||
@@ -89,7 +87,7 @@ func init() {
 | 
				
			|||||||
	factory.RegisterFitPredicate("MatchNodeSelector", predicates.PodMatchNodeSelector)
 | 
						factory.RegisterFitPredicate("MatchNodeSelector", predicates.PodMatchNodeSelector)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Use equivalence class to speed up predicates & priorities
 | 
						// Use equivalence class to speed up predicates & priorities
 | 
				
			||||||
	factory.RegisterGetEquivalencePodFunction(GetEquivalencePod)
 | 
						factory.RegisterGetEquivalencePodFunction(predicates.GetEquivalencePod)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ServiceSpreadingPriority is a priority config factory that spreads pods by minimizing
 | 
						// ServiceSpreadingPriority is a priority config factory that spreads pods by minimizing
 | 
				
			||||||
	// the number of pods (belonging to the same service) on the same node.
 | 
						// the number of pods (belonging to the same service) on the same node.
 | 
				
			||||||
@@ -252,27 +250,3 @@ func copyAndReplace(set sets.String, replaceWhat, replaceWith string) sets.Strin
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetEquivalencePod returns a EquivalencePod which contains a group of pod attributes which can be reused.
 | 
					 | 
				
			||||||
func GetEquivalencePod(pod *v1.Pod) interface{} {
 | 
					 | 
				
			||||||
	// For now we only consider pods:
 | 
					 | 
				
			||||||
	// 1. OwnerReferences is Controller
 | 
					 | 
				
			||||||
	// 2. with same OwnerReferences
 | 
					 | 
				
			||||||
	// to be equivalent
 | 
					 | 
				
			||||||
	if len(pod.OwnerReferences) != 0 {
 | 
					 | 
				
			||||||
		for _, ref := range pod.OwnerReferences {
 | 
					 | 
				
			||||||
			if *ref.Controller {
 | 
					 | 
				
			||||||
				// a pod can only belongs to one controller
 | 
					 | 
				
			||||||
				return &EquivalencePod{
 | 
					 | 
				
			||||||
					ControllerRef: ref,
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EquivalencePod is a group of pod attributes which can be reused as equivalence to schedule other pods.
 | 
					 | 
				
			||||||
type EquivalencePod struct {
 | 
					 | 
				
			||||||
	ControllerRef metav1.OwnerReference
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,7 +66,7 @@ func NewEquivalenceCache(getEquivalencePodFunc algorithm.GetEquivalencePodFunc)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateCachedPredicateItem updates pod predicate for equivalence class
 | 
					// UpdateCachedPredicateItem updates pod predicate for equivalence class
 | 
				
			||||||
func (ec *EquivalenceCache) UpdateCachedPredicateItem(pod *v1.Pod, nodeName, predicateKey string, fit bool, reasons []algorithm.PredicateFailureReason, equivalenceHash uint64) {
 | 
					func (ec *EquivalenceCache) UpdateCachedPredicateItem(podName, nodeName, predicateKey string, fit bool, reasons []algorithm.PredicateFailureReason, equivalenceHash uint64) {
 | 
				
			||||||
	ec.Lock()
 | 
						ec.Lock()
 | 
				
			||||||
	defer ec.Unlock()
 | 
						defer ec.Unlock()
 | 
				
			||||||
	if _, exist := ec.algorithmCache[nodeName]; !exist {
 | 
						if _, exist := ec.algorithmCache[nodeName]; !exist {
 | 
				
			||||||
@@ -87,7 +87,7 @@ func (ec *EquivalenceCache) UpdateCachedPredicateItem(pod *v1.Pod, nodeName, pre
 | 
				
			|||||||
				equivalenceHash: predicateItem,
 | 
									equivalenceHash: predicateItem,
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	glog.V(5).Infof("Updated cached predicate: %v for pod: %v on node: %s, with item %v", predicateKey, pod.GetName(), nodeName, predicateItem)
 | 
						glog.V(5).Infof("Updated cached predicate: %v for pod: %v on node: %s, with item %v", predicateKey, podName, nodeName, predicateItem)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PredicateWithECache returns:
 | 
					// PredicateWithECache returns:
 | 
				
			||||||
@@ -95,10 +95,10 @@ func (ec *EquivalenceCache) UpdateCachedPredicateItem(pod *v1.Pod, nodeName, pre
 | 
				
			|||||||
// 2. reasons if not fit
 | 
					// 2. reasons if not fit
 | 
				
			||||||
// 3. if this cache is invalid
 | 
					// 3. if this cache is invalid
 | 
				
			||||||
// based on cached predicate results
 | 
					// based on cached predicate results
 | 
				
			||||||
func (ec *EquivalenceCache) PredicateWithECache(pod *v1.Pod, nodeName, predicateKey string, equivalenceHash uint64) (bool, []algorithm.PredicateFailureReason, bool) {
 | 
					func (ec *EquivalenceCache) PredicateWithECache(podName, nodeName, predicateKey string, equivalenceHash uint64) (bool, []algorithm.PredicateFailureReason, bool) {
 | 
				
			||||||
	ec.RLock()
 | 
						ec.RLock()
 | 
				
			||||||
	defer ec.RUnlock()
 | 
						defer ec.RUnlock()
 | 
				
			||||||
	glog.V(5).Infof("Begin to calculate predicate: %v for pod: %s on node: %s based on equivalence cache", predicateKey, pod.GetName(), nodeName)
 | 
						glog.V(5).Infof("Begin to calculate predicate: %v for pod: %s on node: %s based on equivalence cache", predicateKey, podName, nodeName)
 | 
				
			||||||
	if algorithmCache, exist := ec.algorithmCache[nodeName]; exist {
 | 
						if algorithmCache, exist := ec.algorithmCache[nodeName]; exist {
 | 
				
			||||||
		if cachePredicate, exist := algorithmCache.predicatesCache.Get(predicateKey); exist {
 | 
							if cachePredicate, exist := algorithmCache.predicatesCache.Get(predicateKey); exist {
 | 
				
			||||||
			predicateMap := cachePredicate.(PredicateMap)
 | 
								predicateMap := cachePredicate.(PredicateMap)
 | 
				
			||||||
@@ -158,31 +158,6 @@ func (ec *EquivalenceCache) InvalidateAllCachedPredicateItemOfNode(nodeName stri
 | 
				
			|||||||
	glog.V(5).Infof("Done invalidating all cached predicates on node: %s", nodeName)
 | 
						glog.V(5).Infof("Done invalidating all cached predicates on node: %s", nodeName)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// InvalidateCachedPredicateItemForPod marks item of given predicateKeys, of given pod (i.e. equivalenceHash),
 | 
					 | 
				
			||||||
// on the given node as invalid
 | 
					 | 
				
			||||||
func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPod(nodeName string, predicateKeys sets.String, pod *v1.Pod) {
 | 
					 | 
				
			||||||
	if len(predicateKeys) == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	equivalenceHash := ec.getHashEquivalencePod(pod)
 | 
					 | 
				
			||||||
	if equivalenceHash == 0 {
 | 
					 | 
				
			||||||
		// no equivalence pod found, just return
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ec.Lock()
 | 
					 | 
				
			||||||
	defer ec.Unlock()
 | 
					 | 
				
			||||||
	if algorithmCache, exist := ec.algorithmCache[nodeName]; exist {
 | 
					 | 
				
			||||||
		for predicateKey := range predicateKeys {
 | 
					 | 
				
			||||||
			if cachePredicate, exist := algorithmCache.predicatesCache.Get(predicateKey); exist {
 | 
					 | 
				
			||||||
				// got the cached item of by predicateKey & pod
 | 
					 | 
				
			||||||
				predicateMap := cachePredicate.(PredicateMap)
 | 
					 | 
				
			||||||
				delete(predicateMap, equivalenceHash)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.V(5).Infof("Done invalidating cached predicates %v on node %s, for pod %v", predicateKeys, nodeName, pod.GetName())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// InvalidateCachedPredicateItemForPodAdd is a wrapper of InvalidateCachedPredicateItem for pod add case
 | 
					// InvalidateCachedPredicateItemForPodAdd is a wrapper of InvalidateCachedPredicateItem for pod add case
 | 
				
			||||||
func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod, nodeName string) {
 | 
					func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod, nodeName string) {
 | 
				
			||||||
	// MatchInterPodAffinity: we assume scheduler can make sure newly binded pod
 | 
						// MatchInterPodAffinity: we assume scheduler can make sure newly binded pod
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,10 +27,15 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
 | 
						"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type predicateItemType struct {
 | 
				
			||||||
 | 
						fit     bool
 | 
				
			||||||
 | 
						reasons []algorithm.PredicateFailureReason
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestUpdateCachedPredicateItem(t *testing.T) {
 | 
					func TestUpdateCachedPredicateItem(t *testing.T) {
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name               string
 | 
							name               string
 | 
				
			||||||
		pod                *v1.Pod
 | 
							pod                string
 | 
				
			||||||
		predicateKey       string
 | 
							predicateKey       string
 | 
				
			||||||
		nodeName           string
 | 
							nodeName           string
 | 
				
			||||||
		fit                bool
 | 
							fit                bool
 | 
				
			||||||
@@ -41,7 +46,7 @@ func TestUpdateCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:               "test 1",
 | 
								name:               "test 1",
 | 
				
			||||||
			pod:                &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "testPod"}},
 | 
								pod:                "testPod",
 | 
				
			||||||
			predicateKey:       "GeneralPredicates",
 | 
								predicateKey:       "GeneralPredicates",
 | 
				
			||||||
			nodeName:           "node1",
 | 
								nodeName:           "node1",
 | 
				
			||||||
			fit:                true,
 | 
								fit:                true,
 | 
				
			||||||
@@ -53,7 +58,7 @@ func TestUpdateCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:               "test 2",
 | 
								name:               "test 2",
 | 
				
			||||||
			pod:                &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "testPod"}},
 | 
								pod:                "testPod",
 | 
				
			||||||
			predicateKey:       "GeneralPredicates",
 | 
								predicateKey:       "GeneralPredicates",
 | 
				
			||||||
			nodeName:           "node2",
 | 
								nodeName:           "node2",
 | 
				
			||||||
			fit:                false,
 | 
								fit:                false,
 | 
				
			||||||
@@ -78,29 +83,33 @@ func TestUpdateCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
					test.equivalenceHash: predicateItem,
 | 
										test.equivalenceHash: predicateItem,
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ecache.UpdateCachedPredicateItem(test.pod, test.nodeName, test.predicateKey, test.fit, test.reasons, test.equivalenceHash)
 | 
							ecache.UpdateCachedPredicateItem(
 | 
				
			||||||
 | 
								test.pod,
 | 
				
			||||||
 | 
								test.nodeName,
 | 
				
			||||||
 | 
								test.predicateKey,
 | 
				
			||||||
 | 
								test.fit,
 | 
				
			||||||
 | 
								test.reasons,
 | 
				
			||||||
 | 
								test.equivalenceHash,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		value, ok := ecache.algorithmCache[test.nodeName].predicatesCache.Get(test.predicateKey)
 | 
							value, ok := ecache.algorithmCache[test.nodeName].predicatesCache.Get(test.predicateKey)
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			t.Errorf("Failed : %s, can't find expected cache item: %v", test.name, test.expectCacheItem)
 | 
								t.Errorf("Failed: %s, can't find expected cache item: %v",
 | 
				
			||||||
 | 
									test.name, test.expectCacheItem)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			cachedMapItem := value.(PredicateMap)
 | 
								cachedMapItem := value.(PredicateMap)
 | 
				
			||||||
			if !reflect.DeepEqual(cachedMapItem[test.equivalenceHash], test.expectCacheItem) {
 | 
								if !reflect.DeepEqual(cachedMapItem[test.equivalenceHash], test.expectCacheItem) {
 | 
				
			||||||
				t.Errorf("Failed : %s, expected cached item: %v, but got: %v", test.name, test.expectCacheItem, cachedMapItem[test.equivalenceHash])
 | 
									t.Errorf("Failed: %s, expected cached item: %v, but got: %v",
 | 
				
			||||||
 | 
										test.name, test.expectCacheItem, cachedMapItem[test.equivalenceHash])
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type predicateItemType struct {
 | 
					func TestPredicateWithECache(t *testing.T) {
 | 
				
			||||||
	fit     bool
 | 
					 | 
				
			||||||
	reasons []algorithm.PredicateFailureReason
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestCachedPredicateItem(t *testing.T) {
 | 
					 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name                              string
 | 
							name                              string
 | 
				
			||||||
		pod                               *v1.Pod
 | 
							podName                           string
 | 
				
			||||||
		nodeName                          string
 | 
							nodeName                          string
 | 
				
			||||||
		predicateKey                      string
 | 
							predicateKey                      string
 | 
				
			||||||
		equivalenceHashForUpdatePredicate uint64
 | 
							equivalenceHashForUpdatePredicate uint64
 | 
				
			||||||
@@ -112,7 +121,7 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:     "test 1",
 | 
								name:     "test 1",
 | 
				
			||||||
			pod:      &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "testPod"}},
 | 
								podName:  "testPod",
 | 
				
			||||||
			nodeName: "node1",
 | 
								nodeName: "node1",
 | 
				
			||||||
			equivalenceHashForUpdatePredicate: 123,
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
			equivalenceHashForCalPredicate:    123,
 | 
								equivalenceHashForCalPredicate:    123,
 | 
				
			||||||
@@ -129,7 +138,7 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:     "test 2",
 | 
								name:     "test 2",
 | 
				
			||||||
			pod:      &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "testPod"}},
 | 
								podName:  "testPod",
 | 
				
			||||||
			nodeName: "node2",
 | 
								nodeName: "node2",
 | 
				
			||||||
			equivalenceHashForUpdatePredicate: 123,
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
			equivalenceHashForCalPredicate:    123,
 | 
								equivalenceHashForCalPredicate:    123,
 | 
				
			||||||
@@ -145,7 +154,7 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:     "test 3",
 | 
								name:     "test 3",
 | 
				
			||||||
			pod:      &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "testPod"}},
 | 
								podName:  "testPod",
 | 
				
			||||||
			nodeName: "node3",
 | 
								nodeName: "node3",
 | 
				
			||||||
			equivalenceHashForUpdatePredicate: 123,
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
			equivalenceHashForCalPredicate:    123,
 | 
								equivalenceHashForCalPredicate:    123,
 | 
				
			||||||
@@ -162,7 +171,7 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:     "test 4",
 | 
								name:     "test 4",
 | 
				
			||||||
			pod:      &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "testPod"}},
 | 
								podName:  "testPod",
 | 
				
			||||||
			nodeName: "node4",
 | 
								nodeName: "node4",
 | 
				
			||||||
			equivalenceHashForUpdatePredicate: 123,
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
			equivalenceHashForCalPredicate:    456,
 | 
								equivalenceHashForCalPredicate:    456,
 | 
				
			||||||
@@ -185,7 +194,14 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
		fakeGetEquivalencePodFunc := func(pod *v1.Pod) interface{} { return nil }
 | 
							fakeGetEquivalencePodFunc := func(pod *v1.Pod) interface{} { return nil }
 | 
				
			||||||
		ecache := NewEquivalenceCache(fakeGetEquivalencePodFunc)
 | 
							ecache := NewEquivalenceCache(fakeGetEquivalencePodFunc)
 | 
				
			||||||
		// set cached item to equivalence cache
 | 
							// set cached item to equivalence cache
 | 
				
			||||||
		ecache.UpdateCachedPredicateItem(test.pod, test.nodeName, test.predicateKey, test.cachedItem.fit, test.cachedItem.reasons, test.equivalenceHashForUpdatePredicate)
 | 
							ecache.UpdateCachedPredicateItem(
 | 
				
			||||||
 | 
								test.podName,
 | 
				
			||||||
 | 
								test.nodeName,
 | 
				
			||||||
 | 
								test.predicateKey,
 | 
				
			||||||
 | 
								test.cachedItem.fit,
 | 
				
			||||||
 | 
								test.cachedItem.reasons,
 | 
				
			||||||
 | 
								test.equivalenceHashForUpdatePredicate,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
		// if we want to do invalid, invalid the cached item
 | 
							// if we want to do invalid, invalid the cached item
 | 
				
			||||||
		if test.expectedInvalidPredicateKey {
 | 
							if test.expectedInvalidPredicateKey {
 | 
				
			||||||
			predicateKeys := sets.NewString()
 | 
								predicateKeys := sets.NewString()
 | 
				
			||||||
@@ -193,15 +209,21 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
			ecache.InvalidateCachedPredicateItem(test.nodeName, predicateKeys)
 | 
								ecache.InvalidateCachedPredicateItem(test.nodeName, predicateKeys)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// calculate predicate with equivalence cache
 | 
							// calculate predicate with equivalence cache
 | 
				
			||||||
		fit, reasons, invalid := ecache.PredicateWithECache(test.pod, test.nodeName, test.predicateKey, test.equivalenceHashForCalPredicate)
 | 
							fit, reasons, invalid := ecache.PredicateWithECache(test.podName,
 | 
				
			||||||
 | 
								test.nodeName,
 | 
				
			||||||
 | 
								test.predicateKey,
 | 
				
			||||||
 | 
								test.equivalenceHashForCalPredicate,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
		// returned invalid should match expectedInvalidPredicateKey or expectedInvalidEquivalenceHash
 | 
							// returned invalid should match expectedInvalidPredicateKey or expectedInvalidEquivalenceHash
 | 
				
			||||||
		if test.equivalenceHashForUpdatePredicate != test.equivalenceHashForCalPredicate {
 | 
							if test.equivalenceHashForUpdatePredicate != test.equivalenceHashForCalPredicate {
 | 
				
			||||||
			if invalid != test.expectedInvalidEquivalenceHash {
 | 
								if invalid != test.expectedInvalidEquivalenceHash {
 | 
				
			||||||
				t.Errorf("Failed : %s when using invalid equivalenceHash, expected invalid: %v, but got: %v", test.name, test.expectedInvalidEquivalenceHash, invalid)
 | 
									t.Errorf("Failed: %s, expected invalid: %v, but got: %v",
 | 
				
			||||||
 | 
										test.name, test.expectedInvalidEquivalenceHash, invalid)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if invalid != test.expectedInvalidPredicateKey {
 | 
								if invalid != test.expectedInvalidPredicateKey {
 | 
				
			||||||
				t.Errorf("Failed : %s, expected invalid: %v, but got: %v", test.name, test.expectedInvalidPredicateKey, invalid)
 | 
									t.Errorf("Failed: %s, expected invalid: %v, but got: %v",
 | 
				
			||||||
 | 
										test.name, test.expectedInvalidPredicateKey, invalid)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// returned predicate result should match expected predicate item
 | 
							// returned predicate result should match expected predicate item
 | 
				
			||||||
@@ -209,7 +231,219 @@ func TestCachedPredicateItem(t *testing.T) {
 | 
				
			|||||||
			t.Errorf("Failed: %s, expected fit: %v, but got: %v", test.name, test.cachedItem.fit, fit)
 | 
								t.Errorf("Failed: %s, expected fit: %v, but got: %v", test.name, test.cachedItem.fit, fit)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if !reflect.DeepEqual(reasons, test.expectedPredicateItem.reasons) {
 | 
							if !reflect.DeepEqual(reasons, test.expectedPredicateItem.reasons) {
 | 
				
			||||||
			t.Errorf("Failed : %s, expected reasons: %v, but got: %v", test.name, test.cachedItem.reasons, reasons)
 | 
								t.Errorf("Failed: %s, expected reasons: %v, but got: %v",
 | 
				
			||||||
 | 
									test.name, test.cachedItem.reasons, reasons)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGetHashEquivalencePod(t *testing.T) {
 | 
				
			||||||
 | 
						//  use default equivalence class calculator
 | 
				
			||||||
 | 
						ecache := NewEquivalenceCache(predicates.GetEquivalencePod)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						isController := true
 | 
				
			||||||
 | 
						pod1 := &v1.Pod{
 | 
				
			||||||
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
								Name: "pod1",
 | 
				
			||||||
 | 
								OwnerReferences: []metav1.OwnerReference{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										APIVersion: "v1",
 | 
				
			||||||
 | 
										Kind:       "ReplicationController",
 | 
				
			||||||
 | 
										Name:       "rc",
 | 
				
			||||||
 | 
										UID:        "123",
 | 
				
			||||||
 | 
										Controller: &isController,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pod2 := &v1.Pod{
 | 
				
			||||||
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
								Name: "pod2",
 | 
				
			||||||
 | 
								OwnerReferences: []metav1.OwnerReference{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										APIVersion: "v1",
 | 
				
			||||||
 | 
										Kind:       "ReplicationController",
 | 
				
			||||||
 | 
										Name:       "rc",
 | 
				
			||||||
 | 
										UID:        "123",
 | 
				
			||||||
 | 
										Controller: &isController,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pod3 := &v1.Pod{
 | 
				
			||||||
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
								Name: "pod3",
 | 
				
			||||||
 | 
								OwnerReferences: []metav1.OwnerReference{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										APIVersion: "v1",
 | 
				
			||||||
 | 
										Kind:       "ReplicationController",
 | 
				
			||||||
 | 
										Name:       "rc",
 | 
				
			||||||
 | 
										UID:        "567",
 | 
				
			||||||
 | 
										Controller: &isController,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hash1 := ecache.getHashEquivalencePod(pod1)
 | 
				
			||||||
 | 
						hash2 := ecache.getHashEquivalencePod(pod2)
 | 
				
			||||||
 | 
						hash3 := ecache.getHashEquivalencePod(pod3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if hash1 != hash2 {
 | 
				
			||||||
 | 
							t.Errorf("Failed: pod %v and %v is expected to be equivalent", pod1.Name, pod2.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if hash2 == hash3 {
 | 
				
			||||||
 | 
							t.Errorf("Failed: pod %v and %v is not expected to be equivalent", pod2.Name, pod3.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// pod4 is a pod without controller ref
 | 
				
			||||||
 | 
						pod4 := &v1.Pod{
 | 
				
			||||||
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
								Name: "pod4",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hash4 := ecache.getHashEquivalencePod(pod4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if hash4 != 0 {
 | 
				
			||||||
 | 
							t.Errorf("Failed: equivalence hash of pod %v is expected to be: 0, but got: %v",
 | 
				
			||||||
 | 
								pod4.Name, hash4)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestInvalidateCachedPredicateItemOfAllNodes(t *testing.T) {
 | 
				
			||||||
 | 
						testPredicate := "GeneralPredicates"
 | 
				
			||||||
 | 
						// tests is used to initialize all nodes
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							podName                           string
 | 
				
			||||||
 | 
							nodeName                          string
 | 
				
			||||||
 | 
							predicateKey                      string
 | 
				
			||||||
 | 
							equivalenceHashForUpdatePredicate uint64
 | 
				
			||||||
 | 
							cachedItem                        predicateItemType
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								podName:  "testPod",
 | 
				
			||||||
 | 
								nodeName: "node1",
 | 
				
			||||||
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
 | 
								cachedItem: predicateItemType{
 | 
				
			||||||
 | 
									fit: false,
 | 
				
			||||||
 | 
									reasons: []algorithm.PredicateFailureReason{
 | 
				
			||||||
 | 
										predicates.ErrPodNotFitsHostPorts,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								podName:  "testPod",
 | 
				
			||||||
 | 
								nodeName: "node2",
 | 
				
			||||||
 | 
								equivalenceHashForUpdatePredicate: 456,
 | 
				
			||||||
 | 
								cachedItem: predicateItemType{
 | 
				
			||||||
 | 
									fit: false,
 | 
				
			||||||
 | 
									reasons: []algorithm.PredicateFailureReason{
 | 
				
			||||||
 | 
										predicates.ErrPodNotFitsHostPorts,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								podName:  "testPod",
 | 
				
			||||||
 | 
								nodeName: "node3",
 | 
				
			||||||
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
 | 
								cachedItem: predicateItemType{
 | 
				
			||||||
 | 
									fit: true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// this case does not need to calculate equivalence hash, just pass an empty function
 | 
				
			||||||
 | 
						fakeGetEquivalencePodFunc := func(pod *v1.Pod) interface{} { return nil }
 | 
				
			||||||
 | 
						ecache := NewEquivalenceCache(fakeGetEquivalencePodFunc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, test := range tests {
 | 
				
			||||||
 | 
							// set cached item to equivalence cache
 | 
				
			||||||
 | 
							ecache.UpdateCachedPredicateItem(
 | 
				
			||||||
 | 
								test.podName,
 | 
				
			||||||
 | 
								test.nodeName,
 | 
				
			||||||
 | 
								testPredicate,
 | 
				
			||||||
 | 
								test.cachedItem.fit,
 | 
				
			||||||
 | 
								test.cachedItem.reasons,
 | 
				
			||||||
 | 
								test.equivalenceHashForUpdatePredicate,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// invalidate cached predicate for all nodes
 | 
				
			||||||
 | 
						ecache.InvalidateCachedPredicateItemOfAllNodes(sets.NewString(testPredicate))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// there should be no cached predicate any more
 | 
				
			||||||
 | 
						for _, test := range tests {
 | 
				
			||||||
 | 
							if algorithmCache, exist := ecache.algorithmCache[test.nodeName]; exist {
 | 
				
			||||||
 | 
								if _, exist := algorithmCache.predicatesCache.Get(testPredicate); exist {
 | 
				
			||||||
 | 
									t.Errorf("Failed: cached item for predicate key: %v on node: %v should be invalidated",
 | 
				
			||||||
 | 
										testPredicate, test.nodeName)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestInvalidateAllCachedPredicateItemOfNode(t *testing.T) {
 | 
				
			||||||
 | 
						testPredicate := "GeneralPredicates"
 | 
				
			||||||
 | 
						// tests is used to initialize all nodes
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							podName                           string
 | 
				
			||||||
 | 
							nodeName                          string
 | 
				
			||||||
 | 
							predicateKey                      string
 | 
				
			||||||
 | 
							equivalenceHashForUpdatePredicate uint64
 | 
				
			||||||
 | 
							cachedItem                        predicateItemType
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								podName:  "testPod",
 | 
				
			||||||
 | 
								nodeName: "node1",
 | 
				
			||||||
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
 | 
								cachedItem: predicateItemType{
 | 
				
			||||||
 | 
									fit:     false,
 | 
				
			||||||
 | 
									reasons: []algorithm.PredicateFailureReason{predicates.ErrPodNotFitsHostPorts},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								podName:  "testPod",
 | 
				
			||||||
 | 
								nodeName: "node2",
 | 
				
			||||||
 | 
								equivalenceHashForUpdatePredicate: 456,
 | 
				
			||||||
 | 
								cachedItem: predicateItemType{
 | 
				
			||||||
 | 
									fit:     false,
 | 
				
			||||||
 | 
									reasons: []algorithm.PredicateFailureReason{predicates.ErrPodNotFitsHostPorts},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								podName:  "testPod",
 | 
				
			||||||
 | 
								nodeName: "node3",
 | 
				
			||||||
 | 
								equivalenceHashForUpdatePredicate: 123,
 | 
				
			||||||
 | 
								cachedItem: predicateItemType{
 | 
				
			||||||
 | 
									fit: true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// this case does not need to calculate equivalence hash, just pass an empty function
 | 
				
			||||||
 | 
						fakeGetEquivalencePodFunc := func(pod *v1.Pod) interface{} { return nil }
 | 
				
			||||||
 | 
						ecache := NewEquivalenceCache(fakeGetEquivalencePodFunc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, test := range tests {
 | 
				
			||||||
 | 
							// set cached item to equivalence cache
 | 
				
			||||||
 | 
							ecache.UpdateCachedPredicateItem(
 | 
				
			||||||
 | 
								test.podName,
 | 
				
			||||||
 | 
								test.nodeName,
 | 
				
			||||||
 | 
								testPredicate,
 | 
				
			||||||
 | 
								test.cachedItem.fit,
 | 
				
			||||||
 | 
								test.cachedItem.reasons,
 | 
				
			||||||
 | 
								test.equivalenceHashForUpdatePredicate,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, test := range tests {
 | 
				
			||||||
 | 
							// invalidate cached predicate for all nodes
 | 
				
			||||||
 | 
							ecache.InvalidateAllCachedPredicateItemOfNode(test.nodeName)
 | 
				
			||||||
 | 
							if _, exist := ecache.algorithmCache[test.nodeName]; exist {
 | 
				
			||||||
 | 
								t.Errorf("Failed: cached item for node: %v should be invalidated", test.nodeName)
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -251,7 +251,7 @@ func podFitsOnNode(pod *v1.Pod, meta interface{}, info *schedulercache.NodeInfo,
 | 
				
			|||||||
		// If equivalenceCache is available
 | 
							// If equivalenceCache is available
 | 
				
			||||||
		if eCacheAvailable {
 | 
							if eCacheAvailable {
 | 
				
			||||||
			// PredicateWithECache will returns it's cached predicate results
 | 
								// PredicateWithECache will returns it's cached predicate results
 | 
				
			||||||
			fit, reasons, invalid = ecache.PredicateWithECache(pod, info.Node().GetName(), predicateKey, equivalenceHash)
 | 
								fit, reasons, invalid = ecache.PredicateWithECache(pod.GetName(), info.Node().GetName(), predicateKey, equivalenceHash)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !eCacheAvailable || invalid {
 | 
							if !eCacheAvailable || invalid {
 | 
				
			||||||
@@ -264,7 +264,7 @@ func podFitsOnNode(pod *v1.Pod, meta interface{}, info *schedulercache.NodeInfo,
 | 
				
			|||||||
			if eCacheAvailable {
 | 
								if eCacheAvailable {
 | 
				
			||||||
				// update equivalence cache with newly computed fit & reasons
 | 
									// update equivalence cache with newly computed fit & reasons
 | 
				
			||||||
				// TODO(resouer) should we do this in another thread? any race?
 | 
									// TODO(resouer) should we do this in another thread? any race?
 | 
				
			||||||
				ecache.UpdateCachedPredicateItem(pod, info.Node().GetName(), predicateKey, fit, reasons, equivalenceHash)
 | 
									ecache.UpdateCachedPredicateItem(pod.GetName(), info.Node().GetName(), predicateKey, fit, reasons, equivalenceHash)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user