apply plugin: 'groovy' dependencies { testImplementation project(':conductor-server') testImplementation project(':conductor-common') testImplementation project(':conductor-rest') testImplementation project(':conductor-core') testImplementation project(':conductor-redis-persistence') testImplementation project(':conductor-cassandra-persistence') testImplementation project(':conductor-es7-persistence') testImplementation project(':conductor-grpc-server') testImplementation project(':conductor-grpc-client') testImplementation project(':conductor-json-jq-task') testImplementation project(':conductor-http-task') testImplementation project(':conductor-scheduler-core') testImplementation project(':conductor-ai') testImplementation "org.conductoross:conductor-client:${revConductorClient}" testImplementation "org.springframework.retry:spring-retry" testImplementation "com.fasterxml.jackson.core:jackson-databind:${revFasterXml}" testImplementation "com.fasterxml.jackson.core:jackson-core:${revFasterXml}" testImplementation "org.apache.commons:commons-lang3" testImplementation "com.google.protobuf:protobuf-java:${revProtoBuf}" testImplementation "com.google.guava:guava:${revGuava}" testImplementation "org.springframework:spring-web" testImplementation "redis.clients:jedis:${revJedis}" implementation "io.orkes.queues:orkes-conductor-queues:${revOrkesQueues}" testImplementation "org.apache.groovy:groovy-all:${revGroovy}" testImplementation "org.spockframework:spock-core:${revSpock}" testImplementation "org.spockframework:spock-spring:${revSpock}" testImplementation "org.elasticsearch.client:elasticsearch-rest-client:${revElasticSearch7}" testImplementation "org.elasticsearch.client:elasticsearch-rest-high-level-client:${revElasticSearch7}" testImplementation "org.testcontainers:elasticsearch:${revTestContainer}" testImplementation "org.testcontainers:localstack:${revTestContainer}" testImplementation "org.testcontainers:spock:${revTestContainer}" testImplementation('junit:junit:4.13.2') testImplementation "org.junit.vintage:junit-vintage-engine" testImplementation "jakarta.ws.rs:jakarta.ws.rs-api:${revJAXRS}" testImplementation "org.glassfish.jersey.core:jersey-common:${revJerseyCommon}" testImplementation "org.awaitility:awaitility:${revAwaitility}" testImplementation "io.projectreactor.netty:reactor-netty-http:${revReactor}" testImplementation "io.projectreactor.netty:reactor-netty-core:${revReactor}" // S3 and AWS dependencies for LocalStack testing testImplementation project(':conductor-awss3-storage') testImplementation project(':conductor-azureblob-storage') testImplementation("com.azure:azure-storage-blob:${revAzureStorageBlobSdk}") { // Use the JDK HTTP client provider for tests; default azure-core-http-netty needs // a netty version that conflicts with the one already on the test-harness classpath. exclude group: 'com.azure', module: 'azure-core-http-netty' } testImplementation 'com.azure:azure-core-http-jdk-httpclient:1.0.3' testImplementation 'com.google.cloud:google-cloud-storage:2.36.1' testImplementation 'com.google.http-client:google-http-client:1.44.1' testImplementation project(':conductor-gcs-storage') testImplementation project(':conductor-local-file-storage') testImplementation project(':conductor-awssqs-event-queue') testImplementation project(':conductor-workflow-event-listener') testImplementation "software.amazon.awssdk:s3:${revAwsSdk}" testImplementation "software.amazon.awssdk:sts:${revAwsSdk}" testImplementation "software.amazon.awssdk:sqs:${revAwsSdk}" testImplementation "commons-io:commons-io:${revCommonsIo}" } tasks.withType(Test) { maxParallelForks = 1 } // File-storage backend integration tests (S3/Azure/GCS) require Docker. Exclude // from the default :test task and expose them under a dedicated task instead. tasks.named('test') { useJUnitPlatform { excludeTags 'file-storage-integration' } } task fileStorageIntegrationTest(type: Test) { description = 'Integration tests for S3/Azure/GCS file-storage backends (requires Docker)' group = 'verification' testClassesDirs = sourceSets.test.output.classesDirs classpath = sourceSets.test.runtimeClasspath useJUnitPlatform { includeTags 'file-storage-integration' } maxParallelForks = 1 } // Spotless cannot format files outside the project dir. The functionalTest source set // references e2e sources directly, so restrict Spotless to project-local sources only. afterEvaluate { spotless { java { target sourceSets .matching { it.name != 'functionalTest' } .collect { it.java } .flatten() } } } // --------------------------------------------------------------------------- // Functional test source set — compiles and runs the e2e tests against an // embedded Conductor server (Spring Boot + TestContainers for Redis & ES). // // PINNED (#964): conductor-client must stay at 5.0.1 for the functional tests. // conductor-client:5.0.1 is a fat JAR that bundles com.netflix.conductor.common.* // classes which shadow the project's own conductor-common module and cause // NoSuchMethodError at runtime. We solve this by creating a "stripped" JAR that // removes the conflicting com/netflix/conductor/common/ classes, keeping the // client API, SDK, and org.conductoross model classes intact. // --------------------------------------------------------------------------- // Resolve conductor-client:5.0.1 in isolation (non-transitive, bypass Spring dep mgmt) configurations { conductorClientRaw { resolutionStrategy.eachDependency { details -> if (details.requested.group == 'org.conductoross' && details.requested.name == 'conductor-client') { details.useVersion '5.0.1' } } } } dependencies { conductorClientRaw('org.conductoross:conductor-client:5.0.1') { transitive = false } } // Strip bundled com.netflix.conductor.common.* classes from the fat JAR. // These conflict with the project's own conductor-common module. task stripConductorClient(type: Jar) { archiveBaseName = 'conductor-client-5.0.1-stripped' destinationDirectory = layout.buildDirectory.dir('stripped-libs') duplicatesStrategy = DuplicatesStrategy.EXCLUDE from(zipTree(configurations.conductorClientRaw.singleFile)) { exclude 'com/netflix/conductor/common/**' } } sourceSets { functionalTest { java { srcDirs = [ project(':conductor-e2e').file('src/test/java'), 'src/functionalTest/java' ] } resources { srcDirs = [ project(':conductor-e2e').file('src/test/resources'), 'src/functionalTest/resources' ] } compileClasspath += sourceSets.main.output + sourceSets.test.output runtimeClasspath += sourceSets.main.output + sourceSets.test.output } } configurations { functionalTestImplementation.extendsFrom testImplementation functionalTestRuntimeOnly.extendsFrom testRuntimeOnly // Remove the original conductor-client (fat JAR) from the functionalTest classpath. // The stripped version (file dependency below) replaces it. functionalTestCompileClasspath { exclude group: 'org.conductoross', module: 'conductor-client' } functionalTestRuntimeClasspath { exclude group: 'org.conductoross', module: 'conductor-client' } // PINNED (#964): e2e tests require Awaitility 4.x — they call pollInterval(Duration) // which was added in 4.0. The main test-harness uses revAwaitility (3.x). This override // applies only to the functionalTest classpath. [functionalTestCompileClasspath, functionalTestRuntimeClasspath].each { cfg -> cfg.resolutionStrategy.eachDependency { details -> if (details.requested.group == 'org.awaitility' && details.requested.name == 'awaitility') { details.useVersion '4.2.0' details.because 'e2e tests use pollInterval(Duration) added in 4.x' } } } } dependencies { // Stripped conductor-client:5.0.1 (without bundled common classes) functionalTestImplementation files(stripConductorClient) // JUnit 5 (e2e tests are Jupiter-based) functionalTestImplementation 'org.junit.jupiter:junit-jupiter-api' functionalTestRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' functionalTestImplementation 'org.junit.jupiter:junit-jupiter-params' // Lombok (used by e2e test classes) functionalTestCompileOnly 'org.projectlombok:lombok:1.18.30' functionalTestAnnotationProcessor 'org.projectlombok:lombok:1.18.30' // Awaitility 4.x (e2e uses 4.2.0; test-harness has 3.x) functionalTestImplementation 'org.awaitility:awaitility:4.2.0' // Commons used by e2e utilities functionalTestImplementation 'org.apache.commons:commons-lang3:3.14.0' functionalTestImplementation 'org.apache.commons:commons-compress:1.26.1' } task functionalTest(type: Test) { description = 'Runs e2e functional tests against an embedded Conductor server with Redis + ES' group = 'verification' testClassesDirs = sourceSets.functionalTest.output.classesDirs classpath = sourceSets.functionalTest.runtimeClasspath useJUnitPlatform() maxParallelForks = 1 minHeapSize = '512m' maxHeapSize = '2g' testLogging { events = ['SKIPPED', 'FAILED'] exceptionFormat = 'short' showStandardStreams = true } // Exclude load/stress tests that are too heavy for the embedded server filter { excludeTestsMatching 'io.conductor.e2e.processing.SetVariableTests.testAllFast' } }