From b97a007204b04aecd658ac3967cf37d7179831a7 Mon Sep 17 00:00:00 2001 From: Parker Bibus Date: Tue, 3 Jan 2023 08:54:56 -0800 Subject: [PATCH 1/5] Add Maui Mobile Testing to the perf repo (port from release/7.0 testing). Move maui android scenario yml template to the correct place. (Private runs) specify that it is the dotnet packs we are removing from the correlation staging Testing the passing of links for the dotnet version. Add rollback file for installing the maui workload on .Net versions 8 and up, and update output dir functionality to work when it is not included. --- azure-pipelines.yml | 13 ++ eng/performance/build_machine_matrix.yml | 14 ++- eng/performance/maui_scenarios_android.proj | 82 +++++++++++++ eng/performance/scenarios.yml | 38 ++++-- scripts/dotnet.py | 20 ++-- src/scenarios/mauiandroid/pre.py | 80 ++++++------- src/scenarios/mauiandroid/test.py | 8 +- src/scenarios/mauiandroidpodcast/post.py | 9 ++ src/scenarios/mauiandroidpodcast/pre.py | 45 +++++++ src/scenarios/mauiandroidpodcast/test.py | 16 +++ src/scenarios/mauiblazorandroid/pre.py | 112 ++++++++++++------ src/scenarios/mauiblazorandroid/test.py | 6 +- src/scenarios/mauishared/mauisharedpython.py | 9 ++ src/scenarios/shared/versionmanager.py | 31 +++++ .../EnvironmentProviderMock.cs | 8 +- .../Reporting.Tests/ReporterTests.cs | 1 + .../Reporting/EnvironmentProvider.cs | 1 + src/tools/Reporting/Reporting/IEnvironment.cs | 5 +- src/tools/Reporting/Reporting/Reporter.cs | 25 ++-- 19 files changed, 414 insertions(+), 109 deletions(-) create mode 100644 eng/performance/maui_scenarios_android.proj create mode 100644 src/scenarios/mauiandroidpodcast/post.py create mode 100644 src/scenarios/mauiandroidpodcast/pre.py create mode 100644 src/scenarios/mauiandroidpodcast/test.py create mode 100644 src/scenarios/mauishared/mauisharedpython.py create mode 100644 src/scenarios/shared/versionmanager.py diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d85879ed62f..e6c59273124 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -273,6 +273,19 @@ jobs: channels: - main + # 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 + dotnetVersionsLinks: + main: https://aka.ms/dotnet/sdk/maui/net8.0.json + ## Maui scenario benchmarks #- template: /eng/performance/build_machine_matrix.yml # parameters: diff --git a/eng/performance/build_machine_matrix.yml b/eng/performance/build_machine_matrix.yml index 7ae27fa9a11..95e18ac7850 100644 --- a/eng/performance/build_machine_matrix.yml +++ b/eng/performance/build_machine_matrix.yml @@ -91,4 +91,16 @@ jobs: vmImage: windows-2019 machinePool: Tiger queue: Windows.10.Arm64.Perf.Surf - ${{ insert }}: ${{ parameters.jobParameters }} \ No newline at end of file + ${{ 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 }} diff --git a/eng/performance/maui_scenarios_android.proj b/eng/performance/maui_scenarios_android.proj new file mode 100644 index 00000000000..703bbb5de89 --- /dev/null +++ b/eng/performance/maui_scenarios_android.proj @@ -0,0 +1,82 @@ + + + + + + true + 1.0.0-prerelease.21566.2 + %HELIX_CORRELATION_PAYLOAD%\microsoft.dotnet.xharness.cli\$(MicrosoftDotNetXHarnessCLIVersion)\tools\net6.0\any\Microsoft.DotNet.XHarness.CLI.dll + + + + $(Python) post.py + scenarios_out + $(CorrelationPayloadDirectory)$(PreparePayloadOutDirectoryName)\ + $(CorrelationPayloadDirectory)$(PreparePayloadOutDirectoryName)/ + + + + + + + + + + 00:30 + + + + + + mauiandroid + $(ScenariosDir)%(ScenarioDirectoryName) + com.companyname.mauiandroiddefault-Signed + com.companyname.mauiandroiddefault + + + mauiandroidpodcast + $(ScenariosDir)%(ScenarioDirectoryName) + com.Microsoft.NetConf2021.Maui-Signed + com.Microsoft.NetConf2021.Maui + + + mauiblazorandroid + $(ScenariosDir)%(ScenarioDirectoryName) + com.companyname.mauiblazorandroiddefault-Signed + com.companyname.mauiblazorandroiddefault + + + + + + + $(Python) pre.py publish -f $(PERFLAB_Framework)-android -o $(PreparePayloadWorkItemBaseDirectory)%(PreparePayloadWorkItem.ScenarioDirectoryName) -r android-arm64 --self-contained + %(PreparePayloadWorkItem.PayloadDirectory) + + + + + + + + echo on; xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y + $(Python) test.py sod --scenario-name "%(Identity)" + + + 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 "& {Expand-Archive %HELIX_WORKITEM_ROOT%\pub\%(HelixWorkItem.ApkName).zip -DestinationPath %HELIX_WORKITEM_ROOT%\pub\}"; del %HELIX_WORKITEM_ROOT%\pub\%(HelixWorkItem.ApkName).zip + $(Python) test.py sod --scenario-name "%(Identity)" + + + echo on; set XHARNESSPATH=$(XharnessPath); xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y + $(Python) test.py devicestartup --device-type android --package-path pub\%(HelixWorkItem.ApkName).apk --package-name %(HelixWorkItem.PackageName) --scenario-name "%(Identity)" + + + echo on; set XHARNESSPATH=$(XharnessPath); xcopy %HELIX_CORRELATION_PAYLOAD%\$(PreparePayloadOutDirectoryName)\%(HelixWorkItem.ScenarioDirectoryName) %HELIX_WORKITEM_ROOT%\pub\ /E /I /Y + $(Python) test.py devicestartup --device-type android --package-path pub\%(HelixWorkItem.ApkName).apk --package-name %(HelixWorkItem.PackageName) --scenario-name "%(Identity)" --disable-animations + + + + + + + diff --git a/eng/performance/scenarios.yml b/eng/performance/scenarios.yml index acd30ea6389..0222d12d63c 100644 --- a/eng/performance/scenarios.yml +++ b/eng/performance/scenarios.yml @@ -6,7 +6,8 @@ parameters: pool: '' # required -- name of the Helix pool queue: '' # required -- name of the Helix queue container: '' # optional -- id of the container - channels: [] # required -- list of channels to download .NET from + channels: [] # optional (must have dotnetVersionsLinks if not used) -- list of channels to download .NET from + dotnetVersionsLinks: [] # optional alternative to channels that uses 'channel: link' values to scrape the link's json for dotnet_version or version projectFile: '' # required -- project file to build (current choices: scenarios.proj/sdk_scenarios.proj ) machinePool: '' # required -- Name of perf machine pool (Tiger, Owl, etc) @@ -81,16 +82,37 @@ jobs: container: ${{ parameters.container }} strategy: matrix: - ${{ each channel in parameters.channels }}: - ${{ channel }}: - _Channel: ${{ channel }} - _Configs: CompilationMode=Tiered RunKind="${{ parameters.kind }}" - _BuildConfig: ${{ parameters.architecture }}_$(_Channel)_${{ parameters.kind }} # needs to be unique to avoid logs overwriting in mc.dot.net + ${{ if ne(length(parameters.channels), 0) }}: + ${{ each channel in parameters.channels }}: + ${{ channel }}: + _Channel: ${{ channel }} + _Configs: CompilationMode=Tiered RunKind="${{ parameters.kind }}" + _BuildConfig: ${{ parameters.architecture }}_$(_Channel)_${{ parameters.kind }} # needs to be unique to avoid logs overwriting in mc.dot.net + ${{ if ne(length(parameters.dotnetVersionsLinks), 0) }}: + ${{ each versionPair in parameters.dotnetVersionsLinks }}: + ${{ versionPair.key }}_Link: + _Channel: ${{ versionPair.key }} + _DotnetVersionLink: ${{ versionPair.value }} + _Configs: CompilationMode=Tiered RunKind="${{ parameters.kind }}" + _BuildConfig: ${{ parameters.architecture }}_$(_Channel)_Linked_${{ parameters.kind }} # needs to be unique to avoid logs overwriting in mc.dot.net steps: - checkout: self clean: true - - script: $(Python) scripts/ci_setup.py --channel $(_Channel) --architecture ${{parameters.architecture}} --perf-hash $(Build.SourceVersion) --queue ${{parameters.queue}} --build-number $(Build.BuildNumber) --build-configs $(_Configs) --output-file $(CorrelationStaging)machine-setup$(ScriptExtension) --install-dir $(CorrelationStaging)dotnet - displayName: Run ci_setup.py + - ${{ if ne(length(parameters.channels), 0) }}: + - script: $(Python) scripts/ci_setup.py --channel $(_Channel) --architecture ${{parameters.architecture}} --perf-hash $(Build.SourceVersion) --queue ${{parameters.queue}} --build-number $(Build.BuildNumber) --build-configs $(_Configs) --output-file $(CorrelationStaging)machine-setup$(ScriptExtension) --install-dir $(CorrelationStaging)dotnet + displayName: Run ci_setup.py + - ${{ elseif ne(length(parameters.dotnetVersionsLinks), 0) }}: + - powershell: | + $data = Invoke-WebRequest -Uri "$(_DotnetVersionLink)" + $values = ConvertFrom-Json $data.content + $dotnet_version_check = $values.dotnet_version + $version_check = $values.version + $dotnet_version = if ($dotnet_version_check) {$dotnet_version_check} Else {$version_check} + Write-Host "##vso[task.setvariable variable=DotnetVersion;]$dotnet_version" + Write-Host "Found dotnet version $dotnet_version" + displayName: Get dotnetVersion to use + - script: $(Python) scripts/ci_setup.py --channel $(_Channel) --dotnet-versions $(DotnetVersion) --architecture ${{parameters.architecture}} --perf-hash $(Build.SourceVersion) --queue ${{parameters.queue}} --build-number $(Build.BuildNumber) --build-configs $(_Configs) --output-file $(CorrelationStaging)machine-setup$(ScriptExtension) --install-dir $(CorrelationStaging)dotnet + displayName: Run ci_setup.py with dotnetVersionsLinks - ${{ if eq(parameters.osName, 'windows') }}: - script: xcopy .\NuGet.config $(CorrelationStaging) && xcopy .\scripts $(CorrelationStaging)scripts\/e && xcopy .\src\scenarios\shared $(CorrelationStaging)shared\/e && xcopy .\src\scenarios\staticdeps $(CorrelationStaging)staticdeps\/e displayName: Copy python libraries and NuGet.config diff --git a/scripts/dotnet.py b/scripts/dotnet.py index 0411dc2ca5c..e7a7d59be39 100755 --- a/scripts/dotnet.py +++ b/scripts/dotnet.py @@ -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 @@ -619,27 +620,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) diff --git a/src/scenarios/mauiandroid/pre.py b/src/scenarios/mauiandroid/pre.py index aed0d76c750..b51ee5f4f1e 100644 --- a/src/scenarios/mauiandroid/pre.py +++ b/src/scenarios/mauiandroid/pre.py @@ -2,48 +2,48 @@ pre-command ''' import sys -import os -from zipfile import ZipFile +import requests +from mauishared.mauisharedpython import RemoveAABFiles from performance.logger import setup_loggers, getLogger -from shutil import copyfile +from shared import const from shared.precommands import PreCommands -from shared.const import PUBDIR -from argparse import ArgumentParser +from shared.versionmanager import versionswritejson, GetVersionFromDllPowershell +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() +target_framework_wo_platform = precommands.framework.split('-')[0] + +# Download what we need +with open ("MauiNuGet.config", "wb") as f: + f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) + +workload_install_args = ['--configfile', 'MauiNuGet.config'] +if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 + workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] + +precommands.install_workload('maui', workload_install_args) + +# 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 +RemoveAABFiles(output_dir) + +# Copy the MauiVersion to a file so we have it on the machine +maui_version = GetVersionFromDllPowershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll") +version_dict = { "mauiVersion": maui_version } +versionswritejson(version_dict, rf"{output_dir}\versions.json") +print(f"Versions: {version_dict}") diff --git a/src/scenarios/mauiandroid/test.py b/src/scenarios/mauiandroid/test.py index 349ef2ebcc7..75fb182f2c7 100644 --- a/src/scenarios/mauiandroid/test.py +++ b/src/scenarios/mauiandroid/test.py @@ -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 versionsreadjsonfilesaveenv EXENAME = 'MauiAndroidDefault' -if __name__ == "__main__": +if __name__ == "__main__": + versionsreadjsonfilesaveenv(rf".\{PUBDIR}\versions.json") + traits = TestTraits(exename=EXENAME, guiapp='false', ) diff --git a/src/scenarios/mauiandroidpodcast/post.py b/src/scenarios/mauiandroidpodcast/post.py new file mode 100644 index 00000000000..abdb7d8db9d --- /dev/null +++ b/src/scenarios/mauiandroidpodcast/post.py @@ -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() diff --git a/src/scenarios/mauiandroidpodcast/pre.py b/src/scenarios/mauiandroidpodcast/pre.py new file mode 100644 index 00000000000..db9d4aae7e6 --- /dev/null +++ b/src/scenarios/mauiandroidpodcast/pre.py @@ -0,0 +1,45 @@ +''' +pre-command +''' +import requests +import subprocess +from mauishared.mauisharedpython import RemoveAABFiles +from performance.logger import setup_loggers, getLogger +from shared.precommands import PreCommands +from shared.versionmanager import versionswritejson, GetVersionFromDllPowershell +from shared import const + +setup_loggers(True) +precommands = PreCommands() +target_framework_wo_platform = precommands.framework.split('-')[0] + +# Download what we need +with open ("MauiNuGet.config", "wb") as f: + f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) + +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 + +workload_install_args = ['--configfile', 'MauiNuGet.config'] +if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 + workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] + +precommands.install_workload('maui', workload_install_args) +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 +RemoveAABFiles(output_dir) + +# Copy the MauiVersion to a file so we have it on the machine +maui_version = GetVersionFromDllPowershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll") +version_dict = { "mauiVersion": maui_version } +versionswritejson(version_dict, rf"{output_dir}\versions.json") +print(f"Versions: {version_dict}") diff --git a/src/scenarios/mauiandroidpodcast/test.py b/src/scenarios/mauiandroidpodcast/test.py new file mode 100644 index 00000000000..1e557a00e46 --- /dev/null +++ b/src/scenarios/mauiandroidpodcast/test.py @@ -0,0 +1,16 @@ +''' +Mobile Maui App +''' +from shared.const import PUBDIR +from shared.runner import TestTraits, Runner +from shared.versionmanager import versionsreadjsonfilesaveenv + +EXENAME = 'MauiAndroidPodcast' + +if __name__ == "__main__": + versionsreadjsonfilesaveenv(rf".\{PUBDIR}\versions.json") + + traits = TestTraits(exename=EXENAME, + guiapp='false', + ) + Runner(traits).run() diff --git a/src/scenarios/mauiblazorandroid/pre.py b/src/scenarios/mauiblazorandroid/pre.py index aed0d76c750..e49f893692b 100644 --- a/src/scenarios/mauiblazorandroid/pre.py +++ b/src/scenarios/mauiblazorandroid/pre.py @@ -2,48 +2,86 @@ pre-command ''' import sys -import os -from zipfile import ZipFile +import requests +from mauishared.mauisharedpython import RemoveAABFiles from performance.logger import setup_loggers, getLogger -from shutil import copyfile +from shared import const from shared.precommands import PreCommands -from shared.const import PUBDIR -from argparse import ArgumentParser +from shared.versionmanager import versionswritejson, GetVersionFromDllPowershell +from test import EXENAME setup_loggers(True) +precommands = PreCommands() +target_framework_wo_platform = precommands.framework.split('-')[0] -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)) +# Download what we need +with open ("MauiNuGet.config", "wb") as f: + f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) +workload_install_args = ['--configfile', 'MauiNuGet.config'] +if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 + workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] +precommands.install_workload('maui', workload_install_args) + +# Setup the Maui folder +precommands.new(template='maui-blazor', + output_dir=const.APPDIR, + bin_dir=const.BINDIR, + exename=EXENAME, + working_directory=sys.path[0], + no_restore=False) + +# Add the index.razor.cs file +with open(f"{const.APPDIR}/Pages/Index.razor.cs", "w") as indexCSFile: + indexCSFile.write(''' + using Microsoft.AspNetCore.Components; + #if ANDROID + using Android.App; + #endif\n\n''' + + f" namespace {EXENAME}.Pages" + +''' + { + public partial class Index + { + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + #if ANDROID + var activity = MainActivity.Context as Activity; + activity.ReportFullyDrawn(); + #else + System.Console.WriteLine(\"__MAUI_Blazor_WebView_OnAfterRender__\"); + #endif + } + } + } + } +''') + +# Replace line in the Android MainActivity.cs file +with open(f"{const.APPDIR}/Platforms/Android/MainActivity.cs", "r") as mainActivityFile: + mainActivityFileLines = mainActivityFile.readlines() + +with open(f"{const.APPDIR}/Platforms/Android/MainActivity.cs", "w") as mainActivityFile: + for line in mainActivityFileLines: + if line.startswith("{"): + mainActivityFile.write("{\npublic static Android.Content.Context Context { get; private set; }\npublic MainActivity() { Context = this; }") + else: + mainActivityFile.write(line) + +# Build the APK +precommands.execute(['--no-restore', '--source', 'MauiNuGet.config']) + +output_dir = const.PUBDIR +if precommands.output: + output_dir = precommands.output +RemoveAABFiles(output_dir) + +# Copy the MauiVersion to a file so we have it on the machine +maui_version = GetVersionFromDllPowershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll") +version_dict = { "mauiVersion": maui_version } +versionswritejson(version_dict, rf"{output_dir}\versions.json") +print(f"Versions: {version_dict}") diff --git a/src/scenarios/mauiblazorandroid/test.py b/src/scenarios/mauiblazorandroid/test.py index 743d5eaeb65..c1b2ce9542a 100644 --- a/src/scenarios/mauiblazorandroid/test.py +++ b/src/scenarios/mauiblazorandroid/test.py @@ -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 versionsreadjsonfilesaveenv EXENAME = 'MauiBlazorAndroidDefault' if __name__ == "__main__": + versionsreadjsonfilesaveenv(rf".\{PUBDIR}\versions.json") + traits = TestTraits(exename=EXENAME, guiapp='false', ) diff --git a/src/scenarios/mauishared/mauisharedpython.py b/src/scenarios/mauishared/mauisharedpython.py new file mode 100644 index 00000000000..127c712bfee --- /dev/null +++ b/src/scenarios/mauishared/mauisharedpython.py @@ -0,0 +1,9 @@ +import subprocess +import os + +# Remove the aab files as we don't need them, this saves space in the correlation payload +def RemoveAABFiles(output_dir="."): + file_list = os.listdir(output_dir) + for file in file_list: + if file.endswith(".aab"): + os.remove(os.path.join(output_dir, file)) diff --git a/src/scenarios/shared/versionmanager.py b/src/scenarios/shared/versionmanager.py new file mode 100644 index 00000000000..acaf5ed0bb2 --- /dev/null +++ b/src/scenarios/shared/versionmanager.py @@ -0,0 +1,31 @@ +''' +Version File Manager +''' +import json +import os +import subprocess + +def versionswritejson(versiondict: dict, outputfile = 'versions.json'): + with open(outputfile, 'w') as file: + json.dump(versiondict, file) + +def versionsreadjson(inputfile = 'versions.json'): + with open(inputfile, 'r') as file: + return json.load(file) + +def versionswriteenv(versiondict: dict): + for key, value in versiondict.items(): + os.environ[key] = value + +def versionsreadjsonfilesaveenv(inputfile = 'versions.json'): + versions = versionsreadjson(inputfile) + print(f"Versions: {versions}") + versionswriteenv(versions) + + # Remove the versions.json file if we are in the lab to ensure SOD doesn't pick it up + if "PERFLAB_INLAB" in os.environ and os.environ["PERFLAB_INLAB"] == "1": + os.remove(inputfile) + +def GetVersionFromDllPowershell(dll_path: str): + result = subprocess.run(['powershell', '-Command', rf'Get-ChildItem {dll_path} | Select-Object -ExpandProperty VersionInfo | Select-Object -ExpandProperty ProductVersion'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) + return result.stdout.decode('utf-8').strip() diff --git a/src/tools/Reporting/Reporting.Tests/EnvironmentProviderMock.cs b/src/tools/Reporting/Reporting.Tests/EnvironmentProviderMock.cs index cf33c408fe3..1939998e176 100644 --- a/src/tools/Reporting/Reporting.Tests/EnvironmentProviderMock.cs +++ b/src/tools/Reporting/Reporting.Tests/EnvironmentProviderMock.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; using System.Collections.Generic; namespace Reporting.Tests @@ -14,6 +15,10 @@ public string GetEnvironmentVariable(string variable) { return Vars?[variable]; } + public IDictionary GetEnvironmentVariables() + { + return Vars; + } } internal class PerfLabEnvironmentProviderMock : EnvironmentProviderMockBase { @@ -23,6 +28,7 @@ public PerfLabEnvironmentProviderMock() { {"PERFLAB_INLAB", "1" }, {"HELIX_CORRELATION_ID","testCorrelationId" }, + {"HELIX_WORKITEM_FRIENDLYNAME","Test Friendly Name" }, {"PERFLAB_PERFHASH","testPerfHash" }, {"PERFLAB_QUEUE","testQueue" }, {"PERFLAB_REPO","testRepo" }, @@ -34,7 +40,7 @@ public PerfLabEnvironmentProviderMock() {"PERFLAB_HIDDEN", "false" }, {"PERFLAB_RUNNAME", "testRunName" }, {"PERFLAB_CONFIGS", "KEY1=VALUE1;KEY2=VALUE2" }, - {"PERFLAB_BUILDTIMESTAMP", new DateTime(1970,1,1).ToString("o") }, + {"PERFLAB_BUILDTIMESTAMP", new DateTime(1970,1,1).ToString("o") } }; } diff --git a/src/tools/Reporting/Reporting.Tests/ReporterTests.cs b/src/tools/Reporting/Reporting.Tests/ReporterTests.cs index c354d23b90f..dca49fe5314 100644 --- a/src/tools/Reporting/Reporting.Tests/ReporterTests.cs +++ b/src/tools/Reporting/Reporting.Tests/ReporterTests.cs @@ -106,6 +106,7 @@ public void JsonCanBeGenerated() var jsonObj = JsonConvert.DeserializeAnonymousType(jsonString, jsonType); Assert.Equal(environment.GetEnvironmentVariable("HELIX_CORRELATION_ID"), jsonObj.Run.CorrelationId); + Assert.Equal(environment.GetEnvironmentVariable("HELIX_WORKITEM_FRIENDLYNAME"), jsonObj.Run.WorkItemName); Assert.Equal(environment.GetEnvironmentVariable("PERFLAB_PERFHASH"), jsonObj.Run.PerfRepoHash); Assert.Equal(environment.GetEnvironmentVariable("PERFLAB_QUEUE"), jsonObj.Run.Queue); Assert.Equal(environment.GetEnvironmentVariable("PERFLAB_REPO"), jsonObj.Build.Repo); diff --git a/src/tools/Reporting/Reporting/EnvironmentProvider.cs b/src/tools/Reporting/Reporting/EnvironmentProvider.cs index 90d28729284..11336a24fce 100644 --- a/src/tools/Reporting/Reporting/EnvironmentProvider.cs +++ b/src/tools/Reporting/Reporting/EnvironmentProvider.cs @@ -11,5 +11,6 @@ namespace Reporting public class EnvironmentProvider : IEnvironment { public string GetEnvironmentVariable(string variable) => Environment.GetEnvironmentVariable(variable); + public System.Collections.IDictionary GetEnvironmentVariables() => Environment.GetEnvironmentVariables(); } } diff --git a/src/tools/Reporting/Reporting/IEnvironment.cs b/src/tools/Reporting/Reporting/IEnvironment.cs index c7dbfb9b002..409edd14285 100644 --- a/src/tools/Reporting/Reporting/IEnvironment.cs +++ b/src/tools/Reporting/Reporting/IEnvironment.cs @@ -2,14 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Text; - namespace Reporting { public interface IEnvironment { string GetEnvironmentVariable(string variable); + System.Collections.IDictionary GetEnvironmentVariables(); } } diff --git a/src/tools/Reporting/Reporting/Reporter.cs b/src/tools/Reporting/Reporting/Reporter.cs index a2ba6e67c2a..3ae4a4a402b 100644 --- a/src/tools/Reporting/Reporting/Reporter.cs +++ b/src/tools/Reporting/Reporting/Reporter.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; +using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -88,14 +89,24 @@ private void Init() BuildName = environment.GetEnvironmentVariable("PERFLAB_BUILDNUM"), TimeStamp = DateTime.Parse(environment.GetEnvironmentVariable("PERFLAB_BUILDTIMESTAMP")), }; - build.AdditionalData["productVersion"] = environment.GetEnvironmentVariable("DOTNET_VERSION"); - build.AdditionalData["targetFrameworks"] = environment.GetEnvironmentVariable("PERFLAB_TARGET_FRAMEWORKS"); - // Additional Data we only want populated if it is available - if (!String.IsNullOrEmpty(environment.GetEnvironmentVariable("MAUI_VERSION"))) - { - build.AdditionalData["mauiVersion"] = environment.GetEnvironmentVariable("MAUI_VERSION"); - } + foreach (DictionaryEntry entry in environment.GetEnvironmentVariables()){ + if (entry.Key.ToString().Equals("PERFLAB_TARGET_FRAMEWORKS", StringComparison.InvariantCultureIgnoreCase)) + { + build.AdditionalData["targetFrameworks"] = entry.Value.ToString(); + } + if (entry.Key.ToString().EndsWith("version", ignoreCase: true, culture: CultureInfo.InvariantCulture)) + { + // Special case the original two special cases, MAUI_VERSION is only needed because runtime based runs use MAUI_VERSION + if(entry.Key.ToString().Equals("DOTNET_VERSION", StringComparison.InvariantCultureIgnoreCase)){ + build.AdditionalData["productVersion"] = entry.Value.ToString(); + } else if(entry.Key.ToString().Equals("MAUI_VERSION", StringComparison.InvariantCultureIgnoreCase)){ + build.AdditionalData["mauiVersion"] = entry.Value.ToString(); + } else { + build.AdditionalData[entry.Key.ToString()] = entry.Value.ToString(); + } + } + } } public string GetJson() { From 0ef11345222335a502ee7ba5d16b3b0fff001c9f Mon Sep 17 00:00:00 2001 From: Parker Bibus Date: Tue, 17 Jan 2023 10:26:10 -0800 Subject: [PATCH 2/5] Fix reporter.cs build error. --- src/tools/Reporting/Reporting/Reporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Reporting/Reporting/Reporter.cs b/src/tools/Reporting/Reporting/Reporter.cs index 3ae4a4a402b..d81b0842bb8 100644 --- a/src/tools/Reporting/Reporting/Reporter.cs +++ b/src/tools/Reporting/Reporting/Reporter.cs @@ -95,7 +95,7 @@ private void Init() { build.AdditionalData["targetFrameworks"] = entry.Value.ToString(); } - if (entry.Key.ToString().EndsWith("version", ignoreCase: true, culture: CultureInfo.InvariantCulture)) + else if(entry.Key.ToString().EndsWith("version", true, CultureInfo.InvariantCulture)) { // Special case the original two special cases, MAUI_VERSION is only needed because runtime based runs use MAUI_VERSION if(entry.Key.ToString().Equals("DOTNET_VERSION", StringComparison.InvariantCultureIgnoreCase)){ From 118fe9589689d499af705059dc6c5aab4f07b7c7 Mon Sep 17 00:00:00 2001 From: Parker Bibus Date: Tue, 17 Jan 2023 16:40:03 -0800 Subject: [PATCH 3/5] Moved stopAppCmd so it is available even if there is an error beforehand, and strip the getActivity output to fix error with the activity name. --- src/scenarios/shared/runner.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/scenarios/shared/runner.py b/src/scenarios/shared/runner.py index 147c1f5b225..a2a3c8a9fc5 100644 --- a/src/scenarios/shared/runner.py +++ b/src/scenarios/shared/runner.py @@ -440,6 +440,14 @@ def run(self): getLogger().info(f"Animation values successfully set to {animationValue}.") try: + stopAppCmd = [ + adb.stdout.strip(), + 'shell', + 'am', + 'force-stop', + self.packagename + ] + installCmd = xharnesscommand() + [ 'android', 'install', @@ -493,7 +501,7 @@ def run(self): # Actual testing some run stuff getLogger().info("Test run to check if permissions are needed") - activityname = getActivity.stdout + activityname = getActivity.stdout.strip() # -W in the start command waits for the app to finish initial draw. startAppCmd = [ @@ -509,18 +517,9 @@ def run(self): testRun.run() testRunStats = re.findall(runSplitRegex, testRun.stdout) # Split results saving value (List: Starting, Status, LaunchState, Activity, TotalTime, WaitTime) getLogger().info(f"Test run activity: {testRunStats[3]}") - time.sleep(10) # Add delay to ensure app is fully installed and give it some time to settle - - stopAppCmd = [ - adb.stdout.strip(), - 'shell', - 'am', - 'force-stop', - self.packagename - ] + RunCommand(stopAppCmd, verbose=True).run() - if "com.google.android.permissioncontroller" in testRunStats[3]: # On perm screen, use the buttons to close it. it will stay away until the app is reinstalled RunCommand(keyInputCmd + ['22'], verbose=True).run() # Select next button From 8167f1651605ef7537d43c0f0821178944a462d3 Mon Sep 17 00:00:00 2001 From: Parker Bibus Date: Wed, 18 Jan 2023 14:01:23 -0800 Subject: [PATCH 4/5] Fixed nitpicks including using proper function naming conventions, misc spacing, and consolidating reused maui methods into mauisharedpython. Also moved mauisharedpython from its own folder to the general shared folder since it was the only file in the maui specific shared folder. --- src/scenarios/mauiandroid/pre.py | 22 +++++-------------- src/scenarios/mauiandroid/test.py | 4 ++-- src/scenarios/mauiandroidpodcast/pre.py | 23 ++++++-------------- src/scenarios/mauiandroidpodcast/test.py | 4 ++-- src/scenarios/mauiblazorandroid/pre.py | 22 +++++-------------- src/scenarios/mauiblazorandroid/test.py | 4 ++-- src/scenarios/mauishared/mauisharedpython.py | 9 -------- src/scenarios/shared/mauisharedpython.py | 22 +++++++++++++++++++ src/scenarios/shared/versionmanager.py | 14 ++++++------ src/tools/Reporting/Reporting/Reporter.cs | 3 ++- 10 files changed, 56 insertions(+), 71 deletions(-) delete mode 100644 src/scenarios/mauishared/mauisharedpython.py create mode 100644 src/scenarios/shared/mauisharedpython.py diff --git a/src/scenarios/mauiandroid/pre.py b/src/scenarios/mauiandroid/pre.py index b51ee5f4f1e..0e64ea31ead 100644 --- a/src/scenarios/mauiandroid/pre.py +++ b/src/scenarios/mauiandroid/pre.py @@ -3,27 +3,17 @@ ''' import sys import requests -from mauishared.mauisharedpython import RemoveAABFiles from performance.logger import setup_loggers, getLogger from shared import const +from shared.mauisharedpython import remove_aab_files, install_versioned_maui from shared.precommands import PreCommands -from shared.versionmanager import versionswritejson, GetVersionFromDllPowershell +from shared.versionmanager import versions_write_json, get_version_from_dll_powershell from test import EXENAME setup_loggers(True) precommands = PreCommands() -target_framework_wo_platform = precommands.framework.split('-')[0] - -# Download what we need -with open ("MauiNuGet.config", "wb") as f: - f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) - -workload_install_args = ['--configfile', 'MauiNuGet.config'] -if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 - workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] - -precommands.install_workload('maui', workload_install_args) +install_versioned_maui(precommands) # Setup the Maui folder precommands.new(template='maui', @@ -40,10 +30,10 @@ output_dir = const.PUBDIR if precommands.output: output_dir = precommands.output -RemoveAABFiles(output_dir) +remove_aab_files(output_dir) # Copy the MauiVersion to a file so we have it on the machine -maui_version = GetVersionFromDllPowershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll") +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 } -versionswritejson(version_dict, rf"{output_dir}\versions.json") +versions_write_json(version_dict, rf"{output_dir}\versions.json") print(f"Versions: {version_dict}") diff --git a/src/scenarios/mauiandroid/test.py b/src/scenarios/mauiandroid/test.py index 75fb182f2c7..5976d343ee1 100644 --- a/src/scenarios/mauiandroid/test.py +++ b/src/scenarios/mauiandroid/test.py @@ -3,12 +3,12 @@ ''' from shared.const import PUBDIR from shared.runner import TestTraits, Runner -from shared.versionmanager import versionsreadjsonfilesaveenv +from shared.versionmanager import versions_read_json_file_save_env EXENAME = 'MauiAndroidDefault' if __name__ == "__main__": - versionsreadjsonfilesaveenv(rf".\{PUBDIR}\versions.json") + versions_read_json_file_save_env(rf".\{PUBDIR}\versions.json") traits = TestTraits(exename=EXENAME, guiapp='false', diff --git a/src/scenarios/mauiandroidpodcast/pre.py b/src/scenarios/mauiandroidpodcast/pre.py index db9d4aae7e6..f5b5fd0514e 100644 --- a/src/scenarios/mauiandroidpodcast/pre.py +++ b/src/scenarios/mauiandroidpodcast/pre.py @@ -3,30 +3,21 @@ ''' import requests import subprocess -from mauishared.mauisharedpython import RemoveAABFiles from performance.logger import setup_loggers, getLogger from shared.precommands import PreCommands -from shared.versionmanager import versionswritejson, GetVersionFromDllPowershell +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() -target_framework_wo_platform = precommands.framework.split('-')[0] - -# Download what we need -with open ("MauiNuGet.config", "wb") as f: - f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) +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 -workload_install_args = ['--configfile', 'MauiNuGet.config'] -if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 - workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] - -precommands.install_workload('maui', workload_install_args) -precommands.existing(projectdir='./dotnet-podcasts',projectfile='./src/Mobile/Microsoft.NetConf2021.Maui.csproj') +precommands.existing(projectdir='./dotnet-podcasts', projectfile='./src/Mobile/Microsoft.NetConf2021.Maui.csproj') # Build the APK precommands._restore() @@ -36,10 +27,10 @@ output_dir = const.PUBDIR if precommands.output: output_dir = precommands.output -RemoveAABFiles(output_dir) +remove_aab_files(output_dir) # Copy the MauiVersion to a file so we have it on the machine -maui_version = GetVersionFromDllPowershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll") +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 } -versionswritejson(version_dict, rf"{output_dir}\versions.json") +versions_write_json(version_dict, rf"{output_dir}\versions.json") print(f"Versions: {version_dict}") diff --git a/src/scenarios/mauiandroidpodcast/test.py b/src/scenarios/mauiandroidpodcast/test.py index 1e557a00e46..45b26f7a7a9 100644 --- a/src/scenarios/mauiandroidpodcast/test.py +++ b/src/scenarios/mauiandroidpodcast/test.py @@ -3,12 +3,12 @@ ''' from shared.const import PUBDIR from shared.runner import TestTraits, Runner -from shared.versionmanager import versionsreadjsonfilesaveenv +from shared.versionmanager import versions_read_json_file_save_env EXENAME = 'MauiAndroidPodcast' if __name__ == "__main__": - versionsreadjsonfilesaveenv(rf".\{PUBDIR}\versions.json") + versions_read_json_file_save_env(rf".\{PUBDIR}\versions.json") traits = TestTraits(exename=EXENAME, guiapp='false', diff --git a/src/scenarios/mauiblazorandroid/pre.py b/src/scenarios/mauiblazorandroid/pre.py index e49f893692b..fa20bdd595d 100644 --- a/src/scenarios/mauiblazorandroid/pre.py +++ b/src/scenarios/mauiblazorandroid/pre.py @@ -3,26 +3,16 @@ ''' import sys import requests -from mauishared.mauisharedpython import RemoveAABFiles from performance.logger import setup_loggers, getLogger from shared import const +from shared.mauisharedpython import remove_aab_files, install_versioned_maui from shared.precommands import PreCommands -from shared.versionmanager import versionswritejson, GetVersionFromDllPowershell +from shared.versionmanager import versions_write_json, get_version_from_dll_powershell from test import EXENAME setup_loggers(True) precommands = PreCommands() -target_framework_wo_platform = precommands.framework.split('-')[0] - -# Download what we need -with open ("MauiNuGet.config", "wb") as f: - f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) - -workload_install_args = ['--configfile', 'MauiNuGet.config'] -if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 - workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] - -precommands.install_workload('maui', workload_install_args) +install_versioned_maui(precommands) # Setup the Maui folder precommands.new(template='maui-blazor', @@ -77,11 +67,11 @@ output_dir = const.PUBDIR if precommands.output: output_dir = precommands.output -RemoveAABFiles(output_dir) +remove_aab_files(output_dir) # Copy the MauiVersion to a file so we have it on the machine -maui_version = GetVersionFromDllPowershell(rf".\{const.APPDIR}\obj\Release\{precommands.framework}\{precommands.runtime_identifier}\linked\Microsoft.Maui.dll") +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 } -versionswritejson(version_dict, rf"{output_dir}\versions.json") +versions_write_json(version_dict, rf"{output_dir}\versions.json") print(f"Versions: {version_dict}") diff --git a/src/scenarios/mauiblazorandroid/test.py b/src/scenarios/mauiblazorandroid/test.py index c1b2ce9542a..a1cee6eba62 100644 --- a/src/scenarios/mauiblazorandroid/test.py +++ b/src/scenarios/mauiblazorandroid/test.py @@ -3,12 +3,12 @@ ''' from shared.const import PUBDIR from shared.runner import TestTraits, Runner -from shared.versionmanager import versionsreadjsonfilesaveenv +from shared.versionmanager import versions_read_json_file_save_env EXENAME = 'MauiBlazorAndroidDefault' if __name__ == "__main__": - versionsreadjsonfilesaveenv(rf".\{PUBDIR}\versions.json") + versions_read_json_file_save_env(rf".\{PUBDIR}\versions.json") traits = TestTraits(exename=EXENAME, guiapp='false', diff --git a/src/scenarios/mauishared/mauisharedpython.py b/src/scenarios/mauishared/mauisharedpython.py deleted file mode 100644 index 127c712bfee..00000000000 --- a/src/scenarios/mauishared/mauisharedpython.py +++ /dev/null @@ -1,9 +0,0 @@ -import subprocess -import os - -# Remove the aab files as we don't need them, this saves space in the correlation payload -def RemoveAABFiles(output_dir="."): - file_list = os.listdir(output_dir) - for file in file_list: - if file.endswith(".aab"): - os.remove(os.path.join(output_dir, file)) diff --git a/src/scenarios/shared/mauisharedpython.py b/src/scenarios/shared/mauisharedpython.py new file mode 100644 index 00000000000..986cc6c6489 --- /dev/null +++ b/src/scenarios/shared/mauisharedpython.py @@ -0,0 +1,22 @@ +import subprocess +import os + +# Remove the aab files as we don't need them, this saves space in the correlation payload +def remove_aab_files(output_dir="."): + file_list = os.listdir(output_dir) + for file in file_list: + if file.endswith(".aab"): + os.remove(os.path.join(output_dir, file)) + +def install_versioned_maui(precommands): + target_framework_wo_platform = precommands.framework.split('-')[0] + + # Download what we need + with open ("MauiNuGet.config", "wb") as f: + f.write(requests.get(f'https://raw.githubusercontent.com/dotnet/maui/{target_framework_wo_platform}/NuGet.config', allow_redirects=True).content) + + workload_install_args = ['--configfile', 'MauiNuGet.config'] + if int(target_framework_wo_platform.split('.')[0][3:]) > 7: # Use the rollback file for versions greater than 7 + workload_install_args += ['--from-rollback-file', f'https://aka.ms/dotnet/maui/{target_framework_wo_platform}.json'] + + precommands.install_workload('maui', workload_install_args) diff --git a/src/scenarios/shared/versionmanager.py b/src/scenarios/shared/versionmanager.py index acaf5ed0bb2..59ad96cb657 100644 --- a/src/scenarios/shared/versionmanager.py +++ b/src/scenarios/shared/versionmanager.py @@ -5,27 +5,27 @@ import os import subprocess -def versionswritejson(versiondict: dict, outputfile = 'versions.json'): +def versions_write_json(versiondict: dict, outputfile = 'versions.json'): with open(outputfile, 'w') as file: json.dump(versiondict, file) -def versionsreadjson(inputfile = 'versions.json'): +def versions_read_json(inputfile = 'versions.json'): with open(inputfile, 'r') as file: return json.load(file) -def versionswriteenv(versiondict: dict): +def versions_write_env(versiondict: dict): for key, value in versiondict.items(): os.environ[key] = value -def versionsreadjsonfilesaveenv(inputfile = 'versions.json'): - versions = versionsreadjson(inputfile) +def versions_read_json_file_save_env(inputfile = 'versions.json'): + versions = versions_read_json(inputfile) print(f"Versions: {versions}") - versionswriteenv(versions) + versions_write_env(versions) # Remove the versions.json file if we are in the lab to ensure SOD doesn't pick it up if "PERFLAB_INLAB" in os.environ and os.environ["PERFLAB_INLAB"] == "1": os.remove(inputfile) -def GetVersionFromDllPowershell(dll_path: str): +def get_version_from_dll_powershell(dll_path: str): result = subprocess.run(['powershell', '-Command', rf'Get-ChildItem {dll_path} | Select-Object -ExpandProperty VersionInfo | Select-Object -ExpandProperty ProductVersion'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) return result.stdout.decode('utf-8').strip() diff --git a/src/tools/Reporting/Reporting/Reporter.cs b/src/tools/Reporting/Reporting/Reporter.cs index d81b0842bb8..13a606b57a3 100644 --- a/src/tools/Reporting/Reporting/Reporter.cs +++ b/src/tools/Reporting/Reporting/Reporter.cs @@ -90,7 +90,8 @@ private void Init() TimeStamp = DateTime.Parse(environment.GetEnvironmentVariable("PERFLAB_BUILDTIMESTAMP")), }; - foreach (DictionaryEntry entry in environment.GetEnvironmentVariables()){ + foreach (DictionaryEntry entry in environment.GetEnvironmentVariables()) + { if (entry.Key.ToString().Equals("PERFLAB_TARGET_FRAMEWORKS", StringComparison.InvariantCultureIgnoreCase)) { build.AdditionalData["targetFrameworks"] = entry.Value.ToString(); From 68a5509ceec0eaff8d1ae8f54bdcc91ae39cb212 Mon Sep 17 00:00:00 2001 From: Parker Bibus Date: Thu, 19 Jan 2023 14:34:30 -0800 Subject: [PATCH 5/5] Added in missing requests import and removed it from places it is no longer needed. --- src/scenarios/mauiandroid/pre.py | 1 - src/scenarios/mauiandroidpodcast/pre.py | 1 - src/scenarios/mauiblazorandroid/pre.py | 1 - src/scenarios/shared/mauisharedpython.py | 2 ++ 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/scenarios/mauiandroid/pre.py b/src/scenarios/mauiandroid/pre.py index 0e64ea31ead..ac601ac1a1b 100644 --- a/src/scenarios/mauiandroid/pre.py +++ b/src/scenarios/mauiandroid/pre.py @@ -2,7 +2,6 @@ pre-command ''' import sys -import requests from performance.logger import setup_loggers, getLogger from shared import const from shared.mauisharedpython import remove_aab_files, install_versioned_maui diff --git a/src/scenarios/mauiandroidpodcast/pre.py b/src/scenarios/mauiandroidpodcast/pre.py index f5b5fd0514e..fb6d4a3d1ef 100644 --- a/src/scenarios/mauiandroidpodcast/pre.py +++ b/src/scenarios/mauiandroidpodcast/pre.py @@ -1,7 +1,6 @@ ''' pre-command ''' -import requests import subprocess from performance.logger import setup_loggers, getLogger from shared.precommands import PreCommands diff --git a/src/scenarios/mauiblazorandroid/pre.py b/src/scenarios/mauiblazorandroid/pre.py index fa20bdd595d..1db66143985 100644 --- a/src/scenarios/mauiblazorandroid/pre.py +++ b/src/scenarios/mauiblazorandroid/pre.py @@ -2,7 +2,6 @@ pre-command ''' import sys -import requests from performance.logger import setup_loggers, getLogger from shared import const from shared.mauisharedpython import remove_aab_files, install_versioned_maui diff --git a/src/scenarios/shared/mauisharedpython.py b/src/scenarios/shared/mauisharedpython.py index 986cc6c6489..bf404baa91f 100644 --- a/src/scenarios/shared/mauisharedpython.py +++ b/src/scenarios/shared/mauisharedpython.py @@ -1,5 +1,7 @@ import subprocess import os +import requests +from shared.precommands import PreCommands # Remove the aab files as we don't need them, this saves space in the correlation payload def remove_aab_files(output_dir="."):