Hi Michelle,

good catch! Now its clear why my change could not help: it was never executed :-).

I looked at class PersistenceManagerTest and I would like to propose two changes:
- Method cleanupMylib should delete the PCPoint and PCRect instances in a single transaction.
- Method tearDown needs to be changed such that closePMF is called in any case.


You find a new version of PersistenceManagerTest attached. Could you do me a favor and check whether this solves the problem (together with the other change of JDO_Test). If yes I would check in PersistenceManagerTest and JDO_Test as fix for JIRA issue JDO-32.

Thanks!

Regards Michael

Okay, here's what was going on. PersistenceManagerTest extends JDO_Test and overrides its tearDown() method. The former's tearDown() calls cleanupMylib() before calling closePMF(). cleanupMylib() fails on trying to clean up the database, throws an exception, and never returns to tearDown, so closePMF() does not get executed.

cleanupMylib() fails because it attempts to delete PCPoint objects before deleting PCRect objects that hold foreign keys to the PCPoints. I changed the order of execution and the tests now pass. I will accept advice on how to avoid this problem in the future if cleanupMylib() fails. Here is the offending code:

   /** */
   protected void tearDown() {
       try {
           cleanup();
           cleanupMylib();
           closePMF();
       }
       catch (Throwable ex) {
           if (debug) ex.printStackTrace();
           if (testSucceeded) {
               // runTest succeeded, but closePMF throws exception =>
               // failure
               fail("Exception during tearDown: " + ex);
           }
           else {
               // runTest failed and closePMF throws exception =>
               // just print the closePMF exception, otherwise the
               // closePMF exception would swallow the test case failure
               if (debug)
                   logger.debug("Exception during tearDown: " + ex);
           }
       }
   }
     /** */
   protected void cleanupMylib() {
       PersistenceManager pm = getPM();
       Transaction tx = null;
       try {
           pm = pmf.getPersistenceManager();
           tx = pm.currentTransaction();
           tx.begin();
           Collection c = getAllObjects(pm, PCRect.class);
           pm.deletePersistentAll(c);
           tx.commit();
                 tx.begin();
           c = getAllObjects(pm, PCPoint.class);
           pm.deletePersistentAll(c);
           tx.commit();
       }
       finally {
           if ((tx != null) && tx.isActive())
               tx.rollback();
           if ((pm != null) && pm.isClosed())
               pm.close();
       }
   }

-- Michelle

Michael Bouschen wrote:

Hi Michelle,

Hi, Michael,

When you get a chance to look at the tests that don't close pmf when they fail, the JIRA number is JDO-32.



I looked into this. Attached you find an updated version of JDO_Test.java. It checks whether pmf.close throws an exception because of open pms. If so it closes the pms and closes the pmf again.


However, I was not able to reproduce the issue. I removed the heap size increase from project.properties. I also added some debug messages to the pm cleanup code I added to the method closing the pmf. It got never printed. I tried the tck default configuration and used the JPOX nightly builds from April 1 and May 1.

Could you please try the attached version of JDO_Test and let me know whether it makes any difference? It might be good to check it in anyway, even if todays tests do not need it.The attached file works for tck20 and tck11 and I'm planning a similar change for ri11.

Thanks!

Regards Michael


Thanks, Michelle





--
Michael Bouschen                [EMAIL PROTECTED] Engineering GmbH
mailto:[EMAIL PROTECTED]        http://www.tech.spree.de/
Tel.:++49/30/235 520-33         Buelowstr. 66                   
Fax.:++49/30/2175 2012          D-10783 Berlin                  

/*
 * 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.api.persistencemanager;


import java.util.Collection;
import java.util.Vector;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.pc.mylib.PCPoint2;
import org.apache.jdo.tck.pc.mylib.PCRect;

public abstract class PersistenceManagerTest extends JDO_Test {
    
    /** */
    protected PersistenceManagerTest() { }

    /** */
    protected void tearDown() {
        Throwable cleanupFailure = null;
        try {
            cleanup();
            cleanupMylib();
        }
        catch (Throwable ex) {
            cleanupFailure = ex;
            // set testSucceeded to false, otherwise a failure during
            // super.tearDown would swallow this exception
            testSucceeded = false;
        }

        // cleanup pmf
        super.tearDown();

        // fail if there was an exception during cleanup
        if (cleanupFailure != null) {
            fail("Exception during cleanupMylib: " + cleanupFailure);
        }
    }
    
    /** */
    protected void cleanupMylib() {
        PersistenceManager pm = getPM();
        Transaction tx = null;
        try {
            pm = pmf.getPersistenceManager();
            tx = pm.currentTransaction();
            tx.begin();
            Collection c = getAllObjects(pm, PCPoint.class);
            pm.deletePersistentAll(c);

            c = getAllObjects(pm, PCRect.class);
            pm.deletePersistentAll(c);
            tx.commit();
        }
        finally {
            if ((tx != null) && tx.isActive())
                tx.rollback();
            if ((pm != null) && pm.isClosed())
                pm.close();
        }
    }
  
    /** */
    protected Object createPCPointInstance(PersistenceManager pm) {
        PCPoint p1 = new PCPoint(8,8);
        Transaction tx = pm.currentTransaction();
        tx.begin();
        pm.makePersistent(p1);
        Object oid = pm.getObjectId(p1);
        tx.commit();
        return oid;
    }
  
    /** */
    public void deletePCPointInstance (PersistenceManager pm, Object oid) {
        Transaction tx = pm.currentTransaction();
        tx.begin();
        Object p1 = pm.getObjectById(oid, true);
        pm.deletePersistent(p1);
        tx.commit();
    }

    /** */
    protected Collection getAllObjects(PersistenceManager pm, Class pcClass) {
        Collection col = new Vector() ;
        try {
            Query query = pm.newQuery();
            query.setClass(pcClass);
            query.setCandidates(pm.getExtent(pcClass, false));
            Object result = query.execute();
            col = (Collection)result;
        } catch (Exception e) {
            fail("Exception in getAllObjects()" + e);
        }
        return col ;
    }

    /** */
    public boolean testState(PCPoint obj, int expectState, String str) {
        int actualState = currentState(obj);
        if (actualState != expectState) {
            if (debug) {
                logger.debug(" Object not in " + str + " state for X = " +
                             obj.getX());
                logger.debug(" current state: " + actualState +
                             " expected state: " + expectState);
            }
            return false;
        }
        return true;
    }

    /** */
    public boolean testState(PCPoint2 obj, int expectState, String str) {
        int actualState = currentState(obj);
        if (actualState != expectState) {
            if (debug) {
                logger.debug(" Object not in " + str + " state for X = " +
                             obj.getX() );
                logger.debug(" current state: " + actualState +
                             " expected state: " + expectState);
            }
            return false;
        }
        return true;
    }
    
    /** */
    public void assertGetX(PCPoint p, int value, String assertion, String 
label) {
        if (p.getX() !=  value) {
            fail(assertion, label);
        }
    }
}



Reply via email to