Skip to content

test: add inline event assertions for cluster object events#7399

Merged
karmada-bot merged 1 commit intokarmada-io:masterfrom
nXtCyberNet:e2e/cluster_object
May 6, 2026
Merged

test: add inline event assertions for cluster object events#7399
karmada-bot merged 1 commit intokarmada-io:masterfrom
nXtCyberNet:e2e/cluster_object

Conversation

@nXtCyberNet
Copy link
Copy Markdown
Contributor

@nXtCyberNet nXtCyberNet commented Apr 16, 2026

What type of PR is this?
/kind feature

What this PR does / why we need it:
Adds inline E2E test assertions for cluster object events emitted by Karmada
controllers, as part of improving the overall event test coverage (~7.8% → higher).

The following events are now covered:

Event Test File Trigger
CreateExecutionSpaceSucceed karmadactl_test.go After cluster join
RemoveExecutionSpaceSucceed karmadactl_test.go After cluster unjoin
TaintClusterSucceed clustertaintpolicy_test.go After taint added/removed
SyncImpersonationConfigSucceed karmadactl_test.go After cluster resource promotion

Failed variants (*Failed) are skipped for now as they require artificially
breaking the environment, which is not practical in E2E as noted in the issue.

Assertions follow Approach 2 (inline) as decided in the community meeting —
placed immediately after the operation that triggers the event, reusing the
existing resource lifecycle with no additional setup cost.

Which issue(s) this PR fixes:
Part of #7252

Special notes for your reviewer:

  • All assertions use controlPlaneClient since cluster events are emitted by
    the Karmada control plane, not member clusters
  • Events are checked in default namespace as cluster-scoped object events
    land there
  • Failed event variants are intentionally omitted per the issue guidance:
    "some failed events may not be easy to construct for testing, so they can
    be ignored for now"

Does this PR introduce a user-facing change?:

NONE

Signed-off-by: nXtCyberNet <rohantech2005@gmail.com>
Copilot AI review requested due to automatic review settings April 16, 2026 10:17
@karmada-bot karmada-bot added the kind/feature Categorizes issue or PR as related to a new feature. label Apr 16, 2026
@karmada-bot karmada-bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Apr 16, 2026
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the end-to-end testing framework for Karmada by introducing inline assertions for critical cluster object events. By verifying these events immediately after their triggering operations, the PR improves the reliability and coverage of the control plane's event emission logic, specifically targeting successful cluster lifecycle and configuration operations.

Highlights

  • Enhanced E2E Test Coverage: Added inline assertions for cluster object events to improve the overall event test coverage in the Karmada E2E suite.
  • Event Assertions Implementation: Integrated assertions for CreateExecutionSpaceSucceed, RemoveExecutionSpaceSucceed, TaintClusterSucceed, and SyncImpersonationConfigSucceed events using the inline approach.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances E2E tests for ClusterTaintPolicy and karmadactl by adding explicit waits for success events, such as TaintClusterSucceed and CreateExecutionSpaceSucceed, to ensure operations are fully processed. Feedback was provided regarding the potential for false positives when waiting for events on shared clusters by reason alone; it is recommended to incorporate checks for event timestamps or counts to ensure the events captured are relevant to the current test execution.

Comment on lines +108 to +110
framework.WaitEventFitWith(kubeClient, "default", targetClusterName, func(event corev1.Event) bool {
return event.Reason == events.EventReasonTaintClusterSucceed
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Waiting for an event on a shared resource (like a pre-existing cluster) by reason alone can lead to false positives if an event with the same reason exists from a previous test run or a different test case. Since targetClusterName is a shared cluster from the environment, consider verifying that the event is recent (e.g., by checking its timestamp against the operation start time or ensuring the event count increased). This applies to other similar assertions in this file (lines 190 and 268).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi maintainers,
I think this concern is valid, but the chances of it actually happening are very low. If you feel it's necessary to address, I can add the timestamp metadata check.
Thanks!

Copy link
Copy Markdown
Member

@mohamedawnallah mohamedawnallah May 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist can you check current codebase if tests running in parallel or sequentially? If in parallel are there any markers or flags that ensures this test not running in parallel with others? That way we can make sure those events emitted indeed from this test not overlapping with others.

NOTE: don't depend on your training data/memory, code is source of truth.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Karmada E2E test suite, tests are generally executed sequentially when using framework.SerialDescribe. This ensures that tests within the same suite do not overlap. However, to be absolutely certain that the events captured by framework.WaitEventFitWith belong to the current test execution, it is best practice to verify the event's LastTimestamp or EventTime against the time the operation was initiated, or to ensure the event count has incremented. This approach remains robust even if the test execution model changes in the future.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist NOTE: don't depend on your training data/memory, code is source of truth.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EventTime or LastTimestamp against the time the operation was initiated.

@gemini-code-assist but depending on time slight variations can be flaky.

On a related question What are the consequences if we unset the related property before the corresponding code paths in the test and assert/watch if they are set during test

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding your question about unsetting properties: while that approach can be effective for testing state transitions, it is often complex to implement for Kubernetes events because events are typically created by controllers asynchronously and are immutable once written to the API server.

To address the concern of potential flakiness while ensuring the event is associated with the current test, a more robust and standard approach in Kubernetes E2E testing is to capture the metav1.Time of the operation start and filter events that occurred after that timestamp. This avoids relying on exact timing and is significantly more reliable than checking for the existence of an event by reason alone, which could indeed be stale from previous test runs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nXtCyberNet I think that's fine perhaps we can leave it as is

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel the issue is not significant. Event testing is just supplementary and not the primary objective; as long as we ensure that the event can be reported properly, that's enough. After reviewing so many E2E event-related cases, I now feel that testing events in UT should be more reliable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reviewing so many E2E event-related cases, I now feel that testing events in UT should be more reliable.

Good point 👍

Comment on lines +216 to +218
framework.WaitEventFitWith(kubeClient, "default", member1, func(event corev1.Event) bool {
return event.Reason == events.EventReasonSyncImpersonationConfigSucceed
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the issue in clustertaintpolicy_test.go, member1 is a shared cluster from the environment. Asserting on the event reason without checking for a recent timestamp or an increased count may result in a false positive if the event already exists from a previous operation or test run.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds inline E2E assertions that validate Karmada control-plane controllers emit specific cluster-related Kubernetes Events after key lifecycle operations, improving event test coverage.

Changes:

  • Add WaitEventFitWith assertions for SyncImpersonationConfigSucceed after cluster resource promotion.
  • Add WaitEventFitWith assertions for CreateExecutionSpaceSucceed / RemoveExecutionSpaceSucceed around cluster join/unjoin flows.
  • Add WaitEventFitWith assertions for TaintClusterSucceed after ClusterTaintPolicy-driven taint add/remove.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
test/e2e/suites/base/karmadactl_test.go Adds event assertions around promote and join/unjoin-related flows.
test/e2e/suites/base/clustertaintpolicy_test.go Adds event assertions for taint-controller emitted cluster events.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +107 to +110
ginkgo.By(fmt.Sprintf("wait for TaintClusterSucceed event on cluster(%s)", targetClusterName), func() {
framework.WaitEventFitWith(kubeClient, "default", targetClusterName, func(event corev1.Event) bool {
return event.Reason == events.EventReasonTaintClusterSucceed
})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This event assertion can be satisfied by a stale TaintClusterSucceed event from a prior test run because it only checks event.Reason for a long-lived, pre-joined cluster name. Consider capturing a baseline (timestamp or existing event set) immediately before triggering the taint, and require the matched event to be newer than that baseline so the assertion is tied to this test’s action.

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +192
ginkgo.By(fmt.Sprintf("wait for TaintClusterSucceed event on cluster(%s)", targetClusterName), func() {
framework.WaitEventFitWith(kubeClient, "default", targetClusterName, func(event corev1.Event) bool {
return event.Reason == events.EventReasonTaintClusterSucceed
})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: because the target cluster is reused across the suite, checking only event.Reason can match an old TaintClusterSucceed event and let this step pass even if the current operation didn’t emit a new event. Gate the match on a baseline (e.g., event timestamp after the condition update) to avoid false positives.

Copilot uses AI. Check for mistakes.
Comment on lines +267 to +270
ginkgo.By(fmt.Sprintf("wait for TaintClusterSucceed event on cluster(%s)", targetClusterName), func() {
framework.WaitEventFitWith(kubeClient, "default", targetClusterName, func(event corev1.Event) bool {
return event.Reason == events.EventReasonTaintClusterSucceed
})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here: the assertion only checks for any TaintClusterSucceed event for targetClusterName, which can already exist from earlier contexts/tests. Record a baseline (time or existing events) before triggering the taint and require a new event after that baseline to ensure the test validates the current change.

Copilot uses AI. Check for mistakes.
Comment on lines +215 to +218
ginkgo.By(fmt.Sprintf("wait for SyncImpersonationConfigSucceed event on cluster(%s)", member1), func() {
framework.WaitEventFitWith(kubeClient, "default", member1, func(event corev1.Event) bool {
return event.Reason == events.EventReasonSyncImpersonationConfigSucceed
})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This event assertion can produce false positives because it only checks for the existence of any SyncImpersonationConfigSucceed event for member1, and that cluster is pre-existing (so older events from earlier setup or tests may already be present). Capture a baseline (e.g., current time or existing event RV/name set) before running the promote commands, and require the matched event to be newer than that baseline so the test proves the operation emitted the event.

Copilot uses AI. Check for mistakes.
@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 42.17%. Comparing base (baffcd9) to head (08b730e).
⚠️ Report is 25 commits behind head on master.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #7399   +/-   ##
=======================================
  Coverage   42.16%   42.17%           
=======================================
  Files         875      875           
  Lines       53603    53618   +15     
=======================================
+ Hits        22602    22613   +11     
- Misses      29304    29307    +3     
- Partials     1697     1698    +1     
Flag Coverage Δ
unittests 42.17% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nXtCyberNet
Copy link
Copy Markdown
Contributor Author

any updates?

// The following tests involve adding NoSchedule and NoExecute effect taints to clusters
// in the test environment, which will impact the resource scheduling of other concurrently
// executed test cases. Therefore, these tests need to be configured to run serially.
var _ = framework.SerialDescribe("Taint cluster with ClusterTaintPolicy", func() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is running sequentially 👍

Copy link
Copy Markdown
Member

@mohamedawnallah mohamedawnallah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nXtCyberNet for the PR, LGTM!

@mohamedawnallah
Copy link
Copy Markdown
Member

Just letting @Vacant2333, @XiShanYongYe-Chang if they have any comments so we can try to get this PR in

@nXtCyberNet
Copy link
Copy Markdown
Contributor Author

Just letting @Vacant2333, @XiShanYongYe-Chang if they have any comments so we can try to get this PR in

@mohamedawnallah Thanks for review.

Copy link
Copy Markdown
Member

@XiShanYongYe-Chang XiShanYongYe-Chang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nXtCyberNet @mohamedawnallah
/approve

Sorry for the late review; I just got back from vacation.

Leave lgtm to @mohamedawnallah

Comment on lines +108 to +110
framework.WaitEventFitWith(kubeClient, "default", targetClusterName, func(event corev1.Event) bool {
return event.Reason == events.EventReasonTaintClusterSucceed
})
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel the issue is not significant. Event testing is just supplementary and not the primary objective; as long as we ensure that the event can be reported properly, that's enough. After reviewing so many E2E event-related cases, I now feel that testing events in UT should be more reliable.

@karmada-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mohamedawnallah, XiShanYongYe-Chang

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@karmada-bot karmada-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 6, 2026
@XiShanYongYe-Chang
Copy link
Copy Markdown
Member

Hi @mohamedawnallah, I would like to invite you to be a reviewer for the E2E module. Would you be willing to do so?

@XiShanYongYe-Chang
Copy link
Copy Markdown
Member

Hi @mohamedawnallah, I would like to invite you to be a reviewer for the E2E module. Would you be willing to do so?

Sorry, I checked, and it has already been added :). You can directly type /lgtm to add this label.

@mohamedawnallah
Copy link
Copy Markdown
Member

/lgtm

@karmada-bot karmada-bot added the lgtm Indicates that a PR is ready to be merged. label May 6, 2026
@karmada-bot karmada-bot merged commit e669d0d into karmada-io:master May 6, 2026
21 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/feature Categorizes issue or PR as related to a new feature. lgtm Indicates that a PR is ready to be merged. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants