From 656a08afdf318000015e8a7a80b566bd9c865cfb Mon Sep 17 00:00:00 2001 From: Krzysztof Wiatrzyk Date: Wed, 28 Oct 2020 14:51:03 +0100 Subject: [PATCH] Move scope specific tests from topologymanager under particular scopes Signed-off-by: Krzysztof Wiatrzyk --- .../topologymanager/scope_container_test.go | 268 ++++++++++++++++++ .../cm/topologymanager/scope_pod_test.go | 268 ++++++++++++++++++ .../topologymanager/topology_manager_test.go | 238 ---------------- 3 files changed, 536 insertions(+), 238 deletions(-) create mode 100644 pkg/kubelet/cm/topologymanager/scope_container_test.go create mode 100644 pkg/kubelet/cm/topologymanager/scope_pod_test.go diff --git a/pkg/kubelet/cm/topologymanager/scope_container_test.go b/pkg/kubelet/cm/topologymanager/scope_container_test.go new file mode 100644 index 00000000000..67eaf5c5803 --- /dev/null +++ b/pkg/kubelet/cm/topologymanager/scope_container_test.go @@ -0,0 +1,268 @@ +/* +Copyright 2020 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 topologymanager + +import ( + "reflect" + "testing" + + v1 "k8s.io/api/core/v1" +) + +func TestContainerCalculateAffinity(t *testing.T) { + tcases := []struct { + name string + hp []HintProvider + expected []map[string][]TopologyHint + }{ + { + name: "No hint providers", + hp: []HintProvider{}, + expected: ([]map[string][]TopologyHint)(nil), + }, + { + name: "HintProvider returns empty non-nil map[string][]TopologyHint", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{}, + }, + }, + expected: []map[string][]TopologyHint{ + {}, + }, + }, + { + name: "HintProvider returns -nil map[string][]TopologyHint from provider", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource": nil, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource": nil, + }, + }, + }, + { + name: "Assorted HintProviders", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource-1/A": { + {NUMANodeAffinity: NewTestBitMask(0), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false}, + }, + "resource-1/B": { + {NUMANodeAffinity: NewTestBitMask(1), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false}, + }, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{ + "resource-2/A": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + "resource-2/B": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{ + "resource-3": nil, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource-1/A": { + {NUMANodeAffinity: NewTestBitMask(0), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false}, + }, + "resource-1/B": { + {NUMANodeAffinity: NewTestBitMask(1), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false}, + }, + }, + { + "resource-2/A": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + "resource-2/B": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + }, + { + "resource-3": nil, + }, + }, + }, + } + + for _, tc := range tcases { + ctnScope := &containerScope{ + scope{ + hintProviders: tc.hp, + policy: &mockPolicy{}, + name: podTopologyScope, + }, + } + + ctnScope.calculateAffinity(&v1.Pod{}, &v1.Container{}) + actual := ctnScope.policy.(*mockPolicy).ph + if !reflect.DeepEqual(tc.expected, actual) { + t.Errorf("Test Case: %s", tc.name) + t.Errorf("Expected result to be %v, got %v", tc.expected, actual) + } + } +} + +func TestContainerAccumulateProvidersHints(t *testing.T) { + tcases := []struct { + name string + hp []HintProvider + expected []map[string][]TopologyHint + }{ + { + name: "TopologyHint not set", + hp: []HintProvider{}, + expected: nil, + }, + { + name: "HintProvider returns empty non-nil map[string][]TopologyHint", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{}, + }, + }, + expected: []map[string][]TopologyHint{ + {}, + }, + }, + { + name: "HintProvider returns - nil map[string][]TopologyHint from provider", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource": nil, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource": nil, + }, + }, + }, + { + name: "2 HintProviders with 1 resource returns hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{ + "resource2": {TopologyHint{}}, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + }, + { + "resource2": {TopologyHint{}}, + }, + }, + }, + { + name: "2 HintProviders 1 with 1 resource 1 with nil hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + }, + }, + &mockHintProvider{nil}, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + }, + nil, + }, + }, + { + name: "2 HintProviders 1 with 1 resource 1 empty hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{}, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + }, + {}, + }, + }, + { + name: "HintProvider with 2 resources returns hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + "resource2": {TopologyHint{}}, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + "resource2": {TopologyHint{}}, + }, + }, + }, + } + + for _, tc := range tcases { + ctnScope := containerScope{ + scope{ + hintProviders: tc.hp, + }, + } + actual := ctnScope.accumulateProvidersHints(&v1.Pod{}, &v1.Container{}) + if !reflect.DeepEqual(actual, tc.expected) { + t.Errorf("Test Case %s: Expected NUMANodeAffinity in result to be %v, got %v", tc.name, tc.expected, actual) + } + } +} diff --git a/pkg/kubelet/cm/topologymanager/scope_pod_test.go b/pkg/kubelet/cm/topologymanager/scope_pod_test.go new file mode 100644 index 00000000000..3d3ec4eb5a5 --- /dev/null +++ b/pkg/kubelet/cm/topologymanager/scope_pod_test.go @@ -0,0 +1,268 @@ +/* +Copyright 2020 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 topologymanager + +import ( + "reflect" + "testing" + + v1 "k8s.io/api/core/v1" +) + +func TestPodCalculateAffinity(t *testing.T) { + tcases := []struct { + name string + hp []HintProvider + expected []map[string][]TopologyHint + }{ + { + name: "No hint providers", + hp: []HintProvider{}, + expected: ([]map[string][]TopologyHint)(nil), + }, + { + name: "HintProvider returns empty non-nil map[string][]TopologyHint", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{}, + }, + }, + expected: []map[string][]TopologyHint{ + {}, + }, + }, + { + name: "HintProvider returns -nil map[string][]TopologyHint from provider", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource": nil, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource": nil, + }, + }, + }, + { + name: "Assorted HintProviders", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource-1/A": { + {NUMANodeAffinity: NewTestBitMask(0), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false}, + }, + "resource-1/B": { + {NUMANodeAffinity: NewTestBitMask(1), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false}, + }, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{ + "resource-2/A": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + "resource-2/B": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{ + "resource-3": nil, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource-1/A": { + {NUMANodeAffinity: NewTestBitMask(0), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false}, + }, + "resource-1/B": { + {NUMANodeAffinity: NewTestBitMask(1), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false}, + }, + }, + { + "resource-2/A": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + "resource-2/B": { + {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, + {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, + }, + }, + { + "resource-3": nil, + }, + }, + }, + } + + for _, tc := range tcases { + podScope := &podScope{ + scope{ + hintProviders: tc.hp, + policy: &mockPolicy{}, + name: podTopologyScope, + }, + } + + podScope.calculateAffinity(&v1.Pod{}) + actual := podScope.policy.(*mockPolicy).ph + if !reflect.DeepEqual(tc.expected, actual) { + t.Errorf("Test Case: %s", tc.name) + t.Errorf("Expected result to be %v, got %v", tc.expected, actual) + } + } +} + +func TestPodAccumulateProvidersHints(t *testing.T) { + tcases := []struct { + name string + hp []HintProvider + expected []map[string][]TopologyHint + }{ + { + name: "TopologyHint not set", + hp: []HintProvider{}, + expected: nil, + }, + { + name: "HintProvider returns empty non-nil map[string][]TopologyHint", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{}, + }, + }, + expected: []map[string][]TopologyHint{ + {}, + }, + }, + { + name: "HintProvider returns - nil map[string][]TopologyHint from provider", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource": nil, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource": nil, + }, + }, + }, + { + name: "2 HintProviders with 1 resource returns hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{ + "resource2": {TopologyHint{}}, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + }, + { + "resource2": {TopologyHint{}}, + }, + }, + }, + { + name: "2 HintProviders 1 with 1 resource 1 with nil hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + }, + }, + &mockHintProvider{nil}, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + }, + nil, + }, + }, + { + name: "2 HintProviders 1 with 1 resource 1 empty hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + }, + }, + &mockHintProvider{ + map[string][]TopologyHint{}, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + }, + {}, + }, + }, + { + name: "HintProvider with 2 resources returns hints", + hp: []HintProvider{ + &mockHintProvider{ + map[string][]TopologyHint{ + "resource1": {TopologyHint{}}, + "resource2": {TopologyHint{}}, + }, + }, + }, + expected: []map[string][]TopologyHint{ + { + "resource1": {TopologyHint{}}, + "resource2": {TopologyHint{}}, + }, + }, + }, + } + + for _, tc := range tcases { + pScope := podScope{ + scope{ + hintProviders: tc.hp, + }, + } + actual := pScope.accumulateProvidersHints(&v1.Pod{}) + if !reflect.DeepEqual(actual, tc.expected) { + t.Errorf("Test Case %s: Expected NUMANodeAffinity in result to be %v, got %v", tc.name, tc.expected, actual) + } + } +} diff --git a/pkg/kubelet/cm/topologymanager/topology_manager_test.go b/pkg/kubelet/cm/topologymanager/topology_manager_test.go index 947151baab3..6c84411c397 100644 --- a/pkg/kubelet/cm/topologymanager/topology_manager_test.go +++ b/pkg/kubelet/cm/topologymanager/topology_manager_test.go @@ -18,7 +18,6 @@ package topologymanager import ( "fmt" - "reflect" "strings" "testing" @@ -143,132 +142,6 @@ func (m *mockHintProvider) Allocate(pod *v1.Pod, container *v1.Container) error return nil } -func TestAccumulateProvidersHints(t *testing.T) { - tcases := []struct { - name string - hp []HintProvider - expected []map[string][]TopologyHint - }{ - { - name: "TopologyHint not set", - hp: []HintProvider{}, - expected: nil, - }, - { - name: "HintProvider returns empty non-nil map[string][]TopologyHint", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{}, - }, - }, - expected: []map[string][]TopologyHint{ - {}, - }, - }, - { - name: "HintProvider returns - nil map[string][]TopologyHint from provider", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource": nil, - }, - }, - }, - expected: []map[string][]TopologyHint{ - { - "resource": nil, - }, - }, - }, - { - name: "2 HintProviders with 1 resource returns hints", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource1": {TopologyHint{}}, - }, - }, - &mockHintProvider{ - map[string][]TopologyHint{ - "resource2": {TopologyHint{}}, - }, - }, - }, - expected: []map[string][]TopologyHint{ - { - "resource1": {TopologyHint{}}, - }, - { - "resource2": {TopologyHint{}}, - }, - }, - }, - { - name: "2 HintProviders 1 with 1 resource 1 with nil hints", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource1": {TopologyHint{}}, - }, - }, - &mockHintProvider{nil}, - }, - expected: []map[string][]TopologyHint{ - { - "resource1": {TopologyHint{}}, - }, - nil, - }, - }, - { - name: "2 HintProviders 1 with 1 resource 1 empty hints", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource1": {TopologyHint{}}, - }, - }, - &mockHintProvider{ - map[string][]TopologyHint{}, - }, - }, - expected: []map[string][]TopologyHint{ - { - "resource1": {TopologyHint{}}, - }, - {}, - }, - }, - { - name: "HintProvider with 2 resources returns hints", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource1": {TopologyHint{}}, - "resource2": {TopologyHint{}}, - }, - }, - }, - expected: []map[string][]TopologyHint{ - { - "resource1": {TopologyHint{}}, - "resource2": {TopologyHint{}}, - }, - }, - }, - } - - for _, tc := range tcases { - mngr := manager{ - hintProviders: tc.hp, - } - actual := mngr.accumulateProvidersHints(&v1.Pod{}, &v1.Container{}) - if !reflect.DeepEqual(actual, tc.expected) { - t.Errorf("Test Case %s: Expected NUMANodeAffinity in result to be %v, got %v", tc.name, tc.expected, actual) - } - } -} - type mockPolicy struct { nonePolicy ph []map[string][]TopologyHint @@ -279,117 +152,6 @@ func (p *mockPolicy) Merge(providersHints []map[string][]TopologyHint) (Topology return TopologyHint{}, true } -func TestCalculateAffinity(t *testing.T) { - tcases := []struct { - name string - hp []HintProvider - expected []map[string][]TopologyHint - }{ - { - name: "No hint providers", - hp: []HintProvider{}, - expected: ([]map[string][]TopologyHint)(nil), - }, - { - name: "HintProvider returns empty non-nil map[string][]TopologyHint", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{}, - }, - }, - expected: []map[string][]TopologyHint{ - {}, - }, - }, - { - name: "HintProvider returns -nil map[string][]TopologyHint from provider", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource": nil, - }, - }, - }, - expected: []map[string][]TopologyHint{ - { - "resource": nil, - }, - }, - }, - { - name: "Assorted HintProviders", - hp: []HintProvider{ - &mockHintProvider{ - map[string][]TopologyHint{ - "resource-1/A": { - {NUMANodeAffinity: NewTestBitMask(0), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false}, - }, - "resource-1/B": { - {NUMANodeAffinity: NewTestBitMask(1), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false}, - }, - }, - }, - &mockHintProvider{ - map[string][]TopologyHint{ - "resource-2/A": { - {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, - }, - "resource-2/B": { - {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, - }, - }, - }, - &mockHintProvider{ - map[string][]TopologyHint{ - "resource-3": nil, - }, - }, - }, - expected: []map[string][]TopologyHint{ - { - "resource-1/A": { - {NUMANodeAffinity: NewTestBitMask(0), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false}, - }, - "resource-1/B": { - {NUMANodeAffinity: NewTestBitMask(1), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false}, - }, - }, - { - "resource-2/A": { - {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, - }, - "resource-2/B": { - {NUMANodeAffinity: NewTestBitMask(2), Preferred: true}, - {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false}, - }, - }, - { - "resource-3": nil, - }, - }, - }, - } - - for _, tc := range tcases { - mngr := manager{} - mngr.policy = &mockPolicy{} - mngr.hintProviders = tc.hp - mngr.calculateAffinity(&v1.Pod{}, &v1.Container{}) - actual := mngr.policy.(*mockPolicy).ph - if !reflect.DeepEqual(tc.expected, actual) { - t.Errorf("Test Case: %s", tc.name) - t.Errorf("Expected result to be %v, got %v", tc.expected, actual) - } - } -} - func TestAddHintProvider(t *testing.T) { tcases := []struct { name string