Skip to content
Open
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
95 changes: 56 additions & 39 deletions test/e2e/steps/demo_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
Expand Down Expand Up @@ -41,6 +42,10 @@ func bash(ctx context.Context, script string) (string, error) {

if err != nil {
logger.V(1).Info("Failed to run", "command", script, "stderr", stderr, "error", err)
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
exitErr.Stderr = stderrBuf.Bytes()
}
}
logger.V(1).Info("Output", "command", script, "output", stdout)

Expand Down Expand Up @@ -81,7 +86,15 @@ func CatalogReportsConditionWithoutReason(ctx context.Context, catalogUserName,
func ensureCatalogPortForward(ctx context.Context) (string, error) {
sc := scenarioCtx(ctx)
if sc.catalogAddr != "" {
return sc.catalogAddr, nil
if catalogPortForwardAlive(sc.catalogAddr) {
return sc.catalogAddr, nil
}
logger.V(1).Info("Catalog port-forward is dead, re-establishing", "addr", sc.catalogAddr)
if sc.catalogCleanup != nil {
sc.catalogCleanup()
}
sc.catalogAddr = ""
sc.catalogCleanup = nil
}

addr, cleanup, err := portForward(ctx, componentNamespaces["catalogd"], "service/catalogd-service", 443)
Expand All @@ -92,68 +105,72 @@ func ensureCatalogPortForward(ctx context.Context) (string, error) {
sc.catalogCleanup = cleanup

waitFor(ctx, func() bool {
client := &http.Client{
Timeout: 3 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //nolint:gosec
DialContext: (&net.Dialer{Timeout: 2 * time.Second}).DialContext,
},
}
resp, err := client.Get(fmt.Sprintf("https://%s/", addr))
if err != nil {
return false
}
resp.Body.Close()
return true
return catalogPortForwardAlive(addr)
})
return addr, nil
}

func catalogPortForwardAlive(addr string) bool {
client := &http.Client{
Timeout: 3 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //nolint:gosec
DialContext: (&net.Dialer{Timeout: 2 * time.Second}).DialContext,
},
}
resp, err := client.Get(fmt.Sprintf("https://%s/", addr))
if err != nil {
return false
}
resp.Body.Close()
return true
}

func catalogCurlJq(ctx context.Context, catalogName, jqFilter string) (string, error) {
addr, err := ensureCatalogPortForward(ctx)
if err != nil {
return "", err
}
script := fmt.Sprintf(
`curl -s -k https://%s/catalogs/%s/api/v1/all | jq -s '%s'`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need jq -s because the catalog format is in JSONLines (jsonl) format, not monolithic JSON, and slurp-mode forces it to re-represent it inside a monolithic object. Without this, jq will error.

`curl -sS -k --retry 3 --retry-delay 2 --retry-all-errors https://%s/catalogs/%s/api/v1/all | jq '%s'`,
addr, catalogName, jqFilter,
)
Comment on lines 134 to 137

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — updated to curl -sS so transport/TLS errors are surfaced on stderr while keeping normal output quiet. This pairs well with the new stderr-to-ExitError propagation in bash().

return bash(ctx, script)
}

func CatalogContainsSomePackages(ctx context.Context, catalogName string) error {
out, err := catalogCurlJq(ctx, catalogName,
`.[] | select(.schema == "olm.package") | .name`)
if err != nil {
return err
}
if strings.TrimSpace(out) == "" {
return fmt.Errorf("catalog %q contains no packages", catalogName)
}
waitFor(ctx, func() bool {
out, err := catalogCurlJq(ctx, catalogName,
`select(.schema == "olm.package") | .name`)
if err != nil {
return false
}
return strings.TrimSpace(out) != ""
})
Comment on lines +142 to +149

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changed functions will no longer return an error. Should the context be checked for a timeout so that an error can be returned?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The waitFor function uses require.Eventually(godog.T(ctx), ..., timeout, tick) which calls t.FailNow() on timeout — the function never returns on failure, it hard-fails the test via runtime.Goexit(). This matches the established pattern used by PodHasContainerCount in the same file (line 209) and dozens of other step functions throughout the test suite. So from a test perspective, the behavior is: either the condition is met within 5 minutes, or the scenario fails immediately.

return nil
}

func PackageHasSomeChannels(ctx context.Context, packageName, catalogName string) error {
out, err := catalogCurlJq(ctx, catalogName,
fmt.Sprintf(`.[] | select(.schema == "olm.channel") | select(.package == "%s") | .name`, packageName))
if err != nil {
return err
}
if strings.TrimSpace(out) == "" {
return fmt.Errorf("package %q in catalog %q has no channels", packageName, catalogName)
}
waitFor(ctx, func() bool {
out, err := catalogCurlJq(ctx, catalogName,
fmt.Sprintf(`select(.schema == "olm.channel") | select(.package == "%s") | .name`, packageName))
if err != nil {
return false
}
return strings.TrimSpace(out) != ""
})
return nil
}

func PackageHasSomeBundles(ctx context.Context, packageName, catalogName string) error {
out, err := catalogCurlJq(ctx, catalogName,
fmt.Sprintf(`.[] | select(.schema == "olm.bundle") | select(.package == "%s") | .name`, packageName))
if err != nil {
return err
}
if strings.TrimSpace(out) == "" {
return fmt.Errorf("package %q in catalog %q has no bundles", packageName, catalogName)
}
waitFor(ctx, func() bool {
out, err := catalogCurlJq(ctx, catalogName,
fmt.Sprintf(`select(.schema == "olm.bundle") | select(.package == "%s") | .name`, packageName))
if err != nil {
return false
}
return strings.TrimSpace(out) != ""
})
return nil
}

Expand Down