Exemple #1
0
 internal CommandLineGroup(CommandLineArgumentParser parser, List <string> longNames)
 {
     this.Parser    = parser;
     this.LongNames = longNames;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="CommandLineOptions"/> class.
        /// </summary>
        internal CommandLineOptions()
        {
            this.Parser = new CommandLineArgumentParser("Coyote",
                                                        "The Coyote tool enables you to systematically test a specified Coyote test, generate " +
                                                        "a reproducible bug-trace if a bug is found, and replay a bug-trace using the VS debugger.");

            var basicGroup = this.Parser.GetOrCreateGroup("Basic", "Basic options", true);
            var commandArg = basicGroup.AddPositionalArgument("command", "The operation perform (test, replay, rewrite)");

            commandArg.AllowedValues = new List <string>(new string[] { "test", "replay", "rewrite", "telemetry" });
            basicGroup.AddPositionalArgument("path", "Path to the Coyote program to test");
            basicGroup.AddArgument("method", "m", "Suffix of the test method to execute");
            basicGroup.AddArgument("outdir", "o", "Dump output to directory x (absolute path or relative to current directory");
            var verbosityArg = basicGroup.AddArgument("verbosity", "v", "Enable verbose log output during testing providing the level of logging you want to see: quiet, minimal, normal, detailed.  Using -v with no argument defaults to 'detailed'", typeof(string), defaultValue: "detailed");

            verbosityArg.AllowedValues = new List <string>(new string[] { "quiet", "minimal", "normal", "detailed" });
            basicGroup.AddArgument("debug", "d", "Enable debugging", typeof(bool)).IsHidden = true;
            basicGroup.AddArgument("break", "b", "Attaches the debugger and also adds a breakpoint when an assertion fails (disabled during parallel testing)", typeof(bool));
            basicGroup.AddArgument("version", null, "Show tool version", typeof(bool));

            var testingGroup = this.Parser.GetOrCreateGroup("testingGroup", "Systematic testing options");

            testingGroup.DependsOn = new CommandLineArgumentDependency()
            {
                Name = "command", Value = "test"
            };
            testingGroup.AddArgument("iterations", "i", "Number of schedules to explore for bugs", typeof(uint));
            testingGroup.AddArgument("timeout", "t", "Timeout in seconds after which no more testing iterations will run (disabled by default)", typeof(uint));
            testingGroup.AddArgument("max-steps", "ms", @"Max scheduling steps to be explored during systematic testing (by default 10,000 unfair and 100,000 fair steps).
You can provide one or two unsigned integer values", typeof(uint)).IsMultiValue = true;
            testingGroup.AddArgument("timeout-delay", null, "Controls the frequency of timeouts by built-in timers (not a unit of time)", typeof(uint));
            testingGroup.AddArgument("deadlock-timeout", null, "Controls how much time (in ms) to wait before reporting a potential deadlock", typeof(uint));
            testingGroup.AddArgument("fail-on-maxsteps", null, "Consider it a bug if the test hits the specified max-steps", typeof(bool));
            testingGroup.AddArgument("liveness-temperature-threshold", null, "Specify the liveness temperature threshold is the liveness temperature value that triggers a liveness bug", typeof(uint));
            testingGroup.AddArgument("parallel", "p", "Number of parallel testing processes (the default '0' runs the test in-process)", typeof(uint));
            testingGroup.AddArgument("sch-random", null, "Choose the random scheduling strategy (this is the default)", typeof(bool));
            testingGroup.AddArgument("sch-probabilistic", "sp", "Choose the probabilistic scheduling strategy with given probability for each scheduling decision where the probability is " +
                                     "specified as the integer N in the equation 0.5 to the power of N.  So for N=1, the probability is 0.5, for N=2 the probability is 0.25, N=3 you get 0.125, etc.", typeof(uint));
            testingGroup.AddArgument("sch-pct", null, "Choose the PCT scheduling strategy with given maximum number of priority switch points", typeof(uint));
            testingGroup.AddArgument("sch-fairpct", null, "Choose the fair PCT scheduling strategy with given maximum number of priority switch points", typeof(uint));
            testingGroup.AddArgument("sch-rl", null, "Choose the reinforcement learning (RL) scheduling strategy", typeof(bool));
            testingGroup.AddArgument("sch-portfolio", null, "Choose the portfolio scheduling strategy", typeof(bool));

            var replayOptions = this.Parser.GetOrCreateGroup("replayOptions", "Replay options");

            replayOptions.DependsOn = new CommandLineArgumentDependency()
            {
                Name = "command", Value = "replay"
            };
            replayOptions.AddPositionalArgument("schedule", "Schedule file to replay");

            var rewritingGroup = this.Parser.GetOrCreateGroup("rewritingGroup", "Binary rewriting options");

            rewritingGroup.DependsOn = new CommandLineArgumentDependency()
            {
                Name = "command", Value = "rewrite"
            };
            rewritingGroup.AddArgument("strong-name-key-file", "snk", "Path to strong name signing key");
            rewritingGroup.AddArgument("assert-data-races", null, "Add assertions for read/write data races", typeof(bool));
            rewritingGroup.AddArgument("rewrite-dependencies", null, "Rewrite all dependent assemblies that are found in the same location as the given path", typeof(bool));
            rewritingGroup.AddArgument("rewrite-unit-tests", null, "Rewrite unit tests to run in the scope of the Coyote testing engine", typeof(bool));
            rewritingGroup.AddArgument("rewrite-threads", null, "Rewrite low-level threading APIs (experimental)", typeof(bool));

            var coverageGroup = this.Parser.GetOrCreateGroup("coverageGroup", "Code and activity coverage options");

            coverageGroup.DependsOn = new CommandLineArgumentDependency()
            {
                Name = "command", Value = "test"
            };
            var coverageArg = coverageGroup.AddArgument("coverage", "c", @"Generate code coverage statistics (via VS instrumentation) with zero or more values equal to:
 code: Generate code coverage statistics (via VS instrumentation)
 activity: Generate activity (state machine, event, etc.) coverage statistics
 activity-debug: Print activity coverage statistics with debug info", typeof(string));

            coverageArg.AllowedValues = new List <string>(new string[] { string.Empty, "code", "activity", "activity-debug" });
            coverageArg.IsMultiValue  = true;
            coverageGroup.AddArgument("instrument", "instr", "Additional file spec(s) to instrument for code coverage (wildcards supported)", typeof(string));
            coverageGroup.AddArgument("instrument-list", "instr-list", "File containing the paths to additional file(s) to instrument for code " +
                                      "coverage, one per line, wildcards supported, lines starting with '//' are skipped", typeof(string));

            var advancedGroup = this.Parser.GetOrCreateGroup("advancedGroup", "Advanced options");

            advancedGroup.DependsOn = new CommandLineArgumentDependency()
            {
                Name = "command", Value = "test"
            };
            advancedGroup.AddArgument("explore", null, "Keep testing until the bound (e.g. iteration or time) is reached", typeof(bool));
            advancedGroup.AddArgument("seed", null, "Specify the random value generator seed", typeof(uint));
            advancedGroup.AddArgument("graph-bug", null, "Output a DGML graph of the iteration that found a bug", typeof(bool));
            advancedGroup.AddArgument("graph", null, "Output a DGML graph of all test iterations whether a bug was found or not", typeof(bool));
            advancedGroup.AddArgument("xml-trace", null, "Specify a filename for XML runtime log output to be written to", typeof(bool));
            advancedGroup.AddArgument("actor-runtime-log", null, "Specify an additional custom logger using fully qualified name: 'fullclass,assembly'", typeof(string));

            var experimentalGroup = this.Parser.GetOrCreateGroup("experimentalGroup", "Experimental options");

            experimentalGroup.DependsOn = new CommandLineArgumentDependency()
            {
                Name = "command", Value = "test"
            };
            experimentalGroup.AddArgument("relaxed-testing", null, "Relax systematic testing to allow for uncontrolled concurrency", typeof(bool));
            experimentalGroup.AddArgument("concurrency-fuzzing", null, "Enable concurrency fuzzing", typeof(bool));

            // Hidden options (for debugging or experimentation only).
            var hiddenGroup = this.Parser.GetOrCreateGroup("hiddenGroup", "Hidden Options");

            hiddenGroup.IsHidden = true;
            hiddenGroup.AddArgument("prefix", null, "Safety prefix bound", typeof(int)); // why is this needed, seems to just be an override for MaxUnfairSchedulingSteps?
            hiddenGroup.AddArgument("run-as-parallel-testing-task", null, null, typeof(bool));
            hiddenGroup.AddArgument("additional-paths", null, null, typeof(string));
            hiddenGroup.AddArgument("testing-scheduler-ipaddress", null, "Specify server ip address and optional port (default: 127.0.0.1:0))", typeof(string));
            hiddenGroup.AddArgument("testing-scheduler-endpoint", null, "Specify a name for the server (default: CoyoteTestScheduler)", typeof(string));
            hiddenGroup.AddArgument("testing-process-id", null, "The id of the controlling TestingProcessScheduler", typeof(uint));
            hiddenGroup.AddArgument("wait-for-testing-processes", null, "Wait for testing processes to start (default is to launch them)", typeof(bool));
            hiddenGroup.AddArgument("parallel-debug", "pd", "Used with --parallel to put up a debugger prompt on each child process", typeof(bool));
        }