mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-15 17:19:55 -07:00
forgetest: the lint takes python -m unittest given a test's file or module
forgectrl's CI runs its dev-server mock test as `python3 -B -m unittest -v tests/test_devserver_mock.py`, and the workflow judge counted python -m unittest only as `unittest discover`: a HOST_TESTED row for that test was refused as not run. _unittest_names: an argument to python -m unittest (not discover) runs the test when it is the test's file (resolved against the step's working-directory) or a dotted name whose module is that file (tests.test_x, tests.test_x.Case.test_one); a -k pattern's value and an argument with a shell variable are not names. Proof: host tests: the CI's own command line, a module, a module with a class and a method; not a module beside it, nor a -k pattern naming it. The manifest tests (34) pass, and the forgetest host suite passes under Linux. Against forgectrl's pinned workflow a row for tests/test_devserver_mock.py is accepted; every earlier verdict on the real workflows is unchanged. Acceptance: none. forgetest is dev-only and in no fingerprint; the lint runs in CI, not in a campaign.
This commit is contained in:
@@ -430,6 +430,30 @@ def _discovers(args, full, at):
|
||||
return posixpath.dirname(full) == at(start) and fnmatch.fnmatchcase(posixpath.basename(full), pattern)
|
||||
|
||||
|
||||
def _unittest_names(args, full, at):
|
||||
"""Whether `python -m unittest ARGS` (not discover) runs the test: an
|
||||
argument is its file (tests/test_x.py), or a dotted name whose module
|
||||
is its file (tests.test_x, tests.test_x.Case.test_one)."""
|
||||
skip = False
|
||||
for a in args:
|
||||
if skip:
|
||||
skip = False
|
||||
continue
|
||||
if a in ("-k",):
|
||||
skip = True
|
||||
continue
|
||||
if a.startswith("-") or "$" in a:
|
||||
continue
|
||||
if a.endswith(".py"):
|
||||
if at(a) == full:
|
||||
return True
|
||||
continue
|
||||
parts = a.split(".")
|
||||
if any(at("/".join(parts[:k]) + ".py") == full for k in range(len(parts), 0, -1)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _pytest_runs(args, full, at):
|
||||
"""Whether pytest ARGS collects the test: named, or its directory given
|
||||
and its file name one pytest collects (test_*.py, *_test.py)."""
|
||||
@@ -451,10 +475,12 @@ def workflow_runs(steps, test_path):
|
||||
resolved against the step's working-directory: the command itself
|
||||
(a script run directly, or a C test's built binary, <dir>/<stem>);
|
||||
the script an interpreter runs (python, bash, sh), a glob matching the
|
||||
whole path; a for loop's list over the test; unittest discover from
|
||||
the test's own directory with a pattern its name matches; pytest on
|
||||
the test or its own directory. An argument to anything else (echo, a
|
||||
build, an install) does not run the test."""
|
||||
whole path; a for loop's list over the test; python -m unittest given
|
||||
the test's file or a dotted name whose module is that file
|
||||
(tests.test_x, tests.test_x.Case.test_one); unittest discover from the
|
||||
test's own directory with a pattern its name matches; pytest on the
|
||||
test or its own directory. An argument to anything else (echo, a build,
|
||||
an install) does not run the test."""
|
||||
full = posixpath.normpath(test_path)
|
||||
stem, ext = posixpath.splitext(posixpath.basename(full))
|
||||
compiled = ext in (".c", ".cc", ".cpp")
|
||||
@@ -478,7 +504,10 @@ def workflow_runs(steps, test_path):
|
||||
if "-m" in args:
|
||||
i = args.index("-m")
|
||||
mod, rest = (args[i + 1], args[i + 2:]) if i + 1 < len(args) else ("", [])
|
||||
if (mod == "unittest" and rest[:1] == ["discover"] and _discovers(rest[1:], full, at)) or \
|
||||
if mod == "unittest" and rest[:1] == ["discover"]:
|
||||
if _discovers(rest[1:], full, at):
|
||||
return True
|
||||
elif (mod == "unittest" and _unittest_names(rest, full, at)) or \
|
||||
(mod == "pytest" and _pytest_runs(rest, full, at)):
|
||||
return True
|
||||
else:
|
||||
|
||||
@@ -293,6 +293,16 @@ class CoverageReportTests(unittest.TestCase):
|
||||
self.assertTrue(self._runs(step % "bash tests/fflog_e2e.sh", "tests/fflog_e2e.sh"))
|
||||
self.assertTrue(self._runs("steps:\n - run: |\n sudo -E FORGEEXT=build/forgeext \\\n"
|
||||
" python3 -B tests/run_test.py\n", "tests/run_test.py"))
|
||||
# python -m unittest given the test's file or its module (the third review: forgectrl's CI
|
||||
# runs its mock test as a file), and not a module beside it or a -k pattern
|
||||
self.assertTrue(self._runs(step % "python3 -B -m unittest -v tests/test_devserver_mock.py",
|
||||
"tests/test_devserver_mock.py"))
|
||||
self.assertTrue(self._runs(step % "python -m unittest tests.test_feeder", "tests/test_feeder.py"))
|
||||
self.assertTrue(self._runs(step % "python -m unittest tests.test_feeder.FeederTests.test_one",
|
||||
"tests/test_feeder.py"))
|
||||
self.assertFalse(self._runs(step % "python -m unittest tests.test_lens", "tests/test_feeder.py"))
|
||||
self.assertFalse(self._runs(step % "python -m unittest -k test_feeder tests.test_lens",
|
||||
"tests/test_feeder.py"))
|
||||
|
||||
def test_the_lint_says_when_it_could_not_read_a_workflow(self):
|
||||
import contextlib
|
||||
|
||||
Reference in New Issue
Block a user