/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.compat;
import java.beans.XMLDecoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.tools.ClassVersionInfo;
import org.jboss.tools.SerialVersionUID;
/**
* Tests of serial version uid compatibility across jboss versions. The
* testsuite/etc/serialVersionUID/xxx.ser is created using the
* org.jboss.tools.SerialVersionUID utility.
*
* @author Scott.Stark@jboss.org
*/
public class SerialVersionUIDUnitTestCase extends TestCase
{
private static final String DB_DIR = "etc/svuid-db";
private static final String DB_FILE_PREFIX = "svuid-";
private static final String VERSION_STRING_1_3_0_GA = "1.3.0.GA";
private static final String VERSION_STRING_1_4_0_GA = "1.4.0.GA";
private static final String JAVA_VERSION_PREFIX_14 = "14";
private static final String JAVA_VERSION_PREFIX_50 = "50";
private static String BLACKLIST_1_3_0_GA[] =
{
// JBCACHE-918
"org.jboss.cache.OptimisticTreeNode",
"org.jboss.cache.optimistic.DefaultDataVersion",
"org.jboss.cache.optimistic.FqnComparator",
};
int mismatchCount = 0;
StringBuffer messages = null;
public SerialVersionUIDUnitTestCase(String name)
{
super(name);
}
protected void setUp()
{
mismatchCount = 0;
if (messages == null)
{
messages = new StringBuffer();
}
}
protected void tearDown()
{
messages.setLength(0);
}
public void testCompat_1_3_0_GA() throws Exception
{
String prefix = getFilePrefix() + VERSION_STRING_1_3_0_GA;
Map db = readDatabase(prefix);
mismatchCount = compare(db, calcClassInfoMap(), prefix,
BLACKLIST_1_3_0_GA, messages);
System.out.println("serialVersionUID mismatches = " + mismatchCount);
if (mismatchCount != 0)
{
fail("Failures for :" + messages.toString());
}
}
public void testCompat_1_4_0_GA() throws Exception
{
String prefix = getFilePrefix() + VERSION_STRING_1_4_0_GA;
Map db = readDatabase(prefix);
mismatchCount = compare(db, calcClassInfoMap(), prefix,
new String[0], messages);
System.out.println("serialVersionUID mismatches = " + mismatchCount);
if (mismatchCount != 0)
{
fail("Failures for :" + messages.toString());
}
}
private String getFilePrefix()
{
String javaVersion = System.getProperty("java.version").trim();
if (javaVersion.startsWith("1.5."))
{
return DB_FILE_PREFIX + JAVA_VERSION_PREFIX_50 + ".";
}
else if (javaVersion.startsWith("1.4."))
{
return DB_FILE_PREFIX + JAVA_VERSION_PREFIX_14 + ".";
}
else
{
return "";
}
}
private Map readDatabase(String dbFilePrefix)
throws Exception
{
File dbFile = new File(DB_DIR, dbFilePrefix + ".xml");
FileInputStream inputStream = new FileInputStream(dbFile);
XMLDecoder xmlObjects = new XMLDecoder(inputStream);
ClassVersionInfo svuidInfo;
TreeMap db = new TreeMap();
boolean doQuit = false;
do
{
try
{
svuidInfo = (ClassVersionInfo) xmlObjects.readObject();
db.put(svuidInfo.getName(), svuidInfo);
}
/*
* TODO: Keep working ?
catch (ClassCastException e)
{
;
}
*/
catch (ArrayIndexOutOfBoundsException e)
{
// No more data
doQuit = true;
}
} while (doQuit == false);
return db;
}
/**
Compare two sets of classes for serialVersionUID compatibility.
@param classInfoMap - the legacy version classes
@param currentClassInfoMap - the current build classes
@param versionName - the legacy version name
@param badPackages - a list of package prefixes to ignore for errors
@return the number of serial version mismatches
*/
private int compare(Map classInfoMap, Map currentClassInfoMap,
String versionName, String[] badPackages, StringBuffer bufferMessages)
throws IOException
{
File out = new File(versionName+".errors");
System.out.println("Writing errors to: "+out.getAbsolutePath());
FileWriter errors = new FileWriter(out);
int mismatchCount = 0;
Iterator iter = currentClassInfoMap.values().iterator();
while( iter.hasNext() )
{
ClassVersionInfo cvi = (ClassVersionInfo) iter.next();
String name = cvi.getName();
ClassVersionInfo cviLegacy = (ClassVersionInfo) classInfoMap.get(name);
if( cviLegacy != null && cvi.getSerialVersion() != cviLegacy.getSerialVersion() )
{
String msg = "serialVersionUID error for "+name
+", " + versionName + ": " + cviLegacy.getSerialVersion()
+", current: "+cvi.getSerialVersion();
// Don't count classes from badPackages
boolean isInBadPkg = false;
for(int n = 0; n < badPackages.length; n ++)
{
String pkg = badPackages[n];
if( name.startsWith(pkg) )
{
isInBadPkg = true;
break;
}
}
if (isInBadPkg)
continue;
if (mismatchCount>0)
{
bufferMessages.append(",\n");
}
bufferMessages.append(name);
mismatchCount ++;
System.err.println(msg);
errors.write(msg);
errors.write('\n');
}
}
errors.close();
// If the mismatchCount is 0 remove the error file
if( mismatchCount == 0 )
out.delete();
return mismatchCount;
}
static Map calcClassInfoMap()
throws IOException
{
SerialVersionUID.processProperties();
Map classInfoMap = SerialVersionUID.processJars();
return classInfoMap;
}
public static Test suite() throws Exception
{
TestSuite suite = new TestSuite();
suite.addTest(new SerialVersionUIDUnitTestCase("testCompat_1_4_0_GA"));
suite.addTest(new SerialVersionUIDUnitTestCase("testCompat_1_3_0_GA"));
return suite;
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(SerialVersionUIDUnitTestCase.class);
}
}