fix(service wait): Wrong check for error window (#661)

The error window introduced with #644 had a wrong conditional. Fixed that and added a test which would have detected this.

Also, this should fix some issues which we tried to detect with #659.
This commit is contained in:
Roland Huß 2020-02-13 20:18:36 +01:00 committed by GitHub
parent 8bca0bdfff
commit 52b56baf52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 23 deletions

View File

@ -41,7 +41,8 @@ type waitForReadyConfig struct {
type WaitForReady interface { type WaitForReady interface {
// Wait on resource the resource with this name until a given timeout // Wait on resource the resource with this name until a given timeout
// and write event messages for unknown event to the status writer // and write event messages for unknown event to the status writer.
// Returns an error (if any) and the overall time it took to wait
Wait(name string, timeout time.Duration, msgCallback MessageCallback) (error, time.Duration) Wait(name string, timeout time.Duration, msgCallback MessageCallback) (error, time.Duration)
} }
@ -161,9 +162,10 @@ func (w *waitForReadyConfig) waitForReadyCondition(start time.Time, name string,
// to a true condition even after the condition went to false. If this is not the case within // to a true condition even after the condition went to false. If this is not the case within
// this window, then an error is returned. // this window, then an error is returned.
// If there is already a timer running, we just log. // If there is already a timer running, we just log.
if errorTimer != nil { if errorTimer == nil {
err := fmt.Errorf("%s: %s", cond.Reason, cond.Message)
errorTimer = time.AfterFunc(errorWindow, func() { errorTimer = time.AfterFunc(errorWindow, func() {
errChan <- fmt.Errorf("%s: %s", cond.Reason, cond.Message) errChan <- err
}) })
} }
} }

View File

@ -30,7 +30,7 @@ import (
type waitForReadyTestCase struct { type waitForReadyTestCase struct {
events []watch.Event events []watch.Event
timeout time.Duration timeout time.Duration
errorExpected bool errorText string
messagesExpected []string messagesExpected []string
} }
@ -54,12 +54,16 @@ func TestAddWaitForReady(t *testing.T) {
}) })
close(fakeWatchApi.eventChan) close(fakeWatchApi.eventChan)
if !tc.errorExpected && err != nil { if tc.errorText == "" && err != nil {
t.Errorf("%d: Error received %v", i, err) t.Errorf("%d: Error received %v", i, err)
continue continue
} }
if tc.errorExpected && err == nil { if tc.errorText != "" {
t.Errorf("%d: No error but expected one", i) if err == nil {
t.Errorf("%d: No error but expected one", i)
} else {
assert.ErrorContains(t, err, tc.errorText)
}
} }
// check messages // check messages
@ -75,20 +79,34 @@ func TestAddWaitForReady(t *testing.T) {
// Test cases which consists of a series of events to send and the expected behaviour. // Test cases which consists of a series of events to send and the expected behaviour.
func prepareTestCases(name string) []waitForReadyTestCase { func prepareTestCases(name string) []waitForReadyTestCase {
return []waitForReadyTestCase{ return []waitForReadyTestCase{
tc(peNormal, name, false), errorTest(name),
tc(peError, name, true), tc(peNormal, name, time.Second, ""),
tc(peWrongGeneration, name, true), tc(peWrongGeneration, name, 1*time.Second, "timeout"),
tc(peTimeout, name, true), tc(peTimeout, name, time.Second, "timeout"),
tc(peReadyFalseWithinErrorWindow, name, false), tc(peReadyFalseWithinErrorWindow, name, time.Second, ""),
} }
} }
func tc(f func(name string) (evts []watch.Event, nrMessages int), name string, isError bool) waitForReadyTestCase { func errorTest(name string) waitForReadyTestCase {
events := []watch.Event{
{watch.Added, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", "msg1")},
{watch.Modified, CreateTestServiceWithConditions(name, corev1.ConditionFalse, corev1.ConditionTrue, "FakeError", "Test Error")},
}
return waitForReadyTestCase{
events: events,
timeout: 3 * time.Second,
errorText: "FakeError",
messagesExpected: []string{"msg1", "Test Error"},
}
}
func tc(f func(name string) (evts []watch.Event, nrMessages int), name string, timeout time.Duration, errorTxt string) waitForReadyTestCase {
events, nrMsgs := f(name) events, nrMsgs := f(name)
return waitForReadyTestCase{ return waitForReadyTestCase{
events, events,
time.Second, timeout,
isError, errorTxt,
pMessages(nrMsgs), pMessages(nrMsgs),
} }
} }
@ -110,14 +128,6 @@ func peNormal(name string) ([]watch.Event, int) {
}, len(messages) }, len(messages)
} }
func peError(name string) ([]watch.Event, int) {
messages := pMessages(1)
return []watch.Event{
{watch.Added, CreateTestServiceWithConditions(name, corev1.ConditionUnknown, corev1.ConditionUnknown, "", messages[0])},
{watch.Modified, CreateTestServiceWithConditions(name, corev1.ConditionFalse, corev1.ConditionTrue, "FakeError", "")},
}, len(messages)
}
func peTimeout(name string) ([]watch.Event, int) { func peTimeout(name string) ([]watch.Event, int) {
messages := pMessages(1) messages := pMessages(1)
return []watch.Event{ return []watch.Event{