forked from apache/calcite
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CALCITE-4885] Fluent test fixtures so that dependent projects can wr…
…ite parser, validator and rules tests The goal is to be able to write tests from both inside and outside of Calcite, and without deriving from a particular test class. We achieve that goal by creating *fixture* objects for each kind of test. Test configuration (e.g. what SQL query to test) belongs in that fixture, and is set using wither methods. Inside the fixture is a *factory* that creates the objects necessary to run the test (parser, validator, and so forth). The factory necssarily contains the config for the parser, validator, etc. Tests configure the factory by calling methods in their fixture. Also inside a fixture is a *tester* that orchestrates the lifecycle (parse, validate, SQL-to-rel, check results). The tester is stateless (necessary state is provided by parameters to its methods, which often include a `SqlTestFactory`). There is one main implementation of the tester, but it can be substituted with an radically different implementations (say one that no-ops, or dumps all SQL expressions to a file). Tests that compare actual results with expected results may have a `DiffRepository` attached to their fixture. There follows descriptions of other refactorings included in this change. The code was deprecated in [CALCITE-4591], [CALCITE-4593], [CALCITE-4446] to be removed before release 1.28. Move classes `DiffRepository`, `MockRelOptPlanner`, `SqlToRelTestBase`, `RelOptTestBase`, `SqlRuntimeTester`, `SqlOperatorTest` (renaming to `CoreSqlOperatorTest`), `SqlOperatorBaseTest` (renaming to `SqlOperatorTest`). Class `Fixtures` is a single place to obtain fixtures to tests of the parser, validator, operators, planner rules, and more. These fixtures can be used within Calcite but also by any project that uses Calcite (the project just needs to use the `testkit` module). `class FixtureTest` tests `Fixtures` and contains examples. Add `fixture()` methods, to create fixtures without SQL, to many test classes including `RelToSqlConverterTest`, `InterpreterTest`, `SqlParserTest`, `SqlValidatorTest`, `DruidAdapter2IT`, `DruidAdapterIT`. (Previously many tests would write `sql("?")` to create tests with dummy SQL. In `class CalciteAssert`, move method `withRel` from `AssertQuery` to `AssertThat`, so that tests can provide a `RelNode` without first providing dummy SQL. Also make the list of hooks (used heavily by `AssertQuery`) immutable. In `SqlTester`, remove methods `checkFieldOrigin`, `checkResultType`, `checkCollation`, `checkCharset`, `checkIntervalConv`, `checkMonotonic`; all can now be implemented in terms of a new method `validateAndThen`, and similar methods `validateAndApply` and `forEachQueryValidateAndThen`. Obsolete `interface SqlToRelTestBase.Tester`; `SqlToRelFixture` now uses `SqlTester`. Move inner `class MockViewExpander` from `SqlToRelTestBase` to `SqlTestFactory`. Method `SqlToRelTestBase.assertValid` becomes `Matchers.relIsValid`. Refactor/rename a few methods, and change 'query' field to 'expression'. State is now in the fixture (`class SqlParserFixture`) or `SqlTestFactory`. Create a fixture (`class SqlParserListFixture`) for list-based parser tests. Remove fixture's `transform` field; config is now transformed immediately, not deferred. Remove field `LINUXIFY` (thread-local state). Fields `SqlToRelFixture.expression` and `SqlValidatorFixture.expression` were each previously called `query` and had the opposite sense; both are now consistent with `SqlParserFixture.expression`. Rename method `sql` to `withSql`, `config` to `withConfig`, etc. Rename method `withDecorrelation` to `withDecorrelate`, `withLateDecorrelation` to `withLateDecorrelate` `with(RelOptPlanner)` to `withPlanner`, `with(HepProgram)` to `withProgram`. `MaterializedViewTester` is now a utility class for materialized view tests but is no longer required to be a base class. Move `interface AbstractMaterializedViewTest.Sql` to top-level `class MaterializedViewFixture`. In `class MaterializedViewSubstitutionVisitorTest`, create a fixture for satisfiability tests. `RelSupplier` was previously an inner class of `class RelOptTestBase`. It is used in metadata tests (`RelMetadataFixture`) and planner rule tests (`RelOptFixture`) but could be used in other tests too. Add `class RelSuppliers` with utilities and implementations for `RelSupplier`. Move `assertXxx` methods into a fixture, `class SqlAdvisorTest.Fixture`. Remove inner `class LexConfiguration`; it relied on a mutable tester in each `SqlValidatorTest` instance, which is no longer there. Implement methods `toString`, `equals`, `hashCode`. Move inner `class Sql` to top-level `class SqlPrettyWriterFixture`. Add `class ConnectionFactories`, utilities for `ConnectionFactory` and `CalciteAssert.ConnectionPostProcessor`. Enumerates all possible 'xxx' in JDBC `ResultSet.getXxx` and `PreparedStatement.setXxx` methods. Utilities for `interface SqlTester.ResultChecker`. Move `interface SqlOperatorTest.Fixture` to `SqlOperatorFixture`. In `class SqlOperatorFixture`, remove `double delta` arguments from methods that test floating-point values; instead use a `ResultChecker` created using a `ResultCheckers` method such as `isWithin` or `isExactly`. Remove method `withLibrary2`. Move `class SqlToRelConverterTest.RelValidityChecker` to top-level. In class `SqlLimitsTest`, move method `checkTypes` to `class SqlTests`. In a few cases we would built complex transforms (instances of `UnaryOperator`) that were applied just before the test ran. Now we try to apply transforms early, storing a transformed config rather than a chained transform. It's easier to understand and debug. Remove method `RelDataTypeSystemImpl.allowExtendedTrim`, which was added in [CALCITE-2571] but was never used. Remove some uses of `assert` in `TypeCoercionTest`. (Never use `assert` in tests!) Use `Assertions.assertEquals`, `Objects.requireNonNull` via static import. In `class SqlValidator.Config`, rename method `sqlConformance()` to `conformance()`, to be consistent with conformance properties elsewhere. In `class TryThreadLocal`, add methods `letIn(T, Supplier)` and `letIn(T, Runnable)`. Close apache#2685
- Loading branch information
1 parent
864268c
commit bf56743
Showing
132 changed files
with
20,012 additions
and
20,323 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
babel/src/test/java/org/apache/calcite/test/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to you under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* Tests for Calcite. | ||
*/ | ||
@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.FIELD) | ||
@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.PARAMETER) | ||
@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.RETURN) | ||
package org.apache.calcite.test; | ||
|
||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.checkerframework.framework.qual.DefaultQualifier; | ||
import org.checkerframework.framework.qual.TypeUseLocation; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
core/src/main/java/org/apache/calcite/rel/RelValidityChecker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to you under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.calcite.rel; | ||
|
||
import org.apache.calcite.rel.core.CorrelationId; | ||
import org.apache.calcite.util.Litmus; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
|
||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
|
||
import java.util.ArrayDeque; | ||
import java.util.Deque; | ||
import java.util.Set; | ||
|
||
/** | ||
* Visitor that checks that every {@link RelNode} in a tree is valid. | ||
* | ||
* @see RelNode#isValid(Litmus, RelNode.Context) | ||
*/ | ||
public class RelValidityChecker extends RelVisitor | ||
implements RelNode.Context { | ||
private int invalidCount; | ||
private final Deque<RelNode> stack = new ArrayDeque<>(); | ||
|
||
@Override public Set<CorrelationId> correlationIds() { | ||
final ImmutableSet.Builder<CorrelationId> builder = | ||
ImmutableSet.builder(); | ||
for (RelNode r : stack) { | ||
builder.addAll(r.getVariablesSet()); | ||
} | ||
return builder.build(); | ||
} | ||
|
||
@Override public void visit(RelNode node, int ordinal, | ||
@Nullable RelNode parent) { | ||
try { | ||
stack.push(node); | ||
if (!node.isValid(Litmus.THROW, this)) { | ||
++invalidCount; | ||
} | ||
super.visit(node, ordinal, parent); | ||
} finally { | ||
stack.pop(); | ||
} | ||
} | ||
|
||
public int invalidCount() { | ||
return invalidCount; | ||
} | ||
} |
Oops, something went wrong.