Skip to content

Commit

Permalink
Merge pull request #146 ScalarVerb: Remove EnsureLocalCacheIsHealthy
Browse files Browse the repository at this point in the history
ScalarVerb: Remove EnsureLocalCacheIsHealthy
  • Loading branch information
wilbaker authored Oct 4, 2019
2 parents a8b0b08 + 8352199 commit 73421a7
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public void DownloadingACommitWithoutTreesDoesntBreakNextClone()
}

[TestCase]
[Ignore("TODO #147: Renamed this test after git recreates the gvfs.sharedCache folder if it's missing")]
public void MountReusesLocalCacheKeyWhenGitObjectsRootDeleted()
{
ScalarFunctionalTestEnlistment enlistment = this.CloneAndMountEnlistment();
Expand All @@ -159,55 +160,17 @@ public void MountReusesLocalCacheKeyWhenGitObjectsRootDeleted()
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.MountScalar();

ScalarHelpers.GetGitObjectsRoot(enlistment.RepoRoot).ShouldEqual(objectsRoot);
objectsRoot.ShouldBeADirectory(this.fileSystem);
mappingFilePath.ShouldBeAFile(this.fileSystem).WithContents(mappingFileContents);

this.AlternatesFileShouldHaveGitObjectsRoot(enlistment);
}
// Downloading objects should recreate the objects directory
this.LoadBlobsViaGit(enlistment);

[TestCase]
public void MountUsesNewLocalCacheKeyWhenLocalCacheDeleted()
{
ScalarFunctionalTestEnlistment enlistment = this.CloneAndMountEnlistment();

enlistment.UnmountScalar();

// Find the current git objects root and ensure it's on disk
string objectsRoot = ScalarHelpers.GetGitObjectsRoot(enlistment.RepoRoot);
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.MountScalar();

// 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 = ScalarHelpers.GetGitObjectsRoot(enlistment.RepoRoot);
newObjectsRoot.ShouldNotEqual(objectsRoot);
newObjectsRoot.ShouldContain(newCacheKey);
newObjectsRoot.ShouldBeADirectory(this.fileSystem);

// The alternates file shouldn't have changed
this.AlternatesFileShouldHaveGitObjectsRoot(enlistment);
}

Expand Down
151 changes: 0 additions & 151 deletions Scalar/CommandLine/ScalarVerb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,6 @@ protected void InitializeLocalCacheAndObjectsPaths(
}

this.InitializeCachePaths(tracer, enlistment);
this.EnsureLocalCacheIsHealthy(tracer, enlistment, retryConfig, serverScalarConfig, cacheServer);

RepoMetadata.Shutdown();
}
Expand Down Expand Up @@ -840,156 +839,6 @@ private void InitializeCachePaths(
enlistment.InitializeCachePaths(localCacheRoot, gitObjectsRoot);
}

private void EnsureLocalCacheIsHealthy(
ITracer tracer,
ScalarEnlistment enlistment,
RetryConfig retryConfig,
ServerScalarConfig serverScalarConfig,
CacheServerInfo cacheServer)
{
if (!Directory.Exists(enlistment.LocalCacheRoot))
{
try
{
tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Local cache root: {enlistment.LocalCacheRoot} missing, recreating it");
Directory.CreateDirectory(enlistment.LocalCacheRoot);
}
catch (Exception e)
{
EventMetadata metadata = new EventMetadata();
metadata.Add("Exception", e.ToString());
metadata.Add("enlistment.LocalCacheRoot", enlistment.LocalCacheRoot);
tracer.RelatedError(metadata, $"{nameof(this.EnsureLocalCacheIsHealthy)}: Exception while trying to create local cache root");

this.ReportErrorAndExit(tracer, "Failed to create local cache: " + enlistment.LocalCacheRoot);
}
}

// Validate that the GitObjectsRoot directory is on disk, and that the Scalar repo is configured to use it.
// If the directory is missing (and cannot be found in the mapping file) a new key for the repo will be added
// to the mapping file and used for BOTH the GitObjectsRoot and BlobSizesRoot
PhysicalFileSystem fileSystem = new PhysicalFileSystem();
if (Directory.Exists(enlistment.GitObjectsRoot))
{
bool gitObjectsRootInAlternates = false;

string alternatesFilePath = this.GetAlternatesPath(enlistment);
if (File.Exists(alternatesFilePath))
{
try
{
using (Stream stream = fileSystem.OpenFileStream(
alternatesFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite,
callFlushFileBuffers: false))
{
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
string alternatesLine = reader.ReadLine();
if (string.Equals(alternatesLine, enlistment.GitObjectsRoot, StringComparison.OrdinalIgnoreCase))
{
gitObjectsRootInAlternates = true;
}
}
}
}
}
catch (Exception e)
{
EventMetadata exceptionMetadata = new EventMetadata();
exceptionMetadata.Add("Exception", e.ToString());
tracer.RelatedError(exceptionMetadata, $"{nameof(this.EnsureLocalCacheIsHealthy)}: Exception while trying to validate alternates file");

this.ReportErrorAndExit(tracer, $"Failed to validate that alternates file includes git objects root: {e.Message}");
}
}
else
{
tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Alternates file not found");
}

if (!gitObjectsRootInAlternates)
{
tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: GitObjectsRoot ({enlistment.GitObjectsRoot}) missing from alternates files, recreating alternates");
string error;
if (!this.TrySetObjectCacheLocation(fileSystem, enlistment, out error))
{
this.ReportErrorAndExit(tracer, $"Failed to update alternates file to include git objects root: {error}");
}
}
}
else
{
tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: GitObjectsRoot ({enlistment.GitObjectsRoot}) missing, determining new root");

if (cacheServer == null)
{
cacheServer = CacheServerResolver.GetCacheServerFromConfig(enlistment);
}

string error;
if (serverScalarConfig == null)
{
if (retryConfig == null)
{
if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error))
{
this.ReportErrorAndExit(tracer, "Failed to determine Scalar timeout and max retries: " + error);
}
}

serverScalarConfig = this.QueryScalarConfig(tracer, enlistment, retryConfig);
}

string localCacheKey;
LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment);
if (!localCacheResolver.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers(
tracer,
serverScalarConfig,
cacheServer,
enlistment.LocalCacheRoot,
localCacheKey: out localCacheKey,
errorMessage: out error))
{
this.ReportErrorAndExit(tracer, $"Previous git objects root ({enlistment.GitObjectsRoot}) not found, and failed to determine new local cache key: {error}");
}

EventMetadata metadata = new EventMetadata();
metadata.Add("localCacheRoot", enlistment.LocalCacheRoot);
metadata.Add("localCacheKey", localCacheKey);
metadata.Add(TracingConstants.MessageKey.InfoMessage, "Initializing and persisting updated paths");
tracer.RelatedEvent(EventLevel.Informational, "ScalarVerb_EnsureLocalCacheIsHealthy_InitializePathsFromKey", metadata);
enlistment.InitializeCachePathsFromKey(enlistment.LocalCacheRoot, localCacheKey);

tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Creating GitObjectsRoot ({enlistment.GitObjectsRoot}), and GitPackRoot ({enlistment.GitPackRoot})");
try
{
Directory.CreateDirectory(enlistment.GitPackRoot);
}
catch (Exception e)
{
EventMetadata exceptionMetadata = new EventMetadata();
exceptionMetadata.Add("Exception", e.ToString());
exceptionMetadata.Add("enlistment.LocalCacheRoot", enlistment.LocalCacheRoot);
exceptionMetadata.Add("enlistment.GitObjectsRoot", enlistment.GitObjectsRoot);
exceptionMetadata.Add("enlistment.GitPackRoot", enlistment.GitPackRoot);
tracer.RelatedError(exceptionMetadata, $"{nameof(this.InitializeLocalCacheAndObjectsPaths)}: Exception while trying to create objects, pack, and sizes folders");

this.ReportErrorAndExit(tracer, "Failed to create objects, pack, and sizes folders");
}

tracer.RelatedInfo($"{nameof(this.EnsureLocalCacheIsHealthy)}: Creating new alternates file and setting object cache in git config");
if (!this.TrySetObjectCacheLocation(fileSystem, enlistment, out error))
{
this.ReportErrorAndExit(tracer, $"Failed to update alterates file with new objects path: {error}");
}
}
}

private ScalarEnlistment CreateEnlistment(string enlistmentRootPath, GitAuthentication authentication)
{
string gitBinPath = ScalarPlatform.Instance.GitInstallation.GetInstalledGitBinPath();
Expand Down

0 comments on commit 73421a7

Please sign in to comment.