Source Code Cross Referenced for AbstractTestCase.java in  » Database-ORM » openjpa » org » apache » openjpa » persistence » common » utils » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » openjpa » org.apache.openjpa.persistence.common.utils 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one
0003:         * or more contributor license agreements.  See the NOTICE file
0004:         * distributed with this work for additional information
0005:         * regarding copyright ownership.  The ASF licenses this file
0006:         * to you under the Apache License, Version 2.0 (the
0007:         * "License"); you may not use this file except in compliance
0008:         * with the License.  You may obtain a copy of the License at
0009:         *
0010:         * http://www.apache.org/licenses/LICENSE-2.0
0011:         *
0012:         * Unless required by applicable law or agreed to in writing,
0013:         * software distributed under the License is distributed on an
0014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015:         * KIND, either express or implied.  See the License for the
0016:         * specific language governing permissions and limitations
0017:         * under the License.
0018:         */
0019:        /*
0020:         * Licensed to the Apache Software Foundation (ASF) under one
0021:         * or more contributor license agreements.  See the NOTICE file
0022:         * distributed with this work for additional information
0023:         * regarding copyright ownership.  The ASF licenses this file
0024:         * to you under the Apache License, Version 2.0 (the
0025:         * "License"); you may not use this file except in compliance
0026:         * with the License.  You may obtain a copy of the License at
0027:         *
0028:         * http://www.apache.org/licenses/LICENSE-2.0
0029:         *
0030:         * Unless required by applicable law or agreed to in writing,
0031:         * software distributed under the License is distributed on an
0032:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0033:         * KIND, either express or implied.  See the License for the
0034:         * specific language governing permissions and limitations
0035:         * under the License.    
0036:         */
0037:        package org.apache.openjpa.persistence.common.utils;
0038:
0039:        import java.util.Map;
0040:        import java.util.Date;
0041:        import java.util.Collection;
0042:        import java.util.EnumSet;
0043:        import java.util.ArrayList;
0044:        import java.util.HashMap;
0045:        import java.util.List;
0046:        import java.util.Iterator;
0047:        import java.util.Collections;
0048:        import java.util.LinkedList;
0049:        import java.util.StringTokenizer;
0050:        import java.util.ListIterator;
0051:        import java.util.NoSuchElementException;
0052:        import java.util.Arrays;
0053:        import java.util.Comparator;
0054:        import java.math.BigInteger;
0055:        import java.math.BigDecimal;
0056:        import java.lang.reflect.InvocationTargetException;
0057:        import java.lang.reflect.Method;
0058:        import java.beans.BeanInfo;
0059:        import java.beans.Introspector;
0060:        import java.beans.PropertyDescriptor;
0061:        import java.io.IOException;
0062:        import java.io.ByteArrayOutputStream;
0063:        import java.io.ObjectOutputStream;
0064:        import java.io.ByteArrayInputStream;
0065:        import java.io.ObjectInputStream;
0066:        import java.io.StringWriter;
0067:        import java.io.PrintWriter;
0068:        import java.io.PrintStream;
0069:        import java.net.URL;
0070:        import javax.persistence.EntityManager;
0071:        import javax.persistence.Query;
0072:        import javax.persistence.EntityManagerFactory;
0073:        import javax.management.IntrospectionException;
0074:
0075:        import org.apache.regexp.RESyntaxException;
0076:        import org.apache.regexp.RE;
0077:        import org.apache.regexp.REUtil;
0078:        import org.apache.openjpa.persistence.test.PersistenceTestCase;
0079:        import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
0080:        import org.apache.openjpa.persistence.OpenJPAEntityManager;
0081:        import org.apache.openjpa.persistence.JPAFacadeHelper;
0082:        import org.apache.openjpa.persistence.OpenJPAPersistence;
0083:        import org.apache.openjpa.conf.OpenJPAConfiguration;
0084:        import org.apache.openjpa.kernel.OpenJPAStateManager;
0085:        import org.apache.openjpa.kernel.BrokerFactory;
0086:        import org.apache.openjpa.lib.log.Log;
0087:        import org.apache.openjpa.meta.ClassMetaData;
0088:
0089:        public abstract class AbstractTestCase extends PersistenceTestCase {
0090:
0091:            private String persistenceXmlResource;
0092:            private Map<Map, OpenJPAEntityManagerFactory> emfs = new HashMap<Map, OpenJPAEntityManagerFactory>();
0093:            private OpenJPAEntityManager currentEntityManager;
0094:
0095:            protected enum Platform {
0096:                EMPRESS, HYPERSONIC, POSTGRESQL, MYSQL, SQLSERVER, DB2, ORACLE, DERBY, INFORMIX, POINTBASE, SYBASE,
0097:            }
0098:
0099:            protected String multiThreadExecuting = null;
0100:            protected boolean inTimeoutThread = false;
0101:
0102:            public AbstractTestCase(String name, String s) {
0103:                setName(name);
0104:                persistenceXmlResource = computePersistenceXmlResource(s);
0105:            }
0106:
0107:            public void tearDown() throws Exception {
0108:                try {
0109:                    super .tearDown();
0110:                } finally {
0111:                    for (EntityManagerFactory emf : emfs.values()) {
0112:                        try {
0113:                            closeEMF(emf);
0114:                        } catch (Exception e) {
0115:                            e.printStackTrace();
0116:                        }
0117:                    }
0118:                }
0119:            }
0120:
0121:            public AbstractTestCase() {
0122:            }
0123:
0124:            public AbstractTestCase(String name) {
0125:                setName(name);
0126:            }
0127:
0128:            protected String computePersistenceXmlResource(String s) {
0129:                String resourceName = getClass().getPackage().getName()
0130:                        .replaceAll("\\.", "/");
0131:                resourceName += "/common/apps/META-INF/persistence.xml";
0132:                URL resource = getClass().getClassLoader().getResource(
0133:                        resourceName);
0134:                if (resource != null)
0135:                    return resourceName;
0136:                return defaultPersistenceXmlResource();
0137:            }
0138:
0139:            protected String defaultPersistenceXmlResource() {
0140:                return "org/apache/openjpa/persistence/"
0141:                        + "common/apps/META-INF/persistence.xml";
0142:            }
0143:
0144:            protected OpenJPAStateManager getStateManager(Object obj,
0145:                    EntityManager em) {
0146:                return JPAFacadeHelper.toBroker(em).getStateManager(obj);
0147:            }
0148:
0149:            protected int deleteAll(Class type, EntityManager em) {
0150:                ClassMetaData meta = JPAFacadeHelper.getMetaData(em, type);
0151:                if (meta != null)
0152:                    return em.createQuery("delete from " + meta.getTypeAlias())
0153:                            .executeUpdate();
0154:                else
0155:                    return -1;
0156:            }
0157:
0158:            protected int deleteAll(Class... types) {
0159:                EntityManager em = getEmf().createEntityManager();
0160:                em.getTransaction().begin();
0161:                int ret = 0;
0162:                for (Class type : types)
0163:                    ret += deleteAll(type, em);
0164:                em.getTransaction().commit();
0165:                em.close();
0166:                return ret;
0167:            }
0168:
0169:            protected OpenJPAEntityManagerFactory getEmf(Map map) {
0170:                if (map == null)
0171:                    map = new HashMap();
0172:                Collection keys = new ArrayList();
0173:                for (Object key : map.keySet())
0174:                    if (key.toString().startsWith("kodo"))
0175:                        keys.add(key);
0176:                if (keys.size() > 0)
0177:                    throw new IllegalArgumentException(
0178:                            "kodo-prefixed properties must be converted to openjpa. "
0179:                                    + "Properties: " + keys);
0180:
0181:                addProperties(map);
0182:
0183:                OpenJPAEntityManagerFactory emf = emfs.get(map);
0184:                if (emf == null) {
0185:                    emf = OpenJPAPersistence.createEntityManagerFactory(
0186:                            "TestConv", persistenceXmlResource, map);
0187:                    emfs.put(map, emf);
0188:                }
0189:                return emf;
0190:            }
0191:
0192:            protected void addProperties(Map map) {
0193:                if (!map.containsKey("openjpa.jdbc.SynchronizeMappings"))
0194:                    map
0195:                            .put(
0196:                                    "openjpa.jdbc.SynchronizeMappings",
0197:                                    "buildSchema(ForeignKeys=true,"
0198:                                            + "SchemaAction='add,deleteTableContents')");
0199:                map.put("openjpa.Log", "SQL=TRACE");
0200:            }
0201:
0202:            protected OpenJPAEntityManagerFactory getEmf() {
0203:                Map m = new HashMap();
0204:                return getEmf(m);
0205:            }
0206:
0207:            protected BrokerFactory getBrokerFactory() {
0208:                return JPAFacadeHelper.toBrokerFactory(getEmf());
0209:            }
0210:
0211:            protected BrokerFactory getBrokerFactory(String[] args) {
0212:                if (args.length % 2 != 0)
0213:                    throw new IllegalArgumentException(
0214:                            "odd number of elements in arg array");
0215:                Map map = new HashMap();
0216:                for (int i = 0; i < args.length; i = i + 2)
0217:                    map.put(args[i], args[i + 1]);
0218:                return JPAFacadeHelper.toBrokerFactory(getEmf(map));
0219:            }
0220:
0221:            protected OpenJPAEntityManager currentEntityManager() {
0222:                if (currentEntityManager == null
0223:                        || !currentEntityManager.isOpen())
0224:                    currentEntityManager = getEmf().createEntityManager();
0225:                return currentEntityManager;
0226:            }
0227:
0228:            protected void startTx(EntityManager em) {
0229:                em.getTransaction().begin();
0230:            }
0231:
0232:            protected boolean isActiveTx(EntityManager em) {
0233:                return em.getTransaction().isActive();
0234:            }
0235:
0236:            protected void endTx(EntityManager em) {
0237:                if (em.getTransaction().isActive()) {
0238:                    if (em.getTransaction().getRollbackOnly())
0239:                        em.getTransaction().rollback();
0240:                    else
0241:                        em.getTransaction().commit();
0242:                }
0243:            }
0244:
0245:            protected void rollbackTx(EntityManager em) {
0246:                em.getTransaction().rollback();
0247:            }
0248:
0249:            protected void endEm(EntityManager em) {
0250:                if (em.isOpen())
0251:                    em.close();
0252:                if (em == currentEntityManager)
0253:                    currentEntityManager = null;
0254:            }
0255:
0256:            protected Object getStackTrace(Throwable t) {
0257:                throw new UnsupportedOperationException();
0258:            }
0259:
0260:            protected OpenJPAConfiguration getConfiguration() {
0261:                return getEmf().getConfiguration();
0262:            }
0263:
0264:            protected Platform getCurrentPlatform() {
0265:                throw new UnsupportedOperationException();
0266:            }
0267:
0268:            protected void bug(int id, String s) {
0269:                bug(id, null, s);
0270:            }
0271:
0272:            protected void bug(Platform platform, int id, Throwable t, String s) {
0273:                bug(EnumSet.of(platform), id, t, s);
0274:            }
0275:
0276:            protected void bug(EnumSet<Platform> platforms, int id,
0277:                    Throwable t, String s) {
0278:                if (platforms.contains(getCurrentPlatform()))
0279:                    bug(id, t, s);
0280:                else
0281:                    fail(String.format(
0282:                            "bug %s is unexpectedly occurring on platform %s",
0283:                            id, getCurrentPlatform()));
0284:            }
0285:
0286:            protected void bug(int id, Throwable t, String s) {
0287:                if (t != null) {
0288:                    if (t instanceof  RuntimeException)
0289:                        throw (RuntimeException) t;
0290:                    else
0291:                        throw new RuntimeException(t);
0292:                } else {
0293:                    fail(s);
0294:                }
0295:            }
0296:
0297:            /**
0298:             * Support method to get a random Integer for testing.
0299:             */
0300:            public static Integer randomInt() {
0301:                return new Integer((int) (Math.random() * Integer.MAX_VALUE));
0302:            }
0303:
0304:            /**
0305:             * Support method to get a random Character for testing.
0306:             */
0307:            public static Character randomChar() {
0308:                char[] TEST_CHAR_ARRAY = new char[] { 'a', 'b', 'c', 'd', 'e',
0309:                        'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
0310:                        'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1',
0311:                        '2', '3', '4', '5', '6', '7', '8', '9' };
0312:
0313:                return new Character(
0314:                        TEST_CHAR_ARRAY[(int) (Math.random() * TEST_CHAR_ARRAY.length)]);
0315:            }
0316:
0317:            /**
0318:             * Support method to get a random Long for testing.
0319:             */
0320:            public static Long randomLong() {
0321:                return new Long((long) (Math.random() * Long.MAX_VALUE));
0322:            }
0323:
0324:            /**
0325:             * Support method to get a random Short for testing.
0326:             */
0327:            public static Short randomShort() {
0328:                return new Short((short) (Math.random() * Short.MAX_VALUE));
0329:            }
0330:
0331:            /**
0332:             * Support method to get a random Double for testing.
0333:             */
0334:            public static Double randomDouble() {
0335:                return new Double(
0336:                        (double) (Math.round(Math.random() * 5000d)) / 1000d);
0337:            }
0338:
0339:            /**
0340:             * Support method to get a random Float for testing.
0341:             */
0342:            public static Float randomFloat() {
0343:                return new Float(
0344:                        (float) (Math.round(Math.random() * 5000f)) / 1000f);
0345:            }
0346:
0347:            /**
0348:             * Support method to get a random Byte for testing.
0349:             */
0350:            public static Byte randomByte() {
0351:                return new Byte((byte) (Math.random() * Byte.MAX_VALUE));
0352:            }
0353:
0354:            /**
0355:             * Support method to get a random Boolean for testing.
0356:             */
0357:            public static Boolean randomBoolean() {
0358:                return new Boolean(Math.random() > 0.5 ? true : false);
0359:            }
0360:
0361:            /**
0362:             * Support method to get a random Date for testing.
0363:             */
0364:            public static Date randomDate() {
0365:                long millis = (long) (Math.random() * System
0366:                        .currentTimeMillis());
0367:
0368:                // round millis to the nearest 1000: this is because some
0369:                // databases do not store the milliseconds correctly (e.g., MySQL).
0370:                // This is a really a bug we should fix. FC #27.
0371:                millis -= (millis % 1000);
0372:
0373:                return new Date(millis);
0374:            }
0375:
0376:            /**
0377:             * Support method to get a random String for testing.
0378:             */
0379:            public static String randomString() {
0380:                // default to a small string, in case column sizes are
0381:                // limited (such as with a string primary key)
0382:                return randomString(50);
0383:            }
0384:
0385:            /**
0386:             * Support method to get a random String for testing.
0387:             */
0388:            public static String randomString(int len) {
0389:                StringBuffer buf = new StringBuffer();
0390:                for (int i = 0; i < (int) (Math.random() * len) + 1; i++)
0391:                    buf.append(randomChar());
0392:                return buf.toString();
0393:            }
0394:
0395:            /**
0396:             * Support method to get a random clob for testing.
0397:             */
0398:            public static String randomClob() {
0399:                StringBuffer sbuf = new StringBuffer();
0400:                while (sbuf.length() < (5 * 1024)) // at least 5K
0401:                {
0402:                    sbuf.append(randomString(1024));
0403:                }
0404:
0405:                return sbuf.toString();
0406:            }
0407:
0408:            /**
0409:             * Support method to get a random BigInteger for testing.
0410:             */
0411:            public static BigInteger randomBigInteger() {
0412:                // too many of our test databases don't support bigints > MAX_LONG:
0413:                // I don't like it, but for now, let's only test below MAX_LONG
0414:                BigInteger lng = new BigInteger(
0415:                        ((long) (Math.random() * Long.MAX_VALUE)) + "");
0416:
0417:                BigInteger multiplier = new BigInteger("1");
0418:                // (1 + (int)(Math.random () * 10000)) + "");
0419:                if (Math.random() < 0.5)
0420:                    multiplier = multiplier.multiply(new BigInteger("-1"));
0421:
0422:                return lng.multiply(multiplier);
0423:            }
0424:
0425:            /**
0426:             * Support method to get a random BigDecimal for testing.
0427:             */
0428:            public static BigDecimal randomBigDecimal() {
0429:                BigInteger start = randomBigInteger();
0430:                String str = start.toString();
0431:                // truncate off the last 8 digits: we still get some
0432:                // overflows with lame databases.
0433:                for (int i = 0; i < 8; i++)
0434:                    if (str.length() > 2)
0435:                        str = str.substring(0, str.length() - 1);
0436:                start = new BigInteger(str);
0437:
0438:                String val = start + "." + ((int) (Math.random() * 10))
0439:                        + ((int) (Math.random() * 10))
0440:                        + ((int) (Math.random() * 10))
0441:                        + ((int) (Math.random() * 10))
0442:                        + ((int) (Math.random() * 10))
0443:                        + ((int) (Math.random() * 10))
0444:                        + ((int) (Math.random() * 10))
0445:                        + ((int) (Math.random() * 10))
0446:                        + ((int) (Math.random() * 10))
0447:                        + ((int) (Math.random() * 10));
0448:
0449:                return new BigDecimal(val);
0450:            }
0451:
0452:            /**
0453:             * Support method to get a random blob for testing.
0454:             */
0455:            public static byte[] randomBlob() {
0456:                // up to 100K blob
0457:                byte[] blob = new byte[(int) (Math.random() * 1024 * 100)];
0458:                for (int i = 0; i < blob.length; i++)
0459:                    blob[i] = randomByte().byteValue();
0460:
0461:                return blob;
0462:            }
0463:
0464:            /**
0465:             * Invoke setters for pimitives and primitive wrappers on the
0466:             * specified object.
0467:             */
0468:            public static Object randomizeBean(Object bean)
0469:                    throws IntrospectionException, IllegalAccessException,
0470:                    InvocationTargetException,
0471:                    java.beans.IntrospectionException {
0472:                BeanInfo info = Introspector.getBeanInfo(bean.getClass());
0473:                PropertyDescriptor[] props = info.getPropertyDescriptors();
0474:                for (int i = 0; i < props.length; i++) {
0475:                    Method write = props[i].getWriteMethod();
0476:                    if (write == null)
0477:                        continue;
0478:
0479:                    Class[] params = write.getParameterTypes();
0480:                    if (params == null || params.length != 1)
0481:                        continue;
0482:
0483:                    Class paramType = params[0];
0484:                    Object arg = null;
0485:
0486:                    if (paramType == boolean.class
0487:                            || paramType == Boolean.class)
0488:                        arg = randomBoolean();
0489:                    else if (paramType == byte.class || paramType == Byte.class)
0490:                        arg = randomByte();
0491:                    else if (paramType == char.class
0492:                            || paramType == Character.class)
0493:                        arg = randomChar();
0494:                    else if (paramType == short.class
0495:                            || paramType == Short.class)
0496:                        arg = randomShort();
0497:                    else if (paramType == int.class
0498:                            || paramType == Integer.class)
0499:                        arg = randomInt();
0500:                    else if (paramType == long.class || paramType == Long.class)
0501:                        arg = randomLong();
0502:                    else if (paramType == double.class
0503:                            || paramType == Double.class)
0504:                        arg = randomDouble();
0505:                    else if (paramType == float.class
0506:                            || paramType == Float.class)
0507:                        arg = randomFloat();
0508:                    else if (paramType == String.class)
0509:                        arg = randomString();
0510:                    else if (paramType == BigInteger.class)
0511:                        arg = randomBigInteger();
0512:                    else if (paramType == BigDecimal.class)
0513:                        arg = randomBigDecimal();
0514:                    else if (paramType == Date.class)
0515:                        arg = randomDate();
0516:
0517:                    if (arg != null)
0518:                        write.invoke(bean, new Object[] { arg });
0519:                }
0520:
0521:                return bean;
0522:            }
0523:
0524:            protected void assertSize(int size, Collection c) {
0525:                assertEquals(size, c.size());
0526:            }
0527:
0528:            protected void assertSize(int size, Query q) {
0529:                assertEquals(size, q.getResultList().size());
0530:            }
0531:
0532:            /**
0533:             * Serialize and deserialize the object.
0534:             *
0535:             * @param validateEquality make sure the hashCode and equals
0536:             * methods hold true
0537:             */
0538:            public static Object roundtrip(Object orig, boolean validateEquality)
0539:                    throws IOException, ClassNotFoundException {
0540:                assertNotNull(orig);
0541:
0542:                ByteArrayOutputStream bout = new ByteArrayOutputStream();
0543:                ObjectOutputStream out = new ObjectOutputStream(bout);
0544:                out.writeObject(orig);
0545:                ByteArrayInputStream bin = new ByteArrayInputStream(bout
0546:                        .toByteArray());
0547:                ObjectInputStream in = new ObjectInputStream(bin);
0548:                Object result = in.readObject();
0549:
0550:                if (validateEquality) {
0551:                    assertEquals(orig.hashCode(), result.hashCode());
0552:                    assertEquals(orig, result);
0553:                }
0554:
0555:                return result;
0556:            }
0557:
0558:            /**
0559:             * @return true if the specified input matches the regular expression regex.
0560:             */
0561:            public static boolean matches(String regex, String input)
0562:                    throws RESyntaxException {
0563:                RE re = REUtil.createRE(regex);
0564:                return re.match(input);
0565:            }
0566:
0567:            public static void assertMatches(String regex, String input) {
0568:                try {
0569:                    if (!(matches(regex, input)))
0570:                        fail("Expected regular expression: <" + regex + ">"
0571:                                + " did not match: <" + input + ">");
0572:                } catch (RESyntaxException e) {
0573:                    throw new IllegalArgumentException(e.toString());
0574:                }
0575:            }
0576:
0577:            public static void assertNotMatches(String regex, String input) {
0578:                try {
0579:                    if (matches(regex, input))
0580:                        fail("Regular expression: <" + regex + ">"
0581:                                + " should not match: <" + input + ">");
0582:                } catch (RESyntaxException e) {
0583:                    throw new IllegalArgumentException(e.toString());
0584:                }
0585:            }
0586:
0587:            /**
0588:             * Check the list if strings and return the ones that match
0589:             * the specified match.
0590:             */
0591:            public static List matches(String regex, Collection input)
0592:                    throws RESyntaxException {
0593:                List matches = new ArrayList();
0594:                for (Iterator i = input.iterator(); i.hasNext();) {
0595:                    String check = (String) i.next();
0596:                    if (matches(regex, check))
0597:                        matches.add(check);
0598:                }
0599:
0600:                return matches;
0601:            }
0602:
0603:            /**
0604:             * Assert that the specified collection of Strings contains at least
0605:             * one string that matches the specified regular expression.
0606:             */
0607:            public static void assertMatches(String regex, Collection input) {
0608:                try {
0609:                    if (matches(regex, input).size() == 0)
0610:                        fail("The specified list of size " + input.size()
0611:                                + " did not contain any strings that match the"
0612:                                + " specified regular expression(\"" + regex
0613:                                + "\")");
0614:                } catch (RESyntaxException e) {
0615:                    throw new IllegalArgumentException(e.toString());
0616:                }
0617:            }
0618:
0619:            /**
0620:             * Assert that the specified collection of Strings does not match
0621:             * the specified regular expression.
0622:             */
0623:            public static void assertNotMatches(String regex, Collection input) {
0624:                try {
0625:                    List matches;
0626:
0627:                    if (((matches = matches(regex, input))).size() > 0)
0628:                        fail("The specified list of size "
0629:                                + input.size()
0630:                                + " did contain one or more strings that matchs the"
0631:                                + " specified illegal regular expression"
0632:                                + " (\"" + regex + "\")."
0633:                                + " First example of a matching message is: "
0634:                                + matches.iterator().next());
0635:                } catch (RESyntaxException e) {
0636:                    throw new IllegalArgumentException(e.toString());
0637:                }
0638:            }
0639:
0640:            protected Log getLog() {
0641:                return getConfiguration().getLog("Tests");
0642:            }
0643:
0644:            ///////////////////
0645:            // Multi threading
0646:            ///////////////////
0647:
0648:            /**
0649:             * Re-execute the invoking method a random number of times
0650:             * in a random number of Threads.
0651:             */
0652:            public void mttest() throws ThreadingException {
0653:                // 6 iterations in 8 threads is a good trade-off between
0654:                // tests taking way too long and having a decent chance of
0655:                // identifying MT problems.
0656:                int iterations = 6;
0657:                int threads = 8;
0658:
0659:                mttest(threads, iterations);
0660:            }
0661:
0662:            /**
0663:             * Execute the calling method <code>iterations</code>
0664:             * times in <code>threads</code> Threads.
0665:             */
0666:            public void mttest(int threads, int iterations) {
0667:                mttest(0, threads, iterations);
0668:            }
0669:
0670:            public void mttest(int serialCount, int threads, int iterations)
0671:                    throws ThreadingException {
0672:                String methodName = callingMethod("mttest");
0673:                mttest(serialCount, threads, iterations, methodName,
0674:                        new Object[0]);
0675:            }
0676:
0677:            /**
0678:             * Execute a test method in multiple threads.
0679:             *
0680:             * @param threads the number of Threads to run in
0681:             * @param iterations the number of times the method should
0682:             * be execute in a single Thread
0683:             * @param method the name of the method to execute
0684:             * @param args the arguments to pass to the method
0685:             * @throws ThreadingException if an errors occur in
0686:             * any of the Threads. The actual exceptions
0687:             * will be embedded in the exception. Note that
0688:             * this means that assert() failures will be
0689:             * treated as errors rather than warnings.
0690:             * @author Marc Prud'hommeaux
0691:             */
0692:            public void mttest(int threads, int iterations,
0693:                    final String method, final Object[] args)
0694:                    throws ThreadingException {
0695:                mttest(0, threads, iterations, method, args);
0696:            }
0697:
0698:            public void mttest(int serialCount, int threads, int iterations,
0699:                    final String method, final Object[] args)
0700:                    throws ThreadingException {
0701:                if (multiThreadExecuting != null
0702:                        && multiThreadExecuting.equals(method)) {
0703:                    // we are currently executing in multi-threaded mode:
0704:                    // don't deadlock!
0705:                    return;
0706:                }
0707:
0708:                multiThreadExecuting = method;
0709:
0710:                try {
0711:                    Class[] paramClasses = new Class[args.length];
0712:                    for (int i = 0; i < paramClasses.length; i++)
0713:                        paramClasses[i] = args[i].getClass();
0714:
0715:                    final Method meth;
0716:
0717:                    try {
0718:                        meth = getClass().getMethod(method, paramClasses);
0719:                    } catch (NoSuchMethodException nsme) {
0720:                        throw new ThreadingException(nsme.toString(), nsme);
0721:                    }
0722:
0723:                    final Object thiz = this ;
0724:
0725:                    mttest("reflection invocation: (" + method + ")",
0726:                            serialCount, threads, iterations,
0727:                            new VolatileRunnable() {
0728:                                public void run() throws Exception {
0729:                                    meth.invoke(thiz, args);
0730:                                }
0731:                            });
0732:                } finally {
0733:                    multiThreadExecuting = null;
0734:                }
0735:            }
0736:
0737:            public void mttest(String title, final int threads,
0738:                    final int iterations, final VolatileRunnable runner)
0739:                    throws ThreadingException {
0740:                mttest(title, 0, threads, iterations, runner);
0741:            }
0742:
0743:            /**
0744:             * Execute a test method in multiple threads.
0745:             *
0746:             * @param title a description of the test, for inclusion in the
0747:             * error message
0748:             * @param serialCount the number of times to run the method
0749:             * serially before spawning threads.
0750:             * @param threads the number of Threads to run in
0751:             * @param iterations the number of times the method should
0752:             * @param runner the VolatileRunnable that will execute
0753:             * the actual test from within the Thread.
0754:             * @throws ThreadingException if an errors occur in
0755:             * any of the Threads. The actual exceptions
0756:             * will be embedded in the exception. Note that
0757:             * this means that assert() failures will be
0758:             * treated as errors rather than warnings.
0759:             * @author Marc Prud'hommeaux be execute in a single Thread
0760:             * @author Marc Prud'hommeaux
0761:             */
0762:            public void mttest(String title, final int serialCount,
0763:                    final int threads, final int iterations,
0764:                    final VolatileRunnable runner) throws ThreadingException {
0765:                final List exceptions = Collections
0766:                        .synchronizedList(new LinkedList());
0767:
0768:                Thread[] runners = new Thread[threads];
0769:
0770:                final long startMillis = System.currentTimeMillis() + 1000;
0771:
0772:                for (int i = 1; i <= threads; i++) {
0773:                    final int this Thread = i;
0774:
0775:                    runners[i - 1] = new Thread(title + " [" + i + " of "
0776:                            + threads + "]") {
0777:                        public void run() {
0778:                            // do our best to have all threads start at the exact
0779:                            // same time. This is imperfect, but the closer we
0780:                            // get to everyone starting at the same time, the
0781:                            // better chance we have for identifying MT problems.
0782:                            while (System.currentTimeMillis() < startMillis)
0783:                                yield();
0784:
0785:                            int this Iteration = 1;
0786:                            try {
0787:                                for (; this Iteration <= iterations; this Iteration++) {
0788:                                    // go go go!
0789:                                    runner.run();
0790:                                }
0791:                            } catch (Throwable error) {
0792:                                synchronized (exceptions) {
0793:                                    // embed the exception into something that gives
0794:                                    // us some more information about the threading
0795:                                    // environment
0796:                                    exceptions.add(new ThreadingException(
0797:                                            "thread=" + this .toString()
0798:                                                    + ";threadNum="
0799:                                                    + this Thread
0800:                                                    + ";maxThreads=" + threads
0801:                                                    + ";iteration="
0802:                                                    + this Iteration
0803:                                                    + ";maxIterations="
0804:                                                    + iterations, error));
0805:                                }
0806:                            }
0807:                        }
0808:                    };
0809:                }
0810:
0811:                // start the serial tests(does not spawn the threads)
0812:                for (int i = 0; i < serialCount; i++) {
0813:                    runners[0].run();
0814:                }
0815:
0816:                // start the multithreaded
0817:                for (int i = 0; i < threads; i++) {
0818:                    runners[i].start();
0819:                }
0820:
0821:                // wait for them all to complete
0822:                for (int i = 0; i < threads; i++) {
0823:                    try {
0824:                        runners[i].join();
0825:                    } catch (InterruptedException e) {
0826:                    }
0827:                }
0828:
0829:                if (exceptions.size() == 0)
0830:                    return; // sweeeeeeeet: no errors
0831:
0832:                // embed all the exceptions that were throws into a
0833:                // ThreadingException
0834:                Throwable[] errors = (Throwable[]) exceptions
0835:                        .toArray(new Throwable[0]);
0836:                throw new ThreadingException("The " + errors.length
0837:                        + " embedded errors " + "occured in the execution of "
0838:                        + iterations + " iterations " + "of " + threads
0839:                        + " threads: [" + title + "]", errors);
0840:            }
0841:
0842:            /**
0843:             * Check to see if we are in the top-level execution stack.
0844:             */
0845:            public boolean isRootThread() {
0846:                return multiThreadExecuting == null;
0847:            }
0848:
0849:            /**
0850:             * A Runnable that can throw an Exception: used to test cases.
0851:             */
0852:            public static interface VolatileRunnable {
0853:
0854:                public void run() throws Exception;
0855:            }
0856:
0857:            /**
0858:             * Exception for errors caught during threading tests.
0859:             */
0860:            public class ThreadingException extends RuntimeException {
0861:
0862:                private final Throwable[] _nested;
0863:
0864:                public ThreadingException(String msg, Throwable nested) {
0865:                    super (msg);
0866:                    if (nested == null)
0867:                        _nested = new Throwable[0];
0868:                    else
0869:                        _nested = new Throwable[] { nested };
0870:                }
0871:
0872:                public ThreadingException(String msg, Throwable[] nested) {
0873:                    super (msg);
0874:                    if (nested == null)
0875:                        _nested = new Throwable[0];
0876:                    else
0877:                        _nested = nested;
0878:                }
0879:
0880:                public void printStackTrace() {
0881:                    printStackTrace(System.out);
0882:                }
0883:
0884:                public void printStackTrace(PrintStream out) {
0885:                    printStackTrace(new PrintWriter(out));
0886:                }
0887:
0888:                public void printStackTrace(PrintWriter out) {
0889:                    super .printStackTrace(out);
0890:                    for (int i = 0; i < _nested.length; i++) {
0891:                        out.print("Nested Throwable #" + (i + 1) + ": ");
0892:                        _nested[i].printStackTrace(out);
0893:                    }
0894:                }
0895:            }
0896:
0897:            /**
0898:             * Return the last method name that called this one by
0899:             * parsing the current stack trace.
0900:             *
0901:             * @param exclude a method name to skip
0902:             * @throws IllegalStateException If the calling method could not be
0903:             * identified.
0904:             * @author Marc Prud'hommeaux
0905:             */
0906:            public String callingMethod(String exclude) {
0907:                // determine the currently executing method by
0908:                // looking at the stack track. Hackish, but convenient.
0909:                StringWriter sw = new StringWriter();
0910:                new Exception().printStackTrace(new PrintWriter(sw));
0911:                for (StringTokenizer stackTrace = new StringTokenizer(sw
0912:                        .toString(), System.getProperty("line.separator")); stackTrace
0913:                        .hasMoreTokens();) {
0914:                    String line = stackTrace.nextToken().trim();
0915:
0916:                    // not a stack trace element
0917:                    if (!(line.startsWith("at ")))
0918:                        continue;
0919:
0920:                    String fullMethodName = line
0921:                            .substring(0, line.indexOf("("));
0922:
0923:                    String shortMethodName = fullMethodName
0924:                            .substring(fullMethodName.lastIndexOf(".") + 1);
0925:
0926:                    // skip our own methods!
0927:                    if (shortMethodName.equals("callingMethod"))
0928:                        continue;
0929:                    if (exclude != null && shortMethodName.equals(exclude))
0930:                        continue;
0931:
0932:                    return shortMethodName;
0933:                }
0934:
0935:                throw new IllegalStateException("Could not identify calling "
0936:                        + "method in stack trace");
0937:            }
0938:
0939:            //////////
0940:            // Timing
0941:            //////////
0942:
0943:            /**
0944:             * Sleep the current Thread for a random amount of time from 0-1000 ms.
0945:             */
0946:            public void sleepRandom() {
0947:                sleepRandom(1000);
0948:            }
0949:
0950:            /**
0951:             * Sleep the current Thread for a random amount of time from
0952:             * 0-<code>max</code> ms.
0953:             */
0954:            public void sleepRandom(int max) {
0955:                try {
0956:                    Thread.currentThread().sleep((long) (Math.random() * max));
0957:                } catch (InterruptedException ex) {
0958:                }
0959:            }
0960:
0961:            /**
0962:             * Re-run this method in the current thread, timing out
0963:             * after the specified number of seconds.
0964:             * Usage:
0965:             * <pre> public void timeOutOperation() { if (timeout(5 * 1000)) return;
0966:             *  Thread.currentThread().sleep(10 * 1000); }
0967:             * </pre>
0968:             * <p/>
0969:             * <p/>
0970:             * <strong>Warning</strong> this method should be used sparingly,
0971:             * and only when you expect that a timeout will <strong>not</strong>
0972:             * occur. It utilized the deprecated {@link Thread#stop()} and
0973:             * {@link Thread#interrupt} methods, which can leave monitors in an
0974:             * invalid state. It is only used because it provides more
0975:             * meaningful information than just seeing that the entire autobuild
0976:             * timed out.
0977:             *
0978:             * @param millis the number of milliseconds we should wait.
0979:             * @return true if we are are in the thread that requested the
0980:             *         timeout, false if we are in the timeout thread itself.
0981:             */
0982:            public boolean timeout(long millis) throws Throwable {
0983:                String methodName = callingMethod("timeout");
0984:                return timeout(millis, methodName);
0985:            }
0986:
0987:            /**
0988:             * @see #timeout(long)
0989:             */
0990:            public boolean timeout(long millis, String methodName)
0991:                    throws Throwable {
0992:                // we are in the timing out-thread: do nothing so the
0993:                // actual test method can run
0994:                if (inTimeoutThread)
0995:                    return false;
0996:
0997:                inTimeoutThread = true;
0998:                long endTime = System.currentTimeMillis() + millis;
0999:
1000:                try {
1001:                    final Method method = getClass().getMethod(methodName,
1002:                            (Class[]) null);
1003:                    final Object thz = this ;
1004:
1005:                    // spawn thread
1006:                    TimeOutThread tot = new TimeOutThread("TimeOutThread ["
1007:                            + methodName + "] (" + millis + "ms)") {
1008:                        public void run() {
1009:                            try {
1010:                                method.invoke(thz, (Object[]) null);
1011:                            } catch (Throwable t) {
1012:                                throwable = t;
1013:                            } finally {
1014:                                completed = true;
1015:                            }
1016:                        }
1017:                    };
1018:
1019:                    tot.start();
1020:
1021:                    // wait for the completion or a timeout to occur
1022:                    tot.join(millis);
1023:
1024:                    // have we timed out? Kill the thread and throw an exception
1025:                    if (System.currentTimeMillis() >= endTime) {
1026:                        // if we are waiting on a monitor, this will give
1027:                        // us a useful stack trace.
1028:                        try {
1029:                            tot.interrupt();
1030:                        } catch (Throwable e) {
1031:                        }
1032:                        Thread.currentThread().sleep(500);
1033:
1034:                        // try to kill the thread
1035:                        try {
1036:                            tot.stop();
1037:                        } catch (Throwable e) {
1038:                        }
1039:                        Thread.currentThread().sleep(500);
1040:
1041:                        throw new OperationTimedOutException("Execution of \""
1042:                                + methodName + "\" timed out after " + millis
1043:                                + " milliseconds", tot.throwable);
1044:                    }
1045:
1046:                    // throw any exceptions that may have occured
1047:                    if (tot.throwable != null)
1048:                        throw tot.throwable;
1049:
1050:                    // I guess everything was OK
1051:                    return true;
1052:                } finally {
1053:                    inTimeoutThread = false;
1054:                }
1055:            }
1056:
1057:            private static class TimeOutThread extends Thread {
1058:
1059:                public Throwable throwable = null;
1060:                public boolean completed = false;
1061:
1062:                public TimeOutThread(String name) {
1063:                    super (name);
1064:                    setDaemon(true);
1065:                }
1066:            }
1067:
1068:            /**
1069:             * Indicates that a timeout occured.
1070:             */
1071:            public static class OperationTimedOutException extends
1072:                    RuntimeException {
1073:
1074:                private final Throwable _err;
1075:
1076:                public OperationTimedOutException(String msg,
1077:                        Throwable throwable) {
1078:                    super (msg);
1079:                    _err = throwable;
1080:                }
1081:
1082:                public void printStackTrace() {
1083:                    printStackTrace(System.out);
1084:                }
1085:
1086:                public void printStackTrace(PrintStream out) {
1087:                    printStackTrace(new PrintWriter(out));
1088:                }
1089:
1090:                public void printStackTrace(PrintWriter out) {
1091:                    super .printStackTrace(out);
1092:                    if (_err != null) {
1093:                        out.print("Nested Throwable: ");
1094:                        _err.printStackTrace(out);
1095:                    }
1096:                }
1097:            }
1098:
1099:            ///////////////
1100:            // Collections
1101:            ///////////////
1102:
1103:            /**
1104:             * Validate that the specified {@link Collection} fulfills the
1105:             * Collection contract as specified by the Collections API.
1106:             * <p/>
1107:             * <strong>Note</strong>: does not validate mutable operations
1108:             */
1109:            public static void validateCollection(Collection collection) {
1110:                int size = collection.size();
1111:                int iterated = 0;
1112:                // ensure we can walk along the iterator
1113:                for (Iterator i = collection.iterator(); i.hasNext();) {
1114:                    iterated++;
1115:                    i.next();
1116:                }
1117:
1118:                // ensure the number of values iterated is the same as the list size
1119:                assertEquals(size, iterated);
1120:
1121:                // also validate the list
1122:                if (collection instanceof  List) {
1123:                    List ll = new ArrayList();
1124:                    for (int i = 0; i < 100; i++)
1125:                        ll.add(new Integer(i));
1126:                    validateList((List) ll);
1127:                    validateList((List) collection);
1128:                }
1129:            }
1130:
1131:            /**
1132:             * Validate that the specified {@link List} fulfills the
1133:             * List contract as specified by the Collections API.
1134:             * <p/>
1135:             * <strong>Note</strong>: does not validate mutable operations
1136:             */
1137:            public static void validateList(List list) {
1138:                Object[] coreValues = list.toArray();
1139:                Object[] values1 = new Object[list.size()];
1140:                Object[] values2 = new Object[list.size()];
1141:                Object[] values3 = new Object[list.size()];
1142:                Object[] values4 = new Object[list.size()];
1143:
1144:                // fill sequential index access list
1145:                for (int i = 0; i < list.size(); i++)
1146:                    values1[i] = list.get(i);
1147:
1148:                // fill sequential list
1149:                int index = 0;
1150:                ListIterator iter;
1151:                for (iter = list.listIterator(0); iter.hasNext();) {
1152:                    assertEquals(index, iter.nextIndex());
1153:                    assertEquals(index, iter.previousIndex() + 1);
1154:                    values2[index] = iter.next();
1155:                    assertTrue(list.contains(values2[index]));
1156:                    index++;
1157:                }
1158:
1159:                // ensure NoSuchElementException is thrown as appropriate
1160:                try {
1161:                    iter.next();
1162:                    fail("next() should have resulted in a NoSuchElementException");
1163:                } catch (NoSuchElementException e) {
1164:                } // as expected
1165:
1166:                // fill reverse sequential list
1167:                int back = 0;
1168:                for (iter = list.listIterator(list.size()); iter.hasPrevious();) {
1169:                    assertEquals(index, iter.previousIndex() + 1);
1170:                    assertEquals(index, iter.nextIndex());
1171:                    values3[--index] = iter.previous();
1172:                    back++;
1173:                }
1174:                assertEquals(list.size(), back);
1175:
1176:                // ensure NoSuchElementException is thrown as appropriate
1177:                try {
1178:                    iter.previous();
1179:                    fail("previous() should have resulted in a "
1180:                            + "NoSuchElementException");
1181:                } catch (NoSuchElementException e) {
1182:                } // as expected
1183:
1184:                // fill random access list
1185:                List indices = new LinkedList();
1186:                for (int i = 0; i < list.size(); i++)
1187:                    indices.add(new Integer(i));
1188:
1189:                for (int i = 0; i < list.size(); i++) {
1190:                    int rand = (int) (Math.random() * indices.size());
1191:                    Integer randIndex = (Integer) indices.remove(rand);
1192:                    values4[randIndex.intValue()] = list.get(randIndex
1193:                            .intValue());
1194:                }
1195:
1196:                assertEquals(Arrays.asList(coreValues), Arrays.asList(values1));
1197:                assertIdentical(Arrays.asList(coreValues), Arrays
1198:                        .asList(values1));
1199:                assertEquals(Arrays.asList(coreValues), Arrays.asList(values2));
1200:                assertIdentical(Arrays.asList(coreValues), Arrays
1201:                        .asList(values2));
1202:                assertEquals(Arrays.asList(coreValues), Arrays.asList(values4));
1203:                assertIdentical(Arrays.asList(coreValues), Arrays
1204:                        .asList(values4));
1205:                assertEquals(Arrays.asList(coreValues), Arrays.asList(values3));
1206:                assertIdentical(Arrays.asList(coreValues), Arrays
1207:                        .asList(values3));
1208:            }
1209:
1210:            /**
1211:             * Assert that the given List contain the exact same
1212:             * elements. This is different than the normal List contract, which
1213:             * states that list1.equals(list2) if each element e1.equals(e2).
1214:             * This method asserts that e1 == n2.
1215:             */
1216:            public static void assertIdentical(List c1, List c2) {
1217:                assertEquals(c1.size(), c2.size());
1218:                for (Iterator i1 = c1.iterator(), i2 = c2.iterator(); i1
1219:                        .hasNext()
1220:                        && i2.hasNext();)
1221:                    assertTrue(i1.next() == i2.next());
1222:            }
1223:
1224:            /**
1225:             * Assert that the collection parameter is already ordered
1226:             * according to the specified comparator.
1227:             */
1228:            public void assertOrdered(Collection c, Comparator comp) {
1229:                List l1 = new LinkedList(c);
1230:                List l2 = new LinkedList(c);
1231:                assertEquals(l1, l2);
1232:                Collections.sort(l2, comp);
1233:                assertEquals(l1, l2);
1234:                Collections.sort(l1, comp);
1235:                assertEquals(l1, l2);
1236:            }
1237:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.