aboutsummaryrefslogtreecommitdiff
path: root/entomologist
diff options
context:
space:
mode:
Diffstat (limited to 'entomologist')
-rw-r--r--entomologist/.classpath7
-rw-r--r--entomologist/.fatjar14
-rw-r--r--entomologist/.project17
-rw-r--r--entomologist/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--entomologist/build.xml26
-rw-r--r--entomologist/comparator.properties29
-rw-r--r--entomologist/entomologist10
-rw-r--r--entomologist/mcomparator.jarbin0 -> 270581 bytes
-rw-r--r--entomologist/src/org/monkey/comparator/BugComparator.java30
-rw-r--r--entomologist/src/org/monkey/comparator/Constants.java65
-rw-r--r--entomologist/src/org/monkey/comparator/Feature.java21
-rw-r--r--entomologist/src/org/monkey/comparator/GeneralPropertiesFeature.java52
-rw-r--r--entomologist/src/org/monkey/comparator/MonkeyComparator.java75
-rw-r--r--entomologist/src/org/monkey/comparator/StackTraceFeature.java167
-rw-r--r--entomologist/src/org/monkey/comparator/Util.java10
-rw-r--r--entomologist/src/org/monkey/comparator/ValueClassifier.java75
-rw-r--r--entomologist/src/org/monkey/comparator/bo/Bug.java44
-rw-r--r--entomologist/src/org/monkey/comparator/bo/Epoch.java24
-rw-r--r--entomologist/src/org/monkey/comparator/bo/Expression.java19
-rw-r--r--entomologist/src/org/monkey/comparator/bo/Function.java38
-rw-r--r--entomologist/src/org/monkey/comparator/bo/XMLParser.java196
-rw-r--r--entomologist/src/org/monkey/comparator/testing/ComparatorTest.java111
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/monkey.xml45
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/monkey_common_and_different_exp.xml47
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/monkey_different_and_longer_history.xml114
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/monkey_different_fname.xml45
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/monkey_different_history.xml60
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/monkey_different_trace.xml61
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/npe.xml29
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/npe_divzero.xml43
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_and_stack_modified.xml42
-rw-r--r--entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_modified.xml37
32 files changed, 1565 insertions, 0 deletions
diff --git a/entomologist/.classpath b/entomologist/.classpath
new file mode 100644
index 0000000..b10b8d9
--- /dev/null
+++ b/entomologist/.classpath
@@ -0,0 +1,7 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<classpath>
3 <classpathentry kind="src" path="src"/>
4 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
5 <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
6 <classpathentry kind="output" path="bin"/>
7</classpath>
diff --git a/entomologist/.fatjar b/entomologist/.fatjar
new file mode 100644
index 0000000..ce6d1ab
--- /dev/null
+++ b/entomologist/.fatjar
@@ -0,0 +1,14 @@
1#Fat Jar Configuration File
2#Sun Jul 15 12:40:42 CEST 2012
3onejar.license.required=true
4manifest.classpath=
5manifest.removesigners=true
6onejar.checkbox=false
7jarname=mcomparator.jar
8manifest.mergeall=true
9manifest.mainclass=org.monkey.comparator.MonkeyComparator
10manifest.file=<createnew>
11jarname.isextern=false
12onejar.expand=
13excludes=
14includes=
diff --git a/entomologist/.project b/entomologist/.project
new file mode 100644
index 0000000..84d2b8a
--- /dev/null
+++ b/entomologist/.project
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<projectDescription>
3 <name>MonkeyBugComparator</name>
4 <comment></comment>
5 <projects>
6 </projects>
7 <buildSpec>
8 <buildCommand>
9 <name>org.eclipse.jdt.core.javabuilder</name>
10 <arguments>
11 </arguments>
12 </buildCommand>
13 </buildSpec>
14 <natures>
15 <nature>org.eclipse.jdt.core.javanature</nature>
16 </natures>
17</projectDescription>
diff --git a/entomologist/.settings/org.eclipse.jdt.core.prefs b/entomologist/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9e22754
--- /dev/null
+++ b/entomologist/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
1#Tue Jan 24 16:34:26 CET 2012
2eclipse.preferences.version=1
3org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
5org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6org.eclipse.jdt.core.compiler.compliance=1.6
7org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8org.eclipse.jdt.core.compiler.debug.localVariable=generate
9org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12org.eclipse.jdt.core.compiler.source=1.6
diff --git a/entomologist/build.xml b/entomologist/build.xml
new file mode 100644
index 0000000..3d99b77
--- /dev/null
+++ b/entomologist/build.xml
@@ -0,0 +1,26 @@
1<?xml version="1.0"?>
2<project name="FatJar mcomparator.jar (experimental)" default="main" basedir=".">
3 <!-- this file was created by Fat-Jar Eclipse Plug-in -->
4 <!-- the ANT-Export is in a very early stage, so this -->
5 <!-- is only experimental, ANT 1.6 or above is -->
6 <!-- required, feedback is always welcome: -->
7 <!-- http://sourceforge.net/projects/fjep -->
8 <!-- uncomment the following lines if using ANT outside Eclipse -->
9 <!--
10 <property name="fjepPath" value="reference:file:plugins/net.sf.fjep.fatjar_0.0.31/fatjar.jar"/>
11 <taskdef name="fatjar.build" classname="net.sf.fjep.anttask.FJBuildTask" classpath="${fjepPath}"/>
12 <typedef name="fatjar.manifest" classname="net.sf.fjep.anttask.FJManifestType" classpath="${fjepPath}"/>
13 <typedef name="fatjar.exclude" classname="net.sf.fjep.anttask.FJExcludeType" classpath="${fjepPath}"/>
14 <typedef name="fatjar.jarsource" classname="net.sf.fjep.anttask.FJJarSourceType" classpath="${fjepPath}"/>
15 <typedef name="fatjar.filesource" classname="net.sf.fjep.anttask.FJFileSourceType" classpath="${fjepPath}"/>
16 -->
17 <!-- uncomment the above lines to use ANT outside of Eclipse -->
18 <target name="main">
19 <fatjar.build output="mcomparator.jar">
20 <fatjar.manifest mainclass="org.monkey.comparator.MonkeyComparator"/>
21 <fatjar.filesource path="/home/safey/EclipseWorkspaceMonkeyComparator/MonkeyBugComparator/bin" relpath="">
22 <fatjar.exclude relpath="org/monkey/comparator/testing/"/>
23 </fatjar.filesource>
24 </fatjar.build>
25 </target>
26</project>
diff --git a/entomologist/comparator.properties b/entomologist/comparator.properties
new file mode 100644
index 0000000..0c4f95f
--- /dev/null
+++ b/entomologist/comparator.properties
@@ -0,0 +1,29 @@
1MAX_INT=2147483647
2MIN_INT=-2147483647
3ENABLE_VALUE_CLASSES=false
4LINE_NUMBER_DIFFERENCE_THRESHOLD=10
5
6# Features' scores
7GENERAL_PROPERTIES_FEATURE_SCORE=100
8STACK_TRACE_FEATURE_SCORE=50
9
10# Weights for feature: Bug General Properties
11BUG_CATEGORY_WEIGHT=0.75
12LINE_NUMBER_WEIGHT=0.00625
13BUG_FUNCTION_NAME_WEIGHT=0.1875
14FILE_NAME_WEIGHT=0.05625
15
16# Weights for feature: Stack-Trace
17# Weight of all function semantics in the stack-trace (function name, file name, line number)
18FUNCTION_SEMANTICS_WEIGHT=0.1
19# Weight of all expressions in the stack-trace
20EXPRESSIONS_WEIGHT=0.9
21
22# Within the function semantics
23FUNCTION_NAME_WEIGHT=0.25
24FUNCTION_LINE_WEIGHT=0.25
25FUNCTION_FILE_NAME=0.5
26
27# Within the expressions of the function
28EXPRESSION_SYTNAX_WEIGHT=0.7
29EXPRESSION_VALUE_WEIGHT=0.3
diff --git a/entomologist/entomologist b/entomologist/entomologist
new file mode 100644
index 0000000..ac3ca9f
--- /dev/null
+++ b/entomologist/entomologist
@@ -0,0 +1,10 @@
1#! /bin/bash
2
3echo "Wrapper for the Monkey bug comparator (entomologist)"
4if ls mcomparator.jar &> /dev/null; then
5 java -jar mcomparator.jar $1 $2 $3 $4
6else
7 echo "Run: entomologist file1.xml file2.xml -p comparator.properties"
8 echo "mcomparator.jar must be in the same directory of this script."
9fi
10
diff --git a/entomologist/mcomparator.jar b/entomologist/mcomparator.jar
new file mode 100644
index 0000000..be6a8d4
--- /dev/null
+++ b/entomologist/mcomparator.jar
Binary files differ
diff --git a/entomologist/src/org/monkey/comparator/BugComparator.java b/entomologist/src/org/monkey/comparator/BugComparator.java
new file mode 100644
index 0000000..d89af84
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/BugComparator.java
@@ -0,0 +1,30 @@
1package org.monkey.comparator;
2
3import java.util.ArrayList;
4
5public class BugComparator {
6 private static ArrayList<Feature> featureList = new ArrayList<Feature>();
7
8 public static boolean register(Feature feature) {
9 featureList.add(feature);
10 return true;
11 }
12
13 public static boolean unregister(Feature feature) {
14 featureList.remove(feature);
15 return true;
16 }
17
18 public static double calculateScore() {
19 double totalScore = 0;
20 double featureScore;
21 Feature feature;
22 for (int i = 0; i < featureList.size(); i++) {
23 feature = featureList.get(i);
24 featureScore = feature.score();
25 //System.out.println(feature.getFeatureName() + " score = " + featureScore);
26 totalScore += featureScore;
27 }
28 return totalScore;
29 }
30}
diff --git a/entomologist/src/org/monkey/comparator/Constants.java b/entomologist/src/org/monkey/comparator/Constants.java
new file mode 100644
index 0000000..f707fdf
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/Constants.java
@@ -0,0 +1,65 @@
1package org.monkey.comparator;
2
3import java.io.FileInputStream;
4import java.io.FileNotFoundException;
5import java.io.IOException;
6import java.util.Properties;
7
8public abstract class Constants {
9 public static int MAX_INT;
10 public static int MIN_INT;
11 public static boolean ENABLE_VALUE_CLASSES;
12 public static int LINE_NUMBER_DIFFERENCE_THRESHOLD;
13
14 /* Features' scores */
15 public static double GENERAL_PROPERTIES_FEATURE_SCORE;
16 public static double STACK_TRACE_FEATURE_SCORE;
17
18 /* Weights for feature: Bug General Properties */
19 public static double BUG_CATEGORY_WEIGHT;
20 public static double LINE_NUMBER_WEIGHT;
21 public static double BUG_FUNCTION_NAME_WEIGHT;
22 public static double FILE_NAME_WEIGHT;
23
24 /* Weights for feature: Stack-Trace */
25 public static double FUNCTION_SEMANTICS_WEIGHT; // Weight of all function semantics in the stack-trace (function name, file name, line number)
26 public static double EXPRESSIONS_WEIGHT; // Weight of all expressions in the stack-trace
27
28 public static double FUNCTION_NAME_WEIGHT; // Within the function semantics
29 public static double FUNCTION_LINE_WEIGHT;
30 public static double FUNCTION_FILE_NAME;
31
32 public static double EXPRESSION_SYTNAX_WEIGHT; // Within the expressions of the function
33 public static double EXPRESSION_VALUE_WEIGHT;
34
35 public static void setUpConstants(String propertiesFilePath) {
36 Properties properties = new Properties();
37 try {
38 properties.load(new FileInputStream(propertiesFilePath));
39 MAX_INT = Integer.parseInt(properties.getProperty("MAX_INT"));
40 MIN_INT = Integer.parseInt(properties.getProperty("MIN_INT"));
41 ENABLE_VALUE_CLASSES = Boolean.parseBoolean(properties.getProperty("ENABLE_VALUE_CLASSES"));
42 LINE_NUMBER_DIFFERENCE_THRESHOLD = Integer.parseInt(properties.getProperty("LINE_NUMBER_DIFFERENCE_THRESHOLD"));
43 GENERAL_PROPERTIES_FEATURE_SCORE = Double.parseDouble(properties.getProperty("GENERAL_PROPERTIES_FEATURE_SCORE"));
44 STACK_TRACE_FEATURE_SCORE = Double.parseDouble(properties.getProperty("STACK_TRACE_FEATURE_SCORE"));
45 BUG_CATEGORY_WEIGHT = Double.parseDouble(properties.getProperty("BUG_CATEGORY_WEIGHT"));
46 LINE_NUMBER_WEIGHT = Double.parseDouble(properties.getProperty("LINE_NUMBER_WEIGHT"));
47 BUG_FUNCTION_NAME_WEIGHT = Double.parseDouble(properties.getProperty("BUG_FUNCTION_NAME_WEIGHT"));
48 FILE_NAME_WEIGHT = Double.parseDouble(properties.getProperty("FILE_NAME_WEIGHT"));
49 FUNCTION_SEMANTICS_WEIGHT = Double.parseDouble(properties.getProperty("FUNCTION_SEMANTICS_WEIGHT"));
50 EXPRESSIONS_WEIGHT = Double.parseDouble(properties.getProperty("EXPRESSIONS_WEIGHT"));
51 FUNCTION_NAME_WEIGHT = Double.parseDouble(properties.getProperty("FUNCTION_NAME_WEIGHT"));
52 FUNCTION_LINE_WEIGHT = Double.parseDouble(properties.getProperty("FUNCTION_LINE_WEIGHT"));
53 FUNCTION_FILE_NAME = Double.parseDouble(properties.getProperty("FUNCTION_FILE_NAME"));
54 EXPRESSION_SYTNAX_WEIGHT = Double.parseDouble(properties.getProperty("EXPRESSION_SYTNAX_WEIGHT"));
55 EXPRESSION_VALUE_WEIGHT = Double.parseDouble(properties.getProperty("EXPRESSION_VALUE_WEIGHT"));
56 } catch (FileNotFoundException e) {
57 e.printStackTrace();
58 } catch (IOException e) {
59 System.err.println("Fatal error: unable to read properties. Entomologist will exit now.");
60 e.printStackTrace();
61 System.exit(1);
62 }
63 }
64
65}
diff --git a/entomologist/src/org/monkey/comparator/Feature.java b/entomologist/src/org/monkey/comparator/Feature.java
new file mode 100644
index 0000000..576ac44
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/Feature.java
@@ -0,0 +1,21 @@
1package org.monkey.comparator;
2
3import org.monkey.comparator.bo.Bug;
4
5public abstract class Feature {
6 protected Bug bugA;
7 protected Bug bugB;
8 protected String featureName = "Feature";
9 protected double featureTotalScore = 0;
10
11 public Feature (Bug bugA, Bug bugB, double featureTotalScore) {
12 this.bugA = bugA;
13 this.bugB = bugB;
14 this.featureTotalScore = featureTotalScore;
15 }
16
17 protected abstract String getFeatureName();
18 protected abstract void assignScorePoints();
19 public abstract double score();
20}
21
diff --git a/entomologist/src/org/monkey/comparator/GeneralPropertiesFeature.java b/entomologist/src/org/monkey/comparator/GeneralPropertiesFeature.java
new file mode 100644
index 0000000..ac4282c
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/GeneralPropertiesFeature.java
@@ -0,0 +1,52 @@
1package org.monkey.comparator;
2
3import org.monkey.comparator.bo.Bug;
4
5public class GeneralPropertiesFeature extends Feature {
6 private static double bugCategoryScore;
7 private static double lineNumberScore;
8 private static double functionNameScore;
9 private static double fileNameScore;
10
11 public GeneralPropertiesFeature(Bug bugA, Bug bugB, double featureTotalScore) {
12 super(bugA, bugB, featureTotalScore);
13 featureName = "Feature: Bug General Properties";
14 }
15
16 private double compareGeneralProperties() {
17 double score = 0;
18 if (bugA.getCategory().equals(bugB.getCategory()))
19 score += bugCategoryScore;
20 if (bugA.getFileName().equals(bugB.getFileName()))
21 score += fileNameScore;
22 if (bugA.getFunctionName().equals(bugB.getFunctionName()))
23 score += functionNameScore;
24 if (bugA.getLineNo() == bugB.getLineNo()) {
25 score += lineNumberScore;
26 } else {
27 score += Util.weightLineNumberDifference(bugA.getLineNo(), bugB.getLineNo()) * lineNumberScore;
28 }
29
30 return score;
31 }
32
33 @Override
34 public double score() {
35 assignScorePoints();
36 return compareGeneralProperties();
37 }
38
39 @Override
40 protected void assignScorePoints() {
41 bugCategoryScore = Constants.BUG_CATEGORY_WEIGHT * featureTotalScore;
42 lineNumberScore = Constants.LINE_NUMBER_WEIGHT * featureTotalScore;
43 functionNameScore = Constants.BUG_FUNCTION_NAME_WEIGHT * featureTotalScore;
44 fileNameScore = Constants.FILE_NAME_WEIGHT * featureTotalScore;
45 }
46
47 @Override
48 protected String getFeatureName() {
49 return featureName;
50 }
51
52}
diff --git a/entomologist/src/org/monkey/comparator/MonkeyComparator.java b/entomologist/src/org/monkey/comparator/MonkeyComparator.java
new file mode 100644
index 0000000..82428a2
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/MonkeyComparator.java
@@ -0,0 +1,75 @@
1package org.monkey.comparator;
2
3import java.io.File;
4import org.monkey.comparator.bo.Bug;
5import org.monkey.comparator.bo.XMLParser;
6
7public class MonkeyComparator {
8 public static double compareBugs(Bug bugA, Bug bugB, String propertiesFilePath) {
9 Constants.setUpConstants(propertiesFilePath);
10
11 double similarityPercentage = 0;
12 double totalScore = Constants.GENERAL_PROPERTIES_FEATURE_SCORE + Constants.STACK_TRACE_FEATURE_SCORE;
13
14 /* Register comparison features and start comparison */
15 Feature generalPropertiesFeature = new GeneralPropertiesFeature(bugA, bugB, Constants.GENERAL_PROPERTIES_FEATURE_SCORE);
16 Feature stackTraceFeature = new StackTraceFeature(bugA, bugB, Constants.STACK_TRACE_FEATURE_SCORE);
17
18 BugComparator.register(generalPropertiesFeature);
19 BugComparator.register(stackTraceFeature);
20 similarityPercentage = (BugComparator.calculateScore() / totalScore) * 100;
21
22 /* Cleanup */
23 BugComparator.unregister(generalPropertiesFeature);
24 BugComparator.unregister(stackTraceFeature);
25
26 return similarityPercentage;
27 }
28
29 private static void showErrorAndExit() {
30 System.err.println("Monkey Bug Comparator takes the following arguments: " +
31 "file1.xml file2.xml -p configuration.properties");
32 System.exit(1);
33 }
34
35 private static boolean checkFilePath(String filePath) {
36 if (new File(filePath).exists() == false) {
37 System.err.println("File " + filePath + " not found!");
38 showErrorAndExit();
39 }
40 return true;
41 }
42 public static void main(String[] args) {
43 String propertiesFilePath = null;
44 String bugAFilePath = null;
45 String bugBFilePath = null;
46
47 if (args.length < 4)
48 showErrorAndExit();
49
50 for (int i = 0; i < args.length; i++) {
51 if (args[i].equals("-p")) {
52 propertiesFilePath = args[++i];
53 checkFilePath(propertiesFilePath);
54 }
55 else if (null == bugAFilePath) {
56 bugAFilePath = args[i];
57 checkFilePath(bugAFilePath);
58 }
59 else if (null == bugBFilePath) {
60 bugBFilePath = args[i];
61 checkFilePath(bugBFilePath);
62 }
63 }
64
65 if (null == propertiesFilePath || null == bugAFilePath || null == bugBFilePath)
66 showErrorAndExit();
67
68 Bug bugA = XMLParser.parse(bugAFilePath);
69 Bug bugB = XMLParser.parse(bugBFilePath);
70 //XMLParser.printBug(bugA);
71 //XMLParser.printBug(bugB);
72
73 System.out.println("Similarity Percentage = " + compareBugs(bugA, bugB, propertiesFilePath));
74 }
75}
diff --git a/entomologist/src/org/monkey/comparator/StackTraceFeature.java b/entomologist/src/org/monkey/comparator/StackTraceFeature.java
new file mode 100644
index 0000000..f2b13eb
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/StackTraceFeature.java
@@ -0,0 +1,167 @@
1package org.monkey.comparator;
2
3
4import org.monkey.comparator.bo.Bug;
5import org.monkey.comparator.bo.Epoch;
6import org.monkey.comparator.bo.Expression;
7import org.monkey.comparator.bo.Function;
8
9public class StackTraceFeature extends Feature {
10 private double functionNameScore;
11 private double functionLineNumberScore;
12 private double functionFileNameScore;
13 private double expressionSyntaxScore;
14 private double expressionValueScore;
15 private int functionNum;
16 private int expressionNum;
17 private int epochNum;
18
19 public StackTraceFeature(Bug bugA, Bug bugB, double featureTotalScore) {
20 super(bugA, bugB, featureTotalScore);
21 featureName = "Feature: Stack-Trace";
22 }
23
24 private double compareFunctions(int epochIndex) {
25 int numFunctionA = bugA.getEpoch(epochIndex).getFunctionNum();
26 int numFunctionB = bugB.getEpoch(epochIndex).getFunctionNum();
27
28 if (numFunctionA >= numFunctionB)
29 return doCompareFunctions(bugB.getEpoch(epochIndex), bugA.getEpoch(epochIndex));
30 return doCompareFunctions(bugA.getEpoch(epochIndex), bugB.getEpoch(epochIndex));
31 }
32
33 private double doCompareFunctions(Epoch shorterEpoch, Epoch longerEpoch) {
34 double functionsScore = 0;
35 double expressionsScore = 0;
36 double tmpExpressionScore = 0;
37
38 int numFunctionShorter = shorterEpoch.getFunctionNum();
39 int numFunctionLonger = longerEpoch.getFunctionNum();
40 Function functionShorterEpoch;
41 Function functionLongerEpoch;
42 for (int i = 0; i < numFunctionShorter; i++) {
43 functionShorterEpoch = shorterEpoch.getFunction(i);
44 for (int j = 0; j < numFunctionLonger; j++) {
45 functionLongerEpoch = longerEpoch.getFunction(j);
46
47 tmpExpressionScore = compareExpressions(functionShorterEpoch, functionLongerEpoch);
48 expressionsScore += tmpExpressionScore;
49 if (tmpExpressionScore > 0) {
50 if (functionShorterEpoch.getLineNo() == functionLongerEpoch.getLineNo()) {
51 functionsScore += functionLineNumberScore;
52 } else {
53 /* If there is some similarity in expressions,
54 * but function line numbers are not the same,
55 * score for function line numbers should NOT be zero */
56 functionsScore += Util.weightLineNumberDifference(functionShorterEpoch.getLineNo(), functionLongerEpoch.getLineNo())
57 * functionLineNumberScore;
58 }
59 if(functionShorterEpoch.getFileName().equals(functionLongerEpoch.getFileName()))
60 functionsScore += functionFileNameScore;
61 if(functionShorterEpoch.getFunctionName().equals(functionLongerEpoch.getFunctionName()))
62 functionsScore += functionNameScore;
63 break;
64 }
65 }
66 }
67 return functionsScore + expressionsScore;
68 }
69
70 private double compareExpressions(Function functionA, Function functionB) {
71 int numExpressionA = functionA.getExpressionNum();
72 int numExpressionB = functionB.getExpressionNum();
73
74 if (numExpressionA >= numExpressionB)
75 return doCompareExpressions(functionB, functionA);
76 return doCompareExpressions(functionA, functionB);
77 }
78
79 private double doCompareExpressions(Function shorterFunction, Function longerFunction) {
80 double expressionsScore = 0;
81 int numExpressionShorter = shorterFunction.getExpressionNum();
82 int numExpressionLonger = longerFunction.getExpressionNum();
83
84 Expression expressionShorterFunction;
85 Expression expressionLongerFunction;
86 for (int i = 0; i < numExpressionShorter; i++) {
87 expressionShorterFunction = shorterFunction.getExpression(i);
88 for (int j = 0; j < numExpressionLonger; j++) {
89 expressionLongerFunction = longerFunction.getExpression(j);
90 if (expressionShorterFunction.getName().equals(expressionLongerFunction.getName())) {
91 expressionsScore += expressionSyntaxScore;
92 if (ValueClassifier.classify(expressionShorterFunction.getValue(), expressionLongerFunction.getValue()))
93 expressionsScore += expressionValueScore;
94 break; // break inner loop
95 }
96 }
97 }
98
99 return expressionsScore;
100 }
101
102 @Override
103 public double score() {
104 assignScorePoints();
105 double finalScore = 0.0;
106 for (int i = 0; i < epochNum; i++)
107 finalScore += compareFunctions(i);
108 return finalScore;
109 }
110
111 @Override
112 protected void assignScorePoints() {
113 int epochNumA = bugA.getEpochNum();
114 int epochNumB = bugB.getEpochNum();
115 epochNum = epochNumA <= epochNumB ? epochNumA : epochNumB; // compare the smallest number of epoch steps
116
117 int expressionNumA, expressionNumB, functionNumA, functionNumB;
118 Function function;
119 for (int i = 0; i < epochNum; i++) {
120 functionNumA = bugA.getEpoch(i).getFunctionNum();
121 functionNumB = bugB.getEpoch(i).getFunctionNum();
122 functionNum += functionNumA >= functionNumB ? functionNumA : functionNumB; // taking the larger number of functions of the two stack traces
123
124 expressionNumA = 0;
125 for (int j = 0; j < functionNumA; j++) {
126 function = bugA.getEpoch(i).getFunction(j);
127 expressionNumA += function.getExpressionNum();
128 }
129
130 expressionNumB = 0;
131 for (int j = 0; j < functionNumB; j++) {
132 function = bugB.getEpoch(i).getFunction(j);
133 expressionNumB += function.getExpressionNum();
134 }
135
136 expressionNum += expressionNumA >= expressionNumB ? expressionNumA : expressionNumB; // taking the larger number of expressions of the two stack traces
137 }
138
139
140 double allFunctionSemanticsScore = Constants.FUNCTION_SEMANTICS_WEIGHT * featureTotalScore;
141 double singleFunctionSemanticsScore = (double)allFunctionSemanticsScore / (double)functionNum;
142 double allExpressionsScore = Constants.EXPRESSIONS_WEIGHT * featureTotalScore;
143 double singleExpressionScore = (double)allExpressionsScore / (double)expressionNum;
144
145 /* Scoring for function semantics details */
146 functionNameScore = Constants.FUNCTION_NAME_WEIGHT *singleFunctionSemanticsScore;
147 functionFileNameScore = Constants.FUNCTION_FILE_NAME * singleFunctionSemanticsScore;
148 functionLineNumberScore = Constants.FUNCTION_LINE_WEIGHT * singleFunctionSemanticsScore;
149
150 /* Scoring for expression semantics details */
151 expressionSyntaxScore = Constants.EXPRESSION_SYTNAX_WEIGHT * singleExpressionScore;
152 expressionValueScore = Constants.EXPRESSION_VALUE_WEIGHT * singleExpressionScore;
153 }
154
155
156 @Override
157 protected String getFeatureName() {
158 return featureName;
159 }
160
161 /*
162 private double testTotalScore() {
163 return ((functionNameScore + functionFileNameScore + functionLineNumberScore) * functionNum) + ((expressionSyntaxScore + expressionValueScore) * expressionNum);
164 }
165 */
166
167}
diff --git a/entomologist/src/org/monkey/comparator/Util.java b/entomologist/src/org/monkey/comparator/Util.java
new file mode 100644
index 0000000..7f3f0c3
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/Util.java
@@ -0,0 +1,10 @@
1package org.monkey.comparator;
2
3public abstract class Util {
4 public static double weightLineNumberDifference(int lineNumberA, int lineNumberB) {
5 double diff = Math.abs(lineNumberA - lineNumberB);
6 double div = diff/(double)Constants.LINE_NUMBER_DIFFERENCE_THRESHOLD;
7 double weight = 1 - div;
8 return weight;
9 }
10}
diff --git a/entomologist/src/org/monkey/comparator/ValueClassifier.java b/entomologist/src/org/monkey/comparator/ValueClassifier.java
new file mode 100644
index 0000000..a81eafb
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/ValueClassifier.java
@@ -0,0 +1,75 @@
1package org.monkey.comparator;
2
3public class ValueClassifier {
4 public static boolean classify(String expressionValueA, String expressionValueB) {
5 /* If value classes disabled compare values normally and return */
6 if (Constants.ENABLE_VALUE_CLASSES == false) {
7 if (expressionValueA.equals(expressionValueB))
8 return true;
9 return false;
10 }
11
12 /* Value classes enabled */
13 if (((expressionValueA.startsWith("0x") || expressionValueA.equals("NULL"))
14 && (expressionValueB.startsWith("0x") || expressionValueB.equals("NULL")))) {
15 return classifyPointer(expressionValueA, expressionValueB);
16 }
17 try {
18 int iA = Integer.parseInt(expressionValueA);
19 int iB = Integer.parseInt(expressionValueB);
20 return classifyInteger(iA, iB);
21 }
22 catch (NumberFormatException e) {
23 try {
24 float fA = Float.parseFloat(expressionValueA);
25 float fB = Float.parseFloat(expressionValueB);
26 return classifyFloat(fA, fB);
27 }
28 catch (NumberFormatException ee) {
29 return classifyString(expressionValueA, expressionValueB);
30 }
31 }
32 }
33
34 private static boolean classifyInteger(int expressionAValue, int expressionBValue) {
35 if (expressionAValue == 0 || expressionBValue == 0 ||
36 expressionAValue == 1 || expressionBValue == 1
37 || expressionAValue == -1 || expressionBValue == -1 ||
38 expressionAValue == Constants.MAX_INT || expressionBValue == Constants.MAX_INT ||
39 expressionAValue == Constants.MIN_INT || expressionBValue == Constants.MIN_INT) {
40 if (expressionAValue == expressionBValue)
41 return true;
42 return false;
43 }
44 return true;
45 }
46
47 private static boolean classifyFloat(float bugAValue, float bugBValue) {
48 if (bugAValue == 0.0 || bugBValue == 0.0) {
49 if (bugAValue == bugBValue)
50 return true;
51 return false;
52 }
53 return true;
54 }
55
56 private static boolean classifyPointer(String bugAValue, String bugBValue) {
57 if (bugAValue.equals("NULL") || bugBValue.equals("NULL")) {
58 if (bugAValue.equals(bugBValue))
59 return true;
60 return false;
61 }
62 return true;
63 }
64
65 private static boolean classifyString(String bugAValue, String bugBValue) {
66 if (bugAValue.equals("NULL") || bugAValue.equals("")
67 || bugBValue.equals("NULL") || bugBValue.equals("")) {
68 if (bugAValue.equals(bugBValue)) {
69 return true;
70 }
71 return false;
72 }
73 return true;
74 }
75}
diff --git a/entomologist/src/org/monkey/comparator/bo/Bug.java b/entomologist/src/org/monkey/comparator/bo/Bug.java
new file mode 100644
index 0000000..62f4d24
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/bo/Bug.java
@@ -0,0 +1,44 @@
1package org.monkey.comparator.bo;
2
3import java.util.ArrayList;
4
5public class Bug {
6 private String category;
7 private String fileName;
8 private int lineNo;
9 private String functionName;
10 private ArrayList<Epoch> epochList = new ArrayList<Epoch>();
11 public void setFileName(String fileName) {
12 this.fileName = fileName;
13 }
14 public String getFileName() {
15 return fileName;
16 }
17 public void setLineNo(int lineNo) {
18 this.lineNo = lineNo;
19 }
20 public int getLineNo() {
21 return lineNo;
22 }
23 public void setFunctionName(String functionName) {
24 this.functionName = functionName;
25 }
26 public String getFunctionName() {
27 return functionName;
28 }
29 public void insertEpoch(Epoch epoch) {
30 this.epochList.add(epoch);
31 }
32 public Epoch getEpoch(int index) {
33 return epochList.get(index);
34 }
35 public void setCategory(String category) {
36 this.category = category;
37 }
38 public String getCategory() {
39 return category;
40 }
41 public int getEpochNum() {
42 return epochList.size();
43 }
44}
diff --git a/entomologist/src/org/monkey/comparator/bo/Epoch.java b/entomologist/src/org/monkey/comparator/bo/Epoch.java
new file mode 100644
index 0000000..71e2554
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/bo/Epoch.java
@@ -0,0 +1,24 @@
1package org.monkey.comparator.bo;
2
3import java.util.ArrayList;
4
5public class Epoch {
6 private int epochStep;
7 private ArrayList<Function> functionList = new ArrayList<Function>();
8
9 public void setEpochStep(int epochStep) {
10 this.epochStep = epochStep;
11 }
12 public int getEpochStep() {
13 return epochStep;
14 }
15 public void insertFunction(Function function) {
16 this.functionList.add(function);
17 }
18 public Function getFunction(int index) {
19 return functionList.get(index);
20 }
21 public int getFunctionNum() {
22 return functionList.size();
23 }
24}
diff --git a/entomologist/src/org/monkey/comparator/bo/Expression.java b/entomologist/src/org/monkey/comparator/bo/Expression.java
new file mode 100644
index 0000000..7903189
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/bo/Expression.java
@@ -0,0 +1,19 @@
1package org.monkey.comparator.bo;
2
3public class Expression {
4 private String name;
5 private String value;
6 public void setName(String name) {
7 this.name = name;
8 }
9 public String getName() {
10 return name;
11 }
12 public void setValue(String value) {
13 this.value = value;
14 }
15 public String getValue() {
16 return value;
17 }
18
19}
diff --git a/entomologist/src/org/monkey/comparator/bo/Function.java b/entomologist/src/org/monkey/comparator/bo/Function.java
new file mode 100644
index 0000000..f6adbd2
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/bo/Function.java
@@ -0,0 +1,38 @@
1package org.monkey.comparator.bo;
2
3import java.util.ArrayList;
4
5public class Function {
6 private String functionName;
7 private int lineNo;
8 private String fileName;
9 private ArrayList<Expression> expressionList = new ArrayList<Expression>();
10
11 public void setFunctionName(String functionName) {
12 this.functionName = functionName;
13 }
14 public String getFunctionName() {
15 return functionName;
16 }
17 public void setLineNo(int lineNo) {
18 this.lineNo = lineNo;
19 }
20 public int getLineNo() {
21 return lineNo;
22 }
23 public void insertExpression(Expression expression) {
24 this.expressionList.add(expression);
25 }
26 public Expression getExpression(int index) {
27 return expressionList.get(index);
28 }
29 public String getFileName() {
30 return fileName;
31 }
32 public void setFileName(String fileName) {
33 this.fileName = fileName;
34 }
35 public int getExpressionNum() {
36 return expressionList.size();
37 }
38}
diff --git a/entomologist/src/org/monkey/comparator/bo/XMLParser.java b/entomologist/src/org/monkey/comparator/bo/XMLParser.java
new file mode 100644
index 0000000..6254730
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/bo/XMLParser.java
@@ -0,0 +1,196 @@
1package org.monkey.comparator.bo;
2
3import java.io.File;
4
5import javax.xml.parsers.DocumentBuilder;
6import javax.xml.parsers.DocumentBuilderFactory;
7
8import org.w3c.dom.Document;
9import org.w3c.dom.Element;
10import org.w3c.dom.Node;
11import org.w3c.dom.NodeList;
12
13public class XMLParser {
14
15 /*
16 * The method parses Monkey's XML Bug Report.
17 * The following is an example the XML file the method expects for parsing
18 * <?xml version="1.0"?>
19 <crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
20 <history>
21 <epoch step="0" >
22 <trace>
23 <function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
24 <expressions>
25 <expression name="crashStruct" >NULL</expression>
26 </expressions>
27 </function>
28 </trace>
29 </epoch>
30 </history>
31 </crash>
32 */
33 public static Bug parse(String filePath) {
34 Bug bug = new Bug();
35 try {
36 NodeList epochNodeList;
37 NodeList traceNodeList;
38 NodeList functionNodeList;
39 NodeList expressionNodeList;
40 NodeList tmpNodeList;
41 Node epochNode;
42 Node traceNode;
43 Node functionNode;
44 Node expressionNode;
45 Node tmpNode = null;
46 Element element;
47 Epoch epoch = null;
48 Function function = null;
49 Expression expression = null;
50 File xmlFile = new File(filePath);
51
52 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
53 .newInstance();
54 DocumentBuilder documentBuilder = documentBuilderFactory
55 .newDocumentBuilder();
56 Document document = documentBuilder.parse(xmlFile);
57 document.getDocumentElement().normalize();
58
59 /* Setting Bug Attributes */
60 element = document.getDocumentElement(); /*
61 * This should be the crash
62 * node
63 */
64 bug.setCategory(element.getAttribute("category"));
65 bug.setFileName(element.getAttribute("file"));
66 bug.setFunctionName(element.getAttribute("function"));
67 bug.setLineNo(Integer.parseInt(element.getAttribute("line")));
68
69 /* History is consisting of a list of epoch nodes */
70 epochNodeList = document.getElementsByTagName("epoch");
71 //printAllNodes(epochNodeList);
72 for (int i = 0; i < epochNodeList.getLength(); i++) {
73 epochNode = epochNodeList.item(i);
74 if (epochNode.getNodeType() == Node.ELEMENT_NODE) {
75 epoch = new Epoch();
76 bug.insertEpoch(epoch);
77 epoch.setEpochStep(Integer.parseInt(epochNode
78 .getAttributes().getNamedItem("step")
79 .getNodeValue()));
80
81 /* Get the list of trace nodes for this epoch node */
82 traceNodeList = epochNode.getChildNodes();
83 for (int j = 0; j < traceNodeList.getLength(); j++) {
84 /* Get the list of function nodes for this trace node */
85 traceNode = traceNodeList.item(j);
86 if (traceNode.getNodeType() == Node.ELEMENT_NODE) {
87 functionNodeList = traceNode.getChildNodes();
88 for (int k = 0; k < functionNodeList.getLength(); k++) {
89 functionNode = functionNodeList.item(k);
90 if (functionNode.getNodeType() == Node.ELEMENT_NODE) {
91 function = new Function();
92 epoch.insertFunction(function);
93 function.setFunctionName(functionNode
94 .getAttributes()
95 .getNamedItem("name")
96 .getNodeValue());
97 function.setLineNo(Integer
98 .parseInt(functionNode
99 .getAttributes()
100 .getNamedItem("line")
101 .getNodeValue()));
102 function.setFileName(functionNode
103 .getAttributes()
104 .getNamedItem("file")
105 .getNodeValue());
106
107 /*
108 * Get the list of expression nodes for this
109 * function
110 */
111 tmpNodeList = functionNode.getChildNodes();
112 for (int t = 0; t < tmpNodeList.getLength(); t++) { // skipping the
113 // unnecessary
114 // node
115 // named
116 // <expressions></expressions>
117 tmpNode = tmpNodeList.item(t);
118 if (tmpNode.getNodeName().equals("expressions"))
119 break;
120 }
121 expressionNodeList = tmpNode.getChildNodes();
122 for (int l = 0; l < expressionNodeList
123 .getLength(); l++) {
124 expressionNode = expressionNodeList
125 .item(l);
126 if (expressionNode.getNodeType() == Node.ELEMENT_NODE) {
127 expression = new Expression();
128 function.insertExpression(expression);
129 expression.setName(expressionNode
130 .getAttributes()
131 .getNamedItem("name")
132 .getNodeValue());
133 expression.setValue(expressionNode
134 .getTextContent());
135 }
136 }
137 } // end if functionNode
138 } // end for functionNodeList
139 } // end if traceNode
140 } // end for traceNodeList
141 } // end if epochNode
142 } // end for epochNodeList
143 } catch (Exception e) {
144 System.err.println("Fatal error: unable to parse XML file. Entomologist will exit now.");
145 e.printStackTrace();
146 System.exit(1);
147 }
148 return bug;
149 }
150
151 public static void printBug(Bug bug) {
152 Epoch epoch;
153 Function function;
154 Expression expression;
155 System.out.println("Bug:");
156 System.out.println("---------");
157 System.out.println("Category: " + bug.getCategory());
158 System.out.println("File Name: " + bug.getFileName());
159 System.out.println("Function Name: " + bug.getFunctionName());
160 System.out.println("Line Number: " + bug.getLineNo());
161 System.out.println("------------------------------------------------------");
162 for (int i = 0; i < bug.getEpochNum(); i++) {
163 epoch = bug.getEpoch(i);
164 System.out.println("Epoch Step: " + epoch.getEpochStep());
165 System.out.println("---------------");
166 for (int j = 0; j < epoch.getFunctionNum(); j++) {
167 function = epoch.getFunction(j);
168 System.out.println("Function: " + function.getFunctionName() + " file: " + function.getFileName() + " Lineno." + function.getLineNo());
169 System.out.println("-----------------------------------------------------");
170 for (int k = 0; k < function.getExpressionNum(); k++) {
171 expression = function.getExpression(k);
172 System.out.println(expression.getName() + " = " + expression.getValue());
173 }
174 System.out.println("");
175 }
176 System.out.println("");
177 }
178 }
179
180
181
182 // This method is used for debugging
183 /*
184 private static void printAllNodes(NodeList nodeList) {
185 NodeList childNodes;
186 for (int i = 0; i < nodeList.getLength(); i++) {
187 if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
188 System.out.println(nodeList.item(i).getNodeName() + " type ="
189 + nodeList.item(i).getNodeType());
190 childNodes = nodeList.item(i).getChildNodes();
191 printAllNodes(childNodes);
192 }
193 }
194 }
195 */
196}
diff --git a/entomologist/src/org/monkey/comparator/testing/ComparatorTest.java b/entomologist/src/org/monkey/comparator/testing/ComparatorTest.java
new file mode 100644
index 0000000..5906fd3
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/ComparatorTest.java
@@ -0,0 +1,111 @@
1package org.monkey.comparator.testing;
2
3import static org.junit.Assert.*;
4
5import org.junit.Test;
6import org.monkey.comparator.MonkeyComparator;
7import org.monkey.comparator.bo.Bug;
8import org.monkey.comparator.bo.XMLParser;
9
10public class ComparatorTest {
11
12 @Test
13 public void testTotalSimilarity() {
14 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey.xml");
15 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey.xml");
16 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
17 assertEquals(100.0, similarityPercentage, 0);
18 System.out.println("score = " + similarityPercentage);
19 }
20
21 @Test
22 public void testSameStackDifferentFunctionNames() {
23 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey.xml");
24 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_fname.xml");
25
26 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
27 assertEquals(99.58333333333333, similarityPercentage, 0);
28 System.out.println("score = " + similarityPercentage);
29 }
30
31 @Test
32 public void testCommonAndDifferentExpressions() {
33 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey.xml");
34 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_common_and_different_exp.xml");
35
36 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
37 assertEquals(93.33333333333333, similarityPercentage, 0);
38 System.out.println("score = " + similarityPercentage);
39 }
40
41 @Test
42 public void testSlightlyDifferentStackTraces() {
43 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey.xml");
44 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_trace.xml");
45
46 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
47 assertEquals(88.8888888888889, similarityPercentage, 0);
48 System.out.println("score = " + similarityPercentage);
49 }
50
51 @Test
52 public void testNpeAndNpeExpressionsModified() {
53 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/npe.xml");
54 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/npe_expressions_modified.xml");
55
56 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
57 assertEquals(89.25, similarityPercentage, 0);
58 System.out.println("score = " + similarityPercentage);
59 }
60
61 @Test
62 public void testNpeAndNpeExpressionsAndStackModified() {
63 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/npe.xml");
64 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/npe_expressions_and_stack_modified.xml");
65
66 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
67 assertEquals(80.76282051282053, similarityPercentage, 0);
68 System.out.println("score = " + similarityPercentage);
69 }
70
71
72 @Test
73 public void testNpeAndDivisionByZero() {
74 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/npe.xml");
75 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/npe_divzero.xml");
76
77 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
78 System.out.println("score = " + similarityPercentage);
79 assertEquals(32.958333333333336, similarityPercentage, 0);
80 }
81
82 @Test
83 public void testIdenticalHistory() {
84 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_trace.xml");
85 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_trace.xml");
86
87 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
88 System.out.println("score = " + similarityPercentage);
89 assertEquals(100.0, similarityPercentage, 0);
90 }
91
92 @Test
93 public void testDifferentHistory() {
94 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_trace.xml");
95 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_history.xml");
96
97 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
98 System.out.println("score = " + similarityPercentage);
99 assertEquals(94.44444444444446, similarityPercentage, 0);
100 }
101
102 @Test
103 public void testDifferentAndLongerHistory() {
104 Bug bugA = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_trace.xml");
105 Bug bugB = XMLParser.parse("src/org/monkey/comparator/testing/refs/monkey_different_and_longer_history.xml");
106
107 double similarityPercentage = MonkeyComparator.compareBugs(bugA, bugB, "comparator.properties");
108 System.out.println("score = " + similarityPercentage);
109 assertEquals(94.44444444444446, similarityPercentage, 0);
110 }
111}
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/monkey.xml b/entomologist/src/org/monkey/comparator/testing/refs/monkey.xml
new file mode 100644
index 0000000..f484a32
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/monkey.xml
@@ -0,0 +1,45 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history>
4<epoch step="0" >
5<trace>
6<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
7<expressions>
8<expression name="crashStruct" >NULL</expression>
9<expression name="x" >5</expression>
10<expression name="y" >6</expression>
11<expression name="s" >Hello</expression>
12</expressions>
13</function>
14<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
15<expressions>
16<expression name="a" >3</expression>
17<expression name="b" >7</expression>
18<expression name="c" >9</expression>
19<expression name="d" >112</expression>
20</expressions>
21</function>
22</trace>
23</epoch>
24<epoch step="1" >
25<trace>
26<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
27<expressions>
28<expression name="crashStruct" >NULL</expression>
29<expression name="x" >5</expression>
30<expression name="y" >6</expression>
31<expression name="s" >Hello</expression>
32</expressions>
33</function>
34<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
35<expressions>
36<expression name="a" >3</expression>
37<expression name="b" >7</expression>
38<expression name="c" >9</expression>
39<expression name="d" >112</expression>
40</expressions>
41</function>
42</trace>
43</epoch>
44</history>
45</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/monkey_common_and_different_exp.xml b/entomologist/src/org/monkey/comparator/testing/refs/monkey_common_and_different_exp.xml
new file mode 100644
index 0000000..9b69ef2
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/monkey_common_and_different_exp.xml
@@ -0,0 +1,47 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history>
4<epoch step="0" >
5<trace>
6<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
7<expressions>
8<expression name="crashStruct" >NULL</expression>
9<expression name="x" >5</expression>
10<expression name="p" >10</expression>
11<expression name="y" >6</expression>
12<expression name="ssss" >Hello</expression>
13</expressions>
14</function>
15<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
16<expressions>
17<expression name="a" >3</expression>
18<expression name="b" >7</expression>
19<expression name="c" >9</expression>
20<expression name="d" >112</expression>
21</expressions>
22</function>
23</trace>
24</epoch>
25<epoch step="1" >
26<trace>
27<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
28<expressions>
29<expression name="crashStruct" >NULL</expression>
30<expression name="x" >5</expression>
31<expression name="p" >10</expression>
32<expression name="y" >6</expression>
33<expression name="ssss" >Hello</expression>
34</expressions>
35</function>
36<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
37<expressions>
38<expression name="a" >3</expression>
39<expression name="b" >7</expression>
40<expression name="c" >9</expression>
41<expression name="d" >112</expression>
42</expressions>
43</function>
44</trace>
45</epoch>
46</history>
47</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_and_longer_history.xml b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_and_longer_history.xml
new file mode 100644
index 0000000..2a2edde
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_and_longer_history.xml
@@ -0,0 +1,114 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history>
4<epoch step="0" >
5<trace>
6<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
7<expressions>
8<expression name="crashStruct" >NULL</expression>
9<expression name="x" >5</expression>
10<expression name="y" >6</expression>
11<expression name="s" >Hello</expression>
12</expressions>
13</function>
14<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
15<expressions>
16<expression name="alpha" >1</expression>
17<expression name="beta" >2</expression>
18<expression name="gamma" >7</expression>
19<expression name="delta" >hurray</expression>
20</expressions>
21</function>
22<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
23<expressions>
24<expression name="a" >3</expression>
25<expression name="b" >7</expression>
26<expression name="c" >9</expression>
27<expression name="d" >112</expression>
28</expressions>
29</function>
30</trace>
31</epoch>
32<epoch step="1" >
33<trace>
34<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
35<expressions>
36<expression name="crashStruct" >NULL</expression>
37<expression name="x" >5</expression>
38<expression name="y" >6</expression>
39<expression name="s" >Hello</expression>
40</expressions>
41</function>
42<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
43<expressions>
44<expression name="alpha" >1</expression>
45<expression name="beta" >2</expression>
46<expression name="gamma" >7</expression>
47<expression name="delta" >hurray</expression>
48</expressions>
49</function>
50<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
51<expressions>
52<expression name="i" >3</expression>
53<expression name="j" >7</expression>
54<expression name="k" >9</expression>
55</expressions>
56</function>
57</trace>
58</epoch>
59<epoch step="2" >
60<trace>
61<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
62<expressions>
63<expression name="crashStruct" >NULL</expression>
64<expression name="x" >5</expression>
65<expression name="y" >6</expression>
66<expression name="s" >Hello</expression>
67</expressions>
68</function>
69<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
70<expressions>
71<expression name="alpha" >1</expression>
72<expression name="beta" >2</expression>
73<expression name="gamma" >7</expression>
74<expression name="delta" >hurray</expression>
75</expressions>
76</function>
77<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
78<expressions>
79<expression name="i" >3</expression>
80<expression name="j" >7</expression>
81<expression name="k" >9</expression>
82</expressions>
83</function>
84</trace>
85</epoch>
86<epoch step="3" >
87<trace>
88<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
89<expressions>
90<expression name="crashStruct" >NULL</expression>
91<expression name="x" >5</expression>
92<expression name="y" >6</expression>
93<expression name="s" >Hello</expression>
94</expressions>
95</function>
96<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
97<expressions>
98<expression name="alpha" >1</expression>
99<expression name="beta" >2</expression>
100<expression name="gamma" >7</expression>
101<expression name="delta" >hurray</expression>
102</expressions>
103</function>
104<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
105<expressions>
106<expression name="i" >3</expression>
107<expression name="j" >7</expression>
108<expression name="k" >9</expression>
109</expressions>
110</function>
111</trace>
112</epoch>
113</history>
114</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_fname.xml b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_fname.xml
new file mode 100644
index 0000000..4bc9adb
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_fname.xml
@@ -0,0 +1,45 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history>
4<epoch step="0" >
5<trace>
6<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
7<expressions>
8<expression name="crashStruct" >NULL</expression>
9<expression name="x" >5</expression>
10<expression name="y" >6</expression>
11<expression name="s" >Hello</expression>
12</expressions>
13</function>
14<function name="theOtherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
15<expressions>
16<expression name="a" >3</expression>
17<expression name="b" >7</expression>
18<expression name="c" >9</expression>
19<expression name="d" >112</expression>
20</expressions>
21</function>
22</trace>
23</epoch>
24<epoch step="1" >
25<trace>
26<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
27<expressions>
28<expression name="crashStruct" >NULL</expression>
29<expression name="x" >5</expression>
30<expression name="y" >6</expression>
31<expression name="s" >Hello</expression>
32</expressions>
33</function>
34<function name="theOtherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
35<expressions>
36<expression name="a" >3</expression>
37<expression name="b" >7</expression>
38<expression name="c" >9</expression>
39<expression name="d" >112</expression>
40</expressions>
41</function>
42</trace>
43</epoch>
44</history>
45</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_history.xml b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_history.xml
new file mode 100644
index 0000000..7fc9ac0
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_history.xml
@@ -0,0 +1,60 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history>
4<epoch step="0" >
5<trace>
6<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
7<expressions>
8<expression name="crashStruct" >NULL</expression>
9<expression name="x" >5</expression>
10<expression name="y" >6</expression>
11<expression name="s" >Hello</expression>
12</expressions>
13</function>
14<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
15<expressions>
16<expression name="alpha" >1</expression>
17<expression name="beta" >2</expression>
18<expression name="gamma" >7</expression>
19<expression name="delta" >hurray</expression>
20</expressions>
21</function>
22<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
23<expressions>
24<expression name="a" >3</expression>
25<expression name="b" >7</expression>
26<expression name="c" >9</expression>
27<expression name="d" >112</expression>
28</expressions>
29</function>
30</trace>
31</epoch>
32<epoch step="1" >
33<trace>
34<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
35<expressions>
36<expression name="crashStruct" >NULL</expression>
37<expression name="x" >5</expression>
38<expression name="y" >6</expression>
39<expression name="s" >Hello</expression>
40</expressions>
41</function>
42<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
43<expressions>
44<expression name="alpha" >1</expression>
45<expression name="beta" >2</expression>
46<expression name="gamma" >7</expression>
47<expression name="delta" >hurray</expression>
48</expressions>
49</function>
50<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
51<expressions>
52<expression name="i" >3</expression>
53<expression name="j" >7</expression>
54<expression name="k" >9</expression>
55</expressions>
56</function>
57</trace>
58</epoch>
59</history>
60</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_trace.xml b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_trace.xml
new file mode 100644
index 0000000..200364c
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/monkey_different_trace.xml
@@ -0,0 +1,61 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history>
4<epoch step="0" >
5<trace>
6<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
7<expressions>
8<expression name="crashStruct" >NULL</expression>
9<expression name="x" >5</expression>
10<expression name="y" >6</expression>
11<expression name="s" >Hello</expression>
12</expressions>
13</function>
14<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
15<expressions>
16<expression name="alpha" >1</expression>
17<expression name="beta" >2</expression>
18<expression name="gamma" >7</expression>
19<expression name="delta" >hurray</expression>
20</expressions>
21</function>
22<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
23<expressions>
24<expression name="a" >3</expression>
25<expression name="b" >7</expression>
26<expression name="c" >9</expression>
27<expression name="d" >112</expression>
28</expressions>
29</function>
30</trace>
31</epoch>
32<epoch step="1" >
33<trace>
34<function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
35<expressions>
36<expression name="crashStruct" >NULL</expression>
37<expression name="x" >5</expression>
38<expression name="y" >6</expression>
39<expression name="s" >Hello</expression>
40</expressions>
41</function>
42<function name="intermediateFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
43<expressions>
44<expression name="alpha" >1</expression>
45<expression name="beta" >2</expression>
46<expression name="gamma" >7</expression>
47<expression name="delta" >hurray</expression>
48</expressions>
49</function>
50<function name="anotherCrashFunction" line="3" file="bug_null_pointer_exception.c" depth="1" >
51<expressions>
52<expression name="a" >3</expression>
53<expression name="b" >7</expression>
54<expression name="c" >9</expression>
55<expression name="d" >112</expression>
56</expressions>
57</function>
58</trace>
59</epoch>
60</history>
61</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/npe.xml b/entomologist/src/org/monkey/comparator/testing/refs/npe.xml
new file mode 100644
index 0000000..a5ae517
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/npe.xml
@@ -0,0 +1,29 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="14" file="bug_null_pointer_exception.c" >
3<history><epoch step="0" >
4<trace><function name="crashFunction" line="14" file="bug_null_pointer_exception.c" depth="0" >
5<expressions><expression name="crashStruct-&gt;crashValue=&quot;hello!&quot;" >
6Not Evaluated</expression>
7<expression name="crashStruct-&gt;crashValue" >
8Not Evaluated</expression>
9<expression name="printf(&quot;Now the program will crash!\n&quot;)" >
10Not Evaluated</expression>
11<expression name="NULL" >
12Not Evaluated</expression>
13<expression name="crashStruct" >
140x0</expression>
15</expressions>
16</function>
17<function name="main" line="19" file="bug_null_pointer_exception.c" depth="1" >
18<expressions><expression name="crashFunction()" >
19Not Evaluated</expression>
20<expression name="argv" >
21Not Evaluated</expression>
22<expression name="argc" >
23Not Evaluated</expression>
24</expressions>
25</function>
26</trace>
27</epoch>
28</history>
29</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/npe_divzero.xml b/entomologist/src/org/monkey/comparator/testing/refs/npe_divzero.xml
new file mode 100644
index 0000000..7af7cfc
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/npe_divzero.xml
@@ -0,0 +1,43 @@
1<?xml version="1.0"?>
2<crash category="Division By Zero" function="crashFunction" line="21" file="bug_null_pointer_exception.c" >
3<history><epoch step="0" >
4<trace><function name="crashFunction" line="21" file="bug_null_pointer_exception.c" depth="0" >
5<expressions><expression name="crashStruct-&gt;crashValue" >
6Not Evaluated</expression>
7<expression name="printf(&quot;Now the program will crash!\n&quot;)" >
8Not Evaluated</expression>
9<expression name="printf(&quot;result = %d\n&quot;,result)" >
10Not Evaluated</expression>
11<expression name="result/k" >
12Not Evaluated</expression>
13<expression name="i&lt;5" >
141</expression>
15<expression name="i" >
161</expression>
17<expression name="printf(&quot;I am alive!\n&quot;)" >
18Not Evaluated</expression>
19<expression name="result" >
20-10</expression>
21<expression name="-1" >
22-1</expression>
23<expression name="k" >
240</expression>
25<expression name="NULL" >
26Not Evaluated</expression>
27<expression name="crashStruct" >
280x0</expression>
29</expressions>
30</function>
31<function name="main" line="30" file="bug_null_pointer_exception.c" depth="1" >
32<expressions><expression name="crashFunction()" >
33Not Evaluated</expression>
34<expression name="argv" >
35Not Evaluated</expression>
36<expression name="argc" >
37Not Evaluated</expression>
38</expressions>
39</function>
40</trace>
41</epoch>
42</history>
43</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_and_stack_modified.xml b/entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_and_stack_modified.xml
new file mode 100644
index 0000000..6082988
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_and_stack_modified.xml
@@ -0,0 +1,42 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="20" file="bug_null_pointer_exception.c" >
3<history><epoch step="0" >
4<trace><function name="crashFunction" line="20" file="bug_null_pointer_exception_modified.c" depth="0" >
5<expressions><expression name="crashStruct-&gt;crashValue=&quot;hello!&quot;" >
6Not Evaluated</expression>
7<expression name="crashStruct-&gt;crashValue" >
8Not Evaluated</expression>
9<expression name="printf(&quot;Now the program will crash!\n&quot;)" >
10Not Evaluated</expression>
11<expression name="NULL" >
12Not Evaluated</expression>
13<expression name="crashStruct" >
140x0</expression>
15<expression name="a+b" >
168</expression>
17<expression name="c" >
188</expression>
19<expression name="b" >
205</expression>
21<expression name="a" >
223</expression>
23</expressions>
24</function>
25<function name="intermediateFunction" line="25" file="bug_null_pointer_exception_modified.c" depth="1" >
26<expressions><expression name="crashFunction()" >
27Not Evaluated</expression>
28</expressions>
29</function>
30<function name="main" line="30" file="bug_null_pointer_exception_modified.c" depth="2" >
31<expressions><expression name="intermediateFunction()" >
32Not Evaluated</expression>
33<expression name="argv" >
34Not Evaluated</expression>
35<expression name="argc" >
36Not Evaluated</expression>
37</expressions>
38</function>
39</trace>
40</epoch>
41</history>
42</crash>
diff --git a/entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_modified.xml b/entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_modified.xml
new file mode 100644
index 0000000..ad2ac79
--- /dev/null
+++ b/entomologist/src/org/monkey/comparator/testing/refs/npe_expressions_modified.xml
@@ -0,0 +1,37 @@
1<?xml version="1.0"?>
2<crash category="npe" function="crashFunction" line="20" file="bug_null_pointer_exception.c" >
3<history><epoch step="0" >
4<trace><function name="crashFunction" line="20" file="bug_null_pointer_exception.c" depth="0" >
5<expressions><expression name="crashStruct-&gt;crashValue=&quot;hello!&quot;" >
6Not Evaluated</expression>
7<expression name="crashStruct-&gt;crashValue" >
8Not Evaluated</expression>
9<expression name="printf(&quot;Now the program will crash!\n&quot;)" >
10Not Evaluated</expression>
11<expression name="NULL" >
12Not Evaluated</expression>
13<expression name="crashStruct" >
140x0</expression>
15<expression name="a+b" >
168</expression>
17<expression name="c" >
188</expression>
19<expression name="b" >
205</expression>
21<expression name="a" >
223</expression>
23</expressions>
24</function>
25<function name="main" line="25" file="bug_null_pointer_exception.c" depth="1" >
26<expressions><expression name="crashFunction()" >
27Not Evaluated</expression>
28<expression name="argv" >
29Not Evaluated</expression>
30<expression name="argc" >
31Not Evaluated</expression>
32</expressions>
33</function>
34</trace>
35</epoch>
36</history>
37</crash>