コード例 #1
0
        /// <summary>
        /// Parse the command line using the options defined in this argument parser.
        /// </summary>
        /// <param name="args">The command line.</param>
        /// <returns>The parsed arguments.</returns>
        public List <CommandLineArgument> ParseArguments(string[] args)
        {
            List <CommandLineArgument> result = new List <CommandLineArgument>();
            int position = 0; // For positional arguments.
            CommandLineArgument current = null;

            for (int idx = 0; idx < args.Length; idx++)
            {
                string arg = args[idx];

                if (arg.StartsWith("-"))
                {
                    if (arg.StartsWith("--"))
                    {
                        var name = arg.Substring(2);
                        current = null;
                        this.Arguments.TryGetValue(name, out current);
                    }
                    else if (arg.StartsWith("-"))
                    {
                        current = null;
                        var name = arg.Substring(1);
                        // Note that "/" is not supported as an argument delimiter because it conflicts with unix file paths.
                        foreach (var s in this.Arguments.Values)
                        {
                            if (s.ShortName == name)
                            {
                                current = s;
                                break;
                            }
                        }

                        if (current == null)
                        {
                            // See if there's a matching long name with no short name defined.
                            foreach (var s in this.Arguments.Values)
                            {
                                if (s.LongName == name)
                                {
                                    current = s;
                                    break;
                                }
                            }
                        }
                    }

                    if (current == null)
                    {
                        throw new Exception(string.Format("Unexpected argument: '{0}'", arg));
                    }

                    current = current.Clone();
                    result.Add(current);

                    if (current.PrintHelp)
                    {
                        this.PrintHelp(Console.Out);
                        Environment.Exit(1);
                    }
                }
                else if (current != null)
                {
                    // The value for the current switch argument.
                    current.AddParsedValue(arg);
                }
                else
                {
                    // Positional arguments.
                    do
                    {
                        if (position < this.PositionalNames.Count)
                        {
                            var name = this.PositionalNames[position++];
                            current = this.Arguments[name];
                        }
                        else
                        {
                            throw new Exception(string.Format("Unexpected positional argument: '{0}'", arg));
                        }
                    }while (!IsRequired(current, result));

                    // Positional arguments have no name so the arg is the value.
                    var temp = current.Clone();
                    temp.Value = current.ParseValue(arg);
                    result.Add(temp);
                    current = null; // This argument is done, cannot have any more values.
                }
            }

            foreach (var arg in this.Arguments.Values)
            {
                if (IsRequired(arg, result) && !(from r in result where r.LongName == arg.LongName select r).Any())
                {
                    if (arg.IsPositional)
                    {
                        throw new Exception(string.Format("Missing required argument: '{0}'", arg.LongName));
                    }
                    else
                    {
                        throw new Exception(string.Format("Missing required argument: '--{0}'", arg.LongName));
                    }
                }
            }

            foreach (var arg in result)
            {
                if (!arg.IsPositional && arg.Value == null && arg.DataType != typeof(bool) && !arg.AllowedValues.Contains(string.Empty))
                {
                    throw new Exception(string.Format("Missing value for argument: '--{0}'", arg.LongName));
                }
            }

            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Updates the configuration with the specified parsed argument.
        /// </summary>
        private static void UpdateConfigurationWithParsedArgument(Configuration configuration, RewritingOptions options, CommandLineArgument option)
        {
            switch (option.LongName)
            {
            case "command":
                configuration.ToolCommand = (string)option.Value;
                break;

            case "outdir":
                configuration.OutputFilePath = (string)option.Value;
                break;

            case "debug":
                configuration.IsDebugVerbosityEnabled = true;
                Debug.IsEnabled = true;
                break;

            case "verbosity":
                configuration.IsVerbose = true;
                string verbosity = (string)option.Value;
                switch (verbosity)
                {
                case "quiet":
                    configuration.IsVerbose = false;
                    break;

                case "detailed":
                    configuration.LogLevel = options.LogLevel = LogSeverity.Informational;
                    break;

                case "normal":
                    configuration.LogLevel = options.LogLevel = LogSeverity.Warning;
                    break;

                case "minimal":
                    configuration.LogLevel = options.LogLevel = LogSeverity.Error;
                    break;

                default:
                    Error.ReportAndExit($"Please give a valid value for 'verbosity' must be one of 'errors', 'warnings', or 'info', but found {verbosity}.");
                    break;
                }

                break;

            case "path":
                if (configuration.ToolCommand is "test" || configuration.ToolCommand is "replay")
                {
                    // In the case of 'coyote test' or 'replay', the path is the assembly to be tested.
                    configuration.AssemblyToBeAnalyzed = (string)option.Value;
                }
                else if (configuration.ToolCommand is "rewrite")
                {
                    // In the case of 'coyote rewrite', the path is the JSON configuration file
                    // with the binary rewriting options.
                    string filename = (string)option.Value;
                    if (Directory.Exists(filename))
                    {
                        // then we want to rewrite a whole folder full of dll's.
                        configuration.RewritingOptionsPath = filename;
                    }
                    else
                    {
                        string extension = Path.GetExtension(filename);
                        if (string.Compare(extension, ".json", StringComparison.OrdinalIgnoreCase) is 0)
                        {
                            configuration.RewritingOptionsPath = filename;
                        }
                        else if (string.Compare(extension, ".dll", StringComparison.OrdinalIgnoreCase) is 0 ||
                                 string.Compare(extension, ".exe", StringComparison.OrdinalIgnoreCase) is 0)
                        {
                            configuration.AssemblyToBeAnalyzed = filename;
                        }
                        else
                        {
                            Error.ReportAndExit("Please give a valid .dll or JSON configuration file for binary rewriting.");
                        }
                    }
コード例 #3
0
        /// <summary>
        /// Updates the configuration with the specified parsed argument.
        /// </summary>
        private static void UpdateConfigurationWithParsedArgument(Configuration configuration, CommandLineArgument option)
        {
            switch (option.LongName)
            {
            case "command":
                configuration.ToolCommand = (string)option.Value;
                break;

            case "outdir":
                configuration.OutputFilePath = (string)option.Value;
                break;

            case "verbose":
                configuration.IsVerbose = true;
                break;

            case "debug":
                configuration.EnableDebugging = true;
                Debug.IsEnabled = true;
                break;

            case "timeout":
                configuration.Timeout = (int)(uint)option.Value;
                break;

            case "path":
                if (configuration.ToolCommand is "test" || configuration.ToolCommand is "replay")
                {
                    // In the case of 'coyote test' or 'replay', the path is the assembly to be tested.
                    configuration.AssemblyToBeAnalyzed = (string)option.Value;
                }
                else if (configuration.ToolCommand is "rewrite")
                {
                    // In the case of 'coyote rewrite', the path is the JSON configuration file
                    // with the binary rewriting options.
                    string filename  = (string)option.Value;
                    string extension = Path.GetExtension(filename);
                    if (string.Compare(extension, ".json", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        configuration.RewritingConfigurationFile = filename;
                    }
                    else if (string.Compare(extension, ".dll", StringComparison.OrdinalIgnoreCase) == 0 ||
                             string.Compare(extension, ".exe", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        configuration.AssemblyToBeAnalyzed = filename;
                    }
                    else
                    {
                        Error.ReportAndExit("Please give a valid .dll or JSON configuration file for binary rewriting.");
                    }
                }

                break;
コード例 #4
0
        /// <summary>
        /// Updates the configuration with the specified parsed argument.
        /// </summary>
        private static void UpdateConfigurationWithParsedArgument(Configuration configuration, CommandLineArgument option)
        {
            switch (option.LongName)
            {
            case "command":
                configuration.ToolCommand = (string)option.Value;
                break;

            case "outdir":
                configuration.OutputFilePath = (string)option.Value;
                break;

            case "verbose":
                configuration.IsVerbose = true;
                break;

            case "debug":
                configuration.EnableDebugging = true;
                Debug.IsEnabled = true;
                break;

            case "timeout":
                configuration.Timeout = (int)(uint)option.Value;
                break;

            case "path":
                configuration.AssemblyToBeAnalyzed = (string)option.Value;
                break;

            case "method":
                configuration.TestMethodName = (string)option.Value;
                break;

            case "seed":
                configuration.RandomGeneratorSeed = (uint)option.Value;
                break;

            case "sch-random":
            case "sch-dfs":
            case "sch-portfolio":
                configuration.SchedulingStrategy = option.LongName.Substring(4);
                break;

            case "sch-probabilistic":
            case "sch-pct":
            case "sch-fairpct":
                configuration.SchedulingStrategy = option.LongName.Substring(4);
                configuration.StrategyBound      = (int)(uint)option.Value;
                break;

            case "schedule":
            {
                string filename  = (string)option.Value;
                string extension = System.IO.Path.GetExtension(filename);
                if (!extension.Equals(".schedule"))
                {
                    Error.ReportAndExit("Please give a valid schedule file " +
                                        "'--replay x', where 'x' has extension '.schedule'.");
                }

                configuration.ScheduleFile = filename;
            }

            break;

            case "break":
                configuration.AttachDebugger = true;
                break;

            case "iterations":
                configuration.TestingIterations = (int)(uint)option.Value;
                break;

            case "parallel":
                configuration.ParallelBugFindingTasks = (uint)option.Value;
                break;

            case "parallel-debug":
                configuration.ParallelDebug = true;
                break;

            case "wait-for-testing-processes":
                configuration.WaitForTestingProcesses = true;
                break;

            case "testing-scheduler-ipaddress":
            {
                var ipAddress = (string)option.Value;
                int port      = 0;
                if (ipAddress.Contains(":"))
                {
                    string[] parts = ipAddress.Split(':');
                    if (parts.Length != 2 || !int.TryParse(parts[1], out port))
                    {
                        Error.ReportAndExit("Please give a valid port number for --testing-scheduler-ipaddress option");
                    }

                    ipAddress = parts[0];
                }

                if (!IPAddress.TryParse(ipAddress, out _))
                {
                    Error.ReportAndExit("Please give a valid ip address for --testing-scheduler-ipaddress option");
                }

                configuration.TestingSchedulerIpAddress = ipAddress + ":" + port;
            }

            break;

            case "run-as-parallel-testing-task":
                configuration.RunAsParallelBugFindingTask = true;
                break;

            case "testing-scheduler-endpoint":
                configuration.TestingSchedulerEndPoint = (string)option.Value;
                break;

            case "testing-process-id":
                configuration.TestingProcessId = (uint)option.Value;
                break;

            case "graph":
                configuration.IsDgmlGraphEnabled = true;
                configuration.IsDgmlBugGraph     = false;
                break;

            case "graph-bug":
                configuration.IsDgmlGraphEnabled = true;
                configuration.IsDgmlBugGraph     = true;
                break;

            case "xml-trace":
                configuration.IsXmlLogEnabled = true;
                break;

            case "actor-runtime-log":
                configuration.CustomActorRuntimeLogType = (string)option.Value;
                break;

            case "explore":
                configuration.PerformFullExploration = true;
                break;

            case "coverage":
                if (option.Value == null)
                {
                    configuration.ReportCodeCoverage     = true;
                    configuration.ReportActivityCoverage = true;
                }
                else
                {
                    foreach (var item in (string[])option.Value)
                    {
                        switch (item)
                        {
                        case "code":
                            configuration.ReportCodeCoverage = true;
                            break;

                        case "activity":
                            configuration.ReportActivityCoverage = true;
                            break;

                        case "activity-debug":
                            configuration.ReportActivityCoverage = true;
                            configuration.DebugActivityCoverage  = true;
                            break;

                        default:
                            break;
                        }
                    }
                }

                break;

            case "instrument":
            case "instrument-list":
                configuration.AdditionalCodeCoverageAssemblies[(string)option.Value] = false;
                break;

            case "timeout-delay":
                configuration.TimeoutDelay = (uint)option.Value;
                break;

            case "max-steps":
            {
                uint[] values = (uint[])option.Value;
                if (values.Length > 2)
                {
                    Error.ReportAndExit("Invalid number of options supplied via '--max-steps'.");
                }

                uint i = values[0];
                uint j;
                if (values.Length == 2)
                {
                    j = values[1];
                    configuration.UserExplicitlySetMaxFairSchedulingSteps = true;
                }
                else
                {
                    j = 10 * i;
                }

                configuration.MaxUnfairSchedulingSteps = (int)i;
                configuration.MaxFairSchedulingSteps   = (int)j;
            }

            break;

            case "fail-on-maxsteps":
                configuration.ConsiderDepthBoundHitAsBug = true;
                break;

            case "prefix":
                configuration.SafetyPrefixBound = (int)option.Value;
                break;

            case "liveness-temperature-threshold":
                configuration.LivenessTemperatureThreshold = (int)(uint)option.Value;
                break;

            default:
                throw new Exception(string.Format("Unhandled parsed argument: '{0}'", option.LongName));
            }
        }