/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Scripting/CoreTest.Desktop/MetadataShadowCopyProviderTests.cs
251 строка
12 KB
Cyrus Najmabadi
Sort usings
19 июн 2025, 03:07
19 июн 2025, 03:07
b2899f6
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; using static Roslyn.Utilities.PlatformInformation; namespace Microsoft.CodeAnalysis.Scripting.Hosting.UnitTests { // TODO: clean up and move to portable tests public class MetadataShadowCopyProviderTests : TestBase { private readonly MetadataShadowCopyProvider _provider; private static readonly ImmutableArray<string> s_systemNoShadowCopyDirectories = IsRunningOnMono ? ImmutableArray<string>.Empty : ImmutableArray.Create( FileUtilities.NormalizeDirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.Windows)), FileUtilities.NormalizeDirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)), FileUtilities.NormalizeDirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)), FileUtilities.NormalizeDirectoryPath(RuntimeEnvironment.GetRuntimeDirectory())); public MetadataShadowCopyProviderTests() { _provider = CreateProvider(CultureInfo.InvariantCulture); } private static MetadataShadowCopyProvider CreateProvider(CultureInfo culture) { return new MetadataShadowCopyProvider(TempRoot.Root, s_systemNoShadowCopyDirectories, culture); } public override void Dispose() { _provider.Dispose(); Assert.False(Directory.Exists(_provider.ShadowCopyDirectory), "Shadow copy directory should have been deleted"); base.Dispose(); } [Fact] public void Errors() { Assert.Throws<ArgumentNullException>(() => _provider.NeedsShadowCopy(null)); Assert.Throws<ArgumentException>(() => _provider.NeedsShadowCopy("c:goo.dll")); Assert.Throws<ArgumentException>(() => _provider.NeedsShadowCopy("bar.dll")); Assert.Throws<ArgumentException>(() => _provider.NeedsShadowCopy(@"\bar.dll")); Assert.Throws<ArgumentException>(() => _provider.NeedsShadowCopy(@"../bar.dll")); Assert.Throws<ArgumentNullException>(() => _provider.SuppressShadowCopy(null)); Assert.Throws<ArgumentException>(() => _provider.SuppressShadowCopy("c:goo.dll")); Assert.Throws<ArgumentException>(() => _provider.SuppressShadowCopy("bar.dll")); Assert.Throws<ArgumentException>(() => _provider.SuppressShadowCopy(@"\bar.dll")); Assert.Throws<ArgumentException>(() => _provider.SuppressShadowCopy(@"../bar.dll")); Assert.Throws<ArgumentOutOfRangeException>(() => _provider.GetMetadataShadowCopy(IsRunningOnMono ? "/goo.dll" : @"c:\goo.dll", (MetadataImageKind)Byte.MaxValue)); Assert.Throws<ArgumentNullException>(() => _provider.GetMetadataShadowCopy(null, MetadataImageKind.Assembly)); Assert.Throws<ArgumentException>(() => _provider.GetMetadataShadowCopy("c:goo.dll", MetadataImageKind.Assembly)); Assert.Throws<ArgumentException>(() => _provider.GetMetadataShadowCopy("bar.dll", MetadataImageKind.Assembly)); Assert.Throws<ArgumentException>(() => _provider.GetMetadataShadowCopy(@"\bar.dll", MetadataImageKind.Assembly)); Assert.Throws<ArgumentException>(() => _provider.GetMetadataShadowCopy(@"../bar.dll", MetadataImageKind.Assembly)); Assert.Throws<ArgumentOutOfRangeException>(() => _provider.GetMetadata(IsRunningOnMono ? "/goo.dll" : @"c:\goo.dll", (MetadataImageKind)Byte.MaxValue)); Assert.Throws<ArgumentNullException>(() => _provider.GetMetadata(null, MetadataImageKind.Assembly)); Assert.Throws<ArgumentException>(() => _provider.GetMetadata("c:goo.dll", MetadataImageKind.Assembly)); } [Fact] public void Copy() { var dir = Temp.CreateDirectory(); var dll = dir.CreateFile("a.dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01); var doc = dir.CreateFile("a.xml").WriteAllText("<hello>"); var sc1 = _provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); var sc2 = _provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.Equal(sc2, sc1); Assert.Equal(dll.Path, sc1.PrimaryModule.OriginalPath); Assert.NotEqual(dll.Path, sc1.PrimaryModule.FullPath); Assert.False(sc1.Metadata.IsImageOwner, "Copy expected"); Assert.Equal(File.ReadAllBytes(dll.Path), File.ReadAllBytes(sc1.PrimaryModule.FullPath)); Assert.Equal(File.ReadAllBytes(doc.Path), File.ReadAllBytes(sc1.DocumentationFile.FullPath)); } [Fact] public void SuppressCopy1() { var dll = Temp.CreateFile().WriteAllText("blah"); _provider.SuppressShadowCopy(dll.Path); var sc1 = _provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.Null(sc1); } [ClrOnlyFact(ClrOnlyReason.Fusion)] public void SuppressCopy_Framework() { // framework assemblies not copied: string mscorlib = typeof(object).Assembly.Location; var sc2 = _provider.GetMetadataShadowCopy(mscorlib, MetadataImageKind.Assembly); Assert.Null(sc2); } [Fact] public void SuppressCopy_ShadowCopyDirectory() { // shadow copies not copied: var dll = Temp.CreateFile("a.dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01); // copy: var sc1 = _provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.NotEqual(dll.Path, sc1.PrimaryModule.FullPath); // file not copied: var sc2 = _provider.GetMetadataShadowCopy(sc1.PrimaryModule.FullPath, MetadataImageKind.Assembly); Assert.Null(sc2); } [Fact] public void Modules() { // modules: { MultiModule.dll, mod2.netmodule, mod3.netmodule } var dir = Temp.CreateDirectory(); string path0 = dir.CreateFile("MultiModule.dll").WriteAllBytes(TestResources.SymbolsTests.MultiModule.MultiModuleDll).Path; string path1 = dir.CreateFile("mod2.netmodule").WriteAllBytes(TestResources.SymbolsTests.MultiModule.mod2).Path; string path2 = dir.CreateFile("mod3.netmodule").WriteAllBytes(TestResources.SymbolsTests.MultiModule.mod3).Path; var metadata1 = _provider.GetMetadata(path0, MetadataImageKind.Assembly) as AssemblyMetadata; Assert.NotNull(metadata1); Assert.Equal(3, metadata1.GetModules().Length); var scDir = Directory.GetFileSystemEntries(_provider.ShadowCopyDirectory).Single(); Assert.True(Directory.Exists(scDir)); var scFiles = Directory.GetFileSystemEntries(scDir); AssertEx.SetEqual(new[] { "MultiModule.dll", "mod2.netmodule", "mod3.netmodule" }, scFiles.Select(p => Path.GetFileName(p))); foreach (var sc in scFiles) { Assert.True(_provider.IsShadowCopy(sc)); if (!IsRunningOnMono) { // files should be locked: Assert.Throws<IOException>(() => File.Delete(sc)); } } // should get the same metadata: var metadata2 = _provider.GetMetadata(path0, MetadataImageKind.Assembly) as AssemblyMetadata; Assert.Same(metadata1, metadata2); // modify the file: File.SetLastWriteTimeUtc(path0, DateTime.Now + TimeSpan.FromHours(1)); // we get an updated image if we ask again: var modifiedMetadata3 = _provider.GetMetadata(path0, MetadataImageKind.Assembly) as AssemblyMetadata; Assert.NotSame(modifiedMetadata3, metadata2); // the file has been modified - we get new metadata: for (int i = 0; i < metadata2.GetModules().Length; i++) { Assert.NotSame(metadata2.GetModules()[i], modifiedMetadata3.GetModules()[i]); } } [Fact] public unsafe void DisposalOnFailure() { var f0 = Temp.CreateFile().WriteAllText("bogus").Path; Assert.Throws<BadImageFormatException>(() => _provider.GetMetadata(f0, MetadataImageKind.Assembly)); string f1 = Temp.CreateFile().WriteAllBytes(TestResources.SymbolsTests.MultiModule.MultiModuleDll).Path; Assert.Throws<FileNotFoundException>(() => _provider.GetMetadata(f1, MetadataImageKind.Assembly)); } [Fact] public void GetMetadata() { var dir = Temp.CreateDirectory(); var dll = dir.CreateFile("a.dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01); var doc = dir.CreateFile("a.xml").WriteAllText("<hello>"); var sc1 = _provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); var sc2 = _provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); var md1 = _provider.GetMetadata(dll.Path, MetadataImageKind.Assembly); Assert.NotNull(md1); Assert.Equal(MetadataImageKind.Assembly, md1.Kind); // This needs to be in different folder from referencesdir to cause the other code path // to be triggered for NeedsShadowCopy method var dir2 = Temp.CreateDirectory(); var dll2 = dir2.CreateFile("a2.dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01); Assert.Equal(1, _provider.CacheSize); var sc3a = _provider.GetMetadataShadowCopy(dll2.Path, MetadataImageKind.Module); Assert.Equal(2, _provider.CacheSize); } [Fact] public void XmlDocComments_SpecificCulture() { var elGR = CultureInfo.GetCultureInfo("el-GR"); var arMA = CultureInfo.GetCultureInfo("ar-MA"); var dir = Temp.CreateDirectory(); var dll = dir.CreateFile("a.dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01); var docInvariant = dir.CreateFile("a.xml").WriteAllText("Invariant"); var docGreek = dir.CreateDirectory(elGR.Name).CreateFile("a.xml").WriteAllText("Greek"); // invariant culture var provider = CreateProvider(CultureInfo.InvariantCulture); var sc = provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.Equal(Path.Combine(Path.GetDirectoryName(sc.PrimaryModule.FullPath), @"a.xml"), sc.DocumentationFile.FullPath); Assert.Equal("Invariant", File.ReadAllText(sc.DocumentationFile.FullPath)); // Greek culture provider = CreateProvider(elGR); sc = provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.Equal(Path.Combine(Path.GetDirectoryName(sc.PrimaryModule.FullPath), @"el-GR", "a.xml"), sc.DocumentationFile.FullPath); Assert.Equal("Greek", File.ReadAllText(sc.DocumentationFile.FullPath)); // Arabic culture (culture specific docs not found, use invariant) provider = CreateProvider(arMA); sc = provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.Equal(Path.Combine(Path.GetDirectoryName(sc.PrimaryModule.FullPath), @"a.xml"), sc.DocumentationFile.FullPath); Assert.Equal("Invariant", File.ReadAllText(sc.DocumentationFile.FullPath)); // no culture: provider = CreateProvider(null); sc = provider.GetMetadataShadowCopy(dll.Path, MetadataImageKind.Assembly); Assert.Null(sc.DocumentationFile); } } }