test(pipelines): cover the hugo_ingest functions the v4 ingest path uses - #260
Open
abhishekKokadwar wants to merge 1 commit into
Open
abhishekKokadwar wants to merge 1 commit into
abhishekKokadwar wants to merge 1 commit into
Conversation
utils/hugo_ingest.py had no tests. kubeflow#249's test plan names tests/test_hugo_ingest.py, but the file was never committed (kubeflow#259). Only the production surface is covered. canonical_rag_ingest imports parse_frontmatter and process_html_table; clean_hugo_markdown has no caller, so testing it would add coverage that exercises nothing. Expectations are taken from the module's docstrings and inline comments, from how parse_canonical_document consumes the results, and from docs/RAG_V4_ARCHITECTURE.md, rather than from whatever the code currently returns: - parse_frontmatter: YAML and TOML give the title/description/weight that parse_canonical_document reads; a byte-order mark does not hide the frontmatter; missing keys stay absent; empty input is returned as-is; malformed frontmatter falls back to ({}, content) instead of aborting the run. - process_html_table: tables become GFM tables; rowspan values repeat into every spanned row (release tables); colspan keeps rows the same width; an escaped pipe does not add a column; text around and between tables stays off the table rows, as canonical_rag_ingest groups rows; the markdownify fallback still produces a table; text with no table is returned unchanged. The ingest dependencies were only in pipelines/requirements.txt and Dockerfile.pipeline, so the tests would have skipped in PR Safety. They are added to requirements-test.txt at the same pinned versions. Signed-off-by: Abhishek <abhikokadwar2@gmail.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
google-oss-prow
Bot
requested review from
franciscojavierarceo and
tarekabouzeid
September 30, 2026 06:03
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #259. First of the three test modules #249's test plan names but that were never committed.
Scope
Only the functions production actually calls.
canonical_rag_ingestimportsparse_frontmatterandprocess_html_tablefromutils/hugo_ingest.py. The third function,clean_hugo_markdown, has no caller, so tests for it would count as coverage without exercising anything (the same problemclean_contenthas intest_pipeline_utils.py).tests/test_hugo_ingest.pyrequirements-test.txtbeautifulsoup4,python-frontmatter,markdownify,html-table-rescuer,toml, pinned to the versions inpipelines/requirements.txtandDockerfile.pipelineWhere the expectations come from
These tests assert intended behaviour, not whatever the code happens to return today. Every assertion is traceable to one of these sources:
try/exceptfallback.parse_canonical_documentreadstitle,descriptionandint(weight or 0). It groups table rows as consecutive lines starting with|(GFM_TABLE_ROW_RE), so the tests group rows the same way.docs/RAG_V4_ARCHITECTURE.md, which names Hugo frontmatter and release tables among the inputs v4 was built to handle.Where the intent was ambiguous I asserted only the unambiguous part. For colspan, the config sets a strategy only for rowspan. So the test checks that every row keeps the same width, not whether the spanned value is repeated.
What is covered
parse_frontmatter: YAML and TOML produce identical metadata; a byte-order mark doesn't hide the frontmatter; missing keys stay absent so callers fall back to defaults; empty andNoneinput pass through; malformed YAML and TOML fall back to({}, content)instead of aborting the ingest run.process_html_table: a table becomes a GFM table with header, separator and rows; a rowspan value repeats into every spanned row (release tables); colspan keeps row width consistent; an escaped pipe inside a cell doesn't add a column; text around and between tables stays off the table rows; the markdownify fallback still yields a table; input without a table comes back unchanged.Do the tests catch regressions?
I broke
hugo_ingest.pyin ten ways and re-ran the suite (the source was restored afterwards):""REPEAT_VALUE→EMPTYmeta or {}→metaThe one survivor changes no behaviour:
python-frontmatterreturns adicteven for empty ornullfrontmatter, soor {}is defensive, and nothing a test could observe depends on it.Checking this caught a weak test of my own. The first "no-table input is unchanged" case used input that BeautifulSoup round-trips unchanged anyway, so it couldn't tell whether the early return existed. It now uses
Katib & Trainer <br> v1.9, which BeautifulSoup would rewrite asKatib & Trainer <br/> v1.9.Verification
PR Safetyconditions. In a fresh Python 3.11 venv with onlyrequirements-test.txtinstalled (no KFP), all 18 tests pass with 0 skipped. Without the added dependencies, they would all skip.pip checkreports no broken requirements alongsidefastmcpand the rest.pyflakesandpycodestyle(E4/E7/E9) are clean. I couldn't runrufflocally because of a Windows Application Control policy, so I usedblack -l 120as a proxy forruff format. I also avoided implicit string concatenation that fits on one line, since that's where the two formatters disagree. The file is pure ASCII: the byte-order-mark test writes that character as a Python escape sequence rather than embedding it invisibly in the source. CI is the authoritative check.Interaction with #258
pytestonmaincurrently aborts at collection because of three other test modules, which #258 fixes. This PR doesn't depend on #258. Its tests pass on their own, as above. But the pytest job will stay red until #258 lands.Found while writing this: a latent bug for the next PR
It isn't in
hugo_ingest, so it's out of scope here, but it's worth recording. Incanonical_rag_ingest._stash_for_html, the same table cell can be stored in two different ways, depending on unrelated content elsewhere on the page:content_textHPO & NAS,<YOUR_TOKEN>HPO & NASget_text(), which decodes the entities, only runs if a raw<and>surviveprocess_html_table. A page whose only HTML is a table has none left. This also contradictshugo_ingest's own comment about preserving placeholder tokens like<YOUR_HF_TOKEN>.It's latent today. I ran all 220 pages under
kubeflow/website/content/en/docsthroughparse_canonical_document, and none of the 124 table blocks is affected. I checked that the scan can detect the bug by feeding it a synthetic page, which it catches. On real pages it doesn't trigger, because every page with a table also contains other HTML. I'll cover it with a test in thecanonical_rag_ingestPR.