You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by al...@apache.org on 2019/08/13 14:13:38 UTC
[camel] 01/02: CAMEL-13826: Moved route coverage to a dedicated
class
This is an automated email from the ASF dual-hosted git repository.
aldettinger pushed a commit to branch CAMEL-13826
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 587c3a8f97846ea9040a9b2916c37613bce3ee24
Author: aldettinger <al...@gmail.com>
AuthorDate: Mon Aug 12 17:52:33 2019 +0200
CAMEL-13826: Moved route coverage to a dedicated class
---
.../camel/test/CamelRouteCoverageDumper.java | 190 +++++++++++++++++++++
.../apache/camel/test/junit5/CamelTestSupport.java | 152 +----------------
.../RouteProcessorDumpRouteCoverageTest.java | 20 ++-
3 files changed, 208 insertions(+), 154 deletions(-)
diff --git a/components/camel-test-junit5/src/main/java/org/apache/camel/test/CamelRouteCoverageDumper.java b/components/camel-test-junit5/src/main/java/org/apache/camel/test/CamelRouteCoverageDumper.java
new file mode 100644
index 0000000..ff3252a
--- /dev/null
+++ b/components/camel-test-junit5/src/main/java/org/apache/camel/test/CamelRouteCoverageDumper.java
@@ -0,0 +1,190 @@
+/*
+ * 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.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import org.apache.camel.Route;
+import org.apache.camel.api.management.ManagedCamelContext;
+import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
+import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
+import org.apache.camel.api.management.mbean.ManagedRouteMBean;
+import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.util.IOHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A <code>CamelRouteCoverageDumper</code> instance dumps the route coverage of
+ * a given camel test.
+ */
+public class CamelRouteCoverageDumper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CamelRouteCoverageDumper.class);
+
+ public void dump(ManagedCamelContextMBean managedCamelContext, ModelCamelContext context, String dumpDir, String dumpFilename, String testClass, String testName,
+ long testTimeTaken)
+ throws Exception {
+ logCoverageSummary(managedCamelContext, context);
+
+ String routeCoverageAsXml = managedCamelContext.dumpRoutesCoverageAsXml();
+ String combined = "<camelRouteCoverage>\n" + gatherTestDetailsAsXml(testClass, testName, testTimeTaken) + routeCoverageAsXml + "\n</camelRouteCoverage>";
+
+ File dumpFile = new File(dumpDir);
+ // ensure dir exists
+ dumpFile.mkdirs();
+ dumpFile = new File(dumpDir, dumpFilename);
+
+ LOG.info("Dumping route coverage to file: {}", dumpFile);
+ InputStream is = new ByteArrayInputStream(combined.getBytes());
+ OutputStream os = new FileOutputStream(dumpFile, false);
+ IOHelper.copyAndCloseInput(is, os);
+ IOHelper.close(os);
+ }
+
+ /**
+ * Groups all processors from Camel context by route id.
+ */
+ private Map<String, List<ManagedProcessorMBean>> findProcessorsForEachRoute(MBeanServer server, ModelCamelContext context)
+ throws MalformedObjectNameException, MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
+ String domain = context.getManagementStrategy().getManagementAgent().getMBeanServerDefaultDomain();
+
+ Map<String, List<ManagedProcessorMBean>> processorsForRoute = new HashMap<>();
+
+ ObjectName processorsObjectName = new ObjectName(domain + ":context=" + context.getManagementName() + ",type=processors,name=*");
+ Set<ObjectName> objectNames = server.queryNames(processorsObjectName, null);
+
+ for (ObjectName objectName : objectNames) {
+ String routeId = server.getAttribute(objectName, "RouteId").toString();
+ String name = objectName.getKeyProperty("name");
+ name = ObjectName.unquote(name);
+
+ ManagedProcessorMBean managedProcessor = context.getExtension(ManagedCamelContext.class).getManagedProcessor(name);
+
+ if (managedProcessor != null) {
+ if (processorsForRoute.get(routeId) == null) {
+ List<ManagedProcessorMBean> processorsList = new ArrayList<>();
+ processorsList.add(managedProcessor);
+
+ processorsForRoute.put(routeId, processorsList);
+ } else {
+ processorsForRoute.get(routeId).add(managedProcessor);
+ }
+ }
+ }
+
+ // sort processors by position in route definition
+ for (Map.Entry<String, List<ManagedProcessorMBean>> entry : processorsForRoute.entrySet()) {
+ Collections.sort(entry.getValue(), Comparator.comparing(ManagedProcessorMBean::getIndex));
+ }
+
+ return processorsForRoute;
+ }
+
+ /**
+ * Gathers test details as xml.
+ */
+ private String gatherTestDetailsAsXml(String testClass, String testName, long timeTaken) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("<test>\n");
+ sb.append(" <class>").append(testClass).append("</class>\n");
+ sb.append(" <method>").append(testName).append("</method>\n");
+ sb.append(" <time>").append(timeTaken).append("</time>\n");
+ sb.append("</test>\n");
+ return sb.toString();
+ }
+
+ /**
+ * Logs route coverage summary, including which routes are uncovered and
+ * what is the coverage of each processor in each route.
+ */
+ private void logCoverageSummary(ManagedCamelContextMBean managedCamelContext, ModelCamelContext context) throws Exception {
+ StringBuilder builder = new StringBuilder("\nCoverage summary\n");
+
+ int routes = managedCamelContext.getTotalRoutes();
+
+ long contextExchangesTotal = managedCamelContext.getExchangesTotal();
+
+ List<String> uncoveredRoutes = new ArrayList<>();
+
+ StringBuilder routesSummary = new StringBuilder();
+ routesSummary.append("\tProcessor coverage\n");
+
+ MBeanServer server = context.getManagementStrategy().getManagementAgent().getMBeanServer();
+
+ Map<String, List<ManagedProcessorMBean>> processorsForRoute = findProcessorsForEachRoute(server, context);
+
+ // log processor coverage for each route
+ for (Route route : context.getRoutes()) {
+ ManagedRouteMBean managedRoute = context.getExtension(ManagedCamelContext.class).getManagedRoute(route.getId());
+ if (managedRoute.getExchangesTotal() == 0) {
+ uncoveredRoutes.add(route.getId());
+ }
+
+ long routeCoveragePercentage = Math.round((double)managedRoute.getExchangesTotal() / contextExchangesTotal * 100);
+ routesSummary.append("\t\tRoute ").append(route.getId()).append(" total: ").append(managedRoute.getExchangesTotal()).append(" (").append(routeCoveragePercentage)
+ .append("%)\n");
+
+ if (server != null) {
+ List<ManagedProcessorMBean> processors = processorsForRoute.get(route.getId());
+ if (processors != null) {
+ for (ManagedProcessorMBean managedProcessor : processors) {
+ String processorId = managedProcessor.getProcessorId();
+ long processorExchangesTotal = managedProcessor.getExchangesTotal();
+ long processorCoveragePercentage = Math.round((double)processorExchangesTotal / contextExchangesTotal * 100);
+ routesSummary.append("\t\t\tProcessor ").append(processorId).append(" total: ").append(processorExchangesTotal).append(" (")
+ .append(processorCoveragePercentage).append("%)\n");
+ }
+ }
+ }
+ }
+
+ int used = routes - uncoveredRoutes.size();
+
+ long contextPercentage = Math.round((double)used / routes * 100);
+ builder.append("\tRoute coverage: ").append(used).append(" out of ").append(routes).append(" routes used (").append(contextPercentage).append("%)\n");
+ builder.append("\t\tCamelContext (").append(managedCamelContext.getCamelId()).append(") total: ").append(contextExchangesTotal).append("\n");
+
+ if (uncoveredRoutes.size() > 0) {
+ builder.append("\t\tUncovered routes: ").append(uncoveredRoutes.stream().collect(Collectors.joining(", "))).append("\n");
+ }
+
+ builder.append(routesSummary);
+ LOG.info(builder.toString());
+ }
+
+}
diff --git a/components/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java b/components/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java
index c7f24d8..1818a98 100644
--- a/components/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java
+++ b/components/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java
@@ -16,31 +16,12 @@
*/
package org.apache.camel.test.junit5;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
import org.apache.camel.CamelContext;
import org.apache.camel.ConsumerTemplate;
@@ -55,7 +36,6 @@ import org.apache.camel.NoSuchEndpointException;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
-import org.apache.camel.Route;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.Service;
@@ -63,8 +43,6 @@ import org.apache.camel.ServiceStatus;
import org.apache.camel.api.management.JmxSystemPropertyKeys;
import org.apache.camel.api.management.ManagedCamelContext;
import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
-import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
-import org.apache.camel.api.management.mbean.ManagedRouteMBean;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
@@ -81,7 +59,7 @@ import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.Language;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.EndpointHelper;
-import org.apache.camel.util.IOHelper;
+import org.apache.camel.test.CamelRouteCoverageDumper;
import org.apache.camel.util.StopWatch;
import org.apache.camel.util.StringHelper;
import org.apache.camel.util.TimeUtils;
@@ -134,6 +112,7 @@ public abstract class CamelTestSupport implements BeforeEachCallback, AfterAllCa
private static final ThreadLocal<AtomicInteger> TESTS = new ThreadLocal<>();
private static final ThreadLocal<CamelTestSupport> INSTANCE = new ThreadLocal<>();
private String currentTestName;
+ private CamelRouteCoverageDumper routeCoverageDumper = new CamelRouteCoverageDumper();
// CHECKSTYLE:ON
@Override
@@ -554,21 +533,7 @@ public abstract class CamelTestSupport implements BeforeEachCallback, AfterAllCa
LOG.warn("Cannot dump route coverage to file as JMX is not enabled. "
+ "Add camel-management-impl JAR as dependency and/or override useJmx() method to enable JMX in the unit test classes.");
} else {
- logCoverageSummary(managedCamelContext);
-
- String xml = managedCamelContext.dumpRoutesCoverageAsXml();
- String combined = "<camelRouteCoverage>\n" + gatherTestDetailsAsXml() + xml + "\n</camelRouteCoverage>";
-
- File file = new File(dir);
- // ensure dir exists
- file.mkdirs();
- file = new File(dir, name);
-
- LOG.info("Dumping route coverage to file: {}", file);
- InputStream is = new ByteArrayInputStream(combined.getBytes());
- OutputStream os = new FileOutputStream(file, false);
- IOHelper.copyAndCloseInput(is, os);
- IOHelper.close(os);
+ routeCoverageDumper.dump(managedCamelContext, context, dir, name, getClass().getName(), currentTestName, timeTaken());
}
}
LOG.info("********************************************************************************");
@@ -618,117 +583,6 @@ public abstract class CamelTestSupport implements BeforeEachCallback, AfterAllCa
}
/**
- * Logs route coverage summary: - which routes are uncovered - what is the
- * coverage of each processor in each route
- */
- private void logCoverageSummary(ManagedCamelContextMBean managedCamelContext) throws Exception {
- StringBuilder builder = new StringBuilder("\nCoverage summary\n");
-
- int routes = managedCamelContext.getTotalRoutes();
-
- long contextExchangesTotal = managedCamelContext.getExchangesTotal();
-
- List<String> uncoveredRoutes = new ArrayList<>();
-
- StringBuilder routesSummary = new StringBuilder();
- routesSummary.append("\tProcessor coverage\n");
-
- MBeanServer server = context.getManagementStrategy().getManagementAgent().getMBeanServer();
-
- Map<String, List<ManagedProcessorMBean>> processorsForRoute = findProcessorsForEachRoute(server);
-
- // log processor coverage for each route
- for (Route route : context.getRoutes()) {
- ManagedRouteMBean managedRoute = context.getExtension(ManagedCamelContext.class).getManagedRoute(route.getId());
- if (managedRoute.getExchangesTotal() == 0) {
- uncoveredRoutes.add(route.getId());
- }
-
- long routeCoveragePercentage = Math.round((double)managedRoute.getExchangesTotal() / contextExchangesTotal * 100);
- routesSummary.append("\t\tRoute ").append(route.getId()).append(" total: ").append(managedRoute.getExchangesTotal()).append(" (").append(routeCoveragePercentage)
- .append("%)\n");
-
- if (server != null) {
- List<ManagedProcessorMBean> processors = processorsForRoute.get(route.getId());
- if (processors != null) {
- for (ManagedProcessorMBean managedProcessor : processors) {
- String processorId = managedProcessor.getProcessorId();
- long processorExchangesTotal = managedProcessor.getExchangesTotal();
- long processorCoveragePercentage = Math.round((double)processorExchangesTotal / contextExchangesTotal * 100);
- routesSummary.append("\t\t\tProcessor ").append(processorId).append(" total: ").append(processorExchangesTotal).append(" (")
- .append(processorCoveragePercentage).append("%)\n");
- }
- }
- }
- }
-
- int used = routes - uncoveredRoutes.size();
-
- long contextPercentage = Math.round((double)used / routes * 100);
- builder.append("\tRoute coverage: ").append(used).append(" out of ").append(routes).append(" routes used (").append(contextPercentage).append("%)\n");
- builder.append("\t\tCamelContext (").append(managedCamelContext.getCamelId()).append(") total: ").append(contextExchangesTotal).append("\n");
-
- if (uncoveredRoutes.size() > 0) {
- builder.append("\t\tUncovered routes: ").append(uncoveredRoutes.stream().collect(Collectors.joining(", "))).append("\n");
- }
-
- builder.append(routesSummary);
- LOG.info(builder.toString());
- }
-
- /**
- * Groups all processors from Camel context by route id
- */
- private Map<String, List<ManagedProcessorMBean>> findProcessorsForEachRoute(MBeanServer server)
- throws MalformedObjectNameException, MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
- String domain = context.getManagementStrategy().getManagementAgent().getMBeanServerDefaultDomain();
-
- Map<String, List<ManagedProcessorMBean>> processorsForRoute = new HashMap<>();
-
- ObjectName processorsObjectName = new ObjectName(domain + ":context=" + context.getManagementName() + ",type=processors,name=*");
- Set<ObjectName> objectNames = server.queryNames(processorsObjectName, null);
-
- for (ObjectName objectName : objectNames) {
- String routeId = server.getAttribute(objectName, "RouteId").toString();
- String name = objectName.getKeyProperty("name");
- name = ObjectName.unquote(name);
-
- ManagedProcessorMBean managedProcessor = context.getExtension(ManagedCamelContext.class).getManagedProcessor(name);
-
- if (managedProcessor != null) {
- if (processorsForRoute.get(routeId) == null) {
- List<ManagedProcessorMBean> processorsList = new ArrayList<>();
- processorsList.add(managedProcessor);
-
- processorsForRoute.put(routeId, processorsList);
- } else {
- processorsForRoute.get(routeId).add(managedProcessor);
- }
- }
- }
-
- // sort processors by position in route definition
- for (Map.Entry<String, List<ManagedProcessorMBean>> entry : processorsForRoute.entrySet()) {
- Collections.sort(entry.getValue(), Comparator.comparing(ManagedProcessorMBean::getIndex));
- }
-
- return processorsForRoute;
- }
-
- /**
- * Gathers test details as xml
- */
- private String gatherTestDetailsAsXml() {
- StringBuilder sb = new StringBuilder();
- sb.append("<test>\n");
- sb.append(" <class>").append(getClass().getName()).append("</class>\n");
- sb.append(" <method>").append(currentTestName).append("</method>\n");
- sb.append(" <time>").append(timeTaken()).append("</time>\n");
- sb.append("</test>\n");
- return sb.toString();
- }
-
- /**
* Returns the timeout to use when shutting down (unit in seconds).
* <p/>
* Will default use 10 seconds.
diff --git a/components/camel-test-junit5/src/test/java/org/apache/camel/test/junit5/patterns/RouteProcessorDumpRouteCoverageTest.java b/components/camel-test-junit5/src/test/java/org/apache/camel/test/junit5/patterns/RouteProcessorDumpRouteCoverageTest.java
index b97959c..e5a99e0 100644
--- a/components/camel-test-junit5/src/test/java/org/apache/camel/test/junit5/patterns/RouteProcessorDumpRouteCoverageTest.java
+++ b/components/camel-test-junit5/src/test/java/org/apache/camel/test/junit5/patterns/RouteProcessorDumpRouteCoverageTest.java
@@ -19,11 +19,14 @@ package org.apache.camel.test.junit5.patterns;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.TestReporter;
import static org.apache.camel.test.junit5.TestSupport.assertFileExists;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
public class RouteProcessorDumpRouteCoverageTest extends CamelTestSupport {
@@ -38,12 +41,19 @@ public class RouteProcessorDumpRouteCoverageTest extends CamelTestSupport {
assertEquals("Bye World", out);
}
- @Override
- @AfterEach
- public void tearDown() throws Exception {
- super.tearDown();
+ @Test
+ public void testProcessorJunit5WithTestParameterInjection(TestInfo info, TestReporter testReporter) throws Exception {
+ assertNotNull(info);
+ assertNotNull(testReporter);
+ String out = template.requestBody("direct:start", "Hello World", String.class);
+ assertEquals("Bye World", out);
+ }
+
+ @AfterAll
+ public static void checkDumpFilesCreatedAfterTests() {
// should create that file when test is done
assertFileExists("target/camel-route-coverage/RouteProcessorDumpRouteCoverageTest-testProcessorJunit5.xml");
+ assertFileExists("target/camel-route-coverage/RouteProcessorDumpRouteCoverageTest-testProcessorJunit5WithTestParameterInjection.xml");
}
@Override