diff options
author | therzok <marius.ungureanu@xamarin.com> | 2018-04-16 20:57:56 +0300 |
---|---|---|
committer | Marius Ungureanu <teromario@yahoo.com> | 2018-04-17 14:13:26 +0300 |
commit | 5fb15f227aa93a5f615047d9ccf7faa333ff662f (patch) | |
tree | fe7a93ecaa1a1ac964a7b362cad7a0296e23183d /main | |
parent | 76103dd4317eb884d96169b888e2e8fc90f3a095 (diff) |
Add test that verifies imports are only loaded once
Fixes VSTS #591651 - Project model evaluation contention
Diffstat (limited to 'main')
3 files changed, 57 insertions, 2 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs index 874b441b06..c8543e34c6 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs @@ -42,6 +42,9 @@ namespace MonoDevelop.Projects.MSBuild { Dictionary<FilePath, LoadedProjectInfo> loadedProjects = new Dictionary<FilePath, LoadedProjectInfo> (); + // For test purposes. + internal static Func<MSBuildProject, MSBuildEvaluationContext> GetEvaluationContext = null; + class LoadedProjectInfo { public MSBuildProject Project; @@ -152,9 +155,9 @@ namespace MonoDevelop.Projects.MSBuild if (pi.NeedsLoad) { LogBeginProjectFileLoad (context, fileName); + pi.LastWriteTime = File.GetLastWriteTimeUtc (fileName); pi.Project.Load (fileName, new MSBuildXmlReader { ForEvaluation = true }); pi.NeedsLoad = false; - pi.LastWriteTime = File.GetLastWriteTimeUtc (fileName); LogEndProjectFileLoad (context); } @@ -218,7 +221,7 @@ namespace MonoDevelop.Projects.MSBuild pi.ReferencedProjects = new List<MSBuildProject> (); try { - var context = new MSBuildEvaluationContext (); + var context = GetEvaluationContext?.Invoke (pi.Project) ?? new MSBuildEvaluationContext (); foreach (var p in pi.GlobalProperties) { context.SetPropertyValue (p.Key, p.Value); StoreProperty (pi, p.Key, p.Value, p.Value); diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildProjectTests.cs b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildProjectTests.cs index ce45cc9365..2f9f0de492 100644 --- a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildProjectTests.cs +++ b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildProjectTests.cs @@ -57,6 +57,56 @@ namespace MonoDevelop.Projects return p; } + class CustomLogger : MSBuildEngineLogger + { + internal Dictionary<string, int> loadTasks = new Dictionary<string, int> (); + internal Dictionary<string, int> evalTasks = new Dictionary<string, int> (); + + static void IncValue (Dictionary<string, int> tasks, string project) + { + tasks.TryGetValue (project, out int count); + tasks [project] = ++count; + } + + public override void LogMessage (string s) + { + Dictionary<string, int> tasks; + + if (s.StartsWith ("Load Project:", StringComparison.Ordinal)) { + tasks = loadTasks; + } else if (s.StartsWith ("Evaluate Project:", StringComparison.Ordinal)) { + tasks = evalTasks; + } else + return; + + IncValue (tasks, s); + } + } + + [Test] + public void ImportsLoadedAndEvaluatedOnlyOnce () + { + try { + using (var p = LoadProject ()) { + CustomLogger log = null; + + DefaultMSBuildEngine.GetEvaluationContext = proj => { + if (proj != p) + return null; + + log = new CustomLogger (); + return new MSBuildEvaluationContext { Log = log }; + }; + + p.Evaluate (); + Assert.That (log.loadTasks.Values, Is.All.EqualTo (1)); + Assert.That (log.evalTasks.Values, Is.All.EqualTo (1)); + } + } finally { + DefaultMSBuildEngine.GetEvaluationContext = null; + } + } + [Test] public void Properties () { diff --git a/main/tests/test-projects/msbuild-project-test/test.csproj b/main/tests/test-projects/msbuild-project-test/test.csproj index a73d66a032..e7029dff67 100755 --- a/main/tests/test-projects/msbuild-project-test/test.csproj +++ b/main/tests/test-projects/msbuild-project-test/test.csproj @@ -68,5 +68,7 @@ </ItemGroup> <Target Name="Conditioned" Condition="false"></Target> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- Imported twice for verification --> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="extra.csproj" /> </Project> |