private List <CoverageProject> GetCoverageProjects(TestConfiguration testConfiguration) { var userRunSettings = testConfiguration.UserRunSettings; var runSettingsRetriever = new RunSettingsRetriever(); var testContainers = testConfiguration.Containers; return(testConfiguration.Containers.Select(container => { var project = new CoverageProject(); project.ProjectName = container.ProjectName; project.TestDllFile = container.Source; project.Is64Bit = container.TargetPlatform.ToString().ToLower().Equals("x64"); var containerData = container.ProjectData; project.ProjectFile = container.ProjectData.ProjectFilePath; project.RunSettingsFile = ThreadHelper.JoinableTaskFactory.Run(() => runSettingsRetriever.GetRunSettingsFileAsync(userRunSettings, containerData)); return project; }).ToList()); }
private void OperationState_StateChanged(object sender, OperationStateChangedEventArgs e) { try { if (e.State == TestOperationStates.TestExecutionStarting) { StopCoverageProcess(); // just to be sure } if (e.State == TestOperationStates.TestExecutionFinished) { var settings = AppOptions.Get(); if (!settings.Enabled) { FCCEngine.CoverageLines.Clear(); UpdateMarginTags?.Invoke(this, null); UpdateOutputWindow?.Invoke(this, null); return; } Logger.Log("================================== START =================================="); var darkMode = CurrentTheme.Equals("Dark", StringComparison.OrdinalIgnoreCase); CoverageProject[] projects = null; try { var testConfiguration = new Operation(e.Operation).Configuration; var userRunSettings = testConfiguration.UserRunSettings; var runSettingsRetriever = new RunSettingsRetriever(); var testContainers = testConfiguration.Containers; projects = testConfiguration.Containers.Select(container => { var project = new CoverageProject(); project.ProjectName = container.ProjectName; project.TestDllFile = container.Source; project.Is64Bit = container.TargetPlatform.ToString().ToLower().Equals("x64"); var containerData = container.ProjectData; project.ProjectFile = container.ProjectData.ProjectFilePath; project.RunSettingsFile = ThreadHelper.JoinableTaskFactory.Run(() => runSettingsRetriever.GetRunSettingsFileAsync(userRunSettings, containerData)); return(project); }).ToArray(); }catch (Exception exc) { throw new Exception("Error test container discoverer reflection", exc); } _reloadCoverageThread = new Thread(() => { try { // compute coverage FCCEngine.ReloadCoverage(projects, darkMode); // update margins { UpdateMarginTagsEventArgs updateMarginTagsEventArgs = null; try { updateMarginTagsEventArgs = new UpdateMarginTagsEventArgs { }; } catch { // ignore } finally { UpdateMarginTags?.Invoke(this, updateMarginTagsEventArgs); } } // update output window { UpdateOutputWindowEventArgs updateOutputWindowEventArgs = null; try { updateOutputWindowEventArgs = new UpdateOutputWindowEventArgs { HtmlContent = File.ReadAllText(FCCEngine.HtmlFilePath) }; } catch { // ignore } finally { UpdateOutputWindow?.Invoke(this, updateOutputWindowEventArgs); } } // log Logger.Log("================================== DONE ==================================="); } catch (Exception exception) { if (!(exception is ThreadAbortException) && _reloadCoverageThread != null) { Logger.Log("Error", exception); Logger.Log("================================== ERROR =================================="); } } }); _reloadCoverageThread.Start(); } } catch (Exception exception) { Logger.Log("Error processing unit test events", exception); } }
public static void LoadCoverageFromTestDllFile(string testDllFile, Action <Exception> callback = null) { ThreadPool.QueueUserWorkItem(x => { try { // project folder var testProjectFolder = GetProjectFolderFromPath(testDllFile); if (string.IsNullOrWhiteSpace(testProjectFolder)) { throw new Exception("Could not establish project folder"); } // coverage folder var coverageFolder = Path.Combine(TempFolder, ConvertPathToName(testProjectFolder)); if (!Directory.Exists(coverageFolder)) { Directory.CreateDirectory(coverageFolder); } // coverage file var coverageFile = Path.Combine(coverageFolder, "coverage.json"); if (File.Exists(coverageFile)) { File.Delete(coverageFile); } // sync built files to coverage folder var buildFolder = Path.GetDirectoryName(testDllFile); FileSynchronizationUtil.Synchronize(buildFolder, coverageFolder); // coverage process RunCoverlet(testDllFile, coverageFolder, coverageFile); // reload var coverageFileContent = File.ReadAllText(coverageFile); var coverageFileJObject = JObject.Parse(coverageFileContent); foreach (var coverageDllFileProperty in coverageFileJObject.Properties()) { var coverageDllFileJObject = (JObject)coverageDllFileProperty.Value; foreach (var sourceFileProperty in coverageDllFileJObject.Properties()) { var sourceFilePath = sourceFileProperty.Name; var projectFolderPath = GetProjectFolderFromPath(sourceFilePath); if (string.IsNullOrWhiteSpace(projectFolderPath)) { continue; } var sourceFileProject = CoverageProjects.SingleOrDefault(pr => pr.FolderPath.Equals(projectFolderPath, StringComparison.OrdinalIgnoreCase)); if (sourceFileProject == null) { sourceFileProject = new CoverageProject { FolderPath = projectFolderPath }; CoverageProjects.Add(sourceFileProject); } var sourceFile = sourceFileProject.SourceFiles.SingleOrDefault(sf => sf.FilePath.Equals(sourceFilePath, StringComparison.OrdinalIgnoreCase)); if (sourceFile == null) { sourceFile = new CoverageSourceFile { FilePath = sourceFilePath }; sourceFileProject.SourceFiles.Add(sourceFile); } sourceFile.Lines.Clear(); var sourceFileJObject = (JObject)sourceFileProperty.Value; foreach (var classProperty in sourceFileJObject.Properties()) { var className = classProperty.Name; var classJObject = (JObject)classProperty.Value; foreach (var methodProperty in classJObject.Properties()) { var methodName = methodProperty.Name; var methodJObject = (JObject)methodProperty.Value; var linesJObject = (JObject)methodJObject["Lines"]; foreach (var lineProperty in linesJObject.Properties()) { var lineNumber = int.Parse(lineProperty.Name); var lineHitCount = lineProperty.Value.Value <int>(); sourceFile.Lines.Add(new CoverageLine { ClassName = className, MethodName = methodName, LineNumber = lineNumber, HitCount = lineHitCount }); } } } } } // callback callback?.Invoke(null); } catch (Exception ex) { callback?.Invoke(ex); } }); }
private void OperationState_StateChanged(object sender, OperationStateChangedEventArgs e) { try { if (e.State == TestOperationStates.TestExecutionStarting) { try { _reloadCoverageThread?.Abort(); } catch { // ignore } finally { _reloadCoverageThread = null; FCCEngine.ClearProcesses(); } } if (e.State == TestOperationStates.TestExecutionFinished) { var settings = AppOptions.Get(); if (!settings.Enabled) { FCCEngine.CoverageLines.Clear(); UpdateMarginTags?.Invoke(this, null); UpdateOutputWindow?.Invoke(this, null); return; } Logger.Log("================================== START =================================="); var operationType = e.Operation.GetType(); var darkMode = CurrentTheme.Equals("Dark", StringComparison.OrdinalIgnoreCase); var testConfiguration = (operationType.GetProperty("Configuration") ?? operationType.GetProperty("Configuration", BindingFlags.Instance | BindingFlags.NonPublic)).GetValue(e.Operation); var testContainers = ((IEnumerable <object>)testConfiguration.GetType().GetProperty("Containers").GetValue(testConfiguration)).ToArray(); var projects = new List <CoverageProject>(); foreach (var container in testContainers) { var project = new CoverageProject(); var containerType = container.GetType(); var containerData = containerType.GetProperty("ProjectData").GetValue(container); var containerDataType = containerData.GetType(); project.ProjectGuid = containerType.GetProperty("ProjectGuid").GetValue(container).ToString(); project.ProjectName = containerType.GetProperty("ProjectName").GetValue(container).ToString(); project.TestDllFileInOutputFolder = containerType.GetProperty("Source").GetValue(container).ToString(); project.TestDllCompilationMode = AssemblyUtil.GetCompilationMode(project.TestDllFileInOutputFolder); project.ProjectFile = containerDataType.GetProperty("ProjectFilePath", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic).GetValue(containerData).ToString(); var defaultOutputFolder = Path.GetDirectoryName(containerDataType.GetProperty("DefaultOutputPath", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic).GetValue(containerData).ToString()); project.WorkFolder = Path.Combine(Path.GetDirectoryName(defaultOutputFolder), "fine-code-coverage"); projects.Add(project); } _reloadCoverageThread = new Thread(() => { try { // compute coverage FCCEngine.ReloadCoverage(projects.ToArray(), darkMode); // update margins { UpdateMarginTagsEventArgs updateMarginTagsEventArgs = null; try { updateMarginTagsEventArgs = new UpdateMarginTagsEventArgs { }; } catch { // ignore } finally { UpdateMarginTags?.Invoke(this, updateMarginTagsEventArgs); } } // update output window { UpdateOutputWindowEventArgs updateOutputWindowEventArgs = null; try { updateOutputWindowEventArgs = new UpdateOutputWindowEventArgs { HtmlContent = File.ReadAllText(FCCEngine.HtmlFilePath) }; } catch { // ignore } finally { UpdateOutputWindow?.Invoke(this, updateOutputWindowEventArgs); } } // log Logger.Log("================================== DONE ==================================="); } catch (Exception exception) { if (!(exception is ThreadAbortException) && _reloadCoverageThread != null) { Logger.Log("Error", exception); Logger.Log("================================== ERROR =================================="); } } }); _reloadCoverageThread.Start(); } } catch (Exception exception) { Logger.Log("Error processing unit test events", exception); } }