Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functional tests for ClientSettingsPolicies #2013

Merged
merged 7 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/functional.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,10 @@ jobs:
ngf_tag=${{ steps.ngf-meta.outputs.version }}
make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag} GINKGO_LABEL=telemetry
working-directory: ./tests

- name: Run functional tests
run: |
ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric
ngf_tag=${{ steps.ngf-meta.outputs.version }}
make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag}
working-directory: ./tests
4 changes: 4 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ Directory structure is as follows:

> Note: Existing NFR tests will be migrated into this testing `suite` and results stored in the `results` directory.

### Logging in tests

To log in the tests, use the `GinkgoWriter` interface described here: https://onsi.github.io/ginkgo/#logging-output.

### Step 1 - Run the tests

#### 1a - Run the functional tests locally
Expand Down
1 change: 1 addition & 0 deletions tests/conformance/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ FROM golang:1.22

WORKDIR /go/src/github.com/nginxinc/nginx-gateway-fabric/tests/conformance

COPY ../. /go/src/github.com/nginxinc/nginx-gateway-fabric/
COPY --link go.mod /go/src/github.com/nginxinc/nginx-gateway-fabric/tests/
COPY --link go.sum /go/src/github.com/nginxinc/nginx-gateway-fabric/tests/
RUN go mod download
Expand Down
10 changes: 4 additions & 6 deletions tests/framework/ngf.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ type InstallationConfig struct {
}

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

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

Expand Down
39 changes: 28 additions & 11 deletions tests/framework/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/tls"
"fmt"
"io"
"net"
"net/http"
"strings"
Expand All @@ -15,6 +16,29 @@ import (
// It resolves to the specified address instead of using DNS.
// The status and body of the response is returned, or an error.
func Get(url, address string, timeout time.Duration) (int, string, error) {
resp, err := makeRequest(http.MethodGet, url, address, nil, timeout)
if err != nil {
return 0, "", err
}

defer resp.Body.Close()

body := new(bytes.Buffer)
_, err = body.ReadFrom(resp.Body)
if err != nil {
return resp.StatusCode, "", err
}

return resp.StatusCode, body.String(), nil
}

// Post sends a POST request to the specified url with the body as the payload.
// It resolves to the specified address instead of using DNS.
func Post(url, address string, body io.Reader, timeout time.Duration) (*http.Response, error) {
return makeRequest(http.MethodPost, url, address, body, timeout)
}

func makeRequest(method, url, address string, body io.Reader, timeout time.Duration) (*http.Response, error) {
dialer := &net.Dialer{}

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

req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
req, err := http.NewRequestWithContext(ctx, method, url, body)
if err != nil {
return 0, "", err
return nil, err
}

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

if err != nil {
return 0, "", err
}
defer resp.Body.Close()

body := new(bytes.Buffer)
_, err = body.ReadFrom(resp.Body)
if err != nil {
return resp.StatusCode, "", err
return nil, err
}

return resp.StatusCode, body.String(), nil
return resp, nil
}
52 changes: 43 additions & 9 deletions tests/framework/resourcemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,11 @@ func (rm *ResourceManager) WaitForAppsToBeReadyWithCtx(ctx context.Context, name
return err
}

if err := rm.waitForRoutesToBeReady(ctx, namespace); err != nil {
if err := rm.waitForHTTPRoutesToBeReady(ctx, namespace); err != nil {
return err
}

if err := rm.waitForGRPCRoutesToBeReady(ctx, namespace); err != nil {
return err
}

Expand Down Expand Up @@ -371,7 +375,7 @@ func (rm *ResourceManager) waitForGatewaysToBeReady(ctx context.Context, namespa
)
}

func (rm *ResourceManager) waitForRoutesToBeReady(ctx context.Context, namespace string) error {
func (rm *ResourceManager) waitForHTTPRoutesToBeReady(ctx context.Context, namespace string) error {
return wait.PollUntilContextCancel(
ctx,
500*time.Millisecond,
Expand All @@ -385,13 +389,29 @@ func (rm *ResourceManager) waitForRoutesToBeReady(ctx context.Context, namespace
var numParents, readyCount int
for _, route := range routeList.Items {
numParents += len(route.Spec.ParentRefs)
for _, parent := range route.Status.Parents {
for _, cond := range parent.Conditions {
if cond.Type == string(v1.RouteConditionAccepted) && cond.Status == metav1.ConditionTrue {
readyCount++
}
}
}
readyCount += countNumberOfReadyParents(route.Status.Parents)
}

return numParents == readyCount, nil
},
)
}

func (rm *ResourceManager) waitForGRPCRoutesToBeReady(ctx context.Context, namespace string) error {
return wait.PollUntilContextCancel(
ctx,
500*time.Millisecond,
true, /* poll immediately */
func(ctx context.Context) (bool, error) {
var routeList v1.GRPCRouteList
if err := rm.K8sClient.List(ctx, &routeList, client.InNamespace(namespace)); err != nil {
return false, err
}

var numParents, readyCount int
for _, route := range routeList.Items {
numParents += len(route.Spec.ParentRefs)
readyCount += countNumberOfReadyParents(route.Status.Parents)
}

return numParents == readyCount, nil
Expand Down Expand Up @@ -649,3 +669,17 @@ func GetReadyNGFPodNames(

return nil, errors.New("unable to find NGF Pod(s)")
}

func countNumberOfReadyParents(parents []v1.RouteParentStatus) int {
readyCount := 0

for _, parent := range parents {
for _, cond := range parent.Conditions {
if cond.Type == string(v1.RouteConditionAccepted) && cond.Status == metav1.ConditionTrue {
readyCount++
}
}
}

return readyCount
}
4 changes: 4 additions & 0 deletions tests/framework/timeout.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type TimeoutConfig struct {

// GetLeaderLeaseTimeout represents the maximum time for NGF to retrieve the leader lease.
GetLeaderLeaseTimeout time.Duration

// GetStatusTimeout represents the maximum time for NGF to update the status of a resource.
GetStatusTimeout time.Duration
}

// DefaultTimeoutConfig populates a TimeoutConfig with the default values.
Expand All @@ -43,5 +46,6 @@ func DefaultTimeoutConfig() TimeoutConfig {
RequestTimeout: 10 * time.Second,
ContainerRestartTimeout: 10 * time.Second,
GetLeaderLeaseTimeout: 60 * time.Second,
GetStatusTimeout: 60 * time.Second,
}
}
13 changes: 8 additions & 5 deletions tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/nginxinc/nginx-gateway-fabric/tests
go 1.22.2

require (
github.com/nginxinc/nginx-gateway-fabric v0.0.0
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/prometheus/client_golang v1.19.1
Expand All @@ -24,7 +25,7 @@ require (
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
Expand Down Expand Up @@ -59,17 +60,17 @@ require (
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.19.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect
google.golang.org/grpc v1.64.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand All @@ -79,3 +80,5 @@ require (
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)

replace github.com/nginxinc/nginx-gateway-fabric => ../
24 changes: 12 additions & 12 deletions tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
Expand Down Expand Up @@ -122,8 +122,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
Expand All @@ -140,8 +140,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -176,12 +176,12 @@ gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuB
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca h1:PupagGYwj8+I4ubCxcmcBRk3VlUWtTg5huQpZR9flmE=
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
Loading
Loading