diff --git a/go.mod b/go.mod index 5c957344..e18922b7 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible k8s.io/component-base v0.17.2 k8s.io/klog v1.0.0 + k8s.io/utils v0.0.0-20200122174043-1e243dd1a584 sigs.k8s.io/boskos v0.0.0-20200515170311-7d36bde8cdf6 ) @@ -95,7 +96,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29 // indirect k8s.io/test-infra v0.0.0-20200514184223-ba32c8aae783 // indirect - k8s.io/utils v0.0.0-20200122174043-1e243dd1a584 // indirect sigs.k8s.io/yaml v1.2.0 // indirect ) diff --git a/pkg/exporters/k8sexporter/condition/manager.go b/pkg/exporters/k8sexporter/condition/manager.go index 347c39c9..fddb6807 100644 --- a/pkg/exporters/k8sexporter/condition/manager.go +++ b/pkg/exporters/k8sexporter/condition/manager.go @@ -26,8 +26,8 @@ import ( "k8s.io/node-problem-detector/pkg/types" problemutil "k8s.io/node-problem-detector/pkg/util" - "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/clock" + v1 "k8s.io/api/core/v1" + "k8s.io/utils/clock" "github.com/golang/glog" ) @@ -68,7 +68,7 @@ type conditionManager struct { // No lock is needed in `sync`, because it is in the same goroutine with the // write operation. sync.RWMutex - clock clock.Clock + clock clock.WithTicker latestTry time.Time resyncNeeded bool client problemclient.Client @@ -79,10 +79,10 @@ type conditionManager struct { } // NewConditionManager creates a condition manager. -func NewConditionManager(client problemclient.Client, clock clock.Clock, heartbeatPeriod time.Duration) ConditionManager { +func NewConditionManager(client problemclient.Client, clockInUse clock.WithTicker, heartbeatPeriod time.Duration) ConditionManager { return &conditionManager{ client: client, - clock: clock, + clock: clockInUse, updates: make(map[string]types.Condition), conditions: make(map[string]types.Condition), heartbeatPeriod: heartbeatPeriod, diff --git a/pkg/exporters/k8sexporter/condition/manager_test.go b/pkg/exporters/k8sexporter/condition/manager_test.go index 4daba6a4..bea833f9 100644 --- a/pkg/exporters/k8sexporter/condition/manager_test.go +++ b/pkg/exporters/k8sexporter/condition/manager_test.go @@ -29,14 +29,14 @@ import ( problemutil "k8s.io/node-problem-detector/pkg/util" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/clock" + testclock "k8s.io/utils/clock/testing" ) const heartbeatPeriod = 1 * time.Minute -func newTestManager() (*conditionManager, *problemclient.FakeProblemClient, *clock.FakeClock) { +func newTestManager() (*conditionManager, *problemclient.FakeProblemClient, *testclock.FakeClock) { fakeClient := problemclient.NewFakeProblemClient() - fakeClock := clock.NewFakeClock(time.Now()) + fakeClock := testclock.NewFakeClock(time.Now()) manager := NewConditionManager(fakeClient, fakeClock, heartbeatPeriod) return manager.(*conditionManager), fakeClient, fakeClock } diff --git a/pkg/exporters/k8sexporter/k8s_exporter.go b/pkg/exporters/k8sexporter/k8s_exporter.go index 66d70c9a..00ea8a81 100644 --- a/pkg/exporters/k8sexporter/k8s_exporter.go +++ b/pkg/exporters/k8sexporter/k8s_exporter.go @@ -25,8 +25,8 @@ import ( "github.com/golang/glog" - "k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/utils/clock" "k8s.io/node-problem-detector/cmd/options" "k8s.io/node-problem-detector/pkg/exporters/k8sexporter/condition" diff --git a/pkg/exporters/k8sexporter/problemclient/problem_client.go b/pkg/exporters/k8sexporter/problemclient/problem_client.go index 48940885..65f434c4 100644 --- a/pkg/exporters/k8sexporter/problemclient/problem_client.go +++ b/pkg/exporters/k8sexporter/problemclient/problem_client.go @@ -29,10 +29,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/clock" clientset "k8s.io/client-go/kubernetes" typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/record" + "k8s.io/utils/clock" "k8s.io/node-problem-detector/cmd/options" "k8s.io/node-problem-detector/pkg/version" @@ -107,7 +107,7 @@ func (c *nodeProblemClient) SetConditions(ctx context.Context, newConditions []v if err != nil { return err } - return c.client.RESTClient().Patch(types.StrategicMergePatchType).Resource("nodes").Name(c.nodeName).SubResource("status").Body(patch).Do().Error() + return c.client.RESTClient().Patch(types.StrategicMergePatchType).Resource("nodes").Name(c.nodeName).SubResource("status").Body(patch).Do(ctx).Error() } func (c *nodeProblemClient) Eventf(eventType, source, reason, messageFmt string, args ...interface{}) { @@ -121,7 +121,7 @@ func (c *nodeProblemClient) Eventf(eventType, source, reason, messageFmt string, } func (c *nodeProblemClient) GetNode(ctx context.Context) (*v1.Node, error) { - return c.client.Nodes().Get(c.nodeName, metav1.GetOptions{}) + return c.client.Nodes().Get(ctx, c.nodeName, metav1.GetOptions{}) } // generatePatch generates condition patch diff --git a/pkg/exporters/k8sexporter/problemclient/problem_client_test.go b/pkg/exporters/k8sexporter/problemclient/problem_client_test.go index 200e3a80..9f80c5d8 100644 --- a/pkg/exporters/k8sexporter/problemclient/problem_client_test.go +++ b/pkg/exporters/k8sexporter/problemclient/problem_client_test.go @@ -22,10 +22,10 @@ import ( "testing" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/clock" "k8s.io/client-go/tools/record" + testclock "k8s.io/utils/clock/testing" "github.com/stretchr/testify/assert" ) @@ -40,7 +40,7 @@ func newFakeProblemClient() *nodeProblemClient { nodeName: testNode, // There is no proper fake for *client.Client for now // TODO(random-liu): Add test for SetConditions when we have good fake for *client.Client - clock: &clock.FakeClock{}, + clock: testclock.NewFakeClock(time.Now()), recorders: make(map[string]record.EventRecorder), nodeRef: getNodeRef("", testNode), } diff --git a/pkg/logcounter/log_counter.go b/pkg/logcounter/log_counter.go index b3959ffd..c1f79a67 100644 --- a/pkg/logcounter/log_counter.go +++ b/pkg/logcounter/log_counter.go @@ -23,7 +23,7 @@ import ( "fmt" "time" - "k8s.io/apimachinery/pkg/util/clock" + "k8s.io/utils/clock" "k8s.io/node-problem-detector/cmd/logcounter/options" "k8s.io/node-problem-detector/pkg/logcounter/types" diff --git a/pkg/logcounter/log_counter_test.go b/pkg/logcounter/log_counter_test.go index f4f1a3cf..107f2ea7 100644 --- a/pkg/logcounter/log_counter_test.go +++ b/pkg/logcounter/log_counter_test.go @@ -23,16 +23,16 @@ import ( "testing" "time" - "k8s.io/apimachinery/pkg/util/clock" + testclock "k8s.io/utils/clock/testing" "k8s.io/node-problem-detector/pkg/logcounter/types" "k8s.io/node-problem-detector/pkg/systemlogmonitor" systemtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" ) -func NewTestLogCounter(pattern string, startTime time.Time) (types.LogCounter, *clock.FakeClock, chan *systemtypes.Log) { +func NewTestLogCounter(pattern string, startTime time.Time) (types.LogCounter, *testclock.FakeClock, chan *systemtypes.Log) { logCh := make(chan *systemtypes.Log) - clock := clock.NewFakeClock(startTime) + clock := testclock.NewFakeClock(startTime) return &logCounter{ logCh: logCh, buffer: systemlogmonitor.NewLogBuffer(bufferSize), diff --git a/pkg/systemlogmonitor/logwatchers/filelog/translator.go b/pkg/systemlogmonitor/logwatchers/filelog/translator.go index 29ee207c..a190f684 100644 --- a/pkg/systemlogmonitor/logwatchers/filelog/translator.go +++ b/pkg/systemlogmonitor/logwatchers/filelog/translator.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/helpers_linux.go b/pkg/util/helpers_linux.go index 1fb5fc16..b279fbec 100644 --- a/pkg/util/helpers_linux.go +++ b/pkg/util/helpers_linux.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/helpers_windows.go b/pkg/util/helpers_windows.go index 6207a37f..0d4ddac8 100644 --- a/pkg/util/helpers_windows.go +++ b/pkg/util/helpers_windows.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/metrics/fakes.go b/pkg/util/metrics/fakes.go index 53b3beea..7b30c7fd 100644 --- a/pkg/util/metrics/fakes.go +++ b/pkg/util/metrics/fakes.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/metrics/fakes_test.go b/pkg/util/metrics/fakes_test.go index 01266af2..bb741968 100644 --- a/pkg/util/metrics/fakes_test.go +++ b/pkg/util/metrics/fakes_test.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/metrics/helpers.go b/pkg/util/metrics/helpers.go index 58037a6f..6597e209 100644 --- a/pkg/util/metrics/helpers.go +++ b/pkg/util/metrics/helpers.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/metrics/metric.go b/pkg/util/metrics/metric.go index 7b4ac57e..d3044cd5 100644 --- a/pkg/util/metrics/metric.go +++ b/pkg/util/metrics/metric.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/metrics/metric_float64.go b/pkg/util/metrics/metric_float64.go index fab1ec01..d6a903bb 100644 --- a/pkg/util/metrics/metric_float64.go +++ b/pkg/util/metrics/metric_float64.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/util/metrics/metric_int64.go b/pkg/util/metrics/metric_int64.go index a01626e1..79416761 100644 --- a/pkg/util/metrics/metric_int64.go +++ b/pkg/util/metrics/metric_int64.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/vendor/k8s.io/utils/clock/clock.go b/vendor/k8s.io/utils/clock/clock.go new file mode 100644 index 00000000..789c0238 --- /dev/null +++ b/vendor/k8s.io/utils/clock/clock.go @@ -0,0 +1,97 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package clock + +import "time" + +// Clock allows for injecting fake or real clocks into code that +// needs to do arbitrary things based on time. +type Clock interface { + Now() time.Time + Since(time.Time) time.Duration + After(d time.Duration) <-chan time.Time + NewTimer(d time.Duration) Timer + Sleep(d time.Duration) + Tick(d time.Duration) <-chan time.Time +} + +var _ = Clock(RealClock{}) + +// RealClock really calls time.Now() +type RealClock struct{} + +// Now returns the current time. +func (RealClock) Now() time.Time { + return time.Now() +} + +// Since returns time since the specified timestamp. +func (RealClock) Since(ts time.Time) time.Duration { + return time.Since(ts) +} + +// After is the same as time.After(d). +func (RealClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +// NewTimer is the same as time.NewTimer(d) +func (RealClock) NewTimer(d time.Duration) Timer { + return &realTimer{ + timer: time.NewTimer(d), + } +} + +// Tick is the same as time.Tick(d) +func (RealClock) Tick(d time.Duration) <-chan time.Time { + return time.Tick(d) +} + +// Sleep is the same as time.Sleep(d) +func (RealClock) Sleep(d time.Duration) { + time.Sleep(d) +} + +// Timer allows for injecting fake or real timers into code that +// needs to do arbitrary things based on time. +type Timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +var _ = Timer(&realTimer{}) + +// realTimer is backed by an actual time.Timer. +type realTimer struct { + timer *time.Timer +} + +// C returns the underlying timer's channel. +func (r *realTimer) C() <-chan time.Time { + return r.timer.C +} + +// Stop calls Stop() on the underlying timer. +func (r *realTimer) Stop() bool { + return r.timer.Stop() +} + +// Reset calls Reset() on the underlying timer. +func (r *realTimer) Reset(d time.Duration) bool { + return r.timer.Reset(d) +} diff --git a/vendor/k8s.io/utils/clock/testing/fake_clock.go b/vendor/k8s.io/utils/clock/testing/fake_clock.go new file mode 100644 index 00000000..2fc34aed --- /dev/null +++ b/vendor/k8s.io/utils/clock/testing/fake_clock.go @@ -0,0 +1,274 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + "sync" + "time" + + "k8s.io/utils/clock" +) + +var ( + _ = clock.Clock(&FakeClock{}) + _ = clock.Clock(&IntervalClock{}) +) + +// FakeClock implements clock.Clock, but returns an arbitrary time. +type FakeClock struct { + lock sync.RWMutex + time time.Time + + // waiters are waiting for the fake time to pass their specified time + waiters []*fakeClockWaiter +} + +type fakeClockWaiter struct { + targetTime time.Time + stepInterval time.Duration + skipIfBlocked bool + destChan chan time.Time + fired bool +} + +// NewFakeClock constructs a fake clock set to the provided time. +func NewFakeClock(t time.Time) *FakeClock { + return &FakeClock{ + time: t, + } +} + +// Now returns f's time. +func (f *FakeClock) Now() time.Time { + f.lock.RLock() + defer f.lock.RUnlock() + return f.time +} + +// Since returns time since the time in f. +func (f *FakeClock) Since(ts time.Time) time.Duration { + f.lock.RLock() + defer f.lock.RUnlock() + return f.time.Sub(ts) +} + +// After is the fake version of time.After(d). +func (f *FakeClock) After(d time.Duration) <-chan time.Time { + f.lock.Lock() + defer f.lock.Unlock() + stopTime := f.time.Add(d) + ch := make(chan time.Time, 1) // Don't block! + f.waiters = append(f.waiters, &fakeClockWaiter{ + targetTime: stopTime, + destChan: ch, + }) + return ch +} + +// NewTimer constructs a fake timer, akin to time.NewTimer(d). +func (f *FakeClock) NewTimer(d time.Duration) clock.Timer { + f.lock.Lock() + defer f.lock.Unlock() + stopTime := f.time.Add(d) + ch := make(chan time.Time, 1) // Don't block! + timer := &fakeTimer{ + fakeClock: f, + waiter: fakeClockWaiter{ + targetTime: stopTime, + destChan: ch, + }, + } + f.waiters = append(f.waiters, &timer.waiter) + return timer +} + +// Tick constructs a fake ticker, akin to time.Tick +func (f *FakeClock) Tick(d time.Duration) <-chan time.Time { + if d <= 0 { + return nil + } + f.lock.Lock() + defer f.lock.Unlock() + tickTime := f.time.Add(d) + ch := make(chan time.Time, 1) // hold one tick + f.waiters = append(f.waiters, &fakeClockWaiter{ + targetTime: tickTime, + stepInterval: d, + skipIfBlocked: true, + destChan: ch, + }) + + return ch +} + +// Step moves the clock by Duration and notifies anyone that's called After, +// Tick, or NewTimer. +func (f *FakeClock) Step(d time.Duration) { + f.lock.Lock() + defer f.lock.Unlock() + f.setTimeLocked(f.time.Add(d)) +} + +// SetTime sets the time. +func (f *FakeClock) SetTime(t time.Time) { + f.lock.Lock() + defer f.lock.Unlock() + f.setTimeLocked(t) +} + +// Actually changes the time and checks any waiters. f must be write-locked. +func (f *FakeClock) setTimeLocked(t time.Time) { + f.time = t + newWaiters := make([]*fakeClockWaiter, 0, len(f.waiters)) + for i := range f.waiters { + w := f.waiters[i] + if !w.targetTime.After(t) { + + if w.skipIfBlocked { + select { + case w.destChan <- t: + w.fired = true + default: + } + } else { + w.destChan <- t + w.fired = true + } + + if w.stepInterval > 0 { + for !w.targetTime.After(t) { + w.targetTime = w.targetTime.Add(w.stepInterval) + } + newWaiters = append(newWaiters, w) + } + + } else { + newWaiters = append(newWaiters, f.waiters[i]) + } + } + f.waiters = newWaiters +} + +// HasWaiters returns true if After has been called on f but not yet satisfied (so you can +// write race-free tests). +func (f *FakeClock) HasWaiters() bool { + f.lock.RLock() + defer f.lock.RUnlock() + return len(f.waiters) > 0 +} + +// Sleep is akin to time.Sleep +func (f *FakeClock) Sleep(d time.Duration) { + f.Step(d) +} + +// IntervalClock implements clock.Clock, but each invocation of Now steps the clock forward the specified duration +type IntervalClock struct { + Time time.Time + Duration time.Duration +} + +// Now returns i's time. +func (i *IntervalClock) Now() time.Time { + i.Time = i.Time.Add(i.Duration) + return i.Time +} + +// Since returns time since the time in i. +func (i *IntervalClock) Since(ts time.Time) time.Duration { + return i.Time.Sub(ts) +} + +// After is unimplemented, will panic. +// TODO: make interval clock use FakeClock so this can be implemented. +func (*IntervalClock) After(d time.Duration) <-chan time.Time { + panic("IntervalClock doesn't implement After") +} + +// NewTimer is unimplemented, will panic. +// TODO: make interval clock use FakeClock so this can be implemented. +func (*IntervalClock) NewTimer(d time.Duration) clock.Timer { + panic("IntervalClock doesn't implement NewTimer") +} + +// Tick is unimplemented, will panic. +// TODO: make interval clock use FakeClock so this can be implemented. +func (*IntervalClock) Tick(d time.Duration) <-chan time.Time { + panic("IntervalClock doesn't implement Tick") +} + +// Sleep is unimplemented, will panic. +func (*IntervalClock) Sleep(d time.Duration) { + panic("IntervalClock doesn't implement Sleep") +} + +var _ = clock.Timer(&fakeTimer{}) + +// fakeTimer implements clock.Timer based on a FakeClock. +type fakeTimer struct { + fakeClock *FakeClock + waiter fakeClockWaiter +} + +// C returns the channel that notifies when this timer has fired. +func (f *fakeTimer) C() <-chan time.Time { + return f.waiter.destChan +} + +// Stop stops the timer and returns true if the timer has not yet fired, or false otherwise. +func (f *fakeTimer) Stop() bool { + f.fakeClock.lock.Lock() + defer f.fakeClock.lock.Unlock() + + newWaiters := make([]*fakeClockWaiter, 0, len(f.fakeClock.waiters)) + for i := range f.fakeClock.waiters { + w := f.fakeClock.waiters[i] + if w != &f.waiter { + newWaiters = append(newWaiters, w) + } + } + + f.fakeClock.waiters = newWaiters + + return !f.waiter.fired +} + +// Reset resets the timer to the fake clock's "now" + d. It returns true if the timer has not yet +// fired, or false otherwise. +func (f *fakeTimer) Reset(d time.Duration) bool { + f.fakeClock.lock.Lock() + defer f.fakeClock.lock.Unlock() + + active := !f.waiter.fired + + f.waiter.fired = false + f.waiter.targetTime = f.fakeClock.time.Add(d) + + var isWaiting bool + for i := range f.fakeClock.waiters { + w := f.fakeClock.waiters[i] + if w == &f.waiter { + isWaiting = true + break + } + } + if !isWaiting { + f.fakeClock.waiters = append(f.fakeClock.waiters, &f.waiter) + } + + return active +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 12bfc427..b8a05601 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -731,6 +731,8 @@ k8s.io/test-infra/prow/logrusutil k8s.io/test-infra/prow/version # k8s.io/utils v0.0.0-20200122174043-1e243dd1a584 ## explicit; go 1.12 +k8s.io/utils/clock +k8s.io/utils/clock/testing k8s.io/utils/inotify k8s.io/utils/integer # sigs.k8s.io/boskos v0.0.0-20200515170311-7d36bde8cdf6