diff options
Diffstat (limited to 'feature-session-persistence/src/test')
-rw-r--r-- | feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java | 73 | ||||
-rw-r--r-- | feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrCloserTest.java | 100 | ||||
-rw-r--r-- | feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java | 335 | ||||
-rw-r--r-- | feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java (renamed from feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchemaTest.java) | 43 | ||||
-rw-r--r-- | feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java | 121 | ||||
-rw-r--r-- | feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java | 984 | ||||
-rw-r--r-- | feature-session-persistence/src/test/resources/META-INF/persistence.xml | 12 | ||||
-rw-r--r-- | feature-session-persistence/src/test/resources/feature-session-persistence.properties | 3 |
8 files changed, 957 insertions, 714 deletions
diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java index c7fa8486..7624d043 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java @@ -36,28 +36,28 @@ public class DroolsSessionEntityTest { DroolsSessionEntity e = makeEnt("mynameA", 1); DroolsSessionEntity e2 = makeEnt("mynameA", 2); - + // session id is not part of hash code assertTrue(e.hashCode() == e2.hashCode()); - + // diff sess name e2 = makeEnt("mynameB", 1); assertTrue(e.hashCode() != e2.hashCode()); } /** - * Ensures that hashCode() functions as expected when the getXxx methods - * are overridden. + * Ensures that hashCode() functions as expected when the getXxx methods are + * overridden. */ @Test public void testHashCode_Subclass() { DroolsSessionEntity e = makeEnt2("mynameA", 1); DroolsSessionEntity e2 = makeEnt("mynameA", 2); - + // session id is not part of hash code assertTrue(e.hashCode() == e2.hashCode()); - + // diff sess name e2 = makeEnt("mynameB", 1); assertTrue(e.hashCode() != e2.hashCode()); @@ -68,10 +68,10 @@ public class DroolsSessionEntityTest { DroolsSessionEntity e = makeEnt("mynameZ", 1); assertEquals("mynameZ", e.getSessionName()); - + e.setSessionName("another"); assertEquals("another", e.getSessionName()); - + // others unchanged assertEquals(1, e.getSessionId()); } @@ -81,10 +81,10 @@ public class DroolsSessionEntityTest { DroolsSessionEntity e = makeEnt("mynameA", 1); assertEquals(1, e.getSessionId()); - + e.setSessionId(20); assertEquals(20, e.getSessionId()); - + // others unchanged assertEquals("mynameA", e.getSessionName()); } @@ -92,13 +92,13 @@ public class DroolsSessionEntityTest { @Test public void testGetCreatedDate_testSetCreatedDate_testGetUpdatedDate_testSetUpdatedDate() { DroolsSessionEntity e = new DroolsSessionEntity(); - + Date crtdt = new Date(System.currentTimeMillis() - 100); e.setCreatedDate(crtdt); Date updt = new Date(System.currentTimeMillis() - 200); e.setUpdatedDate(updt); - + assertEquals(crtdt, e.getCreatedDate()); assertEquals(updt, e.getUpdatedDate()); } @@ -106,16 +106,16 @@ public class DroolsSessionEntityTest { @Test public void testEqualsObject() { DroolsSessionEntity e = makeEnt("mynameA", 1); - + // reflexive assertTrue(e.equals(e)); DroolsSessionEntity e2 = makeEnt("mynameA", 2); - + // session id is not part of hash code assertTrue(e.equals(e2)); assertTrue(e.equals(e2)); - + // diff sess name e2 = makeEnt("mynameB", 1); assertFalse(e.equals(e2)); @@ -123,22 +123,22 @@ public class DroolsSessionEntityTest { } /** - * Ensures that equals() functions as expected when the getXxx methods - * are overridden. + * Ensures that equals() functions as expected when the getXxx methods are + * overridden. */ @Test public void testEqualsObject_Subclass() { DroolsSessionEntity e = makeEnt2("mynameA", 1); - + // reflexive assertTrue(e.equals(e)); DroolsSessionEntity e2 = makeEnt("mynameA", 2); - + // session id is not part of hash code assertTrue(e.equals(e2)); assertTrue(e.equals(e2)); - + // diff sess name e2 = makeEnt("mynameB", 1); assertFalse(e.equals(e2)); @@ -148,34 +148,39 @@ public class DroolsSessionEntityTest { @Test public void testToString() { DroolsSessionEntity e = makeEnt("mynameA", 23); - + assertEquals("{name=mynameA, id=23}", e.toString()); } /** - * Makes a session Entity. The parameters are stored into the Entity - * object via the setXxx methods. - * @param sessnm session name - * @param sessid session id + * Makes a session Entity. The parameters are stored into the Entity object + * via the setXxx methods. + * + * @param sessnm + * session name + * @param sessid + * session id * @return a new session Entity */ private DroolsSessionEntity makeEnt(String sessnm, long sessid) { DroolsSessionEntity e = new DroolsSessionEntity(); - + e.setSessionName(sessnm); e.setSessionId(sessid); - + return e; } - + /** - * Makes a session Entity that overrides the getXxx methods. The - * parameters that are provided are returned by the overridden methods, - * but they are <i>not</i> stored into the Entity object via the setXxx - * methods. - * @param sessnm session name - * @param sessid session id + * Makes a session Entity that overrides the getXxx methods. The parameters + * that are provided are returned by the overridden methods, but they are + * <i>not</i> stored into the Entity object via the setXxx methods. + * + * @param sessnm + * session name + * @param sessid + * session id * @return a new session Entity */ @SuppressWarnings("serial") diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrCloserTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrCloserTest.java deleted file mode 100644 index 7350a7f7..00000000 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrCloserTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * feature-session-persistence - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.drools.persistence; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import javax.persistence.EntityManager; - -import org.junit.Before; -import org.junit.Test; -import org.onap.policy.drools.persistence.EntityMgrCloser; - -public class EntityMgrCloserTest { - - private EntityManager mgr; - - - @Before - public void setUp() throws Exception { - mgr = mock(EntityManager.class); - } - - - /** - * Verifies that the constructor does not do anything extra before - * being closed. - */ - @Test - public void testEntityMgrCloser() { - EntityMgrCloser c = new EntityMgrCloser(mgr); - - // verify not closed yet - verify(mgr, never()).close(); - - c.close(); - } - - /** - * Verifies that the manager gets closed when close() is invoked. - */ - @Test - public void testClose() { - EntityMgrCloser c = new EntityMgrCloser(mgr); - - c.close(); - - // should be closed - verify(mgr).close(); - } - - /** - * Ensures that the manager gets closed when "try" block exits normally. - */ - @Test - public void testClose_TryWithoutExcept() { - try(EntityMgrCloser c = new EntityMgrCloser(mgr)) { - - } - - verify(mgr).close(); - } - - /** - * Ensures that the manager gets closed when "try" block throws an - * exception. - */ - @Test - public void testClose_TryWithExcept() { - try { - try(EntityMgrCloser c = new EntityMgrCloser(mgr)) { - throw new Exception("expected exception"); - } - - } catch (Exception e) { - } - - verify(mgr).close(); - } - -} diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java index 0165b1e4..9c9a30b3 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java @@ -25,37 +25,69 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doThrow; import javax.persistence.EntityManager; -import javax.persistence.EntityTransaction; +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.NotSupportedException; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.SystemException; +import javax.transaction.UserTransaction; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; -import org.onap.policy.drools.persistence.EntityMgrTrans; +import org.onap.policy.drools.persistence.EntityMgrTrans.EntityMgrException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class EntityMgrTransTest { - - private EntityTransaction trans; + + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); + + private static UserTransaction savetrans; + + private UserTransaction trans; private EntityManager mgr; + @BeforeClass + public static void setUpBeforeClass() { + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + + savetrans = EntityMgrTrans.getUserTrans(); + } + + @AfterClass + public static void tearDownAfterClass() { + EntityMgrTrans.setUserTrans(savetrans); + } + @Before public void setUp() throws Exception { - trans = mock(EntityTransaction.class); + trans = mock(UserTransaction.class); mgr = mock(EntityManager.class); - - when(mgr.getTransaction()).thenReturn(trans); - } - + EntityMgrTrans.setUserTrans(trans); + } /** * Verifies that the constructor starts a transaction, but does not do * anything extra before being closed. + * + * @throws Exception */ @Test - public void testEntityMgrTrans() { + public void testEntityMgrTrans() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + EntityMgrTrans t = new EntityMgrTrans(mgr); - + // verify that transaction was started verify(trans).begin(); @@ -63,20 +95,50 @@ public class EntityMgrTransTest { verify(trans, never()).commit(); verify(trans, never()).rollback(); verify(mgr, never()).close(); - + t.close(); } + @Test(expected = EntityMgrException.class) + public void testEntityMgrTrans_RtEx() throws Exception { + + doThrow(new IllegalArgumentException("expected exception")).when(trans).begin(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + + } + } + + @Test(expected = EntityMgrException.class) + public void testEntityMgrTrans_NotSuppEx() throws Exception { + + doThrow(new NotSupportedException("expected exception")).when(trans).begin(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + + } + } + + @Test(expected = EntityMgrException.class) + public void testEntityMgrTrans_SysEx() throws Exception { + + doThrow(new SystemException("expected exception")).when(trans).begin(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + + } + } + /** - * Verifies that the transaction is rolled back and the manager is - * closed when and a transaction is active. + * Verifies that the transaction is rolled back and the manager is closed + * when and a transaction is active. */ @Test - public void testClose_Active() { + public void testClose_Active() throws Exception { EntityMgrTrans t = new EntityMgrTrans(mgr); - when(trans.isActive()).thenReturn(true); - + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + t.close(); // closed and rolled back, but not committed @@ -87,14 +149,14 @@ public class EntityMgrTransTest { /** * Verifies that the manager is closed, but that the transaction is - * <i>not</i> rolled back and when and no transaction is active. + * <i>not</i> rolled back when and no transaction is active. */ @Test - public void testClose_Inactive() { + public void testClose_Inactive() throws Exception { EntityMgrTrans t = new EntityMgrTrans(mgr); - when(trans.isActive()).thenReturn(false); - + when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + t.close(); // closed, but not committed or rolled back @@ -103,16 +165,49 @@ public class EntityMgrTransTest { verify(trans, never()).rollback(); } + @Test(expected = EntityMgrException.class) + public void testClose_IllStateEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new IllegalStateException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + + } + } + + @Test(expected = EntityMgrException.class) + public void testClose_SecEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SecurityException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + + } + } + + @Test(expected = EntityMgrException.class) + public void testClose_SysEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SystemException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + + } + } + /** - * Verifies that the manager is closed and the transaction rolled back - * when "try" block exits normally and a transaction is active. + * Verifies that the manager is closed and the transaction rolled back when + * "try" block exits normally and a transaction is active. */ @Test - public void testClose_TryWithoutExcept_Active() { - when(trans.isActive()).thenReturn(true); - - try(EntityMgrTrans t = new EntityMgrTrans(mgr)) { - + public void testClose_TryWithoutExcept_Active() throws Exception { + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + } // closed and rolled back, but not committed @@ -123,15 +218,16 @@ public class EntityMgrTransTest { /** * Verifies that the manager is closed, but that the transaction is - * <i>not</i> rolled back when "try" block exits normally and no - * transaction is active. + * <i>not</i> rolled back when "try" block exits normally and no transaction + * is active. */ @Test - public void testClose_TryWithoutExcept_Inactive() { - when(trans.isActive()).thenReturn(false); - - try(EntityMgrTrans t = new EntityMgrTrans(mgr)) { - + public void testClose_TryWithoutExcept_Inactive() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + } // closed, but not rolled back or committed @@ -141,19 +237,21 @@ public class EntityMgrTransTest { } /** - * Verifies that the manager is closed and the transaction rolled back - * when "try" block throws an exception and a transaction is active. + * Verifies that the manager is closed and the transaction rolled back when + * "try" block throws an exception and a transaction is active. */ @Test - public void testClose_TryWithExcept_Active() { - when(trans.isActive()).thenReturn(true); - + public void testClose_TryWithExcept_Active() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + try { - try(EntityMgrTrans t = new EntityMgrTrans(mgr)) { - throw new Exception("expected exception"); + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + throw new SystemException("expected exception"); } - + } catch (Exception e) { + logger.trace("expected exception", e); } // closed and rolled back, but not committed @@ -168,15 +266,17 @@ public class EntityMgrTransTest { * transaction is active. */ @Test - public void testClose_TryWithExcept_Inactive() { - when(trans.isActive()).thenReturn(false); - + public void testClose_TryWithExcept_Inactive() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + try { - try(EntityMgrTrans t = new EntityMgrTrans(mgr)) { - throw new Exception("expected exception"); + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + throw new SystemException("expected exception"); } - + } catch (Exception e) { + logger.trace("expected exception", e); } // closed, but not rolled back or committed @@ -186,20 +286,23 @@ public class EntityMgrTransTest { } /** - * Verifies that commit() only commits, and that the subsequent close() - * does not re-commit. + * Verifies that commit() only commits, and that the subsequent close() does + * not re-commit. */ @Test - public void testCommit() { + public void testCommit() throws Exception { EntityMgrTrans t = new EntityMgrTrans(mgr); - + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + t.commit(); - + + when(trans.getStatus()).thenReturn(Status.STATUS_COMMITTED); + // committed, but not closed or rolled back verify(trans).commit(); verify(trans, never()).rollback(); verify(mgr, never()).close(); - + // closed, but not re-committed t.close(); @@ -207,21 +310,90 @@ public class EntityMgrTransTest { verify(mgr).close(); } + @Test(expected = EntityMgrException.class) + public void testCommit_SecEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SecurityException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } + + @Test(expected = EntityMgrException.class) + public void testCommit_IllStateEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new IllegalStateException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } + + @Test(expected = EntityMgrException.class) + public void testCommit_RbEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new RollbackException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } + + @Test(expected = EntityMgrException.class) + public void testCommit_HmEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new HeuristicMixedException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } + + @Test(expected = EntityMgrException.class) + public void testCommit_HrbEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new HeuristicRollbackException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } + + @Test(expected = EntityMgrException.class) + public void testCommit_SysEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SystemException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } + /** - * Verifies that rollback() only rolls back, and that the subsequent - * close() does not re-roll back. + * Verifies that rollback() only rolls back, and that the subsequent close() + * does not re-roll back. */ @Test - public void testRollback() { + public void testRollback() throws Exception { EntityMgrTrans t = new EntityMgrTrans(mgr); - + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + t.rollback(); - + + when(trans.getStatus()).thenReturn(Status.STATUS_ROLLEDBACK); + // rolled back, but not closed or committed verify(trans, never()).commit(); verify(trans).rollback(); verify(mgr, never()).close(); - + // closed, but not re-rolled back t.close(); @@ -229,4 +401,45 @@ public class EntityMgrTransTest { verify(mgr).close(); } + @Test(expected = EntityMgrException.class) + public void testRollback_IllStateEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new IllegalStateException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.rollback(); + } + } + + @Test(expected = EntityMgrException.class) + public void testRollback_SecEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SecurityException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.rollback(); + } + } + + @Test(expected = EntityMgrException.class) + public void testRollback_SysEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SystemException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.rollback(); + } + } + + @Test + public void testEntityMgrException() { + SecurityException secex = new SecurityException("expected exception"); + EntityMgrException ex = new EntityMgrException(secex); + + assertEquals(secex, ex.getCause()); + + } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchemaTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java index d9e25b28..a0af2e6c 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchemaTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java @@ -26,31 +26,44 @@ import java.util.Map; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Generates the schema DDL files. */ -public class GenSchemaTest { - +public class GenSchema { + + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); + private EntityManagerFactory emf; - - /* - * This is a JUnit which is provided as a utility for producing a basic - * ddl schema file in the sql directory. + /** + * Opens the EMF, which generates the schema, as a side-effect. * - * To run this simple add @Test ahead of the method and then run this - * as a JUnit. + * @throws Exception */ - public void generate() throws Exception { + private GenSchema() throws Exception { Map<String, Object> propMap = new HashMap<>(); propMap.put("javax.persistence.jdbc.driver", "org.h2.Driver"); - propMap.put("javax.persistence.jdbc.url", - "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); - - emf = Persistence.createEntityManagerFactory( - "schemaDroolsPU", propMap); - + propMap.put("javax.persistence.jdbc.url", "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); + + emf = Persistence.createEntityManagerFactory("schemaDroolsPU", propMap); + emf.close(); } + + /** + * This is is provided as a utility for producing a basic ddl schema file in + * the sql directory. + */ + public static void main(String[] args) { + try { + new GenSchema(); + + } catch (Exception e) { + logger.error("failed to generate schema", e); + } + } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java index 792e6f8b..dd601dd3 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java @@ -37,31 +37,35 @@ import javax.persistence.Persistence; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.drools.persistence.DroolsSessionEntity; import org.onap.policy.drools.persistence.EntityMgrTrans; import org.onap.policy.drools.persistence.JpaDroolsSessionConnector; public class JpaDroolsSessionConnectorTest { - + private EntityManagerFactory emf; private JpaDroolsSessionConnector conn; - + + @BeforeClass + public static void setUpBeforeClass() { + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + } @Before public void setUp() throws Exception { Map<String, Object> propMap = new HashMap<>(); propMap.put("javax.persistence.jdbc.driver", "org.h2.Driver"); - propMap.put("javax.persistence.jdbc.url", - "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); - - emf = Persistence.createEntityManagerFactory( - "junitDroolsSessionEntityPU", propMap); - + propMap.put("javax.persistence.jdbc.url", "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); + + emf = Persistence.createEntityManagerFactory("junitDroolsSessionEntityPU", propMap); + conn = new JpaDroolsSessionConnector(emf); } - + @After public void tearDown() { // this will cause the memory db to be dropped @@ -73,60 +77,57 @@ public class JpaDroolsSessionConnectorTest { /* * Load up the DB with some data. */ - + addSession("nameA", 10); addSession("nameY", 20); - - + /* * Now test the functionality. */ - + // not found - assertNull( conn.get("unknown")); - - assertEquals("{name=nameA, id=10}", - conn.get("nameA").toString()); - - assertEquals("{name=nameY, id=20}", - conn.get("nameY").toString()); + assertNull(conn.get("unknown")); + + assertEquals("{name=nameA, id=10}", conn.get("nameA").toString()); + + assertEquals("{name=nameY, id=20}", conn.get("nameY").toString()); } - - @Test(expected = RuntimeException.class) + + @Test(expected = IllegalArgumentException.class) public void testGet_NewEx() { EntityManagerFactory emf = mock(EntityManagerFactory.class); EntityManager em = mock(EntityManager.class); - + when(emf.createEntityManager()).thenReturn(em); - when(em.getTransaction()).thenThrow(new RuntimeException("expected exception")); + when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); conn = new JpaDroolsSessionConnector(emf); conn.get("xyz"); } - - @Test(expected = RuntimeException.class) + + @Test(expected = IllegalArgumentException.class) public void testGet_FindEx() { EntityManagerFactory emf = mock(EntityManagerFactory.class); EntityManager em = mock(EntityManager.class); EntityTransaction tr = mock(EntityTransaction.class); - + when(emf.createEntityManager()).thenReturn(em); when(em.getTransaction()).thenReturn(tr); - when(em.find(any(), any())).thenThrow(new RuntimeException("expected exception")); + when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); new JpaDroolsSessionConnector(emf).get("xyz"); } - - @Test(expected = RuntimeException.class) + + @Test(expected = IllegalArgumentException.class) public void testGet_FindEx_CloseEx() { EntityManagerFactory emf = mock(EntityManagerFactory.class); EntityManager em = mock(EntityManager.class); EntityTransaction tr = mock(EntityTransaction.class); - + when(emf.createEntityManager()).thenReturn(em); when(em.getTransaction()).thenReturn(tr); - when(em.find(any(), any())).thenThrow(new RuntimeException("expected exception")); - doThrow(new RuntimeException("expected exception #2")).when(em).close(); + when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); + doThrow(new IllegalArgumentException("expected exception #2")).when(em).close(); new JpaDroolsSessionConnector(emf).get("xyz"); } @@ -134,70 +135,64 @@ public class JpaDroolsSessionConnectorTest { @Test public void testReplace_Existing() { addSession("nameA", 10); - - DroolsSessionEntity sess = - new DroolsSessionEntity("nameA", 30); - + + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + conn.replace(sess); // id should be changed - assertEquals(sess.toString(), - conn.get("nameA").toString()); + assertEquals(sess.toString(), conn.get("nameA").toString()); } @Test public void testReplace_New() { - DroolsSessionEntity sess = - new DroolsSessionEntity("nameA", 30); - + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + conn.replace(sess); - assertEquals(sess.toString(), - conn.get("nameA").toString()); + assertEquals(sess.toString(), conn.get("nameA").toString()); } @Test public void testAdd() { - DroolsSessionEntity sess = - new DroolsSessionEntity("nameA", 30); - + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + conn.replace(sess); - assertEquals(sess.toString(), - conn.get("nameA").toString()); + assertEquals(sess.toString(), conn.get("nameA").toString()); } @Test public void testUpdate() { addSession("nameA", 10); - - DroolsSessionEntity sess = - new DroolsSessionEntity("nameA", 30); - + + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + conn.replace(sess); // id should be changed - assertEquals("{name=nameA, id=30}", - conn.get("nameA").toString()); + assertEquals("{name=nameA, id=30}", conn.get("nameA").toString()); } - /** * Adds a session to the DB. - * @param sessnm session name - * @param sessid session id + * + * @param sessnm + * session name + * @param sessid + * session id */ private void addSession(String sessnm, int sessid) { EntityManager em = emf.createEntityManager(); - - try(EntityMgrTrans trans = new EntityMgrTrans(em)) { + + try (EntityMgrTrans trans = new EntityMgrTrans(em)) { DroolsSessionEntity ent = new DroolsSessionEntity(); - + ent.setSessionName(sessnm); ent.setSessionId(sessid); - + em.persist(ent); - + trans.commit(); } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java index e73031dd..a7c33aba 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java @@ -24,8 +24,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; @@ -33,11 +34,11 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.doThrow; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.net.UnknownHostException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -46,12 +47,19 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; +import javax.transaction.UserTransaction; +import org.apache.commons.dbcp2.BasicDataSource; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -64,34 +72,32 @@ import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieSessionConfiguration; import org.mockito.ArgumentCaptor; -import org.onap.policy.drools.persistence.DroolsPersistenceProperties; -import org.onap.policy.drools.persistence.DroolsSession; -import org.onap.policy.drools.persistence.DroolsSessionConnector; -import org.onap.policy.drools.persistence.PersistenceFeature; import org.onap.policy.drools.core.PolicyContainer; import org.onap.policy.drools.core.PolicySession; +import org.onap.policy.drools.core.PolicySession.ThreadModel; +import org.onap.policy.drools.persistence.PersistenceFeature.PersistenceFeatureException; +import org.onap.policy.drools.persistence.PersistenceFeature.PersistentThreadModel; import org.onap.policy.drools.system.PolicyController; - -import bitronix.tm.BitronixTransactionManager; -import bitronix.tm.Configuration; -import bitronix.tm.resource.jdbc.PoolingDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PersistenceFeatureTest { - private static final String JDBC_DATASRC = "fake.datasource"; + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); + private static final String JDBC_DRIVER = "fake.driver"; private static final String JDBC_URL = "fake.url"; private static final String JDBC_USER = "fake.user"; private static final String JDBC_PASSWD = "fake.password"; + private static final String JTA_OSDIR = "target"; private static final String SRC_TEST_RESOURCES = "src/test/resources"; private static Properties stdprops; - private DroolsSessionConnector jpa; + private JpaDroolsSessionConnector jpa; private DroolsSession sess; - private PoolingDataSource pds; private KieSession kiesess; - private Properties dsprops; + private BasicDataSource bds; private EntityManagerFactory emf; private Connection conn; private Properties props; @@ -101,40 +107,38 @@ public class PersistenceFeatureTest { private KieBase kiebase; private KieStoreServices kiestore; private KieContainer kiecont; - private Configuration bitcfg; - private BitronixTransactionManager bittrans; + private TransactionManager transmgr; + private UserTransaction usertrans; + private TransactionSynchronizationRegistry transreg; private PolicyController polctlr; private PolicyContainer polcont; private PolicySession polsess; private PersistenceFeature.Factory fact; - + private PersistenceFeature feat; - @BeforeClass public static void setUpBeforeClass() throws Exception { stdprops = new Properties(); - stdprops.put(DroolsPersistenceProperties.DB_DATA_SOURCE, JDBC_DATASRC); stdprops.put(DroolsPersistenceProperties.DB_DRIVER, JDBC_DRIVER); stdprops.put(DroolsPersistenceProperties.DB_URL, JDBC_URL); stdprops.put(DroolsPersistenceProperties.DB_USER, JDBC_USER); stdprops.put(DroolsPersistenceProperties.DB_PWD, JDBC_PASSWD); + stdprops.put(DroolsPersistenceProperties.JTA_OBJECTSTORE_DIR, JTA_OSDIR); stdprops.put(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "50"); - } - @AfterClass - public static void tearDownAfterClass() throws Exception { + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); } @Before public void setUp() throws Exception { - jpa = mock(DroolsSessionConnector.class); + jpa = mock(JpaDroolsSessionConnector.class); sess = mock(DroolsSession.class); - pds = mock(PoolingDataSource.class); + bds = mock(BasicDataSource.class); + emf = mock(EntityManagerFactory.class); kiesess = mock(KieSession.class); - dsprops = new Properties(); - emf = null; conn = null; props = new Properties(); kiesvc = mock(KieServices.class); @@ -143,45 +147,56 @@ public class PersistenceFeatureTest { kiebase = mock(KieBase.class); kiestore = mock(KieStoreServices.class); kiecont = mock(KieContainer.class); - bitcfg = mock(Configuration.class); - bittrans = mock(BitronixTransactionManager.class); + transmgr = mock(TransactionManager.class); + usertrans = mock(UserTransaction.class); + transreg = mock(TransactionSynchronizationRegistry.class); polcont = mock(PolicyContainer.class); polctlr = mock(PolicyController.class); polsess = mock(PolicySession.class); fact = mock(PersistenceFeature.Factory.class); - + feat = new PersistenceFeature(); feat.setFactory(fact); - + props.putAll(stdprops); - - when(pds.getUniqueName()).thenReturn("myds"); - + + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + when(fact.getKieServices()).thenReturn(kiesvc); - when(fact.getTransMgrConfig()).thenReturn(bitcfg); - when(fact.getTransMgr()).thenReturn(bittrans); + when(fact.getTransMgr()).thenReturn(transmgr); + when(fact.getUserTrans()).thenReturn(usertrans); + when(fact.getTransSyncReg()).thenReturn(transreg); when(fact.loadProperties(anyString())).thenReturn(props); - + when(kiesvc.newEnvironment()).thenReturn(kieenv); when(kiesvc.getStoreServices()).thenReturn(kiestore); when(kiesvc.newKieSessionConfiguration()).thenReturn(kiecfg); - + when(polcont.getKieContainer()).thenReturn(kiecont); - + when(polsess.getPolicyContainer()).thenReturn(polcont); - + when(kiecont.getKieBase(anyString())).thenReturn(kiebase); } @After public void tearDown() { // this will cause the in-memory test DB to be dropped - if(conn != null) { - try { conn.close(); } catch (SQLException e) { } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + logger.warn("failed to close connection", e); + } } - if(emf != null) { - try { emf.close(); } catch (Exception e) { } + if (emf != null) { + try { + emf.close(); + } catch (IllegalArgumentException e) { + logger.trace("ignored exception", e); + } } } @@ -196,12 +211,12 @@ public class PersistenceFeatureTest { // force getContainerAdjunct() to be invoked feat.activatePolicySession(polcont, "myname", "mybase"); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); - - assertNotNull( adjcap.getValue()); + + assertNotNull(adjcap.getValue()); } @Test @@ -215,41 +230,66 @@ public class PersistenceFeatureTest { // force getContainerAdjunct() to be invoked feat.activatePolicySession(polcont, "myname", "mybase"); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); - + // return adjunct on next call - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); // force getContainerAdjunct() to be invoked again setUpKie("myname2", 999L, true); feat.activatePolicySession(polcont, "myname2", "mybase"); - + // ensure it isn't invoked again verify(polcont, times(1)).setAdjunct(any(), any()); } @Test + public void testGetContainerAdjunct_WrongType() throws Exception { + + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, true); + + // return false adjunct on next call + when(polcont.getAdjunct(any())).thenReturn("not-a-real-adjunct"); + + // force getContainerAdjunct() to be invoked + setUpKie("myname2", 999L, true); + feat.activatePolicySession(polcont, "myname2", "mybase"); + + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); + + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + + assertNotNull(adjcap.getValue()); + } + + @Test public void testGetSequenceNumber() { assertEquals(1, feat.getSequenceNumber()); } @Test public void testGlobalInit() throws Exception { - when(fact.getHostName()).thenReturn("myhost"); - + feat.globalInit(null, SRC_TEST_RESOURCES); - + // verify that various factory methods were invoked - verify(fact).getHostName(); verify(fact).getKieServices(); - verify(fact).getTransMgrConfig(); verify(fact).loadProperties("src/test/resources/feature-session-persistence.properties"); + } + + @Test(expected = NullPointerException.class) + public void testGlobalInit_IOEx() throws Exception { - verify(bitcfg).setJournal(null); - verify(bitcfg).setServerId("myhost"); + when(fact.loadProperties(anyString())).thenThrow(new IOException("expected exception")); + + feat.globalInit(null, SRC_TEST_RESOURCES); } @Test @@ -259,21 +299,18 @@ public class PersistenceFeatureTest { feat.globalInit(null, SRC_TEST_RESOURCES); feat.beforeActivate(null); - - KieSession s = - feat.activatePolicySession(polcont, "myname", "mybase"); + + KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); verify(kiestore, never()).newKieSession(any(), any(), any()); - + assertEquals(s, kiesess); - + verify(ps).executeUpdate(); - verify(kieenv, times(2)).set(anyString(), any()); - verify(pds).init(); - assertFalse( dsprops.isEmpty()); - + verify(kieenv, times(4)).set(anyString(), any()); + verify(jpa).get("myname"); verify(jpa).replace(any()); } @@ -284,12 +321,12 @@ public class PersistenceFeatureTest { PreparedStatement ps = mockDbConn(5); setUpKie("myname", 999L, true); - + props.remove("persistence.type"); - + feat.beforeStart(null); - - assertNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); verify(ps, never()).executeUpdate(); verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any()); @@ -298,7 +335,7 @@ public class PersistenceFeatureTest { /** * Verifies that a new KIE session is created when there is no existing - * session entity. + * session entity. */ @Test public void testActivatePolicySession_New() throws Exception { @@ -306,27 +343,23 @@ public class PersistenceFeatureTest { mockDbConn(5); setUpKie("noName", 999L, true); - - - KieSession s = - feat.activatePolicySession(polcont, "myname", "mybase"); + + KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any()); verify(kiestore).newKieSession(any(), any(), any()); - + assertEquals(s, kiesess); - verify(kieenv, times(2)).set(anyString(), any()); - verify(pds).init(); - assertFalse( dsprops.isEmpty()); + verify(kieenv, times(4)).set(anyString(), any()); verify(jpa).get("myname"); verify(jpa).replace(any()); } /** - * Verifies that a new KIE session is created when there KIE fails - * to load an existing session. + * Verifies that a new KIE session is created when there KIE fails to load + * an existing session. */ @Test public void testActivatePolicySession_LoadFailed() throws Exception { @@ -334,64 +367,88 @@ public class PersistenceFeatureTest { mockDbConn(5); setUpKie("myname", 999L, false); - - - KieSession s = - feat.activatePolicySession(polcont, "myname", "mybase"); + + KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); verify(kiestore).newKieSession(any(), any(), any()); - + assertEquals(s, kiesess); - verify(kieenv, times(2)).set(anyString(), any()); - verify(pds).init(); - assertFalse( dsprops.isEmpty()); + verify(kieenv, times(4)).set(anyString(), any()); verify(jpa).get("myname"); - - ArgumentCaptor<DroolsSession> d = - ArgumentCaptor.forClass(DroolsSession.class); - verify(jpa).replace( d.capture()); - + + ArgumentCaptor<DroolsSession> d = ArgumentCaptor.forClass(DroolsSession.class); + verify(jpa).replace(d.capture()); + assertEquals("myname", d.getValue().getSessionName()); assertEquals(100L, d.getValue().getSessionId()); } @Test - public void testConfigureKieEnv() throws Exception { + public void testLoadDataSource() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); mockDbConn(5); setUpKie("myname", 999L, false); - + feat.activatePolicySession(polcont, "myname", "mybase"); - verify(kieenv, times(2)).set(any(), any()); - - verify(kieenv).set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf); - verify(kieenv).set(EnvironmentName.TRANSACTION_MANAGER, bittrans); + verify(fact).makeEntMgrFact(any()); } @Test - public void testInitDataSource() throws Exception { + public void testConfigureSysProps() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); mockDbConn(5); setUpKie("myname", 999L, false); - + feat.activatePolicySession(polcont, "myname", "mybase"); + + assertEquals("60", System.getProperty("com.arjuna.ats.arjuna.coordinator.defaultTimeout")); + assertEquals(JTA_OSDIR, System.getProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir")); + assertEquals(JTA_OSDIR, System.getProperty("ObjectStoreEnvironmentBean.objectStoreDir")); + } + + @Test + public void testConfigureKieEnv() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, false); + + feat.activatePolicySession(polcont, "myname", "mybase"); + + verify(kieenv, times(4)).set(any(), any()); + + verify(kieenv).set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf); + verify(kieenv).set(EnvironmentName.TRANSACTION, usertrans); + verify(kieenv).set(EnvironmentName.TRANSACTION_MANAGER, transmgr); + verify(kieenv).set(EnvironmentName.TRANSACTION_SYNCHRONIZATION_REGISTRY, transreg); - assertEquals(JDBC_URL, dsprops.getProperty("URL")); - assertEquals(JDBC_USER, dsprops.getProperty("user")); - assertEquals(JDBC_PASSWD, dsprops.getProperty("password")); + verify(bds, times(1)).close(); + } + + @Test + public void testConfigureKieEnv_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, false); - verify(pds).setUniqueName("jdbc/BitronixJTADataSource/myname"); - verify(pds).setClassName(JDBC_DATASRC); - verify(pds).setMaxPoolSize(anyInt()); - verify(pds).setIsolationLevel("SERIALIZABLE"); - verify(pds).setAllowLocalTransactions(true); - verify(pds).init(); + when(fact.getUserTrans()).thenThrow(new IllegalArgumentException("expected exception")); + + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + + } catch(IllegalArgumentException ex) { + logger.trace("expected exception", ex); + } + + verify(bds, times(2)).close(); } @Test @@ -400,14 +457,12 @@ public class PersistenceFeatureTest { mockDbConn(5); setUpKie("myname", 999L, true); - - - KieSession s = - feat.activatePolicySession(polcont, "myname", "mybase"); + + KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); verify(kiestore).loadKieSession(999L, kiebase, kiecfg, kieenv); verify(kiestore, never()).newKieSession(any(), any(), any()); - + assertEquals(s, kiesess); } @@ -421,17 +476,15 @@ public class PersistenceFeatureTest { mockDbConn(5); setUpKie("myname", 999L, false); - + when(kiestore.loadKieSession(anyLong(), any(), any(), any())) - .thenThrow( new RuntimeException("expected exception")); - - - KieSession s = - feat.activatePolicySession(polcont, "myname", "mybase"); + .thenThrow(new IllegalArgumentException("expected exception")); + + KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); verify(kiestore).newKieSession(any(), any(), any()); - + assertEquals(s, kiesess); } @@ -441,90 +494,99 @@ public class PersistenceFeatureTest { mockDbConn(5); setUpKie("myname", 999L, false); - - - KieSession s = - feat.activatePolicySession(polcont, "myname", "mybase"); + + KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); verify(kiestore).newKieSession(kiebase, null, kieenv); - + assertEquals(s, kiesess); } @Test - public void testLoadDataSource_RepeatSameSession() throws Exception { + public void testLoadDataSource_DiffSession() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); mockDbConn(5); setUpKie("myname", 999L, false); - feat.activatePolicySession(polcont, "myname", "mybase"); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); + verify(polcont).setAdjunct(any(), adjcap.capture()); - - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); - + + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + + setUpKie("myname2", 999L, false); + // invoke it again - feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname2", "mybase"); + + verify(fact, times(2)).makeEntMgrFact(any()); + } + + @Test + public void testSelectThreadModel_Persistent() throws Exception { + setUpKie("myname", 999L, true); + + ThreadModel m = feat.selectThreadModel(polsess); + assertNotNull(m); + assertTrue(m instanceof PersistentThreadModel); - verify(fact, times(1)).makePoolingDataSource(); } - + @Test - public void testLoadDataSource_DiffSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); - - mockDbConn(5); - setUpKie("myname", 999L, false); - feat.activatePolicySession(polcont, "myname", "mybase"); - - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + public void testSelectThreadModel_NotPersistent() throws Exception { + when(fact.getPolicyController(any())).thenReturn(polctlr); + assertNull(feat.selectThreadModel(polsess)); - verify(polcont).setAdjunct(any(), adjcap.capture()); + } + + @Test + public void testSelectThreadModel_Start__Run_Update_Stop() throws Exception { + setUpKie("myname", 999L, true); - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); - - setUpKie("myname2", 999L, false); + ThreadModel m = feat.selectThreadModel(polsess); + assertNotNull(m); + assertTrue(m instanceof PersistentThreadModel); - // invoke it again - feat.activatePolicySession(polcont, "myname2", "mybase"); + when(polsess.getKieSession()).thenReturn(kiesess); - verify(fact, times(2)).makePoolingDataSource(); + m.start(); + new CountDownLatch(1).await(10, TimeUnit.MILLISECONDS); + m.updated(); + m.stop(); } @Test public void testDisposeKieSession() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); mockDbConn(5); setUpKie("myname", 999L, false); - + feat.activatePolicySession(polcont, "myname", "mybase"); - - verify(pds, never()).close(); + + verify(emf, never()).close(); verify(polcont).setAdjunct(any(), adjcap.capture()); - - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); - + + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + feat.disposeKieSession(polsess); // call twice to ensure it isn't re-closed feat.disposeKieSession(polsess); - - verify(pds, times(1)).close(); + + verify(emf, times(1)).close(); } @Test public void testDisposeKieSession_NoAdjunct() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - + feat.disposeKieSession(polsess); } @@ -532,56 +594,56 @@ public class PersistenceFeatureTest { public void testDisposeKieSession_NoPersistence() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); mockDbConn(5); setUpKie("myname", 999L, false); - + feat.activatePolicySession(polcont, "myname", "mybase"); - - verify(pds, never()).close(); + + verify(emf, never()).close(); verify(polcont).setAdjunct(any(), adjcap.capture()); - - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); + + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); // specify a session that was never loaded when(polsess.getName()).thenReturn("anotherName"); - + feat.disposeKieSession(polsess); - - verify(pds, never()).close(); + + verify(emf, never()).close(); } @Test public void testDestroyKieSession() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); mockDbConn(5); setUpKie("myname", 999L, false); - + feat.activatePolicySession(polcont, "myname", "mybase"); - - verify(pds, never()).close(); + + verify(emf, never()).close(); verify(polcont).setAdjunct(any(), adjcap.capture()); - - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); - + + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + feat.destroyKieSession(polsess); // call twice to ensure it isn't re-closed feat.destroyKieSession(polsess); - - verify(pds, times(1)).close(); + + verify(emf, times(1)).close(); } @Test public void testDestroyKieSession_NoAdjunct() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - + feat.destroyKieSession(polsess); } @@ -589,105 +651,105 @@ public class PersistenceFeatureTest { public void testDestroyKieSession_NoPersistence() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = - ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); mockDbConn(5); setUpKie("myname", 999L, false); - + feat.activatePolicySession(polcont, "myname", "mybase"); - - verify(pds, never()).close(); + + verify(emf, never()).close(); verify(polcont).setAdjunct(any(), adjcap.capture()); - - when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue()); + + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); // specify a session that was never loaded when(polsess.getName()).thenReturn("anotherName"); - + feat.destroyKieSession(polsess); - verify(pds, never()).close(); + verify(emf, never()).close(); } @Test public void testAfterStart() { - assertFalse( feat.afterStart(null)); + assertFalse(feat.afterStart(null)); } @Test public void testBeforeStart() { - assertFalse( feat.beforeStart(null)); + assertFalse(feat.beforeStart(null)); } @Test public void testBeforeShutdown() { - assertFalse( feat.beforeShutdown(null)); + assertFalse(feat.beforeShutdown(null)); } @Test public void testAfterShutdown() { - assertFalse( feat.afterShutdown(null)); + assertFalse(feat.afterShutdown(null)); } @Test public void testBeforeConfigure() { - assertFalse( feat.beforeConfigure(null, null)); + assertFalse(feat.beforeConfigure(null, null)); } @Test public void testAfterConfigure() { - assertFalse( feat.afterConfigure(null)); + assertFalse(feat.afterConfigure(null)); } @Test public void testBeforeActivate() { - assertFalse( feat.beforeActivate(null)); + assertFalse(feat.beforeActivate(null)); } @Test public void testAfterActivate() { - assertFalse( feat.afterActivate(null)); + assertFalse(feat.afterActivate(null)); } @Test public void testBeforeDeactivate() { - assertFalse( feat.beforeDeactivate(null)); + assertFalse(feat.beforeDeactivate(null)); } @Test public void testAfterDeactivate() { - assertFalse( feat.afterDeactivate(null)); + assertFalse(feat.afterDeactivate(null)); } @Test public void testBeforeStop() { - assertFalse( feat.beforeStop(null)); + assertFalse(feat.beforeStop(null)); } @Test public void testAfterStop() { - assertFalse( feat.afterStop(null)); + assertFalse(feat.afterStop(null)); } @Test public void testBeforeLock() { - assertFalse( feat.beforeLock(null)); + assertFalse(feat.beforeLock(null)); } @Test public void testAfterLock() { - assertFalse( feat.afterLock(null)); + assertFalse(feat.afterLock(null)); } @Test public void testBeforeUnlock() { - assertFalse( feat.beforeUnlock(null)); + assertFalse(feat.beforeUnlock(null)); } @Test public void testAfterUnlock() { - assertFalse( feat.afterUnlock(null)); + assertFalse(feat.afterUnlock(null)); } @Test @@ -697,25 +759,25 @@ public class PersistenceFeatureTest { feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - + feat.activatePolicySession(polcont, "myname", "mybase"); - + verify(s).executeUpdate(); } @Test public void testGetPersistenceTimeout_Missing() throws Exception { - + props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); - + PreparedStatement s = mockDbConn(0); feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - + feat.activatePolicySession(polcont, "myname", "mybase"); - + verify(s, never()).executeUpdate(); } @@ -727,46 +789,31 @@ public class PersistenceFeatureTest { feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - - feat.activatePolicySession(polcont, "myname", "mybase"); - - verify(s, never()).executeUpdate(); - } - @Test - public void testInitHostName() throws Exception { - when(fact.getHostName()).thenReturn("myhost"); - - feat.globalInit(null, SRC_TEST_RESOURCES); - - verify(bitcfg).setServerId("myhost"); - } + feat.activatePolicySession(polcont, "myname", "mybase"); - @Test(expected = RuntimeException.class) - public void testInitHostName_Ex() throws Exception { - when(fact.getHostName()) - .thenThrow( - new UnknownHostException("expected exception")); - - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(s, never()).executeUpdate(); } @Test public void testCleanUpSessionInfo() throws Exception { setUpKie("myname", 999L, true); - + // use a real DB so we can verify that the "delete" works correctly fact = new PartialFactory(); feat.setFactory(fact); - + makeSessionInfoTbl(20000); - + // create mock entity manager for use by JPA connector + EntityManager em = mock(EntityManager.class); + when(emf.createEntityManager()).thenReturn(em); + feat.globalInit(null, SRC_TEST_RESOURCES); - + feat.beforeStart(null); feat.activatePolicySession(polcont, "myname", "mybase"); - + assertEquals("[1, 4, 5]", getSessions().toString()); } @@ -777,10 +824,10 @@ public class PersistenceFeatureTest { feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - + // reset feat.beforeStart(null); - + feat.activatePolicySession(polcont, "myname", "mybase"); verify(s, times(1)).executeUpdate(); @@ -788,11 +835,10 @@ public class PersistenceFeatureTest { feat.activatePolicySession(polcont, "myname", "mybase"); feat.activatePolicySession(polcont, "myname", "mybase"); verify(s, times(1)).executeUpdate(); - // reset feat.beforeStart(null); - + feat.activatePolicySession(polcont, "myname", "mybase"); verify(s, times(2)).executeUpdate(); @@ -809,10 +855,10 @@ public class PersistenceFeatureTest { feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - + // reset feat.beforeActivate(null); - + feat.activatePolicySession(polcont, "myname", "mybase"); verify(s, times(1)).executeUpdate(); @@ -820,11 +866,10 @@ public class PersistenceFeatureTest { feat.activatePolicySession(polcont, "myname", "mybase"); feat.activatePolicySession(polcont, "myname", "mybase"); verify(s, times(1)).executeUpdate(); - // reset feat.beforeActivate(null); - + feat.activatePolicySession(polcont, "myname", "mybase"); verify(s, times(2)).executeUpdate(); @@ -838,60 +883,75 @@ public class PersistenceFeatureTest { public void testCleanUpSessionInfo_NoTimeout() throws Exception { props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); - + PreparedStatement s = mockDbConn(0); feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - + feat.activatePolicySession(polcont, "myname", "mybase"); - + verify(s, never()).executeUpdate(); } @Test public void testCleanUpSessionInfo_NoUrl() throws Exception { PreparedStatement s = mockDbConn(0); - + props.remove(DroolsPersistenceProperties.DB_URL); feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - - feat.activatePolicySession(polcont, "myname", "mybase"); - + + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + } catch (RuntimeException e) { + logger.trace("expected exception", e); + } + verify(s, never()).executeUpdate(); } @Test public void testCleanUpSessionInfo_NoUser() throws Exception { PreparedStatement s = mockDbConn(0); - + props.remove(DroolsPersistenceProperties.DB_USER); feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - - feat.activatePolicySession(polcont, "myname", "mybase"); - + + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + } catch (RuntimeException e) { + logger.trace("expected exception", e); + } + verify(s, never()).executeUpdate(); } @Test public void testCleanUpSessionInfo_NoPassword() throws Exception { PreparedStatement s = mockDbConn(0); - + props.remove(DroolsPersistenceProperties.DB_PWD); feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - - feat.activatePolicySession(polcont, "myname", "mybase"); - + + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + } catch (RuntimeException e) { + logger.trace("expected exception", e); + } + verify(s, never()).executeUpdate(); } @@ -902,9 +962,9 @@ public class PersistenceFeatureTest { feat.globalInit(null, SRC_TEST_RESOURCES); setUpKie("myname", 999L, true); - + feat.activatePolicySession(polcont, "myname", "mybase"); - + verify(s).executeUpdate(); } @@ -914,51 +974,29 @@ public class PersistenceFeatureTest { mockDbConn(5); setUpKie("myname", 999L, true); - - - feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); - ArgumentCaptor<Properties> propcap = - ArgumentCaptor.forClass(Properties.class); - - verify(fact).makeJpaConnector(anyString(), propcap.capture()); - - Properties p = propcap.getValue(); - assertNotNull(p); - - assertEquals(JDBC_DRIVER, - p.getProperty("javax.persistence.jdbc.driver")); - - assertEquals(JDBC_URL, - p.getProperty("javax.persistence.jdbc.url")); - - assertEquals(JDBC_USER, - p.getProperty("javax.persistence.jdbc.user")); - - assertEquals(JDBC_PASSWD, - p.getProperty("javax.persistence.jdbc.password")); + verify(fact).makeJpaConnector(emf); } @Test public void testReplaceSession() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); - ArgumentCaptor<DroolsSession> sesscap = - ArgumentCaptor.forClass(DroolsSession.class); + ArgumentCaptor<DroolsSession> sesscap = ArgumentCaptor.forClass(DroolsSession.class); mockDbConn(5); setUpKie("myname", 999L, true); - - + feat.activatePolicySession(polcont, "myname", "mybase"); - - verify(jpa).replace( sesscap.capture()); - + + verify(jpa).replace(sesscap.capture()); + assertEquals("myname", sesscap.getValue().getSessionName()); assertEquals(999L, sesscap.getValue().getSessionId()); } - + @Test public void testIsPersistenceEnabled_Auto() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -967,10 +1005,10 @@ public class PersistenceFeatureTest { setUpKie("myname", 999L, true); props.setProperty("persistence.type", "auto"); - - assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testIsPersistenceEnabled_Native() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -979,10 +1017,10 @@ public class PersistenceFeatureTest { setUpKie("myname", 999L, true); props.setProperty("persistence.type", "native"); - - assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testIsPersistenceEnabled_None() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -991,23 +1029,22 @@ public class PersistenceFeatureTest { setUpKie("myname", 999L, true); props.remove("persistence.type"); - - assertNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testGetProperties_Ex() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); mockDbConn(5); setUpKie("myname", 999L, true); - - when(fact.getPolicyContainer(polcont)) - .thenThrow( new IllegalArgumentException("expected exception")); - assertNull( feat.activatePolicySession(polcont, "myname", "mybase")); + when(fact.getPolicyController(polcont)).thenThrow(new IllegalArgumentException("expected exception")); + + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testGetProperty_Specific() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -1017,10 +1054,10 @@ public class PersistenceFeatureTest { props.remove("persistence.type"); props.setProperty("persistence.myname.type", "auto"); - - assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testGetProperty_Specific_None() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -1030,10 +1067,10 @@ public class PersistenceFeatureTest { props.remove("persistence.type"); props.setProperty("persistence.xxx.type", "auto"); - - assertNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testGetProperty_Both_SpecificOn() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -1043,10 +1080,10 @@ public class PersistenceFeatureTest { props.setProperty("persistence.type", "other"); props.setProperty("persistence.myname.type", "auto"); - - assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testGetProperty_Both_SpecificDisabledOff() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -1056,10 +1093,10 @@ public class PersistenceFeatureTest { props.setProperty("persistence.type", "auto"); props.setProperty("persistence.myname.type", "other"); - - assertNull( feat.activatePolicySession(polcont, "myname", "mybase")); + + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); } - + @Test public void testGetProperty_None() throws Exception { feat.globalInit(null, SRC_TEST_RESOURCES); @@ -1068,70 +1105,157 @@ public class PersistenceFeatureTest { setUpKie("myname", 999L, true); props.remove("persistence.type"); + + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } + + @Test + public void testPersistenceFeatureException() { + SecurityException secex = new SecurityException("expected exception"); + PersistenceFeatureException ex = new PersistenceFeatureException(secex); + + assertEquals(secex, ex.getCause()); + + } + + @Test + public void testDsEmf_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, false); - assertNull( feat.activatePolicySession(polcont, "myname", "mybase")); + when(fact.makeEntMgrFact(any())).thenThrow(new IllegalArgumentException("expected exception")); + + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + + } catch(IllegalArgumentException ex) { + logger.trace("expected exception", ex); + } + + verify(bds, times(2)).close(); + } + + @Test + public void testDsEmf_Close_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, false); + + feat.activatePolicySession(polcont, "myname", "mybase"); + + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); + + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + + // return adjunct on next call + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + + try { + doThrow(new IllegalArgumentException("expected exception")).when(emf).close(); + + feat.destroyKieSession(polsess); + fail("missing exception"); + + } catch(IllegalArgumentException ex) { + logger.trace("expected exception", ex); + } + + verify(bds, times(2)).close(); + } + + @Test + public void testDsEmf_CloseDataSource_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, false); + + feat.activatePolicySession(polcont, "myname", "mybase"); + + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor + .forClass(PersistenceFeature.ContainerAdjunct.class); + + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + + // return adjunct on next call + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + + try { + doThrow(new SQLException("expected exception")).when(bds).close(); + + feat.destroyKieSession(polsess); + fail("missing exception"); + + } catch(PersistenceFeatureException ex) { + logger.trace("expected exception", ex); + } } - /** * Gets an ordered list of ids of the current SessionInfo records. + * * @return ordered list of SessInfo IDs - * @throws SQLException - * @throws IOException + * @throws SQLException + * @throws IOException */ private List<Integer> getSessions() throws SQLException, IOException { attachDb(); - + ArrayList<Integer> lst = new ArrayList<>(5); - try( - PreparedStatement stmt = conn.prepareStatement("SELECT id from sessioninfo order by id"); + try (PreparedStatement stmt = conn.prepareStatement("SELECT id from sessioninfo order by id"); ResultSet rs = stmt.executeQuery()) { - - while(rs.next()) { - lst.add( rs.getInt(1)); + + while (rs.next()) { + lst.add(rs.getInt(1)); } } - + return lst; } - + /** * Sets up for doing invoking the newKieSession() method. - * @param sessnm name to which JPA should respond with a session - * @param sessid session id to be returned by the session - * @param loadOk {@code true} if loadKieSession() should return a - * value, {@code false} to return null + * + * @param sessnm + * name to which JPA should respond with a session + * @param sessid + * session id to be returned by the session + * @param loadOk + * {@code true} if loadKieSession() should return a value, + * {@code false} to return null + * @throws Exception */ - private void setUpKie(String sessnm, long sessid, boolean loadOk) { - - when(fact.makeJpaConnector(any(), any())).thenReturn(jpa); - when(fact.makePoolingDataSource()).thenReturn(pds); - when(fact.getPolicyContainer(polcont)).thenReturn(polctlr); - + private void setUpKie(String sessnm, long sessid, boolean loadOk) throws Exception { + + when(fact.makeJpaConnector(emf)).thenReturn(jpa); + when(fact.makeEntMgrFact(any())).thenReturn(emf); + when(fact.getPolicyController(polcont)).thenReturn(polctlr); + props.setProperty("persistence.type", "auto"); - + when(polctlr.getProperties()).thenReturn(props); - + when(jpa.get(sessnm)).thenReturn(sess); - - when(pds.getDriverProperties()).thenReturn(dsprops); - + when(sess.getSessionId()).thenReturn(sessid); - + when(polsess.getPolicyContainer()).thenReturn(polcont); when(polsess.getName()).thenReturn(sessnm); - - if(loadOk) { + + if (loadOk) { when(kiesess.getIdentifier()).thenReturn(sessid); - when(kiestore.loadKieSession(anyLong(), any(), any(), any())) - .thenReturn(kiesess); - + when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(kiesess); + } else { // use an alternate id for the new session when(kiesess.getIdentifier()).thenReturn(100L); - when(kiestore.loadKieSession(anyLong(), any(), any(), any())) - .thenReturn(null); + when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(null); } when(kiestore.newKieSession(any(), any(), any())).thenReturn(kiesess); @@ -1139,48 +1263,47 @@ public class PersistenceFeatureTest { /** * Creates the SessionInfo DB table and populates it with some data. - * @param expMs number of milli-seconds for expired sessioninfo records - * @throws SQLException - * @throws IOException + * + * @param expMs + * number of milli-seconds for expired sessioninfo records + * @throws SQLException + * @throws IOException */ - private void makeSessionInfoTbl(int expMs) - throws SQLException, IOException { - + private void makeSessionInfoTbl(int expMs) throws SQLException, IOException { + attachDb(); - try( - PreparedStatement stmt = conn.prepareStatement( - "CREATE TABLE sessioninfo(id int, lastmodificationdate timestamp)")) { + try (PreparedStatement stmt = conn + .prepareStatement("CREATE TABLE sessioninfo(id int, lastmodificationdate timestamp)")) { - stmt.executeUpdate(); + stmt.executeUpdate(); } - try( - PreparedStatement stmt = conn.prepareStatement( - "INSERT into sessioninfo(id, lastmodificationdate) values(?, ?)")) { + try (PreparedStatement stmt = conn + .prepareStatement("INSERT into sessioninfo(id, lastmodificationdate) values(?, ?)")) { Timestamp ts; - + // current data - ts = new Timestamp( System.currentTimeMillis()); + ts = new Timestamp(System.currentTimeMillis()); stmt.setTimestamp(2, ts); - + stmt.setInt(1, 1); stmt.executeUpdate(); - + stmt.setInt(1, 4); stmt.executeUpdate(); - + stmt.setInt(1, 5); stmt.executeUpdate(); - + // expired data - ts = new Timestamp( System.currentTimeMillis() - expMs); + ts = new Timestamp(System.currentTimeMillis() - expMs); stmt.setTimestamp(2, ts); - + stmt.setInt(1, 2); stmt.executeUpdate(); - + stmt.setInt(1, 3); stmt.executeUpdate(); } @@ -1188,17 +1311,18 @@ public class PersistenceFeatureTest { /** * Attaches {@link #conn} to the DB, if it isn't already attached. + * * @throws SQLException - * @throws IOException if the property file cannot be read + * @throws IOException + * if the property file cannot be read */ private void attachDb() throws SQLException, IOException { - if(conn == null) { + if (conn == null) { Properties p = loadDbProps(); - - conn = DriverManager.getConnection( - p.getProperty(DroolsPersistenceProperties.DB_URL), - p.getProperty(DroolsPersistenceProperties.DB_USER), - p.getProperty(DroolsPersistenceProperties.DB_PWD)); + + conn = DriverManager.getConnection(p.getProperty(DroolsPersistenceProperties.DB_URL), + p.getProperty(DroolsPersistenceProperties.DB_USER), + p.getProperty(DroolsPersistenceProperties.DB_PWD)); conn.setAutoCommit(true); } } @@ -1206,27 +1330,30 @@ public class PersistenceFeatureTest { /** * Loads the DB properties from the file, * <i>feature-session-persistence.properties</i>. + * * @return the properties that were loaded - * @throws IOException if the property file cannot be read - * @throws FileNotFoundException if the property file does not exist + * @throws IOException + * if the property file cannot be read + * @throws FileNotFoundException + * if the property file does not exist */ - private Properties loadDbProps() - throws IOException, FileNotFoundException { - + private Properties loadDbProps() throws IOException, FileNotFoundException { + Properties p = new Properties(); - - try(FileReader rdr = new FileReader( - "src/test/resources/feature-session-persistence.properties")) { + + try (FileReader rdr = new FileReader("src/test/resources/feature-session-persistence.properties")) { p.load(rdr); } - + return p; } /** * Create a mock DB connection and statement. - * @param retval value to be returned when the statement is executed, - * or negative to throw an exception + * + * @param retval + * value to be returned when the statement is executed, or + * negative to throw an exception * @return the statement that will be returned by the connection * @throws SQLException */ @@ -1234,58 +1361,57 @@ public class PersistenceFeatureTest { Connection c = mock(Connection.class); PreparedStatement s = mock(PreparedStatement.class); - when(fact.makeDbConnection(anyString(), anyString(), anyString())) - .thenReturn(c); + when(bds.getConnection()).thenReturn(c); + when(fact.makeDataSource(any())).thenReturn(bds); when(c.prepareStatement(anyString())).thenReturn(s); - - if(retval < 0) { + + if (retval < 0) { // should throw an exception - when(s.executeUpdate()) - .thenThrow( new SQLException("expected exception")); - + when(s.executeUpdate()).thenThrow(new SQLException("expected exception")); + } else { // should return the value when(s.executeUpdate()).thenReturn(retval); } - + return s; } - + /** - * A partial factory, which exports a few of the real methods, but - * overrides the rest. + * A partial factory, which exports a few of the real methods, but overrides + * the rest. */ private class PartialFactory extends PersistenceFeature.Factory { - + @Override - public PoolingDataSource makePoolingDataSource() { - return pds; + public TransactionManager getTransMgr() { + return transmgr; } @Override - public KieServices getKieServices() { - return kiesvc; + public UserTransaction getUserTrans() { + return usertrans; } @Override - public BitronixTransactionManager getTransMgr() { - return null; + public TransactionSynchronizationRegistry getTransSyncReg() { + return transreg; } @Override - public EntityManagerFactory makeEntMgrFact(String pu, - Properties propMap) { - if(pu.equals("onapsessionsPU")) { - return null; - } - - return super.makeEntMgrFact("junitPersistenceFeaturePU", propMap); + public KieServices getKieServices() { + return kiesvc; } @Override - public PolicyController getPolicyContainer(PolicyContainer container) { + public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) { + return emf; + } + + @Override + public PolicyController getPolicyController(PolicyContainer container) { return polctlr; } - + } } diff --git a/feature-session-persistence/src/test/resources/META-INF/persistence.xml b/feature-session-persistence/src/test/resources/META-INF/persistence.xml index 6794e24e..5cc1badc 100644 --- a/feature-session-persistence/src/test/resources/META-INF/persistence.xml +++ b/feature-session-persistence/src/test/resources/META-INF/persistence.xml @@ -23,16 +23,8 @@ xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> - <persistence-unit name="junitDroolsSessionEntityPU" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> - <class>org.onap.policy.drools.persistence.DroolsSessionEntity</class> - <properties> - <property name="javax.persistence.schema-generation.database.action" value="create"/> - </properties> - </persistence-unit> - - <persistence-unit name="junitPersistenceFeaturePU" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + <persistence-unit name="junitDroolsSessionEntityPU" transaction-type="JTA"> + <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>org.onap.policy.drools.persistence.DroolsSessionEntity</class> <properties> <property name="javax.persistence.schema-generation.database.action" value="create"/> diff --git a/feature-session-persistence/src/test/resources/feature-session-persistence.properties b/feature-session-persistence/src/test/resources/feature-session-persistence.properties index 6b448dc8..a1e9cc43 100644 --- a/feature-session-persistence/src/test/resources/feature-session-persistence.properties +++ b/feature-session-persistence/src/test/resources/feature-session-persistence.properties @@ -23,6 +23,5 @@ javax.persistence.jdbc.url=jdbc:h2:mem:TestPersistenceFeature javax.persistence.jdbc.user=testuser javax.persistence.jdbc.password=testpass -hibernate.dataSource=org.h2.jdbcx.JdbcDataSource - persistence.sessioninfo.timeout=10 +persistence.objectstore.dir=target/jta |