diff --git a/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/StartAndroidEmulator.cs b/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/StartAndroidEmulator.cs index 4dd077bf49b..adb65136049 100644 --- a/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/StartAndroidEmulator.cs +++ b/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/StartAndroidEmulator.cs @@ -71,7 +71,7 @@ void Run (string emulator) var port = string.IsNullOrEmpty (Port) ? "" : $" -port {Port}"; var showWindow = ShowWindow ? "" : " -no-window"; - var arguments = $"{Arguments ?? string.Empty} -verbose -detect-image-hang -logcat-output \"{LogcatFile}\" -no-boot-anim -no-audio -no-snapshot -cache-size 512 -timezone \"Etc/UTC\" {showWindow}{port} -avd {ImageName}"; + var arguments = $"{Arguments ?? string.Empty} -verbose -detect-image-hang -logcat-output \"{LogcatFile}\" -no-boot-anim -no-audio -no-snapshot -cache-size 512 -change-locale en-US -timezone \"Etc/UTC\" {showWindow}{port} -avd {ImageName}"; Log.LogMessage (MessageImportance.Low, $"Tool {emulator} execution started with arguments: {arguments}"); var psi = new ProcessStartInfo () { FileName = emulator, diff --git a/build-tools/automation/azure-pipelines-nightly.yaml b/build-tools/automation/azure-pipelines-nightly.yaml index a1c876a8484..d5cb9529a88 100644 --- a/build-tools/automation/azure-pipelines-nightly.yaml +++ b/build-tools/automation/azure-pipelines-nightly.yaml @@ -171,4 +171,53 @@ stages: parameters: node_id: 4 + # Localization test jobs + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 1 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 2 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 3 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 4 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 5 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 6 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 7 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 8 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 9 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 10 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 11 + + - template: yaml-templates/run-localization-tests.yaml + parameters: + node_id: 12 + - template: yaml-templates/run-systemapp-tests.yaml diff --git a/build-tools/automation/yaml-templates/run-localization-tests.yaml b/build-tools/automation/yaml-templates/run-localization-tests.yaml new file mode 100644 index 00000000000..1ed205cf539 --- /dev/null +++ b/build-tools/automation/yaml-templates/run-localization-tests.yaml @@ -0,0 +1,57 @@ +# Runs Localization tests against an emulator running on macOS + +parameters: + node_id: 0 + +jobs: + - job: mac_localization_tests_${{ parameters.node_id }} + displayName: Localization Emulator Tests ${{ parameters.node_id }} + pool: + vmImage: $(HostedMacImage) + timeoutInMinutes: 180 + cancelTimeoutInMinutes: 5 + workspace: + clean: all + steps: + - template: setup-test-environment.yaml + + - template: run-xaprepare.yaml + parameters: + arguments: --s=EmulatorTestDependencies + + - task: DownloadPipelineArtifact@2 + inputs: + artifactName: $(TestAssembliesArtifactName) + downloadPath: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration) + + - task: MSBuild@1 + displayName: start emulator + inputs: + solution: tests/Mono.Android-Tests/Mono.Android-Tests.csproj + configuration: $(XA.Build.Configuration) + msbuildArguments: >- + /t:AcquireAndroidTarget /bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/start-emulator.binlog + + - template: run-nunit-tests.yaml + parameters: + testRunTitle: LocalizationTests On Device - macOS + testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/MSBuildDeviceIntegration/$(DotNetStableTargetFramework)/MSBuildDeviceIntegration.dll + useDotNet: true + dotNetTestExtraArgs: --filter "Name~CheckLocalizationIsCorrectNode${{ parameters.node_id }}" + testResultsFile: TestResult-LocalizationTests-Node${{ parameters.node_id }}-$(XA.Build.Configuration).xml + + - task: MSBuild@1 + displayName: shut down emulator + inputs: + solution: tests/Mono.Android-Tests/Mono.Android-Tests.csproj + configuration: $(XA.Build.Configuration) + msbuildArguments: >- + /t:AcquireAndroidTarget,ReleaseAndroidTarget + /bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/shutdown-emulator.binlog + condition: always() + + - template: upload-results.yaml + parameters: + artifactName: Test Results - TimeZoneInfo With Emulator - macOS - ${{ parameters.node_id }} + + - template: fail-on-issue.yaml diff --git a/build-tools/automation/yaml-templates/run-msbuild-device-tests.yaml b/build-tools/automation/yaml-templates/run-msbuild-device-tests.yaml index d44a9070f85..e5264ad1b1c 100644 --- a/build-tools/automation/yaml-templates/run-msbuild-device-tests.yaml +++ b/build-tools/automation/yaml-templates/run-msbuild-device-tests.yaml @@ -65,8 +65,8 @@ jobs: useDotNet: ${{ eq(parameters.target_framework, parameters.dotnet_targetframework) }} testRunTitle: MSBuildDeviceIntegration On Device - macOS-${{ parameters.node_id }} - ${{ parameters.job_suffix }} testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/MSBuildDeviceIntegration/${{ parameters.target_framework }}/MSBuildDeviceIntegration.dll - nunitConsoleExtraArgs: --where "cat == Node-${{ parameters.node_id }} && cat != SystemApplication && cat != TimeZoneInfo && cat != SmokeTests ${{ parameters.nunit_categories }}" - dotNetTestExtraArgs: --filter "TestCategory = Node-${{ parameters.node_id }} & TestCategory != TimeZoneInfo ${{ parameters.nunit_categories }}" + nunitConsoleExtraArgs: --where "cat == Node-${{ parameters.node_id }} && cat != SystemApplication && cat != TimeZoneInfo && cat != Localization && cat != SmokeTests ${{ parameters.nunit_categories }}" + dotNetTestExtraArgs: --filter "TestCategory = Node-${{ parameters.node_id }} & TestCategory != TimeZoneInfo & TestCategory != Localization ${{ parameters.nunit_categories }}" testResultsFile: TestResult-MSBuildDeviceIntegration-${{ parameters.job_name }}-$(XA.Build.Configuration).xml # Tests with no "Node" category. This should be empty, but just in case! Only run these tests on node 1 @@ -76,8 +76,8 @@ jobs: useDotNet: ${{ eq(parameters.target_framework, parameters.dotnet_targetframework) }} testRunTitle: MSBuildDeviceIntegration On Device - macOS-NoNode - ${{ parameters.job_suffix }} testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/MSBuildDeviceIntegration/${{ parameters.target_framework }}/MSBuildDeviceIntegration.dll - nunitConsoleExtraArgs: --where "cat != Node-1 && cat != Node-2 && cat != Node-3 && cat != Node-4 && cat != SystemApplication && cat != TimeZoneInfo && cat != SmokeTests ${{ parameters.nunit_categories }}" - dotNetTestExtraArgs: --filter "TestCategory != Node-1 & TestCategory != Node-2 & TestCategory != Node-3 & TestCategory != Node-4 & TestCategory != TimeZoneInfo ${{ parameters.nunit_categories }}" + nunitConsoleExtraArgs: --where "cat != Node-1 && cat != Node-2 && cat != Node-3 && cat != Node-4 && cat != SystemApplication && cat != TimeZoneInfo && cat != Localization && cat != SmokeTests ${{ parameters.nunit_categories }}" + dotNetTestExtraArgs: --filter "TestCategory != Node-1 & TestCategory != Node-2 & TestCategory != Node-3 & TestCategory != Node-4 & TestCategory != TimeZoneInfo & TestCategory != Localization ${{ parameters.nunit_categories }}" testResultsFile: TestResult-MSBuildDeviceIntegration-${{ parameters.job_name }}-NoNode-$(XA.Build.Configuration).xml - task: MSBuild@1 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 43189393291..4b4d6c88807 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 @@ -66,6 +66,7 @@ public void CheckDevice () if (!HasDevices) { // something went wrong with the emulator. // lets restart it. + TestContext.Out.WriteLine ($"{nameof(CheckDevice)} is restarting the emulator."); RestartDevice (Path.Combine (Root, "Emulator.csproj")); } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs index 3358f392432..8085e9b1131 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs @@ -27,6 +27,51 @@ static class InlineData "; + const string Designer = @" +using System; +using System.Reflection; + +namespace @projectName@ +{ + [System.CodeDom.Compiler.GeneratedCodeAttribute(""System.Resources.Tools.StronglyTypedResourceBuilder"", ""4.0.0.0"")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class @className@ { + + private static System.Resources.ResourceManager resourceMan; + + private static System.Globalization.CultureInfo resourceCulture; + + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(""Microsoft.Performance"", ""CA1811:AvoidUncalledPrivateCode"")] + internal @className@() { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { + get { + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager(""@projectName@.@className@"", typeof(@className@).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + @content@ + } +} +"; + public static string ResxWithContents (string contents) { return Resx.Replace ("", contents); @@ -40,5 +85,27 @@ public static void AddCultureResourcesToProject (IShortFormProject proj, string }); } } + + public static string DesignerWithContents (string projectName, string className, string[] dataNames) + { + var content = new StringBuilder (); + foreach (string data in dataNames) { + content.AppendFormat (@"internal static string {0} {{ + get {{ + return ResourceManager.GetString(""{0}"", resourceCulture); + }} + }}" + Environment.NewLine, data); + } + return Designer.Replace ("@className@", className) + .Replace ("@projectName@", projectName) + .Replace ("@content@", content.ToString ()); + } + + public static void AddCultureResourceDesignerToProject (IShortFormProject proj, string projectName, string className, params string[] dataNames) + { + proj.OtherBuildItems.Add (new BuildItem.Source ($"{className}.Designer.cs") { + TextContent = () => InlineData.DesignerWithContents (projectName, className, dataNames) + }); + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Forms/MainPage.xaml b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Forms/MainPage.xaml index 2a75ede1a6c..cfd86b482f7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Forms/MainPage.xaml +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Forms/MainPage.xaml @@ -3,7 +3,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="${ROOT_NAMESPACE}.MainPage"> -