/* * Copyright 2009-2016 Tilmann Zaeschke. All rights reserved. * * This file is part of ZooDB. * * ZooDB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ZooDB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ZooDB. If not, see <http://www.gnu.org/licenses/>. * * See the README and COPYING files for further information. */ package org.zoodb.test.jdo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Arrays; import java.util.HashSet; import javax.jdo.JDOHelper; import javax.jdo.JDOObjectNotFoundException; import javax.jdo.JDOOptimisticVerificationException; import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManagerFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.zoodb.internal.server.DiskAccessOneFile; import org.zoodb.jdo.ZooJdoHelper; import org.zoodb.jdo.ZooJdoProperties; import org.zoodb.schema.ZooClass; import org.zoodb.schema.ZooHandle; import org.zoodb.schema.ZooSchema; import org.zoodb.test.api.TestSuper; import org.zoodb.test.testutil.TestTools; import org.zoodb.tools.DBStatistics; import org.zoodb.tools.DBStatistics.STATS; public class Test_023_GenericObjects { @Before public void setUp() { DiskAccessOneFile.allowReadConcurrency(true); TestTools.removeDb(); TestTools.createDb(); } @After public void tearDown() { DiskAccessOneFile.allowReadConcurrency(false); TestTools.removeDb(); } @Test public void testCommitFailGenericObjects() { ZooJdoProperties props = new ZooJdoProperties(TestTools.getDbName()); PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); TestTools.defineSchema(TestSuper.class); PersistenceManager pm1 = pmf.getPersistenceManager(); PersistenceManager pm2 = pmf.getPersistenceManager(); pm1.currentTransaction().begin(); pm2.currentTransaction().begin(); ZooSchema s1 = ZooJdoHelper.schema(pm1); ZooClass c1 = s1.getClass(TestSuper.class.getName()); ZooSchema s2 = ZooJdoHelper.schema(pm2); //new TestSuper(1, 11, null); ZooHandle t11 = c1.newInstance(); t11.setValue("_time", 1L); t11.setValue("_id", 11L); ZooHandle t12 = c1.newInstance(); t12.setValue("_time", 2L); t12.setValue("_id", 22L); ZooHandle t13 = c1.newInstance(); t13.setValue("_time", 3L); t13.setValue("_id", 33L); ZooHandle t14 = c1.newInstance(); t14.setValue("_time", 4L); t14.setValue("_id", 44L); ZooHandle t15 = c1.newInstance(); t15.setValue("_time", 5L); t15.setValue("_id", 55L); long oid1 = t11.getOid(); long oid2 = t12.getOid(); long oid3 = t13.getOid(); long oid4 = t14.getOid(); long oid5 = t15.getOid(); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); //concurrent modification ZooHandle t21 = s2.getHandle(oid1); ZooHandle t22 = s2.getHandle(oid2); ZooHandle t23 = s2.getHandle(oid3); ZooHandle t24 = s2.getHandle(oid4); ZooHandle t25 = s2.getHandle(oid5); //modified by both: t1, t3 //modified by 1: t4 //modified by 2: t5 t21.setValue("_id", 21L); t23.setValue("_id", 23L); t25.setValue("_id", 25L); t11.setValue("_id", 11L); t13.setValue("_id", 13L); t14.setValue("_id", 14L); pm2.currentTransaction().commit(); pm2.currentTransaction().begin(); DBStatistics stats = ZooJdoHelper.getStatistics(pm2); //System.out.println("s1_oids="+ stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); //System.out.println("s1_tx="+ stats.getStat(STATS.TX_MGR_BUFFERED_TX_CNT)); //5? assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); try { pm1.currentTransaction().commit(); fail(); } catch (JDOOptimisticVerificationException e) { //good! HashSet<Object> failedOids = new HashSet<>(); for (Throwable t: e.getNestedExceptions()) { Object f = ((JDOOptimisticVerificationException)t).getFailedObject(); failedOids.add(JDOHelper.getObjectId(f)); } assertEquals(Arrays.toString(failedOids.toArray()), 2, failedOids.size()); assertTrue(failedOids.contains(oid1)); assertTrue(failedOids.contains(oid3)); } //5? assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); pm1.currentTransaction().begin(); t11.setValue("_id", t11.getAttrLong("_id") + 1000L); t13.setValue("_id", t13.getAttrLong("_id") + 1000L); t14.setValue("_id", 14L); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); assertEquals(21+1000, t21.getAttrLong("_id")); assertEquals(22, t22.getAttrLong("_id")); assertEquals(23+1000, t23.getAttrLong("_id")); assertEquals(14, t24.getAttrLong("_id")); assertEquals(25, t25.getAttrLong("_id")); pm1.currentTransaction().rollback(); pm2.currentTransaction().rollback(); //5? assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); pm1.close(); pm2.close(); pmf.close(); } @Test public void testCommitFailWithDeleteGenericObjects() { ZooJdoProperties props = new ZooJdoProperties(TestTools.getDbName()); PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); TestTools.defineSchema(TestSuper.class); PersistenceManager pm1 = pmf.getPersistenceManager(); PersistenceManager pm2 = pmf.getPersistenceManager(); pm1.currentTransaction().begin(); pm2.currentTransaction().begin(); ZooSchema s1 = ZooJdoHelper.schema(pm1); ZooClass c1 = s1.getClass(TestSuper.class.getName()); ZooSchema s2 = ZooJdoHelper.schema(pm2); //new TestSuper(1, 11, null); ZooHandle t11 = c1.newInstance(); t11.setValue("_time", 1L); t11.setValue("_id", 11L); ZooHandle t12 = c1.newInstance(); t12.setValue("_time", 2L); t12.setValue("_id", 22L); ZooHandle t13 = c1.newInstance(); t13.setValue("_time", 3L); t13.setValue("_id", 33L); ZooHandle t14 = c1.newInstance(); t14.setValue("_time", 4L); t14.setValue("_id", 44L); ZooHandle t15 = c1.newInstance(); t15.setValue("_time", 5L); t15.setValue("_id", 55L); long oid1 = t11.getOid(); long oid2 = t12.getOid(); long oid3 = t13.getOid(); long oid4 = t14.getOid(); long oid5 = t15.getOid(); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); //concurrent modification ZooHandle t21 = s2.getHandle(oid1); ZooHandle t22 = s2.getHandle(oid2); ZooHandle t23 = s2.getHandle(oid3); ZooHandle t24 = s2.getHandle(oid4); ZooHandle t25 = s2.getHandle(oid5); //deleted by both: t1 //del/mod t2, t3 //deleted by 1: t4 //deleted by 2: t5 t21.remove(); t22.remove(); t23.setValue("_id", 23L); t25.remove(); t11.remove(); t12.setValue("_id", 12L); t13.remove(); t14.remove(); pm2.currentTransaction().commit(); pm2.currentTransaction().begin(); try { pm1.currentTransaction().commit(); fail(); } catch (JDOOptimisticVerificationException e) { //good! HashSet<Object> failedOids = new HashSet<>(); for (Throwable t: e.getNestedExceptions()) { Object f = ((JDOOptimisticVerificationException)t).getFailedObject(); assertTrue(f instanceof ZooHandle); failedOids.add(JDOHelper.getObjectId(f)); } assertEquals(Arrays.toString(failedOids.toArray()), 3, failedOids.size()); assertTrue(failedOids.contains(oid1)); //double delete assertTrue(failedOids.contains(oid2)); //update deleted obj. assertTrue(failedOids.contains(oid3)); //delete updated obj. } pm1.currentTransaction().begin(); try { t11.setValue("_id", 12345L); fail(); } catch (JDOObjectNotFoundException e) { //good } t13.setValue("_id", t13.getAttrLong("_id") + 1000); t14.setValue("_id", 14L); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); assertTrue(JDOHelper.isDeleted(t21)); assertTrue(JDOHelper.isDeleted(t22)); assertEquals(23+1000, t23.getAttrLong("_id")); assertEquals(14, t24.getAttrLong("_id")); assertTrue(JDOHelper.isDeleted(t25)); pm1.currentTransaction().rollback(); pm2.currentTransaction().rollback(); pm1.close(); pm2.close(); pmf.close(); } @Test public void testOidCollisionWithNew() { ZooJdoProperties props = new ZooJdoProperties(TestTools.getDbName()); PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); TestTools.defineSchema(TestSuper.class); PersistenceManager pm1 = pmf.getPersistenceManager(); PersistenceManager pm2 = pmf.getPersistenceManager(); pm1.currentTransaction().begin(); pm2.currentTransaction().begin(); ZooClass c2 = ZooJdoHelper.schema(pm2).getClass(TestSuper.class); ZooHandle[] t1 = new ZooHandle[5]; long[] oids1 = new long[5]; createData(pm1, t1, oids1); //concurrent modification ZooHandle t20 = c2.newInstance((Long) oids1[0]); ZooHandle t21 = c2.newInstance((Long) oids1[1]); ZooHandle t22 = c2.newInstance((Long) oids1[2]); ZooHandle t23 = c2.newInstance(); ZooHandle t24 = c2.newInstance((Long) oids1[4]); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); //modified by both: t1, t3 //modified by 1: t4 //modified by 2: t5 t20.setValue("_id", 20L); t22.setValue("_id", 22L); t24.setValue("_id", 24L); t1[0].setValue("_id", 10L); t1[2].setValue("_id", 12L); t1[3].setValue("_id", 13L); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); DBStatistics stats = ZooJdoHelper.getStatistics(pm1); //5? assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); try { pm2.checkConsistency(); fail(); } catch (JDOOptimisticVerificationException e) { //good! HashSet<Object> failedOids = new HashSet<>(); for (Throwable t: e.getNestedExceptions()) { Object f = ((JDOOptimisticVerificationException)t).getFailedObject(); failedOids.add(JDOHelper.getObjectId(f)); } assertEquals(Arrays.toString(failedOids.toArray()), 4, failedOids.size()); assertTrue(failedOids.contains(oids1[0])); assertTrue(failedOids.contains(oids1[1])); assertTrue(failedOids.contains(oids1[2])); assertTrue(failedOids.contains(oids1[4])); } try { pm2.currentTransaction().commit(); fail(); } catch (JDOOptimisticVerificationException e) { //good! HashSet<Object> failedObjects = new HashSet<>(); for (Throwable t: e.getNestedExceptions()) { Object f = ((JDOOptimisticVerificationException)t).getFailedObject(); failedObjects.add(f); } assertEquals(Arrays.toString(failedObjects.toArray()), 4, failedObjects.size()); assertTrue(failedObjects.contains(t20)); assertTrue(failedObjects.contains(t21)); assertTrue(failedObjects.contains(t22)); assertTrue(failedObjects.contains(t24)); } //5? assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); pm2.currentTransaction().begin(); //TODO revert pm1 and pm2... ? t1[0].setValue("_id", t1[0].getAttrLong("_id") + 1000); t1[2].setValue("_id", t1[2].getAttrLong("_id") + 1000); t1[3].setValue("_id", 13L); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); //these are new instances, fail+rollback does not affect values assertEquals(20, t20.getAttrLong("_id")); assertEquals(0, t21.getAttrLong("_id")); assertEquals(22, t22.getAttrLong("_id")); assertEquals(0, t23.getAttrLong("_id")); assertEquals(24, t24.getAttrLong("_id")); //extra test: //t20 should be transient now. //try to makePersistent and commit() assertFalse(JDOHelper.isPersistent(t20)); pm2.makePersistent(t20); pm2.currentTransaction().commit(); pm2.currentTransaction().begin(); assertTrue(JDOHelper.isPersistent(t20)); pm2.makeTransient(t20); assertFalse(JDOHelper.isPersistent(t20)); pm1.currentTransaction().rollback(); pm2.currentTransaction().rollback(); //5? assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); pm1.close(); pm2.close(); pmf.close(); } @Test public void testOidCollisionWithSetOid() { ZooJdoProperties props = new ZooJdoProperties(TestTools.getDbName()); PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); TestTools.defineSchema(TestSuper.class); PersistenceManager pm1 = pmf.getPersistenceManager(); PersistenceManager pm2 = pmf.getPersistenceManager(); pm1.currentTransaction().begin(); pm2.currentTransaction().begin(); // ZooSchema s1 = ZooJdoHelper.schema(pm1); ZooSchema s2 = ZooJdoHelper.schema(pm2); //data set 1 ZooHandle[] t1 = new ZooHandle[5]; long[] oids1 = new long[5]; createData(pm1, t1, oids1); //concurrent modification TestSuper t21 = new TestSuper(21, 211, null); TestSuper t22 = new TestSuper(22, 222, null); TestSuper t23 = new TestSuper(23, 233, null); TestSuper t24 = new TestSuper(24, 244, null); TestSuper t25 = new TestSuper(25, 255, null); pm2.makePersistent(t21); pm2.makePersistent(t22); pm2.makePersistent(t23); pm2.makePersistent(t24); pm2.makePersistent(t25); // Object oid21 = pm2.getObjectId(t21); // Object oid25 = pm2.getObjectId(t25); pm1.currentTransaction().commit(); pm1.currentTransaction().begin(); pm2.currentTransaction().commit(); pm2.currentTransaction().begin(); try { //TODO remove this and implement test once we support setOid() s2.getHandle(t21).setOid(1); fail(); } catch (UnsupportedOperationException e) { } // //modified by both: t1, t3 // //modified by 1: t4 // //modified by 2: t5 // s2.getHandle(t21).setOid((Long) oid1); // s2.getHandle(t23).setOid((long) oid3); // s2.getHandle(t23).remove(); // s2.getHandle(t24).setOid((long) oid4); //// t21.setId(21); //// t23.setId(23); //// t25.setId(25); // // s1.getHandle(t11).setOid((Long) oid21); // s1.getHandle(t14).setOid((long) oid3); // s1.getHandle(t14).remove(); // s1.getHandle(t15).setOid((long) oid25); //// t11.setId(11); //// t13.setId(13); //// t14.setId(14); // // pm1.currentTransaction().commit(); // pm1.currentTransaction().begin(); // // DBStatistics stats = ZooJdoHelper.getStatistics(pm1); // System.out.println("s1_oids="+ stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); // System.out.println("s1_tx="+ stats.getStat(STATS.TX_MGR_BUFFERED_TX_CNT)); // //5? // assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); // // try { // pm2.currentTransaction().commit(); // fail(); // } catch (JDOOptimisticVerificationException e) { // //good! // HashSet<Object> failedOids = new HashSet<>(); // for (Throwable t: e.getNestedExceptions()) { // Object f = ((JDOOptimisticVerificationException)t).getFailedObject(); // failedOids.add(JDOHelper.getObjectId(f)); // } // assertEquals(2, failedOids.size()); // assertTrue(failedOids.contains(oid1)); // assertTrue(failedOids.contains(oid3)); // } // // //5? // assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); // // pm2.currentTransaction().begin(); // // //TODO revert pm1 and pm2... ? // t11.setId(t11.getId() + 1000); // t13.setId(t13.getId() + 1000); // t14.setId(14); // pm1.currentTransaction().commit(); // pm1.currentTransaction().begin(); // // assertEquals(21+1000, t21.getId()); // assertEquals(22, t22.getId()); // assertEquals(23+1000, t23.getId()); // assertEquals(14, t24.getId()); // assertEquals(25, t25.getId()); // // pm1.currentTransaction().rollback(); pm2.currentTransaction().rollback(); // // //5? // assertEquals(5, stats.getStat(STATS.TX_MGR_BUFFERED_OID_CNT)); pm1.close(); pm2.close(); pmf.close(); } private void createData(PersistenceManager pm, ZooHandle[] data, long[] oids) { ZooSchema s = ZooJdoHelper.schema(pm); ZooClass c = s.getClass(TestSuper.class.getName()); ZooHandle t10 = c.newInstance(); t10.setValue("_time", 1L); t10.setValue("_id", 11L); ZooHandle t11 = c.newInstance(); t11.setValue("_time", 2L); t11.setValue("_id", 22L); ZooHandle t12 = c.newInstance(); t12.setValue("_time", 3L); t12.setValue("_id", 33L); ZooHandle t13 = c.newInstance(); t13.setValue("_time", 4L); t13.setValue("_id", 44L); ZooHandle t14 = c.newInstance(); t14.setValue("_time", 5L); t14.setValue("_id", 55L); data[0] = t10; data[1] = t11; data[2] = t12; data[3] = t13; data[4] = t14; oids[0] = t10.getOid(); oids[1] = t11.getOid(); oids[2] = t12.getOid(); oids[2] = t13.getOid(); oids[4] = t14.getOid(); } }