/*
Copyright (C) 2007 Mobixess Inc. http://www.java-objects-database.com
This file is part of the JODB (Java Objects Database) open source project.
JODB is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation.
JODB 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.mobixess.jodb.tests;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import com.mobixess.jodb.core.IPersistentObjectStatistics;
import com.mobixess.jodb.core.JODBConfig;
import com.mobixess.jodb.core.JODBSessionContainer;
import com.mobixess.jodb.core.io.IRandomAccessBufferFactory.BUFFER_TYPE;
public class SimpleAddTestSE extends SimpleAddTest {
public static int _testCounter;
public static byte _modificationCounter;
public void largeSubstTablesTest() throws Exception{
File testFileDir = new File("./testData/");
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
WriteIntersectingFactory factory = new WriteIntersectingFactory();
JODBConfig.setRandomAccessBufferFactory(factory);
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
long substTableFreeSize = sessionContainer.getDatabaseStatistics().literalSubstFreeSize(0);
long expectedSize = substTableFreeSize;
StringBuffer className = new StringBuffer("TestClass");
int i=0;
for (; className.length()<expectedSize && className.length()< 200;i++) {
className.append("Test"+i);
}
DynamicTestClass dynamicTestClass = new DynamicTestClass(className.toString(),i*10);
Object object = dynamicTestClass.load(sessionContainer,long.class,false);
sessionContainer.set(object);
sessionContainer.commit();
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
if(sessionContainer.getDatabaseStatistics().totalDataEntries()!=2 ){
throw new RuntimeException();
}
long firstPageSize = sessionContainer.getDatabaseStatistics().literalSubstMaxSize(0);
long secondPageSize = sessionContainer.getDatabaseStatistics().literalSubstMaxSize(1);
if(secondPageSize <= firstPageSize){
throw new RuntimeException();
}
List list = sessionContainer.getAllObjects();
if(list.size()!=1){
throw new RuntimeException();
}
dynamicTestClass.delete();
i++;
className.append("Test"+i);
dynamicTestClass = new DynamicTestClass(className.toString(),i*10);
object = dynamicTestClass.load(sessionContainer,long.class,false);
sessionContainer.set(object);
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
if(sessionContainer.getDatabaseStatistics().totalDataEntries() != 3 ){
throw new RuntimeException();
}
sessionContainer.close();
dynamicTestClass.delete();
}
public void multipleSubsTablesTest0(boolean closeAfterCommit) throws Exception{
File testFileDir = new File("./testData/");
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
WriteIntersectingFactory factory = new WriteIntersectingFactory();
JODBConfig.setRandomAccessBufferFactory(factory);
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
int dataEntries = sessionContainer.getDatabaseStatistics().totalDataEntries();
StringBuffer className = new StringBuffer("TestClass");
final int testIndexStart = 100;
int testIndex = testIndexStart;
int totalWritten = 0;
Object object = null;
int newTableCreationIOCalls = 0;
while(dataEntries < 2 && className.length() < 0xFFFF){
factory.intersectionInit(null, Integer.MAX_VALUE, false);
factory.setIntersectEnabled(true);
className.append("Test"+testIndex);
DynamicTestClass dynamicTestClass = new DynamicTestClass(className.toString(),testIndex);
object = dynamicTestClass.load(sessionContainer);
totalWritten++;
testIndex++;
sessionContainer.set(object);
sessionContainer.commit();
newTableCreationIOCalls = factory._counter;
if(closeAfterCommit){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
}
dataEntries = sessionContainer.getDatabaseStatistics().totalDataEntries();
dynamicTestClass.delete();
}
if(dataEntries!=2){
throw new RuntimeException();
}
List list = sessionContainer.getAllObjects();
if(list.size()!=totalWritten){
throw new RuntimeException();
}
int index = list.indexOf(object);
if(index == -1){
throw new RuntimeException();
}
DynamicTestClass dynamicTestClass = new DynamicTestClass(className.toString(),testIndex);
object = dynamicTestClass.load(sessionContainer);
totalWritten++;
testIndex++;
sessionContainer.set(object);
sessionContainer.commit();
if(closeAfterCommit){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
}
dataEntries = sessionContainer.getDatabaseStatistics().totalDataEntries();
dynamicTestClass.delete();
if(dataEntries!=2){
throw new RuntimeException();
}
list = sessionContainer.getAllObjects();
if(list.size()!=totalWritten){
throw new RuntimeException();
}
index = list.indexOf(object);
if(index == -1){
throw new RuntimeException();
}
sessionContainer.close();
className = new StringBuffer("TestClass");
testIndex = testIndexStart;
testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
for (int i = 0 ; i < totalWritten-2; i++) {
className.append("Test"+testIndex);
dynamicTestClass = new DynamicTestClass(className.toString(),testIndex);
object = dynamicTestClass.load(sessionContainer);
testIndex++;
sessionContainer.set(object);
sessionContainer.commit();
if(closeAfterCommit){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
}
dataEntries = sessionContainer.getDatabaseStatistics().totalDataEntries();
dynamicTestClass.delete();
}
if(dataEntries!=1){
throw new RuntimeException();
}
className.append("Test"+testIndex);
dynamicTestClass = new DynamicTestClass(className.toString(),testIndex);
object = dynamicTestClass.load(sessionContainer);
for (int i = 0; i < newTableCreationIOCalls; i++) {
factory.intersectionInit(null, i, true);
factory.setIntersectEnabled(true);
sessionContainer.set(object);
try {
sessionContainer.commit();
break;
} catch (IOException e) {
e.printStackTrace();
}
factory.setIntersectEnabled(false);
if (factory._bufferedType == BUFFER_TYPE.MAIN) {
byte[] incompleteTransaction = factory.getBuffer();
verifyDataReadable(incompleteTransaction, null,totalWritten-2,totalWritten-1);
}
List classes = sessionContainer.getAllObjects();
if(classes.size()!=totalWritten-2){
throw new RuntimeException();
}
if(sessionContainer.getDatabaseStatistics().totalDataEntries()!=1){
throw new RuntimeException();
}
}
factory.setIntersectEnabled(false);
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(dynamicTestClass._classLoader);
sessionContainer.set(object);
sessionContainer.commit();
testIndex++;
dynamicTestClass.delete();
className.append("Test"+testIndex);
dynamicTestClass = new DynamicTestClass(className.toString(),testIndex);
object = dynamicTestClass.load(sessionContainer);
for (int i = 0; i < Integer.MAX_VALUE; i++) {
factory.intersectionInit(null, i, true);
factory.setIntersectEnabled(true);
sessionContainer.set(object);
try {
sessionContainer.commit();
break;
} catch (Exception e) {
e.printStackTrace();
}
factory.setIntersectEnabled(false);
if (factory._bufferedType == BUFFER_TYPE.MAIN) {
byte[] incompleteTransaction = factory.getBuffer();
verifyDataReadable(incompleteTransaction, null,totalWritten,totalWritten+1);
}
List classes = sessionContainer.getAllObjects();
if(classes.size()!=totalWritten){
throw new RuntimeException();
}
if(sessionContainer.getDatabaseStatistics().totalDataEntries()!=2){
throw new RuntimeException();
}
}
factory.setIntersectEnabled(false);
dynamicTestClass.delete();
sessionContainer.close();
}
public void multipleSubsTablesTest() throws Exception{
multipleSubsTablesTest0(true);
multipleSubsTablesTest0(false);
}
public void sizeAndPositioningTest() throws Exception{
File testFileDir = new File("./testData/");
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
ClassLoader classLoaderForShortLengthObject = null;
String className = "Test"+(_testCounter-1)+"Class";
int i = 1;
for (; i < Integer.MAX_VALUE; i++) {
DynamicTestClass dynamicTestClass = new DynamicTestClass(className,i);
Object obj = dynamicTestClass.load(sessionContainer);
classLoaderForShortLengthObject = dynamicTestClass._classLoader;
sessionContainer.set(obj);
sessionContainer.commit();
IPersistentObjectStatistics objectStatistics = sessionContainer.getPersistenceStatistics(obj);
dynamicTestClass.delete();
long size = objectStatistics.getBodySize();
if(size >= 0xFF){
break;
}
}
sessionContainer.close();
testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
sessionContainer = getContainerForFile(testFile);
DynamicTestClass byteLengthDynamicTestClass = new DynamicTestClass(className,i-1);
Object obj = byteLengthDynamicTestClass.load(sessionContainer);
sessionContainer.set(obj);
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(classLoaderForShortLengthObject);
List list = sessionContainer.getAllObjects();
obj = list.get(0);
sessionContainer.set(obj);
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(classLoaderForShortLengthObject);
list = sessionContainer.getAllObjects();
obj = list.get(0);
IPersistentObjectStatistics objectStatistics = sessionContainer.getPersistenceStatistics(obj);
if(objectStatistics.getTotalRecords() != 1){
throw new RuntimeException();
}
modify(obj);
sessionContainer.set(obj);
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(classLoaderForShortLengthObject);
list = sessionContainer.getAllObjects();
obj = list.get(0);
objectStatistics = sessionContainer.getPersistenceStatistics(obj);
if(objectStatistics.getTotalRecords() != 2){
throw new RuntimeException();
}
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(byteLengthDynamicTestClass._classLoader);
list = sessionContainer.getAllObjects();
obj = list.get(0);
modify(obj);
sessionContainer.set(obj);
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
sessionContainer.setClassLoader(classLoaderForShortLengthObject);
list = sessionContainer.getAllObjects();
obj = list.get(0);
objectStatistics = sessionContainer.getPersistenceStatistics(obj);
if(objectStatistics.getTotalRecords() != 1){
throw new RuntimeException(""+objectStatistics.getTotalRecords());
}
sessionContainer.close();
byteLengthDynamicTestClass.delete();
sessionContainer.close();
}
public void run() throws Exception{
ensureTestFolderExists();
largeSubstTablesTest();
checkInputBuffersCount();
multipleSubsTablesTest();
checkInputBuffersCount();
sizeAndPositioningTest();
checkInputBuffersCount();
super.run();
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
SimpleAddTestSE simpleAddTest = new SimpleAddTestSE();
simpleAddTest.run();
/*simpleAddTest.ensureTestFolderExists();
//innerClassTest();
simpleAddTest.objectWithChildFieldsTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.arraysTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.sizeAndPositioningTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.noFieldsObjectTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.multipleSubsTablesTest();
simpleAddTest.fileLockCheck();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.transactionTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.stringTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.transientTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.sizeAndPositioningTest1();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.largeSubstTablesTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.sizeIncreaseTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.arraysTest1();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.setTestBufferFactory();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.objectWithFieldsTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.multipleObjectWithFieldsTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.objectWithChildFieldsModificationTest1();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.objectWithChildFieldsModificationTest0();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.deleteTest();
simpleAddTest.checkInputBuffersCount();
simpleAddTest.gcTest();
simpleAddTest.checkInputBuffersCount();
System.out.println("Test complete");*/
}
public static class DynamicTestClass{
final String _stubName = "ClassStub";
final String _membersString = "/*members*/";
final String _equalsEntry = "/*equals entry*/";
public String _stubText;
public String _name;
public int _entries;
public ClassLoader _classLoader;
File _outputClassSrc;
File _outputDir;
public DynamicTestClass(String name,int totalMembers) throws IOException {
_name = name;
_entries = totalMembers;
InputStream is = getClass().getResourceAsStream("dynamicClasses/ClassStub.txt");
int size = is.available();
byte[] data = new byte[size];
is.read(data);
_stubText = new String(data);
}
public Object load(JODBSessionContainer sessionContainer) throws Exception{
return load(sessionContainer, byte.class, true);
}
public Object load(JODBSessionContainer sessionContainer, Class fieldType, boolean generateEquals) throws Exception{
int nameIndex = _stubText.indexOf(_stubName);
_outputDir = new File("./testData/");
_outputDir.mkdirs();
_outputClassSrc = new File(_outputDir,_name+".java");
FileOutputStream fos = new FileOutputStream(_outputClassSrc);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos);
outputStreamWriter.write(_stubText.substring(0,nameIndex));
outputStreamWriter.write(_name);
int membIndex = _stubText.indexOf(_membersString);
outputStreamWriter.write(_stubText.substring(nameIndex+_stubName.length(),membIndex));
StringBuffer equalText = new StringBuffer();
String memberNamePrefix = "_memberMemberMemberMemberMemberMember";
for (int i = 0; i < _entries; i++) {
outputStreamWriter.write(fieldType.getName()+" "+memberNamePrefix+i+"="+(byte)i+";\r\n");
if(i!=0){
equalText.append("&&");
}
equalText.append(memberNamePrefix+i+"==o1."+memberNamePrefix+i);
}
int equalEntryIndex = _stubText.indexOf(_equalsEntry);
outputStreamWriter.write(_stubText.substring(membIndex+_membersString.length(), equalEntryIndex));
outputStreamWriter.write("if(!(obj instanceof "+_name+")) return false;\r\n");
outputStreamWriter.write(_name+" o1 =("+_name+")obj;\r\nreturn ");
if(generateEquals){
outputStreamWriter.write(equalText.toString()+";\r\n");
}else{
outputStreamWriter.write("false;\r\n");
}
outputStreamWriter.write(_stubText.substring(equalEntryIndex+_equalsEntry.length()));
outputStreamWriter.close();
int errorCode = com.sun.tools.javac.Main.compile(new String[] {
"-classpath", _outputDir.toString()+'\\',
"-d", _outputDir.toString()+'\\',
_outputDir.toString()+'\\'+_name+".java" });
if(errorCode!=0){
throw new RuntimeException();
}
// The dir contains the compiled classes.
File classesDir = _outputDir;
// The parent classloader
ClassLoader parentLoader = SimpleAddTest.class.getClassLoader();
// Load class "sample.PostmanImpl" with our own classloader.
_classLoader = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class cls1 = _classLoader.loadClass(_name);
Object result = cls1.newInstance();
sessionContainer.setClassLoader(_classLoader);
return result;
}
public ClassLoader getClassLoader() {
return _classLoader;
}
public void delete(){
_outputClassSrc.delete();
File compiledClass = new File(_outputDir,_name+".class");
compiledClass.delete();
}
}
}