mirror of
https://github.com/LTTLabsOSS/markbench-tests.git
synced 2026-01-09 22:18:00 -05:00
James round seconds (#129)
this is a ford of jd/harness-fixes that is currently live on the benches, the ONLY thing i changed is im rounding the timestamps to the nearest second please approve --------- Co-authored-by: J-Doiron <139803019+J-Doiron@users.noreply.github.com>
This commit is contained in:
160
hitman3/hitman3.py
Normal file
160
hitman3/hitman3.py
Normal file
@@ -0,0 +1,160 @@
|
||||
"""Hitman World of Assassination test script"""
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
import psutil
|
||||
import pyautogui as gui
|
||||
import sys
|
||||
import winreg
|
||||
|
||||
from hitman3_utils import get_resolution, get_args, process_registry_file, get_benchmark_name
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
||||
|
||||
from harness_utils.keras_service import KerasService
|
||||
from harness_utils.output import (
|
||||
seconds_to_milliseconds,
|
||||
setup_log_directory,
|
||||
write_report_json,
|
||||
DEFAULT_LOGGING_FORMAT,
|
||||
DEFAULT_DATE_FORMAT,
|
||||
)
|
||||
from harness_utils.steam import (
|
||||
exec_steam_run_command,
|
||||
get_build_id
|
||||
)
|
||||
from harness_utils.artifacts import ArtifactManager, ArtifactType
|
||||
|
||||
STEAM_GAME_ID = 1659040
|
||||
STEAM_PATH = os.path.join(os.environ["ProgramFiles(x86)"], "steam")
|
||||
STEAM_EXECUTABLE = "steam.exe"
|
||||
PROCESS_NAMES = ['HITMAN3.exe', 'Launcher.exe']
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
log_dir = os.path.join(script_dir, "run")
|
||||
|
||||
input_file = os.path.join(script_dir, 'graphics.reg')
|
||||
config_file = os.path.join(script_dir, 'graphics_config.txt')
|
||||
hive = winreg.HKEY_CURRENT_USER
|
||||
SUBKEY = r"SOFTWARE\\IO Interactive\\HITMAN3"
|
||||
|
||||
def benchmark_check():
|
||||
benchmark_id = get_benchmark_name(config_file)
|
||||
if benchmark_id == 0:
|
||||
benchmark_name = "Hitman World of Assassination: Dubai"
|
||||
benchmark_time = 102
|
||||
elif benchmark_id == 1:
|
||||
benchmark_name = "Hitman World of Assassination: Dartmoor"
|
||||
benchmark_time = 140
|
||||
else:
|
||||
raise ValueError("Could not determine the benchmark. Is there an error in the registry?")
|
||||
|
||||
return benchmark_name, benchmark_time
|
||||
|
||||
|
||||
def run_benchmark():
|
||||
setup_start_time = int(time.time())
|
||||
am = ArtifactManager(log_dir)
|
||||
process_registry_file(hive, SUBKEY, input_file, config_file)
|
||||
am.copy_file(config_file, ArtifactType.CONFIG_TEXT, "config file")
|
||||
benchmark_name, benchmark_time = benchmark_check()
|
||||
exec_steam_run_command(STEAM_GAME_ID)
|
||||
|
||||
time.sleep(2)
|
||||
location = gui.locateOnScreen(f"{script_dir}\\screenshots\\options.png", confidence=0.7) #luckily this seems to be a set resolution for the button
|
||||
click_me = gui.center(location)
|
||||
gui.moveTo(click_me.x, click_me.y)
|
||||
gui.mouseDown()
|
||||
time.sleep(0.2)
|
||||
gui.mouseUp()
|
||||
time.sleep(2)
|
||||
|
||||
am.take_screenshot("Options1.png", ArtifactType.CONFIG_IMAGE, "1st picture of options")
|
||||
time.sleep(1)
|
||||
gui.scroll(-1000)
|
||||
am.take_screenshot("Options2.png", ArtifactType.CONFIG_IMAGE, "2nd picture of options")
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
|
||||
location = gui.locateOnScreen(f"{script_dir}\\screenshots\\start_benchmark.png", confidence=0.7) #luckily this seems to be a set resolution for the button
|
||||
click_me = gui.center(location)
|
||||
gui.moveTo(click_me.x, click_me.y)
|
||||
gui.mouseDown()
|
||||
time.sleep(0.2)
|
||||
gui.mouseUp()
|
||||
time.sleep(0.2)
|
||||
|
||||
elapsed_setup_time = round(int(time.time()) - setup_start_time, 2)
|
||||
logging.info("Setup took %f seconds", elapsed_setup_time)
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
result = kerasService.look_for_word("crowd", attempts=20, interval=1)
|
||||
if not result:
|
||||
logging.info("Did not find the statistics in the corner. Did the benchmark launch?")
|
||||
raise RuntimeError("Benchmark failed.")
|
||||
|
||||
test_start_time = int(time.time())
|
||||
|
||||
time.sleep(benchmark_time) # sleep during the benchmark which is indicated based on the benchmark detected.
|
||||
|
||||
result = kerasService.look_for_word("overall", attempts=20, interval=1)
|
||||
if not result:
|
||||
logging.info("Did not find the overall FPS score. Did the benchmark crash?")
|
||||
raise RuntimeError("Benchmark failed.")
|
||||
|
||||
test_end_time = int(time.time()) - 1
|
||||
elapsed_test_time = round(test_end_time - test_start_time, 2)
|
||||
logging.info("Benchmark took %f seconds", elapsed_test_time)
|
||||
am.take_screenshot("results.png", ArtifactType.RESULTS_IMAGE, "benchmark results")
|
||||
time.sleep(1)
|
||||
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
if proc.name() in PROCESS_NAMES:
|
||||
proc.terminate()
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||||
pass # Ignore processes that no longer exist or cannot be accessed
|
||||
|
||||
am.create_manifest()
|
||||
return test_start_time, test_end_time, benchmark_name
|
||||
|
||||
|
||||
setup_log_directory(log_dir)
|
||||
|
||||
logging.basicConfig(filename=f'{log_dir}/harness.log',
|
||||
format=DEFAULT_LOGGING_FORMAT,
|
||||
datefmt=DEFAULT_DATE_FORMAT,
|
||||
level=logging.DEBUG)
|
||||
console = logging.StreamHandler()
|
||||
formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
|
||||
console.setFormatter(formatter)
|
||||
logging.getLogger('').addHandler(console)
|
||||
|
||||
args = get_args()
|
||||
kerasService = KerasService(args.keras_host, args.keras_port)
|
||||
|
||||
try:
|
||||
test_start_time, test_end_time, benchmark_name = run_benchmark()
|
||||
height, width = get_resolution(config_file)
|
||||
report = {
|
||||
"resolution": f"{width}x{height}",
|
||||
"benchmark": benchmark_name,
|
||||
"start_time": seconds_to_milliseconds(test_start_time), # seconds * 1000 = millis
|
||||
"end_time": seconds_to_milliseconds(test_end_time),
|
||||
"version": get_build_id(STEAM_GAME_ID)
|
||||
}
|
||||
|
||||
write_report_json(log_dir, "report.json", report)
|
||||
|
||||
except Exception as e:
|
||||
logging.error("Something went wrong running the benchmark!")
|
||||
logging.exception(e)
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
if proc.name() in PROCESS_NAMES:
|
||||
proc.terminate()
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||||
pass # Ignore processes that no longer exist or cannot be accessed
|
||||
|
||||
exit(1)
|
||||
104
hitman3/hitman3_utils.py
Normal file
104
hitman3/hitman3_utils.py
Normal file
@@ -0,0 +1,104 @@
|
||||
"""Utility functions supporting Hitman World of Assassination test script."""
|
||||
from argparse import ArgumentParser
|
||||
import re
|
||||
import winreg
|
||||
import os
|
||||
|
||||
def get_args() -> any:
|
||||
"""Get command line arguments"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--kerasHost", dest="keras_host", help="Host for Keras OCR service", required=True)
|
||||
parser.add_argument(
|
||||
"--kerasPort", dest="keras_port", help="Port for Keras OCR service", required=True)
|
||||
return parser.parse_args()
|
||||
|
||||
def export_registry_key(hive, subkey, input_file):
|
||||
"""Exports a registry key for interpretation."""
|
||||
try:
|
||||
if not os.path.exists(input_file):
|
||||
with open(input_file, 'w', encoding="utf-8") as file:
|
||||
file.write("")
|
||||
with winreg.OpenKey(hive,subkey) as reg_key:
|
||||
with open(input_file, 'w', encoding="utf-8") as reg_file:
|
||||
reg_file.write("Windows Registry Editor Version 5.00\n\n")
|
||||
reg_file.write(f"[{subkey}]\n")
|
||||
try:
|
||||
index = 0
|
||||
while True:
|
||||
value_name, value_data, value_type = winreg.EnumValue(reg_key, index)
|
||||
if value_type == winreg.REG_DWORD:
|
||||
value_data = f"dword:{value_data:08x}"
|
||||
elif value_type == winreg.REG_SZ:
|
||||
value_data = f'"{value_data}"'
|
||||
elif value_type == winreg.REG_QWORD:
|
||||
value_data = f"qword:{value_data:0x16x}"
|
||||
else:
|
||||
value_data = f'"{value_data}"'
|
||||
reg_file.write(f'"{value_name}"={value_data}\n')
|
||||
index += 1
|
||||
except OSError:
|
||||
pass
|
||||
except OSError as e:
|
||||
print(f"Failed to open the registry key: {e}")
|
||||
|
||||
def convert_dword_to_decimal(dword_hex):
|
||||
"""Converts a dword key value to decimal numbers."""
|
||||
return int(dword_hex, 16)
|
||||
|
||||
def process_registry_file(hive, subkey, input_file, config_file):
|
||||
"""Processes the exported registry file and converts it to readable text."""
|
||||
export_registry_key(hive, subkey, input_file)
|
||||
with open(input_file, 'r', encoding="utf-8") as file:
|
||||
lines = file.readlines()
|
||||
|
||||
modified_lines = []
|
||||
|
||||
dword_pattern = re.compile(r'^(\"[^\"]+\")=dword:([0-9a-fA-F]+)', re.IGNORECASE)
|
||||
|
||||
for line in lines:
|
||||
match = dword_pattern.search(line)
|
||||
if match:
|
||||
key = match.group(1)
|
||||
hex_value = match.group(2)
|
||||
decimal_value = convert_dword_to_decimal(hex_value)
|
||||
modified_line = f'{key}={decimal_value}\n'
|
||||
modified_lines.append(modified_line)
|
||||
else:
|
||||
modified_lines.append(line)
|
||||
with open(config_file, 'w', encoding="utf-8") as file:
|
||||
file.writelines(modified_lines)
|
||||
|
||||
def get_resolution(config_file: str) -> tuple[int]:
|
||||
"""Retrieve the resolution from local configuration files."""
|
||||
width_pattern = re.compile(r"\"ResolutionWidth\"=(\d+)")
|
||||
height_pattern = re.compile(r"\"ResolutionHeight\"=(\d+)")
|
||||
width = 0
|
||||
height = 0
|
||||
|
||||
with open(config_file, encoding="utf-8") as file:
|
||||
lines = file.readlines()
|
||||
for line in lines:
|
||||
width_match = width_pattern.match(line)
|
||||
height_match = height_pattern.match(line)
|
||||
|
||||
if width_match:
|
||||
width = width_match.group(1)
|
||||
if height_match:
|
||||
height = height_match.group(1)
|
||||
|
||||
return (height, width)
|
||||
|
||||
def get_benchmark_name(config_file: str) -> tuple[int]:
|
||||
"""Retrieve the resolution from local configuration files."""
|
||||
benchmark_pattern = re.compile(r"\"BenchmarkScene\"=(\d+)")
|
||||
benchmark = 0
|
||||
|
||||
with open(config_file, encoding="utf-8") as file:
|
||||
lines = file.readlines()
|
||||
for line in lines:
|
||||
benchmark_match = benchmark_pattern.match(line)
|
||||
if benchmark_match:
|
||||
benchmark = int(benchmark_match.group(1))
|
||||
|
||||
return (benchmark)
|
||||
9
hitman3/manifest.yaml
Normal file
9
hitman3/manifest.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
friendly_name: "Hitman World of Assassination"
|
||||
executable: "hitman3.py"
|
||||
process_name: "HITMAN3.exe"
|
||||
output_dir: "run"
|
||||
options:
|
||||
- name: kerasHost
|
||||
type: input
|
||||
- name: kerasPort
|
||||
type: input
|
||||
BIN
hitman3/screenshots/options.png
Normal file
BIN
hitman3/screenshots/options.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 616 B |
BIN
hitman3/screenshots/start_benchmark.png
Normal file
BIN
hitman3/screenshots/start_benchmark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 638 B |
Reference in New Issue
Block a user