Skip to content
Draft
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
1 change: 1 addition & 0 deletions .yamllint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rules:
ignore: |
operators/**/*
examples/proxy-settings-policy/app.yaml
tests/suite/manifests/proxy-settings-policy/app.yaml
key-duplicates: enable
key-ordering: disable
line-length:
Expand Down
4 changes: 2 additions & 2 deletions tests/framework/crossplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func fieldExistsInUpstream(
directive Directive,
opts ...Option,
) bool {
options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf(
"Checking upstream for directive %q with value %q\n",
Expand Down Expand Up @@ -131,7 +131,7 @@ func getServerName(serverBlock Directives) string {
}

func (e ExpectedNginxField) fieldFound(directive *Directive, opts ...Option) bool {
options := LogOptions(opts...)
options := TestOptions(opts...)
arg := strings.Join(directive.Args, " ")

valueMatch := arg == e.Value
Expand Down
22 changes: 0 additions & 22 deletions tests/framework/logging.go

This file was deleted.

29 changes: 29 additions & 0 deletions tests/framework/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package framework

type Option func(*Options)

type Options struct {
logEnabled bool
withContext bool
}

func WithLoggingDisabled() Option {
return func(opts *Options) {
opts.logEnabled = false
}
}

func WithContextDisabled() Option {
return func(opts *Options) {
opts.withContext = false
}
}

func TestOptions(opts ...Option) *Options {
options := &Options{logEnabled: true, withContext: true}
for _, opt := range opts {
opt(options)
}

return options
}
4 changes: 2 additions & 2 deletions tests/framework/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ func CreateMetricExistChecker(
) func() error {
return func() error {
queryWithTimestamp := fmt.Sprintf("%s @ %d", query, getTime().Unix())
options := LogOptions(opts...)
options := TestOptions(opts...)

result, err := promInstance.Query(queryWithTimestamp)
if err != nil {
Expand Down Expand Up @@ -536,7 +536,7 @@ func CreateEndTimeFinder(

// CreateResponseChecker returns a function that checks if there is a successful response from a url.
func CreateResponseChecker(url, address string, requestTimeout time.Duration, opts ...Option) func() error {
options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf("Starting checking response for url %q and address %q\n", url, address)
}
Expand Down
42 changes: 34 additions & 8 deletions tests/framework/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func Get(
headers, queryParams map[string]string,
opts ...Option,
) (int, string, error) {
options := LogOptions(opts...)
options := TestOptions(opts...)

resp, err := makeRequest(http.MethodGet, url, address, nil, timeout, headers, queryParams, opts...)
if err != nil {
Expand All @@ -46,12 +46,27 @@ func Get(
return resp.StatusCode, "", err
}
if options.logEnabled {
GinkgoWriter.Printf("Successfully received response and parsed body: %s\n", body.String())
printResponseBody(body)
}

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

func printResponseBody(body *bytes.Buffer) {
maxLogBodyBytes := 2048
bs := body.Bytes()
if len(bs) <= maxLogBodyBytes {
GinkgoWriter.Printf("Successfully received response and parsed body (%d bytes): %s\n", len(bs), string(bs))
} else {
GinkgoWriter.Printf(
"Successfully received response and parsed body (%d bytes, showing first %d): %s...\n",
len(bs),
maxLogBodyBytes,
string(bs[:maxLogBodyBytes]),
)
}
}

// 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(
Expand Down Expand Up @@ -93,10 +108,7 @@ func makeRequest(
return dialer.DialContext(ctx, network, fmt.Sprintf("%s:%s", address, port))
}

ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
requestDetails := fmt.Sprintf(
"Method: %s, URL: %s, Address: %s, Headers: %v, QueryParams: %v\n",
Expand All @@ -106,10 +118,24 @@ func makeRequest(
headers,
queryParams,
)
GinkgoWriter.Printf("Sending request: %s", requestDetails)
GinkgoWriter.Printf("\nSending request: %s", requestDetails)
}

req, err := http.NewRequestWithContext(ctx, method, url, body)
var (
req *http.Request
err error
)
if options.withContext {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

req, err = http.NewRequestWithContext(ctx, method, url, body)
} else {
// Create request without a short-lived context; rely on http.Client.Timeout
// so that the response body can be fully read by the caller without
// being canceled when this function returns.
req, err = http.NewRequest(method, url, body) //nolint:noctx
}
if err != nil {
return nil, err
}
Expand Down
24 changes: 12 additions & 12 deletions tests/framework/resourcemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type ClusterInfo struct {

// Apply creates or updates Kubernetes resources defined as Go objects.
func (rm *ResourceManager) Apply(resources []client.Object, opts ...Option) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf("Applying resources defined as Go objects\n")
}
Expand Down Expand Up @@ -141,7 +141,7 @@ func (rm *ResourceManager) Apply(resources []client.Object, opts ...Option) erro

// ApplyFromFiles creates or updates Kubernetes resources defined within the provided YAML files.
func (rm *ResourceManager) ApplyFromFiles(files []string, namespace string, opts ...Option) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
for _, file := range files {
if options.logEnabled {
GinkgoWriter.Printf("\nApplying resources from file: %q to namespace %q\n", file, namespace)
Expand All @@ -166,7 +166,7 @@ func (rm *ResourceManager) ApplyFromBuffer(buffer *bytes.Buffer, namespace strin
ctx, cancel := context.WithTimeout(context.Background(), rm.TimeoutConfig.CreateTimeout)
defer cancel()

options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf("Applying resources from buffer to namespace %q\n", namespace)
}
Expand Down Expand Up @@ -470,7 +470,7 @@ func (rm *ResourceManager) WaitForPodsToBeReady(
namespace string,
opts ...Option,
) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
waitingErr := wait.PollUntilContextCancel(
ctx,
500*time.Millisecond,
Expand Down Expand Up @@ -941,7 +941,7 @@ func (rm *ResourceManager) GetReadyNGFPodNames(
timeout time.Duration,
opts ...Option,
) ([]string, error) {
options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf("Getting ready NGF Pod names in namespace %q with release name %q\n", namespace, releaseName)
}
Expand Down Expand Up @@ -1002,7 +1002,7 @@ func (rm *ResourceManager) GetReadyNginxPodNames(
timeout time.Duration,
opts ...Option,
) ([]string, error) {
options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf("Getting ready NGINX Pod names in namespace %q\n", namespace)
}
Expand Down Expand Up @@ -1061,7 +1061,7 @@ func getReadyPodNames(podList core.PodList, opts ...Option) []string {
}
}
}
options := LogOptions(opts...)
options := TestOptions(opts...)
if options.logEnabled {
GinkgoWriter.Printf("Found %d ready pod name(s): %v\n", len(names), names)
}
Expand Down Expand Up @@ -1092,7 +1092,7 @@ func (rm *ResourceManager) WaitForPodsToBeReadyWithCount(
count int,
opts ...Option,
) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
GinkgoWriter.Printf("Waiting for %d pods to be ready in namespace %q\n", count, namespace)

return wait.PollUntilContextCancel(
Expand Down Expand Up @@ -1169,7 +1169,7 @@ func (rm *ResourceManager) GetNginxConfig(
opts ...Option,
) (*Payload, error) {
GinkgoWriter.Printf("Getting NGINX config from pod %q in namespace %q\n", nginxPodName, namespace)
options := LogOptions(opts...)
options := TestOptions(opts...)

if err := injectCrossplaneContainer(
rm.ClientGoClient,
Expand Down Expand Up @@ -1249,7 +1249,7 @@ func (rm *ResourceManager) Get(
obj client.Object,
opts ...Option,
) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
if err := rm.K8sClient.Get(ctx, key, obj); err != nil {
// Don't log NotFound errors - they're often expected (e.g., when checking if resource was deleted)
if options.logEnabled && !apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -1283,7 +1283,7 @@ func (rm *ResourceManager) Delete(
deleteOpts []client.DeleteOption,
opts ...Option,
) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
if err := rm.K8sClient.Delete(ctx, obj, deleteOpts...); err != nil {
if options.logEnabled {
GinkgoWriter.Printf("Could not delete k8s resource %q: %w\n", obj.GetName(), err)
Expand All @@ -1301,7 +1301,7 @@ func (rm *ResourceManager) Update(
updateOpts []client.UpdateOption,
opts ...Option,
) error {
options := LogOptions(opts...)
options := TestOptions(opts...)
if err := rm.K8sClient.Update(ctx, obj, updateOpts...); err != nil {
updateResourceErr := fmt.Errorf("error updating k8s resource: %w", err)
if options.logEnabled {
Expand Down
7 changes: 5 additions & 2 deletions tests/suite/graceful_recovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@

cleanUpPortForward()
job, err := runNodeDebuggerJob(nginxPodName)
Expect(err).ToNot(HaveOccurred())

Check failure on line 184 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, ubi, v1.34.0) / Run Tests

It 12/17/25 19:45:52.986

Eventually(
func() error {
Expand Down Expand Up @@ -488,7 +488,7 @@
}
})

It("recovers when NGF Pod is restarted", func() {

Check notice on line 491 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, ubi, v1.34.0) / Run Tests

It 12/17/25 19:46:03.598
leaseName, err := getLeaderElectionLeaseHolderName()
Expect(err).ToNot(HaveOccurred())

Expand Down Expand Up @@ -541,21 +541,24 @@
}
})

It("recovers when drained node is restarted", func() {

Check notice on line 544 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, ubi, v1.34.0) / Run Tests

It 12/17/25 19:46:03.599
runRestartNodeWithDrainingTest(teaURL, coffeeURL, files, &ns)
})

It("recovers when node is restarted abruptly", func() {

Check notice on line 548 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, ubi, v1.34.0) / Run Tests

It 12/17/25 19:46:03.599
if *plusEnabled {
Skip(fmt.Sprintf("Skipping test when using NGINX Plus due to known issue:" +

Check notice on line 550 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, v1.25.16) / Run Tests

It 12/17/25 19:50:22.085

Check notice on line 550 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, v1.34.0) / Run Tests

It 12/17/25 19:49:27.314

Check notice on line 550 in tests/suite/graceful_recovery_test.go

View workflow job for this annotation

GitHub Actions / Functional tests (plus, ubi, v1.25.16) / Run Tests

It 12/17/25 19:50:38.099
" https://github.com/nginx/nginx-gateway-fabric/issues/3248"))
}
runRestartNodeAbruptlyTest(teaURL, coffeeURL, files, &ns)
})
})

func expectRequestToSucceed(appURL, address string, responseBodyMessage string) error {
status, body, err := framework.Get(appURL, address, timeoutConfig.RequestTimeout, nil, nil)
func expectRequestToSucceed(appURL, address string, responseBodyMessage string, opts ...framework.Option) error {
timeBeforeReq := time.Now()
status, body, err := framework.Get(appURL, address, timeoutConfig.RequestTimeout, nil, nil, opts...)
timeAfterReq := time.Now()
GinkgoWriter.Printf("Request duration: %v\n", timeAfterReq.Sub(timeBeforeReq))

if status != http.StatusOK {
return fmt.Errorf("http status was not 200, got %d: %w", status, err)
Expand Down
Loading
Loading