-
Notifications
You must be signed in to change notification settings - Fork 38.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Federated ingress unit test fix #34325
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ limitations under the License. | |
package watch | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
"k8s.io/kubernetes/pkg/runtime" | ||
|
@@ -44,6 +45,8 @@ const ( | |
Modified EventType = "MODIFIED" | ||
Deleted EventType = "DELETED" | ||
Error EventType = "ERROR" | ||
|
||
DefaultChanSize int32 = 100 | ||
) | ||
|
||
// Event represents a single event to a watched resource. | ||
|
@@ -91,7 +94,7 @@ func NewFake() *FakeWatcher { | |
} | ||
} | ||
|
||
func NewFakeWithChanSize(size int) *FakeWatcher { | ||
func NewFakeWithChanSize(size int, blocking bool) *FakeWatcher { | ||
return &FakeWatcher{ | ||
result: make(chan Event, size), | ||
} | ||
|
@@ -150,3 +153,117 @@ func (f *FakeWatcher) Error(errValue runtime.Object) { | |
func (f *FakeWatcher) Action(action EventType, obj runtime.Object) { | ||
f.result <- Event{action, obj} | ||
} | ||
|
||
// RaceFreeFakeWatcher lets you test anything that consumes a watch.Interface; threadsafe. | ||
type RaceFreeFakeWatcher struct { | ||
result chan Event | ||
Stopped bool | ||
sync.Mutex | ||
} | ||
|
||
func NewRaceFreeFake() *RaceFreeFakeWatcher { | ||
return &RaceFreeFakeWatcher{ | ||
result: make(chan Event, DefaultChanSize), | ||
} | ||
} | ||
|
||
// Stop implements Interface.Stop(). | ||
func (f *RaceFreeFakeWatcher) Stop() { | ||
f.Lock() | ||
defer f.Unlock() | ||
if !f.Stopped { | ||
glog.V(4).Infof("Stopping fake watcher.") | ||
close(f.result) | ||
f.Stopped = true | ||
} | ||
} | ||
|
||
func (f *RaceFreeFakeWatcher) IsStopped() bool { | ||
f.Lock() | ||
defer f.Unlock() | ||
return f.Stopped | ||
} | ||
|
||
// Reset prepares the watcher to be reused. | ||
func (f *RaceFreeFakeWatcher) Reset() { | ||
f.Lock() | ||
defer f.Unlock() | ||
f.Stopped = false | ||
f.result = make(chan Event, DefaultChanSize) | ||
} | ||
|
||
func (f *RaceFreeFakeWatcher) ResultChan() <-chan Event { | ||
f.Lock() | ||
defer f.Unlock() | ||
return f.result | ||
} | ||
|
||
// Add sends an add event. | ||
func (f *RaceFreeFakeWatcher) Add(obj runtime.Object) { | ||
f.Lock() | ||
defer f.Unlock() | ||
if !f.Stopped { | ||
select { | ||
case f.result <- Event{Added, obj}: | ||
return | ||
default: | ||
panic(fmt.Errorf("channel full")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this. Why not just:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same for Modify and Delete, Error and Action. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because f.resut <- may block if the buffer is full and wait until the test fail due to timeout. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't agree with that. If you have running only producer and not consumer in your test, then the test is wrong, not the framework. |
||
} | ||
} | ||
} | ||
|
||
// Modify sends a modify event. | ||
func (f *RaceFreeFakeWatcher) Modify(obj runtime.Object) { | ||
f.Lock() | ||
defer f.Unlock() | ||
if !f.Stopped { | ||
select { | ||
case f.result <- Event{Modified, obj}: | ||
return | ||
default: | ||
panic(fmt.Errorf("channel full")) | ||
} | ||
} | ||
} | ||
|
||
// Delete sends a delete event. | ||
func (f *RaceFreeFakeWatcher) Delete(lastValue runtime.Object) { | ||
f.Lock() | ||
defer f.Unlock() | ||
if !f.Stopped { | ||
select { | ||
case f.result <- Event{Deleted, lastValue}: | ||
return | ||
default: | ||
panic(fmt.Errorf("channel full")) | ||
} | ||
} | ||
} | ||
|
||
// Error sends an Error event. | ||
func (f *RaceFreeFakeWatcher) Error(errValue runtime.Object) { | ||
f.Lock() | ||
defer f.Unlock() | ||
if !f.Stopped { | ||
select { | ||
case f.result <- Event{Error, errValue}: | ||
return | ||
default: | ||
panic(fmt.Errorf("channel full")) | ||
} | ||
} | ||
} | ||
|
||
// Action sends an event of the requested type, for table-based testing. | ||
func (f *RaceFreeFakeWatcher) Action(action EventType, obj runtime.Object) { | ||
f.Lock() | ||
defer f.Unlock() | ||
if !f.Stopped { | ||
select { | ||
case f.result <- Event{action, obj}: | ||
return | ||
default: | ||
panic(fmt.Errorf("channel full")) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't you also lock here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can potentially race with Reset().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.