-
Notifications
You must be signed in to change notification settings - Fork 18
🐛 Use local store for agent client #166
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
base: main
Are you sure you want to change the base?
🐛 Use local store for agent client #166
Conversation
Signed-off-by: Jian Qiu <[email protected]>
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: qiujian16 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
WalkthroughDecouple AgentInformerWatcherStore from SharedIndexInformer by using an internal cache.Store, update HandleReceivedResource to preserve metadata and use store-based updates, switch ManifestWork flows from ResourceVersion parsing to Generation, and update tests/integration to seed and operate on the watcher store directly. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
/hold |
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.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/integration/cloudevents/agent/agent.go (1)
31-37: Remove the unreturned and unused informer.The informer created at lines 36-37 is never attached to
watcherStore(which doesn't have aSetInformer()method likeSourceInformerWatcherStoredoes). TheAgentInformerWatcherStoremaintains its own independent cache and handles resources viaHandleReceivedResource(). This informer is dead code from the refactoring and should be deleted to avoid unnecessary resource consumption.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
pkg/cloudevents/clients/addon/client_test.go(2 hunks)pkg/cloudevents/clients/cluster/client_test.go(2 hunks)pkg/cloudevents/clients/csr/client_test.go(1 hunks)pkg/cloudevents/clients/csr/clientholder.go(0 hunks)pkg/cloudevents/clients/store/informer.go(2 hunks)pkg/cloudevents/clients/store/informer_test.go(3 hunks)pkg/cloudevents/clients/store/lister_test.go(2 hunks)pkg/cloudevents/clients/work/agent/client/manifestwork_test.go(6 hunks)pkg/cloudevents/clients/work/store/informer.go(1 hunks)pkg/cloudevents/clients/work/store/informer_test.go(1 hunks)test/integration/cloudevents/agent/agent.go(3 hunks)test/integration/cloudevents/cloudevents_resync_test.go(3 hunks)test/integration/cloudevents/manifestworkclients_reync_test.go(2 hunks)
💤 Files with no reviewable changes (1)
- pkg/cloudevents/clients/csr/clientholder.go
🧰 Additional context used
🧬 Code graph analysis (7)
pkg/cloudevents/clients/work/store/informer.go (2)
pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)
test/integration/cloudevents/agent/agent.go (2)
pkg/cloudevents/clients/store/informer.go (1)
AgentInformerWatcherStore(25-28)pkg/cloudevents/clients/work/store/informer.go (1)
AgentInformerWatcherStore(92-96)
test/integration/cloudevents/manifestworkclients_reync_test.go (4)
test/integration/cloudevents/agent/agent.go (1)
StartWorkAgent(16-40)pkg/cloudevents/clients/utils/utils.go (1)
UID(222-225)pkg/cloudevents/clients/common/common.go (3)
ManifestWorkGR(37-37)CloudEventsOriginalSourceLabelKey(28-28)CloudEventsDataTypeAnnotationKey(14-14)test/integration/cloudevents/util/work.go (1)
NewManifestWorkWithStatus(202-206)
pkg/cloudevents/clients/store/informer.go (4)
pkg/cloudevents/generic/interface.go (1)
ResourceObject(20-38)pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)pkg/cloudevents/clients/work/store/informer.go (2)
NewAgentInformerWatcherStore(130-140)AgentInformerWatcherStore(92-96)
pkg/cloudevents/clients/store/lister_test.go (2)
pkg/cloudevents/clients/store/informer.go (1)
NewAgentInformerWatcherStore(30-37)pkg/cloudevents/clients/common/common.go (1)
CloudEventsOriginalSourceLabelKey(28-28)
pkg/cloudevents/clients/store/informer_test.go (1)
pkg/cloudevents/clients/store/informer.go (1)
NewAgentInformerWatcherStore(30-37)
test/integration/cloudevents/cloudevents_resync_test.go (1)
test/integration/cloudevents/agent/agent.go (1)
StartWorkAgent(16-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: unit
- GitHub Check: integration
- GitHub Check: verify
🔇 Additional comments (17)
pkg/cloudevents/clients/work/store/informer_test.go (1)
514-516: LGTM - Clean simplification of test setup.The change to seed data directly into
store.Storeeliminates the need for fake clients and informer factories, making the test more straightforward and aligned with the PR's goal of decoupling from informers.pkg/cloudevents/clients/work/store/informer.go (1)
130-140: LGTM - Good architectural improvement.The
AgentInformerWatcherStorenow initializes with its owncache.Store, eliminating the dependency on external informer setup. This makes the store self-contained and simplifies its lifecycle management.pkg/cloudevents/clients/csr/client_test.go (1)
77-81: LGTM - Consistent test refactoring.Switching to
watcherStore.Store.Addfor test data seeding aligns with the broader refactoring pattern and removes dependency on informer store initialization.pkg/cloudevents/clients/addon/client_test.go (1)
81-83: LGTM - Simplified test data seeding.Direct store population is cleaner and removes unnecessary informer dependencies.
pkg/cloudevents/clients/cluster/client_test.go (2)
74-77: LGTM - Test data seeding simplified.Consistent with the PR's goal of using local store instead of informer-backed stores.
129-131: LGTM - Consistent pattern applied.The same refactoring pattern is correctly applied in the patch test.
pkg/cloudevents/clients/store/lister_test.go (2)
16-27: LGTM - Clean test simplification.Direct store population removes unnecessary fake clients and informers while maintaining test coverage.
42-53: LGTM - Consistent refactoring.The same pattern is correctly applied for the source lister test.
pkg/cloudevents/clients/store/informer_test.go (3)
19-24: LGTM - Consistent test data setup.Direct store population simplifies test initialization and removes informer dependencies.
64-80: LGTM - Pattern consistently applied.All test cases in
TestListcorrectly use the direct store approach.
135-140: LGTM - Watch test properly updated.The watch test correctly seeds data via direct store access, maintaining test functionality.
test/integration/cloudevents/manifestworkclients_reync_test.go (2)
41-42: LGTM - Integration test adapted correctly.The change to return
watchStorefromStartWorkAgentaligns with the broader refactoring and enables direct store manipulation in integration tests.
55-64: LGTM - Test data seeding updated consistently.Both manifest works are correctly seeded using the new direct store approach, maintaining test functionality.
pkg/cloudevents/clients/work/agent/client/manifestwork_test.go (1)
167-167: LGTM! Direct store population simplifies unit tests.The change from informer-based population to direct
watcherStore.Store.Add()is appropriate for unit tests, making them more isolated and easier to maintain.pkg/cloudevents/clients/store/informer.go (2)
30-37: Store initialization looks correct.The store now initializes with its own
cache.Storeinstance, eliminating the dependency on external informer setup. This is a cleaner architecture.
129-130: No action needed onHasInitiated()implementation.The review comment conflates two distinct store implementations.
AgentInformerWatcherStorehas noSetInformer()method and no initialization tracking requirement—it manages resources directly throughAdd/Update/Deleteand is ready immediately. This differs fromSourceInformerWatcherStore, which requires external setup and conditionally checksInitiated && informer.HasSynced().Returning
trueunconditionally is correct and consistent withSimpleStore[T], which follows the same pattern. TheWaitForStoreInit()function correctly handles multiple implementations with different initialization models. No safety concern exists.test/integration/cloudevents/cloudevents_resync_test.go (1)
125-136: Good improvement: patch-based status updates.Using
CreateMergePatchandagentWorkClient.Patchis more realistic than directly manipulating the in-memory store. This better reflects production behavior where status updates go through the API.
Signed-off-by: Jian Qiu <[email protected]>
9240935 to
555357d
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.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/cloudevents/clients/work/store/informer.go (1)
192-205: Use consistent method for setting deletion timestamp.Line 204 uses direct field assignment (
updatedWork.DeletionTimestamp = work.DeletionTimestamp), while line 184 in the Modified case usesSetDeletionTimestamp(). For consistency and proper pointer handling, use the setter method.Apply this diff:
// we should only update the deletionTimestamp or the local work updatedWork := lastWork.DeepCopy() - updatedWork.DeletionTimestamp = work.DeletionTimestamp + updatedWork.SetDeletionTimestamp(work.DeletionTimestamp) return s.Update(updatedWork)
🧹 Nitpick comments (1)
pkg/cloudevents/clients/work/store/informer.go (1)
182-185: Clarify misleading comment.The comment states "prevent the work from being updated if it is deleting", but the code doesn't prevent the update—it proceeds to line 191. The logic actually preserves the deletion timestamp while allowing spec updates.
Consider revising the comment to:
- // prevent the work from being updated if it is deleting + // preserve the deletion timestamp if the work is already deleting
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (15)
vendor/modules.txtis excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/addon/interface.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1alpha1/addondeploymentconfig.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1alpha1/addontemplate.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1alpha1/clustermanagementaddon.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1alpha1/interface.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1alpha1/managedclusteraddon.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/factory.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/generic.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/informers/externalversions/internalinterfaces/factory_interfaces.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/listers/addon/v1alpha1/addondeploymentconfig.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/listers/addon/v1alpha1/addontemplate.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/listers/addon/v1alpha1/clustermanagementaddon.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/listers/addon/v1alpha1/expansion_generated.gois excluded by!vendor/**vendor/open-cluster-management.io/api/client/addon/listers/addon/v1alpha1/managedclusteraddon.gois excluded by!vendor/**
📒 Files selected for processing (3)
pkg/cloudevents/clients/work/source/codec/manifestbundle.go(2 hunks)pkg/cloudevents/clients/work/store/informer.go(2 hunks)pkg/cloudevents/generic/clients/baseclient.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- pkg/cloudevents/clients/work/source/codec/manifestbundle.go
- pkg/cloudevents/generic/clients/baseclient.go
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/cloudevents/clients/work/store/informer.go (3)
pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)vendor/open-cluster-management.io/api/work/v1/types.go (1)
ManifestWork(18-28)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)
🔇 Additional comments (4)
pkg/cloudevents/clients/work/store/informer.go (4)
96-124: LGTM!The versioner implementation correctly tracks per-resource versions with proper locking. This is necessary now that the store is no longer backed by an informer that would provide resource versions automatically.
140-165: LGTM!The versioning logic correctly assigns incrementing resource versions to each Add/Update operation and cleans up on Delete. This compensates for the absence of informer-managed versions.
204-204: Add nil-check for DeletionTimestamp in Deleted action.The
work.DeletionTimestampfield might benilin the Deleted action. Setting a nil deletion timestamp could lead to unexpected behavior.Verify whether the source guarantees a non-nil
DeletionTimestampin the Deleted action, or add a defensive check:if work.DeletionTimestamp == nil { return fmt.Errorf("received Deleted action for %s/%s with nil DeletionTimestamp", work.Namespace, work.Name) }
128-138: The review comment is based on an incorrect assumption.The
HasInitiated()method is defined in the parent struct (pkg/cloudevents/clients/store/informer.go, lines 129-131) and is hardcoded toreturn true. It does not check theInitiatedfield. Therefore, whetherInitiateddefaults tofalseis irrelevant to the function's behavior, and no action is needed regarding this concern.Likely an incorrect or invalid review 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.
Actionable comments posted: 2
🧹 Nitpick comments (2)
pkg/cloudevents/generic/clients/baseclient.go (2)
82-82: Fix typo in comment.The comment contains "try agin" which should be "try again".
Apply this diff:
- // failed to reconnect, try agin + // failed to reconnect, try again
146-146: Consider checking log level before evaluating evt.String().The direct call to
evt.String()is now evaluated eagerly, even when V(5) logging is disabled. Since CloudEvent serialization can be expensive for large events and V(5) is typically disabled in production, this may introduce unnecessary overhead in high-throughput scenarios.Consider checking if the log level is enabled before evaluating:
For line 146:
- logger.V(5).Info("Sending event", "event", evt.String()) + if klog.V(5).Enabled() { + logger.V(5).Info("Sending event", "event", evt.String()) + }For line 177:
- logger.V(5).Info("Received event", "event", evt.String()) + if klog.V(5).Enabled() { + logger.V(5).Info("Received event", "event", evt.String()) + }Alternatively, if the previous closure-based approach was working well, consider reverting to that pattern to ensure lazy evaluation.
Also applies to: 177-177
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
pkg/cloudevents/clients/store/informer.go(3 hunks)pkg/cloudevents/clients/work/source/client/manifestwork.go(4 hunks)pkg/cloudevents/clients/work/source/codec/manifestbundle_test.go(3 hunks)pkg/cloudevents/clients/work/store/base.go(1 hunks)pkg/cloudevents/clients/work/store/informer.go(2 hunks)pkg/cloudevents/generic/clients/agentclient.go(1 hunks)pkg/cloudevents/generic/clients/agentclient_test.go(1 hunks)pkg/cloudevents/generic/clients/baseclient.go(2 hunks)test/integration-test.mk(1 hunks)test/integration/cloudevents/cloudevents_resync_test.go(3 hunks)test/integration/cloudevents/manifestworkclients_reync_test.go(1 hunks)test/integration/cloudevents/util/work.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- test/integration/cloudevents/manifestworkclients_reync_test.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-16T02:22:20.929Z
Learnt from: skeeey
Repo: open-cluster-management-io/sdk-go PR: 144
File: pkg/cloudevents/generic/options/grpc/protocol/protocol.go:200-213
Timestamp: 2025-09-16T02:22:20.929Z
Learning: In the GRPC CloudEvents protocol implementation, when startEventsReceiver encounters a stream error, it sends the error to reconnectErrorChan. The consumer of this channel handles the error by calling Close() on the protocol, which triggers close(p.closeChan), causing OpenInbound to unblock and call cancel() to properly terminate both the events receiver and heartbeat watcher goroutines.
Applied to files:
pkg/cloudevents/generic/clients/baseclient.go
🧬 Code graph analysis (6)
pkg/cloudevents/generic/clients/agentclient.go (1)
pkg/cloudevents/generic/types/types.go (1)
Modified(94-94)
pkg/cloudevents/clients/store/informer.go (4)
pkg/cloudevents/generic/interface.go (1)
ResourceObject(20-38)pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)pkg/cloudevents/clients/work/store/informer.go (2)
NewAgentInformerWatcherStore(128-138)AgentInformerWatcherStore(90-94)
pkg/cloudevents/clients/work/source/client/manifestwork.go (2)
vendor/open-cluster-management.io/api/work/v1/types.go (1)
ManifestWork(18-28)pkg/cloudevents/clients/common/common.go (1)
CloudEventsResourceVersionAnnotationKey(20-20)
test/integration/cloudevents/cloudevents_resync_test.go (2)
test/integration/cloudevents/agent/agent.go (1)
StartWorkAgent(16-40)pkg/cloudevents/clients/utils/utils.go (1)
Patch(44-82)
pkg/cloudevents/generic/clients/agentclient_test.go (1)
pkg/cloudevents/clients/utils/utils.go (1)
UID(222-225)
pkg/cloudevents/clients/work/store/informer.go (2)
pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: verify
- GitHub Check: integration
- GitHub Check: unit
🔇 Additional comments (20)
pkg/cloudevents/clients/work/source/client/manifestwork.go (3)
7-7: LGTM!The
strconvimport is correctly added to support parsing the generation value from the annotation string.
92-97: Proper error handling for multi-value return.The code correctly handles the new signature of
getWorkResourceVersion, propagates errors, and sets bothGenerationandResourceVersionfields. However, there are critical bugs ingetWorkResourceVersionitself (see comments on lines 318-341).
283-288: Consistent with Create function changes.The implementation mirrors the Create function's handling of the new
getWorkResourceVersionsignature. Error propagation and field assignment are correct, but the same bugs ingetWorkResourceVersionaffect this code path (see comments on lines 318-341).pkg/cloudevents/generic/clients/agentclient_test.go (1)
518-519: Original review comment is incorrect and should be disregarded.The agent client's
specAction()method implements Generation-based change detection: it compares incoming and stored resource generations at line 307-308 (if obj.GetGeneration() < lastObj.GetGeneration() { return evt, nil }). When the incoming event's generation is older than the stored resource's generation, it returns an empty action, which causes thereceive()function to exit early without calling handlers.The concern about inverted ResourceVersion ordering is unfounded—ResourceVersion is not used for change detection. The test correctly validates that older-generation events are ignored, regardless of ResourceVersion values.
test/integration-test.mk (1)
34-34: LGTM!Adding verbose logging (
-v=5) to the cloudevents integration test improves debugging capabilities without affecting functionality.test/integration/cloudevents/util/work.go (1)
178-183: LGTM!Adding
Generation: 1aligns with the PR's shift from ResourceVersion to Generation-based semantics for change detection. This is consistent with Kubernetes conventions where Generation tracks spec changes.pkg/cloudevents/clients/work/source/codec/manifestbundle_test.go (3)
207-208: LGTM!Test expectations correctly updated to use
Generation: 13instead ofResourceVersion: "13", aligning with the PR's shift to Generation-based semantics.
228-234: LGTM!Test data correctly reflects Generation-based semantics with appropriate field types (int64 for Generation).
293-297: LGTM!Expected work object correctly uses
Generation: 13consistent with the updated codec implementation.pkg/cloudevents/clients/work/store/base.go (1)
119-122: LGTM!The replacement of ResourceVersion string parsing with direct Generation comparison simplifies the code and eliminates error handling for string-to-int conversion. This aligns with the PR's shift to Generation-based semantics.
pkg/cloudevents/clients/work/store/informer.go (2)
131-135: LGTM!Initializing
Storewithcache.NewStore(cache.MetaNamespaceKeyFunc)properly establishes a local cache instead of relying on an external informer, consistent with the PR's goal to decouple from SharedIndexInformer.
180-189: LGTM!The refactored logic efficiently creates
updatedWorkonce viaDeepCopy()and reuses it for both DeletionTimestamp preservation and Finalizers/Status restoration, improving code clarity and performance.test/integration/cloudevents/cloudevents_resync_test.go (3)
83-86: LGTM!The updated signature reflects the architectural shift:
StartWorkAgentnow returnswatchStoreinstead of an informer, aligning with the PR's goal to use local stores rather than informer-backed stores.
90-97: LGTM!Replacing informer-based
lister.List()withwatchStore.List()is consistent with the local store architecture and correctly accesseslist.Itemsfor the length check.
114-128: LGTM!The migration to patch-based updates via
agentWorkClient.Patchis more realistic and robust:
- Uses standard JSON merge patch construction
- Goes through the actual client interface
- Follows Kubernetes patching conventions
This is a better testing approach than directly manipulating an in-memory store.
pkg/cloudevents/clients/store/informer.go (4)
19-20: LGTM!Comment accurately reflects the architectural change to using a local store instead of an informer-backed store.
30-34: LGTM!Proper initialization with a concrete
cache.Storeenables the local store architecture, eliminating the dependency on external informers.
62-77: LGTM!The accessor-based approach for extracting namespace/name is more generic and correctly preserves the DeletionTimestamp when the resource is being deleted.
124-124: Review comment is incorrect and conflates different store types.The review incorrectly attributes behavior from
SourceInformerWatcherStore(work/store package) toAgentInformerWatcherStore(clients/store package). These are distinct types with different semantics:
SourceInformerWatcherStore(line 67, work/store): Returnss.Initiated && s.informer.HasSynced()—must wait for remote cache sync. The tests shown (informer_test.go:485–498) verify this behavior.AgentInformerWatcherStore[T](line 123, clients/store): Returnstrueunconditionally—uses local in-memory store, immediately usable upon creation.The unconditional
truereturn at line 124 is correct; agent stores don't depend on cache synchronization. Resync logic in options/generic.go (lines 164, 236) still executes as intended whenWaitForStoreInitimmediately succeeds.Likely an incorrect or invalid review comment.
pkg/cloudevents/generic/clients/agentclient.go (1)
301-311: Verify the semantic change in generation comparison logic is intentional and document the impact.The review concern is valid. The code shows a semantic behavior change where equal generations now return
types.Modifiedinstead of being skipped:if obj.GetGeneration() < lastObj.GetGeneration() { return evt, nil // skip if incoming is older } return types.Modified, nil // process for equal OR newer generationsKey findings:
- Behavior change confirmed: Equal generations now trigger modification handling (fall through to
types.Modified)- No downstream safeguards: ResourceHandlers receive the action but have no built-in deduplication logic
- Contradiction with comment: The "message broker guarantees order of messages" comment suggests equal generations should be skipped, not reprocessed
- Missing test coverage: No explicit test found for equal generation scenario in agentclient_test.go
This violates the Kubernetes pattern where
generation == previousGenerationmeans "no spec change, no work needed." Handlers relying on idempotency assumptions could duplicate processing if the same generation arrives twice.Confirm this change was intentional (bug fix vs. regression), document why equal generations should trigger
Modified, and ensure handlers account for repeated events of the same generation.
a6ea87b to
e7ee2c4
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.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/cloudevents/generic/clients/agentclient.go (1)
303-311: The change from<=to<breaks deduplication for equal non-zero generations.The code now returns
"MODIFIED"(line 311) instead of empty string for equal non-zero generations. At lines 210-211, an empty action is explicitly ignored (if len(action) == 0), but non-empty actions invoke handlers at lines 216-218.Old behavior (
<=): Equal generations → empty action → handlers NOT invoked
New behavior (<): Equal generations →"MODIFIED"→ handlers ARE invokedIn Kubernetes,
generationonly increments when spec changes. Equal generations indicate the spec is unchanged. Invoking handlers for identical specs violates deduplication semantics and will cause unnecessary handler invocations that expect actual modifications.While the message broker guarantees ordering (per comment on lines 301-302), this change breaks the generation-based deduplication that prevents duplicate processing.
Either revert to
<=or add explicit logic to handle equal generations:if obj.GetGeneration() == lastObj.GetGeneration() && obj.GetGeneration() != 0 { return evt, nil }before the<check.
♻️ Duplicate comments (1)
pkg/cloudevents/clients/work/source/client/manifestwork.go (1)
324-338: Fix generation parsing and resourceVersion fallback.Two blockers here:
strconv.ParseInt(..., 16)truncates any generation above int16, so valid values overflow as soon as generation exceeds 32767.- The fallback block always overwrites an annotation-provided resourceVersion with
"0", defeating the annotation entirely.Please switch to 64-bit parsing and only fall back to the stored resourceVersion or
"0"when the annotation is actually empty.Apply this diff:
- generation, err = strconv.ParseInt(resourceVersion, 10, 16) + generation, err = strconv.ParseInt(resourceVersion, 10, 64) if err != nil { return "", 0, errors.NewInternalError(err) } } if generation == 0 { generation = work.Generation } - if len(resourceVersion) == 0 && len(work.ResourceVersion) != 0 { - resourceVersion = work.ResourceVersion - } else { - resourceVersion = "0" - } + if len(resourceVersion) == 0 { + if len(work.ResourceVersion) != 0 { + resourceVersion = work.ResourceVersion + } else { + resourceVersion = "0" + } + }
🧹 Nitpick comments (1)
pkg/cloudevents/generic/clients/agentclient_test.go (1)
518-519: Consider clarifying the test data or adding explanatory comments.The cached resources have Generation 3 with ResourceVersion "1", while the incoming event has Generation 2 with ResourceVersion "2". This creates a counterintuitive state where the cached resource has a higher Generation but lower ResourceVersion, which wouldn't occur in real Kubernetes (ResourceVersion increases monotonically).
While this appears intentional to verify that Generation-based comparison takes precedence over ResourceVersion, the test data may confuse future maintainers. Additionally, both test1 and test2 have identical values, but only test1 is validated—test2's values seem unnecessary.
Consider one of the following:
Option 1: Use consistent increasing values
resources: []*generictesting.MockResource{ - {UID: kubetypes.UID("test1"), Generation: 3, ResourceVersion: "1", Namespace: "cluster1"}, - {UID: kubetypes.UID("test2"), Generation: 3, ResourceVersion: "1", Namespace: "cluster1"}, + {UID: kubetypes.UID("test1"), Generation: 3, ResourceVersion: "3", Namespace: "cluster1"}, + {UID: kubetypes.UID("test2"), Generation: 2, ResourceVersion: "2", Namespace: "cluster1"}, },Option 2: Add a clarifying comment
+// test1 has higher Generation (3 > 2) than incoming to verify Generation-based staleness detection +// ResourceVersion is intentionally lower to confirm it's not used for comparison resources: []*generictesting.MockResource{ {UID: kubetypes.UID("test1"), Generation: 3, ResourceVersion: "1", Namespace: "cluster1"}, {UID: kubetypes.UID("test2"), Generation: 3, ResourceVersion: "1", Namespace: "cluster1"}, },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
pkg/cloudevents/clients/store/informer.go(4 hunks)pkg/cloudevents/clients/work/source/client/manifestwork.go(4 hunks)pkg/cloudevents/clients/work/source/codec/manifestbundle_test.go(3 hunks)pkg/cloudevents/clients/work/store/base.go(1 hunks)pkg/cloudevents/clients/work/store/informer.go(3 hunks)pkg/cloudevents/generic/clients/agentclient.go(1 hunks)pkg/cloudevents/generic/clients/agentclient_test.go(1 hunks)pkg/cloudevents/generic/clients/baseclient.go(2 hunks)test/integration-test.mk(1 hunks)test/integration/cloudevents/cloudevents_resync_test.go(3 hunks)test/integration/cloudevents/manifestworkclients_reync_test.go(1 hunks)test/integration/cloudevents/util/work.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- pkg/cloudevents/generic/clients/baseclient.go
- test/integration-test.mk
- test/integration/cloudevents/manifestworkclients_reync_test.go
- pkg/cloudevents/clients/work/store/informer.go
- test/integration/cloudevents/util/work.go
🧰 Additional context used
🧬 Code graph analysis (5)
pkg/cloudevents/generic/clients/agentclient_test.go (1)
pkg/cloudevents/clients/utils/utils.go (1)
UID(222-225)
pkg/cloudevents/generic/clients/agentclient.go (1)
pkg/cloudevents/generic/types/types.go (1)
Modified(94-94)
pkg/cloudevents/clients/store/informer.go (4)
pkg/cloudevents/generic/interface.go (1)
ResourceObject(20-38)pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)pkg/cloudevents/clients/work/store/informer.go (2)
NewAgentInformerWatcherStore(128-138)AgentInformerWatcherStore(90-94)
test/integration/cloudevents/cloudevents_resync_test.go (2)
test/integration/cloudevents/agent/agent.go (1)
StartWorkAgent(16-40)pkg/cloudevents/clients/utils/utils.go (1)
Patch(44-82)
pkg/cloudevents/clients/work/source/client/manifestwork.go (1)
pkg/cloudevents/clients/common/common.go (1)
CloudEventsResourceVersionAnnotationKey(20-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: integration
- GitHub Check: unit
- GitHub Check: verify
🔇 Additional comments (4)
pkg/cloudevents/clients/work/source/codec/manifestbundle_test.go (3)
228-234: Metadata test data updated consistently.The metadata JSON now uses
Generation: 13instead ofResourceVersion: "13", which is consistent with the broader migration. The metadata structure correctly includes all necessary fields (UID, Name, Namespace, Labels, Annotations, Finalizers).
293-297: Expected work metadata updated consistently.The expected decoded work now uses
Generation: 13matching the metadata JSON setup at lines 228-234. The test expectations are internally consistent and align with the Generation-based approach.
207-208: No issues found - code correctly implements intentional design.The codec implementation confirms the semantic mapping is intentional and working correctly:
- Encode (line 42):
WithResourceVersion(work.Generation)sets "resourceversion" extension to the Generation value- Decode (line 100-108): reads "resourceversion" extension and assigns it to
metaObj.GenerationThis pattern is consistent across the codebase and aligns with the test expectations. The test changes at lines 207-208, 228-234, and 293-297 correctly verify that decoded works receive the Generation field populated from the "resourceversion" extension. The design uses Generation (not ResourceVersion field) for ManifestWork metadata, which is semantically appropriate for this codec's purpose.
pkg/cloudevents/generic/clients/agentclient.go (1)
301-301: LGTM! Comment now accurately reflects generation-based semantics.The updated comment correctly describes the generation-based comparison, aligning with the PR's shift from resource version to generation semantics.
Signed-off-by: Jian Qiu <[email protected]>
e7ee2c4 to
02f0223
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.
Actionable comments posted: 5
♻️ Duplicate comments (1)
pkg/cloudevents/clients/work/source/client/manifestwork.go (1)
334-338: Critical: Logic bug overwrites annotation value with "0".Despite the past review comment claiming this was addressed, the logic still has a critical flaw. When the annotation contains a value (resourceVersion is not empty from line 322-328), the condition on line 334 evaluates to false, causing execution to fall through to line 337 which sets
resourceVersion = "0", overwriting the annotation value.Per the function comment (lines 313-317), the intended behavior is to prefer the annotation value, then fall back to
work.ResourceVersion, then "0". The current code inverts this priority.Apply this diff to fix the logic:
- if len(resourceVersion) == 0 && len(work.ResourceVersion) != 0 { - resourceVersion = work.ResourceVersion - } else { + if len(resourceVersion) == 0 { + if len(work.ResourceVersion) != 0 { + resourceVersion = work.ResourceVersion + } else { + resourceVersion = "0" + } + } + - resourceVersion = "0" - } - return resourceVersion, generation, nil
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
pkg/cloudevents/clients/store/informer.go(4 hunks)pkg/cloudevents/clients/work/source/client/manifestwork.go(4 hunks)pkg/cloudevents/clients/work/source/codec/manifestbundle_test.go(3 hunks)pkg/cloudevents/clients/work/store/base.go(1 hunks)pkg/cloudevents/clients/work/store/informer.go(3 hunks)pkg/cloudevents/generic/clients/agentclient.go(1 hunks)pkg/cloudevents/generic/clients/agentclient_test.go(1 hunks)pkg/cloudevents/generic/clients/baseclient.go(2 hunks)test/integration-test.mk(1 hunks)test/integration/cloudevents/cloudevents_resync_test.go(3 hunks)test/integration/cloudevents/manifestworkclients_reync_test.go(1 hunks)test/integration/cloudevents/util/work.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- test/integration/cloudevents/util/work.go
- pkg/cloudevents/generic/clients/baseclient.go
- pkg/cloudevents/clients/work/source/codec/manifestbundle_test.go
- test/integration-test.mk
- pkg/cloudevents/generic/clients/agentclient.go
🧰 Additional context used
🧬 Code graph analysis (5)
pkg/cloudevents/clients/work/store/informer.go (1)
pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)
test/integration/cloudevents/manifestworkclients_reync_test.go (5)
test/integration/cloudevents/agent/agent.go (1)
StartWorkAgent(16-40)pkg/cloudevents/clients/utils/utils.go (1)
UID(222-225)pkg/cloudevents/clients/common/common.go (3)
ManifestWorkGR(37-37)CloudEventsOriginalSourceLabelKey(28-28)CloudEventsDataTypeAnnotationKey(14-14)test/integration/cloudevents/util/work.go (1)
NewManifestWorkWithStatus(203-207)pkg/cloudevents/clients/work/payload/manifestbundle.go (1)
ManifestBundleEventDataType(11-15)
pkg/cloudevents/clients/store/informer.go (4)
pkg/cloudevents/generic/interface.go (1)
ResourceObject(20-38)pkg/cloudevents/clients/store/base.go (1)
BaseClientWatchStore(15-20)pkg/cloudevents/clients/store/watcher.go (2)
Watcher(12-18)NewWatcher(22-34)pkg/cloudevents/clients/work/store/informer.go (2)
NewAgentInformerWatcherStore(128-138)AgentInformerWatcherStore(90-94)
pkg/cloudevents/clients/work/source/client/manifestwork.go (1)
pkg/cloudevents/clients/common/common.go (1)
CloudEventsResourceVersionAnnotationKey(20-20)
test/integration/cloudevents/cloudevents_resync_test.go (1)
test/integration/cloudevents/agent/agent.go (1)
StartWorkAgent(16-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: integration
- GitHub Check: unit
- GitHub Check: verify
🔇 Additional comments (6)
pkg/cloudevents/clients/store/informer.go (4)
28-35: LGTM! Store initialization is now explicit and self-contained.The constructor properly initializes the Store field with
cache.NewStore(cache.MetaNamespaceKeyFunc), aligning with the decoupling from SharedIndexInformer.
76-78: Deletion timestamp preservation is correct.The logic correctly preserves the deletion timestamp from the last stored object when processing Modified events, ensuring that once an object is marked for deletion, subsequent updates maintain that state.
109-120: Finalizer-aware deletion handling is well-designed.The logic correctly handles the case where a deletion event is received but finalizers remain on the object. By triggering an Update event with the new generation, finalizers, and deletion timestamp, watchers are notified that the object is entering deletion state without prematurely removing it from the store.
132-134: No issues found with HasInitiated() change.
HasInitiated()unconditionally returningtrueis correct forAgentInformerWatcherStore[T]. Verification shows:
- All existing tests create the store and seed it directly without checking
HasInitiated()expectations- This pattern matches
SimpleStore[T], which already returnstrueunconditionally- Callers in
generic.gouseHasInitiated()for resync timing, not strict sync guarantees- Unlike
SourceInformerWatcherStore(which has external informer sync),AgentInformerWatcherStoreinitializes directly and needs no external synchronizationtest/integration/cloudevents/manifestworkclients_reync_test.go (1)
41-64: LGTM!The migration from informer-based store to direct watchStore usage is clean and consistent with the PR's objectives to decouple from SharedIndexInformer.
test/integration/cloudevents/cloudevents_resync_test.go (1)
83-128: LGTM!The migration to watchStore and the addition of proper JSON merge patch logic for updates are both correct and align well with Kubernetes client patterns.
| } | ||
|
|
||
| // prevent the resource from being updated if it is deleting | ||
| // if resource is deleting, keep the deletiong timestamp |
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.
Fix typo in comment.
The comment has a typo: "deletiong" should be "deletion".
Apply this diff to fix the typo:
- // if resource is deleting, keep the deletiong timestamp
+ // if resource is deleting, keep the deletion timestamp📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // if resource is deleting, keep the deletiong timestamp | |
| // if resource is deleting, keep the deletion timestamp |
🤖 Prompt for AI Agents
In pkg/cloudevents/clients/store/informer.go around line 75, fix the typo in the
comment that reads "deletiong" to "deletion": update the comment text to "if
resource is deleting, keep the deletion timestamp" (or "deletion timestamp" as
appropriate) so the comment is spelled correctly.
| logger.Info("the work resource version is great than its generation, ignore", | ||
| "agentResourceVersion", resourceVersion, "sourceResourceVersion", lastResourceVersion) | ||
| if lastWork.Generation != 0 && work.Generation > lastWork.Generation { | ||
| logger.Info("the work generation is great than its local generation, ignore", |
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.
Fix typo in log message.
The log message contains a typo: "great" should be "greater".
Apply this diff:
- logger.Info("the work generation is great than its local generation, ignore",
+ logger.Info("the work generation is greater than its local generation, ignore",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| logger.Info("the work generation is great than its local generation, ignore", | |
| logger.Info("the work generation is greater than its local generation, ignore", |
🤖 Prompt for AI Agents
In pkg/cloudevents/clients/work/store/base.go around line 120, the log message
contains a typo ("great" should be "greater"); update the logger.Info call to
use the corrected message "the work generation is greater than its local
generation, ignore" (preserve surrounding punctuation and variables/arguments
passed to logger.Info).
| "agentResourceVersion", resourceVersion, "sourceResourceVersion", lastResourceVersion) | ||
| if lastWork.Generation != 0 && work.Generation > lastWork.Generation { | ||
| logger.Info("the work generation is great than its local generation, ignore", | ||
| "agentGeneration", lastWork.Generation, "sourceGeneration", work.Generation) |
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.
Swap the log labels to match the actual values.
The log labels appear to be backwards. lastWork.Generation represents the local/source generation, while work.Generation represents the agent generation. The current labels suggest the opposite.
Apply this diff:
- "agentGeneration", lastWork.Generation, "sourceGeneration", work.Generation)
+ "localGeneration", lastWork.Generation, "agentGeneration", work.Generation)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "agentGeneration", lastWork.Generation, "sourceGeneration", work.Generation) | |
| "localGeneration", lastWork.Generation, "agentGeneration", work.Generation) |
🤖 Prompt for AI Agents
In pkg/cloudevents/clients/work/store/base.go around line 121, the log labels
for generation values are reversed: lastWork.Generation is the source/local
generation and work.Generation is the agent generation. Swap the labels so the
call logs "sourceGeneration" with lastWork.Generation and "agentGeneration" with
work.Generation to match the actual values.
| // update the deletionTimeStamp and generation of last work. | ||
| // generation needs to be updated because it is possible that generation still change after | ||
| // the object is in deleting state. | ||
| updatedWork := lastWork.DeepCopy() | ||
| updatedWork.DeletionTimestamp = work.DeletionTimestamp | ||
| updatedWork.Generation = lastWork.Generation | ||
| return s.Update(updatedWork) |
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.
🧩 Analysis chain
Verify generation assignment during deletion.
Line 206 preserves lastWork.Generation when handling a delete event, but if the source sends a newer generation with the delete event (which the comment on line 202-203 acknowledges is possible), we should respect work.Generation instead.
Consider whether the generation should be updated from the incoming work:
updatedWork := lastWork.DeepCopy()
updatedWork.DeletionTimestamp = work.DeletionTimestamp
- updatedWork.Generation = lastWork.Generation
+ updatedWork.Generation = work.Generation
return s.Update(updatedWork)Run the following script to check how generation is used in comparison logic:
🏁 Script executed:
#!/bin/bash
# Search for generation-based comparison logic that might depend on this value
rg -nP '\bGeneration\b' pkg/cloudevents/clients/work/store/ -A3 -B3Length of output: 1422
I need to understand the call flow and how these components interact. Let me search for more context.
Let me search for where the delete action is triggered and how these components interact.
Let me search more specifically for the codebase flow and where these functions are called.
🏁 Script executed:
#!/bin/bash
# Search for where the comparison in base.go (line 119) is invoked
# Look for callers of the function containing that comparison
rg -nP 'work\.Generation\s*>' pkg/cloudevents/clients/work/store/ -B10 -A2Length of output: 1190
🏁 Script executed:
#!/bin/bash
# Find the function containing the delete handler to understand context
rg -nP 'case\s+"delete"' pkg/cloudevents/clients/work/store/informer.go -B5 -A20Length of output: 0
🏁 Script executed:
#!/bin/bash
# Find calls to the store.Update method to see where generation is being compared
rg -nP '\.Update\(' pkg/cloudevents/clients/work/store/ -B3 -A3Length of output: 6629
Let me find the function containing the comparison logic in base.go:
🏁 Script executed:
#!/bin/bash
# Find the function containing the comparison in base.go line 119
rg -nP 'func.*\(' pkg/cloudevents/clients/work/store/base.go -A200 | grep -A20 "work\.Generation\s*>"Length of output: 915
🏁 Script executed:
#!/bin/bash
# Get more context around base.go line 119 - show the full function
sed -n '90,160p' pkg/cloudevents/clients/work/store/base.goLength of output: 2740
🏁 Script executed:
#!/bin/bash
# Look for what calls the function in base.go that contains the comparison
# First, find the function name by looking at the structure
rg -nP 'func.*workProcessor' pkg/cloudevents/clients/work/store/base.go | head -20Length of output: 539
Let me check if there are tests that cover delete events with generation changes:
🏁 Script executed:
#!/bin/bash
# Search for tests covering delete events and generation
rg -n 'Deleted.*[Gg]eneration|[Gg]eneration.*Deleted' pkg/cloudevents/clients/work/store/informer_test.go -B5 -A5Length of output: 0
🏁 Script executed:
#!/bin/bash
# Look at the full delete test case to see if generation is tested
rg -n 'DeletionTimestamp|types\.Deleted' pkg/cloudevents/clients/work/store/informer_test.go -B3 -A10Length of output: 836
🏁 Script executed:
#!/bin/bash
# Check if there are any other references to generation during deletion scenario
rg -n 'Delete|DeletionTimestamp' pkg/cloudevents/clients/work/store/informer.go -B2 -A8Length of output: 2031
Respect source generation during deletion events.
The code comment acknowledges that generation can change while an object is deleting, but line 206 preserves the local generation instead of accepting the source's value. When the source sends a delete event with a new generation, the agent should respect it for consistent version tracking, just as it does for other incoming events.
Change line 206 as suggested:
updatedWork := lastWork.DeepCopy()
updatedWork.DeletionTimestamp = work.DeletionTimestamp
- updatedWork.Generation = lastWork.Generation
+ updatedWork.Generation = work.Generation📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // update the deletionTimeStamp and generation of last work. | |
| // generation needs to be updated because it is possible that generation still change after | |
| // the object is in deleting state. | |
| updatedWork := lastWork.DeepCopy() | |
| updatedWork.DeletionTimestamp = work.DeletionTimestamp | |
| updatedWork.Generation = lastWork.Generation | |
| return s.Update(updatedWork) | |
| // update the deletionTimeStamp and generation of last work. | |
| // generation needs to be updated because it is possible that generation still change after | |
| // the object is in deleting state. | |
| updatedWork := lastWork.DeepCopy() | |
| updatedWork.DeletionTimestamp = work.DeletionTimestamp | |
| updatedWork.Generation = work.Generation | |
| return s.Update(updatedWork) |
🤖 Prompt for AI Agents
In pkg/cloudevents/clients/work/store/informer.go around lines 201 to 207, the
code preserves lastWork.Generation when handling deletion events but should
respect the incoming source's generation; change the assignment so
updatedWork.Generation is set from work.Generation (the incoming object's
generation) instead of lastWork.Generation, then continue to call
s.Update(updatedWork) to persist the updated deletion timestamp and generation.
| {UID: kubetypes.UID("test1"), Generation: 3, ResourceVersion: "1", Namespace: "cluster1"}, | ||
| {UID: kubetypes.UID("test2"), Generation: 3, ResourceVersion: "1", Namespace: "cluster1"}, |
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.
🧩 Analysis chain
Verify test data semantics and consider adding clarifying comments.
The test data has Generation: 3 with ResourceVersion: "1", which violates typical Kubernetes semantics where ResourceVersion should increase with every update (if Generation is 3, ResourceVersion should be ≥ 3). While this may be intentional to verify that Generation-based comparison takes priority over ResourceVersion (incoming Generation 2 < cached Generation 3, so no action despite incoming ResourceVersion "2" > cached "1"), the unrealistic combination could confuse future maintainers.
Additionally:
- The test name "no change resource" is misleading—it's actually testing "stale/older resource rejection based on Generation"
- The
test2resource appears unused in this scenario since onlytest1is referenced in the incoming event
Consider:
- Adding a comment explaining why Generation: 3 with ResourceVersion: "1" is used
- Renaming the test to better reflect its purpose (e.g., "reject older generation resource")
- Using more realistic test data unless the unrealistic combination is specifically required
Run the following script to verify how Generation is used for comparison in the implementation:
🏁 Script executed:
#!/bin/bash
# Description: Find the implementation that compares Generation values to understand the test scenario
# Search for Generation comparison logic in agent client implementation
rg -n -A5 -B5 'Generation' pkg/cloudevents/generic/clients/agentclient.go
# Search for how resources are compared to determine if updates should be applied
ast-grep --pattern $'func $_($$$ ) HandleReceivedResource($$$) {
$$$
}'Length of output: 950
🏁 Script executed:
#!/bin/bash
# Search for other test cases with Generation values to understand data patterns
rg -n 'Generation:' pkg/cloudevents/generic/clients/agentclient_test.go -A1 -B1
# Look at the full test function to see if test2 is referenced elsewhere
sed -n '497,530p' pkg/cloudevents/generic/clients/agentclient_test.go
# Check if there are comments about the test's purpose
sed -n '490,530p' pkg/cloudevents/generic/clients/agentclient_test.goLength of output: 281
Summary
Related issue(s)
Fixes #
Summary by CodeRabbit
Refactor
Bug Fixes
Tests