1+ package org.utbot.framework.plugin.sarif
2+
3+ import org.utbot.framework.codegen.ForceStaticMocking
4+ import org.utbot.framework.codegen.NoStaticMocking
5+ import org.utbot.framework.codegen.model.ModelBasedTestCodeGenerator
6+ import org.utbot.framework.plugin.api.UtBotTestCaseGenerator
7+ import org.utbot.framework.plugin.api.UtTestCase
8+ import org.utbot.sarif.SarifReport
9+ import org.utbot.sarif.SourceFindingStrategy
10+ import org.utbot.summary.summarize
11+ import java.io.File
12+ import java.net.URLClassLoader
13+ import java.nio.file.Path
14+
15+ /* *
16+ * Facade for `createSarifReport` task/mojo.
17+ * Stores common logic between gradle and maven plugins.
18+ */
19+ class CreateSarifReportFacade (
20+ val sarifProperties : SarifExtensionProvider ,
21+ val sourceFindingStrategy : SourceFindingStrategy
22+ ) {
23+
24+ /* *
25+ * Generates tests and a SARIF report for the class [targetClass].
26+ * Requires withUtContext() { ... }.
27+ */
28+ fun generateForClass (
29+ targetClass : TargetClassWrapper ,
30+ workingDirectory : Path ,
31+ runtimeClasspath : String
32+ ) {
33+ initializeEngine(runtimeClasspath, workingDirectory)
34+
35+ val testCases = generateTestCases(targetClass, workingDirectory)
36+ val testClassBody = generateTestCode(targetClass, testCases)
37+ targetClass.testsCodeFile.writeText(testClassBody)
38+
39+ generateReport(targetClass, testCases, testClassBody, sourceFindingStrategy)
40+ }
41+
42+ companion object {
43+ /* *
44+ * Merges all [sarifReports] into one large [mergedSarifReportFile] containing all the information.
45+ * Prints a message about where the SARIF file is saved if [verbose] is true.
46+ */
47+ fun mergeReports (
48+ sarifReports : List <String >,
49+ mergedSarifReportFile : File ,
50+ verbose : Boolean = true
51+ ) {
52+ val mergedReport = SarifReport .mergeReports(sarifReports)
53+ mergedSarifReportFile.writeText(mergedReport)
54+ if (verbose) {
55+ println (" SARIF report was saved to \" ${mergedSarifReportFile.path} \" " )
56+ println (" You can open it using the VS Code extension \" Sarif Viewer\" " )
57+ }
58+ }
59+ }
60+
61+ // internal
62+
63+ private val dependencyPaths by lazy {
64+ val thisClassLoader = this ::class .java.classLoader as URLClassLoader
65+ thisClassLoader.urLs.joinToString(File .pathSeparator) { it.path }
66+ }
67+
68+ private fun initializeEngine (classPath : String , workingDirectory : Path ) {
69+ UtBotTestCaseGenerator .init (workingDirectory, classPath, dependencyPaths) { false }
70+ }
71+
72+ private fun generateTestCases (targetClass : TargetClassWrapper , workingDirectory : Path ): List <UtTestCase > =
73+ UtBotTestCaseGenerator .generateForSeveralMethods(
74+ targetClass.targetMethods(),
75+ sarifProperties.mockStrategy,
76+ sarifProperties.classesToMockAlways,
77+ sarifProperties.generationTimeout
78+ ).map {
79+ it.summarize(targetClass.sourceCodeFile, workingDirectory)
80+ }
81+
82+ private fun generateTestCode (targetClass : TargetClassWrapper , testCases : List <UtTestCase >): String =
83+ initializeCodeGenerator(targetClass)
84+ .generateAsString(testCases, targetClass.testsCodeFile.nameWithoutExtension)
85+
86+ private fun initializeCodeGenerator (targetClass : TargetClassWrapper ) =
87+ ModelBasedTestCodeGenerator ().apply {
88+ val isNoStaticMocking = sarifProperties.staticsMocking is NoStaticMocking
89+ val isForceStaticMocking = sarifProperties.forceStaticMocking == ForceStaticMocking .FORCE
90+ init (
91+ classUnderTest = targetClass.classUnderTest.java,
92+ testFramework = sarifProperties.testFramework,
93+ mockFramework = sarifProperties.mockFramework,
94+ staticsMocking = sarifProperties.staticsMocking,
95+ forceStaticMocking = sarifProperties.forceStaticMocking,
96+ generateWarningsForStaticMocking = isNoStaticMocking && isForceStaticMocking,
97+ codegenLanguage = sarifProperties.codegenLanguage
98+ )
99+ }
100+
101+ /* *
102+ * Creates a SARIF report for the class [targetClass].
103+ * Saves the report to the file specified in [targetClass].
104+ */
105+ private fun generateReport (
106+ targetClass : TargetClassWrapper ,
107+ testCases : List <UtTestCase >,
108+ testClassBody : String ,
109+ sourceFinding : SourceFindingStrategy
110+ ) {
111+ val sarifReport = SarifReport (testCases, testClassBody, sourceFinding).createReport()
112+ targetClass.sarifReportFile.writeText(sarifReport)
113+ }
114+ }
0 commit comments