0001: /*
0002: * Copyright 2006 Davide Deidda
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: /*
0018: * AmmentosTestSuite.java
0019: * JUnit based test
0020: *
0021: * Created on 23 aprile 2005, 8.05
0022: */
0023: package it.biobytes.ammentos.test;
0024:
0025: import junit.framework.*;
0026: import it.biobytes.ammentos.*;
0027: import it.biobytes.ammentos.query.*;
0028: import java.io.BufferedReader;
0029: import java.io.InputStreamReader;
0030: import java.sql.Connection;
0031: import java.sql.PreparedStatement;
0032: import java.util.*;
0033: import java.util.logging.*;
0034: import java.util.concurrent.*;
0035:
0036: /**
0037: *
0038: * @author davide
0039: */
0040: public class AmmentosTestSuite extends TestCase {
0041: private static final String DB_1 = "jdbc:hsqldb:data/db/ammentos";
0042: private static final String DB_2 = "jdbc:hsqldb:data/db/ammentos2";
0043:
0044: /**
0045: * Executes a query in a separate Thread
0046: */
0047: private class QueryExecutor implements Callable<List> {
0048:
0049: private Query m_query;
0050: private Class m_class;
0051:
0052: public QueryExecutor(Class c, Query q) {
0053: m_class = c;
0054: m_query = q;
0055: }
0056:
0057: public List call() {
0058: List res = null;
0059: try {
0060: res = Ammentos.load(m_class, m_query);
0061: } catch (Exception e) {
0062: System.out.println("Error in query executor: "
0063: + e.getMessage());
0064: e.printStackTrace();
0065: }
0066: return res;
0067: }
0068: }
0069:
0070: private static class QueryIterator implements Callable<Integer> {
0071: private Query m_query;
0072: private Class m_class;
0073: private static int m_instanceCounter;
0074: private int m_numInstance;
0075:
0076: public QueryIterator(Class c, Query q) {
0077: m_class = c;
0078: m_query = q;
0079: m_instanceCounter++;
0080: m_numInstance = m_instanceCounter;
0081: }
0082:
0083: public Integer call() throws Exception {
0084: int res = 0;
0085: try {
0086: for (Object obj : Ammentos.iterate(m_class, m_query)) {
0087: res++;
0088: System.out.print("Thread[");
0089: System.out.print(Integer.toString(m_numInstance));
0090: System.out.print("]:");
0091: System.out.print(Integer.toString(res));
0092: System.out.println();
0093: }
0094: } catch (Exception e) {
0095: System.out.println("Error in query iterator: "
0096: + e.getMessage());
0097: e.printStackTrace();
0098: }
0099: return res;
0100: }
0101:
0102: }
0103:
0104: private class SaveExecutor<T> implements Runnable {
0105:
0106: private T m_obj;
0107:
0108: public SaveExecutor(T obj) {
0109: m_obj = obj;
0110: }
0111:
0112: public void run() {
0113: try {
0114: Ammentos.save(m_obj);
0115: } catch (Exception e) {
0116: System.out.println("Error in save executor: "
0117: + e.getMessage());
0118: e.printStackTrace();
0119: }
0120: }
0121: }
0122:
0123: public AmmentosTestSuite() {
0124: super ("Ammentos Tests");
0125: Logger.getLogger("ammentos").setLevel(Level.OFF);
0126:
0127: }
0128:
0129: protected void setUp() throws java.lang.Exception {
0130: // Database creation
0131: prepareDatabase(DB_1);
0132: prepareDatabase(DB_2);
0133:
0134: Ammentos.setDataSource(new TestDataSource(DB_1));
0135: }
0136:
0137: /**
0138: * suite method automatically generated by JUnit module
0139: */
0140: public static junit.framework.Test suite() {
0141: junit.framework.TestSuite suite = new junit.framework.TestSuite(
0142: AmmentosTestSuite.class);
0143: //suite.addTest( new AmmentosTestSuite( "test" ) );
0144: return suite;
0145: }
0146:
0147: // TODO add test methods here. The name must begin with 'test'. For example:
0148: // public void testHello() {}
0149: public static void testNormalPersistence() {
0150: try {
0151: Person person = new Person("testPerson");
0152: person.setName("Jack");
0153: person.setSurname("Redford");
0154:
0155: // This will call insert
0156: Ammentos.save(person);
0157: // This will call update
0158: Ammentos.save(person);
0159:
0160: Person person2 = Ammentos.load(Person.class, "testPerson");
0161: assertTrue(Ammentos.diff(person, person2).isEmpty());
0162:
0163: Student student = new Student("testStudent", "testPerson2");
0164: student.setMedia(12);
0165: student.setName("John");
0166: student.setSurname("Philips");
0167:
0168: // This will call insert
0169: Ammentos.save(student);
0170: // This will call update
0171: Ammentos.save(student);
0172:
0173: Student student2 = Ammentos.load(Student.class,
0174: "testStudent");
0175: assertTrue(Ammentos.diff(student, student2).isEmpty());
0176: assertTrue("John".equals(student2.getName()));
0177: assertTrue("Philips".equals(student2.getSurname()));
0178:
0179: List<Person> people = Ammentos.load(Person.class,
0180: new Query());
0181: assertTrue((people != null) && (people.size() == 2));
0182:
0183: Ammentos.delete(student2);
0184: assertNull(Ammentos.load(Student.class, "testStudent"));
0185: assertNull(Ammentos.load(Person.class, "testPerson2"));
0186:
0187: Ammentos.delete(person);
0188:
0189: assertNull(Ammentos.load(Person.class, "testPerson"));
0190: } catch (Exception e) {
0191: fail("Exception: " + e.getMessage() + " - " + " - "
0192: + e.getStackTrace()[0] + " - "
0193: + e.getStackTrace()[1] + " - "
0194: + e.getStackTrace()[2] + " - "
0195: + e.getStackTrace()[3] + " - "
0196: + e.getStackTrace()[4]);
0197: System.err.println("********");
0198: e.printStackTrace();
0199: System.err.println("********");
0200: }
0201: }
0202:
0203: public void testInheritance() {
0204: try {
0205: DegreedStudent ds = new DegreedStudent("degreedStudent",
0206: "testPerson3");
0207: ds.setDegreeDate(new java.util.Date());
0208: ds.setName("Edward");
0209: ds.setSurname("Collins");
0210: ds.setMedia(25);
0211: Ammentos.save(ds);
0212: Query qry = new Query();
0213:
0214: assertTrue(Ammentos.load(DegreedStudent.class, qry).size() == 1);
0215: assertTrue(Ammentos.load(Student.class, qry).size() == 1);
0216: assertTrue(Ammentos.load(Person.class, qry).size() == 1);
0217:
0218: DegreedStudent ds2 = Ammentos.load(DegreedStudent.class,
0219: qry).get(0);
0220: assertTrue("Edward".equals(ds2.getName()));
0221: assertTrue("Collins".equals(ds2.getSurname()));
0222:
0223: Ammentos.delete(ds);
0224:
0225: assertTrue(Ammentos.load(DegreedStudent.class, qry).size() == 0);
0226: assertTrue(Ammentos.load(Student.class, qry).size() == 0);
0227: assertTrue(Ammentos.load(Person.class, qry).size() == 0);
0228:
0229: } catch (Exception e) {
0230: fail("Exception: " + e.getMessage());
0231: e.printStackTrace();
0232: }
0233: }
0234:
0235: public void testTransactions() {
0236: try {
0237: Ammentos.openTransaction();
0238: DegreedStudent ds = new DegreedStudent("degreedStudent",
0239: "testPerson3");
0240: ds.setDegreeDate(new java.util.Date());
0241: ds.setName("Edward");
0242: ds.setSurname("Collins");
0243: ds.setMedia(25);
0244: Ammentos.save(ds);
0245:
0246: Person person = new Person("testPerson");
0247: person.setName("Steve");
0248: person.setSurname("Andrews");
0249: Ammentos.save(person);
0250:
0251: Query qry = new Query();
0252:
0253: assertTrue(Ammentos.load(DegreedStudent.class, qry).size() == 1);
0254: assertTrue(Ammentos.load(Student.class, qry).size() == 1);
0255: assertTrue(Ammentos.load(Person.class, qry).size() == 2);
0256:
0257: Ammentos.rollbackTransaction();
0258:
0259: assertTrue(Ammentos.load(DegreedStudent.class, qry).size() == 0);
0260: assertTrue(Ammentos.load(Student.class, qry).size() == 0);
0261: assertTrue(Ammentos.load(Person.class, qry).size() == 0);
0262: } catch (Exception e) {
0263: try {
0264: Ammentos.rollbackTransaction();
0265: } catch (Exception ex) {
0266: }
0267: fail("Exception: " + e.getMessage());
0268: e.printStackTrace();
0269: }
0270: }
0271:
0272: public void testConcurrency() {
0273:
0274: Query qry = new Query();
0275: QueryExecutor qe = new QueryExecutor(Person.class, qry);
0276: FutureTask<List> queryTask = new FutureTask<List>(qe);
0277:
0278: Person sePerson = new Person("ProvaPersona");
0279: sePerson.setName("Davide");
0280: sePerson.setSurname("Deidda");
0281: SaveExecutor se = new SaveExecutor<Person>(sePerson);
0282:
0283: try {
0284: Ammentos.openTransaction();
0285: Person person = new Person("testPerson");
0286: person.setName("Alan");
0287: person.setSurname("Ford");
0288: Ammentos.save(person);
0289:
0290: // This thread should see into the current transaction
0291: assertTrue(Ammentos.load(Person.class, qry).size() == 1);
0292:
0293: // This new Thread should save its object out of the previous transaction
0294: Thread saveThread = new Thread(se);
0295: saveThread.start();
0296:
0297: // The query starts in a new Thread. This new thread should not see
0298: // into the opened transaction
0299: Thread queryThread = new Thread(queryTask);
0300: queryThread.start();
0301:
0302: //Waiting for threads to complete execution
0303: queryThread.join();
0304: saveThread.join();
0305:
0306: // The isolation level for this transaction is READ_UNCOMMITTED, so inserted
0307: // data can be read (NB: it's a *dirty* read)
0308: assertTrue(queryTask.get().size() == 2);
0309:
0310: Ammentos.rollbackTransaction();
0311:
0312: // Once the transaction has been rolled back, the person inserted from
0313: // the separated thread should still be present
0314: assertTrue(Ammentos.load(Person.class, qry).size() == 1);
0315:
0316: // Removing sePerson
0317: Ammentos.delete(sePerson);
0318: assertTrue(Ammentos.load(Person.class, qry).size() == 0);
0319: } catch (Exception e) {
0320: e.printStackTrace();
0321: fail("Exception: " + e.getMessage());
0322: } finally {
0323: try {
0324: Ammentos.rollbackTransaction();
0325: } catch (Exception ex) {
0326: }
0327: }
0328: }
0329:
0330: public void testConcurrentIteration() throws PersistenceException {
0331: final int TESTNUMBER = 5000;
0332: for (int i = 0; i < TESTNUMBER; i++) {
0333: Ammentos.save(new Person("person_" + i, "name_" + i,
0334: "surname_" + i));
0335: }
0336:
0337: try {
0338: Query qry = new Query();
0339: QueryIterator qe1 = new QueryIterator(Person.class, qry);
0340: QueryIterator qe2 = new QueryIterator(Person.class, qry);
0341: QueryIterator qe3 = new QueryIterator(Person.class, qry);
0342: QueryIterator qe4 = new QueryIterator(Person.class, qry);
0343: FutureTask<Integer> queryTask1 = new FutureTask<Integer>(
0344: qe1);
0345: FutureTask<Integer> queryTask2 = new FutureTask<Integer>(
0346: qe2);
0347: FutureTask<Integer> queryTask3 = new FutureTask<Integer>(
0348: qe3);
0349:
0350: Thread thread1 = new Thread(queryTask1);
0351: Thread thread2 = new Thread(queryTask2);
0352: Thread thread3 = new Thread(queryTask3);
0353: thread1.start();
0354: thread2.start();
0355: thread3.start();
0356:
0357: assertTrue(thread3.isAlive());
0358: assertTrue(thread2.isAlive());
0359: assertTrue(thread1.isAlive());
0360:
0361: Integer res1 = queryTask1.get();
0362: Integer res2 = queryTask2.get();
0363: Integer res3 = queryTask3.get();
0364:
0365: assertNotNull(res1);
0366: assertTrue(res1 == TESTNUMBER);
0367: assertNotNull(res2);
0368: assertTrue(res2 == TESTNUMBER);
0369: assertNotNull(res3);
0370: assertTrue(res3 == TESTNUMBER);
0371: } catch (InterruptedException ex) {
0372: Logger.getLogger(AmmentosTestSuite.class.getName()).log(
0373: Level.SEVERE, null, ex);
0374: } catch (ExecutionException ex) {
0375: Logger.getLogger(AmmentosTestSuite.class.getName()).log(
0376: Level.SEVERE, null, ex);
0377: }
0378: }
0379:
0380: public void testValidation() {
0381: try {
0382: Ammentos.openTransaction();
0383: Student student = new Student("testStudent", "testPerson");
0384:
0385: // NB: the name starts whith a digit and so is illegal. Validator of
0386: // person should trap this
0387: student.setName("3Marc");
0388: student.setSurname("Morrison");
0389:
0390: try {
0391: Ammentos.save(student);
0392: fail("Validators are not working properly");
0393: } catch (Exception e) {
0394: // This is ok
0395: }
0396: } catch (Exception e) {
0397: e.printStackTrace();
0398: fail("Exception: " + e.getMessage());
0399: } finally {
0400: try {
0401: Ammentos.rollbackTransaction();
0402: } catch (Exception ex) {
0403: }
0404: }
0405: }
0406:
0407: public void testRelation() {
0408: try {
0409: Ammentos.openTransaction();
0410:
0411: Teacher teacher = new Teacher("testPerson");
0412: teacher.setName("William");
0413: teacher.setSurname("Barkley");
0414: Ammentos.save(teacher);
0415:
0416: Course course = new Course("economy");
0417: course.setDescription("Course of economy");
0418: course.setTeacher(teacher);
0419: Ammentos.save(course);
0420:
0421: Course course2 = Ammentos.lookup(Course.class, "economy");
0422: assertNotNull(course2.getTeacher());
0423: assertTrue(Ammentos.diff(teacher, course2.getTeacher())
0424: .size() == 0);
0425:
0426: course = new Course("physics");
0427: course.setDescription("Course of physics");
0428: course.setTeacher(null);
0429: Ammentos.save(course);
0430:
0431: course2 = Ammentos.lookup(Course.class, "physics");
0432: assertNull(course2.getTeacher());
0433: assertTrue(Ammentos.diff(course, course2).size() == 0);
0434:
0435: } catch (Exception e) {
0436: e.printStackTrace();
0437: fail("Exception: " + e.getMessage());
0438: } finally {
0439: try {
0440: Ammentos.rollbackTransaction();
0441: } catch (Exception ex) {
0442: }
0443: }
0444: }
0445:
0446: public void testQueries() {
0447: try {
0448: Ammentos.openTransaction();
0449:
0450: Person person = new Person("testPerson");
0451: person.setName("Alan");
0452: person.setSurname("Ford");
0453: Ammentos.save(person);
0454:
0455: Person person2 = new Person("testPerson2");
0456: person2.setName("Alan");
0457: person2.setSurname("Stevens");
0458: Ammentos.save(person2);
0459:
0460: Query qry = new Query();
0461: qry
0462: .setDomain("(select * from people where id='testPerson') as bo");
0463: ((SimpleQueryFilter) qry.appendFilter("id"))
0464: .setString("testPerson");
0465: List<Person> lp = Ammentos.load(Person.class, qry);
0466: assertTrue(lp.size() == 1);
0467: assertTrue(Ammentos.diff(lp.get(0), person).size() == 0);
0468:
0469: qry = new Query();
0470: qry
0471: .setDomain("(select * from people where id='testPerson2') as bo");
0472: ((SimpleQueryFilter) qry.appendFilter("id"))
0473: .setString("testPerson");
0474:
0475: lp = Ammentos.load(Person.class, qry);
0476: assertTrue(lp.size() == 0);
0477:
0478: // complex query
0479: qry = new Query();
0480: SimpleQueryFilter sqf = new SimpleQueryFilter("name");
0481: sqf.setString("Alan");
0482: qry.appendFilter(sqf);
0483: CompositeQueryFilter cqf = new CompositeQueryFilter();
0484: sqf = new SimpleQueryFilter("surname");
0485: sqf.setString("Stevens");
0486: cqf.addFilter(sqf);
0487:
0488: sqf = new SimpleQueryFilter(QueryFilter.APP_OR, "surname");
0489: sqf.setString("Ford");
0490: cqf.addFilter(sqf);
0491: qry.appendFilter(cqf);
0492:
0493: // System.out.println( "Query: " + qry.getSql() );
0494:
0495: lp = Ammentos.load(Person.class, qry);
0496: assertTrue(lp.size() == 2);
0497:
0498: // Query whith sql fields
0499: qry = new Query();
0500: SqlQueryFilter sqlqf = new SqlQueryFilter(
0501: "name=? and surname=?");
0502: sqlqf.setString("Alan");
0503: sqlqf.setString("Ford");
0504: qry.appendFilter(sqlqf);
0505: sqf = new SimpleQueryFilter("id");
0506: sqf.setString("testPerson");
0507: qry.appendFilter(sqf);
0508:
0509: // System.out.println( "Query: " + qry.getSql() );
0510:
0511: lp = Ammentos.load(Person.class, qry);
0512: assertTrue(lp.size() == 1);
0513: assertTrue(Ammentos.diff(lp.get(0), person).size() == 0);
0514:
0515: // Test short query
0516: sqlqf = new SqlQueryFilter("name=? and surname=?");
0517: sqlqf.setString("Alan");
0518: sqlqf.setString("Ford");
0519: lp = Ammentos.load(Person.class, new Query(sqlqf));
0520: assertTrue(lp.size() == 1);
0521: assertTrue(Ammentos.diff(lp.get(0), person).size() == 0);
0522:
0523: } catch (Exception e) {
0524: e.printStackTrace();
0525: fail("Exception: " + e.getMessage());
0526: } finally {
0527: try {
0528: Ammentos.rollbackTransaction();
0529: } catch (Exception ex) {
0530: }
0531: }
0532: }
0533:
0534: public void testUpdatableLists() {
0535: try {
0536: Ammentos.openTransaction();
0537: Person person = new Person("testPerson");
0538: person.setName("Alan");
0539: person.setSurname("Ford");
0540: Ammentos.save(person);
0541:
0542: person = new Person("testPerson2");
0543: person.setName("Steve");
0544: person.setSurname("Smith");
0545: Ammentos.save(person);
0546:
0547: List<Person> lp = Ammentos.loadUpdatable(Person.class,
0548: new Query());
0549:
0550: assertTrue(lp.size() == 2);
0551: // This will call delete
0552: lp.remove(0);
0553:
0554: List<Person> lp2 = Ammentos.load(Person.class, new Query());
0555: assertTrue(lp2.size() == 1);
0556: person = new Person("testPerson3");
0557: person.setName("Alex");
0558: person.setSurname("Johnson");
0559: // This will call save
0560: lp.add(person);
0561:
0562: lp2 = Ammentos.load(Person.class, new Query());
0563: assertTrue(lp2.size() == 2);
0564: } catch (Exception e) {
0565: e.printStackTrace();
0566: fail("Exception: " + e.getMessage());
0567: } finally {
0568: try {
0569: Ammentos.rollbackTransaction();
0570: } catch (Exception ex) {
0571: }
0572: }
0573: }
0574:
0575: public void testDiff() {
0576: Student s1 = new Student("testStudent", "testPerson");
0577: Student s2 = new Student("testStudent", "testPerson");
0578:
0579: s1.setName("David");
0580: try {
0581: assertTrue(Ammentos.diff(s1, s2).size() == 1);
0582: } catch (Exception e) {
0583: fail("Exception: " + e.getMessage());
0584: }
0585: }
0586:
0587: public void testEntityList() {
0588: Teacher teacher = null;
0589: Course course1 = null;
0590: Course course2 = null;
0591: try {
0592: teacher = new Teacher("Test_Teacher");
0593: teacher.setName("Best");
0594: teacher.setSurname("Teacher");
0595:
0596: course1 = new Course("Course1");
0597: course2 = new Course("Course2");
0598:
0599: teacher.addCourse(course1);
0600: teacher.addCourse(course2);
0601: Ammentos.save(teacher);
0602:
0603: assertTrue(teacher.getCoursesCount() == 2);
0604:
0605: // Test with lookup
0606: System.out.println("LOADING TEACHER...");
0607: Teacher loadedTeacher = Ammentos.load(Teacher.class,
0608: "Test_Teacher");
0609: assertTrue(loadedTeacher.getCoursesCount() == 2);
0610:
0611: System.out.println("TEACHER LOADED ****");
0612: assertTrue(Ammentos.load(Course.class, "Course1") != null);
0613: assertTrue(Ammentos.load(Course.class, "Course2") != null);
0614:
0615: // Test with query
0616: SqlQueryFilter sql = new SqlQueryFilter("id=?");
0617: sql.setObject(teacher, FieldTypeEnum.ENTITY.getFieldType());
0618: List<Teacher> teachers = Ammentos.load(Teacher.class,
0619: new Query(sql));
0620: assertTrue(teachers.get(0).getCoursesCount() == 2);
0621:
0622: // This new save should correctly update courses
0623: Ammentos.save(teacher);
0624:
0625: // Test deleteOnRemove
0626: teacher.removeCourse(course1);
0627: Ammentos.save(teacher);
0628:
0629: loadedTeacher = Ammentos
0630: .load(Teacher.class, "Test_Teacher");
0631: System.out.println("courses: "
0632: + loadedTeacher.getCoursesCount());
0633: assertTrue(loadedTeacher.getCoursesCount() == 1);
0634:
0635: // testing removing objects on loaded object
0636: loadedTeacher.removeCourse(loadedTeacher.getCourses()
0637: .get(0));
0638: Ammentos.save(loadedTeacher);
0639: loadedTeacher = Ammentos
0640: .load(Teacher.class, "Test_Teacher");
0641: assertTrue(loadedTeacher.getCoursesCount() == 0);
0642:
0643: Ammentos.delete(loadedTeacher);
0644:
0645: assertTrue(Ammentos.load(Course.class, "Course1") == null);
0646: assertTrue(Ammentos.load(Course.class, "Course2") == null);
0647: } catch (Exception e) {
0648: e.printStackTrace();
0649: fail(e.getMessage());
0650: } finally {
0651:
0652: try {
0653: Ammentos.delete(teacher);
0654: } catch (Exception e) {
0655: }
0656: ;
0657: }
0658: }
0659:
0660: public void testEntityMap() {
0661: Student student = null;
0662: Course course1 = null;
0663: Course course2 = null;
0664: try {
0665: student = new Student("testMapStudent", "testMapPerson");
0666: student.setName("Oliver");
0667: student.setSurname("Knives");
0668:
0669: course1 = new Course("course1");
0670: course2 = new Course("course2");
0671:
0672: Ammentos.save(course1);
0673: Ammentos.save(course2);
0674:
0675: student.setMark(course1, 4.0f);
0676: student.setMark(course2, 7.0f);
0677: Ammentos.save(student);
0678:
0679: Student loadedStudent = Ammentos.lookup(Student.class,
0680: "testMapStudent");
0681: assertTrue(loadedStudent.getMarks().size() == 2);
0682: assertTrue(loadedStudent.getMark(course1) == 4.0f);
0683: assertTrue(loadedStudent.getMark(course2) == 7.0f);
0684:
0685: // Testing float values
0686: assertTrue(loadedStudent.getFloatMark(course2) == 7.0f);
0687:
0688: loadedStudent.removeMark(course1);
0689: Ammentos.save(loadedStudent);
0690:
0691: loadedStudent = Ammentos.lookup(Student.class,
0692: "testMapStudent");
0693: assertTrue(loadedStudent.getMarks().size() == 1);
0694: assertTrue(loadedStudent.getMark(course2) == 7.0f);
0695:
0696: } catch (Exception e) {
0697: e.printStackTrace();
0698: fail("Error testing maps");
0699: } finally {
0700: try {
0701: Ammentos.delete(student);
0702: } catch (Exception e) {
0703: }
0704: try {
0705: Ammentos.delete(course1);
0706: } catch (Exception e) {
0707: }
0708: try {
0709: Ammentos.delete(course2);
0710: } catch (Exception e) {
0711: }
0712: }
0713: }
0714:
0715: public void testEntityListCircularReferences() {
0716: Person person1 = new Person("TestPerson1");
0717: Person person2 = new Person("TestPerson2");
0718:
0719: person1.setName("TestPerson1_name");
0720: person1.setSurname("TestPerson1_surname");
0721:
0722: person2.setName("TestPerson2_name");
0723: person2.setSurname("TestPerson2_surname");
0724:
0725: person1.setBestFriendFor(person2);
0726: person2.setBestFriendFor(person1);
0727:
0728: try {
0729: Ammentos.save(person1);
0730: Ammentos.save(person2);
0731: assertTrue(true);
0732:
0733: Person loaded_person1 = Ammentos.load(Person.class,
0734: "TestPerson1");
0735: loaded_person1.countBestFriends();
0736: Ammentos.save(loaded_person1);
0737:
0738: assertTrue(true);
0739:
0740: } catch (Exception e) {
0741: fail();
0742: } finally {
0743: try {
0744: Ammentos.delete(person1);
0745: } catch (Exception e) {
0746: }
0747: try {
0748: Ammentos.delete(person2);
0749: } catch (Exception e) {
0750: }
0751: }
0752: }
0753:
0754: public void testClearAll() {
0755: try {
0756: // Creating 22 students
0757: for (int i = 0; i < 22; i++) {
0758: Student s = new Student("testStudent_" + i,
0759: "testPerson_" + i);
0760: s.setName("name_" + i);
0761: s.setSurname("surname_" + i);
0762: Ammentos.save(s);
0763: }
0764:
0765: // Creating filter for students LIKE 'testStudent%'
0766: SqlQueryFilter filter = new SqlQueryFilter("code LIKE ?");
0767: filter.setString("testStudent_%");
0768:
0769: // First ensuring there's actually 22 students matching the filter
0770: assertTrue(Ammentos.load(Student.class, new Query(filter))
0771: .size() == 22);
0772:
0773: // Deleting all students matching the filter
0774: Ammentos.delete(Student.class, filter);
0775:
0776: // Ensuring all 22 students have been deleted
0777: assertTrue(Ammentos.load(Student.class, new Query(filter))
0778: .size() == 0);
0779: } catch (Exception e) {
0780: fail("Exception: " + e.getMessage());
0781: }
0782: }
0783:
0784: public void testMetadata() {
0785: try {
0786: assertTrue(Ammentos.getMetadata(RedHeadedStudent.class) == Ammentos
0787: .getMetadata(DegreedStudent.class));
0788: assertTrue(Ammentos
0789: .getPrimaryKeyField(RedHeadedStudent.class) == Ammentos
0790: .getPrimaryKeyField(DegreedStudent.class));
0791: } catch (Exception e) {
0792: fail("Exception: " + e.getMessage());
0793: }
0794: }
0795:
0796: public void testExtraContext() {
0797: PersistenceContext context = Ammentos
0798: .createContext(new TestDataSource());
0799: try {
0800: // Creating 22 students
0801: for (int i = 0; i < 22; i++) {
0802: Student s = new Student("testStudent_" + i,
0803: "testPerson_" + i);
0804: s.setName("name_" + i);
0805: s.setSurname("surname_" + i);
0806: context.save(s);
0807: }
0808:
0809: // Creating filter for students LIKE 'testStudent%'
0810: SqlQueryFilter filter = new SqlQueryFilter("code LIKE ?");
0811: filter.setString("testStudent_%");
0812:
0813: // First ensuring there's actually 22 students matching the filter
0814: assertTrue(context.load(Student.class, new Query(filter))
0815: .size() == 22);
0816:
0817: // Deleting all students matching the filter
0818: context.delete(Student.class, filter);
0819:
0820: // Ensuring all 22 students have been deleted
0821: assertTrue(context.load(Student.class, new Query(filter))
0822: .size() == 0);
0823: } catch (Exception e) {
0824: fail("Exception: " + e.getMessage());
0825: }
0826: }
0827:
0828: public void testConcurrentContextes() {
0829: PersistenceContext context = Ammentos
0830: .createContext(new TestDataSource(DB_1));
0831: PersistenceContext context2 = Ammentos
0832: .createContext(new TestDataSource(DB_2));
0833: try {
0834: // Creating a student in context 1
0835: Student s = new Student("testStudent", "testPerson");
0836: s.setName("name");
0837: s.setSurname("surname");
0838: context.save(s);
0839:
0840: // Loading student from context 1
0841: s = context.load(Student.class, "testStudent");
0842:
0843: // Saving student in context 2
0844: context2.save(s);
0845:
0846: // Diff
0847: assertTrue(Ammentos.diff(s,
0848: context2.load(Student.class, "testStudent")).size() == 0);
0849: } catch (Exception e) {
0850: fail("Exception: " + e.getMessage());
0851: }
0852: }
0853:
0854: public void testConcurrentContextTransactions() {
0855: PersistenceContext context = Ammentos
0856: .createContext(new TestDataSource(DB_1));
0857: PersistenceContext context2 = Ammentos
0858: .createContext(new TestDataSource(DB_2));
0859: try {
0860: // Creating a student in context 1
0861: Student s = new Student("testStudent", "testPerson");
0862: s.setName("name");
0863: s.setSurname("surname");
0864: context.save(s);
0865:
0866: // Loading student from context 1
0867: s = context.load(Student.class, "testStudent");
0868:
0869: // Saving student in context 2
0870: context2.save(s);
0871:
0872: // Diff
0873: assertTrue(Ammentos.diff(s,
0874: context2.load(Student.class, "testStudent")).size() == 0);
0875:
0876: // Opens transaction in context 1
0877: context.openTransaction();
0878: context.delete(s);
0879:
0880: // Student should not exist in context 1
0881: assertTrue(context.load(Student.class, "testStudent") == null);
0882:
0883: // Student should still exist in context 2
0884: assertTrue(context2.load(Student.class, "testStudent") != null);
0885:
0886: // Transaction is rolled back
0887: context.rollbackTransaction();
0888: assertTrue(context.load(Student.class, "testStudent") != null);
0889:
0890: } catch (Exception e) {
0891: fail("Exception: " + e.getMessage());
0892: }
0893: }
0894:
0895: private void prepareDatabase(String uri) throws Exception {
0896: System.out.println("Preparing database " + uri);
0897: Ammentos.setDataSource(new TestDataSource(uri));
0898: BufferedReader reader = new BufferedReader(
0899: new InputStreamReader(ClassLoader
0900: .getSystemResourceAsStream("test.sql")));
0901: StringBuilder sql = new StringBuilder();
0902: String line = null;
0903: while ((line = reader.readLine()) != null) {
0904: sql.append(line);
0905: }
0906: reader.close();
0907:
0908: Connection conn = Ammentos.getDbConnection();
0909: PreparedStatement pstmt = conn.prepareStatement(sql.toString());
0910: pstmt.execute();
0911: conn.close();
0912: System.out.println("Database " + uri + " prepared");
0913: }
0914:
0915: public void testIterate() throws Exception {
0916: final int numStudents = 10000;
0917: // Creating 1000 students
0918: for (int i = 0; i < numStudents; i++) {
0919: Student s = new Student("testStudent_" + i, "testPerson_"
0920: + i);
0921: s.setName("name_" + i);
0922: s.setSurname("surname_" + i);
0923: Ammentos.save(s);
0924: }
0925:
0926: int count = 0;
0927: for (Student s : Ammentos.iterate(Student.class, new Query())) {
0928: count++;
0929: }
0930:
0931: assertTrue(count == numStudents);
0932:
0933: // Testing framework behavior: call below should throw an exception
0934: boolean exceptionThrown = false;
0935: try {
0936: count = 0;
0937: for (Student s : Ammentos.iterate(Student.class,
0938: new Query())) {
0939: count++;
0940: }
0941: } catch (Exception e) {
0942: exceptionThrown = true;
0943: }
0944:
0945: assertTrue(exceptionThrown);
0946:
0947: // Now calling closeIteration should allow call below
0948: Ammentos.closeIteration();
0949:
0950: exceptionThrown = false;
0951: try {
0952: count = 0;
0953: for (Student s : Ammentos.iterate(Student.class,
0954: new Query())) {
0955: count++;
0956: }
0957: } catch (Exception e) {
0958: exceptionThrown = true;
0959: }
0960:
0961: assertTrue(!exceptionThrown);
0962:
0963: // A try with a different context
0964: PersistenceContext context = Ammentos
0965: .createContext(new TestDataSource(DB_2));
0966: for (int i = 0; i < numStudents; i++) {
0967: Student s = new Student("testStudent_" + i, "testPerson_"
0968: + i);
0969: s.setName("name_" + i);
0970: s.setSurname("surname_" + i);
0971: context.save(s);
0972: }
0973:
0974: count = 0;
0975: for (Student s : context.iterate(Student.class, new Query())) {
0976: count++;
0977: }
0978:
0979: assertTrue(count == numStudents);
0980: Ammentos.closeIteration();
0981: }
0982:
0983: public void testMultipleKeys() {
0984: try {
0985:
0986: Teacher t = new Teacher("teacher_1");
0987: t.setName("name");
0988: t.setSurname("surname");
0989: Ammentos.save(t);
0990:
0991: Course c = new Course("course_1");
0992: Ammentos.save(c);
0993:
0994: Lesson l = new Lesson(t, c);
0995: l.setTopic("description_1");
0996: Ammentos.save(l);
0997:
0998: // This will cause update
0999: l.setTopic("description_2");
1000:
1001: Ammentos.save(l);
1002:
1003: // Normal query loading
1004: SqlQueryFilter sql = new SqlQueryFilter(
1005: "teacher_id=? and course_id=?");
1006: sql.setObject(t, FieldTypeEnum.ENTITY.getFieldType());
1007: sql.setObject(c, FieldTypeEnum.ENTITY.getFieldType());
1008: Lesson l2 = Ammentos.load(Lesson.class, sql).get(0);
1009:
1010: // Asserts loading successful
1011: assertTrue(Ammentos.diff(l, l2).size() == 0);
1012:
1013: // Loading with enhanced load method
1014: Lesson l3 = Ammentos.load(Lesson.class, t, c);
1015:
1016: // Asserts loading successful
1017: assertTrue(Ammentos.diff(l, l3).size() == 0);
1018:
1019: Ammentos.delete(l);
1020: assertTrue(Ammentos.load(Lesson.class, t, c) == null);
1021: } catch (Exception persistenceException) {
1022: persistenceException.printStackTrace();
1023: fail();
1024: }
1025: }
1026:
1027: public void testLoadEmptyTables() {
1028: try {
1029: List<Person> people = Ammentos.load(Person.class,
1030: new Query());
1031: for (Person p : people) {
1032: System.out.println("p: " + p.getName());
1033: }
1034: // If this test causes no exception all is ok
1035: assert (true);
1036: } catch (PersistenceException ex) {
1037: fail("PersistenceException: " + ex.getMessage());
1038: } catch (Exception e) {
1039: fail("Exception: " + e.getMessage());
1040: }
1041: }
1042:
1043: public void testHandlers() {
1044: try {
1045: HandledPerson p = new HandledPerson("handledPerson");
1046: p.setName("a");
1047: p.setSurname("b");
1048:
1049: Ammentos.save(p);
1050: System.out.println("handler log: " + p.getHandlerLog());
1051: assertTrue(p.getHandlerLog()
1052: .equals("BEFORE_SAVEAFTER_SAVE"));
1053: HandledPerson p2 = Ammentos.lookup(HandledPerson.class,
1054: "handledPerson");
1055: assertTrue(p2.getHandlerLog().equals("ON_LOAD"));
1056: Ammentos.delete(p);
1057: assertTrue(p.getHandlerLog().equals(
1058: "BEFORE_SAVEAFTER_SAVEBEFORE_DELETEAFTER_DELETE"));
1059:
1060: // Test with iterators
1061: Ammentos.save(p);
1062: Iterable<HandledPerson> people = Ammentos.iterate(
1063: HandledPerson.class, new Query());
1064: assertTrue(people != null);
1065:
1066: int num = 0;
1067: for (HandledPerson person : people) {
1068: num++;
1069: assertTrue(person.getHandlerLog().equals("ON_LOAD"));
1070: }
1071: assertTrue(num == 1);
1072:
1073: List<HandledPerson> peopleList = Ammentos.load(
1074: HandledPerson.class, new Query());
1075: assertTrue(peopleList != null && peopleList.size() == 1);
1076: for (HandledPerson person : peopleList) {
1077: assertTrue(person.getHandlerLog().equals("ON_LOAD"));
1078: }
1079: } catch (Exception e) {
1080: e.printStackTrace();
1081: fail("Exception: " + e.getMessage());
1082: }
1083: }
1084:
1085: public void testCount() throws PersistenceException {
1086: for (int i = 0; i < 2546; i++) {
1087: Ammentos.save(new Person("person" + i, "name" + i,
1088: "surname" + i));
1089: }
1090:
1091: System.out.println("count: "
1092: + Ammentos.count(Person.class, new Query()));
1093: assertTrue(Ammentos.count(Person.class, new Query()) == 2546);
1094: SqlQueryFilter filter = new SqlQueryFilter(
1095: "name=? or surname=?");
1096: filter.setString("name100");
1097: filter.setString("surname200");
1098: assertTrue(Ammentos.count(Person.class, filter) == 2);
1099: }
1100:
1101: public void testLoadUnique() throws PersistenceException {
1102: Person p1 = new Person("person1", "name1", "surname1");
1103: Person p2 = new Person("person2", "name2", "surname1");
1104:
1105: Ammentos.save(p1);
1106: Ammentos.save(p2);
1107:
1108: // Looking for p1
1109: SqlQueryFilter qry = new SqlQueryFilter("name=? and surname=?");
1110: qry.setString("name1");
1111: qry.setString("surname1");
1112: Person loadedP1 = Ammentos.loadUnique(Person.class, qry);
1113: assertNotNull(loadedP1);
1114: assertTrue(Ammentos.diff(p1, loadedP1).size() == 0);
1115:
1116: // Query with null result
1117: qry = new SqlQueryFilter("name=? and surname=?");
1118: qry.setString("name2");
1119: qry.setString("surname2");
1120: Person nullPerson = Ammentos.loadUnique(Person.class, qry);
1121: assertNull(nullPerson);
1122:
1123: // Query with ambiguous result
1124: qry = new SqlQueryFilter("surname=?");
1125: qry.setString("surname1");
1126: try {
1127: Person ambiguousPerson = Ammentos.loadUnique(Person.class,
1128: qry);
1129: fail("not unique exception should have been thrown");
1130: } catch (PersistenceException ex) {
1131: // this exception must be thrown
1132: }
1133: }
1134:
1135: public void testConcurrentContextCaches()
1136: throws PersistenceException {
1137: PersistenceContext context1 = Ammentos
1138: .createContext(new TestDataSource(DB_1));
1139: PersistenceContext context2 = Ammentos
1140: .createContext(new TestDataSource(DB_2));
1141:
1142: // Saving the object only in context1: context2 must not contain the object
1143: // in cache
1144: Person testPerson = new Person("testPerson", "name", "surname");
1145: context1.save(testPerson);
1146: Person lookupPerson1 = context1.lookup(Person.class, testPerson
1147: .getId());
1148: Person lookupPerson2 = context2.lookup(Person.class, testPerson
1149: .getId());
1150: assertNotNull(lookupPerson1);
1151: assertTrue(Ammentos.diff(testPerson, lookupPerson1).size() == 0);
1152: assertNull(lookupPerson2);
1153:
1154: // Now saving the object in context2: the context must now store the object
1155: // in the cache at lookup call, but the object must not be the same as that
1156: // one in context1
1157: context2.save(testPerson);
1158: lookupPerson2 = context2.lookup(Person.class, testPerson
1159: .getId());
1160: assertNotNull(lookupPerson2);
1161: assertTrue(Ammentos.diff(lookupPerson1, lookupPerson2).size() == 0);
1162: assertNotSame(lookupPerson1, lookupPerson2);
1163: }
1164: }
|