Skip to content

Commit 627a31a

Browse files
committed
Update nfr tests for cp/dp split
1 parent de0fdc2 commit 627a31a

25 files changed

+459
-555
lines changed

charts/nginx-gateway-fabric/values.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -372,19 +372,19 @@ nginx:
372372
# -- The termination grace period of the NGINX data plane pod.
373373
# terminationGracePeriodSeconds: 30
374374

375-
# -- Tolerations for the NGINX Gateway Fabric control plane pod.
375+
# -- Tolerations for the NGINX data plane pod.
376376
# tolerations: []
377377

378-
# -- The nodeSelector of the NGINX Gateway Fabric control plane pod.
378+
# -- The nodeSelector of the NGINX data plane pod.
379379
# nodeSelector: {}
380380

381-
# -- The affinity of the NGINX Gateway Fabric control plane pod.
381+
# -- The affinity of the NGINX data plane pod.
382382
# affinity: {}
383383

384-
# -- The topology spread constraints for the NGINX Gateway Fabric control plane pod.
384+
# -- The topology spread constraints for the NGINX data plane pod.
385385
# topologySpreadConstraints: []
386386

387-
# -- extraVolumes for the NGINX Gateway Fabric control plane pod. Use in conjunction with
387+
# -- extraVolumes for the NGINX data plane pod. Use in conjunction with
388388
# nginx.container.extraVolumeMounts mount additional volumes to the container.
389389
# extraVolumes: []
390390

tests/Makefile

+4-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ build-test-runner-image: ## Build conformance test runner image
4444

4545
.PHONY: build-crossplane-image
4646
build-crossplane-image: ## Build the crossplane image
47-
docker build --build-arg NGINX_CONF_DIR=$(NGINX_CONF_DIR) -t nginx-crossplane:latest -f framework/crossplane/Dockerfile ..
47+
docker build --platform $(GOOS)/$(GOARCH) --build-arg NGINX_CONF_DIR=$(NGINX_CONF_DIR) -t nginx-crossplane:latest -f framework/crossplane/Dockerfile ..
4848

4949
.PHONY: run-conformance-tests
5050
run-conformance-tests: ## Run conformance tests
@@ -105,7 +105,9 @@ sync-files-to-vm: ## Syncs your local NGF files with the NGF repo on the VM
105105
./scripts/sync-files-to-vm.sh
106106

107107
.PHONY: nfr-test
108-
nfr-test: check-for-plus-usage-endpoint ## Run the NFR tests on a GCP VM
108+
nfr-test: GOARCH=amd64
109+
nfr-test: check-for-plus-usage-endpoint build-crossplane-image ## Run the NFR tests on a GCP VM
110+
./scripts/push-crossplane-image.sh
109111
CI=$(CI) ./scripts/run-tests-gcp-vm.sh
110112

111113
.PHONY: start-longevity-test

tests/framework/crossplane.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type ExpectedNginxField struct {
3838
ValueSubstringAllowed bool
3939
}
4040

41+
const crossplaneImageName = "nginx-crossplane:latest"
42+
4143
// ValidateNginxFieldExists accepts the nginx config and the configuration for the expected field,
4244
// and returns whether or not that field exists where it should.
4345
func ValidateNginxFieldExists(conf *Payload, expFieldCfg ExpectedNginxField) error {
@@ -144,11 +146,17 @@ func injectCrossplaneContainer(
144146
k8sClient kubernetes.Interface,
145147
timeout time.Duration,
146148
ngfPodName,
147-
namespace string,
149+
namespace,
150+
crossplaneImageRepo string,
148151
) error {
149152
ctx, cancel := context.WithTimeout(context.Background(), timeout)
150153
defer cancel()
151154

155+
image := crossplaneImageName
156+
if crossplaneImageRepo != "" {
157+
image = crossplaneImageRepo + "/" + image
158+
}
159+
152160
pod := &core.Pod{
153161
ObjectMeta: metav1.ObjectMeta{
154162
Name: ngfPodName,
@@ -160,8 +168,8 @@ func injectCrossplaneContainer(
160168
TargetContainerName: "nginx",
161169
EphemeralContainerCommon: core.EphemeralContainerCommon{
162170
Name: "crossplane",
163-
Image: "nginx-crossplane:latest",
164-
ImagePullPolicy: "Never",
171+
Image: image,
172+
ImagePullPolicy: "IfNotPresent",
165173
Stdin: true,
166174
VolumeMounts: []core.VolumeMount{
167175
{

tests/framework/info.go

+25
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"runtime/debug"
66

7+
. "github.com/onsi/ginkgo/v2"
78
core "k8s.io/api/core/v1"
89
"sigs.k8s.io/controller-runtime/pkg/client"
910
)
@@ -81,3 +82,27 @@ func GetBuildInfo() (commitHash string, commitTime string, dirtyBuild string) {
8182

8283
return
8384
}
85+
86+
// AddNginxLogsAndEventsToReport adds nginx logs and events from the namespace to the report if the spec failed.
87+
func AddNginxLogsAndEventsToReport(rm ResourceManager, namespace string) {
88+
if CurrentSpecReport().Failed() {
89+
var returnLogs string
90+
91+
nginxPodNames, _ := GetReadyNginxPodNames(rm.K8sClient, namespace, rm.TimeoutConfig.GetStatusTimeout)
92+
93+
for _, nginxPodName := range nginxPodNames {
94+
returnLogs += fmt.Sprintf("Logs for Nginx Pod %s:\n", nginxPodName)
95+
nginxLogs, _ := rm.GetPodLogs(
96+
namespace,
97+
nginxPodName,
98+
&core.PodLogOptions{Container: "nginx"},
99+
)
100+
101+
returnLogs += fmt.Sprintf(" %s\n", nginxLogs)
102+
}
103+
AddReportEntry("Nginx Logs", returnLogs, ReportEntryVisibilityNever)
104+
105+
events := GetEvents(rm, namespace)
106+
AddReportEntry("Test Events", events, ReportEntryVisibilityNever)
107+
}
108+
}

tests/framework/prometheus.go

-113
Original file line numberDiff line numberDiff line change
@@ -302,119 +302,6 @@ type Bucket struct {
302302
Val int
303303
}
304304

305-
// GetReloadCount gets the total number of nginx reloads.
306-
func GetReloadCount(promInstance PrometheusInstance, ngfPodName string) (float64, error) {
307-
return getFirstValueOfVector(
308-
fmt.Sprintf(
309-
`nginx_gateway_fabric_nginx_reloads_total{pod="%[1]s"}`,
310-
ngfPodName,
311-
),
312-
promInstance,
313-
)
314-
}
315-
316-
// GetReloadCountWithStartTime gets the total number of nginx reloads from a start time to the current time.
317-
func GetReloadCountWithStartTime(
318-
promInstance PrometheusInstance,
319-
ngfPodName string,
320-
startTime time.Time,
321-
) (float64, error) {
322-
return getFirstValueOfVector(
323-
fmt.Sprintf(
324-
`nginx_gateway_fabric_nginx_reloads_total{pod="%[1]s"}`+
325-
` - `+
326-
`nginx_gateway_fabric_nginx_reloads_total{pod="%[1]s"} @ %d`,
327-
ngfPodName,
328-
startTime.Unix(),
329-
),
330-
promInstance,
331-
)
332-
}
333-
334-
// GetReloadErrsCountWithStartTime gets the total number of nginx reload errors from a start time to the current time.
335-
func GetReloadErrsCountWithStartTime(
336-
promInstance PrometheusInstance,
337-
ngfPodName string,
338-
startTime time.Time,
339-
) (float64, error) {
340-
return getFirstValueOfVector(
341-
fmt.Sprintf(
342-
`nginx_gateway_fabric_nginx_reload_errors_total{pod="%[1]s"}`+
343-
` - `+
344-
`nginx_gateway_fabric_nginx_reload_errors_total{pod="%[1]s"} @ %d`,
345-
ngfPodName,
346-
startTime.Unix(),
347-
),
348-
promInstance,
349-
)
350-
}
351-
352-
// GetReloadAvgTime gets the average time in milliseconds for nginx to reload.
353-
func GetReloadAvgTime(promInstance PrometheusInstance, ngfPodName string) (float64, error) {
354-
return getFirstValueOfVector(
355-
fmt.Sprintf(
356-
`nginx_gateway_fabric_nginx_reloads_milliseconds_sum{pod="%[1]s"}`+
357-
` / `+
358-
`nginx_gateway_fabric_nginx_reloads_total{pod="%[1]s"}`,
359-
ngfPodName,
360-
),
361-
promInstance,
362-
)
363-
}
364-
365-
// GetReloadAvgTimeWithStartTime gets the average time in milliseconds for nginx to reload using a start time
366-
// to the current time to calculate.
367-
func GetReloadAvgTimeWithStartTime(
368-
promInstance PrometheusInstance,
369-
ngfPodName string,
370-
startTime time.Time,
371-
) (float64, error) {
372-
return getFirstValueOfVector(
373-
fmt.Sprintf(
374-
`(nginx_gateway_fabric_nginx_reloads_milliseconds_sum{pod="%[1]s"}`+
375-
` - `+
376-
`nginx_gateway_fabric_nginx_reloads_milliseconds_sum{pod="%[1]s"} @ %[2]d)`+
377-
` / `+
378-
`(nginx_gateway_fabric_nginx_reloads_total{pod="%[1]s"}`+
379-
` - `+
380-
`nginx_gateway_fabric_nginx_reloads_total{pod="%[1]s"} @ %[2]d)`,
381-
ngfPodName,
382-
startTime.Unix(),
383-
),
384-
promInstance,
385-
)
386-
}
387-
388-
// GetReloadBuckets gets the Buckets in millisecond intervals for nginx reloads.
389-
func GetReloadBuckets(promInstance PrometheusInstance, ngfPodName string) ([]Bucket, error) {
390-
return getBuckets(
391-
fmt.Sprintf(
392-
`nginx_gateway_fabric_nginx_reloads_milliseconds_bucket{pod="%[1]s"}`,
393-
ngfPodName,
394-
),
395-
promInstance,
396-
)
397-
}
398-
399-
// GetReloadBucketsWithStartTime gets the Buckets in millisecond intervals for nginx reloads from a start time
400-
// to the current time.
401-
func GetReloadBucketsWithStartTime(
402-
promInstance PrometheusInstance,
403-
ngfPodName string,
404-
startTime time.Time,
405-
) ([]Bucket, error) {
406-
return getBuckets(
407-
fmt.Sprintf(
408-
`nginx_gateway_fabric_nginx_reloads_milliseconds_bucket{pod="%[1]s"}`+
409-
` - `+
410-
`nginx_gateway_fabric_nginx_reloads_milliseconds_bucket{pod="%[1]s"} @ %d`,
411-
ngfPodName,
412-
startTime.Unix(),
413-
),
414-
promInstance,
415-
)
416-
}
417-
418305
// GetEventsCount gets the NGF event batch processing count.
419306
func GetEventsCount(promInstance PrometheusInstance, ngfPodName string) (float64, error) {
420307
return getFirstValueOfVector(

tests/framework/resourcemanager.go

+43-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ import (
4646
"k8s.io/client-go/util/retry"
4747
"sigs.k8s.io/controller-runtime/pkg/client"
4848
v1 "sigs.k8s.io/gateway-api/apis/v1"
49+
50+
ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2"
4951
)
5052

5153
// ResourceManager handles creating/updating/deleting Kubernetes resources.
@@ -647,6 +649,44 @@ func (rm *ResourceManager) GetNGFDeployment(namespace, releaseName string) (*app
647649
return &deployment, nil
648650
}
649651

652+
func (rm *ResourceManager) getGatewayClassNginxProxy(
653+
namespace,
654+
releaseName string,
655+
) (*ngfAPIv1alpha2.NginxProxy, error) {
656+
ctx, cancel := context.WithTimeout(context.Background(), rm.TimeoutConfig.GetTimeout)
657+
defer cancel()
658+
659+
var proxy ngfAPIv1alpha2.NginxProxy
660+
proxyName := releaseName + "-proxy-config"
661+
662+
if err := rm.K8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: proxyName}, &proxy); err != nil {
663+
return nil, err
664+
}
665+
666+
return &proxy, nil
667+
}
668+
669+
// ScaleNginxDeployment scales the Nginx Deployment to the specified number of replicas.
670+
func (rm *ResourceManager) ScaleNginxDeployment(namespace, releaseName string, replicas int32) error {
671+
ctx, cancel := context.WithTimeout(context.Background(), rm.TimeoutConfig.UpdateTimeout)
672+
defer cancel()
673+
674+
// If there is another NginxProxy which "overrides" the gateway class one, then this won't work and
675+
// may need refactoring.
676+
proxy, err := rm.getGatewayClassNginxProxy(namespace, releaseName)
677+
if err != nil {
678+
return fmt.Errorf("error getting NginxProxy: %w", err)
679+
}
680+
681+
proxy.Spec.Kubernetes.Deployment.Replicas = &replicas
682+
683+
if err = rm.K8sClient.Update(ctx, proxy); err != nil {
684+
return fmt.Errorf("error updating NginxProxy: %w", err)
685+
}
686+
687+
return nil
688+
}
689+
650690
// GetEvents returns all Events in the specified namespace.
651691
func (rm *ResourceManager) GetEvents(namespace string) (*core.EventList, error) {
652692
ctx, cancel := context.WithTimeout(context.Background(), rm.TimeoutConfig.GetTimeout)
@@ -825,12 +865,14 @@ func (rm *ResourceManager) WaitForGatewayObservedGeneration(
825865
}
826866

827867
// GetNginxConfig uses crossplane to get the nginx configuration and convert it to JSON.
828-
func (rm *ResourceManager) GetNginxConfig(nginxPodName, namespace string) (*Payload, error) {
868+
// If the crossplane image is loaded locally on the node, crossplaneImageRepo can be empty.
869+
func (rm *ResourceManager) GetNginxConfig(nginxPodName, namespace, crossplaneImageRepo string) (*Payload, error) {
829870
if err := injectCrossplaneContainer(
830871
rm.ClientGoClient,
831872
rm.TimeoutConfig.UpdateTimeout,
832873
nginxPodName,
833874
namespace,
875+
crossplaneImageRepo,
834876
); err != nil {
835877
return nil, err
836878
}

tests/framework/timeout.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func DefaultTimeoutConfig() TimeoutConfig {
4343
CreateTimeout: 60 * time.Second,
4444
UpdateTimeout: 60 * time.Second,
4545
DeleteTimeout: 10 * time.Second,
46-
DeleteNamespaceTimeout: 60 * time.Second,
46+
DeleteNamespaceTimeout: 90 * time.Second,
4747
GetTimeout: 10 * time.Second,
4848
ManifestFetchTimeout: 10 * time.Second,
4949
RequestTimeout: 10 * time.Second,
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
3+
set -eo pipefail
4+
5+
source scripts/vars.env
6+
7+
docker tag nginx-crossplane:latest gcr.io/$GKE_PROJECT/nginx-crossplane:latest
8+
docker push gcr.io/$GKE_PROJECT/nginx-crossplane:latest

tests/suite/advanced_routing_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var _ = Describe("AdvancedRouting", Ordered, Label("functional", "routing"), fun
4848
})
4949

5050
AfterAll(func() {
51+
framework.AddNginxLogsAndEventsToReport(resourceManager, namespace)
5152
cleanUpPortForward()
5253

5354
Expect(resourceManager.DeleteFromFiles(files, namespace)).To(Succeed())

tests/suite/client_settings_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
5757
})
5858

5959
AfterAll(func() {
60+
framework.AddNginxLogsAndEventsToReport(resourceManager, namespace)
6061
cleanUpPortForward()
6162

6263
Expect(resourceManager.DeleteNamespace(namespace)).To(Succeed())
@@ -109,7 +110,7 @@ var _ = Describe("ClientSettingsPolicy", Ordered, Label("functional", "cspolicy"
109110

110111
BeforeAll(func() {
111112
var err error
112-
conf, err = resourceManager.GetNginxConfig(nginxPodName, namespace)
113+
conf, err = resourceManager.GetNginxConfig(nginxPodName, namespace, "")
113114
Expect(err).ToNot(HaveOccurred())
114115
})
115116

tests/suite/dataplane_perf_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ var _ = Describe("Dataplane performance", Ordered, Label("nfr", "performance"),
8888
})
8989

9090
AfterAll(func() {
91+
framework.AddNginxLogsAndEventsToReport(resourceManager, namespace)
9192
cleanUpPortForward()
9293

9394
Expect(resourceManager.DeleteFromFiles(files, namespace)).To(Succeed())

tests/suite/graceful_recovery_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ var _ = Describe("Graceful Recovery test", Ordered, Label("graceful-recovery"),
425425
})
426426

427427
AfterAll(func() {
428+
framework.AddNginxLogsAndEventsToReport(resourceManager, ns.Name)
428429
cleanUpPortForward()
429430
Expect(resourceManager.DeleteFromFiles(files, ns.Name)).To(Succeed())
430431
Expect(resourceManager.DeleteNamespace(ns.Name)).To(Succeed())

tests/suite/longevity_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ var _ = Describe("Longevity", Label("longevity-setup", "longevity-teardown"), fu
8282
Expect(writeTrafficResults(resultsFile, homeDir, "coffee.txt", "HTTP")).To(Succeed())
8383
Expect(writeTrafficResults(resultsFile, homeDir, "tea.txt", "HTTPS")).To(Succeed())
8484

85+
framework.AddNginxLogsAndEventsToReport(resourceManager, ns.Name)
8586
Expect(resourceManager.DeleteFromFiles(files, ns.Name)).To(Succeed())
8687
Expect(resourceManager.DeleteNamespace(ns.Name)).To(Succeed())
8788
})

0 commit comments

Comments
 (0)