mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 10:03:49 -06:00
fix: one failure line per file, tests stay local
This commit is contained in:
1 parent
2478c2a96c
commit
27bd4f1a50
8 files changed
+85
-23
No files matched your search
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
# and Invoke-WebRequest throws on a cut transfer before the hash is read:
|
# and Invoke-WebRequest throws on a cut transfer before the hash is read:
|
||||||
# the site's build rewrites this line there (scripts/sitebootstrap.py).
|
# the site's build rewrites this line there (scripts/sitebootstrap.py).
|
||||||
$mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that."
|
$mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that."
|
||||||
$defaultInstallSha256 = "5f933d4ab032e6e401341818a35eeee9b4018932fde7ad5111fa789375fb350a"
|
$defaultInstallSha256 = "5b8bd7b486d236ee1d00439b2bdd4f6fefcf20112abe3b0f1037e38426d80c15"
|
||||||
$maximumInstallerBytes = 2MB
|
$maximumInstallerBytes = 2MB
|
||||||
$installerExit = 0
|
$installerExit = 0
|
||||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||||
|
|||||||
+4
-4
@@ -6122,11 +6122,11 @@ def _report_outcome(
|
|||||||
# A failure the progress already named on its FAILED line is not named
|
# A failure the progress already named on its FAILED line is not named
|
||||||
# again: line mode listed each one twice (tui_audit_17 P3-7).
|
# again: line mode listed each one twice (tui_audit_17 P3-7).
|
||||||
unsaid = [failure for failure in failures or [] if failure[0] not in SAID_FAILED]
|
unsaid = [failure for failure in failures or [] if failure[0] not in SAID_FAILED]
|
||||||
if unsaid and len(unsaid) > 1 and len(reasons) == 1 and reasons != {""}:
|
if failures and len(failures) > 1 and len(reasons) == 1 and reasons != {""}:
|
||||||
# One cause, said once: a read-only folder listed ten of its files
|
# One cause, said once: a read-only folder listed ten of its files
|
||||||
# and "... and 266 more" above the advice that fixes them all.
|
# and "... and 266 more" above the advice that fixes them all.
|
||||||
say(f" failed: {_plural(len(unsaid), 'file')} ({reasons.pop()}), "
|
said = f", first {unsaid[0][0]}" if unsaid else ""
|
||||||
f"first {unsaid[0][0]}")
|
say(f" failed: {_plural(len(failures), 'file')} ({reasons.pop()}){said}")
|
||||||
else:
|
else:
|
||||||
for dest, reason in unsaid[:10]:
|
for dest, reason in unsaid[:10]:
|
||||||
say(f" failed: {dest}" + (f" ({reason})" if reason else ""))
|
say(f" failed: {dest}" + (f" ({reason})" if reason else ""))
|
||||||
@@ -15547,7 +15547,7 @@ def core_count_words(cores: list[str], base: list[str]) -> str:
|
|||||||
|
|
||||||
def _tui_systems_chosen(state: TuiState) -> list[str]:
|
def _tui_systems_chosen(state: TuiState) -> list[str]:
|
||||||
"""The systems the run is narrowed to, [] for every system."""
|
"""The systems the run is narrowed to, [] for every system."""
|
||||||
return [value for flag, value in _tui_system_flags(state) if value]
|
return [value for _flag, value in _tui_system_flags(state) if value]
|
||||||
|
|
||||||
|
|
||||||
def _chosen_cores(state: TuiState) -> set[str] | None:
|
def _chosen_cores(state: TuiState) -> set[str] | None:
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins
|
|||||||
# curl or wget stop on a cut transfer before the hash is read: the site's
|
# curl or wget stop on a cut transfer before the hash is read: the site's
|
||||||
# build rewrites this line there (scripts/sitebootstrap.py).
|
# build rewrites this line there (scripts/sitebootstrap.py).
|
||||||
MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that."
|
MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that."
|
||||||
DEFAULT_INSTALL_SHA256="5f933d4ab032e6e401341818a35eeee9b4018932fde7ad5111fa789375fb350a"
|
DEFAULT_INSTALL_SHA256="5b8bd7b486d236ee1d00439b2bdd4f6fefcf20112abe3b0f1037e38426d80c15"
|
||||||
MAX_INSTALLER_BYTES=2097152
|
MAX_INSTALLER_BYTES=2097152
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
{
|
{
|
||||||
"dest": "roms/ports/retrobios/install.py",
|
"dest": "roms/ports/retrobios/install.py",
|
||||||
"repo_path": "install.py",
|
"repo_path": "install.py",
|
||||||
"size": 996363,
|
"size": 996397,
|
||||||
"sha256": "5f933d4ab032e6e401341818a35eeee9b4018932fde7ad5111fa789375fb350a",
|
"sha256": "5b8bd7b486d236ee1d00439b2bdd4f6fefcf20112abe3b0f1037e38426d80c15",
|
||||||
"executable": false
|
"executable": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
"muos": {
|
"muos": {
|
||||||
"archive": {
|
"archive": {
|
||||||
"dest": "ARCHIVE/RetroBIOS.muxapp",
|
"dest": "ARCHIVE/RetroBIOS.muxapp",
|
||||||
"size": 1049540,
|
"size": 1049574,
|
||||||
"sha256": "a7a9c2f9b7d018d0aca34731957a13d9d8ab22ea747381e6750d45abbfb70390"
|
"sha256": "30bbe8a0f78cc7b6bb37b9290c69e2244e0b9217339d9ea695f45c0d7815a263"
|
||||||
},
|
},
|
||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
@@ -92,8 +92,8 @@
|
|||||||
{
|
{
|
||||||
"name": "RetroBIOS/install.py",
|
"name": "RetroBIOS/install.py",
|
||||||
"repo_path": "install.py",
|
"repo_path": "install.py",
|
||||||
"size": 996363,
|
"size": 996397,
|
||||||
"sha256": "5f933d4ab032e6e401341818a35eeee9b4018932fde7ad5111fa789375fb350a",
|
"sha256": "5b8bd7b486d236ee1d00439b2bdd4f6fefcf20112abe3b0f1037e38426d80c15",
|
||||||
"executable": false
|
"executable": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -166,8 +166,8 @@
|
|||||||
{
|
{
|
||||||
"dest": ".config/modules/retrobios/install.py",
|
"dest": ".config/modules/retrobios/install.py",
|
||||||
"repo_path": "install.py",
|
"repo_path": "install.py",
|
||||||
"size": 996363,
|
"size": 996397,
|
||||||
"sha256": "5f933d4ab032e6e401341818a35eeee9b4018932fde7ad5111fa789375fb350a",
|
"sha256": "5b8bd7b486d236ee1d00439b2bdd4f6fefcf20112abe3b0f1037e38426d80c15",
|
||||||
"executable": false
|
"executable": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"scanned",
|
"scanned",
|
||||||
"version",
|
"version",
|
||||||
"choices",
|
"choices",
|
||||||
|
"set_aside",
|
||||||
"file",
|
"file",
|
||||||
"system",
|
"system",
|
||||||
"checking",
|
"checking",
|
||||||
@@ -58,6 +59,9 @@
|
|||||||
{
|
{
|
||||||
"$ref": "#/$defs/choices"
|
"$ref": "#/$defs/choices"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/set_aside"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/$defs/file"
|
"$ref": "#/$defs/file"
|
||||||
},
|
},
|
||||||
@@ -299,6 +303,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"set_aside": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"event",
|
||||||
|
"platform",
|
||||||
|
"dests"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"event": {
|
||||||
|
"const": "set_aside"
|
||||||
|
},
|
||||||
|
"platform": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"dests": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"file": {
|
"file": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ _SAVED: dict = {}
|
|||||||
|
|
||||||
def _refuse(host: object) -> None:
|
def _refuse(host: object) -> None:
|
||||||
where = os.environ.get(NETLOG)
|
where = os.environ.get(NETLOG)
|
||||||
if where:
|
# A name under .invalid never resolves (RFC 2606): a test names one to
|
||||||
|
# fail on purpose, refused here before its DNS query leaves.
|
||||||
|
if where and not str(host).endswith(".invalid"):
|
||||||
with open(where, "a", encoding="utf-8") as log:
|
with open(where, "a", encoding="utf-8") as log:
|
||||||
log.write(f"{os.getpid()} {host} {' '.join(sys.argv)[:300]}\n")
|
log.write(f"{os.getpid()} {host} {' '.join(sys.argv)[:300]}\n")
|
||||||
raise OSError(errno.ENETUNREACH, f"a test makes no request to {host}")
|
raise OSError(errno.ENETUNREACH, f"a test makes no request to {host}")
|
||||||
|
|||||||
+27
-6
@@ -10,6 +10,7 @@ import io
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
|
import select
|
||||||
import shlex
|
import shlex
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
@@ -4182,17 +4183,35 @@ class AQuestionLeftWithCtrlDOrCtrlCIsAStop(unittest.TestCase):
|
|||||||
|
|
||||||
home = Path(_tempdir(self))
|
home = Path(_tempdir(self))
|
||||||
master, slave = pty.openpty()
|
master, slave = pty.openpty()
|
||||||
|
# Its output on the terminal too: piped, nothing is asked, and the
|
||||||
|
# test skipped on every machine.
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
[sys.executable, "install.py"], cwd=REPO_ROOT, stdin=slave,
|
[sys.executable, "install.py", "--plain"], cwd=REPO_ROOT, stdin=slave,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True,
|
stdout=slave, stderr=slave,
|
||||||
env={**os.environ, "HOME": str(home), "RETROBIOS_OS": "linux"},
|
# No request leaves the machine: the standalone emulators' lists
|
||||||
|
# come from the network (code_audit_24 P3-13).
|
||||||
|
env={**os.environ, "HOME": str(home), "RETROBIOS_OS": "linux",
|
||||||
|
"RETROBIOS_INSTALL_OFFLINE": "1"},
|
||||||
)
|
)
|
||||||
os.close(slave)
|
os.close(slave)
|
||||||
self.addCleanup(os.close, master)
|
self.addCleanup(os.close, master)
|
||||||
time.sleep(3)
|
out = ""
|
||||||
|
deadline = time.monotonic() + 60
|
||||||
|
while "Which setup?" not in out and proc.poll() is None \
|
||||||
|
and time.monotonic() < deadline:
|
||||||
|
if select.select([master], [], [], 0.2)[0]:
|
||||||
|
out += os.read(master, 65536).decode("utf-8", "replace")
|
||||||
os.write(master, b"\x04")
|
os.write(master, b"\x04")
|
||||||
out, _ = proc.communicate(timeout=60)
|
proc.wait(timeout=60)
|
||||||
if "Choose the platform" not in out:
|
while select.select([master], [], [], 0.2)[0]:
|
||||||
|
try:
|
||||||
|
chunk = os.read(master, 65536)
|
||||||
|
except OSError:
|
||||||
|
break
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
out += chunk.decode("utf-8", "replace")
|
||||||
|
if "Which setup?" not in out:
|
||||||
self.skipTest("a platform was detected on this machine")
|
self.skipTest("a platform was detected on this machine")
|
||||||
self.assertEqual(proc.returncode, 130, out)
|
self.assertEqual(proc.returncode, 130, out)
|
||||||
self.assertIn("Stopped", out)
|
self.assertIn("Stopped", out)
|
||||||
@@ -5211,6 +5230,8 @@ class EventsDescribeTheRun(unittest.TestCase, _SyntheticTree):
|
|||||||
# The systems Choose systems lists, before the files are read.
|
# The systems Choose systems lists, before the files are read.
|
||||||
{"event": "choices", "platform": "retroarch",
|
{"event": "choices", "platform": "retroarch",
|
||||||
"systems": ["sys-a", "sys-b", "other"]},
|
"systems": ["sys-a", "sys-b", "other"]},
|
||||||
|
# Nothing set aside before the choice (code_audit_24 P3-3).
|
||||||
|
{"event": "set_aside", "platform": "retroarch", "dests": []},
|
||||||
# a.bin and b.bin are in place: the first read and the last.
|
# a.bin and b.bin are in place: the first read and the last.
|
||||||
{"event": "checking", "files_done": 1, "files_total": 2},
|
{"event": "checking", "files_done": 1, "files_total": 2},
|
||||||
{"event": "checking", "files_done": 2, "files_total": 2},
|
{"event": "checking", "files_done": 2, "files_total": 2},
|
||||||
|
|||||||
@@ -823,9 +823,16 @@ class Widgets(unittest.TestCase):
|
|||||||
state = fresh_state()
|
state = fresh_state()
|
||||||
press(state, "up")
|
press(state, "up")
|
||||||
self.assertEqual(state.focus["setup"], 2)
|
self.assertEqual(state.focus["setup"], 2)
|
||||||
state = self.systems_state(20)
|
state = fresh_state()
|
||||||
|
state.stack = ["setup", "platforms"]
|
||||||
press(state, "up")
|
press(state, "up")
|
||||||
self.assertEqual(state.focus["systems"], 0)
|
self.assertEqual(state.focus["platforms"], 0)
|
||||||
|
# A list of ticks wraps at any length: None and Done, at its end,
|
||||||
|
# are a few presses up from its first item (tui_audit_17 P3-1).
|
||||||
|
state = self.systems_state(20)
|
||||||
|
state.focus["systems"] = 0
|
||||||
|
press(state, "up")
|
||||||
|
self.assertEqual(install.tui_rows(state)[state.focus["systems"]].action, "done")
|
||||||
|
|
||||||
def test_filter_ignores_case_and_accents(self):
|
def test_filter_ignores_case_and_accents(self):
|
||||||
state = self.systems_state(3)
|
state = self.systems_state(3)
|
||||||
@@ -6777,7 +6784,12 @@ class AuditSevenScreens(unittest.TestCase):
|
|||||||
with SaveDirectoryRepository() as repo:
|
with SaveDirectoryRepository() as repo:
|
||||||
argv = ["install.py", "--platform", "retroarch", "--dest", str(repo.dest),
|
argv = ["install.py", "--platform", "retroarch", "--dest", str(repo.dest),
|
||||||
"--manifest", str(repo.root / "install" / "retroarch.json")]
|
"--manifest", str(repo.root / "install" / "retroarch.json")]
|
||||||
|
# The files come from the repository on the loopback: the module
|
||||||
|
# read its base before the environment named it (code_audit_24
|
||||||
|
# P3-13).
|
||||||
|
served = repo.env()["RETROBIOS_BASE_URL"] + "/{path}"
|
||||||
with mock.patch.dict(os.environ, repo.env()), \
|
with mock.patch.dict(os.environ, repo.env()), \
|
||||||
|
mock.patch.object(install, "RAW_FILE_URL", served), \
|
||||||
mock.patch.object(sys, "argv", argv), \
|
mock.patch.object(sys, "argv", argv), \
|
||||||
mock.patch.object(sys.stdin, "isatty", return_value=True), \
|
mock.patch.object(sys.stdin, "isatty", return_value=True), \
|
||||||
mock.patch.object(install, "_is_terminal", return_value=True), \
|
mock.patch.object(install, "_is_terminal", return_value=True), \
|
||||||
|
|||||||
Reference in new issue
Block a user