helper/resource: Allow unknown pending states (#13099)

Sometimes when waiting on a target state, the set of valid states
through which a value will transition is unknown. This commit adds
support for an empty Pending slice and will treat any states that are not
the target as valid provided the timeouts are not exceeded.
This commit is contained in:
James Nugent 2017-03-28 15:38:42 -04:00 committed by Paul Stack
parent 8496d0e510
commit 0e3a7e6d0d
2 changed files with 34 additions and 1 deletions

View File

@ -141,7 +141,7 @@ func (conf *StateChangeConf) WaitForState() (interface{}, error) {
} }
} }
if !found { if !found && len(conf.Pending) > 0 {
result.Error = &UnexpectedStateError{ result.Error = &UnexpectedStateError{
LastError: err, LastError: err,
State: result.State, State: result.State,

View File

@ -70,6 +70,23 @@ func InconsistentStateRefreshFunc() StateRefreshFunc {
} }
} }
func UnknownPendingStateRefreshFunc() StateRefreshFunc {
sequence := []string{
"unknown1", "unknown2", "done",
}
r := NewStateGenerator(sequence)
return func() (interface{}, string, error) {
idx, s, err := r.NextState()
if err != nil {
return nil, "", err
}
return idx, s, nil
}
}
func TestWaitForState_inconsistent_positive(t *testing.T) { func TestWaitForState_inconsistent_positive(t *testing.T) {
conf := &StateChangeConf{ conf := &StateChangeConf{
Pending: []string{"replicating"}, Pending: []string{"replicating"},
@ -154,6 +171,22 @@ func TestWaitForState_success(t *testing.T) {
} }
} }
func TestWaitForState_successUnknownPending(t *testing.T) {
conf := &StateChangeConf{
Target: []string{"done"},
Refresh: UnknownPendingStateRefreshFunc(),
Timeout: 200 * time.Second,
}
obj, err := conf.WaitForState()
if err != nil {
t.Fatalf("err: %s", err)
}
if obj == nil {
t.Fatalf("should return obj")
}
}
func TestWaitForState_successEmpty(t *testing.T) { func TestWaitForState_successEmpty(t *testing.T) {
conf := &StateChangeConf{ conf := &StateChangeConf{
Pending: []string{"pending", "incomplete"}, Pending: []string{"pending", "incomplete"},