Split Prime95 and cooling Test() objects

This commit is contained in:
2Shirt 2019-11-14 20:16:15 -07:00
parent fec2473b93
commit 402c4359a1
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
3 changed files with 68 additions and 23 deletions

View file

@ -14,9 +14,9 @@ ATTRIBUTE_COLORS = (
('Error', 'RED'), ('Error', 'RED'),
('Maximum', 'PURPLE'), ('Maximum', 'PURPLE'),
) )
CPU_CRITICAL_TEMP = 99
CPU_FAILURE_TEMP = 90 CPU_FAILURE_TEMP = 90
CPU_TEST_MINUTES = 7 CPU_TEST_MINUTES = 7
CPU_THERMAL_LIMIT = 99
KEY_NVME = 'nvme_smart_health_information_log' KEY_NVME = 'nvme_smart_health_information_log'
KEY_SMART = 'ata_smart_attributes' KEY_SMART = 'ata_smart_attributes'
KNOWN_DISK_ATTRIBUTES = { KNOWN_DISK_ATTRIBUTES = {

View file

@ -176,9 +176,14 @@ class State():
if not details['Selected']: if not details['Selected']:
continue continue
if 'CPU' in name: if 'CPU' in name:
test_obj = hw_obj.Test(dev=self.cpu, label=name) # Create two Test objects which will both be used by cpu_mprime_test
self.cpu.tests[name] = test_obj # NOTE: Prime95 should be added first
self.tests[name]['Objects'].append(test_obj) test_mprime_obj = hw_obj.Test(dev=self.cpu, label='Prime95')
test_cooling_obj = hw_obj.Test(dev=self.cpu, label='Cooling')
self.cpu.tests[name] = test_mprime_obj
self.cpu.tests[name] = test_cooling_obj
self.tests[name]['Objects'].append(test_mprime_obj)
self.tests[name]['Objects'].append(test_cooling_obj)
elif 'Disk' in name: elif 'Disk' in name:
for disk in self.disks: for disk in self.disks:
test_obj = hw_obj.Test(dev=disk, label=disk.path.name) test_obj = hw_obj.Test(dev=disk, label=disk.path.name)
@ -290,8 +295,28 @@ def build_menu(cli_mode=False, quick_mode=False):
return menu return menu
def check_cooling_results(test_obj, sensors):
"""Check cooling results and update test_obj."""
max_temp = sensors.cpu_max_temp()
# Check temps
if not max_temp:
test_obj.set_status('Unknown')
elif max_temp >= cfg.hw.CPU_FAILURE_TEMP:
test_obj.failed = True
test_obj.set_status('Failed')
elif 'Aborted' not in test_obj.status:
test_obj.passed = True
test_obj.set_status('Passed')
# Add temps to report
for line in sensors.generate_report(
'Idle', 'Max', 'Cooldown', only_cpu=True):
test_obj.report.append(f' {line}')
def check_mprime_results(test_obj, working_dir): def check_mprime_results(test_obj, working_dir):
"""Check mprime log files to determine if test passed.""" """Check mprime log files and update test_obj."""
passing_lines = {} passing_lines = {}
warning_lines = {} warning_lines = {}
@ -350,15 +375,16 @@ def cpu_mprime_test(state, test_objects):
LOG.info('CPU Test (Prime95)') LOG.info('CPU Test (Prime95)')
prime_log = pathlib.Path(f'{state.log_dir}/prime.log') prime_log = pathlib.Path(f'{state.log_dir}/prime.log')
sensors_out = pathlib.Path(f'{state.log_dir}/sensors.out') sensors_out = pathlib.Path(f'{state.log_dir}/sensors.out')
test_obj = test_objects[0] test_mprime_obj, test_cooling_obj = test_objects
# Bail early # Bail early
if test_obj.disabled: if test_cooling_obj.disabled or test_mprime_obj.disabled:
return return
# Prep # Prep
state.update_top_pane(test_obj.dev.description) state.update_top_pane(test_mprime_obj.dev.description)
test_obj.set_status('Working') test_cooling_obj.set_status('Working')
test_mprime_obj.set_status('Working')
# Start sensors monitor # Start sensors monitor
sensors = hw_sensors.Sensors() sensors = hw_sensors.Sensors()
@ -388,10 +414,10 @@ def cpu_mprime_test(state, test_objects):
try: try:
print_countdown(seconds=cfg.hw.CPU_TEST_MINUTES*60) print_countdown(seconds=cfg.hw.CPU_TEST_MINUTES*60)
except KeyboardInterrupt: except KeyboardInterrupt:
test_obj.set_status('Aborted') test_cooling_obj.set_status('Aborted')
test_mprime_obj.set_status('Aborted')
except hw_sensors.ThermalLimitReachedError: except hw_sensors.ThermalLimitReachedError:
test_obj.failed = True test_mprime_obj.set_status('Aborted')
test_obj.set_status('Failed')
# Stop Prime95 # Stop Prime95
proc_mprime.terminate() proc_mprime.terminate()
@ -408,13 +434,13 @@ def cpu_mprime_test(state, test_objects):
std.print_standard('Saving cooldown temps...') std.print_standard('Saving cooldown temps...')
sensors.save_average_temps(temp_label='Cooldown', seconds=5) sensors.save_average_temps(temp_label='Cooldown', seconds=5)
# Check results and build report # Check Prime95 results
test_obj.report.append(std.color_string('Prime95', 'BLUE')) test_mprime_obj.report.append(std.color_string('Prime95', 'BLUE'))
check_mprime_results(test_obj=test_obj, working_dir=state.log_dir) check_mprime_results(test_obj=test_mprime_obj, working_dir=state.log_dir)
test_obj.report.append(std.color_string('Temps', 'BLUE'))
for line in sensors.generate_report( # Check Cooling results
'Idle', 'Max', 'Cooldown', only_cpu=True): test_cooling_obj.report.append(std.color_string('Temps', 'BLUE'))
test_obj.report.append(f' {line}') check_cooling_results(test_obj=test_cooling_obj, sensors=sensors)
# Cleanup # Cleanup
sensors.stop_background_monitor() sensors.stop_background_monitor()
@ -423,7 +449,8 @@ def cpu_mprime_test(state, test_objects):
tmux.kill_pane(state.panes.pop('Temps', None)) tmux.kill_pane(state.panes.pop('Temps', None))
#TODO: p95 #TODO: p95
std.print_report(test_obj.report) std.print_report(test_mprime_obj.report)
std.print_report(test_cooling_obj.report)
def disk_attribute_check(state, test_objects): def disk_attribute_check(state, test_objects):

View file

@ -9,7 +9,7 @@ import re
from subprocess import CalledProcessError from subprocess import CalledProcessError
from wk.cfg.hw import CPU_THERMAL_LIMIT, SMC_IDS, TEMP_COLORS from wk.cfg.hw import CPU_CRITICAL_TEMP, SMC_IDS, TEMP_COLORS
from wk.exe import run_program, start_thread from wk.exe import run_program, start_thread
from wk.std import color_string, sleep from wk.std import color_string, sleep
@ -46,6 +46,24 @@ class Sensors():
for source_data in sources.values(): for source_data in sources.values():
source_data['Temps'] = [] source_data['Temps'] = []
def cpu_max_temp(self):
"""Get max temp from any CPU source, returns float.
NOTE: If no temps are found this returns zero.
"""
max_temp = 0.0
# Check all CPU Temps
for section, adapters in self.data.items():
if not section.startswith('CPU'):
continue
for sources in adapters.values():
for source_data in sources.values():
max_temp = max(max_temp, source_data.get('Max', 0))
# Done
return max_temp
def generate_report(self, *temp_labels, colored=True, only_cpu=False): def generate_report(self, *temp_labels, colored=True, only_cpu=False):
"""Generate report based on given temp_labels, returns list.""" """Generate report based on given temp_labels, returns list."""
report = [] report = []
@ -163,7 +181,7 @@ class Sensors():
# Raise exception if thermal limit reached # Raise exception if thermal limit reached
if exit_on_thermal_limit and section == 'CPUTemps': if exit_on_thermal_limit and section == 'CPUTemps':
if source_data['Current'] >= CPU_THERMAL_LIMIT: if source_data['Current'] >= CPU_CRITICAL_TEMP:
raise ThermalLimitReachedError('CPU temps reached limit') raise ThermalLimitReachedError('CPU temps reached limit')
def update_sensor_data_macos(self, exit_on_thermal_limit=True): def update_sensor_data_macos(self, exit_on_thermal_limit=True):
@ -187,7 +205,7 @@ class Sensors():
# Raise exception if thermal limit reached # Raise exception if thermal limit reached
if exit_on_thermal_limit and section == 'CPUTemps': if exit_on_thermal_limit and section == 'CPUTemps':
if source_data['Current'] >= CPU_THERMAL_LIMIT: if source_data['Current'] >= CPU_CRITICAL_TEMP:
raise ThermalLimitReachedError('CPU temps reached limit') raise ThermalLimitReachedError('CPU temps reached limit')