This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch 
investigate-and-fix-flaky-aws-eventbridge-localsta
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a91f8bf26b05bbd4b5ba997576b1d087bca770d9
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Jul 27 11:07:04 2026 +0200

    CAMEL-22000: Fix flaky EventBridge LocalStack integration tests
    
    All EventBridge IT tests share a singleton LocalStack container but use
    the same hardcoded rule name "firstrule" without cleanup. When test
    classes run in an unfavorable order, leftover rules from a prior test
    cause assertions on rule counts or rule state to fail with NPEs or
    unexpected counts.
    
    Add @BeforeEach cleanup in the base test class that removes all rules
    (and their targets) from the default event bus before each test,
    ensuring a clean slate regardless of test ordering. This matches the
    isolation patterns used by stable AWS IT tests (SQS, SNS, S3).
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../localstack/Aws2EventbridgeBase.java            | 71 +++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git 
a/components/camel-aws/camel-aws2-eventbridge/src/test/java/org/apache/camel/component/aws2/eventbridge/localstack/Aws2EventbridgeBase.java
 
b/components/camel-aws/camel-aws2-eventbridge/src/test/java/org/apache/camel/component/aws2/eventbridge/localstack/Aws2EventbridgeBase.java
index 8e19e2ca52e4..e12f55b9cdd4 100644
--- 
a/components/camel-aws/camel-aws2-eventbridge/src/test/java/org/apache/camel/component/aws2/eventbridge/localstack/Aws2EventbridgeBase.java
+++ 
b/components/camel-aws/camel-aws2-eventbridge/src/test/java/org/apache/camel/component/aws2/eventbridge/localstack/Aws2EventbridgeBase.java
@@ -22,20 +22,89 @@ import 
org.apache.camel.test.infra.aws.common.services.AWSService;
 import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils;
 import org.apache.camel.test.infra.aws2.services.AWSServiceFactory;
 import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.TestInstance;
 import org.junit.jupiter.api.extension.RegisterExtension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.services.eventbridge.EventBridgeClient;
+import software.amazon.awssdk.services.eventbridge.model.DeleteRuleRequest;
+import software.amazon.awssdk.services.eventbridge.model.ListRulesRequest;
+import software.amazon.awssdk.services.eventbridge.model.ListRulesResponse;
+import 
software.amazon.awssdk.services.eventbridge.model.ListTargetsByRuleRequest;
+import 
software.amazon.awssdk.services.eventbridge.model.ListTargetsByRuleResponse;
+import software.amazon.awssdk.services.eventbridge.model.RemoveTargetsRequest;
+import software.amazon.awssdk.services.eventbridge.model.Target;
 
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 public class Aws2EventbridgeBase extends CamelTestSupport {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(Aws2EventbridgeBase.class);
+    private static final String DEFAULT_EVENT_BUS = "default";
+
     @RegisterExtension
     public static AWSService service = 
AWSServiceFactory.createSingletonEventBridgeService();
 
+    protected EventBridgeClient eventBridgeClient;
+
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
+        eventBridgeClient = AWSSDKClientUtils.newEventBridgeClient();
         EventbridgeComponent eventbridgeComponent = 
context.getComponent("aws2-eventbridge", EventbridgeComponent.class);
-        
eventbridgeComponent.getConfiguration().setEventbridgeClient(AWSSDKClientUtils.newEventBridgeClient());
+        
eventbridgeComponent.getConfiguration().setEventbridgeClient(eventBridgeClient);
         return context;
     }
+
+    /**
+     * Cleans up all EventBridge rules on the default event bus before each 
test. This prevents test interference when
+     * using a singleton LocalStack container shared across test classes — 
leftover rules from a prior test could cause
+     * assertions on rule counts or rule state to fail.
+     */
+    @BeforeEach
+    void cleanUpEventBridgeRules() {
+        if (eventBridgeClient == null) {
+            return;
+        }
+        try {
+            ListRulesResponse listResponse = eventBridgeClient.listRules(
+                    
ListRulesRequest.builder().eventBusName(DEFAULT_EVENT_BUS).build());
+            if (listResponse.hasRules()) {
+                for (var rule : listResponse.rules()) {
+                    removeTargetsAndDeleteRule(rule.name());
+                }
+            }
+        } catch (Exception e) {
+            LOG.warn("Failed to clean up EventBridge rules before test: {}", 
e.getMessage());
+        }
+    }
+
+    private void removeTargetsAndDeleteRule(String ruleName) {
+        try {
+            ListTargetsByRuleResponse targets = 
eventBridgeClient.listTargetsByRule(
+                    ListTargetsByRuleRequest.builder()
+                            .rule(ruleName)
+                            .eventBusName(DEFAULT_EVENT_BUS)
+                            .build());
+            if (targets.hasTargets() && !targets.targets().isEmpty()) {
+                eventBridgeClient.removeTargets(
+                        RemoveTargetsRequest.builder()
+                                .rule(ruleName)
+                                
.ids(targets.targets().stream().map(Target::id).toList())
+                                .eventBusName(DEFAULT_EVENT_BUS)
+                                .build());
+            }
+        } catch (Exception e) {
+            LOG.warn("Failed to remove targets for rule {}: {}", ruleName, 
e.getMessage());
+        }
+        try {
+            eventBridgeClient.deleteRule(
+                    DeleteRuleRequest.builder()
+                            .name(ruleName)
+                            .eventBusName(DEFAULT_EVENT_BUS)
+                            .build());
+        } catch (Exception e) {
+            LOG.warn("Failed to delete rule {}: {}", ruleName, e.getMessage());
+        }
+    }
 }

Reply via email to