Merge pull request #46648 from caesarxuchao/fix-46631

Automatic merge from submit-queue (batch tested with PRs 46648, 46500, 46238, 46668, 46557)

Fix initializer_manager_test.go flake

Fixes https://github.com/kubernetes/kubernetes/issues/46631.

I reproduced the flake after 98 runs.

With the fix, it's not flaky in 1000 runs.
This commit is contained in:
Kubernetes Submit Queue
2017-06-02 15:20:42 -07:00
committed by GitHub
2 changed files with 22 additions and 24 deletions

View File

@@ -46,6 +46,8 @@ type poller struct {
// if the number of consecutive read failure equals or exceeds the failureThreshold , the // if the number of consecutive read failure equals or exceeds the failureThreshold , the
// configuration is regarded as not ready. // configuration is regarded as not ready.
failureThreshold int failureThreshold int
// number of consecutive failures so far.
failures int
// if the configuration is regarded as ready. // if the configuration is regarded as ready.
ready bool ready bool
mergedConfiguration runtime.Object mergedConfiguration runtime.Object
@@ -84,17 +86,18 @@ func (a *poller) setConfigurationAndReady(value runtime.Object) {
} }
func (a *poller) Run(stopCh <-chan struct{}) { func (a *poller) Run(stopCh <-chan struct{}) {
var failure int go wait.Until(a.sync, a.interval, stopCh)
go wait.Until(func() { }
configuration, err := a.get()
if err != nil { func (a *poller) sync() {
failure++ configuration, err := a.get()
if failure >= a.failureThreshold { if err != nil {
a.notReady() a.failures++
} if a.failures >= a.failureThreshold {
return a.notReady()
} }
failure = 0 return
a.setConfigurationAndReady(configuration) }
}, a.interval, stopCh) a.failures = 0
a.setConfigurationAndReady(configuration)
} }

View File

@@ -30,7 +30,6 @@ type mockLister struct {
invoked int invoked int
successes int successes int
failures int failures int
stopCh chan struct{}
configurationList v1alpha1.InitializerConfigurationList configurationList v1alpha1.InitializerConfigurationList
t *testing.T t *testing.T
} }
@@ -40,20 +39,15 @@ func newMockLister(successes, failures int, configurationList v1alpha1.Initializ
failures: failures, failures: failures,
successes: successes, successes: successes,
configurationList: configurationList, configurationList: configurationList,
stopCh: make(chan struct{}),
t: t, t: t,
} }
} }
// The first List will be successful; the next m.failures List will // The first List will be successful; the next m.failures List will
// fail; the next m.successes List will be successful; the stopCh is closed at // fail; the next m.successes List will be successful
// the 1+m.failures+m.successes call. // List should only be called 1+m.failures+m.successes times.
func (m *mockLister) List(options metav1.ListOptions) (*v1alpha1.InitializerConfigurationList, error) { func (m *mockLister) List(options metav1.ListOptions) (*v1alpha1.InitializerConfigurationList, error) {
m.invoked++ m.invoked++
// m.successes could be 0, so call this `if` first.
if m.invoked == 1+m.failures+m.successes {
close(m.stopCh)
}
if m.invoked == 1 { if m.invoked == 1 {
return &m.configurationList, nil return &m.configurationList, nil
} }
@@ -63,7 +57,7 @@ func (m *mockLister) List(options metav1.ListOptions) (*v1alpha1.InitializerConf
if m.invoked <= 1+m.failures+m.successes { if m.invoked <= 1+m.failures+m.successes {
return &m.configurationList, nil return &m.configurationList, nil
} }
m.t.Fatalf("unexpected call to List, stopCh has been closed at the %d time call", 1+m.successes+m.failures) m.t.Fatalf("unexpected call to List, should only be called %d times", 1+m.successes+m.failures)
return nil, nil return nil, nil
} }
@@ -103,8 +97,9 @@ func TestConfiguration(t *testing.T) {
mock := newMockLister(c.successes, c.failures, v1alpha1.InitializerConfigurationList{}, t) mock := newMockLister(c.successes, c.failures, v1alpha1.InitializerConfigurationList{}, t)
manager := NewInitializerConfigurationManager(mock) manager := NewInitializerConfigurationManager(mock)
manager.interval = 1 * time.Millisecond manager.interval = 1 * time.Millisecond
manager.Run(mock.stopCh) for i := 0; i < 1+c.successes+c.failures; i++ {
<-mock.stopCh manager.sync()
}
_, err := manager.Initializers() _, err := manager.Initializers()
if err != nil && c.expectReady { if err != nil && c.expectReady {
t.Errorf("case %s, expect ready, got: %v", c.name, err) t.Errorf("case %s, expect ready, got: %v", c.name, err)