Explorar o código

Ensure AppLocalResolver handles package with multiple libs (#27751)

* Ensure AppLocalResolver handles package with multiple libs

This was failing to pass references to a package which contains more
than one lib.

* Use `AppBaseCompilationAssemblyResolver` in `DiagnosticProject`

* Fix, then reduce use of `TestPathUtilities.GetSolutionRootDirectory(...)` (#27404)

- do not traverse up past the `$(RepoRoot)` when running tests locally
  - if `$(RepoRoot)` is reached, search down for named `*.slnf` file
  - find `*.slnf` file when `$(OutputPath)` is under artifacts/bin/
- analyzer test projects publish needed files anyhow
  - remove `GetProjectDirectory()` helpers

Co-authored-by: Doug Bunting <[email protected]>
Eric StJohn %!s(int64=5) %!d(string=hai) anos
pai
achega
4d47720df2

+ 2 - 27
src/Analyzers/Microsoft.AspNetCore.Analyzer.Testing/src/DiagnosticProject.cs

@@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Analyzer.Testing
         /// </summary>
         /// </summary>
         public static string TestProjectName = "TestProject";
         public static string TestProjectName = "TestProject";
 
 
+        private static readonly ICompilationAssemblyResolver _assemblyResolver = new AppBaseCompilationAssemblyResolver();
         private static readonly Dictionary<Assembly, Solution> _solutionCache = new Dictionary<Assembly, Solution>();
         private static readonly Dictionary<Assembly, Solution> _solutionCache = new Dictionary<Assembly, Solution>();
 
 
         public static Project Create(Assembly testAssembly, string[] sources)
         public static Project Create(Assembly testAssembly, string[] sources)
@@ -41,7 +42,7 @@ namespace Microsoft.AspNetCore.Analyzer.Testing
 
 
                     foreach (var defaultCompileLibrary in DependencyContext.Load(testAssembly).CompileLibraries)
                     foreach (var defaultCompileLibrary in DependencyContext.Load(testAssembly).CompileLibraries)
                     {
                     {
-                        foreach (var resolveReferencePath in defaultCompileLibrary.ResolveReferencePaths(new AppLocalResolver()))
+                        foreach (var resolveReferencePath in defaultCompileLibrary.ResolveReferencePaths(_assemblyResolver))
                         {
                         {
                             solution = solution.AddMetadataReference(projectId, MetadataReference.CreateFromFile(resolveReferencePath));
                             solution = solution.AddMetadataReference(projectId, MetadataReference.CreateFromFile(resolveReferencePath));
                         }
                         }
@@ -69,31 +70,5 @@ namespace Microsoft.AspNetCore.Analyzer.Testing
 
 
             return solution.GetProject(testProject);
             return solution.GetProject(testProject);
         }
         }
-
-        // Required to resolve compilation assemblies inside unit tests
-        private class AppLocalResolver : ICompilationAssemblyResolver
-        {
-            public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
-            {
-                foreach (var assembly in library.Assemblies)
-                {
-                    var dll = Path.Combine(Directory.GetCurrentDirectory(), "refs", Path.GetFileName(assembly));
-                    if (File.Exists(dll))
-                    {
-                        assemblies.Add(dll);
-                        return true;
-                    }
-
-                    dll = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(assembly));
-                    if (File.Exists(dll))
-                    {
-                        assemblies.Add(dll);
-                        return true;
-                    }
-                }
-
-                return false;
-            }
-        }
     }
     }
 }
 }

+ 4 - 21
src/Components/Analyzers/test/AnalyzerTestBase.cs

@@ -5,20 +5,20 @@ using System;
 using System.IO;
 using System.IO;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Analyzer.Testing;
 using Microsoft.AspNetCore.Analyzer.Testing;
-using Microsoft.AspNetCore.Testing;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis;
 
 
 namespace Microsoft.AspNetCore.Components.Analyzers
 namespace Microsoft.AspNetCore.Components.Analyzers
 {
 {
     public abstract class AnalyzerTestBase
     public abstract class AnalyzerTestBase
     {
     {
-        private static readonly string ProjectDirectory = GetProjectDirectory();
+        // Test files are copied to both the bin/ and publish/ folders. Use BaseDirectory on or off Helix.
+        private static readonly string ProjectDirectory = AppContext.BaseDirectory;
 
 
         public TestSource Read(string source)
         public TestSource Read(string source)
         {
         {
             if (!source.EndsWith(".cs"))
             if (!source.EndsWith(".cs"))
             {
             {
-                source = source + ".cs";
+                source += ".cs";
             }
             }
 
 
             var filePath = Path.Combine(ProjectDirectory, "TestFiles", GetType().Name, source);
             var filePath = Path.Combine(ProjectDirectory, "TestFiles", GetType().Name, source);
@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers
         {
         {
             if (!source.EndsWith(".cs"))
             if (!source.EndsWith(".cs"))
             {
             {
-                source = source + ".cs";
+                source += ".cs";
             }
             }
 
 
             var read = Read(source);
             var read = Read(source);
@@ -46,22 +46,5 @@ namespace Microsoft.AspNetCore.Components.Analyzers
         {
         {
             return CreateProject(source).GetCompilationAsync();
             return CreateProject(source).GetCompilationAsync();
         }
         }
-
-        private static string GetProjectDirectory()
-        {
-            // On helix we use the published test files
-            if (SkipOnHelixAttribute.OnHelix())
-            {
-                return AppContext.BaseDirectory;
-            }
-
-            // This test code needs to be updated to support distributed testing.
-            // See https://github.com/dotnet/aspnetcore/issues/10422
-#pragma warning disable 0618
-            var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Components");
-#pragma warning restore 0618
-            var projectDirectory = Path.Combine(solutionDirectory, "Analyzers", "test");
-            return projectDirectory;
-        }
     }
     }
 }
 }

+ 3 - 19
src/Mvc/Mvc.Analyzers/test/Infrastructure/MvcTestSource.cs

@@ -1,16 +1,16 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
 using System;
 using System;
 using System.IO;
 using System.IO;
 using Microsoft.AspNetCore.Analyzer.Testing;
 using Microsoft.AspNetCore.Analyzer.Testing;
-using Microsoft.AspNetCore.Testing;
 
 
 namespace Microsoft.AspNetCore.Mvc
 namespace Microsoft.AspNetCore.Mvc
 {
 {
     public static class MvcTestSource
     public static class MvcTestSource
     {
     {
-        private static readonly string ProjectDirectory = GetProjectDirectory();
+        // Test files are copied to both the bin/ and publish/ folders. Use BaseDirectory on or off Helix.
+        private static readonly string ProjectDirectory = AppContext.BaseDirectory;
 
 
         public static TestSource Read(string testClassName, string testMethod)
         public static TestSource Read(string testClassName, string testMethod)
         {
         {
@@ -23,21 +23,5 @@ namespace Microsoft.AspNetCore.Mvc
             var fileContent = File.ReadAllText(filePath);
             var fileContent = File.ReadAllText(filePath);
             return TestSource.Read(fileContent);
             return TestSource.Read(fileContent);
         }
         }
-
-        private static string GetProjectDirectory()
-        {
-            // On helix we use the published test files
-            if (SkipOnHelixAttribute.OnHelix())
-            {
-                return AppContext.BaseDirectory;
-            }
-
-// https://github.com/dotnet/aspnetcore/issues/9431
-#pragma warning disable 0618
-            var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Mvc");
-#pragma warning restore 0618
-            var projectDirectory = Path.Combine(solutionDirectory, "Mvc.Analyzers", "test");
-            return projectDirectory;
-        }
     }
     }
 }
 }

+ 3 - 19
src/Mvc/Mvc.Api.Analyzers/test/Infrastructure/MvcTestSource.cs

@@ -1,16 +1,16 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
 using System;
 using System;
 using System.IO;
 using System.IO;
 using Microsoft.AspNetCore.Analyzer.Testing;
 using Microsoft.AspNetCore.Analyzer.Testing;
-using Microsoft.AspNetCore.Testing;
 
 
 namespace Microsoft.AspNetCore.Mvc
 namespace Microsoft.AspNetCore.Mvc
 {
 {
     public static class MvcTestSource
     public static class MvcTestSource
     {
     {
-        private static readonly string ProjectDirectory = GetProjectDirectory();
+        // Test files are copied to both the bin/ and publish/ folders. Use BaseDirectory on or off Helix.
+        private static readonly string ProjectDirectory = AppContext.BaseDirectory;
 
 
         public static TestSource Read(string testClassName, string testMethod)
         public static TestSource Read(string testClassName, string testMethod)
         {
         {
@@ -23,21 +23,5 @@ namespace Microsoft.AspNetCore.Mvc
             var fileContent = File.ReadAllText(filePath);
             var fileContent = File.ReadAllText(filePath);
             return TestSource.Read(fileContent);
             return TestSource.Read(fileContent);
         }
         }
-
-        private static string GetProjectDirectory()
-        {
-            // On helix we use the published test files
-            if (SkipOnHelixAttribute.OnHelix())
-            {
-                return AppContext.BaseDirectory;
-            }
-
-// https://github.com/dotnet/aspnetcore/issues/9431
-#pragma warning disable 0618
-            var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Mvc");
-#pragma warning restore 0618
-            var projectDirectory = Path.Combine(solutionDirectory, "Mvc.Api.Analyzers", "test");
-            return projectDirectory;
-        }
     }
     }
 }
 }

+ 14 - 0
src/Testing/src/TestPathUtilities.cs

@@ -22,6 +22,20 @@ namespace Microsoft.AspNetCore.Testing
                     return projectFileInfo.DirectoryName;
                     return projectFileInfo.DirectoryName;
                 }
                 }
 
 
+                projectFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, "AspNetCore.sln"));
+                if (projectFileInfo.Exists)
+                {
+                    // Have reached the solution root. Work down through the src/ folder to find the solution filter.
+                    directoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, "src"));
+                    foreach (var solutionFileInfo in directoryInfo.EnumerateFiles($"{solution}.slnf", SearchOption.AllDirectories))
+                    {
+                        return solutionFileInfo.DirectoryName;
+                    }
+
+                    // No luck. Exit loop and error out.
+                    break;
+                }
+
                 directoryInfo = directoryInfo.Parent;
                 directoryInfo = directoryInfo.Parent;
             }
             }
             while (directoryInfo.Parent != null);
             while (directoryInfo.Parent != null);