Skip to content

Commit be3d9e6

Browse files
authored
Merge pull request #1392 from WebFuzzing/refactor-copyfrom-v2
Refactor copyfrom v2
2 parents 39d2fcb + 3445e0d commit be3d9e6

24 files changed

Lines changed: 182 additions & 57 deletions

File tree

core/src/main/kotlin/org/evomaster/core/problem/enterprise/EnterpriseIndividual.kt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ abstract class EnterpriseIndividual(
180180
*/
181181
fun ensureFlattenedStructure() : Boolean{
182182

183+
Lazy.assert { verifyValidity(); true }
184+
183185
val before = seeAllActions().size
184186

185187
val issues = doFlattenStructure()
@@ -189,14 +191,7 @@ abstract class EnterpriseIndividual(
189191
//no base action should have been lost
190192
Lazy.assert { seeAllActions().size == before }
191193

192-
/*
193-
FIXME There is some major bugs in Gene regarding
194-
copyValueFrom() and setFromDifferentGene()
195-
until fixed, this check will fail.
196-
but the fix will require some major refactoring and testing... it will take time
197-
TODO put back once fixed
198-
*/
199-
//verifyValidity()
194+
Lazy.assert { verifyValidity(); true }
200195

201196
return issues
202197
}

core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestIndividual.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ class RestIndividual(
154154
.sortBy { if ((it as SqlAction).representExistingData) 0 else 1 }
155155
}
156156

157+
/*
158+
Can't do this, as it can change how the test behave when there are bounded tainted values
159+
*/
160+
//seeAllActions().forEach { it.forceNewTaints() }
161+
157162
/*
158163
if we move any environment action to the beginning of the individual, it might impact the fitness
159164
*/

core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestIndividualBuilder.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class RestIndividualBuilder {
103103
other.resetLocalIdRecursively()
104104

105105
//avoid possible taint id conflicts
106+
base.seeAllActions().forEach { it.forceNewTaints() }
106107
other.seeAllActions().forEach { it.forceNewTaints() }
107108

108109
val duplicates = base.addInitializingActions(other.seeInitializingActions())
@@ -122,7 +123,7 @@ class RestIndividualBuilder {
122123
//merge shouldn't lose any actions
123124
assert(before == (after+duplicates)) { "$after+$duplicates!=$before" }
124125

125-
base.verifyValidity()
126+
base.verifyValidity(true)
126127

127128
return base
128129
}

core/src/main/kotlin/org/evomaster/core/search/Individual.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ abstract class Individual(
180180
* All invariants should always be satisfied after any modification of the individual.
181181
* If not, this is a bug.
182182
*/
183-
fun verifyValidity(){
183+
fun verifyValidity(checkForTaints: Boolean = false){
184184

185185
groupsView()?.verifyGroups()
186186

@@ -202,9 +202,18 @@ abstract class Individual(
202202
throw IllegalStateException("There are invalid local ids:\n" + localIdErrors.joinToString("\n"))
203203
}
204204

205-
val taintIdErrors = verifyTaintIds()
206-
if(taintIdErrors.isNotEmpty()){
207-
throw IllegalStateException("There are invalid taint ids:\n" + taintIdErrors.joinToString("\n"))
205+
/*
206+
We cannot really verify it all the time.
207+
Duplicates might exist due to bounded genes.
208+
But flattening (done at minimization, for example) removes the binding, leading
209+
this check to fail.
210+
further problem, many phases (eg security) are done _after_ minimization...
211+
*/
212+
if(checkForTaints) {
213+
val taintIdErrors = verifyTaintIds()
214+
if (taintIdErrors.isNotEmpty()) {
215+
throw IllegalStateException("There are invalid taint ids:\n" + taintIdErrors.joinToString("\n"))
216+
}
208217
}
209218
}
210219

core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -876,12 +876,16 @@ abstract class Gene(
876876
/**
877877
* Genes might contain a value that is also stored
878878
* in another gene of the same type.
879+
*
880+
* If the type of [other] is different, this method might throw an [IllegalArgumentException]
881+
*
882+
* TODO refactor, in which type-check is done here
879883
*/
880884
abstract fun containsSameValueAs(other: Gene): Boolean
881885

882886

883887
/**
884-
* evaluate whether [this] and [gene] belong to one evolution during search
888+
* evaluate whether `this` and [gene] belong to one evolution during search
885889
*/
886890
open fun possiblySame(gene: Gene): Boolean = gene.name == name && gene::class == this::class
887891

@@ -1210,8 +1214,7 @@ abstract class Gene(
12101214
//revert back
12111215
val success = unsafeCopyValueFrom(current)
12121216
//reversion should always work... if fails, it is a bug
1213-
// FIXME put back once all are implemented, eg, TaintedMapGene currently missing
1214-
//assert(success)
1217+
assert(success)
12151218
return false
12161219
}
12171220
return true

core/src/main/kotlin/org/evomaster/core/search/gene/ObjectGene.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,10 @@ class ObjectGene(
112112
.forEach { it.randomize(randomness, tryToForceNewValue) }
113113

114114
if (!isFixed){
115-
Lazy.assert {
116-
template != null && additionalFields != null
117-
}
118-
if (additionalFields!!.isNotEmpty())
115+
Lazy.assert { template != null && additionalFields != null }
116+
if (additionalFields!!.isNotEmpty()) {
119117
killChildren(additionalFields!!)
118+
}
120119
val num = randomness.nextInt(MAX_SIZE_ADDITIONAL_FIELDS)
121120
repeat(num){
122121
val added = sampleElementToAdd(randomness)
@@ -265,9 +264,12 @@ class ObjectGene(
265264
}
266265

267266
if(!isFixed){
268-
//TODO what if there is a mismatch here? semantic of this function is unclear
269-
for (i in additionalFields!!.indices){
270-
ok = ok && this.additionalFields!![i].unsafeCopyValueFrom(other.additionalFields!![i])
267+
if (additionalFields!!.isNotEmpty()) {
268+
killChildren(additionalFields!!)
269+
}
270+
val otherAdditionalFields = other.additionalFields
271+
otherAdditionalFields?.forEach {
272+
addChild(it.copy())
271273
}
272274
}
273275

core/src/main/kotlin/org/evomaster/core/search/gene/SeededGene.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,14 @@ class SeededGene<T>(
114114
if (other !is SeededGene<*>)
115115
return false
116116

117+
this.employSeeded = other.employSeeded
118+
this.isEmploySeededMutable = other.isEmploySeededMutable
119+
117120
val ok = if (employSeeded)
118121
this.seeded.unsafeCopyValueFrom(other.seeded)
119122
else
120123
this.gene.unsafeCopyValueFrom(other.gene as Gene)
121124

122-
if (ok){
123-
this.employSeeded = other.employSeeded
124-
this.isEmploySeededMutable = other.isEmploySeededMutable
125-
}
126125
return ok
127126
}
128127

core/src/main/kotlin/org/evomaster/core/search/gene/UUIDGene.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class UUIDGene(
9292
val gene = other.getPhenotype()
9393

9494
if (gene !is UUIDGene) {
95-
throw IllegalArgumentException("Invalid gene type ${gene.javaClass}")
95+
return false
9696
}
9797
return this.mostSigBits.unsafeCopyValueFrom(gene.mostSigBits)
9898
&& this.leastSigBits.unsafeCopyValueFrom(gene.leastSigBits)

core/src/main/kotlin/org/evomaster/core/search/gene/collection/FlexibleMapGene.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,18 @@ where T : Gene {
5858
}
5959

6060
override fun unsafeCopyValueFrom(other: Gene): Boolean {
61-
//TODO
62-
LoggingUtil.uniqueWarn(log,"unsafeCopyValueFrom() not implemented for FlexibleMapGene")
6361

64-
return false
62+
if(other !is FlexibleMapGene<*>) {
63+
return false
64+
}
65+
66+
killAllChildren()
67+
val elements = other.elements
68+
.mapNotNull { it.copy() as? PairGene<T, FlexibleGene> }
69+
.toMutableList()
70+
elements.forEach { it.resetLocalIdRecursively() }
71+
addChildren(elements)
72+
return true
6573
}
6674

6775
override fun isPrintable(): Boolean {

core/src/main/kotlin/org/evomaster/core/search/gene/collection/MapGene.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,14 @@ abstract class MapGene<K, V>(
243243
TODO support other types if needed
244244
*/
245245
if (isElementApplicableToUniqueCheck(geneValue)){
246-
return elements.filter { ParamUtil.getValueGene(it.first).containsSameValueAs(ParamUtil.getValueGene(geneValue)) }
246+
return elements.filter {
247+
try {
248+
//TODO need refactoring/cleanup... should avoid try/catch
249+
ParamUtil.getValueGene(it.first).containsSameValueAs(ParamUtil.getValueGene(geneValue))
250+
}catch (e: Exception){
251+
false
252+
}
253+
}
247254
}
248255
return listOf()
249256
}

0 commit comments

Comments
 (0)