Skip to content

test(verify): run the source operators, and report what is covered - #8364

Draft
kz930 wants to merge 14 commits into
apache:mainfrom
kz930:feat/verify-sources-and-coverage
Draft

kz930 wants to merge 14 commits into
apache:mainfrom
kz930:feat/verify-sources-and-coverage

Conversation

@kz930

@kz930 kz930 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

A source reads a file rather than an upstream port, so it is configured from a
file the runner writes rather than from a table, and the variants follow the
configuration: a CSV with a header and without, an encoding per charset.

Two reports come with it. One prints which operators run and which are
withheld and why, so the state of the set is a command rather than a claim.
The other parses every generated script and fails on one that a hostile column
name would break, which is a whole class of defect a comparison cannot see.

Any related issues, documentation, discussions?

Part of #8325, 24 of 27; that issue lists the set in order.

Closes #8426, the task this change is the whole of.

How was this PR tested?

The tests in this change cover it. The whole set is exercised together once the last piece lands: every operator run through the engine and through its generated script, and the two answers compared.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

A source reads a file rather than an upstream port, so it is configured from a
file the runner writes rather than from a table, and the variants follow the
configuration: a CSV with a header and without, an encoding per charset.

Two reports come with it. One prints which operators run and which are
withheld and why, so the state of the set is a command rather than a claim.
The other parses every generated script and fails on one that a hostile column
name would break, which is a whole class of defect a comparison cannot see.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added feature platform Non-amber Scala service paths labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @bobbai00
    You can notify them by mentioning @bobbai00 in a comment.

kz930 and others added 2 commits September 2, 2026 17:17
…ady are

It routes a source to the source runner and asks the escaping check for its
findings, and the coverage report in turn reads the operators it discovered.
Split across two changes those references point both ways, and neither
compiles until both land whatever order they land in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The spec printed a tier per operator, a per-kind tally, and every withheld run
with its reason. That is a progress report: it read the same dispositions the
run itself reads and asserted nothing about them, so it could only ever say what
the run had already decided.

What it did assert stays: a small set of operators that must not become
unrunnable. They take the shared table as it is and nothing about them is hard to
run, so one turning up flagged means something upstream of the disposition broke.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.27%. Comparing base (4d7fd49) to head (556bbca).
⚠️ Report is 32 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8364      +/-   ##
============================================
- Coverage     93.62%   93.27%   -0.36%     
- Complexity     4842     4846       +4     
============================================
  Files          1211     1213       +2     
  Lines         49991    50269     +278     
  Branches       6125     6150      +25     
============================================
+ Hits          46805    46887      +82     
- Misses         1675     1870     +195     
- Partials       1511     1512       +1     
Flag Coverage Δ *Carryforward flag
access-control-service 71.78% <ø> (-8.40%) ⬇️
agent-service 99.32% <ø> (ø) Carriedforward from de34e86
amber 89.91% <ø> (+0.06%) ⬆️ Carriedforward from de34e86
computing-unit-managing-service 55.20% <ø> (-21.95%) ⬇️
config-service 87.37% <ø> (+0.24%) ⬆️
file-service 81.53% <ø> (-2.12%) ⬇️
frontend 96.71% <ø> (+0.55%) ⬆️ Carriedforward from de34e86
notebook-migration-service 83.73% <ø> (ø)
pyamber 98.47% <ø> (+0.06%) ⬆️ Carriedforward from de34e86
workflow-compiling-service 77.19% <ø> (+2.19%) ⬆️ Carriedforward from de34e86

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Two comments here restated what the code beside them shows: the three tiers a
source dispatches through, which `canRun` and `flagReason` already spell out,
and this spec's own repetition of the runner's dispatch, which belongs to the
runner.

What replaces them says what each file is for, once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source verification and coverage checks look good.

@kz930
kz930 marked this pull request as draft September 4, 2026 17:12
kz930 and others added 2 commits September 4, 2026 13:22
The translator names a variable per output PORT, not per reader, so a workflow
that draws two charts from one upstream hands both the same name. An operator
that drops rows into it, or assigns a column through it, changes what the other
branch reads. Ten operators did, and every one of them passed: a fixture with a
single branch has nothing to notice it with.

`StandaloneInputCheck` reads the generated code instead of waiting for a run to
disagree, and reports all three spellings: the assignment, the `inplace=True`,
and the rebinding that looks local but renames the shared variable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`in1df.loc[:, "c"] = v` writes to the input exactly as `in1df["c"] = v` does,
and the pattern read only the plain subscript, so an operator would have passed
for choosing the accessor.

What it still cannot see is a mutation through another name: bind the frame to
something else first and the writes below are invisible to anything reading the
code. The scaladoc says so rather than leaving the check looking airtight.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new check catches direct changes to input frames. Looks good.

A hostile-column run now exists, and the two look alike enough that a reader
could take one for a duplicate of the other. What this end cannot do is run the
script; what the run cannot do is make every knob hostile at once, since a table
holds one hostile column per type and the first knob takes it.

The rest is length. StandaloneInputCheck kept a paragraph on what it cannot see,
which rested on no operator doing that today, and the dispatcher stated the
verdict-in-the-test-name rule in four places where one will do.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kz930
kz930 force-pushed the feat/verify-sources-and-coverage branch from 65bda18 to f66d6e5 Compare September 9, 2026 06:50
OperatorBehaviorSpec forks a Python subprocess per operator, and at
core-count concurrency the contention caused rare flakes. A fixed 4 is
deterministic across machines and still runs about three times faster
than serial; it also matches PythonWorkerPool's own default cap, so the
two bounds agree rather than multiply.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Sep 10, 2026
@github-actions github-actions Bot removed the dependencies Pull requests that update a dependency file label Sep 10, 2026
kz930 and others added 3 commits September 10, 2026 16:45
It restated its own signature and listed a codec table that lives in
TupleIO. The reasons a reader cannot derive stay.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Four more --add-opens. Kryo recurses into a timestamp's internals when it
serializes one, and reaches them only in a JVM that has already forked a
Python worker, which is what running this module's tests without
WCS_TEST_FILTER does. The two CI jobs each take half, so CI never gets
there; a local full-module run does, and reports an
InaccessibleObjectException that looks like a defect in the diff.

They arrive with the spec that makes the combination possible.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A scan source is fixtured by the format it declares, so registering an
encoder for "Parquet" is the whole of what the new source needs from this
runner: no handler, and no mention of the operator anywhere here.

The writer is the inverse of ParquetSchemaMapping, which is what the
operator reads the file back with. Every column is written optional, since
Parquet has no null value and only a field that repeats zero times can
carry a hole. A timestamp is written as the wall clock counted from the
epoch, the reading both paths agree on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source coverage and mutation checks look good on the current fixture.

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source output order matters because offset, limit, and downstream first row behavior use it. This comparison ignores order, so an exported source can reverse every row and still pass. Please compare source outputs in order.

@kz930

kz930 commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

The source comparison is already positional. SourceCategoryRunner calls Comparator.assertEqual without arguments, orderSensitive defaults to true, so compare.py never receives --unordered and never sorts either side. A reversed export fails, and ComparatorSpec pins that directly in "treat row-reordered files as unequal under positional comparison".

The epilogue writes a declared-integral column as an integer, the way the
engine's writer does, and a source's declared columns are what the Texera path
already read back here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source checks now compare the schema and row order. The earlier finding is addressed. Looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature platform Non-amber Scala service paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run the source operators, and report what is covered

3 participants