From 06eda592aa0cd91b96de128a1ec5f728c5f22cea Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Tue, 8 May 2012 19:33:31 -0400 Subject: [PATCH 1/2] ARQ-917 support use of @Deployment on a static field of the test class --- .../container/test/api/Deployment.java | 2 +- ...AnnotationDeploymentScenarioGenerator.java | 94 ++++++++++++++++--- .../jboss/arquillian/test/spi/TestClass.java | 15 +++ 3 files changed, 95 insertions(+), 16 deletions(-) diff --git a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java index fd21a943e..455df3497 100644 --- a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java +++ b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java @@ -50,7 +50,7 @@ */ @Documented @Retention(RUNTIME) -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.FIELD}) public @interface Deployment { /** diff --git a/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java b/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java index 0abd8964e..51a1cd111 100644 --- a/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java +++ b/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java @@ -16,6 +16,8 @@ */ package org.jboss.arquillian.container.test.impl.client.deployment; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -57,6 +59,13 @@ public List generate(TestClass testClass) deployments.add(generateDeployment(deploymentMethod)); } + Field[] deploymentFields = testClass.getFields(Deployment.class); + for (Field deploymentField : deploymentFields) + { + validate(deploymentField); + deployments.add(generateDeployment(deploymentField)); + } + return deployments; } @@ -78,26 +87,40 @@ private void validate(Method deploymentMethod) } } + private void validate(Field deploymentField) + { + if(!Modifier.isStatic(deploymentField.getModifiers())) + { + throw new IllegalArgumentException("Field annotated with " + Deployment.class.getName() + " is not static. " + deploymentField); + } + if(!Archive.class.isAssignableFrom(deploymentField.getType()) && !Descriptor.class.isAssignableFrom(deploymentField.getType())) + { + throw new IllegalArgumentException( + "Field annotated with " + Deployment.class.getName() + + " must be of type " + Archive.class.getName() + " or " + Descriptor.class.getName() + ". " + deploymentField); + } + } + /** - * @param deploymentMethod + * @param deploymentMember * @return */ - private DeploymentDescription generateDeployment(Method deploymentMethod) + private DeploymentDescription generateDeployment(AccessibleObject deploymentMember) { - TargetDescription target = generateTarget(deploymentMethod); - ProtocolDescription protocol = generateProtocol(deploymentMethod); + TargetDescription target = generateTarget(deploymentMember); + ProtocolDescription protocol = generateProtocol(deploymentMember); - Deployment deploymentAnnotation = deploymentMethod.getAnnotation(Deployment.class); + Deployment deploymentAnnotation = deploymentMember.getAnnotation(Deployment.class); DeploymentDescription deployment = null; - if(Archive.class.isAssignableFrom(deploymentMethod.getReturnType())) + Class type = getType(deploymentMember); + if(Archive.class.isAssignableFrom(type)) { - deployment = new DeploymentDescription(deploymentAnnotation.name(), invoke(Archive.class, deploymentMethod)); + deployment = new DeploymentDescription(deploymentAnnotation.name(), getOrInvoke(Archive.class, deploymentMember)); deployment.shouldBeTestable(deploymentAnnotation.testable()); } - else if(Descriptor.class.isAssignableFrom(deploymentMethod.getReturnType())) + else if(Descriptor.class.isAssignableFrom(type)) { - deployment = new DeploymentDescription(deploymentAnnotation.name(), invoke(Descriptor.class, deploymentMethod)); - //deployment.shouldBeTestable(false); + deployment = new DeploymentDescription(deploymentAnnotation.name(), getOrInvoke(Descriptor.class, deploymentMember)); } deployment.shouldBeManaged(deploymentAnnotation.managed()); deployment.setOrder(deploymentAnnotation.order()); @@ -110,20 +133,20 @@ else if(Descriptor.class.isAssignableFrom(deploymentMethod.getReturnType())) deployment.setProtocol(protocol); } - if(deploymentMethod.isAnnotationPresent(ShouldThrowException.class)) + if(deploymentMember.isAnnotationPresent(ShouldThrowException.class)) { - deployment.setExpectedException(deploymentMethod.getAnnotation(ShouldThrowException.class).value()); + deployment.setExpectedException(deploymentMember.getAnnotation(ShouldThrowException.class).value()); deployment.shouldBeTestable(false); // can't test against failing deployments } return deployment; } - + /** * @param deploymentMethod * @return */ - private TargetDescription generateTarget(Method deploymentMethod) + private TargetDescription generateTarget(AccessibleObject deploymentMethod) { if(deploymentMethod.isAnnotationPresent(TargetsContainer.class)) { @@ -136,7 +159,7 @@ private TargetDescription generateTarget(Method deploymentMethod) * @param deploymentMethod * @return */ - private ProtocolDescription generateProtocol(Method deploymentMethod) + private ProtocolDescription generateProtocol(AccessibleObject deploymentMethod) { if(deploymentMethod.isAnnotationPresent(OverProtocol.class)) { @@ -145,6 +168,18 @@ private ProtocolDescription generateProtocol(Method deploymentMethod) return ProtocolDescription.DEFAULT; } + private T getOrInvoke(Class type, AccessibleObject deploymentMember) + { + if (deploymentMember instanceof Method) + { + return invoke(type, (Method) deploymentMember); + } + else + { + return get(type, (Field) deploymentMember); + } + } + /** * @param deploymentMethod * @return @@ -160,4 +195,33 @@ private T invoke(Class type, Method deploymentMethod) throw new RuntimeException("Could not invoke deployment method: " + deploymentMethod, e); } } + + /** + * @param deploymentField + * @return + */ + private T get(Class type, Field deploymentField) + { + try + { + return type.cast(deploymentField.get(null)); + } + catch (Exception e) + { + throw new RuntimeException("Could not get value of deployment field: " + deploymentField, e); + } + } + + private Class getType(AccessibleObject member) + { + if (member instanceof Method) + { + return Method.class.cast(member).getReturnType(); + } + else + { + return Field.class.cast(member).getType(); + } + } + } diff --git a/test/spi/src/main/java/org/jboss/arquillian/test/spi/TestClass.java b/test/spi/src/main/java/org/jboss/arquillian/test/spi/TestClass.java index c6d5eb2de..f34db249c 100644 --- a/test/spi/src/main/java/org/jboss/arquillian/test/spi/TestClass.java +++ b/test/spi/src/main/java/org/jboss/arquillian/test/spi/TestClass.java @@ -17,6 +17,7 @@ package org.jboss.arquillian.test.spi; import java.lang.annotation.Annotation; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -86,5 +87,19 @@ public Method[] getMethods(Class annotation) } return foundMethods.toArray(new Method[0]); } + + public Field[] getFields(Class annotation) + { + List found = new ArrayList(); + Field[] fields = testClass.getFields(); + for(Field field: fields) + { + if(field.isAnnotationPresent(annotation)) + { + found.add(field); + } + } + return found.toArray(new Field[0]); + } } From e4d11479b4dc537b2f8b29f434a42894a95c214a Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Sun, 13 May 2012 13:28:40 -0400 Subject: [PATCH 2/2] ARQ-918 Add @ExcludedServices as extensible substitute for @Deployment(testable = false) --- .../deployment/DeploymentDescription.java | 16 +++ .../container/test/api/Deployment.java | 6 +- .../container/test/api/ExcludeServices.java | 69 +++++++++++++ .../container/test/api/OverProtocol.java | 2 +- .../container/test/api/ServiceType.java | 56 +++++++++++ .../test/api/ShouldThrowException.java | 2 +- ...AnnotationDeploymentScenarioGenerator.java | 15 ++- ...onDeploymentScenarioGeneratorTestCase.java | 97 ++++++++++++++++++- .../DeploymentGeneratorTestCase.java | 57 ++++++++++- 9 files changed, 311 insertions(+), 9 deletions(-) create mode 100644 container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ExcludeServices.java create mode 100644 container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ServiceType.java diff --git a/container/spi/src/main/java/org/jboss/arquillian/container/spi/client/deployment/DeploymentDescription.java b/container/spi/src/main/java/org/jboss/arquillian/container/spi/client/deployment/DeploymentDescription.java index b1ecf2bce..aee669838 100644 --- a/container/spi/src/main/java/org/jboss/arquillian/container/spi/client/deployment/DeploymentDescription.java +++ b/container/spi/src/main/java/org/jboss/arquillian/container/spi/client/deployment/DeploymentDescription.java @@ -16,6 +16,9 @@ */ package org.jboss.arquillian.container.spi.client.deployment; +import java.util.ArrayList; +import java.util.List; + import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.descriptor.api.Descriptor; @@ -39,6 +42,7 @@ public class DeploymentDescription private Descriptor descriptor; private Archive testableArchive; + private List servicesToExclude = new ArrayList(); private Class expectedException; @@ -153,6 +157,15 @@ public DeploymentDescription shouldBeTestable(boolean testable) return this; } + public DeploymentDescription shouldExcludeServices(List servicesToExclude) { + if(!isArchiveDeployment()) + { + throw new IllegalArgumentException("Only an Archive deployment can exclude services: " + getName()); + } + this.servicesToExclude = servicesToExclude; + return this; + } + /** * @return the testable */ @@ -161,6 +174,9 @@ public boolean testable() return testable; } + public List servicesToExclude() { + return servicesToExclude; + } /** * @return the testableArchive diff --git a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java index 455df3497..6638a81ce 100644 --- a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java +++ b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/Deployment.java @@ -24,12 +24,12 @@ import java.lang.annotation.Target; /** - * The {@code @Deployment} is used to define which methods should be be considered as deployment producers. Arquillian support + * The {@code @Deployment} is used to define which methods should be be considered as deployment producers. Arquillian supports * two types of deployment units, a {@link Archive} or a {@link Descriptor}. *

- * A deployment represent the isolation level of your test, that being a single JavaArchive or a multi module EnterpriseArchive. + * A deployment represents the isolation level of your test, that being a single JavaArchive or a multi-module EnterpriseArchive. *

- * The deployment producer will be executed to create the deployment before the Test run, this to detect environment problems as soon as + * The deployment producer will be executed to create the deployment before the Test run to detect environment problems as soon as * possible. * *

diff --git a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ExcludeServices.java b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ExcludeServices.java new file mode 100644 index 000000000..221c33d8c --- /dev/null +++ b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ExcludeServices.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed 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.jboss.arquillian.container.test.api; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used with the {@code @Deployment} annotation to identify which Arquillian services should be left out of + * the test archive. + * + *

+ * By default, Arquillian adds a collection of services to the {@code Archive} defined by the {@code @Deployment} member, often + * by wrapping it inside another {@code Archive}. The {@code @ExcludeServices} annotation can be used to disable this behavior + * altogether or exclude certain services types using a set of built-in constants defined in {@link ServiceType}. This list of + * service types is extensible so that extensions can honor additional exclusions. + *

+ * + *

+ * {@code @ExcludeServices} should be used in place of {@code @Deployment(testable = false)}. + *

+ * + *

+ * Usage Example (disable archive modification):
+ *


+ * @Deployment
+ * @ExcludeServices
+ * public static WebArchive create() {
+ *     return ShrinkWrap.create(WebArchive.class).addClass(MyComponent.class);
+ * }
+ * 
+ *

+ * Usage Example (exclude support for in-container testing):
+ *


+ * @Deployment
+ * @ExcludeServices(ServiceType.TEST_RUNNER)
+ * public static WebArchive create() {
+ *     return ShrinkWrap.create(WebArchive.class).addClass(MyComponent.class);
+ * }
+ * 
+ * + * @since 1.0.1.Final + * @author Dan Allen + * @see Deployment + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD}) +public @interface ExcludeServices { + String[] value() default { ServiceType.ALL }; +} diff --git a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/OverProtocol.java b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/OverProtocol.java index 163552239..71f1b5683 100644 --- a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/OverProtocol.java +++ b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/OverProtocol.java @@ -58,7 +58,7 @@ */ @Documented @Retention(RUNTIME) -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.FIELD}) public @interface OverProtocol { /** diff --git a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ServiceType.java b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ServiceType.java new file mode 100644 index 000000000..51f9de1fc --- /dev/null +++ b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ServiceType.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed 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.jboss.arquillian.container.test.api; + +/** + * A collection of constants that represent groups of Arquillian services that are + * added to the deployment archive to facilitate or enhance in-container testing. + * + * @since 1.0.1.Final + * @author Dan Allen + * @see Deployment + */ +public interface ServiceType { + /** + * Represents all Arquillian services that are added to a deployment. + */ + public static final String ALL = "*"; + + /** + * Provides the test runner infrastructure and test class to run tests in-container over the specified protocol. + */ + public static final String TEST_RUNNER = "test-runner"; + + /** + * Instrumentation services for analyzing and managing code running inside the container. + * + *

Instrumentation is the addition of code for the purpose of gathering data to be utilized by tools. Since the changes are + * purely additive, these tools do not modify application state or behavior. Examples include monitoring agents, profilers, + * coverage analyzers, and event loggers.

+ * + *

Not currently honored as an exclusion.

+ */ + public static final String INSTRUMENTATION = "instrumentation"; + + /** + *

Adds additional component model services to the deployment such as CDI for Servlet containers or Spring libraries.

+ * + *

Not currently honored as an exclusion.

+ */ + public static final String DEPLOYERS = "deployers"; +} \ No newline at end of file diff --git a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ShouldThrowException.java b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ShouldThrowException.java index 530e4b5d1..5d1500161 100644 --- a/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ShouldThrowException.java +++ b/container/test-api/src/main/java/org/jboss/arquillian/container/test/api/ShouldThrowException.java @@ -45,7 +45,7 @@ */ @Documented @Retention(RUNTIME) -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.FIELD}) public @interface ShouldThrowException { Class value(); diff --git a/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java b/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java index 51a1cd111..a976b5090 100644 --- a/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java +++ b/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGenerator.java @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.jboss.arquillian.container.spi.client.deployment.DeploymentDescription; @@ -28,7 +29,9 @@ import org.jboss.arquillian.container.spi.client.deployment.TargetDescription; import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.ExcludeServices; import org.jboss.arquillian.container.test.api.OverProtocol; +import org.jboss.arquillian.container.test.api.ServiceType; import org.jboss.arquillian.container.test.api.ShouldThrowException; import org.jboss.arquillian.container.test.api.TargetsContainer; import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScenarioGenerator; @@ -116,7 +119,17 @@ private DeploymentDescription generateDeployment(AccessibleObject deploymentMemb if(Archive.class.isAssignableFrom(type)) { deployment = new DeploymentDescription(deploymentAnnotation.name(), getOrInvoke(Archive.class, deploymentMember)); - deployment.shouldBeTestable(deploymentAnnotation.testable()); + ExcludeServices excludeServicesAnnotation = deploymentMember.getAnnotation(ExcludeServices.class); + if (excludeServicesAnnotation != null) { + List exclusions = Arrays.asList(excludeServicesAnnotation.value()); + deployment.shouldExcludeServices(exclusions); + if (exclusions.contains(ServiceType.ALL) || exclusions.contains(ServiceType.TEST_RUNNER)) { + deployment.shouldBeTestable(false); + } + } + else { + deployment.shouldBeTestable(deploymentAnnotation.testable()); + } } else if(Descriptor.class.isAssignableFrom(type)) { diff --git a/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGeneratorTestCase.java b/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGeneratorTestCase.java index c4e282dd2..3f14ec784 100644 --- a/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGeneratorTestCase.java +++ b/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/AnnotationDeploymentScenarioGeneratorTestCase.java @@ -22,7 +22,9 @@ import org.jboss.arquillian.container.spi.client.deployment.TargetDescription; import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.ExcludeServices; import org.jboss.arquillian.container.test.api.OverProtocol; +import org.jboss.arquillian.container.test.api.ServiceType; import org.jboss.arquillian.container.test.api.ShouldThrowException; import org.jboss.arquillian.container.test.api.TargetsContainer; import org.jboss.arquillian.test.spi.TestClass; @@ -132,7 +134,62 @@ public void shouldReadExpectedAndOverrideDeployment() Assert.assertTrue(JavaArchive.class.isInstance(deploymentOne.getArchive())); Assert.assertEquals(Exception.class, deploymentOne.getExpectedException()); } + + @Test + public void shouldThrowExceptionOnFieldOverridesTestableDeployment() + { + List scenario = generate(ShouldThrowExceptionOnDeploymentField.class); + + Assert.assertNotNull(scenario); + Assert.assertEquals( + "Verify all deployments were found", + 1, scenario.size()); + + DeploymentDescription deploymentOne = scenario.get(0); + + Assert.assertEquals(false, deploymentOne.testable()); + Assert.assertTrue(JavaArchive.class.isInstance(deploymentOne.getArchive())); + Assert.assertEquals(Exception.class, deploymentOne.getExpectedException()); + } + @Test + public void shouldAcceptDeploymentWithExcludedServices() + { + List descriptors = new AnnotationDeploymentScenarioGenerator().generate( + new TestClass(DeploymentWithExcludedServices.class)); + Assert.assertNotNull(descriptors); + Assert.assertEquals(1, descriptors.size()); + DeploymentDescription deployment = descriptors.get(0); + Assert.assertFalse(deployment.testable()); + Assert.assertEquals(1, deployment.servicesToExclude().size()); + Assert.assertEquals(ServiceType.ALL, deployment.servicesToExclude().get(0)); + } + + @Test + public void shouldAcceptDeploymentWithTestRunnerServiceExcluded() + { + List descriptors = new AnnotationDeploymentScenarioGenerator().generate( + new TestClass(DeploymentWithTestRunnerServiceExcluded.class)); + Assert.assertNotNull(descriptors); + Assert.assertEquals(1, descriptors.size()); + DeploymentDescription deployment = descriptors.get(0); + Assert.assertFalse(deployment.testable()); + Assert.assertEquals(1, deployment.servicesToExclude().size()); + Assert.assertEquals(ServiceType.TEST_RUNNER, deployment.servicesToExclude().get(0)); + } + + @Test + public void shouldAllowDeploymentOnField() throws Exception + { + List descriptors = new AnnotationDeploymentScenarioGenerator().generate( + new TestClass(DeploymentOnField.class)); + + Assert.assertNotNull(descriptors); + Assert.assertEquals(1, descriptors.size()); + Assert.assertTrue(descriptors.get(0).testable()); + } + + @Test public void shouldAllowNoDeploymentPresent() throws Exception { List descriptors = new AnnotationDeploymentScenarioGenerator().generate( @@ -192,6 +249,28 @@ public static Archive deploymentTwo() } } + @SuppressWarnings("unused") + private static class DeploymentWithExcludedServices + { + @Deployment + @ExcludeServices + public static Archive createDeployment() + { + return ShrinkWrap.create(JavaArchive.class); + } + } + + @SuppressWarnings("unused") + private static class DeploymentWithTestRunnerServiceExcluded + { + @Deployment + @ExcludeServices(ServiceType.TEST_RUNNER) + public static Archive createDeployment() + { + return ShrinkWrap.create(JavaArchive.class); + } + } + @SuppressWarnings("unused") private static class ExpectedDeploymentExceptionSet { @@ -202,7 +281,23 @@ public static Archive deploymentOne() return ShrinkWrap.create(JavaArchive.class); } } - + + @SuppressWarnings("unused") + private static class DeploymentOnField + { + @Deployment + @ExcludeServices({}) + public static Archive deployment = ShrinkWrap.create(JavaArchive.class); + } + + @SuppressWarnings("unused") + private static class ShouldThrowExceptionOnDeploymentField + { + @Deployment(testable = true) // testable should be overwritten by @ShouldThrowException + @ShouldThrowException(Exception.class) + public static Archive deployment = ShrinkWrap.create(JavaArchive.class); + } + private static class DeploymentNotPresent { } diff --git a/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/DeploymentGeneratorTestCase.java b/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/DeploymentGeneratorTestCase.java index e99d3e820..fd913f606 100644 --- a/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/DeploymentGeneratorTestCase.java +++ b/container/test-impl-base/src/test/java/org/jboss/arquillian/container/test/impl/client/deployment/DeploymentGeneratorTestCase.java @@ -39,6 +39,7 @@ import org.jboss.arquillian.container.spi.client.deployment.DeploymentScenario; import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.ExcludeServices; import org.jboss.arquillian.container.test.api.OverProtocol; import org.jboss.arquillian.container.test.api.TargetsContainer; import org.jboss.arquillian.container.test.impl.client.deployment.event.GenerateDeployment; @@ -160,7 +161,7 @@ public void shouldUseContainerDefaultProtocolIfNonDefaultDefined() public void shouldCallPackagingSPIsOnTestableArchive() throws Exception { addContainer("test-contianer").getContainerConfiguration().setMode("suite"); - addProtocol(PROTOCOL_NAME_1, true); + addProtocol(PROTOCOL_NAME_1, false); fire(createEvent(DeploymentWithDefaults.class)); @@ -171,6 +172,22 @@ public void shouldCallPackagingSPIsOnTestableArchive() throws Exception verifyScenario("_DEFAULT_"); } + + @Test + public void shouldCallPackagingSPIsOnTestableArchiveFromFieldWithContainerAndProtocolReferences() throws Exception + { + addContainer("test-container").getContainerConfiguration().setMode("suite"); + addProtocol(PROTOCOL_NAME_1, false); + + fire(createEvent(DeploymentFieldWithContainerAndProtocolReferences.class)); + + CallMap spi = getManager().resolve(CallMap.class); + Assert.assertTrue(spi.wasCalled(ApplicationArchiveProcessor.class)); + Assert.assertTrue(spi.wasCalled(AuxiliaryArchiveAppender.class)); + Assert.assertTrue(spi.wasCalled(AuxiliaryArchiveProcessor.class)); + + verifyScenario("_DEFAULT_"); + } @Test public void shouldNotCallPackagingSPIsOnNonTestableArchive() throws Exception @@ -187,6 +204,22 @@ public void shouldNotCallPackagingSPIsOnNonTestableArchive() throws Exception verifyScenario("_DEFAULT_"); } + + @Test + public void shouldNotCallPackagingSPIsOnExcludeServicesArchive() throws Exception + { + addContainer("test-contianer").getContainerConfiguration().setMode("suite"); + addProtocol(PROTOCOL_NAME_1, true); + + fire(createEvent(DeploymentExcludeServicesWithDefaults.class)); + + CallMap spi = getManager().resolve(CallMap.class); + Assert.assertFalse(spi.wasCalled(ApplicationArchiveProcessor.class)); + Assert.assertFalse(spi.wasCalled(AuxiliaryArchiveAppender.class)); + Assert.assertFalse(spi.wasCalled(AuxiliaryArchiveProcessor.class)); + + verifyScenario("_DEFAULT_"); + } @Test public void shouldAllowNonManagedDeploymentOnCustomContainer() throws Exception @@ -208,7 +241,7 @@ public void shouldAllowMultipleSameNamedArchiveDeploymentWithDifferentTargets() verifyScenario("X", "Y"); } - + @Test(expected = ValidationException.class) public void shouldThrowExceptionOnMissingContainerReference() throws Exception { @@ -422,6 +455,17 @@ public static JavaArchive deploy() return ShrinkWrap.create(JavaArchive.class); } } + + private static class DeploymentExcludeServicesWithDefaults + { + @SuppressWarnings("unused") + @Deployment + @ExcludeServices + public static JavaArchive deploy() + { + return ShrinkWrap.create(JavaArchive.class); + } + } private static class DeploymentWithContainerReference { @@ -443,6 +487,15 @@ public static JavaArchive deploy() } } + private static class DeploymentFieldWithContainerAndProtocolReferences + { + @SuppressWarnings("unused") + @Deployment + @TargetsContainer("test-container") + @OverProtocol(PROTOCOL_NAME_1) + public static JavaArchive deployment = ShrinkWrap.create(JavaArchive.class); + } + private static class DeploymentManagedWithCustomContainerReference { @SuppressWarnings("unused")