amd-debug-tools 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amd-debug-tools might be problematic. Click here for more details.

amd_debug/common.py CHANGED
@@ -81,6 +81,15 @@ def print_color(message, group) -> None:
81
81
  print(f"{prefix}{color}{message}{suffix}")
82
82
 
83
83
 
84
+ def colorize_choices(choices, default) -> str:
85
+ """Output a list of choices with colors, where the default is highlighted"""
86
+ if default not in choices:
87
+ raise ValueError(f"Default choice '{default}' not in choices")
88
+ choices = [c for c in choices if c != default]
89
+ choices = [f"{Colors.OK}{default}{Colors.ENDC}"] + choices
90
+ return ", ".join(choices)
91
+
92
+
84
93
  def fatal_error(message):
85
94
  """Prints a fatal error message and exits"""
86
95
  _configure_log(None)
@@ -88,6 +97,21 @@ def fatal_error(message):
88
97
  sys.exit(1)
89
98
 
90
99
 
100
+ def apply_prefix_wrapper(header, message):
101
+ """Apply a prefix to wrap a newline delimitted message"""
102
+ s = f"{header.strip()}\n"
103
+ lines = message.strip().split("\n")
104
+ for i, line in enumerate(lines):
105
+ line = line.strip()
106
+ if not line:
107
+ continue
108
+ if i == len(lines) - 1:
109
+ s += f"└─ {line}\n"
110
+ continue
111
+ s += f"│ {line}\n"
112
+ return s
113
+
114
+
91
115
  def show_log_info():
92
116
  """Show log information"""
93
117
  logger = logging.getLogger()
amd_debug/display.py ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-License-Identifier: MIT
3
+ """Display analysis"""
4
+ import os
5
+ from pyudev import Context
6
+
7
+ from amd_debug.common import read_file
8
+
9
+
10
+ class Display:
11
+ """Display analysis"""
12
+
13
+ def __init__(self):
14
+ self.pyudev = Context()
15
+ self.edid = {}
16
+
17
+ for dev in self.pyudev.list_devices(subsystem="drm"):
18
+ if not "card" in dev.device_path:
19
+ continue
20
+ p = os.path.join(dev.sys_path, "status")
21
+ if not os.path.exists(p):
22
+ continue
23
+ f = read_file(p)
24
+ if f != "connected":
25
+ continue
26
+ p = os.path.join(dev.sys_path, "enabled")
27
+ f = read_file(p)
28
+ if f != "enabled":
29
+ continue
30
+ self.edid[dev.sys_name] = os.path.join(dev.sys_path, "edid")
31
+
32
+ def get_edid(self) -> list:
33
+ """Get the path for EDID data for all connected displays"""
34
+ return self.edid
amd_debug/installer.py CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/python3
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
+ """
5
+ This module contains installer support for amd-debug-tools.
6
+ """
7
+
4
8
  import argparse
5
9
  import os
6
10
  import shutil
@@ -21,6 +25,7 @@ class Headers: # pylint: disable=too-few-public-methods
21
25
  """Headers for the script"""
22
26
 
23
27
  MissingIasl = "ACPI extraction tool `iasl` is missing"
28
+ MissingEdidDecode = "EDID decoding tool `edid-decode` is missing"
24
29
  MissingEthtool = "Ethtool is missing"
25
30
  InstallAction = "Attempting to install"
26
31
  MissingFwupd = "Firmware update library `fwupd` is missing"
@@ -171,6 +176,18 @@ class EthtoolPackage(DistroPackage):
171
176
  )
172
177
 
173
178
 
179
+ class EdidDecodePackage(DistroPackage):
180
+ """Edid-Decode package"""
181
+
182
+ def __init__(self):
183
+ super().__init__(
184
+ deb="edid-decode",
185
+ rpm="edid-decode",
186
+ arch=None,
187
+ message=Headers.MissingEdidDecode,
188
+ )
189
+
190
+
174
191
  class FwupdPackage(DistroPackage):
175
192
  """Fwupd package"""
176
193
 
@@ -202,14 +219,14 @@ class Installer(AmdTool):
202
219
  # test if fwupd can report device firmware versions
203
220
  try:
204
221
  import gi # pylint: disable=import-outside-toplevel
205
- from gi.repository import (
222
+ from gi.repository import ( # pylint: disable=import-outside-toplevel
206
223
  GLib as _,
207
- ) # pylint: disable=import-outside-toplevel
224
+ )
208
225
 
209
226
  gi.require_version("Fwupd", "2.0")
210
- from gi.repository import (
227
+ from gi.repository import ( # pylint: disable=import-outside-toplevel
211
228
  Fwupd as _,
212
- ) # pylint: disable=import-outside-toplevel
229
+ )
213
230
 
214
231
  self.fwupd = True
215
232
  except ImportError:
@@ -244,6 +261,20 @@ class Installer(AmdTool):
244
261
  package = EthtoolPackage()
245
262
  if not package.install():
246
263
  return False
264
+ if "edid-decode" in self.requirements:
265
+ try:
266
+ edid = (
267
+ subprocess.call(
268
+ ["edid-decode", "--help"], stdout=subprocess.DEVNULL
269
+ )
270
+ == 255
271
+ )
272
+ except FileNotFoundError:
273
+ edid = False
274
+ if not edid:
275
+ package = EdidDecodePackage()
276
+ if not package.install():
277
+ return False
247
278
  if "fwupd" in self.requirements and not self.fwupd:
248
279
  package = FwupdPackage()
249
280
  if not package.install():
@@ -396,6 +427,7 @@ def install_dep_superset() -> bool:
396
427
  "pandas",
397
428
  "seaborn",
398
429
  "tabulate",
430
+ "edid-decode",
399
431
  )
400
432
  ret = tool.install_dependencies()
401
433
  if ret:
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/python3
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
+ """
5
+ This module contains the s0i3 prerequisite validator for amd-debug-tools.
6
+ """
7
+
8
+ import configparser
4
9
  import logging
5
10
  import os
6
11
  import platform
@@ -9,13 +14,16 @@ import shutil
9
14
  import subprocess
10
15
  import tempfile
11
16
  import struct
12
- import pyudev
13
17
  from datetime import datetime
14
18
  from packaging import version
15
19
 
20
+ import pyudev
21
+
16
22
  from amd_debug.wake import WakeIRQ
23
+ from amd_debug.display import Display
17
24
  from amd_debug.kernel import get_kernel_log, SystemdLogger, DmesgLogger
18
25
  from amd_debug.common import (
26
+ apply_prefix_wrapper,
19
27
  BIT,
20
28
  clear_temporary_message,
21
29
  get_distro,
@@ -111,12 +119,37 @@ class PrerequisiteValidator(AmdTool):
111
119
  self.irqs = []
112
120
  self.smu_version = ""
113
121
  self.smu_program = ""
122
+ self.display = Display()
114
123
 
115
124
  def capture_once(self):
116
125
  """Capture the prerequisites once"""
117
126
  if not self.db.get_last_prereq_ts():
118
127
  self.run()
119
128
 
129
+ def capture_edid(self):
130
+ """Capture and decode the EDID data"""
131
+ edids = self.display.get_edid()
132
+ if len(edids) == 0:
133
+ self.db.record_debug("No EDID data found")
134
+ return True
135
+
136
+ for name, p in edids.items():
137
+ try:
138
+ cmd = ["edid-decode", p]
139
+ output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL).decode(
140
+ "utf-8"
141
+ )
142
+ except FileNotFoundError:
143
+ self.db.record_prereq(
144
+ "edid-decode not installed, unable to decode EDID", "👀"
145
+ )
146
+ return True
147
+ except subprocess.CalledProcessError as e:
148
+ self.db.record_prereq(f"Failed to capture EDID table: {e.output}", "👀")
149
+ return False
150
+ self.db.record_debug(apply_prefix_wrapper(f"EDID for {name}:", output))
151
+ return True
152
+
120
153
  def check_amdgpu(self):
121
154
  """Check for the AMDGPU driver"""
122
155
  for device in self.pyudev.list_devices(subsystem="pci"):
@@ -167,10 +200,10 @@ class PrerequisiteValidator(AmdTool):
167
200
  if self.kernel_log.match_pattern("ath11k_pci.*wcn6855"):
168
201
  match = self.kernel_log.match_pattern("ath11k_pci.*fw_version")
169
202
  if match:
170
- self.db.record_debug("WCN6855 version string: %s" % match)
203
+ self.db.record_debug(f"WCN6855 version string: {match}")
171
204
  objects = match.split()
172
- for i in range(0, len(objects)):
173
- if objects[i] == "fw_build_id":
205
+ for i, obj in enumerate(objects):
206
+ if obj == "fw_build_id":
174
207
  wcn6855 = objects[i + 1]
175
208
 
176
209
  if wcn6855:
@@ -346,6 +379,7 @@ class PrerequisiteValidator(AmdTool):
346
379
 
347
380
  def check_usb3(self):
348
381
  """Check for the USB4 controller"""
382
+ slots = []
349
383
  for device in self.pyudev.list_devices(subsystem="pci", PCI_CLASS="C0330"):
350
384
  slot = device.properties["PCI_SLOT_NAME"]
351
385
  if device.properties.get("DRIVER") != "xhci_hcd":
@@ -354,18 +388,27 @@ class PrerequisiteValidator(AmdTool):
354
388
  )
355
389
  self.failures += [MissingXhciHcd()]
356
390
  return False
357
- self.db.record_prereq(f"USB3 driver `xhci_hcd` bound to {slot}", "✅")
391
+ slots += [slot]
392
+ if slots:
393
+ self.db.record_prereq(
394
+ f"USB3 driver `xhci_hcd` bound to {', '.join(slots)}", "✅"
395
+ )
358
396
  return True
359
397
 
360
398
  def check_usb4(self):
361
399
  """Check if the thunderbolt driver is loaded"""
400
+ slots = []
362
401
  for device in self.pyudev.list_devices(subsystem="pci", PCI_CLASS="C0340"):
363
402
  slot = device.properties["PCI_SLOT_NAME"]
364
403
  if device.properties.get("DRIVER") != "thunderbolt":
365
404
  self.db.record_prereq("USB4 driver `thunderbolt` missing", "❌")
366
405
  self.failures += [MissingThunderbolt()]
367
406
  return False
368
- self.db.record_prereq(f"USB4 driver `thunderbolt` bound to {slot}", "✅")
407
+ slots += [slot]
408
+ if slots:
409
+ self.db.record_prereq(
410
+ f"USB4 driver `thunderbolt` bound to {', '.join(slots)}", "✅"
411
+ )
369
412
  return True
370
413
 
371
414
  def check_sleep_mode(self):
@@ -478,8 +521,8 @@ class PrerequisiteValidator(AmdTool):
478
521
  continue
479
522
  if self.cpu_family and self.cpu_model and self.cpu_model_string:
480
523
  self.db.record_prereq(
481
- "%s (family %x model %x)"
482
- % (self.cpu_model_string, self.cpu_family, self.cpu_model),
524
+ f"{self.cpu_model_string} "
525
+ f"(family {self.cpu_family:x} model {self.cpu_model:x})",
483
526
  "💻",
484
527
  )
485
528
  break
@@ -487,7 +530,7 @@ class PrerequisiteValidator(AmdTool):
487
530
 
488
531
  # See https://github.com/torvalds/linux/commit/ec6c0503190417abf8b8f8e3e955ae583a4e50d4
489
532
  def check_fadt(self):
490
- """Check the kernel emitted a message specific to 6.0 or later indicating FADT had a bit set."""
533
+ """Check the kernel emitted a message indicating FADT had a bit set."""
491
534
  found = False
492
535
  if not self.kernel_log:
493
536
  message = "Unable to test FADT from kernel log"
@@ -575,10 +618,10 @@ class PrerequisiteValidator(AmdTool):
575
618
  """Check if the user has permissions to write to /sys/power/state"""
576
619
  p = os.path.join("/", "sys", "power", "state")
577
620
  try:
578
- with open(p, "w") as w:
621
+ with open(p, "w", encoding="utf-8") as _w:
579
622
  pass
580
623
  except PermissionError:
581
- self.db.record_prereq("%s" % Headers.RootError, "👀")
624
+ self.db.record_prereq(f"{Headers.RootError}", "👀")
582
625
  return False
583
626
  except FileNotFoundError:
584
627
  self.db.record_prereq("Kernel doesn't support power management", "❌")
@@ -608,7 +651,8 @@ class PrerequisiteValidator(AmdTool):
608
651
  )
609
652
  if show_warning:
610
653
  self.db.record_prereq(
611
- "Timer based wakeup doesn't work properly for your ASIC/firmware, please manually wake the system",
654
+ "Timer based wakeup doesn't work properly for your "
655
+ "ASIC/firmware, please manually wake the system",
612
656
  "🚦",
613
657
  )
614
658
  return True
@@ -631,7 +675,7 @@ class PrerequisiteValidator(AmdTool):
631
675
  for line in contents.split("\n"):
632
676
  if "WAKE_INT_MASTER_REG:" in line:
633
677
  val = "en" if int(line.split()[1], 16) & BIT(15) else "dis"
634
- self.db.record_debug("Windows GPIO 0 debounce: %sabled" % val)
678
+ self.db.record_debug(f"Windows GPIO 0 debounce: {val}abled")
635
679
  continue
636
680
  if not header and re.search("trigger", line):
637
681
  debug_str += line + "\n"
@@ -671,7 +715,9 @@ class PrerequisiteValidator(AmdTool):
671
715
  self.db.record_prereq(f"{interface} has WoL enabled", "✅")
672
716
  else:
673
717
  self.db.record_prereq(
674
- f"Platform may have low hardware sleep residency with Wake-on-lan disabled. Run `ethtool -s {interface} wol g` to enable it if necessary.",
718
+ "Platform may have low hardware sleep residency "
719
+ "with Wake-on-lan disabled. Run `ethtool -s "
720
+ f"{interface} wol g` to enable it if necessary.",
675
721
  "🚦",
676
722
  )
677
723
  return True
@@ -726,7 +772,8 @@ class PrerequisiteValidator(AmdTool):
726
772
  # Dictionary of instance id to firmware version mappings that
727
773
  # have been "reported" to be problematic
728
774
  device_map = {
729
- "8c36f7ee-cc11-4a36-b090-6363f54ecac2": "0.1.26", # https://gitlab.freedesktop.org/drm/amd/-/issues/3443
775
+ # https://gitlab.freedesktop.org/drm/amd/-/issues/3443
776
+ "8c36f7ee-cc11-4a36-b090-6363f54ecac2": "0.1.26",
730
777
  }
731
778
  interesting_plugins = ["nvme", "tpm", "uefi_capsule"]
732
779
  if device.get_plugin() in interesting_plugins:
@@ -743,7 +790,8 @@ class PrerequisiteValidator(AmdTool):
743
790
  item in device.get_guids() or item in device.get_instance_ids()
744
791
  ) and ver in device.get_version():
745
792
  self.db.record_prereq(
746
- f"Platform may have problems resuming. Upgrade the firmware for '{device.get_name()}' if you have problems.",
793
+ "Platform may have problems resuming. Upgrade the "
794
+ f"firmware for '{device.get_name()}' if you have problems.",
747
795
  "🚦",
748
796
  )
749
797
  return True
@@ -792,12 +840,13 @@ class PrerequisiteValidator(AmdTool):
792
840
  else:
793
841
  acpi_hid = ""
794
842
  # set prefix if last device
795
- prefix = "| " if dev != devices[-1] else "└─"
796
- debug_str += "{prefix}{name} [{acpi_hid}] : {acpi_path}\n".format(
797
- prefix=prefix, name=name, acpi_hid=acpi_hid, acpi_path=acpi_path
798
- )
843
+ prefix = " " if dev != devices[-1] else "└─"
844
+ debug_str += f"{prefix}{name} [{acpi_hid}] : {acpi_path}\n"
799
845
  if "IDEA5002" in name:
800
- remediation = f"echo {parent.sys_path.split('/')[-1]} | sudo tee /sys/bus/i2c/drivers/{parent.driver}/unbind"
846
+ remediation = (
847
+ f"echo {parent.sys_path.split('/')[-1]} | "
848
+ f"sudo tee /sys/bus/i2c/drivers/{parent.driver}/unbind"
849
+ )
801
850
 
802
851
  self.db.record_prereq(f"{name} may cause spurious wakeups", "❌")
803
852
  self.failures += [I2CHidBug(name, remediation)]
@@ -834,22 +883,13 @@ class PrerequisiteValidator(AmdTool):
834
883
  if os.path.exists(p):
835
884
  acpi = read_file(p)
836
885
  debug_str += (
837
- "{prefix}{pci_slot_name} : {vendor} {cls} [{id}] : {acpi}\n".format(
838
- prefix=prefix,
839
- pci_slot_name=pci_slot_name,
840
- vendor=database_vendor,
841
- cls=database_class,
842
- id=pci_id,
843
- acpi=acpi,
844
- )
886
+ f"{prefix}{pci_slot_name} : "
887
+ f"{database_vendor} {database_class} [{pci_id}] : {acpi}\n"
845
888
  )
846
889
  else:
847
- debug_str += "{prefix}{pci_slot_name} : {vendor} {cls} [{id}]\n".format(
848
- prefix=prefix,
849
- vendor=database_vendor,
850
- pci_slot_name=pci_slot_name,
851
- cls=database_class,
852
- id=pci_id,
890
+ debug_str += (
891
+ f"{prefix}{pci_slot_name} : "
892
+ f"{database_vendor} {database_class} [{pci_id}]\n"
853
893
  )
854
894
  if debug_str:
855
895
  self.db.record_debug(debug_str)
@@ -908,7 +948,7 @@ class PrerequisiteValidator(AmdTool):
908
948
  stdout=subprocess.DEVNULL,
909
949
  stderr=subprocess.DEVNULL,
910
950
  )
911
- self.db.record_debug_file("%s.dsl" % prefix)
951
+ self.db.record_debug_file(f"{prefix}.dsl")
912
952
  except subprocess.CalledProcessError as e:
913
953
  self.db.record_prereq(
914
954
  f"Failed to capture ACPI table: {e.output}", "👀"
@@ -925,10 +965,10 @@ class PrerequisiteValidator(AmdTool):
925
965
  self.db.record_prereq(desc, "🔋")
926
966
 
927
967
  def capture_logind(self):
968
+ """Capture logind.conf settings"""
928
969
  base = os.path.join("/", "etc", "systemd", "logind.conf")
929
970
  if not os.path.exists(base):
930
971
  return True
931
- import configparser
932
972
 
933
973
  config = configparser.ConfigParser()
934
974
  config.read(base)
@@ -982,7 +1022,8 @@ class PrerequisiteValidator(AmdTool):
982
1022
  _, cpu_count, _, _ = read_cpuid(0, 0x80000026, 1)
983
1023
  if cpu_count > max_cpus:
984
1024
  self.db.record_prereq(
985
- f"The kernel has been limited to {max_cpus} CPU cores, but the system has {cpu_count} cores",
1025
+ f"The kernel has been limited to {max_cpus} CPU cores, "
1026
+ f"but the system has {cpu_count} cores",
986
1027
  "❌",
987
1028
  )
988
1029
  self.failures += [LimitedCores(cpu_count, max_cpus)]
@@ -996,12 +1037,6 @@ class PrerequisiteValidator(AmdTool):
996
1037
  except PermissionError:
997
1038
  self.db.record_prereq("CPUID checks unavailable", "🚦")
998
1039
 
999
- if valid:
1000
- self.db.record_prereq(
1001
- f"{self.cpu_model_string} (family {self.cpu_family:x} model {self.cpu_model:x})",
1002
- "✅",
1003
- )
1004
-
1005
1040
  return True
1006
1041
 
1007
1042
  def check_msr(self):
@@ -1020,7 +1055,7 @@ class PrerequisiteValidator(AmdTool):
1020
1055
  if not check_bits(val, expect_val):
1021
1056
  self.failures += [MSRFailure()]
1022
1057
  return False
1023
- self.db.record_prereq("PC6 and CC6 enabled", "✅")
1058
+ self.db.record_prereq("PC6 and CC6 enabled", "✅")
1024
1059
  except FileNotFoundError:
1025
1060
  self.db.record_prereq(
1026
1061
  "Unable to check MSRs: MSR kernel module not loaded", "❌"
@@ -1111,7 +1146,9 @@ class PrerequisiteValidator(AmdTool):
1111
1146
  if "pcie_port_pm=off" in cmdline:
1112
1147
  return True
1113
1148
  self.db.record_prereq(
1114
- "Platform may hang resuming. Upgrade your firmware or add pcie_port_pm=off to kernel command line if you have problems.",
1149
+ "Platform may hang resuming. "
1150
+ "Upgrade your firmware or add pcie_port_pm=off to kernel command "
1151
+ "line if you have problems.",
1115
1152
  "🚦",
1116
1153
  )
1117
1154
  return False
@@ -1139,6 +1176,7 @@ class PrerequisiteValidator(AmdTool):
1139
1176
  self.capture_linux_firmware,
1140
1177
  self.capture_logind,
1141
1178
  self.capture_pci_acpi,
1179
+ self.capture_edid,
1142
1180
  ]
1143
1181
  checks = []
1144
1182
 
amd_debug/s2idle.py CHANGED
@@ -8,7 +8,14 @@ import subprocess
8
8
  import sqlite3
9
9
 
10
10
  from datetime import date, timedelta, datetime
11
- from amd_debug.common import is_root, relaunch_sudo, show_log_info, version, running_ssh
11
+ from amd_debug.common import (
12
+ colorize_choices,
13
+ is_root,
14
+ relaunch_sudo,
15
+ show_log_info,
16
+ version,
17
+ running_ssh,
18
+ )
12
19
 
13
20
  from amd_debug.validator import SleepValidator
14
21
  from amd_debug.installer import Installer
@@ -51,12 +58,14 @@ def display_report_file(fname, fmt) -> None:
51
58
  return
52
59
  user = os.environ.get("SUDO_USER")
53
60
  if user:
54
- # ensure that xdg tools will know how to display the file (user may need to call tool with sudo -E)
61
+ # ensure that xdg tools will know how to display the file
62
+ # (user may need to call tool with sudo -E)
55
63
  if os.environ.get("XDG_SESSION_TYPE"):
56
64
  subprocess.call(["sudo", "-E", "-u", user, "xdg-open", fname])
57
65
  else:
58
66
  print(
59
- f"To display report automatically in browser launch tool with '-E' argument (Example: sudo -E {sys.argv[0]})"
67
+ "To display report automatically in browser launch tool "
68
+ f"with '-E' argument (Example: sudo -E {sys.argv[0]})"
60
69
  )
61
70
 
62
71
 
@@ -98,7 +107,9 @@ def prompt_report_arguments(since, until, fname, fmt) -> str:
98
107
  sys.exit(f"Invalid date, use YYYY-MM-DD: {e}")
99
108
 
100
109
  if not fmt:
101
- fmt = input(f"{Headers.FormatDescription} (default {get_report_format()})? ")
110
+ fmt = input(
111
+ f"{Headers.FormatDescription} ({colorize_choices(Defaults.format_choices, get_report_format())})? "
112
+ )
102
113
  if not fmt:
103
114
  fmt = get_report_format()
104
115
  if fmt not in Defaults.format_choices:
@@ -176,12 +187,12 @@ def report(since, until, fname, fmt, tool_debug, report_debug) -> bool:
176
187
  return True
177
188
 
178
189
 
179
- def test(
190
+ def run_test_cycle(
180
191
  duration, wait, count, fmt, fname, force, debug, rand, logind, bios_debug
181
192
  ) -> bool:
182
193
  """Run a test"""
183
194
  app = Installer(tool_debug=debug)
184
- app.set_requirements("iasl", "ethtool")
195
+ app.set_requirements("iasl", "ethtool", "edid-decode")
185
196
  if not app.install_dependencies():
186
197
  print("Failed to install dependencies")
187
198
  return False
@@ -232,7 +243,7 @@ def test(
232
243
  def install(debug) -> None:
233
244
  """Install the tool"""
234
245
  installer = Installer(tool_debug=debug)
235
- installer.set_requirements("iasl", "ethtool")
246
+ installer.set_requirements("iasl", "ethtool", "edid-decode")
236
247
  if not installer.install_dependencies():
237
248
  sys.exit("Failed to install dependencies")
238
249
  try:
@@ -259,7 +270,8 @@ def parse_args():
259
270
  """Parse command line arguments"""
260
271
  parser = argparse.ArgumentParser(
261
272
  description="Swiss army knife for analyzing Linux s2idle problems",
262
- epilog="The tool can run an immediate test with the 'test' command or can be used to hook into systemd for building reports later.\n"
273
+ epilog="The tool can run an immediate test with the 'test' command "
274
+ "or can be used to hook into systemd for building reports later.\n"
263
275
  "All optional arguments will be prompted if needed.\n"
264
276
  "To use non-interactively, please populate all optional arguments.",
265
277
  )
@@ -282,7 +294,10 @@ def parse_args():
282
294
  test_cmd.add_argument(
283
295
  "--random",
284
296
  action="store_true",
285
- help="Run sleep cycles for random durations and wait, using the --duration and --wait arguments as an upper bound",
297
+ help=(
298
+ "Run sleep cycles for random durations and wait, using the "
299
+ "--duration and --wait arguments as an upper bound",
300
+ ),
286
301
  )
287
302
  test_cmd.add_argument(
288
303
  "--force",
@@ -385,7 +400,7 @@ def main():
385
400
  )
386
401
  elif args.action == "test":
387
402
  relaunch_sudo()
388
- ret = test(
403
+ ret = run_test_cycle(
389
404
  args.duration,
390
405
  args.wait,
391
406
  args.count,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amd-debug-tools
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: debug tools for AMD systems
5
5
  Author-email: Mario Limonciello <superm1@kernel.org>
6
6
  License-Expression: MIT
@@ -0,0 +1,45 @@
1
+ launcher.py,sha256=_Gs0W8tUB2wkTy5Nz4qEzG0VqQcnO7xuIQj0GwV_KbY,968
2
+ test_acpi.py,sha256=wtS43Rz95h7YEEJBeFa6Mswaeo4syBZrw4hY8i0YbJY,3117
3
+ test_batteries.py,sha256=nN5pfP5El7Whypq3HHEpW8bufdf5EWSTVGbayfNQYP4,3360
4
+ test_bios.py,sha256=GBAXE_rXd2G-JE0XJ8AvYcF9Me6LTyQQQ8h0Ib3cpxQ,8981
5
+ test_common.py,sha256=VBPRNLt3y-oSVXC-1HGbZF7jHA_6msW-9MMmbMjNrew,11713
6
+ test_database.py,sha256=q5ZjI5u20f7ki6iCY5o1iPi0YOvPz1_W0LTDraU8mN4,10040
7
+ test_display.py,sha256=hHggv-zBthF1BlwWWSjzAm7BBw1DWcElwil5xAuz87g,5822
8
+ test_failures.py,sha256=H1UxXeVjhJs9-j9yas4vwAha676GX1Es7Kz8RN2B590,6845
9
+ test_installer.py,sha256=LqTAjcRIc7DkdHBYBMsRsbDeVtIh_2oEVhETCb_B0cY,10183
10
+ test_kernel.py,sha256=RW-eLbae02Bhwfu1cegqA1pTj6AS5IqD5lLe-6T0Rjo,7871
11
+ test_launcher.py,sha256=govYHL0Cpj9d5msteV5SfR7Covft31rJuzRkDeytHcY,1461
12
+ test_prerequisites.py,sha256=owO-tMgq_3W4Rm85TgdOFGOabKk9OrUUbRHXD0NHiPg,77018
13
+ test_pstate.py,sha256=a9oAJ9-LANX32XNQhplz6Y75VNYc__QqoSBKIrwvANg,6058
14
+ test_s2idle.py,sha256=VT5iNNVxaL6JdupYPHTIsIVWLBgHRHGTPyXFMO_k1w0,31312
15
+ test_sleep_report.py,sha256=R3cUPPT9r9q4q93xk6NFvi4ySgT5laqidk2SASuTWIo,5878
16
+ test_validator.py,sha256=0dwpWFMHHG16vYo6ON_bUa5Av2NTVEJML93oAZZgcH8,30505
17
+ test_wake.py,sha256=6zi5GVFHQKU1sTWw3O5-aGriB9uu5713QLn4l2wjhpM,7152
18
+ amd_debug/__init__.py,sha256=aOtpIEKGLUStrh0e4qgilHW7HgF4Od-r9pOoZ87NwAM,1105
19
+ amd_debug/acpi.py,sha256=fkD3Sov8cRT5ryPlakRlT7Z9jiCLT9x_MPWxt3xU_tc,3161
20
+ amd_debug/battery.py,sha256=WN-6ys9PHCZIwg7PdwyBOa62GjBp8WKG0v1YZt5_W5s,3122
21
+ amd_debug/bios.py,sha256=wmPKDsTZeQqsHjWpv-YHdgRNlCtFdzHQ6jJf0H3hjN8,3971
22
+ amd_debug/common.py,sha256=QP3UnOrMFO7NGBgi2CGUvBmtYIalm_Z9xxlvcpze_uQ,9613
23
+ amd_debug/database.py,sha256=GkRg3cmaNceyQ2_hy0MBAlMbnTDPHo2co2o4ObWpnQg,10621
24
+ amd_debug/display.py,sha256=5L9x9tI_UoulHpIvuxuVASRtdXta7UCW_JjTb5StEB0,953
25
+ amd_debug/failures.py,sha256=QV3wxl9NYxUV5e0VmMy-pNLg4PoLeCVy0RvBux1pnZM,22536
26
+ amd_debug/installer.py,sha256=2upWqR3e9flu-KruDXkoqCu-P4e3R7aVpMQ6dRRurTU,13064
27
+ amd_debug/kernel.py,sha256=xzAy-sDY5-sd4jxyU7EaBokS7YsvEjoWRuexaTJNRBc,11851
28
+ amd_debug/prerequisites.py,sha256=szi1YT-iY4F3EoG7gRcN9kVTV4XsjDDMTjLfN7vkhJ4,47685
29
+ amd_debug/pstate.py,sha256=akGdJkIxBp0bx3AeGv6ictNxwv8m0j9vQ2IZB0Jx3dM,9518
30
+ amd_debug/s2idle-hook,sha256=LLiaqPtGd0qetu9n6EYxKHZaIdHpVQDONdOuSc0pfFg,1695
31
+ amd_debug/s2idle.py,sha256=QAQ1EIhD823_dBsAmSqZuuGTF--bIz2CK2xA13PgJ8c,12695
32
+ amd_debug/sleep_report.py,sha256=dRoE21nkPMFoa5L9i5XrzPug4KesLfAf1RpPFB7Xpt0,15555
33
+ amd_debug/validator.py,sha256=VomxJOp6ZYBp3oYEaNsD-rvio_b346VSRz7-hyhCS_c,33234
34
+ amd_debug/wake.py,sha256=xT8WrFrN6voCmXWo5dsn4mQ7iR2QJxHrrYBd3EREG-Q,3936
35
+ amd_debug/bash/amd-s2idle,sha256=g_cle1ElCJpwE4wcLezL6y-BdasDKTnNMhrtzKLE9ks,1142
36
+ amd_debug/templates/html,sha256=tnpqHDZF5FfhC6YNRUfOG6Vn9ZtISFr10kEXSB476Mw,14518
37
+ amd_debug/templates/md,sha256=F0xt7m-lOsSz1VeucHA6a-1gsOH7rrik15biXnDgd54,904
38
+ amd_debug/templates/stdout,sha256=hyoOJ96K2dJfnWRWhyCuariLKbEHXvs9mstV_g5aMdI,469
39
+ amd_debug/templates/txt,sha256=nNdsvbPFOhGdL7VA-_4k5aN3nB-6ouGQt6AsWst7T3w,649
40
+ amd_debug_tools-0.2.1.dist-info/licenses/LICENSE,sha256=RBlZI6r3MRGzymI2VDX2iW__D2APDbMhu_Xg5t6BWeo,1066
41
+ amd_debug_tools-0.2.1.dist-info/METADATA,sha256=mNzq0JUgGUeSwdF_H6BRgFb_dNFMvKgu-Htu381x0tE,6783
42
+ amd_debug_tools-0.2.1.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
43
+ amd_debug_tools-0.2.1.dist-info/entry_points.txt,sha256=HC11T2up0pPfroAn6Pg5M2jOZXhkWIipToJ1YPTKqu8,116
44
+ amd_debug_tools-0.2.1.dist-info/top_level.txt,sha256=XYjxExbUTEtiIlag_5iQvZSVOC1EIxhKM4NLklReQ0k,234
45
+ amd_debug_tools-0.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,18 @@
1
+ amd_debug
2
+ launcher
3
+ test_acpi
4
+ test_batteries
5
+ test_bios
6
+ test_common
7
+ test_database
8
+ test_display
9
+ test_failures
10
+ test_installer
11
+ test_kernel
12
+ test_launcher
13
+ test_prerequisites
14
+ test_pstate
15
+ test_s2idle
16
+ test_sleep_report
17
+ test_validator
18
+ test_wake