consume bring your own shim(byos) (#9018)

If there are shims packaged by convention in nupkg. Shim Repository will simply copy it to the right location.

The query interface ToolPackageInstance will be in charge of finding the shim folder and filter the right RID. Shim Repository will pick the right file after the folder is located since Shim Repository knows the shim name and it also book keep the files at uninstallation.
During development, due to the wrong adapter level. The mock duplicated too much logic. So, I corrected the abstraction level to lower (only create shim). And replaced the existing mock with a much smaller one without any atomic control and file move, copy logic. At the same time. The chmod, which is a IO action, causes problem during tests. So I added adapter layer to it and put it in Util.
This commit is contained in:
William Li 2018-04-10 15:42:50 -07:00 committed by GitHub
commit b0ee5db411
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 898 additions and 208 deletions

View file

@ -119,7 +119,7 @@ namespace Microsoft.DotNet.ShellShim.Tests
IShellShimRepository shellShimRepository;
if (testMockBehaviorIsInSync)
{
shellShimRepository = new ShellShimRepositoryMock(new DirectoryPath(pathToShim));
shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
}
else
{
@ -161,7 +161,7 @@ namespace Microsoft.DotNet.ShellShim.Tests
IShellShimRepository shellShimRepository;
if (testMockBehaviorIsInSync)
{
shellShimRepository = new ShellShimRepositoryMock(new DirectoryPath(pathToShim));
shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
}
else
{
@ -198,7 +198,7 @@ namespace Microsoft.DotNet.ShellShim.Tests
IShellShimRepository shellShimRepository;
if (testMockBehaviorIsInSync)
{
shellShimRepository = new ShellShimRepositoryMock(new DirectoryPath(pathToShim));
shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
}
else
{
@ -223,7 +223,7 @@ namespace Microsoft.DotNet.ShellShim.Tests
IShellShimRepository shellShimRepository;
if (testMockBehaviorIsInSync)
{
shellShimRepository = new ShellShimRepositoryMock(new DirectoryPath(pathToShim));
shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
}
else
{
@ -252,7 +252,7 @@ namespace Microsoft.DotNet.ShellShim.Tests
IShellShimRepository shellShimRepository;
if (testMockBehaviorIsInSync)
{
shellShimRepository = new ShellShimRepositoryMock(new DirectoryPath(pathToShim));
shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
}
else
{
@ -288,7 +288,7 @@ namespace Microsoft.DotNet.ShellShim.Tests
IShellShimRepository shellShimRepository;
if (testMockBehaviorIsInSync)
{
shellShimRepository = new ShellShimRepositoryMock(new DirectoryPath(pathToShim));
shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
}
else
{
@ -315,6 +315,67 @@ namespace Microsoft.DotNet.ShellShim.Tests
Directory.EnumerateFileSystemEntries(pathToShim).Should().BeEmpty();
}
[Fact]
public void WhenPackagedShimProvidedItCopies()
{
const string tokenToIdentifyCopiedShim = "packagedShim";
var shellCommandName = nameof(ShellShimRepositoryTests) + Path.GetRandomFileName();
var pathToShim = GetNewCleanFolderUnderTempRoot();
var packagedShimFolder = GetNewCleanFolderUnderTempRoot();
var dummyShimPath = Path.Combine(packagedShimFolder, shellCommandName);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
dummyShimPath = dummyShimPath + ".exe";
}
File.WriteAllText(dummyShimPath, tokenToIdentifyCopiedShim);
ShellShimRepository shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
shellShimRepository.CreateShim(
new FilePath("dummy.dll"),
shellCommandName,
new[] {new FilePath(dummyShimPath)});
var createdShim = Directory.EnumerateFileSystemEntries(pathToShim).Single();
File.ReadAllText(createdShim).Should().Contain(tokenToIdentifyCopiedShim);
}
[Fact]
public void WhenMutipleSameNamePackagedShimProvidedItThrows()
{
const string tokenToIdentifyCopiedShim = "packagedShim";
var shellCommandName = nameof(ShellShimRepositoryTests) + Path.GetRandomFileName();
var pathToShim = GetNewCleanFolderUnderTempRoot();
var packagedShimFolder = GetNewCleanFolderUnderTempRoot();
var dummyShimPath = Path.Combine(packagedShimFolder, shellCommandName);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
dummyShimPath = dummyShimPath + ".exe";
}
File.WriteAllText(dummyShimPath, tokenToIdentifyCopiedShim);
ShellShimRepository shellShimRepository = GetShellShimRepositoryWithMockMaker(pathToShim);
FilePath[] filePaths = new[] { new FilePath(dummyShimPath), new FilePath("path" + dummyShimPath) };
Action a = () => shellShimRepository.CreateShim(
new FilePath("dummy.dll"),
shellCommandName,
new[] { new FilePath(dummyShimPath), new FilePath("path" + dummyShimPath) });
a.ShouldThrow<ShellShimException>()
.And.Message
.Should().Contain(
string.Format(
CommonLocalizableStrings.MoreThanOnePackagedShimAvailable,
string.Join(';', filePaths)));
}
private static void MakeNameConflictingCommand(string pathToPlaceShim, string shellCommandName)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
@ -440,5 +501,12 @@ namespace Microsoft.DotNet.ShellShim.Tests
return CleanFolderUnderTempRoot.FullName;
}
private ShellShimRepository GetShellShimRepositoryWithMockMaker(string pathToShim)
{
return new ShellShimRepository(
new DirectoryPath(pathToShim),
appHostShellShimMaker: new AppHostShellShimMakerMock());
}
}
}