Skip to content

Commit 765eae2

Browse files
committed
Add bwc tests, more timestamp testing
Signed-off-by: Daniel Widdis <[email protected]>
1 parent 7f5cd10 commit 765eae2

File tree

8 files changed

+499
-13
lines changed

8 files changed

+499
-13
lines changed

.github/workflows/test_bwc.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: BWC
2+
on:
3+
push:
4+
branches:
5+
- "**"
6+
pull_request:
7+
branches:
8+
- "**"
9+
10+
jobs:
11+
Build-ff-linux:
12+
strategy:
13+
matrix:
14+
java: [11,17,21]
15+
fail-fast: false
16+
17+
name: Test Flow Framework BWC
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Setup Java ${{ matrix.java }}
22+
uses: actions/setup-java@v4
23+
with:
24+
distribution: 'temurin'
25+
java-version: ${{ matrix.java }}
26+
27+
- name: Checkout Flow Framework
28+
uses: actions/checkout@v4
29+
30+
- name: Assemble Flow Framework
31+
run: |
32+
plugin_version=`./gradlew properties -q | grep "opensearch_build:" | awk '{print $2}'`
33+
echo plugin_version $plugin_version
34+
./gradlew assemble
35+
echo "Creating ./src/test/resources/org/opensearch/flowframework/bwc/flow-framework/$plugin_version ..."
36+
mkdir -p ./src/test/resources/org/opensearch/flowframework/bwc/flow-framework/$plugin_version
37+
echo "Copying ./build/distributions/*.zip to ./src/test/resources/org/opensearch/flowframework/bwc/flow-framework/$plugin_version ..."
38+
ls ./build/distributions/
39+
cp ./build/distributions/*.zip ./src/test/resources/org/opensearch/flowframework/bwc/flow-framework/$plugin_version
40+
echo "Copied ./build/distributions/*.zip to ./src/test/resources/org/opensearch/flowframework/bwc/flow-framework/$plugin_version ..."
41+
ls ./src/test/resources/org/opensearch/flowframework/bwc/flow-framework/$plugin_version
42+
- name: Run Flow Framework Backwards Compatibility Tests
43+
run: |
44+
echo "Running backwards compatibility tests ..."
45+
./gradlew bwcTestSuite -Dtests.security.manager=false

build.gradle

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import java.nio.file.Files
22
import org.opensearch.gradle.testclusters.OpenSearchCluster
3+
import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask
34
import org.opensearch.gradle.test.RestIntegTestTask
45
import java.util.concurrent.Callable
56
import java.nio.file.Paths
@@ -23,6 +24,16 @@ buildscript {
2324
opensearch_no_snapshot = opensearch_build.replace("-SNAPSHOT","")
2425
System.setProperty('tests.security.manager', 'false')
2526
common_utils_version = System.getProperty("common_utils.version", opensearch_build)
27+
28+
bwcVersionShort = "2.12.0"
29+
bwcVersion = bwcVersionShort + ".0"
30+
bwcOpenSearchFFDownload = 'https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/' + bwcVersionShort + '/latest/linux/x64/tar/builds/' +
31+
'opensearch/plugins/opensearch-flow-framework-' + bwcVersion + '.zip'
32+
baseName = "ffBwcCluster"
33+
bwcFilePath = "src/test/resources/org/opensearch/flowframework/bwc/"
34+
bwcFlowFrameworkPath = bwcFilePath + "flowframework/"
35+
36+
isSameMajorVersion = opensearch_version.split("\\.")[0] == bwcVersionShort.split("\\.")[0]
2637
}
2738

2839
repositories {
@@ -78,6 +89,9 @@ dependencyLicenses.enabled = false
7889
// This requires an additional Jar not published as part of build-tools
7990
loggerUsageCheck.enabled = false
8091
thirdPartyAudit.enabled = false
92+
// Allow test cases to be named Tests without having to be inherited from LuceneTestCase.
93+
// see https://github.com/elastic/elasticsearch/blob/323f312bbc829a63056a79ebe45adced5099f6e6/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/TestingConventionsTasks.java
94+
testingConventions.enabled = false
8195

8296
// No need to validate pom, as we do not upload to maven/sonatype
8397
validateNebulaPom.enabled = false
@@ -192,6 +206,12 @@ jacocoTestReport {
192206
}
193207
tasks.named("check").configure { dependsOn(jacocoTestReport) }
194208

209+
tasks.named("yamlRestTest").configure {
210+
filter {
211+
excludeTestsMatching "org.opensearch.flowframework.rest.*IT"
212+
excludeTestsMatching "org.opensearch.flowframework.bwc.*IT"
213+
}
214+
}
195215

196216
// Set up integration tests
197217
task integTest(type: RestIntegTestTask) {
@@ -231,6 +251,13 @@ integTest {
231251
}
232252
}
233253

254+
// Exclude BWC tests, run separately
255+
if (System.getProperty("tests.rest.bwcsuite") == null) {
256+
filter {
257+
excludeTestsMatching "org.opensearch.flowframework.bwc.*IT"
258+
}
259+
}
260+
234261
// Exclude integration tests that require security plugin
235262
if (System.getProperty("https") == null || System.getProperty("https") == "false") {
236263
filter {
@@ -425,6 +452,166 @@ task integTestRemote(type: RestIntegTestTask) {
425452
}
426453
}
427454

455+
2.times {i ->
456+
testClusters {
457+
"${baseName}$i" {
458+
testDistribution = "ARCHIVE"
459+
versions = [bwcVersionShort, opensearch_version]
460+
numberOfNodes = 3
461+
plugin(provider(new Callable<RegularFile>(){
462+
@Override
463+
RegularFile call() throws Exception {
464+
return new RegularFile() {
465+
@Override
466+
File getAsFile() {
467+
if (new File("$project.rootDir/$bwcFilePath/flow-framework/$bwcVersion").exists()) {
468+
project.delete(files("$project.rootDir/$bwcFilePath/flow-framework/$bwcVersion"))
469+
}
470+
project.mkdir bwcFlowFrameworkPath + bwcVersion
471+
ant.get(src: bwcOpenSearchFFDownload,
472+
dest: bwcFlowFrameworkPath + bwcVersion,
473+
httpusecaches: false)
474+
return fileTree(bwcFlowFrameworkPath + bwcVersion).getSingleFile()
475+
}
476+
}
477+
}
478+
}))
479+
setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}"
480+
setting 'http.content_type.required', 'true'
481+
}
482+
}
483+
}
484+
485+
List<Provider<RegularFile>> plugins = [
486+
provider(new Callable<RegularFile>(){
487+
@Override
488+
RegularFile call() throws Exception {
489+
return new RegularFile() {
490+
@Override
491+
File getAsFile() {
492+
return configurations.zipArchive.asFileTree.getSingleFile()
493+
}
494+
}
495+
}
496+
}),
497+
provider(new Callable<RegularFile>(){
498+
@Override
499+
RegularFile call() throws Exception {
500+
return new RegularFile() {
501+
@Override
502+
File getAsFile() {
503+
return fileTree(bwcFilePath + "flow-framework/" + project.version).getSingleFile()
504+
}
505+
}
506+
}
507+
})
508+
]
509+
510+
// Creates 2 test clusters with 3 nodes of the old version.
511+
2.times {i ->
512+
task "${baseName}#oldVersionClusterTask$i"(type: StandaloneRestIntegTestTask) {
513+
onlyIf { isSameMajorVersion || (i == 1) }
514+
useCluster testClusters."${baseName}$i"
515+
filter {
516+
includeTestsMatching "org.opensearch.flowframework.bwc.*IT"
517+
}
518+
systemProperty 'tests.rest.bwcsuite', 'old_cluster'
519+
systemProperty 'tests.rest.bwcsuite_round', 'old'
520+
systemProperty 'tests.plugin_bwc_version', bwcVersion
521+
nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}$i".allHttpSocketURI.join(",")}")
522+
nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}$i".getName()}")
523+
}
524+
}
525+
526+
// Upgrades one node of the old cluster to new OpenSearch version with upgraded plugin version
527+
// This results in a mixed cluster with 2 nodes on the old version and 1 upgraded node.
528+
// This is also used as a one third upgraded cluster for a rolling upgrade.
529+
task "${baseName}#mixedClusterTask"(type: StandaloneRestIntegTestTask) {
530+
onlyIf { isSameMajorVersion }
531+
useCluster testClusters."${baseName}0"
532+
dependsOn "${baseName}#oldVersionClusterTask0"
533+
doFirst {
534+
testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins)
535+
}
536+
filter {
537+
includeTestsMatching "org.opensearch.flowframework.bwc.*IT"
538+
}
539+
systemProperty 'tests.rest.bwcsuite', 'mixed_cluster'
540+
systemProperty 'tests.rest.bwcsuite_round', 'first'
541+
systemProperty 'tests.plugin_bwc_version', bwcVersion
542+
nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}")
543+
nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}")
544+
}
545+
546+
// Upgrades the second node to new OpenSearch version with upgraded plugin version after the first node is upgraded.
547+
// This results in a mixed cluster with 1 node on the old version and 2 upgraded nodes.
548+
// This is used for rolling upgrade.
549+
task "${baseName}#twoThirdsUpgradedClusterTask"(type: StandaloneRestIntegTestTask) {
550+
onlyIf { isSameMajorVersion }
551+
dependsOn "${baseName}#mixedClusterTask"
552+
useCluster testClusters."${baseName}0"
553+
doFirst {
554+
testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins)
555+
}
556+
filter {
557+
includeTestsMatching "org.opensearch.flowframework.bwc.*IT"
558+
}
559+
systemProperty 'tests.rest.bwcsuite', 'mixed_cluster'
560+
systemProperty 'tests.rest.bwcsuite_round', 'second'
561+
systemProperty 'tests.plugin_bwc_version', bwcVersion
562+
nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}")
563+
nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}")
564+
}
565+
566+
// Upgrades the third node to new OpenSearch version with upgraded plugin version after the second node is upgraded.
567+
// This results in a fully upgraded cluster.
568+
// This is used for rolling upgrade.
569+
task "${baseName}#rollingUpgradeClusterTask"(type: StandaloneRestIntegTestTask) {
570+
onlyIf { isSameMajorVersion }
571+
dependsOn "${baseName}#twoThirdsUpgradedClusterTask"
572+
useCluster testClusters."${baseName}0"
573+
doFirst {
574+
testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins)
575+
}
576+
filter {
577+
includeTestsMatching "org.opensearch.flowframework.bwc.*IT"
578+
}
579+
mustRunAfter "${baseName}#mixedClusterTask"
580+
systemProperty 'tests.rest.bwcsuite', 'mixed_cluster'
581+
systemProperty 'tests.rest.bwcsuite_round', 'third'
582+
systemProperty 'tests.plugin_bwc_version', bwcVersion
583+
nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}")
584+
nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}")
585+
}
586+
587+
// Upgrades all the nodes of the old cluster to new OpenSearch version with upgraded plugin version
588+
// at the same time resulting in a fully upgraded cluster.
589+
task "${baseName}#fullRestartClusterTask"(type: StandaloneRestIntegTestTask) {
590+
dependsOn "${baseName}#oldVersionClusterTask1"
591+
useCluster testClusters."${baseName}1"
592+
doFirst {
593+
testClusters."${baseName}1".upgradeAllNodesAndPluginsToNextVersion(plugins)
594+
}
595+
filter {
596+
includeTestsMatching "org.opensearch.flowframework.bwc.*IT"
597+
}
598+
systemProperty 'tests.rest.bwcsuite', 'upgraded_cluster'
599+
systemProperty 'tests.plugin_bwc_version', bwcVersion
600+
nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}1".allHttpSocketURI.join(",")}")
601+
nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}1".getName()}")
602+
}
603+
604+
// A bwc test suite which runs all the bwc tasks combined.
605+
task bwcTestSuite(type: StandaloneRestIntegTestTask) {
606+
filter {
607+
excludeTestsMatching '**.*Test*'
608+
excludeTestsMatching '**.*IT*'
609+
setFailOnNoMatchingTests(false)
610+
}
611+
dependsOn tasks.named("${baseName}#mixedClusterTask")
612+
dependsOn tasks.named("${baseName}#rollingUpgradeClusterTask")
613+
dependsOn tasks.named("${baseName}#fullRestartClusterTask")
614+
}
428615

429616
// test retry configuration
430617
allprojects {
@@ -438,6 +625,11 @@ allprojects {
438625
}
439626
}
440627
}
628+
// Needed for Gradle 9.0
629+
tasks.withType(StandaloneRestIntegTestTask).configureEach {
630+
testClassesDirs = sourceSets.test.output.classesDirs
631+
classpath = sourceSets.test.runtimeClasspath
632+
}
441633
}
442634

443635
// Automatically sets up the integration test cluster locally

src/main/java/org/opensearch/flowframework/model/Template.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ public Template(
101101
this.workflows = Map.copyOf(workflows);
102102
this.uiMetadata = uiMetadata;
103103
this.user = user;
104-
this.createdTime = createdTime == null ? Instant.now() : createdTime;
105-
this.lastUpdatedTime = (lastUpdatedTime == null || lastUpdatedTime.isBefore(this.createdTime)) ? this.createdTime : lastUpdatedTime;
104+
this.createdTime = createdTime;
105+
this.lastUpdatedTime = lastUpdatedTime;
106106
this.lastProvisionedTime = lastProvisionedTime;
107107
}
108108

src/main/java/org/opensearch/flowframework/transport/CreateWorkflowTransportAction.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public CreateWorkflowTransportAction(
9696
protected void doExecute(Task task, WorkflowRequest request, ActionListener<WorkflowResponse> listener) {
9797

9898
User user = getUserContext(client);
99+
Instant creationTime = Instant.now();
99100
Template templateWithUser = new Template(
100101
request.getTemplate().name(),
101102
request.getTemplate().description(),
@@ -105,9 +106,9 @@ protected void doExecute(Task task, WorkflowRequest request, ActionListener<Work
105106
request.getTemplate().workflows(),
106107
request.getTemplate().getUiMetadata(),
107108
user,
108-
request.getTemplate().createdTime(),
109-
request.getTemplate().lastUpdatedTime(),
110-
request.getTemplate().lastProvisionedTime()
109+
creationTime,
110+
creationTime,
111+
null
111112
);
112113

113114
String[] validateAll = { "all" };

0 commit comments

Comments
 (0)