aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2019-09-03 17:02:04 +0200
committerGitHub <noreply@github.com>2019-09-03 17:02:04 +0200
commit526709ff0442e985edd498e14c736de8302dc867 (patch)
tree86245289d8f3325fc6915218b5eb39f45aac562b
parentdbd627eb61743340cb565ce41308beb4383a77be (diff)
prog: move all flag mutation logic into flags() (#1362)
This makes it a bit easier to understand. Also fix an issue with using flag value as bit number.
-rw-r--r--prog/mutation.go22
-rw-r--r--prog/rand.go24
2 files changed, 22 insertions, 24 deletions
diff --git a/prog/mutation.go b/prog/mutation.go
index 8a33c3e2e..6c356c4b4 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -236,29 +236,9 @@ func (t *IntType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Ca
func (t *FlagsType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool) {
a := arg.(*ConstArg)
-
for oldVal := a.Val; oldVal == a.Val; {
- // Generate a new value.
- if r.nOutOf(1, 5) {
- a.Val = r.flags(t.Vals, t.BitMask, 0)
- continue
- }
-
- if !t.BitMask || (t.BitMask && r.nOutOf(1, 4)) {
- a.Val = r.flags(t.Vals, t.BitMask, a.Val)
- continue
- }
-
- for stop := false; !stop; stop = r.oneOf(3) {
- idx := r.rand(len(t.Vals))
- if r.bin() {
- a.Val |= 1 << t.Vals[idx]
- } else {
- a.Val &= ^(1 << t.Vals[idx])
- }
- }
+ a.Val = r.flags(t.Vals, t.BitMask, a.Val)
}
-
return
}
diff --git a/prog/rand.go b/prog/rand.go
index 819b1104f..cbfc960a8 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -140,13 +140,31 @@ func (r *randGen) randPageCount() (n uint64) {
// Change a flag value or generate a new one.
func (r *randGen) flags(vv []uint64, bitmask bool, oldVal uint64) (v uint64) {
v = oldVal
+ if r.oneOf(5) {
+ // Ignore the old value sometimes.
+ v = 0
+ }
switch {
case (bitmask && r.nOutOf(7, 10)) || (!bitmask && r.nOutOf(1, 5)):
- for stop := false; !stop; stop = r.bin() {
- v |= vv[r.rand(len(vv))] // prioritized when bitmask = true
+ // Try flipping randomly chosen flags.
+ // Prioritized when bitmask == true.
+ for stop := false; !stop; stop = r.oneOf(3) {
+ flag := vv[r.rand(len(vv))]
+ if r.oneOf(5) {
+ // Try choosing adjacent bit values in case we forgot
+ // to add all relevant flags to the descriptions.
+ if r.bin() {
+ flag >>= 1
+ } else {
+ flag <<= 1
+ }
+ }
+ v ^= flag
}
case (bitmask && r.nOutOf(2, 3)) || (!bitmask && r.nOutOf(7, 8)):
- v = vv[r.rand(len(vv))] // prioritized when bitmask = false
+ // Chose a random flag.
+ // Prioritized when bitmask == false.
+ v = vv[r.rand(len(vv))]
case r.bin():
v = 0
default: