From b4f8b7f43bef7582ff47fbdbc91c2c0fdbcfe5d4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Oct 2014 18:28:03 -0700 Subject: [PATCH] helper/resource: RetryError for quitting quickly --- helper/resource/wait.go | 21 ++++++++++++++++++--- helper/resource/wait_test.go | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/helper/resource/wait.go b/helper/resource/wait.go index 5fcd59c26f..326555053f 100644 --- a/helper/resource/wait.go +++ b/helper/resource/wait.go @@ -18,14 +18,29 @@ func Retry(timeout time.Duration, f RetryFunc) error { MinTimeout: 500 * time.Millisecond, Refresh: func() (interface{}, string, error) { err = f() - if err != nil { - return 42, "error", nil + if err == nil { + return 42, "success", nil } - return 42, "success", nil + if rerr, ok := err.(RetryError); ok { + err = rerr.Err + return nil, "quit", err + } + + return 42, "error", nil }, } c.WaitForState() return err } + +// RetryError, if returned, will quit the retry immediately with the +// Err. +type RetryError struct { + Err error +} + +func (e RetryError) Error() string { + return e.Err.Error() +} diff --git a/helper/resource/wait_test.go b/helper/resource/wait_test.go index 34ca6ce188..f79d276567 100644 --- a/helper/resource/wait_test.go +++ b/helper/resource/wait_test.go @@ -37,3 +37,26 @@ func TestRetry_timeout(t *testing.T) { t.Fatal("should error") } } + +func TestRetry_error(t *testing.T) { + t.Parallel() + + expected := fmt.Errorf("nope") + f := func() error { + return RetryError{expected} + } + + errCh := make(chan error) + go func() { + errCh <- Retry(1*time.Second, f) + }() + + select { + case err := <-errCh: + if err != expected { + t.Fatalf("bad: %#v", err) + } + case <-time.After(5 * time.Second): + t.Fatal("timeout") + } +}