blob: 0754860bc43770b12fed42cccfc648de224d683d [file] [log] [blame]
/*
* 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
*
* https://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.jdo.tck.api.converter;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import javax.jdo.JDOHelper;
import javax.jdo.Query;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.converter.IPCPoint;
import org.apache.jdo.tck.pc.converter.PCPoint;
import org.apache.jdo.tck.pc.converter.PCPointAnnotated;
import org.apache.jdo.tck.pc.converter.PCPointProp;
import org.apache.jdo.tck.pc.converter.PCPointPropAnnotated;
import org.apache.jdo.tck.util.BatchTestRunner;
import org.apache.jdo.tck.util.IntegerToStringConverter;
/**
* <B>Title:</B>IntAttributeConverterTest <br>
* <B>Keywords:</B> mapping <br>
* <B>Assertion ID:</B> [not identified] <br>
* <B>Assertion Description: </B> A IPCPoint instance has an int and an Integer field, that are
* stored as strings in the datastore. The int / Integer fields are converted using an
* AttributeConverter.
*/
public class IntAttributeConverterTest extends JDO_Test {
private static final int MIN_X = 1;
private static final int MIN_Y = 5;
/**
* The <code>main</code> is called when the class is directly executed from the command line.
*
* @param args The arguments passed to the program.
*/
public static void main(String[] args) {
BatchTestRunner.run(IntAttributeConverterTest.class);
}
/**
* @see JDO_Test#localSetUp()
*/
@Override
protected void localSetUp() {
addTearDownClass(PCPoint.class);
addTearDownClass(PCPointAnnotated.class);
addTearDownClass(PCPointProp.class);
addTearDownClass(PCPointPropAnnotated.class);
}
/** Test method creating and storing a PCPoint instance. */
public void testStorePCPointInstance() {
runStoreIPCPointInstance(PCPoint.class);
}
/** Test method reading a PCPoint instance from the datastore. */
public void testReadPCPointInstance() {
runReadIPCPointInstance(PCPoint.class);
}
/** Test method modifying a PCPoint instance and storing in the datastore. */
public void testModifyPCPointInstance() {
runModifyIPCPointInstance(PCPoint.class);
}
/** Test method running a PCPoint query with a query parameter of type Point. */
public void testPCPointQueryWithPointParam() {
runQueryWithIntParameter(PCPoint.class);
}
/** Test method running a PCPoint query with a query parameter of type String. */
public void testPCPointQueryWithStringParam() throws Exception {
runQueryWithStringParameter(PCPoint.class);
}
/** Test method creating and storing a PCPointAnnotated instance. */
public void testStorePCPointAnnotatedInstance() {
runStoreIPCPointInstance(PCPointAnnotated.class);
}
/** Test method reading a PCPointAnnotated instance from the datastore. */
public void testReadPCPointAnnotatedInstance() {
runReadIPCPointInstance(PCPointAnnotated.class);
}
/** Test method modifying a PCPointAnnotated instance and storing in the datastore. */
public void testModifyPCPointAnnotatedInstance() {
runModifyIPCPointInstance(PCPointAnnotated.class);
}
/** Test method running a PCPointAnnotated query with a query parameter of type String. */
public void testPCPointAnnotatedQueryWithPointParam() {
runQueryWithIntParameter(PCPointAnnotated.class);
}
/** Test method running a PCPointAnnotated query with a query parameter of type Point. */
public void testPCPointAnnotatedQueryWithStringParam() throws Exception {
runQueryWithStringParameter(PCPointAnnotated.class);
}
/** Test method creating and storing a PCPoint instance. */
public void testStorePCPointPropInstance() {
runStoreIPCPointInstance(PCPointProp.class);
}
/** Test method reading a PCPoint instance from the datastore. */
public void testReadPCPointPropInstance() {
runReadIPCPointInstance(PCPointProp.class);
}
/** Test method modifying a PCPoint instance and storing in the datastore. */
public void testModifyPCPointPropInstance() {
runModifyIPCPointInstance(PCPointProp.class);
}
/** Test method running a PCPoint query with a query parameter of type Point. */
public void testPCPointPropQueryWithPointParam() {
runQueryWithIntParameter(PCPointProp.class);
}
/** Test method running a PCPoint query with a query parameter of type String. */
public void testPCPointPropQueryWithStringParam() throws Exception {
runQueryWithStringParameter(PCPointProp.class);
}
/** Test method creating and storing a PCPointAnnotated instance. */
public void testStorePCPointPropAnnotatedInstance() {
runStoreIPCPointInstance(PCPointPropAnnotated.class);
}
/** Test method reading a PCPointAnnotated instance from the datastore. */
public void testReadPCPointPropAnnotatedInstance() {
runReadIPCPointInstance(PCPointPropAnnotated.class);
}
/** Test method modifying a PCPointAnnotated instance and storing in the datastore. */
public void testModifyPCPointPropAnnotatedInstance() {
runModifyIPCPointInstance(PCPointPropAnnotated.class);
}
/** Test method running a PCPointAnnotated query with a query parameter of type String. */
public void testPCPointPropAnnotatedQueryWithPointParam() {
runQueryWithIntParameter(PCPointPropAnnotated.class);
}
/** Test method running a PCPointAnnotated query with a query parameter of type Point. */
public void testPCPointPropAnnotatedQueryWithStringParam() throws Exception {
runQueryWithStringParameter(PCPointPropAnnotated.class);
}
// Helper methods
/**
* Helper method creating a IPCPoint instance. It should call AttributeConverter method
* convertToDatastore.
*/
private <T extends IPCPoint> void runStoreIPCPointInstance(Class<T> pcPointClass) {
int nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
int nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
// Create a persistent IPCPoint instance and store its oid
// AttributeConverter method convertToDatastore is called when persisting instance
createIPCPointInstances(pcPointClass, 1);
// convertToDatastore should be called twice
assertEquals(2, IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should not be called
assertEquals(0, IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
}
/**
* Helper method reading a IPCPoint instance from the datastore. It should call AttributeConverter
* method convertToAttribute.
*/
private <T extends IPCPoint> void runReadIPCPointInstance(Class<T> pcPointClass) {
IPCPoint point;
Object oid;
int nrOfDbCalls;
int nrOfAttrCalls;
// Create a persistent IPCPoint instance and store its oid
oid = createIPCPointInstances(pcPointClass, 1);
// Cleanup the 2nd-level cache and close the pm to make sure PCPoint instances are not cached
pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcPointClass);
pm.close();
pm = null;
nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
pm = getPM();
pm.currentTransaction().begin();
// Read the IPCPoint instance from the datastore, this should call convertToAttribute
point = (IPCPoint) pm.getObjectById(oid);
int x = point.getX();
Integer y = point.getY();
pm.currentTransaction().commit();
// convertToDatastore should not be called
assertEquals(0, IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should be called twice
assertEquals(2, IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
// Check the values of the associated Point instances
assertEquals(MIN_X, x);
assertEquals(MIN_Y, y == null ? 0 : y.intValue());
}
/**
* Helper method modifying a IPCPoint instance. It should call AttributeConverter method
* convertToDatastore.
*/
private <T extends IPCPoint> void runModifyIPCPointInstance(Class<T> pcPointClass) {
Transaction tx;
IPCPoint point;
Object oid;
int nrOfDbCalls;
int nrOfAttrCalls;
// Create a persistent IPCPoint instance and store its oid
oid = createIPCPointInstances(pcPointClass, 1);
// Cleanup the 2nd-level cache and close the pm to make sure PCPoint instances are not cached
pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcPointClass);
pm.close();
pm = null;
nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
pm = getPM();
tx = pm.currentTransaction();
tx.begin();
// Load the PCPoint instance, this should call convertToAttribute
point = (IPCPoint) pm.getObjectById(oid);
// Update IPCPoint instance, this should call convertToDatastore
point.setX(MIN_X + 1);
point.setY(Integer.valueOf(MIN_Y + 1));
// IPCPoint instance should be dirty
assertTrue(JDOHelper.isDirty(point));
tx.commit();
// convertToDatastore should be called twice
assertEquals(2, IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should be called twice
assertEquals(2, IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
}
/**
* Helper method running a query with an int parameter. The parameter value is converted using the
* AttributeConverter.
*
* @throws Exception
*/
private <T extends IPCPoint> void runQueryWithIntParameter(Class<T> pcPointClass) {
int nrOfDbCalls;
int nrOfAttrCalls;
nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
createIPCPointInstances(pcPointClass, 5);
// convertToDatastore should be called twice per instance = 10 times
assertEquals(10, IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should not be called
assertEquals(0, IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
// Cleanup the 2nd-level cache and close the pm to make sure PCPoint instances are not cached
pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcPointClass);
pm.close();
pm = null;
nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
pm = getPM();
pm.currentTransaction().begin();
try (Query<T> q = pm.newQuery(pcPointClass, "this.x == :param")) {
q.setParameters(MIN_X + 1);
// AttributeConverter method convertToAttribute is called when loading instance from the
// datastore
List<T> res = q.executeList();
assertEquals(1, res.size());
IPCPoint point = res.get(0);
// Check the coordinates of the associated Point instances
assertEquals(MIN_X + 1, point.getX());
assertEquals(MIN_Y + 1, point.getY() == null ? 0 : point.getY().intValue());
} catch (Exception e) {
fail(e.getMessage());
} finally {
pm.currentTransaction().commit();
}
// convertToDatastore should be called to handle the query parameter
assertTrue(IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls >= 1);
// convertToAttribute should be called at least twice
assertTrue(IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
}
/**
* Helper method running a query with a Point parameter. The string parameter is compared to the
* converted int field.
*
* @throws Exception
*/
private <T extends IPCPoint> void runQueryWithStringParameter(Class<T> pcPointClass)
throws Exception {
int nrOfDbCalls;
int nrOfAttrCalls;
nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
createIPCPointInstances(pcPointClass, 5);
// convertToDatastore should be called twice per instance = 10 times
assertEquals(10, IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should not be called
assertEquals(0, IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
// Cleanup the 2nd-level cache and close the pm to make sure PCPoint instances are not cached
pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcPointClass);
pm.close();
pm = null;
nrOfDbCalls = IntegerToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = IntegerToStringConverter.getNrOfConvertToAttributeCalls();
pm = getPM();
pm.currentTransaction().begin();
try (Query<T> q = pm.newQuery(pcPointClass, "this.x == param")) {
q.declareParameters("String param");
q.setParameters("3");
// AttributeConverter method convertToAttribute is called when loading instance from the
// datastore
List<T> res = q.executeList();
assertEquals(1, res.size());
IPCPoint point = res.get(0);
assertEquals(MIN_X + 2, point.getX());
assertEquals(MIN_Y + 2, point.getY() == null ? 0 : point.getY().intValue());
} finally {
pm.currentTransaction().commit();
}
// convertToDatastore should not be called
assertTrue(IntegerToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls == 0);
// convertToAttribute should be called at least twice
assertTrue(IntegerToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
}
/**
* Helper method to create IPCPoint instances.
*
* @param pcPointClass class instance of the IPCPoint implementation class to be created
* @param nrOfObjects number of IPCPoint instances to be created
* @return ObjectId of the first IPCPoint instance
*/
private <T extends IPCPoint> Object createIPCPointInstances(
Class<T> pcPointClass, int nrOfObjects) {
IPCPoint point;
Object oid = null;
if (nrOfObjects < 1) {
return null;
}
pm = getPM();
try {
pm.currentTransaction().begin();
point = pcPointClass.getConstructor().newInstance();
point.setX(MIN_X);
point.setY(Integer.valueOf(MIN_Y));
pm.makePersistent(point);
oid = pm.getObjectId(point);
for (int i = 1; i < nrOfObjects; i++) {
point = pcPointClass.getConstructor().newInstance();
point.setX(MIN_X + i);
point.setY(Integer.valueOf(MIN_Y + i));
pm.makePersistent(point);
}
pm.currentTransaction().commit();
} catch (NoSuchMethodException
| SecurityException
| InstantiationException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException ex) {
fail("Error creating IPCPoint instance: " + ex.getMessage());
} finally {
if (pm.currentTransaction().isActive()) {
pm.currentTransaction().rollback();
}
}
return oid;
}
}