Index: tck/src/java/org/apache/jdo/tck/api/persistencemanager/close/AutoCloseable.java =================================================================== --- tck/src/java/org/apache/jdo/tck/api/persistencemanager/close/AutoCloseable.java (revision 1777712) +++ tck/src/java/org/apache/jdo/tck/api/persistencemanager/close/AutoCloseable.java (working copy) @@ -17,9 +17,7 @@ package org.apache.jdo.tck.api.persistencemanager.close; -import javax.jdo.JDOUserException; import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; import org.apache.jdo.tck.api.persistencemanager.PersistenceManagerTest; import org.apache.jdo.tck.util.BatchTestRunner; @@ -32,7 +30,8 @@ *Assertion IDs: A12.6 ?. *
*Assertion Description: -In a non-managed environment, if the PM is created with try-with-resources then it is automatically closed at the end of that block. + * In a non-managed environment, if the PM is created with try-with-resources + * then it is automatically closed at the end of that block. */ public class AutoCloseable extends PersistenceManagerTest { @@ -50,15 +49,50 @@ BatchTestRunner.run(AutoCloseable.class); } - /** */ - public void test() { + /** + * The method creates a pm with try-with-resources and checks that it is closed after the block. + */ + public void testTryWithResource() { - try (PersistenceManager pm1 = getPM()) - { + try (PersistenceManager pm1 = getPM()) { pm = pm1; - assertFalse(pm.isClosed()); + if (pm.isClosed()) { + fail(ASSERTION_FAILED, + "PersistenceManager is expected to be open inside try-with-resource block."); + } } - assertTrue(pm.isClosed()); + if (!pm.isClosed()) { + fail(ASSERTION_FAILED, + "PersistenceManager should be closed after try-with-resource block."); + } } + + /** + * The method creates a pm with try-with-resources and checks that it is closed after the block, + * if the block is ended with an exception. + */ + public void testTryWithResourceThrowingException() { + + try (PersistenceManager pm1 = getPM()) { + pm = pm1; + if (pm.isClosed()) { + fail(ASSERTION_FAILED, + "PersistenceManager is expected to be open inside try-with-resource block."); + } + throw new DummyException(); + } catch (DummyException ex) { + // exception is expected + } + + if (!pm.isClosed()) { + fail(ASSERTION_FAILED, + "PersistenceManager should be closed after try-with-resource block."); + } + } + + /** + * DummyException used in method testTryWithResourceThrowingException. + */ + private static final class DummyException extends Exception {} } Index: tck/src/java/org/apache/jdo/tck/extents/AutoCloseable.java =================================================================== --- tck/src/java/org/apache/jdo/tck/extents/AutoCloseable.java (nonexistent) +++ tck/src/java/org/apache/jdo/tck/extents/AutoCloseable.java (working copy) @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.extents; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import javax.jdo.Extent; +import javax.jdo.PersistenceManager; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.pc.mylib.PCPoint; +import org.apache.jdo.tck.util.BatchTestRunner; +import org.apache.jdo.tck.pc.company.Department; + +/** + *Title: AutoCloseable + *
+ *Keywords: exception + *
+ *Assertion IDs: A12.6 ?. + *
+ *Assertion Description: + * In a non-managed environment, if the extent is created with try-with-resources + * all results of execute(...) methods on this query instance are automatically + * closed at the end of that block and all resources associated with it are released. + */ +public class AutoCloseable extends ExtentTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A12.6-? (AutoCloseable) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(AutoCloseable.class); + } + + /** + * This methods creates an extent instance with try-with-resources and + * checks that an iterator for the query result is not accessible after the block. + */ + public void testTryWithResource() { + + PersistenceManager pm = getPM(); + Transaction tx = pm.currentTransaction(); + + try { + tx.begin(); + + Extent extent = null; + Iterator iterator = null; + try (Extent extent1 = pm.getExtent(Department.class)) { + extent = extent1; + iterator = extent1.iterator(); + if (!iterator.hasNext()) { + fail(ASSERTION_FAILED, "(1) Open extent iterator should have elements."); + } + } catch (Exception ex) { + fail(ASSERTION_FAILED, "(2) Unexpected exception " + ex); + } + + // check iterator retrieved in try-with-resource block + if (iterator.hasNext()) { + fail(ASSERTION_FAILED, + "(3) Closed extent iterator should return false on hasNext()."); + } + try { + Department next = iterator.next(); + fail(ASSERTION_FAILED, + "(4) Closed extent iterator should throw NoSuchElementException on next()."); + } catch (NoSuchElementException ex) { + // expected exception + } + + Iterator iterator2 = extent.iterator(); + if (!iterator2.hasNext()) { + fail(ASSERTION_FAILED, "(5) extent should be usable and should have elements."); + } + + tx.commit(); + } finally { + if (tx != null && tx.isActive()) { + tx.rollback(); + } + } + } + + /** + * This methods creates an extent instance with try-with-resources and + * checks that an iterator for the query result is not accessible after the block, + * if the block is ended with an exception. + */ + public void testTryWithResourceThrowingException() { + + PersistenceManager pm = getPM(); + Transaction tx = pm.currentTransaction(); + + try { + tx.begin(); + + Extent extent = null; + Iterator iterator = null; + try (Extent extent1 = pm.getExtent(Department.class)) { + extent = extent1; + iterator = extent1.iterator(); + if (!iterator.hasNext()) { + fail(ASSERTION_FAILED, "(1) Open extent iterator should have elements."); + } + throw new DummyException(); + } catch (DummyException ex) { + // expected exception + } catch (Exception ex) { + fail(ASSERTION_FAILED, "(2) Unexpected exception " + ex); + } + + // check iterator retrieved in try-with-resource block + if (iterator.hasNext()) { + fail(ASSERTION_FAILED, + "(3) Closed extent iterator should return false on hasNext()."); + } + try { + Department next = iterator.next(); + fail(ASSERTION_FAILED, + "(4) Closed extent iterator should throw NoSuchElementException on next()."); + } catch (NoSuchElementException ex) { + // expected exception + } + + Iterator iterator2 = extent.iterator(); + if (!iterator2.hasNext()) { + fail(ASSERTION_FAILED, "(5) extent should be usable and should have elements."); + } + + tx.commit(); + } finally { + if (tx != null && tx.isActive()) { + tx.rollback(); + } + } + } + + /** + * DummyException used in method testTryWithResourceThrowingException. + */ + private static final class DummyException extends Exception {} + +} Index: tck/src/java/org/apache/jdo/tck/query/api/AutoCloseable.java =================================================================== --- tck/src/java/org/apache/jdo/tck/query/api/AutoCloseable.java (nonexistent) +++ tck/src/java/org/apache/jdo/tck/query/api/AutoCloseable.java (working copy) @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.api; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import javax.jdo.JDOUserException; +import javax.jdo.Query; +import javax.jdo.PersistenceManager; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; +import org.apache.jdo.tck.pc.mylib.PCPoint; + +/** + *Title: AutoCloseable + *
+ *Keywords: query close + *
+ *Assertion IDs: A14.6.7-3. + *
+ *Assertion Description: + * In a non-managed environment, if the query is created with try-with-resources + * all results of execute(...) methods on this query instance are automatically + * closed at the end of that block and all resources associated with it are released. + */ +public class AutoCloseable extends QueryTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.7-3 (AutoCloseable) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(AutoCloseable.class); + } + + /** + * This methods creates a query instance with try-with-resources and + * checks that an iterator for the query result is not accessible after the block. + */ + public void testTryWithResource() { + + PersistenceManager pm = getPM(); + Transaction tx = pm.currentTransaction(); + + try { + tx.begin(); + + Query query = null; + List queryResult = null; + Iterator iterator = null; + try (Query query1 = pm.newQuery(PCPoint.class)) { + query = query1; + queryResult = (List) query1.execute(); + iterator = queryResult.iterator(); + if (!iterator.hasNext()) { + fail(ASSERTION_FAILED, "(1) Iterator of open query result should have elements."); + } + } catch (Exception ex) { + fail(ASSERTION_FAILED, "(2) Unexpected exception " + ex); + } + + // check iterator retrieved in try-with-resource block + if (iterator.hasNext()) { + fail(ASSERTION_FAILED, + "(3) Iterator of closed query result should return false on hasNext()."); + } + try { + PCPoint next = iterator.next(); + fail(ASSERTION_FAILED, + "(4) Iterator of closed query result should throw NoSuchElementException on next()."); + } catch (NoSuchElementException ex) { + // expected exception + } + + // create new Iterator and check its behaviour + Iterator iterator2 = queryResult.iterator(); + if (iterator2.hasNext()) { + fail(ASSERTION_FAILED, + "(5) Iterator of closed query result should return false on hasNext()."); + } + try { + PCPoint next = iterator2.next(); + fail(ASSERTION_FAILED, + "(6) Iterator of closed query result should throw NoSuchElementException on next()."); + } catch (NoSuchElementException ex) { + // expected exception + } + + // check query result itself + try { + int size = queryResult.size(); + fail(ASSERTION_FAILED, "(7) closed query result should not be accessible."); + } catch (JDOUserException ex) { + // expected exception when accessing closed query result + } + try { + PCPoint elem = queryResult.get(0); + fail(ASSERTION_FAILED, "(8) closed query result should not be accessible."); + } catch (JDOUserException ex) { + // expected exception when accessing closed query result + } + try { + boolean empty = queryResult.isEmpty(); + fail(ASSERTION_FAILED, "(9) closed query result should not be accessible."); + } catch (JDOUserException ex) { + // expected exception when accessing closed query result + } + // Check query instance is still usable + queryResult = (List) query.execute(); + if (queryResult.isEmpty()) { + fail(ASSERTION_FAILED, + "(10) query instance should be usable and execution should return a non empty result."); + } + + tx.commit(); + } finally { + if (tx != null && tx.isActive()) { + tx.rollback(); + } + } + } + + /** + * This methods creates a query instance with try-with-resources and + * checks that an iterator for the query result is not accessible after the block, + * if the block is ended with an exception. + */ + public void testTryWithResourceThrowingException() { + + PersistenceManager pm = getPM(); + Transaction tx = pm.currentTransaction(); + + try { + tx.begin(); + + Query query = null; + List queryResult = null; + Iterator iterator = null; + try (Query query1 = pm.newQuery(PCPoint.class)) { + query = query1; + queryResult = (List) query1.execute(); + iterator = queryResult.iterator(); + if (!iterator.hasNext()) { + fail(ASSERTION_FAILED, "(1) Iterator of open query result should have elements."); + } + throw new DummyException(); + } catch (DummyException ex) { + // expected exception + } catch (Exception ex) { + fail(ASSERTION_FAILED, "(2) Unexpected exception " + ex); + } + + // check iterator retrieved in try-with-resource block + if (iterator.hasNext()) { + fail(ASSERTION_FAILED, + "(3) Iterator of closed query result should return false on hasNext()."); + } + try { + PCPoint next = iterator.next(); + fail(ASSERTION_FAILED, + "(4) Iterator of closed query result should throw NoSuchElementException on next()."); + } catch (NoSuchElementException ex) { + // expected exception + } + + // create new Iterator and check its behaviour + Iterator iterator2 = queryResult.iterator(); + if (iterator2.hasNext()) { + fail(ASSERTION_FAILED, + "(5) Iterator of closed query result should return false on hasNext()."); + } + try { + PCPoint next = iterator2.next(); + fail(ASSERTION_FAILED, + "(6) Iterator of closed query result should throw NoSuchElementException on next()."); + } catch (NoSuchElementException ex) { + // expected exception + } + + // check query result itself + try { + int size = queryResult.size(); + fail(ASSERTION_FAILED, "(7) closed query result should not be accessible."); + } catch (JDOUserException ex) { + // expected exception when accessing closed query result + } + try { + PCPoint elem = queryResult.get(0); + fail(ASSERTION_FAILED, "(8) closed query result should not be accessible."); + } catch (JDOUserException ex) { + // expected exception when accessing closed query result + } + try { + boolean empty = queryResult.isEmpty(); + fail(ASSERTION_FAILED, "(9) closed query result should not be accessible."); + } catch (JDOUserException ex) { + // expected exception when accessing closed query result + } + + // Check query instance is still usable + queryResult = (List) query.execute(); + if (queryResult.isEmpty()) { + fail(ASSERTION_FAILED, + "(10) query instance should be usable and execution should return a non empty result."); + } + + tx.commit(); + } finally { + if (tx != null && tx.isActive()) { + tx.rollback(); + } + } + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(PCPoint.class); + loadAndPersistPCPoints(getPM()); + } + + /** + * DummyException used in method testTryWithResourceThrowingException. + */ + private static final class DummyException extends Exception {} +} Index: tck/src/conf/extents.conf =================================================================== --- tck/src/conf/extents.conf (revision 1777712) +++ tck/src/conf/extents.conf (working copy) @@ -20,6 +20,7 @@ jdo.tck.mapping = 0 jdo.tck.requiredOptions = jdo.tck.classes = \ +org.apache.jdo.tck.extents.AutoCloseable \ org.apache.jdo.tck.extents.CloseAll \ org.apache.jdo.tck.extents.CloseOfExtentIteratorIsIteratorSpecific \ org.apache.jdo.tck.extents.GetCandidateClass \ Index: tck/src/conf/query.conf =================================================================== --- tck/src/conf/query.conf (revision 1777712) +++ tck/src/conf/query.conf (working copy) @@ -20,6 +20,7 @@ jdo.tck.mapping = 0 jdo.tck.requiredOptions = jdo.tck.classes = \ +org.apache.jdo.tck.query.api.AutoCloseable \ org.apache.jdo.tck.query.api.ChangeQuery \ org.apache.jdo.tck.query.api.Close \ org.apache.jdo.tck.query.api.CloseAll \