Add unit tests. Make DbStore handle cases where the bug type or category
authorChris Jaekl <cejaekl@yahoo.com>
Wed, 30 Dec 2015 06:11:50 +0000 (15:11 +0900)
committerChris Jaekl <cejaekl@yahoo.com>
Wed, 30 Dec 2015 06:11:50 +0000 (15:11 +0900)
is not present in the message collection more gracefully.

prod/cfb.properties
prod/net/jaekl/cfb/CFB.java
prod/net/jaekl/cfb/CfbBundle.java
prod/net/jaekl/cfb/store/DbStore.java
prod/net/jaekl/cfb/xml/messages/BugCategory.java
prod/net/jaekl/cfb/xml/messages/BugPattern.java
prod/net/jaekl/cfb/xml/messages/MessageCollection.java
test/net/jaekl/cfb/store/DbStoreTest.java
test/net/jaekl/cfb/xml/BugInstanceTest.java
test/net/jaekl/cfb/xml/MessagesXmlData.java

index 7ddb59db1fa2c403b81f7ef3159191644b074083..f27ec184f8c6b262f657501781c4b3e1f2ed4b86 100644 (file)
@@ -1,5 +1,7 @@
 analysis.failed=Attempt to analyze source code failed.  Will now stop.
 analyzed.at=Analyzed at {0}
+bug.category.unknown=Internal error:  The bug category {0} is unknown.  Perhaps the Findbugs versions used to generate the report, and the FindBugs messages.xml, do not match?
+bug.type.unknown=Internal error:  The bug pattern type {0} is unknown.  Perhaps the Findbugs versions used to generate the report, and eth FindBugs messages.xml, do not match?
 cannot.connect.to.db=Unable to connect to, or to initialize, database {2} on {0}:{1} as user {3}.
 cannot.exec=Got result code {1} when attempting to execute command-line:  {0}
 cannot.send.mail=Attempt to send email to {0} failed:  {1}
index 63271ec9cdd5c3036b2875ab68a59e8a53fce7b3..639a73198088ffcf7e9335286dbeb4932512ad0a 100644 (file)
@@ -29,6 +29,7 @@ import net.jaekl.cfb.db.TypeMismatchException;
 import net.jaekl.cfb.db.driver.DbDriver;
 import net.jaekl.cfb.db.driver.PostgresqlDriver;
 import net.jaekl.cfb.store.DbStore;
+import net.jaekl.cfb.store.StoreException;
 import net.jaekl.qd.xml.XmlParseException;
 
 import org.apache.commons.cli.CommandLine;
@@ -235,6 +236,10 @@ public class CFB {
                        Notifier notifier = new Notifier(m_bundle, m_config);
                        notifier.sendEmailIfNeeded(pw, report);
                }
+               catch (StoreException exc) {
+                       exc.printStackTrace(pw);
+                       return;
+               }
                catch (SQLException exc) {
                        reportUnableToConnect(pw, exc);
                        return;
index 0cb7a4082cd574a27b04882d0314c0c92606e783..5f5aa9ee8b52ce303cf45c623a8853800c32b1e4 100644 (file)
@@ -13,6 +13,8 @@ import net.jaekl.qd.QDBundleFactory;
 public class CfbBundle {
        public static final String ANALYSIS_FAILED = "analysis.failed";
        public static final String ANALYZED_AT = "analyzed.at";
+       public static final String BUG_CATEGORY_UNKNOWN = "bug.category.unknown";
+       public static final String BUG_TYPE_UNKNOWN = "bug.type.unknown";
        public static final String CANNOT_CONNECT = "cannot.connect.to.db";
        public static final String CANNOT_EXEC = "cannot.exec";
        public static final String CANNOT_SEND_MAIL = "cannot.send.mail";
index 3860ca5637e5c2fd31f93bec95b1d59900dec6d5..ed22291387c14c8047593d7b1a11932633df6361 100644 (file)
@@ -3,7 +3,9 @@ package net.jaekl.cfb.store;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.List;
+import java.util.Locale;
 
+import net.jaekl.cfb.CfbBundle;
 import net.jaekl.cfb.analyze.Analysis;
 import net.jaekl.cfb.db.CfbSchema;
 import net.jaekl.cfb.db.Column;
@@ -17,6 +19,8 @@ import net.jaekl.cfb.db.driver.DbDriver;
 import net.jaekl.cfb.xml.BugCollection;
 import net.jaekl.cfb.xml.BugInstance;
 import net.jaekl.cfb.xml.LocalVariable;
+import net.jaekl.cfb.xml.messages.BugCategory;
+import net.jaekl.cfb.xml.messages.BugPattern;
 import net.jaekl.cfb.xml.messages.MessageCollection;
 
 public class DbStore {
@@ -42,7 +46,9 @@ public class DbStore {
                return getAnalysis(priorId);
        }
        
-       public boolean put(Analysis analysis) throws SQLException, TypeMismatchException {
+       public boolean put(Analysis analysis) throws SQLException, TypeMismatchException, StoreException {
+               CfbBundle bundle = CfbBundle.getInst(Locale.getDefault());
+               
                if (null == analysis) {
                        return false;
                }
@@ -82,6 +88,13 @@ public class DbStore {
                        Location secondLoc = (locs.size() > 1) ? locs.get(1) : null;
                        Location thirdLoc  = (locs.size() > 2) ? locs.get(2) : null;
                        
+                       if (BugPattern.UNKNOWN.getId() == bugId) {
+                               throw new StoreException(bundle.get(CfbBundle.BUG_TYPE_UNKNOWN, ""+bug.getType()));
+                       }
+                       if (BugCategory.UNKNOWN.getId() == categoryId) {
+                               throw new StoreException(bundle.get(CfbBundle.BUG_CATEGORY_UNKNOWN, ""+bug.getCategory()));
+                       }
+                       
                        values[row][0] = foundId;
                        values[row][1] = runId;
                        values[row][2] = bugId;
index 757aacfb124472981e597da46b6c826da810e1ed..7adb0b515d816b403044b039318d4789ff95b9bb 100644 (file)
@@ -15,6 +15,8 @@ public class BugCategory extends ParseResult {
        static final String TAG = "BugCategory";
        static final String[] INTERNAL = { DESCRIPTION, ABBREVIATION, DETAILS };
        static final Object[][] EXTERNAL = { };
+       
+       public static final BugCategory UNKNOWN = new BugCategory(-2);
 
        String m_category;
        String m_descr;
@@ -25,9 +27,16 @@ public class BugCategory extends ParseResult {
        public BugCategory() 
        {
                super(TAG, INTERNAL, EXTERNAL);
+               m_id = (-1);
                m_category = m_descr = m_abbrev = m_details = "";
        }
        
+       BugCategory(long id)
+       {
+               this();
+               m_id = (-2); 
+       }
+       
        public String getCategory() { return m_category; }
        public String getDescr() { return m_descr; }
        public String getAbbrev() { return m_abbrev; }
index e8e381c55410cd0bb1f16752a1751c5ad40f05a1..1493ac6381b43c66d1999ddd55bc6c68bd2318d9 100644 (file)
@@ -16,6 +16,8 @@ public class BugPattern extends ParseResult {
        static final String[] INTERNAL = { SHORT, LONG, DETAILS };
        static final Object[][] EXTERNAL = {  };
        
+       public static final BugPattern UNKNOWN = new BugPattern(-2); 
+       
        String m_type;
        String m_short;
        String m_long;
@@ -25,9 +27,15 @@ public class BugPattern extends ParseResult {
        public BugPattern() 
        {
                super(TAG, INTERNAL, EXTERNAL);
+               m_id = (-1);
                m_type = m_short = m_long = m_details = "";
        }
        
+       BugPattern(long id) {
+               this();
+               m_id = id;
+       }
+       
        public String getType() { return m_type; }
        public String getShort() { return m_short; }
        public String getLong() { return m_long; }
index ba4b97ca7b45797b214b6959987e14bdf2bd803f..560e04e267bec04f8f9e07af63ddc796c4b572a0 100644 (file)
@@ -23,10 +23,22 @@ public class MessageCollection extends ParseResult {
        }
        
        public Collection<BugCategory> getCategories() { return m_categories.values(); }
-       public BugCategory getCategory(String category) { return m_categories.get(category); }
+       public BugCategory getCategory(String category) { 
+               BugCategory cat = m_categories.get(category); 
+               if (null == cat) {
+                       cat = BugCategory.UNKNOWN;
+               }
+               return cat;
+       }
        
        public Collection<BugPattern> getPatterns() { return m_patterns.values(); }
-       public BugPattern getPattern(String type) { return m_patterns.get(type); }
+       public BugPattern getPattern(String type) { 
+               BugPattern pat = m_patterns.get(type);
+               if (null == pat) {
+                       pat = BugPattern.UNKNOWN;
+               }
+               return pat;
+       }
 
        @Override
        public void endContents(String uri, String localName, String qName, String chars) 
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());
index b7e98fbf7aee5bfb4f27961615273c36b23090ab..0c734bcfa933e6be20a353d99e5eaab0cbe52486 100644 (file)
@@ -9,7 +9,7 @@ import org.junit.Test;
 public class BugInstanceTest {
 
        @Test
-       public void testGetPrincpalLocation() {
+       public void testGetPrincipalLocation() {
                Location[][][] data = 
                {
                        {
index 5b81dcadcef7bc483542e5a26c0f336622500442..94e3f09ff72454fd188af460fc254f56e2cf82a1 100644 (file)
@@ -5,7 +5,7 @@ public class MessagesXmlData {
                  "<?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"
@@ -222,6 +222,41 @@ public class MessagesXmlData {
                + ""
                + "             ]]>"
                + "                 </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>";
 }