Skip to content
This repository has been archived by the owner on Nov 27, 2024. It is now read-only.

Commit

Permalink
e2e: enable setting poll timeout and step duration (#154)
Browse files Browse the repository at this point in the history
In some circumstances, we need to adjust the step and timeout duration
of the polling we do during e2e tests.  This hooks them up to the
E2E_POLL_STEP_DURATION and E2E_POLL_TIMEOUT environment variables.

These environment variables accept values similar to the `--timeout`
parameter of `kubectl wait`.  For instance, to set a timeout of five
minutes for polling timeouts, we set `E2E_POLL_TIMEOUT=5m`.  By default,
polling timeouts after 1 minute, and steps are run every second.

Signed-off-by: Andy Sadler <ansadler@redhat.com>
  • Loading branch information
sadlerap authored May 23, 2024
1 parent 6d3caab commit e2cc680
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 21 deletions.
16 changes: 6 additions & 10 deletions e2e/hook/cleanup_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ package hook
import (
"context"
"errors"
"time"

"github.com/cucumber/godog"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"

// tcontext "github.com/konflux-workspaces/workspaces/e2e/pkg/context"
// corev1 "k8s.io/api/core/v1"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
tcontext "github.com/konflux-workspaces/workspaces/e2e/pkg/context"
"github.com/konflux-workspaces/workspaces/e2e/pkg/poll"
workspacesv1alpha1 "github.com/konflux-workspaces/workspaces/operator/api/v1alpha1"
)

Expand All @@ -38,7 +34,7 @@ func deleteResources(ctx context.Context, sc *godog.Scenario, err error) (contex
continue
}

if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Delete(ctx, &r); err != nil {
if kerrors.IsNotFound(err) {
return true, nil
Expand All @@ -62,7 +58,7 @@ func deleteResources(ctx context.Context, sc *godog.Scenario, err error) (contex
continue
}

if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Delete(ctx, &r); err != nil {
if kerrors.IsNotFound(err) {
return true, nil
Expand All @@ -86,7 +82,7 @@ func deleteResources(ctx context.Context, sc *godog.Scenario, err error) (contex
continue
}

if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Delete(ctx, &r); err != nil {
if kerrors.IsNotFound(err) {
return true, nil
Expand All @@ -110,7 +106,7 @@ func deleteResources(ctx context.Context, sc *godog.Scenario, err error) (contex
continue
}

if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Delete(ctx, &r); err != nil {
if kerrors.IsNotFound(err) {
return true, nil
Expand All @@ -134,7 +130,7 @@ func deleteResources(ctx context.Context, sc *godog.Scenario, err error) (contex
continue
}

if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Delete(ctx, &r); err != nil {
if kerrors.IsNotFound(err) {
return true, nil
Expand Down
44 changes: 44 additions & 0 deletions e2e/pkg/poll/poll.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package poll

import (
"context"
"fmt"
"os"
"time"

"k8s.io/apimachinery/pkg/util/wait"
)

const envE2EPollTimeout = "E2E_POLL_TIMEOUT"
const envE2EPollStepDuration = "E2E_POLL_STEP_DURATION"

func init() {
pollTimeout = max(getDurationFromEnv(envE2EPollTimeout, time.Minute), 10*time.Second)
pollStepDuration = max(getDurationFromEnv(envE2EPollStepDuration, time.Second), time.Second)
if pollTimeout < pollStepDuration {
panic(fmt.Sprintf("Poll timeout (%v) longer than step duration (%v)", pollTimeout, pollStepDuration))
}
}

var pollTimeout time.Duration
var pollStepDuration time.Duration

func getDurationFromEnv(envVar string, defaultDuration time.Duration) time.Duration {
value := os.Getenv(envVar)
duration, err := time.ParseDuration(value)
if err != nil {
duration = defaultDuration
}
return duration
}

// WaitForConditionImmediately runs the function `condition` periodically to poll the
// status of a condition. It waits for either condition's first return value
// to be `true`, or for a timeout to be hit.
//
// By default, this timeout is 1 minute, and `condition` is checked every
// second. These can be overridden with the `E2E_POLL_TIMEOUT` and
// `E2E_POLL_STEP_DURATION` environment variables.
func WaitForConditionImmediately(ctx context.Context, condition func(ctx context.Context) (bool, error)) error {
return wait.PollUntilContextTimeout(ctx, pollStepDuration, pollTimeout, true, condition)
}
5 changes: 2 additions & 3 deletions e2e/step/user/user_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import (
"crypto/md5"
"encoding/hex"
"fmt"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/konflux-workspaces/workspaces/e2e/pkg/cli"
tcontext "github.com/konflux-workspaces/workspaces/e2e/pkg/context"
"github.com/konflux-workspaces/workspaces/e2e/pkg/poll"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
)
Expand Down Expand Up @@ -56,7 +55,7 @@ func OnboardUser(ctx context.Context, cli cli.Cli, namespace, name string) (*too
}

lu := toolchainv1alpha1.UserSignup{}
if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Get(ctx, client.ObjectKeyFromObject(&u), &lu); err != nil {
return false, client.IgnoreNotFound(err)
}
Expand Down
5 changes: 2 additions & 3 deletions e2e/step/workspace/workspace_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ package workspace
import (
"context"
"fmt"
"time"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
"github.com/konflux-workspaces/workspaces/e2e/pkg/cli"
tcontext "github.com/konflux-workspaces/workspaces/e2e/pkg/context"
"github.com/konflux-workspaces/workspaces/e2e/pkg/poll"
"github.com/konflux-workspaces/workspaces/e2e/step/user"
workspacesv1alpha1 "github.com/konflux-workspaces/workspaces/operator/api/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -57,7 +56,7 @@ func getWorkspace(ctx context.Context, cli cli.Cli, ns, name string) (*workspace
Namespace: ns,
},
}
if err := wait.PollUntilContextTimeout(ctx, time.Second*5, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Get(ctx, client.ObjectKeyFromObject(&w), &w); err != nil {
return false, client.IgnoreNotFound(err)
}
Expand Down
9 changes: 4 additions & 5 deletions e2e/step/workspace/workspace_then.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ package workspace
import (
"context"
"fmt"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/konflux-workspaces/workspaces/e2e/pkg/cli"
tcontext "github.com/konflux-workspaces/workspaces/e2e/pkg/context"
"github.com/konflux-workspaces/workspaces/e2e/pkg/poll"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
workspacesv1alpha1 "github.com/konflux-workspaces/workspaces/operator/api/v1alpha1"
Expand Down Expand Up @@ -75,7 +74,7 @@ func thenTheOwnerIsGrantedAdminAccessToTheWorkspace(ctx context.Context) error {
u := tcontext.RetrieveUser(ctx)
ns := tcontext.RetrieveKubespaceNamespace(ctx)

return wait.PollUntilContextTimeout(ctx, 1*time.Second, 1*time.Minute, true, func(ctx context.Context) (done bool, err error) {
return poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
asbb := toolchainv1alpha1.SpaceBindingList{}
if err := cli.Client.List(ctx, &asbb, client.InNamespace(ns)); err != nil {
return false, client.IgnoreNotFound(err)
Expand Down Expand Up @@ -116,7 +115,7 @@ func workspaceIsReadableForEveryone(ctx context.Context, cli cli.Cli, namespace,
Namespace: namespace,
},
}
if err := wait.PollUntilContextTimeout(ctx, time.Second, time.Minute, true, func(ctx context.Context) (done bool, err error) {
if err := poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Get(ctx, client.ObjectKeyFromObject(sb), sb); err != nil {
return false, client.IgnoreNotFound(err)
}
Expand All @@ -141,7 +140,7 @@ func thenTheWorkspaceVisibilityIsUpdatedTo(ctx context.Context, visibility strin
w := tcontext.RetrieveInternalWorkspace(ctx)
cli := tcontext.RetrieveHostClient(ctx)
wk := client.ObjectKeyFromObject(&w)
return wait.PollUntilContextTimeout(ctx, 1*time.Second, 1*time.Minute, true, func(ctx context.Context) (done bool, err error) {
return poll.WaitForConditionImmediately(ctx, func(ctx context.Context) (done bool, err error) {
if err := cli.Get(ctx, wk, &w); err != nil {
return false, err
}
Expand Down

0 comments on commit e2cc680

Please sign in to comment.