Skip to content

Commit

Permalink
♻️ Refactor test
Browse files Browse the repository at this point in the history
  • Loading branch information
yhs0602 committed May 14, 2024
1 parent af6a0f9 commit af827cf
Show file tree
Hide file tree
Showing 61 changed files with 145 additions and 698 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ bin/
.vscode/

### Mac OS ###
.DS_Store
.DS_Store
**/classes.dex.cache
5 changes: 3 additions & 2 deletions src/main/kotlin/vm/instruction/InvokeInstruction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ open class InvokeVirtual(pc: Int, val code: CodeItem) : Instruction._35c(pc, cod
val args = Array(A) { memory.registers[argRegList[it]] }
val instance = args.firstOrNull()
if (instance !is RegisterValue.ObjectRef) {
memory.exception = ExceptionValue("InvokeVirtual: Not an object reference")
memory.exception = ExceptionValue("InvokeVirtual: Not an object reference: $instance")
// throw Exception("InvokeVirtual: Not an object reference")
return pc + insnLength
}
val method = environment.getMethod(code, BBBB, instance, direct = false, false)
Expand Down Expand Up @@ -53,7 +54,7 @@ class InvokeSuper(pc: Int, code: CodeItem) : InvokeVirtual(pc, code) {
val args = Array(A) { memory.registers[argRegList[it]] }
val instance = args.firstOrNull()
if (instance !is RegisterValue.ObjectRef) {
memory.exception = ExceptionValue("InvokeVirtual: Not an object reference")
memory.exception = ExceptionValue("InvokeSuper: Not an object reference")
return pc + insnLength
}
val method = environment.getMethod(code, BBBB, instance, direct = false, true)
Expand Down
79 changes: 79 additions & 0 deletions src/test/kotlin/SimpleOperationTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import com.yhs0602.dex.DexFile
import com.yhs0602.dex.TypeId
import com.yhs0602.vm.Environment
import com.yhs0602.vm.GeneralMockedClass
import com.yhs0602.vm.RegisterValue
import com.yhs0602.vm.executeMethod
import com.yhs0602.vm.instance.MockedInstance
import java.io.PrintStream
import java.nio.file.Paths
import kotlin.jvm.internal.Intrinsics
import kotlin.test.Test

class SimpleOperationTest {
@Test
fun testReadFile() {
val path = Paths.get("src/test/resources/advanced/")
val inputDirectory = path.toFile()
println(inputDirectory.absolutePath)
val dexes = inputDirectory.listFiles { _, name ->
name.endsWith(".dex")
} ?: error("No dex files found")
val parsedDexes = dexes.map {
DexFile.fromFile(it)
}
val packageName = "com.example.sample"
val packageNameStr = packageName.replace(".", "/")
val classes = parsedDexes.flatMap { it.classDefs }
val className = "TargetMethods"
val classNameStr = "L$packageNameStr/$className;"
val classDef = classes.find {
it.classDef.typeId.descriptor == classNameStr
} ?: error("No class found")
val methods = classDef.classData?.run {
directMethods + virtualMethods
} ?: error("No methods found")
val methodName = "doTest"
val method = methods.find {
it.methodId.name == methodName
} ?: error("No method found")
val codeItem = method.codeItem ?: error("No code found")
val args = Array(codeItem.insSize.toInt()) {
RegisterValue.ObjectRef(
TypeId("com/example/sample/TargetMethods;"), MockedInstance(
Object::class.java
)
) // To simply pass anything
}
val mockedClassesList = listOf(
GeneralMockedClass(StringBuilder::class.java),
GeneralMockedClass(PrintStream::class.java),
GeneralMockedClass(System::class.java),
GeneralMockedClass(Intrinsics::class.java),
GeneralMockedClass(Object::class.java),
)
val mockedMethodList = mockedClassesList.flatMap {
it.getMethods()
}
val mockedMethods = mockedMethodList.associateBy {
Triple(it.classId, it.parameters, it.name)
}
val mockedClasses = mockedClassesList.associateBy {
it.classId
}
val environment = Environment(
parsedDexes,
mockedMethods,
mockedClasses,
beforeInstruction = { pc, instruction, memory, depth ->
val indentation = " ".repeat(depth)
println("$indentation Before $instruction: $pc// ${memory.registers.toList()} exception=${memory.exception}, returnValue = ${memory.returnValue.contentToString()}") // Debug
},
afterInstruction = { pc, instruction, memory, depth ->
val indentation = " ".repeat(depth)
println("$indentation After $instruction: $pc// ${memory.registers.toList()} exception=${memory.exception}, returnValue = ${memory.returnValue.contentToString()}") // Debug
}
)
executeMethod(codeItem, environment, args, args.size, 0)
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
61 changes: 61 additions & 0 deletions src/test/resources/advanced/TargetMethods.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.example.sample

class TargetMethods {
fun simpleMethod(a: Int, b: Int): Int {
return a + b
}

fun conditionalMethod(a: Int, b: Int): Int {
return if (a > b) {
a
} else {
b
}
}

fun loopMethod(count: Int): Int {
var sum = 0
for (i in 1..count) {
sum += i
}
return sum
}

fun arrayMethod(arr: IntArray): Int {
var sum = 0
for (num in arr) {
sum += num
}
return sum
}

fun instanceMethod(other: TargetMethods): Int {
return simpleMethod(3, other.conditionalMethod(5, 2))
}


companion object {
@JvmStatic
fun doTest() {
val thisObject = TargetMethods()
val simpleResult = thisObject.simpleMethod(2, 3)
assert(simpleResult == 5)
println("Simple method: $simpleResult") // Output: Simple method: 5
val conditionalResult = thisObject.conditionalMethod(5, 3)
assert(conditionalResult == 5)
println("Conditional method: $conditionalResult")
// Output: Conditional method: 5
val loopMethodResult = thisObject.loopMethod(5)
assert(loopMethodResult == 15)
println("Loop method: $loopMethodResult") // Output: Loop method: 15
val myArray = intArrayOf(1, 2, 3, 4, 5)
val arrayMethodResult = thisObject.arrayMethod(myArray)
assert(arrayMethodResult == 15)
println("Array method: $arrayMethodResult") // Output: Array method: 15
val other2Object = TargetMethods()
val instanceMethodResult = thisObject.instanceMethod(other2Object)
assert(instanceMethodResult == 8)
println("Instance method: $instanceMethodResult") // Output: Instance method: 8
}
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added src/test/resources/advanced/classes4.dex
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion test-data/advanced/classes.dex.cache/code-version

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
78 changes: 0 additions & 78 deletions test-data/advanced/classes.dex.cache/sources/37/00002437.java

This file was deleted.

70 changes: 0 additions & 70 deletions test-data/advanced/classes.dex.cache/sources/38/00002438.java

This file was deleted.

16 changes: 0 additions & 16 deletions test-data/advanced/classes.dex.cache/sources/5a/0000245a.java

This file was deleted.

Loading

0 comments on commit af827cf

Please sign in to comment.