Beispiel #1
0
        public override void Parse(TestResultCollection collection)
        {
            XPathDocument  doc = new XPathDocument(this.InputStream);
            XPathNavigator nav = doc.CreateNavigator();

            // Move to document root node
            if ((nav.MoveToFirstChild()) && (nav.LocalName == Xml.TestResult))
            {
                ParseTestUnitsReport(nav, null, collection);
            }
        }
 /// <summary>
 /// Registers any-and-all console output messages with all tests within the collection
 /// </summary>
 /// <param name="output">The console output</param>
 /// <param name="collection">The test collection in which to place console log entries</param>
 private void RegisterMessages(string output, TestResultCollection collection)
 {
     if (!string.IsNullOrEmpty(output))
     {
         // Attach the console output to each TestCase result in the collection
         // since we cannot distinguish to which TestCase (in case multiple TestCases are registered)
         // the output is associated with.
         foreach (TestResult result in collection)
         {
             // Consider the whole console contents as 1 entry.
             result.LogEntries.Add(CreateLogEntry(output));
         }
     }
 }
 public override void Parse(TestResultCollection collection)
 {
     // serge: now log output for dependent test cases supported, the have additional XML
     // element, that corrupts XML document structure
     using (XmlTextReader xtr = new XmlTextReader(this.InputStream, XmlNodeType.Element, null))
     {
         while (xtr.Read())
         {
             if (xtr.NodeType == XmlNodeType.Element && xtr.Name == Xml.TestLog)
             {
                 XmlDocument doc         = new XmlDocument();
                 XmlElement  elemTestLog = doc.CreateElement(Xml.TestLog);
                 elemTestLog.InnerXml = xtr.ReadInnerXml();
                 ParseTestUnitsLog(elemTestLog.ChildNodes, new QualifiedNameBuilder(), collection);
                 break;
             }
         }
     }
 }
        /// <summary>
        /// Processes the standard output and populates the relevant test result data of the referenced collection
        /// </summary>
        /// <param name="collection">test result collection where the leak information data will be inserted at</param>
        public override void Parse(TestResultCollection collection)
        {
            // NOTE Disposing is handled by parent class
            string strConsoleOutput = new StreamReader(this.InputStream).ReadToEnd();

            //the below regex is intended to only to "detect" if any memory leaks are present. Note that any console output printed by the test generally appears before the memory leaks dump.
            Regex regexObj    = new Regex(@"Detected\smemory\sleaks!\nDumping objects\s->\n(.*)Object dump complete.", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline);
            Match outputMatch = regexObj.Match(strConsoleOutput);

            //leak has been detected
            if (outputMatch.Success)
            {
                RegisterMemoryLeak(outputMatch.Groups[1].Value, collection);
            }

            // Extract non-memory leak output
            string output = strConsoleOutput.Substring(0, ((outputMatch.Success) ? outputMatch.Index : strConsoleOutput.Length));

            RegisterMessages(output, collection);
        }
 public abstract void Parse(TestResultCollection collection);
        /// <summary>
        /// Registers the provided memory leak string representation within the test collection
        /// </summary>
        /// <param name="leakInformation">The full memory leak information</param>
        /// <param name="collection">The test collection in which to place memory leak entries</param>
        private void RegisterMemoryLeak(string leakInformation, TestResultCollection collection)
        {
            foreach (TestResult result in collection)
            {
                if (this.FailTestOnMemoryLeak)
                {
                    result.Result = TestResultType.Failed;
                }

                Regex regexLeakInformation = new Regex(@"(?:([\\:\w\rA-z.]*?)([\w\d.]*)\((\d{1,})\)\s:\s)?\{(\d{1,})\}[\w\s\d]*,\s(\d{1,})[\s\w.]*\n(.*?)(?=$|(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d)", RegexOptions.IgnoreCase | RegexOptions.Singleline);   //the old one wasRegex regexLeakInformation = new Regex(@"^(.*\\)(.*?)\((\d{1,})\).*?{(\d{1,})}.*?(\d{1,})\sbyte", RegexOptions.IgnoreCase | RegexOptions.Multiline);

                /*
                 *
                 * The same regex works for when the complete file path along with the line number are reported in the console output such as in the below sample output
                 *
                 * d:\hwa\dev\svn\boostunittestadapterdev\branches\tempbugfixing\sample\boostunittest\boostunittest2\adapterbugs.cpp(58) : {869} normal block at 0x00A88A58, 4 bytes long.
                 *  Data: <    > CD CD CD CD
                 * d:\hwa\dev\svn\boostunittestadapterdev\branches\tempbugfixing\sample\boostunittest\boostunittest2\adapterbugs.cpp(55) : {868} normal block at 0x00A88788, 4 bytes long.
                 *  Data: <    > F5 01 00 00
                 *
                 * and also when this information is not reported such as in the below sample output
                 *
                 * {869} normal block at 0x005E8998, 4 bytes long.
                 * Data: <    > CD CD CD CD
                 * {868} normal block at 0x005E8848, 4 bytes long.
                 * Data: <    > F5 01 00 00
                 *
                 */

                #region regexLeakInformation

                // (?:([\\:\w\rA-z.]*?)([\w\d.]*)\((\d{1,})\)\s:\s)?\{(\d{1,})\}[\w\s\d]*,\s(\d{1,})[\s\w.]*\n(.*?)(?=$|(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d)
                //
                // Options: Case insensitive; Exact spacing; Dot matches line breaks; ^$ don't match at line breaks; Numbered capture
                //
                // Match the regular expression below «(?:([\\:\w\rA-z.]*?)([\w\d.]*)\((\d{1,})\)\s:\s)?»
                //    Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
                //    Match the regex below and capture its match into backreference number 1 «([\\:\w\rA-z.]*?)»
                //       Match a single character present in the list below «[\\:\w\rA-z.]*?»
                //          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
                //          The backslash character «\\»
                //          The literal character “:” «:»
                //          A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //          The carriage return character «\r»
                //          A character in the range between “A” and “z” (case insensitive) «A-z»
                //          The literal character “.” «.»
                //    Match the regex below and capture its match into backreference number 2 «([\w\d.]*)»
                //       Match a single character present in the list below «[\w\d.]*»
                //          Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //          A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //          A “digit” (0–9 in any Unicode script) «\d»
                //          The literal character “.” «.»
                //    Match the character “(” literally «\(»
                //    Match the regex below and capture its match into backreference number 3 «(\d{1,})»
                //       Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //          Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                //    Match the character “)” literally «\)»
                //    Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //    Match the character “:” literally «:»
                //    Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                // Match the character “{” literally «\{»
                // Match the regex below and capture its match into backreference number 4 «(\d{1,})»
                //    Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                // Match the character “}” literally «\}»
                // Match a single character present in the list below «[\w\s\d]*»
                //    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //    A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //    A “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //    A “digit” (0–9 in any Unicode script) «\d»
                // Match the character “,” literally «,»
                // Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                // Match the regex below and capture its match into backreference number 5 «(\d{1,})»
                //    Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                // Match a single character present in the list below «[\s\w.]*»
                //    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //    A “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //    A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //    The literal character “.” «.»
                // Match the line feed character «\n»
                // Match the regex below and capture its match into backreference number 6 «(.*?)»
                //    Match any single character «.*?»
                //       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
                // Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=$|(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d)»
                //    Match this alternative (attempting the next alternative only if this one fails) «$»
                //       Assert position at the end of the string, or before the line break at the end of the string, if any (line feed) «$»
                //    Or match this alternative (the entire group fails if this one fails to match) «(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d»
                //       Match the regular expression below «(?:[\\\w.:]*\(\d{1,}\)\s:\s)?»
                //          Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
                //          Match a single character present in the list below «[\\\w.:]*»
                //             Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //             The backslash character «\\»
                //             A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //             A single character from the list “.:” «.:»
                //          Match the character “(” literally «\(»
                //          Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //             Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                //          Match the character “)” literally «\)»
                //          Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //          Match the character “:” literally «:»
                //          Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //       Match the character “{” literally «\{»
                //       Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //          Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                //       Match a single character that is a “digit” (0–9 in any Unicode script) «\d»

                #endregion regexLeakInformation

                Match matchLeakInformation = regexLeakInformation.Match(leakInformation);
                while (matchLeakInformation.Success)
                {
                    LogEntryMemoryLeak leak = new LogEntryMemoryLeak();

                    result.LogEntries.Add(leak);

                    //Capturing group 1,2 and 3 will have the 'Success' property false in case the C++ new operator has not been replaced via the macro

                    // Temporary variable used to try and parse unsigned integer values;
                    uint value = 0;

                    if (matchLeakInformation.Groups[1].Success && matchLeakInformation.Groups[2].Success && matchLeakInformation.Groups[3].Success)
                    {
                        leak.LeakSourceFilePath = matchLeakInformation.Groups[1].Value;

                        leak.LeakSourceFileName = matchLeakInformation.Groups[2].Value;

                        if (uint.TryParse(matchLeakInformation.Groups[3].Value, out value))
                        {
                            leak.LeakLineNumber = value;
                        }

                        leak.LeakSourceFileAndLineNumberReportingActive = true;
                    }
                    else
                    {
                        leak.LeakSourceFileAndLineNumberReportingActive = false;
                    }

                    if (uint.TryParse(matchLeakInformation.Groups[4].Value, out value))
                    {
                        leak.LeakMemoryAllocationNumber = value;
                    }

                    if (uint.TryParse(matchLeakInformation.Groups[5].Value, out value))
                    {
                        leak.LeakSizeInBytes = value;
                    }

                    leak.LeakLeakedDataContents = matchLeakInformation.Groups[6].Value;

                    matchLeakInformation = matchLeakInformation.NextMatch();
                }
            }
        }
 /// <summary>
 /// Parses child TestUnit nodes.
 /// </summary>
 /// <param name="nodes">The collection of Xml nodes which are valid TestUnit nodes.</param>
 /// <param name="path">The QualifiedNameBuilder which hosts the current fully qualified path.</param>
 /// <param name="collection">The TestResultCollection which will host the result.</param>
 private static void ParseTestUnitsLog(XmlNodeList nodes, QualifiedNameBuilder path, TestResultCollection collection)
 {
     foreach (XmlNode child in nodes)
     {
         if (child.NodeType == XmlNodeType.Element)
         {
             if (child.Name == Xml.TestSuite)
             {
                 ParseTestSuiteLog(child, path, collection);
             }
             else if (child.Name == Xml.TestCase)
             {
                 ParseTestCaseLog(child, path, collection);
             }
         }
     }
 }
        /// <summary>
        /// Parses a TestCase log node.
        /// </summary>
        /// <param name="node">The TestCase Xml node to parse.</param>
        /// <param name="path">The QualifiedNameBuilder which hosts the current fully qualified path.</param>
        /// <param name="collection">The TestResultCollection which will host the result.</param>
        private static void ParseTestCaseLog(XmlNode node, QualifiedNameBuilder path, TestResultCollection collection)
        {
            // Temporarily push TestCase on TestSuite name builder to acquire the fully qualified name of the TestCase
            path.Push(node.Attributes[Xml.Name].Value);

            // Acquire result record of this TestCase
            TestResult result = collection[path.ToString()];

            if (result == null)
            {
                result = new TestResult(collection);
                collection[path.ToString()] = result;
            }

            // Reset path to original value
            path.Pop();

            XmlNode testingTime = node.SelectSingleNode(Xml.TestingTime);

            if (testingTime != null)
            {
                // Boost test testing time is listed in microseconds
                result.Duration += ulong.Parse(testingTime.InnerText, CultureInfo.InvariantCulture);
            }

            ParseTestCaseLogEntries(node.ChildNodes, result);
        }
        /// <summary>
        /// Parses a TestSuite log node.
        /// </summary>
        /// <param name="node">The TestSuite Xml node to parse.</param>
        /// <param name="path">The QualifiedNameBuilder which hosts the current fully qualified path.</param>
        /// <param name="collection">The TestResultCollection which will host the result.</param>
        private static void ParseTestSuiteLog(XmlNode node, QualifiedNameBuilder path, TestResultCollection collection)
        {
            path.Push(node.Attributes[Xml.Name].Value);

            ParseTestUnitsLog(node.ChildNodes, path, collection);

            path.Pop();
        }
Beispiel #10
0
        /// <summary>
        /// Parses child TestUnit nodes.
        /// </summary>
        /// <param name="nav">The parent XPathNavigator which hosts TestUnit nodes.</param>
        /// <param name="parent">The parent TestSuite to which TestUnits are attached to.</param>
        /// <param name="collection">The TestResultCollection which will host the result.</param>
        private static void ParseTestUnitsReport(XPathNavigator nav, TestSuite parent, TestResultCollection collection)
        {
            foreach (XPathNavigator child in nav.SelectChildren(Xml.TestSuite, string.Empty))
            {
                ParseTestSuiteReport(child, parent, collection);
            }

            foreach (XPathNavigator child in nav.SelectChildren(Xml.TestCase, string.Empty))
            {
                ParseTestCaseReport(child, parent, collection);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Parses a general test result information from the provided node.
        /// </summary>
        /// <param name="node">The XPathNavigator pointing to a TestUnit node.</param>
        /// <param name="unit">The test unit for which the test results are related to.</param>
        /// <param name="collection">The TestResultCollection which will host the result.</param>
        private static TestResult ParseTestResult(XPathNavigator node, TestUnit unit, TestResultCollection collection)
        {
            TestResult result = new TestResult(collection);

            result.Unit   = unit;
            result.Result = ParseResultType(node.GetAttribute(Xml.Result, string.Empty));

            result.AssertionsPassed = uint.Parse(node.GetAttribute(Xml.AssertionsPassed, string.Empty), CultureInfo.InvariantCulture);
            result.AssertionsFailed = uint.Parse(node.GetAttribute(Xml.AssertionsFailed, string.Empty), CultureInfo.InvariantCulture);
            result.ExpectedFailures = uint.Parse(node.GetAttribute(Xml.ExpectedFailures, string.Empty), CultureInfo.InvariantCulture);

            return(result);
        }
Beispiel #12
0
        /// <summary>
        /// Parses a TestCase node.
        /// </summary>
        /// <param name="node">The XPathNavigator pointing to a TestCase node.</param>
        /// <param name="parent">The parent TestSuite to which TestUnits are attached to.</param>
        /// <param name="collection">The TestResultCollection which will host the result.</param>
        private static void ParseTestCaseReport(XPathNavigator node, TestSuite parent, TestResultCollection collection)
        {
            QualifiedNameBuilder fullname = new QualifiedNameBuilder(parent);

            fullname.Push(node.GetAttribute(Xml.Name, string.Empty));

            TestCase testCase = null;

            // If the test is already available, reuse it
            TestResult current = collection[fullname.ToString()];

            if (current != null)
            {
                testCase = current.Unit as TestCase;
            }

            // Else construct and add it to the appropriate parent
            if (testCase == null)
            {
                testCase = new TestCase(fullname.Peek(), parent);
            }

            TestResult result = ParseTestResult(node, testCase, collection);

            // Aggregate results. Common use-case in BOOST_DATA_TEST_CASE.
            collection[fullname.ToString()] = Aggregate(result, current);
        }
Beispiel #13
0
        /// <summary>
        /// Parses a TestSuite node.
        /// </summary>
        /// <param name="node">The XPathNavigator pointing to a TestSuite node.</param>
        /// <param name="parent">The parent TestSuite to which TestUnits are attached to.</param>
        /// <param name="collection">The TestResultCollection which will host the result.</param>
        private static void ParseTestSuiteReport(XPathNavigator node, TestSuite parent, TestResultCollection collection)
        {
            TestSuite testSuite = new TestSuite(node.GetAttribute(Xml.Name, string.Empty), parent);

            collection[testSuite] = ParseTestResult(node, testSuite, collection);

            ParseTestUnitsReport(node, testSuite, collection);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="collection">The parent collection which hosts this TestResult.</param>
 public TestResult(TestResultCollection collection)
 {
     this.Collection = collection;
     this.LogEntries = new List <LogEntry>();
     this.Duration   = 0;
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="collection">The TestResultCollection which hosts all results.</param>
 /// <param name="types">The types to lookup</param>
 public TestCaseResultVisitor(TestResultCollection collection, IEnumerable <TestResultType> types)
 {
     this.Collection  = collection;
     this.ResultTypes = types;
     this.Count       = 0;
 }