Created
January 24, 2017 22:36
-
-
Save bbarry/0b13578aad0379e3171dd5dc7d50af5b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Fact(Skip = "This test generator is capable of producing crashes that are not yet fixed; see, for example, Fuzz5815")] | |
public void Fuzz() | |
{ | |
int dt = Math.Abs(new DateTime().Ticks.GetHashCode() % 10000000); | |
// generate a pattern-matching switch randomly from templates | |
string[] expressions = new[] | |
{ | |
"M", // a method group | |
"(() => 1)", // a lambda expression | |
"1", // a constant | |
"2", // a constant | |
"null", // the null constant | |
"default(int?)", // a null constant of type int? | |
"((int?)1)", // a constant of type int? | |
"M()", // a method invocation | |
"double.NaN", // a scary constant | |
"1.1", // a double constant | |
"NotFound" // an unbindable expression | |
}; | |
string[] types = new[] | |
{ | |
"object", | |
"var", | |
"int", | |
"int?", | |
"double", | |
"string", | |
"NotFound" | |
}; | |
// include casted method calls of the provided types | |
expressions = types.Select(t => "((" + t + ")M())").Concat(expressions).ToArray(); | |
// forms: | |
// {expression} | |
// {type} x{0-9} | |
// {type} _ | |
string[] patterns = expressions | |
.Concat(types.SelectMany(t => Enumerable.Range(0, 10).Select(i => t + " x" + i))) | |
.Concat(types.Select(t => t + " _")) | |
.ToArray(); | |
for (int i = 1; i < 100000; i++) | |
{ | |
PatternMatchingFuzz(i + dt, expressions, patterns); | |
} | |
} | |
public void PatternMatchingFuzz(int dt, string[] expressions, string[] patterns) | |
{ | |
Random r = new Random(dt); | |
string Expression() => expressions[r.Next(expressions.Length)]; | |
string Pattern() => patterns[r.Next(patterns.Length)]; | |
const string body = @" | |
public class Program{0} | |
{{ | |
public static void Main(string[] args) | |
{{ | |
{1} | |
}} | |
private static object M() => null; | |
}}"; | |
var statement = new StringBuilder(); | |
switch (r.Next(2)) | |
{ | |
case 0: | |
// test the "is-pattern" expression | |
statement.AppendFormat("if ({0} is {1}) {{}}", Expression(), Pattern()); | |
break; | |
case 1: | |
// test the pattern switch statement | |
statement.AppendFormat("switch ({0})\n{{\n", Expression()); | |
var nCases = r.Next(5); | |
for (int i = 1; i <= nCases; i++) | |
{ | |
statement.AppendFormat(" case {0}:\n", Pattern()); | |
if (i == nCases || r.Next(2) == 0) | |
{ | |
statement.AppendLine(" break;"); | |
} | |
} | |
statement.AppendLine("}"); | |
break; | |
default: | |
throw null; | |
} | |
var program = string.Format(body, dt, statement); | |
CreateCompilationWithMscorlib45(program).GetDiagnostics(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment