test(workflow-operator): add unit test coverage for Python UDF operator descriptors - #5876
Conversation
…or descriptors Pin behavior of three previously-untested Python-UDF descriptors: - PythonUDFOpDescV2: operatorInfo (Python UDF, PYTHON_GROUP, dynamic ports); getPhysicalOp wires OpExecWithCode(code, "python") + carries port identities; rejects workers <= 0; schema propagation (retainInputColumns=false -> output columns only; true -> input + output columns); round-trip - PythonUDFSourceOpDescV2: operatorInfo (1-out Python UDF, no inputs / one output, reconfigurable); sourceSchema() from the columns field; getPhysicalOp source wiring; rejects workers <= 0; round-trip - PythonTableReducerOpDesc: operatorInfo (Python Table Reducer, PYTHON_GROUP); getOutputSchemas folds the lambda units into the output schema and rejects the empty default; round-trip 18 new tests; scalafmtCheck + scalafixAll --check clean; no production-code changes.
Automated Reviewer SuggestionsBased on the
|
There was a problem hiding this comment.
Pull request overview
This PR adds Scala unit tests under common/workflow-operator to pin the behavior of previously untested Python UDF operator descriptors (logical metadata, physical-op wiring, schema propagation, and polymorphic JSON round-trip), without changing production code.
Changes:
- Add
PythonUDFOpDescV2Speccovering operatorInfo defaults, physical-op wiring, worker validation, schema propagation, and JSON round-trip. - Add
PythonUDFSourceOpDescV2Speccovering operatorInfo,sourceSchema(), physical-op wiring, worker validation, and JSON round-trip. - Add
PythonTableReducerOpDescSpeccovering operatorInfo, output schema folding/validation, generated Python code shape, and JSON round-trip.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/udf/python/PythonUDFOpDescV2Spec.scala | New unit tests for PythonUDFOpDescV2 covering metadata, physical wiring, schema propagation, and serialization. |
| common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/udf/python/source/PythonUDFSourceOpDescV2Spec.scala | New unit tests for PythonUDFSourceOpDescV2 covering source schema, physical wiring, and serialization. |
| common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/udf/python/PythonTableReducerOpDescSpec.scala | New unit tests for PythonTableReducerOpDesc covering output schema folding, codegen shape, and serialization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
| config | throughput | MB/s | latency | max Δ latest / 7d | |
|---|---|---|---|---|---|
| 🔴 | bs=10 sw=10 sl=64 | 434 | 0.265 | 22,778/31,811/31,811 us | 🔴 +21.5% / 🟢 -9.1% |
| 🔴 | bs=100 sw=10 sl=64 | 954 | 0.582 | 102,378/137,430/137,430 us | 🔴 +6.9% / 🟢 -8.8% |
| ⚪ | bs=1000 sw=10 sl=64 | 1,093 | 0.667 | 911,901/960,421/960,421 us | ⚪ within ±5% / 🟢 -6.3% |
Baseline details
Latest main ed22158 from same runner
| config | metric | PR | latest main | 7d avg | Δ latest | Δ 7d |
|---|---|---|---|---|---|---|
| bs=10 sw=10 sl=64 | throughput | 434 tuples/sec | 472 tuples/sec | 410.82 tuples/sec | -8.1% | +5.6% |
| bs=10 sw=10 sl=64 | MB/s | 0.265 MB/s | 0.288 MB/s | 0.251 MB/s | -8.0% | +5.7% |
| bs=10 sw=10 sl=64 | p50 | 22,778 us | 18,745 us | 23,785 us | +21.5% | -4.2% |
| bs=10 sw=10 sl=64 | p95 | 31,811 us | 31,190 us | 34,980 us | +2.0% | -9.1% |
| bs=10 sw=10 sl=64 | p99 | 31,811 us | 31,190 us | 34,980 us | +2.0% | -9.1% |
| bs=100 sw=10 sl=64 | throughput | 954 tuples/sec | 941 tuples/sec | 891.94 tuples/sec | +1.4% | +7.0% |
| bs=100 sw=10 sl=64 | MB/s | 0.582 MB/s | 0.575 MB/s | 0.544 MB/s | +1.2% | +6.9% |
| bs=100 sw=10 sl=64 | p50 | 102,378 us | 103,079 us | 112,277 us | -0.7% | -8.8% |
| bs=100 sw=10 sl=64 | p95 | 137,430 us | 128,575 us | 139,802 us | +6.9% | -1.7% |
| bs=100 sw=10 sl=64 | p99 | 137,430 us | 128,575 us | 139,802 us | +6.9% | -1.7% |
| bs=1000 sw=10 sl=64 | throughput | 1,093 tuples/sec | 1,102 tuples/sec | 1,041 tuples/sec | -0.8% | +5.0% |
| bs=1000 sw=10 sl=64 | MB/s | 0.667 MB/s | 0.672 MB/s | 0.635 MB/s | -0.7% | +5.0% |
| bs=1000 sw=10 sl=64 | p50 | 911,901 us | 904,675 us | 972,714 us | +0.8% | -6.3% |
| bs=1000 sw=10 sl=64 | p95 | 960,421 us | 939,598 us | 1,023,057 us | +2.2% | -6.1% |
| bs=1000 sw=10 sl=64 | p99 | 960,421 us | 939,598 us | 1,023,057 us | +2.2% | -6.1% |
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,460.85,200,128000,434,0.265,22778.35,31810.98,31810.98
1,100,10,64,20,2095.82,2000,1280000,954,0.582,102377.51,137430.43,137430.43
2,1000,10,64,20,18300.42,20000,12800000,1093,0.667,911901.15,960420.80,960420.80
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5876 +/- ##
============================================
+ Coverage 53.91% 54.00% +0.09%
- Complexity 2780 2802 +22
============================================
Files 1099 1099
Lines 42565 42565
Branches 4577 4577
============================================
+ Hits 22947 22989 +42
+ Misses 18282 18235 -47
- Partials 1336 1341 +5
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ptor specs - assert RuntimeException on output/input column collision (retainInputColumns) - include outputColumns in the PythonUDFOpDescV2 round-trip - include columns in the PythonUDFSourceOpDescV2 round-trip - pin expression and newAttributeName in the PythonTableReducer round-trip
…or descriptors (apache#5876) ### What changes were proposed in this PR? Pin behavior of three previously-untested Python-UDF descriptors in `common/workflow-operator/udf/python/`. No production-code changes. | Spec | Source class | Tests | | --- | --- | --- | | `PythonUDFOpDescV2Spec` | `PythonUDFOpDescV2` | 7 | | `PythonUDFSourceOpDescV2Spec` | `PythonUDFSourceOpDescV2` | 5 | | `PythonTableReducerOpDescSpec` | `PythonTableReducerOpDesc` | 6 | **Behavior pinned** | Surface | Contract | | --- | --- | | `operatorInfo` | exact name + `PYTHON_GROUP`; `PythonUDFOpDescV2` dynamic 1-in/1-out; `PythonUDFSourceOpDescV2` zero inputs / one output + `supportReconfiguration` | | `getPhysicalOp` | wires `OpExecWithCode(code, "python")`; port identities carried; rejects `workers <= 0` (`IllegalArgumentException`) | | Schema propagation | `PythonUDFOpDescV2`: `retainInputColumns=false` → only the output columns, `true` → input + output columns (full map keyed by the declared output port); `PythonUDFSourceOpDescV2`: `sourceSchema()` from the `columns` field; `PythonTableReducerOpDesc`: `getOutputSchemas` folds the lambda units and rejects the empty default | | Round-trip | config fields preserved through the polymorphic base | ### Any related issues, documentation, discussions? Closes apache#5873. ### How was this PR tested? - `sbt "WorkflowOperator/testOnly org.apache.texera.amber.operator.udf.python.PythonUDFOpDescV2Spec org.apache.texera.amber.operator.udf.python.source.PythonUDFSourceOpDescV2Spec org.apache.texera.amber.operator.udf.python.PythonTableReducerOpDescSpec"` — 18 tests, all green - `sbt "WorkflowOperator/Test/scalafmtCheck"` and `sbt "WorkflowOperator/Test/scalafix --check"` — clean - CI to confirm ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 4.8 [1M context])
What changes were proposed in this PR?
Pin behavior of three previously-untested Python-UDF descriptors in
common/workflow-operator/udf/python/. No production-code changes.PythonUDFOpDescV2SpecPythonUDFOpDescV2PythonUDFSourceOpDescV2SpecPythonUDFSourceOpDescV2PythonTableReducerOpDescSpecPythonTableReducerOpDescBehavior pinned
operatorInfoPYTHON_GROUP;PythonUDFOpDescV2dynamic 1-in/1-out;PythonUDFSourceOpDescV2zero inputs / one output +supportReconfigurationgetPhysicalOpOpExecWithCode(code, "python"); port identities carried; rejectsworkers <= 0(IllegalArgumentException)PythonUDFOpDescV2:retainInputColumns=false→ only the output columns,true→ input + output columns (full map keyed by the declared output port);PythonUDFSourceOpDescV2:sourceSchema()from thecolumnsfield;PythonTableReducerOpDesc:getOutputSchemasfolds the lambda units and rejects the empty defaultAny related issues, documentation, discussions?
Closes #5873.
How was this PR tested?
sbt "WorkflowOperator/testOnly org.apache.texera.amber.operator.udf.python.PythonUDFOpDescV2Spec org.apache.texera.amber.operator.udf.python.source.PythonUDFSourceOpDescV2Spec org.apache.texera.amber.operator.udf.python.PythonTableReducerOpDescSpec"— 18 tests, all greensbt "WorkflowOperator/Test/scalafmtCheck"andsbt "WorkflowOperator/Test/scalafix --check"— cleanWas this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8 [1M context])