Add unit tests. Make DbStore handle cases where the bug type or category
[cfb.git] / test / net / jaekl / cfb / store / DbStoreTest.java
1 package net.jaekl.cfb.store;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotNull;
6 import static org.junit.Assert.assertNull;
7 import static org.junit.Assert.assertTrue;
8 import static org.junit.Assert.fail;
9
10 import java.io.ByteArrayInputStream;
11 import java.io.FileNotFoundException;
12 import java.io.IOException;
13 import java.io.UnsupportedEncodingException;
14 import java.nio.charset.Charset;
15 import java.sql.SQLException;
16 import java.util.Date;
17
18 import net.jaekl.cfb.analyze.Analysis;
19 import net.jaekl.cfb.analyze.MessageMap;
20 import net.jaekl.cfb.db.CfbSchema;
21 import net.jaekl.cfb.db.TypeMismatchException;
22 import net.jaekl.cfb.db.driver.ConnectionMock;
23 import net.jaekl.cfb.db.driver.DbDriverMock;
24 import net.jaekl.cfb.util.Command;
25 import net.jaekl.cfb.xml.BugCollection;
26 import net.jaekl.cfb.xml.MessagesXmlData;
27
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.xml.sax.InputSource;
31 import org.xml.sax.SAXException;
32
33 public class DbStoreTest {      
34         private static final String BUG_COLLECTION_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
35                         + "<BugCollection version=\"2.0.3\" sequence=\"0\" timestamp=\"1425655198000\" analysisTimestamp=\"1451305502231\" release=\"\">"
36                         + "<Project projectName=\"JUnit\">"
37                         + "<Jar>/data/prog/findbugs-3.0.1/lib/junit.jar</Jar>"
38                         + "</Project>"
39                         + "<BugInstance type=\"VO_VOLATILE_INCREMENT\" priority=\"2\" abbrev=\"VO\" category=\"MT_CORRECTNESS\">"
40                         + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
41                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
42                         + "</Class>"
43                         + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
44                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
45                         + "</Method>"
46                         + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
47                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
48                         + "</Field>"
49                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
50                         + "</BugInstance>"
51                         + "<BugInstance type=\"DM_NUMBER_CTOR\" priority=\"2\" abbrev=\"Bx\" category=\"PERFORMANCE\">"
52                         + "<Class classname=\"junit.framework.Assert\">"
53                         + "<SourceLine classname=\"junit.framework.Assert\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
54                         + "</Class>"
55                         + "<Method classname=\"junit.framework.Assert\" name=\"assertEquals\" signature=\"(Ljava/lang/String;BB)V\" isStatic=\"true\">"
56                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"156\" end=\"157\" startBytecode=\"0\" endBytecode=\"86\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
57                         + "</Method>"
58                         + "<Method classname=\"java.lang.Byte\" name=\"&lt;init&gt;\" signature=\"(B)V\" isStatic=\"false\" role=\"METHOD_CALLED\">"
59                         + "<SourceLine classname=\"java.lang.Byte\" start=\"307\" end=\"309\" startBytecode=\"0\" endBytecode=\"41\" sourcefile=\"Byte.java\" sourcepath=\"java/lang/Byte.java\"/>"
60                         + "</Method>"
61                         + "<Method classname=\"java.lang.Byte\" name=\"valueOf\" signature=\"(B)Ljava/lang/Byte;\" isStatic=\"true\" role=\"SHOULD_CALL\">"
62                         + "<SourceLine classname=\"java.lang.Byte\" start=\"87\" end=\"87\" startBytecode=\"0\" endBytecode=\"33\" sourcefile=\"Byte.java\" sourcepath=\"java/lang/Byte.java\"/>"
63                         + "</Method>"
64                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"156\" end=\"156\" startBytecode=\"6\" endBytecode=\"6\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
65                         + "</BugInstance>"
66                         + "<BugInstance type=\"DM_NUMBER_CTOR\" priority=\"2\" abbrev=\"Bx\" category=\"PERFORMANCE\">"
67                         + "<Class classname=\"junit.framework.Assert\">"
68                         + "<SourceLine classname=\"junit.framework.Assert\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
69                         + "</Class>"
70                         + "<Method classname=\"junit.framework.Assert\" name=\"assertEquals\" signature=\"(Ljava/lang/String;CC)V\" isStatic=\"true\">"
71                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"169\" end=\"170\" startBytecode=\"0\" endBytecode=\"86\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
72                         + "</Method>"
73                         + "<Method classname=\"java.lang.Character\" name=\"&lt;init&gt;\" signature=\"(C)V\" isStatic=\"false\" role=\"METHOD_CALLED\">"
74                         + "<SourceLine classname=\"java.lang.Character\" start=\"2056\" end=\"2058\" startBytecode=\"0\" endBytecode=\"41\" sourcefile=\"Character.java\" sourcepath=\"java/lang/Character.java\"/>"
75                         + "</Method>"
76                         + "<Method classname=\"java.lang.Character\" name=\"valueOf\" signature=\"(C)Ljava/lang/Character;\" isStatic=\"true\" role=\"SHOULD_CALL\">"
77                         + "<SourceLine classname=\"java.lang.Character\" start=\"2085\" end=\"2088\" startBytecode=\"0\" endBytecode=\"52\" sourcefile=\"Character.java\" sourcepath=\"java/lang/Character.java\"/>"
78                         + "</Method>"
79                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"169\" end=\"169\" startBytecode=\"6\" endBytecode=\"6\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
80                         + "</BugInstance>"
81                         + "</BugCollection>";
82         
83         private static final String UNKNOWN_BUG_CATEGORY_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
84                         + "<BugCollection version=\"2.0.3\" sequence=\"0\" timestamp=\"1425655198000\" analysisTimestamp=\"1451305502231\" release=\"\">"
85                         + "<Project projectName=\"JUnit\">"
86                         + "<Jar>/data/prog/findbugs-3.0.1/lib/junit.jar</Jar>"
87                         + "</Project>"
88                         + "<BugInstance type=\"VO_VOLATILE_INCREMENT\" priority=\"2\" abbrev=\"VO\" category=\"NON_EXTANT\">"
89                         + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
90                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
91                         + "</Class>"
92                         + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
93                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
94                         + "</Method>"
95                         + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
96                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
97                         + "</Field>"
98                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
99                         + "</BugInstance>"
100                         + "</BugCollection>";
101
102         private static final String UNKNOWN_BUG_PATTERN_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
103                         + "<BugCollection version=\"2.0.3\" sequence=\"0\" timestamp=\"1425655198000\" analysisTimestamp=\"1451305502231\" release=\"\">"
104                         + "<Project projectName=\"JUnit\">"
105                         + "<Jar>/data/prog/findbugs-3.0.1/lib/junit.jar</Jar>"
106                         + "</Project>"
107                         + "<BugInstance type=\"DN_DOES_NOT_EXIST\" priority=\"2\" abbrev=\"DN\" category=\"MT_CORRECTNESS\">"
108                         + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
109                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
110                         + "</Class>"
111                         + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
112                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
113                         + "</Method>"
114                         + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
115                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
116                         + "</Field>"
117                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
118                         + "</BugInstance>"
119                         + "</BugCollection>";
120         
121         private DbStore m_store;
122         
123         @Before
124         public void setUp() throws SQLException, FileNotFoundException, UnsupportedEncodingException, IOException, SAXException 
125         {
126                 MessageMap msgMap = new MessageMap();
127                 msgMap.parse(new InputSource(new ByteArrayInputStream(MessagesXmlData.XML.getBytes("UTF-8"))));
128                 
129                 DbDriverMock driver = new DbDriverMock();
130                 CfbSchema schema = new CfbSchema(driver);
131                 ConnectionMock con = new ConnectionMock();
132
133                 schema.setMessageMap(msgMap);
134                 schema.ensureDbInitialized(con);                
135
136                 m_store = new DbStore(con, driver, msgMap.getColl());
137         }
138
139         @Test
140         public void testGetPrior_withNoEntries() throws SQLException, TypeMismatchException {
141                 // First test:  getPrior(null) should return null
142                 Analysis actual = m_store.getPrior(null);
143                 assertNull(actual);
144                 
145                 // Second test:  getPrior(current) with no data in the DB should return null
146                 String projName = "ProjectName";
147                 String version = "1.2.3";
148                 Date start = new Date(1234567890);
149                 Date end = new Date(1234567900);
150                 Analysis current = new Analysis(projName, version);
151                 current.setStart(start);
152                 current.setEnd(end);
153                 actual = m_store.getPrior(current);
154                 assertNull(actual);
155         }
156         
157         private BugCollection parseBugCollection(String xml) throws IOException, SAXException
158         {
159                 Charset utf8 = Charset.forName(Command.UTF_8);
160                 
161                 try ( ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes(utf8)))
162                 {
163                         InputSource inputSource = new InputSource(bais); 
164                         Analysis analysis = new Analysis(null, null);
165                         analysis.parse(inputSource);
166                         
167                         assertNotNull(analysis);
168                         
169                         BugCollection bugColl = analysis.getBugCollection();
170                         return bugColl;
171                 }
172         }
173         
174         @Test
175         public void testPut_null() throws StoreException, SQLException, TypeMismatchException
176         {
177                 // Adding null should return false, with no exception thrown
178                 boolean result = m_store.put(null);
179                 assertFalse(result);            
180         }
181         
182         @Test
183         public void testPut_withUnknownPatternOrCategory() throws SQLException, TypeMismatchException, IOException, SAXException 
184         {
185                 final String[] data = { UNKNOWN_BUG_PATTERN_XML, UNKNOWN_BUG_CATEGORY_XML};
186                 String projName = "ProjectName";
187                 String firstVersion = "1.0.1";
188                 Date firstStart = new Date(100);
189                 Date firstEnd = new Date(200);
190                 Analysis firstAnalysis = new Analysis(projName, firstVersion);
191                 firstAnalysis.setStart(firstStart);
192                 firstAnalysis.setEnd(firstEnd);
193
194                 for (String xml : data) {
195                         firstAnalysis.setBugCollection(parseBugCollection(xml));
196
197                         try {
198                                 m_store.put(firstAnalysis);
199                                 fail("Should have thrown an exception\n" + xml);
200                         }
201                         catch (StoreException exc) {
202                                 // This is the success path
203                         }
204                 }
205         }
206
207         @Test
208         public void testPut_thenGetPrior() throws SQLException, TypeMismatchException, IOException, SAXException, StoreException {
209                 String projName = "ProjectName";
210                 String firstVersion = "1.0.1";
211                 Date firstStart = new Date(100);
212                 Date firstEnd = new Date(200);
213                 Analysis firstAnalysis = new Analysis(projName, firstVersion);
214                 firstAnalysis.setStart(firstStart);
215                 firstAnalysis.setEnd(firstEnd);
216                 firstAnalysis.setBugCollection(parseBugCollection(BUG_COLLECTION_XML));
217                 
218                 // Adding a valid Analysis object should return true
219                 boolean result = m_store.put(firstAnalysis);
220                 assertTrue(result);
221                 
222                 // Create a second Analysis object
223                 String secondVersion = "1.0.2";
224                 Date secondStart = new Date(2300);
225                 Date secondEnd = new Date(2400);
226                 Analysis secondAnalysis = new Analysis(projName, secondVersion);
227                 secondAnalysis.setStart(secondStart);
228                 secondAnalysis.setEnd(secondEnd);
229                 
230                 // Retrieve the first Analysis object
231                 Analysis priorAnalysis = m_store.getPrior(secondAnalysis);
232                 assertNotNull(priorAnalysis);
233                 assertEquals(firstAnalysis.getProjectName(), priorAnalysis.getProjectName());
234                 assertEquals(firstAnalysis.getBuildNumber(), priorAnalysis.getBuildNumber());
235                 assertEquals(firstAnalysis.getStart(), priorAnalysis.getStart());
236                 assertEquals(firstAnalysis.getEnd(), priorAnalysis.getEnd());
237                 assertEquals(firstAnalysis.getBugCollection(), priorAnalysis.getBugCollection());
238         }
239 /*
240         @Test
241         public void testGetBugType() {
242                 fail("Not yet implemented");
243         }
244
245         @Test
246         public void testGetCategoryName() {
247                 fail("Not yet implemented");
248         }
249
250         @Test
251         public void testGetLoc() {
252                 fail("Not yet implemented");
253         }
254
255         @Test
256         public void testGetLocId() {
257                 fail("Not yet implemented");
258         }
259
260         @Test
261         public void testFindLocId() {
262                 fail("Not yet implemented");
263         }
264
265         @Test
266         public void testStoreLoc() {
267                 fail("Not yet implemented");
268         }
269
270         @Test
271         public void testGetVarIdBugInstance() {
272                 fail("Not yet implemented");
273         }
274
275         @Test
276         public void testGetVar() {
277                 fail("Not yet implemented");
278         }
279
280         @Test
281         public void testGetVarIdLocalVariable() {
282                 fail("Not yet implemented");
283         }
284
285         @Test
286         public void testFindVarId() {
287                 fail("Not yet implemented");
288         }
289
290         @Test
291         public void testStoreVar() {
292                 fail("Not yet implemented");
293         }
294
295         @Test
296         public void testGetPriorId() {
297                 fail("Not yet implemented");
298         }
299
300         @Test
301         public void testGetAnalysis() {
302                 fail("Not yet implemented");
303         }
304
305         @Test
306         public void testGetBugCollection() {
307                 fail("Not yet implemented");
308         }
309 */
310 }