package net.jaekl.cfb.store;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
import java.sql.SQLException;
import java.util.Date;
import net.jaekl.cfb.db.TypeMismatchException;
import net.jaekl.cfb.db.driver.ConnectionMock;
import net.jaekl.cfb.db.driver.DbDriverMock;
+import net.jaekl.cfb.util.Command;
+import net.jaekl.cfb.xml.BugCollection;
import net.jaekl.cfb.xml.MessagesXmlData;
-import net.jaekl.cfb.xml.messages.MessageCollection;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-public class DbStoreTest {
+public class DbStoreTest {
+ private static final String BUG_COLLECTION_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<BugCollection version=\"2.0.3\" sequence=\"0\" timestamp=\"1425655198000\" analysisTimestamp=\"1451305502231\" release=\"\">"
+ + "<Project projectName=\"JUnit\">"
+ + "<Jar>/data/prog/findbugs-3.0.1/lib/junit.jar</Jar>"
+ + "</Project>"
+ + "<BugInstance type=\"VO_VOLATILE_INCREMENT\" priority=\"2\" abbrev=\"VO\" category=\"MT_CORRECTNESS\">"
+ + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Class>"
+ + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Method>"
+ + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Field>"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</BugInstance>"
+ + "<BugInstance type=\"DM_NUMBER_CTOR\" priority=\"2\" abbrev=\"Bx\" category=\"PERFORMANCE\">"
+ + "<Class classname=\"junit.framework.Assert\">"
+ + "<SourceLine classname=\"junit.framework.Assert\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
+ + "</Class>"
+ + "<Method classname=\"junit.framework.Assert\" name=\"assertEquals\" signature=\"(Ljava/lang/String;BB)V\" isStatic=\"true\">"
+ + "<SourceLine classname=\"junit.framework.Assert\" start=\"156\" end=\"157\" startBytecode=\"0\" endBytecode=\"86\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
+ + "</Method>"
+ + "<Method classname=\"java.lang.Byte\" name=\"<init>\" signature=\"(B)V\" isStatic=\"false\" role=\"METHOD_CALLED\">"
+ + "<SourceLine classname=\"java.lang.Byte\" start=\"307\" end=\"309\" startBytecode=\"0\" endBytecode=\"41\" sourcefile=\"Byte.java\" sourcepath=\"java/lang/Byte.java\"/>"
+ + "</Method>"
+ + "<Method classname=\"java.lang.Byte\" name=\"valueOf\" signature=\"(B)Ljava/lang/Byte;\" isStatic=\"true\" role=\"SHOULD_CALL\">"
+ + "<SourceLine classname=\"java.lang.Byte\" start=\"87\" end=\"87\" startBytecode=\"0\" endBytecode=\"33\" sourcefile=\"Byte.java\" sourcepath=\"java/lang/Byte.java\"/>"
+ + "</Method>"
+ + "<SourceLine classname=\"junit.framework.Assert\" start=\"156\" end=\"156\" startBytecode=\"6\" endBytecode=\"6\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
+ + "</BugInstance>"
+ + "<BugInstance type=\"DM_NUMBER_CTOR\" priority=\"2\" abbrev=\"Bx\" category=\"PERFORMANCE\">"
+ + "<Class classname=\"junit.framework.Assert\">"
+ + "<SourceLine classname=\"junit.framework.Assert\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
+ + "</Class>"
+ + "<Method classname=\"junit.framework.Assert\" name=\"assertEquals\" signature=\"(Ljava/lang/String;CC)V\" isStatic=\"true\">"
+ + "<SourceLine classname=\"junit.framework.Assert\" start=\"169\" end=\"170\" startBytecode=\"0\" endBytecode=\"86\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
+ + "</Method>"
+ + "<Method classname=\"java.lang.Character\" name=\"<init>\" signature=\"(C)V\" isStatic=\"false\" role=\"METHOD_CALLED\">"
+ + "<SourceLine classname=\"java.lang.Character\" start=\"2056\" end=\"2058\" startBytecode=\"0\" endBytecode=\"41\" sourcefile=\"Character.java\" sourcepath=\"java/lang/Character.java\"/>"
+ + "</Method>"
+ + "<Method classname=\"java.lang.Character\" name=\"valueOf\" signature=\"(C)Ljava/lang/Character;\" isStatic=\"true\" role=\"SHOULD_CALL\">"
+ + "<SourceLine classname=\"java.lang.Character\" start=\"2085\" end=\"2088\" startBytecode=\"0\" endBytecode=\"52\" sourcefile=\"Character.java\" sourcepath=\"java/lang/Character.java\"/>"
+ + "</Method>"
+ + "<SourceLine classname=\"junit.framework.Assert\" start=\"169\" end=\"169\" startBytecode=\"6\" endBytecode=\"6\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
+ + "</BugInstance>"
+ + "</BugCollection>";
+
+ private static final String UNKNOWN_BUG_CATEGORY_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<BugCollection version=\"2.0.3\" sequence=\"0\" timestamp=\"1425655198000\" analysisTimestamp=\"1451305502231\" release=\"\">"
+ + "<Project projectName=\"JUnit\">"
+ + "<Jar>/data/prog/findbugs-3.0.1/lib/junit.jar</Jar>"
+ + "</Project>"
+ + "<BugInstance type=\"VO_VOLATILE_INCREMENT\" priority=\"2\" abbrev=\"VO\" category=\"NON_EXTANT\">"
+ + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Class>"
+ + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Method>"
+ + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Field>"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</BugInstance>"
+ + "</BugCollection>";
+
+ private static final String UNKNOWN_BUG_PATTERN_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<BugCollection version=\"2.0.3\" sequence=\"0\" timestamp=\"1425655198000\" analysisTimestamp=\"1451305502231\" release=\"\">"
+ + "<Project projectName=\"JUnit\">"
+ + "<Jar>/data/prog/findbugs-3.0.1/lib/junit.jar</Jar>"
+ + "</Project>"
+ + "<BugInstance type=\"DN_DOES_NOT_EXIST\" priority=\"2\" abbrev=\"DN\" category=\"MT_CORRECTNESS\">"
+ + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Class>"
+ + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Method>"
+ + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</Field>"
+ + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
+ + "</BugInstance>"
+ + "</BugCollection>";
+
private DbStore m_store;
@Before
schema.setMessageMap(msgMap);
schema.ensureDbInitialized(con);
- MessageCollection msgColl = new MessageCollection();
- m_store = new DbStore(con, driver, msgColl);
+ m_store = new DbStore(con, driver, msgMap.getColl());
}
@Test
actual = m_store.getPrior(current);
assertNull(actual);
}
+
+ private BugCollection parseBugCollection(String xml) throws IOException, SAXException
+ {
+ Charset utf8 = Charset.forName(Command.UTF_8);
+
+ try ( ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes(utf8)))
+ {
+ InputSource inputSource = new InputSource(bais);
+ Analysis analysis = new Analysis(null, null);
+ analysis.parse(inputSource);
+
+ assertNotNull(analysis);
+
+ BugCollection bugColl = analysis.getBugCollection();
+ return bugColl;
+ }
+ }
+
+ @Test
+ public void testPut_null() throws StoreException, SQLException, TypeMismatchException
+ {
+ // Adding null should return false, with no exception thrown
+ boolean result = m_store.put(null);
+ assertFalse(result);
+ }
+
+ @Test
+ public void testPut_withUnknownPatternOrCategory() throws SQLException, TypeMismatchException, IOException, SAXException
+ {
+ final String[] data = { UNKNOWN_BUG_PATTERN_XML, UNKNOWN_BUG_CATEGORY_XML};
+ String projName = "ProjectName";
+ String firstVersion = "1.0.1";
+ Date firstStart = new Date(100);
+ Date firstEnd = new Date(200);
+ Analysis firstAnalysis = new Analysis(projName, firstVersion);
+ firstAnalysis.setStart(firstStart);
+ firstAnalysis.setEnd(firstEnd);
+
+ for (String xml : data) {
+ firstAnalysis.setBugCollection(parseBugCollection(xml));
+
+ try {
+ m_store.put(firstAnalysis);
+ fail("Should have thrown an exception\n" + xml);
+ }
+ catch (StoreException exc) {
+ // This is the success path
+ }
+ }
+ }
@Test
- public void testPut_thenGetPrior() throws SQLException, TypeMismatchException {
+ public void testPut_thenGetPrior() throws SQLException, TypeMismatchException, IOException, SAXException, StoreException {
String projName = "ProjectName";
String firstVersion = "1.0.1";
Date firstStart = new Date(100);
Analysis firstAnalysis = new Analysis(projName, firstVersion);
firstAnalysis.setStart(firstStart);
firstAnalysis.setEnd(firstEnd);
+ firstAnalysis.setBugCollection(parseBugCollection(BUG_COLLECTION_XML));
+ // Adding a valid Analysis object should return true
boolean result = m_store.put(firstAnalysis);
assertTrue(result);
+ // Create a second Analysis object
String secondVersion = "1.0.2";
Date secondStart = new Date(2300);
Date secondEnd = new Date(2400);
secondAnalysis.setStart(secondStart);
secondAnalysis.setEnd(secondEnd);
+ // Retrieve the first Analysis object
Analysis priorAnalysis = m_store.getPrior(secondAnalysis);
assertNotNull(priorAnalysis);
assertEquals(firstAnalysis.getProjectName(), priorAnalysis.getProjectName());
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<MessageCollection xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+ "xsi:noNamespaceSchemaLocation=\"messagecollection.xsd\">\n"
- + "<BugCategory category=\"CORRECTNESS\">\n"
+ + " <BugCategory category=\"CORRECTNESS\">\n"
+ " <Description>Correctness</Description>\n"
+ " <Abbreviation>C</Abbreviation>\n"
+ " <Details>Probable bug - an apparent coding mistake\n"
+ ""
+ " ]]>"
+ " </Details>"
- + " </BugPattern>"
+ + " </BugPattern>"
+ + " <BugPattern type=\"VO_VOLATILE_INCREMENT\">"
+ + " <ShortDescription>An increment to a volatile field isn't atomic</ShortDescription>"
+ + " <LongDescription>Increment of volatile field {2} in {1}</LongDescription>"
+ + " <Details>"
+ + " <![CDATA["
+ + " <p>This code increments a volatile field. Increments of volatile fields aren't"
+ + " atomic. If more than one thread is incrementing the field at the same time,"
+ + " increments could be lost."
+ + " </p>"
+ + " ]]>"
+ + " </Details>"
+ + " </BugPattern> "
+ + " <BugPattern type=\"DM_NUMBER_CTOR\">"
+ + " <ShortDescription>Method invokes inefficient Number constructor; use static valueOf instead</ShortDescription>"
+ + " <LongDescription>{1} invokes inefficient {2} constructor; use {3} instead</LongDescription>"
+ + " <Details>"
+ + " <![CDATA["
+ + " <p>"
+ + " Using <code>new Integer(int)</code> is guaranteed to always result in a new object whereas"
+ + " <code>Integer.valueOf(int)</code> allows caching of values to be done by the compiler, class library, or JVM."
+ + " Using of cached values avoids object allocation and the code will be faster."
+ + " </p>"
+ + " <p>"
+ + " Values between -128 and 127 are guaranteed to have corresponding cached instances"
+ + " and using <code>valueOf</code> is approximately 3.5 times faster than using constructor."
+ + " For values outside the constant range the performance of both styles is the same."
+ + " </p>"
+ + " <p>"
+ + " Unless the class must be compatible with JVMs predating Java 1.5,"
+ + " use either autoboxing or the <code>valueOf()</code> method when creating instances of"
+ + " <code>Long</code>, <code>Integer</code>, <code>Short</code>, <code>Character</code>, and <code>Byte</code>."
+ + " </p>"
+ + " ]]>"
+ + " </Details>"
+ + " </BugPattern>"
+ "</MessageCollection>";
}