private static PerDocumentSequencePoints GenerateSequencePointInfoImpl(IRunExecutorHost host, RunStartParams rsp) { var timeFilter = rsp.StartTime; var buildOutputRoot = rsp.Solution.BuildRoot.Item; Logger.LogInfo( "Generating sequence point info: Time filter - {0}, Build output root - {1}.", timeFilter.ToLocalTime(), buildOutputRoot); var perDocSP = new PerDocumentSequencePoints(); Engine.Engine.FindAndExecuteForEachAssembly( host, buildOutputRoot, timeFilter, (string assemblyPath) => { Logger.LogInfo("Generating sequence point info for {0}.", assemblyPath); var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { ReadSymbols = true }); VisitAllTypes( assembly.Modules, (m, t) => { FindSequencePointForType(rsp, perDocSP, m, t); }); }); return(perDocSP); }
public static void FindAndExecuteForEachAssembly(IRunExecutorHost host, string buildOutputRoot, DateTime timeFilter, Action <string> action, int?maxThreads = null) { int madDegreeOfParallelism = maxThreads.HasValue ? maxThreads.Value : Environment.ProcessorCount; Logger.LogInfo("FindAndExecuteForEachAssembly: Running with {0} threads.", madDegreeOfParallelism); var extensions = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { ".dll", ".exe" }; Parallel.ForEach( Directory.EnumerateFiles(buildOutputRoot, "*").Where(s => extensions.Contains(Path.GetExtension(s))), new ParallelOptions { MaxDegreeOfParallelism = madDegreeOfParallelism }, assemblyPath => { if (!File.Exists(Path.ChangeExtension(assemblyPath, ".pdb"))) { return; } var lastWriteTime = File.GetLastWriteTimeUtc(assemblyPath); if (lastWriteTime < timeFilter) { return; } Logger.LogInfo("FindAndExecuteForEachAssembly: Running for assembly {0}. LastWriteTime: {1}.", assemblyPath, lastWriteTime.ToLocalTime()); action(assemblyPath); }); }
private static RunStepResult DiscoverUnitTests(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { if (!host.CanContinue()) { throw new OperationCanceledException(); } var output = RunTestHost("discover", rsp); RunStepStatus rss = RunStepStatus.Succeeded; if (output.Item1 != 0) { rss = RunStepStatus.Failed; } var testsPerAssembly = PerDocumentLocationDTestCases.Deserialize(FilePath.NewFilePath(rsp.DataFiles.DiscoveredUnitDTestsStore.Item)); var totalTests = testsPerAssembly.Values.Aggregate(0, (acc, e) => acc + e.Count); TelemetryClient.TrackEvent(rsi.name.Item, new Dictionary <string, string>(), new Dictionary <string, double> { { "TestCount", totalTests } }); return(rss.ToRSR(RunData.NewTestCases(testsPerAssembly), "Unit Tests Discovered - which ones - TBD")); }
public static void Instrument(IRunExecutorHost host, RunStartParams rsp, Func <DocumentLocation, IEnumerable <DTestCase> > findTest) { try { InstrumentImpl(host, rsp, findTest); } catch (Exception e) { Logger.LogError("Failed to instrument. Exception: {0}", e); } }
public static PerDocumentSequencePoints GenerateSequencePointInfo(IRunExecutorHost host, RunStartParams rsp) { try { return(GenerateSequencePointInfoImpl(host, rsp)); } catch (Exception e) { Logger.LogError("Failed to instrument. Exception: {0}", e); } return(null); }
private static RunStepResult DiscoverSequencePoints(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { var sequencePoint = Instrumentation.GenerateSequencePointInfo(host, rsp); if (sequencePoint != null) { sequencePoint.Serialize(rsp.DataFiles.SequencePointStore); } var totalSP = sequencePoint.Values.Aggregate(0, (acc, e) => acc + e.Count); TelemetryClient.TrackEvent(rsi.name.Item, new Dictionary <string, string>(), new Dictionary <string, double> { { "SequencePointCount", totalSP } }); return(RunStepStatus.Succeeded.ToRSR(RunData.NewSequencePoints(sequencePoint), "Binaries Instrumented - which ones - TBD")); }
private static RunStepResult DeleteBuildOutput(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { if (Directory.Exists(rsp.Solution.BuildRoot.Item)) { foreach (var file in Directory.EnumerateFiles(rsp.Solution.BuildRoot.Item, "*.pdb")) { File.Delete(file); var dll = Path.ChangeExtension(file, "dll"); if (File.Exists(dll)) { File.Delete(dll); } } } return(RunStepStatus.Succeeded.ToRSR(RunData.NoData, "What was done - TBD")); }
private static RunStepResult TakeSolutionSnapshot(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { var solutionGrandParentPath = Path.GetDirectoryName(Path.GetDirectoryName(rsp.Solution.Path.Item)); var projects = VsSolution.GetProjects(host.HostVersion, rsp.Solution.Path.Item).ToList(); var toCopy = new List <Tuple <string, SearchOption> > { new Tuple <string, SearchOption>(Path.GetDirectoryName(rsp.Solution.Path.Item), SearchOption.TopDirectoryOnly), }; Array.ForEach(rsp.Config.SnapshotIncludeFolders, item => { toCopy.Add(new Tuple <string, SearchOption>(Path.Combine(Path.GetDirectoryName(rsp.Solution.Path.Item), item), SearchOption.AllDirectories)); }); projects.ForEach(p => { var projectFile = Path.Combine(Path.GetDirectoryName(rsp.Solution.Path.Item), p.RelativePath); var folder = Path.GetDirectoryName(projectFile); toCopy.Add(new Tuple <string, SearchOption>(folder, SearchOption.AllDirectories)); }); toCopy.ForEach(item => { if (!host.CanContinue()) { throw new OperationCanceledException(); } CopyFiles(rsp, solutionGrandParentPath, item.Item1, item.Item2); }); SnapshotGC.mark(FilePath.NewFilePath(Path.GetDirectoryName(rsp.Solution.SnapshotPath.Item))); TelemetryClient.TrackEvent(rsi.name.Item, new Dictionary <string, string>(), new Dictionary <string, double> { { "ProjectCount", projects.Count } }); return(RunStepStatus.Succeeded.ToRSR(RunData.NoData, "What was done - TBD")); }
private static RunStepResult RunTests(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { if (!host.CanContinue()) { throw new OperationCanceledException(); } var output = RunTestHost("execute", rsp); RunStepStatus rss = RunStepStatus.Succeeded; if (output.Item1 != 0) { rss = RunStepStatus.Failed; } var testResults = PerTestIdDResults.Deserialize(FilePath.NewFilePath(rsp.DataFiles.TestResultsStore.Item)); var coverageSession = PerSequencePointIdTestRunId.Deserialize(FilePath.NewFilePath(rsp.DataFiles.CoverageSessionStore.Item)); var testFailureInfo = PerDocumentLocationTestFailureInfo.Deserialize(FilePath.NewFilePath(rsp.DataFiles.TestFailureInfoStore.Item)); return(rss.ToRSR(RunData.NewTestRunOutput(testResults, testFailureInfo, coverageSession), output.Item2)); }
private static RunStepResult BuildSolutionSnapshot(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { var output = ExecuteProcess( Path.Combine( Environment.GetEnvironmentVariable("ProgramFiles(x86)"), string.Format(@"MSBuild\{0}\Bin\msbuild.exe", host.HostVersion)), string.Format( @"/m /v:minimal /p:DebugSymbols=true /p:DebugType=full /p:Optimize=false /p:Configuration=Debug /p:CreateVsixContainer=false /p:DeployExtension=false /p:CopyVsixExtensionFiles=false /p:RunCodeAnalysis=false {0} /p:OutDir=""{1}\\"" ""{2}""", string.Join(" ", (rsp.Config.AdditionalMSBuildProperties ?? new string[0]).Select(it => string.Format("/p:{0}", it))), rsp.Solution.BuildRoot.Item, rsp.Solution.SnapshotPath.Item) ); RunStepStatus rss = RunStepStatus.Succeeded; if (output.Item1 != 0) { rss = RunStepStatus.Failed; } return(rss.ToRSR(RunData.NoData, output.Item2)); }
private static void InstrumentImpl(IRunExecutorHost host, RunStartParams rsp, Func <DocumentLocation, IEnumerable <DTestCase> > findTest) { var timeFilter = rsp.StartTime; var solutionRoot = Path.GetDirectoryName(rsp.Solution.Path.Item); var buildOutputRoot = rsp.Solution.BuildRoot.Item; Logger.LogInfo( "Instrumenting: Time filter - {0}, Build output root - {1}.", timeFilter.ToLocalTime(), buildOutputRoot); System.Reflection.StrongNameKeyPair snKeyPair = null; var snKeyFile = Directory.EnumerateFiles(solutionRoot, "*.snk").FirstOrDefault(); if (snKeyFile != null) { snKeyPair = new System.Reflection.StrongNameKeyPair(File.ReadAllBytes(snKeyFile)); Logger.LogInfo("Using strong name from {0}.", snKeyFile); } var asmResolver = new DefaultAssemblyResolver(); Array.ForEach(asmResolver.GetSearchDirectories(), asmResolver.RemoveSearchDirectory); asmResolver.AddSearchDirectory(buildOutputRoot); var readerParams = new ReaderParameters { AssemblyResolver = asmResolver, ReadSymbols = true, }; string testRunnerPath = Path.GetFullPath(typeof(R4nd0mApps.TddStud10.TestRuntime.Marker).Assembly.Location); var enterSPMD = from t in ModuleDefinition.ReadModule(testRunnerPath).GetTypes() where t.Name == "Marker" from m in t.Methods where m.Name == "EnterSequencePoint" select m; var exitUTMD = from t in ModuleDefinition.ReadModule(testRunnerPath).GetTypes() where t.Name == "Marker" from m in t.Methods where m.Name == "ExitUnitTest" select m; Func <string, string> rebaseDocument = s => PathBuilder.rebaseCodeFilePath(rsp.Solution.Path, rsp.Solution.SnapshotPath, FilePath.NewFilePath(s)).Item; Engine.Engine.FindAndExecuteForEachAssembly( host, buildOutputRoot, timeFilter, (string assemblyPath) => { Logger.LogInfo("Instrumenting {0}.", assemblyPath); var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, readerParams); var hasSn = assembly.Name.HasPublicKey; /* * IL_0001: ldstr <assemblyId> * IL_0006: ldstr <mdtoken> * IL_000b: ldstr <spid> * IL_000d: call void R4nd0mApps.TddStud10.TestHost.Marker::ExitUnitTest(string, ldstr, ldstr) */ MethodReference enterSPMR = assembly.MainModule.Import(enterSPMD.First()); MethodReference exitUTMR = assembly.MainModule.Import(exitUTMD.First()); VisitAllTypes( assembly.Modules, (m, t) => { InstrumentType(rsp, findTest, assemblyPath, rebaseDocument, enterSPMR, exitUTMR, m, t); }); var backupAssemblyPath = Path.ChangeExtension(assemblyPath, ".original"); File.Delete(backupAssemblyPath); File.Move(assemblyPath, backupAssemblyPath); try { assembly.Write(assemblyPath, new WriterParameters { WriteSymbols = true, StrongNameKeyPair = hasSn ? snKeyPair : null }); } catch { Logger.LogInfo("Backing up or instrumentation failed. Attempting to revert back changes to {0}.", assemblyPath); File.Delete(assemblyPath); File.Move(backupAssemblyPath, assemblyPath); throw; } }, 1); }
private static RunStepResult RefreshTestRuntime(IRunExecutorHost host, RunStartParams rsp, RunStepInfo rsi) { var output = TestRunTimeInstaller.Install(rsp.Solution.BuildRoot.Item); return(RunStepStatus.Succeeded.ToRSR(RunData.NoData, string.Format("Copied Test Runtime: {0}", output))); }