Browse Source

Run Avalonia.LeakTests on CI (#19720)

* Check Avalonia.LeakTests

* Enable DotMemoryUnit

* Fix TransitionTests
Ilya Pospelov 2 weeks ago
parent
commit
9bf7abcdfe
2 changed files with 48 additions and 9 deletions
  1. 41 9
      nukebuild/Build.cs
  2. 7 0
      tests/Avalonia.LeakTests/TransitionTests.cs

+ 41 - 9
nukebuild/Build.cs

@@ -1,8 +1,10 @@
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.IO.Compression;
 using System.Linq;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using System.Xml.Linq;
@@ -10,8 +12,10 @@ using Nuke.Common;
 using Nuke.Common.Tooling;
 using Nuke.Common.Tools.DotNet;
 using Nuke.Common.Tools.Npm;
+using Nuke.Common.Utilities;
 using static Nuke.Common.EnvironmentInfo;
 using static Nuke.Common.IO.PathConstruction;
+using static Nuke.Common.Tools.DotMemoryUnit.DotMemoryUnitTasks;
 using static Nuke.Common.Tools.DotNet.DotNetTasks;
 using static Serilog.Log;
 using MicroCom.CodeGenerator;
@@ -183,6 +187,31 @@ partial class Build : NukeBuild
         });
 
     void RunCoreTest(string projectName)
+    {
+        RunCoreTest(projectName, (project, tfm) =>
+        {
+            DotNetTest(c => ApplySetting(c, project,tfm));
+        });
+    }
+
+    void RunCoreDotMemoryUnit(string projectName)
+    {
+        RunCoreTest(projectName, (project, tfm) =>
+        {
+            var testSettings = ApplySetting(new DotNetTestSettings(), project, tfm);
+            var testToolPath = GetToolPathInternal(new DotNetTasks(), testSettings);
+            var testArgs = GetArguments(testSettings).JoinSpace();
+            DotMemoryUnit($"{testToolPath} --propagate-exit-code -- {testArgs:nq}");
+        });
+
+        [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(GetToolPathInternal))]
+        extern static string GetToolPathInternal(ToolTasks tasks, ToolOptions options);
+
+        [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(GetArguments))]
+        extern static IEnumerable<string> GetArguments(ToolOptions options);
+    }
+
+    void RunCoreTest(string projectName, Action<string, string> runTest)
     {
         Information($"Running tests from {projectName}");
         var project = RootDirectory.GlobFiles(@$"**\{projectName}.csproj").FirstOrDefault()
@@ -228,17 +257,20 @@ partial class Build : NukeBuild
 
             Information($"Running for {projectName} ({tfm}) ...");
 
-            DotNetTest(c => ApplySetting(c)
-                .SetProjectFile(project)
-                .SetFramework(tfm)
-                .EnableNoBuild()
-                .EnableNoRestore()
-                .When(_ => Parameters.PublishTestResults, _ => _
-                    .SetLoggers("trx")
-                    .SetResultsDirectory(Parameters.TestResultsRoot)));
+            runTest(project, tfm);
         }
     }
 
+    DotNetTestSettings ApplySetting(DotNetTestSettings settings, string project, string tfm) =>
+        ApplySetting(settings)
+        .SetProjectFile(project)
+        .SetFramework(tfm)
+        .EnableNoBuild()
+        .EnableNoRestore()
+        .When(_ => Parameters.PublishTestResults, _ => _
+            .SetLoggers("trx")
+            .SetResultsDirectory(Parameters.TestResultsRoot));
+
     Target RunHtmlPreviewerTests => _ => _
         .DependsOn(CompileHtmlPreviewer)
         .OnlyWhenStatic(() => !(Parameters.SkipPreviewer || Parameters.SkipTests))
@@ -296,7 +328,7 @@ partial class Build : NukeBuild
         {
             void DoMemoryTest()
             {
-                RunCoreTest("Avalonia.LeakTests");
+                RunCoreDotMemoryUnit("Avalonia.LeakTests");
             }
             ControlFlow.ExecuteWithRetry(DoMemoryTest, delay: TimeSpan.FromMilliseconds(3));
         });

+ 7 - 0
tests/Avalonia.LeakTests/TransitionTests.cs

@@ -3,6 +3,7 @@ using Avalonia.Animation;
 using Avalonia.Controls;
 using Avalonia.Data;
 using Avalonia.Styling;
+using Avalonia.Threading;
 using Avalonia.UnitTests;
 using JetBrains.dotMemoryUnit;
 using Xunit;
@@ -99,6 +100,9 @@ namespace Avalonia.LeakTests
 
                 var result = run();
 
+                // Process all Loaded events to free control reference(s)
+                Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded);
+
                 dotMemory.Check(memory =>
                     Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Button>()).ObjectsCount));
             }
@@ -141,6 +145,9 @@ namespace Avalonia.LeakTests
 
                 var result = run();
 
+                // Process all Loaded events to free control reference(s)
+                Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded);
+
                 dotMemory.Check(memory =>
                     Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Button>()).ObjectsCount));
             }