From 4e57af4ac841067463f9b59b2a599bf44ed31ef9 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 27 Feb 2025 09:30:52 +0800 Subject: [PATCH 01/17] add a fix --- .../impact/impactinfocollection/ImpactsOfIndividual.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt b/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt index c6f96966d6..a4c45f1e1d 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt @@ -58,7 +58,10 @@ open class ImpactsOfIndividual( fixedMainActionImpacts = individual.seeFixedMainActions().map { a -> ImpactsOfAction(a) }.toMutableList(), dynamicMainActionImpacts = individual.seeDynamicMainActions().map { a-> ImpactsOfAction(a) }.toMutableList() ) { - if (individual.seeActions(ActionFilter.NO_INIT).isEmpty()) + if (individual.seeActions(ActionFilter.NO_INIT).isEmpty() + // It allows to have tests which are only composed of schedule actions, + // then we need to put it as part of main action later + && individual.seeActions(ActionFilter.ONLY_SCHEDULE_TASK).isEmpty()) throw IllegalArgumentException("there is no main action") if (fitnessValue != null) { From 4423f33459c7e1a520884d6a9bf02fe82ae0ff4a Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 27 Feb 2025 15:12:28 +0800 Subject: [PATCH 02/17] fix a bug in initializing rpc individual --- .../core/problem/rpc/service/RPCSampler.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt index 9d3d80177c..c3d359f14d 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt @@ -124,15 +124,16 @@ class RPCSampler: ApiWsSampler() { }.toMutableList() val leftlen = config.maxTestSize - len - if (leftlen > 0 && randomness.nextBoolean(config.probOfSamplingScheduleTask)){ + val scheduleTaskSize = if (leftlen > 0 && randomness.nextBoolean(config.probOfSamplingScheduleTask)){ val slen = randomness.nextInt(1, leftlen) val scheduleActions = (0 until slen).map { sampleRandomScheduleTaskAction() } actions.addAll(0, scheduleActions) - } + scheduleActions.size + }else 0 - val ind = createRPCIndividual(sampleType = SampleType.RANDOM, actions) + val ind = createRPCIndividual(sampleType = SampleType.RANDOM, actions, scheduleTaskSize) ind.doGlobalInitialize(searchGlobalState) return ind } @@ -211,13 +212,15 @@ class RPCSampler: ApiWsSampler() { ) } - private fun createRPCIndividual(sampleType: SampleType, actions : MutableList) : RPCIndividual{ + private fun createRPCIndividual(sampleType: SampleType, actions : MutableList, scheduleTaskSize : Int = 0) : RPCIndividual{ // enable tracking in rpc return RPCIndividual( sampleType = sampleType, trackOperator = if(config.trackingEnabled()) this else null, index = if (config.trackingEnabled()) time.evaluatedIndividuals else -1, - allActions=actions + allActions=actions, + mainSize = actions.size - scheduleTaskSize, + scheduleTaskSize = scheduleTaskSize ) } } From 35662212ff048cd51adb1ff7fd92c23dfed4ad8f Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Sun, 9 Mar 2025 13:48:04 +0800 Subject: [PATCH 03/17] stop executing of schedule tasks if any fails --- .../client/java/controller/internal/SutController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java index 4700fd6056..1b674ad87d 100644 --- a/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java @@ -956,8 +956,8 @@ public final void invokeScheduleTasks(List dtos, Sche newScheduleAction(dto, queryFromDatabase); invokeScheduleTask(dto, responseDto); }catch (Exception e){ - // now we execute all schedule tasks - SimpleLogger.warn(e.getMessage()); + // we stop executing the following schedule task + throw new RuntimeException(e); } } assert dtos.size() == responseDto.results.size(); From 7ba548128388d190798ed23f60e91fb538279df7 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Sun, 9 Mar 2025 14:07:07 +0800 Subject: [PATCH 04/17] construct action results for successfully executed task and the last failed one --- .../core/problem/rpc/service/RPCFitness.kt | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt index 57a2ceb9df..aa93ff21b3 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt @@ -136,8 +136,6 @@ class RPCFitness : ApiWsFitness() { private fun executeScheduleTasks(firstIndex : Int, tasks : List, actionResults : MutableList) : Boolean{ searchTimeController.waitForRateLimiter() - val taskResults = tasks.map { ScheduleTaskActionResult(it.getLocalId()) } - actionResults.addAll(taskResults) val taskDtos = tasks.mapIndexed { index, scheduleTaskAction -> rpcHandler.transformScheduleTaskInvocationDto(scheduleTaskAction).apply { this.index = firstIndex + index } @@ -147,15 +145,20 @@ class RPCFitness : ApiWsFitness() { val response = rc.invokeScheduleTasksAndGetResults(command) if (response != null){ - if (taskResults.size == response.results.size){ - taskResults.forEachIndexed { index, taskResult -> - val resultDto = response.results[index] - taskResult.setResultBasedOnDto(resultDto) - } + if (response.results.size > tasks.size) + throw IllegalStateException("Received more responses (ie, ${response.results.size}) than tasks (ie, ${tasks.size})") + + val taskResults = response.results.mapIndexed { index, resultDto -> + val taskResult = ScheduleTaskActionResult(tasks[index].getLocalId()) + taskResult.setResultBasedOnDto(resultDto) + taskResult.stopping = resultDto.status == ExecutionStatusDto.FAILED + taskResult } + actionResults.addAll(taskResults) + }else{ + log.warn("no response when executing schedule tasks") } - val ok = (response != null && response.results.none { it.status == ExecutionStatusDto.FAILED }) - taskResults.last().stopping = !ok + val ok = (response != null && response.results.size == tasks.size && response.results.none { it.status == ExecutionStatusDto.FAILED }) return ok } From 58463f6864124b748e7d6b199c5eb00d4dce4214 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Wed, 19 Mar 2025 11:50:16 +0800 Subject: [PATCH 05/17] temporal fix --- .../search/impact/impactinfocollection/ImpactsOfIndividual.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt b/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt index a4c45f1e1d..cf09283586 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt @@ -237,7 +237,8 @@ open class ImpactsOfIndividual( //for fixed action val fixed = individual.seeFixedMainActions() if ((fixed.isNotEmpty() && fixed.size != fixedMainActionImpacts.size) || - (fixed.isEmpty() && !noneActionIndividual())) + (fixed.isEmpty() && individual.seeActions(ActionFilter.ONLY_SCHEDULE_TASK).isEmpty() // TODO Man: need a better way to handle schedule task and main action + && !noneActionIndividual())) throw IllegalArgumentException("inconsistent size of actions and impacts") fixed.forEach { action -> From 33a47d8eb76258c2b140450b3187d6d3fc26e58a Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Wed, 19 Mar 2025 16:25:42 +0800 Subject: [PATCH 06/17] fix --- .../core/problem/rpc/service/RPCStructureMutator.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCStructureMutator.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCStructureMutator.kt index 237d58a058..9e41eb4178 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCStructureMutator.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCStructureMutator.kt @@ -33,8 +33,13 @@ class RPCStructureMutator : ApiWsStructureMutator() { private fun mutateForRandomType(individual: RPCIndividual, mutatedGenes: MutatedGeneSpecification?) { + /* + TODO + here we implement strategies to support structure mutation on main action, + as we support the schedule task now, also need to be able to apply structure mutation on schedule task + */ val size = individual.seeMainExecutableActions().size - if ((size + 1 < config.maxTestSize) && (size == 1 || randomness.nextBoolean())){ + if ((size + 1 < config.maxTestSize) && (size <= 1 || randomness.nextBoolean())){ // add val sampledAction = sampler.sampleRandomAction() From f2afc4c385339b3b6b94db40040d0b5b49a242bb Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Tue, 25 Mar 2025 13:36:56 +0800 Subject: [PATCH 07/17] add more log info for failure of execution of schedule task --- .../core/problem/rpc/service/RPCFitness.kt | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt index aa93ff21b3..038dffe8a8 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCFitness.kt @@ -92,8 +92,14 @@ class RPCFitness : ApiWsFitness() { val additionalInfoForScheduleTask = dto.additionalInfoList.subList(0, scheduleTasksResults.size) // TODO man might need to handle additional targets for schedule task later - val additionalInfoForMainTask= dto.additionalInfoList.subList(scheduleTasksResults.size, dto.additionalInfoList.size) - handleResponseTargets(fv, individual.seeAllActions().filterIsInstance(), rpcActionResults, additionalInfoForMainTask) + if (rpcActionResults.isNotEmpty()){ + val startingIndexForMainAction = scheduleTasksResults.size + if (startingIndexForMainAction > dto.additionalInfoList.size) + throw IllegalStateException("missing ${rpcActionResults.size} additionalInfo for RPC Actions, starting Index: $startingIndexForMainAction, and total: ${dto.additionalInfoList.size}") + val additionalInfoForMainTask= dto.additionalInfoList.subList(scheduleTasksResults.size, dto.additionalInfoList.size) + handleResponseTargets(fv, individual.seeAllActions().filterIsInstance(), rpcActionResults, additionalInfoForMainTask) + } + if (config.isEnabledTaintAnalysis()) { Lazy.assert { (scheduleTasksResults.size + rpcActionResults.size) == dto.additionalInfoList.size } @@ -133,6 +139,9 @@ class RPCFitness : ApiWsFitness() { // } // } + /** + * @return if all tasks have been successfully executed + */ private fun executeScheduleTasks(firstIndex : Int, tasks : List, actionResults : MutableList) : Boolean{ searchTimeController.waitForRateLimiter() @@ -148,18 +157,21 @@ class RPCFitness : ApiWsFitness() { if (response.results.size > tasks.size) throw IllegalStateException("Received more responses (ie, ${response.results.size}) than tasks (ie, ${tasks.size})") - val taskResults = response.results.mapIndexed { index, resultDto -> + response.results.forEachIndexed { index, resultDto -> val taskResult = ScheduleTaskActionResult(tasks[index].getLocalId()) taskResult.setResultBasedOnDto(resultDto) taskResult.stopping = resultDto.status == ExecutionStatusDto.FAILED - taskResult + actionResults.add(taskResult) + if (taskResult.stopping){ + log.warn("fail to execute the task at $index (in total ${tasks.size}), and the task name is ${tasks[index].taskName}") + return false + } } - actionResults.addAll(taskResults) }else{ log.warn("no response when executing schedule tasks") } - val ok = (response != null && response.results.size == tasks.size && response.results.none { it.status == ExecutionStatusDto.FAILED }) - return ok + + return response != null && response.results.size == tasks.size } private fun executeNewAction(action: RPCCallAction, index: Int, actionResults: MutableList) : Boolean{ From 11efed62bc1c24f573edd90f76c32bb3202bb05b Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Tue, 25 Mar 2025 13:48:16 +0800 Subject: [PATCH 08/17] fix get impact --- .../kotlin/org/evomaster/core/search/EvaluatedIndividual.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt b/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt index 43c7f8453d..1e30cf0768 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt @@ -18,6 +18,7 @@ import org.evomaster.core.problem.rest.RestCallAction import org.evomaster.core.problem.rest.RestCallResult import org.evomaster.core.problem.rest.RestIndividual import org.evomaster.core.problem.rest.resource.ResourceImpactOfIndividual +import org.evomaster.core.scheduletask.ScheduleTaskAction import org.evomaster.core.search.action.* import org.evomaster.core.search.action.ActionFilter.* import org.evomaster.core.search.service.monitor.ProcessMonitorExcludeField @@ -988,7 +989,7 @@ class EvaluatedIndividual( return !invalid } private fun initializingActionClasses(): List> { - return listOf(MongoDbAction::class, SqlAction::class) + return listOf(MongoDbAction::class, SqlAction::class, ScheduleTaskAction::class) } fun hasAnyPotentialFault() = this.fitness.hasAnyPotentialFault(this.individual.searchGlobalState!!.idMapper) From ccda87828ab7f014252dd041392eb0ed6c620408 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Tue, 25 Mar 2025 13:50:52 +0800 Subject: [PATCH 09/17] add a check for schedule action cluster --- .../org/evomaster/core/problem/rpc/service/RPCSampler.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt index c3d359f14d..802a7b2ee4 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt @@ -109,7 +109,9 @@ class RPCSampler: ApiWsSampler() { * sample a schedule task action from [scheduleActionCluster] at random * @param noSeedProbability specifies a probability which does not apply seeded one */ - fun sampleRandomScheduleTaskAction(noSeedProbability: Double = 0.05) : ScheduleTaskAction { + private fun sampleRandomScheduleTaskAction(noSeedProbability: Double = 0.05) : ScheduleTaskAction { + if (scheduleActionCluster.isEmpty()) + throw IllegalStateException("cannot sample schedule action with empty cluster") val action = randomness.choose(scheduleActionCluster).copy() as ScheduleTaskAction action.doInitialize(randomness) rpcHandler.scheduleActionWithRandomSeeded(action, noSeedProbability) @@ -124,7 +126,7 @@ class RPCSampler: ApiWsSampler() { }.toMutableList() val leftlen = config.maxTestSize - len - val scheduleTaskSize = if (leftlen > 0 && randomness.nextBoolean(config.probOfSamplingScheduleTask)){ + val scheduleTaskSize = if (scheduleActionCluster.isNotEmpty() && leftlen > 0 && randomness.nextBoolean(config.probOfSamplingScheduleTask)){ val slen = randomness.nextInt(1, leftlen) val scheduleActions = (0 until slen).map { sampleRandomScheduleTaskAction() From 19be4e721226e3f69ba1298729976a5783bcffc7 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 27 Mar 2025 15:15:31 +0800 Subject: [PATCH 10/17] specified a seeded test which contains only schedule tasks --- .../fakemockobject/FakeMockObjectController.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java b/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java index 83fe8157d5..6ed24f13e2 100644 --- a/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java +++ b/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java @@ -133,6 +133,16 @@ public List seedRPCTests() { }}, new SeededRPCTestDto(){{ testName = "test_4"; + scheduleTaskInvocations = Arrays.asList( + new ScheduleTaskInvocationDto(){{ + appKey = "fake.app"; + taskName = "executeFlag"; + descriptiveInfo = "a scheduled task for invoking executeFlag"; + }} + ); + }}, + new SeededRPCTestDto(){{ + testName = "test_5"; rpcFunctions = Arrays.asList( new SeededRPCActionDto(){{ interfaceName = FakeMockObjectService.Iface.class.getName(); From e2eee6d69b8d217dd29c6403ab141f1681ea0e9d Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 3 Apr 2025 15:15:51 +0800 Subject: [PATCH 11/17] init impacts for schedule task --- .../core/problem/api/service/ApiWsStructureMutator.kt | 1 + .../rest/resource/ResourceImpactOfIndividual.kt | 3 ++- .../evomaster/core/problem/rpc/service/RPCSampler.kt | 1 - .../org/evomaster/core/search/EvaluatedIndividual.kt | 2 +- .../impact/impactinfocollection/ImpactsOfIndividual.kt | 10 ++++++++-- .../core/search/impact/IndividualImpactTest.kt | 2 +- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/api/service/ApiWsStructureMutator.kt b/core/src/main/kotlin/org/evomaster/core/problem/api/service/ApiWsStructureMutator.kt index 971375b788..74a103d589 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/api/service/ApiWsStructureMutator.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/api/service/ApiWsStructureMutator.kt @@ -161,6 +161,7 @@ abstract class ApiWsStructureMutator : StructureMutator() { addInitializingSqlActions(individual, mutatedGenes, sampler) addInitializingMongoDbActions(individual, mutatedGenes, sampler) addInitializingHostnameResolutionActions(individual, mutatedGenes, sampler) + // TODO if we handle schedule actions with structure mutator } private fun addInitializingMongoDbActions( diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/resource/ResourceImpactOfIndividual.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/resource/ResourceImpactOfIndividual.kt index c6af451554..12a07fcfc7 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/resource/ResourceImpactOfIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/resource/ResourceImpactOfIndividual.kt @@ -8,6 +8,7 @@ import org.evomaster.core.search.impact.impactinfocollection.ImpactsOfAction import org.evomaster.core.search.impact.impactinfocollection.ImpactsOfIndividual import org.evomaster.core.search.impact.impactinfocollection.InitializationGroupedActionsImpacts import org.evomaster.core.search.impact.impactinfocollection.value.numeric.IntegerGeneImpact +import kotlin.reflect.KClass /** * created by manzhang on 2021/10/21 @@ -56,7 +57,7 @@ class ResourceImpactOfIndividual : ImpactsOfIndividual { this.anySqlTableSizeImpact = anySqlTableSizeImpact } - constructor(individual: RestIndividual, initActionTypes: List, abstractInitializationGeneToMutate: Boolean, fitnessValue: FitnessValue?) + constructor(individual: RestIndividual, initActionTypes: List>, abstractInitializationGeneToMutate: Boolean, fitnessValue: FitnessValue?) : super(individual, initActionTypes, abstractInitializationGeneToMutate, fitnessValue) { resourceSizeImpact = mutableMapOf().apply { individual.seeResource(RestIndividual.ResourceFilter.ALL).forEach { r-> diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt index 802a7b2ee4..c5bfeca204 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt @@ -153,7 +153,6 @@ class RPCSampler: ApiWsSampler() { adHocInitialIndividuals.forEach { it.doGlobalInitialize(searchGlobalState) } - adHocInitialIndividuals } override fun initSeededTests(infoDto: SutInfoDto?) { diff --git a/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt b/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt index 1e30cf0768..fcd5f669b7 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/EvaluatedIndividual.kt @@ -109,7 +109,7 @@ class EvaluatedIndividual( trackOperator = trackOperator, index = index, impactInfo = if ((config.isEnabledImpactCollection())) { - val initActionTypes = individual.seeInitializingActions().groupBy { it::class.java.name }.keys.toList() + val initActionTypes = individual.seeInitializingActions().groupBy { it::class }.keys.toList() if (individual is RestIndividual && config.isEnabledResourceDependency()) ResourceImpactOfIndividual(individual, initActionTypes, config.abstractInitializationGeneToMutate, fitness) else diff --git a/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt b/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt index cf09283586..c42823c312 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/impact/impactinfocollection/ImpactsOfIndividual.kt @@ -49,8 +49,8 @@ open class ImpactsOfIndividual( val impactsOfStructure: ActionStructureImpact = ActionStructureImpact("StructureSize") ) { - constructor(individual: Individual, initActionTypes: List, abstractInitializationGeneToMutate: Boolean, fitnessValue: FitnessValue?) : this( - initActionImpacts = initActionTypes.associateWith { + constructor(individual: Individual, initActionTypes: List>, abstractInitializationGeneToMutate: Boolean, fitnessValue: FitnessValue?) : this( + initActionImpacts = initActionTypes.map { it.java.name }.associateWith { InitializationGroupedActionsImpacts( abstractInitializationGeneToMutate ) @@ -67,6 +67,12 @@ open class ImpactsOfIndividual( if (fitnessValue != null) { impactsOfStructure.updateStructure(individual, fitnessValue) } + val scheduleTasks = individual.seeActions(ActionFilter.ONLY_SCHEDULE_TASK) + if (scheduleTasks.isNotEmpty()){ + scheduleTasks.groupBy { it::class.java.name }.forEach { (t, u) -> + initActionImpacts[t]?.initInitializationActions(listOf(u), 0)?:throw IllegalStateException("InitializationGroupedActionsImpacts is not created for $t") + } + } } companion object { diff --git a/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt b/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt index c62bfd95c9..680df86411 100644 --- a/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt @@ -30,7 +30,7 @@ class IndividualImpactTest { val ind = generateFkIndividual() - val impactInfo = ImpactsOfIndividual(ind, listOf(SqlAction::class.java.name),false, null) + val impactInfo = ImpactsOfIndividual(ind, listOf(SqlAction::class),false, null) impactInfo.fixedMainActionImpacts.apply { assertEquals(2, size) From 79b50c0d0473cddff7fe7443a1ac7a4779ab151b Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 3 Apr 2025 15:37:26 +0800 Subject: [PATCH 12/17] add schedule task size in constructor of rest individual --- .../kotlin/org/evomaster/core/problem/rest/RestIndividual.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt index aad7511044..5b8d779ba6 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt @@ -40,7 +40,8 @@ class RestIndividual( sqlSize: Int = 0, mongoSize: Int = 0, dnsSize: Int = 0, - groups : GroupsOfChildren = getEnterpriseTopGroups(allActions,mainSize,sqlSize,mongoSize,dnsSize, 0) + scheduleSize : Int = 0, + groups : GroupsOfChildren = getEnterpriseTopGroups(allActions,mainSize,sqlSize,mongoSize,dnsSize, scheduleSize) ): ApiWsIndividual(sampleType, trackOperator, index, allActions, childTypeVerifier = EnterpriseChildTypeVerifier(RestCallAction::class.java,RestResourceCalls::class.java), groups) { From b9110cfc2c71d6b8be25c36af3f8328e131c90b4 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 3 Apr 2025 15:37:32 +0800 Subject: [PATCH 13/17] add test --- .../kotlin/org/evomaster/core/TestUtils.kt | 15 +++++++++ .../search/impact/IndividualImpactTest.kt | 31 +++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/core/src/test/kotlin/org/evomaster/core/TestUtils.kt b/core/src/test/kotlin/org/evomaster/core/TestUtils.kt index b03910bee1..d05aff7cc1 100644 --- a/core/src/test/kotlin/org/evomaster/core/TestUtils.kt +++ b/core/src/test/kotlin/org/evomaster/core/TestUtils.kt @@ -14,6 +14,7 @@ import org.evomaster.core.problem.httpws.auth.HttpWsAuthenticationInfo import org.evomaster.core.problem.httpws.auth.HttpWsNoAuth import org.evomaster.core.problem.rest.* import org.evomaster.core.problem.rest.param.QueryParam +import org.evomaster.core.scheduletask.ScheduleTaskAction import org.evomaster.core.search.gene.numeric.IntegerGene import org.evomaster.core.search.gene.string.StringGene import org.evomaster.core.search.gene.sql.SqlForeignKeyGene @@ -90,4 +91,18 @@ object TestUtils { return RestCallAction(id, HttpVerb.GET, RestPath(pathString), actions) } + fun generateFakeScheduleAction() : ScheduleTaskAction{ + val queryNameParam = QueryParam("name", StringGene("name")) + val queryIdParam = QueryParam("id", IntegerGene("id")) + + return ScheduleTaskAction( + taskId = "fake.schedule.task", + taskName = "fake.task", + parameters = mutableListOf(queryNameParam, queryIdParam), + immutableExtraInfo = mutableMapOf( + "ip" to "www.foo.org" + ) + ) + } + } \ No newline at end of file diff --git a/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt b/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt index 680df86411..0fe716686f 100644 --- a/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/search/impact/IndividualImpactTest.kt @@ -3,9 +3,13 @@ package org.evomaster.core.search.impact import org.evomaster.core.TestUtils import org.evomaster.core.problem.enterprise.SampleType import org.evomaster.core.problem.rest.RestIndividual +import org.evomaster.core.problem.rest.resource.RestResourceCalls +import org.evomaster.core.scheduletask.ScheduleTaskAction +import org.evomaster.core.search.action.ActionComponent import org.evomaster.core.search.impact.impactinfocollection.ImpactsOfIndividual import org.evomaster.core.sql.SqlAction import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Test /** @@ -17,12 +21,23 @@ class IndividualImpactTest { private fun generateFkIndividual() : RestIndividual{ val twoDbActions = TestUtils.generateTwoFakeDbActions(1001L, 1002L, 12345L, 10L, "Foo", "Bar", 0, 42) + val scheduleAction = TestUtils.generateFakeScheduleAction() val fooAction = TestUtils.generateFakeQueryRestAction("1", "/foo") val barAction = TestUtils.generateFakeQueryRestAction("2", "/bar", true) - return RestIndividual(mutableListOf(fooAction, barAction), SampleType.RANDOM, twoDbActions.toMutableList()) +// return RestIndividual(mutableListOf(fooAction, barAction), SampleType.RANDOM, twoDbActions.toMutableList()) + return RestIndividual( + sampleType = SampleType.SEEDED, + allActions = twoDbActions + .plus(scheduleAction) + .plus(RestResourceCalls(actions = listOf(fooAction), sqlActions = mutableListOf())) + .plus(RestResourceCalls(actions = listOf(barAction), sqlActions = mutableListOf())).toMutableList(), + mainSize = 2, + sqlSize = 2, + scheduleSize = 1 + ) } @Test @@ -30,12 +45,24 @@ class IndividualImpactTest { val ind = generateFkIndividual() - val impactInfo = ImpactsOfIndividual(ind, listOf(SqlAction::class),false, null) + val impactInfo = ImpactsOfIndividual(ind, listOf(SqlAction::class, ScheduleTaskAction::class),false, null) impactInfo.fixedMainActionImpacts.apply { assertEquals(2, size) assertEquals(2, this[0].geneImpacts.size) assertEquals(1, this[1].geneImpacts.size) } + + impactInfo.initActionImpacts.apply { + assertEquals(2, size) + val scheduleImpacts = this[ScheduleTaskAction::class.java.name] + assertNotNull(scheduleImpacts) + scheduleImpacts.apply { + assertEquals(1, this!!.getSize()) + getAll()[0].apply { + assertEquals(2, this.geneImpacts.size) + } + } + } } } From 95fb86a6fafb1925ee973ab2c5368cd88cd6d46f Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 3 Apr 2025 15:38:33 +0800 Subject: [PATCH 14/17] add doc --- core/src/test/kotlin/org/evomaster/core/TestUtils.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/test/kotlin/org/evomaster/core/TestUtils.kt b/core/src/test/kotlin/org/evomaster/core/TestUtils.kt index d05aff7cc1..8c8515d9f9 100644 --- a/core/src/test/kotlin/org/evomaster/core/TestUtils.kt +++ b/core/src/test/kotlin/org/evomaster/core/TestUtils.kt @@ -91,6 +91,10 @@ object TestUtils { return RestCallAction(id, HttpVerb.GET, RestPath(pathString), actions) } + /** + * generate fake schedule task for unit testing, + * the schedule task has two query parameters, ie, name typed with string, and id typed with integer + */ fun generateFakeScheduleAction() : ScheduleTaskAction{ val queryNameParam = QueryParam("name", StringGene("name")) val queryIdParam = QueryParam("id", IntegerGene("id")) From a7dd92a3acb131e37e7ecbb3c6f9d1091b69b88b Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Thu, 3 Apr 2025 15:48:02 +0800 Subject: [PATCH 15/17] fix --- .../externalservice/rpc/RPCExternalServiceAction.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/externalservice/rpc/RPCExternalServiceAction.kt b/core/src/main/kotlin/org/evomaster/core/problem/externalservice/rpc/RPCExternalServiceAction.kt index b5da8508b9..1d5a04c370 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/externalservice/rpc/RPCExternalServiceAction.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/externalservice/rpc/RPCExternalServiceAction.kt @@ -44,9 +44,13 @@ class RPCExternalServiceAction( companion object{ fun getRPCExternalServiceActionName(apiDto: MockRPCExternalServiceDto, index: Int) = - getRPCExternalServiceActionName(apiDto.interfaceFullName, apiDto.functionName, apiDto.requestRules?.get(index), apiDto.responseFullTypesWithGeneric?.get(index)?:apiDto.responseTypes[index]) - - + getRPCExternalServiceActionName( + apiDto.interfaceFullName, + apiDto.functionName, + apiDto.requestRules?.run{ + if (this.size > index) get(index) + else throw IllegalArgumentException("request rules are unspecified for function ${apiDto.functionName} from interface ${apiDto.interfaceFullName}") }, + apiDto.responseFullTypesWithGeneric?.run{ if (this.size > index) get(index) else null }?:apiDto.responseTypes[index]) fun getRPCExternalServiceActionName(interfaceName: String, functionName: String, requestRuleIdentifier: String?, responseClassType: String) = "$interfaceName$EXACTION_NAME_SEPARATOR$functionName$EXACTION_NAME_SEPARATOR${requestRuleIdentifier?:"ANY"}$EXACTION_NAME_SEPARATOR$responseClassType" } From 4238d075dd5e1b0eb554320c9b833365ff30cffc Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Wed, 23 Apr 2025 10:35:40 +0800 Subject: [PATCH 16/17] reproduce the problem related to additional info --- .../FakeMockObjectController.java | 173 ++++++++++-------- 1 file changed, 98 insertions(+), 75 deletions(-) diff --git a/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java b/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java index 6ed24f13e2..c5a074451e 100644 --- a/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java +++ b/e2e-tests/spring-rpc/spring-rpc-thrift/src/test/java/com/foo/rpc/examples/spring/fakemockobject/FakeMockObjectController.java @@ -52,7 +52,7 @@ public ProblemInfo getProblemInfo() { @Override public String startClient() { - String url = "http://localhost:"+getSutPort()+"/fakemockobject"; + String url = "http://localhost:" + getSutPort() + "/fakemockobject"; try { // init client TTransport transport = new THttpClient(url); @@ -69,16 +69,16 @@ public String startClient() { public List seedRPCTests() { return Arrays.asList( - new SeededRPCTestDto(){{ + new SeededRPCTestDto() {{ testName = "test_1"; rpcFunctions = Arrays.asList( - new SeededRPCActionDto(){{ + new SeededRPCActionDto() {{ interfaceName = FakeMockObjectService.Iface.class.getName(); functionName = "getFooFromExternalService"; - inputParams= Arrays.asList("0"); - inputParamTypes= Arrays.asList(int.class.getName()); - mockRPCExternalServiceDtos= Arrays.asList( - new MockRPCExternalServiceDto(){{ + inputParams = Arrays.asList("0"); + inputParamTypes = Arrays.asList(int.class.getName()); + mockRPCExternalServiceDtos = Arrays.asList( + new MockRPCExternalServiceDto() {{ appKey = "fake.app"; interfaceFullName = "com.foo.rpc.examples.spring.fakemockobject.external.fake.api.GetApiData"; functionName = "one"; @@ -92,16 +92,16 @@ public List seedRPCTests() { ); }}, - new SeededRPCTestDto(){{ + new SeededRPCTestDto() {{ testName = "test_2"; rpcFunctions = Arrays.asList( - new SeededRPCActionDto(){{ + new SeededRPCActionDto() {{ interfaceName = FakeMockObjectService.Iface.class.getName(); functionName = "getBarFromDatabase"; - inputParams= Arrays.asList("42"); - inputParamTypes= Arrays.asList(int.class.getName()); + inputParams = Arrays.asList("42"); + inputParamTypes = Arrays.asList(int.class.getName()); mockDatabaseDtos = Arrays.asList( - new MockDatabaseDto(){{ + new MockDatabaseDto() {{ appKey = "fake.app"; commandName = "com.foo.rpc.examples.spring.fakemockobject.external.fake.db.GetDbData.one"; response = "{\"exName\":\"bar\",\"exId\":42,\"exInfo\":[\"2023-08-14\"]}"; @@ -112,53 +112,76 @@ public List seedRPCTests() { ); }}, - new SeededRPCTestDto(){{ - testName = "test_3"; - rpcFunctions = Arrays.asList( - new SeededRPCActionDto(){{ - interfaceName = FakeMockObjectService.Iface.class.getName(); - functionName = "getAllBarFromDatabase"; - inputParams= Arrays.asList(); - inputParamTypes= Arrays.asList(); - mockDatabaseDtos = Arrays.asList( - new MockDatabaseDto(){{ + new SeededRPCTestDto() {{ + testName = "test_3"; + rpcFunctions = Arrays.asList( + new SeededRPCActionDto() {{ + interfaceName = FakeMockObjectService.Iface.class.getName(); + functionName = "getAllBarFromDatabase"; + inputParams = Arrays.asList(); + inputParamTypes = Arrays.asList(); + mockDatabaseDtos = Arrays.asList( + new MockDatabaseDto() {{ + appKey = "fake.app"; + commandName = "com.foo.rpc.examples.spring.fakemockobject.external.fake.db.GetDbData.all"; + response = "[]"; + responseFullType = ArrayList.class.getName(); + }} + ); + }} + ); + }}, + new SeededRPCTestDto() {{ + testName = "test_4"; + scheduleTaskInvocations = Arrays.asList( + new ScheduleTaskInvocationDto() {{ appKey = "fake.app"; - commandName = "com.foo.rpc.examples.spring.fakemockobject.external.fake.db.GetDbData.all"; - response = "[]"; - responseFullType = ArrayList.class.getName(); + taskName = "executeFlag"; + descriptiveInfo = "a scheduled task for invoking executeFlag"; + }} + ); + }}, + new SeededRPCTestDto() {{ + testName = "test_5"; + rpcFunctions = Arrays.asList( + new SeededRPCActionDto() {{ + interfaceName = FakeMockObjectService.Iface.class.getName(); + functionName = "isExecutedToday"; + inputParams = Arrays.asList(); + inputParamTypes = Arrays.asList(); }} - ); - }} - ); - }}, - new SeededRPCTestDto(){{ - testName = "test_4"; - scheduleTaskInvocations = Arrays.asList( - new ScheduleTaskInvocationDto(){{ - appKey = "fake.app"; - taskName = "executeFlag"; - descriptiveInfo = "a scheduled task for invoking executeFlag"; - }} - ); - }}, - new SeededRPCTestDto(){{ - testName = "test_5"; - rpcFunctions = Arrays.asList( - new SeededRPCActionDto(){{ - interfaceName = FakeMockObjectService.Iface.class.getName(); - functionName = "isExecutedToday"; - inputParams= Arrays.asList(); - inputParamTypes= Arrays.asList(); - }} - ); - scheduleTaskInvocations = Arrays.asList( - new ScheduleTaskInvocationDto(){{ - appKey = "fake.app"; - taskName = "executeFlag"; - descriptiveInfo = "a scheduled task for invoking executeFlag"; - }} - ); - }} + ); + scheduleTaskInvocations = Arrays.asList( + new ScheduleTaskInvocationDto() {{ + appKey = "fake.app"; + taskName = "executeFlag"; + descriptiveInfo = "a scheduled task for invoking executeFlag"; + }} + ); + }}, + new SeededRPCTestDto() {{ + testName = "test_6"; + rpcFunctions = Arrays.asList( + new SeededRPCActionDto() {{ + interfaceName = FakeMockObjectService.Iface.class.getName(); + functionName = "isExecutedToday"; + inputParams = Arrays.asList(); + inputParamTypes = Arrays.asList(); + }} + ); + scheduleTaskInvocations = Arrays.asList( + new ScheduleTaskInvocationDto() {{ + appKey = "fake.app"; + taskName = "executeFlag"; + descriptiveInfo = "a scheduled task for invoking executeFlag"; + }}, + new ScheduleTaskInvocationDto() {{ + appKey = "fake.app"; + taskName = "executeFlag"; + descriptiveInfo = "a scheduled task for invoking executeFlag"; + }} + ); + }} ); } @@ -166,13 +189,13 @@ public List seedRPCTests() { @Override public boolean customizeMockingDatabase(List databaseDtos, boolean enabled) { try { - if (enabled){ + if (enabled) { boolean ok = true; - for (MockDatabaseDto dto: databaseDtos){ - if (dto.response!= null && dto.responseFullType != null){ + for (MockDatabaseDto dto : databaseDtos) { + if (dto.response != null && dto.responseFullType != null) { JsonNode json = mapper.readTree(dto.response); - if (json instanceof ArrayNode){ - for (JsonNode j : json){ + if (json instanceof ArrayNode) { + for (JsonNode j : json) { FakeDatabaseRow data = new FakeDatabaseRow(); if (j.has("exId")) data.id = Integer.parseInt(j.get("exId").asText()); @@ -180,21 +203,21 @@ public boolean customizeMockingDatabase(List databaseDtos, bool data.name = j.get("exName").asText(); else data.name = j.asText(); - if (j.has("exInfo") && j.get("exInfo") instanceof ArrayNode){ - if (!j.get("exInfo").isEmpty()){ + if (j.has("exInfo") && j.get("exInfo") instanceof ArrayNode) { + if (!j.get("exInfo").isEmpty()) { data.info = j.get("exInfo").asText(); } } ok = ok && client.backdoor(null, data, null); } - }else { + } else { FakeDatabaseRow data = new FakeDatabaseRow(); if (json.has("exId")) data.id = Integer.parseInt(json.get("exId").asText()); if (json.has("exName")) data.name = json.get("exName").asText(); - if (json.has("exInfo") && json.get("exInfo") instanceof ArrayNode){ - if (!json.get("exInfo").isEmpty()){ + if (json.has("exInfo") && json.get("exInfo") instanceof ArrayNode) { + if (!json.get("exInfo").isEmpty()) { data.info = json.get("exInfo").asText(); } } @@ -203,7 +226,7 @@ public boolean customizeMockingDatabase(List databaseDtos, bool } } return ok; - }else { + } else { return client.backdoor(null, null, null); } } catch (TException | JsonProcessingException e) { @@ -215,18 +238,18 @@ public boolean customizeMockingDatabase(List databaseDtos, bool public boolean customizeMockingRPCExternalService(List externalServiceDtos, boolean enabled) { try { - if (enabled){ + if (enabled) { boolean ok = true; - for (MockRPCExternalServiceDto dto: externalServiceDtos){ - if (dto.responses!= null && !dto.responses.isEmpty() && dto.responses.size() == dto.responseTypes.size()){ + for (MockRPCExternalServiceDto dto : externalServiceDtos) { + if (dto.responses != null && !dto.responses.isEmpty() && dto.responses.size() == dto.responseTypes.size()) { JsonNode json = mapper.readTree(dto.responses.get(0)); FakeRetrieveData data = new FakeRetrieveData(); if (json.has("exId")) data.id = Integer.parseInt(json.get("exId").asText()); if (json.has("exName")) data.name = json.get("exName").asText(); - if (json.has("exInfo") && json.get("exInfo") instanceof ArrayNode){ - if (!json.get("exInfo").isEmpty()){ + if (json.has("exInfo") && json.get("exInfo") instanceof ArrayNode) { + if (!json.get("exInfo").isEmpty()) { data.info = json.get("exInfo").asText(); } } @@ -234,7 +257,7 @@ public boolean customizeMockingRPCExternalService(List Date: Wed, 23 Apr 2025 11:01:35 +0800 Subject: [PATCH 17/17] fix additional info --- .../controller/EmbeddedSutController.java | 25 ++++++++++++++++--- .../controller/ExternalSutController.java | 24 ++++++++++++++++++ .../controller/internal/SutController.java | 3 +++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/EmbeddedSutController.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/EmbeddedSutController.java index 31afd7d307..99a858dfbd 100644 --- a/client-java/controller/src/main/java/org/evomaster/client/java/controller/EmbeddedSutController.java +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/EmbeddedSutController.java @@ -3,6 +3,7 @@ import org.evomaster.client.java.controller.api.dto.ActionDto; import org.evomaster.client.java.controller.api.dto.BootTimeInfoDto; import org.evomaster.client.java.controller.api.dto.UnitsInfoDto; +import org.evomaster.client.java.controller.api.dto.problem.rpc.ScheduleTaskInvocationDto; import org.evomaster.client.java.controller.internal.SutController; import org.evomaster.client.java.instrumentation.*; import org.evomaster.client.java.instrumentation.object.ClassToSchema; @@ -10,9 +11,7 @@ import org.evomaster.client.java.instrumentation.staticstate.ObjectiveRecorder; import org.evomaster.client.java.instrumentation.staticstate.UnitsInfoRecorder; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -75,6 +74,26 @@ public final void newActionSpecificHandler(ActionDto dto){ )); } + @Override + public void newScheduleActionSpecificHandler(ScheduleTaskInvocationDto dto) { + List inputVariables = new ArrayList<>(); + if (dto.requestParams != null && (!dto.requestParams.isEmpty())){ + inputVariables.addAll(dto.requestParams.stream().map(e-> e.stringValue).collect(Collectors.toList())); + } else if (dto.requestParamsAsStrings != null){ + inputVariables.addAll(dto.requestParamsAsStrings); + } + + ExecutionTracer.setAction(new Action( + dto.index, + dto.taskName, + inputVariables, + // might handle external service later, then add empty collection for the moment. + new HashMap<>(), + new HashMap<>(), + new ArrayList<>() + )); + } + @Override public final UnitsInfoDto getUnitsInfoDto(){ return getUnitsInfoDto(UnitsInfoRecorder.getInstance()); diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/ExternalSutController.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/ExternalSutController.java index c31274c857..5aac497172 100644 --- a/client-java/controller/src/main/java/org/evomaster/client/java/controller/ExternalSutController.java +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/ExternalSutController.java @@ -3,6 +3,7 @@ import org.evomaster.client.java.controller.api.dto.ActionDto; import org.evomaster.client.java.controller.api.dto.BootTimeInfoDto; import org.evomaster.client.java.controller.api.dto.UnitsInfoDto; +import org.evomaster.client.java.controller.api.dto.problem.rpc.ScheduleTaskInvocationDto; import org.evomaster.client.java.instrumentation.*; import org.evomaster.client.java.instrumentation.staticstate.ExecutionTracer; import org.evomaster.client.java.instrumentation.staticstate.ObjectiveRecorder; @@ -455,6 +456,29 @@ public final void newActionSpecificHandler(ActionDto dto) { } } + @Override + public void newScheduleActionSpecificHandler(ScheduleTaskInvocationDto dto) { + if (isInstrumentationActivated()) { + + List inputVariables = new ArrayList<>(); + if (dto.requestParams != null && (!dto.requestParams.isEmpty())){ + inputVariables.addAll(dto.requestParams.stream().map(e-> e.stringValue).collect(Collectors.toList())); + } else if (dto.requestParamsAsStrings != null){ + inputVariables.addAll(dto.requestParamsAsStrings); + } + + serverController.setAction(new Action( + dto.index, + dto.taskName, + inputVariables, + // might handle external service later, then add empty collection for the moment. + new HashMap<>(), + new HashMap<>(), + new ArrayList<>() + )); + } + } + @Override public final UnitsInfoDto getUnitsInfoDto(){ diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java index 1b674ad87d..29cf203586 100644 --- a/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java @@ -938,6 +938,8 @@ public final void newScheduleAction(ScheduleTaskInvocationDto dto, boolean query this.actionIndex = dto.index; resetExtraHeuristics(); + + newScheduleActionSpecificHandler(dto); } public final void executeHandleLocalAuthenticationSetup(RPCActionDto dto, ActionResponseDto responseDto){ @@ -1192,6 +1194,7 @@ private RPCType getRPCType(RPCActionDto dto){ public abstract void newActionSpecificHandler(ActionDto dto); + public abstract void newScheduleActionSpecificHandler(ScheduleTaskInvocationDto dto); /** * Check if bytecode instrumentation is on.