You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ji...@apache.org on 2024/06/07 14:03:57 UTC
(camel-quarkus) branch camel-main updated: Refactor of CamelQuarkusTestSupport to extends AbstractTestSupport
This is an automated email from the ASF dual-hosted git repository.
jiriondrusek pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/camel-main by this push:
new ae1be18aea Refactor of CamelQuarkusTestSupport to extends AbstractTestSupport
ae1be18aea is described below
commit ae1be18aea7ee1ff12981474c4fffa8aac664829
Author: JiriOndrusek <on...@gmail.com>
AuthorDate: Fri Jun 7 09:24:53 2024 +0200
Refactor of CamelQuarkusTestSupport to extends AbstractTestSupport
---
.../quarkus/test/CamelQuarkusTestSupport.java | 320 +++++++++++++--------
.../test/CustomCamelContextConfiguration.java | 34 +++
.../test/CustomTestExecutionConfiguration.java | 30 ++
3 files changed, 263 insertions(+), 121 deletions(-)
diff --git a/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CamelQuarkusTestSupport.java b/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CamelQuarkusTestSupport.java
index e91435d977..626391d0ad 100644
--- a/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CamelQuarkusTestSupport.java
+++ b/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CamelQuarkusTestSupport.java
@@ -26,14 +26,29 @@ import io.quarkus.test.junit.callback.QuarkusTestContext;
import io.quarkus.test.junit.callback.QuarkusTestMethodContext;
import jakarta.inject.Inject;
import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.Processor;
import org.apache.camel.Route;
+import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.quarkus.core.FastCamelContext;
import org.apache.camel.spi.Registry;
+import org.apache.camel.test.junit5.AbstractTestSupport;
+import org.apache.camel.test.junit5.CamelContextManager;
import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.camel.test.junit5.ContextManagerFactory;
+import org.apache.camel.test.junit5.TestSupport;
+import org.apache.camel.test.junit5.util.ExtensionHelper;
+import org.apache.camel.test.junit5.util.RouteCoverageDumperExtension;
+import org.apache.camel.util.StopWatch;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,11 +87,20 @@ import org.slf4j.LoggerFactory;
* them.</li>
* </ul>
*/
-public class CamelQuarkusTestSupport extends CamelTestSupport
+public class CamelQuarkusTestSupport extends AbstractTestSupport
implements QuarkusTestProfile {
private static final Logger LOG = LoggerFactory.getLogger(CamelQuarkusTestSupport.class);
+// @RegisterExtension
+// protected CamelTestSupport camelTestSupportExtension = this;
+
+ private final StopWatch watch = new StopWatch();
+ private String currentTestName;
+
+ private CamelContextManager contextManager;
+ private final ContextManagerFactory contextManagerFactory;
+
@Inject
protected CamelContext context;
@@ -86,12 +110,40 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
Set<String> createdRoutes;
public CamelQuarkusTestSupport() {
- super(new ContextNotStoppingManagerFactory());
+ super(new CustomTestExecutionConfiguration(), new CustomCamelContextConfiguration());
+
+ this.contextManagerFactory = new ContextNotStoppingManagerFactory();
+
+ testConfigurationBuilder()
+ .withCustomUseAdviceWith(isUseAdviceWith())
+ .withJMX(useJmx())
+ .withUseRouteBuilder(isUseRouteBuilder())
+ .withDumpRouteCoverage(isDumpRouteCoverage())
+ .withAutoStartContext(false);
+
+ contextConfiguration()
+ .withCustomCamelContextSupplier(this::camelContextSupplier)
+ .withCustomPostProcessor(this::postProcessTest)
+ .withCustomRoutesSupplier(this::createRouteBuilders)
+ .withRegistryBinder(this::bindToRegistry)
+ .withUseOverridePropertiesWithPropertiesComponent(useOverridePropertiesWithPropertiesComponent())
+ .withRouteFilterExcludePattern(getRouteFilterExcludePattern())
+ .withRouteFilterIncludePattern(getRouteFilterIncludePattern())
+ .withMockEndpoints(isMockEndpoints())
+ .withMockEndpointsAndSkip(isMockEndpointsAndSkip());
//CQ starts and stops context with the application start/stop
testConfiguration().withAutoStartContext(false);
}
+ CustomCamelContextConfiguration contextConfiguration() {
+ return (CustomCamelContextConfiguration)camelContextConfiguration;
+ }
+
+ CustomTestExecutionConfiguration testConfigurationBuilder() {
+ return (CustomTestExecutionConfiguration)testConfigurationBuilder;
+ }
+
//------------------------ quarkus callbacks ---------------
/**
@@ -130,29 +182,28 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
* @return The context from Quarkus CDI container
* @throws Exception Overridden method has to throw the same Exception as superclass.
*/
- @Override
- protected CamelContext createCamelContext() throws Exception {
+ protected CamelContext camelContextSupplier() throws Exception {
return this.context;
}
/**
* The same functionality as {@link CamelTestSupport#bindToRegistry(Registry)}.
*/
- @Override
protected void bindToRegistry(Registry registry) throws Exception {
//CamelTestSupport has to use the same context as CamelQuarkusTestSupport
Assertions.assertEquals(context, super.context, "Different context found!");
- super.bindToRegistry(registry);
}
/**
* The same functionality as {@link CamelTestSupport#postProcessTest()} .
*/
- @Override
protected void postProcessTest() throws Exception {
//CamelTestSupport has to use the same context as CamelQuarkusTestSupport
Assertions.assertEquals(context, super.context, "Different context found!");
- super.postProcessTest();
+
+ template = contextManager.template();
+ fluentTemplate = contextManager.fluentTemplate();
+ consumer = contextManager.consumer();
}
/**
@@ -160,138 +211,114 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
*/
@Override
public CamelContext context() {
- //CamelTestSupport has to use the same context as CamelQuarkusTestSupport
- Assertions.assertEquals(context, super.context, "Different context found!");
- return super.context();
+ return this.context;
}
- /**
- * This method is not called on Camel Quarkus because the `CamelRegistry` is created and owned by Quarkus CDI container.
- * If you need to customize the registry upon creation, you may want to override {@link #createCamelContext()}
- * in the following way:
- *
- * <pre>
- * @Override
- * protected CamelContext createCamelContext() throws Exception {
- * CamelContext ctx = super.createCamelContext();
- * Registry registry = ctx.getRegistry();
- * // do something with the registry...
- * return ctx;
- * }
- * </pre>
- *
- * @return Never returns any result. UnsupportedOperationException is thrown instead.
- */
- @Override
- protected final Registry createCamelRegistry() {
- throw new UnsupportedOperationException("won't be executed.");
+ @Deprecated(since = "4.7.0")
+ public long timeTaken() {
+ return watch.taken();
}
/**
- * This method does nothing. All necessary tasks are performed in
- * {@link BeforeEachCallback#beforeEach(QuarkusTestMethodContext)}
- * Use {@link #doAfterConstruct()} instead of this method.
+ * Gets the name of the current test being executed.
*/
- @Override
- public final void beforeAll(ExtensionContext context) {
- //replaced by quarkus callback (beforeEach)
+ public final String getCurrentTestName() {
+ return currentTestName;
}
/**
- * This method does nothing. All tasks are performed in {@link BeforeEachCallback#beforeEach(QuarkusTestMethodContext)}
- * Use {@link #doBeforeEach(QuarkusTestMethodContext)} instead of this method.
+ * Common test setup. For internal use.
+ *
+ * @deprecated Use {@link #setupResources()} instead
+ * @throws Exception if unable to setup the test
*/
- @Override
- public final void beforeEach(ExtensionContext context) throws Exception {
- //replaced by quarkus callback (beforeEach)
- }
+ @Deprecated(since = "4.7.0")
+ public void setUp() throws Exception {
+ ExtensionHelper.testStartHeader(getClass(), currentTestName);
- /**
- * This method does nothing. All necessary tasks are performed in
- * {@link BeforeEachCallback#beforeEach(QuarkusTestMethodContext)}
- * Use {@link #doAfterAll(QuarkusTestContext)} instead of this method.
- */
- @Override
- public final void afterAll(ExtensionContext context) {
- //in camel-quarkus, junit5 uses different classloader, necessary code was moved into quarkus's callback
- }
+ setupResources();
+ doPreSetup();
- /**
- * This method does nothing. All necessary tasks are performed in
- * {@link BeforeEachCallback#beforeEach(QuarkusTestMethodContext)}
- * Use {@link #doAfterEach(QuarkusTestMethodContext)} instead of this method.
- */
- @Override
- public final void afterEach(ExtensionContext context) throws Exception {
- //in camel-quarkus, junit5 uses different classloader, necessary code was moved into quarkus's callback
+ contextManager.createCamelContext(this);
+ context = contextManager.context();
+
+ doPostSetup();
+
+ // only start timing after all the setup
+ watch.restart();
}
/**
- * This method does nothing All necessary tasks are performed in
- * {@link BeforeEachCallback#beforeEach(QuarkusTestMethodContext)}
- * Use {@link #doAfterEach(QuarkusTestMethodContext)} instead of this method.
+ * Common test tear down. For internal use.
+ *
+ * @deprecated Use {@link #cleanupResources()} instead
+ * @throws Exception if unable to setup the test
*/
- @Override
- public final void afterTestExecution(ExtensionContext context) throws Exception {
- //in camel-quarkus, junit5 uses different classloader, necessary code was moved into quarkus's callback
+ @Deprecated(since = "4.7.0")
+ @AfterEach
+ public void tearDown() throws Exception {
+ long time = watch.taken();
+
+ if (isRouteCoverageEnabled()) {
+ ExtensionHelper.testEndFooter(getClass(), currentTestName, time, new RouteCoverageDumperExtension((ModelCamelContext) context));
+ } else {
+ ExtensionHelper.testEndFooter(getClass(), currentTestName, time);
+ }
+
+ if (testConfigurationBuilder.isCreateCamelContextPerClass()) {
+ // will tear down test specially in afterAll callback
+ return;
+ }
+
+ LOG.debug("tearDown()");
+
+ contextManager.stop();
+
+ doPostTearDown();
+ cleanupResources();
+
}
/**
- * Method {@link CamelTestSupport#setUp()} is triggered via annotation {@link org.junit.jupiter.api.BeforeEach}.
- * Its execution is disabled (by using overriding method without any annotation) and is executed from
- * {@link BeforeEachCallback}
+ * Strategy to perform any post-action, after {@link CamelContext} is stopped. This is meant for internal Camel
+ * usage and should not be used by user classes.
+ *
+ * @deprecated use {@link #cleanupResources()} instead.
*/
- @Override
- public void setUp() throws Exception {
- super.setUp();
+ @Deprecated(since = "4.7.0")
+ protected void doPostTearDown() throws Exception {
+ // noop
}
+
/**
- * Method {@link CamelTestSupport#tearDown()} is triggered via annotation
- * {@link org.junit.jupiter.api.AfterEach}.
- * Its execution is disabled (by using overriding method without any annotation) and is executed from
- * {@link AfterEachCallback}
+ * Factory method which derived classes can use to create a {@link RouteBuilder} to define the routes for testing
*/
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
+ protected RoutesBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ // no routes added by default
+ }
+ };
}
/**
- * This method stops the Camel context. Be aware that on of the limitation that Quarkus brings is that context
- * can not be started (lifecycle f the context is bound to the application) .
+ * Factory method which derived classes can use to create an array of {@link org.apache.camel.builder.RouteBuilder}s
+ * to define the routes for testing
*
- * @throws Exception
+ * @see #createRouteBuilder()
+ * @deprecated This method will be made private. Do not use
*/
- @Override
- protected void stopCamelContext() throws Exception {
- //context is started and stopped via quarkus lifecycle
+ @Deprecated(since = "4.7.0")
+ protected RoutesBuilder[] createRouteBuilders() throws Exception {
+ return new RoutesBuilder[] { createRouteBuilder() };
}
- /**
- * Allows running of the CamelTestSupport child in the Quarkus application.
- * Method is not intended to be overridden.
- */
- @Override
- protected final void unsupportedCheck() {
- //can run on Quarkus
-
- //log warning in case that at least one RouteBuilder in the registry, it might mean, that unintentionally
- // RouteBuilders are shared across or that RouteBuilder is created with @Produces
- if (isUseRouteBuilder() && !context.getRegistry().findByType(RouteBuilder.class).isEmpty()) {
- LOG.warn(
- "Test with `true` in `isUserRouteBuilder' and `RouteBuilder` detected in the context registry. " +
- "All tests will share this routeBuilder from the registry. This is usually not intended. " +
- "If `@Produces` is used to create such a RouteBuilder, please refactor the code " +
- "by overriding the method `createRouteBuilder()` instead.");
- }
- }
void internalAfterAll(QuarkusTestContext context, ExtensionContext extensionContext) {
try {
- if (isCreateCamelContextPerClass()) {
- super.afterAll(extensionContext);
- } else {
+ if (!testConfiguration().isCreateCamelContextPerClass()) {
doPostTearDown();
}
cleanupResources();
@@ -302,11 +329,29 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
}
void internalBeforeAll(ExtensionContext context) {
- super.beforeAll(context);
+ final boolean perClassPresent
+ = context.getTestInstanceLifecycle().filter(lc -> lc.equals(TestInstance.Lifecycle.PER_CLASS)).isPresent();
+ if (perClassPresent) {
+ LOG.trace("Creating a legacy context manager for {}", context.getDisplayName());
+ testConfigurationBuilder().withCustomCreateCamelContextPerClass(perClassPresent);
+ contextManager = contextManagerFactory.createContextManager(ContextManagerFactory.Type.BEFORE_ALL,
+ testConfigurationBuilder, camelContextConfiguration);
+ }
+
+ ExtensionContext.Store globalStore = context.getStore(ExtensionContext.Namespace.GLOBAL);
+ contextManager.setGlobalStore(globalStore);
}
void internalBeforeEach(ExtensionContext context) throws Exception {
- super.beforeEach(context);
+ if (contextManager == null) {
+ LOG.trace("Creating a transient context manager for {}", context.getDisplayName());
+ contextManager = contextManagerFactory.createContextManager(ContextManagerFactory.Type.BEFORE_EACH,
+ testConfigurationBuilder, camelContextConfiguration);
+ }
+
+ currentTestName = context.getDisplayName();
+ ExtensionContext.Store globalStore = context.getStore(ExtensionContext.Namespace.GLOBAL);
+ contextManager.setGlobalStore(globalStore);
}
/**
@@ -316,7 +361,6 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
* If this method is overridden, <i>super.doPreSetup()</i> has to be called.
* </p>
*/
- @Override
protected void doPreSetup() throws Exception {
if (isUseAdviceWith() || isUseDebugger()) {
((FastCamelContext) context).suspend();
@@ -326,8 +370,6 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
//save the routeIds of routes existing before setup
createdRoutes = context.getRoutes().stream().map(r -> r.getRouteId()).collect(Collectors.toSet());
}
-
- super.doPreSetup();
}
/**
@@ -337,7 +379,6 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
* If this method is overridden, <i>super.doPostSetup()</i> has to be called.
* </p>
*/
- @Override
protected void doPostSetup() throws Exception {
if (isUseAdviceWith() || isUseDebugger()) {
((FastCamelContext) context).resume();
@@ -358,15 +399,6 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
}
createdRoutes = allRoutes;
}
- super.doPostSetup();
- }
-
- /**
- * This method does nothing. The context starts together with Quarkus engine.
- */
- @Override
- protected final void startCamelContext() {
- //context has already started
}
/**
@@ -396,4 +428,50 @@ public class CamelQuarkusTestSupport extends CamelTestSupport
modelCamelContext.startRouteDefinitions(definitions);
}
+ /**
+ * Resolves the mandatory Mock endpoint using a URI of the form <code>mock:someName</code>
+ *
+ * @param uri the URI which typically starts with "mock:" and has some name
+ * @return the mandatory mock endpoint or an exception is thrown if it could not be resolved
+ */
+ protected final MockEndpoint getMockEndpoint(String uri) {
+ return getMockEndpoint(uri, true);
+ }
+
+ /**
+ * Resolves the {@link MockEndpoint} using a URI of the form <code>mock:someName</code>, optionally creating it if
+ * it does not exist. This implementation will lookup existing mock endpoints and match on the mock queue name, eg
+ * mock:foo and mock:foo?retainFirst=5 would match as the queue name is foo.
+ *
+ * @param uri the URI which typically starts with "mock:" and has some name
+ * @param create whether to allow the endpoint to be created if it doesn't exist
+ * @return the mock endpoint or an {@link NoSuchEndpointException} is thrown if it could not
+ * be resolved
+ * @throws NoSuchEndpointException is the mock endpoint does not exist
+ */
+ @Deprecated(since = "4.7.0")
+ protected final MockEndpoint getMockEndpoint(String uri, boolean create) throws NoSuchEndpointException {
+ return TestSupport.getMockEndpoint(context, uri, create);
+ }
+
+ /**
+ * Single step debugs and Camel invokes this method before entering the given processor. This method is NOOP.
+ *
+ * @deprecated Use {@link #camelContextConfiguration()} to set an instance of {@link DebugBreakpoint}
+ */
+ @Deprecated(since = "4.7.0")
+ protected void debugBefore(
+ Exchange exchange, Processor processor, ProcessorDefinition<?> definition, String id, String label) {
+ }
+
+ /**
+ * Single step debugs and Camel invokes this method after processing the given processor. This method is NOOP.
+ *
+ * @deprecated Use {@link #camelContextConfiguration()} to set an instance of {@link DebugBreakpoint}
+ */
+ @Deprecated(since = "4.7.0")
+ protected void debugAfter(
+ Exchange exchange, Processor processor, ProcessorDefinition<?> definition, String id, String label,
+ long timeTaken) {
+ }
}
diff --git a/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CustomCamelContextConfiguration.java b/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CustomCamelContextConfiguration.java
new file mode 100644
index 0000000000..05b93dcb4f
--- /dev/null
+++ b/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CustomCamelContextConfiguration.java
@@ -0,0 +1,34 @@
+/*
+ * 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.quarkus.test;
+
+import org.apache.camel.test.junit5.CamelContextConfiguration;
+
+public final class CustomCamelContextConfiguration extends CamelContextConfiguration {
+
+ CustomCamelContextConfiguration withCustomCamelContextSupplier(CamelContextSupplier camelContextSupplier) {
+ return (CustomCamelContextConfiguration)super.withCamelContextSupplier(camelContextSupplier);
+ }
+
+ CustomCamelContextConfiguration withCustomPostProcessor(PostProcessor postProcessor) {
+ return (CustomCamelContextConfiguration)super.withPostProcessor(postProcessor);
+ }
+
+ CustomCamelContextConfiguration withCustomRoutesSupplier(RoutesSupplier routesSupplier) {
+ return (CustomCamelContextConfiguration) super.withRoutesSupplier(routesSupplier);
+ }
+}
diff --git a/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CustomTestExecutionConfiguration.java b/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CustomTestExecutionConfiguration.java
new file mode 100644
index 0000000000..b2444e49a1
--- /dev/null
+++ b/test-framework/junit5/src/main/java/org/apache/camel/quarkus/test/CustomTestExecutionConfiguration.java
@@ -0,0 +1,30 @@
+/*
+ * 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.quarkus.test;
+
+import org.apache.camel.test.junit5.TestExecutionConfiguration;
+
+public final class CustomTestExecutionConfiguration extends TestExecutionConfiguration {
+
+ CustomTestExecutionConfiguration withCustomUseAdviceWith(boolean useAdviceWith) {
+ return (CustomTestExecutionConfiguration) super.withUseAdviceWith(useAdviceWith);
+ }
+
+ CustomTestExecutionConfiguration withCustomCreateCamelContextPerClass(boolean createCamelContextPerClass) {
+ return (CustomTestExecutionConfiguration)super.withCreateCamelContextPerClass(createCamelContextPerClass);
+ }
+}