Further unit tests: CFB and Delta
[cfb.git] / test / net / jaekl / cfb / analyze / DeltaTest.java
1 package net.jaekl.cfb.analyze;
2
3 import static org.junit.Assert.*;
4
5 import java.io.ByteArrayInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.IOException;
8 import java.util.HashSet;
9
10 import net.jaekl.cfb.util.Command;
11 import net.jaekl.cfb.xml.BugInstance;
12
13 import org.junit.Test;
14 import org.xml.sax.InputSource;
15 import org.xml.sax.SAXException;
16
17 public class DeltaTest {
18         private static final String DM_DEFAULT_ENCODING = ""
19                         + "<BugInstance type=\"DM_DEFAULT_ENCODING\" priority=\"1\" rank=\"19\" abbrev=\"Dm\" category=\"I18N\">\n"
20                         + "<Class classname=\"net.jaekl.cfb.CFB\">\n"
21                         + "<SourceLine classname=\"net.jaekl.cfb.CFB\" start=\"32\" end=\"119\" sourcefile=\"CFB.java\" sourcepath=\"net/jaekl/cfb/CFB.java\"/>\n"
22                         + "</Class>\n"
23                         + "<Method classname=\"net.jaekl.cfb.CFB\" name=\"main\" signature=\"([Ljava/lang/String;)V\" isStatic=\"true\">\n"
24                         + "<SourceLine classname=\"net.jaekl.cfb.CFB\" start=\"112\" end=\"119\" startBytecode=\"0\" endBytecode=\"266\" sourcefile=\"CFB.java\" sourcepath=\"net/jaekl/cfb/CFB.java\"/>\n"
25                         + "</Method>\n"
26                         + "<Method classname=\"java.io.PrintWriter\" name=\"&lt;init&gt;\" signature=\"(Ljava/io/OutputStream;)V\" isStatic=\"false\" role=\"METHOD_CALLED\">\n"
27                         + "<SourceLine classname=\"java.io.PrintWriter\" start=\"131\" end=\"132\" startBytecode=\"0\" endBytecode=\"62\" sourcefile=\"PrintWriter.java\" sourcepath=\"java/io/PrintWriter.java\"/>\n"
28                         + "</Method>\n"
29                         + "<SourceLine classname=\"net.jaekl.cfb.CFB\" start=\"114\" end=\"114\" startBytecode=\"22\" endBytecode=\"22\" sourcefile=\"CFB.java\" sourcepath=\"net/jaekl/cfb/CFB.java\"/>\n"
30                         + "</BugInstance>\n";
31         
32         private static final String RCN_REDUNDANT_NULL_CHECK = ""
33                         + "<BugInstance type=\"RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE\" priority=\"2\" rank=\"18\" abbrev=\"RCN\" category=\"STYLE\">\n"
34                         + "<Class classname=\"net.jaekl.cfb.CFB\">\n"
35                         + "<SourceLine classname=\"net.jaekl.cfb.CFB\" start=\"32\" end=\"119\" sourcefile=\"CFB.java\" sourcepath=\"net/jaekl/cfb/CFB.java\"/>\n"
36                         + "</Class>\n"
37                         + "<Method classname=\"net.jaekl.cfb.CFB\" name=\"doMain\" signature=\"(Ljava/io/PrintWriter;[Ljava/lang/String;)V\" isStatic=\"false\">\n"
38                         + "<SourceLine classname=\"net.jaekl.cfb.CFB\" start=\"96\" end=\"109\" startBytecode=\"0\" endBytecode=\"407\" sourcefile=\"CFB.java\" sourcepath=\"net/jaekl/cfb/CFB.java\"/>\n"
39                         + "</Method>\n"
40                         + "<LocalVariable name=\"con\" register=\"5\" pc=\"44\" role=\"LOCAL_VARIABLE_VALUE_OF\"/>\n"
41                         + "<Method classname=\"net.jaekl.cfb.db.driver.DbDriver\" name=\"connect\" signature=\"(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;\" isStatic=\"false\" role=\"METHOD_RETURN_VALUE_OF\">\n"
42                         + "<SourceLine classname=\"net.jaekl.cfb.db.driver.DbDriver\" sourcefile=\"DbDriver.java\" sourcepath=\"net/jaekl/cfb/db/driver/DbDriver.java\"/>\n"
43                         + "</Method>\n"
44                         + "<SourceLine classname=\"net.jaekl.cfb.CFB\" start=\"101\" end=\"101\" startBytecode=\"46\" endBytecode=\"46\" sourcefile=\"CFB.java\" sourcepath=\"net/jaekl/cfb/CFB.java\" role=\"SOURCE_REDUNDANT_NULL_CHECK\"/>\n"
45                         + "</BugInstance>\n";
46
47         private static String VO_VOLATILE_INCREMENT = ""
48                         + "<BugInstance type=\"VO_VOLATILE_INCREMENT\" priority=\"2\" abbrev=\"VO\" category=\"MT_CORRECTNESS\">"
49                         + "<Class classname=\"junit.extensions.ActiveTestSuite\">"
50                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
51                         + "</Class>"
52                         + "<Method classname=\"junit.extensions.ActiveTestSuite\" name=\"runFinished\" signature=\"()V\" isStatic=\"false\">"
53                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"69\" startBytecode=\"0\" endBytecode=\"64\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
54                         + "</Method>"
55                         + "<Field classname=\"junit.extensions.ActiveTestSuite\" name=\"fActiveTestDeathCount\" signature=\"I\" isStatic=\"false\">"
56                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
57                         + "</Field>"
58                         + "<SourceLine classname=\"junit.extensions.ActiveTestSuite\" start=\"67\" end=\"67\" startBytecode=\"7\" endBytecode=\"7\" sourcefile=\"ActiveTestSuite.java\" sourcepath=\"junit/extensions/ActiveTestSuite.java\"/>"
59                         + "</BugInstance>";
60         
61         private static final String DM_NUMBER_CTOR_156 = ""
62                         + "<BugInstance type=\"DM_NUMBER_CTOR\" priority=\"2\" abbrev=\"Bx\" category=\"PERFORMANCE\">"
63                         + "<Class classname=\"junit.framework.Assert\">"
64                         + "<SourceLine classname=\"junit.framework.Assert\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
65                         + "</Class>"
66                         + "<Method classname=\"junit.framework.Assert\" name=\"assertEquals\" signature=\"(Ljava/lang/String;BB)V\" isStatic=\"true\">"
67                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"156\" end=\"157\" startBytecode=\"0\" endBytecode=\"86\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
68                         + "</Method>"
69                         + "<Method classname=\"java.lang.Byte\" name=\"&lt;init&gt;\" signature=\"(B)V\" isStatic=\"false\" role=\"METHOD_CALLED\">"
70                         + "<SourceLine classname=\"java.lang.Byte\" start=\"307\" end=\"309\" startBytecode=\"0\" endBytecode=\"41\" sourcefile=\"Byte.java\" sourcepath=\"java/lang/Byte.java\"/>"
71                         + "</Method>"
72                         + "<Method classname=\"java.lang.Byte\" name=\"valueOf\" signature=\"(B)Ljava/lang/Byte;\" isStatic=\"true\" role=\"SHOULD_CALL\">"
73                         + "<SourceLine classname=\"java.lang.Byte\" start=\"87\" end=\"87\" startBytecode=\"0\" endBytecode=\"33\" sourcefile=\"Byte.java\" sourcepath=\"java/lang/Byte.java\"/>"
74                         + "</Method>"
75                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"156\" end=\"156\" startBytecode=\"6\" endBytecode=\"6\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
76                         + "</BugInstance>";
77
78         private static final String DM_NUMBER_CTOR_169 = ""
79                         + "<BugInstance type=\"DM_NUMBER_CTOR\" priority=\"2\" abbrev=\"Bx\" category=\"PERFORMANCE\">"
80                         + "<Class classname=\"junit.framework.Assert\">"
81                         + "<SourceLine classname=\"junit.framework.Assert\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
82                         + "</Class>"
83                         + "<Method classname=\"junit.framework.Assert\" name=\"assertEquals\" signature=\"(Ljava/lang/String;CC)V\" isStatic=\"true\">"
84                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"169\" end=\"170\" startBytecode=\"0\" endBytecode=\"86\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
85                         + "</Method>"
86                         + "<Method classname=\"java.lang.Character\" name=\"&lt;init&gt;\" signature=\"(C)V\" isStatic=\"false\" role=\"METHOD_CALLED\">"
87                         + "<SourceLine classname=\"java.lang.Character\" start=\"2056\" end=\"2058\" startBytecode=\"0\" endBytecode=\"41\" sourcefile=\"Character.java\" sourcepath=\"java/lang/Character.java\"/>"
88                         + "</Method>"
89                         + "<Method classname=\"java.lang.Character\" name=\"valueOf\" signature=\"(C)Ljava/lang/Character;\" isStatic=\"true\" role=\"SHOULD_CALL\">"
90                         + "<SourceLine classname=\"java.lang.Character\" start=\"2085\" end=\"2088\" startBytecode=\"0\" endBytecode=\"52\" sourcefile=\"Character.java\" sourcepath=\"java/lang/Character.java\"/>"
91                         + "</Method>"
92                         + "<SourceLine classname=\"junit.framework.Assert\" start=\"169\" end=\"169\" startBytecode=\"6\" endBytecode=\"6\" sourcefile=\"Assert.java\" sourcepath=\"junit/framework/Assert.java\"/>"
93                         + "</BugInstance>";
94
95         private static final String PROLOGUE = ""
96                         + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
97                         + "<BugCollection version=\"3.0.1\" sequence=\"0\" timestamp=\"1440757060000\" analysisTimestamp=\"1440761315847\" release=\"\">\n"
98                         + "<Project projectName=\"CFB\">\n"
99                         + "<Jar>/home/chris/prog/././cfb/bin</Jar>\n"
100                         + "<SrcDir>/home/chris/prog/././cfb/src</SrcDir>\n"
101                         + "</Project>\n";
102         
103         private static final String EPILOGUE = ""
104                         + "</BugCollection>\n";
105
106         private Analysis analysisFromXml(String xml, String projectName, String version) 
107                 throws FileNotFoundException, IOException, SAXException 
108         {
109                 Analysis analysis = new Analysis(projectName, version);
110                 ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes(Command.UTF_8));
111                 InputSource inputSource = new InputSource(bais); 
112                 analysis.parse(inputSource);
113                 
114                 return analysis;
115         }
116         
117         private HashSet<String> buildSet(String[][] bugSpecs, int from, int to)
118         {
119                 HashSet<String> set = new HashSet<String>();
120                 for (int i = from; i <= to; ++i) {
121                         set.add(bugSpecs[i][1]);
122                 }
123                 
124                 return set;
125         }
126         
127         private String buildXml(String[][] bugSpecs, int from, int to)
128         {
129                 StringBuilder sb = new StringBuilder(PROLOGUE);
130                 for (int i = from; i <= to; ++i) {
131                         sb.append(bugSpecs[i][0]);
132                 }
133                 sb.append(EPILOGUE);
134                 
135                 return sb.toString();           
136         }
137         
138         private boolean contains(BugInstance[] bugs, String bugName)
139         {
140                 for (BugInstance bug : bugs) {
141                         if (bugName.equals(bug.getType())) {
142                                 return true;
143                         }
144                 }
145                 return false;
146         }
147         
148         private void execDeltaForRanges (String[][] bugSpecs, int w, int x, int y, int z) throws FileNotFoundException, IOException, SAXException 
149         {
150                 final String PROJECT_NAME = "ProjectName";
151                 String firstXml = buildXml(bugSpecs, w, x);
152                 String secondXml = buildXml(bugSpecs, y, z);
153                 HashSet<String> firstSet = buildSet(bugSpecs, w, x);
154                 HashSet<String> secondSet = buildSet(bugSpecs, y, z);
155                 
156                 Analysis first = analysisFromXml(firstXml, PROJECT_NAME, "1.0.1");
157                 Analysis second = analysisFromXml(secondXml, PROJECT_NAME, "1.0.2");
158                 
159                 assertNotNull(first);
160                 assertNotNull(second);
161                 
162                 Delta delta = new Delta(first, second);
163
164                 for (int i = 0; i < bugSpecs.length; ++i) {
165                         String bugName = bugSpecs[i][1];
166                         if (firstSet.contains(bugName) && secondSet.contains(bugName)) {
167                                 assertTrue(contains(delta.getCommon(), bugName));
168                                 assertFalse(contains(delta.getFixed(), bugName));
169                                 assertFalse(contains(delta.getNew(), bugName));
170                         }
171                         else if (firstSet.contains(bugName) && !secondSet.contains(bugName)) {
172                                 assertFalse(contains(delta.getCommon(), bugName));
173                                 assertTrue(contains(delta.getFixed(), bugName));
174                                 assertFalse(contains(delta.getNew(), bugName));
175                         }
176                         else if (!firstSet.contains(bugName) && secondSet.contains(bugName)) {
177                                 assertFalse(contains(delta.getCommon(), bugName));
178                                 assertFalse(contains(delta.getFixed(), bugName));
179                                 assertTrue(contains(delta.getNew(), bugName));
180                         }
181                         else if (!firstSet.contains(bugName) && !secondSet.contains(bugName)) {
182                                 assertFalse(contains(delta.getCommon(), bugName));
183                                 assertFalse(contains(delta.getFixed(), bugName));
184                                 assertFalse(contains(delta.getNew(), bugName));                         
185                         }
186                 }
187         }
188
189         @Test
190         public void test_computeDeltas() throws FileNotFoundException, IOException, SAXException 
191         {
192                 String[][] bugSpecs = {
193                                 { DM_DEFAULT_ENCODING, "DM_DEFAULT_ENCODING" },
194                                 { RCN_REDUNDANT_NULL_CHECK, "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" },
195                                 { DM_NUMBER_CTOR_156, "DM_NUMBER_CTOR" },
196                                 { DM_NUMBER_CTOR_169, "DM_NUMBER_CTOR" }
197                 };
198
199                 for (int w = 0; w < bugSpecs.length; ++w) {
200                         for (int x = w + 1; x < bugSpecs.length; ++x) {
201                                 for (int y = 0; y < bugSpecs.length; ++y) {
202                                         for (int z = y + 1; z < bugSpecs.length; ++z) {
203                                                 execDeltaForRanges(bugSpecs, w, x, y, z);
204                                         }
205                                 }
206                         }
207                 }
208         }
209
210         @Test
211         public void test_deltaWithNoPrior() throws FileNotFoundException, IOException, SAXException 
212         {
213                 String[][] bugSpecs = {
214                                 { DM_DEFAULT_ENCODING, "DM_DEFAULT_ENCODING" },
215                                 { RCN_REDUNDANT_NULL_CHECK, "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" },
216                                 { VO_VOLATILE_INCREMENT, "VO_VOLATILE_INCREMENT" },
217                                 { DM_NUMBER_CTOR_156, "DM_NUMBER_CTOR" },
218                                 { DM_NUMBER_CTOR_169, "DM_NUMBER_CTOR" }
219                 };
220                 
221                 final String PROJECT_NAME = "AlphaOne";
222                 String secondXml = buildXml(bugSpecs, 0, bugSpecs.length - 1);
223                 
224                 Analysis second = analysisFromXml(secondXml, PROJECT_NAME, "1.0.1");
225                 
226                 Delta delta = new Delta(null, second);
227                 
228                 assertNotNull(delta);
229                 for (int i = 0; i < bugSpecs.length; ++i) {
230                         assertFalse(contains(delta.getCommon(), bugSpecs[i][1]));
231                         assertFalse(contains(delta.getFixed(), bugSpecs[i][1]));
232                         assertTrue(contains(delta.getNew(), bugSpecs[i][1]));
233                 }
234         }
235 }