mirror of
https://github.com/servo/servo.git
synced 2025-07-05 14:33:38 +01:00
OHOS: Allow test-speedometer-ohos to run speedometer on the device (#37636)
Adds test-speedometer-ohos which will let it speedometer run on device. It assumes we already have servoshell installed on device. We then grab the log file, parse the json from it and output to bencher optionally. Requires https://github.com/servo/servo/pull/37690 and https://github.com/servo/servo/pull/37631 to be merged. Testing: Tested on device. Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
This commit is contained in:
parent
c67b0ab538
commit
d4c0d2ecbb
1 changed files with 98 additions and 26 deletions
|
@ -18,6 +18,7 @@ import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
import tidy
|
import tidy
|
||||||
import wpt
|
import wpt
|
||||||
|
@ -481,6 +482,12 @@ class MachCommands(CommandBase):
|
||||||
def test_speedometer(self, servo_binary: str, bmf_output: str | None = None):
|
def test_speedometer(self, servo_binary: str, bmf_output: str | None = None):
|
||||||
return self.speedometer_runner(servo_binary, bmf_output)
|
return self.speedometer_runner(servo_binary, bmf_output)
|
||||||
|
|
||||||
|
@Command("test-speedometer-ohos", description="Run servo's speedometer on a ohos device", category="testing")
|
||||||
|
@CommandArgument("--bmf-output", default=None, help="Specifcy BMF JSON output file")
|
||||||
|
# This needs to be a separate command because we do not need a binary locally
|
||||||
|
def test_speedometer_ohos(self, bmf_output: str | None = None):
|
||||||
|
return self.speedometer_runner_ohos(bmf_output)
|
||||||
|
|
||||||
@Command("update-jquery", description="Update the jQuery test suite expected results", category="testing")
|
@Command("update-jquery", description="Update the jQuery test suite expected results", category="testing")
|
||||||
@CommandBase.common_command_arguments(binary_selection=True)
|
@CommandBase.common_command_arguments(binary_selection=True)
|
||||||
def update_jquery(self, servo_binary: str):
|
def update_jquery(self, servo_binary: str):
|
||||||
|
@ -615,6 +622,37 @@ class MachCommands(CommandBase):
|
||||||
|
|
||||||
return check_call([run_file, "|".join(tests), bin_path, base_dir, bmf_output])
|
return check_call([run_file, "|".join(tests), bin_path, base_dir, bmf_output])
|
||||||
|
|
||||||
|
def speedometer_to_bmf(self, speedometer: str, bmf_output: str | None):
|
||||||
|
output = dict()
|
||||||
|
|
||||||
|
def parse_speedometer_result(result):
|
||||||
|
if result["unit"] == "ms":
|
||||||
|
output[f"Speedometer/{result['name']}"] = {
|
||||||
|
"latency": { # speedometer has ms we need to convert to ns
|
||||||
|
"value": float(result["mean"]) * 1000000.0,
|
||||||
|
"lower_value": float(result["min"]) * 1000000.0,
|
||||||
|
"upper_value": float(result["max"]) * 1000000.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elif result["unit"] == "score":
|
||||||
|
output[f"Speedometer/{result['name']}"] = {
|
||||||
|
"score": {
|
||||||
|
"value": float(result["mean"]),
|
||||||
|
"lower_value": float(result["min"]),
|
||||||
|
"upper_value": float(result["max"]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
raise "Unknown unit!"
|
||||||
|
|
||||||
|
for child in result["children"]:
|
||||||
|
parse_speedometer_result(child)
|
||||||
|
|
||||||
|
for v in speedometer.values():
|
||||||
|
parse_speedometer_result(v)
|
||||||
|
with open(bmf_output, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(output, f, indent=4)
|
||||||
|
|
||||||
def speedometer_runner(self, binary: str, bmf_output: str | None):
|
def speedometer_runner(self, binary: str, bmf_output: str | None):
|
||||||
speedometer = json.loads(
|
speedometer = json.loads(
|
||||||
subprocess.check_output(
|
subprocess.check_output(
|
||||||
|
@ -633,35 +671,69 @@ class MachCommands(CommandBase):
|
||||||
print(f"Score: {speedometer['Score']['mean']} ± {speedometer['Score']['delta']}")
|
print(f"Score: {speedometer['Score']['mean']} ± {speedometer['Score']['delta']}")
|
||||||
|
|
||||||
if bmf_output:
|
if bmf_output:
|
||||||
output = dict()
|
self.speedometer_to_bmf(speedometer, bmf_output)
|
||||||
|
|
||||||
def parse_speedometer_result(result):
|
def speedometer_runner_ohos(self, bmf_output: str | None):
|
||||||
if result["unit"] == "ms":
|
hdc_path: str = shutil.which("hdc")
|
||||||
output[f"Speedometer/{result['name']}"] = {
|
log_path: str = "/data/app/el2/100/base/org.servo.servo/cache/servo.log"
|
||||||
"latency": { # speedometer has ms we need to convert to ns
|
if hdc_path is None:
|
||||||
"value": float(result["mean"]) * 1000.0,
|
hdc_path = path.join(os.getenv("OHOS_SDK_NATIVE"), "../", "toolchains", "hdc")
|
||||||
"lower_value": float(result["min"]) * 1000.0,
|
|
||||||
"upper_value": float(result["max"]) * 1000.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elif result["unit"] == "score":
|
|
||||||
output[f"Speedometer/{result['name']}"] = {
|
|
||||||
"score": {
|
|
||||||
"value": float(result["mean"]),
|
|
||||||
"lower_value": float(result["min"]),
|
|
||||||
"upper_value": float(result["max"]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
raise "Unknown unit!"
|
|
||||||
|
|
||||||
for child in result["children"]:
|
def read_log_file() -> str:
|
||||||
parse_speedometer_result(child)
|
subprocess.call([hdc_path, "file", "recv", log_path])
|
||||||
|
file = ""
|
||||||
|
try:
|
||||||
|
file = open("servo.log")
|
||||||
|
except OSError:
|
||||||
|
return ""
|
||||||
|
return file.read()
|
||||||
|
|
||||||
for v in speedometer.values():
|
subprocess.call([hdc_path, "shell", "aa", "force-stop", "org.servo.servo"])
|
||||||
parse_speedometer_result(v)
|
|
||||||
with open(bmf_output, "w", encoding="utf-8") as f:
|
subprocess.call([hdc_path, "shell", "rm", log_path])
|
||||||
json.dump(output, f, indent=4)
|
subprocess.call(
|
||||||
|
[
|
||||||
|
hdc_path,
|
||||||
|
"shell",
|
||||||
|
"aa",
|
||||||
|
"start",
|
||||||
|
"-a",
|
||||||
|
"EntryAbility",
|
||||||
|
"-b",
|
||||||
|
"org.servo.servo",
|
||||||
|
"-U",
|
||||||
|
"https://servospeedometer.netlify.app?headless=1",
|
||||||
|
"--ps",
|
||||||
|
"--log-filter",
|
||||||
|
"script::dom::console",
|
||||||
|
"--psn",
|
||||||
|
"--log-to-file",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# A current (2025-06-23) run took 3m 49s = 229s. We keep a safety margin
|
||||||
|
# but we will exit earlier if we see "{"
|
||||||
|
# Currently ohos has a bug where the event loop gets stuck. We produce a
|
||||||
|
# touch event every minute to prevent this
|
||||||
|
# See https://github.com/servo/servo/issues/37727
|
||||||
|
whole_file: str = ""
|
||||||
|
for i in range(10):
|
||||||
|
sleep(30)
|
||||||
|
subprocess.call([hdc_path, "shell", "uinput", "-T", "-d", "100", "100"])
|
||||||
|
subprocess.call([hdc_path, "shell", "uinput", "-T", "-u", "105", "105"])
|
||||||
|
whole_file = read_log_file()
|
||||||
|
if "[INFO script::dom::console]" in whole_file:
|
||||||
|
# technically the file could not have been written completely yet
|
||||||
|
# on devices with slow flash, we might want to wait a bit more
|
||||||
|
sleep(2)
|
||||||
|
whole_file = read_log_file()
|
||||||
|
break
|
||||||
|
start_index: int = whole_file.index("[INFO script::dom::console]") + len("[INFO script::dom::console]") + 1
|
||||||
|
json_string = whole_file[start_index:]
|
||||||
|
speedometer = json.loads(json_string)
|
||||||
|
print(f"Score: {speedometer['Score']['mean']} ± {speedometer['Score']['delta']}")
|
||||||
|
if bmf_output:
|
||||||
|
self.speedometer_to_bmf(speedometer, bmf_output)
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
"update-net-cookies",
|
"update-net-cookies",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue