Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorMutatingMethods.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentClose.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentClose.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentClose.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentClose.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.jdo.tck.extents;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.jdo.Extent;
+
+import org.apache.jdo.tck.pc.company.Employee;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Iterator Next After Extent Close
+ *<BR>
+ *<B>Keywords:</B> extent exception
+ *<BR>
+ *<B>Assertion ID:</B> A15.3-10.
+ *<BR>
+ *<B>Assertion Description: </B>
+After a call to <code>Extent.close(Iterator i)</code>,
+the parameter <code>Iterator</code>
+will throw a <code>NoSuchElementException</code> to <code>next()</code>.
+
+ */
+
+public class IteratorNextAfterExtentClose extends ExtentTest {
+
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A15.3-10 (IteratorNextAfterExtentClose) failed: ";
+
+ /**
+ * The <code>main</code> 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(IteratorNextAfterExtentClose.class);
+ }
+
+ /** */
+ public void test() {
+
+ try {
+ beginTransaction();
+ Extent ex = getPM().getExtent (Employee.class, true);
+ Iterator it1 = ex.iterator();
+ deleteEmployee((Employee)it1.next());
+ Iterator it2 = ex.iterator();
+ addEmployee();
+ Iterator it3 = ex.iterator();
+ ex.close(it1);
+ ex.close(it2);
+ ex.close(it3);
+
+ try {
+ tryNext(it1);
+ tryNext(it2);
+ tryNext(it3);
+ rollbackTransaction();
+
+ Iterator it4 = ex.iterator();
+ int count4 = countIterator(it4);
+ if (count4 != 2) {
+ fail(ASSERTION_FAILED,
+ "Iterator4 after rollback: " + count4 + "; should be
2");
+ }
+ }
+ catch (Exception unexpected) {
+ rollbackTransaction();
+ cleanup();
+ fail(ASSERTION_FAILED,
+ "unexpected exception " + unexpected);
+ }
+ }
+ catch (Exception unexpected) {
+ fail(ASSERTION_FAILED,
+ "unexpected exception " + unexpected);
+ }
+ finally {
+ cleanup();
+ }
+ }
+
+ /** */
+ void tryNext (Iterator it) throws Exception {
+ try {
+ it.next();
+ fail(ASSERTION_FAILED,
+ "expected NoSuchElementException thrown by iterator.next().");
+ } catch (NoSuchElementException expected) {
+ // expecteed exception
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentClose.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentCloseAll.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentCloseAll.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentCloseAll.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentCloseAll.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.jdo.tck.extents;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.jdo.Extent;
+
+import org.apache.jdo.tck.pc.company.Employee;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Iterator Next After Extent CloseAll
+ *<BR>
+ *<B>Keywords:</B> extent
+ *<BR>
+ *<B>Assertion ID:</B> A15.3-13.
+ *<BR>
+ *<B>Assertion Description: </B>
+After a call to <code>Extent.closeAll()</code>, all iterators acquired from
this
+<code>Extent</code> will throw a <code>NoSuchElementException</code>
+to <code>next()</code>.
+
+ */
+
+public class IteratorNextAfterExtentCloseAll extends ExtentTest {
+
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A15.3-13 (IteratorNextAfterExtentCloseAll) failed: ";
+
+ /**
+ * The <code>main</code> 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(IteratorNextAfterExtentCloseAll.class);
+ }
+
+ /** */
+ public void test() {
+
+ try {
+ beginTransaction();
+ Extent ex = getPM().getExtent (Employee.class, true);
+ Iterator it1 = ex.iterator();
+ deleteEmployee((Employee)it1.next());
+ Iterator it2 = ex.iterator();
+ addEmployee();
+ Iterator it3 = ex.iterator();
+ ex.closeAll();
+
+ if (!tryNext(it1)) {
+ fail(ASSERTION_FAILED,
+ "iterator1.next() does not throw
NoSuchElementException.");
+ }
+ if (!tryNext(it2)) {
+ fail(ASSERTION_FAILED,
+ "iterator2.next() does not throw
NoSuchElementException.");
+ }
+ if (!tryNext(it3)) {
+ fail(ASSERTION_FAILED,
+ "iterator3.next() does not throw
NoSuchElementException.");
+ }
+ }
+ finally {
+ rollbackTransaction();
+ cleanup();
+ }
+ }
+
+ /** */
+ boolean tryNext (Iterator it) {
+ try {
+ it.next();
+ } catch (NoSuchElementException expected) {
+ return true;
+ }
+ return false;
+ }
+
+}
+
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/IteratorNextAfterExtentCloseAll.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/Iterators.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/Iterators.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/Iterators.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/Iterators.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.jdo.tck.extents;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Iterators
+ *<BR>
+ *<B>Keywords:</B> extent
+ *<BR>
+ *<B>Assertion ID:</B> A15.3-1.
+ *<BR>
+ *<B>Assertion Description: </B>
+<code>Extent.iterator()</code> returns an <code>Iterator</code>
+over all the instances in the <code>Extent</code>.
+
+ */
+
+public class Iterators extends ExtentTest {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A15.3-1 (Iterators) failed: ";
+
+ /**
+ * The <code>main</code> 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(Iterators.class);
+ }
+
+ /** */
+ public void test() {
+
+ Extent ex = getExtent();
+
+ int count = 0;
+ for (Iterator it = ex.iterator(); it.hasNext();++count) {
+ Object emp = it.next();
+ if (debug) logger.debug(emp.toString());
+ }
+
+ if (count != 2) {
+ fail(ASSERTION_FAILED,
+ "Emplyoee extent should have 2 instances, got " + count);
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/extents/Iterators.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/HollowInstanceMaintainsPK.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/HollowInstanceMaintainsPK.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/HollowInstanceMaintainsPK.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/HollowInstanceMaintainsPK.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.mylib.PCRect;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test that Hollow Instances maintains PK
+ *<BR>
+ *<B>Keywords:</B> lifecycle hollow instance PK
+ *<BR>
+ *<B>Assertion IDs:</B> A5.5.4-3
+ *<BR>
+ *<B>Assertion Description: </B>
+ If the instance is of a class using application identity, the hollow instance
maintains its primary key fields.
+ */
+
+public class HollowInstanceMaintainsPK extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A5.5.4-3 (HollowInstanceMaintainsPK) failed: ";
+
+ /**
+ * The <code>main</code> 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(HollowInstanceMaintainsPK.class);
+ }
+
+ /** */
+ public void test() {
+ if (!isApplicationIdentitySupported()) {
+ if (debug) logger.debug("Application Identity is not supported");
+ }
+ else {
+ pm = getPM();
+ pm.currentTransaction().begin();
+
+ PCRect obj = getPersistentNewInstance();
+
+ long beforeValue=obj.getId();
+ pm.currentTransaction().commit(); // obj should transition to
HOLLOW
+ long afterValue=obj.getId();
+ if (beforeValue!=afterValue) {
+ fail(ASSERTION_FAILED,
+ "Key field value incorrect after commit. Expected: " +
+ beforeValue + " Found: " + afterValue);
+ }
+ }
+ }
+
+ /** */
+ private PCRect getPersistentNewInstance() {
+ PCRect obj = new PCRect();
+ pm.makePersistent(obj); // obj should transition to persistent-new
+ int curr = currentState(obj);
+ if( curr != PERSISTENT_NEW ){
+ fail(ASSERTION_FAILED,
+ "StateTransitions: Unable to create persistent-new instance "
+
+ "from transient instance via makePersistent(), state is " +
+ states[curr]);
+ }
+ return obj;
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/HollowInstanceMaintainsPK.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/MultiplePMsReturnInstancesRepresentingSamePC.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/MultiplePMsReturnInstancesRepresentingSamePC.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/MultiplePMsReturnInstancesRepresentingSamePC.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/MultiplePMsReturnInstancesRepresentingSamePC.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test that Multiple PMs return different instances representing
same PC object
+ *<BR>
+ *<B>Keywords:</B> lifecycle Multiple PMs getObjectById equal
+ *<BR>
+ *<B>Assertion IDs:</B> A5.4-7
+ *<BR>
+ *<B>Assertion Description: </B>
+ The instance returned by a call to getObjectById(Object) of different
PersistenceManager
+ instances returned by the same PersistenceManagerFactory represent the same
persistent object,
+ but with different Java object identity (specifically, all instances returned
by getObjectId from the instances
+ must return true to equals comparisons with all others).
+ */
+
+public class MultiplePMsReturnInstancesRepresentingSamePC extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A5.4-7 (MultiplePMsReturnInstancesRepresentingSamePC)
failed: ";
+
+ private static final int NUM_OBJECTS = 50;
+
+ /**
+ * The <code>main</code> 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(MultiplePMsReturnInstancesRepresentingSamePC.class);
+ }
+
+ public MultiplePMsReturnInstancesRepresentingSamePC()
+ {
+ }
+
+ public void test() {
+ PersistenceManager pm2 = null;
+ PersistenceManager pm3 = null;
+
+ try {
+ pm = getPM();
+ // Get two more PMs
+ pm2 = pmf.getPersistenceManager();
+ pm3 = pmf.getPersistenceManager();
+
+ Object[] obj = generatePersistentInstances();
+
+ Extent extent = pm.getExtent(StateTransitionObj.class,
false);
+ Iterator iter = extent.iterator();
+ if( !iter.hasNext() ){
+ fail(ASSERTION_FAILED,
+ "Extent for StateTransitionObj should
not be empty");
+ }
+ extent.close(iter);
+
+
+ for (int i=0; i<NUM_OBJECTS; i++)
+ {
+ Object obj1 = obj[i];
+ Object objId1 = pm.getObjectId(obj1);
+ Object obj2 = pm2.getObjectById(objId1,false);
+ Object objId2 = pm2.getObjectId(obj2);
+ Object obj3 = pm3.getObjectById(objId1,false);
+ Object objId3 = pm3.getObjectId(obj3);
+
+ //Verify that objects are different instances
+ if (!((obj1!=obj2) && (obj1!=obj3)))
+ {
+ fail(ASSERTION_FAILED,
+ "Objects are not different
instances. obj1=" + obj1 + " obj2= " + obj2 + " obj3= " + obj3);
+ }
+
+ //Verify that object Ids are equal
+ if (!(objId1.equals(objId2) &&
objId1.equals(objId3)))
+ {
+ fail(ASSERTION_FAILED,
+ "Object Ids are not equal.
objId1=" + objId1 + " objId2= " + objId2 + " objId3= " + objId3);
+ }
+ }
+ }
+ finally {
+ if (pm2!=null && !pm2.isClosed())
+ {
+ pm2.close();
+ }
+ if (pm3!=null && !pm3.isClosed())
+ {
+ pm3.close();
+ }
+ }
+ }
+
+ private Object[] generatePersistentInstances()
+ {
+ StateTransitionObj[] objects = new
StateTransitionObj[NUM_OBJECTS];
+ try {
+ Transaction t = pm.currentTransaction();
+ t.begin();
+ for(int i = 0; i < NUM_OBJECTS; ++i ){
+ objects[i]=new StateTransitionObj(i);
+ objects[i].writeField(i);
+ pm.makePersistent(objects[i]);
+ }
+ t.commit();
+ return objects;
+ }
+ finally {
+ Transaction tx = pm.currentTransaction();
+ if (tx.isActive()) {
+ tx.rollback();
+ }
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/MultiplePMsReturnInstancesRepresentingSamePC.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/ObjectIdNotModifiedWhenObjectIdInstanceModified.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/ObjectIdNotModifiedWhenObjectIdInstanceModified.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/ObjectIdNotModifiedWhenObjectIdInstanceModified.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/ObjectIdNotModifiedWhenObjectIdInstanceModified.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test that ObjectId is not modified even if ObjectId returned
by GetObjectId() is modified
+ *<BR>
+ *<B>Keywords:</B> lifecycle GetObjectId
+ *<BR>
+ *<B>Assertion IDs:</B> A5.4-6
+ *<BR>
+ *<B>Assertion Description: </B>
+ The object returned by any call to getObjectId might be modified by the user,
+ but that modification does not affect the identity of the object that was
originally referred.
+ */
+
+public class ObjectIdNotModifiedWhenObjectIdInstanceModified extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A5.4-6 (ObjectIdNotModifiedWhenObjectIdInstanceModified)
failed: ";
+
+ private static final int NUM_OBJECTS = 50;
+
+ /**
+ * The <code>main</code> 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(ObjectIdNotModifiedWhenObjectIdInstanceModified.class);
+ }
+
+ public ObjectIdNotModifiedWhenObjectIdInstanceModified()
+ {
+ }
+
+ public void test() throws Exception {
+ pm = getPM();
+
+ Object[] obj = generatePersistentInstances();
+
+ Extent extent = pm.getExtent(StateTransitionObj.class, false);
+ Iterator iter = extent.iterator();
+ if( !iter.hasNext() ){
+ fail(ASSERTION_FAILED,
+ "Extent for StateTransitionObj should not be
empty");
+ }
+ extent.close(iter);
+
+ for (int i=0; i<NUM_OBJECTS; i++)
+ {
+ Object objId=pm.getObjectId(obj[i]);
+ mangleObject(objId);
+ Object objId2 = pm.getObjectId(obj[i]); // get another
ObjectId copy
+ if (objId.equals(objId2))
+ fail(ASSERTION_FAILED,
+ "object Id has been changed");
+ }
+ }
+
+ private Object[] generatePersistentInstances()
+ {
+ StateTransitionObj[] objects = new
StateTransitionObj[NUM_OBJECTS];
+ try {
+ Transaction t = pm.currentTransaction();
+ t.begin();
+ for(int i = 0; i < NUM_OBJECTS; ++i ){
+ objects[i]=new StateTransitionObj(i);
+ objects[i].writeField(i);
+ pm.makePersistent(objects[i]);
+ }
+ t.commit();
+ return objects;
+ }
+ finally {
+ Transaction tx = pm.currentTransaction();
+ if (tx.isActive()) {
+ tx.rollback();
+ }
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/ObjectIdNotModifiedWhenObjectIdInstanceModified.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMReturnsIdenticalInstancesForEqualObjIds.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMReturnsIdenticalInstancesForEqualObjIds.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMReturnsIdenticalInstancesForEqualObjIds.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMReturnsIdenticalInstancesForEqualObjIds.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test that a PM returns the same JDO instance if
getObjectById(ObjectId) is called multiple times with the same objectId instance
+ *<BR>
+ *<B>Keywords:</B> lifecycle getObjectById
+ *<BR>
+ *<B>Assertion IDs:</B> A5.4-2, A5.4-8, A5.4-10
+ *<BR>
+ *<B>Assertion Description: </B>
+ Any instances returned by any calls to getObjectById(Object) with the same
object id instance to the same
+ PersistenceManager instance must be identical (assuming the instances were
not garbage collected between calls).
+ */
+
+public class PMReturnsIdenticalInstancesForEqualObjIds extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertions A5.4-2, A5.4-8, A5.4-10
(PMReturnsIdenticalInstancesForEqualObjIds) failed: ";
+
+ private static final int NUM_OBJECTS = 50;
+
+ /**
+ * The <code>main</code> 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(PMReturnsIdenticalInstancesForEqualObjIds.class);
+ }
+
+ public PMReturnsIdenticalInstancesForEqualObjIds()
+ {
+ }
+
+ public void test() {
+ pm = getPM();
+
+ Object[] obj = generatePersistentInstances();
+
+ Extent extent = pm.getExtent(StateTransitionObj.class, false);
+ Iterator iter = extent.iterator();
+ if( !iter.hasNext() ){
+ fail(ASSERTION_FAILED,
+ "Extent for StateTransitionObj should not be
empty");
+ }
+ extent.close(iter);
+
+ for (int i=0; i<NUM_OBJECTS; i++)
+ {
+ Object objId=pm.getObjectId(obj[i]);
+ // check that getObjectById returns identical instance
+ Object obj2 = pm.getObjectById(objId, true);
+ if (!(obj2==obj[i]))
+ {
+ fail(ASSERTION_FAILED,
+ "objects with OId = " + objId + " are
not identical");
+ }
+ }
+ }
+
+ private Object[] generatePersistentInstances()
+ {
+ StateTransitionObj[] objects = new
StateTransitionObj[NUM_OBJECTS];
+ try {
+ Transaction t = pm.currentTransaction();
+ t.begin();
+ for(int i = 0; i < NUM_OBJECTS; ++i ){
+ objects[i]=new StateTransitionObj(i);
+ objects[i].writeField(i);
+ pm.makePersistent(objects[i]);
+ }
+ t.commit();
+ return objects;
+ }
+ finally {
+ Transaction tx = pm.currentTransaction();
+ if (tx.isActive()) {
+ tx.rollback();
+ }
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMReturnsIdenticalInstancesForEqualObjIds.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMsCanSharePCClassesButNotPCInstances.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMsCanSharePCClassesButNotPCInstances.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMsCanSharePCClassesButNotPCInstances.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMsCanSharePCClassesButNotPCInstances.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.*;
+import javax.jdo.*;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+import org.apache.jdo.tck.util.ThreadExceptionHandler;
+
+/**
+ *<B>Title:</B> Test PM ability to share PC classes but not PC instances
+ *<BR>
+ *<B>Keywords:</B> PM share PC class
+ *<BR>
+ *<B>Assertion IDs:</B> A5.2-1,A5.2-2,A5.2-3
+ *<BR>
+ *<B>Assertion Description: </B>
+ Several JDO PersistenceManagers might be coresident and might
+ share the same persistence capable classes] (although a JDO instance can be
+ associated with only one PersistenceManager at a time)
+ */
+
+public class PMsCanSharePCClassesButNotPCInstances extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertions A5.2-1,A5.2-2,A5.2-3
(PMsCanSharePCClassesButNotPCInstances) failed: ";
+
+ /** The number of active threads. Each thread has its own PM. */
+ private int threads = 0;
+
+ /** The total number of attempts to insert PC instances */
+ private int attempts = 0;
+
+ /** The number of inserters. Each inserter runs in its own thread. */
+ private int inserters = 5;
+
+ /** The number of objects inserted. */
+ protected int insertedCount = 0;
+
+ /** The number of objects that is expected to have been inserted. */
+ protected int insertedCountExpected = 0;
+
+ /**
+ * The <code>main</code> 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(PMsCanSharePCClassesButNotPCInstances.class);
+ }
+
+ public PMsCanSharePCClassesButNotPCInstances()
+ {
+ }
+
+ public void test() {
+ // test shared PC - only one PM should succeed to insert the shared PC
+ threads = 0;
+ attempts = 0;
+ insertedCount = 0;
+ insertedCountExpected = 1;
+ insertObjects(true);
+
+ // test non-shared PCs - each PM should succeed to insert its own
non-shared PC
+ threads = 0;
+ attempts = 0;
+ //insertedCount = 0; //Don't reset this value since we have not
deleted the inserted object from the shared PC test above
+ insertedCountExpected += inserters;
+ insertObjects(false);
+ }
+
+ protected void insertObjects(boolean sharedPC) {
+ Object pc = null;
+
+ ThreadExceptionHandler threadGroup = new ThreadExceptionHandler();
+ for (int i = 0; i < inserters; i++) {
+ if (sharedPC) { // each thread shares one PC
+ if (pc==null)
+ pc = new StateTransitionObj(i);
+ }
+ else { // each thread has its own PC
+ pc = new StateTransitionObj(i);
+ }
+ threads++;
+ Thread t = new Thread(threadGroup, new Inserter(pmf, pc,
sharedPC));
+ t.setName("Inserter-" + i);
+ t.start();
+ }
+
+ Thread.currentThread().yield();
+
+ while (! attemptsComplete()) {
+ try {
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException ex) {
+ logger.debug("interrupted while waiting for threads to
insert");
+ }
+ }
+
+ while (threads > 0) {
+ try {
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException ex) {
+ logger.debug("interrupted while waiting for threads to
finish");
+ }
+ }
+ }
+
+ synchronized void signal() {
+ threads--;
+ }
+
+ protected synchronized void incrAttempts() {
+ attempts++;
+ }
+
+ protected synchronized boolean attemptsComplete() {
+ return attempts == inserters;
+ }
+
+ class Inserter implements Runnable {
+ private final PersistenceManager pm;
+ private final Object pc;
+ private final Class instanceClass;
+ private final boolean sharedPC;
+
+ Inserter(PersistenceManagerFactory pmf, Object pc, boolean sharedPC) {
+ this.pm = pmf.getPersistenceManager();
+ this.pc = pc;
+ this.instanceClass = pc.getClass();
+ this.sharedPC = sharedPC;
+ }
+
+ protected synchronized void announce(String msg, Object pc) {
+ insertedCount++;
+ Object oid = JDOHelper.getObjectId(pc);
+ if (debug)
+ logger.debug(msg + this.getClass().getName() + ": " + oid +
+ ", " + pc);
+ }
+
+ public void run() {
+ Transaction tx = null;
+ try {
+ if (debug) logger.debug("running");
+ tx = pm.currentTransaction();
+ tx.begin();
+ try {
+ pm.makePersistent(pc);
+ announce("inserted ", pc);
+ tx.commit();
+ }
+ catch (JDOException ex) {
+ if (!sharedPC) //we expect an exception for all but one of
the inserters in the case of a shared PC
+ throw ex;
+ }
+ finally {
+ if (tx != null && tx.isActive())
+ tx.rollback();
+ }
+ incrAttempts();
+
+ while (!attemptsComplete()) {
+ try {
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException ex) {
+ if (debug) logger.debug(" interrupted");
+ }
+ }
+
+ //Verify that the number of inserted objects matches the
expected number
+ if (insertedCount!=insertedCountExpected)
+ {
+ fail(ASSERTION_FAILED,
+ "Wrong number of objects in extent. Inserted=" +
+ insertedCount + " Expected=" + insertedCountExpected);
+ }
+
+ if (debug) logger.debug("getting Extent");
+ int objCount = 0;
+ if (debug)
+ logger.debug("getting Extent of " +
instanceClass.getName());
+ Extent e = pm.getExtent(instanceClass, false);
+ for (Iterator i = e.iterator(); i.hasNext();) {
+ Object instance = (Object)i.next();
+ objCount++;
+ }
+
+ //Verify that the number of inserted objects matches the
number of objects in the extent
+ if (insertedCount!=objCount)
+ {
+ fail(ASSERTION_FAILED,
+ "Wrong number of objects in extent.
Inserted="+insertedCount+" Found="+objCount);
+ }
+ } finally {
+ if (tx != null && tx.isActive())
+ tx.rollback();
+ if (pm != null && !pm.isClosed())
+ pm.close();
+ PMsCanSharePCClassesButNotPCInstances.this.signal();
+ }
+ }
+
+ public String toString() {
+ String rc = "Inserter ";
+ if (debug) {
+ rc += Thread.currentThread().toString();
+ }
+ return rc;
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/PMsCanSharePCClassesButNotPCInstances.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,768 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test State Transitions
+ *<BR>
+ *<B>Keywords:</B> lifecycle
+ *<BR>
+ *<B>Assertion IDs:</B> A5.9-1 through A5.9-190
+ *<B>Assertion Description: </B>
+ All possible state transistions are being tested in this test.
+ */
+
+public class StateTransitions extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertions A5.9-1 through A5.9-190 (StateTransitions) failed: ";
+
+ /**
+ * The <code>main</code> 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(StateTransitions.class);
+ }
+
+ private Transaction transaction;
+ private int scenario;
+ private int operation;
+ private int current_state;
+ private int expected_state;
+ private int new_state;
+
+/**
+ * Operations that cause state changes
+ */
+ private static final int MAKEPERSISTENT = 0;
+ private static final int DELETEPERSISTENT = 1;
+ private static final int MAKETRANSACTIONAL = 2;
+ private static final int MAKENONTRANSACTIONAL = 3;
+ private static final int MAKETRANSIENT = 4;
+ private static final int COMMITNORETAINVALUES = 5;
+ private static final int COMMITRETAINVALUES = 6;
+ private static final int ROLLBACKNORESTOREVALUES = 7;
+ private static final int ROLLBACKRESTOREVALUES = 8;
+ private static final int REFRESHDATASTORE = 9;
+ private static final int REFRESHOPTIMISTIC = 10;
+ private static final int EVICT = 11;
+ private static final int READOUTSIDETX = 12;
+ private static final int READOPTIMISTIC = 13;
+ private static final int READDATASTORE = 14;
+ private static final int WRITEOUTSIDETX = 15;
+ private static final int WRITEINSIDETX = 16;
+ private static final int RETRIEVEOUTSIDETX = 17;
+ private static final int RETRIEVEINSIDETX = 18;
+
+ private static final String[] operations = {
+ "makePersistent",
+ "deletePersistent",
+ "makeTransactional",
+ "makeNontransactional",
+ "makeTransient",
+ "commit, retainValues=false",
+ "commit, retainValues=true",
+ "rollback, restoreValues=false",
+ "rollback, restoreValues=true",
+ "refresh with active datastore tx",
+ "refresh with active optimistic tx",
+ "evict",
+ "read field outside tx",
+ "read field with active optimistic tx",
+ "read field with active datastore tx",
+ "write field outside tx",
+ "write field with active tx",
+ "retrieve outside tx",
+ "retrieve with active tx"
+ };
+ private static final int NUM_OPERATIONS = 19;
+
+ private static final boolean[] closes_transaction =
+ { false, false, false, false, false, true, true, true, true, false,
+ false, false, false, false, false, false, false, false, false };
+
+ /**
+ * Illegal state transitions
+ */
+ private static final int UNCHANGED = -1;
+ private static final int ERROR = -2;
+ private static final int IMPOSSIBLE = -3;
+ private static final int NOT_APPLICABLE = -4;
+
+ /**
+ * State transitions
+ */
+ public static final int[][] transitions = { // [operation] [current state]
= new state
+ // makePersistent
+ { PERSISTENT_NEW, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED,
PERSISTENT_NEW,
+ PERSISTENT_NEW, UNCHANGED, UNCHANGED, UNCHANGED},
+
+ // deletePersistent
+ { ERROR, PERSISTENT_NEW_DELETED, PERSISTENT_DELETED,
PERSISTENT_DELETED,
+ PERSISTENT_DELETED, ERROR, ERROR, UNCHANGED, UNCHANGED,
PERSISTENT_DELETED},
+
+ // makeTransactional
+ { TRANSIENT_CLEAN, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN,
+ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN},
+
+ // makeNontransactional
+ { ERROR, ERROR, PERSISTENT_NONTRANSACTIONAL, ERROR, UNCHANGED,
+ TRANSIENT, ERROR, ERROR, ERROR, UNCHANGED},
+
+ // makeTransient
+ { UNCHANGED, ERROR, TRANSIENT, ERROR, TRANSIENT,
+ UNCHANGED, UNCHANGED, ERROR, ERROR, TRANSIENT},
+
+ // commit, retainValues = false
+ { UNCHANGED, HOLLOW, HOLLOW, HOLLOW, UNCHANGED, UNCHANGED,
+ TRANSIENT_CLEAN, TRANSIENT, TRANSIENT, UNCHANGED},
+
+ // commit, retainValues = true
+ { UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL,
+ PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED, TRANSIENT_CLEAN,
+ TRANSIENT, TRANSIENT, UNCHANGED},
+
+ // rollback, restoreValues = false
+ { UNCHANGED, TRANSIENT, HOLLOW, HOLLOW, UNCHANGED, UNCHANGED,
+ TRANSIENT_CLEAN, TRANSIENT, HOLLOW, UNCHANGED},
+
+ // rollback, restoreValues = true
+ { UNCHANGED, TRANSIENT, PERSISTENT_NONTRANSACTIONAL,
PERSISTENT_NONTRANSACTIONAL,
+ UNCHANGED, UNCHANGED, TRANSIENT_CLEAN, TRANSIENT,
PERSISTENT_NONTRANSACTIONAL, UNCHANGED},
+
+ // refresh with active datastore transaction
+ { UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
+ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED},
+
+ // refresh with active optimistic transaction
+ { UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NONTRANSACTIONAL,
UNCHANGED,
+ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED},
+
+ // evict
+ { NOT_APPLICABLE, UNCHANGED, HOLLOW, UNCHANGED, UNCHANGED,
+ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, HOLLOW},
+
+ // read field outside transaction
+ { UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
PERSISTENT_NONTRANSACTIONAL,
+ UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED},
+
+ // read field with active optimistic transaction
+ { UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED,
PERSISTENT_NONTRANSACTIONAL,
+ UNCHANGED, UNCHANGED, ERROR, ERROR, UNCHANGED},
+
+ // read field with active datastore transaction
+ { UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN,
+ UNCHANGED, UNCHANGED, ERROR, ERROR, PERSISTENT_CLEAN},
+
+ // write field outside transaction
+ { UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
PERSISTENT_NONTRANSACTIONAL,
+ UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED},
+
+ // write field with active transaction
+ { UNCHANGED, UNCHANGED, PERSISTENT_DIRTY, UNCHANGED, PERSISTENT_DIRTY,
+ TRANSIENT_DIRTY, UNCHANGED, ERROR, ERROR, PERSISTENT_DIRTY},
+
+ // retrieve outside transaction
+ { UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
PERSISTENT_NONTRANSACTIONAL,
+ UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED},
+
+ // retrieve with active transaction
+ { UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN,
+ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN}
+ };
+
+ private static final int DATASTORE_TX = 0;
+ private static final int OPTIMISTIC_TX = 1;
+ private static final int NO_TX = 2;
+
+ private static final String[] scenario_string = {
+ "datastore transaction", "optimistic transaction", "no transaction"
+ };
+
+ private static final boolean[][] applies_to_scenario = {
+ // Datastore Optimistic No tx
+ { true, true, false }, // makePersistent
+ { true, true, false }, // deletePersistent
+ { true, true, false }, // makeTransactional
+ { true, true, false }, // makeNontransactional
+ { true, true, false }, // makeTransient
+ { true, true, false }, // commit RetainValues =
false
+ { true, true, false }, // commit RetainValues = true
+ { true, true, false }, // rollback RestoreValues =
false
+ { true, true, false }, // rollback RestoreValues =
true
+ { true, false, false }, // refresh with active
datastore transaction
+ { false, true, false }, // refresh with active
optimistic transaction
+ { true, true, false }, // evict
+ { false, false, true }, // read field outside of a
transaction
+ { false, true, false }, // read field with active
optimistic transaction
+ { true, false, false }, // read field with active
datastore transaction
+ { false, false, true }, // write field or makeDirty
outside of a transaction
+ { true, true, false }, // write field or makeDirty
with active transaction
+ { false, true, true }, // retrieve outside of a
transaction or with active optimistic transaction
+ { true, false, false } // retrieve with active
datastore transaction
+ };
+
+ public StateTransitions()
+ {
+ }
+
+ public void test() {
+ pm = getPM();
+ generatePersistentInstances();
+
+ scenario = DATASTORE_TX;
+ checkTransitions();
+
+ if( isOptimisticSupported() ){
+ scenario = OPTIMISTIC_TX;
+ checkTransitions();
+ }
+
+ scenario = NO_TX;
+ checkTransitions();
+ }
+
+ /** */
+ private void generatePersistentInstances()
+ {
+ if( doPersistentInstancesExist() ) return;
+ int i;
+ Transaction t = pm.currentTransaction();
+ t.begin();
+ for( i = 0; i < 50; ++i ){
+ StateTransitionObj sto = new StateTransitionObj(i);
+ sto.writeField(i);
+ pm.makePersistent(sto);
+ }
+ t.commit();
+ if( !doPersistentInstancesExist() )
+ if (debug)
+ logger.debug("StateTransitions unable to create instances of
StateTransitionsObj");
+ }
+
+ /** */
+ private boolean doPersistentInstancesExist()
+ {
+ boolean ret;
+ Transaction t = pm.currentTransaction();
+ t.begin();
+ Extent e = pm.getExtent(StateTransitionObj.class, false);
+ Iterator iter = e.iterator();
+ ret = iter.hasNext();
+ t.rollback();
+ return ret;
+ }
+
+ /** */
+ void checkTransitions()
+ {
+ for( operation = 0; operation < NUM_OPERATIONS; ++operation ){
+ // rule out situations that do not apply
+ if( ! applies_to_scenario[operation][scenario] ) continue;
+ if( operation == READOUTSIDETX &&
!isNontransactionalReadSupported() ) continue;
+ if( operation == WRITEOUTSIDETX &&
!isNontransactionalWriteSupported() ) continue;
+ if( operation == COMMITRETAINVALUES && !isRetainValuesSupported()
) continue;
+ if( operation == MAKENONTRANSACTIONAL &&
+ !(isNontransactionalReadSupported() ||
isNontransactionalWriteSupported()) )
+ continue;
+
+ for( current_state = 0; current_state < NUM_STATES;
++current_state){
+ if( scenario == OPTIMISTIC_TX && current_state ==
PERSISTENT_CLEAN ) continue;
+ if( (current_state == TRANSIENT_CLEAN || current_state ==
TRANSIENT_DIRTY) &&
+ !isTransientTransactionalSupported() )
+ continue; // this state is not supported by
implementation
+ if( current_state == PERSISTENT_NONTRANSACTIONAL &&
+ !(isNontransactionalReadSupported() ||
isNontransactionalWriteSupported()) )
+ continue; // this state is not supported by
implementation
+
+ expected_state = transitions[operation][current_state];
+ if( expected_state == IMPOSSIBLE ) continue;
+ if( expected_state == NOT_APPLICABLE ) continue;
+ if( expected_state == UNCHANGED ) expected_state =
current_state;
+ try {
+ transaction = pm.currentTransaction();
+ if( transaction.isActive()){
+ if (debug)
+ logger.debug("Transaction is active (but should
not be), rolling back");
+ transaction.rollback();
+ }
+
+ if( scenario != NO_TX ){
+ if( operation == COMMITNORETAINVALUES )
+ transaction.setRetainValues(false);
+ if( operation == COMMITRETAINVALUES )
+ transaction.setRetainValues(true);
+ if( operation == ROLLBACKNORESTOREVALUES )
+ transaction.setRestoreValues(false);
+ if( operation == ROLLBACKRESTOREVALUES )
+ transaction.setRestoreValues(true);
+
+ transaction.setOptimistic(scenario == OPTIMISTIC_TX);
+ transaction.begin();
+ if( !transaction.isActive() )
+ if (debug)
+ logger.debug("StateTransitions: Transaction
should be active, but it is not");
+ }
+
+ StateTransitionObj obj = getInstanceInState(current_state);
+ if( obj == null ){ // could not get object in state
+ if( transaction.isActive() ) transaction.rollback();
+ continue;
+ }
+
+ // Apply operation, catching possible exception
+ Exception e = null;
+ try {
+ applyOperation(operation, obj);
+ } catch( Exception excep ){
+ if( excep instanceof javax.jdo.JDOUserException ){
+ e = excep;
+ } else {
+ printSituation();
+ fail(ASSERTION_FAILED,
+ "StateTransitions: Unexpected exception:" +
excep);
+ continue;
+ }
+ }
+
+ // Get new state, verify correct transition and exceptions
occurred
+ new_state = currentState(obj);
+ if( expected_state == ERROR ){
+ if( e == null ){
+ printSituation();
+ fail(ASSERTION_FAILED,
+ "StateTransitions: JDOUserException should
have been thrown");
+ } else {
+ if( new_state != current_state ){
+ printSituation();
+ fail(ASSERTION_FAILED,
+ "StateTransitions: " +
+ " JDOUserException properly thrown, but
instance should remain in current state," +
+ "instance changed state to " +
states[new_state]);
+ }
+ }
+ }
+ if( expected_state >= 0 && new_state != expected_state &&
+ !((new_state == HOLLOW && expected_state ==
PERSISTENT_NONTRANSACTIONAL) ||
+ (new_state == PERSISTENT_NONTRANSACTIONAL &&
expected_state == HOLLOW)) ) {
+ // status interrogation gives same values for
PERSISTENT_NONTRANSACTIONAL and HOLLOW
+ printSituation();
+ fail(ASSERTION_FAILED,
+ "StateTransitions: Invalid state transition to " +
+ states[new_state] + ", new state should be " +
+ states[expected_state]);
+ }
+ if( transaction.isActive() ) transaction.rollback();
+ }
+ catch(Exception unexpected_exception) {
+ printSituation();
+ if (transaction.isActive())
+ transaction.rollback();
+ fail(ASSERTION_FAILED,
+ "Unexpected exception caught in StateTransitions " +
unexpected_exception);
+ }
+ }
+ }
+ }
+
+ /** */
+ void printSituation()
+ {
+ if (debug) {
+ logger.debug(" (" + scenario_string[scenario] +
+ ", initial state=" + states[current_state] +
+ ", operation=" + operations[operation] + ")");
+ }
+ }
+
+ /** */
+ void applyOperation(int operation, StateTransitionObj stobj)
+ {
+ StateTransitionObj obj = (StateTransitionObj) stobj;
+ switch( operation ){
+ case MAKEPERSISTENT:
+ {
+ pm.makePersistent(obj);
+ break;
+ }
+ case DELETEPERSISTENT:
+ {
+ pm.deletePersistent(obj);
+ break;
+ }
+ case MAKETRANSACTIONAL:
+ {
+ pm.makeTransactional(obj);
+ break;
+ }
+ case MAKENONTRANSACTIONAL:
+ {
+ pm.makeNontransactional(obj);
+ break;
+ }
+ case MAKETRANSIENT:
+ {
+ pm.makeTransient(obj);
+ break;
+ }
+ case COMMITNORETAINVALUES:
+ {
+ pm.currentTransaction().commit();
+ break;
+ }
+ case COMMITRETAINVALUES:
+ {
+ pm.currentTransaction().commit();
+ break;
+ }
+ case ROLLBACKNORESTOREVALUES:
+ {
+ pm.currentTransaction().rollback();
+ break;
+ }
+ case ROLLBACKRESTOREVALUES:
+ {
+ pm.currentTransaction().rollback();
+ break;
+ }
+ case REFRESHDATASTORE:
+ {
+ pm.refresh(obj);
+ break;
+ }
+ case REFRESHOPTIMISTIC:
+ {
+ pm.refresh(obj);
+ break;
+ }
+ case EVICT:
+ {
+ pm.evict(obj);
+ break;
+ }
+ case READOUTSIDETX:
+ {
+ int val = obj.readField();
+ break;
+ }
+ case READOPTIMISTIC:
+ {
+ int val = obj.readField();
+ break;
+ }
+ case READDATASTORE:
+ {
+ int val = obj.readField();
+ break;
+ }
+ case WRITEOUTSIDETX:
+ {
+ obj.writeField(42);
+ break;
+ }
+ case WRITEINSIDETX:
+ {
+ obj.writeField(42);
+ break;
+ }
+ case RETRIEVEOUTSIDETX:
+ {
+ pm.retrieve(obj);
+ break;
+ }
+ case RETRIEVEINSIDETX:
+ {
+ pm.retrieve(obj);
+ break;
+ }
+ default:
+ {
+ fail(ASSERTION_FAILED,
+ "StateTransitions internal error, illegal operation " +
operation);
+ }
+ }
+ }
+
+ /**
+ * Get an instance in the specified state.
+ */
+ private StateTransitionObj getInstanceInState(int state)
+ {
+ switch(state) {
+ case TRANSIENT:
+ return getTransientInstance();
+ case PERSISTENT_NEW:
+ return getPersistentNewInstance();
+ case PERSISTENT_CLEAN:
+ return getPersistentCleanInstance();
+ case PERSISTENT_DIRTY:
+ return getPersistentDirtyInstance();
+ case HOLLOW:
+ return getHollowInstance();
+ case TRANSIENT_CLEAN:
+ return getTransientCleanInstance();
+ case TRANSIENT_DIRTY:
+ return getTransientDirtyInstance();
+ case PERSISTENT_NEW_DELETED:
+ return getPersistentNewDeletedInstance();
+ case PERSISTENT_DELETED:
+ return getPersistentDeletedInstance();
+ case PERSISTENT_NONTRANSACTIONAL:
+ return getPersistentNontransactionalInstance();
+ default:
+ {
+ return null;
+ }
+ }
+ }
+
+ /** */
+ private StateTransitionObj getTransientInstance()
+ {
+ StateTransitionObj obj = new StateTransitionObj(23);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT ) {
+ if (debug) {
+ logger.debug("StateTransitions: Unable to create transient
instance, state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ private StateTransitionObj getPersistentNewInstance()
+ {
+ StateTransitionObj obj = getTransientInstance();
+ if( obj == null ) return null;
+ pm.makePersistent(obj); // should transition to persistent-new
+ int curr = currentState(obj);
+ if( curr != PERSISTENT_NEW ) {
+ if (debug) {
+ logger.debug("StateTransitions: Unable to create
persistent-new instance" +
+ " from transient instance via makePersistent(),
state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getPersistentCleanInstance()
+ {
+ StateTransitionObj obj = getHollowInstance();
+ if( obj == null ) return null;
+ StateTransitionObj sto = (StateTransitionObj) obj;
+ int val = sto.readField();
+ int curr = currentState(sto);
+ if( curr != PERSISTENT_CLEAN ) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
persistent-clean instance" +
+ " from a hollow instance by reading a field,
state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getPersistentDirtyInstance()
+ {
+ StateTransitionObj obj = getHollowInstance();
+ if( obj == null ) return null;
+ StateTransitionObj pcobj = (StateTransitionObj) obj;
+ pcobj.writeField(23);
+ int curr = currentState(obj);
+ if( curr != PERSISTENT_DIRTY ) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
persistent-dirty instance" +
+ " from a hollow instance by writing a field,
state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getHollowInstance()
+ {
+ Extent extent = pm.getExtent(StateTransitionObj.class, false);
+ Iterator iter = extent.iterator();
+ if( !iter.hasNext() ){
+ if (debug)
+ logger.debug("Extent for StateTransitionObj should not be
empty");
+ return null;
+ }
+ StateTransitionObj obj = (StateTransitionObj) iter.next();
+
+ transaction.setRetainValues(false);
+ if ( !transaction.isActive() )
+ transaction.begin();
+ if( !transaction.isActive() )
+ if (debug)
+ logger.debug("getHollowInstance: Transaction should be active,
but it is not");
+
+ transaction.commit(); // This should put the instance in the HOLLOW
state
+
+ if( scenario != NO_TX ){
+ if( operation == COMMITNORETAINVALUES )
+ transaction.setRetainValues(false);
+ if( operation == COMMITRETAINVALUES )
+ transaction.setRetainValues(true);
+ if( operation == ROLLBACKNORESTOREVALUES )
+ transaction.setRestoreValues(false);
+ if( operation == ROLLBACKRESTOREVALUES )
+ transaction.setRestoreValues(true);
+
+ transaction.setOptimistic(scenario == OPTIMISTIC_TX);
+ transaction.begin();
+ if( !transaction.isActive() )
+ if (debug)
+ logger.debug("getHollowInstance: Transaction should be
active, but it is not");
+ }
+
+ int curr = currentState(obj);
+ if( curr != HOLLOW && curr != PERSISTENT_NONTRANSACTIONAL ){
+ if (debug) {
+ logger.debug("StateTransition: Attempt to get hollow instance
via accessing extent failed, state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getTransientCleanInstance()
+ {
+ StateTransitionObj obj = getTransientInstance();
+ if( obj == null ) return null;
+ pm.makeTransactional(obj);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_CLEAN ) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
transient-clean instance" +
+ " from a transient instance via
makeTransactional(), state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getTransientDirtyInstance()
+ {
+ StateTransitionObj obj = getTransientCleanInstance();
+ if( obj == null ) return null;
+ StateTransitionObj pcobj = (StateTransitionObj) obj;
+ pcobj.writeField(23);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_DIRTY ) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
transient-dirty instance" +
+ " from a transient-clean instance via modifying a
field, state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getPersistentNewDeletedInstance()
+ {
+ StateTransitionObj obj = getPersistentNewInstance();
+ if( obj == null ) return null;
+ pm.deletePersistent(obj); // should transition to
persistent-new-deleted
+ int curr = currentState(obj);
+ if( curr != PERSISTENT_NEW_DELETED) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
persistent-new-deleted instance" +
+ " from a persistent-new instance via
deletePersistent, state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getPersistentDeletedInstance()
+ {
+ StateTransitionObj obj = getHollowInstance();
+ if( obj == null ) return null;
+ pm.deletePersistent(obj);
+ int curr = currentState(obj);
+ if( curr != PERSISTENT_DELETED ) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
persistent-deleted instance" +
+ " from a persistent instance via
deletePersistent(), state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return obj;
+ }
+
+ /** */
+ public StateTransitionObj getPersistentNontransactionalInstance()
+ {
+ StateTransitionObj obj = getHollowInstance();
+ if( obj == null ) return null;
+ pm.makeNontransactional(obj);
+ int curr = currentState(obj);
+ if( curr != PERSISTENT_NONTRANSACTIONAL && curr != HOLLOW ) {
+ if (debug) {
+ logger.debug("StateTransition: Unable to create
persistent-nontransactional instance" +
+ " from a persistent-clean instance via
makeNontransactional(), state is " +
+ states[curr]);
+ }
+ printSituation();
+ return null;
+ }
+ return null;
+ }
+
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test Transient Transactional Commit
+ *<BR>
+ *<B>Keywords:</B> lifecycle transienttransactional commit
+ *<BR>
+ *<B>Assertion IDs:</B> A5.1-3
+ *<BR>
+ *<B>Assertion Description: </B>
+ If <code>TransientTransactional</code> is supported, a transient
transactional instance
+ will have its state preserved when its associated transaction commits.
+*/
+
+
+public class TransientTransactionalStateCommit extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A5.1-3 (TransientTransactionalStateCommit) failed: ";
+
+ private static final int CLEAN_VALUE = 12;
+ private static final int DIRTY_VALUE = 123;
+
+ /**
+ * The <code>main</code> 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(TransientTransactionalStateCommit.class);
+ }
+
+ /** */
+ public void test() {
+ if (!isTransientTransactionalSupported()) {
+ logger.debug("Transient transactional instances are not
supported");
+ }
+ else {
+ pm = getPM();
+
+ StateTransitionObj obj = getTransientInstance();
+
+ pm.currentTransaction().begin();
+
+ makeTransientDirty(obj);
+
+ int beforeValue=obj.readField();
+ pm.currentTransaction().commit();
+ int afterValue=obj.readField();
+ if (beforeValue!=afterValue)
+ {
+ fail(ASSERTION_FAILED,
+ "Field value incorrect after commit. Expected: " +
+ beforeValue + " Found: " + afterValue);
+ }
+ }
+ }
+
+ protected StateTransitionObj getTransientInstance() {
+ StateTransitionObj obj = new StateTransitionObj(CLEAN_VALUE);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT ){
+ fail(ASSERTION_FAILED,
+ "Unable to create transient instance, state is " +
+ states[curr]);
+ }
+ return obj;
+ }
+
+ protected void makeTransientClean(StateTransitionObj obj) {
+ if( obj == null ) return;
+ pm.makeTransactional(obj);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_CLEAN ){
+ fail(ASSERTION_FAILED,
+ "Unable to create transient-clean instance " +
+ "from a transient instance via makeTransactional(), state is
" +
+ states[curr]);
+ }
+ }
+
+ protected void makeTransientDirty(StateTransitionObj obj) {
+ if( obj == null ) return;
+ makeTransientClean(obj);
+ obj.writeField(DIRTY_VALUE);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_DIRTY ){
+ fail(ASSERTION_FAILED,
+ "Unable to create transient-dirty instance " +
+ "from a transient-clean instance via modifying a field, state
is " +
+ states[curr]);
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle;
+
+import java.util.Iterator;
+
+import javax.jdo.Extent;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Transaction;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Test Transient Transactional Rollback
+ *<BR>
+ *<B>Keywords:</B> lifecycle transienttransactional rollback
+ *<BR>
+ *<B>Assertion IDs:</B> A5.1-4
+ *<B>Assertion Description: </B>
+ If <code>TransientTransactional</code> is supported, a transient
transactional instance
+ will have its state restored to its state prior to becoming transactional when
+ its associated transaction aborts or on rollback.
+ */
+
+public class TransientTransactionalStateRollback extends JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A5.1-4 (TransientTransactionalStateRollback) failed: ";
+
+ private static final int CLEAN_VALUE = 12;
+ private static final int DIRTY_VALUE = 123;
+
+ /**
+ * The <code>main</code> 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(TransientTransactionalStateRollback.class);
+ }
+
+ /** */
+ public void test() {
+ if (!isTransientTransactionalSupported()) {
+ logger.debug("Transient transactional instances are not
supported");
+ }
+ else {
+ pm = getPM();
+
+ // Get transient instance and read field value
+ StateTransitionObj obj = getTransientInstance();
+
+ int beforeValue=obj.readField();
+
+ // Start transaction
+ Transaction tx = pm.currentTransaction();
+ tx.begin();
+
+ // Get transient dirty instance
+ makeTransientDirty(obj);
+
+ // Rollback
+ tx.rollback();
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_CLEAN ){
+ fail(ASSERTION_FAILED,
+ "StateTransition: Unable to create transient-clean
instance " +
+ "from a transient-dirty instance via tx.rollback(), state
is " + states[curr]);
+ }
+
+ // Check that field value has been rolled back
+ int afterValue=obj.readField();
+ if (beforeValue!=afterValue)
+ {
+ fail(ASSERTION_FAILED,
+ "Field value incorrect after rollback. Expected:
"+beforeValue+" Found: "+afterValue);
+ }
+ }
+ }
+
+ protected StateTransitionObj getTransientInstance() {
+ StateTransitionObj obj = new StateTransitionObj(CLEAN_VALUE);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT ){
+ fail(ASSERTION_FAILED,
+ "Unable to create transient instance, state is " +
states[curr]);
+ }
+ return obj;
+ }
+
+ protected void makeTransientClean(StateTransitionObj obj) {
+ if( obj == null ) return;
+ pm.makeTransactional(obj);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_CLEAN ){
+ fail(ASSERTION_FAILED,
+ "Unable to create transient-clean instance " +
+ "from a transient instance via makeTransactional(), state is
" + states[curr]);
+ }
+ }
+
+ protected void makeTransientDirty(StateTransitionObj obj) {
+ if( obj == null ) return;
+ makeTransientClean(obj);
+ obj.writeField(DIRTY_VALUE);
+ int curr = currentState(obj);
+ if( curr != TRANSIENT_DIRTY ){
+ fail(ASSERTION_FAILED,
+ "Unable to create transient-dirty instance " +
+ "from a transient-clean instance via modifying a field, state
is " + states[curr]);
+ }
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java
URL:
http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java?view=auto&rev=160090
==============================================================================
---
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java
(added)
+++
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java
Mon Apr 4 12:41:23 2005
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.lifecycle.nontransactional;
+
+import java.util.Iterator;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Extent;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Modification of Nontransactional Persistent Instance Outside a
Transaction
+ *<BR>
+ *<B>Keywords:</B> nontransactionalwrite
+ *<BR>
+ *<B>Assertion ID:</B> A5.6-9.
+ *<BR>
+ *<B>Assertion Description: </B>
+ * With <code>NontransactionalWrite</code> set to <code>true</code>,
+ * modification of nontransactional persistent instances is permitted outside
+ * a transaction. The changes do not participate in any subsequent
transaction.
+ */
+
+public class ModificationOfNontransactionalInstanceOutsideTransaction extends
JDO_Test {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A5.6-9
(ModificationOfNontransactionalInstanceOutsideTransaction) failed: ";
+
+ /**
+ * The <code>main</code> 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(ModificationOfNontransactionalInstanceOutsideTransaction.class);
+ }
+
+ /**
+ * The pc instance, set by method createAndModifyInstance.
+ */
+ private StateTransitionObj object;
+
+ /**
+ * The ObjectId of the pc instance, set by method
+ * createAndModifyInstance.
+ */
+ private Object oid;
+
+ /**
+ * The original value of the int field of the pc instance,
+ * set by method createAndModifyInstance.
+ */
+ private int originalValue;
+
+ /** */
+ public void testDifferentPM() {
+ if (!isNontransactionalWriteSupported()) {
+ printUnsupportedOptionalFeatureNotTested(
+ "NontransactionalWrite", "testDifferentPM");
+ }
+ else {
+ pm = getPM();
+ createAndModifyInstance();
+
+ int value=object.readField();
+ if (value!=999){
+ fail(ASSERTION_FAILED,
+ "Unable to write value to field with
setNontransactionalWrite==true");
+ }
+
+ // begin new transaction, read instance from datastore and
+ // verify that old value is still there
+ PersistenceManager pm2 = null;
+ try {
+ pm2 = getPMF().getPersistenceManager();
+ pm2.currentTransaction().begin();
+ StateTransitionObj object2 =
+ (StateTransitionObj)pm2.getObjectById(oid,true);
+ if (object2 == null){
+ fail(ASSERTION_FAILED,
+ "Failed to read instance from datastore via
pm.getObjectById(...)");
+ }
+
+ int value2 = object2.readField();
+ if (value2 != originalValue){
+ fail(ASSERTION_FAILED,
+ "Value has been changed with
setNontransactionalWrite==true. " +
+ "New value is " + value2 + " ... Old value was " +
originalValue);
+ }
+ pm2.currentTransaction().commit();
+ }
+ finally {
+ if ((pm2 != null) && !pm2.isClosed()) {
+ if (pm2.currentTransaction().isActive())
+ pm2.currentTransaction().rollback();
+ pm2.close();
+ }
+ }
+ }
+ }
+
+ /** */
+ public void testSameInstance() {
+ if (!isNontransactionalWriteSupported()) {
+ printUnsupportedOptionalFeatureNotTested(
+ "NontransactionalWrite", "testDifferentPM");
+ }
+ else {
+ pm = getPM();
+ createAndModifyInstance();
+
+ // use the object in a new datastore transaction
+ pm.currentTransaction().setOptimistic(false);
+ pm.currentTransaction().begin();
+ int value = object.readField();
+ if (value != originalValue){
+ fail(ASSERTION_FAILED,
+ "Value has been changed with
setNontransactionalWrite==true. " +
+ "New value is " + value + " ... Old value was " +
originalValue);
+ }
+ pm.currentTransaction().commit();
+ }
+ }
+
+ /** */
+ public void testIterateExtent() {
+ if (!isNontransactionalWriteSupported()) {
+ printUnsupportedOptionalFeatureNotTested(
+ "NontransactionalWrite", "testDifferentPM");
+ }
+ else {
+ pm = getPM();
+ createAndModifyInstance();
+
+ // iterate the extent and use the object in a new datastore
transaction
+ pm.currentTransaction().setOptimistic(false);
+ pm.currentTransaction().begin();
+ Extent e = pm.getExtent(StateTransitionObj.class, false);
+ for (Iterator i = e.iterator(); i.hasNext();) {
+ StateTransitionObj next = (StateTransitionObj)i.next();
+ if (oid.equals(pm.getObjectId(next))) {
+ // found instance
+ int value = next.readField();
+ if (value != originalValue){
+ fail(ASSERTION_FAILED,
+ "Value has been changed with
setNontransactionalWrite==true. " +
+ "New value is " + value + " ... Old value was " +
originalValue);
+ }
+ }
+ }
+ pm.currentTransaction().commit();
+ }
+ }
+
+ /** */
+ private void createAndModifyInstance() {
+ pm.currentTransaction().begin();
+ // create and save the pc instance
+ object = getPersistentNewInstance();
+ // save the ObjectId
+ oid = pm.getObjectId(object);
+ // save the value of the int field
+ originalValue = object.readField();
+ pm.currentTransaction().commit();
+
+ // change field outside of transaction
+ pm.currentTransaction().setNontransactionalWrite(true);
+ object.writeField(999);
+ }
+
+ /** */
+ private StateTransitionObj getPersistentNewInstance() {
+ StateTransitionObj obj = new StateTransitionObj();
+ pm.makePersistent(obj); // obj should transition to PERSISTENT_NEW
+ int curr = currentState(obj);
+ if (curr != PERSISTENT_NEW) {
+ fail(ASSERTION_FAILED,
+ "Unable to create persistent-new instance " +
+ "from transient instance via makePersistent(), state is " +
+ getStateOfInstance(obj));
+ }
+ return obj;
+ }
+}
Propchange:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java
------------------------------------------------------------------------------
svn:executable = *