Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add withConfig test support for kotlin2cpg #3001

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ package io.joern.kotlin2cpg.querying
import io.joern.kotlin2cpg.testfixtures.KotlinCode2CpgFixture
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators}
import io.shiftleft.semanticcpg.language._
import io.joern.kotlin2cpg.Config
import io.joern.x2cpg.X2CpgConfig

class DefaultContentRootsTests extends KotlinCode2CpgFixture(withOssDataflow = false, withDefaultJars = true) {
class DefaultContentRootsTests extends KotlinCode2CpgFixture(withOssDataflow = false) {

override def getOverrideConfig(): Option[X2CpgConfig[?]] = {
val config = Config().withClasspath(getTestResourcesPaths())
Some(config)
}

"CPG for code with a simple function declaration with parameters of stdlib types, but not fully specified" should {
val cpg = code("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@ import io.shiftleft.codepropertygraph.generated.edges.{Capture, Ref}
import io.shiftleft.codepropertygraph.generated.nodes.{Binding, Block, ClosureBinding, MethodRef, Return}
import io.shiftleft.semanticcpg.language._
import overflowdb.traversal.jIteratortoTraversal
import io.joern.kotlin2cpg.Config
import io.joern.x2cpg.X2CpgConfig

class LambdaTests extends KotlinCode2CpgFixture(withOssDataflow = false) {

override def getOverrideConfig(): Option[X2CpgConfig[?]] = {
val config = Config().withClasspath(getTestResourcesPaths())
Some(config)
}

class LambdaTests extends KotlinCode2CpgFixture(withOssDataflow = false, withDefaultJars = true) {
"CPG for code with a simple lambda which captures a method parameter" should {
val cpg = code("fun f1(p: String) { 1.let { println(p) } }")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package io.joern.kotlin2cpg.querying

import io.joern.kotlin2cpg.testfixtures.KotlinCode2CpgFixture
import io.joern.kotlin2cpg.Config
import io.joern.x2cpg.Defines
import io.shiftleft.semanticcpg.language._
import io.joern.x2cpg.X2CpgConfig

class TypeAliasTests extends KotlinCode2CpgFixture(withOssDataflow = false) {

override def getOverrideConfig(): Option[X2CpgConfig[?]] = {
val config = Config().withClasspath(getTestResourcesPaths())
Some(config)
}

class TypeAliasTests extends KotlinCode2CpgFixture(withOssDataflow = false, withDefaultJars = true) {
"CPG for code with simple typealias to Int" should {
val cpg = code("""
|package mypkg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,22 @@ import io.shiftleft.utils.ProjectRoot
import java.io.File

trait KotlinFrontend extends LanguageFrontend {
protected val withTestResourcePaths: Boolean

override val fileSuffix: String = ".kt"

override def execute(sourceCodeFile: File): Cpg = {
val defaultContentRoot =
BFile(ProjectRoot.relativise("joern-cli/frontends/kotlin2cpg/src/test/resources/jars/"))
implicit val defaultConfig: Config =
Config(
classpath = if (withTestResourcePaths) Set(defaultContentRoot.path.toAbsolutePath.toString) else Set(),
includeJavaSourceFiles = true
implicit val defaultConfig: Config = getConfig()
.map(_.asInstanceOf[Config])
.getOrElse(
Config(
includeJavaSourceFiles = true
)
)
new Kotlin2Cpg().createCpg(sourceCodeFile.getAbsolutePath).get
}
}

class KotlinTestCpg(override protected val withTestResourcePaths: Boolean) extends TestCpg with KotlinFrontend {
class KotlinTestCpg() extends TestCpg with KotlinFrontend {
private var _withOssDataflow = false

def withOssDataflow(value: Boolean = true): this.type = {
Expand All @@ -49,10 +48,17 @@ class KotlinTestCpg(override protected val withTestResourcePaths: Boolean) exten
}
}

class KotlinCode2CpgFixture(withOssDataflow: Boolean = false, withDefaultJars: Boolean = false)
extends Code2CpgFixture(() => new KotlinTestCpg(withDefaultJars).withOssDataflow(withOssDataflow)) {
class KotlinCode2CpgFixture(withOssDataflow: Boolean = false)
extends Code2CpgFixture(() => new KotlinTestCpg().withOssDataflow(withOssDataflow)) {

implicit val context: EngineContext = EngineContext()

protected def flowToResultPairs(path: Path): List[(String, Option[Integer])] = path.resultPairs()

protected def getTestResourcesPaths(): Set[String] = {
val defaultContentRoot =
BFile(ProjectRoot.relativise("joern-cli/frontends/kotlin2cpg/src/test/resources/jars/"))

Set(defaultContentRoot.path.toAbsolutePath().toString)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

import scala.collection.mutable
import io.joern.x2cpg.X2CpgConfig

// Fixture class from which all tests which require a code to CPG translation step
// should either directly or indirectly use. The intended way is to derive from
Expand All @@ -18,18 +19,25 @@ class Code2CpgFixture[T <: TestCpg](testCpgFactory: () => T)
with Matchers
with BeforeAndAfterAll
with Inside {
private val cpgs = mutable.ArrayBuffer.empty[TestCpg]
private val cpgs = mutable.ArrayBuffer.empty[TestCpg]
private var config: Option[X2CpgConfig[_]] = None

/** This method can be overridden to specify config that should be used for all tests in a fixture.
*/
def getOverrideConfig(): Option[X2CpgConfig[_]] = {
None
}

def code(code: String): T = {
val newCpg = testCpgFactory().moreCode(code)
cpgs.append(newCpg)
newCpg
newCpg.withConfig(getOverrideConfig())
}

def code(code: String, fileName: String): T = {
val newCpg = testCpgFactory().moreCode(code, fileName)
cpgs.append(newCpg)
newCpg
newCpg.withConfig(getOverrideConfig())
}

override def afterAll(): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ abstract class TestCpg extends Cpg() with LanguageFrontend {
this
}

def withConfig(config: Option[X2CpgConfig[_]]): this.type = {
config.foreach(setConfig)
this
}

private def checkGraphEmpty(): Unit = {
if (_graph.isDefined) {
throw new RuntimeException("Modifying test data is not allowed after accessing graph.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ import io.joern.util.QueryUtil
import io.shiftleft.codepropertygraph.Cpg
import io.shiftleft.codepropertygraph.generated.nodes.ConfigFile
import io.shiftleft.semanticcpg.language._
import io.joern.x2cpg.X2CpgConfig
import io.joern.kotlin2cpg.Config

class AndroidQueryTestSuite[QB <: QueryBundle](val queryBundle: QB)
extends KotlinCode2CpgFixture(withOssDataflow = true, withDefaultJars = true) {
extends KotlinCode2CpgFixture(withOssDataflow = true) {

override def getOverrideConfig(): Option[X2CpgConfig[_]] = {
val config = Config().withClasspath(getTestResourcesPaths())
Some(config)
}

val argumentProvider = new QDBArgumentProvider(3)

Expand Down