public void GetChainOfJunctions() { string targetDirectory = GetFullPath("target"); Directory.CreateDirectory(targetDirectory); string intermediateJunction = GetFullPath("intermediate.jct"); Directory.CreateDirectory(intermediateJunction); FileUtilities.CreateJunction(intermediateJunction, targetDirectory); string sourceJunction = GetFullPath("source.jct"); Directory.CreateDirectory(sourceJunction); FileUtilities.CreateJunction(sourceJunction, intermediateJunction); using (SafeFileHandle handle = OpenHandleForReparsePoint(sourceJunction)) { var chain = new List <string>(); FileUtilities.GetChainOfReparsePoints(handle, sourceJunction, chain); XAssert.AreEqual(3, chain.Count, "Chain of reparse points: " + string.Join(" -> ", chain)); XAssert.ArePathEqual(sourceJunction, TrimPathPrefix(chain[0])); XAssert.ArePathEqual(intermediateJunction, TrimPathPrefix(chain[1])); XAssert.ArePathEqual(targetDirectory, TrimPathPrefix(chain[2])); } }
private void VerifyResolveSymlink(string symlinkPath, string target, string expectedResult) { FileUtilities.CreateDirectory(Path.GetDirectoryName(symlinkPath)); XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(symlinkPath, target, isTargetFile: true)); var maybeResult = FileUtilities.ResolveSymlinkTarget(symlinkPath, target); if (expectedResult != null) { XAssert.IsTrue(maybeResult.Succeeded, maybeResult.Succeeded ? string.Empty : maybeResult.Failure.DescribeIncludingInnerFailures()); XAssert.ArePathEqual(expectedResult, maybeResult.Result); } else { XAssert.IsFalse(maybeResult.Succeeded); } }
[Trait("Category", "WindowsOSOnly")] // TODO: Fix for non Windows public void GetChainOfSymlinksWithDirectorySymlink() { // File and directory layout: // Enlist // | // +---Intermediate // | \---Current // | file.lnk ==> ..\..\Target\file.txt // | // +---Source ==> Intermediate\Current // | // \---Target // file.txt // Create a concrete file /Target/file.txt string targetFile = GetFullPath(R("Target", "file.txt")); FileUtilities.CreateDirectory(Path.GetDirectoryName(targetFile)); File.WriteAllText(targetFile, "Contents"); // Create a symlink /Intermediate/Current/file.lnk --> ../../Target/file.txt string intermediateLink = GetFullPath(R("Intermediate", "Current", "file.lnk")); FileUtilities.CreateDirectory(Path.GetDirectoryName(intermediateLink)); XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(intermediateLink, R("..", "..", "Target", "file.txt"), isTargetFile: true)); // Create a directory symlink /Source --> Intermediate/Current // Access /Source/file.lnk. string sourceLink = GetFullPath(R("Source", "file.lnk")); XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(Path.GetDirectoryName(sourceLink), R("Intermediate", "Current"), isTargetFile: false)); using (SafeFileHandle handle = OpenHandleForReparsePoint(sourceLink)) { var chain = new List <string>(); FileUtilities.GetChainOfReparsePoints(handle, sourceLink, chain); // There are two ways of reaching file.lnk, (1) /Source/file.lnk, and (2) /Intermediate/Current/file.lnk. // For Windows, BuildXL does not track all possible paths reaching to file.lnk; only what the tool/user accesses. // In this case, we access /Source/file.lnk. Thus, only /Source/file.lnk and /Target/file.txt are in the chain. // TODO: Reconcile this with Mac implementation. XAssert.AreEqual(2, chain.Count, "Chain of reparse points: " + string.Join(" -> ", chain)); XAssert.ArePathEqual(sourceLink, TrimPathPrefix(chain[0])); XAssert.ArePathEqual(targetFile, TrimPathPrefix(chain[1])); } }
public void TestGetRelativePath(string root, string filePath, string oldValue, string newValue, string expectedPath) { var replacementArgs = new global::Tool.DropDaemon.DropDaemon.RelativePathReplacementArguments(oldValue, newValue); XAssert.ArePathEqual(expectedPath, global::Tool.DropDaemon.DropDaemon.GetRelativePath(root, filePath, replacementArgs)); }
public void TestResolveSymlinkWithDirectorySymlinkOrJunction(bool useJunction, bool oneDotDot) { // File and directory layout: // Enlist // | // +---Intermediate // | \---Current // | file.lnk ==> ..\..\Target\file.txt (or ..\Target\file.txt) // | // +---Source ==> Intermediate\Current // | // \---Target // file.txt // Create a symlink Enlist/Intermediate/Current/file.lnk --> ../../Target/file.txt (or ../Target/file.txt) string symlinkFile = GetFullPath(R("Enlist", "Intermediate", "Current", "file.lnk")); FileUtilities.CreateDirectory(GetFullPath(R("Enlist", "Intermediate", "Current"))); var relativeTarget = oneDotDot ? R("..", "Target", "file.txt") : R("..", "..", "Target", "file.txt"); XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(symlinkFile, relativeTarget, isTargetFile: true)); // Create a directory symlink Enlist/Source --> Enlist/Intermediate/Current string symlinkDirectory = GetFullPath(R("Enlist", "Source")); if (useJunction) { FileUtilities.CreateDirectory(symlinkDirectory); FileUtilities.CreateJunction(symlinkDirectory, GetFullPath(R("Enlist", "Intermediate", "Current"))); } else { XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(symlinkDirectory, R("Intermediate", "Current"), isTargetFile: false)); } string expectedFinalPath = null; if (useJunction) { expectedFinalPath = oneDotDot ? GetFullPath(R("Enlist", "Target", "file.txt")) : GetFullPath(R("Target", "file.txt")); } else { expectedFinalPath = oneDotDot ? GetFullPath(R("Enlist", "Intermediate", "Target", "file.txt")) : GetFullPath(R("Enlist", "Target", "file.txt")); } // Resolve symlink Enlist/Source/file.lnk by supplying the symlink relative target path (../../Target/file.txt or ../Target/file.txt). var maybeResult = FileUtilities.ResolveSymlinkTarget(GetFullPath(R("Enlist", "Source", "file.lnk")), relativeTarget); XAssert.PossiblySucceeded(maybeResult); XAssert.ArePathEqual(expectedFinalPath, maybeResult.Result); // Resolve symlink Enlist/Source/file.lnk without supplying the symlink target path // The result should be Enlist/Target/file.txt maybeResult = FileUtilities.ResolveSymlinkTarget(GetFullPath(R("Enlist", "Source", "file.lnk"))); XAssert.PossiblySucceeded(maybeResult); XAssert.ArePathEqual(expectedFinalPath, maybeResult.Result); }