Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove yaml-tests dependency on fdb-record-layer-core test code #3252

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.lang.annotation.RetentionPolicy;

/**
* Mark specific {@link YamlTestConfig} as disabled for the current test in an {@link YamlTest} test class.
* Mark specific {@link YamlTestConfig} as disabled for the current test in an {@link YamlTestExtension} test class.
* <p>
* Any config in {@link #value()} will be skipped for the annotated test.
* </p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

/**
* Mark specific {@link YamlTestConfig} that are designated test maintenance helper configs as enabled for the current
* test in an {@link YamlTest} test class.
* test in an {@link YamlTestExtension} test class.
* <p>
* Any config in {@link #value()} will be included for the annotated test. Any config not included will be skipped.
* </p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@ public final class YamlRunner {
static final String TEST_NIGHTLY_REPETITION = "tests.yaml.iterations";

@Nonnull
private final String resourcePath;

private final YamlConnectionFactory factory;
@Nonnull
private final YamlExecutionContext executionContext;
private final YamlExecutionContext.ContextOptions additionalOptions;

public YamlRunner(@Nonnull String resourcePath, @Nonnull YamlConnectionFactory factory,
@Nonnull final YamlExecutionContext.ContextOptions additionalOptions) throws RelationalException {
this.resourcePath = resourcePath;
this.executionContext = new YamlExecutionContext(resourcePath, factory, additionalOptions);
public YamlRunner(@Nonnull YamlConnectionFactory factory,
@Nonnull final YamlExecutionContext.ContextOptions additionalOptions) {
this.factory = factory;
this.additionalOptions = additionalOptions;
}

public void run() throws Exception {
public void runYamsql(@Nonnull String resourcePath) throws Exception {
YamlExecutionContext executionContext = new YamlExecutionContext(resourcePath, factory, additionalOptions);
try {
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(true);
Expand All @@ -92,16 +92,16 @@ public void run() throws Exception {
block.execute();
}

evaluateTestBlockResults(testBlocks);
replaceTestFileIfRequired();
replaceMetricsFileIfRequired();
evaluateTestBlockResults(testBlocks, resourcePath);
replaceTestFileIfRequired(executionContext);
replaceMetricsFileIfRequired(executionContext);
} catch (RelationalException | IOException e) {
logger.error("‼️ running test file '{}' was not successful", resourcePath, e);
throw e;
}
}

private void evaluateTestBlockResults(List<TestBlock> testBlocks) {
private void evaluateTestBlockResults(List<TestBlock> testBlocks, final String resourcePath) {
logger.info("");
logger.info("");
logger.info("--------------------------------------------------------------------------------------------------------------");
Expand Down Expand Up @@ -140,24 +140,24 @@ private static InputStream getInputStream(@Nonnull final String resourcePath) th
return inputStream;
}

private void replaceTestFileIfRequired() {
private void replaceTestFileIfRequired(final YamlExecutionContext executionContext) {
if (executionContext.getEditedFileStream() == null || !executionContext.isDirty()) {
return;
}
try {
try (var writer = new PrintWriter(new FileWriter(Path.of(System.getProperty("user.dir")).resolve(Path.of("src", "test", "resources", resourcePath)).toAbsolutePath().toString(), StandardCharsets.UTF_8))) {
try (var writer = new PrintWriter(new FileWriter(Path.of(System.getProperty("user.dir")).resolve(Path.of("src", "test", "resources", executionContext.resourcePath)).toAbsolutePath().toString(), StandardCharsets.UTF_8))) {
for (var line : executionContext.getEditedFileStream()) {
writer.println(line);
}
}
logger.info("🟢 Source file {} replaced.", resourcePath);
logger.info("🟢 Source file {} replaced.", executionContext.resourcePath);
} catch (IOException e) {
logger.error("⚠️ Source file {} could not be replaced with corrected file.", resourcePath);
logger.error("⚠️ Source file {} could not be replaced with corrected file.", executionContext.resourcePath);
Assertions.fail(e);
}
}

private void replaceMetricsFileIfRequired() throws RelationalException {
private void replaceMetricsFileIfRequired(final YamlExecutionContext executionContext) throws RelationalException {
if (!executionContext.isDirtyMetrics()) {
return;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import com.apple.foundationdb.relational.yamltests.configs.YamlTestConfig;

/**
* An enum of reasons to disable a {@link YamlTest} test for a given {@link YamlTestConfig}.
* An enum of reasons to disable a {@link YamlTestExtension} test for a given {@link YamlTestConfig}.
* <p>
* Note: Part of the reason this exists as an enum, is that fields on annotations can only be certain types, and
* enum seemed like the cleanest.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.Extension;
Expand All @@ -57,7 +56,20 @@
import java.util.stream.Stream;

/**
* Extension that backs {@link YamlTest}.
* An extension for test classes that run {@code .yamsql} files.
* <p>
* Test classes extended with this should have all their tests annotated with
* {@link org.junit.jupiter.api.TestTemplate}, instead of {@link org.junit.jupiter.api.Test}.
* Note: This doesn't work with {@link org.junit.jupiter.params.ParameterizedTest}.
* Each {@link org.junit.jupiter.api.TestTemplate} will be run with each of the varying
* {@link com.apple.foundationdb.relational.yamltests.configs.YamlTestConfig}, and passed in a parameter:
* {@link YamlRunner} to run the {@code .yamsql} file.
* </p>
* <p>
* If a specific test cannot be run with a specific config due to a bug, it can be ignored by adding the
* annotation {@link ExcludeYamlTestConfig}. Ideally, these are short lived, primarily to support adding a config,
* and then fixing some tests that may fail with that config.
* </p>
*/
public class YamlTestExtension implements TestTemplateInvocationContextProvider, BeforeAllCallback, AfterAllCallback {
private static final Logger logger = LogManager.getLogger(YamlTestExtension.class);
Expand Down Expand Up @@ -233,7 +245,7 @@ public List<Extension> getAdditionalExtensions() {
}

/**
* Parameter resolver for the class when injecting the {@link YamlTest.Runner}.
* Parameter resolver for the class when injecting the {@link YamlRunner}.
*/
private static final class ClassParameterResolver implements ParameterResolver {

Expand All @@ -254,27 +266,12 @@ public ClassParameterResolver(@Nonnull final YamlTestConfig config,

@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
return parameterContext.getParameter().getType().equals(YamlTest.Runner.class);
return parameterContext.getParameter().getType().equals(YamlRunner.class);
}

@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
return new YamlTest.Runner() {
@Override
public void runYamsql(final String fileName) throws Exception {
if (filters != null) {
Assumptions.assumeTrue(filters.filter(config), excludedReason);
}
var yamlRunner = new YamlRunner(fileName, config.createConnectionFactory(),
config.getRunnerOptions());
try {
yamlRunner.run();
} catch (Exception e) {
logger.error("‼️ running test file '{}' was not successful", fileName, e);
throw e;
}
}
};
return new YamlRunner(config.createConnectionFactory(), config.getRunnerOptions());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,10 @@

package com.apple.foundationdb.relational.yamltests.command;

import com.apple.foundationdb.record.TestHelpers;
import com.apple.foundationdb.record.query.plan.cascades.debug.Debugger;
import com.apple.foundationdb.record.query.plan.debug.DebuggerWithSymbolTables;
import com.apple.foundationdb.relational.api.Continuation;
import com.apple.foundationdb.relational.api.exceptions.RelationalException;
import com.apple.foundationdb.relational.recordlayer.util.ExceptionUtil;
import com.apple.foundationdb.relational.util.Assert;
import com.apple.foundationdb.relational.util.Environment;
import com.apple.foundationdb.relational.yamltests.CustomYamlConstructor;
import com.apple.foundationdb.relational.yamltests.Matchers;
import com.apple.foundationdb.relational.yamltests.YamlConnection;
Expand Down Expand Up @@ -151,7 +147,6 @@ void executeInternal(@Nonnull final YamlConnection connection) throws SQLExcepti

private void executeInternal(@Nonnull final YamlConnection connection, boolean checkCache, @Nonnull QueryExecutor executor)
throws SQLException, RelationalException {
enableCascadesDebugger();
boolean shouldExecute = true;
boolean queryIsRunning = false;
Continuation continuation = null;
Expand Down Expand Up @@ -179,13 +174,13 @@ private void executeInternal(@Nonnull final YamlConnection connection, boolean c
// can result in the explain plan being put into the plan cache, so running without the debugger
// can pollute cache and thus interfere with the explain's results
Integer finalMaxRows = maxRows;
runWithDebugger(() -> executor.execute(connection, null, queryConfig, checkCache, finalMaxRows));
executor.execute(connection, null, queryConfig, checkCache, finalMaxRows);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This disables all sanity checks within the planner. See Debugger.isSane()

} else if (QueryConfig.QUERY_CONFIG_EXPLAIN.equals(queryConfig.getConfigName()) || QueryConfig.QUERY_CONFIG_EXPLAIN_CONTAINS.equals(queryConfig.getConfigName())) {
Assert.that(!queryIsRunning, "Explain test should not be intermingled with query result tests");
// ignore debugger configuration, always set the debugger for explain, so we can always get consistent
// results
Integer finalMaxRows1 = maxRows;
runWithDebugger(() -> executor.execute(connection, null, queryConfig, checkCache, finalMaxRows1));
executor.execute(connection, null, queryConfig, checkCache, finalMaxRows1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here.

} else if (QueryConfig.QUERY_CONFIG_NO_OP.equals(queryConfig.getConfigName())) {
// Do nothing for noop execution.
continue;
Expand Down Expand Up @@ -233,31 +228,4 @@ static void reportTestFailure(@Nonnull String message, @Nullable Throwable throw
Assertions.fail(message, throwable);
}
}

private static void runWithDebugger(@Nonnull TestHelpers.DangerousRunnable r) throws SQLException {
final var savedDebugger = Debugger.getDebugger();
try {
Debugger.setDebugger(DebuggerWithSymbolTables.withoutSanityChecks());
Debugger.setup();
r.run();
} catch (Exception t) {
throw ExceptionUtil.toRelationalException(t).toSqlException();
} finally {
Debugger.setDebugger(savedDebugger);
}
}

/**
* Enables internal Cascades debugger which, among other things, sets plan identifiers in a stable fashion making
* it easier to view plans and reproduce planning steps.
*
* @implNote
* This is copied from fdb-relational-core:test subproject to avoid having a dependency just for getting access to it.
*/
private static void enableCascadesDebugger() {
if (Debugger.getDebugger() == null && Environment.isDebug()) {
Debugger.setDebugger(DebuggerWithSymbolTables.withoutSanityChecks());
}
Debugger.setup();
}
}
3 changes: 2 additions & 1 deletion yaml-tests/src/test/java/InitialVersionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ private void doRunCurrentVersion(String testName) throws Exception {
}

private void doRun(String testName, YamlConnectionFactory connectionFactory) throws Exception {
new YamlRunner("initial-version/" + testName + ".yamsql", connectionFactory, YamlExecutionContext.ContextOptions.EMPTY_OPTIONS).run();
new YamlRunner(connectionFactory, YamlExecutionContext.ContextOptions.EMPTY_OPTIONS)
.runYamsql("initial-version/" + testName + ".yamsql");
}

YamlConnectionFactory createConnectionFactory() {
Expand Down
3 changes: 2 additions & 1 deletion yaml-tests/src/test/java/SupportedVersionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ static void afterAll() throws Exception {
}

private void doRun(String fileName) throws Exception {
new YamlRunner(fileName, createConnectionFactory(), YamlExecutionContext.ContextOptions.EMPTY_OPTIONS).run();
new YamlRunner(createConnectionFactory(), YamlExecutionContext.ContextOptions.EMPTY_OPTIONS)
.runYamsql(fileName);
}

YamlConnectionFactory createConnectionFactory() {
Expand Down
Loading