You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2010/05/06 01:28:27 UTC
svn commit: r941541 - in /openjpa/trunk/openjpa-slice/src/test:
java/org/apache/openjpa/slice/TestTransaction.java
resources/META-INF/persistence.xml
Author: ppoddar
Date: Wed May 5 23:28:26 2010
New Revision: 941541
URL: http://svn.apache.org/viewvc?rev=941541&view=rev
Log:
OPENJPA-1649: Add a test to verify transaction atomicity across slices.
Added:
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestTransaction.java (with props)
Modified:
openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml
Added: openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestTransaction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestTransaction.java?rev=941541&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestTransaction.java (added)
+++ openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestTransaction.java Wed May 5 23:28:26 2010
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.slice;
+
+import java.util.List;
+import java.util.Random;
+
+import javax.persistence.EntityManager;
+import javax.persistence.RollbackException;
+
+/**
+ * Tests that if any of the slices fail then none of the slices are committed.
+ *
+ * The test setup assumes that configuration is created for each slice to store
+ * cars from a particular Manufacturer.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TestTransaction extends SliceTestCase {
+ private static final Random rng = new Random(System.currentTimeMillis());
+ Manufacturer[] manufacturers;
+
+ protected String getPersistenceUnitName() {
+ return System.getProperty("unit","car");
+ }
+
+
+ public void setUp() throws Exception {
+ super.setUp(CLEAR_TABLES,
+ Car.class, Manufacturer.class,
+ "openjpa.slice.DistributionPolicy", CarDistributorPolicy.class.getName());
+ DistributedConfiguration conf = (DistributedConfiguration)emf.getConfiguration();
+ List<Slice> slices = conf.getSlices((Slice.Status[])null);
+ assertFalse(slices.isEmpty());
+ manufacturers = persistManufacturers(slices);
+ }
+
+ public void testCommitsAreAtomic() {
+ int nCarStart = count(Car.class);
+ persistCars(false);
+ int nCarStage1 = count(Car.class);
+ assertEquals(nCarStart+manufacturers.length, nCarStage1);
+
+ for (int i = 0; i < 10; i++) {
+ persistCars(true);
+ int nCarStage2 = count(Car.class);
+ assertEquals(nCarStage1, nCarStage2);
+ }
+ }
+
+ Manufacturer getManufacturer(EntityManager em, Slice slice) {
+ Manufacturer m = em.find(Manufacturer.class, slice.getName());
+ if (m == null) {
+ m = new Manufacturer();
+ m.setName(slice.getName());
+ em.persist(m);
+ }
+ return m;
+ }
+
+ /**
+ * Creates the manufacturers each per given slice.
+ */
+ Manufacturer[] persistManufacturers(List<Slice> slices) {
+ Manufacturer[] manufacturers = new Manufacturer[slices.size()];
+ int i = 0;
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ for (Slice slice : slices) {
+ manufacturers[i++] = getManufacturer(em, slice);
+ }
+ em.getTransaction().commit();
+ return manufacturers;
+ }
+
+ /**
+ * Create new car for each manufacture.
+ * @param introduceError if true then one of the car will carry null VIN.
+ */
+ void persistCars(boolean introduceError) {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ int i = introduceError ? rng.nextInt(manufacturers.length) : -1;
+ for (int j = 0; j < manufacturers.length; j++) {
+ Manufacturer maker = em.find(Manufacturer.class, manufacturers[j].getName());
+ Car car = newCar(maker);
+ em.persist(car);
+ if (i == j)
+ car.setVin(null); // this will make the commit fail
+ }
+ try {
+ em.getTransaction().commit();
+ if (introduceError) {
+ fail("Expected " + RollbackException.class.getName());
+ }
+ } catch (RollbackException e) {
+ if (!introduceError) {
+ fail("Expected " + RollbackException.class.getName());
+ } else {
+ // this is expected
+ }
+ }
+ }
+
+ Car newCar(Manufacturer maker) {
+ Car car = new Car();
+ car.setVin(maker.getName().charAt(0) + randomString(6));
+ car.setMaker(maker);
+ return car;
+ }
+
+ String randomString(int n) {
+ StringBuilder s = new StringBuilder();
+ for (int i = 0; i < n; i++) {
+ s.append(rng.nextInt(10));
+ }
+ return s.toString();
+ }
+
+ /**
+ * A distribution policy that selects the slice based on Manufacturer.
+ * @author Pinaki Poddar
+ *
+ */
+ public static class CarDistributorPolicy implements DistributionPolicy {
+ @Override
+ public String distribute(Object pc, List<String> slices, Object context) {
+ if (pc instanceof Manufacturer) {
+ return ((Manufacturer)pc).getName();
+ } else if (pc instanceof Car) {
+ if (((Car) pc).getMaker() == null) {
+ throw new RuntimeException("New " + pc + " must have a non-null Manufacturer");
+ }
+ return distribute(((Car)pc).getMaker(), slices, context);
+ }
+ throw new RuntimeException("No policy for " + pc.getClass().getName());
+ }
+ }
+}
Propchange: openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestTransaction.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml?rev=941541&r1=941540&r2=941541&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml (original)
+++ openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml Wed May 5 23:28:26 2010
@@ -180,4 +180,53 @@
</properties>
</persistence-unit>
+ <persistence-unit name="car">
+ <class>org.apache.openjpa.slice.Car</class>
+ <class>org.apache.openjpa.slice.Manufacturer</class>
+
+ <properties>
+ <property name="openjpa.BrokerFactory" value="slice"/>
+ <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+
+ <property name="openjpa.slice.Names" value="BMW,Honda,Ford"/>
+
+ <property name="openjpa.ConnectionUserName" value=""/>
+ <property name="openjpa.ConnectionPassword" value=""/>
+
+ <property name="openjpa.slice.BMW.ConnectionURL" value="jdbc:derby:target/database/bmw;create=true"/>
+ <property name="openjpa.slice.Honda.ConnectionURL" value="jdbc:derby:target/database/honda;create=true"/>
+ <property name="openjpa.slice.Ford.ConnectionURL" value="jdbc:derby:target/database/ford;create=true"/>
+
+ <property name="openjpa.Multithreaded" value="false"/>
+ <property name="openjpa.Log" value="DefaultLevel=INFO, Enhance=TRACE, SQL=TRACE"/>
+ <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=native"/>
+ <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
+ <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
+ <property name="openjpa.DynamicEnhancementAgent" value="false"/>
+ </properties>
+ </persistence-unit>
+
+
+ <persistence-unit name="car.mysql">
+ <properties>
+ <property name="openjpa.BrokerFactory" value="slice"/>
+ <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
+
+ <property name="openjpa.slice.Names" value="BMW,Honda,Ford"/>
+
+ <property name="openjpa.ConnectionUserName" value="root"/>
+ <property name="openjpa.ConnectionPassword" value=""/>
+ <property name="openjpa.slice.BMW.ConnectionURL" value="jdbc:mysql://localhost/bmw"/>
+ <property name="openjpa.slice.Honda.ConnectionURL" value="jdbc:mysql://localhost/ford"/>
+ <property name="openjpa.slice.Ford.ConnectionURL" value="jdbc:mysql://localhost/honda"/>
+
+ <property name="openjpa.Multithreaded" value="false"/>
+ <property name="openjpa.jdbc.SynchronizeMappings" value="refresh"/>
+ <property name="openjpa.jdbc.MappingDefaults" value="DefaultMissingInfo=true"/>
+ <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
+ <property name="openjpa.DynamicEnhancementAgent" value="false"/>
+ </properties>
+ </persistence-unit>
+
+
</persistence>