Initial ScalaTest/JUnit setup.
This commit is contained in:
parent
dac1f130f8
commit
9c27279a2a
|
@ -92,6 +92,16 @@
|
|||
<artifactId>eu.aniketos.dasca.crosslanguage</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scalatest</groupId>
|
||||
<artifactId>scalatest_2.11</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* (C) Copyright 2016 The University of Sheffield.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
*/
|
||||
|
||||
package eu.aniketos.dasca.crosslanguage.test.apps
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference
|
||||
import com.ibm.wala.ipa.callgraph.CGNode
|
||||
import eu.aniketos.dasca.crosslanguage.util.Util
|
||||
import eu.aniketos.dasca.crosslanguage.builder.CordovaCGBuilder
|
||||
import eu.aniketos.dasca.crosslanguage.builder.FilterJavaCallSites
|
||||
import eu.aniketos.dasca.crosslanguage.builder.MockCordovaExec
|
||||
import eu.aniketos.dasca.crosslanguage.builder.ReplacePluginDefinesAndRequires
|
||||
import java.io.File
|
||||
import eu.aniketos.dasca.crosslanguage.util.JavaScriptSourceLocation
|
||||
import eu.aniketos.dasca.crosslanguage.util.JavaSourceLocation
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory
|
||||
import eu.aniketos.dasca.crosslanguage.util.SourceLocation
|
||||
import eu.aniketos.dasca.crosslanguage.builder.FilterJSFrameworks
|
||||
import scala.collection.mutable.LinkedHashSet
|
||||
import com.ibm.wala.classLoader.IMethod
|
||||
|
||||
|
||||
class AppTest(apk:String, expectedConnections:Set[(SourceLocation, SourceLocation)]){
|
||||
def apkDir = "src/main/resources/";
|
||||
|
||||
private var js2JavaHits = -1;
|
||||
private var js2JavaMisses = -1;
|
||||
private var js2JavaTotal = -1;
|
||||
|
||||
private var java2JSHits = -1;
|
||||
private var java2JSMisses = -1;
|
||||
private var java2JSTotal = -1;
|
||||
|
||||
def getJS2JavaHits() = {
|
||||
js2JavaHits
|
||||
}
|
||||
def getJS2JavaMisses() = {
|
||||
js2JavaMisses
|
||||
}
|
||||
|
||||
def getJS2JavaErrors() = {
|
||||
js2JavaTotal - js2JavaHits
|
||||
}
|
||||
|
||||
def getJS2JavaRecall() = {
|
||||
100.0 * js2JavaHits / (js2JavaHits + js2JavaMisses)
|
||||
}
|
||||
|
||||
def getJS2JavaPrecision() = {
|
||||
100.0 * js2JavaHits / js2JavaTotal
|
||||
}
|
||||
|
||||
|
||||
def getJava2JSHits() = {
|
||||
java2JSHits
|
||||
}
|
||||
def getJava2JSMisses() = {
|
||||
java2JSMisses
|
||||
}
|
||||
|
||||
def getJava2JSErrors() = {
|
||||
java2JSTotal - java2JSHits
|
||||
}
|
||||
|
||||
def getJava2JSRecall() = {
|
||||
100.0 * java2JSHits / (java2JSHits + java2JSMisses)
|
||||
}
|
||||
|
||||
def getJava2JSPrecision() = {
|
||||
100.0 * java2JSHits / java2JSTotal
|
||||
}
|
||||
|
||||
private var truePositives = Set[(SourceLocation, SourceLocation)]()
|
||||
private var falseNegatives = Set[(SourceLocation, SourceLocation)]()
|
||||
private var falsePositives = Set[(SourceLocation, SourceLocation)]()
|
||||
|
||||
def getTruePositives() = {
|
||||
truePositives
|
||||
}
|
||||
|
||||
def getFalseNegatives() = {
|
||||
falseNegatives
|
||||
}
|
||||
|
||||
def getFalsePositives() = {
|
||||
falsePositives
|
||||
}
|
||||
|
||||
def analyze() = {
|
||||
val builder = CordovaCGBuilder(new File(apkDir,apk))
|
||||
val mcg = builder.createCallGraph
|
||||
val crossTargets = mcg.getAllCrossTargets
|
||||
val convertedCrossTargets = convertToSourceLocationPairs(crossTargets)
|
||||
|
||||
val (javaPairs, jsPairs) = convertedCrossTargets.partition({case (origin, target) => origin.isInstanceOf[JavaSourceLocation]})
|
||||
java2JSTotal = javaPairs.size
|
||||
js2JavaTotal = jsPairs.size
|
||||
val (found, notFound) = expectedConnections.partition(p => convertedCrossTargets.contains(p))
|
||||
java2JSHits = found.count(_._1.isInstanceOf[JavaSourceLocation])
|
||||
js2JavaHits = found.count(_._1.isInstanceOf[JavaScriptSourceLocation])
|
||||
java2JSMisses = notFound.count(_._1.isInstanceOf[JavaSourceLocation])
|
||||
js2JavaMisses = notFound.count(_._1.isInstanceOf[JavaScriptSourceLocation])
|
||||
|
||||
truePositives = found
|
||||
falseNegatives = notFound
|
||||
falsePositives = convertedCrossTargets -- expectedConnections
|
||||
}
|
||||
|
||||
def convertToSourceLocationPairs(crossTargets: Map[(CGNode, CallSiteReference), LinkedHashSet[CGNode]]): Set[(SourceLocation, SourceLocation)] = {
|
||||
for (
|
||||
origin <- crossTargets.keys;
|
||||
target <- crossTargets.get(origin).get
|
||||
) yield {
|
||||
if (Util.isJavaNode(origin._1)) {
|
||||
target.getIR match {
|
||||
case ir: AstIRFactory[IMethod]#AstIR => (JavaSourceLocation(origin._1, origin._2), JavaScriptSourceLocation(ir))
|
||||
case _ => (JavaSourceLocation(origin._1, origin._2), new JavaScriptSourceLocation(-1, -1, "unknown"))
|
||||
}
|
||||
} else {
|
||||
origin._1.getIR match {
|
||||
case ir: AstIRFactory[IMethod]#AstIR => (JavaScriptSourceLocation(ir, origin._2), JavaSourceLocation(target))
|
||||
case _ => (new JavaScriptSourceLocation(-1, -1, "unknown"), JavaSourceLocation(target))
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toSet
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* (C) Copyright 2016 The University of Sheffield.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
*/
|
||||
|
||||
package eu.aniketos.dasca.crosslanguage.test.apps
|
||||
|
||||
|
||||
import collection.mutable.Stack
|
||||
import org.scalatest._
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
import eu.aniketos.dasca.crosslanguage.util.JavaScriptSourceLocation
|
||||
import eu.aniketos.dasca.crosslanguage.util.JavaSourceLocation
|
||||
import eu.aniketos.dasca.crosslanguage.util.SourceLocation
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class FeatherweightInfoTest extends FlatSpec with Matchers {
|
||||
def ApkName: String = "de.zertapps.dvhma.featherweight.apk"
|
||||
def connections = Set[(SourceLocation, SourceLocation)](
|
||||
(new JavaSourceLocation(43, "com/borismus/webintent/WebIntent"), new JavaScriptSourceLocation(31, 12, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(145, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"), new JavaScriptSourceLocation(77, 1, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(126, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"), new JavaScriptSourceLocation(77, 1, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(49, "com/borismus/webintent/WebIntent"), new JavaScriptSourceLocation(26, 58, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(49, "com/borismus/webintent/WebIntent"), new JavaScriptSourceLocation(25, 51, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(52, "com/borismus/webintent/WebIntent"), new JavaScriptSourceLocation(31, 12, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(36, "com/borismus/webintent/WebIntent"), new JavaScriptSourceLocation(31, 12, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(85, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"), new JavaScriptSourceLocation(77, 1, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(62, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"), new JavaScriptSourceLocation(46, 21, "www/js/index.js"))
|
||||
,(new JavaSourceLocation(62, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"), new JavaScriptSourceLocation(68, 25, "www/js/index.js"))
|
||||
,(new JavaScriptSourceLocation(7, 12, "www/plugins/de.zertapps.dvhma.plugins.webintent/www/webintent.js"), new JavaSourceLocation(28, "com/borismus/webintent/WebIntent"))
|
||||
,(new JavaScriptSourceLocation(28, 12, "www/plugins/de.zertapps.dvhma.plugins.storage/www/DVHMA-Storage.js"), new JavaSourceLocation(43, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"))
|
||||
,(new JavaScriptSourceLocation(24, 12, "www/plugins/de.zertapps.dvhma.plugins.storage/www/DVHMA-Storage.js"), new JavaSourceLocation(43, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"))
|
||||
,(new JavaScriptSourceLocation(16, 12, "www/plugins/de.zertapps.dvhma.plugins.storage/www/DVHMA-Storage.js"), new JavaSourceLocation(43, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"))
|
||||
,(new JavaScriptSourceLocation(20, 12, "www/plugins/de.zertapps.dvhma.plugins.storage/www/DVHMA-Storage.js"), new JavaSourceLocation(43, "de/zertapps/dvhma/plugins/storage/DVHMAStorage"))
|
||||
)
|
||||
|
||||
def fixture =
|
||||
new {
|
||||
val app = new AppTest(ApkName, connections);
|
||||
app.analyze();
|
||||
}
|
||||
|
||||
|
||||
|
||||
"Java -> JavaScript" should "report ten hits" in {
|
||||
fixture.app.getJS2JavaHits() should be (10)
|
||||
}
|
||||
|
||||
it should "report no misses" in {
|
||||
fixture.app.getJS2JavaMisses() should be (0)
|
||||
}
|
||||
|
||||
it should "report no errors" in {
|
||||
fixture.app.getJS2JavaErrors() should be (0)
|
||||
}
|
||||
|
||||
it should "have a precision of 100%" in {
|
||||
fixture.app.getJS2JavaPrecision() should be (100.0 +- 0.1)
|
||||
}
|
||||
|
||||
it should "have a recall of 100%" in {
|
||||
fixture.app.getJS2JavaRecall() should be (100.0 +- 0.1)
|
||||
}
|
||||
|
||||
|
||||
|
||||
"JavaScript -> Java" should "report ten hits" in {
|
||||
fixture.app.getJS2JavaHits() should be (5)
|
||||
}
|
||||
|
||||
it should "report no misses" in {
|
||||
fixture.app.getJS2JavaMisses() should be (0)
|
||||
}
|
||||
|
||||
it should "report no errors" in {
|
||||
fixture.app.getJS2JavaErrors() should be (0)
|
||||
}
|
||||
|
||||
it should "have a precision of 100%" in {
|
||||
fixture.app.getJS2JavaPrecision() should be (100.0 +- 0.1)
|
||||
}
|
||||
|
||||
it should "have a recall of 100%" in {
|
||||
fixture.app.getJS2JavaRecall() should be (100.0 +- 0.1)
|
||||
}
|
||||
|
||||
|
||||
|
||||
"Reported connections" should "contain all expected connections" in {
|
||||
fixture.app.getTruePositives() should contain theSameElementsAs connections
|
||||
}
|
||||
|
||||
it should "not contain false negatives" in {
|
||||
fixture.app.getFalseNegatives() shouldBe empty
|
||||
}
|
||||
|
||||
it should "not contain false positives" in {
|
||||
fixture.app.getFalsePositives() shouldBe empty
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue