Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Release/7.0] Add Maui Mobile Android Benchmarks #2789

Merged
merged 48 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7a9eec0
First round of adding Maui Android testing to the performance pipeline.
LoopedBard3 Dec 5, 2022
d9c9421
Add testing run to yaml for running the android tests.
LoopedBard3 Dec 5, 2022
cc2f119
Fix incorrect $/% mixup in the maui_scenarios_android.proj and add pu…
LoopedBard3 Dec 5, 2022
135b715
Add debugging print variables and add no restore to mauiandroid test.
LoopedBard3 Dec 6, 2022
8ca2ded
Try using MacOS to build the maui apps, then run on the android phones.
LoopedBard3 Dec 6, 2022
2306cbd
Try switch from $ to % for variabile interpolation for non-windows pr…
LoopedBard3 Dec 6, 2022
8b5d419
Remove non-windows run commands since all the android devices are cur…
LoopedBard3 Dec 6, 2022
3ab14c6
Setup testing upload of the corelation staging to see how big it is.
LoopedBard3 Dec 6, 2022
6d60691
Try removing the dotnet directory since we don't need it and it is to…
LoopedBard3 Dec 7, 2022
98dbe75
Print the current rate limit for debugging purposes.
LoopedBard3 Dec 7, 2022
811a616
Revert "Setup testing upload of the corelation staging to see how big…
LoopedBard3 Dec 7, 2022
6dc0a0c
Remove debugging print statements, adding no restore fixed the issue.
LoopedBard3 Dec 7, 2022
17df5a3
Updated the get_commit_date method to use the github patches instead …
LoopedBard3 Dec 7, 2022
6f26422
Fix dotnet.py get_commit_time Logger information.
LoopedBard3 Dec 7, 2022
dc61f72
Change osName to be the run machine, not build machine.
LoopedBard3 Dec 8, 2022
b739648
Try using windows-2022 for android builds.
LoopedBard3 Dec 8, 2022
a9412d8
Only remove the dotnet\packs path since they take up multiple gigabytes.
LoopedBard3 Dec 8, 2022
451bbdd
Add timeout for the maui android scenarios helix work items.
LoopedBard3 Dec 8, 2022
cacece4
Fix the xcopy commands to ensure there is not a prompt since we are o…
LoopedBard3 Dec 8, 2022
ab8766b
Changed APK Name to not include the file extension, and enabled extra…
LoopedBard3 Dec 8, 2022
b49edf4
Added android podcast app testing and added XHARNESSPATH to the preco…
LoopedBard3 Dec 9, 2022
b3ab3c1
Don't try to remove the dotnet-podcasts directory as it is causing pe…
LoopedBard3 Dec 9, 2022
e820801
Fixed .git folder delete issue.
LoopedBard3 Dec 9, 2022
2ec4bad
Add MauiVersion stuff to the pre.py and test.py commands.
LoopedBard3 Dec 9, 2022
425f6af
Ensure the Maui_Version file is downloaded with the apk file and make…
LoopedBard3 Dec 10, 2022
0cd22d7
Try different xcopy directory format to see if it gets found.
LoopedBard3 Dec 12, 2022
e3b2215
Try using batch available tools and see if powershell is available.
LoopedBard3 Dec 12, 2022
87a671f
Fix ampersand.
LoopedBard3 Dec 12, 2022
25c6486
Readd podcast and blazor scenario, and remove rollback file for net7.0.
LoopedBard3 Dec 12, 2022
b5bd304
Try using a specific version link and getting that version.
LoopedBard3 Dec 12, 2022
edaaf48
Try using key values for the channels with links.
LoopedBard3 Dec 12, 2022
7f34f2c
Testing how to pass link.
LoopedBard3 Dec 12, 2022
dc52537
Removed version passing functionality as net7.0 shouldn't need it for…
LoopedBard3 Dec 13, 2022
65b7342
Remove channelHasVersionLink from scenarios.yml.
LoopedBard3 Dec 13, 2022
76b64a1
Fix spacing issue.
LoopedBard3 Dec 13, 2022
833905e
Final Cleanup commit.
LoopedBard3 Dec 13, 2022
4963e8d
Makes timeouts global for maui_scenarios_android.proj and clarifies d…
LoopedBard3 Dec 14, 2022
be55f55
Update pre and test py's to use shared methods and add version manage…
LoopedBard3 Dec 14, 2022
2cfb5fe
Resetup testing.
LoopedBard3 Dec 14, 2022
06139f5
Fix GetEnvironmentVariables not being found for environment.
LoopedBard3 Dec 14, 2022
d7e7405
Fix versionswritejson path in the pre.pys to not start with .\.
LoopedBard3 Dec 14, 2022
40a176d
Fix Reporting.Tests by adding in HELIX_WORKITEM_FRIENDLYNAME environm…
LoopedBard3 Dec 14, 2022
330d457
Fix timeout time, should be parsable now.
LoopedBard3 Dec 14, 2022
aecc325
Add special cases to the reporter for environment variable versions a…
LoopedBard3 Dec 15, 2022
b13d06a
Move GetVersionFromDLL to the version manager shared script since it …
LoopedBard3 Dec 16, 2022
47aeff5
Undo yml testing changes.
LoopedBard3 Dec 16, 2022
966861d
Fixed type and added in manual run conditional.
LoopedBard3 Dec 28, 2022
65f5404
Backport changes made to main for final version.
LoopedBard3 Jan 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,19 @@ jobs:
projectFile: maui_scenarios.proj
channels:
- release/7.0

# Maui Android scenario benchmarks
- template: /eng/performance/build_machine_matrix.yml
parameters:
jobTemplate: /eng/performance/scenarios.yml
buildMachines:
- win-x64-android-arm64
isPublic: false
jobParameters:
kind: maui_scenarios_android
projectFile: maui_scenarios_android.proj
channels:
- release/7.0

################################################
# Scheduled Private jobs
Expand Down
14 changes: 13 additions & 1 deletion eng/performance/build_machine_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,16 @@ jobs:
vmImage: windows-2019
machinePool: Tiger
queue: Windows.10.Arm64.Perf.Surf
${{ insert }}: ${{ parameters.jobParameters }}
${{ insert }}: ${{ parameters.jobParameters }}

- ${{ if and(containsValue(parameters.buildMachines, 'win-x64-android-arm64'), not(eq(parameters.isPublic, true))) }}: # Windows ARM64 Pixel only used in private builds currently
- template: ${{ parameters.jobTemplate }}
parameters:
osName: windows
architecture: x64
osVersion: 19H1
pool:
vmImage: 'windows-2022'
queue: Windows.10.Amd64.Pixel.Perf
machinePool: Pixel
${{ insert }}: ${{ parameters.jobParameters }}
82 changes: 82 additions & 0 deletions eng/performance/maui_scenarios_android.proj
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<Project Sdk="Microsoft.DotNet.Helix.Sdk" DefaultTargets="Test">

<Import Project="Scenarios.Common.props" />

<PropertyGroup>
<IncludeXHarnessCli>true</IncludeXHarnessCli>
<MicrosoftDotNetXHarnessCLIVersion>1.0.0-prerelease.21566.2</MicrosoftDotNetXHarnessCLIVersion>
<XharnessPath>%HELIX_CORRELATION_PAYLOAD%\microsoft.dotnet.xharness.cli\$(MicrosoftDotNetXHarnessCLIVersion)\tools\net6.0\any\Microsoft.DotNet.XHarness.CLI.dll</XharnessPath>
</PropertyGroup>

<PropertyGroup>
<AfterPreparePayloadWorkItemCommand>$(Python) post.py</AfterPreparePayloadWorkItemCommand>
<PreparePayloadOutDirectoryName>scenarios_out</PreparePayloadOutDirectoryName>
<PreparePayloadWorkItemBaseDirectory Condition="'$(TargetsWindows)' == 'true'">$(CorrelationPayloadDirectory)$(PreparePayloadOutDirectoryName)\</PreparePayloadWorkItemBaseDirectory>
<PreparePayloadWorkItemBaseDirectory Condition="'$(TargetsWindows)' != 'true'">$(CorrelationPayloadDirectory)$(PreparePayloadOutDirectoryName)/</PreparePayloadWorkItemBaseDirectory>
</PropertyGroup>

<Target Name="RemoveDotnetFromCorrelationStaging" BeforeTargets="BeforeTest">
<Message Text="Removing Dotnet from Correlation Staging" Importance="high" />
<RemoveDir Directories="$(CorrelationPayloadDirectory)dotnet\packs" />
</Target>

<ItemDefinitionGroup>
<HelixWorkItem>
<Timeout>00:30</Timeout>
</HelixWorkItem>
</ItemDefinitionGroup>

<ItemGroup>
<MAUIAndroidScenario Include="Maui Android Default">
<ScenarioDirectoryName>mauiandroid</ScenarioDirectoryName>
<PayloadDirectory>$(ScenariosDir)%(ScenarioDirectoryName)</PayloadDirectory>
<ApkName>com.companyname.mauiandroiddefault-Signed</ApkName>
<PackageName>com.companyname.mauiandroiddefault</PackageName>
</MAUIAndroidScenario>
<MAUIAndroidScenario Include="Maui Android Podcast">
<ScenarioDirectoryName>mauiandroidpodcast</ScenarioDirectoryName>
<PayloadDirectory>$(ScenariosDir)%(ScenarioDirectoryName)</PayloadDirectory>
<ApkName>com.Microsoft.NetConf2021.Maui-Signed</ApkName>
<PackageName>com.Microsoft.NetConf2021.Maui</PackageName>
</MAUIAndroidScenario>
<MAUIAndroidScenario Include="Maui Blazor Android Default">
<ScenarioDirectoryName>mauiblazorandroid</ScenarioDirectoryName>
<PayloadDirectory>$(ScenariosDir)%(ScenarioDirectoryName)</PayloadDirectory>
<ApkName>com.companyname.mauiblazorandroiddefault-Signed</ApkName>
<PackageName>com.companyname.mauiblazorandroiddefault</PackageName>
</MAUIAndroidScenario>
</ItemGroup>


<ItemGroup>
<PreparePayloadWorkItem Include="@(MAUIAndroidScenario)">
<Command>$(Python) pre.py publish -f $(PERFLAB_Framework)-android -o $(PreparePayloadWorkItemBaseDirectory)%(PreparePayloadWorkItem.ScenarioDirectoryName) -r android-arm64 --self-contained</Command>
<WorkingDirectory>%(PreparePayloadWorkItem.PayloadDirectory)</WorkingDirectory>
</PreparePayloadWorkItem>
</ItemGroup>


<!-- We only run the android tests from Windows machines (at least for now) -->
<ItemGroup>
<HelixWorkItem Include="@(MAUIAndroidScenario -> 'SOD - %(Identity) APK Size')">
<PreCommands>echo on; xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y</PreCommands>
<Command>$(Python) test.py sod --scenario-name &quot;%(Identity)&quot;</Command>
</HelixWorkItem>
<HelixWorkItem Include="@(MAUIAndroidScenario -> 'SOD - %(Identity) Extracted Size')">
<PreCommands>echo on; xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y; ren %HELIX_WORKITEM_ROOT%\pub\%(HelixWorkItem.ApkName).apk %(HelixWorkItem.ApkName).zip; powershell.exe -nologo -noprofile -command "&amp; {Expand-Archive %HELIX_WORKITEM_ROOT%\pub\%(HelixWorkItem.ApkName).zip -DestinationPath %HELIX_WORKITEM_ROOT%\pub\}"; del %HELIX_WORKITEM_ROOT%\pub\%(HelixWorkItem.ApkName).zip</PreCommands>
<Command>$(Python) test.py sod --scenario-name &quot;%(Identity)&quot;</Command>
</HelixWorkItem>
<HelixWorkItem Include="@(MAUIAndroidScenario -> 'Device Startup - %(Identity)')">
<PreCommands>echo on; set XHARNESSPATH=$(XharnessPath); xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y</PreCommands>
<Command>$(Python) test.py devicestartup --device-type android --package-path pub\%(HelixWorkItem.ApkName).apk --package-name %(HelixWorkItem.PackageName) --scenario-name &quot;%(Identity)&quot;</Command>
</HelixWorkItem>
<HelixWorkItem Include="@(MAUIAndroidScenario -> 'Device Startup - %(Identity) NoAnimation')">
<PreCommands>echo on; set XHARNESSPATH=$(XharnessPath); xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y</PreCommands>
<Command>$(Python) test.py devicestartup --device-type android --package-path pub\%(HelixWorkItem.ApkName).apk --package-name %(HelixWorkItem.PackageName) --scenario-name &quot;%(Identity)&quot; --disable-animations</Command>
</HelixWorkItem>
</ItemGroup>


<Import Project="PreparePayloadWorkItems.targets" />

</Project>
20 changes: 12 additions & 8 deletions scripts/dotnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
"""

import ssl
import datetime
from argparse import Action, ArgumentParser, ArgumentTypeError, ArgumentError
from collections import namedtuple
from glob import iglob
from json import loads
from logging import getLogger
from os import chmod, environ, listdir, makedirs, path, pathsep, system
from re import search
from re import search, match, MULTILINE
from shutil import rmtree
from stat import S_IRWXU
from subprocess import CalledProcessError, check_output
Expand Down Expand Up @@ -611,27 +612,30 @@ def get_commit_date(
if not commit_sha:
raise ValueError('.NET Commit sha was not defined.')

# Example URL: https://github.com/dotnet/runtime/commit/2d76178d5faa97be86fc8d049c7dbcbdf66dc497.patch
url = None
urlformat = 'https://api.github.com/repos/%s/%s/commits/%s'
if repository is None:
# The origin of the repo where the commit belongs to has changed
# between release. Here we attempt to naively guess the repo.
core_sdk_frameworks = ChannelMap.get_supported_frameworks()
repo = 'core-sdk' if framework in core_sdk_frameworks else 'cli'
url = urlformat % ('dotnet', repo, commit_sha)
url = f'https://github.com/dotnet/{repo}/commit/{commit_sha}.patch'
else:
owner, repo = get_repository(repository)
url = urlformat % (owner, repo, commit_sha)
url = f'https://github.com/{owner}/{repo}/commit/{commit_sha}.patch'

build_timestamp = None
sleep_time = 10 # Start with 10 second sleep timer
sleep_time = 10 # Start with 10 second sleep timer
for retrycount in range(5):
try:
with urlopen(url) as response:
getLogger().info("Commit: %s", url)
item = loads(response.read().decode('utf-8'))
build_timestamp = item['commit']['committer']['date']
break
patch = response.read().decode('utf-8')
dateMatch = search(r'^Date: (.+)$', patch, MULTILINE)
if dateMatch:
build_timestamp = datetime.datetime.strptime(dateMatch.group(1), '%a, %d %b %Y %H:%M:%S %z').astimezone(datetime.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
getLogger().info(f"Got UTC timestamp {build_timestamp} from {dateMatch.group(1)}")
break
except URLError as error:
getLogger().warning(f"URL Error trying to get commit date from {url}; Reason: {error.reason}; Attempt {retrycount}")
sleep(sleep_time)
Expand Down
69 changes: 29 additions & 40 deletions src/scenarios/mauiandroid/pre.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,37 @@
pre-command
'''
import sys
import os
from zipfile import ZipFile
from performance.logger import setup_loggers, getLogger
from shutil import copyfile
from shared import const
from shared.mauisharedpython import remove_aab_files, install_versioned_maui
from shared.precommands import PreCommands
from shared.const import PUBDIR
from argparse import ArgumentParser
from shared.versionmanager import versions_write_json, get_version_from_dll_powershell
from test import EXENAME

setup_loggers(True)

parser = ArgumentParser()
parser.add_argument('--unzip', help='Unzip APK and report extracted tree', action='store_true', default=False)
parser.add_argument(
'--apk-name',
dest='apk',
required=True,
type=str,
help='Name of the APK to setup')
args = parser.parse_args()

if not os.path.exists(PUBDIR):
os.mkdir(PUBDIR)
apkname = args.apk
apknamezip = '%s.zip' % (apkname)
if not os.path.exists(apkname):
getLogger().error('Cannot find %s' % (apkname))
exit(-1)
if args.unzip:
if not os.path.exists(apknamezip):
copyfile(apkname, apknamezip)

with ZipFile(apknamezip) as zip:
zip.extractall(os.path.join('.', PUBDIR))

assets_dir = os.path.join(PUBDIR, 'assets')
assets_zip = os.path.join(assets_dir, 'assets.zip')
with ZipFile(assets_zip) as zip:
zip.extractall(assets_dir)

os.remove(assets_zip)
else:
copyfile(apkname, os.path.join(PUBDIR, apkname))



precommands = PreCommands()
install_versioned_maui(precommands)

# Setup the Maui folder
precommands.new(template='maui',
output_dir=const.APPDIR,
bin_dir=const.BINDIR,
exename=EXENAME,
working_directory=sys.path[0],
no_restore=False)

# Build the APK
precommands.execute(['--no-restore', '--source', 'MauiNuGet.config'])

# Remove the aab files as we don't need them, this saves space
output_dir = const.PUBDIR
if precommands.output:
output_dir = precommands.output
remove_aab_files(output_dir)

# Copy the MauiVersion to a file so we have it on the machine
maui_version = get_version_from_dll_powershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll")
version_dict = { "mauiVersion": maui_version }
versions_write_json(version_dict, rf"{output_dir}\versions.json")
print(f"Versions: {version_dict}")
8 changes: 6 additions & 2 deletions src/scenarios/mauiandroid/test.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
'''
C# Console app
Mobile Maui App
'''
from shared.const import PUBDIR
from shared.runner import TestTraits, Runner
from shared.versionmanager import versions_read_json_file_save_env

EXENAME = 'MauiAndroidDefault'

if __name__ == "__main__":
if __name__ == "__main__":
versions_read_json_file_save_env(rf".\{PUBDIR}\versions.json")

traits = TestTraits(exename=EXENAME,
guiapp='false',
)
Expand Down
9 changes: 9 additions & 0 deletions src/scenarios/mauiandroidpodcast/post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'''
post cleanup script
'''

from shared.postcommands import clean_directories
from performance.common import remove_directory

remove_directory("dotnet-podcasts")
clean_directories()
35 changes: 35 additions & 0 deletions src/scenarios/mauiandroidpodcast/pre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'''
pre-command
'''
import subprocess
from performance.logger import setup_loggers, getLogger
from shared.precommands import PreCommands
from shared.mauisharedpython import remove_aab_files, install_versioned_maui
from shared.versionmanager import versions_write_json, get_version_from_dll_powershell
from shared import const

setup_loggers(True)
precommands = PreCommands()
install_versioned_maui(precommands)

branch = f'{precommands.framework[:6]}'
subprocess.run(['git', 'clone', 'https://github.com/microsoft/dotnet-podcasts.git', '-b', branch, '--single-branch', '--depth', '1'])
subprocess.run(['powershell', '-Command', r'Remove-Item -Path .\\dotnet-podcasts\\.git -Recurse -Force']) # Git files have permission issues, do their deletion separately

precommands.existing(projectdir='./dotnet-podcasts', projectfile='./src/Mobile/Microsoft.NetConf2021.Maui.csproj')

# Build the APK
precommands._restore()
precommands.execute(['--no-restore'])

# Remove the aab files as we don't need them, this saves space
output_dir = const.PUBDIR
if precommands.output:
output_dir = precommands.output
remove_aab_files(output_dir)

# Copy the MauiVersion to a file so we have it on the machine
maui_version = get_version_from_dll_powershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll")
version_dict = { "mauiVersion": maui_version }
versions_write_json(version_dict, rf"{output_dir}\versions.json")
print(f"Versions: {version_dict}")
16 changes: 16 additions & 0 deletions src/scenarios/mauiandroidpodcast/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'''
Mobile Maui App
'''
from shared.const import PUBDIR
from shared.runner import TestTraits, Runner
from shared.versionmanager import versions_read_json_file_save_env

EXENAME = 'MauiAndroidPodcast'

if __name__ == "__main__":
versions_read_json_file_save_env(rf".\{PUBDIR}\versions.json")

traits = TestTraits(exename=EXENAME,
guiapp='false',
)
Runner(traits).run()
Loading