Skip to content

Commit 18f8c53

Browse files
author
Kate Osborn
committed
Add functional tests for ClientSettingsPolicy
1 parent 7edcfed commit 18f8c53

19 files changed

+869
-34
lines changed

.github/workflows/functional.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,10 @@ jobs:
119119
ngf_tag=${{ steps.ngf-meta.outputs.version }}
120120
make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag} GINKGO_LABEL=telemetry
121121
working-directory: ./tests
122+
123+
- name: Run functional tests
124+
run: |
125+
ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric
126+
ngf_tag=${{ steps.ngf-meta.outputs.version }}
127+
make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag}
128+
working-directory: ./tests

tests/framework/ngf.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ type InstallationConfig struct {
3232
}
3333

3434
// InstallGatewayAPI installs the specified version of the Gateway API resources.
35-
func InstallGatewayAPI(
36-
k8sClient client.Client,
37-
apiVersion,
38-
k8sVersion string,
39-
) ([]byte, error) {
35+
func InstallGatewayAPI(apiVersion string) ([]byte, error) {
4036
apiPath := fmt.Sprintf("%s/v%s/standard-install.yaml", gwInstallBasePath, apiVersion)
4137

4238
if output, err := exec.Command("kubectl", "apply", "-f", apiPath).CombinedOutput(); err != nil {
@@ -163,7 +159,9 @@ func setImageArgs(cfg InstallationConfig) []string {
163159
if cfg.ServiceType != "" {
164160
args = append(args, formatValueSet("service.type", cfg.ServiceType)...)
165161
if cfg.ServiceType == "LoadBalancer" && cfg.IsGKEInternalLB {
166-
args = append(args, formatValueSet(`service.annotations.networking\.gke\.io\/load-balancer-type`, "Internal")...)
162+
args = append(
163+
args,
164+
formatValueSet(`service.annotations.networking\.gke\.io\/load-balancer-type`, "Internal")...)
167165
}
168166
}
169167

tests/framework/request.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"crypto/tls"
77
"fmt"
8+
"io"
89
"net"
910
"net/http"
1011
"strings"
@@ -15,6 +16,29 @@ import (
1516
// It resolves to the specified address instead of using DNS.
1617
// The status and body of the response is returned, or an error.
1718
func Get(url, address string, timeout time.Duration) (int, string, error) {
19+
resp, err := makeRequest(http.MethodGet, url, address, nil, timeout)
20+
if err != nil {
21+
return 0, "", err
22+
}
23+
24+
defer resp.Body.Close()
25+
26+
body := new(bytes.Buffer)
27+
_, err = body.ReadFrom(resp.Body)
28+
if err != nil {
29+
return resp.StatusCode, "", err
30+
}
31+
32+
return resp.StatusCode, body.String(), nil
33+
}
34+
35+
// Post sends a POST request to the specified url with the body as the payload.
36+
// It resolves to the specified address instead of using DNS.
37+
func Post(url, address string, body io.Reader, timeout time.Duration) (*http.Response, error) {
38+
return makeRequest(http.MethodPost, url, address, body, timeout)
39+
}
40+
41+
func makeRequest(method, url, address string, body io.Reader, timeout time.Duration) (*http.Response, error) {
1842
dialer := &net.Dialer{}
1943

2044
http.DefaultTransport.(*http.Transport).DialContext = func(
@@ -30,9 +54,9 @@ func Get(url, address string, timeout time.Duration) (int, string, error) {
3054
ctx, cancel := context.WithTimeout(context.Background(), timeout)
3155
defer cancel()
3256

33-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
57+
req, err := http.NewRequestWithContext(ctx, method, url, body)
3458
if err != nil {
35-
return 0, "", err
59+
return nil, err
3660
}
3761

3862
var resp *http.Response
@@ -48,15 +72,8 @@ func Get(url, address string, timeout time.Duration) (int, string, error) {
4872
}
4973

5074
if err != nil {
51-
return 0, "", err
52-
}
53-
defer resp.Body.Close()
54-
55-
body := new(bytes.Buffer)
56-
_, err = body.ReadFrom(resp.Body)
57-
if err != nil {
58-
return resp.StatusCode, "", err
75+
return nil, err
5976
}
6077

61-
return resp.StatusCode, body.String(), nil
78+
return resp, nil
6279
}

tests/framework/resourcemanager.go

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,11 @@ func (rm *ResourceManager) WaitForAppsToBeReadyWithCtx(ctx context.Context, name
313313
return err
314314
}
315315

316-
if err := rm.waitForRoutesToBeReady(ctx, namespace); err != nil {
316+
if err := rm.waitForHTTPRoutesToBeReady(ctx, namespace); err != nil {
317+
return err
318+
}
319+
320+
if err := rm.waitForGRPCRoutesToBeReady(ctx, namespace); err != nil {
317321
return err
318322
}
319323

@@ -371,7 +375,7 @@ func (rm *ResourceManager) waitForGatewaysToBeReady(ctx context.Context, namespa
371375
)
372376
}
373377

374-
func (rm *ResourceManager) waitForRoutesToBeReady(ctx context.Context, namespace string) error {
378+
func (rm *ResourceManager) waitForHTTPRoutesToBeReady(ctx context.Context, namespace string) error {
375379
return wait.PollUntilContextCancel(
376380
ctx,
377381
500*time.Millisecond,
@@ -385,13 +389,29 @@ func (rm *ResourceManager) waitForRoutesToBeReady(ctx context.Context, namespace
385389
var numParents, readyCount int
386390
for _, route := range routeList.Items {
387391
numParents += len(route.Spec.ParentRefs)
388-
for _, parent := range route.Status.Parents {
389-
for _, cond := range parent.Conditions {
390-
if cond.Type == string(v1.RouteConditionAccepted) && cond.Status == metav1.ConditionTrue {
391-
readyCount++
392-
}
393-
}
394-
}
392+
readyCount += countNumberOfReadyParents(route.Status.Parents)
393+
}
394+
395+
return numParents == readyCount, nil
396+
},
397+
)
398+
}
399+
400+
func (rm *ResourceManager) waitForGRPCRoutesToBeReady(ctx context.Context, namespace string) error {
401+
return wait.PollUntilContextCancel(
402+
ctx,
403+
500*time.Millisecond,
404+
true, /* poll immediately */
405+
func(ctx context.Context) (bool, error) {
406+
var routeList v1.GRPCRouteList
407+
if err := rm.K8sClient.List(ctx, &routeList, client.InNamespace(namespace)); err != nil {
408+
return false, err
409+
}
410+
411+
var numParents, readyCount int
412+
for _, route := range routeList.Items {
413+
numParents += len(route.Spec.ParentRefs)
414+
readyCount += countNumberOfReadyParents(route.Status.Parents)
395415
}
396416

397417
return numParents == readyCount, nil
@@ -649,3 +669,17 @@ func GetReadyNGFPodNames(
649669

650670
return nil, errors.New("unable to find NGF Pod(s)")
651671
}
672+
673+
func countNumberOfReadyParents(parents []v1.RouteParentStatus) int {
674+
readyCount := 0
675+
676+
for _, parent := range parents {
677+
for _, cond := range parent.Conditions {
678+
if cond.Type == string(v1.RouteConditionAccepted) && cond.Status == metav1.ConditionTrue {
679+
readyCount++
680+
}
681+
}
682+
}
683+
684+
return readyCount
685+
}

tests/framework/timeout.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ type TimeoutConfig struct {
2929

3030
// GetLeaderLeaseTimeout represents the maximum time for NGF to retrieve the leader lease.
3131
GetLeaderLeaseTimeout time.Duration
32+
33+
// GetStatusTimeout represents the maximum time for NGF to update the status of a resource.
34+
GetStatusTimeout time.Duration
3235
}
3336

3437
// DefaultTimeoutConfig populates a TimeoutConfig with the default values.
@@ -43,5 +46,6 @@ func DefaultTimeoutConfig() TimeoutConfig {
4346
RequestTimeout: 10 * time.Second,
4447
ContainerRestartTimeout: 10 * time.Second,
4548
GetLeaderLeaseTimeout: 60 * time.Second,
49+
GetStatusTimeout: 60 * time.Second,
4650
}
4751
}

tests/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/nginxinc/nginx-gateway-fabric/tests
33
go 1.22.2
44

55
require (
6+
github.com/nginxinc/nginx-gateway-fabric v0.1.0-rc.1.0.20240521170716-206f1364bf89
67
github.com/onsi/ginkgo/v2 v2.18.0
78
github.com/onsi/gomega v1.33.1
89
github.com/prometheus/client_golang v1.19.1
@@ -67,7 +68,7 @@ require (
6768
golang.org/x/time v0.5.0 // indirect
6869
golang.org/x/tools v0.21.0 // indirect
6970
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
70-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
71+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
7172
google.golang.org/grpc v1.63.2 // indirect
7273
google.golang.org/protobuf v1.33.0 // indirect
7374
gopkg.in/inf.v0 v0.9.1 // indirect

tests/go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
8888
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
8989
github.com/onsi/ginkgo/v2 v2.18.0 h1:W9Y7IWXxPUpAit9ieMOLI7PJZGaW22DTKgiVAuhDTLc=
9090
github.com/onsi/ginkgo/v2 v2.18.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
91+
github.com/nginxinc/nginx-gateway-fabric v0.1.0-rc.1.0.20240521170716-206f1364bf89 h1:yjxJLIRWuHqZnu8XKeU99Cie1qhvFF4k5d1Ph7v0WJI=
92+
github.com/nginxinc/nginx-gateway-fabric v0.1.0-rc.1.0.20240521170716-206f1364bf89/go.mod h1:9IgBmhj9OYKPQJRhacdJRmZxm8j1XbAkxLiA4zkN+fQ=
9193
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
9294
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
9395
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -122,8 +124,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
122124
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
123125
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
124126
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
125-
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
126-
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
127+
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
128+
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
127129
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
128130
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
129131
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -176,8 +178,8 @@ gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuB
176178
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca h1:PupagGYwj8+I4ubCxcmcBRk3VlUWtTg5huQpZR9flmE=
177179
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
178180
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
179-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
180-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
181+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4=
182+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
181183
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
182184
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
183185
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=

0 commit comments

Comments
 (0)