public void CloneWithDefaultLocalCacheLocation() { FileSystemRunner fileSystem = FileSystemRunner.DefaultRunner; string homeDirectory = Environment.GetEnvironmentVariable("HOME"); homeDirectory.ShouldBeADirectory(fileSystem); string newEnlistmentRoot = GSDFunctionalTestEnlistment.GetUniqueEnlistmentRoot(); ProcessStartInfo processInfo = new ProcessStartInfo(GSDTestConfig.PathToGSD); processInfo.Arguments = $"clone {Properties.Settings.Default.RepoToClone} {newEnlistmentRoot} --no-mount --no-prefetch"; processInfo.WindowStyle = ProcessWindowStyle.Hidden; processInfo.CreateNoWindow = true; processInfo.UseShellExecute = false; processInfo.RedirectStandardOutput = true; ProcessResult result = ProcessHelper.Run(processInfo); result.ExitCode.ShouldEqual(0, result.Errors); string dotGSDRoot = Path.Combine(newEnlistmentRoot, GSDTestConfig.DotGSDRoot); dotGSDRoot.ShouldBeADirectory(fileSystem); string localCacheRoot = GSDHelpers.GetPersistedLocalCacheRoot(dotGSDRoot); string gitObjectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(dotGSDRoot); string defaultGSDCacheRoot = Path.Combine(homeDirectory, ".gvfsCache"); localCacheRoot.StartsWith(defaultGSDCacheRoot, StringComparison.Ordinal).ShouldBeTrue($"Local cache root did not default to using {homeDirectory}"); gitObjectsRoot.StartsWith(defaultGSDCacheRoot, StringComparison.Ordinal).ShouldBeTrue($"Git objects root did not default to using {homeDirectory}"); RepositoryHelpers.DeleteTestDirectory(newEnlistmentRoot); }
public void MountFailsWhenNoLocalCacheRootInRepoMetadata() { this.Enlistment.UnmountGSD(); string majorVersion; string minorVersion; GSDHelpers.GetPersistedDiskLayoutVersion(this.Enlistment.DotGSDRoot, out majorVersion, out minorVersion); majorVersion.ShouldNotBeNull(); minorVersion.ShouldNotBeNull(); string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(this.Enlistment.DotGSDRoot).ShouldNotBeNull(); string metadataPath = Path.Combine(this.Enlistment.DotGSDRoot, GSDHelpers.RepoMetadataName); string metadataBackupPath = metadataPath + ".backup"; this.fileSystem.MoveFile(metadataPath, metadataBackupPath); this.fileSystem.CreateEmptyFile(metadataPath); GSDHelpers.SaveDiskLayoutVersion(this.Enlistment.DotGSDRoot, majorVersion, minorVersion); GSDHelpers.SaveGitObjectsRoot(this.Enlistment.DotGSDRoot, objectsRoot); this.MountShouldFail("Failed to determine local cache path from repo metadata"); this.fileSystem.DeleteFile(metadataPath); this.fileSystem.MoveFile(metadataBackupPath, metadataPath); this.Enlistment.MountGSD(); }
private void AlternatesFileShouldHaveGitObjectsRoot(GSDFunctionalTestEnlistment enlistment) { string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(enlistment.DotGSDRoot); string alternatesFileContents = Path.Combine(enlistment.RepoRoot, ".git", "objects", "info", "alternates").ShouldBeAFile(this.fileSystem).WithContents(); alternatesFileContents.ShouldEqual(objectsRoot); }
public void MountReusesLocalCacheKeyWhenGitObjectsRootDeleted() { GSDFunctionalTestEnlistment enlistment = this.CloneAndMountEnlistment(); enlistment.UnmountGSD(); // Find the current git objects root and ensure it's on disk string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(enlistment.DotGSDRoot).ShouldNotBeNull(); objectsRoot.ShouldBeADirectory(this.fileSystem); string mappingFilePath = Path.Combine(enlistment.LocalCacheRoot, "mapping.dat"); string mappingFileContents = this.fileSystem.ReadAllText(mappingFilePath); mappingFileContents.Length.ShouldNotEqual(0, "mapping.dat should not be empty"); // Delete the git objects root folder, mount should re-create it and the mapping.dat file should not change RepositoryHelpers.DeleteTestDirectory(objectsRoot); enlistment.MountGSD(); GSDHelpers.GetPersistedGitObjectsRoot(enlistment.DotGSDRoot).ShouldEqual(objectsRoot); objectsRoot.ShouldBeADirectory(this.fileSystem); mappingFilePath.ShouldBeAFile(this.fileSystem).WithContents(mappingFileContents); this.AlternatesFileShouldHaveGitObjectsRoot(enlistment); }
public void DeleteCacheDuringHydrations() { GSDFunctionalTestEnlistment enlistment1 = this.CloneAndMountEnlistment(); string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(enlistment1.DotGSDRoot).ShouldNotBeNull(); objectsRoot.ShouldBeADirectory(this.fileSystem); Task task1 = Task.Run(() => { this.HydrateEntireRepo(enlistment1); }); while (!task1.IsCompleted) { try { // Delete objectsRoot rather than this.localCachePath as the blob sizes database cannot be deleted while GSD is mounted RepositoryHelpers.DeleteTestDirectory(objectsRoot); Thread.Sleep(100); } catch (IOException) { // Hydration may have handles into the cache, so failing this delete is expected. } } task1.Exception.ShouldBeNull(); enlistment1.Status().ShouldContain("Mount status: Ready"); }
public void DeleteObjectsCacheAndCacheMappingBeforeMount() { GSDFunctionalTestEnlistment enlistment1 = this.CloneAndMountEnlistment(); GSDFunctionalTestEnlistment enlistment2 = this.CloneAndMountEnlistment(); enlistment1.UnmountGSD(); string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(enlistment1.DotGSDRoot).ShouldNotBeNull(); objectsRoot.ShouldBeADirectory(this.fileSystem); RepositoryHelpers.DeleteTestDirectory(objectsRoot); string metadataPath = Path.Combine(this.localCachePath, "mapping.dat"); metadataPath.ShouldBeAFile(this.fileSystem); this.fileSystem.DeleteFile(metadataPath); enlistment1.MountGSD(); Task task1 = Task.Run(() => this.HydrateRootFolder(enlistment1)); Task task2 = Task.Run(() => this.HydrateRootFolder(enlistment2)); task1.Wait(); task2.Wait(); task1.Exception.ShouldBeNull(); task2.Exception.ShouldBeNull(); enlistment1.Status().ShouldContain("Mount status: Ready"); enlistment2.Status().ShouldContain("Mount status: Ready"); this.AlternatesFileShouldHaveGitObjectsRoot(enlistment1); this.AlternatesFileShouldHaveGitObjectsRoot(enlistment2); }
public void MountRegeneratesAlternatesFileWhenMissingFromDisk() { this.Enlistment.UnmountGSD(); string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(this.Enlistment.DotGSDRoot).ShouldNotBeNull(); string alternatesFilePath = Path.Combine(this.Enlistment.RepoRoot, ".git", "objects", "info", "alternates"); alternatesFilePath.ShouldBeAFile(this.fileSystem).WithContents(objectsRoot); this.fileSystem.DeleteFile(alternatesFilePath); this.Enlistment.MountGSD(); alternatesFilePath.ShouldBeAFile(this.fileSystem).WithContents(objectsRoot); }
public void MountUsesNewLocalCacheKeyWhenLocalCacheDeleted() { GSDFunctionalTestEnlistment enlistment = this.CloneAndMountEnlistment(); enlistment.UnmountGSD(); // Find the current git objects root and ensure it's on disk string objectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(enlistment.DotGSDRoot).ShouldNotBeNull(); objectsRoot.ShouldBeADirectory(this.fileSystem); string mappingFilePath = Path.Combine(enlistment.LocalCacheRoot, "mapping.dat"); string mappingFileContents = this.fileSystem.ReadAllText(mappingFilePath); mappingFileContents.Length.ShouldNotEqual(0, "mapping.dat should not be empty"); // Delete the local cache folder, mount should re-create it and generate a new mapping file and local cache key RepositoryHelpers.DeleteTestDirectory(enlistment.LocalCacheRoot); enlistment.MountGSD(); // Mount should recreate the local cache root enlistment.LocalCacheRoot.ShouldBeADirectory(this.fileSystem); // Determine the new local cache key string newMappingFileContents = mappingFilePath.ShouldBeAFile(this.fileSystem).WithContents(); const int GuidStringLength = 32; string mappingFileKey = "A {\"Key\":\"https://gvfs.visualstudio.com/ci/_git/fortests\",\"Value\":\""; int localKeyIndex = newMappingFileContents.IndexOf(mappingFileKey); string newCacheKey = newMappingFileContents.Substring(localKeyIndex + mappingFileKey.Length, GuidStringLength); // Validate the new objects root is on disk and uses the new key objectsRoot.ShouldNotExistOnDisk(this.fileSystem); string newObjectsRoot = GSDHelpers.GetPersistedGitObjectsRoot(enlistment.DotGSDRoot); newObjectsRoot.ShouldNotEqual(objectsRoot); newObjectsRoot.ShouldContain(newCacheKey); newObjectsRoot.ShouldBeADirectory(this.fileSystem); this.AlternatesFileShouldHaveGitObjectsRoot(enlistment); }