The problem seems to lie in here:
func (c *fakeAPIClient) Actions(args params.Entities) (params.ActionResults, error) {
// If the test supplies a delay time too long, we'll return an error
// to prevent the test hanging. If the given wait is up, then return
// the results; otherwise, return a pending status.
select {
case _ = <-c.delay.C:
// The API delay timer is up. Pass pre-canned results back.
return params.ActionResults{Results: c.actionResults}, c.apiErr
case _ = <-c.timeout.C:
// Timeout to prevent tests from hanging.
return params.ActionResults{}, errors.New("test timed out before wait time")
default:
// Timeout should only be nonzero in case we want to test
// pending behavior with a --wait flag on FetchCommand.
return params.ActionResults{Results: []params.ActionResult{{
Status: params.ActionPending,
Output: map[string]interface{}{},
Started: time.Date(2015, time.February, 14, 8, 15, 0, 0, time.UTC),
Enqueued: time.Date(2015, time.February, 14, 8, 13, 0, 0, time.UTC),
}}}, nil
}
The issue is that while it is true that the setup does:
fakeClient := makeFakeClient(
0*time.Second, // No API delay
5*time.Second, // 5 second test timeout
tc.tags,
tc.results,
tc.actionsByNames,
"", // No API error
)
which creates:
delay: time.NewTimer(delay),
timeout: time.NewTimer(timeout),
Apparently there is no guarantee that time.NewTimer(0) will actually be ready before the 'default:' branch is evaluated.
the _ = <time.NewTimer(0 *time.Second).C seems very strange.
Presumably it is meant to handle the case where c.delay.C isn't actually ready, but I don't think it actually gives us that.
Note also that all of these are *real* time.NewTimer calls, not *clock* calls. Which also adds real-clock-skew issues.
I'd like to fix those things, but the easier thing to do is just add '--wait 1s' to all the calls, in which case the code will see the Pending result, and keep trying until it sees something else.
The problem seems to lie in here: ActionResults, error) {
func (c *fakeAPIClient) Actions(args params.Entities) (params.
// If the test supplies a delay time too long, we'll return an error
// to prevent the test hanging. If the given wait is up, then return
// the results; otherwise, return a pending status.
// First, sync.
_ = <-time.NewTimer(0 * time.Second).C
select { ActionResults{ Results: c.actionResults}, c.apiErr ActionResults{ }, errors.New("test timed out before wait time") ActionResults{ Results: []params. ActionResult{ { ActionPending, interface{ }{},
case _ = <-c.delay.C:
// The API delay timer is up. Pass pre-canned results back.
return params.
case _ = <-c.timeout.C:
// Timeout to prevent tests from hanging.
return params.
default:
// Timeout should only be nonzero in case we want to test
// pending behavior with a --wait flag on FetchCommand.
return params.
Status: params.
Output: map[string]
Started: time.Date(2015, time.February, 14, 8, 15, 0, 0, time.UTC),
Enqueued: time.Date(2015, time.February, 14, 8, 13, 0, 0, time.UTC),
}}}, nil
}
The issue is that while it is true that the setup does: Names,
fakeClient := makeFakeClient(
0*time.Second, // No API delay
5*time.Second, // 5 second test timeout
tc.tags,
tc.results,
tc.actionsBy
"", // No API error
)
which creates: delay), timeout) ,
delay: time.NewTimer(
timeout: time.NewTimer(
Apparently there is no guarantee that time.NewTimer(0) will actually be ready before the 'default:' branch is evaluated.
the _ = <time.NewTimer(0 *time.Second).C seems very strange.
Presumably it is meant to handle the case where c.delay.C isn't actually ready, but I don't think it actually gives us that.
Note also that all of these are *real* time.NewTimer calls, not *clock* calls. Which also adds real-clock-skew issues.
I'd like to fix those things, but the easier thing to do is just add '--wait 1s' to all the calls, in which case the code will see the Pending result, and keep trying until it sees something else.