Description
Task Summary
Two pure workflow-operator classes have small, sharply-defined coverage gaps: AggregationOperation (common/workflow-operator/.../aggregate/AggregationOperation.scala, ~81%, 16 lines unhit) and IntervalJoinOpExec (common/workflow-operator/.../intervalJoin/IntervalJoinOpExec.scala, ~86%, 15 lines unhit). Both are dependency-free in-memory logic — no DB, no storage, no clock. Most of what is left is partial branch coverage rather than whole untested methods, so the lines below are named from codecov's line-level data; testing anything else in these files will re-cover already-green code. Extend the existing AggregationOperationSpec and IntervalOpExecSpec rather than adding new files.
Behavior to add
AggregationOperation — the 16 unhit lines are:
- The four-clause type guard in
sumAgg(138-141),minAgg(196-199) andmaxAgg(221-224) — 12 of the 16 lines, and the main prize. Each isattributeType != INTEGER && != DOUBLE && != LONG && != TIMESTAMP, and the clauses are only partially exercised. For each of the three aggregations, call it with each supported type so the chain falls all the way through, and with unsupported types (STRING, BOOLEAN, BINARY) so it short-circuits at different clauses and throwsUnsupportedOperationException. Assert the message names the aggregation and the offending type. getNumericalValue's TIMESTAMP branch (249-250) — AVERAGE over a TIMESTAMP column is the only route in. Two timestamps an hour apart should average to their epoch-millis midpoint.AveragePartialObj(29) — the case class is never constructed today, which means no test currently drives an AVERAGE partial end to end. An AVERAGE round-trip (init→iteratetwice →merge→finalAgg) covers this and 249-250 together.newAggFunc'scase a: AggregationFunction => a(127) — the non-COUNT arm of the COUNT→SUM remap. Existing tests only drive the COUNT arm; assert that SUM/MIN/MAX/AVERAGE pass through unchanged.
IntervalJoinOpExec — the 15 unhit lines are:
- The
TimeIntervalTypeladder in the right-bound computation (201-212) plus the per-type dispatch at 176, 186 and 196 — 11 of the 15 lines, and the main prize. Cover YEAR / MONTH / DAY / HOUR / MINUTE / SECOND, and thecase Nonefallback at 213-214 (plusDays). ReachingNoneneeds care: every existing test goes through the 6-argumentIntervalJoinOpDescconstructor, which forcesSome(...), and the field is declaredvar timeIntervalType: Option[TimeIntervalType] = _, i.e. initialised tonullrather thanNone. Build a TIMESTAMP desc withtimeIntervalTypeleft unset, serialize it, and assert day semantics — whether Jackson materialisesNoneornullhere is exactly the unobvious part worth pinning. processNumValue's bound-combination arms (144, 148) — theincludeLeftBound && !includeRightBoundand!includeLeftBound && includeRightBounddispatch conditions.removeTooSmallTupleInRightCache(97) — the right-cache eviction comparison. Note the left-cache equivalent is already covered; only the right side is red.intervalCompare(165).
Keep TIMESTAMP fixtures away from Feb 29 and DST boundaries; the interval arithmetic goes through plusYears/plusMonths calendar math.
A correctness defect in the same file (not a coverage item)
While writing the maxAgg tests, note that maxAgg seeds its accumulator with AttributeTypeUtils.minValue(attributeType) but its finaliser collapses to null when the partial equals AttributeTypeUtils.maxValue(attributeType). minAgg is consistent — it seeds maxValue and finalises against maxValue. So maxAgg has it both ways round: MAX over an empty input returns the type's minimum instead of null, and a legitimate MAX result that happens to equal the type's maximum is wrongly collapsed to null.
Those finaliser lines are already covered, so fixing this will not move the coverage number — it is a correctness fix that happens to sit next to the work. Fix it in the same PR (#6878 is the precedent for fix-plus-tests) or file it separately, but do not encode the current result as if it were intended.
Task Type
- Refactor / Cleanup
- DevOps / Deployment / CI
- Testing / QA
- Documentation
- Performance
- Other
Activity
fix(workflow-operator): fall back to day semantics for an unset inter…
fix(workflow-operator, v1.2): fall back to day semantics for an unset…