Skip to content

Commit

Permalink
feat: add utils.PollE
Browse files Browse the repository at this point in the history
  • Loading branch information
grayside committed Jul 26, 2023
1 parent cda1dc1 commit e37715c
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 4 deletions.
20 changes: 16 additions & 4 deletions infra/blueprint-test/pkg/utils/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package utils

import (
"fmt"
"time"

"github.com/mitchellh/go-testing-interface"
Expand All @@ -25,12 +26,21 @@ import (
// Polls on a particular condition function while the returns true.
// It fails the test if the condition is not met within numRetries.
func Poll(t testing.TB, condition func() (bool, error), numRetries int, interval time.Duration) {
err := PollE(t, condition, numRetries, interval)
if err != nil {
t.Fatalf("failed to pull provided condition after %d retries, last error: %v", numRetries, err)
}
}

// Polls on a particular condition function while the returns true.
// Returns an error if the condition is not met within numRetries.
func PollE(t testing.TB, condition func() (bool, error), numRetries int, interval time.Duration) error {
if numRetries < 0 {
t.Fatal("invalid value for numRetries. Must be >= 0")
return fmt.Errorf("invalid value for numRetries. Must be >= 0")
}

if interval <= 0 {
t.Fatal("invalid value for numRetries. Must be > 0")
return fmt.Errorf("invalid value for numRetries. Must be > 0")
}

retry, err := condition()
Expand All @@ -45,10 +55,12 @@ func Poll(t testing.TB, condition func() (bool, error), numRetries int, interval
}

if err != nil {
t.Fatalf("failed to pull provided condition after %d retries, last error: %v", numRetries, err)
return fmt.Errorf("failed to pull provided condition after %d retries, last error: %v", numRetries, err)
}

if retry {
t.Fatalf("polling timed out after %d retries with %d second intervals", numRetries, interval/time.Second)
return fmt.Errorf("polling timed out after %d retries with %d second intervals", numRetries, interval/time.Second)
}

return nil
}
92 changes: 92 additions & 0 deletions infra/blueprint-test/pkg/utils/poll_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package utils_test

import (
"errors"
"strings"
"testing"
"time"

"github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/utils"
)

func TestPoll(t *testing.T) {
testcases := []struct {
label string
condition func() (bool, error)
want string
}{
{
label: "error",
condition: func() (bool, error) {
return true, errors.New("condition failure")
},
want: "condition failure",
},
{
label: "timeout",
condition: func() (bool, error) {
return true, nil
},
want: "polling timed out",
},
}

for _, tc := range testcases {
t.Run(tc.label, func(t *testing.T) {
it := &inspectableT{t, nil}
utils.Poll(it, tc.condition, 3, time.Millisecond)
if !strings.Contains(it.err.Error(), tc.want) {
t.Errorf("got %v, want %v", it.err, tc.want)
}
})
}
}

func TestPollE(t *testing.T) {
testcases := []struct {
label string
condition func() (bool, error)
want string
}{
{
label: "error",
condition: func() (bool, error) {
return true, errors.New("condition failure")
},
want: "condition failure",
},
{
label: "timeout",
condition: func() (bool, error) {
return true, nil
},
want: "polling timed out",
},
}

for _, tc := range testcases {
t.Run(tc.label, func(t *testing.T) {
it := &inspectableT{t, nil}
err := utils.PollE(it, tc.condition, 3, time.Millisecond)
if !strings.Contains(err.Error(), tc.want) {
t.Errorf("got %v, want %v", it.err, tc.want)
}
})
}
}

0 comments on commit e37715c

Please sign in to comment.