-
Notifications
You must be signed in to change notification settings - Fork 99
Bareminimum workqueue test #263
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
Conversation
|
/ok to test |
| // Create a context with timeout for processing. | ||
| // use DefaultTypedControllerRateLimiter Base delay: 5ms | ||
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) | ||
| defer cancel() | ||
|
|
||
| // Test EnqueueRaw | ||
| t.Run("EnqueueRaw", func(t *testing.T) { | ||
| var called int32 | ||
| callback := func(ctx context.Context, obj any) error { | ||
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| wq.EnqueueRaw("AnyObject", callback) | ||
| wq.processNextWorkItem(ctx) | ||
|
|
||
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("EnqueueRaw callback was not invoked") | ||
| } | ||
| }) | ||
| // Test Enqueue with valid and invalid runtime.Object and nill callback | ||
| // TODO: Implement a proper claim spec that needs to be processed | ||
| t.Run("EnqueueValid", func(t *testing.T) { | ||
| var called int32 | ||
| callback := func(ctx context.Context, obj any) error { | ||
| _, ok := obj.(runtime.Object) | ||
| if !ok { | ||
| t.Errorf("Expected runtime.Object, got %T", obj) | ||
| } | ||
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| validObj := &runtime.Unknown{} | ||
| wq.Enqueue(validObj, callback) | ||
| wq.processNextWorkItem(ctx) | ||
|
|
||
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("Enqueue callback was not invoked") | ||
| } | ||
| }) | ||
|
|
||
| t.Run("EnqueueInvalid", func(t *testing.T) { | ||
| callback := func(ctx context.Context, obj any) error { return nil } | ||
| wq.Enqueue("NotRuntimeObject", callback) | ||
| }) | ||
|
|
||
| t.Run("NilCallback", func(t *testing.T) { | ||
| validObj := &runtime.Unknown{} | ||
| wq.Enqueue(validObj, nil) | ||
| wq.processNextWorkItem(ctx) | ||
| }) |
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.
| // Create a context with timeout for processing. | |
| // use DefaultTypedControllerRateLimiter Base delay: 5ms | |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) | |
| defer cancel() | |
| // Test EnqueueRaw | |
| t.Run("EnqueueRaw", func(t *testing.T) { | |
| var called int32 | |
| callback := func(ctx context.Context, obj any) error { | |
| atomic.StoreInt32(&called, 1) | |
| return nil | |
| } | |
| wq.EnqueueRaw("AnyObject", callback) | |
| wq.processNextWorkItem(ctx) | |
| if atomic.LoadInt32(&called) != 1 { | |
| t.Error("EnqueueRaw callback was not invoked") | |
| } | |
| }) | |
| // Test Enqueue with valid and invalid runtime.Object and nill callback | |
| // TODO: Implement a proper claim spec that needs to be processed | |
| t.Run("EnqueueValid", func(t *testing.T) { | |
| var called int32 | |
| callback := func(ctx context.Context, obj any) error { | |
| _, ok := obj.(runtime.Object) | |
| if !ok { | |
| t.Errorf("Expected runtime.Object, got %T", obj) | |
| } | |
| atomic.StoreInt32(&called, 1) | |
| return nil | |
| } | |
| validObj := &runtime.Unknown{} | |
| wq.Enqueue(validObj, callback) | |
| wq.processNextWorkItem(ctx) | |
| if atomic.LoadInt32(&called) != 1 { | |
| t.Error("Enqueue callback was not invoked") | |
| } | |
| }) | |
| t.Run("EnqueueInvalid", func(t *testing.T) { | |
| callback := func(ctx context.Context, obj any) error { return nil } | |
| wq.Enqueue("NotRuntimeObject", callback) | |
| }) | |
| t.Run("NilCallback", func(t *testing.T) { | |
| validObj := &runtime.Unknown{} | |
| wq.Enqueue(validObj, nil) | |
| wq.processNextWorkItem(ctx) | |
| }) | |
| ctx := context.Background() | |
| tests := []struct { | |
| name string | |
| obj any | |
| callback func(context.Context, any) error | |
| called *int32 | |
| }{ | |
| { | |
| name: "EnqueueRaw", | |
| obj: "AnyObject", | |
| callback: func(ctx context.Context, obj any) error { | |
| atomic.StoreInt32(&called, 1) | |
| return nil | |
| }, | |
| called: new(int32), | |
| }, | |
| { | |
| name: "EnqueueValid", | |
| obj: &runtime.Unknown{}, | |
| callback: func(ctx context.Context, obj any) error { | |
| if _, ok := obj.(runtime.Object); !ok { | |
| t.Errorf("Expected runtime.Object, got %T", obj) | |
| } | |
| atomic.StoreInt32(&called, 1) | |
| return nil | |
| }, | |
| called: new(int32), | |
| }, | |
| { | |
| name: "EnqueueInvalid", | |
| obj: "NotRuntimeObject", | |
| callback: func(ctx context.Context, obj any) error { return nil }, | |
| }, | |
| { | |
| name: "NilCallback", | |
| obj: &runtime.Unknown{}, | |
| }, | |
| } | |
| for _, tt := range tests { | |
| t.Run(tt.name, func(t *testing.T) { | |
| wq.Enqueue(tt.obj, tt.callback) | |
| wq.processNextWorkItem(ctx) | |
| if tt.called != nil && atomic.LoadInt32(tt.called) != 1 { | |
| t.Error("Callback was not invoked") | |
| } | |
| }) | |
| } |
This is a more compact and readable form factor.
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.
+1 on this
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.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("Enqueue callback was not invoked") | ||
| } |
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.
Could you comment on why it's required to use atomics in the context of the tests?
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.
I read that this is a standard go practice to use atomics to test callback functions
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.
Would be nice to have a bit deeper understanding here what type of challenge the usage of atomics really addresses in this particular context. I also don't understand that yet. We'll see.
I just had a quick web search on the topic and found the new and shiny https://go.dev/blog/synctest -- looks interesting.
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.
PR Overview
This pull request adds a preliminary unit test for the WorkQueue package to verify that items are enqueued and processed with a default rate limiter and provide appropriate error handling in cases such as invalid types or missing callbacks.
- Added tests for different enqueue scenarios including raw data, valid objects, invalid type, and nil callbacks.
- Validates that callback execution is triggered correctly under controlled conditions.
Reviewed Changes
| File | Description |
|---|---|
| pkg/workqueue/workqueue_test.go | Added tests for WorkQueue functionality covering various enqueuing scenarios |
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
d6dae83 to
7c8dde8
Compare
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.
PR Overview
This PR introduces a preliminary unit test for the workqueue package to validate that items are enqueued and processed correctly, including edge cases such as invalid objects and nil callbacks.
- Adds table-driven tests for multiple scenarios (valid, invalid, nil callback).
- Initializes the workqueue with a default rate limiter and verifies callback invocation where applicable.
Reviewed Changes
| File | Description |
|---|---|
| pkg/workqueue/workqueue_test.go | Adds preliminary unit tests for the pkg/workqueue module |
Copilot reviewed 1 out of 1 changed files in this pull request and generated no comments.
Comments suppressed due to low confidence (2)
pkg/workqueue/workqueue_test.go:38
- Consider increasing the timeout duration to reduce the risk of test flakiness in slower environments.
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
pkg/workqueue/workqueue_test.go:84
- [nitpick] Consider explicitly validating that no callback is invoked when a nil callback is provided to improve test robustness.
name: "NilCallback",
7c8dde8 to
60f3084
Compare
Signed-off-by: Swati Gupta <[email protected]>
60f3084 to
053866d
Compare
ArangoGutierrez
left a comment
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.
test list form factor
| // Create a WorkQueue using the default rate limiter. | ||
| defaultRateLimiter := DefaultControllerRateLimiter() | ||
| wq := New(defaultRateLimiter) | ||
|
|
||
| require.NotNil(t, wq) | ||
| require.NotNil(t, wq.queue) | ||
|
|
||
| // Create a context with timeout for processing. | ||
| // use DefaultTypedControllerRateLimiter Base delay: 5ms | ||
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) | ||
| defer cancel() | ||
|
|
||
| // Test EnqueueRaw | ||
| t.Run("EnqueueRaw", func(t *testing.T) { | ||
| var called int32 | ||
| callback := func(ctx context.Context, obj any) error { | ||
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| wq.EnqueueRaw("AnyObject", callback) | ||
| wq.processNextWorkItem(ctx) | ||
|
|
||
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("EnqueueRaw callback was not invoked") | ||
| } | ||
| }) | ||
| // Test Enqueue with valid and invalid runtime.Object and nil callback | ||
| // TODO: Implement a proper claim spec that needs to be processed | ||
| t.Run("EnqueueValid", func(t *testing.T) { | ||
| var called int32 | ||
| callback := func(ctx context.Context, obj any) error { | ||
| _, ok := obj.(runtime.Object) | ||
| if !ok { | ||
| t.Errorf("Expected runtime.Object, got %T", obj) | ||
| } | ||
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| validObj := &runtime.Unknown{} | ||
| wq.Enqueue(validObj, callback) | ||
| wq.processNextWorkItem(ctx) | ||
|
|
||
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("Enqueue callback was not invoked") | ||
| } | ||
| }) | ||
|
|
||
| t.Run("EnqueueInvalid", func(t *testing.T) { | ||
| callback := func(ctx context.Context, obj any) error { return nil } | ||
| wq.Enqueue("NotRuntimeObject", callback) | ||
| }) | ||
|
|
||
| t.Run("NilCallback", func(t *testing.T) { | ||
| validObj := &runtime.Unknown{} | ||
| wq.Enqueue(validObj, nil) | ||
| wq.processNextWorkItem(ctx) | ||
| }) |
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.
| // Create a WorkQueue using the default rate limiter. | |
| defaultRateLimiter := DefaultControllerRateLimiter() | |
| wq := New(defaultRateLimiter) | |
| require.NotNil(t, wq) | |
| require.NotNil(t, wq.queue) | |
| // Create a context with timeout for processing. | |
| // use DefaultTypedControllerRateLimiter Base delay: 5ms | |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) | |
| defer cancel() | |
| // Test EnqueueRaw | |
| t.Run("EnqueueRaw", func(t *testing.T) { | |
| var called int32 | |
| callback := func(ctx context.Context, obj any) error { | |
| atomic.StoreInt32(&called, 1) | |
| return nil | |
| } | |
| wq.EnqueueRaw("AnyObject", callback) | |
| wq.processNextWorkItem(ctx) | |
| if atomic.LoadInt32(&called) != 1 { | |
| t.Error("EnqueueRaw callback was not invoked") | |
| } | |
| }) | |
| // Test Enqueue with valid and invalid runtime.Object and nil callback | |
| // TODO: Implement a proper claim spec that needs to be processed | |
| t.Run("EnqueueValid", func(t *testing.T) { | |
| var called int32 | |
| callback := func(ctx context.Context, obj any) error { | |
| _, ok := obj.(runtime.Object) | |
| if !ok { | |
| t.Errorf("Expected runtime.Object, got %T", obj) | |
| } | |
| atomic.StoreInt32(&called, 1) | |
| return nil | |
| } | |
| validObj := &runtime.Unknown{} | |
| wq.Enqueue(validObj, callback) | |
| wq.processNextWorkItem(ctx) | |
| if atomic.LoadInt32(&called) != 1 { | |
| t.Error("Enqueue callback was not invoked") | |
| } | |
| }) | |
| t.Run("EnqueueInvalid", func(t *testing.T) { | |
| callback := func(ctx context.Context, obj any) error { return nil } | |
| wq.Enqueue("NotRuntimeObject", callback) | |
| }) | |
| t.Run("NilCallback", func(t *testing.T) { | |
| validObj := &runtime.Unknown{} | |
| wq.Enqueue(validObj, nil) | |
| wq.processNextWorkItem(ctx) | |
| }) | |
| wq := New(DefaultControllerRateLimiter()) | |
| require.NotNil(t, wq) | |
| require.NotNil(t, wq.queue) | |
| ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) | |
| defer cancel() | |
| tests := []struct { | |
| name string | |
| obj any | |
| callback func(context.Context, any) error | |
| validate func(*testing.T, *int32) | |
| processNextWorkItem bool | |
| }{ | |
| { | |
| name: "EnqueueRaw", | |
| obj: "AnyObject", | |
| callback: func(ctx context.Context, obj any) error { | |
| atomic.StoreInt32(obj.(*int32), 1) | |
| return nil | |
| }, | |
| validate: func(t *testing.T, called *int32) { | |
| if atomic.LoadInt32(called) != 1 { | |
| t.Error("EnqueueRaw callback was not invoked") | |
| } | |
| }, | |
| processNextWorkItem: true, | |
| }, | |
| { | |
| name: "EnqueueValid", | |
| obj: &runtime.Unknown{}, | |
| callback: func(ctx context.Context, obj any) error { | |
| if _, ok := obj.(runtime.Object); !ok { | |
| t.Errorf("Expected runtime.Object, got %T", obj) | |
| } | |
| atomic.StoreInt32(new(int32), 1) | |
| return nil | |
| }, | |
| validate: func(t *testing.T, called *int32) { | |
| // No validation needed for runtime.Object type | |
| }, | |
| processNextWorkItem: true, | |
| }, | |
| { | |
| name: "EnqueueInvalid", | |
| obj: "NotRuntimeObject", | |
| callback: func(ctx context.Context, obj any) error { return nil }, | |
| validate: nil, | |
| processNextWorkItem: false, | |
| }, | |
| { | |
| name: "NilCallback", | |
| obj: &runtime.Unknown{}, | |
| callback: nil, | |
| validate: nil, | |
| processNextWorkItem: true, | |
| }, | |
| } | |
| for _, tt := range tests { | |
| t.Run(tt.name, func(t *testing.T) { | |
| var called int32 | |
| if tt.name == "EnqueueRaw" { | |
| wq.EnqueueRaw(&called, tt.callback) | |
| } else { | |
| wq.Enqueue(tt.obj, tt.callback) | |
| } | |
| if tt.processNextWorkItem { | |
| wq.processNextWorkItem(ctx) | |
| if tt.validate != nil { | |
| tt.validate(t, &called) | |
| } | |
| } | |
| }) | |
| } |
I have tested this suggestion it works
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.
IMO, it may be a bit of an overkill to add the extra validate func and bool just to make the test compact. If its not strongly desired, I would like to stick to the current format.
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.
@ArangoGutierrez how do we move forward with this? :)
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.
@ArangoGutierrez how do we move forward with this? :)
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.
I think a not-so-bad answer at this point is -- let's just move.
| defer cancel() | ||
|
|
||
| // Test EnqueueRaw | ||
| t.Run("EnqueueRaw", func(t *testing.T) { |
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.
I think the behaviour of EnqueueRaw should be a different test suite. We want to test similar test cases as for Enqueue.
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("EnqueueRaw callback was not invoked") | ||
| } |
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.
Is this sufficient? Should we not also check that the callback was called with the expected values / object?
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.
I would have expected a reply to this good question :). What's sufficient or not for now (in this patch) is of course up to our own discretion.
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.
My thought was to keep the test aligned with what workqueue.go does:
- add the right item (valid object and callback func) and reject the incomplete
- process it
- handle retry
Looking at the workqueue.go, we only invoke the callback. I think the computeDomain controller code would be a better place to actually test the callbacks. Because most action happens there as I recall.
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| wq.EnqueueRaw("AnyObject", callback) |
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.
@elezar sure i can add more individuals tests similar to Enqueue. This will not even go to the callback check as it will throw error on invalid obj.
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.
Copilot reviewed 1 out of 1 changed files in this pull request and generated no comments.
Comments suppressed due to low confidence (2)
pkg/workqueue/workqueue_test.go:79
- The 'EnqueueInvalid' test does not assert the expected outcome for handling an invalid runtime.Object. Consider adding assertions to verify that the proper error or warning is produced.
wq.Enqueue("NotRuntimeObject", callback)
pkg/workqueue/workqueue_test.go:84
- The 'NilCallback' test enqueues a work item with a nil callback without verifying the resulting behavior. It would be beneficial to add assertions to confirm that the expected error or log message is generated.
wq.Enqueue(validObj, nil)
jgehrcke
left a comment
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.
This has been sitting here for I think too long of a long time. I'd like to just see some movement here and want to merge this patch.
Maybe it's nice to add a few more thoughts:
-
I left some feedback that I hope we can at least partially take into account in the future. I trust that the current version of the patch won't break anything.
-
We can and will iterate on the code added here, after merge.
-
In the future, I hope that we can help each other out a little better: as a patch author, one should have (and communicate) a good and strong reason for building a patch, and then stand behind it. As a reviewer, one should make obvious which changes at a minimum one wants to see before approving a patch.
There are probably many more thoughts that apply here. We'll figure it all out.
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) | ||
| defer cancel() | ||
|
|
||
| // Test EnqueueRaw |
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.
To outsiders (like myself!), this comment does not explain what this test is about. This comment would have been the perfect opportunity to tell me. :)
So, for the future this means: a good code comment tells the part of the story that the code by itself does not tell. It shortens the time it takes to understand what code is doing.
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.
Noted.
|
|
||
| func TestEnqueue(t *testing.T) { | ||
| // Create a WorkQueue using the default rate limiter. | ||
| defaultRateLimiter := DefaultControllerRateLimiter() |
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.
Which other rate limiter could we have chosen here? Why do we pick the default rate limiter? What's the advantage or disadvantage?
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.
We set our workqueue processing to default. We could do a custom one but i dont think its needed
See: https://github.com/NVIDIA/k8s-dra-driver-gpu/blob/main/pkg/workqueue/workqueue.go#L38
Def: https://github.com/kubernetes/client-go/blob/master/util/workqueue/default_rate_limiters.go#L50
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("EnqueueRaw callback was not invoked") | ||
| } |
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.
I would have expected a reply to this good question :). What's sufficient or not for now (in this patch) is of course up to our own discretion.
| t.Error("EnqueueRaw callback was not invoked") | ||
| } | ||
| }) | ||
| // Test Enqueue with valid and invalid runtime.Object and nil callback |
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.
You probably notice yourself: this is another code comment that doesn't really say more than code does already.
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("Enqueue callback was not invoked") | ||
| } |
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.
Would be nice to have a bit deeper understanding here what type of challenge the usage of atomics really addresses in this particular context. I also don't understand that yet. We'll see.
I just had a quick web search on the topic and found the new and shiny https://go.dev/blog/synctest -- looks interesting.
| // Create a WorkQueue using the default rate limiter. | ||
| defaultRateLimiter := DefaultControllerRateLimiter() | ||
| wq := New(defaultRateLimiter) | ||
|
|
||
| require.NotNil(t, wq) | ||
| require.NotNil(t, wq.queue) | ||
|
|
||
| // Create a context with timeout for processing. | ||
| // use DefaultTypedControllerRateLimiter Base delay: 5ms | ||
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) | ||
| defer cancel() | ||
|
|
||
| // Test EnqueueRaw | ||
| t.Run("EnqueueRaw", func(t *testing.T) { | ||
| var called int32 | ||
| callback := func(ctx context.Context, obj any) error { | ||
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| wq.EnqueueRaw("AnyObject", callback) | ||
| wq.processNextWorkItem(ctx) | ||
|
|
||
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("EnqueueRaw callback was not invoked") | ||
| } | ||
| }) | ||
| // Test Enqueue with valid and invalid runtime.Object and nil callback | ||
| // TODO: Implement a proper claim spec that needs to be processed | ||
| t.Run("EnqueueValid", func(t *testing.T) { | ||
| var called int32 | ||
| callback := func(ctx context.Context, obj any) error { | ||
| _, ok := obj.(runtime.Object) | ||
| if !ok { | ||
| t.Errorf("Expected runtime.Object, got %T", obj) | ||
| } | ||
| atomic.StoreInt32(&called, 1) | ||
| return nil | ||
| } | ||
| validObj := &runtime.Unknown{} | ||
| wq.Enqueue(validObj, callback) | ||
| wq.processNextWorkItem(ctx) | ||
|
|
||
| if atomic.LoadInt32(&called) != 1 { | ||
| t.Error("Enqueue callback was not invoked") | ||
| } | ||
| }) | ||
|
|
||
| t.Run("EnqueueInvalid", func(t *testing.T) { | ||
| callback := func(ctx context.Context, obj any) error { return nil } | ||
| wq.Enqueue("NotRuntimeObject", callback) | ||
| }) | ||
|
|
||
| t.Run("NilCallback", func(t *testing.T) { | ||
| validObj := &runtime.Unknown{} | ||
| wq.Enqueue(validObj, nil) | ||
| wq.processNextWorkItem(ctx) | ||
| }) |
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.
I think a not-so-bad answer at this point is -- let's just move.
probably good point, but to be honest I don't understand "test list form factor", and we can probably move on, and do this post-merge if it provides value.
Appreciate your feedback. Agree that my communication and our collaboration could be better. I prefer to give just enough context without overwhelming details. In future, i will try to provide a better description of the problem and the reasoning, especially in the comments. To quote Jeff Atwood, "Code tells you how; comments tell you why." |
|
I will iterate on it later and also incorporate the feedback for other tests. Merging it for now. |
This adds a preliminary unit test for
pkg/workqueuewhich initialize the WorkQueue with a default Rate-limiter for handling event failures and retries asynchronously. The tests make sure the items added are valid and processed.Heres the Test results