davsclaus commented on code in PR #27576: URL: https://github.com/apache/camel/pull/27576#discussion_r4220562620
########## core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteGroupExchangeCountTest.java: ########## @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.management; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.api.management.ManagedCamelContext; +import org.apache.camel.api.management.mbean.ManagedRouteGroupMBean; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that a route group counts each exchange once per entry into the group: calls nested inside another route of the + * same group are not counted again (CAMEL-24887). + */ +@DisabledOnOs(OS.AIX) +public class ManagedRouteGroupExchangeCountTest extends ManagementTestSupport { + + @Test + public void testGroupCountsExchangeOnce() throws Exception { + ManagedCamelContext mcc = context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); + + // send 1 message through x1 -> x2 (both in group "g") + template.sendBody("direct:x1", "Hello"); + + ManagedRouteGroupMBean group = mcc.getManagedRouteGroup("g"); + assertNotNull(group); + assertEquals(1, group.getExchangesCompleted()); + assertEquals(1, group.getExchangesTotal()); + assertEquals(0, group.getExchangesInflight()); + + // send 2 more messages + template.sendBody("direct:x1", "World"); + template.sendBody("direct:x1", "!"); + + assertEquals(3, group.getExchangesCompleted()); + assertEquals(3, group.getExchangesTotal()); + } + + @Test + public void testGroupCountsOnceWhenRoutingThroughNonGroupRoute() throws Exception { + ManagedCamelContext mcc = context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); + + // send 1 message through x1 (group "g") -> y (no group) -> x2 (group "g") + template.sendBody("direct:x1-via-y", "Hello"); + + ManagedRouteGroupMBean group = mcc.getManagedRouteGroup("g"); + assertNotNull(group); + assertEquals(1, group.getExchangesCompleted()); + assertEquals(1, group.getExchangesTotal()); + } + + @Test + public void testGroupCountsWhenEntryIsOutsideGroup() throws Exception { + ManagedCamelContext mcc = context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); + + // send 1 message to a route outside the group that calls x2 (in group "g") directly + template.sendBody("direct:outside", "Hello"); + + ManagedRouteGroupMBean group = mcc.getManagedRouteGroup("g"); + assertNotNull(group); + assertEquals(1, group.getExchangesCompleted()); + } + + @Test + public void testGroupCountsFailure() throws Exception { + ManagedCamelContext mcc = context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); + + // send 1 message that will fail in x2-fail (group "g") + try { + template.sendBody("direct:x1-fail", "Hello"); + } catch (Exception e) { + // expected + } + + ManagedRouteGroupMBean group = mcc.getManagedRouteGroup("g"); + assertNotNull(group); + assertEquals(1, group.getExchangesFailed()); + assertEquals(0, group.getExchangesCompleted()); + assertEquals(0, group.getExchangesInflight()); + } + + @Test + public void testTwoGroupsOnOnePath() throws Exception { + ManagedCamelContext mcc = context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); + + // send 1 message through g1-route (group "g1") -> g2-route (group "g2") + template.sendBody("direct:g1-route", "Hello"); + + ManagedRouteGroupMBean group1 = mcc.getManagedRouteGroup("g1"); + ManagedRouteGroupMBean group2 = mcc.getManagedRouteGroup("g2"); + assertNotNull(group1); + assertNotNull(group2); + assertEquals(1, group1.getExchangesCompleted()); + assertEquals(1, group2.getExchangesCompleted()); + } + + @Test + public void testWireTapGroupCounts() throws Exception { + ManagedCamelContext mcc = context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); + + getMockEndpoint("mock:wt-done").expectedMessageCount(1); + + template.sendBody("direct:wt", "Hello"); + + assertMockEndpointsSatisfied(); + + // wait for the wireTapped exchange to complete in route "wt-target" + await().atMost(5, TimeUnit.SECONDS) + .untilAsserted(() -> assertEquals(1L, mcc.getManagedRoute("wt-target").getExchangesCompleted())); + + // each route counts independently at the route level + assertEquals(1, mcc.getManagedRoute("wt").getExchangesCompleted()); + assertEquals(1, mcc.getManagedRoute("wt-target").getExchangesCompleted()); + + // the group count is consistent with how the CamelContext MBean counts exchanges + long ctxCompleted = mcc.getManagedCamelContext().getExchangesCompleted(); + + ManagedRouteGroupMBean group = mcc.getManagedRouteGroup("g"); + assertNotNull(group); + assertEquals(ctxCompleted, group.getExchangesCompleted()); + assertEquals(ctxCompleted, group.getExchangesTotal()); Review Comment: This can still read stale values. After the `await` on the `wt-target` route counter, the CamelContext and group counters may not have been updated yet, because `CompositePerformanceCounter` updates them after the route counter. So the test can see `ctxCompleted == 2` with the group still at 1, and fail randomly. Or it can read both as 1 and pass even though the counts are stale. Comparing against `ctxCompleted` also means the expected value of 2 is never asserted. Could you wait on the group counter itself, and pin the value? ```suggestion // the wireTapped copy is a separate exchange with its own UnitOfWork, so the group // (like the CamelContext MBean) counts it as a second exchange. Wait on the group // counter itself: it is updated after the route and CamelContext counters ManagedRouteGroupMBean group = mcc.getManagedRouteGroup("g"); assertNotNull(group); await().atMost(5, TimeUnit.SECONDS) .untilAsserted(() -> assertEquals(2, group.getExchangesCompleted())); assertEquals(2, group.getExchangesTotal()); // each route counts independently at the route level assertEquals(1, mcc.getManagedRoute("wt").getExchangesCompleted()); assertEquals(1, mcc.getManagedRoute("wt-target").getExchangesCompleted()); assertEquals(2, mcc.getManagedCamelContext().getExchangesCompleted()); ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
