diff --git a/eng/performance/build_machine_matrix.yml b/eng/performance/build_machine_matrix.yml
index 976a0e71478..3cd0f3cf902 100644
--- a/eng/performance/build_machine_matrix.yml
+++ b/eng/performance/build_machine_matrix.yml
@@ -110,9 +110,9 @@ jobs:
parameters:
osName: osx
architecture: x64
- osVersion: 12
+ osVersion: 13
pool:
- vmImage: 'macos-12'
- queue: OSX.1015.Amd64.Iphone.Perf
+ vmImage: 'macos-13'
+ queue: OSX.13.Amd64.Iphone.Perf
machinePool: iPhoneMini12
${{ insert }}: ${{ parameters.jobParameters }}
diff --git a/eng/performance/maui_scenarios_ios.proj b/eng/performance/maui_scenarios_ios.proj
index 393529f1020..19605345c62 100644
--- a/eng/performance/maui_scenarios_ios.proj
+++ b/eng/performance/maui_scenarios_ios.proj
@@ -3,6 +3,7 @@
true
+ 9.0.0-prerelease.23606.1
diff --git a/src/scenarios/shared/runner.py b/src/scenarios/shared/runner.py
index 86acf00715d..30b2f46ceea 100644
--- a/src/scenarios/shared/runner.py
+++ b/src/scenarios/shared/runner.py
@@ -2,15 +2,15 @@
Module for running scenario tasks
'''
-from genericpath import exists
import sys
import os
import glob
import re
import time
-from datetime import datetime
import json
+from genericpath import exists
+from datetime import datetime, timedelta
from logging import exception, getLogger
from collections import namedtuple
from argparse import ArgumentParser
@@ -666,9 +666,22 @@ def run(self):
getLogger().info("Checking device state.")
cmdline = xharnesscommand() + ['apple', 'state']
- adb = RunCommand(cmdline, verbose=True)
- adb.run()
-
+ apple_state = RunCommand(cmdline, verbose=True)
+ apple_state.run()
+
+ # Get the name and version of the device from the output of apple_state above
+ # Example output expected (PERFIOS-01 is the device name, and 17.0.2 is the version):
+ # Connected Devices:
+ # PERFIOS-01 00008101-001A09223E08001E 17.0.2 iPhone iOS
+ deviceInfoMatch = re.search(r'Connected Devices:\s+(?P\S+)\s+\S+\s+(?P\S+)', apple_state.stdout)
+ if deviceInfoMatch:
+ deviceName = deviceInfoMatch.group('deviceName')
+ deviceVersion = deviceInfoMatch.group('deviceVersion')
+ getLogger().info(f"Device Name: {deviceName}")
+ getLogger().info(f"Device Version: {deviceVersion}")
+ else:
+ raise Exception("Device name or version not found in the output of apple_state command.")
+
getLogger().info("Installing app on device.")
installCmd = xharnesscommand() + [
'apple',
@@ -683,17 +696,19 @@ def run(self):
getLogger().info("Completed install.")
allResults = []
+ timeToFirstDrawEventEndDateTime = datetime.now() # This is used to keep track of the latest time to draw end event, we use this to calculate time to draw and also as a reference point for the next iteration log time.
for i in range(self.startupiterations + 1): # adding one iteration to account for the warmup iteration
getLogger().info("Waiting 10 secs to ensure we're not getting confused with previous app run.")
time.sleep(10)
getLogger().info(f"Collect startup data for iteration {i}.")
- runCmdTimestamp = datetime.now()
+ runCmdTimestamp = timeToFirstDrawEventEndDateTime + timedelta(seconds=1)
runCmd = xharnesscommand() + [
'apple',
'mlaunch',
'--',
- f'--launchdevbundleid={self.packagename}',
+ '--launchdev', self.packagepath,
+ '--devname', deviceName
]
runCmdCommand = RunCommand(runCmd, verbose=True)
@@ -726,7 +741,12 @@ def run(self):
getLogger().error("App launch failed, please rerun the script to start a new measurement.")
raise
- app_pid_search = re.search("Launched application.*with pid (?P\d+)", runCmdCommand.stdout)
+ # If the device version is less than 17 we need to use the old pid search
+ # otherwise we use the new pid search
+ if deviceVersion < '17':
+ app_pid_search = re.search(r"Launched application.*with pid (?P\d+)", runCmdCommand.stdout)
+ else:
+ app_pid_search = re.search(r"The app.*launched with pid (?P\d+)", runCmdCommand.stdout)
app_pid = int(app_pid_search.group('app_pid'))
logarchive_filename = os.path.join(const.TMPDIR, f'iteration{i}.logarchive')
@@ -748,6 +768,7 @@ def run(self):
'mlaunch',
'--',
f'--killdev={app_pid}',
+ '--devname', deviceName
]
killCmdCommand = RunCommand(killCmd, verbose=True)
killCmdCommand.run()
@@ -783,7 +804,7 @@ def run(self):
try:
lineData = json.loads(line)
if 'Now monitoring resource allowance' in lineData['eventMessage'] or 'Stopped monitoring' in lineData['eventMessage']:
- events.append (lineData)
+ events.append(lineData)
except:
break
@@ -799,16 +820,16 @@ def run(self):
timeToFirstDrawEventStop = events[3]
# validate log messages
- if f'application<{self.packagename}>:{app_pid}' not in timeToMainEventStart['eventMessage'] or 'Now monitoring resource allowance of 20.00s' not in timeToMainEventStart['eventMessage']:
+ if f'{self.packagename}' not in timeToMainEventStart['eventMessage'] or 'Now monitoring resource allowance of 20.00s' not in timeToMainEventStart['eventMessage']:
raise Exception(f"Invalid timeToMainEventStart: {timeToMainEventStart['eventMessage']}")
- if f'application<{self.packagename}>:{app_pid}' not in timeToMainEventStop['eventMessage'] or 'Stopped monitoring' not in timeToMainEventStop['eventMessage']:
+ if f'{self.packagename}' not in timeToMainEventStop['eventMessage'] or 'Stopped monitoring' not in timeToMainEventStop['eventMessage']:
raise Exception(f"Invalid timeToMainEventStop: {timeToMainEventStop['eventMessage']}")
- if f'application<{self.packagename}>:{app_pid}' not in timeToFirstDrawEventStart['eventMessage'] or 'Now monitoring resource allowance of' not in timeToFirstDrawEventStart['eventMessage']:
+ if f'{self.packagename}' not in timeToFirstDrawEventStart['eventMessage'] or 'Now monitoring resource allowance of' not in timeToFirstDrawEventStart['eventMessage']:
raise Exception(f"Invalid timeToFirstDrawEventStart: {timeToFirstDrawEventStart['eventMessage']}")
- if f'application<{self.packagename}>:{app_pid}' not in timeToFirstDrawEventStop['eventMessage'] or 'Stopped monitoring' not in timeToFirstDrawEventStop['eventMessage']:
+ if f'{self.packagename}' not in timeToFirstDrawEventStop['eventMessage'] or 'Stopped monitoring' not in timeToFirstDrawEventStop['eventMessage']:
raise Exception(f"Invalid timeToFirstDrawEventStop: {timeToFirstDrawEventStop['eventMessage']}")
timeToMainEventStartDateTime = datetime.strptime(timeToMainEventStart['timestamp'], '%Y-%m-%d %H:%M:%S.%f%z')