-
Notifications
You must be signed in to change notification settings - Fork 3.3k
hack/ci: fix log summary for non-int ginkgo suites #29535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| #!/usr/bin/env python3 | ||
| # | ||
| # tests for github_log_summary.py | ||
| # | ||
|
|
||
| import importlib.util | ||
| import os | ||
| import tempfile | ||
| import unittest | ||
|
|
||
| TESTS_DIR = os.path.dirname(os.path.abspath(__file__)) | ||
|
|
||
| # The tool is a script, not a module, so load it by path. | ||
| spec = importlib.util.spec_from_file_location( | ||
| "github_log_summary", os.path.join(TESTS_DIR, "github_log_summary.py") | ||
| ) | ||
| github_log_summary = importlib.util.module_from_spec(spec) | ||
| spec.loader.exec_module(github_log_summary) | ||
|
|
||
|
|
||
| # Trimmed-down versions of what logformatter emits. The ginkgo path wraps | ||
| # failures in a "log-failed" span inside the "tt" block; the bats path marks | ||
| # up each line with a "bats-*" class. | ||
| GINKGO_HTML = """<div class='tt'> <!-- begin processed output --> | ||
| <span class="timestamp">[+0298s] </span><span class="log-failed">[FAILED] podman pod correctly sets up PIDNS</span> | ||
| <span class="timestamp">[+0298s] </span>expected exit code 0, got 125 | ||
| </div> | ||
| """ | ||
|
|
||
| GINKGO_PASSING_HTML = """<div class='tt'> <!-- begin processed output --> | ||
| <span class="timestamp">[+0271s] </span>ok, all tests passed | ||
| </div> | ||
| """ | ||
|
|
||
| BATS_HTML = """<div class='tt'> <!-- begin processed output --> | ||
| <span class='bats-failed'><a name='t--00001'>not ok 1 podman run</a></span> | ||
| <span class='bats-log'># expected 0, got 125</span> | ||
| </div> | ||
| """ | ||
|
|
||
|
|
||
| def summarize(html, name): | ||
| """Write html to a file called name, then run it through the filter.""" | ||
| with tempfile.TemporaryDirectory() as tmpdir: | ||
| path = os.path.join(tmpdir, name) | ||
| with open(path, "w", encoding="utf-8") as f: | ||
| f.write(html) | ||
| return github_log_summary.filter_html_file(path) | ||
|
|
||
|
|
||
| class TestFormatDetection(unittest.TestCase): | ||
| def test_ginkgo_int_suite(self): | ||
| """The int suite is ginkgo and is detected as such.""" | ||
| out = "".join(summarize(GINKGO_HTML, "int-local-root-fedora.log.html")) | ||
| self.assertIn("[FAILED] podman pod correctly sets up PIDNS", out) | ||
| self.assertIn("expected exit code 0, got 125", out) | ||
|
|
||
| def test_ginkgo_suite_not_named_int(self): | ||
| """Ginkgo suites are detected by content, not by the file name. | ||
|
|
||
| The bindings suite is ginkgo but is not called "int-". Keying off the | ||
| name meant its failures were parsed with the bats parser, which found | ||
| no bats markup and so reported nothing useful. | ||
| """ | ||
| out = "".join(summarize(GINKGO_HTML, "bindings-root-fedora.log.html")) | ||
| self.assertIn("[FAILED] podman pod correctly sets up PIDNS", out) | ||
| self.assertIn("expected exit code 0, got 125", out) | ||
|
Comment on lines
+58
to
+67
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we're now using content instead of the filename, this test is the same as the one before
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah you are right it is redundant and the bigger gap is that all my ginkgo fixtures are -p-shaped so no one could catch this so i will sort it out when i rebuild then from real ouput |
||
|
|
||
| def test_bats_suite(self): | ||
| """The bats parser still handles bats logs.""" | ||
| out = "".join(summarize(BATS_HTML, "sys-local-root-fedora.log.html")) | ||
| self.assertIn("not ok 1 podman run", out) | ||
| self.assertIn("expected 0, got 125", out) | ||
|
|
||
| def test_ginkgo_without_failures(self): | ||
| """A ginkgo log with no failures has nothing to report.""" | ||
| out = "".join(summarize(GINKGO_PASSING_HTML, "int-local-root-fedora.log.html")) | ||
| self.assertEqual(out.strip(), "") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you test this? the logformatter script implies that log-failed won't be emitted if tests are not run with -p.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on an unrelated note: it seems that the bindings test that run without -p currently are classed as log-passed and though I guessed why that happens (ginkgo printing the status at the end instead of the beginning). I was thinking of sending in a patch for this in logformatter but it seems this must've been caught before, thoughts? @Luap99
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have never looked deeply into the logformatter logic, I do not understand most of the perl script there.
The bindings tests fail rarely so I never looked really closely there
And yes it would be nice to test this by pushing a error into the bindings test and verify the the summary work asnd have an actual test content based on real bindings output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed @Luap99 , a fixture built from real output is the right bar. What's on the branch now is hand-written and I can't honestly claim it matches what bindings actually produces.
Plan:
Push a deliberate failure into one of the pkg/bindings/test specs, let CI produce a real failing log, check the summary against that, and build the test fixture from the artifact. Then revert the deliberate failure.
On why this wasn't caught before — I think the log-* classes were only ever read by humans until github_log_summary.py started depending on them in June. Reading the HTML you see the red [FAILED] text in the block and don't notice the heading above it is green, so there was nothing to notice until something parsed them.
@danishprakash you mentioned maybe sending a logformatter patch — do you want to take that, or should I fold it into this PR? I have one working locally but don't want to duplicate your work.