Skip to content

test(utilities): use pairwise parameter matrices in TestHoodieDeltaStreamer and SchemaEvolutionQuick - #20359

Closed
databird07 wants to merge 1 commit into
apache:masterfrom
databird07:perf/deltastreamer-pairwise-matrix
Closed

databird07 wants to merge 1 commit into
apache:masterfrom
databird07:perf/deltastreamer-pairwise-matrix

Conversation

@databird07

Copy link
Copy Markdown
Contributor

Describe the issue this Pull Request addresses

TestHoodieDeltaStreamer (~1860s) and TestHoodieDeltaStreamerSchemaEvolutionQuick (~410s) are the most expensive classes in hudi-utilities CI. Most of their cost is full-factorial parameter matrices whose rows repeat behaviour that other rows already cover.

Summary and Changelog

  • testLogicalTypesWithJsonSource: 16 -> 8 rows, using an even-parity half fraction, so every pair of factor values still runs together.
  • testCOWLogicalRepair / testMORLogicalRepair: drop the v6/v8 "reconcile with verdict" rows. The reconcile path doesn't branch on table version and still runs on the current version.
  • testUpsertsCOWContinuousMode: drop SPARK x v8. v8 still runs with AVRO records, and all combinations still run on the current version.
  • SchemaEvolutionQuick: remove an exact duplicate MOR row, halve testReorderingColumn the same way, and remove one row that differs only in rowWriterEnable, which has no effect in these upsert-only tests.
  • No test bodies, waits or polling intervals change. Table versions 6, 8, 9 and 10 and both COW and MOR are still exercised.

Impact

Test-only. DeltaStreamer 198 -> 185 invocations (full class 1437s -> 1284s). SchemaEvolutionQuick 52 -> 39 invocations, median 268s -> 213s over 20 runs. JaCoCo shows no lost lines at class level. Measured locally on JDK 17 with 4 pinned CPUs and JaCoCo on; full numbers are in the commit message.

Risk Level

low. Only parameter rows are removed. The one tradeoff (no Spark-record StreamSync write to a v8 table) is called out in the commit message.

Documentation Update

none

Contributor's checklist

  • Read through contributor's guide
  • Enough context is provided in the sections above
  • Adequate tests were added if applicable

…reamer and SchemaEvolutionQuick

These two classes are the most expensive in hudi-utilities CI (~1860 s and
~410 s). Most of their cost comes from full-factorial parameter matrices. This
change removes only parameter rows that duplicate behaviour already covered.
No test bodies, waits or continuous-mode polling/sleep intervals change.

TestHoodieDeltaStreamer (198 -> 185 invocations):
- testLogicalTypesWithJsonSource: 16 -> 8. Replace the full 2^4 factorial
  hasTransformer x orderingField x recordType x tableType with its
  even-parity half fraction, so every pair of factor values still runs
  together in at least one row.
- testCOWLogicalRepair / testMORLogicalRepair: drop the SIX and EIGHT
  "reconcile with verdict" rows. The reconcile path does not branch on table
  version and still runs on CURRENT. The v6 guard rows and v8 default-path
  rows stay.
- testUpsertsCOWContinuousMode: drop SPARK x EIGHT. v8 still runs with AVRO,
  and all combinations still run on the current version. Tradeoff: this was
  the only test in hudi-utilities where StreamSync writes Spark records to a
  v8 table. It is dropped deliberately under the rule that every write
  version runs at least once and all combinations run only on the latest.
  Spark-record writes are still covered on CURRENT, and v8 writes are still
  covered with AVRO. JaCoCo shows no lost lines in the full class.

TestHoodieDeltaStreamerSchemaEvolutionQuick (52 -> 39 invocations):
- testArgs: remove an exact duplicate MERGE_ON_READ row.
- testReorderingColumn: 16 -> 8, using the same half fraction over
  rowWriterEnable x nullForDeletedCols x useKafkaSource x tableType.
- testParamsWithSchemaTransformer: remove a COPY_ON_WRITE row that differs
  from a kept row only in rowWriterEnable. That flag has no effect in these
  upsert-only tests.

Table versions 6, 8, 9 and 10 and both COW and MOR are still exercised.

Measured locally (JDK 17, Spark 3.5, JaCoCo on, taskset 4 CPUs, 20 serial
runs before and after, all exit 0):
- changed DeltaStreamer methods: median 474 s -> 337.5 s, p90 490 -> 349
  (48 -> 35 tests)
- SchemaEvolutionQuick full class: median 268 s -> 213 s, p90 282 -> 225
  (52 -> 39 tests)
- full TestHoodieDeltaStreamer, one run: 1437 s -> 1284 s
JaCoCo intersection across all 20 runs: Quick 25663 -> 25663 lines (no loss).
For the changed DeltaStreamer methods alone, 4 HoodieSparkRecord.toIndexedRecord
lines drop out of the intersection. Other tests in the full class still cover
them. The remaining union-only differences are nondeterministic paths. One
baseline run had a pre-existing Kafka produce race (partition leader not yet
elected after createTopic) that Surefire's retry absorbed.
@github-actions github-actions Bot added the size:S PR with lines of changes in (10, 100] label Oct 16, 2026

@hudi-agent hudi-agent 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.

⚠️ 🤖 This review was generated by an AI agent and may contain mistakes. Please verify any suggestions before applying.

Thanks for working on this! The PR trims the TestHoodieDeltaStreamer and SchemaEvolutionQuick parameter matrices: it switches two 2^4 factorials to even-parity half fractions that still cover every pair of values, and drops one exact duplicate row, a few rows that only varied the table version on the reconcile path, and a row that only changed rowWriterEnable, which these upsert-only tests never use. No correctness issues found. A few style/readability suggestions in the inline comments. Please take a look, and this should be ready for a Hudi committer or PMC member to take it from here. One readability suggestion on the parity filter below.

cc @yihua

for (String tableType : new String[] {"COPY_ON_WRITE", "MERGE_ON_READ"}) {
b.add(Arguments.of(tableType, rowWriterEnable, useKafkaSource, nullForDeletedCols));
// Half fraction: every pair of factor values still appears together in at least one row.
boolean evenParity = !(rowWriterEnable ^ nullForDeletedCols ^ useKafkaSource ^ tableType.equals("MERGE_ON_READ"));

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.

🤖 nit: could you simplify the XOR chain, e.g. by counting the true flags and checking % 2 == 0, or by listing the 8 rows explicitly like logicalTypesWithJsonSourceArgs?

⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.

@databird07

Copy link
Copy Markdown
Contributor Author

Combined into #20364 so the total impact can be reviewed in one place; this commit is included there unchanged. Closing.

@databird07 databird07 closed this Oct 16, 2026
@codecov-commenter

codecov-commenter commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.12%. Comparing base (e9da226) to head (5d82c03).
⚠️ Report is 19 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #20359      +/-   ##
============================================
- Coverage     80.70%   78.12%   -2.59%     
+ Complexity    35124    34022    -1102     
============================================
  Files          2553     2553              
  Lines        143524   143629     +105     
  Branches      17474    17623     +149     
============================================
- Hits         115830   112206    -3624     
- Misses        19746    23247    +3501     
- Partials       7948     8176     +228     
Components Coverage Δ
hudi-common 82.54% <ø> (-1.62%) ⬇️
hudi-client 79.59% <ø> (-4.36%) ⬇️
hudi-flink 86.07% <ø> (+0.01%) ⬆️
hudi-spark-datasource 67.19% <ø> (-7.00%) ⬇️
hudi-utilities 78.19% <ø> (+0.01%) ⬆️
hudi-cli 70.80% <ø> (ø)
hudi-hadoop 69.05% <ø> (-2.11%) ⬇️
hudi-sync 76.85% <ø> (+0.26%) ⬆️
hudi-io 81.34% <ø> (-0.19%) ⬇️
hudi-timeline-service 78.53% <ø> (-4.88%) ⬇️
hudi-cloud 81.00% <ø> (ø)
hudi-kafka-connect 57.90% <ø> (+3.41%) ⬆️
Flag Coverage Δ
common-and-other-modules 52.64% <ø> (+0.11%) ⬆️
flink-integration-tests 49.64% <ø> (+0.05%) ⬆️
hadoop-mr-java-client 43.95% <ø> (+0.01%) ⬆️
integration-tests 13.44% <ø> (+<0.01%) ⬆️
spark-client-hadoop-common 38.68% <ø> (+<0.01%) ⬆️
spark-java-tests 32.17% <ø> (-20.60%) ⬇️
spark-scala-tests 47.74% <ø> (-0.01%) ⬇️
utilities 36.88% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 407 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

size:S PR with lines of changes in (10, 100]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants