Add unit tests. Make DbStore handle cases where the bug type or category
[cfb.git] / test / net / jaekl / cfb / store / DbStoreTest.java
index c4e2668448eeddd692385366131d3d44993aa0e7..f269a9cd126205bfe0a0dc2db63ff9a99fc37536 100644 (file)
@@ -1,11 +1,17 @@
 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;
 
@@ -15,15 +21,103 @@ import net.jaekl.cfb.db.CfbSchema;
 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=\"&lt;init&gt;\" 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=\"&lt;init&gt;\" 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
@@ -39,8 +133,7 @@ public class DbStoreTest {
                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
@@ -60,9 +153,59 @@ public class DbStoreTest {
                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);
@@ -70,10 +213,13 @@ public class DbStoreTest {
                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);
@@ -81,6 +227,7 @@ public class DbStoreTest {
                secondAnalysis.setStart(secondStart);
                secondAnalysis.setEnd(secondEnd);
                
+               // Retrieve the first Analysis object
                Analysis priorAnalysis = m_store.getPrior(secondAnalysis);
                assertNotNull(priorAnalysis);
                assertEquals(firstAnalysis.getProjectName(), priorAnalysis.getProjectName());