From 1f0053d0bed40e1d2fd8229019318baee09786ad Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Thu, 26 Dec 2024 22:16:21 +0100 Subject: [PATCH 1/4] starting with JSON WFC Report --- wfc/pom.xml | 25 ++++++++++++++++++++++ wfc/src/main/resources/schemas/report.yaml | 17 +++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 wfc/src/main/resources/schemas/report.yaml diff --git a/wfc/pom.xml b/wfc/pom.xml index e39ea69f5e..4b0d84d620 100644 --- a/wfc/pom.xml +++ b/wfc/pom.xml @@ -20,6 +20,14 @@ + + + com.fasterxml.jackson.core + jackson-databind + 2.5.4 + + + org.junit.jupiter @@ -55,6 +63,23 @@ + + org.jsonschema2pojo + jsonschema2pojo-maven-plugin + 1.2.2 + + ${basedir}/src/main/resources/schemas + com.webfuzzing + yamlschema + + + + + generate + + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/wfc/src/main/resources/schemas/report.yaml b/wfc/src/main/resources/schemas/report.yaml new file mode 100644 index 0000000000..f522979a7e --- /dev/null +++ b/wfc/src/main/resources/schemas/report.yaml @@ -0,0 +1,17 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "TODO" +title: "Web Fuzzing Report" +description: "Schema TODO..." +type: "object" +properties: + schema_version: + type: string + tool_name: + type: string + creation_time: + type: string + format: date-time +required: ["schema_version","tool_name","creation_time"] + + + From 0d7e601a154563bae2209ccd817637069c0e2726 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Thu, 26 Dec 2024 22:45:29 +0100 Subject: [PATCH 2/4] basic version --- wfc/pom.xml | 17 +++++++++++++++-- wfc/src/main/resources/schemas/report.yaml | 21 +++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/wfc/pom.xml b/wfc/pom.xml index 4b0d84d620..d100a20978 100644 --- a/wfc/pom.xml +++ b/wfc/pom.xml @@ -68,16 +68,29 @@ jsonschema2pojo-maven-plugin 1.2.2 - ${basedir}/src/main/resources/schemas - com.webfuzzing yamlschema + report.yaml generate + + ${basedir}/src/main/resources/schemas/report.yaml + com.webfuzzing.commons.report + + + + + + + + + + + diff --git a/wfc/src/main/resources/schemas/report.yaml b/wfc/src/main/resources/schemas/report.yaml index f522979a7e..755538fd86 100644 --- a/wfc/src/main/resources/schemas/report.yaml +++ b/wfc/src/main/resources/schemas/report.yaml @@ -1,8 +1,8 @@ $schema: "https://json-schema.org/draft/2020-12/schema" $id: "TODO" title: "Web Fuzzing Report" -description: "Schema TODO..." -type: "object" +description: "Schema Definition for Web Fuzzing Commons Reports" +type: object properties: schema_version: type: string @@ -11,7 +11,24 @@ properties: creation_time: type: string format: date-time + rest_report: + $ref: "#/$def/RESTReport" required: ["schema_version","tool_name","creation_time"] +$def: + RESTReport: + type: object + properties: + faults: + $ref: "#/$def/Faults" + required: ["faults"] + + Faults: + type: object + properties: + total_number: + type: integer + min: 0 + required: ["total_number"] From fd53243002142e1152f25185ca0305cedbf99c1e Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Fri, 27 Dec 2024 23:22:13 +0100 Subject: [PATCH 3/4] first basic version of WFC Report --- .../kotlin/org/evomaster/core/EMConfig.kt | 8 ++ .../main/kotlin/org/evomaster/core/Main.kt | 79 ++++++++----------- .../core/output/TestSuiteSplitter.kt | 3 +- .../enterprise/service/EnterpriseModule.kt | 13 +++ .../enterprise/service/WFCReportWriter.kt | 53 +++++++++++++ .../problem/graphql/service/GraphQLModule.kt | 3 +- .../problem/rest/service/RestBaseModule.kt | 3 +- .../core/problem/rpc/service/RPCModule.kt | 3 +- .../problem/webfrontend/service/WebModule.kt | 3 +- .../org/evomaster/core/search/Solution.kt | 4 + docs/options.md | 1 + .../splitter/TestSuiteSplitterTest.java | 2 +- 12 files changed, 123 insertions(+), 52 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/EnterpriseModule.kt create mode 100644 core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt diff --git a/core/src/main/kotlin/org/evomaster/core/EMConfig.kt b/core/src/main/kotlin/org/evomaster/core/EMConfig.kt index 622c746cea..cbcba81803 100644 --- a/core/src/main/kotlin/org/evomaster/core/EMConfig.kt +++ b/core/src/main/kotlin/org/evomaster/core/EMConfig.kt @@ -594,6 +594,9 @@ class EMConfig { if(dockerLocalhost && !runningInDocker){ throw ConfigProblemException("Specifying 'dockerLocalhost' only makes sense when running EvoMaster inside Docker.") } + if(writeWFCReport && !createTests){ + throw ConfigProblemException("Cannot create a WFC Report if tests are not generated (i.e., 'createTests' is false)") + } } private fun checkPropertyConstraints(m: KMutableProperty<*>) { @@ -1242,6 +1245,11 @@ class EMConfig { @FilePath var statisticsFile = "statistics.csv" + + @Experimental + @Cfg("Output a JSON file representing statistics of the fuzzing session, written in the WFC Report format.") + var writeWFCReport = false + @Cfg("Whether should add to an existing statistics file, instead of replacing it") var appendToStatisticsFile = false diff --git a/core/src/main/kotlin/org/evomaster/core/Main.kt b/core/src/main/kotlin/org/evomaster/core/Main.kt index 4a58d0cd82..3214c0b290 100644 --- a/core/src/main/kotlin/org/evomaster/core/Main.kt +++ b/core/src/main/kotlin/org/evomaster/core/Main.kt @@ -18,6 +18,7 @@ import org.evomaster.core.output.TestSuiteSplitter import org.evomaster.core.output.clustering.SplitResult import org.evomaster.core.output.service.TestSuiteWriter import org.evomaster.core.problem.api.ApiWsIndividual +import org.evomaster.core.problem.enterprise.service.WFCReportWriter import org.evomaster.core.problem.externalservice.httpws.service.HarvestActualHttpWsResponseHandler import org.evomaster.core.problem.externalservice.httpws.service.HttpWsExternalServiceHandler import org.evomaster.core.problem.graphql.GraphQLIndividual @@ -257,6 +258,7 @@ class Main { writeCoveredTargets(injector, solution) writeTests(injector, solution, controllerInfo) + writeWFCReport(injector, solution) writeStatistics(injector, solution) //FIXME if other phases after search, might get skewed data on 100% snapshots... resetExternalServiceHandler(injector) @@ -690,19 +692,14 @@ class Main { val writer = injector.getInstance(TestSuiteWriter::class.java) - //TODO: enable splitting for csharp. Currently not enabled due to an error while running generated tests in multiple classes (error in starting the SUT) - if (config.problemType == EMConfig.ProblemType.REST && !config.outputFormat.isCsharp()) { + if (config.problemType == EMConfig.ProblemType.REST ) { - val splitResult = TestSuiteSplitter.split(solution, config, writer.getPartialOracles()) + val splitResult = TestSuiteSplitter.split(solution, config) solution.clusteringTime = splitResult.clusteringTime.toInt() - splitResult.splitOutcome.filter { !it.individuals.isNullOrEmpty() } + splitResult.splitOutcome + .filter { !it.individuals.isNullOrEmpty() } .forEach { writer.writeTests(it, controllerInfoDto?.fullName, controllerInfoDto?.executableFullPath, snapshotTimestamp) } - -// if (config.executiveSummary) { -// writeExecSummary(injector, controllerInfoDto, splitResult, snapshotTimestamp) -// //writeExecutiveSummary(injector, solution, controllerInfoDto, partialOracles) -// } } else { /* TODO refactor all the PartialOracle stuff that is meant for only REST @@ -715,6 +712,8 @@ class Main { fun writeTests(injector: Injector, solution: Solution<*>, controllerInfoDto: ControllerInfoDto?, snapshot: String = "") { + //TODO: the code here is quite messy. Needs to be refactored and simplified + val config = injector.getInstance(EMConfig::class.java) if (!config.createTests) { @@ -727,10 +726,9 @@ class Main { LoggingUtil.getInfoLogger().info("Going to save $tests to ${config.outputFolder}") val writer = injector.getInstance(TestSuiteWriter::class.java) - //TODO: enable splitting for csharp. Currently not enabled due to an error while running generated tests in multiple classes (error in starting the SUT) - if (config.problemType == EMConfig.ProblemType.REST && !config.outputFormat.isCsharp()) { + if (config.problemType == EMConfig.ProblemType.REST) { - val splitResult = TestSuiteSplitter.split(solution, config, writer.getPartialOracles()) + val splitResult = TestSuiteSplitter.split(solution, config) solution.clusteringTime = splitResult.clusteringTime.toInt() splitResult.splitOutcome @@ -741,21 +739,11 @@ class Main { config.maxTestsPerTestSuite ) } - .forEach { writer.writeTests(it, controllerInfoDto?.fullName,controllerInfoDto?.executableFullPath, snapshot) } + .forEach { + writer.writeTests(it, controllerInfoDto?.fullName,controllerInfoDto?.executableFullPath, snapshot) + } -// if (config.executiveSummary) { -// -// // Onur - if there are fault cases, executive summary makes sense -// if ( splitResult.splitOutcome.any{ it.individuals.isNotEmpty() -// && it.termination != Termination.SUCCESSES}) { -// writeExecSummary(injector, controllerInfoDto, splitResult) -// } -// -// //writeExecSummary(injector, controllerInfoDto, splitResult) -// //writeExecutiveSummary(injector, solution, controllerInfoDto, partialOracles) -// } - } else - if (config.problemType == EMConfig.ProblemType.RPC){ + } else if (config.problemType == EMConfig.ProblemType.RPC){ // Man: only enable for RPC as it lacks of unit tests writer.writeTestsDuringSeeding(solution, controllerInfoDto?.fullName, controllerInfoDto?.executableFullPath) @@ -766,7 +754,7 @@ class Main { for RPC, just simple split based on whether there exist any exception in a test TODD need to check with Andrea whether we use cluster or other type */ - EMConfig.TestSuiteSplitType.FAULTS -> { + else -> { val splitResult = TestSuiteSplitter.splitRPCByException(solution as Solution) splitResult.splitOutcome .filter { !it.individuals.isNullOrEmpty() } @@ -777,21 +765,13 @@ class Main { ) } .forEach { writer.writeTests(it, controllerInfoDto?.fullName,controllerInfoDto?.executableFullPath, snapshot) } - - // disable executiveSummary -// if (config.executiveSummary) { -// writeExecSummary(injector, controllerInfoDto, splitResult) -// } } } }else if (config.problemType == EMConfig.ProblemType.GRAPHQL) { when(config.testSuiteSplitType){ EMConfig.TestSuiteSplitType.NONE -> writer.writeTests(solution, controllerInfoDto?.fullName, controllerInfoDto?.executableFullPath,) - //EMConfig.TestSuiteSplitType.CLUSTER -> throw IllegalStateException("GraphQL problem does not support splitting tests by cluster at this time") - //EMConfig.TestSuiteSplitType.CODE -> else -> { - //throw IllegalStateException("GraphQL problem does not support splitting tests by code at this time") val splitResult = TestSuiteSplitter.split(solution, config) splitResult.splitOutcome .filter{ !it.individuals.isNullOrEmpty() } @@ -801,22 +781,31 @@ class Main { config.maxTestsPerTestSuite ) } - .forEach { writer.writeTests(it, controllerInfoDto?.fullName, controllerInfoDto?.executableFullPath, snapshot ) } + .forEach { + writer.writeTests(it, controllerInfoDto?.fullName, controllerInfoDto?.executableFullPath, snapshot ) + } } - /* - GraphQL could be split by code (where code is available and trustworthy) - */ } - } else - { - /* - TODO refactor all the PartialOracle stuff that is meant for only REST - */ - + } else { writer.writeTests(solution, controllerInfoDto?.fullName, controllerInfoDto?.executableFullPath,) } } + private fun writeWFCReport(injector: Injector, solution: Solution<*>){ + + //TODO will need to change input from Solution to the outout of generated tests + + val config = injector.getInstance(EMConfig::class.java) + + if (!config.writeWFCReport) { + return + } + + val wfcr = injector.getInstance(WFCReportWriter::class.java) + + wfcr.writeReport(solution) + } + private fun writeStatistics(injector: Injector, solution: Solution<*>) { val config = injector.getInstance(EMConfig::class.java) diff --git a/core/src/main/kotlin/org/evomaster/core/output/TestSuiteSplitter.kt b/core/src/main/kotlin/org/evomaster/core/output/TestSuiteSplitter.kt index 0a033b4d35..2799c71892 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/TestSuiteSplitter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/TestSuiteSplitter.kt @@ -78,8 +78,7 @@ object TestSuiteSplitter { * the original [Solution] */ fun split(solution: Solution<*>, - config: EMConfig, - oracles: PartialOracles = PartialOracles() + config: EMConfig ): SplitResult { // TODO splitting support for other problem types diff --git a/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/EnterpriseModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/EnterpriseModule.kt new file mode 100644 index 0000000000..5bad3865a1 --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/EnterpriseModule.kt @@ -0,0 +1,13 @@ +package org.evomaster.core.problem.enterprise.service + +import com.google.inject.AbstractModule + +abstract class EnterpriseModule : AbstractModule() { + + override fun configure() { + super.configure() + + bind(WFCReportWriter::class.java) + .asEagerSingleton() + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt b/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt new file mode 100644 index 0000000000..886ca0840e --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt @@ -0,0 +1,53 @@ +package org.evomaster.core.problem.enterprise.service + +import com.fasterxml.jackson.databind.ObjectMapper +import com.google.inject.Inject +import com.webfuzzing.commons.report.Faults +import com.webfuzzing.commons.report.RESTReport +import org.evomaster.core.EMConfig +import org.evomaster.core.search.Solution +import java.nio.file.Files +import java.nio.file.Paths +import java.util.* + +class WFCReportWriter { + + + @Inject + private lateinit var config: EMConfig + + + fun writeReport(solution: Solution<*>) { + + val report = com.webfuzzing.commons.report.Report() + + report.schemaVersion = "0.0.1" //TODO + report.toolName = "EvoMaster" + //TODO tool version + report.creationTime = Date() // FIXME use new JDK dates + + if(config.problemType == EMConfig.ProblemType.REST) { + val rest = RESTReport() + report.restReport = rest + + val faults = Faults() + rest.faults = faults + + faults.totalNumber = solution.totalNumberOfDetectedFaults() + + //TODO all other entries + } + //TODO other problem types + + val jackson = ObjectMapper() + val json = jackson.writeValueAsString(report) + + val path = Paths.get(config.outputFolder, "report.json").toAbsolutePath() + + Files.createDirectories(path.parent) + Files.deleteIfExists(path) + Files.createFile(path) + + path.toFile().appendText(json) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLModule.kt index c21844760f..15ac1c71a6 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLModule.kt @@ -5,6 +5,7 @@ import com.google.inject.TypeLiteral import org.evomaster.core.output.service.GraphQLTestCaseWriter import org.evomaster.core.output.service.TestCaseWriter import org.evomaster.core.output.service.TestSuiteWriter +import org.evomaster.core.problem.enterprise.service.EnterpriseModule import org.evomaster.core.problem.graphql.GraphQLIndividual import org.evomaster.core.problem.rest.RestIndividual import org.evomaster.core.remote.service.RemoteController @@ -17,7 +18,7 @@ import org.evomaster.core.search.service.mutator.Mutator import org.evomaster.core.search.service.mutator.StandardMutator import org.evomaster.core.search.service.mutator.StructureMutator -class GraphQLModule : AbstractModule() { +class GraphQLModule : EnterpriseModule() { override fun configure() { diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestBaseModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestBaseModule.kt index 28928568f3..491a3e4936 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestBaseModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestBaseModule.kt @@ -5,12 +5,13 @@ import com.google.inject.TypeLiteral import org.evomaster.core.output.service.RestTestCaseWriter import org.evomaster.core.output.service.TestCaseWriter import org.evomaster.core.output.service.TestSuiteWriter +import org.evomaster.core.problem.enterprise.service.EnterpriseModule import org.evomaster.core.problem.rest.RestIndividual import org.evomaster.core.search.service.Archive import org.evomaster.core.search.service.Minimizer import org.evomaster.core.seeding.service.rest.PirToRest -open class RestBaseModule : AbstractModule() { +open class RestBaseModule : EnterpriseModule() { override fun configure() { diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCModule.kt index 071ddfd4df..489fe15620 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCModule.kt @@ -5,6 +5,7 @@ import com.google.inject.TypeLiteral import org.evomaster.core.output.service.RPCTestCaseWriter import org.evomaster.core.output.service.TestCaseWriter import org.evomaster.core.output.service.TestSuiteWriter +import org.evomaster.core.problem.enterprise.service.EnterpriseModule import org.evomaster.core.problem.rest.RestIndividual import org.evomaster.core.problem.rpc.RPCIndividual import org.evomaster.core.problem.webfrontend.WebIndividual @@ -21,7 +22,7 @@ import org.evomaster.core.search.service.mutator.StructureMutator /** * created by manzhang on 2021/11/26 */ -class RPCModule : AbstractModule(){ +class RPCModule : EnterpriseModule(){ override fun configure() { bind(object : TypeLiteral>() {}) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/webfrontend/service/WebModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/webfrontend/service/WebModule.kt index 85ddd01a8b..8ae848456f 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/webfrontend/service/WebModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/webfrontend/service/WebModule.kt @@ -5,6 +5,7 @@ import com.google.inject.TypeLiteral import org.evomaster.core.output.service.TestCaseWriter import org.evomaster.core.output.service.TestSuiteWriter import org.evomaster.core.output.service.WebTestCaseWriter +import org.evomaster.core.problem.enterprise.service.EnterpriseModule import org.evomaster.core.problem.graphql.GraphQLIndividual import org.evomaster.core.problem.rest.RestIndividual import org.evomaster.core.problem.webfrontend.WebIndividual @@ -24,7 +25,7 @@ import org.evomaster.core.search.service.mutator.StructureMutator * * TODO See equivalent RestModule */ -class WebModule: AbstractModule() { +class WebModule: EnterpriseModule() { override fun configure() { bind(object : TypeLiteral>() {}) diff --git a/core/src/main/kotlin/org/evomaster/core/search/Solution.kt b/core/src/main/kotlin/org/evomaster/core/search/Solution.kt index 7c39008a10..216d21bc06 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/Solution.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/Solution.kt @@ -87,4 +87,8 @@ where T : Individual { .map { it.code } .toSet() } + + fun totalNumberOfDetectedFaults() : Int { + return DetectedFaultUtils.getDetectedFaults(this).size + } } diff --git a/docs/options.md b/docs/options.md index 0e8d727f0c..f6a441a844 100644 --- a/docs/options.md +++ b/docs/options.md @@ -279,3 +279,4 @@ There are 3 types of options: |`useWeightedSampling`| __Boolean__. When sampling from archive based on targets, decide whether to use weights based on properties of the targets (e.g., a target likely leading to a flag will be sampled less often). *Default value*: `false`.| |`wbProbabilityUseDataPool`| __Double__. Specify the probability of using the data pool when sampling test cases. This is for white-box (wb) mode. *Constraints*: `probability 0.0-1.0`. *Default value*: `0.2`.| |`writeSnapshotTestsIntervalInSeconds`| __Int__. The size (in seconds) of the interval that the snapshots will be printed, if enabled. *Default value*: `3600`.| +|`writeWFCReport`| __Boolean__. Output a JSON file representing statistics of the fuzzing session, written in the WFC Report format. *Default value*: `false`.| diff --git a/e2e-tests/spring-rest-openapi-v2/src/test/java/org/evomaster/e2etests/spring/examples/splitter/TestSuiteSplitterTest.java b/e2e-tests/spring-rest-openapi-v2/src/test/java/org/evomaster/e2etests/spring/examples/splitter/TestSuiteSplitterTest.java index be852e86ee..cde5e829d6 100644 --- a/e2e-tests/spring-rest-openapi-v2/src/test/java/org/evomaster/e2etests/spring/examples/splitter/TestSuiteSplitterTest.java +++ b/e2e-tests/spring-rest-openapi-v2/src/test/java/org/evomaster/e2etests/spring/examples/splitter/TestSuiteSplitterTest.java @@ -80,7 +80,7 @@ private void testRunEMMulti(EMConfig.TestSuiteSplitType splitType, Boolean execu Solution solution = initAndRun(args); assertTrue(solution.getIndividuals().size() >= 1); - SplitResult splits = TestSuiteSplitter.INSTANCE.split(solution, em, new PartialOracles()); + SplitResult splits = TestSuiteSplitter.INSTANCE.split(solution, em); assertTrue(splits.splitOutcome.size() >= 1); }; From 6677df2cd56bd9da6035bf4eab3b85468f94f649 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Sat, 28 Dec 2024 21:32:15 +0100 Subject: [PATCH 4/4] changed property locations --- .../core/problem/enterprise/service/WFCReportWriter.kt | 10 +++++----- wfc/src/main/resources/schemas/report.yaml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt b/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt index 886ca0840e..e17549c07a 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/enterprise/service/WFCReportWriter.kt @@ -26,15 +26,15 @@ class WFCReportWriter { //TODO tool version report.creationTime = Date() // FIXME use new JDK dates + val faults = Faults() + report.faults = faults + faults.totalNumber = solution.totalNumberOfDetectedFaults() + + if(config.problemType == EMConfig.ProblemType.REST) { val rest = RESTReport() report.restReport = rest - val faults = Faults() - rest.faults = faults - - faults.totalNumber = solution.totalNumberOfDetectedFaults() - //TODO all other entries } //TODO other problem types diff --git a/wfc/src/main/resources/schemas/report.yaml b/wfc/src/main/resources/schemas/report.yaml index 755538fd86..3d17be49f1 100644 --- a/wfc/src/main/resources/schemas/report.yaml +++ b/wfc/src/main/resources/schemas/report.yaml @@ -11,16 +11,16 @@ properties: creation_time: type: string format: date-time + faults: + $ref: "#/$def/Faults" rest_report: $ref: "#/$def/RESTReport" -required: ["schema_version","tool_name","creation_time"] +required: ["schema_version","tool_name","creation_time","faults"] $def: RESTReport: type: object properties: - faults: - $ref: "#/$def/Faults" - required: ["faults"] + required: [] Faults: type: object