k8s.io/kubernetes@v1.29.3/test/e2e/network/fixture.go (about) 1 /* 2 Copyright 2019 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 network 18 19 import ( 20 "context" 21 22 v1 "k8s.io/api/core/v1" 23 apierrors "k8s.io/apimachinery/pkg/api/errors" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/util/intstr" 26 "k8s.io/apimachinery/pkg/util/uuid" 27 clientset "k8s.io/client-go/kubernetes" 28 "k8s.io/client-go/util/retry" 29 imageutils "k8s.io/kubernetes/test/utils/image" 30 31 "github.com/onsi/ginkgo/v2" 32 ) 33 34 // TestFixture is a simple helper class to avoid too much boilerplate in tests 35 type TestFixture struct { 36 ServiceName string 37 Namespace string 38 Client clientset.Interface 39 40 TestID string 41 Labels map[string]string 42 43 rcs map[string]bool 44 services map[string]bool 45 Name string 46 Image string 47 } 48 49 // NewServerTest creates a new TestFixture for the tests. 50 func NewServerTest(client clientset.Interface, namespace string, serviceName string) *TestFixture { 51 t := &TestFixture{} 52 t.Client = client 53 t.Namespace = namespace 54 t.ServiceName = serviceName 55 t.TestID = t.ServiceName + "-" + string(uuid.NewUUID()) 56 t.Labels = map[string]string{ 57 "testid": t.TestID, 58 } 59 60 t.rcs = make(map[string]bool) 61 t.services = make(map[string]bool) 62 63 t.Name = "webserver" 64 t.Image = imageutils.GetE2EImage(imageutils.Agnhost) 65 66 return t 67 } 68 69 // BuildServiceSpec builds default config for a service (which can then be changed) 70 func (t *TestFixture) BuildServiceSpec() *v1.Service { 71 service := &v1.Service{ 72 ObjectMeta: metav1.ObjectMeta{ 73 Name: t.ServiceName, 74 Namespace: t.Namespace, 75 }, 76 Spec: v1.ServiceSpec{ 77 Selector: t.Labels, 78 Ports: []v1.ServicePort{{ 79 Port: 80, 80 TargetPort: intstr.FromInt32(80), 81 }}, 82 }, 83 } 84 return service 85 } 86 87 // CreateRC creates a replication controller and records it for cleanup. 88 func (t *TestFixture) CreateRC(rc *v1.ReplicationController) (*v1.ReplicationController, error) { 89 rc, err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Create(context.TODO(), rc, metav1.CreateOptions{}) 90 if err == nil { 91 t.rcs[rc.Name] = true 92 } 93 return rc, err 94 } 95 96 // CreateService creates a service, and record it for cleanup 97 func (t *TestFixture) CreateService(service *v1.Service) (*v1.Service, error) { 98 result, err := t.Client.CoreV1().Services(t.Namespace).Create(context.TODO(), service, metav1.CreateOptions{}) 99 if err == nil { 100 t.services[service.Name] = true 101 } 102 return result, err 103 } 104 105 // DeleteService deletes a service, and remove it from the cleanup list 106 func (t *TestFixture) DeleteService(serviceName string) error { 107 err := t.Client.CoreV1().Services(t.Namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{}) 108 if err == nil { 109 delete(t.services, serviceName) 110 } 111 return err 112 } 113 114 // Cleanup cleans all ReplicationControllers and Services which this object holds. 115 func (t *TestFixture) Cleanup() []error { 116 var errs []error 117 for rcName := range t.rcs { 118 ginkgo.By("stopping RC " + rcName + " in namespace " + t.Namespace) 119 err := retry.RetryOnConflict(retry.DefaultRetry, func() error { 120 // First, resize the RC to 0. 121 old, err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Get(context.TODO(), rcName, metav1.GetOptions{}) 122 if err != nil { 123 if apierrors.IsNotFound(err) { 124 return nil 125 } 126 return err 127 } 128 x := int32(0) 129 old.Spec.Replicas = &x 130 if _, err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Update(context.TODO(), old, metav1.UpdateOptions{}); err != nil { 131 if apierrors.IsNotFound(err) { 132 return nil 133 } 134 return err 135 } 136 return nil 137 }) 138 if err != nil { 139 errs = append(errs, err) 140 } 141 // TODO(mikedanese): Wait. 142 // Then, delete the RC altogether. 143 if err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Delete(context.TODO(), rcName, metav1.DeleteOptions{}); err != nil { 144 if !apierrors.IsNotFound(err) { 145 errs = append(errs, err) 146 } 147 } 148 } 149 150 for serviceName := range t.services { 151 ginkgo.By("deleting service " + serviceName + " in namespace " + t.Namespace) 152 err := t.Client.CoreV1().Services(t.Namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{}) 153 if err != nil { 154 if !apierrors.IsNotFound(err) { 155 errs = append(errs, err) 156 } 157 } 158 } 159 160 return errs 161 }