Skip to content

Commit 7ded691

Browse files
committed
Add polling wait for leader election lease to change and refactored expect Request
1 parent 610ab12 commit 7ded691

File tree

1 file changed

+81
-17
lines changed

1 file changed

+81
-17
lines changed

tests/suite/graceful_recovery_test.go

Lines changed: 81 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
. "github.com/onsi/ginkgo/v2"
1212
. "github.com/onsi/gomega"
13+
coordination "k8s.io/api/coordination/v1"
1314
core "k8s.io/api/core/v1"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
"k8s.io/apimachinery/pkg/types"
@@ -22,7 +23,8 @@ import (
2223
const (
2324
// FIXME(bjee19): Find an automated way to keep the version updated here similar to dependabot.
2425
// https://github.com/nginxinc/nginx-gateway-fabric/issues/1665
25-
debugImage = "busybox:1.28"
26+
debugImage = "busybox:1.28"
27+
2628
teaURL = "https://cafe.example.com/tea"
2729
coffeeURL = "http://cafe.example.com/coffee"
2830
nginxContainerName = "nginx"
@@ -67,15 +69,20 @@ var _ = Describe("Graceful Recovery test", Ordered, Label("nfr", "graceful-recov
6769
Expect(err).ToNot(HaveOccurred())
6870
Expect(podNames).ToNot(BeEmpty())
6971

72+
leaseName, err := getLeaderElectionLeaseHolderName()
73+
Expect(err).ToNot(HaveOccurred())
74+
7075
output, err := restartNGFProcess(ngfContainerName)
7176
Expect(err).ToNot(HaveOccurred(), string(output))
7277

7378
checkContainerLogsForErrors(podNames[0])
7479

80+
err = waitForLeaderLeaseToChange(leaseName)
81+
Expect(err).ToNot(HaveOccurred())
82+
7583
err = waitForWorkingTraffic()
7684
Expect(err).ToNot(HaveOccurred())
7785

78-
// I tried just deleting the routes and ran into a bunch of issues, deleting all the files was better
7986
Expect(resourceManager.DeleteFromFiles(files, ns.Name)).To(Succeed())
8087

8188
err = waitForFailingTraffic()
@@ -93,11 +100,17 @@ var _ = Describe("Graceful Recovery test", Ordered, Label("nfr", "graceful-recov
93100
Expect(err).ToNot(HaveOccurred())
94101
Expect(podNames).ToNot(BeEmpty())
95102

103+
leaseName, err := getLeaderElectionLeaseHolderName()
104+
Expect(err).ToNot(HaveOccurred())
105+
96106
output, err := restartNginxContainer(nginxContainerName)
97107
Expect(err).ToNot(HaveOccurred(), string(output))
98108

99109
checkContainerLogsForErrors(podNames[0])
100110

111+
err = waitForLeaderLeaseToChange(leaseName)
112+
Expect(err).ToNot(HaveOccurred())
113+
101114
err = waitForWorkingTraffic()
102115
Expect(err).ToNot(HaveOccurred())
103116

@@ -231,10 +244,10 @@ func waitForWorkingTraffic() error {
231244
500*time.Millisecond,
232245
true, /* poll immediately */
233246
func(_ context.Context) (bool, error) {
234-
if err := expectRequest(teaURL, address, http.StatusOK, "URI: /tea"); err != nil {
247+
if err := expectRequestToSucceed(teaURL, address, "URI: /tea"); err != nil {
235248
return false, nil
236249
}
237-
if err := expectRequest(coffeeURL, address, http.StatusOK, "URI: /coffee"); err != nil {
250+
if err := expectRequestToSucceed(coffeeURL, address, "URI: /coffee"); err != nil {
238251
return false, nil
239252
}
240253
return true, nil
@@ -246,39 +259,53 @@ func waitForFailingTraffic() error {
246259
ctx, cancel := context.WithTimeout(context.Background(), timeoutConfig.RequestTimeout)
247260
defer cancel()
248261

262+
//nolint:nilerr
249263
return wait.PollUntilContextCancel(
250264
ctx,
251265
500*time.Millisecond,
252266
true, /* poll immediately */
253267
func(_ context.Context) (bool, error) {
254-
if err := expectRequest(teaURL, address, 0, "URI: /tea"); err == nil {
268+
if err := expectRequestToFail(teaURL, address, "URI: /tea"); err != nil {
255269
return false, nil
256270
}
257-
if err := expectRequest(coffeeURL, address, 0, "URI: /coffee"); err == nil {
271+
if err := expectRequestToFail(coffeeURL, address, "URI: /coffee"); err != nil {
258272
return false, nil
259273
}
260274
return true, nil
261275
},
262276
)
263277
}
264278

265-
func expectRequest(appURL string, address string, httpStatus int, responseBodyMessage string) error {
279+
func expectRequestToSucceed(appURL string, address string, responseBodyMessage string) error {
266280
status, body, err := framework.Get(appURL, address, timeoutConfig.RequestTimeout)
267-
if status != httpStatus {
268-
return errors.New("http statuses were not equal")
281+
if status != http.StatusOK {
282+
return errors.New("http status was not 200")
269283
}
270-
if httpStatus == http.StatusOK {
271-
if !strings.Contains(body, responseBodyMessage) {
272-
return errors.New("expected response body to contain body message")
273-
}
274-
} else {
275-
if strings.Contains(body, responseBodyMessage) {
276-
return errors.New("expected response body to not contain body message")
277-
}
284+
285+
if !strings.Contains(body, responseBodyMessage) {
286+
return errors.New("expected response body to contain correct body message")
278287
}
288+
279289
return err
280290
}
281291

292+
func expectRequestToFail(appURL string, address string, responseBodyMessage string) error {
293+
status, body, err := framework.Get(appURL, address, timeoutConfig.RequestTimeout)
294+
if status != 0 {
295+
return errors.New("expected http status to be 0")
296+
}
297+
298+
if strings.Contains(body, responseBodyMessage) {
299+
return errors.New("expected response body to not contain correct body message")
300+
}
301+
302+
if err == nil {
303+
return errors.New("expected request to error")
304+
}
305+
306+
return nil
307+
}
308+
282309
func checkContainerLogsForErrors(ngfPodName string) {
283310
sinceSeconds := int64(15)
284311
logs, err := resourceManager.GetPodLogs(
@@ -297,3 +324,40 @@ func checkContainerLogsForErrors(ngfPodName string) {
297324
Expect(err).ToNot(HaveOccurred())
298325
Expect(logs).ToNot(ContainSubstring("error"), logs)
299326
}
327+
328+
func waitForLeaderLeaseToChange(originalLeaseName string) error {
329+
leaseCtx, leaseCancel := context.WithTimeout(context.Background(), 1*time.Minute)
330+
defer leaseCancel()
331+
332+
//nolint:nilerr
333+
return wait.PollUntilContextCancel(
334+
leaseCtx,
335+
500*time.Millisecond,
336+
true, /* poll immediately */
337+
func(_ context.Context) (bool, error) {
338+
leaseName, err := getLeaderElectionLeaseHolderName()
339+
if err != nil {
340+
return false, nil
341+
}
342+
343+
if originalLeaseName != leaseName {
344+
return true, nil
345+
}
346+
347+
return false, nil
348+
},
349+
)
350+
}
351+
352+
func getLeaderElectionLeaseHolderName() (string, error) {
353+
ctx, cancel := context.WithTimeout(context.Background(), timeoutConfig.GetTimeout)
354+
defer cancel()
355+
356+
var lease coordination.Lease
357+
key := types.NamespacedName{Name: "ngf-test-nginx-gateway-fabric-leader-election", Namespace: ngfNamespace}
358+
359+
if err := k8sClient.Get(ctx, key, &lease); err != nil {
360+
return "", errors.New("could not retrieve leader election lease")
361+
}
362+
return *lease.Spec.HolderIdentity, nil
363+
}

0 commit comments

Comments
 (0)