diff --git a/plugin/pkg/scheduler/algorithm/priorities/util/BUILD b/plugin/pkg/scheduler/algorithm/priorities/util/BUILD index 7d69da117c9..00026932896 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/util/BUILD +++ b/plugin/pkg/scheduler/algorithm/priorities/util/BUILD @@ -5,6 +5,7 @@ licenses(["notice"]) load( "@io_bazel_rules_go//go:def.bzl", "go_library", + "go_test", ) go_library( @@ -37,3 +38,14 @@ filegroup( srcs = [":package-srcs"], tags = ["automanaged"], ) + +go_test( + name = "go_default_test", + srcs = ["topologies_test.go"], + library = ":go_default_library", + tags = ["automanaged"], + deps = [ + "//pkg/api/v1:go_default_library", + "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", + ], +) diff --git a/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go b/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go index 3615a7bc2f5..0638ab0836b 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go +++ b/plugin/pkg/scheduler/algorithm/priorities/util/topologies.go @@ -56,7 +56,20 @@ func NodesHaveSameTopologyKey(nodeA, nodeB *v1.Node, topologyKey string) bool { if len(topologyKey) == 0 { return false } - return nodeA.Labels != nil && nodeB.Labels != nil && len(nodeA.Labels[topologyKey]) > 0 && nodeA.Labels[topologyKey] == nodeB.Labels[topologyKey] + + if nodeA.Labels == nil || nodeB.Labels == nil { + return false + } + + nodeALabel, okA := nodeA.Labels[topologyKey] + nodeBLabel, okB := nodeB.Labels[topologyKey] + + // If found label in both nodes, check the label + if okB && okA { + return nodeALabel == nodeBLabel + } + + return false } type Topologies struct { diff --git a/plugin/pkg/scheduler/algorithm/priorities/util/topologies_test.go b/plugin/pkg/scheduler/algorithm/priorities/util/topologies_test.go new file mode 100644 index 00000000000..ec98aca7fa0 --- /dev/null +++ b/plugin/pkg/scheduler/algorithm/priorities/util/topologies_test.go @@ -0,0 +1,124 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/api/v1" +) + +func TestNodesHaveSameTopologyKey(t *testing.T) { + tests := []struct { + name string + nodeA, nodeB *v1.Node + topologyKey string + expected bool + }{ + { + name: "nodeA{'a':'a'} vs. empty label in nodeB", + nodeA: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "a", + }, + }, + }, + nodeB: &v1.Node{}, + expected: false, + topologyKey: "a", + }, + { + name: "nodeA{'a':'a'} vs. nodeB{'a':'a'}", + nodeA: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "a", + }, + }, + }, + nodeB: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "a", + }, + }, + }, + expected: true, + topologyKey: "a", + }, + { + name: "nodeA{'a':''} vs. empty label in nodeB", + nodeA: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "", + }, + }, + }, + nodeB: &v1.Node{}, + expected: false, + topologyKey: "a", + }, + { + name: "nodeA{'a':''} vs. nodeB{'a':''}", + nodeA: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "", + }, + }, + }, + nodeB: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "", + }, + }, + }, + expected: true, + topologyKey: "a", + }, + { + name: "nodeA{'a':'a'} vs. nodeB{'a':'a'} by key{'b'}", + nodeA: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "a", + }, + }, + }, + nodeB: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "a": "a", + }, + }, + }, + expected: false, + topologyKey: "b", + }, + } + + for _, test := range tests { + got := NodesHaveSameTopologyKey(test.nodeA, test.nodeB, test.topologyKey) + if test.expected != got { + t.Errorf("%v: expected %t, got %t", test.name, test.expected, got) + } + } +}