Class TestNGAdminIntegrationSetup

java.lang.Object
org.springframework.test.context.testng.AbstractTestNGSpringContextTests
org.broadleafcommerce.test.TestNGAdminIntegrationSetup
All Implemented Interfaces:
org.springframework.beans.factory.Aware, org.springframework.context.ApplicationContextAware, org.testng.IHookable, org.testng.ITestNGListener
Direct Known Subclasses:
AdminPermissionTest, AdminRoleTest, AdminUserTest

@BroadleafAdminIntegrationTest @TestExecutionListeners({org.springframework.test.context.transaction.TransactionalTestExecutionListener.class,org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener.class,org.springframework.test.context.support.DependencyInjectionTestExecutionListener.class}) public abstract class TestNGAdminIntegrationSetup extends org.springframework.test.context.testng.AbstractTestNGSpringContextTests
Base TestNG support class used for Broadleaf Admin tests. This is slightly different than the normal AbstractTestNGSpringContextTests in that this also includes the other default TestExecutionListeners in order to use @Transactional in test methods, while not marking the entire test as @Transactional (like in TestNGTransactionalAdminIntegrationSetup.
Author:
Phillip Verheyden (phillipuniverse)
See Also:
  • Field Summary

    Fields inherited from class org.springframework.test.context.testng.AbstractTestNGSpringContextTests

    applicationContext, logger
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    This was added as a result of update to 7.0 with new spring, hdsqldb, testng, surefire and maybe something else So now spring test framework caches application context and so when some test is starting it will check if needs to create a new context or can use cached.

    Methods inherited from class org.springframework.test.context.testng.AbstractTestNGSpringContextTests

    run, setApplicationContext, springTestContextAfterTestClass, springTestContextAfterTestMethod, springTestContextBeforeTestClass, springTestContextBeforeTestMethod, springTestContextPrepareTestInstance

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • TestNGAdminIntegrationSetup

      public TestNGAdminIntegrationSetup()
  • Method Details

    • reSetApplicationContext

      @BeforeClass(alwaysRun=true, dependsOnMethods="springTestContextPrepareTestInstance") public void reSetApplicationContext()
      This was added as a result of update to 7.0 with new spring, hdsqldb, testng, surefire and maybe something else So now spring test framework caches application context and so when some test is starting it will check if needs to create a new context or can use cached. Seems this basically depends on @ContextHierarchy and @ContextConfiguration and maybe their combination. Now we do have some ApplicationContextAware implementations that provide access to a context via static method, so they store it in static variable. Lets assume situation TestA is running, as it is the first application context(lest name it contextA) will be created for it. We have DefaultPostLoaderDao that not only caches context in its static variable but also acts as a singleton and also caches its instance in static variable. If it happens that during TestA run there will be invocation of PostLoaderDao it will have spring context pointing to contextA and PostLoaderDao instance to the one that was get from the contextA. Now TestB is running and let's imaging that new context is created for it. Now PostLoaderDao has application context instance pointing to contextB - beacuse of AppicationContextAware interface, but PostLoaderDao instance is pointing to the one the was created from contextA. The problem here that PostLoader has a references injected and one of them will have a reference to em, and em one way or another will be bound to db connection that in case of in-memory/in-process hsqldb will hold a reference to hsqldb session, that has a reference to database itself. Now test2 does something in transaction, let's say read/query for example. Now inside transaction loader dao is invoked(like DiscreteOrderItem.getSku). In case of transaction is not marked as a readonly and hibernate session flush mode is not set to manual, hibernate will flush and hsqldb session/db will mark tables involved in read as "writing". Now Postloader does findById or whatever query that reference one of the tables that were read in the beginning of the transaction. HSQLDB session/database will check if it has "writing" tables - and it does, it will get associated to corresponding table(sku in this case) hsqldb session And check if the current session and associated are the same, if not it will pause current thread till number of holding "writing lock" tables will not decrement. And because it all happens in one transaction/thread it will hang forever. So this is a defensive mechanism to make sure that application code is always using the lates version of the application context and doesn't have a stale static references. This happens in tests only as in real application there is only 1 context that is created on a startup.