예제 #1
0
        public override void Update()
        {
            Log.Info("Updating Coverage");

            for (int i = 0; i < variables.Coverages.Length; i++)
            {
                variables.Coverages[i].satCount = 0;
            }

            Vessel[] Satellites = VesselHelper.GetSatellites();

            for (int i = 0; i < Satellites.Length; i++)
            {
                Vessel Satellite = Satellites[i];

                CelestialBody  Body   = Satellite.GetOrbit().referenceBody;
                CoverageReport Report = GetReport(Body.GetName());
                Report.satCount++;
                Report.Update();
            }

            double totalCoverage = 0;

            for (int i = 0; i < variables.Coverages.Length; i++)
            {
                totalCoverage += variables.Coverages[i].coverage;
            }

            variables.satelliteCoverage = totalCoverage / variables.Coverages.Length;
            variables.modSCSatellite    = (int)(100 * variables.satelliteCoverage * StateFundingGlobal.fetch.GameInstance.Gov.scModifier);
        }
예제 #2
0
 private void SanitizeReport(CoverageReport report)
 {
     foreach (var package in report.Packages.Package)
     {
         SanitizePackage(package);
     }
 }
        public void ConditionCoverageTest()
        {
            var report = new CoverageReport
            {
                Packages = new Packages
                {
                    Package = new List <Package>
                    {
                        new Package
                        {
                            Classes = new Classes
                            {
                                Class = new List <Class>
                                {
                                    new Class
                                    {
                                        Methods = new Methods
                                        {
                                            Method = new List <Method>()
                                        },
                                        Lines = new Lines
                                        {
                                            Line = new List <Line>
                                            {
                                                new Line
                                                {
                                                    Number            = 1,
                                                    Hits              = 0,
                                                    Branch            = "True",
                                                    ConditionCoverage = "33% (1/3)",
                                                    Conditions        = new Conditions
                                                    {
                                                        Condition = new List <Condition>
                                                        {
                                                            new Condition
                                                            {
                                                                Number   = "1",
                                                                Coverage = "33.3%",
                                                                Type     = "jump"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            var logger           = new MessageLogger <ReportCalculator>();
            var reportCalculator = new ReportCalculator(logger);

            reportCalculator.CalculateStatistics(report);
            // TODO: Not correct, but no exception
            Assert.Equal("33.3% (0.7/2)", report.Packages.Package[0].Classes.Class[0].Lines.Line[0].ConditionCoverage);
        }
 private void BuildMethodBlocks(CoverageReport.MethodDescriptor md, MethodItem mdItem)
 {
     foreach (CoverageReport.InnerBlockData ibd in md.insBlocks)
     {
         CoveredVariantItem cvItem = new CoveredVariantItem();
         cvItem.Blocks = ibd.blocks;
         mdItem.AddBlock(cvItem);
     }
 }
예제 #5
0
 private void MergeReports(CoverageReport mergedReport, ICollection <CoverageReport> reports)
 {
     mergedReport.Packages = new Packages
     {
         Package = new List <Package>()
     };
     foreach (var report in reports)
     {
         MergePackages(mergedReport, report.Packages.Package);
     }
 }
 public void LoadFromFile(string fileName)
 {
     CoverageReport report = new CoverageReport();
     ReportReader reportReader = new ReportReader();
     using (StreamReader reader = new StreamReader(fileName))
     {
         reportReader.ReadReport(report, reader);
     }
     setReport(report);
     reportFileName = fileName;
 }
예제 #7
0
        private bool MergeSources(CoverageReport mergedReport, ICollection <CoverageReport> reports)
        {
            _logger.LogDebug("Making all file names absolute.");

            foreach (var report in reports)
            {
                MakePathsAbsolute(report);
            }

            return(true);
        }
        public virtual void WriteReport(CoverageReport report, TextWriter writer)
        {
            XmlDocument xml = new XmlDocument();

            XmlNode root = xml.AppendChild(xml.CreateElement("coverage"));
            root.Attributes.Append(xml.CreateAttribute("profilerVersion")).Value = VersionString(GetHelperAssembly().GetName().Version);
            root.Attributes.Append(xml.CreateAttribute("driverVersion")).Value = VersionString(GetHelperAssembly().GetName().Version);

            // FIXME: Need start and end times
            root.Attributes.Append(xml.CreateAttribute("startTime")).Value = report.start.ToString(NCOVER_DATE_FORMAT);
            root.Attributes.Append(xml.CreateAttribute("measureTime")).Value = report.end.ToString(NCOVER_DATE_FORMAT);

            foreach (CoverageReport.AssemblyDescriptor assembly in report.assemblies)
            {
                XmlNode moduleNode = root.AppendChild(xml.CreateElement("module"));
                moduleNode.Attributes.Append(xml.CreateAttribute("name")).Value = assembly.assemblyPath;    // NCover calls the full path the 'name' and the assembly name the 'assembly'
                moduleNode.Attributes.Append(xml.CreateAttribute("assembly")).Value = assembly.name;
                moduleNode.Attributes.Append(xml.CreateAttribute("assemblyIdentity")).Value = assembly.assemblyIdentity;

                foreach (CoverageReport.TypeDescriptor dType in assembly.types)
                {
                    foreach (CoverageReport.MethodDescriptor dMethod in dType.methods)
                    {
                        XmlNode methodNode = moduleNode.AppendChild(xml.CreateElement("method"));
                        methodNode.Attributes.Append(xml.CreateAttribute("name")).Value = dMethod.methodName;
                        methodNode.Attributes.Append(xml.CreateAttribute("excluded")).Value = "false";
                        methodNode.Attributes.Append(xml.CreateAttribute("instruments")).Value = "true";
                        methodNode.Attributes.Append(xml.CreateAttribute("class")).Value = dType.typeName;

                        foreach (CoverageReport.InnerBlockData bData in dMethod.insBlocks)
                        {
                            foreach (CoverageReport.InnerBlock inner in bData.blocks)
                            {
                                if (inner.fileId != 0)
                                {
                                    XmlNode point = methodNode.AppendChild(xml.CreateElement("seqpnt"));
                                    point.Attributes.Append(xml.CreateAttribute("visitcount")).Value = inner.visitCount.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("excluded")).Value = "false";
                                    point.Attributes.Append(xml.CreateAttribute("line")).Value = inner.startLine.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("column")).Value = inner.startColumn.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("endline")).Value = inner.endLine.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("endcolumn")).Value = inner.endLine.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("document")).Value = report.GetFileUrl(inner.fileId);
                                }
                            }
                        }
                    }
                }
            }

            xml.Save(writer);
        }
예제 #9
0
 private void MakePathsAbsolute(CoverageReport report)
 {
     foreach (var package in report.Packages.Package)
     {
         foreach (var cl in package.Classes.Class)
         {
             var source = report.Sources?.Source;
             if (!string.IsNullOrEmpty(source))
             {
                 cl.Filename = Path.Combine(source, cl.Filename);
             }
         }
     }
 }
예제 #10
0
        /// <summary>
        /// Serializes the report and writes it to the file system.
        /// </summary>
        /// <param name="report">The report to serialize and write.</param>
        /// <param name="outputFilePath">The output file path.</param>
        public void Write(CoverageReport report, string outputFilePath)
        {
            report.Packages.Package = report.Packages.Package.OrderBy(p => p.Name).ToList();

            var xmlSerializer = new XmlSerializer(typeof(CoverageReport));

            using (var writer = XmlWriter.Create(outputFilePath, new XmlWriterSettings
            {
                Indent = true,
                IndentChars = "  "
            }))
            {
                xmlSerializer.Serialize(writer, report);
            }

            _logger.LogInformation($"Wrote merged report at '{outputFilePath}'.");
        }
예제 #11
0
        private CoverageReport GetReport(string bodyName)
        {
            for (var i = 0; i < variables.Coverages.Length; i++)
            {
                CoverageReport Report = variables.Coverages[i];
                if (Report.entity == bodyName)
                {
                    return(Report);
                }
            }

            CoverageReport CReport = new CoverageReport();

            CReport.entity = bodyName;

            return(CReport);
        }
        /// <summary>
        /// Calculates the statistics of the coverage report.
        /// </summary>
        /// <param name="report">The coverage report.</param>
        public void CalculateStatistics(CoverageReport report)
        {
            _reportCalculator.LogInformation("Calculating the statistics of the merged report...");

            var reportCounters = new Counters();

            foreach (var package in report.Packages.Package)
            {
                CalculatePackage(package, reportCounters);
            }

            report.LinesCovered = reportCounters.LinesCovered;
            report.LinesValid   = reportCounters.LinesValid;
            report.LineRate     = GetRate(reportCounters.LinesCovered, reportCounters.LinesValid);

            report.BranchesCovered = reportCounters.BranchesCovered;
            report.BranchesValid   = reportCounters.BranchesValid;
            report.BranchRate      = GetRate(reportCounters.BranchesCovered, reportCounters.BranchesValid);
        }
예제 #13
0
        /// <summary>
        /// Merges the reports into one single report.
        /// </summary>
        /// <param name="reports">The reports.</param>
        /// <returns>The merged report.</returns>
        public CoverageReport Merge(ICollection <CoverageReport> reports)
        {
            _logger.LogInformation("Merging reports...");

            var mergedReport = new CoverageReport
            {
                Version   = reports.Min(r => r.Version),
                Timestamp = reports.Max(r => r.Timestamp)
            };

            if (MergeSources(mergedReport, reports))
            {
                MergeReports(mergedReport, reports);

                return(mergedReport);
            }

            return(null);
        }
예제 #14
0
        public SatelliteCoverageFactor(FactorVariables factorVariables) : base(factorVariables)
        {
            variables.satelliteCoverage = 0;
            // Initialize coverage for Celestial Bodies (other than the Sun)

            CelestialBody[] Bodies = FlightGlobals.Bodies.ToArray();
            variables.Coverages = new CoverageReport[Bodies.Length - 1];
            CelestialBody home = Planetarium.fetch.Home;

            if (home == null)
            {
                home = FlightGlobals.Bodies.Find(body => body.isHomeWorld == true);
            }

            if (home != null)
            {
                StateFundingGlobal.refRadius = home.Radius / 10;
            }

            int k = 0;

            for (int i = 0; i < Bodies.Length; i++)
            {
                CelestialBody Body = Bodies[i];

                // Don't need to survey the sun
                //if (Body.GetName() != StateFundingGlobal.Sun)
                if (Body != Planetarium.fetch.Sun)
                {
                    CoverageReport Report = new CoverageReport();
                    Report.entity = Body.GetName();

                    // Benchmark: Kerbin
                    // 10 sats till full coverage on Kerbin
                    Report.satCountForFullCoverage = (int)Math.Ceiling(Body.Radius / StateFundingGlobal.refRadius);

                    variables.Coverages[k] = Report;
                    k++;
                }
            }
        }
 private static List <FileCoverageModel> Parse(CoverageReport report)
 {
     return(report.Packages.Package
            .SelectMany(package => package.Classes.Class)
            .Select(c => new FileCoverageModel
     {
         RelativeFilename = c.Filename,
         UncoveredLines = c.Lines.Line
                          .Where(l => l.Hits == 0)
                          .Select(l => l.Number)
                          .ToList(),
         CoveredLines = c.Lines.Line
                        .Where(l => l.Hits > 0 ||
                               l.ConditionCoverage?.ToLower() == "true" && l.Branch.StartsWith("100"))
                        .Select(l => l.Number)
                        .ToList(),
         PartlyCoveredLines = c.Lines.Line
                              .Where(l => l.ConditionCoverage?.ToLower() == "true" && !l.Branch.StartsWith("100"))
                              .Select(l => l.Number)
                              .ToList()
     })
            .ToList());
 }
예제 #16
0
        private void MergePackages(CoverageReport mergedReport, List <Package> packages)
        {
            foreach (var package in packages)
            {
                var existingPackage = mergedReport.Packages.Package.FirstOrDefault(p => p.Name == package.Name);
                if (existingPackage == null)
                {
                    existingPackage = new Package
                    {
                        Name       = package.Name,
                        LineRate   = 0, // To be calculated
                        BranchRate = 0, // To be calculated
                        Complexity = 0, // To be calculated?
                        Classes    = new Classes
                        {
                            Class = new List <Class>()
                        }
                    };
                    mergedReport.Packages.Package.Add(existingPackage);
                }

                MergeClasses(existingPackage, package.Classes.Class);
            }
        }
예제 #17
0
 public void Add(CoverageReport.RunLogMessage runLogMessage)
 {
     PutLogEntry(runLogMessage);
 }
예제 #18
0
        private void PutLogEntry(CoverageReport.RunLogMessage item)
        {
            if (InvokeRequired)
            {
                Invoke(new PutLogEntryDelegate(PutLogEntry), item);
                return;
            }

            tbLog.AppendText(string.Format(CultureInfo.CurrentCulture,
                "[{0,6}][{1,6}]{2}{3}",
                item.ThreadId, item.MsOffset, item.Message, Environment.NewLine));
        }
예제 #19
0
 public BlockStylizer(CoverageReport.InnerBlock[] points)
 {
     this.points = points;
 }
 public InstrumentedBlocksWalkerInner()
 {
     coverage = new CoverageReport();
 }
        private void setReport(CoverageReport report)
        {
            if (Report != null && ReportClosing != null)
                ReportClosing(this, EventArgs.Empty);

            CoverageReportWrapper wrapper = new CoverageReportWrapper(report);
            wrapper.Build();

            reportFileName = null;
            reportWrapper = wrapper;
            if (Report != null && ReportOpened != null)
                ReportOpened(this, EventArgs.Empty);
        }
예제 #22
0
        public void ReadReport(CoverageReport report, TextReader reader)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(reader);

            XmlNode root = xml.SelectSingleNode("/PartCoverReport");
            if (root == null) throw new ReportException("Wrong report format");
            XmlAttribute verAttribute = root.Attributes["ver"];
            if (verAttribute == null) throw new ReportException("Wrong report format");
            XmlAttribute exitCodeAttribute = root.Attributes["exitCode"];
            if (exitCodeAttribute != null) report.ExitCode = GetIntAttribute(root, exitCodeAttribute.Name);

            foreach (XmlNode fileNode in xml.SelectNodes("/PartCoverReport/file"))
                report.AddFile(GetUInt32Attribute(fileNode, "id"), GetStringAttribute(fileNode, "url"));

            foreach (XmlNode typeNode in xml.SelectNodes("/PartCoverReport/type"))
            {
                CoverageReport.TypeDescriptor dType = new CoverageReport.TypeDescriptor();
                dType.assemblyName = GetStringAttribute(typeNode, "asm");
                dType.typeName = GetStringAttribute(typeNode, "name");
                dType.flags = GetUInt32Attribute(typeNode, "flags");

                foreach (XmlNode methodNode in typeNode.SelectNodes("method"))
                {
                    CoverageReport.MethodDescriptor dMethod = new CoverageReport.MethodDescriptor(0);
                    dMethod.methodName = GetStringAttribute(methodNode, "name");
                    dMethod.methodSig = GetStringAttribute(methodNode, "sig");
                    dMethod.flags = GetUInt32Attribute(methodNode, "flags");
                    dMethod.implFlags = GetUInt32Attribute(methodNode, "iflags");

                    foreach (XmlNode blockNode in methodNode.SelectNodes("code"))
                    {
                        CoverageReport.InnerBlockData dBlock = new CoverageReport.InnerBlockData();
                        foreach (XmlNode pointNode in blockNode.SelectNodes("pt"))
                        {
                            CoverageReport.InnerBlock dPoint = new CoverageReport.InnerBlock();
                            dPoint.visitCount = GetUInt32Attribute(pointNode, "visit");
                            dPoint.position = GetUInt32Attribute(pointNode, "pos");
                            dPoint.blockLen = GetUInt32Attribute(pointNode, "len");
                            if (pointNode.Attributes["fid"] != null)
                            {
                                dPoint.fileId = GetUInt32Attribute(pointNode, "fid");
                                dPoint.startLine = GetUInt32Attribute(pointNode, "sl");
                                dPoint.startColumn = GetUInt32Attribute(pointNode, "sc");
                                dPoint.endLine = GetUInt32Attribute(pointNode, "el");
                                dPoint.endColumn = GetUInt32Attribute(pointNode, "ec");
                            }
                            dBlock.AddBlock(dPoint);
                        }
                        dMethod.AddBlockData(dBlock);
                    }
                    dType.AddMethod(dMethod);
                }
                report.AddType(dType);
            }

            foreach (XmlNode messageNode in xml.SelectNodes("/PartCoverReport/run/tracker/message"))
                report.AddTrackerMessage(messageNode);

            foreach (XmlNode messageNode in xml.SelectNodes("/PartCoverReport/run/log/message"))
                report.AddLogFileMessage(messageNode);
        }
예제 #23
0
 public void Add(CoverageReport.RunHistoryMessage runHistoryMessage)
 {
     SetMessage(runHistoryMessage.Message);
 }
 public CoverageReportWrapper(CoverageReport report)
 {
     this.report = report;
 }
 private void BuildMethods(CoverageReport.MethodDescriptor[] mdList, ClassItem classItem)
 {
     foreach (CoverageReport.MethodDescriptor md in mdList)
     {
         MethodItem mdItem = new MethodItem(md, classItem);
         BuildMethodBlocks(md, mdItem);
         classItem.AddMethod(mdItem);
     }
 }
예제 #26
0
 internal void OnLogMessage(CoverageReport.RunLogMessage message)
 {
     blockWalker.Report.runLog.Add(message);
     if (OnEventMessage != null) OnEventMessage(this, new EventArgs<CoverageReport.RunLogMessage>(message));
 }
예제 #27
0
        public void WriteTest()
        {
            var coverageReport = new CoverageReport
            {
                Version         = "1.9",
                Timestamp       = "123",
                LinesCovered    = 1,
                LinesValid      = 2,
                LineRate        = 0.5f,
                BranchesCovered = 0,
                BranchesValid   = 0,
                BranchRate      = 0,
                Sources         = new Sources
                {
                    Source = @"D:\dummy-project\src\"
                },
                Packages = new Packages
                {
                    Package = new List <Package>
                    {
                        new Package
                        {
                            Name       = "Package1",
                            LineRate   = 0.5f,
                            BranchRate = 0f,
                            Complexity = 0f,
                            Classes    = new Classes
                            {
                                Class = new List <Class>
                                {
                                    new Class
                                    {
                                        Name       = "Package1.Class1",
                                        Filename   = "Class1.cs",
                                        LineRate   = 0.5f,
                                        BranchRate = 0f,
                                        Complexity = 0f,
                                        Lines      = new Lines
                                        {
                                            Line = new List <Line>
                                            {
                                                new Line {
                                                    Number = 1, Hits = 1, Branch = "False"
                                                },
                                                new Line {
                                                    Number = 2, Hits = 0, Branch = "False"
                                                }
                                            }
                                        },
                                        Methods = new Methods
                                        {
                                            Method = new List <Method>
                                            {
                                                new Method
                                                {
                                                    Name       = "Method1",
                                                    Signature  = "()",
                                                    LineRate   = 0.5f,
                                                    BranchRate = 0f,
                                                    Lines      = new Lines
                                                    {
                                                        Line = new List <Line>
                                                        {
                                                            new Line {
                                                                Number = 1, Hits = 1, Branch = "False"
                                                            },
                                                            new Line {
                                                                Number = 2, Hits = 0, Branch = "False"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            var outputFilePath = "output.xml";

            var logger       = new MessageLogger <ReportWriter>();
            var reportWriter = new ReportWriter(logger);

            reportWriter.Write(coverageReport, outputFilePath);

            Assert.True(File.Exists(outputFilePath));

            var fileLoader = new FileLoader(new NullLogger <FileLoader>());
            var reports    = fileLoader.LoadFiles(new[] { outputFilePath });

            Assert.Single(reports);

            var readReport = reports[0];

            Assert.Equal(coverageReport.LineRate, readReport.LineRate);
            Assert.Equal(coverageReport.LinesCovered, readReport.LinesCovered);
            Assert.Equal(coverageReport.LinesValid, readReport.LinesValid);
            Assert.Equal(coverageReport.BranchRate, readReport.BranchRate);
            Assert.Equal(coverageReport.BranchesCovered, readReport.BranchesCovered);
            Assert.Equal(coverageReport.BranchesValid, readReport.BranchesValid);

            Assert.Single(logger.Messages);
            Assert.Equal("Wrote merged report at 'output.xml'.", logger.Messages[0]);
        }
 public void Load(CoverageReport report)
 {
     setReport(report);
 }
        public virtual void WriteReport(CoverageReport report, TextWriter writer)
        {
            XmlDocument xml = new XmlDocument();

            XmlNode root = xml.AppendChild(xml.CreateElement("PartCoverReport"));
            root.Attributes.Append(xml.CreateAttribute("ver")).Value = VersionString(GetHelperAssembly().GetName().Version);

            if (report.ExitCode.HasValue)
                root.Attributes.Append(xml.CreateAttribute("exitCode")).Value = report.ExitCode.Value.ToString(CultureInfo.InvariantCulture);

            foreach (CoverageReport.FileDescriptor dFile in report.files)
            {
                XmlNode fileNode = root.AppendChild(xml.CreateElement("file"));
                fileNode.Attributes.Append(xml.CreateAttribute("id")).Value = dFile.fileId.ToString(CultureInfo.InvariantCulture);
                fileNode.Attributes.Append(xml.CreateAttribute("url")).Value = dFile.fileUrl;
            }
            foreach (CoverageReport.AssemblyDescriptor assembly in report.assemblies)
            {
                foreach (CoverageReport.TypeDescriptor dType in assembly.types)
                {
                    XmlNode typeNode = root.AppendChild(xml.CreateElement("type"));
                    typeNode.Attributes.Append(xml.CreateAttribute("asm")).Value = dType.assemblyName;
                    typeNode.Attributes.Append(xml.CreateAttribute("name")).Value = dType.typeName;
                    typeNode.Attributes.Append(xml.CreateAttribute("flags")).Value =
                        dType.flags.ToString(CultureInfo.InvariantCulture);

                    foreach (CoverageReport.MethodDescriptor dMethod in dType.methods)
                    {
                        XmlNode methodNode = typeNode.AppendChild(xml.CreateElement("method"));
                        methodNode.Attributes.Append(xml.CreateAttribute("name")).Value = dMethod.methodName;
                        methodNode.Attributes.Append(xml.CreateAttribute("sig")).Value = dMethod.methodSig;
                        methodNode.Attributes.Append(xml.CreateAttribute("flags")).Value =
                            dMethod.flags.ToString(CultureInfo.InvariantCulture);
                        methodNode.Attributes.Append(xml.CreateAttribute("iflags")).Value =
                            dMethod.implFlags.ToString(CultureInfo.InvariantCulture);

                        foreach (CoverageReport.InnerBlockData bData in dMethod.insBlocks)
                        {
                            XmlNode codeNode = methodNode.AppendChild(xml.CreateElement("code"));
                            foreach (CoverageReport.InnerBlock inner in bData.blocks)
                            {
                                XmlNode point = codeNode.AppendChild(xml.CreateElement("pt"));
                                point.Attributes.Append(xml.CreateAttribute("visit")).Value =
                                    inner.visitCount.ToString(CultureInfo.InvariantCulture);
                                point.Attributes.Append(xml.CreateAttribute("pos")).Value =
                                    inner.position.ToString(CultureInfo.InvariantCulture);
                                point.Attributes.Append(xml.CreateAttribute("len")).Value =
                                    inner.blockLen.ToString(CultureInfo.InvariantCulture);
                                if (inner.fileId != 0)
                                {
                                    point.Attributes.Append(xml.CreateAttribute("fid")).Value =
                                        inner.fileId.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("sl")).Value =
                                        inner.startLine.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("sc")).Value =
                                        inner.startColumn.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("el")).Value =
                                        inner.endLine.ToString(CultureInfo.InvariantCulture);
                                    point.Attributes.Append(xml.CreateAttribute("ec")).Value =
                                        inner.endColumn.ToString(CultureInfo.InvariantCulture);
                                }
                            }
                        }
                    }
                }
            }

            XmlNode runNode = root.AppendChild(xml.CreateElement("run"));

            XmlNode runTrackerNode = runNode.AppendChild(xml.CreateElement("tracker"));
            foreach (CoverageReport.RunHistoryMessage rhm in report.runHistory)
            {
                XmlNode messageNode = runTrackerNode.AppendChild(xml.CreateElement("message"));
                messageNode.Attributes.Append(xml.CreateAttribute("tm")).Value = rhm.Time.ToUniversalTime().Ticks.ToString(CultureInfo.InvariantCulture);
                messageNode.InnerText = rhm.Message;
            }

            XmlNode runLogNode = runNode.AppendChild(xml.CreateElement("log"));
            foreach (CoverageReport.RunLogMessage rlm in report.runLog)
            {
                XmlNode messageNode = runLogNode.AppendChild(xml.CreateElement("message"));
                messageNode.Attributes.Append(xml.CreateAttribute("tr")).Value = rlm.ThreadId.ToString(CultureInfo.InvariantCulture);
                messageNode.Attributes.Append(xml.CreateAttribute("ms")).Value = rlm.MsOffset.ToString(CultureInfo.InvariantCulture);
                messageNode.InnerText = rlm.Message;
            }

            xml.Save(writer);
        }