blob: b302c66de9805c0f9ae09b2e5fb37e314f26f59d [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
*
* 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.geronimo.transaction.log;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.List;
import javax.transaction.xa.Xid;
import junit.framework.TestCase;
import org.apache.geronimo.transaction.manager.TransactionLog;
/**
*
*
* @version $Rev$ $Date$
*
* */
public abstract class AbstractLogTest extends TestCase {
private Object startBarrier = new Object();
private Object stopBarrier = new Object();
private int startedThreads = 0;
private int stoppedThreads = 0;
long totalDuration = 0;
private Xid xid;
private List names;
final Object mutex = new Object();
long totalXidCount = 0;
private Writer resultsXML;
private Writer resultsCSV;
public void testDummy() throws Exception {}
public void testTransactionLog() throws Exception {
File resultFileXML = new File(getResultFileName() + ".xml");
resultsXML = new FileWriter(resultFileXML);
resultsXML.write("<log-test>\n");
File resultFileCSV = new File(getResultFileName() + ".csv");
resultsCSV = new FileWriter(resultFileCSV);
resultsCSV.write("workerCount,xidCount,TotalXids,missingXids,DurationMilliseconds,XidsPerSecond,AverageForceTime,AverageBytesPerForce,AverageLatency\n");
int xidCount = Integer.getInteger("xa.log.test.xid.count", 50).intValue();
int minWorkerCount = Integer.getInteger("xa.log.test.worker.count.min", 20).intValue();
int maxWorkerCount = Integer.getInteger("xa.log.test.worker.count.max", 40).intValue();
int workerCountStep = Integer.getInteger("xa.log.test.worker.count.step", 20).intValue();
int repCount = Integer.getInteger("xa.log.test.repetition.count", 1).intValue();
long maxTime = Long.getLong("xa.log.test.max.time.seconds", 30).longValue() * 1000;
int overtime = 0;
try {
for (int workers = minWorkerCount; workers <= maxWorkerCount; workers += workerCountStep) {
for (int reps = 0; reps < repCount; reps++) {
if (testTransactionLog(workers, xidCount) > maxTime) {
overtime++;
if (overtime > 1) {
return;
}
}
resultsCSV.flush();
resultsXML.flush();
}
}
} finally {
resultsXML.write("</log-test>\n");
resultsXML.flush();
resultsXML.close();
resultsCSV.flush();
resultsCSV.close();
}
}
protected abstract String getResultFileName();
public long testTransactionLog(int workers, int xidCount) throws Exception {
TransactionLog transactionLog = createTransactionLog();
xid = new XidImpl2(new byte[Xid.MAXGTRIDSIZE]);
//TODO Supply an actual list
names = Collections.EMPTY_LIST;
long startTime = journalTest(transactionLog, workers, xidCount);
long stopTime = System.currentTimeMillis();
printSpeedReport(transactionLog, startTime, stopTime, workers, xidCount);
closeTransactionLog(transactionLog);
return stopTime - startTime;
}
protected abstract void closeTransactionLog(TransactionLog transactionLog) throws Exception ;
protected abstract TransactionLog createTransactionLog() throws Exception;
private long journalTest(final TransactionLog logger, final int workers, final int xidCount)
throws Exception {
totalXidCount = 0;
startedThreads = 0;
stoppedThreads = 0;
totalDuration = 0;
for (int i = 0; i < workers; i++) {
new Thread() {
public void run() {
long localXidCount = 0;
boolean exception = false;
long localDuration = 0;
try {
synchronized (startBarrier) {
++startedThreads;
startBarrier.notifyAll();
while (startedThreads < (workers + 1)) startBarrier.wait();
}
long localStartTime = System.currentTimeMillis();
for (int i = 0; i < xidCount; i++) {
// journalize COMMITTING record
Object logMark = logger.prepare(xid, names);
//localXidCount++;
// journalize FORGET record
logger.commit(xid, logMark);
localXidCount++;
}
localDuration = System.currentTimeMillis() - localStartTime;
} catch (Exception e) {
//
// FIXME: Remove System.err usage
//
System.err.println(Thread.currentThread().getName());
e.printStackTrace(System.err);
exception = true;
} finally {
synchronized (mutex) {
totalXidCount += localXidCount;
totalDuration += localDuration;
}
synchronized (stopBarrier) {
++stoppedThreads;
stopBarrier.notifyAll();
}
}
}
}
.start();
}
// Wait for all the workers to be ready..
long startTime = 0;
synchronized (startBarrier) {
while (startedThreads < workers) startBarrier.wait();
++startedThreads;
startBarrier.notifyAll();
startTime = System.currentTimeMillis();
}
// Wait for all the workers to finish.
synchronized (stopBarrier) {
while (stoppedThreads < workers) stopBarrier.wait();
}
return startTime;
}
void printSpeedReport(TransactionLog logger, long startTime, long stopTime, int workers, int xidCount) throws IOException {
long mc = ((long) xidCount) * workers;
long duration = (stopTime - startTime);
long xidsPerSecond = (totalXidCount * 1000 / (duration));
int averageForceTime = logger.getAverageForceTime();
int averageBytesPerForce = logger.getAverageBytesPerForce();
long averageLatency = totalDuration/totalXidCount;
resultsXML.write("<run><workers>" + workers + "</workers><xids-per-thread>" + xidCount + "</xids-per-thread><expected-total-xids>" + mc + "</expected-total-xids><missing-xids>" + (mc - totalXidCount) + "</missing-xids><totalDuration-milliseconds>" + duration + "</totalDuration-milliseconds><xids-per-second>" + xidsPerSecond + "</xids-per-second></run>\n");
resultsXML.write(logger.getXMLStats() + "\n");
resultsCSV.write("" + workers + "," + xidCount + "," + mc + "," + (mc - totalXidCount) + "," + duration + "," + xidsPerSecond + "," + averageForceTime + "," + averageBytesPerForce + "," + averageLatency + "\n");
}
}