minor
This commit is contained in:
parent
0e0442d2b1
commit
65d39fe60d
|
@ -74,7 +74,7 @@ be overloaded. Which is especially useful when `nil` for `ref` is not an accepta
|
||||||
|
|
||||||
### Needed config
|
### Needed config
|
||||||
|
|
||||||
Compile with at least `nim c --cc:clang -d:useMalloc -t:"-fsanitize=fuzzer,address,undefined" -l:"-fsanitize=fuzzer,address,undefined" -d:nosignalhandler --nomain:on -g`, `--mm:arc|orc` is recommended.
|
Compile with at least `--cc:clang -d:useMalloc -t:"-fsanitize=fuzzer,address,undefined" -l:"-fsanitize=fuzzer,address,undefined" -d:nosignalhandler --nomain:on -g`, `--mm:arc|orc` is recommended.
|
||||||
|
|
||||||
Sample [nim.cfg](tests/nim.cfg) and [.nimble](https://github.com/planetis-m/fuzz-playground/blob/master/playground.nimble) files
|
Sample [nim.cfg](tests/nim.cfg) and [.nimble](https://github.com/planetis-m/fuzz-playground/blob/master/playground.nimble) files
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ proc mutate*(value: var string; sizeIncreaseHint: int; enforceChanges: bool; r:
|
||||||
else:
|
else:
|
||||||
repeatMutate(mutateString(move value, high(int), sizeIncreaseHint, r))
|
repeatMutate(mutateString(move value, high(int), sizeIncreaseHint, r))
|
||||||
|
|
||||||
proc mutate*[S; T: SomeNumber|bool|char](value: var array[S, T]; sizeIncreaseHint: int;
|
proc mutate*[S; T: ByteSized](value: var array[S, T]; sizeIncreaseHint: int;
|
||||||
enforceChanges: bool; r: var Rand) =
|
enforceChanges: bool; r: var Rand) =
|
||||||
repeatMutate(mutateArray(value, r))
|
repeatMutate(mutateArray(value, r))
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# This example produces valid graphs, not garbage, without using graph library functions.
|
# This example produces valid graphs, not garbage, without using graph library functions.
|
||||||
|
import std/[packedsets, deques]
|
||||||
when defined(runFuzzTests):
|
when defined(runFuzzTests):
|
||||||
const
|
const
|
||||||
MaxNodes = 8 # User defined, statically limits number of nodes.
|
MaxNodes = 8 # User defined, statically limits number of nodes.
|
||||||
|
@ -21,6 +22,8 @@ type
|
||||||
data: T
|
data: T
|
||||||
edges: seq[NodeIdx]
|
edges: seq[NodeIdx]
|
||||||
|
|
||||||
|
proc len*[T](x: Graph[T]): int {.inline.} = x.nodes.len
|
||||||
|
|
||||||
proc `[]`*[T](x: Graph[T]; idx: Natural): lent T {.inline.} = x.nodes[idx].data
|
proc `[]`*[T](x: Graph[T]; idx: Natural): lent T {.inline.} = x.nodes[idx].data
|
||||||
proc `[]`*[T](x: var Graph[T]; idx: Natural): var T {.inline.} = x.nodes[idx].data
|
proc `[]`*[T](x: var Graph[T]; idx: Natural): var T {.inline.} = x.nodes[idx].data
|
||||||
|
|
||||||
|
@ -46,6 +49,23 @@ proc deleteEdge*[T](x: var Graph[T]; `from`, to: Natural) =
|
||||||
fromNode.edges.delete(toNodeIdx)
|
fromNode.edges.delete(toNodeIdx)
|
||||||
x.deleteNode(toNode.int) # sneaky bug
|
x.deleteNode(toNode.int) # sneaky bug
|
||||||
|
|
||||||
|
proc breadthFirstSearch[T](x: Graph[T]; `from`: Natural): seq[NodeIdx] =
|
||||||
|
var queue: Deque[NodeIdx]
|
||||||
|
queue.addLast(`from`.NodeIdx)
|
||||||
|
|
||||||
|
result = @[`from`.NodeIdx]
|
||||||
|
var visited: PackedSet[NodeIdx]
|
||||||
|
visited.incl `from`.NodeIdx
|
||||||
|
|
||||||
|
while queue.len > 0:
|
||||||
|
let idx = queue.popFirst()
|
||||||
|
template node: untyped = x.nodes[idx.int]
|
||||||
|
for toNode in node.edges:
|
||||||
|
if toNode notin visited:
|
||||||
|
queue.addLast(toNode)
|
||||||
|
visited.incl toNode
|
||||||
|
result.add(toNode)
|
||||||
|
|
||||||
when defined(runFuzzTests) and isMainModule:
|
when defined(runFuzzTests) and isMainModule:
|
||||||
import std/random, drchaos/[mutator, common]
|
import std/random, drchaos/[mutator, common]
|
||||||
|
|
||||||
|
@ -60,61 +80,18 @@ when defined(runFuzzTests) and isMainModule:
|
||||||
proc mutate(value: var seq[NodeIdx]; sizeIncreaseHint: int; enforceChanges: bool; r: var Rand) =
|
proc mutate(value: var seq[NodeIdx]; sizeIncreaseHint: int; enforceChanges: bool; r: var Rand) =
|
||||||
repeatMutateInplace(mutateSeq(value, tmp, MaxEdges, sizeIncreaseHint, r))
|
repeatMutateInplace(mutateSeq(value, tmp, MaxEdges, sizeIncreaseHint, r))
|
||||||
|
|
||||||
#proc postProcess[T: SomeNumber](x: var seq[Node[T]]; r: var Rand) =
|
proc postProcess[T: SomeNumber](x: var seq[Node[T]]; r: var Rand) =
|
||||||
#if x.len >= 8:
|
for n in x.mitems:
|
||||||
#x[0].data = 63
|
var i = 0
|
||||||
#x[1].data = 3
|
while i <= n.edges.high:
|
||||||
#x[2].data = -56
|
if n.edges[i].int >= x.len:
|
||||||
#x[3].data = 100
|
delete(n.edges, i)
|
||||||
#x[4].data = -100
|
else: inc i
|
||||||
#x[5].data = -78
|
|
||||||
#x[6].data = 46
|
|
||||||
#x[7].data = 120
|
|
||||||
|
|
||||||
func fuzzTarget(x: Graph[int8]) =
|
func fuzzTarget(x: Graph[int8]) =
|
||||||
when defined(dumpFuzzInput): debugEcho(x)
|
when defined(dumpFuzzInput): debugEcho(x)
|
||||||
if x.nodes.len == 8 and
|
if x.len > 0:
|
||||||
x.nodes[0].data == 63 and
|
let nodesExplored = breadthFirstSearch(x, `from` = 0)
|
||||||
x.nodes[1].data == 3 and
|
assert nodesExplored[0] == 0.NodeIdx
|
||||||
x.nodes[2].data == -56 and
|
|
||||||
x.nodes[3].data == 100 and
|
|
||||||
x.nodes[4].data == -100 and
|
|
||||||
x.nodes[5].data == -78 and
|
|
||||||
x.nodes[6].data == 46 and
|
|
||||||
x.nodes[7].data == 120 and
|
|
||||||
|
|
||||||
x.nodes[0].edges.len == 2 and
|
|
||||||
x.nodes[0].edges[0] == 1.NodeIdx and
|
|
||||||
x.nodes[0].edges[1] == 2.NodeIdx and
|
|
||||||
x.nodes[1].edges.len == 2 and
|
|
||||||
x.nodes[1].edges[0] == 3.NodeIdx and
|
|
||||||
x.nodes[1].edges[1] == 4.NodeIdx and
|
|
||||||
x.nodes[2].edges.len == 2 and
|
|
||||||
x.nodes[2].edges[0] == 5.NodeIdx and
|
|
||||||
x.nodes[2].edges[1] == 6.NodeIdx and
|
|
||||||
x.nodes[3].edges.len == 1 and
|
|
||||||
x.nodes[3].edges[0] == 7.NodeIdx and
|
|
||||||
x.nodes[4].edges.len == 0 and
|
|
||||||
x.nodes[5].edges.len == 0 and
|
|
||||||
x.nodes[6].edges.len == 0 and
|
|
||||||
x.nodes[7].edges.len == 0:
|
|
||||||
doAssert false
|
|
||||||
# Here you could call library functions and check invariants.
|
|
||||||
# Such as when removing edges, the number of nodes should remain the same.
|
|
||||||
#var x = x
|
|
||||||
#let oldLen = x.nodes.len
|
|
||||||
#x.deleteEdge(1, 2)
|
|
||||||
#doAssert oldLen == x.nodes.len
|
|
||||||
|
|
||||||
defaultMutator(fuzzTarget)
|
defaultMutator(fuzzTarget)
|
||||||
|
|
||||||
#(nodes: @[
|
|
||||||
#(data: 63, edges: @[1, 2]),
|
|
||||||
#(data: 3, edges: @[3, 4]),
|
|
||||||
#(data: -56, edges: @[5, 6]),
|
|
||||||
#(data: 100, edges: @[7]),
|
|
||||||
#(data: -100, edges: @[]),
|
|
||||||
#(data: -78, edges: @[]),
|
|
||||||
#(data: 46, edges: @[]),
|
|
||||||
#(data: 120, edges: @[])
|
|
||||||
#])
|
|
||||||
|
|
|
@ -17,6 +17,6 @@ proc mutate(value: var DiceFace; sizeIncreaseHint: int; enforceChanges: bool; r:
|
||||||
repeatMutate(r.sample([df1, df2, df3, df4, df5, df6]))
|
repeatMutate(r.sample([df1, df2, df3, df4, df5, df6]))
|
||||||
|
|
||||||
func fuzzTarget(x: array[10, DiceFace]) =
|
func fuzzTarget(x: array[10, DiceFace]) =
|
||||||
doAssert x != array[10, DiceFace]([0, 32, 2, 4, 8, 4, 32, 8, 16, 2])
|
doAssert x != [df1, df6, df2, df3, df4, df3, df6, df4, df5, df2]
|
||||||
|
|
||||||
defaultMutator(fuzzTarget)
|
defaultMutator(fuzzTarget)
|
||||||
|
|
Loading…
Reference in New Issue