openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r627979 [6/39] - in /openjpa/trunk: openjpa-lib/src/test/java/org/apache/openjpa/lib/test/ openjpa-persistence-jdbc/ openjpa-persistence-jdbc/src/test/java/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/ openjpa-pers...
Date Fri, 15 Feb 2008 09:20:40 GMT
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest1.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,143 @@
+/*
+ * 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.openjpa.persistence.common.apps;
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+
+/**
+ *	<p>Persitent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@Table(name="rtest1")
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class RuntimeTest1 implements Serializable
+{
+
+	private static final long serialVersionUID = 1L;
+
+	@Transient
+	public static final String someStaticField = "someField";
+
+	private Locale		localeField;
+
+	@Id
+	private int			intField;
+
+	@Column(length=35)
+	private String		stringField;
+
+	// transactional only
+	@Column(length=35)
+	public String		transString;
+
+	// relations
+	//@Transient
+	@OneToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	private RuntimeTest1	selfOneOne;
+
+	@Transient
+	private Set		selfOneMany = new HashSet ();
+
+
+	public RuntimeTest1 ()
+	{}
+
+	public RuntimeTest1(int key)
+	{
+		this.intField = key;
+	}
+
+	public RuntimeTest1 (String str, int i)
+	{
+		stringField = str;
+		intField = i;
+	}
+
+	public int getIntField ()
+	{
+		return this.intField;
+	}
+
+
+	public void setIntField (int intField)
+	{
+		this.intField = intField;
+	}
+
+	public String getStringField ()
+	{
+		return this.stringField;
+	}
+
+	public void setStringField (String stringField)
+	{
+		this.stringField = stringField;
+	}
+
+	public RuntimeTest1 getSelfOneOne ()
+	{
+		return this.selfOneOne;
+	}
+
+	public void setSelfOneOne (RuntimeTest1 selfOneOne)
+	{
+		this.selfOneOne = selfOneOne;
+	}
+
+	public Set getSelfOneMany ()
+	{
+		return this.selfOneMany;
+	}
+
+	public void setSelfOneMany (Set selfOneMany)
+	{
+		this.selfOneMany = selfOneMany;
+	}
+
+	public String toString()
+	{
+		return "IntField: "+intField+", StringField: "+stringField+" .";
+	}
+
+	public Locale getLocaleField() {
+		return localeField;
+	}
+
+	public void setLocaleField(Locale localeField) {
+		this.localeField = localeField;
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/RuntimeTest2.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,64 @@
+/*
+ * 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.openjpa.persistence.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.Table;
+
+
+/**
+ *	<p>Persitent type used in testing.</p>
+ *
+ *	@author		Abe White
+ */
+@Entity
+@DiscriminatorValue("RT2")
+public class RuntimeTest2 extends RuntimeTest1
+{
+	private static final long serialVersionUID = 1L;
+	private int intField2;
+
+	public RuntimeTest2 (int key)
+	{
+		super(key);
+	}
+
+	public RuntimeTest2 (String str, int i)
+	{
+		super (str, i);
+	}
+
+	public int getIntField2 ()
+	{
+		return this.intField2;
+	}
+
+	public void setIntField2 (int intField2)
+	{
+		this.intField2 = intField2;
+	}
+
+	public String toString()
+	{
+		return "IntField: "+intField2+", StringField: "+super.getStringField()+" .";
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/ScienceCourse.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,47 @@
+/*
+ * 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.openjpa.persistence.common.apps;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("Science")
+public class ScienceCourse extends Course
+{
+	private static final long serialVersionUID = 1L;
+
+	private String relCourse;
+
+	public ScienceCourse(String relCourse)
+	{
+		this.relCourse = relCourse;
+	}
+
+	public ScienceCourse(int id, String relCourse)
+	{
+		super(id);
+		this.relCourse = relCourse;
+	}
+
+	public String getRelCourse()
+	{
+		return relCourse;
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/apps/Student.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,87 @@
+/*
+ * 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.openjpa.persistence.common.apps;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+public class Student implements Serializable {
+
+	@Transient
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@Column(length=50)
+	private String name;
+
+	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	@JoinTable(name="STUD_COURSE",
+		            joinColumns=@JoinColumn(name="STUD_ID"),
+		            inverseJoinColumns=@JoinColumn(name="CRSE_ID"))
+	private List<Course> course;
+
+	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+	@JoinTable(name="STUD_DEP",
+		            joinColumns=@JoinColumn(name="STUD_ID"),
+		            inverseJoinColumns=@JoinColumn(name="DEP_ID"))
+	private List<Department> department;
+
+	public Student(){}
+
+	public Student(String name)
+	{
+		this.name = name;
+	}
+
+	public Student(String name, List<Course> clist, List<Department> dlist)
+	{
+		this.name = name;
+		this.course = clist;
+		this.department = dlist;
+	}
+
+	public List<Course> getCourse() {
+		return course;
+	}
+
+	public void setCourse(List<Course> course) {
+		this.course = course;
+	}
+
+	public List<Department> getDepartment() {
+		return department;
+	}
+
+	public void setDepartment(List<Department> department) {
+		this.department = department;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/AbstractTestCase.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,1167 @@
+/*
+ * 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.
+ */
+/*
+ * 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.openjpa.persistence.common.utils;
+
+import java.util.Map;
+import java.util.Date;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.math.BigInteger;
+import java.math.BigDecimal;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+import java.io.PrintStream;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.management.IntrospectionException;
+
+import org.apache.regexp.RESyntaxException;
+import org.apache.regexp.RE;
+import org.apache.regexp.REUtil;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.lib.log.Log;
+
+public abstract class AbstractTestCase extends PersistenceTestCase {
+
+    protected enum Platform {
+        EMPRESS,
+        HYPERSONIC,
+        POSTGRESQL,
+        MYSQL,
+        SQLSERVER,
+        DB2,
+        ORACLE,
+        DERBY,
+        INFORMIX,
+        POINTBASE,
+        SYBASE,
+    }
+
+    protected String multiThreadExecuting = null;
+    protected boolean inTimeoutThread = false;
+
+
+    public AbstractTestCase(String name, String s) {
+        setName(name);
+    }
+
+    public AbstractTestCase() {
+    }
+
+    public AbstractTestCase(String name) {
+        setName(name);
+    }
+
+    protected OpenJPAStateManager getStateManager(Object obj,
+        EntityManager pm) {
+        throw new UnsupportedOperationException();
+    }
+
+    protected int deleteAll(Class type, EntityManager em) {
+        final boolean useDeleteByQuery = true;
+
+        if (useDeleteByQuery) {
+            Broker broker = JPAFacadeHelper.toBroker(em);
+            org.apache.openjpa.kernel.Query query = broker.newQuery(
+                JPQLParser.LANG_JPQL, type, "");
+            query.setCandidateType(type, true);
+            return (int) query.deleteAll();
+        } else {
+            List list = OpenJPAPersistence.cast(em).createExtent(type, true)
+                .list();
+            int size = list.size();
+            for (Object o : list)
+                em.remove(o);
+            return size;
+        }
+    }
+
+    protected int deleteAll(Class... types) {
+        EntityManager em = getEmf().createEntityManager();
+        em.getTransaction().begin();
+        int ret = 0;
+        for (Class type : types)
+            ret += deleteAll(type, em);
+        em.getTransaction().commit();
+        em.close();
+        return ret;
+    }
+
+    protected OpenJPAEntityManagerFactory getEmf(Map map) {
+        Collection keys = new ArrayList();
+        for (Object key : map.keySet())
+            if (key.toString().startsWith("kodo"))
+                keys.add(key);
+        if (keys.size() > 0)
+            throw new IllegalArgumentException(
+                "kodo-prefixed properties must be converted to openjpa. " +
+                "Properties: " + keys);
+        throw new UnsupportedOperationException();
+    }
+
+    protected OpenJPAEntityManagerFactory getEmf() {
+        throw new UnsupportedOperationException();
+    }
+
+    protected BrokerFactory getBrokerFactory() {
+        return JPAFacadeHelper.toBrokerFactory(getEmf());
+    }
+
+    protected BrokerFactory getBrokerFactory(String[] args) {
+        if (args.length % 2 != 0)
+            throw new IllegalArgumentException(
+                "odd number of elements in arg array");
+        Map map = new HashMap();
+        for (int i = 0; i < args.length; i = i + 2)
+            map.put(args[i], args[i+1]);
+        return JPAFacadeHelper.toBrokerFactory(getEmf(map));
+    }
+
+    protected OpenJPAEntityManager currentEntityManager() {
+        throw new UnsupportedOperationException();
+    }
+
+    protected void startTx(EntityManager em) {
+        em.getTransaction().begin();
+    }
+
+    protected boolean isActiveTx(EntityManager em) {
+        return em.getTransaction().isActive();
+    }
+
+    protected void endTx(EntityManager em) {
+        if (em.getTransaction().isActive()) {
+            if (em.getTransaction().getRollbackOnly())
+                em.getTransaction().rollback();
+            else
+                em.getTransaction().commit();
+        }
+    }
+
+    protected void rollbackTx(EntityManager em) {
+        em.getTransaction().rollback();
+    }
+
+    protected void endEm(EntityManager em) {
+        if (em.isOpen())
+            em.close();
+    }
+
+    protected Object getStackTrace(Throwable t) {
+        throw new UnsupportedOperationException();
+    }
+
+    protected OpenJPAConfiguration getConfiguration() {
+        throw new UnsupportedOperationException();
+    }
+
+    protected Platform getCurrentPlatform() {
+        throw new UnsupportedOperationException();
+    }
+
+    protected void bug(int id, String s) {
+        bug(id, null, s);
+    }
+    
+    protected void bug(Platform platform, int id, Throwable t, String s) {
+        bug(EnumSet.of(platform), id, t, s);
+    }
+
+    protected void bug(EnumSet<Platform> platforms, int id, Throwable t, String s) {
+        if (platforms.contains(getCurrentPlatform()))
+            bug(id, t, s);
+        else
+            fail(String.format(
+                "bug %s is unexpectedly occurring on platform %s",
+                id, getCurrentPlatform()));
+    }
+
+    protected void bug(int id, Throwable t, String s) {
+        if (t != null) {
+            if (t instanceof RuntimeException)
+                throw (RuntimeException) t;
+            else
+                throw new RuntimeException(t);
+        } else {
+            fail(s);
+        }
+    }
+
+    /**
+     * Support method to get a random Integer for testing.
+     */
+    public static Integer randomInt() {
+        return new Integer((int) (Math.random() * Integer.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Character for testing.
+     */
+    public static Character randomChar() {
+        char [] TEST_CHAR_ARRAY = new char []{
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
+            '2', '3', '4', '5', '6', '7', '8', '9' };
+
+        return new Character(TEST_CHAR_ARRAY[
+                (int) (Math.random() * TEST_CHAR_ARRAY.length)]);
+    }
+
+    /**
+     * Support method to get a random Long for testing.
+     */
+    public static Long randomLong() {
+        return new Long((long) (Math.random() * Long.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Short for testing.
+     */
+    public static Short randomShort() {
+        return new Short((short) (Math.random() * Short.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Double for testing.
+     */
+    public static Double randomDouble() {
+        return new Double((double) (Math.round(Math.random() * 5000d)) / 1000d);
+    }
+
+    /**
+     * Support method to get a random Float for testing.
+     */
+    public static Float randomFloat() {
+        return new Float((float) (Math.round(Math.random() * 5000f)) / 1000f);
+    }
+
+    /**
+     * Support method to get a random Byte for testing.
+     */
+    public static Byte randomByte() {
+        return new Byte((byte) (Math.random() * Byte.MAX_VALUE));
+    }
+
+    /**
+     * Support method to get a random Boolean for testing.
+     */
+    public static Boolean randomBoolean() {
+        return new Boolean(Math.random() > 0.5 ? true : false);
+    }
+
+    /**
+     * Support method to get a random Date for testing.
+     */
+    public static Date randomDate() {
+        long millis = (long) (Math.random() * System.currentTimeMillis());
+
+        // round millis to the nearest 1000: this is because some
+        // databases do not store the milliseconds correctly (e.g., MySQL).
+        // This is a really a bug we should fix. FC #27.
+        millis -= (millis % 1000);
+
+        return new Date(millis);
+    }
+
+    /**
+     * Support method to get a random String for testing.
+     */
+    public static String randomString() {
+        // default to a small string, in case column sizes are
+        // limited (such as with a string primary key)
+        return randomString(50);
+    }
+
+    /**
+     * Support method to get a random String for testing.
+     */
+    public static String randomString(int len) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
+            buf.append(randomChar());
+        return buf.toString();
+    }
+
+    /**
+     * Support method to get a random clob for testing.
+     */
+    public static String randomClob() {
+        StringBuffer sbuf = new StringBuffer();
+        while (sbuf.length() < (5 * 1024)) // at least 5K
+        {
+            sbuf.append(randomString(1024));
+        }
+
+        return sbuf.toString();
+    }
+
+    /**
+     * Support method to get a random BigInteger for testing.
+     */
+    public static BigInteger randomBigInteger() {
+        // too many of our test databases don't support bigints > MAX_LONG:
+        // I don't like it, but for now, let's only test below MAX_LONG
+        BigInteger lng = new BigInteger(
+                ((long) (Math.random() * Long.MAX_VALUE)) + "");
+
+        BigInteger multiplier = new BigInteger("1");
+        // (1 + (int)(Math.random () * 10000)) + "");
+        if (Math.random() < 0.5)
+            multiplier = multiplier.multiply(new BigInteger("-1"));
+
+        return lng.multiply(multiplier);
+    }
+
+    /**
+     * Support method to get a random BigDecimal for testing.
+     */
+    public static BigDecimal randomBigDecimal() {
+        BigInteger start = randomBigInteger();
+        String str = start.toString();
+        // truncate off the last 8 digits: we still get some
+        // overflows with lame databases.
+        for (int i = 0; i < 8; i++)
+            if (str.length() > 2)
+                str = str.substring(0, str.length() - 1);
+        start = new BigInteger(str);
+
+        String val = start + "."
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10))
+                + ((int) (Math.random() * 10));
+
+        return new BigDecimal(val);
+    }
+
+    /**
+     * Support method to get a random blob for testing.
+     */
+    public static byte[] randomBlob() {
+        // up to 100K blob
+        byte [] blob = new byte [(int) (Math.random() * 1024 * 100)];
+        for (int i = 0; i < blob.length; i++)
+            blob[i] = randomByte().byteValue();
+
+        return blob;
+    }
+
+    /**
+     * Invoke setters for pimitives and primitive wrappers on the
+     * specified object.
+     */
+    public static Object randomizeBean(Object bean)
+    throws IntrospectionException, IllegalAccessException,
+        InvocationTargetException, java.beans.IntrospectionException {
+        BeanInfo info = Introspector.getBeanInfo(bean.getClass());
+        PropertyDescriptor[] props = info.getPropertyDescriptors();
+        for (int i = 0; i < props.length; i++) {
+            Method write = props[i].getWriteMethod();
+            if (write == null)
+                continue;
+
+            Class [] params = write.getParameterTypes();
+            if (params == null || params.length != 1)
+                continue;
+
+            Class paramType = params[0];
+            Object arg = null;
+
+            if (paramType == boolean.class || paramType == Boolean.class)
+                arg = randomBoolean();
+            else if (paramType == byte.class || paramType == Byte.class)
+                arg = randomByte();
+            else if (paramType == char.class || paramType == Character.class)
+                arg = randomChar();
+            else if (paramType == short.class || paramType == Short.class)
+                arg = randomShort();
+            else if (paramType == int.class || paramType == Integer.class)
+                arg = randomInt();
+            else if (paramType == long.class || paramType == Long.class)
+                arg = randomLong();
+            else if (paramType == double.class || paramType == Double.class)
+                arg = randomDouble();
+            else if (paramType == float.class || paramType == Float.class)
+                arg = randomFloat();
+            else if (paramType == String.class)
+                arg = randomString();
+            else if (paramType == BigInteger.class)
+                arg = randomBigInteger();
+            else if (paramType == BigDecimal.class)
+                arg = randomBigDecimal();
+            else if (paramType == Date.class)
+                arg = randomDate();
+
+            if (arg != null)
+                write.invoke(bean, new Object []{ arg });
+        }
+
+        return bean;
+    }
+
+    protected void assertSize(int size, Collection c) {
+        assertEquals(size, c.size());
+    }
+
+    protected void assertSize(int size, Query q) {
+        assertEquals(size, q.getResultList().size());
+    }
+
+    /**
+     * Serialize and deserialize the object.
+     *
+     * @param validateEquality make sure the hashCode and equals
+     * methods hold true
+     */
+    public static Object roundtrip(Object orig, boolean validateEquality)
+        throws IOException, ClassNotFoundException {
+        assertNotNull(orig);
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.writeObject(orig);
+        ByteArrayInputStream bin = new ByteArrayInputStream(
+            bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bin);
+        Object result = in.readObject();
+
+        if (validateEquality) {
+            assertEquals(orig.hashCode(), result.hashCode());
+            assertEquals(orig, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * @return true if the specified input matches the regular expression regex.
+     */
+    public static boolean matches(String regex, String input)
+        throws RESyntaxException {
+        RE re = REUtil.createRE(regex);
+        return re.match(input);
+    }
+
+    public static void assertMatches(String regex, String input) {
+        try {
+            if (!(matches(regex, input)))
+                fail("Expected regular expression: <" + regex + ">"
+                    + " did not match: <" + input + ">");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    public static void assertNotMatches(String regex, String input) {
+        try {
+            if (matches(regex, input))
+                fail("Regular expression: <" + regex + ">"
+                    + " should not match: <" + input + ">");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * Check the list if strings and return the ones that match
+     * the specified match.
+     */
+    public static List matches(String regex, Collection input)
+        throws RESyntaxException {
+        List matches = new ArrayList();
+        for (Iterator i = input.iterator(); i.hasNext();) {
+            String check = (String) i.next();
+            if (matches(regex, check))
+                matches.add(check);
+        }
+
+        return matches;
+    }
+
+    /**
+     * Assert that the specified collection of Strings contains at least
+     * one string that matches the specified regular expression.
+     */
+    public static void assertMatches(String regex, Collection input) {
+        try {
+            if (matches(regex, input).size() == 0)
+                fail("The specified list of size " + input.size()
+                    + " did not contain any strings that match the"
+                    + " specified regular expression(\"" + regex + "\")");
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    /**
+     * Assert that the specified collection of Strings does not match
+     * the specified regular expression.
+     */
+    public static void assertNotMatches(String regex, Collection input) {
+        try {
+            List matches;
+
+            if (((matches = matches(regex, input))).size() > 0)
+                fail("The specified list of size " + input.size()
+                    + " did contain one or more strings that matchs the"
+                    + " specified illegal regular expression"
+                    + " (\"" + regex + "\")."
+                    + " First example of a matching message is: "
+                    + matches.iterator().next());
+        } catch (RESyntaxException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    protected Log getLog() {
+        return getConfiguration().getLog("Tests");
+    }
+
+    ///////////////////
+    // Multi threading
+    ///////////////////
+
+    /**
+     * Re-execute the invoking method a random number of times
+     * in a random number of Threads.
+     */
+    public void mttest() throws ThreadingException {
+        // 6 iterations in 8 threads is a good trade-off between
+        // tests taking way too long and having a decent chance of
+        // identifying MT problems.
+        int iterations = 6;
+        int threads = 8;
+
+        mttest(threads, iterations);
+    }
+
+    /**
+     * Execute the calling method <code>iterations</code>
+     * times in <code>threads</code> Threads.
+     */
+    public void mttest(int threads, int iterations) {
+        mttest(0, threads, iterations);
+    }
+
+    public void mttest(int serialCount, int threads, int iterations)
+        throws ThreadingException {
+        String methodName = callingMethod("mttest");
+        mttest(serialCount, threads, iterations, methodName, new Object [0]);
+    }
+
+    /**
+     * Execute a test method in multiple threads.
+     *
+     * @param threads the number of Threads to run in
+     * @param iterations the number of times the method should
+     * be execute in a single Thread
+     * @param method the name of the method to execute
+     * @param args the arguments to pass to the method
+     * @throws ThreadingException if an errors occur in
+     * any of the Threads. The actual exceptions
+     * will be embedded in the exception. Note that
+     * this means that assert() failures will be
+     * treated as errors rather than warnings.
+     * @author Marc Prud'hommeaux
+     */
+    public void mttest(int threads, int iterations, final String method,
+        final Object [] args) throws ThreadingException {
+        mttest(0, threads, iterations, method, args);
+    }
+
+    public void mttest(int serialCount,
+        int threads, int iterations, final String method, final Object [] args)
+        throws ThreadingException {
+        if (multiThreadExecuting != null && multiThreadExecuting.equals(method))
+        {
+            // we are currently executing in multi-threaded mode:
+            // don't deadlock!
+            return;
+        }
+
+        multiThreadExecuting = method;
+
+        try {
+            Class [] paramClasses = new Class [args.length];
+            for (int i = 0; i < paramClasses.length; i++)
+                paramClasses[i] = args[i].getClass();
+
+            final Method meth;
+
+            try {
+                meth = getClass().getMethod(method, paramClasses);
+            } catch (NoSuchMethodException nsme) {
+                throw new ThreadingException(nsme.toString(), nsme);
+            }
+
+            final Object thiz = this;
+
+            mttest("reflection invocation: (" + method + ")",
+                serialCount, threads, iterations, new VolatileRunnable() {
+                public void run() throws Exception {
+                    meth.invoke(thiz, args);
+                }
+            });
+        } finally {
+            multiThreadExecuting = null;
+        }
+    }
+
+    public void mttest(String title, final int threads, final int iterations,
+        final VolatileRunnable runner) throws ThreadingException {
+        mttest(title, 0, threads, iterations, runner);
+    }
+
+    /**
+     * Execute a test method in multiple threads.
+     *
+     * @param title a description of the test, for inclusion in the
+     * error message
+     * @param serialCount the number of times to run the method
+     * serially before spawning threads.
+     * @param threads the number of Threads to run in
+     * @param iterations the number of times the method should
+     * @param runner the VolatileRunnable that will execute
+     * the actual test from within the Thread.
+     * @throws ThreadingException if an errors occur in
+     * any of the Threads. The actual exceptions
+     * will be embedded in the exception. Note that
+     * this means that assert() failures will be
+     * treated as errors rather than warnings.
+     * @author Marc Prud'hommeaux be execute in a single Thread
+     * @author Marc Prud'hommeaux
+     */
+    public void mttest(String title, final int serialCount,
+        final int threads, final int iterations, final VolatileRunnable runner)
+        throws ThreadingException {
+        final List exceptions = Collections.synchronizedList(new LinkedList());
+
+        Thread [] runners = new Thread [threads];
+
+        final long startMillis = System.currentTimeMillis() + 1000;
+
+        for (int i = 1; i <= threads; i++) {
+            final int thisThread = i;
+
+            runners[i - 1] =
+                new Thread(title + " [" + i + " of " + threads + "]") {
+                    public void run() {
+                        // do our best to have all threads start at the exact
+                        // same time. This is imperfect, but the closer we
+                        // get to everyone starting at the same time, the
+                        // better chance we have for identifying MT problems.
+                        while (System.currentTimeMillis() < startMillis)
+                            yield();
+
+                        int thisIteration = 1;
+                        try {
+                            for (; thisIteration <= iterations; thisIteration++)
+                            {
+                                // go go go!
+                                runner.run();
+                            }
+                        } catch (Throwable error) {
+                            synchronized (exceptions) {
+                                // embed the exception into something that gives
+                                // us some more information about the threading
+                                // environment
+                                exceptions.add(new ThreadingException("thread="
+                                    + this.toString()
+                                    + ";threadNum=" + thisThread
+                                    + ";maxThreads=" + threads
+                                    + ";iteration=" + thisIteration
+                                    + ";maxIterations=" + iterations, error));
+                            }
+                        }
+                    }
+                };
+        }
+
+        // start the serial tests(does not spawn the threads)
+        for (int i = 0; i < serialCount; i++) {
+            runners[0].run();
+        }
+
+        // start the multithreaded
+        for (int i = 0; i < threads; i++) {
+            runners[i].start();
+        }
+
+        // wait for them all to complete
+        for (int i = 0; i < threads; i++) {
+            try {
+                runners[i].join();
+            } catch (InterruptedException e) {
+            }
+        }
+
+        if (exceptions.size() == 0)
+            return; // sweeeeeeeet: no errors
+
+        // embed all the exceptions that were throws into a
+        // ThreadingException
+        Throwable [] errors = (Throwable []) exceptions.toArray(
+            new Throwable [0]);
+        throw new ThreadingException("The "
+            + errors.length + " embedded errors "
+            + "occured in the execution of " + iterations + " iterations "
+            + "of " + threads + " threads: [" + title + "]", errors);
+    }
+
+    /**
+     * Check to see if we are in the top-level execution stack.
+     */
+    public boolean isRootThread() {
+        return multiThreadExecuting == null;
+    }
+
+    /**
+     * A Runnable that can throw an Exception: used to test cases.
+     */
+    public static interface VolatileRunnable {
+
+        public void run() throws Exception;
+    }
+
+    /**
+     * Exception for errors caught during threading tests.
+     */
+    public class ThreadingException extends RuntimeException {
+
+        private final Throwable[] _nested;
+
+        public ThreadingException(String msg, Throwable nested) {
+            super(msg);
+            if (nested == null)
+                _nested = new Throwable[0];
+            else
+                _nested = new Throwable[]{ nested };
+        }
+
+        public ThreadingException(String msg, Throwable[] nested) {
+            super(msg);
+            if (nested == null)
+                _nested = new Throwable[0];
+            else
+                _nested = nested;
+        }
+
+        public void printStackTrace() {
+            printStackTrace(System.out);
+        }
+
+        public void printStackTrace(PrintStream out) {
+            printStackTrace(new PrintWriter(out));
+        }
+
+        public void printStackTrace(PrintWriter out) {
+            super.printStackTrace(out);
+            for (int i = 0; i < _nested.length; i++) {
+                out.print("Nested Throwable #" + (i + 1) + ": ");
+                _nested[i].printStackTrace(out);
+            }
+        }
+    }
+
+    /**
+     * Return the last method name that called this one by
+     * parsing the current stack trace.
+     *
+     * @param exclude a method name to skip
+     * @throws IllegalStateException If the calling method could not be
+     * identified.
+     * @author Marc Prud'hommeaux
+     */
+    public String callingMethod(String exclude) {
+        // determine the currently executing method by
+        // looking at the stack track. Hackish, but convenient.
+        StringWriter sw = new StringWriter();
+        new Exception().printStackTrace(new PrintWriter(sw));
+        for (StringTokenizer stackTrace = new StringTokenizer(sw.toString(),
+            System.getProperty("line.separator"));
+            stackTrace.hasMoreTokens();) {
+            String line = stackTrace.nextToken().trim();
+
+            // not a stack trace element
+            if (!(line.startsWith("at ")))
+                continue;
+
+            String fullMethodName = line.substring(0, line.indexOf("("));
+
+            String shortMethodName = fullMethodName.substring(
+                fullMethodName.lastIndexOf(".") + 1);
+
+            // skip our own methods!
+            if (shortMethodName.equals("callingMethod"))
+                continue;
+            if (exclude != null && shortMethodName.equals(exclude))
+                continue;
+
+            return shortMethodName;
+        }
+
+        throw new IllegalStateException("Could not identify calling "
+            + "method in stack trace");
+    }
+
+    //////////
+    // Timing
+    //////////
+
+    /**
+     * Sleep the current Thread for a random amount of time from 0-1000 ms.
+     */
+    public void sleepRandom() {
+        sleepRandom(1000);
+    }
+
+    /**
+     * Sleep the current Thread for a random amount of time from
+     * 0-<code>max</code> ms.
+     */
+    public void sleepRandom(int max) {
+        try {
+            Thread.currentThread().sleep((long) (Math.random() * max));
+        } catch (InterruptedException ex) {
+        }
+    }
+
+    /**
+     * Re-run this method in the current thread, timing out
+     * after the specified number of seconds.
+     * Usage:
+     * <pre> public void timeOutOperation() { if (timeout(5 * 1000)) return;
+     *  Thread.currentThread().sleep(10 * 1000); }
+     * </pre>
+     * <p/>
+     * <p/>
+     * <strong>Warning</strong> this method should be used sparingly,
+     * and only when you expect that a timeout will <strong>not</strong>
+     * occur. It utilized the deprecated {@link Thread#stop()} and
+     * {@link Thread#interrupt} methods, which can leave monitors in an
+     * invalid state. It is only used because it provides more
+     * meaningful information than just seeing that the entire autobuild
+     * timed out.
+     *
+     * @param millis the number of milliseconds we should wait.
+     * @return true if we are are in the thread that requested the
+     *         timeout, false if we are in the timeout thread itself.
+     */
+    public boolean timeout(long millis) throws Throwable {
+        String methodName = callingMethod("timeout");
+        return timeout(millis, methodName);
+    }
+
+    /**
+     * @see #timeout(long)
+     */
+    public boolean timeout(long millis, String methodName) throws Throwable {
+        // we are in the timing out-thread: do nothing so the
+        // actual test method can run
+        if (inTimeoutThread)
+            return false;
+
+        inTimeoutThread = true;
+        long endTime = System.currentTimeMillis() + millis;
+
+        try {
+            final Method method = getClass().
+                getMethod(methodName, (Class[]) null);
+            final Object thz = this;
+
+            // spawn thread
+            TimeOutThread tot = new TimeOutThread("TimeOutThread ["
+                + methodName + "] (" + millis + "ms)") {
+                public void run() {
+                    try {
+                        method.invoke(thz, (Object[]) null);
+                    } catch (Throwable t) {
+                        throwable = t;
+                    } finally {
+                        completed = true;
+                    }
+                }
+            };
+
+            tot.start();
+
+            // wait for the completion or a timeout to occur
+            tot.join(millis);
+
+            // have we timed out? Kill the thread and throw an exception
+            if (System.currentTimeMillis() >= endTime) {
+                // if we are waiting on a monitor, this will give
+                // us a useful stack trace.
+                try {
+                    tot.interrupt();
+                } catch (Throwable e) {
+                }
+                Thread.currentThread().sleep(500);
+
+                // try to kill the thread
+                try {
+                    tot.stop();
+                } catch (Throwable e) {
+                }
+                Thread.currentThread().sleep(500);
+
+                throw new OperationTimedOutException("Execution of \""
+                    + methodName + "\" timed out after "
+                    + millis + " milliseconds", tot.throwable);
+            }
+
+            // throw any exceptions that may have occured
+            if (tot.throwable != null)
+                throw tot.throwable;
+
+            // I guess everything was OK
+            return true;
+        } finally {
+            inTimeoutThread = false;
+        }
+    }
+
+    private static class TimeOutThread extends Thread {
+
+        public Throwable throwable = null;
+        public boolean completed = false;
+
+        public TimeOutThread(String name) {
+            super(name);
+            setDaemon(true);
+        }
+    }
+
+    /**
+     * Indicates that a timeout occured.
+     */
+    public static class OperationTimedOutException extends RuntimeException {
+
+        private final Throwable _err;
+
+        public OperationTimedOutException(String msg, Throwable throwable) {
+            super(msg);
+            _err = throwable;
+        }
+
+        public void printStackTrace() {
+            printStackTrace(System.out);
+        }
+
+        public void printStackTrace(PrintStream out) {
+            printStackTrace(new PrintWriter(out));
+        }
+
+        public void printStackTrace(PrintWriter out) {
+            super.printStackTrace(out);
+            if (_err != null) {
+                out.print("Nested Throwable: ");
+                _err.printStackTrace(out);
+            }
+        }
+    }
+
+    ///////////////
+    // Collections
+    ///////////////
+
+    /**
+     * Validate that the specified {@link Collection} fulfills the
+     * Collection contract as specified by the Collections API.
+     * <p/>
+     * <strong>Note</strong>: does not validate mutable operations
+     */
+    public static void validateCollection(Collection collection) {
+        int size = collection.size();
+        int iterated = 0;
+        // ensure we can walk along the iterator
+        for (Iterator i = collection.iterator(); i.hasNext();) {
+            iterated++;
+            i.next();
+        }
+
+        // ensure the number of values iterated is the same as the list size
+        assertEquals(size, iterated);
+
+        // also validate the list
+        if (collection instanceof List) {
+            List ll = new ArrayList();
+            for (int i = 0; i < 100; i++)
+                ll.add(new Integer(i));
+            validateList((List) ll);
+            validateList((List) collection);
+        }
+    }
+
+    /**
+     * Validate that the specified {@link List} fulfills the
+     * List contract as specified by the Collections API.
+     * <p/>
+     * <strong>Note</strong>: does not validate mutable operations
+     */
+    public static void validateList(List list) {
+        Object [] coreValues = list.toArray();
+        Object [] values1 = new Object [list.size()];
+        Object [] values2 = new Object [list.size()];
+        Object [] values3 = new Object [list.size()];
+        Object [] values4 = new Object [list.size()];
+
+        // fill sequential index access list
+        for (int i = 0; i < list.size(); i++)
+            values1[i] = list.get(i);
+
+        // fill sequential list
+        int index = 0;
+        ListIterator iter;
+        for (iter = list.listIterator(0); iter.hasNext();) {
+            assertEquals(index, iter.nextIndex());
+            assertEquals(index, iter.previousIndex() + 1);
+            values2[index] = iter.next();
+            assertTrue(list.contains(values2[index]));
+            index++;
+        }
+
+        // ensure NoSuchElementException is thrown as appropriate
+        try {
+            iter.next();
+            fail("next() should have resulted in a NoSuchElementException");
+        } catch (NoSuchElementException e) {
+        } // as expected
+
+        // fill reverse sequential list
+        int back = 0;
+        for (iter = list.listIterator(list.size()); iter.hasPrevious();) {
+            assertEquals(index, iter.previousIndex() + 1);
+            assertEquals(index, iter.nextIndex());
+            values3[--index] = iter.previous();
+            back++;
+        }
+        assertEquals(list.size(), back);
+
+        // ensure NoSuchElementException is thrown as appropriate
+        try {
+            iter.previous();
+            fail("previous() should have resulted in a "
+                + "NoSuchElementException");
+        } catch (NoSuchElementException e) {
+        } // as expected
+
+        // fill random access list
+        List indices = new LinkedList();
+        for (int i = 0; i < list.size(); i++)
+            indices.add(new Integer(i));
+
+        for (int i = 0; i < list.size(); i++) {
+            int rand = (int) (Math.random() * indices.size());
+            Integer randIndex = (Integer) indices.remove(rand);
+            values4[randIndex.intValue()] = list.get(randIndex.intValue());
+        }
+
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values1));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values1));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values2));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values2));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values4));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values4));
+        assertEquals(Arrays.asList(coreValues), Arrays.asList(values3));
+        assertIdentical(Arrays.asList(coreValues), Arrays.asList(values3));
+    }
+
+    /**
+     * Assert that the given List contain the exact same
+     * elements. This is different than the normal List contract, which
+     * states that list1.equals(list2) if each element e1.equals(e2).
+     * This method asserts that e1 == n2.
+     */
+    public static void assertIdentical(List c1, List c2) {
+        assertEquals(c1.size(), c2.size());
+        for (Iterator i1 = c1.iterator(), i2 = c2.iterator();
+            i1.hasNext() && i2.hasNext();)
+            assertTrue(i1.next() == i2.next());
+    }
+
+    /**
+     * Assert that the collection parameter is already ordered
+     * according to the specified comparator.
+     */
+    public void assertOrdered(Collection c, Comparator comp) {
+        List l1 = new LinkedList(c);
+        List l2 = new LinkedList(c);
+        assertEquals(l1, l2);
+        Collections.sort(l2, comp);
+        assertEquals(l1, l2);
+        Collections.sort(l1, comp);
+        assertEquals(l1, l2);
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/BufferedLogFactory.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,101 @@
+/*
+ * 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.openjpa.persistence.common.utils;
+
+import java.util.*;
+
+import org.apache.openjpa.lib.log.*;
+
+/**
+ * Simple default log implementation to test whether certain messages
+ * are logged or not.
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class BufferedLogFactory
+    extends LogFactoryImpl {
+
+    private int bufferSize = 10000;
+    private List buffer = new ArrayList();
+    private List disallowedMessages = new LinkedList();
+
+    protected LogImpl newLogImpl() {
+        return new BufferedLog();
+    }
+
+    public List getBuffer() {
+        return Collections.unmodifiableList(buffer);
+    }
+
+    public void clear() {
+        buffer.clear();
+    }
+
+    public void clearDisallowedMessages() {
+        disallowedMessages.clear();
+    }
+
+    public void addDisallowedMessage(String regexp) {
+        disallowedMessages.add(regexp);
+    }
+
+    public boolean removeDisallowedMessage(String regexp) {
+        return disallowedMessages.remove(regexp);
+    }
+
+    public List getDisallowedMessages() {
+        return Collections.unmodifiableList(disallowedMessages);
+    }
+
+    public void assertLogMessage(String regex) {
+    	AbstractTestCase.assertMatches(regex, getBuffer());
+    }
+
+    public void assertNoLogMessage(String regex) {
+    	AbstractTestCase.assertNotMatches(regex, getBuffer());
+    }
+
+    public void setBufferSize(int bufferSize) {
+        this.bufferSize = bufferSize;
+    }
+
+    public int getBufferSize() {
+        return this.bufferSize;
+    }
+
+    public class BufferedLog
+        extends LogFactoryImpl.LogImpl {
+
+        protected void log(short level, String message, Throwable t) {
+            super.log(level, message, t);
+            buffer.add(message);
+
+            // trim to max buffer length
+            while (buffer.size() > getBufferSize())
+                buffer.iterator().remove();
+
+            if (disallowedMessages.size() > 0) {
+                for (Iterator i = disallowedMessages.iterator(); i.hasNext();) {
+                    String regex = (String) i.next();
+                    AbstractTestCase.assertNotMatches(regex, message);
+                }
+            }
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/common/utils/Bug.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,80 @@
+/*
+ * 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.openjpa.persistence.common.utils;
+
+import java.io.*;
+
+import junit.framework.*;
+
+/**
+ * Extension of an assertion error that indicates to the outside
+ * build process (if any) that an assertion failed due to a known
+ * bug.
+ *
+ * @author Marc Prud'hommeaux
+ */
+public class Bug
+    extends AssertionFailedError {
+
+    public static final String BUG_TOKEN = "SOLARBUG";
+    public static final String BUG_DELIMITER = "|";
+
+    private Throwable error = null;
+    private int trackingId;
+
+    // the the static factory method, please
+    private Bug(int trackingId, Throwable t, String message) {
+        super(BUG_DELIMITER + BUG_TOKEN + BUG_DELIMITER
+            + trackingId + BUG_DELIMITER + message);
+        this.trackingId = trackingId;
+        error = t;
+
+        printStackTrace(System.err);
+    }
+
+    public static Bug bug(int trackingId, Throwable t, String message) {
+        return new Bug(trackingId, t, message);
+    }
+
+    public void printStackTrace(PrintWriter pw) {
+        super.printStackTrace(pw);
+        if (error != null) {
+            pw.println("Embedded error message:");
+            error.printStackTrace(pw);
+        }
+    }
+
+    public void printStackTrace(PrintStream ps) {
+        super.printStackTrace(ps);
+        if (error != null) {
+            ps.println("Embedded error message:");
+            error.printStackTrace(ps);
+        }
+    }
+
+    public String getMessage() {
+        return super.getMessage() + " [reported bug #" + trackingId + "]";
+    }
+
+    public int getTrackingId() {
+        return trackingId;
+    }
+}
+
+

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestKodoConfiguration.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,230 @@
+/*
+ * 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.openjpa.persistence.conf;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.common.utils.BufferedLogFactory;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.conf.Value;
+
+/**
+ * <p>Tests the JDO configuration classes.</p>
+ *
+ * @author Marc Prud'hommeaux
+ */
+public class TestKodoConfiguration
+    extends AbstractTestCase {
+
+    public TestKodoConfiguration(String test) {
+        super(test, "confcactusapp");
+    }
+
+    /**
+     * Test that you can set the connection factory and other properties as
+     * objects.
+     */
+    public void testSetObjects() {
+        Map map = new HashMap();
+        Object cfactory = new Object();
+        Object cfactory2 = new Object();
+        map.put("openjpa.ConnectionFactory", cfactory);
+        map.put("openjpa.ConnectionFactory2", cfactory2);
+        map.put("openjpa.Optimistic", Boolean.FALSE);
+        map.put("openjpa.LockTimeout", new Integer(503));
+
+        // use new conf so no unexpected restrictions on type of connection
+        // factory
+        OpenJPAConfiguration conf = new OpenJPAConfigurationImpl(true, false);
+        conf.fromProperties(map);
+        assertEquals(cfactory, conf.getConnectionFactory());
+        assertEquals(cfactory2, conf.getConnectionFactory2());
+        assertEquals(false, conf.getOptimistic());
+        assertEquals(503, conf.getLockTimeout());
+
+        OpenJPAConfiguration conf2 = new OpenJPAConfigurationImpl(true, false);
+        conf2.fromProperties(map);
+        assertEquals(conf, conf2);
+
+        Map p = conf.toProperties(false);
+        assertTrue(!p.containsKey("openjpa.ConnectionFactory"));
+        assertTrue(!p.containsKey("openjpa.ConnectionFactory2"));
+        assertEquals("false", p.get("openjpa.Optimistic"));
+        assertEquals("503", p.get("openjpa.LockTimeout"));
+        assertEquals(p, conf2.toProperties(false));
+
+        map.put("openjpa.LockTimeout", new Integer(504));
+        OpenJPAConfiguration conf3 = new OpenJPAConfigurationImpl(true, false);
+        conf3.fromProperties(map);
+        assertNotEquals(conf, conf3);
+    }
+
+    public void testClassAliases()
+        throws Exception {
+        OpenJPAConfiguration conf = getConfiguration();
+        if (!(conf instanceof OpenJPAConfigurationImpl))
+            return;
+
+        Value[] values = ((OpenJPAConfigurationImpl) conf).getValues();
+        String[] aliases;
+        String clsName;
+        List failures = new ArrayList();
+        for (int i = 0; i < values.length; i++) {
+            if (!(values[i] instanceof PluginValue))
+                continue;
+
+            aliases = values[i].getAliases();
+            for (int j = 0; j < aliases.length; j += 2) {
+                try {
+                    clsName = Configurations.getClassName(aliases[j + 1]);
+                    if (clsName != null)
+                        Class.forName(clsName);
+                } catch (ClassNotFoundException cnfe) {
+                    failures.add("Key: " + aliases[j] + " for property "
+                        + values[i].getProperty() + " does not list a valid "
+                        + "class: " + aliases[j + 1]);
+                } catch (UnsupportedClassVersionError ucve) {
+                    //### JDK 5 plugin; ignore
+                }
+            }
+        }
+        if (failures.size() != 0)
+            fail(failures.toString());
+    }
+
+    public void testBeanAccessors()
+        throws Exception {
+        OpenJPAConfiguration conf = getConfiguration();
+        OpenJPAConfigurationImpl simp = (OpenJPAConfigurationImpl) conf.clone();
+
+        Value[] values = simp.getValues();
+        PropertyDescriptor[] pds = simp.getPropertyDescriptors();
+        List failures = new ArrayList();
+        for (int i = 0; i < values.length; i++) {
+            try {
+                assertNotNull(pds[i].getShortDescription());
+                assertNotNull(pds[i].getDisplayName());
+
+                Method setter = pds[i].getWriteMethod();
+                Method getter = pds[i].getReadMethod();
+                assertNotNull(setter);
+                assertNotNull(getter);
+
+                assertNotNull("Missing attribute ("
+                    + Configuration.ATTRIBUTE_TYPE
+                    + ") for property " + pds[i].getName(),
+                    pds[i].getValue(Configuration.ATTRIBUTE_TYPE));
+
+                assertNotNull("Missing attribute ("
+                    + Configuration.ATTRIBUTE_CATEGORY
+                    + ") for property " + pds[i].getName(),
+                    pds[i].getValue(Configuration.ATTRIBUTE_CATEGORY));
+
+                assertNotNull("Missing attribute ("
+                    + Configuration.ATTRIBUTE_ORDER
+                    + ") for property " + pds[i].getName(),
+                    pds[i].getValue(Configuration.ATTRIBUTE_ORDER));
+
+                pds[i].getReadMethod().invoke(simp, (Object[]) null);
+
+            } catch (Exception e) {
+                failures.add(pds[i].getName());
+            }
+        }
+        if (failures.size() != 0)
+            fail("not all properties had valid comments / setters / getters."
+                + " failed props: " + failures);
+    }
+
+    /**
+     * Tests that invalid plug-in values throw the appropriate exception
+     * type.
+     */
+    public void testInvalidPlugins() {
+        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
+        config.setLog("log3j");
+        try {
+            config.getLogFactory().getLog("Foo");
+            fail("getting the Foo log should have failed");
+        } catch (RuntimeException re) {
+            // as expected ... make sure the exception suggests the
+            // name "log4j" in the message
+            assertTrue(-1 != re.getMessage().indexOf("log4j"));
+        }
+    }
+
+    public void testInvalidConfigurationWarnings() {
+        Properties props = new Properties();
+        props.setProperty("openjpa.MaxxFetchDepth", "1");
+
+        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
+        // track the messages
+        BufferedLogFactory log = new BufferedLogFactory();
+        config.setLogFactory(log);
+
+        config.fromProperties(props);
+
+        // make sure we got a warning that contains the string with the
+        // bad property name and a hint for the valid property name.
+        log.assertLogMessage("*\"openjpa.MaxxFetchDepth\"*");
+        log.assertLogMessage("*\"openjpa.MaxFetchDepth\"*");
+
+        log.clear();
+
+        // now make sure we do *not* try to validate sub-configurations (such
+        // as kodo.jdbc.Foo).
+        props.clear();
+        props.setProperty("openjpa.jdbc.Foo", "XXX");
+        props.setProperty("oponjpa", "XXX");
+        config.fromProperties(props);
+        log.assertNoLogMessage("*\"openjpa.jdbc.Foo\"*");
+        log.assertNoLogMessage("*\"oponjpa\"*");
+    }
+
+    /**
+     * Tests that invalid fixed-list values throw the appropriate exception
+     * type.
+     */
+    public void testInvalidNonPluginValues() {
+        OpenJPAConfiguration config = new OpenJPAConfigurationImpl();
+        try {
+            config.setConnectionFactoryMode("aoeu");
+            fail("setting the ConnectionFactoryMode to aoeu should fail");
+        } catch (RuntimeException re) {
+            re.printStackTrace();
+            // as expected ... make sure the exception suggests the
+            // valid names in the message.
+            assertTrue(-1 != re.getMessage().indexOf("managed"));
+            assertTrue(-1 != re.getMessage().indexOf("local"));
+            assertTrue(-1 != re.getMessage().indexOf("true"));
+            assertTrue(-1 != re.getMessage().indexOf("false"));
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/CacheLoadTest.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,178 @@
+/*
+ * 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.openjpa.persistence.datacache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+
+import org.apache.openjpa.persistence.datacache.common.apps.AttachA;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachB;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachC;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachD;
+import org.apache.openjpa.persistence.datacache.common.apps.AttachE;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * Tests load on the cache. To run:
+ * <p/>
+ * java -Dkodo.properties=hsql.properties -Dcachetest.threads=30
+ * -Dcachetest.iterations=1000 kodo.datacache.CacheLoadTest
+ *
+ * @author <a href="mailto:marc@solarmetric.com">Marc Prud'hommeaux</a>
+ */
+public class CacheLoadTest
+    extends AbstractTestCase {
+
+    private EntityManagerFactory emf;
+    protected int threadCount =
+        Integer.getInteger("cachetest.threads", 30).intValue();
+    protected int interationCount =
+        Integer.getInteger("cachetest.iterations", 1000).intValue();
+
+    public void setUp() {
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.DataCache", "true");
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.QueryCache", "true");
+        emf = getEmf(propsMap);
+    }
+
+    public void testCacheLoad()
+        throws Exception {
+        mttest(Integer.getInteger("cachetest.threads", 30).intValue(),
+            Integer.getInteger("cachetest.iterations", 1000).intValue());
+
+        switch ((int) (Math.random() * 4)) {
+            case 0:
+                insert();
+                break;
+            case 1:
+                query();
+                break;
+            case 2:
+                delete();
+                break;
+            case 3:
+                read();
+                break;
+        }
+    }
+
+    private int rnd(int num) {
+        return randomInt().intValue() % num;
+    }
+
+    private void insert()
+        throws Exception {
+
+        EntityManager em = emf.createEntityManager();
+        startTx(em);
+
+        for (int i = 0; i < (rnd(100)); i++) {
+            em.persist(randomizeBean(rndclass().newInstance()));
+        }
+
+        endTx(em);
+        endEm(em);
+    }
+
+    private void query() {
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) emf.createEntityManager();
+
+        String[] filters = new String[]{
+            "select from " + AttachA.class.getName() + " where aint > 0",
+            "select from " + AttachA.class.getName() + " where aint < 0",
+            "select from " + AttachB.class.getName() + " where aint > 0",
+            "select from " + AttachB.class.getName() + " where aint < 0",
+            "select from " + AttachC.class.getName() + " where aint > 0",
+            "select from " + AttachC.class.getName() + " where aint < 0",
+        };
+
+        for (int i = 0; i < rnd(50); i++) {
+            try {
+                new ArrayList((Collection) em
+                    .createQuery("org.apache.openjpa.kernel.jpql.JPQL",
+                        filters[randomInt().intValue() % filters.length]).
+                    getResultList());
+            } catch (IllegalStateException e) {
+                e.printStackTrace();
+            }
+        }
+
+        endEm(em);
+    }
+
+    private void delete() {
+
+        try {
+            OpenJPAEntityManager em =
+                (OpenJPAEntityManager) emf.createEntityManager();
+            startTx(em);
+
+            for (Iterator i = em.createExtent(rndclass(), Math.random() > 0.5f).
+                iterator(); i.hasNext();) {
+                Object o = i.next();
+                if (Math.random() > 0.6f)
+                    em.remove(o);
+            }
+
+            endTx(em);
+            endEm(em);
+        } catch (IllegalStateException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void read() {
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) emf.createEntityManager();
+
+        for (Iterator i = em.createExtent(rndclass(), Math.random() > 0.5f).
+            iterator(); i.hasNext();) {
+            Object o = i.next();
+        }
+
+        endEm(em);
+    }
+
+    private Class rndclass() {
+        Class[] c = new Class[]{
+            AttachA.class,
+            AttachB.class,
+            AttachC.class,
+            AttachD.class,
+            AttachE.class,
+        };
+
+        return c[(int) (Math.random() * c.length)];
+    }
+}
+



Mime
View raw message