1
16
17 package network
18
19 import (
20 "context"
21
22 v1 "k8s.io/api/core/v1"
23 "k8s.io/apimachinery/pkg/util/wait"
24 "k8s.io/kubernetes/test/e2e/framework"
25 e2eservice "k8s.io/kubernetes/test/e2e/framework/service"
26 "k8s.io/kubernetes/test/e2e/upgrades"
27
28 "github.com/onsi/ginkgo/v2"
29 )
30
31
32
33
34 type ServiceUpgradeTest struct {
35 jig *e2eservice.TestJig
36 tcpService *v1.Service
37 tcpIngressIP string
38 svcPort int
39 }
40
41
42 func (ServiceUpgradeTest) Name() string { return "service-upgrade" }
43
44
45 func (t *ServiceUpgradeTest) Setup(ctx context.Context, f *framework.Framework) {
46 serviceName := "service-test"
47 jig := e2eservice.NewTestJig(f.ClientSet, f.Namespace.Name, serviceName)
48
49 ns := f.Namespace
50 cs := f.ClientSet
51
52 ginkgo.By("creating a TCP service " + serviceName + " with type=LoadBalancer in namespace " + ns.Name)
53 _, err := jig.CreateTCPService(ctx, func(s *v1.Service) {
54 s.Spec.Type = v1.ServiceTypeLoadBalancer
55 })
56 framework.ExpectNoError(err)
57 tcpService, err := jig.WaitForLoadBalancer(ctx, e2eservice.GetServiceLoadBalancerCreationTimeout(ctx, cs))
58 framework.ExpectNoError(err)
59
60
61 tcpIngressIP := e2eservice.GetIngressPoint(&tcpService.Status.LoadBalancer.Ingress[0])
62 svcPort := int(tcpService.Spec.Ports[0].Port)
63
64 ginkgo.By("creating pod to be part of service " + serviceName)
65 rc, err := jig.Run(ctx, jig.AddRCAntiAffinity)
66 framework.ExpectNoError(err)
67
68 ginkgo.By("creating a PodDisruptionBudget to cover the ReplicationController")
69 _, err = jig.CreatePDB(ctx, rc)
70 framework.ExpectNoError(err)
71
72
73 ginkgo.By("hitting the pod through the service's LoadBalancer")
74 timeout := e2eservice.LoadBalancerLagTimeoutDefault
75 if framework.ProviderIs("aws") {
76 timeout = e2eservice.LoadBalancerLagTimeoutAWS
77 }
78 e2eservice.TestReachableHTTP(ctx, tcpIngressIP, svcPort, timeout)
79
80 t.jig = jig
81 t.tcpService = tcpService
82 t.tcpIngressIP = tcpIngressIP
83 t.svcPort = svcPort
84 }
85
86
87 func (t *ServiceUpgradeTest) Test(ctx context.Context, f *framework.Framework, done <-chan struct{}, upgrade upgrades.UpgradeType) {
88 switch upgrade {
89 case upgrades.MasterUpgrade, upgrades.ClusterUpgrade:
90 t.test(ctx, f, done, true, true)
91 case upgrades.NodeUpgrade:
92 t.test(ctx, f, done, true, false)
93 default:
94 t.test(ctx, f, done, false, false)
95 }
96 }
97
98
99 func (t *ServiceUpgradeTest) Teardown(ctx context.Context, f *framework.Framework) {
100
101 }
102
103 func (t *ServiceUpgradeTest) test(ctx context.Context, f *framework.Framework, done <-chan struct{}, testDuringDisruption, testFinalizer bool) {
104 if testDuringDisruption {
105
106 ginkgo.By("continuously hitting the pod through the service's LoadBalancer")
107
108 wait.Until(func() {
109 e2eservice.TestReachableHTTP(ctx, t.tcpIngressIP, t.svcPort, e2eservice.LoadBalancerLagTimeoutDefault)
110 }, framework.Poll, done)
111 } else {
112
113 ginkgo.By("waiting for upgrade to finish without checking if service remains up")
114 <-done
115 }
116
117
118 ginkgo.By("hitting the pod through the service's LoadBalancer")
119 e2eservice.TestReachableHTTP(ctx, t.tcpIngressIP, t.svcPort, e2eservice.LoadBalancerLagTimeoutDefault)
120 if testFinalizer {
121 defer func() {
122 ginkgo.By("Check that service can be deleted with finalizer")
123 e2eservice.WaitForServiceDeletedWithFinalizer(ctx, t.jig.Client, t.tcpService.Namespace, t.tcpService.Name)
124 }()
125 ginkgo.By("Check that finalizer is present on loadBalancer type service")
126 e2eservice.WaitForServiceUpdatedWithFinalizer(ctx, t.jig.Client, t.tcpService.Namespace, t.tcpService.Name, true)
127 }
128 }
129
View as plain text