diff --git a/Configuration.props b/Configuration.props
index 4f97dd67381..e4ff79d9bf4 100644
--- a/Configuration.props
+++ b/Configuration.props
@@ -184,8 +184,9 @@
5.0
7583922_latest
$(AndroidSdkFullPath)\cmdline-tools\$(CommandLineToolsFolder)\bin
- 7033400
- 30.3.5
+
+ 8129060
+ 31.3.1
$(AndroidSdkFullPath)\emulator
emulator
$(AndroidNdkDirectory)\ndk-build
@@ -242,12 +243,12 @@
-
+
True
-
+
True
diff --git a/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/CreateAndroidEmulator.cs b/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/CreateAndroidEmulator.cs
index 3386ff2d4f0..8d8d1754a22 100644
--- a/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/CreateAndroidEmulator.cs
+++ b/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/CreateAndroidEmulator.cs
@@ -24,6 +24,7 @@ public class CreateAndroidEmulator : ToolTask
public string ImageName {get; set;} = "XamarinAndroidTestRunner64";
public string DeviceName {get; set;} = "pixel_4";
+ public string ImageType {get; set;} = "default";
public string DataPartitionSizeMB {get; set;} = "2048";
public string RamSizeMB {get; set;} = "2048";
@@ -32,6 +33,9 @@ public class CreateAndroidEmulator : ToolTask
public override bool Execute ()
{
+ if (string.IsNullOrEmpty (ToolExe))
+ ToolExe = "avdmanager";
+
var dirs = string.IsNullOrEmpty (ToolPath)
? null
: new [] { ToolPath };
@@ -43,7 +47,7 @@ public override bool Execute ()
ToolExe = filename;
if (string.IsNullOrEmpty (TargetId) && !string.IsNullOrEmpty (SdkVersion)) {
- TargetId = "system-images;android-" + SdkVersion + ";default;" + AndroidAbi;
+ TargetId = $"system-images;android-{SdkVersion};{ImageType};{AndroidAbi}";
}
var env = new List ();
diff --git a/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/RunInstrumentationTests.cs b/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/RunInstrumentationTests.cs
index 4345b514a18..eb03232b392 100644
--- a/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/RunInstrumentationTests.cs
+++ b/build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/RunInstrumentationTests.cs
@@ -19,7 +19,8 @@ public class RunInstrumentationTests : Adb
const int StateGetLogcat = 1;
const int StateClearLogcat = 2;
const int StatePullFiles = 3;
- const int MaxState = StatePullFiles;
+ const int StateRunAsCatFiles = 4;
+ const int MaxState = StateRunAsCatFiles;
public string TestFixture { get; set; }
@@ -41,6 +42,8 @@ public class RunInstrumentationTests : Adb
public string LogLevel { get; set; }
+ public int ApiLevel { get; set; }
+
int currentState = -1;
int instrumentationExitCode = 99;
string targetTestResultsPath;
@@ -98,10 +101,17 @@ public override bool Execute ()
ArgumentsString = $"{AdbTarget} {AdbOptions} logcat -c",
IgnoreExitCode = true,
},
-
new CommandInfo {
ArgumentsGenerator = () => $"{AdbTarget} {AdbOptions} pull \"{targetTestResultsPath}\" \"{NUnit2TestResultsFile}\"",
- ShouldRun = () => !String.IsNullOrEmpty (targetTestResultsPath)
+ ShouldRun = () => !String.IsNullOrEmpty (targetTestResultsPath) && ApiLevel != 30,
+ IgnoreExitCode = true,
+ },
+ new CommandInfo {
+ ArgumentsGenerator = () => $"{AdbTarget} {AdbOptions} shell run-as {PackageName} cat \"{targetTestResultsPath}\"",
+ ShouldRun = () => !String.IsNullOrEmpty (targetTestResultsPath) && ApiLevel == 30,
+ StdoutFilePath = NUnit2TestResultsFile,
+ StdoutAppend = false,
+ IgnoreExitCode = true,
},
};
}
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 18fd79b80f7..4dd077bf49b 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
@@ -34,6 +34,7 @@ public class StartAndroidEmulator : Task
public string ToolPath {get; set;}
public string ToolExe {get; set;}
public string LogcatFile {get; set;}
+ public bool ShowWindow {get; set;} = true;
public override bool Execute ()
{
@@ -69,7 +70,8 @@ void Run (string emulator)
return;
var port = string.IsNullOrEmpty (Port) ? "" : $" -port {Port}";
- var arguments = $"{Arguments ?? string.Empty} -verbose -logcat-output \"{LogcatFile}\" -no-boot-anim -no-audio -no-snapshot -cache-size 512 -timezone \"Etc/UTC\" -avd {ImageName}{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}";
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 7b6a3e3f264..1b7eb512983 100644
--- a/build-tools/automation/azure-pipelines-nightly.yaml
+++ b/build-tools/automation/azure-pipelines-nightly.yaml
@@ -74,18 +74,31 @@ stages:
Android21-x86:
avdApiLevel: 21
avdAbi: x86
+ avdType: default
Android23-x86:
avdApiLevel: 23
avdAbi: x86
+ avdType: default
Android24-x86:
avdApiLevel: 24
avdAbi: x86
+ avdType: default
Android26-x86_64:
avdApiLevel: 26
avdAbi: x86_64
+ avdType: default
Android28-x86_64:
avdApiLevel: 28
avdAbi: x86_64
+ avdType: default
+ Android30-x86_64:
+ avdApiLevel: 30
+ avdAbi: x86_64
+ avdType: default
+ Android31-x86_64:
+ avdApiLevel: 31
+ avdAbi: x86_64
+ avdType: default
pool:
vmImage: $(HostedMacImage)
workspace:
@@ -113,15 +126,15 @@ stages:
inputs:
solution: tests/Mono.Android-Tests/Mono.Android-Tests.csproj
configuration: $(XA.Build.Configuration)
- msbuildArguments: /t:InstallAvdImage;AcquireAndroidTarget /p:TestAvdApiLevel=$(avdApiLevel) /p:TestAvdAbi=$(avdAbi) /bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/install-emulator-$(avdApiLevel).binlog
+ msbuildArguments: /t:InstallAvdImage;AcquireAndroidTarget /p:TestAvdApiLevel=$(avdApiLevel) /p:TestAvdAbi=$(avdAbi) /p:TestAvdType=$(avdType) /bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/install-emulator-$(avdApiLevel).binlog
- template: yaml-templates/apk-instrumentation.yaml
parameters:
configuration: $(XA.Build.Configuration)
- testName: Mono.Android_Tests-$(avdApiLevel)-$(avdAbi)
+ testName: Mono.Android_Tests-$(avdApiLevel)-$(avdAbi)-$(avdType)
project: tests/Mono.Android-Tests/Mono.Android-Tests.csproj
testResultsFiles: TestResult-Mono.Android_Tests-$(XA.Build.Configuration).xml
- extraBuildArgs: /p:TestAvdApiLevel=$(avdApiLevel) /p:TestAvdAbi=$(avdAbi)
+ extraBuildArgs: /p:TestAvdApiLevel=$(avdApiLevel) /p:TestAvdAbi=$(avdAbi) /p:TestAvdType=$(avdType)
artifactSource: bin/Test$(XA.Build.Configuration)/Mono.Android_Tests-Signed.apk
artifactFolder: Default
@@ -130,13 +143,13 @@ stages:
inputs:
solution: tests/Mono.Android-Tests/Mono.Android-Tests.csproj
configuration: $(XA.Build.Configuration)
- msbuildArguments: /t:AcquireAndroidTarget,ReleaseAndroidTarget /p:TestAvdApiLevel=$(avdApiLevel) /p:TestAvdAbi=$(avdAbi) /bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/shutdown-emulator.binlog
+ msbuildArguments: /t:AcquireAndroidTarget,ReleaseAndroidTarget /p:TestAvdApiLevel=$(avdApiLevel) /p:TestAvdAbi=$(avdAbi) /p:TestAvdType=$(avdType) /bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/shutdown-emulator.binlog
condition: always()
- template: yaml-templates/upload-results.yaml
parameters:
configuration: $(XA.Build.Configuration)
- artifactName: Test Results - Emulator $(avdApiLevel)-$(avdAbi) - macOS
+ artifactName: Test Results - Emulator $(avdApiLevel)-$(avdAbi)-$(avdType) - macOS
- template: yaml-templates/fail-on-issue.yaml
diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml
index 5afdc1047b9..ab2368dd5f8 100644
--- a/build-tools/automation/azure-pipelines.yaml
+++ b/build-tools/automation/azure-pipelines.yaml
@@ -996,6 +996,7 @@ stages:
node_id: 1
job_name: mac_msbuilddevice_tests_1
job_suffix: Legacy
+ nunit_categories: '&& cat != Debugger'
provisionatorChannel: ${{ parameters.provisionatorChannel }}
- template: yaml-templates/run-msbuild-device-tests.yaml
@@ -1003,6 +1004,7 @@ stages:
node_id: 2
job_name: mac_msbuilddevice_tests_2
job_suffix: Legacy
+ nunit_categories: '&& cat != Debugger'
provisionatorChannel: ${{ parameters.provisionatorChannel }}
- template: yaml-templates/run-msbuild-device-tests.yaml
@@ -1010,6 +1012,16 @@ stages:
node_id: 3
job_name: mac_msbuilddevice_tests_3
job_suffix: Legacy
+ nunit_categories: '&& cat != Debugger'
+ provisionatorChannel: ${{ parameters.provisionatorChannel }}
+
+ - template: yaml-templates/run-msbuild-device-tests.yaml
+ parameters:
+ node_id: 4
+ job_name: mac_msbuilddevice_tests_with_debugger
+ job_suffix: Legacy
+ jdkTestFolder: $(XA.Jdk11.Folder)
+ nunit_categories: '&& cat == Debugger'
provisionatorChannel: ${{ parameters.provisionatorChannel }}
# Check - "Xamarin.Android (MSBuild Emulator Tests macOS - One .NET)"
@@ -1040,6 +1052,15 @@ stages:
target_framework: 'net6.0'
provisionatorChannel: ${{ parameters.provisionatorChannel }}
+ - template: yaml-templates/run-msbuild-device-tests.yaml
+ parameters:
+ node_id: 4
+ job_name: mac_dotnetdevice_tests_4
+ job_suffix: One .NET
+ nunit_categories: $(DotNetNUnitCategories)
+ target_framework: 'net6.0'
+ provisionatorChannel: ${{ parameters.provisionatorChannel }}
+
- stage: designer_tests
displayName: Designer Tests
dependsOn: mac_build
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 05ed310672c..5ad51b43315 100644
--- a/build-tools/automation/yaml-templates/run-msbuild-device-tests.yaml
+++ b/build-tools/automation/yaml-templates/run-msbuild-device-tests.yaml
@@ -73,8 +73,8 @@ jobs:
useDotNet: ${{ eq(parameters.target_framework, 'net6.0') }}
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 != SystemApplication && cat != TimeZoneInfo && cat != SmokeTests ${{ parameters.nunit_categories }}"
- dotNetTestExtraArgs: --filter "TestCategory != Node-1 & TestCategory != Node-2 & TestCategory != Node-3 & TestCategory != TimeZoneInfo ${{ parameters.nunit_categories }}"
+ 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 }}"
testResultsFile: TestResult-MSBuildDeviceIntegration-${{ parameters.job_name }}-NoNode-$(XA.Build.Configuration).xml
- task: MSBuild@1
diff --git a/build-tools/check-boot-times/Program.cs b/build-tools/check-boot-times/Program.cs
index f274c87c2f3..85789c408ac 100644
--- a/build-tools/check-boot-times/Program.cs
+++ b/build-tools/check-boot-times/Program.cs
@@ -130,9 +130,10 @@ static async Task GetBootTime (bool coldBoot)
{
var times = new List ();
int errors = 0;
+ var timeoutInMS = (int) TimeSpan.FromMinutes (15).TotalMilliseconds;
Stopwatch sw = new Stopwatch ();
- var token = coldBoot ? "emulator: INFO: boot time" : "onGuestSendCommand";
+ var token = coldBoot ? "boot completed" : "onGuestSendCommand";
for (int i = 0; i < executionTimes; i++) {
await CloseEmulator ();
@@ -162,7 +163,7 @@ bool validation (string data, ManualResetEvent mre)
bool hasTimedOut = false;
sw.Reset ();
sw.Start ();
- if (!await RunProcess (emulatorPath, $"-avd {deviceName} {bootOptions} -verbose", 300000, validation, async () => {
+ if (!await RunProcess (emulatorPath, $"-avd {deviceName} {bootOptions} -verbose -detect-image-hang", timeoutInMS, validation, async () => {
hasTimedOut = true;
await ForceKillEmulator ();
})) {
diff --git a/build-tools/scripts/TestApks.targets b/build-tools/scripts/TestApks.targets
index 42b846c8286..1b080efabef 100644
--- a/build-tools/scripts/TestApks.targets
+++ b/build-tools/scripts/TestApks.targets
@@ -19,11 +19,14 @@
29
x86_64
- system-images;android-$(TestAvdApiLevel);default;$(TestAvdAbi)
+ default
+ system-images;android-$(TestAvdApiLevel);$(TestAvdType);$(TestAvdAbi)
XamarinAndroidTestRunner$(TestAvdApiLevel)-$(TestAvdAbi)
<_AdbEmulatorPort>5570
+ <_AdbEmulatorShowWindow Condition=" '$(RunningOnCI)' == 'True' And '$(_AdbEmulatorShowWindow)' == '' ">False
+ <_AdbEmulatorShowWindow Condition=" '$(_AdbEmulatorShowWindow)' == '' ">True
<_ApkSizesReferenceDirectory>$(MSBuildThisFileDirectory)..\..\tests\apk-sizes-reference
- 5
+ 10
$([MSBuild]::Multiply($(AvdLaunchTimeoutMinutes), 60))
$([MSBuild]::Multiply($(AvdLaunchTimeoutSeconds), 1000))
<_LogcatFilenameBase>$(MSBuildThisFileDirectory)..\..\bin\Test$(Configuration)\logcat-$(Configuration)$(TestsFlavor)
@@ -58,6 +61,7 @@
SdkVersion="$(TestAvdApiLevel)"
TargetId="$(SdkManagerImageName)"
ImageName="$(TestAvdName)"
+ ImageType="$(TestAvdType)"
ToolExe="$(AvdManagerToolExe)"
ToolPath="$(CommandLineToolsBinPath)"
RamSizeMB="3072"
@@ -71,6 +75,7 @@
ImageName="$(TestAvdName)"
LogcatFile="$(_LogcatFilenameBase)-full.txt"
Port="$(_AdbEmulatorPort)"
+ ShowWindow="$(_AdbEmulatorShowWindow)"
ToolExe="$(EmulatorToolExe)"
ToolPath="$(EmulatorToolPath)">
@@ -83,7 +88,7 @@
Arguments="$(_AdbTarget) wait-for-device"
ToolExe="$(AdbToolExe)"
ToolPath="$(AdbToolPath)"
- Timeout="120000"
+ Timeout="$(AvdLaunchTimeoutMS)"
WriteOutputAsMessage="True"
/>
();
foreach (var fileMatch in testConfigFiles) {
- Utilities.CopyFilesSimple (Directory.GetFiles (testConfigDir, fileMatch), destinationRoot, false);
+ // Handle files which might appear in multiple filters
+ // eg logcat-Relase-full.log will appear in both logcat* AND *log
+ foreach (var file in Directory.GetFiles (testConfigDir, fileMatch)) {
+ if (matchedFiles.Contains (file))
+ continue;
+ matchedFiles.Add (file);
+ }
}
+ Utilities.CopyFilesSimple (matchedFiles, destinationRoot, false);
}
var testConfigCompatDir = Path.Combine (testConfigDir, "compatibility");
diff --git a/samples/VSAndroidApp/Properties/AndroidManifest.xml b/samples/VSAndroidApp/Properties/AndroidManifest.xml
index 64fca08fbf8..c48b180aa79 100644
--- a/samples/VSAndroidApp/Properties/AndroidManifest.xml
+++ b/samples/VSAndroidApp/Properties/AndroidManifest.xml
@@ -1,9 +1,9 @@
-
-
+
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 fb14f67d0c3..43189393291 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
@@ -52,6 +52,14 @@ public void DeviceSetup ()
CreateGuestUser (GuestUserName);
}
+ [OneTimeTearDown]
+ public void DeviceTearDown ()
+ {
+ // make sure we are not on a guest user anymore.
+ SwitchUser ();
+ DeleteGuestUser(GuestUserName);
+ }
+
[SetUp]
public void CheckDevice ()
{
@@ -71,6 +79,7 @@ protected override void CleanupTest ()
string local = Path.Combine (outputDir, "screenshot.png");
string deviceLog = Path.Combine (outputDir, "logcat-failed.log");
string remote = "/data/local/tmp/screenshot.png";
+ string localUi = Path.Combine (outputDir, "ui.xml");
RunAdbCommand ($"shell screencap {remote}");
var output = RunAdbCommand ($"logcat -d");
File.WriteAllText (deviceLog, output);
@@ -81,6 +90,13 @@ protected override void CleanupTest ()
} else {
TestContext.WriteLine ($"{local} did not exist!");
}
+ var ui = GetUI (timeoutInSeconds: 0);
+ ui.Save (localUi);
+ if (File.Exists (localUi)) {
+ TestContext.AddTestAttachment (localUi);
+ } else {
+ TestContext.WriteLine ($"{localUi} did not exist!");
+ }
}
ClearAdbLogcat ();
@@ -183,7 +199,7 @@ protected static bool MonitorAdbLogcat (Func action, string logcat
}
}
- protected static bool WaitForDebuggerToStart (string logcatFilePath, int timeout = 60)
+ protected static bool WaitForDebuggerToStart (string logcatFilePath, int timeout = 120)
{
bool result = MonitorAdbLogcat ((line) => {
return line.IndexOf ("Trying to initialize the debugger with options:", StringComparison.OrdinalIgnoreCase) > 0;
@@ -191,7 +207,7 @@ protected static bool WaitForDebuggerToStart (string logcatFilePath, int timeout
return result;
}
- static Regex regex = new Regex (@"\s*(\++)(?\d)s(?\d+)ms", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+ static Regex regex = new Regex (@"\s*(\++)(?\d+)s(?\d+)ms", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
protected static bool WaitForPermissionActivity (string logcatFilePath, int timeout = 5)
{
@@ -203,6 +219,12 @@ protected static bool WaitForPermissionActivity (string logcatFilePath, int time
return result;
}
+ protected static void ClearBlockingDialogs ()
+ {
+ ClickButton ("", "android:id/aerr_wait", "Wait");
+ WaitFor ((int)TimeSpan.FromSeconds (2).TotalMilliseconds);
+ }
+
protected static bool WaitForAppBuiltForOlderAndroidWarning (string packageName, string logcatFilePath, int timeout = 5)
{
bool result = MonitorAdbLogcat ((line) => {
@@ -213,12 +235,12 @@ protected static bool WaitForAppBuiltForOlderAndroidWarning (string packageName,
return result;
}
- protected static bool WaitForActivityToStart (string activityNamespace, string activityName, string logcatFilePath, int timeout = 60)
+ protected static bool WaitForActivityToStart (string activityNamespace, string activityName, string logcatFilePath, int timeout = 120)
{
return WaitForActivityToStart (activityNamespace, activityName, logcatFilePath, out TimeSpan time, timeout);
}
- protected static bool WaitForActivityToStart (string activityNamespace, string activityName, string logcatFilePath, out TimeSpan startupTime, int timeout = 60)
+ protected static bool WaitForActivityToStart (string activityNamespace, string activityName, string logcatFilePath, out TimeSpan startupTime, int timeout = 120)
{
startupTime = TimeSpan.Zero;
string capturedLine = string.Empty;
@@ -235,12 +257,16 @@ protected static bool WaitForActivityToStart (string activityNamespace, string a
return result;
}
- protected static XDocument GetUI ()
+ protected static XDocument GetUI (int timeoutInSeconds = 120)
{
var ui = RunAdbCommand ("exec-out uiautomator dump /dev/tty");
+ int time = 0;
while (ui.Contains ("ERROR:")) {
ui = RunAdbCommand ("exec-out uiautomator dump /dev/tty");
WaitFor (1);
+ time += 1;
+ if (time * 1000 > timeoutInSeconds)
+ break;
}
ui = ui.Replace ("UI hierchary dumped to: /dev/tty", string.Empty).Trim ();
try {
@@ -250,18 +276,17 @@ protected static XDocument GetUI ()
}
}
- protected static (int x, int y, int w, int h) GetControlBounds (string packageName, string uiElement, string text)
+ protected static (int x, int y, int w, int h)? GetControlBounds (string packageName, string uiElement, string text, int timeoutInSeconds = 120)
{
var regex = new Regex (@"[(0-9)]\d*", RegexOptions.Compiled);
- var result = (x: 0, y: 0, w: 0, h: 0);
- var uiDoc = GetUI ();
+ var uiDoc = GetUI (timeoutInSeconds);
var node = uiDoc.XPathSelectElement ($"//node[contains(@resource-id,'{uiElement}')]");
if (node == null)
node = uiDoc.XPathSelectElement ($"//node[contains(@content-desc,'{uiElement}')]");
if (node == null)
node = uiDoc.XPathSelectElement ($"//node[contains(@text,'{text}')]");
if (node == null)
- return result;
+ return null;
var bounds = node.Attribute ("bounds");
var matches = regex.Matches (bounds.Value);
int.TryParse (matches [0].Value, out int x);
@@ -271,10 +296,13 @@ protected static (int x, int y, int w, int h) GetControlBounds (string packageNa
return (x: x, y: y, w: w, h: h);
}
- protected static void ClickButton (string packageName, string buttonName, string buttonText)
+ protected static bool ClickButton (string packageName, string buttonName, string buttonText, int timeoutInSeconds = 30)
{
- var bounds = GetControlBounds (packageName, buttonName, buttonText);
- RunAdbInput ("input tap", bounds.x + ((bounds.w - bounds.x) / 2), bounds.y + ((bounds.h - bounds.y) / 2));
+ var bounds = GetControlBounds (packageName, buttonName, buttonText, timeoutInSeconds);
+ if (!bounds.HasValue)
+ return false;
+ RunAdbInput ("input tap", bounds.Value.x + ((bounds.Value.w - bounds.Value.x) / 2), bounds.Value.y + ((bounds.Value.h - bounds.Value.y) / 2));
+ return true;
}
///
@@ -313,7 +341,7 @@ protected static string [] GetOverrideDirectoryPaths (string packageName)
protected static void CreateGuestUser (string username)
{
- if (GetUserId (username) != -1)
+ if (GetUserId (username) == -1)
RunAdbCommand ($"shell pm create-user --guest {username}");
}
@@ -327,7 +355,9 @@ protected static void DeleteGuestUser (string username)
protected static int GetUserId (string username)
{
string output = RunAdbCommand ($"shell pm list users");
- Regex regex = new Regex (@"UserInfo{(?\d+):" + username, RegexOptions.Compiled);
+ if (string.IsNullOrEmpty (username))
+ username = "Owner";
+ Regex regex = new Regex ($@"UserInfo{{(?\d+):{username}", RegexOptions.Compiled);
Console.WriteLine (output);
var match = regex.Match (output);
if (match.Success) {
@@ -336,7 +366,7 @@ protected static int GetUserId (string username)
return -1;
}
- protected static bool SwitchUser (string username)
+ protected static bool SwitchUser (string username = "")
{
int userId = GetUserId (username);
if (userId == -1)
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
index 1d90657fd1a..22d1f013e52 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
@@ -5,37 +5,37 @@
"Size": 3032
},
"assemblies/Java.Interop.dll": {
- "Size": 54984
+ "Size": 55094
},
"assemblies/Mono.Android.dll": {
- "Size": 87771
+ "Size": 87709
},
"assemblies/rc.bin": {
- "Size": 1045
+ "Size": 1083
},
"assemblies/System.Linq.dll": {
- "Size": 10157
+ "Size": 10116
},
"assemblies/System.Private.CoreLib.dll": {
- "Size": 521019
+ "Size": 519296
},
"assemblies/System.Runtime.CompilerServices.Unsafe.dll": {
- "Size": 1184
+ "Size": 1163
},
"assemblies/System.Runtime.dll": {
- "Size": 2410
+ "Size": 2369
},
"assemblies/UnnamedProject.dll": {
- "Size": 3544
+ "Size": 3543
},
"classes.dex": {
"Size": 345328
},
"lib/arm64-v8a/libmonodroid.so": {
- "Size": 382760
+ "Size": 382776
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3176048
+ "Size": 3192432
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 776216
@@ -44,10 +44,10 @@
"Size": 84064
},
"lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": {
- "Size": 150024
+ "Size": 150032
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 12424
+ "Size": 12440
},
"META-INF/BNDLTOOL.RSA": {
"Size": 1213
@@ -83,5 +83,5 @@
"Size": 1904
}
},
- "PackageSize": 2705399
+ "PackageSize": 2701303
}
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
index 56915b5f6ea..2694418af3e 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
@@ -5,184 +5,184 @@
"Size": 3568
},
"assemblies/FormsViewGroup.dll": {
- "Size": 7251
+ "Size": 7247
},
"assemblies/Java.Interop.dll": {
- "Size": 61908
+ "Size": 62006
},
"assemblies/Mono.Android.dll": {
- "Size": 442164
+ "Size": 441706
},
"assemblies/mscorlib.dll": {
- "Size": 3795
+ "Size": 3798
},
"assemblies/netstandard.dll": {
- "Size": 5495
+ "Size": 5499
},
"assemblies/rc.bin": {
"Size": 1083
},
"assemblies/System.Collections.Concurrent.dll": {
- "Size": 11223
+ "Size": 11227
},
"assemblies/System.Collections.dll": {
"Size": 16736
},
"assemblies/System.Collections.NonGeneric.dll": {
- "Size": 8438
+ "Size": 8439
},
"assemblies/System.ComponentModel.dll": {
- "Size": 1956
+ "Size": 1961
},
"assemblies/System.ComponentModel.Primitives.dll": {
- "Size": 2562
+ "Size": 2566
},
"assemblies/System.ComponentModel.TypeConverter.dll": {
- "Size": 5965
+ "Size": 5968
},
"assemblies/System.Console.dll": {
- "Size": 6528
+ "Size": 6530
},
"assemblies/System.Core.dll": {
- "Size": 1924
+ "Size": 1928
},
"assemblies/System.Diagnostics.TraceSource.dll": {
- "Size": 6754
+ "Size": 6756
},
"assemblies/System.dll": {
- "Size": 2271
+ "Size": 2275
},
"assemblies/System.Drawing.dll": {
- "Size": 1954
+ "Size": 1957
},
"assemblies/System.Drawing.Primitives.dll": {
- "Size": 12200
+ "Size": 12199
},
"assemblies/System.IO.Compression.dll": {
- "Size": 17214
+ "Size": 17218
},
"assemblies/System.IO.IsolatedStorage.dll": {
- "Size": 10565
+ "Size": 10566
},
"assemblies/System.Linq.dll": {
- "Size": 19471
+ "Size": 19474
},
"assemblies/System.Linq.Expressions.dll": {
- "Size": 182079
+ "Size": 182081
},
"assemblies/System.Net.Http.dll": {
- "Size": 65835
+ "Size": 65831
},
"assemblies/System.Net.Primitives.dll": {
- "Size": 22366
+ "Size": 22364
},
"assemblies/System.Net.Requests.dll": {
- "Size": 3729
+ "Size": 3731
},
"assemblies/System.ObjectModel.dll": {
"Size": 11970
},
"assemblies/System.Private.CoreLib.dll": {
- "Size": 757439
+ "Size": 757425
},
"assemblies/System.Private.DataContractSerialization.dll": {
"Size": 191072
},
"assemblies/System.Private.Uri.dll": {
- "Size": 43673
+ "Size": 43677
},
"assemblies/System.Private.Xml.dll": {
- "Size": 220174
+ "Size": 220171
},
"assemblies/System.Private.Xml.Linq.dll": {
- "Size": 17100
+ "Size": 17101
},
"assemblies/System.Runtime.CompilerServices.Unsafe.dll": {
"Size": 1214
},
"assemblies/System.Runtime.dll": {
- "Size": 2553
+ "Size": 2557
},
"assemblies/System.Runtime.Serialization.dll": {
- "Size": 1886
+ "Size": 1889
},
"assemblies/System.Runtime.Serialization.Formatters.dll": {
- "Size": 2632
+ "Size": 2634
},
"assemblies/System.Runtime.Serialization.Primitives.dll": {
- "Size": 3936
+ "Size": 3940
},
"assemblies/System.Security.Cryptography.Algorithms.dll": {
- "Size": 6810
+ "Size": 6809
},
"assemblies/System.Security.Cryptography.Primitives.dll": {
"Size": 2968
},
"assemblies/System.Text.RegularExpressions.dll": {
- "Size": 76705
+ "Size": 76698
},
"assemblies/System.Xml.dll": {
- "Size": 1777
+ "Size": 1779
},
"assemblies/UnnamedProject.dll": {
- "Size": 117240
+ "Size": 117239
},
"assemblies/Xamarin.AndroidX.Activity.dll": {
- "Size": 6076
+ "Size": 6069
},
"assemblies/Xamarin.AndroidX.AppCompat.AppCompatResources.dll": {
- "Size": 6099
+ "Size": 6095
},
"assemblies/Xamarin.AndroidX.AppCompat.dll": {
- "Size": 112593
+ "Size": 112590
},
"assemblies/Xamarin.AndroidX.CardView.dll": {
- "Size": 6816
+ "Size": 6809
},
"assemblies/Xamarin.AndroidX.CoordinatorLayout.dll": {
- "Size": 16609
+ "Size": 16603
},
"assemblies/Xamarin.AndroidX.Core.dll": {
- "Size": 96724
+ "Size": 96723
},
"assemblies/Xamarin.AndroidX.DrawerLayout.dll": {
- "Size": 14275
+ "Size": 14273
},
"assemblies/Xamarin.AndroidX.Fragment.dll": {
- "Size": 39933
+ "Size": 39924
},
"assemblies/Xamarin.AndroidX.Legacy.Support.Core.UI.dll": {
- "Size": 6139
+ "Size": 6132
},
"assemblies/Xamarin.AndroidX.Lifecycle.Common.dll": {
- "Size": 6595
+ "Size": 6592
},
"assemblies/Xamarin.AndroidX.Lifecycle.LiveData.Core.dll": {
- "Size": 6675
+ "Size": 6671
},
"assemblies/Xamarin.AndroidX.Lifecycle.ViewModel.dll": {
- "Size": 3275
+ "Size": 3273
},
"assemblies/Xamarin.AndroidX.Loader.dll": {
- "Size": 12676
+ "Size": 12671
},
"assemblies/Xamarin.AndroidX.RecyclerView.dll": {
- "Size": 84690
+ "Size": 84688
},
"assemblies/Xamarin.AndroidX.SavedState.dll": {
- "Size": 5082
+ "Size": 5077
},
"assemblies/Xamarin.AndroidX.SwipeRefreshLayout.dll": {
- "Size": 10390
+ "Size": 10382
},
"assemblies/Xamarin.AndroidX.ViewPager.dll": {
- "Size": 17994
+ "Size": 17986
},
"assemblies/Xamarin.Forms.Core.dll": {
"Size": 528450
},
"assemblies/Xamarin.Forms.Platform.Android.dll": {
- "Size": 385000
+ "Size": 384996
},
"assemblies/Xamarin.Forms.Platform.dll": {
"Size": 56878
@@ -191,16 +191,16 @@
"Size": 60774
},
"assemblies/Xamarin.Google.Android.Material.dll": {
- "Size": 40136
+ "Size": 40134
},
"classes.dex": {
- "Size": 3483796
+ "Size": 3458288
},
"lib/arm64-v8a/libmonodroid.so": {
"Size": 382776
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3171952
+ "Size": 3192432
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 776216
@@ -212,7 +212,7 @@
"Size": 150032
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 133232
+ "Size": 133192
},
"META-INF/android.support.design_material.version": {
"Size": 12
@@ -779,7 +779,7 @@
"Size": 470
},
"res/drawable-hdpi-v4/icon.png": {
- "Size": 4762
+ "Size": 4791
},
"res/drawable-hdpi-v4/notification_bg_low_normal.9.png": {
"Size": 212
@@ -1967,5 +1967,5 @@
"Size": 341228
}
},
- "PackageSize": 7938591
+ "PackageSize": 7930399
}
\ No newline at end of file
diff --git a/src/Xamarin.Android.NUnitLite/Gui/Instrumentations/TestSuiteInstrumentation.cs b/src/Xamarin.Android.NUnitLite/Gui/Instrumentations/TestSuiteInstrumentation.cs
index 9c1d4c1eb53..aceff344af5 100644
--- a/src/Xamarin.Android.NUnitLite/Gui/Instrumentations/TestSuiteInstrumentation.cs
+++ b/src/Xamarin.Android.NUnitLite/Gui/Instrumentations/TestSuiteInstrumentation.cs
@@ -60,11 +60,14 @@ public override void OnStart ()
Log.Info (TAG, "NUnit automated tests started");
var testResult = AndroidRunner.Runner.Run (AndroidRunner.GetSetupTestTarget (arguments), TargetContext);
var resultsFile = GetResultsPath ();
+ Log.Info (TAG, $"NUnit resultsFile {resultsFile}");
if (resultsFile != null) {
var startTime = DateTime.Now;
var resultsXml = new NUnit2XmlOutputWriter (startTime);
resultsXml.WriteResultFile (testResult, resultsFile);
- results.PutString ("nunit2-results-path", ToAdbPath (resultsFile));
+ Log.Info (TAG, $"NUnit resultsFile {resultsFile} written");
+ results.PutString ("nunit2-results-path", resultsFile);
+ Log.Info (TAG, $"NUnit PutString {resultsFile} done.");
}
Log.Info (TAG, "NUnit automated tests completed");
int run = 0, passed = 0, skipped = 0, inconclusive = 0;
@@ -103,47 +106,18 @@ public override void OnStart ()
string GetResultsPath ()
{
- Java.IO.File resultsPathFile = GetExternalFilesDir ();
- var usePathFile = resultsPathFile != null && resultsPathFile.Exists ();
- var resultsPath = usePathFile
- ? resultsPathFile.AbsolutePath
- : Path.Combine (Context.FilesDir.AbsolutePath, ".__override__");
+ string pid = Guid.NewGuid ().ToString ();
+ Java.IO.File resultsPathFile = null;
+#if __ANDROID_19__
+ int sdk = ((int)Build.VERSION.SdkInt);
+ if (sdk >= 19)
+ resultsPathFile = TargetContext.GetExternalFilesDir (null);
+#endif
+ bool usePathFile = resultsPathFile != null && resultsPathFile.Exists ();
+ string resultsPath = usePathFile ? resultsPathFile.AbsolutePath : TargetContext.FilesDir.AbsolutePath;
if (!usePathFile && !Directory.Exists (resultsPath))
Directory.CreateDirectory (resultsPath);
- return Path.Combine (resultsPath, "TestResults.xml");
- }
-
- Java.IO.File GetExternalFilesDir ()
- {
- if (((int)Build.VERSION.SdkInt) < 19)
- return null;
- string type = null;
-#if __ANDROID_19__
- type = global::Android.OS.Environment.DirectoryDocuments;
-#else // !__ANDROID_19__
- type = global::Android.OS.Environment.DirectoryDownloads;
-#endif // !__ANDROID_19__
- return Context.GetExternalFilesDir (type);
- }
-
- // On some Android targets, the external storage directory is "emulated",
- // in which case the paths used on-device by the application are *not*
- // paths that can be used off-device with `adb pull`.
- // For example, `Contxt.GetExternalFilesDir()` may return `/storage/emulated/foo`,
- // but `adb pull /storage/emulated/foo` will *fail*; instead, we may need
- // `adb pull /mnt/shell/emulated/foo`.
- // The `$EMULATED_STORAGE_SOURCE` and `$EMULATED_STORAGE_TARGET` environment
- // variables control the "on-device" (`$EMULATED_STORAGE_TARGET`) and
- // "off-device" (`$EMULATED_STORAGE_SOURCE`) directory prefixes
- string ToAdbPath (string path)
- {
- var source = System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_SOURCE");
- var target = System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_TARGET");
-
- if (!string.IsNullOrEmpty (source) && !string.IsNullOrEmpty (target) && path.StartsWith (target, StringComparison.Ordinal)) {
- return path.Replace (target, source);
- }
- return path;
+ return Path.Combine (resultsPath, $"TestResults_{(pid.Replace ("-", "_"))}.xml");
}
protected abstract void AddTests ();
diff --git a/tests/EmbeddedDSOs/EmbeddedDSO/Properties/AndroidManifest.xml b/tests/EmbeddedDSOs/EmbeddedDSO/Properties/AndroidManifest.xml
index 99a124bf8ec..78abbbd92a6 100644
--- a/tests/EmbeddedDSOs/EmbeddedDSO/Properties/AndroidManifest.xml
+++ b/tests/EmbeddedDSOs/EmbeddedDSO/Properties/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/tests/MSBuildDeviceIntegration/Tests/AotProfileTests.cs b/tests/MSBuildDeviceIntegration/Tests/AotProfileTests.cs
index 3ade7ecd684..3bc35032b0b 100644
--- a/tests/MSBuildDeviceIntegration/Tests/AotProfileTests.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/AotProfileTests.cs
@@ -26,7 +26,7 @@ public void BuildBasicApplicationAndAotProfileIt ()
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
};
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
AddDotNetProfilerNativeLibraries (proj);
var port = 9000 + new Random ().Next (1000);
proj.SetProperty ("AndroidAotProfilerPort", port.ToString ());
diff --git a/tests/MSBuildDeviceIntegration/Tests/BundleToolTests.cs b/tests/MSBuildDeviceIntegration/Tests/BundleToolTests.cs
index 143aa370863..aa546d6d10d 100644
--- a/tests/MSBuildDeviceIntegration/Tests/BundleToolTests.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/BundleToolTests.cs
@@ -19,7 +19,7 @@ public class BundleToolTests : DeviceTest
new object[] { true },
};
- static readonly string [] Abis = new [] { "armeabi-v7a", "arm64-v8a", "x86" };
+ static readonly string [] Abis = new [] { "armeabi-v7a", "arm64-v8a", "x86", "x86_64" };
XamarinAndroidLibraryProject lib;
XamarinAndroidApplicationProject app;
ProjectBuilder libBuilder, appBuilder;
diff --git a/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs b/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs
index 3011e2e0ad2..b8e7bc22c7d 100755
--- a/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs
@@ -13,7 +13,7 @@
namespace Xamarin.Android.Build.Tests
{
[TestFixture]
- [Category ("UsesDevice"), Category ("Node-3")]
+ [Category ("UsesDevice")]
public class DebuggingTest : DeviceTest {
[TearDown]
public void ClearDebugProperties ()
@@ -43,15 +43,17 @@ void SetTargetFrameworkAndManifest(XamarinAndroidApplicationProject proj, Builde
}
[Test]
+ [Category ("Node-3")]
public void ApplicationRunsWithoutDebugger ([Values (false, true)] bool isRelease, [Values (false, true)] bool extractNativeLibs, [Values (false, true)] bool useEmbeddedDex)
{
AssertHasDevices ();
+ SwitchUser ();
var proj = new XamarinFormsAndroidApplicationProject () {
IsRelease = isRelease,
};
if (isRelease || !CommercialBuildAvailable) {
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
}
proj.SetDefaultTargetDevice ();
if (Builder.UseDotNet && isRelease) {
@@ -79,9 +81,11 @@ public void ApplicationRunsWithoutDebugger ([Values (false, true)] bool isReleas
}
[Test]
+ [Category ("Node-3")]
public void ClassLibraryMainLauncherRuns ([Values (true, false)] bool preloadAssemblies)
{
AssertHasDevices ();
+ SwitchUser ();
var path = Path.Combine ("temp", TestName);
@@ -89,7 +93,7 @@ public void ClassLibraryMainLauncherRuns ([Values (true, false)] bool preloadAss
ProjectName = "MyApp",
};
if (!CommercialBuildAvailable) {
- app.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ app.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
}
app.SetDefaultTargetDevice ();
app.SetProperty ("AndroidEnablePreloadAssemblies", preloadAssemblies.ToString ());
@@ -162,17 +166,26 @@ public void ClassLibraryMainLauncherRuns ([Values (true, false)] bool preloadAss
};
#pragma warning restore 414
- [Test, Category ("Debugger")]
+ [Test, Category ("Debugger"), Category ("Node-4")]
[TestCaseSource (nameof (DebuggerCustomAppTestCases))]
+ [Retry(5)]
public void CustomApplicationRunsWithDebuggerAndBreaks (bool embedAssemblies, string fastDevType, bool activityStarts)
{
AssertCommercialBuild ();
AssertHasDevices ();
+ SwitchUser ();
+
+ var path = Path.Combine (Root, "temp", TestName);
+ if (Directory.Exists (path)) {
+ TestContext.Out.WriteLine ($"Deleting previous run at '{path}'");
+ Directory.Delete (path,recursive:true);
+ }
+
var proj = new XamarinAndroidApplicationProject () {
IsRelease = false,
AndroidFastDeploymentType = fastDevType,
};
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
proj.SetProperty ("EmbedAssembliesIntoApk", embedAssemblies.ToString ());
proj.SetDefaultTargetDevice ();
proj.Sources.Add (new BuildItem.Source ("MyApplication.cs") {
@@ -198,7 +211,7 @@ public override void OnCreate ()
}
"),
});
- using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
+ using (var b = CreateApkBuilder (path)) {
SetTargetFrameworkAndManifest (proj, b);
Assert.True (b.Install (proj), "Project should have installed.");
@@ -220,7 +233,7 @@ public override void OnCreate ()
int port = rnd.Next (10000, 20000);
TestContext.Out.WriteLine ($"{port}");
var args = new SoftDebuggerConnectArgs ("", IPAddress.Loopback, port) {
- MaxConnectionAttempts = 10,
+ MaxConnectionAttempts = 2000, // we need a long delay here to get a reliable connection
};
var startInfo = new SoftDebuggerStartInfo (args) {
WorkingDirectory = Path.Combine (b.ProjectDirectory, proj.IntermediateOutputPath, "android", "assets"),
@@ -237,18 +250,18 @@ public override void OnCreate ()
"AndroidAttachDebugger=True",
}), "Project should have run.");
- // do we expect the app to start?
- Assert.AreEqual (activityStarts, WaitForDebuggerToStart (Path.Combine (Root, b.ProjectDirectory, "logcat.log")), "Activity should have started");
- if (!activityStarts)
- return;
- // we need to give a bit of time for the debug server to start up.
- WaitFor (2000);
session.LogWriter += (isStderr, text) => { Console.WriteLine (text); };
session.OutputWriter += (isStderr, text) => { Console.WriteLine (text); };
session.DebugWriter += (level, category, message) => { Console.WriteLine (message); };
+ // do we expect the app to start?
+ Assert.AreEqual (activityStarts, WaitForDebuggerToStart (Path.Combine (Root, b.ProjectDirectory, "logcat.log")), "Debugger should have started");
+ if (!activityStarts)
+ return;
+ Assert.False (session.HasExited, "Target should not have exited.");
session.Run (startInfo, options);
var expectedTime = TimeSpan.FromSeconds (1);
var actualTime = ProfileFor (() => session.IsConnected);
+ Assert.True (session.IsConnected, "Debugger should have connected but it did not.");
TestContext.Out.WriteLine ($"Debugger connected in {actualTime}");
Assert.LessOrEqual (actualTime, expectedTime, $"Debugger should have connected within {expectedTime} but it took {actualTime}.");
// we need to wait here for a while to allow the breakpoints to hit
@@ -328,20 +341,29 @@ public override void OnCreate ()
};
#pragma warning restore 414
- [Test, Category ("SmokeTests"), Category ("Debugger")]
+ [Test, Category ("SmokeTests"), Category ("Debugger"), Category ("Node-4")]
[TestCaseSource (nameof(DebuggerTestCases))]
+ [Retry (5)]
public void ApplicationRunsWithDebuggerAndBreaks (bool embedAssemblies, string fastDevType, bool allowDeltaInstall, string username, string debugType)
{
AssertCommercialBuild ();
AssertHasDevices ();
+ SwitchUser ();
+ WaitFor (5000);
+
+ var path = Path.Combine (Root, "temp", TestName);
+ if (Directory.Exists (path)) {
+ TestContext.Out.WriteLine ($"Deleting previous run at '{path}'");
+ Directory.Delete (path,recursive:true);
+ }
- var path = Path.Combine ("temp", TestName);
int userId = GetUserId (username);
List parameters = new List ();
if (userId >= 0)
parameters.Add ($"AndroidDeviceUserId={userId}");
if (SwitchUser (username)) {
- WaitFor (5);
+ WaitFor (5000);
+ ClearBlockingDialogs ();
ClickButton ("", "android:id/button1", "Yes continue");
}
@@ -368,7 +390,7 @@ public Foo ()
};
app.MainPage = app.MainPage.Replace ("InitializeComponent ();", "InitializeComponent (); new Foo ();");
app.AddReference (lib);
- app.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ app.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
app.SetProperty (KnownProperties._AndroidAllowDeltaInstall, allowDeltaInstall.ToString ());
if (!string.IsNullOrEmpty (debugType)) {
app.SetProperty ("DebugType", debugType);
@@ -412,7 +434,7 @@ public Foo ()
int port = rnd.Next (10000, 20000);
TestContext.Out.WriteLine ($"{port}");
var args = new SoftDebuggerConnectArgs ("", IPAddress.Loopback, port) {
- MaxConnectionAttempts = 10,
+ MaxConnectionAttempts = 2000,
};
var startInfo = new SoftDebuggerStartInfo (args) {
WorkingDirectory = Path.Combine (appBuilder.ProjectDirectory, app.IntermediateOutputPath, "android", "assets"),
@@ -431,17 +453,24 @@ public Foo ()
Assert.True (appBuilder.RunTarget (app, "_Run", doNotCleanupOnUpdate: true,
parameters: parameters.ToArray ()), "Project should have run.");
- Assert.IsTrue (WaitForDebuggerToStart (Path.Combine (Root, appBuilder.ProjectDirectory, "logcat.log")), "Activity should have started");
- // we need to give a bit of time for the debug server to start up.
- WaitFor (2000);
- session.LogWriter += (isStderr, text) => { Console.WriteLine (text); };
- session.OutputWriter += (isStderr, text) => { Console.WriteLine (text); };
- session.DebugWriter += (level, category, message) => { Console.WriteLine (message); };
+ session.LogWriter += (isStderr, text) => {
+ TestContext.Out.WriteLine (text);
+ };
+ session.OutputWriter += (isStderr, text) => {
+ TestContext.Out.WriteLine (text);
+ };
+ session.DebugWriter += (level, category, message) => {
+ TestContext.Out.WriteLine (message);
+ };
+ Assert.IsTrue (WaitForDebuggerToStart (Path.Combine (Root, appBuilder.ProjectDirectory, "logcat.log")), "Debugger should have started");
session.Run (startInfo, options);
- WaitFor (TimeSpan.FromSeconds (30), () => session.IsConnected);
+ TestContext.Out.WriteLine ($"Detected debugger startup in log");
+ Assert.False (session.HasExited, "Target should not have exited.");
+ WaitFor (TimeSpan.FromSeconds (30), () => session.IsConnected );
Assert.True (session.IsConnected, "Debugger should have connected but it did not.");
// we need to wait here for a while to allow the breakpoints to hit
// but we need to timeout
+ TestContext.Out.WriteLine ($"Debugger connected.");
TimeSpan timeout = TimeSpan.FromSeconds (60);
int expected = 4;
while (session.IsConnected && breakcountHitCount < 3 && timeout >= TimeSpan.Zero) {
@@ -452,7 +481,8 @@ public Foo ()
Assert.AreEqual (expected, breakcountHitCount, $"Should have hit {expected} breakpoints. Only hit {breakcountHitCount}");
breakcountHitCount = 0;
ClearAdbLogcat ();
- ClickButton (app.PackageName, "myXFButton", "CLICK ME");
+ ClearBlockingDialogs ();
+ Assert.True (ClickButton (app.PackageName, "myXFButton", "CLICK ME"), "Button should have been clicked!");
while (session.IsConnected && breakcountHitCount < 1 && timeout >= TimeSpan.Zero) {
Thread.Sleep (10);
timeout = timeout.Subtract (TimeSpan.FromMilliseconds (10));
diff --git a/tests/MSBuildDeviceIntegration/Tests/DeleteBinObjTest.cs b/tests/MSBuildDeviceIntegration/Tests/DeleteBinObjTest.cs
index b536634bc2c..783b4d58af0 100644
--- a/tests/MSBuildDeviceIntegration/Tests/DeleteBinObjTest.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/DeleteBinObjTest.cs
@@ -50,7 +50,9 @@ void RunTest (string name, string sln, string csproj, string version, string rev
"IntermediateOutputPath=" + Path.Combine ("obj", isRelease ? "Release" : "Debug", "90") + Path.DirectorySeparatorChar
};
if (isRelease || !CommercialBuildAvailable) {
- parameters.Add (KnownProperties.AndroidSupportedAbis + "=\"armeabi-v7a;x86\"");
+ parameters.Add (KnownProperties.AndroidSupportedAbis + "=\"armeabi-v7a;x86;x86_64\"");
+ } else {
+ parameters.Add (KnownProperties.AndroidSupportedAbis + "=\"armeabi-v7a;arm64-v8a;x86;x86_64\"");
}
if (HasDevices) {
Assert.IsTrue (builder.Install (project, doNotCleanupOnUpdate: true, parameters: parameters.ToArray (), saveProject: false),
diff --git a/tests/MSBuildDeviceIntegration/Tests/DeploymentTest.cs b/tests/MSBuildDeviceIntegration/Tests/DeploymentTest.cs
index c78bca35f76..26096b0cf25 100644
--- a/tests/MSBuildDeviceIntegration/Tests/DeploymentTest.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/DeploymentTest.cs
@@ -38,7 +38,7 @@ public void BeforeDeploymentTests ()
RunAdbCommand ("shell settings put global auto_time_zone 0");
proj = new XamarinFormsAndroidApplicationProject ();
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
var mainPage = proj.Sources.First (x => x.Include () == "MainPage.xaml.cs");
var source = mainPage.TextContent ().Replace ("InitializeComponent ();", @"InitializeComponent ();
Console.WriteLine ($""TimeZoneInfoNative={Java.Util.TimeZone.Default.ID}"");
@@ -60,6 +60,7 @@ public void BeforeDeploymentTests ()
";
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
+ builder.BuildLogFile = "install.log";
Assert.IsTrue (builder.Install (proj), "Install should have succeeded.");
}
@@ -69,8 +70,18 @@ public void AfterDeploymentTests ()
if (HasDevices && proj != null)
RunAdbCommand ($"uninstall {proj.PackageName}");
- if (TestContext.CurrentContext.Result.FailCount == 0 && builder != null && Directory.Exists (Path.Combine (Root, builder.ProjectDirectory)))
- Directory.Delete (Path.Combine (Root, builder.ProjectDirectory), recursive: true);
+ if (builder != null)
+ return;
+
+ string output = Path.Combine (Root, builder.ProjectDirectory);
+ if (TestContext.CurrentContext.Result.FailCount == 0 && Directory.Exists (output)) {
+ Directory.Delete (output, recursive: true);
+ return;
+ }
+
+ foreach (var file in Directory.GetFiles (output, "*.log", SearchOption.AllDirectories)) {
+ TestContext.AddTestAttachment (file, Path.GetFileName (output));
+ }
}
[Test]
@@ -135,8 +146,10 @@ public void CheckResouceIsOverridden ([Values (true, false)] bool useAapt2)
WaitForPermissionActivity (Path.Combine (Root, builder.ProjectDirectory, "permission-logcat.log"));
WaitForActivityToStart (app.PackageName, "MainActivity",
Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log"), 15);
+ ClearBlockingDialogs ();
XDocument ui = GetUI ();
XElement node = ui.XPathSelectElement ($"//node[contains(@resource-id,'myButton')]");
+ Assert.IsNotNull (node , "Could not find `my-Button` in the user interface. Check the screenshot of the test failure.");
StringAssert.AreEqualIgnoringCase ("Click Me! One", node.Attribute ("text").Value, "Text of Button myButton should have been \"Click Me! One\"");
b.BuildLogFile = "clean.log";
Assert.IsTrue (b.Clean (app, doNotCleanupOnUpdate: true), "Clean should have suceeded.");
@@ -185,6 +198,7 @@ public void CheckXamarinFormsAppDeploysAndAButtonWorks ()
WaitForActivityToStart (proj.PackageName, "MainActivity",
Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log"), 15);
ClearAdbLogcat ();
+ ClearBlockingDialogs ();
ClickButton (proj.PackageName, "myXFButton", "CLICK ME");
Assert.IsTrue (MonitorAdbLogcat ((line) => {
return line.Contains ("Button was Clicked!");
diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
index dcc77f12b11..6c36e6a6083 100644
--- a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
@@ -41,7 +41,7 @@ public void GlobalLayoutEvent_ShouldRegisterAndFire_OnActivityLaunch ([Values (f
TargetSdkVersion = null,
};
if (isRelease || !CommercialBuildAvailable) {
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86", "x86_64");
}
proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}",
$@"button.ViewTreeObserver.GlobalLayout += Button_ViewTreeObserver_GlobalLayout;
@@ -190,7 +190,7 @@ public void SmokeTestBuildAndRunWithSpecialCharacters ()
ProjectName = testName,
IsRelease = true,
};
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
proj.SetDefaultTargetDevice ();
using (var builder = CreateApkBuilder (Path.Combine (rootPath, proj.ProjectName))){
Assert.IsTrue (builder.Install (proj), "Install should have succeeded.");
@@ -494,7 +494,7 @@ public void JsonDeserializationCreatesJavaHandle ([Values (false, true)] bool is
};
if (isRelease || !CommercialBuildAvailable) {
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86", "x86_64");
}
proj.References.Add (new BuildItem.Reference ("System.Runtime.Serialization"));
diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs
index 7cc5bf0ada0..12bf43c3770 100644
--- a/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/InstallTests.cs
@@ -38,7 +38,7 @@ public void ReInstallIfUserUninstalled ([Values (false, true)] bool isRelease)
IsRelease = isRelease,
};
if (isRelease) {
- proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
+ proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86", "x86_64");
}
using (var builder = CreateApkBuilder ()) {
Assert.IsTrue (builder.Build (proj));
@@ -69,7 +69,7 @@ public void InstallAndUnInstall ([Values (false, true)] bool isRelease)
if (isRelease) {
// Set debuggable=true to allow run-as command usage with a release build
proj.AndroidManifest = proj.AndroidManifest.Replace ("Mono.Android-Tests
Properties\AndroidManifest.xml
armeabi-v7a;x86
+ $(AndroidSupportedAbis);x86_64
true
All
true
@@ -45,6 +46,7 @@
None
false
true
+ true
true
@@ -53,6 +55,7 @@
4
false
true
+ true
r8
diff --git a/tests/Mono.Android-Tests/Properties/AndroidManifest.xml b/tests/Mono.Android-Tests/Properties/AndroidManifest.xml
index a67c4caa579..3a108a7ade0 100644
--- a/tests/Mono.Android-Tests/Properties/AndroidManifest.xml
+++ b/tests/Mono.Android-Tests/Properties/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/tests/Mono.Android-Tests/Runtime-AppBundle/Properties/AndroidManifest.xml b/tests/Mono.Android-Tests/Runtime-AppBundle/Properties/AndroidManifest.xml
index 88d4e606197..b4953758066 100644
--- a/tests/Mono.Android-Tests/Runtime-AppBundle/Properties/AndroidManifest.xml
+++ b/tests/Mono.Android-Tests/Runtime-AppBundle/Properties/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/AndroidManifest.xml b/tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/AndroidManifest.xml
index 7ef0c18d3a7..aae3d489b4b 100644
--- a/tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/AndroidManifest.xml
+++ b/tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/tests/Mono.Android-Tests/Runtime-MultiDex/Properties/AndroidManifest.xml b/tests/Mono.Android-Tests/Runtime-MultiDex/Properties/AndroidManifest.xml
index adfa8536d7b..cb56511ab2d 100644
--- a/tests/Mono.Android-Tests/Runtime-MultiDex/Properties/AndroidManifest.xml
+++ b/tests/Mono.Android-Tests/Runtime-MultiDex/Properties/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/tests/Mono.Android-Tests/System.Net/NetworkInterfaces.cs b/tests/Mono.Android-Tests/System.Net/NetworkInterfaces.cs
index d850ceae07d..f6515799427 100644
--- a/tests/Mono.Android-Tests/System.Net/NetworkInterfaces.cs
+++ b/tests/Mono.Android-Tests/System.Net/NetworkInterfaces.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using Java.Net;
@@ -9,7 +10,7 @@
using MNetworkInterface = System.Net.NetworkInformation.NetworkInterface;
using JNetworkInterface = Java.Net.NetworkInterface;
-namespace System.NetTests
+namespace System.NetTests
{
[TestFixture]
public class NetworkInterfacesTest
@@ -73,7 +74,7 @@ bool AddressesAreEqual (List one, List two)
return false;
if (one.Count != two.Count)
return false;
-
+
foreach (IPAddress addr in one) {
if (!two.Contains (addr))
return false;
@@ -181,6 +182,9 @@ byte[] GetHardwareAddress (MNetworkInterface inf)
// Map to android's idea of device address
if (bytes.Length == 0 || inf.NetworkInterfaceType == NetworkInterfaceType.Tunnel)
return null;
+ // if all the bytes are zero return null like Java does.
+ if (bytes.All (x => x == 0))
+ return null;
return bytes;
}
diff --git a/tests/TestRunner.Core/TestInstrumentation.cs b/tests/TestRunner.Core/TestInstrumentation.cs
index 3095f10ce4d..0f9abf5fcee 100644
--- a/tests/TestRunner.Core/TestInstrumentation.cs
+++ b/tests/TestRunner.Core/TestInstrumentation.cs
@@ -62,7 +62,7 @@ string FindTestAssembly (string name)
if (aname == null)
return null;
-
+
foreach (string dir in TestAssemblyDirectories) {
if (String.IsNullOrEmpty (dir))
continue;
@@ -244,7 +244,7 @@ void LogDeviceInfo ()
LogPaddedInfo ("VERSION.Release", Build.VERSION.Release, alignColumn);
LogPaddedInfo ("VERSION.Sdk", Build.VERSION.Sdk, alignColumn);
LogPaddedInfo ("VERSION.SdkInt", Build.VERSION.SdkInt.ToString (), alignColumn);
- LogPaddedInfo ("Device Date/Time", DateTime.UtcNow.ToString (), alignColumn);
+ LogPaddedInfo ("Device Date/Time", DateTime.UtcNow.ToString (), alignColumn);
// FIXME: add data about how the app was compiled (e.g. ARMvX, LLVM, Linker options)
}
@@ -285,7 +285,7 @@ bool RunTests (ref Bundle results)
results.PutLong (ResultInconclusiveTests, runner.InconclusiveTests);
results.PutLong (ResultTotalTests, runner.TotalTests);
results.PutLong (ResultFilteredTests, runner.FilteredTests);
- results.PutString (ResultResultsFilePath, ToAdbPath (resultsFilePath));
+ results.PutString (ResultResultsFilePath, ToAdbPath(resultsFilePath));
Log.Info (LogTag, $"Passed: {runner.PassedTests}, Failed: {runner.FailedTests}, Skipped: {runner.SkippedTests}, Inconclusive: {runner.InconclusiveTests}, Total: {runner.TotalTests}, Filtered: {runner.FilteredTests}");
@@ -380,7 +380,7 @@ protected HashSet LoadExcludedTests (TextReader reader)
string line = reader.ReadLine ()?.Trim ();
if (line == null)
return excludedTestNames;
-
+
if (line.Length == 0 || line.StartsWith ("#", StringComparison.Ordinal))
continue;
@@ -407,7 +407,9 @@ string ToAdbPath (string path)
string source = global::System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_SOURCE")?.Trim ();
string target = global::System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_TARGET")?.Trim ();
- if (!String.IsNullOrEmpty (source) && !String.IsNullOrEmpty (target) && path.StartsWith (target, StringComparison.Ordinal)) {
+ if (!String.IsNullOrEmpty (source) && !String.IsNullOrEmpty (target) &&
+ path.StartsWith (target, StringComparison.Ordinal) &&
+ ((int)Build.VERSION.SdkInt) <= 28) {
return path.Replace (target, source);
}
diff --git a/tests/TestRunner.Core/TestRunner.cs b/tests/TestRunner.Core/TestRunner.cs
index b24051fd431..886063a53bf 100644
--- a/tests/TestRunner.Core/TestRunner.cs
+++ b/tests/TestRunner.Core/TestRunner.cs
@@ -97,18 +97,21 @@ protected virtual string GetResultsFilePath ()
{
if (String.IsNullOrEmpty (ResultsFileName))
throw new InvalidOperationException ("Runner didn't specify a valid results file name");
-
+
+ string pid = Guid.NewGuid ().ToString ();
+
Java.IO.File resultsPathFile = null;
#if __ANDROID_19__
- if (((int)Build.VERSION.SdkInt) >= 19)
- resultsPathFile = Context.GetExternalFilesDir (global::Android.OS.Environment.DirectoryDocuments);
+ int sdk = ((int)Build.VERSION.SdkInt);
+ if (sdk >= 19)
+ resultsPathFile = Context.GetExternalFilesDir (null);
#endif
bool usePathFile = resultsPathFile != null && resultsPathFile.Exists ();
- string resultsPath = usePathFile ? resultsPathFile.AbsolutePath : Path.Combine (Context.FilesDir.AbsolutePath, ".__override__");
+ string resultsPath = usePathFile ? resultsPathFile.AbsolutePath : Context.FilesDir.AbsolutePath;
if (!usePathFile && !Directory.Exists (resultsPath))
Directory.CreateDirectory (resultsPath);
- return Path.Combine (resultsPath, ResultsFileName);
+ return Path.Combine (resultsPath, $"{(pid.Replace ("-", "_"))}_{ResultsFileName}");
}
}
}