Skip to content

java-cdk: introduce TestDatabase - #32656

Closed
Marius Posta (postamar) wants to merge 14 commits into
masterfrom
postamar/test-database-cdk
Closed

Marius Posta (postamar) wants to merge 14 commits into
masterfrom
postamar/test-database-cdk

Conversation

@postamar

@postamar Marius Posta (postamar) commented Nov 17, 2023

Copy link
Copy Markdown
Contributor

This PR extracts a new, generic TestDatabase superclass from the the newly-introduced PostgresTestDatabase, and rewrites the CdcSourceTest and JdbcSourceAcceptanceTest base classes using these types.

@vercel

vercel Bot commented Nov 17, 2023

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
airbyte-docs ⬜️ Ignored (Inspect) Visit Preview Nov 22, 2023 4:28pm

@octavia-squidington-iii Octavia Squidington III (octavia-squidington-iii) added the CDK Connector Development Kit label Nov 17, 2023
@@ -1,74 +0,0 @@
/*

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved to source-mysql, see #32658.

}

}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved to source-postgres, see #32657.

.filter(d -> d.compareTo(CONNECT_TIMEOUT_DEFAULT) >= 0);
};
return parsedConnectionTimeout.orElse(CONNECT_TIMEOUT_DEFAULT).toMillis();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Stephane Geneix (@stephane-airbyte) I hope this is less offensive, despite having left in some Optional usages. I agree the previous iteration wasn't readable but I honestly believe that this one is.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The purpose of adding support for these new databases is to speed up the test cases in which a timeout is expected. We don't want to have to wait a whole minute every time.

.put("tunnel_user_password", tunnelMethod.equals(SSH_PASSWORD_AUTH) ? SSH_PASSWORD : "")
.put("ssh_key", tunnelMethod.equals(SSH_KEY_AUTH) ? bastion.execInContainer("cat", "var/bastion/id_rsa").getStdout() : "")
.build());
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This got lifted out of getTunnelConfig because we can't use the latter with the new TestDatabase.ConfigBuilder objects.

@Override
public void close() {
stopAndClose();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Dunno why this wasn't an AutoCloseable in the first place! I leftstopAndClose in place because why not.

mySQLContainer.start();
final Map<String, String> connectionProperties = Map.of(
CONNECT_TIMEOUT, "30");
CONNECT_TIMEOUT, "5000");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to reflect the addition of MySQL support in getConnectionTimeoutMs. For MySQL the timeout value is expressed in milliseconds.

Map.of("loginTimeout", "5"));
assertNotNull(dataSource);
assertEquals(HikariDataSource.class, dataSource.getClass());
assertEquals(5000, ((HikariDataSource) dataSource).getHikariConfigMXBean().getConnectionTimeout());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a case to cover the new MS SQL Server support in getConnectionTimeoutMs.

final CdcTargetPosition<T> targetPosition,
final boolean trackSchemaHistory,
final Duration firstRecordWaitTime,
final Duration subsequentRecordWaitTime,

@postamar Marius Posta (postamar) Nov 22, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Plumbing this value here and all the way into the DebeziumRecordIterator allows us to speed up the tests by relying on a different default value in tests. This change has no impact in production.

/**
* In the default case here, we don't know for sure whether the Debezium Engine will produce records
* or not. We therefore pass {@link canShortCircuitDebeziumEngine} = false.
*/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm getting rid of the canShortCircuitDebeziumEngine functionality. It's not easily portable and there are easier ways to speed up the tests almost as well. Namely, heartbeats and a shorter subsequentRecordWaitTime.

import org.slf4j.LoggerFactory;

public class FirstRecordWaitTimeUtil {
public class RecordWaitTimeUtil {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed this class as a consequence of plumbing subsequentRecordWaitTime.

import java.util.Optional;
import org.junit.jupiter.api.Test;

public class RecordWaitTimeUtilTest {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed FirstRecordWaitTimeUtilTest into this as a consequence of plumbing subsequentRecordWaitTime.


@ParameterizedTest
@Disabled
@ValueSource(strings = {"pgoutput", "wal2json"})

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The removal of wal2json touches #31937.

final var slotStateAtTheEnd = getReplicationSlot(database, fullReplicationSlot, plugin, dbName);
Assertions.assertEquals(slotStateAfterCommit, slotStateAtTheEnd);

container.stop();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed this part of the test case which is what covered the debezium short-circuiting functionality in maybeReplicationStreamIntervalHasRecords. It also was flaky which is why the test is no longer disabled.

import org.slf4j.LoggerFactory;

public abstract class CdcSourceTest {
public abstract class CdcSourceTest<S extends Source, T extends TestDatabase<?, T, ?>> {

@postamar Marius Posta (postamar) Nov 22, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This class is rewritten so that the only mutable state shared across test methods is protected T testdb,. The test logic itself remains unchanged.

}

protected void maybeSetShorterConnectionTimeout() {
protected void maybeSetShorterConnectionTimeout(final JsonNode config) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Signature was changed to reflect that of the similar method in the new JdbcSourceTest fixture.

@SuppressFBWarnings(
value = {"MS_SHOULD_BE_FINAL"},
justification = "The static variables are updated in subclasses for convenience, and cannot be final.")
abstract public class JdbcSourceTest<S extends Source, T extends TestDatabase<?, T, ?>> {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This class is JdbcSourceAcceptanceTest but where the only mutable state shared between test methods is protected T testdb;. This is the same idea as for CdcSourceTest but unlike that class, JdbcSourceAcceptanceTest is still used by many non-certified connectors.

Comment thread build.gradle
systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'fixed'
systemProperty 'junit.jupiter.execution.parallel.config.fixed.parallelism', 1
// Order test classes by annotation.
systemProperty 'junit.jupiter.testclass.order.default', 'org.junit.jupiter.api.ClassOrderer$OrderAnnotation'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This allows decorating test classes with @Order(...) annotations to help long-running classes get scheduled early on.

class AirbyteJavaConnectorExtension {

boolean useLocalCdk = true
boolean useLocalCdk

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't think true is a safe default at all.

void setUseLocalCdk(boolean useLocalCdk) {
this.useLocalCdk = useLocalCdk
addCdkDependencies()
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is a bit of a hack (but gradle kind of sucks) to remove the need for the explicit addCdkDependencies() call in the connector's build.gradle, since setting useLocalCdk to either true or false is mandatory anyway. We should revisit this when we revamp the CDK development lifecycle.

The other changes to this file in this diff are benign additions or readability improvements.

@postamar

Copy link
Copy Markdown
Contributor Author

This is now ready for review. I added some commentary to help the review process. See companion PRs for application to certified source connectors:

@postamar

Copy link
Copy Markdown
Contributor Author

Closed in favour of Graphite stacked PR #32772.

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

Labels

CDK Connector Development Kit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants