public InstrumentationResult Execute() { id = 0; result = new InstrumentationResult { SourcePath = normalizedWorkDir, HitsFile = hitsFile }; foreach (var assemblyFile in assemblies) { RestoreBackup(assemblyFile); } var assemblyGroups = assemblies .Where(ShouldInstrumentAssembly) .GroupBy(FileUtils.GetFileHash) .ToArray(); foreach (var assemblyGroup in assemblyGroups) { VisitAssemblyGroup(assemblyGroup); } return(result); }
private void VisitAssemblyGroup( InstrumentationContext context, InstrumentationResult result, IEnumerable <FileInfo> groupFiles) { var firstAssemblyFile = groupFiles.First(); var instrumentedAssembly = _assemblyInstrumenter.InstrumentAssembly( context, firstAssemblyFile); if (instrumentedAssembly == null) { return; } foreach (var assemblyFile in groupFiles) { var pdbFile = FileUtils.GetPdbFile(assemblyFile); var assemblyBackupFile = FileUtils.GetBackupFile(assemblyFile); var pdbBackupFile = FileUtils.GetBackupFile(pdbFile); //Backup File.Copy(assemblyFile.FullName, assemblyBackupFile.FullName, true); File.Copy(pdbFile.FullName, pdbBackupFile.FullName, true); //Override assembly File.Copy(instrumentedAssembly.TempAssemblyFile, assemblyFile.FullName, true); File.Copy(instrumentedAssembly.TempPdbFile, pdbFile.FullName, true); //Copy instrumentation dependencies var assemblyDirectory = assemblyFile.Directory; var hitServicesPath = Path.GetFileName(hitServicesAssembly.Location); var newHitServicesPath = Path.Combine(assemblyDirectory.FullName, hitServicesPath); if (!File.Exists(newHitServicesPath)) { File.Copy(hitServicesAssembly.Location, newHitServicesPath, true); result.AddExtraAssembly(newHitServicesPath); } instrumentedAssembly.AddLocation( assemblyFile.FullName, assemblyBackupFile.FullName, pdbFile.FullName, pdbBackupFile.FullName ); var hitServicesAssemblyVersion = FileVersionInfo.GetVersionInfo(hitServicesAssembly.Location); foreach (var depsJsonFile in assemblyDirectory.GetFiles("*.deps.json")) { DepsJsonUtils.PatchDepsJson(depsJsonFile, hitServicesAssemblyVersion.ProductVersion); } } result.AddInstrumentedAssembly(instrumentedAssembly); File.Delete(instrumentedAssembly.TempAssemblyFile); File.Delete(instrumentedAssembly.TempPdbFile); }
public InstrumentationResult Instrument(IInstrumentationContext context) { _logger.LogTrace("Hit services assembly location: {assemblyLocation}", hitServicesAssembly.Location); var result = new InstrumentationResult { SourcePath = context.Workdir.FullName, HitsPath = context.HitsPath }; var assemblyGroups = context.Assemblies .Where(ShouldInstrumentAssemblyFile) .GroupBy(FileUtils.GetFileHash) .ToArray(); foreach (var assemblyGroup in assemblyGroups) { VisitAssemblyGroup( context, result, assemblyGroup.ToArray()); } return(result); }
public InstrumentationResult Execute(InstrumentationContext context) { context.Workdir = context.Workdir.AddEndingDirectorySeparator(); var result = new InstrumentationResult { SourcePath = context.Workdir.FullName, HitsPath = context.HitsPath }; var assemblyGroups = context.Assemblies .Where(ShouldInstrumentAssemblyFile) .GroupBy(FileUtils.GetFileHash) .ToArray(); foreach (var assemblyGroup in assemblyGroups) { VisitAssemblyGroup( context, result, assemblyGroup); } return(result); }
public static void Execute(InstrumentationResult result, string output, float threshold) { var hits = Hits.TryReadFromFile(result.HitsFile); var document = new XDocument( new XDeclaration("1.0", "utf-8", null), CreateCoverageElement(result, hits) ); var xmlWriterSettings = new XmlWriterSettings { Indent = true }; var path = Path.GetDirectoryName(output); if (!string.IsNullOrEmpty(path)) { Directory.CreateDirectory(Path.GetDirectoryName(output)); } using (StreamWriter sw = File.CreateText(output)) using (XmlWriter writer = XmlWriter.Create(sw, xmlWriterSettings)) { document.WriteTo(writer); } }
public void Execute(InstrumentationResult result) { foreach (var assembly in result.Assemblies) { foreach (var assemblyLocation in assembly.Locations) { if (File.Exists(assemblyLocation.BackupFile)) { File.Copy(assemblyLocation.BackupFile, assemblyLocation.File, true); File.Delete(assemblyLocation.BackupFile); } if (File.Exists(assemblyLocation.BackupPdbFile)) { File.Copy(assemblyLocation.BackupPdbFile, assemblyLocation.PdbFile, true); File.Delete(assemblyLocation.BackupPdbFile); } var assemblyDirectory = _fileSystem.FileInfo.FromFileName(assemblyLocation.File).Directory; foreach (var depsJsonFile in assemblyDirectory.GetFiles("*.deps.json")) { _depsJsonUtils.UnpatchDepsJson(depsJsonFile); } } } foreach (var extraAssembly in result.ExtraAssemblies) { if (File.Exists(extraAssembly)) { File.Delete(extraAssembly); } } }
public InstrumentationResult InstrumentAssembly(string assemblyPath) { AssemblyDefinition assembly = null; InstrumentationResult preInstrumentationResult = this.CheckAndLoadAssembly(assemblyPath, out assembly); if (preInstrumentationResult != InstrumentationResult.OK) { return(preInstrumentationResult); } bool instrumented = false; List <IInstrumenter> instrumenters = new List <IInstrumenter>(); foreach (var module in assembly.Modules) { bool isMixedMode = (module.Attributes & ModuleAttributes.ILOnly) == 0; if (isMixedMode) { return(InstrumentationResult.SKIPPED_MixedModeAssembly); } // instrumenters.Add(new FieldUseInstrumenter(module, this.srtRuntimeModule)); instrumenters.Add(new AsyncInstrumenter()); instrumenters.Add(new FieldInstrumenter(module, this.srtRuntimeModule)); foreach (var type in module.GetAllTypes()) { bool implementsBlacklistedInterface = type.Interfaces.Any(x => Constants.BlackListInterface.Contains(x.InterfaceType.FullName)); if (implementsBlacklistedInterface) { continue; } var allMethods = type.Methods.Where(x => x.HasBody); foreach (IInstrumenter instrumenter in instrumenters) { instrumented |= instrumenter.Instrument(allMethods); } } } try { assembly.Write(new WriterParameters() { WriteSymbols = this.PdbExists(assemblyPath) }); string assemblyDirectory = Path.GetDirectoryName(assemblyPath); string logDirMarkerFile = Path.Combine(assemblyDirectory, Constants.LogDirMarkerFile); File.WriteAllText(logDirMarkerFile, assemblyPath); } catch (Exception e) { return(InstrumentationResult.ERROR_Other); } assembly.Dispose(); return(instrumented ? InstrumentationResult.OK : InstrumentationResult.SKIPPED_NothingToInstrument); }
/// <summary> /// Instruments a list of assemblies. /// </summary> /// <param name="assemblyPaths">A list of assemblies to instrument.</param> /// <returns>0, if at least one input assembly is instrumented correctly.</returns> public InstrumentationResult Instrument(List <string> assemblyPaths) { if (assemblyPaths == null) { return(InstrumentationResult.ERROR_ARGUMENTS); } bool instrumented = false; string directoryPath = null; Console.WriteLine("Instrumenting assemblies."); foreach (string path in assemblyPaths) { Console.Write($"{Path.GetFileName(path)} ..."); // var result = this.ilRewriter.RewriteThreadSafetyAPIs(path); InstrumentationResult result = this.ilRewriter.InstrumentAssembly(path); Console.WriteLine(result); if (result == InstrumentationResult.OK) { directoryPath = Path.GetDirectoryName(path); instrumented = true; } } Console.WriteLine("Instrumentation complete. Copying TSVD files."); if (instrumented) { Helper.CopyDependentAssemblies(directoryPath); Helper.CopyRuntimeConfiguration(directoryPath, this.runtimeConfigurationFile); } Console.WriteLine($"Done."); return(instrumented ? InstrumentationResult.OK : InstrumentationResult.ERROR_INSTRUMENTATION); }
public static void Execute(InstrumentationResult result) { foreach (var assembly in result.Assemblies) { foreach (var assemblyLocation in assembly.Locations) { if (File.Exists(assemblyLocation.BackupFile)) { File.Copy(assemblyLocation.BackupFile, assemblyLocation.File, true); File.Delete(assemblyLocation.BackupFile); } if (File.Exists(assemblyLocation.BackupPdbFile)) { File.Copy(assemblyLocation.BackupPdbFile, assemblyLocation.PdbFile, true); File.Delete(assemblyLocation.BackupPdbFile); } } } foreach (var extraAssembly in result.ExtraAssemblies) { if (File.Exists(extraAssembly)) { File.Delete(extraAssembly); } } }
public static int IsHigherThanThreshold(InstrumentationResult result, float threshold) { var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Sequences .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = kvFile.Value.Sequences .Where(h => hits.WasHit(h.HitId)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; } var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; return(isHigherThanThreshold ? 0 : 1); }
private static XElement CratePackagesElement(InstrumentationResult result, HitsInfo hitsInfo) { return(new XElement( XName.Get("packages"), result.Assemblies .Where(a => a.SourceFiles.Count > 0) .Select(a => CreatePackageElement(a, hitsInfo)) )); }
private static IEnumerable <XElement> CreatePackagesElement(InstrumentationResult result, HitsInfo hits) { return(result.Assemblies.Select(assembly => new XElement( XName.Get("package"), new XAttribute(XName.Get("name"), assembly.Name), CreateMetricsElement(CountPackageMetrics(assembly, hits)), CreateFilesElement(assembly, hits) ))); }
private static XElement CrateSourcesElement(InstrumentationResult result, HitsInfo hitsInfo) { return(new XElement( XName.Get("sources"), new XElement("source", new XText(result.SourcePath) ) )); }
private static XElement CreateProjectElement(InstrumentationResult result, long timestamp, HitsInfo hits) { return(new XElement( XName.Get("project"), new XAttribute(XName.Get("timestamp"), timestamp), new XAttribute(XName.Get("name"), result.SourcePath), CreateMetricsElement(CountProjectMetrics(result, hits)), CreatePackagesElement(result, hits) )); }
private static void SaveCoverageFile(IFileInfo coverageFile, InstrumentationResult result) { var settings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }; var json = JsonConvert.SerializeObject(result, Formatting.Indented, settings); File.WriteAllText(coverageFile.FullName, json); }
private static XElement CreateCoverageElement(InstrumentationResult result, HitsInfo hits) { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); return(new XElement( XName.Get("coverage"), new XAttribute(XName.Get("generated"), timestamp), new XAttribute(XName.Get("clover"), "4.1.0"), CreateProjectElement(result, timestamp, hits) )); }
private static CloverCounter CountProjectMetrics(InstrumentationResult result, HitsInfo hits) { return(result.Assemblies .Select(t => CountPackageMetrics(t, hits)) .Aggregate(new CloverCounter(), (counter, next) => { counter.Add(next); counter.Packages += 1; return counter; }));; }
public Summary CalculateSummary( InstrumentationResult result, float threshold) { var hitsInfo = _hitsReader.TryReadFromDirectory(result.HitsPath); return(CalculateFilesSummary( result.GetSourceFiles(), hitsInfo, threshold)); }
public async Task Execute() { var result = new InstrumentationResult(); _coverageLoadedFileOption.SetupGet(x => x.Result).Returns(result); _uninstrumenter.Setup(x => x.Uninstrument(result)); var exitCode = await Sut.Execute(); exitCode.Should().Be(0); }
public virtual int Execute(InstrumentationResult result, float threshold) { var hits = File.Exists(result.HitsFile) ? File.ReadAllLines(result.HitsFile).Select(h => int.Parse(h)).ToArray() : new int[0]; var files = result.Assemblies .SelectMany(assembly => assembly.Value.Files) .ToDictionary( x => x.Key, x => x.Value ); SetFileColumnLength(files.Keys.Select(s => s.Length).Concat(new[] { 10 }).Max()); WriteHeader(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Instructions .SelectMany(i => Enumerable.Range(i.StartLine, i.EndLine - i.StartLine + 1)) .Distinct() .Count(); var hitInstructions = kvFile.Value.Instructions.Where(h => hits.Contains(h.Id)).ToArray(); var coveredLines = hitInstructions .SelectMany(i => Enumerable.Range(i.StartLine, i.EndLine - i.StartLine + 1)) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; var coveragePercentage = (float)coveredLines / lines; var fileColor = coveragePercentage >= threshold ? ConsoleColor.Green : ConsoleColor.Red; WriteReport(kvFile, lines, coveredLines, coveragePercentage, fileColor); WriteDetailedReport(result, files, hits); } var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; var totalsColor = isHigherThanThreshold ? ConsoleColor.Green : ConsoleColor.Red; WriteFooter(totalLines, totalCoveredLines, totalCoveragePercentage, threshold, totalsColor); return(isHigherThanThreshold ? 0 : 1); }
public override void ReceiveValue(string value) { base.ReceiveValue(value); if (!FileInfo.Exists) { throw new ValidationException($"Coverage file does not exist '{FileInfo.FullName}'"); } var coverageFileString = _fileSystem.File.ReadAllText(FileInfo.FullName); Result = JsonConvert.DeserializeObject <InstrumentationResult>(coverageFileString); }
public async Task Execute() { var result = new InstrumentationResult(); var output = MockFor <IFileInfo>(); _coverageLoadedFileOption.SetupGet(x => x.Result).Returns(result); _coberturaOutputOption.SetupGet(x => x.FileInfo).Returns(output.Object); _coberturaReport.Setup(x => x.Execute(result, output.Object)); var exitCode = await Sut.Execute(); exitCode.Should().Be(0); }
protected override FileInfo PrepareValue(string value) { var fileInfo = base.PrepareValue(value); if (!fileInfo.Exists) { throw new FileNotFoundException($"Coverage file does not exist '{fileInfo.FullName}'"); } var coverageFileString = File.ReadAllText(fileInfo.FullName); Result = JsonConvert.DeserializeObject <InstrumentationResult>(coverageFileString); return(fileInfo); }
public async Task Execute(float threshold, bool noFail) { var result = new InstrumentationResult(); var output = MockFor <IDirectoryInfo>(); _coverageLoadedFileOption.SetupGet(x => x.Result).Returns(result); _thresholdOption.SetupGet(x => x.Value).Returns(threshold); _noFailOption.SetupGet(x => x.Value).Returns(noFail); _consoleReport.Setup(x => x.Execute(result, threshold, noFail)) .Returns(0); var exitCode = await Sut.Execute(); exitCode.Should().Be(0); }
private async Task SaveCoverageFileAsync(IFileInfo coverageFile, InstrumentationResult result) { var settings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }; var json = JsonConvert.SerializeObject(result, Formatting.Indented, settings); Directory.CreateDirectory( Path.GetDirectoryName(coverageFile.FullName) ?? throw new InvalidOperationException("Can't find directory name.")); await File.WriteAllTextAsync(coverageFile.FullName, json); _logger.LogInformation("Saved coverage file to: {CoverageFilePath}", coverageFile.FullName); }
private static XElement CreateCoverageElement(InstrumentationResult result, HitsInfo hitsInfo) { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var allLines = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .Where(h => hitsInfo.WasHit(h.HitId)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); var allBranches = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .SelectMany(i => i.Conditions) .SelectMany(c => c.Branches) .Count(); var coveredBranches = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .SelectMany(i => i.Conditions) .SelectMany(c => c.Branches) .Where(b => hitsInfo.WasHit(b.HitId)) .Count(); var lineRate = allLines == 0 ? 1d : (double)coveredLines / (double)allLines; var branchRate = allBranches == 0 ? 1d : (double)coveredBranches / (double)allBranches; return(new XElement( XName.Get("coverage"), new XAttribute(XName.Get("lines-valid"), allLines), new XAttribute(XName.Get("lines-covered"), coveredLines), new XAttribute(XName.Get("line-rate"), lineRate), new XAttribute(XName.Get("branches-valid"), allBranches), new XAttribute(XName.Get("branches-covered"), coveredBranches), new XAttribute(XName.Get("branch-rate"), branchRate), new XAttribute(XName.Get("complexity"), 0), new XAttribute(XName.Get("timestamp"), timestamp), new XAttribute(XName.Get("version"), "1.0.0"), CrateSourcesElement(result, hitsInfo), CratePackagesElement(result, hitsInfo) )); }
public virtual int Execute(InstrumentationResult result, float threshold) { var hits = File.Exists(result.HitsFile) ? File.ReadAllLines(result.HitsFile).Select(h => int.Parse(h)).ToHashSet() : new HashSet <int>(); var files = result.GetSourceFiles(); SetFileColumnLength(files.Keys.Select(s => s.Length).Concat(new[] { 10 }).Max()); WriteHeader(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Instructions .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = kvFile.Value.Instructions .Where(h => hits.Contains(h.Id)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; var coveragePercentage = (float)coveredLines / lines; var fileColor = coveragePercentage >= threshold ? ConsoleColor.Green : ConsoleColor.Red; WriteReport(kvFile, lines, coveredLines, coveragePercentage, fileColor); } WriteDetailedReport(result, files, hits); var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; var totalsColor = isHigherThanThreshold ? ConsoleColor.Green : ConsoleColor.Red; WriteFooter(totalLines, totalCoveredLines, totalCoveragePercentage, threshold, totalsColor); return(isHigherThanThreshold ? 0 : 1); }
public async Task Execute(string rootPath, string expectedRootPath) { rootPath = rootPath?.ToOSPath(); expectedRootPath = expectedRootPath?.ToOSPath(); var result = new InstrumentationResult(); _mockFileSystem.Directory.SetCurrentDirectory("/current-directory".ToOSPath()); Sut.OutputOption.ReceiveValue("coveralls.json"); Sut.RepoTokenOption.ReceiveValue("repo-token"); Sut.ServiceJobIdOption.ReceiveValue("service-job-id"); Sut.ServiceNameOption.ReceiveValue("service-name"); Sut.CommitMessageOption.ReceiveValue("commit-message"); Sut.RootPathOption.ReceiveValue(rootPath); Sut.CommitOption.ReceiveValue("commit"); Sut.CommitAuthorNameOption.ReceiveValue("commit-author-name"); Sut.CommitAuthorEmailOption.ReceiveValue("commit-author-email"); Sut.CommitCommitterNameOption.ReceiveValue("commit-committer-name"); Sut.CommitCommitterEmailOption.ReceiveValue("commit-committer-email"); Sut.BranchOption.ReceiveValue("branch"); Sut.RemoteOption.ReceiveValue("remote"); Sut.RemoteUrlOption.ReceiveValue("remote-url"); _coverageLoadedFileOption.SetupGet(x => x.Result).Returns(result); _coverallsReport.Setup(x => x.Execute( result, "coveralls.json", "repo-token", "service-job-id", "service-name", "commit-message", expectedRootPath, "commit", "commit-author-name", "commit-author-email", "commit-committer-name", "commit-committer-email", "branch", "remote", "remote-url")) .ReturnsAsync(0); var exitCode = await Sut.Execute(); exitCode.Should().Be(0); }
public virtual int Execute(InstrumentationResult result, float threshold) { var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); SetFileColumnLength(files.Keys.Select(s => s.Length).Concat(new[] { 10 }).Max()); WriteHeader(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Sequences .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = kvFile.Value.Sequences .Where(h => hits.WasHit(h.HitId)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; var coveragePercentage = (float)coveredLines / lines; var fileColor = coveragePercentage >= threshold ? ConsoleColor.Green : ConsoleColor.Red; WriteReport(kvFile, lines, coveredLines, coveragePercentage, fileColor); } WriteDetailedReport(result, files, hits); var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; var totalsColor = isHigherThanThreshold ? ConsoleColor.Green : ConsoleColor.Red; WriteFooter(totalLines, totalCoveredLines, totalCoveragePercentage, threshold, totalsColor); return(isHigherThanThreshold ? 0 : 1); }
public void Execute(InstrumentationResult result, IFileInfo output) { var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); var document = new XDocument( new XDeclaration("1.0", "utf-8", null), CreateCoverageElement(result, hits) ); var xmlWriterSettings = new XmlWriterSettings { Indent = true }; output.Directory.Create(); using (var sw = output.CreateText()) using (var writer = XmlWriter.Create(sw, xmlWriterSettings)) { document.WriteTo(writer); } }