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);
        }
Example #2
0
        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);
            });
        }
Example #3
0
        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);
        }
Example #6
0
        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"));
        }
Example #7
0
        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"));
        }
Example #8
0
        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"));
        }
Example #9
0
        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));
        }
Example #10
0
        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);
        }
Example #12
0
        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)));
        }