Skip to content

Commit

Permalink
Merge branch 'master' into json-parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
seran authored Oct 29, 2024
2 parents 14c8941 + 634ce0f commit c0e3b34
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ Migrations/
/e2e-tests/spring-rest-bb/maven/target/
/target/
/wfc/target/
/process_data/
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.evomaster.core.problem.rest.resource.ResourceImpactOfIndividual
import org.evomaster.core.search.Individual.GeneFilter
import org.evomaster.core.search.action.*
import org.evomaster.core.search.action.ActionFilter.*
import org.evomaster.core.search.service.monitor.ProcessMonitorExcludeField
import org.evomaster.core.search.service.mutator.EvaluatedMutation
import org.evomaster.core.search.tracer.TrackingHistory
import org.slf4j.Logger
Expand All @@ -41,6 +42,7 @@ class EvaluatedIndividual<T>(
private val results: List<out ActionResult>,

// for tracking its history
@ProcessMonitorExcludeField
override var trackOperator: TrackOperator? = null,
override var index: Int = Traceable.DEFAULT_INDEX,

Expand All @@ -51,6 +53,7 @@ class EvaluatedIndividual<T>(

override var evaluatedResult: EvaluatedMutation? = null

@ProcessMonitorExcludeField
override var tracking: TrackingHistory<out Traceable>? = null

companion object {
Expand Down
15 changes: 10 additions & 5 deletions core/src/main/kotlin/org/evomaster/core/search/Individual.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.evomaster.core.search.gene.optional.OptionalGene
import org.evomaster.core.search.gene.string.StringGene
import org.evomaster.core.search.service.Randomness
import org.evomaster.core.search.service.SearchGlobalState
import org.evomaster.core.search.service.monitor.ProcessMonitorExcludeField
import org.evomaster.core.search.service.mutator.EvaluatedMutation
import org.evomaster.core.search.tracer.Traceable
import org.evomaster.core.search.tracer.TraceableElementCopyFilter
Expand All @@ -34,11 +35,13 @@ import org.slf4j.LoggerFactory
* @param children specify the children of the individual with the constructor
*
*/
abstract class Individual(override var trackOperator: TrackOperator? = null,
override var index: Int = Traceable.DEFAULT_INDEX,
children: MutableList<out ActionComponent>,
childTypeVerifier: (Class<*>) -> Boolean = {k -> ActionComponent::class.java.isAssignableFrom(k)},
groups : GroupsOfChildren<StructuralElement>? = null
abstract class Individual(
@ProcessMonitorExcludeField
override var trackOperator: TrackOperator? = null,
override var index: Int = Traceable.DEFAULT_INDEX,
children: MutableList<out ActionComponent>,
childTypeVerifier: (Class<*>) -> Boolean = {k -> ActionComponent::class.java.isAssignableFrom(k)},
groups : GroupsOfChildren<StructuralElement>? = null
) : Traceable,
StructuralElement(
children,
Expand Down Expand Up @@ -71,6 +74,7 @@ abstract class Individual(override var trackOperator: TrackOperator? = null,
* Note that if the evalutedIndividual is tracked (i.e., [EMConfig.enableTrackEvaluatedIndividual]),
* we do not recommend to track the individual
*/
@ProcessMonitorExcludeField
override var tracking: TrackingHistory<out Traceable>? = null

/**
Expand All @@ -88,6 +92,7 @@ abstract class Individual(override var trackOperator: TrackOperator? = null,
*
* However, when running actual search with MIO, its presence is checked
*/
@ProcessMonitorExcludeField
var searchGlobalState : SearchGlobalState? = null
private set

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.evomaster.core.search.action.ActionComponent
import org.evomaster.core.problem.api.param.Param
import org.evomaster.core.search.gene.Gene
import org.evomaster.core.search.gene.root.CompositeGene
import org.evomaster.core.search.service.monitor.ProcessMonitorExcludeField
import org.slf4j.LoggerFactory
import kotlin.reflect.KClass

Expand Down Expand Up @@ -33,7 +34,9 @@ abstract class StructuralElement (
*/

protected open val children : MutableList<out StructuralElement> = mutableListOf(),
@ProcessMonitorExcludeField
protected val childTypeVerifier: (Class<*>) -> Boolean = {_ -> true},
@ProcessMonitorExcludeField
private var groups : GroupsOfChildren<StructuralElement>? = null
) {

Expand Down Expand Up @@ -85,6 +88,7 @@ abstract class StructuralElement (
* parent of the element, which contains current the element
* Note that [parent] can be null when the element is root
*/
@ProcessMonitorExcludeField
var parent : StructuralElement? = null
private set

Expand Down
2 changes: 2 additions & 0 deletions core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.evomaster.core.problem.enterprise.SampleType
import org.evomaster.core.search.RootElement
import org.evomaster.core.search.gene.utils.GeneUtils
import org.evomaster.core.search.service.SearchGlobalState
import org.evomaster.core.search.service.monitor.ProcessMonitorExcludeField


/**
Expand Down Expand Up @@ -107,6 +108,7 @@ abstract class Gene(
*
* In other words, this relationship is symmetric, transitive but not reflexive
*/
@ProcessMonitorExcludeField
private val bindingGenes: MutableSet<Gene> = mutableSetOf()

init{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ class SearchTimeController {
recording = false
}

/**
* @return if recoding is stopped,
* ie, search has been terminated, and start to handle post actions after search
*/
fun isRecordingStopped() = (!recording)

/**
* Make sure we do not make too many requests in a short amount of time, to avoid
* possible DoS attacks.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.evomaster.core.search.service.monitor

/**
* specify field which should be excluded when saving process monitor data
*/
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class ProcessMonitorExcludeField
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ class SearchProcessMonitor: SearchListener {
)

private val strategy: ExclusionStrategy = object : ExclusionStrategy {
//TODO systematic way to configure the skipped field
/*
now can employ ProcessMonitorExcludeField to skip field
*/
override fun shouldSkipField(field: FieldAttributes): Boolean {
return field.name == "parent" || field.name == "bindingGenes"
return field.getAnnotation(ProcessMonitorExcludeField::class.java) != null
}

//skip abstract StructuralElement element
Expand Down Expand Up @@ -128,11 +130,14 @@ class SearchProcessMonitor: SearchListener {
}

fun <T: Individual> record(added: Boolean, improveArchive : Boolean, evalInd : EvaluatedIndividual<T>){
if(config.enableProcessMonitor){
if(config.enableProcessMonitor
// currently we only record info during fuzzing
&& !time.isRecordingStopped()){
if(config.processInterval == 0.0 || time.percentageUsedBudget() >= tb * config.processInterval/100.0){
when(config.processFormat){
EMConfig.ProcessDataFormat.JSON_ALL->{
if(evalInd != eval) throw IllegalStateException("Mismatched evaluated individual under monitor")
if(evalInd != eval && evalInd.index != (eval as EvaluatedIndividual<T>).index)
throw IllegalStateException("Mismatched evaluated individual under monitor")
/*
step is assigned when an individual is evaluated (part of calculateCoverage of FitnessFunction),
but in order to record if the evaluated individual added into Archive, we need to save it after executing addIfNeeded in Archive
Expand All @@ -142,7 +147,6 @@ class SearchProcessMonitor: SearchListener {
step!!.improvedArchive = improveArchive
saveStep(step!!.indexOfEvaluation, step!!)
if(config.showProgress) log.info("number of targets: ${step!!.populations.size}")

}
EMConfig.ProcessDataFormat.TEST_IND , EMConfig.ProcessDataFormat.TARGET_TEST_IND->{
saveStepAsTest(index = time.evaluatedIndividuals,evalInd = evalInd, doesIncludeTarget = config.processFormat == EMConfig.ProcessDataFormat.TARGET_TEST_IND)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.evomaster.core.search.tracer

import org.evomaster.core.search.service.monitor.ProcessMonitorExcludeField
import org.evomaster.core.search.service.mutator.EvaluatedMutation

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import com.netflix.governator.guice.LifecycleInjector
import org.evomaster.core.BaseModule
import org.evomaster.core.EMConfig
import org.evomaster.core.TestUtils
import org.evomaster.core.search.algorithms.MioAlgorithm
import org.evomaster.core.search.algorithms.onemax.OneMaxFitness
import org.evomaster.core.search.algorithms.onemax.OneMaxIndividual
import org.evomaster.core.search.algorithms.onemax.OneMaxModule
import org.evomaster.core.search.algorithms.onemax.OneMaxSampler
import org.evomaster.core.search.service.monitor.SearchOverall
import org.evomaster.core.search.service.monitor.SearchProcessMonitor
import org.evomaster.core.search.service.monitor.StepOfSearchProcess
Expand All @@ -31,6 +33,8 @@ class ProcessMonitorTest{
private lateinit var config: EMConfig
private lateinit var processMonitor : SearchProcessMonitor
private lateinit var randomness: Randomness
private lateinit var sampler: OneMaxSampler
private lateinit var mio: MioAlgorithm<OneMaxIndividual>

@BeforeEach
fun init(){
Expand All @@ -44,13 +48,16 @@ class ProcessMonitorTest{
object : TypeLiteral<Archive<OneMaxIndividual>>() {}))
processMonitor = injector.getInstance(Key.get(SearchProcessMonitor::class.java))
randomness = injector.getInstance(Key.get(Randomness::class.java))

sampler = injector.getInstance(OneMaxSampler::class.java)
mio = injector.getInstance(Key.get(
object : TypeLiteral<MioAlgorithm<OneMaxIndividual>>() {}))
ff = injector.getInstance(OneMaxFitness::class.java)
config = injector.getInstance(EMConfig::class.java)
config.stoppingCriterion = EMConfig.StoppingCriterion.ACTION_EVALUATIONS
config.processFormat = EMConfig.ProcessDataFormat.JSON_ALL
config.useTimeInFeedbackSampling = false
config.minimize = false

}


Expand Down Expand Up @@ -221,5 +228,24 @@ class ProcessMonitorTest{

}

}
@Test
fun testActivateProcessMonitorMIO(){
config.processFiles = "target/process_data_mio"
config.enableProcessMonitor = true
config.maxEvaluations = 50
config.stoppingCriterion = EMConfig.StoppingCriterion.INDIVIDUAL_EVALUATIONS
config.minimize = true

processMonitor.postConstruct()

assertFalse(Files.exists(Paths.get(config.processFiles)))
assertFalse(Files.exists(Paths.get(processMonitor.getStepDirAsPath())))

mio.search()


assert(Files.exists(Paths.get(config.processFiles)))
assert(Files.exists(Paths.get(processMonitor.getStepDirAsPath())))
assert(Files.exists(Paths.get(processMonitor.getStepAsPath(1))))
}
}
2 changes: 2 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ Under development in `master` branch.

### Addressed GitHub Issues

- #765: Details how to use evomaster + info on found faults
- #822: additionalProperties: [true/false] causes crash
- #986: Should this test be in EvoMaster_fault_representatives_Test.java and is resolveLocation() working as expected?
- #989: TestCaseWriter login cookie variable name
- #1055: Unable to start EVoMaster in public petstore API
- #1069: Error in EvoMaster 3.1.0: Black-Box Testing Initialization Failure with InvocationTargetException and NoSuchMethodError
Expand Down

0 comments on commit c0e3b34

Please sign in to comment.