-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Destinations CDK: better integration tests #45113
Destinations CDK: better integration tests #45113
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Skipped Deployment
|
da9d896
to
7e3fa25
Compare
b0b856d
to
8d9871f
Compare
7e3fa25
to
48ca85d
Compare
8d9871f
to
228765c
Compare
236be41
to
70b9a9c
Compare
build.gradle
Outdated
@@ -55,16 +55,16 @@ allprojects { | |||
sourceCompatibility = JavaVersion.VERSION_21 | |||
targetCompatibility = JavaVersion.VERSION_21 | |||
compileJava { | |||
options.compilerArgs += ["-Werror", "-Xlint:all,-serial,-processing"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll revert this before merging, this was just driving me nuts locally
import org.junit.jupiter.api.Disabled; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public class TestingSilentDestinationAcceptanceTest extends DestinationAcceptanceTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't check what these two classes are doing, but will revive these tests before merging this PR
70b9a9c
to
6384e77
Compare
...te-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/test/util/DestinationProcess.kt
Outdated
Show resolved
Hide resolved
48ca85d
to
26b418a
Compare
e476fcc
to
617d533
Compare
26b418a
to
1930d44
Compare
ab66980
to
70220ef
Compare
1930d44
to
e0b98f1
Compare
70220ef
to
bde7d82
Compare
e0b98f1
to
0feb717
Compare
0b18a1a
to
7eedfd8
Compare
f8e49cf
to
4cdec03
Compare
} | ||
|
||
@Test | ||
open fun testBasicWrite() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test case is mostly here to (a) be a quick smoke test on our state handling, and (b) show the typical interaction with DestinationProcess
. Most tests we'll actually write don't need any of the state stuff, and would look more like:
runSync(config, stream, listOf(records...))
dumpAndDiffRecords(...)
// (potentially more syncs, if we're e.g. testing refreshes)
28207e7
to
1508fa6
Compare
c2f4b23
to
30b24fb
Compare
airbyte-integrations/connectors/destination-e2e-test/build.gradle
Outdated
Show resolved
Hide resolved
30b24fb
to
43cbd5c
Compare
1508fa6
to
a30248e
Compare
c36924e
to
cd7a833
Compare
a30248e
to
2b8def0
Compare
cd7a833
to
78dc640
Compare
2b8def0
to
e905aed
Compare
78dc640
to
2d3af61
Compare
LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC) | ||
.format(DateTimeFormatter.ofPattern("YYYYMMDD")) | ||
// stream name doesn't need to be randomized, only the namespace. | ||
val randomizedNamespace = "test$timestampString$randomSuffix" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that we never test the null namespace case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can still do that. Something along these lines, specifics of config.setDefaultNamespace
tbd:
val modifiedConfig = config.setDefaultNamespace(randomizedNamespace)
runSync(modifiedConfig, records = listOf(Record(namespace=null, ...)))
verify(namespace=randomizedNamespace, ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
though it's a bit trickier for s3, where namespace=null is an actual thing :/ I think we'd just disregard randomizedNamespace
for that:
runSync(config, records=[Record(namespace = null, name = "test_stream_with_random_chars1234")])
(i.e. this field is purely advisory, it's up to each individual test to use it or not)
|
||
package io.airbyte.cdk.test.util | ||
|
||
fun interface DestinationCleaner { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dq, why is the cleaner its own thing and not an entry point into the process?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like why not have a cleanup
method on DestinationProcess? I think they're pretty separate concerns - the dest process is just the connector (i.e. it supports spec/check/write)
but the cleaner is a weird out-of-connector thing. @stephane-airbyte 's recent Snowflake PR actually has a good example of what I want this class to do - https://github.com/airbytehq/airbyte/pull/45370/files#diff-c86b086ef3cc7bf564aedd699868dcc38661d51b3cc1bf34616720971866c6f6
(i.e. show schemas
-> drop schema
/etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks solid to me. If you want to merge it down into e2e I'll start working on the final productionalization.
I think overall we'll want to iterate on these interfaces (mine and yours) and work out how we want to handle configs, injection in general, mapping to and from schemas and records, all that. But we can learn as we go.
2d3af61
to
d8e2b9e
Compare
d8e2b9e
to
d55ec66
Compare
// so we have to suppress the entire class. | ||
// Thanks, spotbugs. | ||
@SuppressFBWarnings("NP_NONNULL_RETURN_VIOLATION", justification = "Micronaut DI") | ||
abstract class IntegrationTest( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@johnny-schmidt / @stephane-airbyte I do want to call this piece out specifically - I copied this pattern from existing tests, but it could (/should) just be some utility class that gets constructed by test classes, instead of an extra layer of inheritance.
I'm basically reserving my next couple weeks to work on testing stuff (and probably won't have time to make big changes b/c OC)... so I'd prefer to just leave that debate for later, so we can at least get things merged + unblock further development? It should be a pretty simple switch, just a bit tedious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with this as a foundation. We can talk through some of the implications of this stuff at the next CDK meeting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sgtm!
+1. This is just the bare minimum to show what I want to do + get some basic demonstrations working, I fully expect we'll be tweaking/adding stuff as we go. |
d55ec66
into
issue-9361/load-cdk-with-e2e-dest-post-refactor
Implement the test framework, write a minimal set of base tests, and implement those tests for destination-e2e-test. I stuck with our existing abstract class + concrete per-destination implementation strategy, because:
override testFoo() { super.testFoo() }
declarations. But even without that, we still get the test case.general review guide: