Skip to content

Commit ad86668

Browse files
authored
[ci] Add Windows 'DebuggingTest' job (#9951)
A new [Intel based Windows pool][0] has been configured to run Android emulator test jobs on. This pool currently has capacity to scale up to 10 agents. The `StartAndroidEmulator` task and the execution environment for the `AcquireAndroidTarget` target have been updated to address issues with emulator launch attempts hanging on these Windows VMs with this seemingly related output: The STDIO streams did not close within 10 seconds of the exit event from process 'C:\Program Files\dotnet\dotnet.exe'. This may indicate a child process inherited the STDIO streams and has not yet exited. A new "Windows > Tests > Debugging" job has been added to the MSBuild Device tests stage that currently runs all tests in the `DebuggingTest` category. Starting with only one new job will allow us to start to scale up on Windows while monitoring for potential performance/reliabilty issues. [0]: https://ms.portal.azure.com/?feature.customportal=false#@microsoft.onmicrosoft.com/resource/subscriptions/cd4829e2-e38b-43d2-8316-2f2009f36f97/resourcegroups/1ESobjects/providers/Microsoft.CloudTest/hostedpools/Android-1ESPT/overview
1 parent 69e5f18 commit ad86668

File tree

5 files changed

+91
-48
lines changed

5 files changed

+91
-48
lines changed

build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/StartAndroidEmulator.cs

+22-36
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ public class StartAndroidEmulator : Task
3737

3838
public override bool Execute ()
3939
{
40-
Run (GetEmulatorPath ());
40+
var ranSuccessfully = Run (GetEmulatorPath ());
4141

4242
if (!string.IsNullOrEmpty (Port)) {
4343
AdbTarget = $"-s emulator-{Port}";
4444
}
4545

46-
return !Log.HasLoggedErrors;
46+
return ranSuccessfully && !Log.HasLoggedErrors;
4747
}
4848

4949
string GetEmulatorPath ()
@@ -63,10 +63,10 @@ string GetEmulatorPath ()
6363
return path;
6464
}
6565

66-
void Run (string emulator)
66+
bool Run (string emulator)
6767
{
6868
if (emulator == null)
69-
return;
69+
return false;
7070

7171
var port = string.IsNullOrEmpty (Port) ? "" : $"-port {Port}";
7272
var arguments = $"{Arguments ?? string.Empty} -verbose -detect-image-hang -logcat-output \"{LogcatFile}\" -no-audio -no-snapshot -cache-size 512 -change-locale en-US -timezone \"Etc/UTC\" {port} -avd {ImageName}";
@@ -136,40 +136,26 @@ void Run (string emulator)
136136
p.OutputDataReceived += output;
137137
p.ErrorDataReceived += error;
138138

139-
p.Start ();
140-
p.BeginOutputReadLine ();
141-
p.BeginErrorReadLine ();
142-
143-
const int Timeout = 20*1000;
144-
int i = WaitHandle.WaitAny (new[]{sawError}, millisecondsTimeout: Timeout);
145-
if (i == 0 || Log.HasLoggedErrors) {
146-
p.Kill ();
147-
return;
139+
try {
140+
p.Start ();
141+
EmulatorProcessId = p.Id;
142+
p.BeginOutputReadLine ();
143+
p.BeginErrorReadLine ();
144+
145+
const int Timeout = 20*1000;
146+
int i = WaitHandle.WaitAny (new[]{sawError}, millisecondsTimeout: Timeout);
147+
if (i == 0 || Log.HasLoggedErrors) {
148+
p.Kill ();
149+
return false;
150+
}
151+
} finally {
152+
p.CancelOutputRead ();
153+
p.CancelErrorRead ();
154+
p.OutputDataReceived -= output;
155+
p.ErrorDataReceived -= error;
148156
}
149-
150-
p.CancelOutputRead ();
151-
p.CancelErrorRead ();
152-
153-
p.OutputDataReceived -= output;
154-
p.ErrorDataReceived -= error;
155-
156-
p.OutputDataReceived += WriteProcessOutputMessage;
157-
p.ErrorDataReceived += WriteProcessErrorMessage;
158-
159-
p.BeginOutputReadLine ();
160-
p.BeginErrorReadLine ();
161-
162-
EmulatorProcessId = p.Id;
163-
}
164-
165-
static void WriteProcessOutputMessage (object sender, DataReceivedEventArgs e)
166-
{
167-
Console.WriteLine (e.Data);
157+
return true;
168158
}
169159

170-
static void WriteProcessErrorMessage (object sender, DataReceivedEventArgs e)
171-
{
172-
Console.Error.WriteLine (e.Data);
173-
}
174160
}
175161
}

build-tools/automation/yaml-templates/run-dotnet-preview.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ parameters:
99
condition: succeeded()
1010
continueOnError: true
1111
retryCountOnTaskFailure: 0
12+
taskTimeoutInMinutes: 0
1213

1314
steps:
1415
- powershell: |
@@ -31,3 +32,4 @@ steps:
3132
condition: ${{ parameters.condition }}
3233
continueOnError: ${{ parameters.continueOnError }}
3334
retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }}
35+
timeoutInMinutes: ${{ parameters.taskTimeoutInMinutes }}

build-tools/automation/yaml-templates/stage-msbuild-emulator-tests.yaml

+52
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,55 @@ stages:
154154
- template: /build-tools/automation/yaml-templates/fail-on-issue.yaml
155155
parameters:
156156
condition: ${{ parameters.shouldFailOnIssue }}
157+
158+
- job: debug_windows_tests
159+
displayName: Windows > Tests > Debugging
160+
timeoutInMinutes: 180
161+
pool:
162+
name: Android-1ESPT
163+
image: $(WindowsPoolImage1ESPT)
164+
os: windows
165+
workspace:
166+
clean: all
167+
steps:
168+
- template: /build-tools/automation/yaml-templates/setup-test-environment.yaml
169+
parameters:
170+
installTestSlicer: true
171+
installApkDiff: false
172+
xaSourcePath: ${{ parameters.xaSourcePath }}
173+
repositoryAlias: ${{ parameters.repositoryAlias }}
174+
commit: ${{ parameters.commit }}
175+
xaprepareScenario: EmulatorTestDependencies
176+
177+
- task: DownloadPipelineArtifact@2
178+
inputs:
179+
artifactName: $(TestAssembliesArtifactName)
180+
downloadPath: ${{ parameters.xaSourcePath }}/bin/Test$(XA.Build.Configuration)
181+
182+
- template: /build-tools/automation/yaml-templates/start-stop-emulator.yaml
183+
parameters:
184+
xaSourcePath: ${{ parameters.xaSourcePath }}
185+
startContinueOnError: ${{ parameters.emulatorStartContinueOnError }}
186+
187+
- template: /build-tools/automation/yaml-templates/run-sliced-nunit-tests.yaml
188+
parameters:
189+
testAssembly: $(System.DefaultWorkingDirectory)\bin\Test$(XA.Build.Configuration)\MSBuildDeviceIntegration\$(DotNetStableTargetFramework)\MSBuildDeviceIntegration.dll
190+
testFilter: name == DebuggingTest
191+
testRunTitle: DebuggingTest tests on Windows
192+
193+
- ${{ if ne(parameters.usesCleanImages, true) }}:
194+
- template: /build-tools/automation/yaml-templates/start-stop-emulator.yaml
195+
parameters:
196+
command: stop
197+
xaSourcePath: ${{ parameters.xaSourcePath }}
198+
199+
- template: /build-tools/automation/yaml-templates/upload-results.yaml
200+
parameters:
201+
configuration: $(XA.Build.Configuration)
202+
artifactName: Test Results - Emulator Debugging - Windows-$(System.JobPositionInPhase)
203+
xaSourcePath: ${{ parameters.xaSourcePath }}
204+
use1ESTemplate: ${{ parameters.use1ESTemplate }}
205+
206+
- template: /build-tools/automation/yaml-templates/fail-on-issue.yaml
207+
parameters:
208+
condition: ${{ parameters.shouldFailOnIssue }}

build-tools/automation/yaml-templates/start-stop-emulator.yaml

+14-11
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ parameters:
77
avdType: # Device AVD, like 'android-wear', required if 'specificImage' is 'true'
88
emulatorMSBuildArgs: # Extra args to pass to the emulator configuration like '-p:TestAvdExtraBootArgs=-writable-system', optional
99
launchTimeoutMin: 20 # Minutes to wait for the emulator to start
10+
taskTimeoutInMinutes: 30 # Minutes to wait for the task to finish
1011
startContinueOnError: false # If 'true', do not mark the step as failed if starting the emulator fails
1112
xaSourcePath: $(System.DefaultWorkingDirectory) # working directory
1213

1314
steps:
1415
- ${{ if eq(parameters.command, 'start') }}:
15-
- task: DotNetCoreCLI@2
16-
displayName: Start emulator
17-
continueOnError: ${{ parameters.startContinueOnError }}
18-
inputs:
19-
projects: ${{ parameters.xaSourcePath }}/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Emulator.csproj
16+
- template: /build-tools/automation/yaml-templates/run-dotnet-preview.yaml
17+
parameters:
18+
displayName: Start emulator
19+
continueOnError: ${{ parameters.startContinueOnError }}
20+
taskTimeoutInMinutes: ${{ parameters.taskTimeoutInMinutes }}
21+
project: ${{ parameters.xaSourcePath }}/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Emulator.csproj
2022
${{ if eq(parameters.specificImage, true) }}:
2123
arguments: >-
2224
-c $(XA.Build.Configuration) -t:"InstallAvdImage;AcquireAndroidTarget"
@@ -35,12 +37,13 @@ steps:
3537
-bl:$(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/start-emulator.binlog
3638
3739
- ${{ if eq(parameters.command, 'stop') }}:
38-
- task: DotNetCoreCLI@2
39-
displayName: Stop emulator
40-
condition: always()
41-
continueOnError: true
42-
inputs:
43-
projects: ${{ parameters.xaSourcePath }}/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Emulator.csproj
40+
- template: /build-tools/automation/yaml-templates/run-dotnet-preview.yaml
41+
parameters:
42+
displayName: Stop emulator
43+
condition: always()
44+
continueOnError: true
45+
taskTimeoutInMinutes: ${{ parameters.taskTimeoutInMinutes }}
46+
project: ${{ parameters.xaSourcePath }}/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Emulator.csproj
4447
${{ if eq(parameters.specificImage, true) }}:
4548
arguments: >-
4649
-c $(XA.Build.Configuration) -t:"AcquireAndroidTarget,ReleaseAndroidTarget"

build-tools/scripts/TestApks.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
AvdManagerHome="$(AvdManagerHome)"
8080
Arguments="$(TestAvdExtraBootArgs)"
8181
ImageName="$(TestAvdName)"
82-
LogcatFile="$(_LogcatFilenameBase)-full.txt"
82+
LogcatFile="$(_LogcatFilenameBase)-start-emu.txt"
8383
Port="$(_AdbEmulatorPort)"
8484
ToolExe="$(EmulatorToolExe)"
8585
ToolPath="$(EmulatorToolPath)">

0 commit comments

Comments
 (0)