diff --git a/test-framework/src/main/java/org/apache/directory/server/core/integ/CreateDSTestExtension.java b/test-framework/src/main/java/org/apache/directory/server/core/integ/CreateDSTestExtension.java index 3d23c1e811..db123c2506 100644 --- a/test-framework/src/main/java/org/apache/directory/server/core/integ/CreateDSTestExtension.java +++ b/test-framework/src/main/java/org/apache/directory/server/core/integ/CreateDSTestExtension.java @@ -21,6 +21,7 @@ import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.UUID; import org.apache.directory.api.util.FileUtils; @@ -39,42 +40,41 @@ import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class CreateDSTestExtension implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback, AfterAllCallback +public class CreateDSTestExtension extends TypeBasedParameterResolver implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback, AfterAllCallback { private static final Logger LOG = LoggerFactory.getLogger( CreateDSTestExtension.class ); private static final String CLASS_DS = "classDirectoryService"; private static final String METHOD_DS = "methodDirectoryService"; - private void setDirectoryService( ExtensionContext context, String fieldName, DirectoryService directoryService ) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException - { - Class testClass = context.getTestClass().get(); - Field field = testClass.getField( fieldName ); - field.set( null, directoryService ); - } + private static final Namespace TEST_NAMESPACE = Namespace.create( "apacheds-extension" ); - - private DirectoryService getDirectoryService( ExtensionContext context, String fieldName ) + private void setDirectoryService( ExtensionContext context, String fieldName, DirectoryService directoryService ) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Class testClass = context.getTestClass().get(); - Field directoryServiceField = testClass.getField( fieldName ); - - if ( directoryServiceField != null ) + // Tests that extend AbstractLdapTestUnit, or have similarly named static variables + if ( testClassContainsField( context, fieldName ) ) { - return ( DirectoryService ) directoryServiceField.get( testClass ); - } - else - { - return null; + Class testClass = context.getRequiredTestClass(); + Field field = testClass.getField( fieldName ); + field.set( null, directoryService ); } } - - + + private boolean testClassContainsField( ExtensionContext context, String fieldName ) + { + Class testClass = context.getRequiredTestClass(); + return Arrays.stream( testClass.getFields() ) + .anyMatch( field -> field.getName().equals( fieldName ) ); + } + /** * In the BeforeALl method, we will create a DirectoryService instance that will be used by all * the tests for this class. This DirectoryService will be destroyed in the AfterAll callback. @@ -141,6 +141,8 @@ public void beforeAll( ExtensionContext context ) throws Exception LdapServer classLdapServer = ServerAnnotationProcessor.createLdapServer( createLapServer, directoryService ); } + // store the DS instance in the test context + getStore( context ).put( CLASS_DS, directoryService ); // The created DS is now stored in the test class setDirectoryService( context, CLASS_DS, directoryService ); @@ -148,15 +150,13 @@ public void beforeAll( ExtensionContext context ) throws Exception /** - * We have to shutown the global DS now + * We have to shutdown the global DS now */ @Override public void afterAll( ExtensionContext context ) throws Exception { LOG.trace( "Shutting down global directory service" ); - Class testClass = context.getTestClass().get(); - Field directoryServiceField = testClass.getField( CLASS_DS ); - DirectoryService directoryService = ( DirectoryService ) directoryServiceField.get( testClass ); + DirectoryService directoryService = getStore( context ).get( CLASS_DS, DirectoryService.class ); Method shutdownMethod = directoryService.getClass().getDeclaredMethod( "shutdown", new Class[]{} ); shutdownMethod.invoke( directoryService ); @@ -171,13 +171,13 @@ public void afterAll( ExtensionContext context ) throws Exception public void beforeEach( ExtensionContext context ) throws Exception { // Don't run the test if the @Disabled annotation is used - if ( context.getTestMethod().get().getAnnotation( Disabled.class ) != null ) + if ( context.getRequiredTestMethod().getAnnotation( Disabled.class ) != null ) { return; } - AnnotatedElement methodAnnotation = context.getTestMethod().get(); - AnnotatedElement classAnnotation = context.getTestClass().get(); + AnnotatedElement methodAnnotation = context.getRequiredTestMethod(); + AnnotatedElement classAnnotation = context.getRequiredTestClass(); DirectoryService directoryService; CreateDS createDs = methodAnnotation.getAnnotation( CreateDS.class ); @@ -190,11 +190,14 @@ public void beforeEach( ExtensionContext context ) throws Exception DSAnnotationProcessor.applyLdifs( methodAnnotation, methodAnnotation.getClass().getName(), directoryService ); setDirectoryService( context, METHOD_DS, directoryService ); + + // store the DS instance in the test context + getMethodStore( context ).put( METHOD_DS, directoryService ); } else { // We don't have a local DS, so use the global one - directoryService = getDirectoryService( context, CLASS_DS ); + directoryService = getStore( context ).get( CLASS_DS, DirectoryService.class ); DSAnnotationProcessor.applyLdifs( methodAnnotation, methodAnnotation.getClass().getName(), directoryService ); } @@ -205,17 +208,43 @@ public void beforeEach( ExtensionContext context ) throws Exception public void afterEach( ExtensionContext context ) throws Exception { LOG.trace( "Shutting down directory service" ); - Class testClass = context.getTestClass().get(); - Field directoryServiceField = testClass.getField( METHOD_DS ); - DirectoryService directoryService = ( DirectoryService ) directoryServiceField.get( testClass ); - + ExtensionContext.Store store = getMethodStore( context ); + DirectoryService directoryService = getMethodStore( context ).get( METHOD_DS, DirectoryService.class ); + if ( directoryService != null ) { Method shutdownMethod = directoryService.getClass().getDeclaredMethod( "shutdown", new Class[]{} ); shutdownMethod.invoke( directoryService ); FileUtils.deleteDirectory( directoryService.getInstanceLayout().getInstanceDirectory() ); - + + // Remove instance from context setDirectoryService( context, METHOD_DS, null ); + store.remove( METHOD_DS ); + } + } + + @Override + public DirectoryService resolveParameter( ParameterContext parameterContext, ExtensionContext extensionContext ) throws ParameterResolutionException + { + DirectoryService directoryService = getMethodStore( extensionContext ).get( METHOD_DS, DirectoryService.class ); + if ( directoryService == null ) + { + directoryService = getStore( extensionContext ).get( CLASS_DS, DirectoryService.class ); } + if ( directoryService == null ) + { + throw new ParameterResolutionException( "Failed to resolve DirectoryService parameter" ); + } + return directoryService; + } + + private ExtensionContext.Store getStore( ExtensionContext extensionContext ) + { + return extensionContext.getStore( TEST_NAMESPACE ); + } + + private ExtensionContext.Store getMethodStore( ExtensionContext extensionContext ) + { + return extensionContext.getStore( TEST_NAMESPACE.append( extensionContext.getUniqueId() ) ); } } diff --git a/test-framework/src/test/java/org/apache/directory/server/core/integ/TestNoParentClass.java b/test-framework/src/test/java/org/apache/directory/server/core/integ/TestNoParentClass.java new file mode 100644 index 0000000000..a5549b74d3 --- /dev/null +++ b/test-framework/src/test/java/org/apache/directory/server/core/integ/TestNoParentClass.java @@ -0,0 +1,53 @@ +package org.apache.directory.server.core.integ; + +import org.apache.directory.api.ldap.model.name.Dn; +import org.apache.directory.server.core.annotations.ApplyLdifs; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.api.DirectoryService; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith( CreateDSTestExtension.class ) +@CreateDS(name = "ClassDS") +@ApplyLdifs({ + "dn: cn=testClassA,ou=system", + "objectClass: person", + "cn: testClassA", + "sn: sn_testClassA", + + "dn: cn=testClassA2,ou=system", + "objectClass: person", + "cn: testClassA2", + "sn: sn_testClassA2" }) +public class TestNoParentClass { + + @Test + @CreateDS(name = "testDS") + @ApplyLdifs({ + "dn: cn=testMethodA,ou=system", + "objectClass: person", + "cn: testMethodA", + "sn: sn_testMethodA" }) + public void testWithFactoryAnnotation(DirectoryService directoryService) throws Exception + { + assertTrue( directoryService.getAdminSession().exists( new Dn( "cn=testClassA,ou=system" ) ) ); + assertTrue( directoryService.getAdminSession().exists( new Dn( "cn=testMethodA,ou=system" ) ) ); + } + + @Test + @ApplyLdifs({ + "dn: cn=testMethodWithApplyLdif,ou=system", + "objectClass: person", + "cn: testMethodWithApplyLdif", + "sn: sn_testMethodWithApplyLdif" }) + public void testWithoutFactoryAnnotation(DirectoryService directoryService) throws Exception + { + assertTrue( directoryService.getAdminSession().exists( new Dn( "cn=testClassA,ou=system" ) ) ); + assertTrue( directoryService.getAdminSession().exists( new Dn( "cn=testClassA2,ou=system" ) ) ); + assertFalse( directoryService.getAdminSession().exists( new Dn( "cn=testMethodA,ou=system" ) ) ); + assertTrue( directoryService.getAdminSession().exists( new Dn( "cn=testMethodWithApplyLdif,ou=system" ) ) ); + } +}