diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index e76e9243d47..e817d25fc12 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -1103,7 +1103,7 @@ stages: condition: and(eq(dependencies.mac_build.result, 'Succeeded'), eq(variables['RunAllTests'], true)) jobs: - # Check - "Xamarin.Android (Test Integrated Regression - macOS)" + # Check - "Xamarin.Android (Regression Tests Mac-1)" - job: integrated_regression_mac_1 displayName: Mac-1 pool: @@ -1119,7 +1119,7 @@ stages: parameters: node_id: 1 - # Check - "Xamarin.Android (Test Integrated Regression - macOS)" + # Check - "Xamarin.Android (Regression Tests Mac-2)" - job: integrated_regression_mac_2 displayName: Mac-2 pool: @@ -1135,23 +1135,7 @@ stages: parameters: node_id: 2 - # Check - "Xamarin.Android (Test Integrated Regression - macOS)" - - job: integrated_regression_mac_3 - displayName: Mac-3 - pool: - name: VSEng-Xamarin-Mac-Devices - demands: - - android - timeoutInMinutes: 240 - cancelTimeoutInMinutes: 5 - workspace: - clean: all - steps: - - template: yaml-templates/run-integrated-regression-tests.yaml - parameters: - node_id: 3 - - # Check - "Xamarin.Android (Test Integrated Regression - Windows)" + # Check - "Xamarin.Android (Regression Tests Windows-1)" - job: integrated_regression_Win_1 displayName: Windows-1 pool: @@ -1173,7 +1157,7 @@ stages: - template: remove-visualstudio.yml@yaml - # Check - "Xamarin.Android (Test Integrated Regression - Windows)" + # Check - "Xamarin.Android (Regression Tests Windows-2)" - job: integrated_regression_Win_2 displayName: Windows-2 pool: @@ -1195,28 +1179,6 @@ stages: - template: remove-visualstudio.yml@yaml - # Check - "Xamarin.Android (Test Integrated Regression - Windows)" - - job: integrated_regression_Win_3 - displayName: Windows-3 - 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 - parameters: - node_id: 3 - - - 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 index b9b46ff7b86..e997250bf9f 100644 --- a/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml +++ b/build-tools/automation/yaml-templates/run-integrated-regression-tests.yaml @@ -90,51 +90,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: Smoke Tests - nunitConsoleExtraArgs: --where "cat == RegressionTests" - - - template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Installer Tests - nunitConsoleExtraArgs: --where "cat == InstallationTests" - - - template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Fast Deploy Tests - nunitConsoleExtraArgs: --where "cat == FastDevTests" - condition: and(succeeded(), eq(variables['XA.Commercial.Build'], 'true')) - - - template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Debug Tests - nunitConsoleExtraArgs: --where "cat == DebuggerTests" - condition: and(succeeded(), eq(variables['XA.Commercial.Build'], 'true')) - - - template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Linker Tests - nunitConsoleExtraArgs: --where "cat == LinkerTests" - - - template: run-nunit-tests.yaml - parameters: - nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe - testAssembly: $(System.DefaultWorkingDirectory)/XQA.Android/XQA.Android.dll - testRunTitle: Wearable Tests - nunitConsoleExtraArgs: --where "cat == Wearable" - -- ${{ if eq(parameters.node_id, 2) }}: - template: run-nunit-tests.yaml parameters: nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe @@ -149,7 +104,7 @@ steps: testRunTitle: AOT Tests nunitConsoleExtraArgs: --where "cat == AotSupport" -- ${{ if eq(parameters.node_id, 3) }}: +- ${{ if eq(parameters.node_id, 2) }}: - template: run-nunit-tests.yaml parameters: nunitConsole: $(System.DefaultWorkingDirectory)/NUnit.ConsoleRunner/tools/nunit3-console.exe diff --git a/src/Mono.Android/Test/Mono.Android-Test.Shared.projitems b/src/Mono.Android/Test/Mono.Android-Test.Shared.projitems index 9ee41241229..8904936743c 100644 --- a/src/Mono.Android/Test/Mono.Android-Test.Shared.projitems +++ b/src/Mono.Android/Test/Mono.Android-Test.Shared.projitems @@ -42,6 +42,7 @@ + diff --git a/src/Mono.Android/Test/Mono.Android-Tests.csproj b/src/Mono.Android/Test/Mono.Android-Tests.csproj index fa55152cccc..c507c72a00c 100644 --- a/src/Mono.Android/Test/Mono.Android-Tests.csproj +++ b/src/Mono.Android/Test/Mono.Android-Tests.csproj @@ -18,6 +18,7 @@ Properties\AndroidManifest.xml armeabi-v7a;x86 False + All true ..\..\..\product.snk v11.0 diff --git a/src/Mono.Android/Test/System.Text/EncodingTests.cs b/src/Mono.Android/Test/System.Text/EncodingTests.cs new file mode 100644 index 00000000000..fd3da6aaea8 --- /dev/null +++ b/src/Mono.Android/Test/System.Text/EncodingTests.cs @@ -0,0 +1,22 @@ +using System; +using System.Text; + +using NUnit.Framework; + +namespace Xamarin.Android.RuntimeTests +{ + [TestFixture] + public class EncodingTests + { + EncodingInfo[] EncodingTestData = Encoding.GetEncodings (); + + [Test, TestCaseSource (nameof (EncodingTestData))] + public void GetAllAvailableEncodings (EncodingInfo info) + { + // Requires All or can throw: + // System.NotSupportedException : Encoding 37 data could not be found. Make sure you have correct international codeset assembly installed and enabled. + Encoding enc = info.GetEncoding (); + Assert.IsNotNull (enc.EncodingName, $"Failed to get Encoding from '{info.DisplayName}'."); + } + } +} 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 1a4eede245b..448a4009306 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 @@ -399,7 +399,11 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true, proj.SetProperty (proj.ReleaseProperties, "AndroidSigningKeyPass", Uri.EscapeDataString (pass)); proj.SetProperty (proj.ReleaseProperties, "AndroidSigningStorePass", Uri.EscapeDataString (pass)); proj.SetProperty (proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk); - proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86"); + if (perAbiApk) { + proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "arm64-v8a", "x86_64"); + } else { + proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86"); + } using (var b = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name))) { var bin = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath); Assert.IsTrue (b.Build (proj), "First build failed"); @@ -417,6 +421,17 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true, } } + // Make sure the APKs have unique version codes + if (perAbiApk) { + int armManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "armeabi-v7a", "AndroidManifest.xml")); + int x86ManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "x86", "AndroidManifest.xml")); + int arm64ManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "arm64-v8a", "AndroidManifest.xml")); + int x86_64ManifestCode = GetVersionCodeFromIntermediateManifest (Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "x86_64", "AndroidManifest.xml")); + var versionList = new List { armManifestCode, x86ManifestCode, arm64ManifestCode, x86_64ManifestCode }; + Assert.True (versionList.Distinct ().Count () == versionList.Count, + $"APK version codes were not unique - armeabi-v7a: {armManifestCode}, x86: {x86ManifestCode}, arm64-v8a: {arm64ManifestCode}, x86_64: {x86_64ManifestCode}"); + } + var item = proj.AndroidResources.First (x => x.Include () == "Resources\\values\\Strings.xml"); item.TextContent = () => proj.StringsXml.Replace ("${PROJECT_NAME}", "Foo"); item.Timestamp = null; @@ -435,6 +450,18 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true, } } } + + int GetVersionCodeFromIntermediateManifest (string manifestFilePath) + { + var doc = XDocument.Load (manifestFilePath); + var versionCode = doc.Descendants () + .Where (e => e.Name == "manifest") + .Select (m => m.Attribute ("{http://schemas.android.com/apk/res/android}versionCode")).FirstOrDefault (); + + if (!int.TryParse (versionCode?.Value, out int parsedCode)) + Assert.Fail ($"Unable to parse 'versionCode' value from manifest content: {File.ReadAllText (manifestFilePath)}."); + return parsedCode; + } } [Test] diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs index 0ee9968fc1a..80489d73508 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs @@ -241,5 +241,52 @@ public void LinkDescription () } } } + + [Test] + public void LinkWithNullAttribute () + { + var proj = new XamarinAndroidApplicationProject { + IsRelease = true, + OtherBuildItems = { + new BuildItem ("Compile", "NullAttribute.cs") { TextContent = () => @" +using System; +using Android.Content; +using Android.Widget; +namespace UnnamedProject { + public class MyAttribute : Attribute + { + Type[] types; + + public Type[] Types { + get { return types; } + } + + public MyAttribute (Type[] ta) + { + types = ta; + } + } + + [MyAttribute (null)] + public class AttributedButtonStub : Button + { + public AttributedButtonStub (Context context) : base (context) + { + } + } +}" + }, + } + }; + + proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}", +$@" var myButton = new AttributedButtonStub (this); + myButton.Text = ""Bug #35710""; +"); + + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Building a project with a null attribute value should have succeded."); + } + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/DeviceTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/DeviceTest.cs index 4564f0cd93a..5dda6a31e8a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/DeviceTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/DeviceTest.cs @@ -29,19 +29,14 @@ protected override void CleanupTest () string deviceLog = Path.Combine (outputDir, "logcat-failed.log"); string remote = "/data/local/tmp/screenshot.png"; RunAdbCommand ($"shell screencap {remote}"); + RunAdbCommand ($"logcat -d > \"{deviceLog}\""); RunAdbCommand ($"pull {remote} \"{local}\""); RunAdbCommand ($"shell rm {remote}"); - RunAdbCommand ($"logcat -d > {deviceLog}"); if (File.Exists (local)) { TestContext.AddTestAttachment (local); } else { TestContext.WriteLine ($"{local} did not exist!"); } - if (File.Exists (deviceLog)) { - TestContext.AddTestAttachment (deviceLog); - } else { - TestContext.WriteLine ($"{deviceLog} did not exist!"); - } } base.CleanupTest (); diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs index d085eb9681e..1422122e655 100644 --- a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using NUnit.Framework; using Xamarin.ProjectTools; using System.IO; @@ -25,6 +25,31 @@ static byte [] GetKeystore () } } + string[] GetOverrideDirectoryPaths (string packageName) + { + return new string [] { + $"/data/data/{packageName}/files/.__override__", + $"/storage/emulated/0/Android/data/{packageName}/files/.__override__", + $"/mnt/shell/emulated/0/Android/data/{packageName}/files/.__override__", + $"/storage/sdcard/Android/data/{packageName}/files/.__override__", + }; + } + + string GetContentFromAllOverrideDirectories (string packageName, bool useRunAsCommand = true) + { + var adbShellArgs = $"shell ls"; + if (useRunAsCommand) + adbShellArgs = $"shell run-as {packageName} ls"; + + var directorylist = string.Empty; + foreach (var dir in GetOverrideDirectoryPaths (packageName)) { + var listing = RunAdbCommand ($"{adbShellArgs} {dir}"); + if (!listing.Contains ("No such file or directory")) + directorylist += $"{listing} "; + } + return directorylist; + } + [Test] public void ReInstallIfUserUninstalled ([Values (false, true)] bool isRelease) { @@ -64,6 +89,8 @@ public void InstallAndUnInstall ([Values (false, true)] bool isRelease) IsRelease = isRelease, }; if (isRelease) { + // Set debuggable=true to allow run-as command usage with a release build + proj.AndroidManifest = proj.AndroidManifest.Replace (" InlineData.ResxWithContents ("Cancel") + }, + new BuildItem ("EmbeddedResource", "Foo.es.resx") { + TextContent = () => InlineData.ResxWithContents ("Cancelar") + } + } + }; + + using (var builder = CreateApkBuilder ()) { + Assert.IsTrue (builder.Install (proj), "Install should have succeeded."); + var projectOutputPath = Path.Combine (Root, builder.ProjectDirectory, proj.OutputPath); + var resourceFilesFromDisk = Directory.EnumerateFiles (projectOutputPath, "*.resources.dll", SearchOption.AllDirectories) + .Select (r => r = r.Replace (projectOutputPath, string.Empty).Replace ("\\", "/")); + + var overrideContents = string.Empty; + foreach (var dir in GetOverrideDirectoryPaths (proj.PackageName)) { + overrideContents += RunAdbCommand ($"shell find {dir}"); + } + builder.Uninstall (proj); + Assert.IsTrue (resourceFilesFromDisk.Any (), $"Unable to find any localized assemblies in {resourceFilesFromDisk}"); + foreach (var res in resourceFilesFromDisk) { + StringAssert.Contains (res, overrideContents, $"{res} did not exist in the .__override__ directory.\nFound:{overrideContents}"); + } + + } + } } } diff --git a/tests/Runtime-AppBundle/Mono.Android-TestsAppBundle.csproj b/tests/Runtime-AppBundle/Mono.Android-TestsAppBundle.csproj index 97e60b7325e..8bf77175a1c 100644 --- a/tests/Runtime-AppBundle/Mono.Android-TestsAppBundle.csproj +++ b/tests/Runtime-AppBundle/Mono.Android-TestsAppBundle.csproj @@ -18,6 +18,7 @@ Properties\AndroidManifest.xml armeabi-v7a;x86 False + All d8 aab <_MonoAndroidTest>..\..\src\Mono.Android\Test\ diff --git a/tests/Runtime-MultiDex/Mono.Android-TestsMultiDex.csproj b/tests/Runtime-MultiDex/Mono.Android-TestsMultiDex.csproj index 69b981d2a58..75a4c09266f 100644 --- a/tests/Runtime-MultiDex/Mono.Android-TestsMultiDex.csproj +++ b/tests/Runtime-MultiDex/Mono.Android-TestsMultiDex.csproj @@ -18,6 +18,7 @@ Properties\AndroidManifest.xml armeabi-v7a;x86 False + All true d8 true