Factor out comparison-based oracle reproducers to share common base - #1351
Conversation
|
I think this PR already improves on the current state, but I'm now wondering whether we can further improve it: conceptually, the individual logic bug test oracles are different from the unexpected error oracle. Thus, rather than instantiating specific reproducers for the logic bug oracles, can we have a separate |
|
Indeed, the above refactor ended up mainly factoring out the logic-bug aspect, but the unexpected-error aspect can be factored out better and would be applicable to essentially all oracles. I have added a new commit. The unexpected-error reproduction now has its own class, and any oracle can implement it simply with a functional interface. There are still specific reproducers for the logic bug oracles, but now these only contain the logic that's necessary for the logic-bug reproduction. I kept the |
Summary
The EET, TLP-WHERE and NoREC oracles all detect a bug the same way. Each evaluates two things that should agree and compares them. When they disagree (or when one triggers an unexpected database error), the oracle produces a
Reproducerthat re-runs the comparison against the reduced database during test case reduction.The three
Reproducerimplementations had shared logic. Each decided whether a reduced database still shows the bug, took care to distinguish the original failure from an unrelated error introduced by the reduction itself, and formatted the failing queries into the reduced test case. This PR moves that shared logic into a new abstract class and rewrites the three reproducers on top of it. There is no change in behaviour.Changes
New base class (
common/oracle/AbstractComparisonReproducer.java)Holds the
bugStillTriggerscontrol flow and thegetBugInformationformatting that the three oracles previously duplicated. This covers re-evaluating both sides, treating an unexpected error as a reproduction only when it is the same error the original failure reported, and writing the header that introduces the failing queries.A subclass supplies only the parts that differ between oracles. This includes how each side is evaluated against the database, how the two sides are compared, and how the failing queries are written out.
common/oracle/EETOracle.javaEETReproducernow extends the base class. A side is evaluated by reading the first column of a query's result set, and the two are compared withassumeResultSetsAreEqual.common/oracle/TLPWhereOracle.javaTLPWhereReproducernow extends the base class. The original side is a plain result set and the transformed side is the combined result of the three partition queries. Because the comparison also needs the human-readable combined query strings thatgetCombinedResultSetfills in, a small value class carries them alongside the result set for the transformed side.common/oracle/NoRECOracle.javaNoRECReproducernow extends the base class. The two sides are integer row counts compared for inequality, keeping the existing guard that treats a failed count (-1) on either side as no reproduction.