k8s.io/kubernetes@v1.29.3/test/integration/framework/perf_utils.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package framework 18 19 import ( 20 "context" 21 22 v1 "k8s.io/api/core/v1" 23 "k8s.io/apimachinery/pkg/api/resource" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/util/rand" 26 clientset "k8s.io/client-go/kubernetes" 27 "k8s.io/klog/v2" 28 testutils "k8s.io/kubernetes/test/utils" 29 ) 30 31 const ( 32 retries = 5 33 ) 34 35 // IntegrationTestNodePreparer holds configuration information for the test node preparer. 36 type IntegrationTestNodePreparer struct { 37 client clientset.Interface 38 countToStrategy []testutils.CountToStrategy 39 nodeNamePrefix string 40 nodeSpec *v1.Node 41 } 42 43 // NewIntegrationTestNodePreparer creates an IntegrationTestNodePreparer configured with defaults. 44 func NewIntegrationTestNodePreparer(client clientset.Interface, countToStrategy []testutils.CountToStrategy, nodeNamePrefix string) testutils.TestNodePreparer { 45 return &IntegrationTestNodePreparer{ 46 client: client, 47 countToStrategy: countToStrategy, 48 nodeNamePrefix: nodeNamePrefix, 49 } 50 } 51 52 // NewIntegrationTestNodePreparerWithNodeSpec creates an IntegrationTestNodePreparer configured with nodespec. 53 func NewIntegrationTestNodePreparerWithNodeSpec(client clientset.Interface, countToStrategy []testutils.CountToStrategy, nodeSpec *v1.Node) testutils.TestNodePreparer { 54 return &IntegrationTestNodePreparer{ 55 client: client, 56 countToStrategy: countToStrategy, 57 nodeSpec: nodeSpec, 58 } 59 } 60 61 // PrepareNodes prepares countToStrategy test nodes. 62 func (p *IntegrationTestNodePreparer) PrepareNodes(ctx context.Context, nextNodeIndex int) error { 63 numNodes := 0 64 for _, v := range p.countToStrategy { 65 numNodes += v.Count 66 } 67 68 klog.Infof("Making %d nodes", numNodes) 69 baseNode := &v1.Node{ 70 ObjectMeta: metav1.ObjectMeta{ 71 GenerateName: p.nodeNamePrefix, 72 }, 73 Status: v1.NodeStatus{ 74 Capacity: v1.ResourceList{ 75 v1.ResourcePods: *resource.NewQuantity(110, resource.DecimalSI), 76 v1.ResourceCPU: resource.MustParse("4"), 77 v1.ResourceMemory: resource.MustParse("32Gi"), 78 }, 79 Phase: v1.NodeRunning, 80 Conditions: []v1.NodeCondition{ 81 {Type: v1.NodeReady, Status: v1.ConditionTrue}, 82 }, 83 }, 84 } 85 86 if p.nodeSpec != nil { 87 baseNode = p.nodeSpec 88 } 89 90 for i := 0; i < numNodes; i++ { 91 var err error 92 for retry := 0; retry < retries; retry++ { 93 // Create nodes with the usual kubernetes.io/hostname label. 94 // For that we need to know the name in advance, if we want to 95 // do it in one request. 96 node := baseNode.DeepCopy() 97 name := node.Name 98 if name == "" { 99 name = node.GenerateName + rand.String(5) 100 node.Name = name 101 } 102 if node.Labels == nil { 103 node.Labels = make(map[string]string) 104 } 105 node.Labels["kubernetes.io/hostname"] = name 106 _, err = p.client.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) 107 if err == nil { 108 break 109 } 110 } 111 if err != nil { 112 klog.Fatalf("Error creating node: %v", err) 113 } 114 } 115 116 nodes, err := waitListAllNodes(p.client) 117 if err != nil { 118 klog.Fatalf("Error listing nodes: %v", err) 119 } 120 index := nextNodeIndex 121 for _, v := range p.countToStrategy { 122 for i := 0; i < v.Count; i, index = i+1, index+1 { 123 if err := testutils.DoPrepareNode(ctx, p.client, &nodes.Items[index], v.Strategy); err != nil { 124 klog.Errorf("Aborting node preparation: %v", err) 125 return err 126 } 127 } 128 } 129 return nil 130 } 131 132 // CleanupNodes deletes existing test nodes. 133 func (p *IntegrationTestNodePreparer) CleanupNodes(ctx context.Context) error { 134 // TODO(#93794): make CleanupNodes only clean up the nodes created by this 135 // IntegrationTestNodePreparer to make this more intuitive. 136 nodes, err := waitListAllNodes(p.client) 137 if err != nil { 138 klog.Fatalf("Error listing nodes: %v", err) 139 } 140 var errRet error 141 for i := range nodes.Items { 142 if err := p.client.CoreV1().Nodes().Delete(ctx, nodes.Items[i].Name, metav1.DeleteOptions{}); err != nil { 143 klog.Errorf("Error while deleting Node: %v", err) 144 errRet = err 145 } 146 } 147 return errRet 148 }