Пример #1
0
        /// <summary>
        /// Initalize this class with a record with recommended values for a BaseRecord
        /// </summary>
        /// <param name="record"></param>
        internal ResultPrimarySecondary(BaseRecord record)
        {
            //Short-circut some values
            Conclusion = record.Conclusion;
            string description = string.IsNullOrWhiteSpace(record.Description) ? string.Empty : record.Description;

            switch (Conclusion)
            {
            //The primary result for these conclusion is always our pre-set value and (if available) the description from the script as secondary
            case ConclusionEnum.Success:
            case ConclusionEnum.DoesNotApply:
            case ConclusionEnum.Fatal:

                //Set Primary to a descriptive text, e.g. Conclusiong==Success -> "OK (Success)"
                Primary = ConclusionEnumConverter.ConclusionHumanized(Conclusion);

                if (record is AssetRecord)
                {
                    //For an asset that returned SUCCESS, the VALUE the asset has retrieved is the interessting part, hence change primary to the value
                    if (Conclusion == ConclusionEnum.Success)
                    {
                        Primary = (record as AssetRecord).Data;
                    }

                    //Assign to secondary either the default conclusion description or the one from the script
                    Secondary = string.IsNullOrWhiteSpace(description) ? ConclusionEnumConverter.AssetRecordConclusionDescription(Conclusion) : description;
                }
                else
                {
                    Secondary = string.IsNullOrWhiteSpace(description) ? ConclusionEnumConverter.TestRecordConclusionDescription(Conclusion) : description;
                }

                break;


            //For these conclusions, the text will be promoted to be Primary, and our internal description for the conclusion is secondary.
            //The exception for this rule is if we have text, then the value from the script will be used
            case ConclusionEnum.Inconclusive:
            case ConclusionEnum.Major:
            case ConclusionEnum.Minor:
                if (record is AssetRecord)
                {
                    Primary   = string.IsNullOrEmpty(description) ? ConclusionEnumConverter.ConclusionHumanized(Conclusion) : description;
                    Secondary = ConclusionEnumConverter.AssetRecordConclusionDescription(Conclusion);
                }
                else
                {
                    Primary   = string.IsNullOrEmpty(description) ? ConclusionEnumConverter.ConclusionHumanized(Conclusion) : description;
                    Secondary = ConclusionEnumConverter.TestRecordConclusionDescription(Conclusion);
                }
                break;


            default:
                throw new ArgumentOutOfRangeException(string.Format("Found unknown ConclusionEnum: {0}", Conclusion.ToString()));
            }
        }
Пример #2
0
        public BaseRecord(BaseRecord copyFrom)
        {
            this.Name        = copyFrom.Name;
            this.Conclusion  = copyFrom.Conclusion;
            this.Description = copyFrom.Description;

            this.ScriptFilePath   = copyFrom.ScriptFilePath;
            this.ProcessMessages  = copyFrom.ProcessMessages;
            this.ScriptSuccessful = copyFrom.ScriptSuccessful;
        }
Пример #3
0
        void ProcessHashtableOutputInternal(BaseRecord record, Hashtable table)
        {
            //We need a a key "Data" or this is considered to be fatal. The value of this key can still be NULL.
            if (table.ContainsKey(Xteq5EngineConstant.ReturnedHashtableKeyData) == false)
            {
                record.Conclusion = ConclusionEnum.Fatal;
                record.AddLineToProcessMessages("Data key missing from returned hashtable");

                ProcessFailure(record);
            }
            else
            {
                string name = GetStringFromHashtable(table, Xteq5EngineConstant.ReturnedHashtableKeyName);
                if (string.IsNullOrEmpty(name) == false)
                {
                    record.Name = name;
                }

                string text = GetStringFromHashtable(table, Xteq5EngineConstant.ReturnedHashtableKeyText);
                if (string.IsNullOrEmpty(text) == false)
                {
                    record.Description = text;
                }

                string data = GetStringFromHashtable(table, Xteq5EngineConstant.ReturnedHashtableKeyData);
                if (string.IsNullOrEmpty(data))
                {
                    //Empty data means DoesNotApply
                    record.Conclusion = ConclusionEnum.DoesNotApply;

                    ProcessEmptyData(record, table);
                }
                else
                {
                    //The data key contains something. First try if the result is maybe the string "n/a"
                    ConclusionEnum conclusion = ConclusionEnumConverter.ParseConclusion(data);
                    if (conclusion == ConclusionEnum.DoesNotApply)
                    {
                        //The script returned n/a (DoesNotApply), so it can be processed as an empty record
                        record.Conclusion = ConclusionEnum.DoesNotApply;
                        ProcessEmptyData(record, table);
                    }
                    else
                    {
                        //The result was something else. Let the implementation decide.
                        ProcessNonEmptyData(record, table, data);
                    }
                }
            }
        }
Пример #4
0
        protected override void ProcessNonEmptyData(BaseRecord record, Hashtable table, string dataKeyValue)
        {
            //The basic values are all set by :base() and it was also validated that the hashtable contains a key ".Data".
            TestRecord testRecord = new TestRecord(record);

            //Data is not NULL and not "", hence we need to check which conclusion the author wanted to report
            ConclusionEnum conclusion = ConclusionEnumConverter.ParseConclusion(dataKeyValue);

            if (conclusion == ConclusionEnum.Fatal)
            {
                //We were not able to parse the value inside .Data
                testRecord.AddLineToProcessMessages(string.Format("Unable to parse result {0}", dataKeyValue));
            }
            testRecord.Conclusion = conclusion;

            _results.Add(testRecord);
        }
Пример #5
0
        //This needs to be called by the implementation to start the replacement process
        protected void StartGenerating(Report report)
        {
            ReplaceHeaderValuesInternal(report);

            ReplaceAssetStatisticsInternal(report);
            ReplaceTestStatisticsInternal(report);

            ReplaceResultTextInternal();
            ReplaceAssetConclusionTextInternal();
            ReplaceTestConclusionTextInternal();

            ReplaceTestRecommendedActionTextInternal();

            //Begin details replacement for assets
            StringBuilder sbAssets = new StringBuilder();

            StartAssetDetails(sbAssets);
            foreach (AssetRecord asset in report.Assets)
            {
                BaseRecord             baseRec = asset as BaseRecord;
                ResultPrimarySecondary rps     = new ResultPrimarySecondary(baseRec);

                ProcessAsset(sbAssets, asset, baseRec, rps);
            }
            EndAssetDetails(sbAssets);

            ReplaceAssetList("AssetRows".ToUpper(), sbAssets.ToString());


            //Begin details replacment for tests
            StringBuilder sbTests = new StringBuilder();

            StartTestDetails(sbTests);
            foreach (TestRecord test in report.Tests)
            {
                BaseRecord             baseRec = test as BaseRecord;
                ResultPrimarySecondary rps     = new ResultPrimarySecondary(baseRec);

                ProcessTest(sbTests, test, baseRec, rps);
            }
            EndTestDetails(sbAssets);

            ReplaceTestList("TestRows".ToUpper(), sbTests.ToString());
        }
Пример #6
0
        /// <summary>
        /// Generates a JSON formated output report
        /// </summary>
        /// <param name="report">The report that should be transfered into JSON</param>
        /// <returns>A JSON formated string</returns>
        public override string Generate(Report report)
        {
            ReportClass rep = new ReportClass();

            rep.IssuesFound = new IssuesFoundClass();

            rep.ID                  = report.ID;
            rep.Compilation         = report.CompilationFolder;
            rep.EngineVersion       = report.EngineVersion;
            rep.EngineVersionString = report.EngineVersion.ToString();
            rep.Username            = report.UserName;
            rep.Computername        = report.ComputerName;
            rep.Text                = report.UserText;
            rep.StartDateTimeUTC    = report.StartedUTC;
            rep.EndDateTimeUTC      = report.EndedUTC;
            rep.RuntimeSeconds      = report.RuntimeSeconds;

            rep.IssuesFound.Any    = report.IssuesFound;
            rep.IssuesFound.Assets = report.AssetIssuesFound;
            rep.IssuesFound.Tests  = report.TestIssuesFound;

            rep.AssetStatistics = report.AssetStatiscs;
            rep.TestStatistics  = report.TestStatiscs;

            rep.Assets = new List <ItemDetail>();
            rep.Tests  = new List <ItemDetail>();

            //Loop over all assets
            foreach (AssetRecord asset in report.Assets)
            {
                BaseRecord baseRec = asset as BaseRecord;
                rep.Assets.Add(ConvertToItemDetail(baseRec));
            }

            //Loop over all tests
            foreach (TestRecord test in report.Tests)
            {
                BaseRecord baseRec = test as BaseRecord;
                rep.Tests.Add(ConvertToItemDetail(baseRec));
            }

            //MTH: I can't even imaging how much magic happens in this single call.
            return(JsonConvert.SerializeObject(rep));
        }
Пример #7
0
        string CreateRecordDetails(string tagName, BaseRecord record, ResultPrimarySecondary resultPrimSecond)
        {
            //Yes, this somewhat cheating....
            WeakHTMLTag tag = new WeakHTMLTag(tagName);

            WeakHTMLTag name = new WeakHTMLTag("Name");

            name.Text = record.Name;

            WeakHTMLTag filename = new WeakHTMLTag("Filename");

            filename.Text = record.ScriptFilename;

            WeakHTMLTag conclusion = new WeakHTMLTag("Conclusion");

            conclusion.Text = ((int)record.Conclusion).ToString();

            WeakHTMLTag conclusionString = new WeakHTMLTag("ConclusionString");

            conclusionString.Text = record.Conclusion.ToString();



            //Create sub tag "result"
            WeakHTMLTag primary = new WeakHTMLTag("Primary");

            primary.Text = resultPrimSecond.Primary;

            WeakHTMLTag secondary = new WeakHTMLTag("Secondary");

            secondary.Text = resultPrimSecond.Secondary;

            WeakHTMLTag result = new WeakHTMLTag("Result");

            result.HTML = primary.ToString() + secondary.ToString();


            //Construct the final XML
            tag.HTML = name.ToString() + filename.ToString() + conclusion.ToString() + conclusionString.ToString() + result.ToString();

            return(tag.ToString());
        }
Пример #8
0
        private ItemDetail ConvertToItemDetail(BaseRecord baseRec)
        {
            ItemDetail detail = new ItemDetail();

            detail.Name             = baseRec.Name;
            detail.Filename         = baseRec.ScriptFilename;
            detail.Conclusion       = baseRec.Conclusion;
            detail.ConclusionString = baseRec.Conclusion.ToString();

            ResultPrimarySecondary rps = new ResultPrimarySecondary(baseRec);

            ItemResult result = new ItemResult();

            result.Primary  = rps.Primary;
            result.Seconday = rps.Secondary;

            detail.Result = result;

            return(detail);
        }
Пример #9
0
        protected override void ProcessNonEmptyData(BaseRecord record, Hashtable table, string dataKeyValue)
        {
            AssetRecord assetRecord = new AssetRecord(record);

            //Data is set = Conclusion.Success
            assetRecord.Conclusion = ConclusionEnum.Success;
            assetRecord.Data       = dataKeyValue;

            //Check the object that was returned and copy it to .DataNative (if we support the type)
            object dataObjectFromHashtable = GetObjectFromHashtable(table, Xteq5EngineConstant.ReturnedHashtableKeyData);

            if (dataObjectFromHashtable is string)
            {
                //String is the default of .Data. Therefore no action is required
            }
            else
            {
                if (dataObjectFromHashtable is bool)
                {
                    assetRecord.DataNative = (Boolean)dataObjectFromHashtable;
                }
                else
                {
                    if (dataObjectFromHashtable is int)
                    {
                        assetRecord.DataNative = (int)dataObjectFromHashtable;
                    }

                    else
                    {
                        if (dataObjectFromHashtable is System.Version)
                        {
                            assetRecord.DataNative = dataObjectFromHashtable as System.Version;
                        }
                    }
                }
            }


            _results.Add(assetRecord);
        }
Пример #10
0
 //Called by this class for each test that exists. Imlementation must add the content to the given stringbuilder.
 protected abstract void ProcessTest(StringBuilder sbTests, TestRecord test, BaseRecord baseRec, ResultPrimarySecondary resultPrimSecond);
Пример #11
0
 //Called by this class for each asset that exists. Imlementation must add the content to the given stringbuilder.
 protected abstract void ProcessAsset(StringBuilder sbAssets, AssetRecord asset, BaseRecord baseRec, ResultPrimarySecondary resultPrimSecond);
Пример #12
0
 protected override void ProcessTest(StringBuilder sbTests, TestRecord test, BaseRecord baseRec, ResultPrimarySecondary resultPrimSecond)
 {
     sbTests.AppendLine(CreateTableRow(baseRec, resultPrimSecond));
 }
Пример #13
0
 protected override void ProcessAsset(StringBuilder sbAssets, AssetRecord asset, BaseRecord baseRec, ResultPrimarySecondary resultPrimSecond)
 {
     sbAssets.AppendLine(CreateTableRow(baseRec, resultPrimSecond));
 }
Пример #14
0
 internal TestRecord(BaseRecord baseRecord)
     : base(baseRecord)
 {
 }
Пример #15
0
 protected abstract void ProcessFailure(BaseRecord record);
Пример #16
0
 protected abstract void ProcessEmptyData(BaseRecord record, Hashtable table);
Пример #17
0
 internal AssetRecord(BaseRecord baseRecord)
     : base(baseRecord)
 {
     Data       = string.Empty;
     DataNative = null;
 }
Пример #18
0
        protected async Task RunInternalAsync(PSScriptRunner scriptRunner, string scriptDirectory, IProgress <RunnerProgressDetail> progress = null)
        {
            //Assign progress reporter and set it that it can be used after calling Report()
            _reporter = new ProgressReporter <RunnerProgressDetail>(progress, createNewInstanceAfterReport: true);

            //Report that we are about to start
            _reporter.Content.Action = RunnerAction.Starting;
            _reporter.Report();


            string[] allScripts = Directory.GetFiles(scriptDirectory, Xteq5EngineConstant.ScriptFilePattern);
            NaturalSort.Sort(allScripts);

            foreach (string scriptFilename in allScripts)
            {
                //Set the values we already have
                BaseRecord record = new BaseRecord();
                record.ScriptFilePath = scriptFilename;
                record.Name           = Path.GetFileNameWithoutExtension(scriptFilename);

                try
                {
                    //Report back status
                    ReportProgressScript(scriptFilename);

                    using (ExecutionResult execResult = await scriptRunner.RunScriptFileAsync(scriptFilename))
                    {
                        record.ProcessMessages = execResult.ToString();

                        if (execResult.Successful == false)
                        {
                            ProcessFailure(record);
                        }
                        else
                        {
                            //The script was run OK
                            record.ScriptSuccessful = true;


                            //Search the output
                            Hashtable table          = new Hashtable(); //new() is required or the compiler will complain about an unassigned local variable
                            bool      foundHashtable = false;

                            //Search the output collection for a hashtable
                            foreach (PSObject psobj in execResult.StreamOutput)
                            {
                                if (psobj.BaseObject != null && psobj.BaseObject is Hashtable)
                                {
                                    foundHashtable = true;
                                    table          = psobj.BaseObject as Hashtable;
                                    break;
                                }
                            }

                            if (foundHashtable == false)
                            {
                                //No hashtable was found within output stream. Add this to messages
                                record.AddLineToProcessMessages("No Hashtable was returned");

                                ProcessFailure(record);
                            }
                            else
                            {
                                ProcessHashtableOutputInternal(record, table);
                            }
                        }
                    }
                }
                catch (Exception exc)
                {
                    //That didn't go well
                    record.ProcessMessages = exc.ToString();

                    //Let the actual implementation decide what to do next
                    ProcessFailure(record);
                }


                //MTH: End of processing with this file. Next one please!
            }


            //Report status that this entire run has finished
            _reporter.Content.Action = RunnerAction.Ended;
            _reporter.Report();
        }
Пример #19
0
 protected abstract void ProcessNonEmptyData(BaseRecord record, Hashtable table, string dataKeyValue);