]> git.lizzy.rs Git - rust.git/commitdiff
Improve the cycle-collector fuzzer
authorJesse Ruderman <jruderman@gmail.com>
Sat, 25 Feb 2012 03:26:42 +0000 (19:26 -0800)
committerJesse Ruderman <jruderman@gmail.com>
Sat, 25 Feb 2012 03:26:42 +0000 (19:26 -0800)
src/fuzzer/cycles.rs

index 8e8bef792707e4017e5fe63b29fe0b98c7649c10..494121aaa2c63d3edb137cb965b4bb3d19be2e79 100644 (file)
@@ -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,
+
+    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,
 
-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 : [],
+        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);
+    }
 }