public CanonicalTrackedInputFiles(ITask ownerTask, ITaskItem[] tlogFiles, ITaskItem[] sourceFiles, ITaskItem[] excludedInputPaths, CanonicalTrackedOutputFiles outputs, bool useMinimalRebuildOptimization, bool maintainCompositeRootingMarkers)
 {
     this.outputNewestTime = DateTime.MinValue;
     this.outputNewest = "";
     this.excludedInputPaths = new HashSet<string>(StringComparer.Ordinal);
     this.lastWriteTimeCache = new ConcurrentDictionary<string, DateTime>(StringComparer.Ordinal);
     this.InternalConstruct(ownerTask, tlogFiles, sourceFiles, null, excludedInputPaths, outputs, useMinimalRebuildOptimization, maintainCompositeRootingMarkers);
 }
Пример #2
0
		protected override bool ComputeOutOfDateSources()
		{
			// Same as base class, other than the things commented out.
			// We're not using CustomTrackedVCToolTask's File Tracker, we're using our own. Hence these changes.

			if (this.TrackerIntermediateDirectory != null)
			{
				string trackerIntermediateDirectory = this.TrackerIntermediateDirectory;
			}
			if (this.MinimalRebuildFromTracking || this.TrackFileAccess)
			{
				this.AssignDefaultTLogPaths();
			}
			if (this.MinimalRebuildFromTracking && !this.ForcedRebuildRequired())
			{
				CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, this.TLogWriteFiles);
				this.SourceDependencies = new CanonicalTrackedInputFiles(this, this.TLogReadFiles, this.Sources /*TrackedInputFiles*/, this.ExcludedInputPaths, outputs, /*this.UseMinimalRebuildOptimization*/ true, /*this.MaintainCompositeRootingMarkers*/ false);
				ITaskItem[] sourcesOutOfDateThroughTracking = this.SourceDependencies.ComputeSourcesNeedingCompilation(/*false*/);
				List<ITaskItem> sourcesWithChangedCommandLines = this.GenerateSourcesOutOfDateDueToCommandLine();
				this.SourcesCompiled = this.MergeOutOfDateSourceLists(sourcesOutOfDateThroughTracking, sourcesWithChangedCommandLines);
				if (this.SourcesCompiled.Length == 0)
				{
					this.SkippedExecution = true;
					return this.SkippedExecution;
				}
				this.SourcesCompiled = this.AssignOutOfDateSources(this.SourcesCompiled);
				this.SourceDependencies.RemoveEntriesForSource(this.SourcesCompiled);
				this.SourceDependencies.SaveTlog();
				outputs.RemoveEntriesForSource(this.SourcesCompiled);
				outputs.SaveTlog();
			}
			else
			{
				this.SourcesCompiled = this.TrackedInputFiles;
				if ((this.SourcesCompiled == null) || (this.SourcesCompiled.Length == 0))
				{
					this.SkippedExecution = true;
					return this.SkippedExecution;
				}
			}

//			if (this.TrackFileAccess)
//			{
//				this.RootSource = FileTracker.FormatRootingMarker(this.SourcesCompiled);
//			}

			this.SkippedExecution = false;
			return this.SkippedExecution;
		}
Пример #3
0
        public void WriteTLogWithInitialEmptyLine()
        {
            Console.WriteLine("Test: WriteTLogWithInitialEmptyLine");

            // Prepare files
            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "", "^FOO" });
            MockTask task = DependencyTestHelper.MockTask;

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles
                (
                    task,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))
                );

            Assert.Equal(1, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should have a warning."
            Assert.Equal(0, d.DependencyTable.Count); // "DependencyTable should be empty."
        }
Пример #4
0
        public void RootContainsSubRoots()
        {
            Console.WriteLine("Test: RootContainsSubRoots");
            CanonicalTrackedOutputFiles output = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    null);

            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "a|b|C|d|e|F|g"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "a"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "g"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "d"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "a|b"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "f|g"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "b|a"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "g|f"));
            Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "b|e"));
        }
Пример #5
0
        public void RemoveRootsWithSharedOutputs_CurrentRootNotInTable()
        {
            Console.WriteLine("Test: RemoveRootsWithSharedOutputs");

            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.tlh", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.tli", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register

            string rootingMarker1 = Path.GetFullPath("TestFiles\\one.cpp") + "|" + Path.GetFullPath("TestFiles\\three.cpp") + "|" + Path.GetFullPath("TestFiles\\two.cpp");
            string rootingMarker2 = Path.GetFullPath("TestFiles\\one.cpp") + "|" + Path.GetFullPath("TestFiles\\three.cpp");
            string rootingMarker3 = Path.GetFullPath("TestFiles\\one.cpp");

            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + rootingMarker1.ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + rootingMarker2.ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one3.obj"),
                Path.GetFullPath("TestFiles\\one3.tlh"),
                Path.GetFullPath("TestFiles\\one3.tli"),
                "^" + rootingMarker3.ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.obj"),
            });

            CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker1));
            Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker2));
            Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker3));

            outputs.RemoveRootsWithSharedOutputs(new ITaskItem[] { new TaskItem("TestFiles\\four.cpp"), new TaskItem("TestFiles\\one.cpp"), new TaskItem("TestFiles\\three.cpp"), new TaskItem("TestFiles\\two.cpp") });

            Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker1));
            Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker2));
            Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker3));
        }
Пример #6
0
        public void OutputSingleCanonicalCLAcrossTlogs()
        {
            Console.WriteLine("Test: OutputSingleCanonicalCLAcrossTlogs");
            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\oNe.obj"),
            });

            File.WriteAllLines("TestFiles\\two.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one.pch"),
            });

            ITaskItem[] tlogs = {
                                    new TaskItem("TestFiles\\one.tlog"),
                                    new TaskItem("TestFiles\\two.tlog")
                                };

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    tlogs);

            ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")));

            Assert.Equal(2, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\one.pch"));
        }
Пример #7
0
        public void OutputMultipleUnrecognisedRootCanonicalCL()
        {
            Console.WriteLine("Test: OutputMultipleUnrecognisedRootCanonicalCL");

            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp") + "|" + Path.GetFullPath("TestFiles\\two.cpp") + "|" + Path.GetFullPath("TestFiles\\three.cpp"),
                Path.GetFullPath("TestFiles\\oNe.obj"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
            });

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")));

            ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")));

            Assert.Equal(0, outputs.Length);
        }
Пример #8
0
        public void OutputMultipleCanonicalCLLongTempPath()
        {
            Console.WriteLine("Test: OutputMultipleCanonicalCLLongTempPath");

            ITaskItem[] sources = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))};

            string oldTempPath = Environment.GetEnvironmentVariable("TEMP");
            string oldTmpPath = Environment.GetEnvironmentVariable("TMP");
            string newTempPath = Path.GetFullPath("TestFiles\\ThisIsAReallyVeryLongTemporaryPlace\\ThatIsLongerThanTheSourcePaths");

            Directory.CreateDirectory(newTempPath);
            Environment.SetEnvironmentVariable("TEMP", newTempPath);
            Environment.SetEnvironmentVariable("TMP", newTempPath);

            Console.WriteLine("Test: OutputMultipleCanonicalCL");

            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + FileTracker.FormatRootingMarker(sources),
                Path.GetFullPath("TestFiles\\oNe.obj"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
            });

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")));

            ITaskItem[] outputs = d.OutputsForSource(sources);

            Environment.SetEnvironmentVariable("TEMP", oldTempPath);
            Environment.SetEnvironmentVariable("TMP", oldTmpPath);

            Assert.Equal(3, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj"));
            Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj"));
        }
Пример #9
0
        public void MultipleCanonicalCLMissingOutputDependencyRemoved()
        {
            Console.WriteLine("Test: MultipleCanonicalCLMissingOutputDependencyRemoved");
            // Prepare files
            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.cpp", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.obj", "");

            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
            });

            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one.obj"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\sometempfile2.obj")
            });

            string missing = Path.GetFullPath("TestFiles\\sometempfile2.obj");

            CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));
            // Save out the compacted read log - our missing dependency will be compacted away
            // Use an anonymous method to encapsulate the contains check for the tlogs
            compactOutputs.SaveTlog(delegate (string fullTrackedPath)
            {
                // We need to answer the question "should fullTrackedPath be included in the TLog?"
                return (String.Compare(fullTrackedPath, missing, StringComparison.OrdinalIgnoreCase) != 0);
            });

            // Read the Tlogs back in..
            compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));
            // Compact the read tlog
            CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    new TaskItem[] { new TaskItem("TestFiles\\one.cpp"), new TaskItem("TestFiles\\two.cpp") },
                    null,
                    compactOutputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            compactInputs.SaveTlog();

            ITaskItem[] outofDate = compactInputs.ComputeSourcesNeedingCompilation();
            Assert.Equal(0, outofDate.Length);
        }
Пример #10
0
        private CanonicalTrackedOutputFiles ConstructWriteTLog( ITaskItem[] upToDateSources )
        {
            // Remove any files we're about to compile from the log
            TaskItem item = new TaskItem( Path.Combine( TrackerIntermediateDirectory, WriteTLogNames[0] ) );
            CanonicalTrackedOutputFiles files = new CanonicalTrackedOutputFiles( new TaskItem[] { item } );
            files.RemoveEntriesForSource( Sources );

            // Add in the files we're compiling right now. Essentially just updating their output object filenames.
            foreach ( ITaskItem sourceItem in upToDateSources )
            {
                string sourcePath = Path.GetFullPath( sourceItem.ItemSpec ).ToUpperInvariant();
                string objectFile = Path.GetFullPath( sourceItem.GetMetadata( "ObjectFileName" ) ).ToUpperInvariant();
                files.AddComputedOutputForSourceRoot( sourcePath, objectFile );
            }

            // Save it out
            files.SaveTlog();

            // Pass onto the ReadTLog saving
            return files;
        }
Пример #11
0
        private void ConstructReadTLog( ITaskItem[] upToDateSources, CanonicalTrackedOutputFiles outputs )
        {
            string readTrackerPath = Path.GetFullPath( TrackerIntermediateDirectory + "\\" + ReadTLogNames[0] );

            // Rewrite out read log, with the sources we're *not* compiling right now.
            TaskItem readTrackerItem = new TaskItem( readTrackerPath );
            CanonicalTrackedInputFiles files = new CanonicalTrackedInputFiles(new TaskItem[] { readTrackerItem }, Sources, outputs, false, false);
            files.RemoveEntriesForSource(Sources);
            files.SaveTlog();

            // Now append onto the read log the sources we're compiling. It'll parse the .d files for each compiled file, so we know the
            // dependency header files associated with it, these will be recorded in the logfile.
            using ( StreamWriter writer = new StreamWriter( readTrackerPath, true, Encoding.Unicode ) )
            {
                foreach ( ITaskItem sourceItem in upToDateSources )
                {
                    string itemSpec = sourceItem.ItemSpec;
                    string sourcePath = Path.GetFullPath( sourceItem.ItemSpec ).ToUpperInvariant();
                    string objectFile = Path.GetFullPath( sourceItem.GetMetadata( "ObjectFileName" ) );
                    string dotDFile = Path.GetFullPath( Path.GetDirectoryName( objectFile ) + "\\" + Path.GetFileNameWithoutExtension( objectFile ) + ".d" );

                    try
                    {
                        writer.WriteLine("^" + sourcePath);
                        if (File.Exists(dotDFile))
                        {
                            DepFileParse depFileParse = new DepFileParse(dotDFile);

                            foreach (string dependentFile in depFileParse.DependentFiles)
                            {
                                if (dependentFile != sourcePath)
                                {
                                    if (File.Exists(dependentFile) == false)
                                    {
                                        Log.LogMessage(MessageImportance.High, "File " + sourcePath + " is missing dependent file: " + dependentFile);
                                    }

                                    writer.WriteLine(dependentFile);
                                }
                            }

                            // Done with this .d file. So delete it
                            try
                            {
                                File.Delete(dotDFile);
                            }
                            finally
                            {

                            }
                        }
                        else if (File.Exists(objectFile))
                        {
                            Log.LogMessage(MessageImportance.High, "File " + sourcePath + " is missing it's .d file: " + dotDFile);
                        }
                    }
                    catch ( Exception )
                    {
                        Log.LogError( "Failed processing dependencies in: " + dotDFile );
                    }
                }
            }
        }
Пример #12
0
 protected virtual void RemoveTaskSpecificOutputs(CanonicalTrackedOutputFiles compactOutputs)
 {
 }
Пример #13
0
 //         private void BeginUnicodeOutput()
 //         {
 //             this.unicodePipeReadHandle = null;
 //             this.unicodePipeWriteHandle = null;
 //             this.unicodeOutputEnded = null;
 //             if (this.UseUnicodeOutput)
 //             {
 //                 NativeMethodsShared.SecurityAttributes lpPipeAttributes = new NativeMethodsShared.SecurityAttributes {
 //                     lpSecurityDescriptor = NativeMethodsShared.NullIntPtr,
 //                     bInheritHandle = true
 //                 };
 //                 if (NativeMethodsShared.CreatePipe(out this.unicodePipeReadHandle, out this.unicodePipeWriteHandle, lpPipeAttributes, 0))
 //                 {
 //                     List<string> list = new List<string>();
 //                     if (base.EnvironmentVariables != null)
 //                     {
 //                         list.AddRange(base.EnvironmentVariables);
 //                     }
 //                     list.Add("VS_UNICODE_OUTPUT=" + this.unicodePipeWriteHandle.DangerousGetHandle());
 //                     base.EnvironmentVariables = list.ToArray();
 //                     this.unicodeOutputEnded = new AutoResetEvent(false);
 //                     ThreadPool.QueueUserWorkItem(new WaitCallback(this.ReadUnicodeOutput));
 //                 }
 //                 else
 //                 {
 //                     base.Log.LogWarningWithCodeFromResources("TrackedVCToolTask.CreateUnicodeOutputPipeFailed", new object[] { this.ToolName });
 //                 }
 //             }
 //         }
 /*internal*/
 protected virtual bool ComputeOutOfDateSources()
 {
     if (this.TrackerIntermediateDirectory != null)
     {
         string trackerIntermediateDirectory = this.TrackerIntermediateDirectory;
     }
     if (this.MinimalRebuildFromTracking || this.TrackFileAccess)
     {
         this.AssignDefaultTLogPaths();
     }
     if (this.MinimalRebuildFromTracking && !this.ForcedRebuildRequired())
     {
         CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, this.TLogWriteFiles);
         this.sourceDependencies = new CanonicalTrackedInputFiles(this, this.TLogReadFiles, this.TrackedInputFiles, this.ExcludedInputPaths, outputs, this.UseMinimalRebuildOptimization, this.MaintainCompositeRootingMarkers);
         ITaskItem[] sourcesOutOfDateThroughTracking = this.SourceDependencies.ComputeSourcesNeedingCompilation(false);
         List<ITaskItem> sourcesWithChangedCommandLines = this.GenerateSourcesOutOfDateDueToCommandLine();
         this.SourcesCompiled = this.MergeOutOfDateSourceLists(sourcesOutOfDateThroughTracking, sourcesWithChangedCommandLines);
         if (this.SourcesCompiled.Length == 0)
         {
             this.SkippedExecution = true;
             return this.SkippedExecution;
         }
         this.SourcesCompiled = this.AssignOutOfDateSources(this.SourcesCompiled);
         this.SourceDependencies.RemoveEntriesForSource(this.SourcesCompiled);
         this.SourceDependencies.SaveTlog();
         outputs.RemoveEntriesForSource(this.SourcesCompiled);
         outputs.SaveTlog();
     }
     else
     {
         this.SourcesCompiled = this.TrackedInputFiles;
         if ((this.SourcesCompiled == null) || (this.SourcesCompiled.Length == 0))
         {
             this.SkippedExecution = true;
             return this.SkippedExecution;
         }
     }
     if (this.TrackFileAccess)
     {
         this.RootSource = FileTracker.FormatRootingMarker(this.SourcesCompiled);
     }
     this.SkippedExecution = false;
     return this.SkippedExecution;
 }
Пример #14
0
 protected virtual void AddTaskSpecificOutputs(ITaskItem[] sources, CanonicalTrackedOutputFiles compactOutputs)
 {
 }
 public CanonicalTrackedInputFiles(ITask ownerTask, ITaskItem[] tlogFiles, ITaskItem sourceFile, ITaskItem[] excludedInputPaths, CanonicalTrackedOutputFiles outputs, bool useMinimalRebuildOptimization, bool maintainCompositeRootingMarkers)
 {
     this.outputNewestTime   = DateTime.MinValue;
     this.outputNewest       = "";
     this.excludedInputPaths = new HashSet <string>(StringComparer.Ordinal);
     this.lastWriteTimeCache = new ConcurrentDictionary <string, DateTime>(StringComparer.Ordinal);
     ITaskItem[] sourceFiles = new ITaskItem[] { sourceFile };
     this.InternalConstruct(ownerTask, tlogFiles, sourceFiles, null, excludedInputPaths, outputs, useMinimalRebuildOptimization, maintainCompositeRootingMarkers);
 }
 private void InternalConstruct(ITask ownerTask, ITaskItem[] tlogFiles, ITaskItem[] sourceFiles, ITaskItem[] outputFiles, ITaskItem[] excludedInputPaths, CanonicalTrackedOutputFiles outputs, bool useMinimalRebuildOptimization, bool maintainCompositeRootingMarkers)
 {
     if (ownerTask != null)
     {
         this.Log = new TaskLoggingHelper(ownerTask);
         this.Log.TaskResources     = AssemblyResources.PrimaryResources;
         this.Log.HelpKeywordPrefix = "MSBuild.";
     }
     this.tlogFiles     = TrackedDependencies.ExpandWildcards(tlogFiles);
     this.tlogAvailable = TrackedDependencies.ItemsExist(this.tlogFiles);
     this.sourceFiles   = sourceFiles;
     this.outputs       = outputs;
     this.outputFiles   = outputFiles;
     this.useMinimalRebuildOptimization   = useMinimalRebuildOptimization;
     this.maintainCompositeRootingMarkers = maintainCompositeRootingMarkers;
     if (excludedInputPaths != null)
     {
         foreach (ITaskItem item in excludedInputPaths)
         {
             string str = FileUtilities.EnsureNoTrailingSlash(FileUtilities.NormalizePath(item.ItemSpec)).ToUpperInvariant();
             this.excludedInputPaths.Add(str);
         }
     }
     this.dependencyTable = new Dictionary <string, Dictionary <string, string> >(StringComparer.OrdinalIgnoreCase);
     if (this.tlogFiles != null)
     {
         this.ConstructDependencyTable();
     }
 }
Пример #17
0
        public void ExcludeSpecificDirectory()
        {
            Console.WriteLine("Test: ExcludeSpecificDirectory");

            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\three.cpp", "");

            Thread.Sleep(sleepTimeMilliseconds);

            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\three.obj", "");

            Thread.Sleep(sleepTimeMilliseconds);

            Directory.CreateDirectory("TestFiles\\Foo");
            DependencyTestHelper.WriteAll("TestFiles\\Foo\\one2.h", "");

            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register

            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\Foo\\one2.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one3.h").ToUpperInvariant(),
                "^" + Path.GetFullPath("TestFiles\\two.cpp").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\Foo\\one2.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one3.h").ToUpperInvariant(),
                "^" + Path.GetFullPath("TestFiles\\three.cpp").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\Foo\\one2.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one3.h").ToUpperInvariant(),
            });

            // Our source files
            ITaskItem[] sources = {
                                    new TaskItem("TestFiles\\one.cpp"),
                                    new TaskItem("TestFiles\\two.cpp"),
                                    new TaskItem("TestFiles\\three.cpp"),
                                };

            // Prepare write tlog
            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one.obj").ToUpperInvariant(),
                "^" + Path.GetFullPath("TestFiles\\two.cpp").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\two.obj").ToUpperInvariant(),
                "^" + Path.GetFullPath("TestFiles\\three.cpp").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\three.obj").ToUpperInvariant(),
            });

            // Represent our tracked and computed outputs
            CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            // Represent our tracked and provided inputs
            CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    sources,
                    new TaskItem[] { new TaskItem(Path.GetFullPath("TeSTfiles\\Foo")) },
                    outputs,
                    true, /* minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            // All things should be up to date
            ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation();
            Assert.Equal(0, outofdate.Length);
        }
Пример #18
0
        protected virtual CanonicalTrackedOutputFiles OutputWriteTLog(ITaskItem[] inputs)
        {
            string path = Path.Combine(TlogDirectory, WriteTLogFilename);
            TaskItem item = new TaskItem(path);
            CanonicalTrackedOutputFiles trackedFiles =
                new CanonicalTrackedOutputFiles(new TaskItem[] { item });

            foreach (ITaskItem sourceItem in Sources)
            {
                //remove this entry associated with compiled source which is about to be recomputed
                trackedFiles.RemoveEntriesForSource(sourceItem);

                //add entry with updated information
                string upper = Path.GetFullPath(sourceItem.ItemSpec).ToUpperInvariant();
                trackedFiles.AddComputedOutputForSourceRoot(upper, OutputFile);
            }

            //output tlog
            trackedFiles.SaveTlog();

            return trackedFiles;
        }
Пример #19
0
        public void OutputCLMinimalRebuildOptimizationComputed()
        {
            Console.WriteLine("Test: OutputCLMinimalRebuildOptimizationComputed");

            // Prepare read tlog
            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\three.cpp", "");
            Thread.Sleep(sleepTimeMilliseconds);
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\three.obj", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + Path.GetFullPath("TestFiles\\three.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
            });

            // Our source files
            ITaskItem[] sources = {
                                    new TaskItem("TestFiles\\one.cpp"),
                                    new TaskItem("TestFiles\\two.cpp"),
                                    new TaskItem("TestFiles\\three.cpp"),
                                };

            // Prepare write tlog
            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + FileTracker.FormatRootingMarker(sources),
                Path.GetFullPath("TestFiles\\one.obj"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
            });

            // Represent our tracked and computed outputs
            CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            // "Compute" the additional output information for this compilation, rather than them being tracked
            outputs.AddComputedOutputForSourceRoot(Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"));
            outputs.AddComputedOutputForSourceRoot(Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\two.obj"));
            outputs.AddComputedOutputForSourceRoot(Path.GetFullPath("TestFiles\\three.cpp"), Path.GetFullPath("TestFiles\\three.obj"));

            // Represent our tracked and provided inputs
            CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    sources,
                    null,
                    outputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            // First of all, all things should be up to date
            ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation();
            Assert.Equal(0, outofdate.Length);

            // Delete one of the outputs in the group
            File.Delete(Path.GetFullPath("TestFiles\\two.obj"));

            // With optimization off, all sources in the group will need compilation
            d.SourcesNeedingCompilation = null;
            outofdate = d.ComputeSourcesNeedingCompilation();
            Assert.Equal(3, outofdate.Length);

            // With optimization on, only the source that matches the output will need compilation
            d = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    sources,
                    null,
                    outputs,
                    true, /* enable minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            outofdate = d.ComputeSourcesNeedingCompilation();
            Assert.Equal(1, outofdate.Length);
            // And the source is.. two.cpp!
            Assert.Equal(outofdate[0].ItemSpec, "TestFiles\\two.cpp");
        }
Пример #20
0
        protected virtual void OutputReadTLog(ITaskItem[] compiledSources,
                                              CanonicalTrackedOutputFiles outputs)
        {
            string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilenames[0]);

            using (var writer = new StreamWriter(trackerPath, false, Encoding.Unicode))
            {
                string sourcePath = "";
                foreach (ITaskItem source in Sources)
                {
                    if (sourcePath != "")
                        sourcePath += "|";
                    sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvariant();
                }

                writer.WriteLine("^" + sourcePath);
                foreach (ITaskItem source in Sources)
                {
                    writer.WriteLine(Path.GetFullPath(source.ItemSpec).ToUpperInvariant());
                }
                writer.WriteLine(Path.GetFullPath(OutputFile).ToUpperInvariant());
            }
        }
Пример #21
0
        public void OutputMultipleCanonicalCLSubrootMisMatch()
        {
            Console.WriteLine("Test: OutputMultipleCanonicalCLSubrootMisMatch");

            // sources is NOT a subset of source
            ITaskItem[] sources = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))};
            ITaskItem[] sources2 = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\five.cpp"))};
            ITaskItem[] sources2Match = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\five.cpp"))};
            ITaskItem[] sourcesPlusOne = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\eight.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))};

            // Do note sources2Match and source2 is missing three.cpp.  It is to test if the RootContainsAllSubRootComponents can handle the case.

            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + FileTracker.FormatRootingMarker(sources),
                Path.GetFullPath("TestFiles\\oNe.obj"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
                "^" + FileTracker.FormatRootingMarker(sources2),
                Path.GetFullPath("TestFiles\\fOUr.obj"),
                Path.GetFullPath("TestFiles\\fIve.obj"),
                Path.GetFullPath("TestFiles\\sIx.obj"),
                Path.GetFullPath("TestFiles\\sEvEn.obj"),
                Path.GetFullPath("TestFiles\\EIght.obj"),
            });

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")));

            ITaskItem[] outputs = d.OutputsForSource(sources2Match, /*searchForSubRootsInCompositeRootingMarkers*/ false);

            Assert.Equal(5, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\fOUr.obj"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\fIve.obj"));
            Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\sIx.obj"));
            Assert.Equal(outputs[3].ItemSpec, Path.GetFullPath("TestFiles\\sEvEn.obj"));
            Assert.Equal(outputs[4].ItemSpec, Path.GetFullPath("TestFiles\\EIght.obj"));

            ITaskItem[] outputs2 = d.OutputsForSource(sources2Match, /*searchForSubRootsInCompositeRootingMarkers*/ true);

            Assert.Equal(5, outputs2.Length);
            Assert.Equal(outputs2[0].ItemSpec, Path.GetFullPath("TestFiles\\fOUr.obj"));
            Assert.Equal(outputs2[1].ItemSpec, Path.GetFullPath("TestFiles\\fIve.obj"));
            Assert.Equal(outputs2[2].ItemSpec, Path.GetFullPath("TestFiles\\sIx.obj"));
            Assert.Equal(outputs2[3].ItemSpec, Path.GetFullPath("TestFiles\\sEvEn.obj"));
            Assert.Equal(outputs2[4].ItemSpec, Path.GetFullPath("TestFiles\\EIght.obj"));

            ITaskItem[] outputs3 = d.OutputsForSource(sourcesPlusOne, /*searchForSubRootsInCompositeRootingMarkers*/ true);

            Assert.Equal(3, outputs3.Length);
            Assert.Equal(outputs3[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.Equal(outputs3[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj"));
            Assert.Equal(outputs3[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj"));

            ITaskItem[] outputs4 = d.OutputsForSource(sourcesPlusOne, /*searchForSubRootsInCompositeRootingMarkers*/ false);

            Assert.Equal(0, outputs4.Length);
        }
Пример #22
0
        protected void CalcSourcesToBuild()
        {
            //check if full recompile is required otherwise perform incremental
            if (ForcedRebuildRequired() || MinimalRebuildFromTracking == false)
            {
                CompileSourceList = Sources;
                return;
            }

            //retrieve list of sources out of date due to command line changes
            List<ITaskItem> outOfDateSourcesFromCommandLine = GetOutOfDateSourcesFromCmdLineChanges();

            //retrieve sources out of date due to tracking
            CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, TLogWriteFiles);
            TrackedInputFiles = new CanonicalTrackedInputFiles(this,
                                                               TLogReadFiles,
                                                               Sources,
                                                               ExcludedInputPaths,
                                                               outputs,
                                                               true,
                                                               false);
            ITaskItem[] outOfDateSourcesFromTracking = TrackedInputFiles.ComputeSourcesNeedingCompilation();

            //merge out of date lists
            CompileSourceList = MergeOutOfDateSources(outOfDateSourcesFromTracking, outOfDateSourcesFromCommandLine);
            if (CompileSourceList.Length == 0)
            {
                SkippedExecution = true;
                return;
            }

            //remove sources to compile from tracked file list
            TrackedInputFiles.RemoveEntriesForSource(CompileSourceList);
            outputs.RemoveEntriesForSource(CompileSourceList);
            TrackedInputFiles.SaveTlog();
            outputs.SaveTlog();
        }
Пример #23
0
        public void OutputNonExistentTlog()
        {
            Console.WriteLine("Test: NonExistentTlog");

            // Just to be sure, delete the test tlog.
            File.Delete("TestFiles\\one.tlog");

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")));

            ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")));

            Assert.Null(outputs);
        }
Пример #24
0
        public void OutputMultipleCanonicalCLSubrootMatch()
        {
            Console.WriteLine("Test: OutputMultipleCanonicalCLSubrootMatch");

            // sources is a subset of source2
            ITaskItem[] sources = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))};
            ITaskItem[] sources2 = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\five.cpp"))};

            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + FileTracker.FormatRootingMarker(sources),
                Path.GetFullPath("TestFiles\\oNe.obj"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
                "^" + FileTracker.FormatRootingMarker(sources2),
                Path.GetFullPath("TestFiles\\fOUr.obj"),
                Path.GetFullPath("TestFiles\\fIve.obj"),
                Path.GetFullPath("TestFiles\\sIx.obj"),
                Path.GetFullPath("TestFiles\\sEvEn.obj"),
                Path.GetFullPath("TestFiles\\EIght.obj"),
            });

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")));

            ITaskItem[] outputs = d.OutputsForSource(sources2, /*searchForSubRootsInCompositeRootingMarkers*/ false);

            Assert.IsTrue(outputs.Length == 5);
            Assert.IsTrue(outputs[0].ItemSpec == Path.GetFullPath("TestFiles\\fOUr.obj"));
            Assert.IsTrue(outputs[1].ItemSpec == Path.GetFullPath("TestFiles\\fIve.obj"));
            Assert.IsTrue(outputs[2].ItemSpec == Path.GetFullPath("TestFiles\\sIx.obj"));
            Assert.IsTrue(outputs[3].ItemSpec == Path.GetFullPath("TestFiles\\sEvEn.obj"));
            Assert.IsTrue(outputs[4].ItemSpec == Path.GetFullPath("TestFiles\\EIght.obj"));

            ITaskItem[] outputs2 = d.OutputsForSource(sources2, /*searchForSubRootsInCompositeRootingMarkers*/ true);

            Assert.IsTrue(outputs2.Length == 8);
            Assert.IsTrue(outputs2[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.IsTrue(outputs2[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj"));
            Assert.IsTrue(outputs2[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj"));
            Assert.IsTrue(outputs2[3].ItemSpec == Path.GetFullPath("TestFiles\\fOUr.obj"));
            Assert.IsTrue(outputs2[4].ItemSpec == Path.GetFullPath("TestFiles\\fIve.obj"));
            Assert.IsTrue(outputs2[5].ItemSpec == Path.GetFullPath("TestFiles\\sIx.obj"));
            Assert.IsTrue(outputs2[6].ItemSpec == Path.GetFullPath("TestFiles\\sEvEn.obj"));
            Assert.IsTrue(outputs2[7].ItemSpec == Path.GetFullPath("TestFiles\\EIght.obj"));

            // Test if sources can find the superset.
            ITaskItem[] outputs3 = d.OutputsForSource(sources, /*searchForSubRootsInCompositeRootingMarkers*/ true);

            Assert.IsTrue(outputs3.Length == 8);
            Assert.IsTrue(outputs3[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.IsTrue(outputs3[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj"));
            Assert.IsTrue(outputs3[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj"));
            Assert.IsTrue(outputs3[3].ItemSpec == Path.GetFullPath("TestFiles\\fOUr.obj"));
            Assert.IsTrue(outputs3[4].ItemSpec == Path.GetFullPath("TestFiles\\fIve.obj"));
            Assert.IsTrue(outputs3[5].ItemSpec == Path.GetFullPath("TestFiles\\sIx.obj"));
            Assert.IsTrue(outputs3[6].ItemSpec == Path.GetFullPath("TestFiles\\sEvEn.obj"));
            Assert.IsTrue(outputs3[7].ItemSpec == Path.GetFullPath("TestFiles\\EIght.obj"));

            ITaskItem[] outputs4 = d.OutputsForSource(sources, /*searchForSubRootsInCompositeRootingMarkers*/ false);

            Assert.IsTrue(outputs4.Length == 3);
            Assert.IsTrue(outputs4[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.IsTrue(outputs4[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj"));
            Assert.IsTrue(outputs4[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj"));
        }
Пример #25
0
        public void RemoveDependencyFromEntry()
        {
            Console.WriteLine("Test: RemoveDependencyFromEntry");
            // Prepare files
            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.tlh", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.tli", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                Path.GetFullPath("TestFiles\\one3.obj"),
                Path.GetFullPath("TestFiles\\one3.tlh"),
                Path.GetFullPath("TestFiles\\one3.tli"),
            });

            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                Path.GetFullPath("TestFiles\\one3.obj"),
                Path.GetFullPath("TestFiles\\one3.tlh"),
                Path.GetFullPath("TestFiles\\one3.tli"),
            });

            CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));
            compactOutputs.RemoveDependencyFromEntry(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\one3.obj")));
            compactOutputs.SaveTlog();

            CanonicalTrackedOutputFiles writtenOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            Assert.False(writtenOutputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].ContainsKey(Path.GetFullPath("TestFiles\\one3.obj")));

            CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")),
                    null,
                    compactOutputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            compactInputs.RemoveDependencyFromEntry(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\one3.obj")));
            compactInputs.SaveTlog();

            CanonicalTrackedInputFiles writtenInputs = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")),
                    null,
                    writtenOutputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            Assert.False(writtenInputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].ContainsKey(Path.GetFullPath("TestFiles\\one3.obj")));
        }
Пример #26
0
        public void OutputMultipleSingleSubRootCanonicalCL()
        {
            Console.WriteLine("Test: OutputMultipleSingleSubRootCanonicalCL");

            ITaskItem[] sources = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))};

            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + FileTracker.FormatRootingMarker(sources),
                Path.GetFullPath("TestFiles\\oNe.obj"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
            });

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")));

            ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")));

            Assert.IsTrue(outputs.Length == 3);
            Assert.IsTrue(outputs[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.IsTrue(outputs[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj"));
            Assert.IsTrue(outputs[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj"));
        }
Пример #27
0
        public void ReplaceOutputForSource()
        {
            Console.WriteLine("Test: ReplaceOutputForSource");

            if (File.Exists(Path.GetFullPath("TestFiles\\three.i")))
            {
                File.Delete(Path.GetFullPath("TestFiles\\three.i"));
            }

            // Prepare read tlog
            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\three.cpp", "");
            Thread.Sleep(sleepTimeMilliseconds);
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\two.obj", "");
            DependencyTestHelper.WriteAll("TestFiles\\three.obj", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + Path.GetFullPath("TestFiles\\three.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
            });

            // Our source files
            ITaskItem[] sources = {
                                    new TaskItem("TestFiles\\one.cpp"),
                                    new TaskItem("TestFiles\\two.cpp"),
                                    new TaskItem("TestFiles\\three.cpp"),
                                };

            // Prepare write tlog
            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one.obj"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\two.obj"),
                "^" + Path.GetFullPath("TestFiles\\three.cpp"),
                Path.GetFullPath("TestFiles\\three.obj"),
            });

            // Represent our tracked and computed outputs
            CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            // Change the output (note that this doesn't affect the timestamp)
            File.Move(Path.GetFullPath("TestFiles\\three.obj"), Path.GetFullPath("TestFiles\\three.i"));

            string threeRootingMarker = FileTracker.FormatRootingMarker(new TaskItem("TestFiles\\three.cpp"));
            // Remove the fact that three.obj was the tracked output
            bool removed = outputs.RemoveOutputForSourceRoot(threeRootingMarker, Path.GetFullPath("TestFiles\\three.obj"));
            Assert.True(removed);
            // "Compute" the replacement output information for this compilation, rather than the one originally tracked
            outputs.AddComputedOutputForSourceRoot(threeRootingMarker, Path.GetFullPath("TestFiles\\three.i"));

            // Represent our tracked and provided inputs
            CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    sources,
                    null,
                    outputs,
                    true, /* minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            // We should have one output for three.cpp
            Assert.Equal(1, outputs.DependencyTable[threeRootingMarker].Count);
            Assert.Equal(false, outputs.DependencyTable[threeRootingMarker].ContainsKey(Path.GetFullPath("TestFiles\\three.obj")));

            // All things should be up to date
            ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation();
            Assert.Equal(0, outofdate.Length);

            // Delete the new output
            File.Delete(Path.GetFullPath("TestFiles\\three.i"));

            // This means a recompile would be required for the roots
            d.SourcesNeedingCompilation = null;
            outofdate = d.ComputeSourcesNeedingCompilation();
            Assert.Equal(1, outofdate.Length);
        }
Пример #28
0
        public void WriteTLogWithEmptyLineBetweenRoots()
        {
            Console.WriteLine("Test: WriteTLogWithEmptyLineImmediatelyAfterRoot");

            // Prepare files
            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "^FOO", "FOO", "", "^BAR", "BAR" });
            MockTask task = DependencyTestHelper.MockTask;

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles
                (
                    task,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))
                );

            Assert.AreEqual(1, ((task as ITask).BuildEngine as MockEngine).Warnings, "Should have a warning.");
            Assert.AreEqual(0, d.DependencyTable.Count, "DependencyTable should be empty.");
        }
Пример #29
0
        public void SaveCompactedWriteTlog()
        {
            Console.WriteLine("Test: SaveCompactedWriteTlog");
            TaskItem fooItem = new TaskItem("foo");

            ITaskItem[] sources = new TaskItem[] {
                                    new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")),
                                    new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))};

            string rootMarker = FileTracker.FormatRootingMarker(sources);

            // Prepare files
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.tlog", new string[] {
                "#Command some-command",
                "^" + rootMarker,
                Path.GetFullPath("TestFiles\\oNe.obj"),
                "^" + fooItem.GetMetadata("Fullpath"),
                Path.GetFullPath("TestFiles\\foo1.bar"),
                Path.GetFullPath("TestFiles\\bar1.baz"),
            });

            File.WriteAllLines("TestFiles\\two.tlog", new string[] {
                "#Command some-command",
                "^" + rootMarker,
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\three.obj"),
                "^" + fooItem.GetMetadata("Fullpath"),
                Path.GetFullPath("TestFiles\\foo2.bar"),
                Path.GetFullPath("TestFiles\\bar2.baz"),
            });

            ITaskItem[] tlogs = {
                                    new TaskItem("TestFiles\\one.tlog"),
                                    new TaskItem("TestFiles\\two.tlog")
                                };

            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    tlogs);

            ITaskItem[] outputs = d.OutputsForSource(sources);

            Assert.Equal(3, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj"));
            Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj"));

            outputs = d.OutputsForSource(fooItem);
            Assert.Equal(4, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\foo1.bar"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\bar1.baz"));
            Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\foo2.bar"));
            Assert.Equal(outputs[3].ItemSpec, Path.GetFullPath("TestFiles\\bar2.baz"));

            // Compact the tlog removing all entries for "foo" leaving the other entries intact
            d.RemoveEntriesForSource(fooItem);
            d.SaveTlog();

            // All the tlogs need to still be there even after compaction
            // It's OK for them to be empty, but their absence might mean a partial clean
            // A missing tlog would mean a clean build
            Assert.True(Microsoft.Build.Utilities.TrackedDependencies.ItemsExist(tlogs));

            // All log information should now be in the tlog[0]
            ITaskItem[] tlogs2 = {
                                    tlogs[0]
                                 };

            CanonicalTrackedOutputFiles d2 = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    tlogs2);

            outputs = d2.OutputsForSource(fooItem);
            Assert.Equal(0, outputs.Length);

            outputs = d2.OutputsForSource(sources);
            Assert.Equal(3, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj"));
            Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj"));

            // There should be no difference even if we send in all the original tlogs
            CanonicalTrackedOutputFiles d3 = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    tlogs);

            outputs = d3.OutputsForSource(fooItem);
            Assert.Equal(0, outputs.Length);

            outputs = d3.OutputsForSource(sources);
            Assert.Equal(3, outputs.Length);
            Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj"));
            Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj"));
            Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj"));
        }
Пример #30
0
        public void MultipleCanonicalCLCompactMissingOnSuccess()
        {
            Console.WriteLine("Test: MultipleCanonicalCLCompactMissingOnSuccess");
            // Prepare files
            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
            });

            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one.obj"),
                Path.GetFullPath("TestFiles\\sometempfile.obj")
            });

            CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));
            compactOutputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")));
            compactOutputs.SaveTlog();

            // Compact the read tlog
            CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")),
                    null,
                    compactOutputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            compactInputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")));
            compactInputs.SaveTlog();

            CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")),
                    null,
                    outputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation();

            Assert.Equal(0, outofdate.Length);
        }
Пример #31
0
        public void InvalidWriteTLogName()
        {
            Console.WriteLine("Test: InvalidWriteTLogName");

            MockTask task = DependencyTestHelper.MockTask;

            CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles
                (
                    task,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\|one|.write.tlog"))
                );

            Assert.Equal(1, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should have an error."
            Assert.Equal(0, d.DependencyTable.Count); // "DependencyTable should be empty."
        }
Пример #32
0
        public void MultipleCanonicalCLCompactMissingOnSuccessMultiEntry()
        {
            Console.WriteLine("Test: MultipleCanonicalCLCompactMissingOnSuccessMultiEntry");
            // Prepare files
            DependencyTestHelper.WriteAll("TestFiles\\one1.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one2.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one3.h", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.cpp", "");
            DependencyTestHelper.WriteAll("TestFiles\\one.obj", "");
            Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register
            File.WriteAllLines("TestFiles\\one.read.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one1.h"),
                Path.GetFullPath("TestFiles\\one2.h"),
                Path.GetFullPath("TestFiles\\one3.h"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\two1.h"),
                Path.GetFullPath("TestFiles\\two2.h"),
            });

            File.WriteAllLines("TestFiles\\one.write.tlog", new string[] {
                "#Command some-command",
                "^" + Path.GetFullPath("TestFiles\\one.cpp"),
                Path.GetFullPath("TestFiles\\one.obj"),
                Path.GetFullPath("TestFiles\\sometempfile.obj"),
                "^" + Path.GetFullPath("TestFiles\\two.cpp"),
                Path.GetFullPath("TestFiles\\two.obj"),
                Path.GetFullPath("TestFiles\\sometempfile2.obj")
            });

            CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));
            compactOutputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")));
            compactOutputs.SaveTlog();
            // Compact the read tlog
            CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")),
                    null,
                    compactOutputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            compactInputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")));
            compactInputs.SaveTlog();

            CanonicalTrackedOutputFiles writtenOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")));

            CanonicalTrackedInputFiles writtenInputs = new CanonicalTrackedInputFiles
                (
                    DependencyTestHelper.MockTask,
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")),
                    DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")),
                    null,
                    writtenOutputs,
                    false, /* no minimal rebuild optimization */
                    false /* shred composite rooting markers */
                );

            Assert.Equal(1, writtenOutputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].Count);
            Assert.Equal(4, writtenInputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].Count);
            // Everything to do with two.cpp should be left intact
            Assert.Equal(2, writtenOutputs.DependencyTable[Path.GetFullPath("TestFiles\\two.cpp")].Count);
            Assert.Equal(3, writtenInputs.DependencyTable[Path.GetFullPath("TestFiles\\two.cpp")].Count);
        }