From ae21413746629f3d7fa0902557017ec92e1882f5 Mon Sep 17 00:00:00 2001 From: Kevin Willford Date: Wed, 26 Sep 2018 14:32:28 -0600 Subject: [PATCH 1/4] Check modified paths for parent directories before adding --- GVFS/GVFS.Common/ModifiedPathsDatabase.cs | 20 +++- .../EnlistmentPerFixture/GitFilesTests.cs | 2 - .../Common/ModifiedPathsDatabaseTests.cs | 95 ++++++++++++++----- 3 files changed, 89 insertions(+), 28 deletions(-) diff --git a/GVFS/GVFS.Common/ModifiedPathsDatabase.cs b/GVFS/GVFS.Common/ModifiedPathsDatabase.cs index ffde4f6927..338c1f4ce2 100644 --- a/GVFS/GVFS.Common/ModifiedPathsDatabase.cs +++ b/GVFS/GVFS.Common/ModifiedPathsDatabase.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text; using GVFS.Common.FileSystem; using GVFS.Common.Tracing; @@ -67,7 +69,7 @@ public bool TryAdd(string path, bool isFolder, out bool isRetryable) { isRetryable = true; string entry = this.NormalizeEntryString(path, isFolder); - if (!this.modifiedPaths.Contains(entry)) + if (!this.modifiedPaths.Contains(entry) && !this.ContainsParentDirectory(entry)) { try { @@ -183,6 +185,22 @@ private bool TryParseRemoveLine(string line, out string key, out string error) return true; } + private bool ContainsParentDirectory(string modifiedPath) + { + string[] pathParts = modifiedPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + StringBuilder parentFolder = new StringBuilder(); + foreach (string pathPart in pathParts.Take(pathParts.Length - 1)) + { + parentFolder.Append(pathPart + "/"); + if (this.modifiedPaths.Contains(parentFolder.ToString())) + { + return true; + } + } + + return false; + } + private string NormalizeEntryString(string virtualPath, bool isFolder) { // TODO(Mac) This can be optimized if needed diff --git a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs index bfbdcc4576..8a0a0c3f64 100644 --- a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs +++ b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs @@ -77,7 +77,6 @@ public void CreateFileInFolderTest() this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/"); - GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/" + fileName); } [TestCase, Order(4)] @@ -140,7 +139,6 @@ public void CaseOnlyRenameOfNewFolderKeepsModifiedPathsEntries() string[] expectedModifiedPathsEntriesAfterCreate = { "A Folder/", - "A Folder/testfile", }; string[] expectedModifiedPathsEntriesAfterRename = diff --git a/GVFS/GVFS.UnitTests/Common/ModifiedPathsDatabaseTests.cs b/GVFS/GVFS.UnitTests/Common/ModifiedPathsDatabaseTests.cs index 3134842008..663a76bb08 100644 --- a/GVFS/GVFS.UnitTests/Common/ModifiedPathsDatabaseTests.cs +++ b/GVFS/GVFS.UnitTests/Common/ModifiedPathsDatabaseTests.cs @@ -22,31 +22,31 @@ A dir1/dir2/file3.txt [TestCase] public void ParsesExistingDataCorrectly() { - ModifiedPathsDatabase mpd = CreateModifiedPathsDatabase(ExistingEntries); - mpd.Count.ShouldEqual(3); - mpd.Contains("file.txt", isFolder: false).ShouldBeTrue(); - mpd.Contains("dir/file2.txt", isFolder: false).ShouldBeTrue(); - mpd.Contains("dir1/dir2/file3.txt", isFolder: false).ShouldBeTrue(); + ModifiedPathsDatabase modifiedPathsDatabase = CreateModifiedPathsDatabase(ExistingEntries); + modifiedPathsDatabase.Count.ShouldEqual(3); + modifiedPathsDatabase.Contains("file.txt", isFolder: false).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir/file2.txt", isFolder: false).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir1/dir2/file3.txt", isFolder: false).ShouldBeTrue(); } [TestCase] public void AddsDefaultEntry() { - ModifiedPathsDatabase mpd = CreateModifiedPathsDatabase(initialContents: string.Empty); - mpd.Count.ShouldEqual(1); - mpd.Contains(DefaultEntry, isFolder: false).ShouldBeTrue(); + ModifiedPathsDatabase modifiedPathsDatabase = CreateModifiedPathsDatabase(initialContents: string.Empty); + modifiedPathsDatabase.Count.ShouldEqual(1); + modifiedPathsDatabase.Contains(DefaultEntry, isFolder: false).ShouldBeTrue(); } [TestCase] public void BadDataFailsToLoad() { - ConfigurableFileSystem fs = new ConfigurableFileSystem(); - fs.ExpectedFiles.Add(MockEntryFileName, new ReusableMemoryStream("This is bad data!\r\n")); + ConfigurableFileSystem configurableFileSystem = new ConfigurableFileSystem(); + configurableFileSystem.ExpectedFiles.Add(MockEntryFileName, new ReusableMemoryStream("This is bad data!\r\n")); string error; - ModifiedPathsDatabase mpd; - ModifiedPathsDatabase.TryLoadOrCreate(null, MockEntryFileName, fs, out mpd, out error).ShouldBeFalse(); - mpd.ShouldBeNull(); + ModifiedPathsDatabase modifiedPathsDatabase; + ModifiedPathsDatabase.TryLoadOrCreate(null, MockEntryFileName, configurableFileSystem, out modifiedPathsDatabase, out error).ShouldBeFalse(); + modifiedPathsDatabase.ShouldBeNull(); } [TestCase] @@ -74,6 +74,51 @@ public void DirectorySeparatorAddedForFolder() TestAddingPath(pathToAdd: Path.Combine("dir", "subdir"), pathInList: Path.Combine("dir", "subdir") + Path.DirectorySeparatorChar, isFolder: true); } + [TestCase] + public void EntryNotAddedIfParentDirectoryExists() + { + ModifiedPathsDatabase modifiedPathsDatabase = CreateModifiedPathsDatabase(initialContents: "A dir/\r\n"); + modifiedPathsDatabase.Count.ShouldEqual(1); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + + // Try adding a file for the directory that is in the modified paths + modifiedPathsDatabase.TryAdd("dir/file.txt", isFolder: false, isRetryable: out _); + modifiedPathsDatabase.Count.ShouldEqual(1); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + + // Try adding a directory for the directory that is in the modified paths + modifiedPathsDatabase.TryAdd("dir/dir2", isFolder: true, isRetryable: out _); + modifiedPathsDatabase.Count.ShouldEqual(1); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + + // Try adding a file for a directory that is not in the modified paths + modifiedPathsDatabase.TryAdd("dir2/file.txt", isFolder: false, isRetryable: out _); + modifiedPathsDatabase.Count.ShouldEqual(2); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/file.txt", isFolder: false).ShouldBeTrue(); + + // Try adding a directory for a the directory that is not in the modified paths + modifiedPathsDatabase.TryAdd("dir2/dir", isFolder: true, isRetryable: out _); + modifiedPathsDatabase.Count.ShouldEqual(3); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/file.txt", isFolder: false).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/dir", isFolder: true).ShouldBeTrue(); + + // Try adding a file in a subdirectory that is in the modified paths + modifiedPathsDatabase.TryAdd("dir2/dir/file.txt", isFolder: false, isRetryable: out _); + modifiedPathsDatabase.Count.ShouldEqual(3); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/file.txt", isFolder: false).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/dir", isFolder: true).ShouldBeTrue(); + + // Try adding a directory for a subdirectory that is in the modified paths + modifiedPathsDatabase.TryAdd("dir2/dir/dir3", isFolder: true, isRetryable: out _); + modifiedPathsDatabase.Count.ShouldEqual(3); + modifiedPathsDatabase.Contains("dir", isFolder: true).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/file.txt", isFolder: false).ShouldBeTrue(); + modifiedPathsDatabase.Contains("dir2/dir", isFolder: true).ShouldBeTrue(); + } + private static void TestAddingPath(string path, bool isFolder = false) { TestAddingPath(path, path, isFolder); @@ -81,13 +126,13 @@ private static void TestAddingPath(string path, bool isFolder = false) private static void TestAddingPath(string pathToAdd, string pathInList, bool isFolder = false) { - ModifiedPathsDatabase mpd = CreateModifiedPathsDatabase(initialContents: $"A {DefaultEntry}\r\n"); + ModifiedPathsDatabase modifiedPathsDatabase = CreateModifiedPathsDatabase(initialContents: $"A {DefaultEntry}\r\n"); bool isRetryable; - mpd.TryAdd(pathToAdd, isFolder, out isRetryable); - mpd.Count.ShouldEqual(2); - mpd.Contains(pathInList, isFolder).ShouldBeTrue(); - mpd.Contains(ToGitPathSeparators(pathInList), isFolder).ShouldBeTrue(); - mpd.GetAllModifiedPaths().ShouldContainSingle(x => string.Compare(x, ToGitPathSeparators(pathInList), StringComparison.OrdinalIgnoreCase) == 0); + modifiedPathsDatabase.TryAdd(pathToAdd, isFolder, out isRetryable); + modifiedPathsDatabase.Count.ShouldEqual(2); + modifiedPathsDatabase.Contains(pathInList, isFolder).ShouldBeTrue(); + modifiedPathsDatabase.Contains(ToGitPathSeparators(pathInList), isFolder).ShouldBeTrue(); + modifiedPathsDatabase.GetAllModifiedPaths().ShouldContainSingle(x => string.Compare(x, ToGitPathSeparators(pathInList), StringComparison.OrdinalIgnoreCase) == 0); } private static string ToGitPathSeparators(string path) @@ -102,14 +147,14 @@ private static string ToPathSeparators(string path) private static ModifiedPathsDatabase CreateModifiedPathsDatabase(string initialContents) { - ConfigurableFileSystem fs = new ConfigurableFileSystem(); - fs.ExpectedFiles.Add(MockEntryFileName, new ReusableMemoryStream(initialContents)); + ConfigurableFileSystem configurableFileSystem = new ConfigurableFileSystem(); + configurableFileSystem.ExpectedFiles.Add(MockEntryFileName, new ReusableMemoryStream(initialContents)); string error; - ModifiedPathsDatabase mpd; - ModifiedPathsDatabase.TryLoadOrCreate(null, MockEntryFileName, fs, out mpd, out error).ShouldBeTrue(); - mpd.ShouldNotBeNull(); - return mpd; + ModifiedPathsDatabase modifiedPathsDatabase; + ModifiedPathsDatabase.TryLoadOrCreate(null, MockEntryFileName, configurableFileSystem, out modifiedPathsDatabase, out error).ShouldBeTrue(); + modifiedPathsDatabase.ShouldNotBeNull(); + return modifiedPathsDatabase; } } } From 8c8c06f9b7f198d986d20c29481e0066260e14e3 Mon Sep 17 00:00:00 2001 From: Kevin Willford Date: Fri, 28 Sep 2018 11:59:51 -0600 Subject: [PATCH 2/4] Fix test the will no longer have child entries of a folder in the modified paths --- .../Windows/Tests/DiskLayoutUpgradeTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/GVFS/GVFS.FunctionalTests.Windows/Windows/Tests/DiskLayoutUpgradeTests.cs b/GVFS/GVFS.FunctionalTests.Windows/Windows/Tests/DiskLayoutUpgradeTests.cs index eb1ce473d9..1f39f0285e 100644 --- a/GVFS/GVFS.FunctionalTests.Windows/Windows/Tests/DiskLayoutUpgradeTests.cs +++ b/GVFS/GVFS.FunctionalTests.Windows/Windows/Tests/DiskLayoutUpgradeTests.cs @@ -328,8 +328,6 @@ public void MountCreatesModifiedPathsDatabase() { "A .gitattributes", "A developer/me/", - "A developer/me/JLANGE9._prerazzle", - "A developer/me/StateSwitch.Save", "A tools/x86/remote.exe", "A tools/x86/runelevated.exe", "A tools/amd64/remote.exe", From 8eddf8b19522f60722a0d0ce67778f687fb8d6cb Mon Sep 17 00:00:00 2001 From: Kevin Willford Date: Mon, 1 Oct 2018 10:34:35 -0600 Subject: [PATCH 3/4] Cleanup ContainsParentDirectory and add checks in tests for unexpected paths --- GVFS/GVFS.Common/ModifiedPathsDatabase.cs | 12 ++++---- .../EnlistmentPerFixture/GitFilesTests.cs | 29 +++++++++++-------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/GVFS/GVFS.Common/ModifiedPathsDatabase.cs b/GVFS/GVFS.Common/ModifiedPathsDatabase.cs index 338c1f4ce2..5a7e34c43c 100644 --- a/GVFS/GVFS.Common/ModifiedPathsDatabase.cs +++ b/GVFS/GVFS.Common/ModifiedPathsDatabase.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; using GVFS.Common.FileSystem; using GVFS.Common.Tracing; @@ -187,12 +185,12 @@ private bool TryParseRemoveLine(string line, out string key, out string error) private bool ContainsParentDirectory(string modifiedPath) { - string[] pathParts = modifiedPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - StringBuilder parentFolder = new StringBuilder(); - foreach (string pathPart in pathParts.Take(pathParts.Length - 1)) + string[] pathParts = modifiedPath.Split(new char[] { GVFSConstants.GitPathSeparator }, StringSplitOptions.RemoveEmptyEntries); + string parentFolder = string.Empty; + for (int i = 0; i < pathParts.Length - 1; i++) { - parentFolder.Append(pathPart + "/"); - if (this.modifiedPaths.Contains(parentFolder.ToString())) + parentFolder += pathParts[i] + GVFSConstants.GitPathSeparatorString; + if (this.modifiedPaths.Contains(parentFolder)) { return true; } diff --git a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs index 8a0a0c3f64..5352f7fc86 100644 --- a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs +++ b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs @@ -77,6 +77,7 @@ public void CreateFileInFolderTest() this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/"); + GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/" + fileName); } [TestCase, Order(4)] @@ -97,6 +98,7 @@ public void RenameEmptyFolderTest() this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedEntries); + GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName + "/"); } [TestCase, Order(5)] @@ -111,6 +113,17 @@ public void RenameFolderTest() renamedFolderName + "/", }; + string[] unexpectedModifiedEntries = + { + renamedFolderName + "/" + fileNames[0], + renamedFolderName + "/" + fileNames[1], + renamedFolderName + "/" + fileNames[2], + folderName + "/", + folderName + "/" + fileNames[0], + folderName + "/" + fileNames[1], + folderName + "/" + fileNames[2], + }; + this.Enlistment.GetVirtualPathTo(folderName).ShouldNotExistOnDisk(this.fileSystem); this.fileSystem.CreateDirectory(this.Enlistment.GetVirtualPathTo(folderName)); foreach (string fileName in fileNames) @@ -125,6 +138,7 @@ public void RenameFolderTest() this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedEntries); + GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, unexpectedModifiedEntries); } [TestCase, Order(6)] @@ -136,26 +150,17 @@ public void CaseOnlyRenameOfNewFolderKeepsModifiedPathsEntries() Assert.Ignore("Powershell does not support case only renames."); } - string[] expectedModifiedPathsEntriesAfterCreate = - { - "A Folder/", - }; - - string[] expectedModifiedPathsEntriesAfterRename = - { - "A folder/", - }; - this.fileSystem.CreateDirectory(Path.Combine(this.Enlistment.RepoRoot, "Folder")); this.fileSystem.CreateEmptyFile(Path.Combine(this.Enlistment.RepoRoot, "Folder", "testfile")); this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); - GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedPathsEntriesAfterCreate); + GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "A Folder/"); this.fileSystem.RenameDirectory(this.Enlistment.RepoRoot, "Folder", "folder"); this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); - GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, expectedModifiedPathsEntriesAfterRename); + GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "A folder/"); + GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "A folder/testfile"); } [TestCase, Order(7)] From 558b7e2c0aa300b31c0898a1a6f65ddc9cded279 Mon Sep 17 00:00:00 2001 From: Kevin Willford Date: Mon, 1 Oct 2018 15:58:16 -0600 Subject: [PATCH 4/4] Make checks on the modified paths be more strict --- .../EnlistmentPerFixture/GitFilesTests.cs | 6 ++--- .../ModifiedPathsTests.cs | 12 +++------ .../Tests/GitCommands/GitCommandsTests.cs | 6 +++-- .../GVFS.FunctionalTests/Tools/GVFSHelpers.cs | 25 ++++++++++++++++--- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs index 5352f7fc86..3313fb8f68 100644 --- a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs +++ b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/GitFilesTests.cs @@ -154,13 +154,13 @@ public void CaseOnlyRenameOfNewFolderKeepsModifiedPathsEntries() this.fileSystem.CreateEmptyFile(Path.Combine(this.Enlistment.RepoRoot, "Folder", "testfile")); this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); - GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "A Folder/"); + GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "Folder/"); this.fileSystem.RenameDirectory(this.Enlistment.RepoRoot, "Folder", "folder"); this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete."); - GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "A folder/"); - GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "A folder/testfile"); + GVFSHelpers.ModifiedPathsShouldContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "folder/"); + GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, "folder/testfile"); } [TestCase, Order(7)] diff --git a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerTestCase/ModifiedPathsTests.cs b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerTestCase/ModifiedPathsTests.cs index ee4c1e060f..f8e42331e6 100644 --- a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerTestCase/ModifiedPathsTests.cs +++ b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerTestCase/ModifiedPathsTests.cs @@ -53,7 +53,7 @@ public void DeletedTempFileIsRemovedFromModifiedFiles(FileSystemRunner fileSyste tempFile.ShouldNotExistOnDisk(fileSystem); this.Enlistment.UnmountGVFS(); - this.ValidateModifiedPathsDoNotContain(fileSystem, "temp.txt"); + GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, "temp.txt"); } [TestCaseSource(typeof(FileSystemRunner), FileSystemRunner.TestRunners)] @@ -64,7 +64,7 @@ public void DeletedTempFolderIsRemovedFromModifiedFiles(FileSystemRunner fileSys tempFolder.ShouldNotExistOnDisk(fileSystem); this.Enlistment.UnmountGVFS(); - this.ValidateModifiedPathsDoNotContain(fileSystem, "Temp/"); + GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, "Temp/"); } [TestCaseSource(typeof(FileSystemRunner), FileSystemRunner.TestRunners)] @@ -79,7 +79,7 @@ public void DeletedTempFolderDeletesFilesFromModifiedFiles(FileSystemRunner file tempFile2.ShouldNotExistOnDisk(fileSystem); this.Enlistment.UnmountGVFS(); - this.ValidateModifiedPathsDoNotContain(fileSystem, "Temp/", "Temp/temp1.txt", "Temp/temp2.txt"); + GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, "Temp/", "Temp/temp1.txt", "Temp/temp2.txt"); } [Category(Categories.MacTODO.M2)] @@ -219,11 +219,5 @@ private string CreateFile(FileSystemRunner fileSystem, string relativePath) tempFile.ShouldBeAFile(fileSystem); return tempFile; } - - private void ValidateModifiedPathsDoNotContain(FileSystemRunner fileSystem, params string[] paths) - { - GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, paths.Select(x => $"A {x}" + Environment.NewLine).ToArray()); - GVFSHelpers.ModifiedPathsShouldNotContain(fileSystem, this.Enlistment.DotGVFSRoot, paths.Select(x => $"D {x}" + Environment.NewLine).ToArray()); - } } } diff --git a/GVFS/GVFS.FunctionalTests/Tests/GitCommands/GitCommandsTests.cs b/GVFS/GVFS.FunctionalTests/Tests/GitCommands/GitCommandsTests.cs index c623f5ea72..31ac5cb08c 100644 --- a/GVFS/GVFS.FunctionalTests/Tests/GitCommands/GitCommandsTests.cs +++ b/GVFS/GVFS.FunctionalTests/Tests/GitCommands/GitCommandsTests.cs @@ -980,15 +980,17 @@ public void EditFileNeedingUtf8Encoding() { this.ValidateGitCommand("checkout -b tests/functional/EditFileNeedingUtf8Encoding"); this.ValidateGitCommand("status"); + string virtualFile = Path.Combine(this.Enlistment.RepoRoot, EncodingFileFolder, EncodingFilename); string controlFile = Path.Combine(this.ControlGitRepo.RootPath, EncodingFileFolder, EncodingFilename); + string relativeGitPath = EncodingFileFolder + "/" + EncodingFilename; string contents = virtualFile.ShouldBeAFile(this.FileSystem).WithContents(); string expectedContents = controlFile.ShouldBeAFile(this.FileSystem).WithContents(); contents.ShouldEqual(expectedContents); // Confirm that the entry is not in the the modified paths database - GVFSHelpers.ModifiedPathsShouldNotContain(this.FileSystem, this.Enlistment.DotGVFSRoot, EncodingFilename); + GVFSHelpers.ModifiedPathsShouldNotContain(this.FileSystem, this.Enlistment.DotGVFSRoot, relativeGitPath); this.ValidateGitCommand("status"); this.AppendAllText(ContentWhenEditingFile, virtualFile); @@ -997,7 +999,7 @@ public void EditFileNeedingUtf8Encoding() this.ValidateGitCommand("status"); // Confirm that the entry was added to the modified paths database - GVFSHelpers.ModifiedPathsShouldContain(this.FileSystem, this.Enlistment.DotGVFSRoot, EncodingFilename); + GVFSHelpers.ModifiedPathsShouldContain(this.FileSystem, this.Enlistment.DotGVFSRoot, relativeGitPath); } [TestCase] diff --git a/GVFS/GVFS.FunctionalTests/Tools/GVFSHelpers.cs b/GVFS/GVFS.FunctionalTests/Tools/GVFSHelpers.cs index 95e988c182..58abd79851 100644 --- a/GVFS/GVFS.FunctionalTests/Tools/GVFSHelpers.cs +++ b/GVFS/GVFS.FunctionalTests/Tools/GVFSHelpers.cs @@ -4,10 +4,10 @@ using Microsoft.Data.Sqlite; using Newtonsoft.Json; using NUnit.Framework; +using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; namespace GVFS.FunctionalTests.Tools { @@ -19,6 +19,9 @@ public static class GVFSHelpers public static readonly string PlaceholderListFile = Path.Combine("databases", "PlaceholderList.dat"); public static readonly string RepoMetadataName = Path.Combine("databases", "RepoMetadata.dat"); + private const string ModifedPathsLineAddPrefix = "A "; + private const string ModifedPathsLineDeletePrefix = "D "; + private const string DiskLayoutMajorVersionKey = "DiskLayoutVersion"; private const string DiskLayoutMinorVersionKey = "DiskLayoutMinorVersion"; private const string LocalCacheRootKey = "LocalCacheRoot"; @@ -111,15 +114,29 @@ public static void ModifiedPathsShouldContain(FileSystemRunner fileSystem, strin { string modifiedPathsDatabase = Path.Combine(dotGVFSRoot, TestConstants.Databases.ModifiedPaths); modifiedPathsDatabase.ShouldBeAFile(fileSystem); - GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase).ShouldContain( - gitPaths.Select(path => path + ModifiedPathsNewLine).ToArray()); + string modifedPathsContents = GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase); + string[] modifedPathLines = modifedPathsContents.Split(new[] { ModifiedPathsNewLine }, StringSplitOptions.None); + foreach (string gitPath in gitPaths) + { + modifedPathLines.ShouldContain(path => path.Equals(ModifedPathsLineAddPrefix + gitPath)); + } } public static void ModifiedPathsShouldNotContain(FileSystemRunner fileSystem, string dotGVFSRoot, params string[] gitPaths) { string modifiedPathsDatabase = Path.Combine(dotGVFSRoot, TestConstants.Databases.ModifiedPaths); modifiedPathsDatabase.ShouldBeAFile(fileSystem); - GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase).ShouldNotContain(ignoreCase: true, unexpectedSubstrings: gitPaths); + string modifedPathsContents = GVFSHelpers.ReadAllTextFromWriteLockedFile(modifiedPathsDatabase); + string[] modifedPathLines = modifedPathsContents.Split(new[] { ModifiedPathsNewLine }, StringSplitOptions.None); + foreach (string gitPath in gitPaths) + { + modifedPathLines.ShouldNotContain( + path => + { + return path.Equals(ModifedPathsLineAddPrefix + gitPath, StringComparison.OrdinalIgnoreCase) || + path.Equals(ModifedPathsLineDeletePrefix + gitPath, StringComparison.OrdinalIgnoreCase); + }); + } } private static byte[] StringToShaBytes(string sha)