public static ExitCodes Reentry(string exitCodePath, string op, string[] args) { ExitCodes exitCode = ExitCodes.UnknownError; Exception exception = null; try { MethodInfo selected; foreach (MethodInfo mi in typeof(TestMemory).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { foreach (CustomAttributeData attr in mi.CustomAttributes) { if (attr.AttributeType == typeof(OpAttribute)) { object[] attrArgs = new object[attr.ConstructorArguments.Count]; for (int i = 0; i < attrArgs.Length; i++) { attrArgs[i] = attr.ConstructorArguments[i].Value; } OpAttribute opAttr = (OpAttribute)attr.Constructor.Invoke(attrArgs); if (String.Equals(op, opAttr.Op)) { selected = mi; goto Found; } } } } Debug.Assert(false, String.Format("Unknown command \"{0}\" passed to TestMemory.Reentry()", op)); return(exitCode = ExitCodes.UnknownCommand); Found: TestMemory test = new TestMemory(args); selected.Invoke(test, null); // pre-JIT/warmup System.GC.Collect(2 /*gen*/, GCCollectionMode.Forced, true /*blocking*/, true /*compacting*/); // Try to avoid GC to stabilize results for implementations caching workspaces via weak references. // compute maximum size for TryStartNoGCRegion(). Assume workstation GC (has lower limits) int ephemeralSegmentSize = (Environment.Is64BitProcess ? 256 : 16) * 1024 * 1024; System.GC.TryStartNoGCRegion(ephemeralSegmentSize); CLRProfilerControl.AllocationLoggingActive = true; selected.Invoke(test, null); CLRProfilerControl.AllocationLoggingActive = false; System.GC.EndNoGCRegion(); return(exitCode = ExitCodes.Success); } catch (Exception exception2) { exception = exception2; return(exitCode = ExitCodes.Exception); } finally { // CLR Profiler doesn't pass exit code through - use a file to do so File.WriteAllText(exitCodePath, String.Concat((int)exitCode, Environment.NewLine, exception)); } }
public static int Main(string[] args) { // hook for reentrant invocation under profiler const int ProfilerCallbackArgCount = 3; if ((args.Length >= ProfilerCallbackArgCount) && String.Equals(args[0], TestMemory.CallbackCommandSwitch)) { string[] subArgs = new string[args.Length - ProfilerCallbackArgCount]; Array.Copy(args, ProfilerCallbackArgCount, subArgs, 0, subArgs.Length); return((int)TestMemory.Reentry(args[1], args[2], subArgs)); } TestFramework(); Options options = new Options(); List <long> breakIterations = new List <long>(); Dictionary <string, bool> stochasticEnables = InitializeEnables(StochasticTokens); Dictionary <string, bool> unitEnables = InitializeEnables(UnitTestTokens); Dictionary <string, bool> perfEnables = InitializeEnables(PerfTestDriver.CategoryTokens); options.seed = Environment.TickCount; bool[] disables = new bool[Tests.Length]; options.perfGroup = PerfTestDriver.Group.Priority; for (int n = 0; n < args.Length; n++) { string arg = args[n]; if (arg.StartsWith("seed:")) { options.seed = Int32.Parse(arg.Substring(5)); } else if (arg.StartsWith("timelimit:")) { options.timeLimit = Int32.Parse(arg.Substring(10)); } else if (String.Equals(arg, "-all")) { for (int i = 0; i < disables.Length; i++) { disables[i] = true; } } else if (String.Equals(arg, "+all")) { for (int i = 0; i < disables.Length; i++) { disables[i] = false; } } else if (String.Equals(arg, "baseline")) { options.baseline = true; } else if (String.Equals(arg, "failhard:")) { arg = arg.Substring(9); if (Array.IndexOf(new string[] { "on", "yes", "true" }, arg) >= 0) { options.failHard = true; } else if (Array.IndexOf(new string[] { "off", "no", "false" }, arg) >= 0) { options.failHard = false; } else { throw new ArgumentException(); } } else if (arg.StartsWith("break:")) { breakIterations.Add(Int64.Parse(arg.Substring(6))); } else if (String.Equals(arg, "fullperf")) { options.perfGroup = PerfTestDriver.Group.Full; } else if (HandledEnableDisable(arg, unitEnables, "unit", "Unit test", UnitTestTokens)) { } else if (HandledEnableDisable(arg, stochasticEnables, "random", "Stochastic test", StochasticTokens)) { } else if (HandledEnableDisable(arg, perfEnables, "perf", "Perf category", PerfTestDriver.CategoryTokens)) { } else { bool disable; if (arg.StartsWith("+")) { disable = false; arg = arg.Substring(1); } else if (arg.StartsWith("-")) { disable = true; arg = arg.Substring(1); } else { throw new ArgumentException(); } int i = Array.FindIndex(Tests, delegate(KeyValuePair <string, TestMethod> candidate) { return(String.Equals(candidate.Key, arg)); }); if (i < 0) { throw new ArgumentException(String.Format("Specified test \"{0}\" not found", arg)); } disables[i] = disable; } } options.breakIterations = breakIterations.ToArray(); options.stochasticEnables = new List <KeyValuePair <string, bool> >(stochasticEnables).ToArray(); options.unitEnables = new List <KeyValuePair <string, bool> >(unitEnables).ToArray(); options.perfEnables = new List <KeyValuePair <string, bool> >(perfEnables).ToArray(); int exitCode = 0; for (int i = 0; i < Tests.Length; i++) { if (!Tests[i].Value(options, !disables[i])) { exitCode = 1; } Console.WriteLine(); } if (Debugger.IsAttached) { Console.ReadLine(); } return(exitCode); }