fixture.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. Copyright 2019 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package network
  14. import (
  15. "context"
  16. v1 "k8s.io/api/core/v1"
  17. apierrors "k8s.io/apimachinery/pkg/api/errors"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/apimachinery/pkg/util/intstr"
  20. "k8s.io/apimachinery/pkg/util/uuid"
  21. clientset "k8s.io/client-go/kubernetes"
  22. "k8s.io/client-go/util/retry"
  23. imageutils "k8s.io/kubernetes/test/utils/image"
  24. "github.com/onsi/ginkgo"
  25. )
  26. // TestFixture is a simple helper class to avoid too much boilerplate in tests
  27. type TestFixture struct {
  28. ServiceName string
  29. Namespace string
  30. Client clientset.Interface
  31. TestID string
  32. Labels map[string]string
  33. rcs map[string]bool
  34. services map[string]bool
  35. Name string
  36. Image string
  37. }
  38. // NewServerTest creates a new TestFixture for the tests.
  39. func NewServerTest(client clientset.Interface, namespace string, serviceName string) *TestFixture {
  40. t := &TestFixture{}
  41. t.Client = client
  42. t.Namespace = namespace
  43. t.ServiceName = serviceName
  44. t.TestID = t.ServiceName + "-" + string(uuid.NewUUID())
  45. t.Labels = map[string]string{
  46. "testid": t.TestID,
  47. }
  48. t.rcs = make(map[string]bool)
  49. t.services = make(map[string]bool)
  50. t.Name = "webserver"
  51. t.Image = imageutils.GetE2EImage(imageutils.Agnhost)
  52. return t
  53. }
  54. // BuildServiceSpec builds default config for a service (which can then be changed)
  55. func (t *TestFixture) BuildServiceSpec() *v1.Service {
  56. service := &v1.Service{
  57. ObjectMeta: metav1.ObjectMeta{
  58. Name: t.ServiceName,
  59. Namespace: t.Namespace,
  60. },
  61. Spec: v1.ServiceSpec{
  62. Selector: t.Labels,
  63. Ports: []v1.ServicePort{{
  64. Port: 80,
  65. TargetPort: intstr.FromInt(80),
  66. }},
  67. },
  68. }
  69. return service
  70. }
  71. // CreateRC creates a replication controller and records it for cleanup.
  72. func (t *TestFixture) CreateRC(rc *v1.ReplicationController) (*v1.ReplicationController, error) {
  73. rc, err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Create(context.TODO(), rc, metav1.CreateOptions{})
  74. if err == nil {
  75. t.rcs[rc.Name] = true
  76. }
  77. return rc, err
  78. }
  79. // CreateService creates a service, and record it for cleanup
  80. func (t *TestFixture) CreateService(service *v1.Service) (*v1.Service, error) {
  81. result, err := t.Client.CoreV1().Services(t.Namespace).Create(context.TODO(), service, metav1.CreateOptions{})
  82. if err == nil {
  83. t.services[service.Name] = true
  84. }
  85. return result, err
  86. }
  87. // DeleteService deletes a service, and remove it from the cleanup list
  88. func (t *TestFixture) DeleteService(serviceName string) error {
  89. err := t.Client.CoreV1().Services(t.Namespace).Delete(context.TODO(), serviceName, nil)
  90. if err == nil {
  91. delete(t.services, serviceName)
  92. }
  93. return err
  94. }
  95. // Cleanup cleans all ReplicationControllers and Services which this object holds.
  96. func (t *TestFixture) Cleanup() []error {
  97. var errs []error
  98. for rcName := range t.rcs {
  99. ginkgo.By("stopping RC " + rcName + " in namespace " + t.Namespace)
  100. err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
  101. // First, resize the RC to 0.
  102. old, err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Get(context.TODO(), rcName, metav1.GetOptions{})
  103. if err != nil {
  104. if apierrors.IsNotFound(err) {
  105. return nil
  106. }
  107. return err
  108. }
  109. x := int32(0)
  110. old.Spec.Replicas = &x
  111. if _, err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Update(context.TODO(), old, metav1.UpdateOptions{}); err != nil {
  112. if apierrors.IsNotFound(err) {
  113. return nil
  114. }
  115. return err
  116. }
  117. return nil
  118. })
  119. if err != nil {
  120. errs = append(errs, err)
  121. }
  122. // TODO(mikedanese): Wait.
  123. // Then, delete the RC altogether.
  124. if err := t.Client.CoreV1().ReplicationControllers(t.Namespace).Delete(context.TODO(), rcName, nil); err != nil {
  125. if !apierrors.IsNotFound(err) {
  126. errs = append(errs, err)
  127. }
  128. }
  129. }
  130. for serviceName := range t.services {
  131. ginkgo.By("deleting service " + serviceName + " in namespace " + t.Namespace)
  132. err := t.Client.CoreV1().Services(t.Namespace).Delete(context.TODO(), serviceName, nil)
  133. if err != nil {
  134. if !apierrors.IsNotFound(err) {
  135. errs = append(errs, err)
  136. }
  137. }
  138. }
  139. return errs
  140. }