Esempio n. 1
0
        /// <summary>
        /// Returns true if the action is enabled in the current state.
        /// If the action is not enabled, provides a reason in <paramref name="failureReason"/>.
        /// </summary>
        /// <param name="action">action whose enabledness is being checked</param>
        /// <param name="failureReason">failure reason if the action is not enabled</param>
        /// <returns>true if the action is enabled, false otherwise</returns>
        public bool IsActionEnabled(CompoundTerm action, out string failureReason)
        {
            if (!AllActionSymbols.Contains(action.Symbol))
            {
                failureReason = "Action symbol '" + action.Symbol.ToString() + "' not enabled in the model";
                return(false);
            }
            else
            {
                bool isEnabled = modelProgram.IsEnabled(currState, action);
                if (!isEnabled)
                {
                    failureReason = "Action '" + ConformanceTester.MakeQuotedString(action.ToString()) + "' not enabled in the model";

                    foreach (string s in modelProgram.GetEnablingConditionDescriptions(currState, action, true))
                    {
                        failureReason += "\n";
                        failureReason += s;
                    }
                    return(false);
                }
                else
                {
                    failureReason = "";
                    return(true);
                }
            }
        }
Esempio n. 2
0
        public static void RunWithCommandLineArguments(string[] args)
        {
            //System.Diagnostics.Debugger.Break();
            ConformanceTester confTester = null;

            try
            {
                ConfTesterCommandLineSettings settings = new ConfTesterCommandLineSettings();
                if (!Parser.ParseArgumentsWithUsage(args, settings))
                {
                    //Console.ReadLine();
                    return;
                }

                #region load the libraries
                List <Assembly> libs = new List <Assembly>();
                try
                {
                    if (settings.reference != null)
                    {
                        foreach (string l in settings.reference)
                        {
                            libs.Add(System.Reflection.Assembly.LoadFrom(l));
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException(e.Message);
                }
                #endregion

                #region create the implementation stepper using the factory method
                string implStepperMethodName;
                string implStepperClassName;
                ReflectionHelper.SplitFullMethodName(settings.iut, out implStepperClassName, out implStepperMethodName);
                Type       implStepperType   = ReflectionHelper.FindType(libs, implStepperClassName);
                MethodInfo implStepperMethod = ReflectionHelper.FindMethod(implStepperType, implStepperMethodName, Type.EmptyTypes, typeof(IStepper));
                IStepper   implStepper       = null;
                try
                {
                    implStepper = (IStepper)implStepperMethod.Invoke(null, null);
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException("Invocation of '" + settings.iut + "' failed: " + e.ToString());
                }
                #endregion

                #region create a model program for each model using the factory method and compose into product
                string       mpMethodName;
                string       mpClassName;
                ModelProgram mp = null;
                if (settings.model != null && settings.model.Length > 0)
                {
                    ReflectionHelper.SplitFullMethodName(settings.model[0], out mpClassName, out mpMethodName);
                    Type       mpType   = ReflectionHelper.FindType(libs, mpClassName);
                    MethodInfo mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                    try
                    {
                        mp = (ModelProgram)mpMethod.Invoke(null, null);
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Invocation of '" + settings.model[0] + "' failed: " + e.ToString());
                    }
                    for (int i = 1; i < settings.model.Length; i++)
                    {
                        ReflectionHelper.SplitFullMethodName(settings.model[i], out mpClassName, out mpMethodName);
                        mpType   = ReflectionHelper.FindType(libs, mpClassName);
                        mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                        ModelProgram mp2 = null;
                        try
                        {
                            mp2 = (ModelProgram)mpMethod.Invoke(null, null);
                        }
                        catch (Exception e)
                        {
                            throw new ModelProgramUserException("Invocation of '" + settings.model[i] + "' failed: " + e.ToString());
                        }
                        mp = new ProductModelProgram(mp, mp2);
                    }
                }
                #endregion

                #region load the test cases if any
                Sequence <Sequence <CompoundTerm> > testcases = Sequence <Sequence <CompoundTerm> > .EmptySequence;
                if (!String.IsNullOrEmpty(settings.testSuite))
                {
                    try
                    {
                        System.IO.StreamReader testSuiteReader =
                            new System.IO.StreamReader(settings.testSuite);
                        string testSuiteAsString = testSuiteReader.ReadToEnd();
                        testSuiteReader.Close();
                        CompoundTerm testSuite = (CompoundTerm)Term.Parse(testSuiteAsString);
                        foreach (CompoundTerm testCaseTerm in testSuite.Arguments)
                        {
                            Sequence <CompoundTerm> testCase =
                                testCaseTerm.Arguments.Convert <CompoundTerm>(delegate(Term t) { return((CompoundTerm)t); });
                            testcases = testcases.AddLast(testCase);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create test suite: " + e.Message);
                    }
                }
                #endregion

                #region load the fsms if any
                Dictionary <string, FSM> fsms = new Dictionary <string, FSM>();
                if (settings.fsm != null && settings.fsm.Length > 0)
                {
                    try
                    {
                        foreach (string fsmFile in settings.fsm)
                        {
                            System.IO.StreamReader fsmReader = new System.IO.StreamReader(fsmFile);
                            string fsmAsString = fsmReader.ReadToEnd();
                            fsmReader.Close();
                            fsms[fsmFile] = FSM.FromTerm(CompoundTerm.Parse(fsmAsString));
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create fsm: " + e.Message);
                    }
                }
                #endregion

                if (mp == null && testcases.IsEmpty && fsms.Count == 0)
                {
                    throw new ModelProgramUserException("No model, fsm, or test suite was given.");
                }

                if (fsms.Count > 0)
                {
                    foreach (string fsmName in fsms.Keys)
                    {
                        ModelProgram fsmmp = new FsmModelProgram(fsms[fsmName], fsmName);
                        if (mp == null)
                        {
                            mp = fsmmp;
                        }
                        else
                        {
                            mp = new ProductModelProgram(mp, fsmmp);
                        }
                    }
                }

                #region create the model stepper
                IStrategy ms;

                if (!testcases.IsEmpty)
                {
                    ms = new TestSuiteStepper(settings.startTestAction, testcases, mp);
                }
                else
                {
                    ms = CreateModelStepper(libs, mp, settings.modelStepper, settings.coverage);
                }

                #endregion

                confTester = new ConformanceTester(ms, implStepper);

                #region configure conformance tester settings

                confTester.ContinueOnFailure = settings.continueOnFailure;
                confTester.StepsCnt          = (testcases.IsEmpty ? settings.steps : 0);
                confTester.MaxStepsCnt       = (testcases.IsEmpty ? settings.maxSteps : 0);
                confTester.RunsCnt           = (testcases.IsEmpty ? settings.runs : testcases.Count);
                confTester.WaitAction        = settings.waitAction;
                confTester.TimeoutAction     = settings.timeoutAction;

                Symbol waitActionSymbol    = confTester.waitActionSet.Choose();
                Symbol timeoutActionSymbol = confTester.timeoutAction.FunctionSymbol1;

                Set <Symbol> obs = new Set <string>(settings.observableAction).Convert <Symbol>(delegate(string s) { return(Symbol.Parse(s)); });
                confTester.ObservableActionSymbols = obs;

                Set <Symbol> cleanup = new Set <string>(settings.cleanupAction).Convert <Symbol>(delegate(string s) { return(Symbol.Parse(s)); });
                confTester.CleanupActionSymbols = cleanup;

                if (confTester.IsAsync)
                {
                    //remove the wait and timeout action symbol from tester action symbols
                    if (confTester.testerActionSymbols.Contains(waitActionSymbol) ||
                        confTester.testerActionSymbols.Contains(timeoutActionSymbol))
                    {
                        confTester.testerActionSymbols =
                            confTester.testerActionSymbols.Remove(waitActionSymbol).Remove(timeoutActionSymbol);
                    }
                }

                Set <Symbol> internals = new Set <string>(settings.internalAction).Convert <Symbol>(delegate(string s) { return(Symbol.Parse(s)); });

                confTester.InternalActionSymbols =
                    (testcases.IsEmpty || settings.startTestAction != "Test" ?
                     internals :
                     internals.Add(Symbol.Parse("Test")));

                TimeSpan timeout = new TimeSpan(0, 0, 0, 0, settings.timeout);
                confTester.TesterActionTimeout = delegate(IState s, CompoundTerm a) { return(timeout); };
                confTester.Logfile             = settings.logfile;
                confTester.OverwriteLog        = settings.overwriteLog;
                if (settings.randomSeed != 0)
                {
                    confTester.RandomSeed = settings.randomSeed;
                }
                #endregion

                //finally, run the application
                confTester.Run();
            }
            catch (ModelProgramUserException)
            {
                throw;
            }
            catch (ConformanceTesterException e)
            {
                throw new ModelProgramUserException(e.Message);
            }
            finally
            {
                if (confTester != null)
                {
                    confTester.Dispose();
                }
            }
        }
Esempio n. 3
0
        public static void RunWithCommandLineArguments(string[] args)
        {
            //System.Diagnostics.Debugger.Break();
            ConformanceTester confTester = null;

            try
            {
                ConfTesterCommandLineSettings settings = new ConfTesterCommandLineSettings();
                if (!Parser.ParseArgumentsWithUsage(args, settings))
                {
                    //Console.ReadLine();
                    return;
                }

                #region load the libraries
                List <Assembly> libs = new List <Assembly>();
                try
                {
                    if (settings.reference != null)
                    {
                        foreach (string l in settings.reference)
                        {
                            libs.Add(System.Reflection.Assembly.LoadFrom(l));
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException(e.Message);
                }
                #endregion

                #region create the implementation stepper using the factory method
                string implStepperMethodName;
                string implStepperClassName;
                ReflectionHelper.SplitFullMethodName(settings.iut, out implStepperClassName, out implStepperMethodName);
                Type       implStepperType   = ReflectionHelper.FindType(libs, implStepperClassName);
                MethodInfo implStepperMethod = ReflectionHelper.FindMethod(implStepperType, implStepperMethodName, Type.EmptyTypes, typeof(IStepper));
                IStepper   implStepper       = null;
                try
                {
                    implStepper = (IStepper)implStepperMethod.Invoke(null, null);
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException("Invocation of '" + settings.iut + "' failed: " + e.ToString());
                }
                #endregion

                #region create a model program for each model using the factory method and compose into product
                string       mpMethodName;
                string       mpClassName;
                ModelProgram mp = null;
                if (settings.model != null && settings.model.Length > 0)
                {
                    ReflectionHelper.SplitFullMethodName(settings.model[0], out mpClassName, out mpMethodName);
                    Type       mpType   = ReflectionHelper.FindType(libs, mpClassName);
                    MethodInfo mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                    try
                    {
                        mp = (ModelProgram)mpMethod.Invoke(null, null);
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Invocation of '" + settings.model[0] + "' failed: " + e.ToString());
                    }
                    for (int i = 1; i < settings.model.Length; i++)
                    {
                        ReflectionHelper.SplitFullMethodName(settings.model[i], out mpClassName, out mpMethodName);
                        mpType   = ReflectionHelper.FindType(libs, mpClassName);
                        mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                        ModelProgram mp2 = null;
                        try
                        {
                            mp2 = (ModelProgram)mpMethod.Invoke(null, null);
                        }
                        catch (Exception e)
                        {
                            throw new ModelProgramUserException("Invocation of '" + settings.model[i] + "' failed: " + e.ToString());
                        }
                        mp = new ProductModelProgram(mp, mp2);
                    }
                }
                #endregion

                #region create a model program from given namespace and feature names
                if (settings.mp != null && settings.mp.Length > 0)
                {
                    if (libs.Count == 0)
                    {
                        throw new ModelProgramUserException("No reference was provided to load models from.");
                    }
                    //parse the model program name and the feature names for each entry
                    foreach (string mps in settings.mp)
                    {
                        //the first element is the model program, the remaining ones are
                        //feature names
                        string[] mpsSplit = mps.Split(new string[] { "[", "]", "," },
                                                      StringSplitOptions.RemoveEmptyEntries);
                        if (mpsSplit.Length == 0)
                        {
                            throw new ModelProgramUserException("Invalid model program specifier '" + mps + "'.");
                        }
                        string       mpName     = mpsSplit[0];
                        Assembly     mpAssembly = ReflectionHelper.FindAssembly(libs, mpName);
                        Set <string> mpFeatures = new Set <string>(mpsSplit).Remove(mpName);
                        ModelProgram mp1        = new LibraryModelProgram(mpAssembly, mpName, mpFeatures);
                        mp = (mp == null ? mp1 : new ProductModelProgram(mp, mp1));
                    }
                }

                #endregion

                #region load the test cases if any
                Sequence <Sequence <CompoundTerm> > testcases = Sequence <Sequence <CompoundTerm> > .EmptySequence;
                if (!String.IsNullOrEmpty(settings.testSuite))
                {
                    try
                    {
                        System.IO.StreamReader testSuiteReader =
                            new System.IO.StreamReader(settings.testSuite);
                        string testSuiteAsString = testSuiteReader.ReadToEnd();
                        testSuiteReader.Close();
                        CompoundTerm testSuite = (CompoundTerm)Term.Parse(testSuiteAsString);
                        foreach (CompoundTerm testCaseTerm in testSuite.Arguments)
                        {
                            Sequence <CompoundTerm> testCase =
                                testCaseTerm.Arguments.Convert <CompoundTerm>(delegate(Term t) { return((CompoundTerm)t); });
                            testcases = testcases.AddLast(testCase);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create test suite: " + e.Message);
                    }
                }
                #endregion

                #region load the fsms if any
                Dictionary <string, FSM> fsms = new Dictionary <string, FSM>();
                if (settings.fsm != null && settings.fsm.Length > 0)
                {
                    try
                    {
                        foreach (string fsmFile in settings.fsm)
                        {
                            System.IO.StreamReader fsmReader = new System.IO.StreamReader(fsmFile);
                            string fsmAsString = fsmReader.ReadToEnd();
                            fsmReader.Close();
                            fsms[fsmFile] = FSM.FromTerm(CompoundTerm.Parse(fsmAsString));
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create fsm: " + e.Message);
                    }
                }
                #endregion


                // Requirements metrics

                #region load all the requirements from an external file - if any
                if (!String.IsNullOrEmpty(settings.RequirementsFile))
                {
                    try
                    {
                        System.IO.StreamReader reqsReader =
                            new System.IO.StreamReader(settings.RequirementsFile);
                        string   line;
                        char[]   splitchars = { '|' };
                        string[] splitedLine;
                        while ((line = reqsReader.ReadLine()) != null)
                        {
                            if (line.Length > 5)
                            {
                                splitedLine = line.Split(splitchars);
                                // The format of a requirement line is:
                                // action (ignore by the parser) | id | description
                                AllRequirements.Add(new KeyValuePair <string, string>(splitedLine[1].Trim().ToLower(), splitedLine[2].Trim().ToLower()));
                            }
                        }
                        reqsReader.Close();
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create all-requirements list: " + e.Message);
                    }
                }
                #endregion


                if (mp == null && testcases.IsEmpty && fsms.Count == 0)
                {
                    throw new ModelProgramUserException("No model, fsm, or test suite was given.");
                }

                if (fsms.Count > 0)
                {
                    foreach (string fsmName in fsms.Keys)
                    {
                        ModelProgram fsmmp = new FsmModelProgram(fsms[fsmName], fsmName);
                        if (mp == null)
                        {
                            mp = fsmmp;
                        }
                        else
                        {
                            mp = new ProductModelProgram(mp, fsmmp);
                        }
                    }
                }

                #region create the model stepper
                IStrategy    ms;
                Set <Symbol> obs = new Set <string>(settings.observableAction).Convert <Symbol>(delegate(string s) { return(Symbol.Parse(s)); });
                if (!testcases.IsEmpty)
                {
                    ms = new TestSuiteStepper(settings.startTestAction, testcases, mp);
                }
                else
                {
                    ms = CreateModelStepper(libs, mp, settings.modelStepper, settings.coverage, obs);
                }

                #endregion

                confTester = new ConformanceTester(ms, implStepper);

                #region configure conformance tester settings

                confTester.ContinueOnFailure = settings.continueOnFailure;
                confTester.StepsCnt          = (testcases.IsEmpty ? settings.steps : 0);
                confTester.MaxStepsCnt       = (testcases.IsEmpty ? settings.maxSteps : 0);
                confTester.RunsCnt           = (testcases.IsEmpty ? settings.runs : testcases.Count);
                confTester.WaitAction        = settings.waitAction;
                confTester.TimeoutAction     = settings.timeoutAction;
                confTester.ShowTestCaseCoveredRequirements = settings.showTestCaseCoveredRequirements;
                confTester.showMetrics = settings.showMetrics;

                Symbol waitActionSymbol    = confTester.waitActionSet.Choose();
                Symbol timeoutActionSymbol = confTester.timeoutAction.Symbol;


                confTester.ObservableActionSymbols = obs;

                Set <Symbol> cleanup = new Set <string>(settings.cleanupAction).Convert <Symbol>(delegate(string s) { return(Symbol.Parse(s)); });
                confTester.CleanupActionSymbols = cleanup;

                if (confTester.IsAsync)
                {
                    //remove the wait and timeout action symbol from tester action symbols
                    if (confTester.testerActionSymbols.Contains(waitActionSymbol) ||
                        confTester.testerActionSymbols.Contains(timeoutActionSymbol))
                    {
                        confTester.testerActionSymbols =
                            confTester.testerActionSymbols.Remove(waitActionSymbol).Remove(timeoutActionSymbol);
                    }
                }

                Set <Symbol> internals = new Set <string>(settings.internalAction).Convert <Symbol>(delegate(string s) { return(Symbol.Parse(s)); });

                confTester.InternalActionSymbols =
                    (testcases.IsEmpty || settings.startTestAction != "Test" ?
                     internals :
                     internals.Add(Symbol.Parse("Test")));

                TimeSpan timeout = new TimeSpan(0, 0, 0, 0, settings.timeout);
                confTester.TesterActionTimeout = delegate(IState s, CompoundTerm a) { return(timeout); };
                confTester.Logfile             = settings.logfile;
                confTester.OverwriteLog        = settings.overwriteLog;
                if (settings.randomSeed != 0)
                {
                    confTester.RandomSeed = settings.randomSeed;
                }
                #endregion

                //finally, run the application
                confTester.Run();
            }
            catch (ModelProgramUserException)
            {
                throw;
            }
            catch (ConformanceTesterException e)
            {
                throw new ModelProgramUserException(e.Message);
            }
            finally
            {
                if (confTester != null)
                {
                    confTester.Dispose();
                }
            }
        }
        public static void RunWithCommandLineArguments(string[] args)
        {
            //System.Diagnostics.Debugger.Break();
            ConformanceTester confTester = null;
            try
            {

                ConfTesterCommandLineSettings settings = new ConfTesterCommandLineSettings();
                if (!Parser.ParseArgumentsWithUsage(args, settings))
                {
                    //Console.ReadLine();
                    return;
                }

                #region load the libraries
                List<Assembly> libs = new List<Assembly>();
                try
                {
                    if (settings.reference != null)
                    {
                        foreach (string l in settings.reference)
                        {
                            libs.Add(System.Reflection.Assembly.LoadFrom(l));
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException(e.Message);
                }
                #endregion

                #region create the implementation stepper using the factory method
                string implStepperMethodName;
                string implStepperClassName;
                ReflectionHelper.SplitFullMethodName(settings.iut, out implStepperClassName, out implStepperMethodName);
                Type implStepperType = ReflectionHelper.FindType(libs, implStepperClassName);
                MethodInfo implStepperMethod = ReflectionHelper.FindMethod(implStepperType, implStepperMethodName, Type.EmptyTypes, typeof(IStepper));
                IStepper implStepper = null;
                try
                {
                    implStepper = (IStepper)implStepperMethod.Invoke(null, null);
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException("Invocation of '" + settings.iut + "' failed: " + e.ToString());
                }
                #endregion

                #region create a model program for each model using the factory method and compose into product
                string mpMethodName;
                string mpClassName;
                ModelProgram mp = null;
                if (settings.model != null && settings.model.Length > 0)
                {
                    ReflectionHelper.SplitFullMethodName(settings.model[0], out mpClassName, out mpMethodName);
                    Type mpType = ReflectionHelper.FindType(libs, mpClassName);
                    MethodInfo mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                    try
                    {
                        mp = (ModelProgram)mpMethod.Invoke(null, null);
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Invocation of '" + settings.model[0] + "' failed: " + e.ToString());
                    }
                    for (int i = 1; i < settings.model.Length; i++)
                    {
                        ReflectionHelper.SplitFullMethodName(settings.model[i], out mpClassName, out mpMethodName);
                        mpType = ReflectionHelper.FindType(libs, mpClassName);
                        mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                        ModelProgram mp2 = null;
                        try
                        {
                            mp2 = (ModelProgram)mpMethod.Invoke(null, null);
                        }
                        catch (Exception e)
                        {
                            throw new ModelProgramUserException("Invocation of '" + settings.model[i] + "' failed: " + e.ToString());
                        }
                        mp = new ProductModelProgram(mp, mp2);
                    }
                }
                #endregion

                #region create a model program from given namespace and feature names
                if (settings.mp != null && settings.mp.Length > 0)
                {
                    if (libs.Count == 0)
                    {
                        throw new ModelProgramUserException("No reference was provided to load models from.");
                    }
                    //parse the model program name and the feature names for each entry
                    foreach (string mps in settings.mp)
                    {
                        //the first element is the model program, the remaining ones are
                        //feature names
                        string[] mpsSplit = mps.Split(new string[] { "[", "]", "," },
                            StringSplitOptions.RemoveEmptyEntries);
                        if (mpsSplit.Length == 0)
                        {
                            throw new ModelProgramUserException("Invalid model program specifier '" + mps + "'.");
                        }
                        string mpName = mpsSplit[0];
                        Assembly mpAssembly = ReflectionHelper.FindAssembly(libs, mpName);
                        Set<string> mpFeatures = new Set<string>(mpsSplit).Remove(mpName);
                        ModelProgram mp1 = new LibraryModelProgram(mpAssembly, mpName, mpFeatures);
                        mp = (mp == null ? mp1 : new ProductModelProgram(mp, mp1));
                    }
                }

                #endregion

                #region load the test cases if any
                Sequence<Sequence<CompoundTerm>> testcases = Sequence<Sequence<CompoundTerm>>.EmptySequence;
                if (!String.IsNullOrEmpty(settings.testSuite))
                {
                    try
                    {
                        System.IO.StreamReader testSuiteReader =
                            new System.IO.StreamReader(settings.testSuite);
                        string testSuiteAsString = testSuiteReader.ReadToEnd();
                        testSuiteReader.Close();
                        CompoundTerm testSuite = (CompoundTerm)Term.Parse(testSuiteAsString);
                        foreach (CompoundTerm testCaseTerm in testSuite.Arguments)
                        {
                            Sequence<CompoundTerm> testCase =
                                testCaseTerm.Arguments.Convert<CompoundTerm>(delegate(Term t) { return (CompoundTerm)t; });
                            testcases = testcases.AddLast(testCase);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create test suite: " + e.Message);
                    }
                }
                #endregion

                #region load the fsms if any
                Dictionary<string, FSM> fsms = new Dictionary<string, FSM>();
                if (settings.fsm != null && settings.fsm.Length > 0)
                {
                    try
                    {
                        foreach (string fsmFile in settings.fsm)
                        {
                            System.IO.StreamReader fsmReader = new System.IO.StreamReader(fsmFile);
                            string fsmAsString = fsmReader.ReadToEnd();
                            fsmReader.Close();
                            fsms[fsmFile] = FSM.FromTerm(CompoundTerm.Parse(fsmAsString));
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create fsm: " + e.Message);
                    }
                }
                #endregion

                // Requirements metrics

                #region load all the requirements from an external file - if any
                if (!String.IsNullOrEmpty(settings.RequirementsFile))
                {
                    try
                    {
                        System.IO.StreamReader reqsReader =
                            new System.IO.StreamReader(settings.RequirementsFile);
                        string line;
                        char[] splitchars = { '|' };
                        string[] splitedLine;
                        while ((line = reqsReader.ReadLine()) != null)
                        {
                            if (line.Length > 5)
                            {
                                splitedLine = line.Split(splitchars);
                                // The format of a requirement line is:
                                // action (ignore by the parser) | id | description
                                AllRequirements.Add(new KeyValuePair<string, string>(splitedLine[1].Trim().ToLower(), splitedLine[2].Trim().ToLower()));
                            }
                        }
                        reqsReader.Close();
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create all-requirements list: " + e.Message);
                    }
                }
                #endregion

                if (mp == null && testcases.IsEmpty && fsms.Count == 0)
                {
                    throw new ModelProgramUserException("No model, fsm, or test suite was given.");
                }

                if (fsms.Count > 0)
                {
                    foreach (string fsmName in fsms.Keys)
                    {
                        ModelProgram fsmmp = new FsmModelProgram(fsms[fsmName], fsmName);
                        if (mp == null)
                            mp = fsmmp;
                        else
                            mp = new ProductModelProgram(mp, fsmmp);
                    }
                }

                #region create the model stepper
                IStrategy ms;
                Set<Symbol> obs = new Set<string>(settings.observableAction).Convert<Symbol>(delegate(string s) { return Symbol.Parse(s); });
                if (!testcases.IsEmpty)
                {
                    ms = new TestSuiteStepper(settings.startTestAction, testcases, mp);
                }
                else
                {
                    ms = CreateModelStepper(libs, mp, settings.modelStepper, settings.coverage, obs);
                }

                #endregion

                confTester = new ConformanceTester(ms, implStepper);

                #region configure conformance tester settings

                confTester.ContinueOnFailure = settings.continueOnFailure;
                confTester.StepsCnt = (testcases.IsEmpty ? settings.steps : 0);
                confTester.MaxStepsCnt = (testcases.IsEmpty ? settings.maxSteps : 0);
                confTester.RunsCnt = (testcases.IsEmpty ? settings.runs : testcases.Count);
                confTester.WaitAction = settings.waitAction;
                confTester.TimeoutAction = settings.timeoutAction;
                confTester.ShowTestCaseCoveredRequirements = settings.showTestCaseCoveredRequirements;
                confTester.showMetrics = settings.showMetrics;

                Symbol waitActionSymbol = confTester.waitActionSet.Choose();
                Symbol timeoutActionSymbol = confTester.timeoutAction.Symbol;

                confTester.ObservableActionSymbols = obs;

                Set<Symbol> cleanup = new Set<string>(settings.cleanupAction).Convert<Symbol>(delegate(string s) { return Symbol.Parse(s); });
                confTester.CleanupActionSymbols = cleanup;

                if (confTester.IsAsync)
                {
                    //remove the wait and timeout action symbol from tester action symbols
                    if (confTester.testerActionSymbols.Contains(waitActionSymbol) ||
                        confTester.testerActionSymbols.Contains(timeoutActionSymbol))
                        confTester.testerActionSymbols =
                            confTester.testerActionSymbols.Remove(waitActionSymbol).Remove(timeoutActionSymbol);
                }

                Set<Symbol> internals = new Set<string>(settings.internalAction).Convert<Symbol>(delegate(string s) { return Symbol.Parse(s); });

                confTester.InternalActionSymbols =
                    (testcases.IsEmpty || settings.startTestAction != "Test" ?
                     internals :
                     internals.Add(Symbol.Parse("Test")));

                TimeSpan timeout = new TimeSpan(0, 0, 0, 0, settings.timeout);
                confTester.TesterActionTimeout = delegate(IState s, CompoundTerm a) { return timeout; };
                confTester.Logfile = settings.logfile;
                confTester.OverwriteLog = settings.overwriteLog;
                if (settings.randomSeed != 0)
                {
                    confTester.RandomSeed = settings.randomSeed;
                }
                #endregion

                //finally, run the application
                confTester.Run();
            }
            catch (ModelProgramUserException)
            {
                throw;
            }
            catch (ConformanceTesterException e)
            {
                throw new ModelProgramUserException(e.Message);
            }
            finally
            {
                if (confTester != null)
                    confTester.Dispose();
            }
        }
        public static void RunWithCommandLineArguments(string[] args)
        {
            //System.Diagnostics.Debugger.Break();
            ConformanceTester confTester = null;
            try
            {

                ConfTesterCommandLineSettings settings = new ConfTesterCommandLineSettings();
                if (!Parser.ParseArgumentsWithUsage(args, settings))
                {
                    //Console.ReadLine();
                    return;
                }

                #region load the libraries
                List<Assembly> libs = new List<Assembly>();
                try
                {
                    if (settings.reference != null)
                    {
                        foreach (string l in settings.reference)
                        {
                            libs.Add(System.Reflection.Assembly.LoadFrom(l));
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException(e.Message);
                }
                #endregion

                #region create the implementation stepper using the factory method
                string implStepperMethodName;
                string implStepperClassName;
                ReflectionHelper.SplitFullMethodName(settings.iut, out implStepperClassName, out implStepperMethodName);
                Type implStepperType = ReflectionHelper.FindType(libs, implStepperClassName);
                MethodInfo implStepperMethod = ReflectionHelper.FindMethod(implStepperType, implStepperMethodName, Type.EmptyTypes, typeof(IStepper));
                IStepper implStepper = null;
                try
                {
                    implStepper = (IStepper)implStepperMethod.Invoke(null, null);
                }
                catch (Exception e)
                {
                    throw new ModelProgramUserException("Invocation of '" + settings.iut + "' failed: " + e.ToString());
                }
                #endregion

                #region create a model program for each model using the factory method and compose into product
                string mpMethodName;
                string mpClassName;
                ModelProgram mp = null;
                if (settings.model != null && settings.model.Length > 0)
                {
                    ReflectionHelper.SplitFullMethodName(settings.model[0], out mpClassName, out mpMethodName);
                    Type mpType = ReflectionHelper.FindType(libs, mpClassName);
                    MethodInfo mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                    try
                    {
                        mp = (ModelProgram)mpMethod.Invoke(null, null);
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Invocation of '" + settings.model[0] + "' failed: " + e.ToString());
                    }
                    for (int i = 1; i < settings.model.Length; i++)
                    {
                        ReflectionHelper.SplitFullMethodName(settings.model[i], out mpClassName, out mpMethodName);
                        mpType = ReflectionHelper.FindType(libs, mpClassName);
                        mpMethod = ReflectionHelper.FindMethod(mpType, mpMethodName, Type.EmptyTypes, typeof(ModelProgram));
                        ModelProgram mp2 = null;
                        try
                        {
                            mp2 = (ModelProgram)mpMethod.Invoke(null, null);
                        }
                        catch (Exception e)
                        {
                            throw new ModelProgramUserException("Invocation of '" + settings.model[i] + "' failed: " + e.ToString());
                        }
                        mp = new ProductModelProgram(mp, mp2);
                    }
                }
                #endregion

                #region load the test cases if any
                Sequence<Sequence<CompoundTerm>> testcases = Sequence<Sequence<CompoundTerm>>.EmptySequence;
                if (!String.IsNullOrEmpty(settings.testSuite))
                {
                    try
                    {
                        System.IO.StreamReader testSuiteReader =
                            new System.IO.StreamReader(settings.testSuite);
                        string testSuiteAsString = testSuiteReader.ReadToEnd();
                        testSuiteReader.Close();
                        CompoundTerm testSuite = (CompoundTerm)Term.Parse(testSuiteAsString);
                        foreach (CompoundTerm testCaseTerm in testSuite.Arguments)
                        {
                            Sequence<CompoundTerm> testCase =
                                testCaseTerm.Arguments.Convert<CompoundTerm>(delegate(Term t) { return (CompoundTerm)t; });
                            testcases = testcases.AddLast(testCase);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create test suite: " + e.Message);
                    }
                }
                #endregion

                #region load the fsms if any
                Dictionary<string, FSM> fsms = new Dictionary<string, FSM>();
                if (settings.fsm != null && settings.fsm.Length > 0)
                {
                    try
                    {
                        foreach (string fsmFile in settings.fsm)
                        {
                            System.IO.StreamReader fsmReader = new System.IO.StreamReader(fsmFile);
                            string fsmAsString = fsmReader.ReadToEnd();
                            fsmReader.Close();
                            fsms[fsmFile] = FSM.FromTerm(CompoundTerm.Parse(fsmAsString));
                        }
                    }
                    catch (Exception e)
                    {
                        throw new ModelProgramUserException("Cannot create fsm: " + e.Message);
                    }
                }
                #endregion

                if (mp == null && testcases.IsEmpty && fsms.Count == 0)
                {
                    throw new ModelProgramUserException("No model, fsm, or test suite was given.");
                }

                if (fsms.Count > 0)
                {
                    foreach (string fsmName in fsms.Keys)
                    {
                        ModelProgram fsmmp = new FsmModelProgram(fsms[fsmName], fsmName);
                        if (mp == null)
                            mp = fsmmp;
                        else
                            mp = new ProductModelProgram(mp, fsmmp);
                    }
                }

                #region create the model stepper
                IStrategy ms;

                if (!testcases.IsEmpty)
                {
                    ms = new TestSuiteStepper(settings.startTestAction, testcases, mp);
                }
                else
                {
                    ms = CreateModelStepper(libs, mp, settings.modelStepper, settings.coverage);
                }

                #endregion

                confTester = new ConformanceTester(ms, implStepper);

                #region configure conformance tester settings

                confTester.ContinueOnFailure = settings.continueOnFailure;
                confTester.StepsCnt = (testcases.IsEmpty ? settings.steps : 0);
                confTester.MaxStepsCnt = (testcases.IsEmpty ? settings.maxSteps : 0);
                confTester.RunsCnt = (testcases.IsEmpty ? settings.runs : testcases.Count);
                confTester.WaitAction = settings.waitAction;
                confTester.TimeoutAction = settings.timeoutAction;

                Symbol waitActionSymbol = confTester.waitActionSet.Choose();
                Symbol timeoutActionSymbol = confTester.timeoutAction.FunctionSymbol1;

                Set<Symbol> obs = new Set<string>(settings.observableAction).Convert<Symbol>(delegate(string s) { return Symbol.Parse(s); });
                confTester.ObservableActionSymbols = obs;

                Set<Symbol> cleanup = new Set<string>(settings.cleanupAction).Convert<Symbol>(delegate(string s) { return Symbol.Parse(s); });
                confTester.CleanupActionSymbols = cleanup;

                if (confTester.IsAsync)
                {
                    //remove the wait and timeout action symbol from tester action symbols
                    if (confTester.testerActionSymbols.Contains(waitActionSymbol) ||
                        confTester.testerActionSymbols.Contains(timeoutActionSymbol))
                        confTester.testerActionSymbols =
                            confTester.testerActionSymbols.Remove(waitActionSymbol).Remove(timeoutActionSymbol);
                }

                Set<Symbol> internals = new Set<string>(settings.internalAction).Convert<Symbol>(delegate(string s) { return Symbol.Parse(s); });

                confTester.InternalActionSymbols =
                    (testcases.IsEmpty || settings.startTestAction != "Test" ?
                     internals :
                     internals.Add(Symbol.Parse("Test")));

                TimeSpan timeout = new TimeSpan(0, 0, 0, 0, settings.timeout);
                confTester.TesterActionTimeout = delegate(IState s, CompoundTerm a) { return timeout; };
                confTester.Logfile = settings.logfile;
                confTester.OverwriteLog = settings.overwriteLog;
                if (settings.randomSeed != 0)
                {
                    confTester.RandomSeed = settings.randomSeed;
                }
                #endregion

                //finally, run the application
                confTester.Run();
            }
            catch (ModelProgramUserException)
            {
                throw;
            }
            catch (ConformanceTesterException e)
            {
                throw new ModelProgramUserException(e.Message);
            }
            finally
            {
                if (confTester != null)
                    confTester.Dispose();
            }
        }