From 33e105a62f55755ab2eccc40ce6225f1adbc40a1 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 11:29:45 -0400 Subject: [PATCH 01/12] Update incremental build perf tests --- .../run-integrated-regression-tests.yaml | 7 -- .../AndroidUpdateResourcesTest.cs | 20 ----- .../Xamarin.Android.Build.Tests/BuildTest.cs | 56 -------------- .../IncrementalBuildTest.cs | 77 +++++++++++++++++-- 4 files changed, 69 insertions(+), 91 deletions(-) diff --git a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml index e1d6603aee3..ff728889a36 100644 --- a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml +++ b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml @@ -86,13 +86,6 @@ steps: testRunTitle: Smoke Tests on Device nunitConsoleExtraArgs: --where "cat == RegressionDeviceTests" -- template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Incremental Build Tests - nunitConsoleExtraArgs: --where "cat == BuildPerformance" - - template: run-nunit-tests.yaml parameters: nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs index 5b4884e804d..8264128c275 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs @@ -80,26 +80,6 @@ public void BuildAppWithSystemNamespace () } } - [Test] - public void RepetitiveBuild () - { - if (Directory.Exists ("temp/RepetitiveBuild")) - Directory.Delete ("temp/RepetitiveBuild", true); - var proj = new XamarinAndroidApplicationProject (); - using (var b = CreateApkBuilder ("temp/RepetitiveBuild", cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) { - b.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic; - b.ThrowOnBuildFailure = false; - Assert.IsTrue (b.Build (proj), "first build failed"); - Assert.IsTrue (b.Build (proj), "second build failed"); - Assert.IsTrue (b.Output.IsTargetSkipped ("_Sign"), "failed to skip some build"); - var item = proj.AndroidResources.First (x => x.Include () == "Resources\\values\\Strings.xml"); - item.TextContent = () => proj.StringsXml.Replace ("${PROJECT_NAME}", "Foo"); - item.Timestamp = null; - Assert.IsTrue (b.Build (proj), "third build failed"); - Assert.IsFalse (b.Output.IsTargetSkipped ("_Sign"), "incorrectly skipped some build"); - } - } - [Test] [Category ("SmokeTests"), Category ("dotnet")] public void DesignTimeBuild ([Values(false, true)] bool isRelease, [Values (false, true)] bool useManagedParser, [Values (false, true)] bool useAapt2) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 2356ed84448..8fe69da2858 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -1429,62 +1429,6 @@ abstract class ExtendsClassValue extends ClassValue {} } } - [Test] - public void BasicApplicationRepetitiveBuild () - { - var proj = new XamarinAndroidApplicationProject (); - using (var b = CreateApkBuilder ("temp/BasicApplicationRepetitiveBuild", cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) { - b.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic; - b.ThrowOnBuildFailure = false; - Assert.IsTrue (b.Build (proj), "first build failed"); - var firstBuildTime = b.LastBuildTime; - Assert.IsTrue (b.Build (proj), "second build failed"); - Assert.IsTrue ( - firstBuildTime > b.LastBuildTime, "Second build ({0}) should have been faster than the first ({1})", - b.LastBuildTime, firstBuildTime - ); - Assert.IsTrue ( - b.Output.IsTargetSkipped ("_Sign"), - "the _Sign target should not run"); - var item = proj.AndroidResources.First (x => x.Include () == "Resources\\values\\Strings.xml"); - item.TextContent = () => proj.StringsXml.Replace ("${PROJECT_NAME}", "Foo"); - item.Timestamp = null; - Assert.IsTrue (b.Build (proj), "third build failed"); - Assert.IsFalse ( - b.Output.IsTargetSkipped ("_Sign"), - "the _Sign target should run"); - } - } - - [Test] - [Category ("SmokeTests"), Category ("dotnet")] - public void BasicApplicationRepetitiveReleaseBuild () - { - var proj = new XamarinAndroidApplicationProject () { IsRelease = true }; - using (var b = CreateApkBuilder ()) { - var foo = new BuildItem.Source ("Foo.cs") { - TextContent = () => @"using System; - namespace UnnamedProject { - public class Foo { - } - }" - }; - proj.Sources.Add (foo); - Assert.IsTrue (b.Build (proj), "first build failed"); - var firstBuildTime = b.LastBuildTime; - Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build failed"); - Assert.IsTrue ( - firstBuildTime > b.LastBuildTime, "Second build ({0}) should have been faster than the first ({1})", - b.LastBuildTime, firstBuildTime - ); - b.Output.AssertTargetIsSkipped ("_Sign"); - b.Output.AssertTargetIsSkipped (KnownTargets.LinkAssembliesShrink); - proj.Touch ("Foo.cs"); - Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "third build failed"); - b.Output.AssertTargetIsNotSkipped ("CoreCompile"); - b.Output.AssertTargetIsNotSkipped ("_Sign"); - } - } [Test] public void BuildBasicApplicationCheckMdb () diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs index 5e1e5f7360e..c4cfafd5a8e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs @@ -15,6 +15,63 @@ namespace Xamarin.Android.Build.Tests [Parallelizable (ParallelScope.Children)] public class IncrementalBuildTest : BaseTest { + [Test] + public void BasicApplicationRepetitiveBuild () + { + var proj = new XamarinAndroidApplicationProject (); + using (var b = CreateApkBuilder ("temp/BasicApplicationRepetitiveBuild", cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) { + b.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic; + b.ThrowOnBuildFailure = false; + Assert.IsTrue (b.Build (proj), "first build failed"); + var firstBuildTime = b.LastBuildTime; + Assert.IsTrue (b.Build (proj), "second build failed"); + Assert.IsTrue ( + firstBuildTime > b.LastBuildTime, "Second build ({0}) should have been faster than the first ({1})", + b.LastBuildTime, firstBuildTime + ); + Assert.IsTrue ( + b.Output.IsTargetSkipped ("_Sign"), + "the _Sign target should not run"); + var item = proj.AndroidResources.First (x => x.Include () == "Resources\\values\\Strings.xml"); + item.TextContent = () => proj.StringsXml.Replace ("${PROJECT_NAME}", "Foo"); + item.Timestamp = null; + Assert.IsTrue (b.Build (proj), "third build failed"); + Assert.IsFalse ( + b.Output.IsTargetSkipped ("_Sign"), + "the _Sign target should run"); + } + } + + [Test] + [Category ("SmokeTests")] + public void BasicApplicationRepetitiveReleaseBuild () + { + var proj = new XamarinAndroidApplicationProject () { IsRelease = true }; + using (var b = CreateApkBuilder ()) { + var foo = new BuildItem.Source ("Foo.cs") { + TextContent = () => @"using System; + namespace UnnamedProject { + public class Foo { + } + }" + }; + proj.Sources.Add (foo); + Assert.IsTrue (b.Build (proj), "first build failed"); + var firstBuildTime = b.LastBuildTime; + Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build failed"); + Assert.IsTrue ( + firstBuildTime > b.LastBuildTime, "Second build ({0}) should have been faster than the first ({1})", + b.LastBuildTime, firstBuildTime + ); + b.Output.AssertTargetIsSkipped ("_Sign"); + b.Output.AssertTargetIsSkipped (KnownTargets.LinkAssembliesShrink); + proj.Touch ("Foo.cs"); + Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "third build failed"); + b.Output.AssertTargetIsNotSkipped ("CoreCompile"); + b.Output.AssertTargetIsNotSkipped ("_Sign"); + } + } + [Test] public void CheckNothingIsDeletedByIncrementalClean ([Values (true, false)] bool enableMultiDex, [Values (true, false)] bool useAapt2) { @@ -236,7 +293,6 @@ public TestMe createTestMe () { } [Test] - [Category ("dotnet")] public void ResolveNativeLibrariesInManagedReferences () { var lib = new XamarinAndroidLibraryProject () { @@ -345,7 +401,7 @@ public Class2 () //https://github.com/xamarin/xamarin-android/issues/2247 [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void AppProjectTargetsDoNotBreak () { var targets = new List { @@ -373,6 +429,7 @@ public void AppProjectTargetsDoNotBreak () } using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { Assert.IsTrue (b.Build (proj), "first build should succeed"); + var firstBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped!"); } @@ -394,15 +451,19 @@ public void AppProjectTargetsDoNotBreak () //NOTE: second build, targets will run because inputs changed Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "second build should succeed"); + var secondBuildTime = b.LastBuildTime; foreach (var target in targets) { b.Output.AssertTargetIsNotSkipped (target); } //NOTE: third build, targets should certainly *not* run! there are no changes Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "third build should succeed"); + var thirdBuildTime = b.LastBuildTime; foreach (var target in targets) { b.Output.AssertTargetIsSkipped (target); } + Assert.IsTrue (secondBuildTime < firstBuildTime, $"Second incremental build: '{secondBuildTime}' should be faster than clean build: '{firstBuildTime}'."); + Assert.IsTrue (thirdBuildTime < secondBuildTime, $"Third unchanged build: '{thirdBuildTime}' should be faster than partially incremental second build: '{secondBuildTime}'."); } } @@ -435,6 +496,7 @@ public void LibraryProjectTargetsDoNotBreak () }; using (var b = CreateDllBuilder (Path.Combine ("temp", TestName))) { Assert.IsTrue (b.Build (proj), "first build should succeed"); + var firstBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped!"); } @@ -451,20 +513,24 @@ public void LibraryProjectTargetsDoNotBreak () //NOTE: second build, targets will run because inputs changed Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "second build should succeed"); + var secondBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped on second build!"); } //NOTE: third build, targets should certainly *not* run! there are no changes Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "third build should succeed"); + var thirdBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on third build!"); } + Assert.IsTrue (secondBuildTime < firstBuildTime, $"Second incremental build: '{secondBuildTime}' should be faster than clean build: '{firstBuildTime}'."); + Assert.IsTrue (thirdBuildTime < secondBuildTime, $"Third unchanged build: '{thirdBuildTime}' should be faster than partially incremental second build: '{secondBuildTime}'."); } } [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void ProduceReferenceAssembly () { var path = Path.Combine ("temp", TestName); @@ -580,7 +646,6 @@ public void TransitiveDependencyProduceReferenceAssembly () } [Test] - [Category ("dotnet")] public void LinkAssembliesNoShrink () { var proj = new XamarinFormsAndroidApplicationProject (); @@ -839,7 +904,6 @@ public void CasingOnJavaLangObject () } [Test] - [Category ("dotnet")] public void GenerateJavaStubsAndAssembly ([Values (true, false)] bool isRelease) { var targets = new [] { @@ -1145,7 +1209,6 @@ public void AaptError ([Values (true, false)] bool useAapt2) } [Test] - [Category ("dotnet")] public void AndroidResourceChange () { var proj = new XamarinAndroidApplicationProject (); @@ -1233,7 +1296,6 @@ public void AndroidAssetMissing () } [Test] - [Category ("dotnet")] [NonParallelizable] public void AndroidXMigrationBug () { @@ -1267,7 +1329,6 @@ public void AndroidXMigrationBug () } [Test] - [Category ("dotnet")] public void ChangeSupportedAbis () { var proj = new XamarinFormsAndroidApplicationProject (); From ba6de55ea8e07a660b890d9beda24f9bab3d6f8f Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 12:44:11 -0400 Subject: [PATCH 02/12] Migrate fastdev QA tests --- .../Tests/InstallTests.cs | 87 ++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs index 1422122e655..444786992db 100644 --- a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs @@ -180,7 +180,7 @@ public void SwitchConfigurationsShouldRedeploy () directorylist = GetContentFromAllOverrideDirectories (proj.PackageName); StringAssert.Contains ($"{proj.AssemblyName}", directorylist, $"{proj.AssemblyName} not found in fastdev directory."); - + Assert.IsTrue (builder.Uninstall (proj)); Assert.AreNotEqual ($"package:{proj.PackageName}", RunAdbCommand ($"shell pm list packages {proj.PackageName}").Trim (), $"{proj.PackageName} is installed on the device."); @@ -264,12 +264,24 @@ public void ToggleFastDev () var proj = new XamarinAndroidApplicationProject { AndroidUseSharedRuntime = true, EmbedAssembliesIntoApk = false, + OtherBuildItems = { + new BuildItem.NoActionResource ($"UnnamedProject.dll.config") { + TextContent = () => "", + Metadata = { + { "CopyToOutputDirectory", "PreserveNewest"}, + } + } + } }; using (var builder = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name))) { Assert.IsTrue (builder.Install (proj), "Install should have succeeded."); var directorylist = GetContentFromAllOverrideDirectories (proj.PackageName); StringAssert.Contains ($"{proj.ProjectName}.dll", directorylist, $"{proj.ProjectName}.dll should exist in the .__override__ directory."); + // Configuration files are not supported in One .NET, we don't need to make sure that they're fast deployed. + if (!Builder.UseDotNet) { + StringAssert.Contains ($"{proj.ProjectName}.dll.config", directorylist, $"{proj.ProjectName}.dll.config should exist in the .__override__ directory."); + } //Now toggle FastDev to OFF proj.AndroidUseSharedRuntime = false; @@ -463,5 +475,78 @@ public void LocalizedAssemblies_ShouldBeFastDeployed () } } + + [Test] + public void IncrementalFastDeployment () + { + AssertCommercialBuild (); + AssertHasDevices (); + + var lib1 = new XamarinAndroidLibraryProject () { + ProjectName = "Library1", + Sources = { + new BuildItem.Source ("Class1.cs") { + TextContent = () => "namespace Library1 { public class Class1 { } }" + }, + } + }; + + var lib2 = new DotNetStandard { + ProjectName = "Library2", + Sdk = "Microsoft.NET.Sdk", + TargetFramework = "netstandard2.0", + Sources = { + new BuildItem.Source ("Class2.cs") { + TextContent = () => "namespace Library2 { public class Class2 { } }" + }, + } + }; + + var app = new XamarinFormsAndroidApplicationProject () { + AndroidUseSharedRuntime = true, + EmbedAssembliesIntoApk = false, + References = { + new BuildItem ("ProjectReference", "..\\Library1\\Library1.csproj"), + new BuildItem ("ProjectReference", "..\\Library2\\Library2.csproj"), + }, + }; + + // Set up library projects + var rootPath = Path.Combine (Root, "temp", TestName); + using (var lb1 = CreateDllBuilder (Path.Combine (rootPath, lib1.ProjectName))) + Assert.IsTrue (lb1.Build (lib1), "First library build should have succeeded."); + using (var lb2 = CreateDllBuilder (Path.Combine (rootPath, lib2.ProjectFilePath))) + Assert.IsTrue (lb2.Build (lib2), "Second library build should have succeeded."); + + using (var builder = CreateApkBuilder ()) { + builder.ThrowOnBuildFailure = false; + Assert.IsTrue (builder.Install (app), "First install should have succeeded."); + var firstInstallTime = b.LastBuildTime; + Assert.IsTrue (builder.Install (app, doNotCleanupOnUpdate: true, saveProject: false), "Second install should have succeeded."); + var secondInstallTime = builder.LastBuildTime; + + var filesToTouch = new [] { + Path.Combine (rootPath, lib1.ProjectName, "Class1.cs"), + Path.Combine (rootPath, lib2.ProjectName, "Class2.cs"), + Path.Combine (rootPath, app.ProjectName, "MainPage.xaml"), + }; + foreach (var file in filesToTouch) { + FileAssert.Exists (file); + File.SetLastWriteTimeUtc (file, DateTime.UtcNow); + } + + Assert.IsTrue (builder.Install (app, doNotCleanupOnUpdate: true, saveProject: false), "Third install should have succeeded."); + var thirdInstallTime = builder.LastBuildTime; + Assert.IsTrue (builder.Install (app, doNotCleanupOnUpdate: true, saveProject: false), "Fourth install should have succeeded."); + var fourthInstalTime = builder.LastBuildTime; + + Assert.IsTrue (thirdInstallTime < firstInstallTime, $"Third incremental install: '{thirdInstallTime}' should be faster than clean install: '{firstInstallTime}'."); + Assert.IsTrue (secondInstallTime < firstInstallTime && secondInstallTime < thirdInstallTime, + $"Second unchanged install: '{secondInstallTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'."); + Assert.IsTrue (fourthInstalTime < firstInstallTime && fourthInstalTime < thirdInstallTime, + $"Fourth unchanged install: '{fourthInstalTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'."); + } + } + } } From ef91977b7099c53f9761565b573e9a7ca2aa981c Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 14:01:38 -0400 Subject: [PATCH 03/12] Fix new incremental fastdev test --- tests/MSBuildDeviceIntegration/Tests/InstallTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs index 444786992db..983f3155f6a 100644 --- a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs @@ -515,13 +515,13 @@ public void IncrementalFastDeployment () var rootPath = Path.Combine (Root, "temp", TestName); using (var lb1 = CreateDllBuilder (Path.Combine (rootPath, lib1.ProjectName))) Assert.IsTrue (lb1.Build (lib1), "First library build should have succeeded."); - using (var lb2 = CreateDllBuilder (Path.Combine (rootPath, lib2.ProjectFilePath))) + using (var lb2 = CreateDllBuilder (Path.Combine (rootPath, lib2.ProjectName))) Assert.IsTrue (lb2.Build (lib2), "Second library build should have succeeded."); - using (var builder = CreateApkBuilder ()) { + using (var builder = CreateApkBuilder (Path.Combine (rootPath, app.ProjectName))) { builder.ThrowOnBuildFailure = false; Assert.IsTrue (builder.Install (app), "First install should have succeeded."); - var firstInstallTime = b.LastBuildTime; + var firstInstallTime = builder.LastBuildTime; Assert.IsTrue (builder.Install (app, doNotCleanupOnUpdate: true, saveProject: false), "Second install should have succeeded."); var secondInstallTime = builder.LastBuildTime; From e335bb002a0fb03ecdeed18e460856d56c72c2a8 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 14:53:30 -0400 Subject: [PATCH 04/12] Remove Hello and Runtime test categories These two suites are still running on a larger set of devices as part of https://dev.azure.com/devdiv/DevDiv/_release?definitionId=476&view=mine&_a=releases. We can revisit the need to run these on both emulators and devices in a future PR. --- .../run-integrated-regression-tests.yaml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml index ff728889a36..dd38e8017ce 100644 --- a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml +++ b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml @@ -64,21 +64,6 @@ steps: } displayName: Test Environment Setup -- template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Mono.Android-Tests Debug on Device - nunitConsoleExtraArgs: --where "cat == RuntimeTests" - -- template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Hello Tests on Device - nunitConsoleExtraArgs: --where "cat == Hello" - condition: and(succeeded(), eq(variables['XA.Commercial.Build'], 'true')) - - template: run-nunit-tests.yaml parameters: nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe From 9e368a626ada7c6bee8db19d2eea3f235134f39d Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 15:08:23 -0400 Subject: [PATCH 05/12] Remove all 'dotnet' test categories The 'DotNetIgnore' category should be used to filter out tests which are incompatible with One .NET --- .../AndroidDependenciesTests.cs | 2 +- .../AndroidUpdateResourcesTest.cs | 8 +---- .../Xamarin.Android.Build.Tests/BuildTest.cs | 32 +++---------------- .../DesignerTests.cs | 2 +- .../EnvironmentContentTests.cs | 5 +-- .../PackagingTest.cs | 4 +-- .../Xamarin.Android.Build.Tests/WearTests.cs | 2 +- 7 files changed, 11 insertions(+), 44 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs index d87d8c5af27..13b1dadfe42 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs @@ -9,7 +9,7 @@ namespace Xamarin.Android.Build.Tests { [TestFixture] - [Category ("Node-3"), Category ("dotnet")] + [Category ("Node-3")] [Parallelizable (ParallelScope.Children)] public class AndroidDependenciesTests : BaseTest { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs index 8264128c275..ff599c48b03 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs @@ -18,7 +18,6 @@ namespace Xamarin.Android.Build.Tests public class AndroidUpdateResourcesTest : BaseTest { [Test] - [Category ("dotnet")] public void CheckMultipleLibraryProjectReferenceAlias ([Values (true, false)] bool withGlobal) { var path = Path.Combine (Root, "temp", TestName); @@ -81,7 +80,7 @@ public void BuildAppWithSystemNamespace () } [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void DesignTimeBuild ([Values(false, true)] bool isRelease, [Values (false, true)] bool useManagedParser, [Values (false, true)] bool useAapt2) { var regEx = new Regex (@"(?([a-zA-Z_0-9])+)\slibrary_name=(?([0-9A-Za-z])+);", RegexOptions.Compiled | RegexOptions.Multiline ); @@ -219,7 +218,6 @@ public void ReportAaptWarningsForBlankLevel ([Values (false, true)] bool useAapt } [Test] - [Category ("dotnet")] public void RepetiviteBuildUpdateSingleResource ([Values (false, true)] bool useAapt2) { var proj = new XamarinAndroidApplicationProject (); @@ -774,7 +772,6 @@ public void CheckAaptErrorRaisedForDuplicateResourceinApp () } [Test] - [Category ("dotnet")] public void CheckFilesAreRemoved () { var proj = new XamarinAndroidApplicationProject () { @@ -810,7 +807,6 @@ public void CheckFilesAreRemoved () { } [Test] - [Category ("dotnet")] public void CheckDontUpdateResourceIfNotNeeded () { var path = Path.Combine ("temp", TestName); @@ -915,7 +911,6 @@ public string GetFoo () { } [Test] - [Category ("dotnet")] public void BuildAppWithManagedResourceParser() { var path = Path.Combine ("temp", "BuildAppWithManagedResourceParser"); @@ -955,7 +950,6 @@ public void BuildAppWithManagedResourceParser() [Test] [NonParallelizable] - [Category ("dotnet")] public void BuildAppWithManagedResourceParserAndLibraries () { int maxBuildTimeMs = 10000; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 8fe69da2858..64b1982bc04 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -46,7 +46,6 @@ public static string [] SupportedTargetFrameworks () } [Test] - [Category ("dotnet")] public void BuildBasicApplication ([ValueSource (nameof (SupportedTargetFrameworks))] string tfv, [Values (true, false)] bool isRelease) { var proj = new XamarinAndroidApplicationProject { @@ -134,7 +133,6 @@ public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile () }; [Test] - [Category ("dotnet")] [TestCaseSource (nameof (BuildHasNoWarningsSource))] public void BuildHasNoWarnings (bool isRelease, bool xamarinForms, bool multidex, string packageFormat) { @@ -264,7 +262,6 @@ public void BuildBasicApplicationAppCompat ([Values (true, false)] bool usePacka } [Test] - [Category ("dotnet")] [NonParallelizable] public void AndroidXMigration ([Values (true, false)] bool isRelease) { @@ -694,7 +691,6 @@ public void TargetFrameworkMonikerAssemblyAttributesPath () } [Test] - [Category ("dotnet")] [NonParallelizable] public void CheckTimestamps ([Values (true, false)] bool isRelease) { @@ -863,7 +859,6 @@ public void BuildIncrementingAssemblyVersion () } [Test] - [Category ("dotnet")] public void BuildIncrementingClassName () { int count = 0; @@ -1113,7 +1108,7 @@ public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, boo [Test] [NonParallelizable] // On MacOS, parallel /restore causes issues - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void BuildProguardEnabledProject ([Values (true, false)] bool isRelease, [Values ("dx", "d8")] string dexTool, [Values ("", "proguard", "r8")] string linkTool) { AssertDexToolSupported (dexTool); @@ -1178,7 +1173,7 @@ XamarinAndroidApplicationProject CreateMultiDexRequiredApplication (string debug } [Test] - [Category ("Minor"), Category ("dotnet")] + [Category ("Minor")] public void BuildApplicationOver65536Methods ([Values ("dx", "d8")] string dexTool) { AssertDexToolSupported (dexTool); @@ -1191,7 +1186,6 @@ public void BuildApplicationOver65536Methods ([Values ("dx", "d8")] string dexTo } [Test] - [Category ("dotnet")] public void CreateMultiDexWithSpacesInConfig ([Values ("dx", "d8")] string dexTool) { AssertDexToolSupported (dexTool); @@ -1205,7 +1199,6 @@ public void CreateMultiDexWithSpacesInConfig ([Values ("dx", "d8")] string dexTo } [Test] - [Category ("dotnet")] public void BuildMultiDexApplication ([Values ("dx", "d8")] string dexTool) { AssertDexToolSupported (dexTool); @@ -1239,7 +1232,6 @@ public void BuildMultiDexApplication ([Values ("dx", "d8")] string dexTool) } [Test] - [Category ("dotnet")] public void BuildAfterMultiDexIsNotRequired ([Values ("dx", "d8")] string dexTool) { AssertDexToolSupported (dexTool); @@ -1284,7 +1276,6 @@ public void BuildAfterMultiDexIsNotRequired ([Values ("dx", "d8")] string dexToo } [Test] - [Category ("dotnet")] public void MultiDexCustomMainDexFileList ([Values ("dx", "d8")] string dexTool, [Values ("19", "21")] string minSdkVersion) { AssertDexToolSupported (dexTool); @@ -1463,7 +1454,6 @@ public void BuildBasicApplicationCheckMdbRepeatBuild () } [Test] - [Category ("dotnet")] public void BuildAppCheckDebugSymbols () { var path = Path.Combine ("temp", TestContext.CurrentContext.Test.Name); @@ -1599,7 +1589,6 @@ public void BuildBasicApplicationCheckMdbAndPortablePdb () } [Test] - [Category ("dotnet")] public void BuildBasicApplicationCheckConfigFiles () { var proj = new XamarinAndroidApplicationProject (); @@ -1870,7 +1859,6 @@ public void CheckLintConfigMerging () [Test] [NonParallelizable] // fails on NuGet restore - [Category ("dotnet")] /// /// Reference https://bugzilla.xamarin.com/show_bug.cgi?id=29568 /// @@ -1905,7 +1893,6 @@ public void BuildLibraryWhichUsesResources ([Values (false, true)] bool isReleas #pragma warning restore 414 [Test] - [Category ("dotnet")] [TestCaseSource (nameof (BuildApplicationWithJavaSourceChecks))] public void BuildApplicationWithJavaSource (bool isRelease, bool expectedResult) { @@ -1937,7 +1924,6 @@ public void BuildApplicationWithJavaSource (bool isRelease, bool expectedResult) } [Test] - [Category ("dotnet")] [TestCaseSource (nameof (RuntimeChecks))] public void CheckWhichRuntimeIsIncluded (string supportedAbi, bool debugSymbols, string debugType, bool? optimize, bool? embedAssemblies, string expectedRuntime) { var proj = new XamarinAndroidApplicationProject (); @@ -2178,7 +2164,7 @@ public void BuildWithNativeLibraryUnknownAbi () } [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void BuildWithExternalJavaLibrary () { var path = Path.Combine ("temp", "BuildWithExternalJavaLibrary"); @@ -2244,7 +2230,6 @@ public void CheckItemMetadata ([Values (true, false)] bool isRelease) // Context https://bugzilla.xamarin.com/show_bug.cgi?id=29706 [Test] - [Category ("dotnet")] public void CheckLogicalNamePathSeperators ([Values (false, true)] bool isRelease) { var illegalSeperator = IsWindows ? "/" : @"\"; @@ -2627,7 +2612,6 @@ public void BuildApplicationWithSpacesInPath ([Values (true, false)] bool enable } [Test] - [Category ("dotnet")] public void BuildReleaseApplicationWithNugetPackages () { var proj = new XamarinAndroidApplicationProject () { @@ -2837,7 +2821,7 @@ public void CompileBeforeUpgradingNuGet () } [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void BuildBasicApplicationCheckPdb () { var proj = new XamarinAndroidApplicationProject { @@ -3432,7 +3416,7 @@ public void ProguardBOMError () } [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void Desugar ([Values (true, false)] bool isRelease, [Values ("dx", "d8")] string dexTool, [Values ("", "proguard", "r8")] string linkTool) { AssertDexToolSupported (dexTool); @@ -3545,7 +3529,6 @@ public void foo() //See: https://developer.android.com/about/versions/marshmallow/android-6.0-changes#behavior-apache-http-client [Test] - [Category ("dotnet")] public void MissingOrgApacheHttpClient ([Values ("dx", "d8")] string dexTool) { AssertDexToolSupported (dexTool); @@ -3629,7 +3612,6 @@ public void XA0115 (string abis) } [Test] - [Category ("dotnet")] public void XA0119 () { var proj = new XamarinAndroidApplicationProject (); @@ -3644,7 +3626,6 @@ public void XA0119 () } [Test] - [Category ("dotnet")] public void XA0119AAB () { var proj = new XamarinAndroidApplicationProject (); @@ -3685,7 +3666,6 @@ public void FastDeploymentDoesNotAddContentProvider () } [Test] - [Category ("dotnet")] public void DuplicateJCWNames () { var source = @"[Android.Runtime.Register (""examplelib.EmptyClass"")] public class EmptyClass : Java.Lang.Object { }"; @@ -3730,7 +3710,6 @@ public void DuplicateJCWNames () } [Test] - [Category ("dotnet")] public void DuplicateManagedNames () { var source = @"public class EmptyClass : Java.Lang.Object { }"; @@ -4032,7 +4011,6 @@ public void AbiDelimiters ([Values ("armeabi-v7a%3bx86", "armeabi-v7a,x86")] str } [Test] - [Category ("dotnet")] public void WorkManager () { var proj = new XamarinFormsAndroidApplicationProject (); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DesignerTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DesignerTests.cs index b5c2d95445e..bdc46259e66 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DesignerTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DesignerTests.cs @@ -9,7 +9,7 @@ namespace Xamarin.Android.Build.Tests { [TestFixture] - [Category ("Node-3"), Category ("dotnet")] + [Category ("Node-3")] public class DesignerTests : BaseTest { static readonly string [] DesignerParameters = new [] { "DesignTimeBuild=True", "AndroidUseManagedDesignTimeResourceGenerator=False" }; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs index f66c1031e1a..93fbdad2eb1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs @@ -16,7 +16,7 @@ public class EnvironmentContentTests : BaseTest { [Test] [NonParallelizable] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline")] string sequencePointsMode) { const string supportedAbis = "armeabi-v7a;x86"; @@ -78,7 +78,6 @@ public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline } [Test] - [Category ("dotnet")] public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline")] string sequencePointsMode) { const string supportedAbis = "armeabi-v7a;x86"; @@ -110,7 +109,6 @@ public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline" } [Test] - [Category ("dotnet")] public void CheckConcurrentGC () { var proj = new XamarinAndroidApplicationProject () { @@ -195,7 +193,6 @@ public void CheckBuildIdIsUnique ([Values ("apk", "aab")] string packageFormat) } [Test] - [Category ("dotnet")] public void CheckHttpClientHandlerType () { var proj = new XamarinAndroidApplicationProject () { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs index 448a4009306..a1a76ae86e2 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs @@ -124,7 +124,6 @@ public void CheckIncludedAssemblies () } [Test] - [Category ("dotnet")] public void CheckClassesDexIsIncluded ([Values ("dx", "d8", "invalid")] string dexTool) { var proj = new XamarinAndroidApplicationProject () { @@ -289,7 +288,6 @@ public void ExplicitPackageNamingPolicy () } [Test] - [Category ("dotnet")] public void CheckMetadataSkipItemsAreProcessedCorrectly () { var packages = new List () { @@ -504,7 +502,7 @@ public void CheckAapt2WarningsDoNotGenerateErrors () } [Test] - [Category ("SmokeTests"), Category ("dotnet")] + [Category ("SmokeTests")] public void CheckAppBundle ([Values (true, false)] bool isRelease) { var proj = new XamarinAndroidApplicationProject () { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/WearTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/WearTests.cs index 070fbc02197..0b206a6888e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/WearTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/WearTests.cs @@ -5,7 +5,7 @@ namespace Xamarin.Android.Build.Tests { [TestFixture] - [Category ("Node-2"), Category ("dotnet")] + [Category ("Node-2")] public class WearTests : BaseTest { [Test] From ab72daa23afd885e6ef6e40d266f81e434667487 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 16:58:48 -0400 Subject: [PATCH 06/12] Remove / import 'RegressionDeviceTests' QA test category --- .../run-integrated-regression-tests.yaml | 7 ---- ...BugzillaTests.cs => InstallAndRunTests.cs} | 39 ++++++++++++++++--- 2 files changed, 34 insertions(+), 12 deletions(-) rename tests/MSBuildDeviceIntegration/Tests/{BugzillaTests.cs => InstallAndRunTests.cs} (58%) diff --git a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml index dd38e8017ce..dfa8ad15af9 100644 --- a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml +++ b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml @@ -64,13 +64,6 @@ steps: } displayName: Test Environment Setup -- template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Smoke Tests on Device - nunitConsoleExtraArgs: --where "cat == RegressionDeviceTests" - - template: run-nunit-tests.yaml parameters: nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe diff --git a/tests/MSBuildDeviceIntegration/Tests/BugzillaTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs similarity index 58% rename from tests/MSBuildDeviceIntegration/Tests/BugzillaTests.cs rename to tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs index e34e09e52d4..f6b7286b58f 100644 --- a/tests/MSBuildDeviceIntegration/Tests/BugzillaTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using NUnit.Framework; using Xamarin.ProjectTools; @@ -11,7 +7,7 @@ namespace Xamarin.Android.Build.Tests { [SingleThreaded] [Category ("UsesDevices")] - public class BugzillaTests : DeviceTest + public class InstallAndRunTests : DeviceTest { static ProjectBuilder builder; static XamarinAndroidApplicationProject proj; @@ -25,6 +21,9 @@ public void Teardown () if (TestContext.CurrentContext.Result.Outcome.Status == NUnit.Framework.Interfaces.TestStatus.Passed && builder != null && Directory.Exists (builder.ProjectDirectory)) Directory.Delete (builder.ProjectDirectory, recursive: true); + + builder?.Dispose (); + proj = null; } [Test] @@ -59,5 +58,35 @@ void Button_ViewTreeObserver_GlobalLayout (object sender, EventArgs e) }, Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log"), 45), $"Output did not contain {expectedLogcatOutput}!"); } + [Test] + public void SubscribeToAppDomainUnhandledException () + { + AssertHasDevices (); + + proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + }; + proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86", "x86_64"); + proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}", +@" AppDomain.CurrentDomain.UnhandledException += (sender, e) => { + Console.WriteLine (""# Unhandled Exception: sender={0}; e.IsTerminating={1}; e.ExceptionObject={2}"", + sender, e.IsTerminating, e.ExceptionObject); + }; + throw new Exception (""CRASH""); +"); + builder = CreateApkBuilder (); + Assert.IsTrue (builder.Install (proj), "Install should have succeeded."); + ClearAdbLogcat (); + if (CommercialBuildAvailable) + Assert.True (builder.RunTarget (proj, "_Run"), "Project should have run."); + else + AdbStartActivity ($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity"); + + string expectedLogcatOutput = "# Unhandled Exception: sender=RootDomain; e.IsTerminating=True; e.ExceptionObject=System.Exception: CRASH"; + Assert.IsTrue (MonitorAdbLogcat ((line) => { + return line.Contains (expectedLogcatOutput); + }, Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log"), 45), $"Output did not contain {expectedLogcatOutput}!"); + } + } } From 87709b3e7aba2b333e827c7f958d7e4e0d3b131d Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 9 Sep 2020 17:02:09 -0400 Subject: [PATCH 07/12] Spacing fixes --- tests/MSBuildDeviceIntegration/Tests/InstallTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs index 983f3155f6a..e323ee0236c 100644 --- a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs @@ -180,7 +180,7 @@ public void SwitchConfigurationsShouldRedeploy () directorylist = GetContentFromAllOverrideDirectories (proj.PackageName); StringAssert.Contains ($"{proj.AssemblyName}", directorylist, $"{proj.AssemblyName} not found in fastdev directory."); - + Assert.IsTrue (builder.Uninstall (proj)); Assert.AreNotEqual ($"package:{proj.PackageName}", RunAdbCommand ($"shell pm list packages {proj.PackageName}").Trim (), $"{proj.PackageName} is installed on the device."); @@ -265,10 +265,10 @@ public void ToggleFastDev () AndroidUseSharedRuntime = true, EmbedAssembliesIntoApk = false, OtherBuildItems = { - new BuildItem.NoActionResource ($"UnnamedProject.dll.config") { + new BuildItem.NoActionResource ("UnnamedProject.dll.config") { TextContent = () => "", Metadata = { - { "CopyToOutputDirectory", "PreserveNewest"}, + { "CopyToOutputDirectory", "PreserveNewest" }, } } } From dfdfadc2321e6f2fcac722015b8d9e9aa13fbc72 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Thu, 10 Sep 2020 16:08:05 -0400 Subject: [PATCH 08/12] Remove regression test jobs --- build-tools/automation/azure-pipelines.yaml | 34 -------- .../run-integrated-regression-tests.yaml | 81 ------------------- 2 files changed, 115 deletions(-) delete mode 100644 build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index 85c55524e1f..7fb5a210883 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -1109,40 +1109,6 @@ stages: condition: and(eq(dependencies.mac_build.result, 'Succeeded'), eq(variables['RunAllTests'], true)) jobs: - # Check - "Xamarin.Android (Regression Tests Mac)" - - job: integrated_regression_mac - displayName: Mac - pool: - name: VSEng-Xamarin-Mac-Devices - demands: - - android - timeoutInMinutes: 240 - cancelTimeoutInMinutes: 5 - workspace: - clean: all - steps: - - template: yaml-templates/run-integrated-regression-tests.yaml - - # Check - "Xamarin.Android (Regression Tests Windows)" - - job: integrated_regression_win - displayName: Windows - pool: - name: VSEng-Xamarin-Win-XMA - demands: - - android - timeoutInMinutes: 240 - cancelTimeoutInMinutes: 5 - workspace: - clean: all - variables: - XQA_VISUALSTUDIO_LOCATION: '%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise' - steps: - - template: remove-visualstudio.yml@yaml - - - template: yaml-templates\run-integrated-regression-tests.yaml - - - template: remove-visualstudio.yml@yaml - # TimeZoneInfo tests - template: yaml-templates\run-timezoneinfo-tests.yaml parameters: diff --git a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml deleted file mode 100644 index dfa8ad15af9..00000000000 --- a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml +++ /dev/null @@ -1,81 +0,0 @@ -steps: -- task: xamops.azdevex.lingering-process-task.lingering-process-task@1 - -- task: DownloadBuildArtifacts@0 - inputs: - buildType: specific - project: 0bdbc590-a062-4c3f-b0f6-9383f67865ee - pipeline: 'XQA.sln' - buildVersionToDownload: latestFromBranch - branchName: refs/heads/master - downloadType: specific - itemPattern: | - XQA.Android/** - provisionator/** - NUnit.ConsoleRunner/** - downloadPath: $(System.DefaultWorkingDirectory) - -- checkout: self - clean: true - submodules: recursive - -- checkout: monodroid - clean: true - submodules: recursive - path: s/xamarin-android/external/monodroid - persistCredentials: true - -- checkout: qa - clean: true - fetchDepth: 10 - -- checkout: samples - clean: true - fetchDepth: 10 - -- checkout: xfsamples - clean: true - fetchDepth: 10 - - # Clear out VS installer content before provisioning VS to avoid using unstable tools from pre-release installers. -- powershell: Remove-Item "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer" -Recurse -Force -ErrorAction Ignore - displayName: Delete VS Installer - condition: and(succeeded(), eq(variables['agent.os'], 'Windows_NT')) - -- task: xamops.azdevex.provisionator-task.provisionator@2 - displayName: Provision Android Dependencies - inputs: - github_token: $(GitHub.Token) - provisioning_script: $(System.DefaultWorkingDirectory)/provisionator/xamarin-android.csx - provisioning_extra_args: -vv - -- script: make prepare-update-mono V=1 PREPARE_CI=1 PREPARE_AUTOPROVISION=1 - workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-android - displayName: install mono - condition: and(succeeded(), eq(variables['agent.os'], 'Darwin')) - -- template: run-installer.yaml - -- powershell: | - if ([Environment]::OSVersion.Platform -eq "Unix") { - mono $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll --where "cat == XAUnitTestSetup || cat == XATestPrep || cat == EnvironmentInfo" - } else { - $(System.DefaultWorkingDirectory)\NUnit.ConsoleRunner\tools\nunit3-console.exe $(System.DefaultWorkingDirectory)\XQA.Android\XQA.Android.dll --where "cat == XAUnitTestSetup || cat == XATestPrep || cat == EnvironmentInfo" - } - displayName: Test Environment Setup - -- template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: AOT Tests - nunitConsoleExtraArgs: --where "cat == AotSupport" - -- template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Test Environment Cleanup - nunitConsoleExtraArgs: --where "cat == XATestCleanUp" - -- template: fail-on-issue.yaml From 6a4f940d944200f0aca787ded65acc71b1b368b7 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Thu, 10 Sep 2020 16:08:47 -0400 Subject: [PATCH 09/12] Move AOT tests to AotTests, migrate missing regression test --- .../Xamarin.Android.Build.Tests/AotTests.cs | 342 ++++++++++++++++++ .../BuildTest.TestCaseSource.cs | 4 +- .../Xamarin.Android.Build.Tests/BuildTest.cs | 300 --------------- 3 files changed, 344 insertions(+), 302 deletions(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs new file mode 100644 index 00000000000..93399f86d35 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs @@ -0,0 +1,342 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Microsoft.Build.Framework; +using Mono.Cecil; +using NUnit.Framework; +using Xamarin.ProjectTools; + +namespace Xamarin.Android.Build.Tests +{ + [Category ("Node-1"), Category ("AOT")] + [Parallelizable (ParallelScope.Children)] + public class AotTests : BaseTest + { + [Test, Category ("SmokeTests")] + public void BuildBasicApplicationReleaseProfiledAot () + { + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + AndroidEnableProfiledAot = true, + }; + proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidExtraAotOptions", "--verbose"); + using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Using profile data file.*build.Xamarin.Android.startup\.aotprofile", b.LastBuildOutput, "Should use default AOT profile", RegexOptions.IgnoreCase); + StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Method.*emitted at", b.LastBuildOutput, "Should contain verbose AOT compiler output", RegexOptions.IgnoreCase); + } + } + + [Test] + public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile () + { + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + AndroidEnableProfiledAot = true, + }; + proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidUseDefaultAotProfile", "false"); + using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + StringAssertEx.DoesNotContainRegex (@"\[aot-compiler stdout\] Using profile data file.*build.Xamarin.Android.startup.*\.aotprofile", b.LastBuildOutput, "Should not use default AOT profile", RegexOptions.IgnoreCase); + } + } + + + [Test] + [TestCaseSource (nameof (BuildTest.AotChecks))] + [Category ("SmokeTests")] + public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult) + { + var path = Path.Combine ("temp", string.Format ("BuildAotApplication AndÜmläüts_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult)); + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + BundleAssemblies = false, + AotAssemblies = true, + }; + proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1"); + proj.SetAndroidSupportedAbis (supportedAbis); + proj.SetProperty ("EnableLLVM", enableLLVM.ToString ()); + bool checkMinLlvmPath = enableLLVM && (supportedAbis == "armeabi-v7a" || supportedAbis == "x86"); + if (checkMinLlvmPath) { + // Set //uses-sdk/@android:minSdkVersion so that LLVM uses the right libc.so + proj.AndroidManifest = $@" + + + + +"; + } + using (var b = CreateApkBuilder (path)) { + if (!b.CrossCompilerAvailable (supportedAbis)) + Assert.Ignore ($"Cross compiler for {supportedAbis} was not available"); + if (!b.GetSupportedRuntimes ().Any (x => supportedAbis == x.Abi)) + Assert.Ignore ($"Runtime for {supportedAbis} was not available."); + b.ThrowOnBuildFailure = false; + b.Verbosity = LoggerVerbosity.Diagnostic; + Assert.AreEqual (expectedResult, b.Build (proj), "Build should have {0}.", expectedResult ? "succeeded" : "failed"); + if (!expectedResult) + return; + //NOTE: Windows has shortened paths such as: C:\Users\myuser\ANDROI~3\ndk\PLATFO~1\AN3971~1\arch-x86\usr\lib\libc.so + if (checkMinLlvmPath && !IsWindows) { + // LLVM passes a direct path to libc.so, and we need to use the libc.so + // which corresponds to the *minimum* SDK version specified in AndroidManifest.xml + // Since we overrode minSdkVersion=16, that means we should use libc.so from android-16. + StringAssertEx.ContainsRegex (@"\s*\[aot-compiler stdout].*android-16.arch-.*.usr.lib.libc\.so", b.LastBuildOutput, "AOT+LLVM should use libc.so from minSdkVersion!"); + } + foreach (var abi in supportedAbis.Split (new char [] { ';' })) { + var libapp = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, + "bundles", abi, "libmonodroid_bundle_app.so"); + Assert.IsFalse (File.Exists (libapp), abi + " libmonodroid_bundle_app.so should not exist"); + var assemblies = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, + "aot", abi, "libaot-UnnamedProject.dll.so"); + Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi); + var apk = Path.Combine (Root, b.ProjectDirectory, + proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"); + using (var zipFile = ZipHelper.OpenZip (apk)) { + Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile, + string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)), + "lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi); + Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile, + "assemblies/UnnamedProject.dll"), + "UnnamedProject.dll should be in the UnnamedProject.UnnamedProject.apk"); + } + } + Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed"); + Assert.IsTrue ( + b.Output.IsTargetSkipped ("_CompileJava"), + "the _CompileJava target should be skipped"); + Assert.IsTrue ( + b.Output.IsTargetSkipped ("_BuildApkEmbed"), + "the _BuildApkEmbed target should be skipped"); + } + } + + [Test] + [TestCaseSource (nameof (BuildTest.AotChecks))] + [Category ("Minor"), Category ("MkBundle")] + public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult) + { + var path = Path.Combine ("temp", string.Format ("BuildAotApplicationAndBundle AndÜmläüts_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult)); + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + BundleAssemblies = true, + AotAssemblies = true, + }; + proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1"); + proj.SetAndroidSupportedAbis (supportedAbis); + proj.SetProperty ("EnableLLVM", enableLLVM.ToString ()); + using (var b = CreateApkBuilder (path)) { + if (!b.CrossCompilerAvailable (supportedAbis)) + Assert.Ignore ("Cross compiler was not available"); + if (!b.GetSupportedRuntimes ().Any (x => supportedAbis == x.Abi)) + Assert.Ignore ($"Runtime for {supportedAbis} was not available."); + b.ThrowOnBuildFailure = false; + Assert.AreEqual (expectedResult, b.Build (proj), "Build should have {0}.", expectedResult ? "succeeded" : "failed"); + if (!expectedResult) + return; + foreach (var abi in supportedAbis.Split (new char [] { ';' })) { + var libapp = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, + "bundles", abi, "libmonodroid_bundle_app.so"); + Assert.IsTrue (File.Exists (libapp), abi + " libmonodroid_bundle_app.so does not exist"); + var assemblies = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, + "aot", abi, "libaot-UnnamedProject.dll.so"); + Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi); + var apk = Path.Combine (Root, b.ProjectDirectory, + proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"); + using (var zipFile = ZipHelper.OpenZip (apk)) { + Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile, + string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)), + "lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi); + Assert.IsNull (ZipHelper.ReadFileFromZip (zipFile, + "assemblies/UnnamedProject.dll"), + "UnnamedProject.dll should not be in the UnnamedProject.UnnamedProject.apk"); + } + } + Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed"); + Assert.IsTrue ( + b.Output.IsTargetSkipped ("_CompileJava"), + "the _CompileJava target should be skipped"); + Assert.IsTrue ( + b.Output.IsTargetSkipped ("_BuildApkEmbed"), + "the _BuildApkEmbed target should be skipped"); + } + } + + + [Test] + [NonParallelizable] + [Category ("SmokeTests")] + public void BuildAMassiveApp () + { + var testPath = Path.Combine ("temp", "BuildAMassiveApp"); + TestOutputDirectories [TestContext.CurrentContext.Test.ID] = Path.Combine (Root, testPath); + var sb = new SolutionBuilder ("BuildAMassiveApp.sln") { + SolutionPath = Path.Combine (Root, testPath), + Verbosity = LoggerVerbosity.Diagnostic, + }; + var app1 = new XamarinAndroidApplicationProject () { + TargetFrameworkVersion = sb.LatestTargetFrameworkVersion (), + ProjectName = "App1", + AotAssemblies = true, + IsRelease = true, + PackageReferences = { + KnownPackages.SupportDesign_27_0_2_1, + KnownPackages.SupportCompat_27_0_2_1, + KnownPackages.SupportCoreUI_27_0_2_1, + KnownPackages.SupportCoreUtils_27_0_2_1, + KnownPackages.SupportFragment_27_0_2_1, + KnownPackages.SupportMediaCompat_27_0_2_1, + KnownPackages.GooglePlayServicesMaps_42_1021_1, + KnownPackages.Xamarin_Build_Download_0_4_11, + }, + }; + //NOTE: BuildingInsideVisualStudio prevents the projects from being built as dependencies + sb.BuildingInsideVisualStudio = false; + app1.Imports.Add (new Import ("foo.targets") { + TextContent = () => @" + + + + armeabi-v7a;x86 + $(AndroidSupportedAbis);arm64-v8a + $(AndroidSupportedAbis);x86_64 + + + + + + False + + + + +", + }); + app1.SetProperty (KnownProperties.AndroidUseSharedRuntime, "False"); + sb.Projects.Add (app1); + var code = new StringBuilder (); + code.AppendLine ("using System;"); + code.AppendLine ("namespace App1 {"); + code.AppendLine ("\tpublic class AppCode {"); + code.AppendLine ("\t\tpublic void Foo () {"); + for (int i = 0; i < 128; i++) { + var libName = $"Lib{i}"; + var lib = new XamarinAndroidLibraryProject () { + TargetFrameworkVersion = sb.LatestTargetFrameworkVersion (), + ProjectName = libName, + IsRelease = true, + OtherBuildItems = { + new AndroidItem.AndroidAsset ($"Assets\\{libName}.txt") { + TextContent = () => "Asset1", + Encoding = Encoding.ASCII, + }, + new AndroidItem.AndroidAsset ($"Assets\\subfolder\\{libName}.txt") { + TextContent = () => "Asset2", + Encoding = Encoding.ASCII, + }, + }, + Sources = { + new BuildItem.Source ($"{libName}.cs") { + TextContent = () => @"using System; + +namespace "+ libName + @" { + + public class " + libName + @" { + public static void Foo () { + } + } +}" + }, + } + }; + var strings = lib.AndroidResources.First (x => x.Include () == "Resources\\values\\Strings.xml"); + strings.TextContent = () => @" + + " + libName + @" +"; + sb.Projects.Add (lib); + app1.References.Add (new BuildItem.ProjectReference ($"..\\{libName}\\{libName}.csproj", libName, lib.ProjectGuid)); + code.AppendLine ($"\t\t\t{libName}.{libName}.Foo ();"); + } + code.AppendLine ("\t\t}"); + code.AppendLine ("\t}"); + code.AppendLine ("}"); + app1.Sources.Add (new BuildItem.Source ("Code.cs") { + TextContent = () => code.ToString (), + }); + Assert.IsTrue (sb.Build (new string [] { "Configuration=Release" }), "Solution should have built."); + Assert.IsTrue (sb.BuildProject (app1, "SignAndroidPackage"), "Build of project should have succeeded"); + sb.Dispose (); + } + + [Test] + public void HybridAOT () + { + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + AotAssemblies = true, + }; + proj.SetProperty ("AndroidAotMode", "Hybrid"); + // So we can use Mono.Cecil to open assemblies directly + proj.SetProperty ("AndroidEnableAssemblyCompression", "False"); + + using (var b = CreateApkBuilder ()) { + b.Build (proj); + + var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk"); + FileAssert.Exists (apk); + using (var zip = ZipHelper.OpenZip (apk)) { + var entry = zip.ReadEntry ($"assemblies/{proj.ProjectName}.dll"); + Assert.IsNotNull (entry, $"{proj.ProjectName}.dll should exist in apk!"); + using (var stream = new MemoryStream ()) { + entry.Extract (stream); + stream.Position = 0; + using (var assembly = AssemblyDefinition.ReadAssembly (stream)) { + var type = assembly.MainModule.GetType ($"{proj.ProjectName}.MainActivity"); + var method = type.Methods.First (m => m.Name == "OnCreate"); + Assert.LessOrEqual (method.Body.Instructions.Count, 1, "OnCreate should have stripped method bodies!"); + } + } + } + } + } + + [Test] + public void NoSymbolsArgShouldReduceAppSize ([Values (true, false)] bool enableHybridAot) + { + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + AotAssemblies = true, + }; + var supportedAbi = "arm64-v8a"; + proj.SetAndroidSupportedAbis (supportedAbi); + proj.SetProperty ("EnableLLVM", true.ToString ()); + if (enableHybridAot) + proj.SetProperty ("AndroidAotMode", "Hybrid"); + + var xaAssemblySize = 0; + var xaAssemblySizeNoSymbol = 0; + + using (var b = CreateApkBuilder ()) { + b.ThrowOnBuildFailure = false; + Assert.IsTrue (b.Build (proj), "First build should have succeeded."); + var apkPath = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk"); + FileAssert.Exists (apkPath); + using (var apk = ZipHelper.OpenZip (apkPath)) { + xaAssemblySize = ZipHelper.ReadFileFromZip (apk, $"lib/{supportedAbi}/libaot-Mono.Android.dll.so").Length; + } + proj.SetProperty ("AndroidAotAdditionalArguments", "no-write-symbols"); + Assert.IsTrue (b.Build (proj), "Second build should have succeeded."); + FileAssert.Exists (apkPath); + using (var apk = ZipHelper.OpenZip (apkPath)) { + xaAssemblySizeNoSymbol = ZipHelper.ReadFileFromZip (apk, $"lib/{supportedAbi}/libaot-Mono.Android.dll.so").Length; + } + Assert.IsTrue (xaAssemblySize > 0 && xaAssemblySizeNoSymbol > 0, $"Mono.Android.dll.so size was not updated after first or second build. Before: '{xaAssemblySize}' After: '{xaAssemblySizeNoSymbol}'."); + Assert.Less (xaAssemblySizeNoSymbol, xaAssemblySize, "Mono.Android.dll.so should have been smaller after 'no-write-symbols' build."); + } + } + + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs index c786ead4fa5..7c24bc357e5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Text; @@ -12,7 +12,7 @@ namespace Xamarin.Android.Build.Tests public partial class BuildTest : BaseTest { #pragma warning disable 414 - static object [] AotChecks () => new object [] { + public static object [] AotChecks () => new object [] { new object[] { /* supportedAbis */ "armeabi-v7a", /* enableLLVM */ false, diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 64b1982bc04..793b948360e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Reflection; using System.Text; -using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; @@ -57,36 +56,6 @@ public void BuildBasicApplication ([ValueSource (nameof (SupportedTargetFramewor } } - [Test] - [Category ("SmokeTests"), Category ("AOT")] - public void BuildBasicApplicationReleaseProfiledAot () - { - var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, - AndroidEnableProfiledAot = true, - }; - proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidExtraAotOptions", "--verbose"); - using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { - Assert.IsTrue (b.Build (proj), "Build should have succeeded."); - StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Using profile data file.*build.Xamarin.Android.startup\.aotprofile", b.LastBuildOutput, "Should use default AOT profile", RegexOptions.IgnoreCase); - StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Method.*emitted at", b.LastBuildOutput, "Should contain verbose AOT compiler output", RegexOptions.IgnoreCase); - } - } - - [Test, Category ("AOT")] - public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile () - { - var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, - AndroidEnableProfiledAot = true, - }; - proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidUseDefaultAotProfile", "false"); - using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { - Assert.IsTrue (b.Build (proj), "Build should have succeeded."); - StringAssertEx.DoesNotContainRegex (@"\[aot-compiler stdout\] Using profile data file.*build.Xamarin.Android.startup.*\.aotprofile", b.LastBuildOutput, "Should not use default AOT profile", RegexOptions.IgnoreCase); - } - } - static readonly object [] BuildHasNoWarningsSource = new object [] { new object [] { /* isRelease */ false, @@ -986,126 +955,6 @@ public void BuildMkBundleApplicationReleaseAllAbi () } } - [Test] - [TestCaseSource (nameof (AotChecks))] - [Category ("SmokeTests"), Category ("AOT")] - public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult) - { - var path = Path.Combine ("temp", string.Format ("BuildAotApplication AndÜmläüts_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult)); - var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, - BundleAssemblies = false, - AotAssemblies = true, - }; - proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1"); - proj.SetAndroidSupportedAbis (supportedAbis); - proj.SetProperty ("EnableLLVM", enableLLVM.ToString ()); - bool checkMinLlvmPath = enableLLVM && (supportedAbis == "armeabi-v7a" || supportedAbis == "x86"); - if (checkMinLlvmPath) { - // Set //uses-sdk/@android:minSdkVersion so that LLVM uses the right libc.so - proj.AndroidManifest = $@" - - - - -"; - } - using (var b = CreateApkBuilder (path)) { - if (!b.CrossCompilerAvailable (supportedAbis)) - Assert.Ignore ($"Cross compiler for {supportedAbis} was not available"); - if (!b.GetSupportedRuntimes ().Any (x => supportedAbis == x.Abi)) - Assert.Ignore ($"Runtime for {supportedAbis} was not available."); - b.ThrowOnBuildFailure = false; - b.Verbosity = LoggerVerbosity.Diagnostic; - Assert.AreEqual (expectedResult, b.Build (proj), "Build should have {0}.", expectedResult ? "succeeded" : "failed"); - if (!expectedResult) - return; - //NOTE: Windows has shortened paths such as: C:\Users\myuser\ANDROI~3\ndk\PLATFO~1\AN3971~1\arch-x86\usr\lib\libc.so - if (checkMinLlvmPath && !IsWindows) { - // LLVM passes a direct path to libc.so, and we need to use the libc.so - // which corresponds to the *minimum* SDK version specified in AndroidManifest.xml - // Since we overrode minSdkVersion=16, that means we should use libc.so from android-16. - StringAssertEx.ContainsRegex (@"\s*\[aot-compiler stdout].*android-16.arch-.*.usr.lib.libc\.so", b.LastBuildOutput, "AOT+LLVM should use libc.so from minSdkVersion!"); - } - foreach (var abi in supportedAbis.Split (new char [] { ';' })) { - var libapp = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, - "bundles", abi, "libmonodroid_bundle_app.so"); - Assert.IsFalse (File.Exists (libapp), abi + " libmonodroid_bundle_app.so should not exist"); - var assemblies = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, - "aot", abi, "libaot-UnnamedProject.dll.so"); - Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi); - var apk = Path.Combine (Root, b.ProjectDirectory, - proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"); - using (var zipFile = ZipHelper.OpenZip (apk)) { - Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile, - string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)), - "lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi); - Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile, - "assemblies/UnnamedProject.dll"), - "UnnamedProject.dll should be in the UnnamedProject.UnnamedProject.apk"); - } - } - Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed"); - Assert.IsTrue ( - b.Output.IsTargetSkipped ("_CompileJava"), - "the _CompileJava target should be skipped"); - Assert.IsTrue ( - b.Output.IsTargetSkipped ("_BuildApkEmbed"), - "the _BuildApkEmbed target should be skipped"); - } - } - - [Test] - [TestCaseSource (nameof (AotChecks))] - [Category ("Minor"), Category ("MkBundle"), Category ("AOT")] - public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult) - { - var path = Path.Combine ("temp", string.Format ("BuildAotApplicationAndBundle AndÜmläüts_{0}_{1}_{2}", supportedAbis, enableLLVM, expectedResult)); - var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, - BundleAssemblies = true, - AotAssemblies = true, - }; - proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1"); - proj.SetAndroidSupportedAbis (supportedAbis); - proj.SetProperty ("EnableLLVM", enableLLVM.ToString ()); - using (var b = CreateApkBuilder (path)) { - if (!b.CrossCompilerAvailable (supportedAbis)) - Assert.Ignore ("Cross compiler was not available"); - if (!b.GetSupportedRuntimes ().Any (x => supportedAbis == x.Abi)) - Assert.Ignore ($"Runtime for {supportedAbis} was not available."); - b.ThrowOnBuildFailure = false; - Assert.AreEqual (expectedResult, b.Build (proj), "Build should have {0}.", expectedResult ? "succeeded" : "failed"); - if (!expectedResult) - return; - foreach (var abi in supportedAbis.Split (new char [] { ';' })) { - var libapp = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, - "bundles", abi, "libmonodroid_bundle_app.so"); - Assert.IsTrue (File.Exists (libapp), abi + " libmonodroid_bundle_app.so does not exist"); - var assemblies = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, - "aot", abi, "libaot-UnnamedProject.dll.so"); - Assert.IsTrue (File.Exists (assemblies), "{0} libaot-UnnamedProject.dll.so does not exist", abi); - var apk = Path.Combine (Root, b.ProjectDirectory, - proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk"); - using (var zipFile = ZipHelper.OpenZip (apk)) { - Assert.IsNotNull (ZipHelper.ReadFileFromZip (zipFile, - string.Format ("lib/{0}/libaot-UnnamedProject.dll.so", abi)), - "lib/{0}/libaot-UnnamedProject.dll.so should be in the UnnamedProject.UnnamedProject.apk", abi); - Assert.IsNull (ZipHelper.ReadFileFromZip (zipFile, - "assemblies/UnnamedProject.dll"), - "UnnamedProject.dll should not be in the UnnamedProject.UnnamedProject.apk"); - } - } - Assert.AreEqual (expectedResult, b.Build (proj), "Second Build should have {0}.", expectedResult ? "succeeded" : "failed"); - Assert.IsTrue ( - b.Output.IsTargetSkipped ("_CompileJava"), - "the _CompileJava target should be skipped"); - Assert.IsTrue ( - b.Output.IsTargetSkipped ("_BuildApkEmbed"), - "the _BuildApkEmbed target should be skipped"); - } - } - [Test] [NonParallelizable] // On MacOS, parallel /restore causes issues [Category ("SmokeTests")] @@ -2533,17 +2382,6 @@ public interface OnFooListener } } - [Test] - public void BuildReleaseApplication () - { - var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, - }; - using (var b = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name))) { - Assert.IsTrue (b.Build (proj), "Build should have succeeded."); - } - } - [Test] [Category ("SmokeTests"), Category ("AOT")] public void BuildApplicationWithSpacesInPath ([Values (true, false)] bool enableMultiDex, [Values ("dx", "d8")] string dexTool, [Values ("", "proguard", "r8")] string linkTool) @@ -3232,112 +3070,6 @@ public void ValidateUseLatestAndroid () Directory.Delete (referencesPath, recursive: true); } - [Test] - [NonParallelizable] - [Category ("SmokeTests"), Category ("AOT")] - public void BuildAMassiveApp() - { - var testPath = Path.Combine("temp", "BuildAMassiveApp"); - TestOutputDirectories [TestContext.CurrentContext.Test.ID] = Path.Combine (Root, testPath); - var sb = new SolutionBuilder("BuildAMassiveApp.sln") { - SolutionPath = Path.Combine(Root, testPath), - Verbosity = LoggerVerbosity.Diagnostic, - }; - var app1 = new XamarinAndroidApplicationProject() { - TargetFrameworkVersion = sb.LatestTargetFrameworkVersion (), - ProjectName = "App1", - AotAssemblies = true, - IsRelease = true, - PackageReferences = { - KnownPackages.SupportDesign_27_0_2_1, - KnownPackages.SupportCompat_27_0_2_1, - KnownPackages.SupportCoreUI_27_0_2_1, - KnownPackages.SupportCoreUtils_27_0_2_1, - KnownPackages.SupportFragment_27_0_2_1, - KnownPackages.SupportMediaCompat_27_0_2_1, - KnownPackages.GooglePlayServicesMaps_42_1021_1, - KnownPackages.Xamarin_Build_Download_0_4_11, - }, - }; - //NOTE: BuildingInsideVisualStudio prevents the projects from being built as dependencies - sb.BuildingInsideVisualStudio = false; - app1.Imports.Add (new Import ("foo.targets") { - TextContent = () => @" - - - - armeabi-v7a;x86 - $(AndroidSupportedAbis);arm64-v8a - $(AndroidSupportedAbis);x86_64 - - - - - - False - - - - -", - }); - app1.SetProperty(KnownProperties.AndroidUseSharedRuntime, "False"); - sb.Projects.Add(app1); - var code = new StringBuilder(); - code.AppendLine("using System;"); - code.AppendLine("namespace App1 {"); - code.AppendLine("\tpublic class AppCode {"); - code.AppendLine("\t\tpublic void Foo () {"); - for (int i = 0; i < 128; i++) { - var libName = $"Lib{i}"; - var lib = new XamarinAndroidLibraryProject() { - TargetFrameworkVersion = sb.LatestTargetFrameworkVersion (), - ProjectName = libName, - IsRelease = true, - OtherBuildItems = { - new AndroidItem.AndroidAsset ($"Assets\\{libName}.txt") { - TextContent = () => "Asset1", - Encoding = Encoding.ASCII, - }, - new AndroidItem.AndroidAsset ($"Assets\\subfolder\\{libName}.txt") { - TextContent = () => "Asset2", - Encoding = Encoding.ASCII, - }, - }, - Sources = { - new BuildItem.Source ($"{libName}.cs") { - TextContent = () => @"using System; - -namespace "+ libName + @" { - - public class " + libName + @" { - public static void Foo () { - } - } -}" - }, - } - }; - var strings = lib.AndroidResources.First(x => x.Include() == "Resources\\values\\Strings.xml"); - strings.TextContent = () => @" - - " + libName + @" -"; - sb.Projects.Add(lib); - app1.References.Add(new BuildItem.ProjectReference($"..\\{libName}\\{libName}.csproj", libName, lib.ProjectGuid)); - code.AppendLine($"\t\t\t{libName}.{libName}.Foo ();"); - } - code.AppendLine("\t\t}"); - code.AppendLine("\t}"); - code.AppendLine("}"); - app1.Sources.Add(new BuildItem.Source("Code.cs") { - TextContent = ()=> code.ToString (), - }); - Assert.IsTrue(sb.Build(new string[] { "Configuration=Release" }), "Solution should have built."); - Assert.IsTrue(sb.BuildProject(app1, "SignAndroidPackage"), "Build of project should have succeeded"); - sb.Dispose(); - } - [Test] public void XA4212 () { @@ -4192,37 +3924,5 @@ public void XA4310 ([Values ("apk", "aab")] string packageFormat) } } - [Test] - [Category ("AOT")] - public void HybridAOT () - { - var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, - AotAssemblies = true, - }; - proj.SetProperty ("AndroidAotMode", "Hybrid"); - // So we can use Mono.Cecil to open assemblies directly - proj.SetProperty ("AndroidEnableAssemblyCompression", "False"); - - using (var b = CreateApkBuilder ()) { - b.Build (proj); - - var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}.apk"); - FileAssert.Exists (apk); - using (var zip = ZipHelper.OpenZip (apk)) { - var entry = zip.ReadEntry ($"assemblies/{proj.ProjectName}.dll"); - Assert.IsNotNull (entry, $"{proj.ProjectName}.dll should exist in apk!"); - using (var stream = new MemoryStream ()) { - entry.Extract (stream); - stream.Position = 0; - using (var assembly = AssemblyDefinition.ReadAssembly (stream)) { - var type = assembly.MainModule.GetType ($"{proj.ProjectName}.MainActivity"); - var method = type.Methods.First (m => m.Name == "OnCreate"); - Assert.LessOrEqual (method.Body.Instructions.Count, 1, "OnCreate should have stripped method bodies!"); - } - } - } - } - } } } From edfb2414793d9d38a09398b22c9e17eaedf15b17 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Mon, 14 Sep 2020 10:29:12 -0400 Subject: [PATCH 10/12] Move AOT tests to node-2, fix incremental assert --- .../Xamarin.Android.Build.Tests/AotTests.cs | 49 +++++++++++++++++-- .../BuildTest.TestCaseSource.cs | 45 +---------------- .../IncrementalBuildTest.cs | 2 +- 3 files changed, 47 insertions(+), 49 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs index 93399f86d35..6de38933a40 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs @@ -10,7 +10,7 @@ namespace Xamarin.Android.Build.Tests { - [Category ("Node-1"), Category ("AOT")] + [Category ("Node-2"), Category ("AOT")] [Parallelizable (ParallelScope.Children)] public class AotTests : BaseTest { @@ -43,9 +43,51 @@ public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile () } } + static object [] AotChecks () => new object [] { + new object[] { + /* supportedAbis */ "armeabi-v7a", + /* enableLLVM */ false, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "armeabi-v7a", + /* enableLLVM */ true, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "arm64-v8a", + /* enableLLVM */ false, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "arm64-v8a", + /* enableLLVM */ true, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "x86", + /* enableLLVM */ false, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "x86", + /* enableLLVM */ true, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "x86_64", + /* enableLLVM */ false, + /* expectedResult */ true, + }, + new object[] { + /* supportedAbis */ "x86_64", + /* enableLLVM */ true, + /* expectedResult */ true, + }, + }; [Test] - [TestCaseSource (nameof (BuildTest.AotChecks))] + [TestCaseSource (nameof (AotChecks))] [Category ("SmokeTests")] public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult) { @@ -114,7 +156,7 @@ public void BuildAotApplicationAndÜmläüts (string supportedAbis, bool enableL } [Test] - [TestCaseSource (nameof (BuildTest.AotChecks))] + [TestCaseSource (nameof (AotChecks))] [Category ("Minor"), Category ("MkBundle")] public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, bool enableLLVM, bool expectedResult) { @@ -164,7 +206,6 @@ public void BuildAotApplicationAndBundleAndÜmläüts (string supportedAbis, boo } } - [Test] [NonParallelizable] [Category ("SmokeTests")] diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs index 7c24bc357e5..ee3cfc89540 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.TestCaseSource.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Text; @@ -12,49 +12,6 @@ namespace Xamarin.Android.Build.Tests public partial class BuildTest : BaseTest { #pragma warning disable 414 - public static object [] AotChecks () => new object [] { - new object[] { - /* supportedAbis */ "armeabi-v7a", - /* enableLLVM */ false, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "armeabi-v7a", - /* enableLLVM */ true, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "arm64-v8a", - /* enableLLVM */ false, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "arm64-v8a", - /* enableLLVM */ true, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "x86", - /* enableLLVM */ false, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "x86", - /* enableLLVM */ true, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "x86_64", - /* enableLLVM */ false, - /* expectedResult */ true, - }, - new object[] { - /* supportedAbis */ "x86_64", - /* enableLLVM */ true, - /* expectedResult */ true, - }, - }; - static object [] RuntimeChecks () => new object [] { new object[] { /* supportedAbi */ "armeabi-v7a", diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs index c4cfafd5a8e..8b0c406872c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs @@ -462,7 +462,7 @@ public void AppProjectTargetsDoNotBreak () foreach (var target in targets) { b.Output.AssertTargetIsSkipped (target); } - Assert.IsTrue (secondBuildTime < firstBuildTime, $"Second incremental build: '{secondBuildTime}' should be faster than clean build: '{firstBuildTime}'."); + Assert.IsTrue (thirdBuildTime < firstBuildTime, $"Third unchanged build: '{thirdBuildTime}' should be faster than clean build: '{firstBuildTime}'."); Assert.IsTrue (thirdBuildTime < secondBuildTime, $"Third unchanged build: '{thirdBuildTime}' should be faster than partially incremental second build: '{secondBuildTime}'."); } } From 12defcc0c2fbd3972b05a72efff913f56d953c44 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Mon, 14 Sep 2020 12:07:50 -0400 Subject: [PATCH 11/12] Update test to cover legacy '__ANDROID_$(ApiLevel)__' defines --- .../Xamarin.Android.Build.Tests/BuildTest.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 793b948360e..31b5ef6bb80 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -513,23 +513,27 @@ module Xamarin.Android.Tests } [Test] - public void DesignTimeBuildHasAndrodDefine () + public void DesignTimeBuildHasAndroidDefines () { - var proj = new XamarinAndroidApplicationProject () { - - }; + var proj = new XamarinAndroidApplicationProject (); + var didParse = int.TryParse (proj.TargetSdkVersion, out int apiLevel); + Assert.IsTrue (didParse, $"Unable to parse {proj.TargetSdkVersion} as an int."); + var androidDefines = new List (); + for (int i = 1; i <= apiLevel; ++i) { + androidDefines.Add ($"!__ANDROID_{i}__"); + } proj.Sources.Add (new BuildItem ("Compile", "IsAndroidDefined.cs") { - TextContent = () => @" + TextContent = () => $@" namespace Xamarin.Android.Tests -{ - public class Foo { - public void FooMethod () { -#if !__ANDROID__ || !__MOBILE__ +{{ + public class Foo {{ + public void FooMethod () {{ +#if !__ANDROID__ || !__MOBILE__ || {string.Join (" || ", androidDefines)} Compile Error please :) #endif - } - } -} + }} + }} +}} ", }); using (var b = CreateApkBuilder (Path.Combine ("temp", TestName ))) { From 18ef66517c4564c2de8f388fa14ab9a75fe31575 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Mon, 14 Sep 2020 13:19:22 -0400 Subject: [PATCH 12/12] Don't track standalone library rebuild timing --- .../Xamarin.Android.Build.Tests/IncrementalBuildTest.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs index 8b0c406872c..4d8a28816fa 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs @@ -402,6 +402,7 @@ public Class2 () //https://github.com/xamarin/xamarin-android/issues/2247 [Test] [Category ("SmokeTests")] + [NonParallelizable] // Do not run timing sensitive tests in parallel public void AppProjectTargetsDoNotBreak () { var targets = new List { @@ -496,7 +497,6 @@ public void LibraryProjectTargetsDoNotBreak () }; using (var b = CreateDllBuilder (Path.Combine ("temp", TestName))) { Assert.IsTrue (b.Build (proj), "first build should succeed"); - var firstBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped!"); } @@ -513,19 +513,15 @@ public void LibraryProjectTargetsDoNotBreak () //NOTE: second build, targets will run because inputs changed Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "second build should succeed"); - var secondBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsFalse (b.Output.IsTargetSkipped (target), $"`{target}` should *not* be skipped on second build!"); } //NOTE: third build, targets should certainly *not* run! there are no changes Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "third build should succeed"); - var thirdBuildTime = b.LastBuildTime; foreach (var target in targets) { Assert.IsTrue (b.Output.IsTargetSkipped (target), $"`{target}` should be skipped on third build!"); } - Assert.IsTrue (secondBuildTime < firstBuildTime, $"Second incremental build: '{secondBuildTime}' should be faster than clean build: '{firstBuildTime}'."); - Assert.IsTrue (thirdBuildTime < secondBuildTime, $"Third unchanged build: '{thirdBuildTime}' should be faster than partially incremental second build: '{secondBuildTime}'."); } }