diff --git a/Scalar.FunctionalTests/Tests/DiskLayoutVersionTests.cs b/Scalar.FunctionalTests/Tests/DiskLayoutVersionTests.cs
deleted file mode 100644
index e3bacd1c56..0000000000
--- a/Scalar.FunctionalTests/Tests/DiskLayoutVersionTests.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using NUnit.Framework;
-using Scalar.FunctionalTests.Tests.EnlistmentPerTestCase;
-using Scalar.FunctionalTests.Tools;
-using Scalar.Tests.Should;
-using System.Runtime.InteropServices;
-
-namespace Scalar.FunctionalTests.Tests
-{
- [TestFixture]
- [Category(Categories.ExtraCoverage)]
- [Category(Categories.NeedsUpdatesForNonVirtualizedMode)]
- public class DiskLayoutVersionTests : TestsWithEnlistmentPerTestCase
- {
- private const int WindowsCurrentDiskLayoutMajorVersion = 0;
- private const int MacCurrentDiskLayoutMajorVersion = 0;
- private const int WindowsCurrentDiskLayoutMinimumMajorVersion = 0;
- private const int MacCurrentDiskLayoutMinimumMajorVersion = 0;
- private const int CurrentDiskLayoutMinorVersion = 0;
- private int currentDiskMajorVersion;
- private int currentDiskMinimumMajorVersion;
-
- [SetUp]
- public override void CreateEnlistment()
- {
- base.CreateEnlistment();
-
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- this.currentDiskMajorVersion = MacCurrentDiskLayoutMajorVersion;
- this.currentDiskMinimumMajorVersion = MacCurrentDiskLayoutMinimumMajorVersion;
- }
- else
- {
- this.currentDiskMajorVersion = WindowsCurrentDiskLayoutMajorVersion;
- this.currentDiskMinimumMajorVersion = WindowsCurrentDiskLayoutMinimumMajorVersion;
- }
- }
-
- [TestCase]
- public void MountSucceedsIfMinorVersionHasAdvancedButNotMajorVersion()
- {
- // Advance the minor version, mount should still work
- this.Enlistment.UnmountScalar();
- ScalarHelpers.SaveDiskLayoutVersion(
- this.Enlistment.DotScalarRoot,
- this.currentDiskMajorVersion.ToString(),
- (CurrentDiskLayoutMinorVersion + 1).ToString());
- this.Enlistment.TryMountScalar().ShouldBeTrue("Mount should succeed because only the minor version advanced");
-
- // Advance the major version, mount should fail
- this.Enlistment.UnmountScalar();
- ScalarHelpers.SaveDiskLayoutVersion(
- this.Enlistment.DotScalarRoot,
- (this.currentDiskMajorVersion + 1).ToString(),
- CurrentDiskLayoutMinorVersion.ToString());
- this.Enlistment.TryMountScalar().ShouldBeFalse("Mount should fail because the major version has advanced");
- }
-
- [TestCase]
- public void MountFailsIfBeforeMinimumVersion()
- {
- // Mount should fail if on disk version is below minimum supported version
- this.Enlistment.UnmountScalar();
- ScalarHelpers.SaveDiskLayoutVersion(
- this.Enlistment.DotScalarRoot,
- (this.currentDiskMinimumMajorVersion - 1).ToString(),
- CurrentDiskLayoutMinorVersion.ToString());
- this.Enlistment.TryMountScalar().ShouldBeFalse("Mount should fail because we are before minimum version");
- }
- }
-}
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs
index 90c5594b43..b2f4ee27a8 100644
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs
+++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs
@@ -15,19 +15,11 @@ public class CloneTests : TestsWithEnlistmentPerFixture
private const int ScalarGenericError = 3;
[TestCase]
- public void CloneInsideMountedEnlistment()
+ public void CloneInsideExistingEnlistment()
{
this.SubfolderCloneShouldFail();
}
- [TestCase]
- public void CloneInsideUnmountedEnlistment()
- {
- this.Enlistment.UnmountScalar();
- this.SubfolderCloneShouldFail();
- this.Enlistment.MountScalar();
- }
-
[TestCase]
public void CloneWithLocalCachePathWithinSrc()
{
@@ -53,20 +45,19 @@ public void SparseCloneWithNoFetchOfCommitsAndTreesSucceeds()
try
{
- enlistment = ScalarFunctionalTestEnlistment.CloneAndMountWithPerRepoCache(ScalarTestConfig.PathToScalar, skipFetchCommitsAndTrees: true);
+ enlistment = ScalarFunctionalTestEnlistment.CloneWithPerRepoCache(ScalarTestConfig.PathToScalar, skipFetchCommitsAndTrees: true);
ProcessResult result = GitProcess.InvokeProcess(enlistment.RepoRoot, "status");
result.ExitCode.ShouldEqual(0, result.Errors);
}
finally
{
- enlistment?.UnmountAndDeleteAll();
+ enlistment?.DeleteAll();
}
}
[TestCase]
[Category(Categories.MacOnly)]
- [Category(Categories.NeedsUpdatesForNonVirtualizedMode)]
public void CloneWithDefaultLocalCacheLocation()
{
FileSystemRunner fileSystem = FileSystemRunner.DefaultRunner;
@@ -77,8 +68,6 @@ public void CloneWithDefaultLocalCacheLocation()
ProcessStartInfo processInfo = new ProcessStartInfo(ScalarTestConfig.PathToScalar);
- // Needs update for non-virtualized mode: this used to have --no-mount to avoid an issue
- // with registering the mount with the service.
processInfo.Arguments = $"clone {Properties.Settings.Default.RepoToClone} {newEnlistmentRoot} --no-fetch-commits-and-trees";
processInfo.WindowStyle = ProcessWindowStyle.Hidden;
processInfo.CreateNoWindow = true;
@@ -102,14 +91,14 @@ public void CloneWithDefaultLocalCacheLocation()
[TestCase]
public void CloneToPathWithSpaces()
{
- ScalarFunctionalTestEnlistment enlistment = ScalarFunctionalTestEnlistment.CloneAndMountEnlistmentWithSpacesInPath(ScalarTestConfig.PathToScalar);
- enlistment.UnmountAndDeleteAll();
+ ScalarFunctionalTestEnlistment enlistment = ScalarFunctionalTestEnlistment.CloneEnlistmentWithSpacesInPath(ScalarTestConfig.PathToScalar);
+ enlistment.DeleteAll();
}
[TestCase]
public void CloneCreatesCorrectFilesInRoot()
{
- ScalarFunctionalTestEnlistment enlistment = ScalarFunctionalTestEnlistment.CloneAndMount(ScalarTestConfig.PathToScalar);
+ ScalarFunctionalTestEnlistment enlistment = ScalarFunctionalTestEnlistment.Clone(ScalarTestConfig.PathToScalar);
try
{
Directory.GetFiles(enlistment.EnlistmentRoot).ShouldBeEmpty("There should be no files in the enlistment root after cloning");
@@ -120,7 +109,7 @@ public void CloneCreatesCorrectFilesInRoot()
}
finally
{
- enlistment.UnmountAndDeleteAll();
+ enlistment.DeleteAll();
}
}
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/FetchCommitsAndTreesWithoutSharedCacheTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/FetchCommitsAndTreesWithoutSharedCacheTests.cs
index e8506ab9f7..39b0b8f1fe 100644
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/FetchCommitsAndTreesWithoutSharedCacheTests.cs
+++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/FetchCommitsAndTreesWithoutSharedCacheTests.cs
@@ -104,7 +104,7 @@ public void FetchCommitsAndTreesCleansUpBadPrefetchPack()
[TestCase, Order(4)]
public void FetchCommitsAndTreesCleansUpOldPrefetchPack()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
string[] prefetchPacks = this.ReadPrefetchPackFileNames();
long oldestPackTimestamp = this.GetOldestPackTimestamp(prefetchPacks);
@@ -135,7 +135,7 @@ public void FetchCommitsAndTreesCleansUpOldPrefetchPack()
[Category(Categories.MacTODO.TestNeedsToLockFile)]
public void FetchCommitsAndTreesFailsWhenItCannotRemoveABadPrefetchPack()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
string[] prefetchPacks = this.ReadPrefetchPackFileNames();
long mostRecentPackTimestamp = this.GetMostRecentPackTimestamp(prefetchPacks);
@@ -168,7 +168,7 @@ public void FetchCommitsAndTreesFailsWhenItCannotRemoveABadPrefetchPack()
[Category(Categories.MacTODO.TestNeedsToLockFile)]
public void FetchCommitsAndTreesFailsWhenItCannotRemoveAPrefetchPackNewerThanBadPrefetchPack()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
string[] prefetchPacks = this.ReadPrefetchPackFileNames();
long oldestPackTimestamp = this.GetOldestPackTimestamp(prefetchPacks);
@@ -202,7 +202,7 @@ public void FetchCommitsAndTreesFailsWhenItCannotRemoveAPrefetchPackNewerThanBad
[Category(Categories.MacTODO.TestNeedsToLockFile)]
public void FetchCommitsAndTreesFailsWhenItCannotRemoveAPrefetchIdxNewerThanBadPrefetchPack()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
string[] prefetchPacks = this.ReadPrefetchPackFileNames();
long oldestPackTimestamp = this.GetOldestPackTimestamp(prefetchPacks);
@@ -239,7 +239,7 @@ public void FetchCommitsAndTreesFailsWhenItCannotRemoveAPrefetchIdxNewerThanBadP
[TestCase, Order(8)]
public void FetchCommitsAndTreesCleansUpStaleTempPrefetchPacks()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
// Create stale packs and idxs in the temp folder
string stalePackContents = "StalePack";
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/LooseObjectStepTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/LooseObjectStepTests.cs
index ff35b1d85e..b99d787abc 100644
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/LooseObjectStepTests.cs
+++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/LooseObjectStepTests.cs
@@ -31,7 +31,7 @@ public LooseObjectStepTests()
[Order(1)]
public void NoLooseObjectsDoesNothing()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
this.DeleteFiles(this.GetLooseObjectFiles());
this.DeleteFiles(this.GetLooseObjectFiles());
@@ -133,7 +133,7 @@ public void CorruptLooseObjectIsDeleted()
private void ClearAllObjects()
{
- this.Enlistment.UnmountScalar();
+ this.Enlistment.UnregisterRepo();
// Delete/Move any starting loose objects and packfiles
this.DeleteFiles(this.GetLooseObjectFiles());
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs
deleted file mode 100644
index 5ce991fa3c..0000000000
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-using NUnit.Framework;
-using Scalar.FunctionalTests.FileSystemRunners;
-using Scalar.FunctionalTests.Properties;
-using Scalar.FunctionalTests.Should;
-using Scalar.FunctionalTests.Tools;
-using Scalar.Tests.Should;
-using System.Diagnostics;
-using System.IO;
-
-namespace Scalar.FunctionalTests.Tests.EnlistmentPerFixture
-{
- [TestFixture]
- [Category(Categories.ExtraCoverage)]
- [Category(Categories.NeedsUpdatesForNonVirtualizedMode)]
- public class MountTests : TestsWithEnlistmentPerFixture
- {
- private const int ScalarGenericError = 3;
- private const uint GenericRead = 2147483648;
- private const uint FileFlagBackupSemantics = 3355443;
-
- private FileSystemRunner fileSystem;
-
- public MountTests()
- {
- this.fileSystem = new SystemIORunner();
- }
-
- [TestCaseSource(typeof(MountSubfolders), MountSubfolders.MountFolders)]
- public void SecondMountAttemptFails(string mountSubfolder)
- {
- this.MountShouldFail(0, "already mounted", this.Enlistment.GetSourcePath(mountSubfolder));
- }
-
- [TestCase]
- public void MountFailsOutsideEnlistment()
- {
- this.MountShouldFail("is not a valid Scalar enlistment", Path.GetDirectoryName(this.Enlistment.EnlistmentRoot));
- }
-
- [TestCase]
- public void MountSetsCoreHooksPath()
- {
- this.Enlistment.UnmountScalar();
-
- GitProcess.Invoke(this.Enlistment.RepoRoot, "config --unset core.hookspath");
- string.IsNullOrWhiteSpace(
- GitProcess.Invoke(this.Enlistment.RepoRoot, "config core.hookspath"))
- .ShouldBeTrue();
-
- this.Enlistment.MountScalar();
- string expectedHooksPath = Path.Combine(this.Enlistment.RepoRoot, ".git", "hooks");
- expectedHooksPath = GitHelpers.ConvertPathToGitFormat(expectedHooksPath);
-
- GitProcess.Invoke(
- this.Enlistment.RepoRoot, "config core.hookspath")
- .Trim('\n')
- .ShouldEqual(expectedHooksPath);
- }
-
- [TestCase]
- public void MountChangesMountId()
- {
- string mountId = GitProcess.Invoke(this.Enlistment.RepoRoot, "config scalar.mount-id")
- .Trim('\n');
- this.Enlistment.UnmountScalar();
- this.Enlistment.MountScalar();
- GitProcess.Invoke(this.Enlistment.RepoRoot, "config scalar.mount-id")
- .Trim('\n')
- .ShouldNotEqual(mountId, "scalar.mount-id should change on every mount");
- }
-
- [TestCase]
- public void MountFailsWhenNoOnDiskVersion()
- {
- this.Enlistment.UnmountScalar();
-
- // Get the current disk layout version
- string majorVersion;
- string minorVersion;
- ScalarHelpers.GetPersistedDiskLayoutVersion(this.Enlistment.DotScalarRoot, out majorVersion, out minorVersion);
-
- int majorVersionNum;
- int minorVersionNum;
- int.TryParse(majorVersion.ShouldNotBeNull(), out majorVersionNum).ShouldEqual(true);
- int.TryParse(minorVersion.ShouldNotBeNull(), out minorVersionNum).ShouldEqual(true);
-
- // Move the RepoMetadata database to a temp file
- string versionDatabasePath = Path.Combine(this.Enlistment.DotScalarRoot, ScalarHelpers.RepoMetadataName);
- versionDatabasePath.ShouldBeAFile(this.fileSystem);
-
- string tempDatabasePath = versionDatabasePath + "_MountFailsWhenNoOnDiskVersion";
- tempDatabasePath.ShouldNotExistOnDisk(this.fileSystem);
-
- this.fileSystem.MoveFile(versionDatabasePath, tempDatabasePath);
- versionDatabasePath.ShouldNotExistOnDisk(this.fileSystem);
-
- this.MountShouldFail("Failed to upgrade repo disk layout");
-
- // Move the RepoMetadata database back
- this.fileSystem.DeleteFile(versionDatabasePath);
- this.fileSystem.MoveFile(tempDatabasePath, versionDatabasePath);
- tempDatabasePath.ShouldNotExistOnDisk(this.fileSystem);
- versionDatabasePath.ShouldBeAFile(this.fileSystem);
-
- this.Enlistment.MountScalar();
- }
-
- [TestCase]
- public void MountFailsWhenNoGitObjectsRootInGitConfig()
- {
- this.Enlistment.UnmountScalar();
- string gitObjectsRoot = ScalarHelpers.GetObjectsRootFromGitConfig(this.Enlistment.RepoRoot);
-
- GitProcess.Invoke(this.Enlistment.RepoRoot, $"config --local --unset-all {ScalarHelpers.GitConfigObjectCache}");
- this.MountShouldFail("Failed to determine git objects root from git config");
- GitProcess.Invoke(this.Enlistment.RepoRoot, $"config--local {ScalarHelpers.GitConfigObjectCache} {gitObjectsRoot}");
- this.Enlistment.MountScalar();
- }
-
- [TestCase]
- public void MountRegeneratesAlternatesFileWhenMissingGitObjectsRoot()
- {
- this.Enlistment.UnmountScalar();
-
- string objectsRoot = ScalarHelpers.GetObjectsRootFromGitConfig(this.Enlistment.RepoRoot);
-
- string alternatesFilePath = Path.Combine(this.Enlistment.RepoRoot, ".git", "objects", "info", "alternates");
- alternatesFilePath.ShouldBeAFile(this.fileSystem).WithContents(objectsRoot);
- this.fileSystem.WriteAllText(alternatesFilePath, "Z:\\invalidPath");
-
- this.Enlistment.MountScalar();
-
- alternatesFilePath.ShouldBeAFile(this.fileSystem).WithContents(objectsRoot);
- }
-
- [TestCase]
- public void MountRegeneratesAlternatesFileWhenMissingFromDisk()
- {
- this.Enlistment.UnmountScalar();
-
- string objectsRoot = ScalarHelpers.GetObjectsRootFromGitConfig(this.Enlistment.RepoRoot);
-
- string alternatesFilePath = Path.Combine(this.Enlistment.RepoRoot, ".git", "objects", "info", "alternates");
- alternatesFilePath.ShouldBeAFile(this.fileSystem).WithContents(objectsRoot);
- this.fileSystem.DeleteFile(alternatesFilePath);
-
- this.Enlistment.MountScalar();
-
- alternatesFilePath.ShouldBeAFile(this.fileSystem).WithContents(objectsRoot);
- }
-
- [TestCaseSource(typeof(MountSubfolders), MountSubfolders.MountFolders)]
- public void MountFailsAfterBreakingDowngrade(string mountSubfolder)
- {
- MountSubfolders.EnsureSubfoldersOnDisk(this.Enlistment, this.fileSystem);
- this.Enlistment.UnmountScalar();
-
- string majorVersion;
- string minorVersion;
- ScalarHelpers.GetPersistedDiskLayoutVersion(this.Enlistment.DotScalarRoot, out majorVersion, out minorVersion);
-
- int majorVersionNum;
- int minorVersionNum;
- int.TryParse(majorVersion.ShouldNotBeNull(), out majorVersionNum).ShouldEqual(true);
- int.TryParse(minorVersion.ShouldNotBeNull(), out minorVersionNum).ShouldEqual(true);
-
- ScalarHelpers.SaveDiskLayoutVersion(this.Enlistment.DotScalarRoot, (majorVersionNum + 1).ToString(), "0");
-
- this.MountShouldFail("do not allow mounting after downgrade", this.Enlistment.GetSourcePath(mountSubfolder));
-
- ScalarHelpers.SaveDiskLayoutVersion(this.Enlistment.DotScalarRoot, majorVersionNum.ToString(), minorVersionNum.ToString());
- this.Enlistment.MountScalar();
- }
-
- [TestCaseSource(typeof(MountSubfolders), MountSubfolders.MountFolders)]
- public void MountFailsUpgradingFromInvalidUpgradePath(string mountSubfolder)
- {
- MountSubfolders.EnsureSubfoldersOnDisk(this.Enlistment, this.fileSystem);
- string headCommitId = GitProcess.Invoke(this.Enlistment.RepoRoot, "rev-parse HEAD");
-
- this.Enlistment.UnmountScalar();
-
- string majorVersion;
- string minorVersion;
- ScalarHelpers.GetPersistedDiskLayoutVersion(this.Enlistment.DotScalarRoot, out majorVersion, out minorVersion);
-
- int majorVersionNum;
- int minorVersionNum;
- int.TryParse(majorVersion.ShouldNotBeNull(), out majorVersionNum).ShouldEqual(true);
- int.TryParse(minorVersion.ShouldNotBeNull(), out minorVersionNum).ShouldEqual(true);
-
- // 1 will always be below the minumum support version number
- ScalarHelpers.SaveDiskLayoutVersion(this.Enlistment.DotScalarRoot, "1", "0");
- this.MountShouldFail("Breaking change to Scalar disk layout has been made since cloning", this.Enlistment.GetSourcePath(mountSubfolder));
-
- ScalarHelpers.SaveDiskLayoutVersion(this.Enlistment.DotScalarRoot, majorVersionNum.ToString(), minorVersionNum.ToString());
- this.Enlistment.MountScalar();
- }
-
- private void MountShouldFail(int expectedExitCode, string expectedErrorMessage, string mountWorkingDirectory = null)
- {
- string enlistmentRoot = this.Enlistment.EnlistmentRoot;
-
- // TODO: 865304 Use app.config instead of --internal* arguments
- ProcessStartInfo processInfo = new ProcessStartInfo(ScalarTestConfig.PathToScalar);
- processInfo.Arguments = "mount " + TestConstants.InternalUseOnlyFlag + " " + ScalarHelpers.GetInternalParameter();
- processInfo.WindowStyle = ProcessWindowStyle.Hidden;
- processInfo.WorkingDirectory = string.IsNullOrEmpty(mountWorkingDirectory) ? enlistmentRoot : mountWorkingDirectory;
- processInfo.UseShellExecute = false;
- processInfo.RedirectStandardOutput = true;
-
- ProcessResult result = ProcessHelper.Run(processInfo);
- result.ExitCode.ShouldEqual(expectedExitCode, $"mount exit code was not {expectedExitCode}. Output: {result.Output}");
- result.Output.ShouldContain(expectedErrorMessage);
- }
-
- private void MountShouldFail(string expectedErrorMessage, string mountWorkingDirectory = null)
- {
- this.MountShouldFail(ScalarGenericError, expectedErrorMessage, mountWorkingDirectory);
- }
-
- private class MountSubfolders
- {
- public const string MountFolders = "Folders";
- private static object[] mountFolders =
- {
- new object[] { string.Empty },
- new object[] { "GVFS" },
- };
-
- public static object[] Folders
- {
- get
- {
- return mountFolders;
- }
- }
-
- public static void EnsureSubfoldersOnDisk(ScalarFunctionalTestEnlistment enlistment, FileSystemRunner fileSystem)
- {
- // Enumerate the directory to ensure that the folder is on disk after Scalar is unmounted
- foreach (object[] folder in Folders)
- {
- string folderPath = enlistment.GetSourcePath((string)folder[0]);
- folderPath.ShouldBeADirectory(fileSystem).WithItems();
- }
- }
- }
- }
-}
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/TestsWithEnlistmentPerFixture.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/TestsWithEnlistmentPerFixture.cs
index 40b2ad867f..00d632d562 100644
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/TestsWithEnlistmentPerFixture.cs
+++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/TestsWithEnlistmentPerFixture.cs
@@ -27,13 +27,13 @@ public virtual void CreateEnlistment()
{
if (this.forcePerRepoObjectCache)
{
- this.Enlistment = ScalarFunctionalTestEnlistment.CloneAndMountWithPerRepoCache(
+ this.Enlistment = ScalarFunctionalTestEnlistment.CloneWithPerRepoCache(
ScalarTestConfig.PathToScalar,
this.skipFetchCommitsAndTreesDuringClone);
}
else
{
- this.Enlistment = ScalarFunctionalTestEnlistment.CloneAndMount(ScalarTestConfig.PathToScalar, fullClone: this.fullClone);
+ this.Enlistment = ScalarFunctionalTestEnlistment.Clone(ScalarTestConfig.PathToScalar, fullClone: this.fullClone);
}
}
@@ -42,7 +42,7 @@ public virtual void DeleteEnlistment()
{
if (this.Enlistment != null)
{
- this.Enlistment.UnmountAndDeleteAll();
+ this.Enlistment.DeleteAll();
}
}
}
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/UnmountTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/UnmountTests.cs
deleted file mode 100644
index d01dd6d5f9..0000000000
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/UnmountTests.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using NUnit.Framework;
-using Scalar.FunctionalTests.FileSystemRunners;
-using Scalar.FunctionalTests.Tools;
-using Scalar.Tests.Should;
-using System.Diagnostics;
-using System.IO;
-using System.Threading;
-
-namespace Scalar.FunctionalTests.Tests.EnlistmentPerFixture
-{
- [TestFixture]
- [Category(Categories.ExtraCoverage)]
- [Category(Categories.NeedsUpdatesForNonVirtualizedMode)]
- public class UnmountTests : TestsWithEnlistmentPerFixture
- {
- private FileSystemRunner fileSystem;
-
- public UnmountTests()
- {
- this.fileSystem = new SystemIORunner();
- }
-
- [SetUp]
- public void SetupTest()
- {
- ScalarProcess scalarProcess = new ScalarProcess(
- ScalarTestConfig.PathToScalar,
- this.Enlistment.EnlistmentRoot,
- Path.Combine(this.Enlistment.EnlistmentRoot, ScalarTestConfig.DotScalarRoot));
-
- if (!scalarProcess.IsEnlistmentMounted())
- {
- scalarProcess.Mount();
- }
- }
-
- [TestCase]
- public void UnmountWaitsForLock()
- {
- ManualResetEventSlim lockHolder = GitHelpers.AcquireScalarLock(this.Enlistment, out _);
-
- using (Process unmountingProcess = this.StartUnmount())
- {
- unmountingProcess.WaitForExit(3000).ShouldEqual(false, "Unmount completed while lock was acquired.");
-
- // Release the lock.
- lockHolder.Set();
-
- unmountingProcess.WaitForExit(10000).ShouldEqual(true, "Unmount didn't complete as expected.");
- }
- }
-
- [TestCase]
- public void UnmountSkipLock()
- {
- ManualResetEventSlim lockHolder = GitHelpers.AcquireScalarLock(this.Enlistment, out _, Timeout.Infinite, true);
-
- using (Process unmountingProcess = this.StartUnmount("--skip-wait-for-lock"))
- {
- unmountingProcess.WaitForExit(10000).ShouldEqual(true, "Unmount didn't complete as expected.");
- }
-
- // Signal process holding lock to terminate and release lock.
- lockHolder.Set();
- }
-
- private Process StartUnmount(string extraParams = "")
- {
- string enlistmentRoot = this.Enlistment.EnlistmentRoot;
-
- // TODO: 865304 Use app.config instead of --internal* arguments
- ProcessStartInfo processInfo = new ProcessStartInfo(ScalarTestConfig.PathToScalar);
- processInfo.Arguments = "unmount " + extraParams + " " + TestConstants.InternalUseOnlyFlag + " " + ScalarHelpers.GetInternalParameter();
- processInfo.WindowStyle = ProcessWindowStyle.Hidden;
- processInfo.WorkingDirectory = enlistmentRoot;
- processInfo.UseShellExecute = false;
-
- Process executingProcess = new Process();
- executingProcess.StartInfo = processInfo;
- executingProcess.Start();
-
- return executingProcess;
- }
- }
-}
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/CaseOnlyFolderRenameTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/CaseOnlyFolderRenameTests.cs
deleted file mode 100644
index 335d4f9563..0000000000
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/CaseOnlyFolderRenameTests.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using NUnit.Framework;
-using Scalar.FunctionalTests.FileSystemRunners;
-using Scalar.FunctionalTests.Should;
-using Scalar.Tests.Should;
-using System.IO;
-
-namespace Scalar.FunctionalTests.Tests.EnlistmentPerTestCase
-{
- [TestFixture]
- [Category(Categories.NeedsUpdatesForNonVirtualizedMode)]
- public class CaseOnlyFolderRenameTests : TestsWithEnlistmentPerTestCase
- {
- private FileSystemRunner fileSystem;
-
- public CaseOnlyFolderRenameTests()
- {
- this.fileSystem = new BashRunner();
- }
-
- // MacOnly because renames of partial folders are blocked on Windows
- [TestCase]
- [Category(Categories.MacOnly)]
- public void CaseRenameFoldersAndRemountAndRenameAgain()
- {
- // Projected folder without a physical folder
- string parentFolderName = "Scalar";
- string oldScalarSubFolderName = "Scalar";
- string oldScalarSubFolderPath = Path.Combine(parentFolderName, oldScalarSubFolderName);
- string newScalarSubFolderName = "scalar";
- string newScalarSubFolderPath = Path.Combine(parentFolderName, newScalarSubFolderName);
-
- this.Enlistment.GetSourcePath(oldScalarSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(oldScalarSubFolderName);
-
- this.fileSystem.MoveFile(this.Enlistment.GetSourcePath(oldScalarSubFolderPath), this.Enlistment.GetSourcePath(newScalarSubFolderPath));
-
- this.Enlistment.GetSourcePath(newScalarSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(newScalarSubFolderName);
-
- // Projected folder with a physical folder
- string oldTestsSubFolderName = "Scalar.FunctionalTests";
- string oldTestsSubFolderPath = Path.Combine(parentFolderName, oldTestsSubFolderName);
- string newTestsSubFolderName = "scalar.functionaltests";
- string newTestsSubFolderPath = Path.Combine(parentFolderName, newTestsSubFolderName);
-
- string fileToAdd = "NewFile.txt";
- string fileToAddContent = "This is new file text.";
- string fileToAddPath = this.Enlistment.GetSourcePath(Path.Combine(oldTestsSubFolderPath, fileToAdd));
- this.fileSystem.WriteAllText(fileToAddPath, fileToAddContent);
-
- this.Enlistment.GetSourcePath(oldTestsSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(oldTestsSubFolderName);
-
- this.fileSystem.MoveFile(this.Enlistment.GetSourcePath(oldTestsSubFolderPath), this.Enlistment.GetSourcePath(newTestsSubFolderPath));
-
- this.Enlistment.GetSourcePath(newTestsSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(newTestsSubFolderName);
-
- // Remount
- this.Enlistment.UnmountScalar();
- this.Enlistment.MountScalar();
-
- this.Enlistment.GetSourcePath(newScalarSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(newScalarSubFolderName);
- this.Enlistment.GetSourcePath(newTestsSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(newTestsSubFolderName);
- this.Enlistment.GetSourcePath(Path.Combine(newTestsSubFolderPath, fileToAdd)).ShouldBeAFile(this.fileSystem).WithContents().ShouldEqual(fileToAddContent);
-
- // Rename each folder again
- string finalScalarSubFolderName = "gvFS";
- string finalScalarSubFolderPath = Path.Combine(parentFolderName, finalScalarSubFolderName);
- this.fileSystem.MoveFile(this.Enlistment.GetSourcePath(newScalarSubFolderPath), this.Enlistment.GetSourcePath(finalScalarSubFolderPath));
- this.Enlistment.GetSourcePath(finalScalarSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(finalScalarSubFolderName);
-
- string finalTestsSubFolderName = "scalar.FunctionalTESTS";
- string finalTestsSubFolderPath = Path.Combine(parentFolderName, finalTestsSubFolderName);
- this.fileSystem.MoveFile(this.Enlistment.GetSourcePath(newTestsSubFolderPath), this.Enlistment.GetSourcePath(finalTestsSubFolderPath));
- this.Enlistment.GetSourcePath(finalTestsSubFolderPath).ShouldBeADirectory(this.fileSystem).WithCaseMatchingName(finalTestsSubFolderName);
- this.Enlistment.GetSourcePath(Path.Combine(finalTestsSubFolderPath, fileToAdd)).ShouldBeAFile(this.fileSystem).WithContents().ShouldEqual(fileToAddContent);
- }
- }
-}
diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/TestsWithEnlistmentPerTestCase.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/TestsWithEnlistmentPerTestCase.cs
index d84e0a796c..214a4a89eb 100644
--- a/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/TestsWithEnlistmentPerTestCase.cs
+++ b/Scalar.FunctionalTests/Tests/EnlistmentPerTestCase/TestsWithEnlistmentPerTestCase.cs
@@ -23,13 +23,13 @@ public virtual void CreateEnlistment()
{
if (this.forcePerRepoObjectCache)
{
- this.Enlistment = ScalarFunctionalTestEnlistment.CloneAndMountWithPerRepoCache(
+ this.Enlistment = ScalarFunctionalTestEnlistment.CloneWithPerRepoCache(
ScalarTestConfig.PathToScalar,
skipFetchCommitsAndTrees: false);
}
else
{
- this.Enlistment = ScalarFunctionalTestEnlistment.CloneAndMount(ScalarTestConfig.PathToScalar);
+ this.Enlistment = ScalarFunctionalTestEnlistment.Clone(ScalarTestConfig.PathToScalar);
}
}
@@ -38,7 +38,7 @@ public virtual void DeleteEnlistment()
{
if (this.Enlistment != null)
{
- this.Enlistment.UnmountAndDeleteAll();
+ this.Enlistment.DeleteAll();
}
}
}
diff --git a/Scalar.FunctionalTests/Tests/GitCommands/AddStageTests.cs b/Scalar.FunctionalTests/Tests/GitCommands/AddStageTests.cs
index 5434d6522f..e5b879a816 100644
--- a/Scalar.FunctionalTests/Tests/GitCommands/AddStageTests.cs
+++ b/Scalar.FunctionalTests/Tests/GitCommands/AddStageTests.cs
@@ -1,8 +1,5 @@
using NUnit.Framework;
using Scalar.FunctionalTests.Properties;
-using Scalar.FunctionalTests.Tools;
-using System.IO;
-using System.Threading;
namespace Scalar.FunctionalTests.Tests.GitCommands
{
@@ -42,28 +39,5 @@ public void AddAndStageHardLinksTest()
this.ValidateGitCommand("stage AuthoringTestsLink.md");
this.RunGitCommand("commit -m \"Created AuthoringTestsLink.md\"");
}
-
- [TestCase, Order(4)]
- public void AddAllowsPlaceholderCreation()
- {
- this.CommandAllowsPlaceholderCreation("add", "GVFS", "GVFS", "Program.cs");
- }
-
- [TestCase, Order(5)]
- public void StageAllowsPlaceholderCreation()
- {
- this.CommandAllowsPlaceholderCreation("stage", "GVFS", "GVFS", "App.config");
- }
-
- private void CommandAllowsPlaceholderCreation(string command, params string[] fileToReadPathParts)
- {
- string fileToRead = Path.Combine(fileToReadPathParts);
- this.EditFile($"Some new content for {command}.", "Protocol.md");
- ManualResetEventSlim resetEvent = GitHelpers.RunGitCommandWithWaitAndStdIn(this.Enlistment, resetTimeout: 3000, command: $"{command} -p", stdinToQuit: "q", processId: out _);
- this.FileContentsShouldMatch(fileToRead);
- this.ValidateGitCommand("--no-optional-locks status");
- resetEvent.Wait();
- this.RunGitCommand("reset --hard");
- }
}
}
diff --git a/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs b/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs
index bf543f0e30..15321a48b7 100644
--- a/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs
+++ b/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs
@@ -206,7 +206,7 @@ protected virtual void CreateEnlistment()
protected void CreateEnlistment(string commitish = null)
{
- this.Enlistment = ScalarFunctionalTestEnlistment.CloneAndMount(
+ this.Enlistment = ScalarFunctionalTestEnlistment.Clone(
ScalarTestConfig.PathToScalar,
commitish: commitish,
fullClone: this.validateWorkingTree != Settings.ValidateWorkingTreeMode.SparseMode);
@@ -219,7 +219,7 @@ protected virtual void DeleteEnlistment()
{
if (this.Enlistment != null)
{
- this.Enlistment.UnmountAndDeleteAll();
+ this.Enlistment.DeleteAll();
}
if (this.ControlGitRepo != null)
diff --git a/Scalar.FunctionalTests/Tests/GitCommands/ResetMixedTests.cs b/Scalar.FunctionalTests/Tests/GitCommands/ResetMixedTests.cs
index 74c35941ab..c66fe90b8a 100644
--- a/Scalar.FunctionalTests/Tests/GitCommands/ResetMixedTests.cs
+++ b/Scalar.FunctionalTests/Tests/GitCommands/ResetMixedTests.cs
@@ -43,19 +43,6 @@ public void ResetMixedAndCheckoutOrphanBranch()
this.FilesShouldMatchCheckoutOfTargetBranch();
}
- [TestCase]
- public void ResetMixedAndRemount()
- {
- this.ValidateGitCommand("checkout " + GitRepoTests.ConflictTargetBranch);
- this.ValidateGitCommand("reset --mixed HEAD~1");
- this.FilesShouldMatchCheckoutOfTargetBranch();
-
- this.Enlistment.UnmountScalar();
- this.Enlistment.MountScalar();
- this.ValidateGitCommand("status");
- this.FilesShouldMatchCheckoutOfTargetBranch();
- }
-
[TestCase]
public void ResetMixedThenCheckoutWithConflicts()
{
diff --git a/Scalar.FunctionalTests/Tests/GitCommands/ResetSoftTests.cs b/Scalar.FunctionalTests/Tests/GitCommands/ResetSoftTests.cs
index c7d96c5a8b..80770282b7 100644
--- a/Scalar.FunctionalTests/Tests/GitCommands/ResetSoftTests.cs
+++ b/Scalar.FunctionalTests/Tests/GitCommands/ResetSoftTests.cs
@@ -20,19 +20,6 @@ public void ResetSoft()
this.FilesShouldMatchCheckoutOfTargetBranch();
}
- [TestCase]
- public void ResetSoftThenRemount()
- {
- this.ValidateGitCommand("checkout " + GitRepoTests.ConflictTargetBranch);
- this.ValidateGitCommand("reset --soft HEAD~1");
- this.FilesShouldMatchCheckoutOfTargetBranch();
-
- this.Enlistment.UnmountScalar();
- this.Enlistment.MountScalar();
- this.ValidateGitCommand("status");
- this.FilesShouldMatchCheckoutOfTargetBranch();
- }
-
[TestCase]
public void ResetSoftThenCheckoutWithConflicts()
{
diff --git a/Scalar.FunctionalTests/Tests/GitCommands/StatusTests.cs b/Scalar.FunctionalTests/Tests/GitCommands/StatusTests.cs
index 5190390d8c..c727744371 100644
--- a/Scalar.FunctionalTests/Tests/GitCommands/StatusTests.cs
+++ b/Scalar.FunctionalTests/Tests/GitCommands/StatusTests.cs
@@ -210,7 +210,6 @@ private void WaitForStatusCacheToBeGenerated(bool waitForNewFile = true)
private void ValidGitStatusWithRetry(string srcPath)
{
- this.Enlistment.WaitForBackgroundOperations();
try
{
this.ValidateGitCommand("status");
diff --git a/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs b/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs
index 72dd404bc4..c928f3b240 100644
--- a/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs
+++ b/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs
@@ -38,13 +38,13 @@ public void SetCacheLocation()
[TestCase]
public void ParallelDownloadsInSharedCache()
{
- ScalarFunctionalTestEnlistment enlistment1 = this.CloneAndMountEnlistment();
- ScalarFunctionalTestEnlistment enlistment2 = this.CloneAndMountEnlistment();
+ ScalarFunctionalTestEnlistment enlistment1 = this.CloneEnlistment();
+ ScalarFunctionalTestEnlistment enlistment2 = this.CloneEnlistment();
ScalarFunctionalTestEnlistment enlistment3 = null;
Task task1 = Task.Run(() => this.LoadBlobsViaGit(enlistment1));
Task task2 = Task.Run(() => this.LoadBlobsViaGit(enlistment2));
- Task task3 = Task.Run(() => enlistment3 = this.CloneAndMountEnlistment());
+ Task task3 = Task.Run(() => enlistment3 = this.CloneEnlistment());
task1.Wait();
task2.Wait();
@@ -54,67 +54,30 @@ public void ParallelDownloadsInSharedCache()
task2.Exception.ShouldBeNull();
task3.Exception.ShouldBeNull();
- enlistment1.Status().ShouldContain("Mount status: Ready");
- enlistment2.Status().ShouldContain("Mount status: Ready");
- enlistment3.Status().ShouldContain("Mount status: Ready");
-
this.AlternatesFileShouldHaveGitObjectsRoot(enlistment1);
this.AlternatesFileShouldHaveGitObjectsRoot(enlistment2);
this.AlternatesFileShouldHaveGitObjectsRoot(enlistment3);
}
- [TestCase]
- [Category(Categories.NeedsUpdatesForNonVirtualizedMode)]
- public void DeleteObjectsCacheBeforeMount()
- {
- ScalarFunctionalTestEnlistment enlistment1 = this.CloneAndMountEnlistment();
- ScalarFunctionalTestEnlistment enlistment2 = this.CloneAndMountEnlistment();
-
- enlistment1.UnmountScalar();
-
- string objectsRoot = ScalarHelpers.GetObjectsRootFromGitConfig(enlistment1.RepoRoot);
- objectsRoot.ShouldBeADirectory(this.fileSystem);
- RepositoryHelpers.DeleteTestDirectory(objectsRoot);
-
- enlistment1.MountScalar();
-
- Task task1 = Task.Run(() => this.LoadBlobsViaGit(enlistment1));
- Task task2 = Task.Run(() => this.LoadBlobsViaGit(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);
- }
-
[TestCase]
public void DownloadingACommitWithoutTreesDoesntBreakNextClone()
{
- ScalarFunctionalTestEnlistment enlistment1 = this.CloneAndMountEnlistment();
+ ScalarFunctionalTestEnlistment enlistment1 = this.CloneEnlistment();
GitProcess.Invoke(enlistment1.RepoRoot, "cat-file -s " + WellKnownCommitSha).ShouldEqual("293\n");
- ScalarFunctionalTestEnlistment enlistment2 = this.CloneAndMountEnlistment(WellKnownBranch);
- enlistment2.Status().ShouldContain("Mount status: Ready");
+ ScalarFunctionalTestEnlistment enlistment2 = this.CloneEnlistment(WellKnownBranch);
}
[TestCase]
- public void MountReusesLocalCacheKeyWhenGitObjectsRootDeleted()
+ public void GitObjectsRecreatedWhenDownloadingObjects()
{
- ScalarFunctionalTestEnlistment enlistment = this.CloneAndMountEnlistment();
-
- enlistment.UnmountScalar();
+ ScalarFunctionalTestEnlistment enlistment = this.CloneEnlistment();
// Find the current git objects root and ensure it's on disk
string objectsRoot = ScalarHelpers.GetObjectsRootFromGitConfig(enlistment.RepoRoot);
objectsRoot.ShouldBeADirectory(this.fileSystem);
RepositoryHelpers.DeleteTestDirectory(objectsRoot);
- enlistment.MountScalar();
ScalarHelpers.GetObjectsRootFromGitConfig(enlistment.RepoRoot).ShouldEqual(objectsRoot);
@@ -155,7 +118,7 @@ protected override void OnTearDownEnlistmentsDeleted()
RepositoryHelpers.DeleteTestDirectory(this.localCacheParentPath);
}
- private ScalarFunctionalTestEnlistment CloneAndMountEnlistment(string branch = null)
+ private ScalarFunctionalTestEnlistment CloneEnlistment(string branch = null)
{
return this.CreateNewEnlistment(this.localCachePath, branch);
}
diff --git a/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/TestsWithMultiEnlistment.cs b/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/TestsWithMultiEnlistment.cs
index 46df05792d..d283f428f0 100644
--- a/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/TestsWithMultiEnlistment.cs
+++ b/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/TestsWithMultiEnlistment.cs
@@ -13,7 +13,7 @@ public void DeleteEnlistments()
{
foreach (ScalarFunctionalTestEnlistment enlistment in this.enlistmentsToDelete)
{
- enlistment.UnmountAndDeleteAll();
+ enlistment.DeleteAll();
}
this.OnTearDownEnlistmentsDeleted();
@@ -33,7 +33,7 @@ protected ScalarFunctionalTestEnlistment CreateNewEnlistment(
string branch = null,
bool skipFetchCommitsAndTrees = false)
{
- ScalarFunctionalTestEnlistment output = ScalarFunctionalTestEnlistment.CloneAndMount(
+ ScalarFunctionalTestEnlistment output = ScalarFunctionalTestEnlistment.Clone(
ScalarTestConfig.PathToScalar,
branch,
localCacheRoot,
diff --git a/Scalar.FunctionalTests/Tools/GitHelpers.cs b/Scalar.FunctionalTests/Tools/GitHelpers.cs
index 9f218bce0e..64a65e8050 100644
--- a/Scalar.FunctionalTests/Tools/GitHelpers.cs
+++ b/Scalar.FunctionalTests/Tools/GitHelpers.cs
@@ -7,49 +7,13 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-
namespace Scalar.FunctionalTests.Tools
{
public static class GitHelpers
{
- ///
- /// This string must match the command name provided in the
- /// Scalar.FunctionalTests.LockHolder program.
- ///
- private const string LockHolderCommandName = @"Scalar.FunctionalTests.LockHolder";
- private const string LockHolderCommand = @"Scalar.FunctionalTests.LockHolder.dll";
-
private const string WindowsPathSeparator = "\\";
private const string GitPathSeparator = "/";
- private static string LockHolderCommandPath
- {
- get
- {
- // On OSX functional tests are run from inside Publish directory. Dependent
- // assemblies including LockHolder test are available at the same level in
- // the same directory.
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- return Path.Combine(
- Settings.Default.CurrentDirectory,
- LockHolderCommand);
- }
- else
- {
- // On Windows, FT is run from the Output directory of Scalar.FunctionalTest project.
- // LockHolder is a .netcore assembly and can be found inside netcoreapp2.1
- // subdirectory of Scalar.FunctionalTest Output directory.
- return Path.Combine(
- Settings.Default.CurrentDirectory,
- "netcoreapp2.1",
- LockHolderCommand);
- }
- }
- }
-
public static string ConvertPathToGitFormat(string relativePath)
{
return relativePath.Replace(WindowsPathSeparator, GitPathSeparator);
@@ -138,133 +102,12 @@ public static void ValidateGitCommand(
}
}
- ///
- /// Acquire the ScalarLock. This method will return once the ScalarLock has been acquired.
- ///
- /// The ID of the process that acquired the lock.
- /// that can be signaled to exit the lock acquisition program.
- public static ManualResetEventSlim AcquireScalarLock(
- ScalarFunctionalTestEnlistment enlistment,
- out int processId,
- int resetTimeout = Timeout.Infinite,
- bool skipReleaseLock = false)
- {
- string args = LockHolderCommandPath;
- if (skipReleaseLock)
- {
- args += " --skip-release-lock";
- }
-
- return RunCommandWithWaitAndStdIn(
- enlistment,
- resetTimeout,
- "dotnet",
- args,
- GitHelpers.LockHolderCommandName,
- "done",
- out processId);
- }
-
- ///
- /// Run the specified Git command. This method will return once the ScalarLock has been acquired.
- ///
- /// The ID of the process that acquired the lock.
- /// that can be signaled to exit the lock acquisition program.
- public static ManualResetEventSlim RunGitCommandWithWaitAndStdIn(
- ScalarFunctionalTestEnlistment enlistment,
- int resetTimeout,
- string command,
- string stdinToQuit,
- out int processId)
- {
- return
- RunCommandWithWaitAndStdIn(
- enlistment,
- resetTimeout,
- Properties.Settings.Default.PathToGit,
- command,
- "git " + command,
- stdinToQuit,
- out processId);
- }
-
public static void ErrorsShouldMatch(string command, ProcessResult expectedResult, ProcessResult actualResult)
{
actualResult.Errors.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.ShouldMatchInOrder(expectedResult.Errors.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries), LinesAreEqual, command + " Errors Lines");
}
- ///
- /// Run the specified command as an external program. This method will return once the ScalarLock has been acquired.
- ///
- /// The ID of the process that acquired the lock.
- /// that can be signaled to exit the lock acquisition program.
- private static ManualResetEventSlim RunCommandWithWaitAndStdIn(
- ScalarFunctionalTestEnlistment enlistment,
- int resetTimeout,
- string pathToCommand,
- string args,
- string lockingProcessCommandName,
- string stdinToQuit,
- out int processId)
- {
- ManualResetEventSlim resetEvent = new ManualResetEventSlim(initialState: false);
-
- ProcessStartInfo processInfo = new ProcessStartInfo(pathToCommand);
- processInfo.WorkingDirectory = enlistment.RepoRoot;
- processInfo.UseShellExecute = false;
- processInfo.RedirectStandardOutput = true;
- processInfo.RedirectStandardError = true;
- processInfo.RedirectStandardInput = true;
- processInfo.Arguments = args;
-
- Process holdingProcess = Process.Start(processInfo);
- StreamWriter stdin = holdingProcess.StandardInput;
- processId = holdingProcess.Id;
-
- enlistment.WaitForLock(lockingProcessCommandName);
-
- Task.Run(
- () =>
- {
- resetEvent.Wait(resetTimeout);
-
- try
- {
- // Make sure to let the holding process end.
- if (stdin != null)
- {
- stdin.WriteLine(stdinToQuit);
- stdin.Close();
- }
-
- if (holdingProcess != null)
- {
- bool holdingProcessHasExited = holdingProcess.WaitForExit(10000);
-
- if (!holdingProcess.HasExited)
- {
- holdingProcess.Kill();
- }
-
- holdingProcess.Dispose();
-
- holdingProcessHasExited.ShouldBeTrue("Locking process did not exit in time.");
- }
- }
- catch (Exception ex)
- {
- Assert.Fail($"{nameof(RunCommandWithWaitAndStdIn)} exception closing stdin {ex.ToString()}");
- }
- finally
- {
- resetEvent.Set();
- }
- });
-
- return resetEvent;
- }
-
private static bool LinesAreEqual(string actualLine, string expectedLine)
{
return actualLine.Equals(expectedLine);
diff --git a/Scalar.FunctionalTests/Tools/ScalarFunctionalTestEnlistment.cs b/Scalar.FunctionalTests/Tools/ScalarFunctionalTestEnlistment.cs
index 03e5e83b05..100e48a59d 100644
--- a/Scalar.FunctionalTests/Tools/ScalarFunctionalTestEnlistment.cs
+++ b/Scalar.FunctionalTests/Tools/ScalarFunctionalTestEnlistment.cs
@@ -80,14 +80,14 @@ public string Commitish
get; private set;
}
- public static ScalarFunctionalTestEnlistment CloneAndMountWithPerRepoCache(string pathToGvfs, bool skipFetchCommitsAndTrees)
+ public static ScalarFunctionalTestEnlistment CloneWithPerRepoCache(string pathToGvfs, bool skipFetchCommitsAndTrees)
{
string enlistmentRoot = ScalarFunctionalTestEnlistment.GetUniqueEnlistmentRoot();
string localCache = ScalarFunctionalTestEnlistment.GetRepoSpecificLocalCacheRoot(enlistmentRoot);
- return CloneAndMount(pathToGvfs, enlistmentRoot, null, localCacheRoot: localCache, skipFetchCommitsAndTrees: skipFetchCommitsAndTrees);
+ return Clone(pathToGvfs, enlistmentRoot, null, localCacheRoot: localCache, skipFetchCommitsAndTrees: skipFetchCommitsAndTrees);
}
- public static ScalarFunctionalTestEnlistment CloneAndMount(
+ public static ScalarFunctionalTestEnlistment Clone(
string pathToGvfs,
string commitish = null,
string localCacheRoot = null,
@@ -95,14 +95,14 @@ public static ScalarFunctionalTestEnlistment CloneAndMount(
bool fullClone = true)
{
string enlistmentRoot = ScalarFunctionalTestEnlistment.GetUniqueEnlistmentRoot();
- return CloneAndMount(pathToGvfs, enlistmentRoot, commitish, localCacheRoot, skipFetchCommitsAndTrees, fullClone);
+ return Clone(pathToGvfs, enlistmentRoot, commitish, localCacheRoot, skipFetchCommitsAndTrees, fullClone);
}
- public static ScalarFunctionalTestEnlistment CloneAndMountEnlistmentWithSpacesInPath(string pathToGvfs, string commitish = null)
+ public static ScalarFunctionalTestEnlistment CloneEnlistmentWithSpacesInPath(string pathToGvfs, string commitish = null)
{
string enlistmentRoot = ScalarFunctionalTestEnlistment.GetUniqueEnlistmentRootWithSpaces();
string localCache = ScalarFunctionalTestEnlistment.GetRepoSpecificLocalCacheRoot(enlistmentRoot);
- return CloneAndMount(pathToGvfs, enlistmentRoot, commitish, localCache);
+ return Clone(pathToGvfs, enlistmentRoot, commitish, localCache);
}
public static string GetUniqueEnlistmentRoot()
@@ -126,7 +126,7 @@ public void DeleteEnlistment()
RepositoryHelpers.DeleteTestDirectory(this.EnlistmentRoot);
}
- public void CloneAndMount(bool skipFetchCommitsAndTrees)
+ public void Clone(bool skipFetchCommitsAndTrees)
{
this.scalarProcess.Clone(this.RepoUrl, this.Commitish, skipFetchCommitsAndTrees, fullClone: this.fullClone);
@@ -149,25 +149,14 @@ public void CloneAndMount(bool skipFetchCommitsAndTrees)
}
}
- public void MountScalar()
- {
- this.scalarProcess.Mount();
- }
-
- public bool TryMountScalar()
- {
- string output;
- return this.TryMountScalar(out output);
- }
-
- public bool TryMountScalar(out string output)
+ public string FetchCommitsAndTrees(bool failOnError = true, string standardInput = null)
{
- return this.scalarProcess.TryMount(out output);
+ return this.scalarProcess.FetchCommitsAndTrees(failOnError, standardInput);
}
- public string FetchCommitsAndTrees(bool failOnError = true, string standardInput = null)
+ public void UnregisterRepo()
{
- return this.scalarProcess.FetchCommitsAndTrees(failOnError, standardInput);
+ // TODO: #111: Unregister the repo from the service
}
public void Repair(bool confirm)
@@ -200,21 +189,6 @@ public string Status(string trace = null)
return this.scalarProcess.Status(trace);
}
- public bool WaitForBackgroundOperations(int maxWaitMilliseconds = DefaultMaxWaitMSForStatusCheck)
- {
- return this.WaitForStatus(maxWaitMilliseconds, ZeroBackgroundOperations).ShouldBeTrue("Background operations failed to complete.");
- }
-
- public bool WaitForLock(string lockCommand, int maxWaitMilliseconds = DefaultMaxWaitMSForStatusCheck)
- {
- return this.WaitForStatus(maxWaitMilliseconds, string.Format(LockHeldByGit, lockCommand));
- }
-
- public void UnmountScalar()
- {
- this.scalarProcess.Unmount();
- }
-
public string GetCacheServer()
{
return this.scalarProcess.CacheServer("--get");
@@ -225,9 +199,8 @@ public string SetCacheServer(string arg)
return this.scalarProcess.CacheServer("--set " + arg);
}
- public void UnmountAndDeleteAll()
+ public void DeleteAll()
{
- this.UnmountScalar();
this.DeleteEnlistment();
}
@@ -252,7 +225,7 @@ public string GetObjectPathTo(string objectHash)
objectHash.Substring(2));
}
- private static ScalarFunctionalTestEnlistment CloneAndMount(
+ private static ScalarFunctionalTestEnlistment Clone(
string pathToGvfs,
string enlistmentRoot,
string commitish,
@@ -270,11 +243,11 @@ private static ScalarFunctionalTestEnlistment CloneAndMount(
try
{
- enlistment.CloneAndMount(skipFetchCommitsAndTrees);
+ enlistment.Clone(skipFetchCommitsAndTrees);
}
catch (Exception e)
{
- Console.WriteLine("Unhandled exception in CloneAndMount: " + e.ToString());
+ Console.WriteLine($"Unhandled exception in {nameof(ScalarFunctionalTestEnlistment.Clone)}: " + e.ToString());
TestResultsHelper.OutputScalarLogs(enlistment);
throw;
}
@@ -286,19 +259,5 @@ private static string GetRepoSpecificLocalCacheRoot(string enlistmentRoot)
{
return Path.Combine(enlistmentRoot, ScalarTestConfig.DotScalarRoot, ".scalarCache");
}
-
- private bool WaitForStatus(int maxWaitMilliseconds, string statusShouldContain)
- {
- string status = null;
- int totalWaitMilliseconds = 0;
- while (totalWaitMilliseconds <= maxWaitMilliseconds && (status == null || !status.Contains(statusShouldContain)))
- {
- Thread.Sleep(SleepMSWaitingForStatusCheck);
- status = this.Status();
- totalWaitMilliseconds += SleepMSWaitingForStatusCheck;
- }
-
- return totalWaitMilliseconds <= maxWaitMilliseconds;
- }
}
}
diff --git a/Scalar.Installer.Mac/scripts/preinstall b/Scalar.Installer.Mac/scripts/preinstall
index 926d22c6be..205e27c904 100755
--- a/Scalar.Installer.Mac/scripts/preinstall
+++ b/Scalar.Installer.Mac/scripts/preinstall
@@ -2,7 +2,7 @@
SCALARBINPATH="/usr/local/scalar/scalar"
if [ -f "${SCALARBINPATH}" ]; then
- unmountCmd="${SCALARBINPATH} service --unmount-all"
+ unmountCmd="${SCALARBINPATH} service --help"
echo $unmountCmd
eval $unmountCmd || exit 1
fi
diff --git a/Scalar.Installer.Mac/uninstall_scalar.sh b/Scalar.Installer.Mac/uninstall_scalar.sh
index ed356d3330..78f36e1e70 100755
--- a/Scalar.Installer.Mac/uninstall_scalar.sh
+++ b/Scalar.Installer.Mac/uninstall_scalar.sh
@@ -9,16 +9,6 @@ ScalarCOMMANDPATH="/usr/local/bin/scalar"
UNINSTALLERCOMMANDPATH="/usr/local/bin/uninstall_scalar.sh"
INSTALLERPACKAGEID="com.scalar.pkg"
-function UnloadKext()
-{
- kextLoaded=`/usr/sbin/kextstat -b "$KEXTID" | wc -l`
- if [ $kextLoaded -eq "2" ]; then
- unloadCmd="sudo /sbin/kextunload -b $KEXTID"
- echo "$unloadCmd..."
- eval $unloadCmd || exit 1
- fi
-}
-
function UnInstallScalar()
{
if [ -f "${LAUNCHDAEMONDIRECTORY}/$LOGDAEMONLAUNCHDFILENAME" ]; then
@@ -82,7 +72,6 @@ function ForgetPackage()
function Run()
{
- UnloadKext
UnInstallScalar
ForgetPackage
echo "Successfully uninstalled Scalar"
diff --git a/Scalar.Installer.Windows/Setup.iss b/Scalar.Installer.Windows/Setup.iss
index b900711b63..71ec1740e6 100644
--- a/Scalar.Installer.Windows/Setup.iss
+++ b/Scalar.Installer.Windows/Setup.iss
@@ -330,69 +330,39 @@ begin
DeleteFile(TempFilename);
end;
-procedure UnmountRepos();
+procedure StopMaintenanceTasks();
var
ResultCode: integer;
begin
- Exec('scalar.exe', 'service --unmount-all', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ // TODO: #185 Instead of calling --help, use the correct action for stopping the
+ // maintenance task
+ Exec('scalar.exe', 'service --help', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end;
-procedure MountRepos();
+procedure RegisterUserWithService();
var
StatusText: string;
- MountOutput: ansiString;
+ RegisterOutput: ansiString;
ResultCode: integer;
MsgBoxText: string;
begin
StatusText := WizardForm.StatusLabel.Caption;
- WizardForm.StatusLabel.Caption := 'Mounting Repos.';
+ WizardForm.StatusLabel.Caption := 'Registering with service.';
WizardForm.ProgressGauge.Style := npbstMarquee;
- ExecWithResult(ExpandConstant('{app}') + '\scalar.exe', 'service --mount-all', '', SW_HIDE, ewWaitUntilTerminated, ResultCode, MountOutput);
+ // TODO: #190 Instead of --help use the service action that will register the user with the service
+ ExecWithResult(ExpandConstant('{app}') + '\scalar.exe', 'service --help', '', SW_HIDE, ewWaitUntilTerminated, ResultCode, RegisterOutput);
WizardForm.StatusLabel.Caption := StatusText;
WizardForm.ProgressGauge.Style := npbstNormal;
if (ResultCode <> 0) then
begin
- MsgBoxText := 'Mounting one or more repos failed:' + #13#10 + MountOutput;
+ MsgBoxText := 'Registering with service failed:' + #13#10 + RegisterOutput;
SuppressibleMsgBox(MsgBoxText, mbConfirmation, MB_OK, IDOK);
ExitCode := 17;
end;
end;
-function ConfirmUnmountAll(): Boolean;
-var
- MsgBoxResult: integer;
- Repos: ansiString;
- ResultCode: integer;
- MsgBoxText: string;
-begin
- Result := False;
- if ExecWithResult('scalar.exe', 'service --list-mounted', '', SW_HIDE, ewWaitUntilTerminated, ResultCode, Repos) then
- begin
- if Repos = '' then
- begin
- Result := False;
- end
- else
- begin
- if ResultCode = 0 then
- begin
- MsgBoxText := 'The following repos are currently mounted:' + #13#10 + Repos + #13#10 + 'Setup needs to unmount all repos before it can proceed, and those repos will be unavailable while setup is running. Do you want to continue?';
- MsgBoxResult := SuppressibleMsgBox(MsgBoxText, mbConfirmation, MB_OKCANCEL, IDOK);
- if (MsgBoxResult = IDOK) then
- begin
- Result := True;
- end
- else
- begin
- Abort();
- end;
- end;
- end;
- end;
-end;
-
function EnsureScalarNotRunning(): Boolean;
var
MsgBoxResult: integer;
@@ -419,7 +389,7 @@ end;
function InitializeUninstall(): Boolean;
begin
- UnmountRepos();
+ StopMaintenanceTasks();
Result := EnsureScalarNotRunning();
end;
@@ -443,11 +413,7 @@ begin
end;
ssPostInstall:
begin
- if ExpandConstant('{param:REMOUNTREPOS|true}') = 'true' then
- begin
- StartScalarServiceUI();
- MountRepos();
- end
+ RegisterUserWithService();
end;
end;
end;
@@ -473,13 +439,7 @@ function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
NeedsRestart := False;
Result := '';
- if ConfirmUnmountAll() then
- begin
- if ExpandConstant('{param:REMOUNTREPOS|true}') = 'true' then
- begin
- UnmountRepos();
- end
- end;
+ StopMaintenanceTasks();
if not EnsureScalarNotRunning() then
begin
Abort();
diff --git a/Scalar/CommandLine/CloneVerb.cs b/Scalar/CommandLine/CloneVerb.cs
index 042ad61657..63c912ef01 100644
--- a/Scalar/CommandLine/CloneVerb.cs
+++ b/Scalar/CommandLine/CloneVerb.cs
@@ -3,6 +3,7 @@
using Scalar.Common.FileSystem;
using Scalar.Common.Git;
using Scalar.Common.Http;
+using Scalar.Common.NamedPipes;
using Scalar.Common.Tracing;
using System;
using System.Diagnostics;
@@ -11,7 +12,7 @@
namespace Scalar.CommandLine
{
- [Verb(CloneVerb.CloneVerbName, HelpText = "Clone a git repo and mount it as a Scalar virtual repo")]
+ [Verb(CloneVerb.CloneVerbName, HelpText = "Clone a git repo and register it with the service as a Scalar repo")]
public class CloneVerb : ScalarVerb
{
private const string CloneVerbName = "clone";
@@ -278,17 +279,9 @@ private Result DoClone(string fullEnlistmentRootPathParameter, string normalized
this.ConfigureWatchmanIntegration();
- this.Execute(
- this.enlistment,
- verb =>
- {
- verb.SkipMountedCheck = true;
- verb.SkipVersionCheck = true;
- verb.ResolvedCacheServer = this.cacheServer;
- verb.DownloadedScalarConfig = this.serverScalarConfig;
- });
-
cloneResult = this.CheckoutRepo();
+
+ this.RegisterWithService();
}
return cloneResult;
@@ -471,11 +464,6 @@ private void CheckNotInsideExistingRepo(string normalizedEnlistmentRootPath)
{
this.ReportErrorAndExit("Error: You can't clone inside an existing Scalar repo ({0})", existingEnlistmentRoot);
}
-
- if (this.IsExistingPipeListening(normalizedEnlistmentRootPath))
- {
- this.ReportErrorAndExit($"Error: There is currently a Scalar.Mount process running for '{normalizedEnlistmentRootPath}'. This process must be stopped before cloning.");
- }
}
private bool TryDetermineLocalCacheAndInitializePaths(string localCacheRoot, out string errorMessage)
@@ -587,6 +575,82 @@ private Result CreateClone()
return new Result(true);
}
+ private void RegisterWithService()
+ {
+ if (!this.Unattended)
+ {
+ this.tracer.RelatedInfo($"{nameof(this.Execute)}: Registering with service");
+
+ string errorMessage = string.Empty;
+ if (this.ShowStatusWhileRunning(
+ () => { return this.RegisterRepoWithService(out errorMessage); },
+ "Registering with service"))
+ {
+ this.tracer.RelatedInfo($"{nameof(this.Execute)}: Registered with service");
+ }
+ else
+ {
+ this.Output.WriteLine(" WARNING: " + errorMessage);
+ this.tracer.RelatedInfo($"{nameof(this.Execute)}: Failed to register with service");
+ }
+ }
+ }
+
+ private bool RegisterRepoWithService(out string errorMessage)
+ {
+ errorMessage = string.Empty;
+
+ NamedPipeMessages.RegisterRepoRequest request = new NamedPipeMessages.RegisterRepoRequest();
+ request.EnlistmentRoot = this.enlistment.EnlistmentRoot;
+
+ request.OwnerSID = ScalarPlatform.Instance.GetCurrentUser();
+
+ using (NamedPipeClient client = new NamedPipeClient(this.ServicePipeName))
+ {
+ if (!client.Connect())
+ {
+ errorMessage = "Unable to register repo because Scalar.Service is not responding.";
+ return false;
+ }
+
+ try
+ {
+ client.SendRequest(request.ToMessage());
+ NamedPipeMessages.Message response = client.ReadResponse();
+ if (response.Header == NamedPipeMessages.RegisterRepoRequest.Response.Header)
+ {
+ NamedPipeMessages.RegisterRepoRequest.Response message = NamedPipeMessages.RegisterRepoRequest.Response.FromMessage(response);
+
+ if (!string.IsNullOrEmpty(message.ErrorMessage))
+ {
+ errorMessage = message.ErrorMessage;
+ return false;
+ }
+
+ if (message.State != NamedPipeMessages.CompletionState.Success)
+ {
+ errorMessage = "Unable to register repo. " + errorMessage;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ errorMessage = string.Format("Scalar.Service responded with unexpected message: {0}", response);
+ return false;
+ }
+ }
+ catch (BrokenPipeException e)
+ {
+ errorMessage = "Unable to communicate with Scalar.Service: " + e.ToString();
+ return false;
+ }
+ }
+ }
+
private Result TryInitRepo()
{
string repoPath = this.enlistment.WorkingDirectoryBackingRoot;
diff --git a/Scalar/CommandLine/DiagnoseVerb.cs b/Scalar/CommandLine/DiagnoseVerb.cs
index bd25d4d1cd..fd085f289d 100644
--- a/Scalar/CommandLine/DiagnoseVerb.cs
+++ b/Scalar/CommandLine/DiagnoseVerb.cs
@@ -78,12 +78,7 @@ protected override void Execute(ScalarEnlistment enlistment)
this.RecordVersionInformation();
- this.ShowStatusWhileRunning(
- () =>
- this.RunAndRecordScalarVerb(archiveFolderPath, "scalar_status.txt") != ReturnCode.Success ||
- this.RunAndRecordScalarVerb(archiveFolderPath, "scalar_unmount.txt", verb => verb.SkipLock = true) == ReturnCode.Success,
- "Unmounting",
- suppressGvfsLogMessage: true);
+ this.RunAndRecordScalarVerb(archiveFolderPath, "scalar_status.txt");
this.ShowStatusWhileRunning(
() =>
@@ -157,11 +152,6 @@ protected override void Execute(ScalarEnlistment enlistment)
},
"Copying logs");
- this.ShowStatusWhileRunning(
- () => this.RunAndRecordScalarVerb(archiveFolderPath, "scalar_mount.txt") == ReturnCode.Success,
- "Mounting",
- suppressGvfsLogMessage: true);
-
this.CopyAllFiles(enlistment.DotScalarRoot, Path.Combine(archiveFolderPath, ScalarPlatform.Instance.Constants.DotScalarRoot), "logs", copySubFolders: false);
}
diff --git a/Scalar/CommandLine/MountVerb.cs b/Scalar/CommandLine/MountVerb.cs
deleted file mode 100644
index d3a257c0ba..0000000000
--- a/Scalar/CommandLine/MountVerb.cs
+++ /dev/null
@@ -1,323 +0,0 @@
-using CommandLine;
-using Scalar.Common;
-using Scalar.Common.FileSystem;
-using Scalar.Common.Git;
-using Scalar.Common.Http;
-using Scalar.Common.NamedPipes;
-using Scalar.Common.Tracing;
-using Scalar.DiskLayoutUpgrades;
-using System;
-using System.IO;
-
-namespace Scalar.CommandLine
-{
- [Verb(MountVerb.MountVerbName, HelpText = "Mount a Scalar virtual repo")]
- public class MountVerb : ScalarVerb.ForExistingEnlistment
- {
- private const string MountVerbName = "mount";
-
- [Option(
- 'v',
- ScalarConstants.VerbParameters.Mount.Verbosity,
- Default = ScalarConstants.VerbParameters.Mount.DefaultVerbosity,
- Required = false,
- HelpText = "Sets the verbosity of console logging. Accepts: Verbose, Informational, Warning, Error")]
- public string Verbosity { get; set; }
-
- [Option(
- 'k',
- ScalarConstants.VerbParameters.Mount.Keywords,
- Default = ScalarConstants.VerbParameters.Mount.DefaultKeywords,
- Required = false,
- HelpText = "A CSV list of logging filter keywords. Accepts: Any, Network")]
- public string KeywordsCsv { get; set; }
-
- public bool SkipMountedCheck { get; set; }
- public bool SkipVersionCheck { get; set; }
- public CacheServerInfo ResolvedCacheServer { get; set; }
- public ServerScalarConfig DownloadedScalarConfig { get; set; }
-
- protected override string VerbName
- {
- get { return MountVerbName; }
- }
-
- public override void InitializeDefaultParameterValues()
- {
- this.Verbosity = ScalarConstants.VerbParameters.Mount.DefaultVerbosity;
- this.KeywordsCsv = ScalarConstants.VerbParameters.Mount.DefaultKeywords;
- }
-
- protected override void PreCreateEnlistment()
- {
- string errorMessage;
- string enlistmentRoot;
- if (!ScalarPlatform.Instance.TryGetScalarEnlistmentRoot(this.EnlistmentRootPathParameter, out enlistmentRoot, out errorMessage))
- {
- this.ReportErrorAndExit("Error: '{0}' is not a valid Scalar enlistment", this.EnlistmentRootPathParameter);
- }
-
- if (!this.SkipMountedCheck)
- {
- if (this.IsExistingPipeListening(enlistmentRoot))
- {
- this.ReportErrorAndExit(tracer: null, exitCode: ReturnCode.Success, error: $"The repo at '{enlistmentRoot}' is already mounted.");
- }
- }
-
- if (!DiskLayoutUpgrade.TryRunAllUpgrades(enlistmentRoot))
- {
- this.ReportErrorAndExit("Failed to upgrade repo disk layout. " + ConsoleHelper.GetScalarLogMessage(enlistmentRoot));
- }
-
- string error;
- if (!DiskLayoutUpgrade.TryCheckDiskLayoutVersion(tracer: null, enlistmentRoot: enlistmentRoot, error: out error))
- {
- this.ReportErrorAndExit("Error: " + error);
- }
- }
-
- protected override void Execute(ScalarEnlistment enlistment)
- {
- string errorMessage = null;
- string mountExecutableLocation = null;
- using (JsonTracer tracer = new JsonTracer(ScalarConstants.ScalarEtwProviderName, "ExecuteMount"))
- {
- PhysicalFileSystem fileSystem = new PhysicalFileSystem();
- ScalarContext context = new ScalarContext(tracer, fileSystem, enlistment);
-
- CacheServerInfo cacheServer = this.ResolvedCacheServer ?? CacheServerResolver.GetCacheServerFromConfig(enlistment);
-
- tracer.AddLogFileEventListener(
- ScalarEnlistment.GetNewScalarLogFileName(enlistment.ScalarLogsRoot, ScalarConstants.LogFileTypes.MountVerb),
- EventLevel.Verbose,
- Keywords.Any);
- tracer.WriteStartEvent(
- enlistment.EnlistmentRoot,
- enlistment.RepoUrl,
- cacheServer.Url,
- this.AddVerbDataToMetadata(new EventMetadata
- {
- { "Unattended", this.Unattended },
- { "IsElevated", ScalarPlatform.Instance.IsElevated() },
- { "NamedPipeName", enlistment.NamedPipeName },
- { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter },
- }));
-
- RetryConfig retryConfig = null;
- ServerScalarConfig serverScalarConfig = this.DownloadedScalarConfig;
- if (!this.SkipVersionCheck)
- {
- string authErrorMessage;
- if (!this.TryAuthenticate(tracer, enlistment, out authErrorMessage))
- {
- this.Output.WriteLine(" WARNING: " + authErrorMessage);
- this.Output.WriteLine(" Mount will proceed, but new files cannot be accessed until Scalar can authenticate.");
- }
-
- if (serverScalarConfig == null)
- {
- if (retryConfig == null)
- {
- retryConfig = this.GetRetryConfig(tracer, enlistment);
- }
-
- serverScalarConfig = this.QueryScalarConfig(tracer, enlistment, retryConfig);
- }
-
- this.ValidateClientVersions(tracer, enlistment, serverScalarConfig, showWarnings: true);
-
- CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment);
- cacheServer = cacheServerResolver.ResolveNameFromRemote(cacheServer.Url, serverScalarConfig);
- this.Output.WriteLine("Configured cache server: " + cacheServer);
- }
-
- this.InitializeLocalCacheAndObjectsPaths(tracer, enlistment, retryConfig, serverScalarConfig, cacheServer);
-
- if (!this.ShowStatusWhileRunning(
- () => { return this.PerformPreMountValidation(tracer, enlistment, out mountExecutableLocation, out errorMessage); },
- "Validating repo"))
- {
- this.ReportErrorAndExit(tracer, errorMessage);
- }
-
- if (!this.SkipVersionCheck)
- {
- string error;
- if (!RepoMetadata.TryInitialize(tracer, enlistment.DotScalarRoot, out error))
- {
- this.ReportErrorAndExit(tracer, error);
- }
-
- try
- {
- GitProcess git = new GitProcess(enlistment);
- this.LogEnlistmentInfoAndSetConfigValues(tracer, git, enlistment);
- }
- finally
- {
- RepoMetadata.Shutdown();
- }
- }
-
- if (!this.ShowStatusWhileRunning(
- () => { return this.TryMount(tracer, enlistment, mountExecutableLocation, out errorMessage); },
- "Mounting"))
- {
- this.ReportErrorAndExit(tracer, errorMessage);
- }
-
- if (!this.Unattended)
- {
- tracer.RelatedInfo($"{nameof(this.Execute)}: Registering for automount");
-
- if (this.ShowStatusWhileRunning(
- () => { return this.RegisterMount(enlistment, out errorMessage); },
- "Registering for automount"))
- {
- tracer.RelatedInfo($"{nameof(this.Execute)}: Registered for automount");
- }
- else
- {
- this.Output.WriteLine(" WARNING: " + errorMessage);
- tracer.RelatedInfo($"{nameof(this.Execute)}: Failed to register for automount");
- }
- }
- }
- }
-
- private bool PerformPreMountValidation(ITracer tracer, ScalarEnlistment enlistment, out string mountExecutableLocation, out string errorMessage)
- {
- errorMessage = string.Empty;
- mountExecutableLocation = string.Empty;
-
- // We have to parse these parameters here to make sure they are valid before
- // handing them to the background process which cannot tell the user when they are bad
- EventLevel verbosity;
- Keywords keywords;
- this.ParseEnumArgs(out verbosity, out keywords);
-
- mountExecutableLocation = Path.Combine(ProcessHelper.GetCurrentProcessLocation(), ScalarPlatform.Instance.Constants.MountExecutableName);
- if (!File.Exists(mountExecutableLocation))
- {
- errorMessage = $"Could not find {ScalarPlatform.Instance.Constants.MountExecutableName}. You may need to reinstall Scalar.";
- return false;
- }
-
- GitProcess git = new GitProcess(enlistment);
- if (!git.IsValidRepo())
- {
- errorMessage = "The .git folder is missing or has invalid contents";
- return false;
- }
-
- if (!ScalarPlatform.Instance.FileSystem.IsFileSystemSupported(enlistment.EnlistmentRoot, out string error))
- {
- errorMessage = $"FileSystem unsupported: {error}";
- return false;
- }
-
- return true;
- }
-
- private bool TryMount(ITracer tracer, ScalarEnlistment enlistment, string mountExecutableLocation, out string errorMessage)
- {
- if (!ScalarVerb.TrySetRequiredGitConfigSettings(enlistment))
- {
- errorMessage = "Unable to configure git repo";
- return false;
- }
-
- const string ParamPrefix = "--";
-
- tracer.RelatedInfo($"{nameof(this.TryMount)}: Launching background process('{mountExecutableLocation}') for {enlistment.EnlistmentRoot}");
-
- ScalarPlatform.Instance.StartBackgroundScalarProcess(
- tracer,
- mountExecutableLocation,
- new[]
- {
- enlistment.EnlistmentRoot,
- ParamPrefix + ScalarConstants.VerbParameters.Mount.Verbosity,
- this.Verbosity,
- ParamPrefix + ScalarConstants.VerbParameters.Mount.Keywords,
- this.KeywordsCsv,
- ParamPrefix + ScalarConstants.VerbParameters.Mount.StartedByService,
- this.StartedByService.ToString(),
- ParamPrefix + ScalarConstants.VerbParameters.Mount.StartedByVerb,
- true.ToString()
- });
-
- tracer.RelatedInfo($"{nameof(this.TryMount)}: Waiting for repo to be mounted");
- return ScalarEnlistment.WaitUntilMounted(tracer, enlistment.EnlistmentRoot, this.Unattended, out errorMessage);
- }
-
- private bool RegisterMount(ScalarEnlistment enlistment, out string errorMessage)
- {
- errorMessage = string.Empty;
-
- NamedPipeMessages.RegisterRepoRequest request = new NamedPipeMessages.RegisterRepoRequest();
- request.EnlistmentRoot = enlistment.EnlistmentRoot;
-
- request.OwnerSID = ScalarPlatform.Instance.GetCurrentUser();
-
- using (NamedPipeClient client = new NamedPipeClient(this.ServicePipeName))
- {
- if (!client.Connect())
- {
- errorMessage = "Unable to register repo because Scalar.Service is not responding.";
- return false;
- }
-
- try
- {
- client.SendRequest(request.ToMessage());
- NamedPipeMessages.Message response = client.ReadResponse();
- if (response.Header == NamedPipeMessages.RegisterRepoRequest.Response.Header)
- {
- NamedPipeMessages.RegisterRepoRequest.Response message = NamedPipeMessages.RegisterRepoRequest.Response.FromMessage(response);
-
- if (!string.IsNullOrEmpty(message.ErrorMessage))
- {
- errorMessage = message.ErrorMessage;
- return false;
- }
-
- if (message.State != NamedPipeMessages.CompletionState.Success)
- {
- errorMessage = "Unable to register repo. " + errorMessage;
- return false;
- }
- else
- {
- return true;
- }
- }
- else
- {
- errorMessage = string.Format("Scalar.Service responded with unexpected message: {0}", response);
- return false;
- }
- }
- catch (BrokenPipeException e)
- {
- errorMessage = "Unable to communicate with Scalar.Service: " + e.ToString();
- return false;
- }
- }
- }
-
- private void ParseEnumArgs(out EventLevel verbosity, out Keywords keywords)
- {
- if (!Enum.TryParse(this.KeywordsCsv, out keywords))
- {
- this.ReportErrorAndExit("Error: Invalid logging filter keywords: " + this.KeywordsCsv);
- }
-
- if (!Enum.TryParse(this.Verbosity, out verbosity))
- {
- this.ReportErrorAndExit("Error: Invalid logging verbosity: " + this.Verbosity);
- }
- }
- }
-}
diff --git a/Scalar/CommandLine/ScalarVerb.cs b/Scalar/CommandLine/ScalarVerb.cs
index 60ac12e0e1..c7a1bb5adb 100644
--- a/Scalar/CommandLine/ScalarVerb.cs
+++ b/Scalar/CommandLine/ScalarVerb.cs
@@ -436,19 +436,6 @@ protected VstsInfoData QueryVstsInfo(ITracer tracer, ScalarEnlistment enlistment
return vstsInfo;
}
- protected bool IsExistingPipeListening(string enlistmentRoot)
- {
- using (NamedPipeClient pipeClient = new NamedPipeClient(ScalarPlatform.Instance.GetNamedPipeName(enlistmentRoot)))
- {
- if (pipeClient.Connect(500))
- {
- return true;
- }
- }
-
- return false;
- }
-
protected void ValidateClientVersions(ITracer tracer, ScalarEnlistment enlistment, ServerScalarConfig scalarConfig, bool showWarnings)
{
this.CheckGitVersion(tracer, enlistment, out string gitVersion);
diff --git a/Scalar/CommandLine/ServiceVerb.cs b/Scalar/CommandLine/ServiceVerb.cs
index 9f290d7622..5336720828 100644
--- a/Scalar/CommandLine/ServiceVerb.cs
+++ b/Scalar/CommandLine/ServiceVerb.cs
@@ -14,24 +14,10 @@ public class ServiceVerb : ScalarVerb.ForNoEnlistment
private const string ServiceVerbName = "service";
[Option(
- "mount-all",
+ "list-registered",
Default = false,
Required = false,
- HelpText = "Mounts all repos")]
- public bool MountAll { get; set; }
-
- [Option(
- "unmount-all",
- Default = false,
- Required = false,
- HelpText = "Unmounts all repos")]
- public bool UnmountAll { get; set; }
-
- [Option(
- "list-mounted",
- Default = false,
- Required = false,
- HelpText = "Prints a list of all mounted repos")]
+ HelpText = "Prints a list of all repos registered with the service")]
public bool List { get; set; }
protected override string VerbName
@@ -41,7 +27,7 @@ protected override string VerbName
public override void Execute()
{
- int optionCount = new[] { this.MountAll, this.UnmountAll, this.List }.Count(flag => flag);
+ int optionCount = new[] { this.List }.Count(flag => flag);
if (optionCount == 0)
{
this.ReportErrorAndExit($"Error: You must specify an argument. Run 'scalar {ServiceVerbName} --help' for details.");
@@ -62,66 +48,7 @@ public override void Execute()
{
foreach (string repoRoot in repoList)
{
- if (this.IsRepoMounted(repoRoot))
- {
- this.Output.WriteLine(repoRoot);
- }
- }
- }
- else if (this.MountAll)
- {
- List failedRepoRoots = new List();
-
- foreach (string repoRoot in repoList)
- {
- if (!this.IsRepoMounted(repoRoot))
- {
- this.Output.WriteLine("\r\nMounting repo at " + repoRoot);
- ReturnCode result = this.Execute(repoRoot);
-
- if (result != ReturnCode.Success)
- {
- failedRepoRoots.Add(repoRoot);
- }
- }
- }
-
- if (failedRepoRoots.Count() > 0)
- {
- string errorString = $"The following repos failed to mount:{Environment.NewLine}{string.Join("\r\n", failedRepoRoots.ToArray())}";
- Console.Error.WriteLine(errorString);
- this.ReportErrorAndExit(Environment.NewLine + errorString);
- }
- }
- else if (this.UnmountAll)
- {
- List failedRepoRoots = new List();
-
- foreach (string repoRoot in repoList)
- {
- if (this.IsRepoMounted(repoRoot))
- {
- this.Output.WriteLine("\r\nUnmounting repo at " + repoRoot);
- ReturnCode result = this.Execute(
- repoRoot,
- verb =>
- {
- verb.SkipUnregister = true;
- verb.SkipLock = true;
- });
-
- if (result != ReturnCode.Success)
- {
- failedRepoRoots.Add(repoRoot);
- }
- }
- }
-
- if (failedRepoRoots.Count() > 0)
- {
- string errorString = $"The following repos failed to unmount:{Environment.NewLine}{string.Join(Environment.NewLine, failedRepoRoots.ToArray())}";
- Console.Error.WriteLine(errorString);
- this.ReportErrorAndExit(Environment.NewLine + errorString);
+ this.Output.WriteLine(repoRoot);
}
}
}
@@ -179,24 +106,5 @@ private bool TryGetRepoList(out List repoList, out string errorMessage)
return false;
}
}
-
- private bool IsRepoMounted(string repoRoot)
- {
- // Hide the output of status
- StringWriter statusOutput = new StringWriter();
- ReturnCode result = this.Execute(
- repoRoot,
- verb =>
- {
- verb.Output = statusOutput;
- });
-
- if (result == ReturnCode.Success)
- {
- return true;
- }
-
- return false;
- }
}
}
diff --git a/Scalar/CommandLine/UnmountVerb.cs b/Scalar/CommandLine/UnmountVerb.cs
deleted file mode 100644
index 9209a1042b..0000000000
--- a/Scalar/CommandLine/UnmountVerb.cs
+++ /dev/null
@@ -1,194 +0,0 @@
-using CommandLine;
-using Scalar.Common;
-using Scalar.Common.NamedPipes;
-
-namespace Scalar.CommandLine
-{
- [Verb(UnmountVerb.UnmountVerbName, HelpText = "Unmount a Scalar virtual repo")]
- public class UnmountVerb : ScalarVerb
- {
- private const string UnmountVerbName = "unmount";
-
- [Value(
- 0,
- Required = false,
- Default = "",
- MetaName = "Enlistment Root Path",
- HelpText = "Full or relative path to the Scalar enlistment root")]
- public override string EnlistmentRootPathParameter { get; set; }
-
- [Option(
- ScalarConstants.VerbParameters.Unmount.SkipLock,
- Default = false,
- Required = false,
- HelpText = "Force unmount even if the lock is not available.")]
- public bool SkipLock { get; set; }
-
- public bool SkipUnregister { get; set; }
-
- protected override string VerbName
- {
- get { return UnmountVerbName; }
- }
-
- public override void Execute()
- {
- this.ValidatePathParameter(this.EnlistmentRootPathParameter);
-
- string errorMessage;
- string root;
- if (!ScalarPlatform.Instance.TryGetScalarEnlistmentRoot(this.EnlistmentRootPathParameter, out root, out errorMessage))
- {
- this.ReportErrorAndExit(
- "Error: '{0}' is not a valid Scalar enlistment",
- this.EnlistmentRootPathParameter);
- }
-
- if (!this.ShowStatusWhileRunning(
- () => { return this.Unmount(root, out errorMessage); },
- "Unmounting"))
- {
- this.ReportErrorAndExit(errorMessage);
- }
-
- if (!this.Unattended && !this.SkipUnregister)
- {
- if (!this.ShowStatusWhileRunning(
- () => { return this.UnregisterRepo(root, out errorMessage); },
- "Unregistering automount"))
- {
- this.Output.WriteLine(" WARNING: " + errorMessage);
- }
- }
- }
-
- private bool Unmount(string enlistmentRoot, out string errorMessage)
- {
- errorMessage = string.Empty;
-
- string pipeName = ScalarPlatform.Instance.GetNamedPipeName(enlistmentRoot);
- string rawGetStatusResponse = string.Empty;
-
- try
- {
- using (NamedPipeClient pipeClient = new NamedPipeClient(pipeName))
- {
- if (!pipeClient.Connect())
- {
- errorMessage = "Unable to connect to Scalar.Mount";
- return false;
- }
-
- pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
- rawGetStatusResponse = pipeClient.ReadRawResponse();
- NamedPipeMessages.GetStatus.Response getStatusResponse =
- NamedPipeMessages.GetStatus.Response.FromJson(rawGetStatusResponse);
-
- switch (getStatusResponse.MountStatus)
- {
- case NamedPipeMessages.GetStatus.Mounting:
- errorMessage = "Still mounting, please try again later";
- return false;
-
- case NamedPipeMessages.GetStatus.Unmounting:
- errorMessage = "Already unmounting, please wait";
- return false;
-
- case NamedPipeMessages.GetStatus.Ready:
- break;
-
- case NamedPipeMessages.GetStatus.MountFailed:
- break;
-
- default:
- errorMessage = "Unrecognized response to GetStatus: " + rawGetStatusResponse;
- return false;
- }
-
- pipeClient.SendRequest(NamedPipeMessages.Unmount.Request);
- string unmountResponse = pipeClient.ReadRawResponse();
-
- switch (unmountResponse)
- {
- case NamedPipeMessages.Unmount.Acknowledged:
- string finalResponse = pipeClient.ReadRawResponse();
- if (finalResponse == NamedPipeMessages.Unmount.Completed)
- {
- errorMessage = string.Empty;
- return true;
- }
- else
- {
- errorMessage = "Unrecognized final response to unmount: " + finalResponse;
- return false;
- }
-
- case NamedPipeMessages.Unmount.NotMounted:
- errorMessage = "Unable to unmount, repo was not mounted";
- return false;
-
- case NamedPipeMessages.Unmount.MountFailed:
- errorMessage = "Unable to unmount, previous mount attempt failed";
- return false;
-
- default:
- errorMessage = "Unrecognized response to unmount: " + unmountResponse;
- return false;
- }
- }
- }
- catch (BrokenPipeException e)
- {
- errorMessage = "Unable to communicate with Scalar: " + e.ToString();
- return false;
- }
- }
-
- private bool UnregisterRepo(string rootPath, out string errorMessage)
- {
- errorMessage = string.Empty;
- NamedPipeMessages.UnregisterRepoRequest request = new NamedPipeMessages.UnregisterRepoRequest();
- request.EnlistmentRoot = rootPath;
-
- using (NamedPipeClient client = new NamedPipeClient(this.ServicePipeName))
- {
- if (!client.Connect())
- {
- errorMessage = "Unable to unregister repo because Scalar.Service is not responding. " + ScalarVerb.StartServiceInstructions;
- return false;
- }
-
- try
- {
- client.SendRequest(request.ToMessage());
- NamedPipeMessages.Message response = client.ReadResponse();
- if (response.Header == NamedPipeMessages.UnregisterRepoRequest.Response.Header)
- {
- NamedPipeMessages.UnregisterRepoRequest.Response message = NamedPipeMessages.UnregisterRepoRequest.Response.FromMessage(response);
-
- if (message.State != NamedPipeMessages.CompletionState.Success)
- {
- errorMessage = message.ErrorMessage;
- return false;
- }
- else
- {
- errorMessage = string.Empty;
- return true;
- }
- }
- else
- {
- errorMessage = string.Format("Scalar.Service responded with unexpected message: {0}", response);
- return false;
- }
- }
- catch (BrokenPipeException e)
- {
- errorMessage = "Unable to communicate with Scalar.Service: " + e.ToString();
- return false;
- }
- }
- }
- }
-}
diff --git a/Scalar/Program.cs b/Scalar/Program.cs
index 4222af4019..faeea75eaf 100644
--- a/Scalar/Program.cs
+++ b/Scalar/Program.cs
@@ -21,10 +21,8 @@ public static void Main(string[] args)
typeof(ConfigVerb),
typeof(MaintenanceVerb),
typeof(DiagnoseVerb),
- typeof(MountVerb),
typeof(ServiceVerb),
typeof(StatusVerb),
- typeof(UnmountVerb),
typeof(UpgradeVerb),
};
diff --git a/Scalar/Scalar.Windows.csproj b/Scalar/Scalar.Windows.csproj
index 795b7dda26..3857f8303c 100644
--- a/Scalar/Scalar.Windows.csproj
+++ b/Scalar/Scalar.Windows.csproj
@@ -116,11 +116,9 @@
-
-
PlatformLoader.Windows.cs