Improve the cycle-collector fuzzer
This commit is contained in:
parent
c00a7b08eb
commit
f455dc1976
|
@ -1,59 +1,91 @@
|
|||
use std;
|
||||
import vec;
|
||||
import std::rand;
|
||||
import option;
|
||||
import uint::range;
|
||||
|
||||
// random uint less than n
|
||||
fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }
|
||||
|
||||
// random choice from a vec
|
||||
fn choice<T: copy>(r : rand::rng, v : [T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }
|
||||
fn choice<T: copy>(r : rand::rng, v : [const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }
|
||||
|
||||
// 1 in n chance of being true
|
||||
fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u }
|
||||
// k in n chance of being true
|
||||
fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }
|
||||
|
||||
|
||||
const iters : uint = 1000u;
|
||||
const vlen : uint = 100u;
|
||||
|
||||
enum maybe_pointy {
|
||||
no_pointy,
|
||||
yes_pointy(@pointy),
|
||||
none,
|
||||
p(@pointy)
|
||||
}
|
||||
|
||||
type pointy = {
|
||||
mutable x : maybe_pointy,
|
||||
mutable y : maybe_pointy,
|
||||
mutable z : fn@()->()
|
||||
};
|
||||
mut a : maybe_pointy,
|
||||
mut b : ~maybe_pointy,
|
||||
mut c : @maybe_pointy,
|
||||
|
||||
fn allunder(n: uint, it: block(uint)) {
|
||||
let i: uint = 0u;
|
||||
while i < n { it(i); i += 1u; }
|
||||
mut f : fn@()->(),
|
||||
mut g : fn~()->(),
|
||||
|
||||
mut m : [maybe_pointy],
|
||||
mut n : [mut maybe_pointy],
|
||||
mut o : {x : int, y : maybe_pointy}
|
||||
};
|
||||
// To add: objects; ifaces; anything type-parameterized?
|
||||
|
||||
fn empty_pointy() -> @pointy {
|
||||
ret @{
|
||||
mut a : none,
|
||||
mut b : ~none,
|
||||
mut c : @none,
|
||||
|
||||
mut f : fn@()->(){},
|
||||
mut g : fn~()->(){},
|
||||
|
||||
mut m : [],
|
||||
mut n : [mut],
|
||||
mut o : {x : 0, y : none}
|
||||
}
|
||||
}
|
||||
|
||||
fn nopT(_x : @pointy) { }
|
||||
fn nop() { }
|
||||
fn nopP(_x : @pointy) { }
|
||||
fn nop<T>(_x: T) { }
|
||||
|
||||
fn test_cycles(r : rand::rng)
|
||||
fn test_cycles(r : rand::rng, k: uint, n: uint)
|
||||
{
|
||||
const max : uint = 10u;
|
||||
let v : [mut @pointy] = [mut];
|
||||
|
||||
let v : [mutable @pointy] = [mutable];
|
||||
allunder(max) {|_i|
|
||||
v += [mutable @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: bind nop() }];
|
||||
// Create a graph with no edges
|
||||
range(0u, vlen) {|_i|
|
||||
v += [mut empty_pointy()];
|
||||
}
|
||||
|
||||
allunder(max) {|i|
|
||||
v[i].x = yes_pointy(v[under(r, max)]);
|
||||
v[i].y = yes_pointy(v[under(r, max)]);
|
||||
v[i].z = bind nopT(v[under(r, max)]);
|
||||
// Fill in the graph with random edges, with density k/n
|
||||
range(0u, vlen) {|i|
|
||||
if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
|
||||
if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
|
||||
if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }
|
||||
|
||||
if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
|
||||
if (false) { v[i].g = bind (fn~(_x: @pointy) { })(choice(r, v)); }
|
||||
// https://github.com/mozilla/rust/issues/1899
|
||||
|
||||
if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
|
||||
if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; }
|
||||
if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
|
||||
}
|
||||
|
||||
// Drop refs one at a time
|
||||
allunder(max) {|i|
|
||||
v[i] = @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: bind nop() };
|
||||
range(0u, vlen) {|i|
|
||||
v[i] = empty_pointy()
|
||||
}
|
||||
}
|
||||
|
||||
fn main()
|
||||
{
|
||||
let r = rand::mk_rng();
|
||||
test_cycles(r);
|
||||
range(0u, iters) {|i|
|
||||
test_cycles(r, i, iters);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue