Skip to content

Commit a4c863a

Browse files
committed
Added acceptance tests for task versioning
resolves spring-attic#4735
1 parent 608e539 commit a4c863a

File tree

1 file changed

+290
-36
lines changed
  • spring-cloud-dataflow-server/src/test/java/org/springframework/cloud/dataflow/integration/test

1 file changed

+290
-36
lines changed

spring-cloud-dataflow-server/src/test/java/org/springframework/cloud/dataflow/integration/test/DataFlowIT.java

Lines changed: 290 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
import org.springframework.web.util.UriComponentsBuilder;
9393

9494
import static org.assertj.core.api.Assertions.assertThat;
95+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
9596
import static org.junit.jupiter.api.Assertions.assertThrows;
9697
import static org.junit.jupiter.api.Assertions.assertTrue;
9798

@@ -213,6 +214,7 @@ public class DataFlowIT {
213214
public void before() {
214215
Awaitility.setDefaultPollInterval(Duration.ofSeconds(5));
215216
Awaitility.setDefaultTimeout(Duration.ofMinutes(15));
217+
resetTimestampVersion();
216218
}
217219

218220
@AfterEach
@@ -975,6 +977,9 @@ protected StreamApplication app(String appName) {
975977
// -----------------------------------------------------------------------
976978
public static final int EXIT_CODE_SUCCESS = 0;
977979
public static final int EXIT_CODE_ERROR = 1;
980+
public static final String TEST_VERSION_NUMBER = "2.1.0.RELEASE";
981+
public static final String CURRENT_VERSION_NUMBER = "2.1.1.RELEASE";
982+
978983

979984
private List<String> composedTaskLaunchArguments(String... additionalArguments) {
980985
// the dataflow-server-use-user-access-token=true argument is required COMPOSED tasks in
@@ -1546,8 +1551,12 @@ private List<String> createNewJobandStepScenario(String jobName, String stepName
15461551
}
15471552

15481553
private void validateSuccessfulTaskLaunch(Task task, long launchId) {
1554+
validateSuccessfulTaskLaunch(task, launchId, 1);
1555+
}
1556+
1557+
private void validateSuccessfulTaskLaunch(Task task, long launchId, int sizeExpected) {
15491558
Awaitility.await().until(() -> task.executionStatus(launchId) == TaskExecutionStatus.COMPLETE);
1550-
assertThat(task.executions().size()).isEqualTo(1);
1559+
assertThat(task.executions().size()).isEqualTo(sizeExpected);
15511560
assertThat(task.execution(launchId).isPresent()).isTrue();
15521561
assertThat(task.execution(launchId).get().getExitCode()).isEqualTo(EXIT_CODE_SUCCESS);
15531562
}
@@ -1645,53 +1654,298 @@ public void basicBatchFailRestartTest() {
16451654
}
16461655

16471656
@Test
1648-
public void multipleTaskAppVersionTest() {
1657+
public void testLaunchOfDefaultThenVersion() {
1658+
// Scenario: I want to create a task app with 2 versions using default version
1659+
// Given A task with 2 versions
1660+
// And I create a task definition
1661+
// When I launch task definition using default app version
1662+
// And I launch task definition using version 2 of app
1663+
// Then Both tasks should succeed
1664+
// And It launches the specified version
16491665
logger.info("multiple task app version test");
1650-
Assumptions.assumeTrue(!runtimeApps.dataflowServerVersionLowerThan("2.8.0"),
1651-
"upgradeRollbackTaskAppVersionTest: SKIP - SCDF 2.7.x and below!");
1666+
minimumVersionCheck("testLaunchOfDefaultThenVersion");
16521667

1653-
try (Task task = Task.builder(dataFlowOperations)
1668+
Task task = createTaskDefinition();
1669+
1670+
long launchId = task.launch();
1671+
validateSuccessfulTaskLaunch(task, launchId);
1672+
registerNewTimestampVersion();
1673+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1674+
launchId = task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null);
1675+
validateSuccessfulTaskLaunch(task, launchId, 2);
1676+
validateSpecifiedVersion(task, TEST_VERSION_NUMBER);
1677+
}
1678+
1679+
@Test
1680+
public void testCreateTaskWithTwoVersionsLaunchDefaultVersion() {
1681+
// Scenario: I want to create a task app with 2 versions using default version
1682+
// Given A task with 2 versions
1683+
// And I create a task definition
1684+
// When I launch task definition using default app version
1685+
// Then Task should succeed
1686+
// And It launches the specified version
1687+
minimumVersionCheck("testCreateTaskWithTwoVersionsLaunchDefaultVersion");
1688+
registerNewTimestampVersion();
1689+
Task task = createTaskDefinition();
1690+
long launchId = task.launch();
1691+
validateSuccessfulTaskLaunch(task, launchId);
1692+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1693+
}
1694+
1695+
@Test
1696+
public void testLaunchOfNewVersionThenPreviousVersion() {
1697+
// Scenario: I want to create a task app with 2 versions run new version then default
1698+
// Given A task with 2 versions
1699+
// And I create a task definition
1700+
// And I launch task definition using version 2 of app
1701+
// When I launch task definition using version 1 of app
1702+
// Then Task should succeed
1703+
// And It launches the specified version
1704+
minimumVersionCheck("testLaunchOfNewVersionThenDefault");
1705+
registerNewTimestampVersion();
1706+
Task task = createTaskDefinition();
1707+
long launchId = task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null);
1708+
validateSuccessfulTaskLaunch(task, launchId);
1709+
assertThat(task.execution(launchId).get().getResourceUrl()).contains(TEST_VERSION_NUMBER);
1710+
1711+
launchId = task.launch(Collections.singletonMap("version.timestamp", CURRENT_VERSION_NUMBER), null);
1712+
validateSuccessfulTaskLaunch(task, launchId, 2);
1713+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1714+
}
1715+
1716+
@Test
1717+
public void testWhenNoVersionIsSpecifiedPreviousVersionShouldBeUsed()
1718+
{
1719+
// Scenario: When no version is specified previous used version should be used.
1720+
// Given A task with 2 versions
1721+
// And I create a task definition
1722+
// And I launch task definition using version 2 of app
1723+
// When I launch task definition using no app version
1724+
// Then Task should succeed
1725+
// And It launches the version 2 of app
1726+
minimumVersionCheck("testWhenNoVersionIsSpecifiedPreviousVersionShouldBeUsed");
1727+
registerNewTimestampVersion();
1728+
Task task = createTaskDefinition();
1729+
long launchId = task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null);
1730+
validateSuccessfulTaskLaunch(task, launchId);
1731+
validateSpecifiedVersion(task, TEST_VERSION_NUMBER);
1732+
1733+
launchId = task.launch();
1734+
validateSuccessfulTaskLaunch(task, launchId, 2);
1735+
validateSpecifiedVersion(task, TEST_VERSION_NUMBER, 2);
1736+
}
1737+
1738+
@Test
1739+
public void testCreateTaskWithOneVersionLaunchInvalidVersion()
1740+
{
1741+
// Scenario: I want to create a task app with 1 version run invalid version
1742+
// Given A task with 1 versions
1743+
// And I create a task definition
1744+
// When I launch task definition using version 2 of app
1745+
// Then Task should fail
1746+
minimumVersionCheck("testCreateTaskWithOneVersionLaunchInvalidVersion");
1747+
Task task = createTaskDefinition();
1748+
assertThatThrownBy(() -> task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null)).
1749+
isInstanceOf(DataFlowClientException.class).hasMessageContaining("Unknown task app: timestamp");
1750+
}
1751+
1752+
@Test
1753+
public void testInvalidVersionUsageShouldNotAffectSubsequentDefaultLaunch() {
1754+
// Scenario: Invalid version usage should not affect subsequent default launch
1755+
// Given A task with 1 versions
1756+
// And I create a task definition
1757+
// And I launch task definition using version 2 of app
1758+
// When I launch task definition using default app version
1759+
// Then Task should succeed
1760+
// And It launches the specified version
1761+
minimumVersionCheck("testInvalidVersionUsageShouldNotAffectSubsequentDefaultLaunch");
1762+
Task task = createTaskDefinition();
1763+
assertThatThrownBy(() -> task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null)).
1764+
isInstanceOf(DataFlowClientException.class).hasMessageContaining("Unknown task app: timestamp");
1765+
1766+
long launchId = task.launch();
1767+
validateSuccessfulTaskLaunch(task, launchId, 1);
1768+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER, 1);
1769+
}
1770+
1771+
@Test
1772+
public void testDeletePreviouslyUsedVersionShouldFailIfRelaunched() {
1773+
// Scenario: Deleting a previously used version should fail if relaunched.
1774+
// Given A task with 2 versions
1775+
// And I create a task definition
1776+
// And I launch task definition using version 2 of app
1777+
// And I unregister version 2 of app
1778+
// When I launch task definition using version 2 of app
1779+
// Then Task should fail
1780+
minimumVersionCheck("testDeletePreviouslyUsedVersionShouldFailIfRelaunched");
1781+
1782+
registerNewTimestampVersion();
1783+
Task task = createTaskDefinition();
1784+
1785+
long launchId = task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null);
1786+
validateSuccessfulTaskLaunch(task, launchId);
1787+
resetTimestampVersion();
1788+
assertThatThrownBy(() -> task.launch(Collections.singletonMap("version.timestamp", TEST_VERSION_NUMBER), null)).
1789+
isInstanceOf(DataFlowClientException.class).hasMessageContaining("Unknown task app: timestamp");
1790+
}
1791+
1792+
@Test
1793+
public void testChangingTheAppDefaultVersionRunningBetweenChangesShouldBeSuccessful() {
1794+
// Scenario: Changing the app default version and running between changes should be successful
1795+
// Given A task with 2 versions
1796+
// And I create a task definition
1797+
// And I launch task definition using default app version
1798+
// And I set the default to version 2 of the app
1799+
// When I launch task definition using default app version
1800+
// Then Task should succeed
1801+
// And The version for the task execution should be version 2
1802+
minimumVersionCheck("testChangingTheAppDefaultVersionRunningBetweenChangesShouldBeSuccessful");
1803+
Task task = createTaskDefinition();
1804+
1805+
long launchId = task.launch();
1806+
validateSuccessfulTaskLaunch(task, launchId);
1807+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1808+
1809+
registerNewTimestampVersion();
1810+
setDefaultVersionForTimestamp(TEST_VERSION_NUMBER);
1811+
launchId = task.launch();
1812+
validateSuccessfulTaskLaunch(task, launchId, 2);
1813+
validateSpecifiedVersion(task, TEST_VERSION_NUMBER);
1814+
}
1815+
1816+
@Test
1817+
public void testRollingBackDefaultToPreviousVersionAndRunningShouldBeSuccessful() {
1818+
// Scenario: Rolling back default to previous version and running should be successful
1819+
// Given A task with 2 versions
1820+
// And I create a task definition
1821+
// And I launch task definition using default app version
1822+
// And I set the default to version 2 of the app
1823+
// And I launch task definition using default app version
1824+
// And I set the default to version 1 of the app
1825+
// When I create a task definition
1826+
// And I launch task definition using default app version
1827+
// Then Task should succeed
1828+
// And The version for the task execution should be version 1
1829+
minimumVersionCheck("testRollingBackDefaultToPreviousVersionAndRunningShouldBeSuccessful");
1830+
registerNewTimestampVersion();
1831+
Task task = createTaskDefinition();
1832+
long launchId = task.launch();
1833+
validateSuccessfulTaskLaunch(task, launchId);
1834+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1835+
1836+
setDefaultVersionForTimestamp(TEST_VERSION_NUMBER);
1837+
launchId = task.launch();
1838+
validateSuccessfulTaskLaunch(task, launchId, 2);
1839+
validateSpecifiedVersion(task, TEST_VERSION_NUMBER);
1840+
1841+
task = createTaskDefinition();
1842+
setDefaultVersionForTimestamp(CURRENT_VERSION_NUMBER);
1843+
launchId = task.launch();
1844+
validateSuccessfulTaskLaunch(task, launchId);
1845+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1846+
}
1847+
1848+
@Test
1849+
public void testUnregisteringAppShouldPreventTaskDefinitionLaunch() {
1850+
// Scenario: Unregistering app should prevent task definition launch
1851+
// Given A task with 1 versions
1852+
// And I create a task definition
1853+
// And I launch task definition using default app version
1854+
// And I unregister version 1 of app
1855+
// When I launch task definition using default app version
1856+
// Then Task should fail
1857+
minimumVersionCheck("testUnregisteringAppShouldPreventTaskDefinitionLaunch");
1858+
Task task = createTaskDefinition();
1859+
long launchId = task.launch();
1860+
validateSuccessfulTaskLaunch(task, launchId);
1861+
validateSpecifiedVersion(task, CURRENT_VERSION_NUMBER);
1862+
AppRegistryOperations appRegistryOperations = this.dataFlowOperations.appRegistryOperations();
1863+
appRegistryOperations.unregister("timestamp", ApplicationType.task, CURRENT_VERSION_NUMBER);
1864+
1865+
assertThatThrownBy(() -> task.launch()).
1866+
isInstanceOf(DataFlowClientException.class).hasMessageContaining("Unknown task app: timestamp");
1867+
}
1868+
1869+
private Task createTaskDefinition() {
1870+
return Task.builder(dataFlowOperations)
16541871
.name(randomTaskName())
16551872
.definition("timestamp")
16561873
.description("Test scenario batch app that will fail on first pass")
1657-
.build()) {
1874+
.build() ;
1875+
}
16581876

1659-
String stepName = randomStepName();
1660-
// task first launch
1661-
long launchId = task.launch();
1662-
//Verify task
1663-
validateSuccessfulTaskLaunch(task, launchId);
1877+
private void minimumVersionCheck(String testName) {
1878+
Assumptions.assumeTrue(!runtimeApps.dataflowServerVersionLowerThan("2.8.0"),
1879+
testName + ": SKIP - SCDF 2.7.x and below!");
1880+
}
1881+
1882+
private void registerNewTimestampVersion() {
1883+
registerTimestamp(TEST_VERSION_NUMBER);
1884+
}
1885+
1886+
private void registerTimestamp(String versionNumber) {
1887+
AppRegistryOperations appRegistryOperations = this.dataFlowOperations.appRegistryOperations();
1888+
1889+
DetailedAppRegistrationResource taskResource = appRegistryOperations.info("timestamp-batch", ApplicationType.task, false);
1890+
if (taskResource.getUri().startsWith("maven:")) {
1891+
try {
1892+
appRegistryOperations.register("timestamp", ApplicationType.task,
1893+
"maven://org.springframework.cloud.task.app:timestamp-task:" + versionNumber,
1894+
"maven://org.springframework.cloud.task.app:timestamp-task:" + versionNumber, false);
1895+
}
1896+
catch (DataFlowClientException dfe) {
1897+
logger.info(dfe.getMessage(), dfe);
1898+
}
1899+
}
1900+
else {
1901+
try {
1902+
appRegistryOperations.register("timestamp", ApplicationType.task,
1903+
"docker:springcloudtask/timestamp-task:" + versionNumber,
1904+
null, false);
1905+
}
1906+
catch (DataFlowClientException dfe) {
1907+
logger.info(dfe.getMessage(), dfe);
1908+
}
1909+
}
1910+
}
1911+
1912+
private void setDefaultVersionForTimestamp(String version) {
1913+
AppRegistryOperations appRegistryOperations = this.dataFlowOperations.appRegistryOperations();
1914+
appRegistryOperations.makeDefault("timestamp", ApplicationType.task, version);
1915+
}
1916+
1917+
private void resetTimestampVersion() {
1918+
try {
16641919
AppRegistryOperations appRegistryOperations = this.dataFlowOperations.appRegistryOperations();
1665-
DetailedAppRegistrationResource taskResource = appRegistryOperations.info("timestamp", ApplicationType.task, false);
1666-
if (taskResource.getUri().startsWith("maven:")) {
1667-
try {
1668-
appRegistryOperations.register("timestamp", ApplicationType.task,
1669-
"maven://org.springframework.cloud.task.app:timestamp-task:2.1.0.RELEASE",
1670-
"maven://org.springframework.cloud.task.app:timestamp-task:2.1.0.RELEASE", false);
1671-
}
1672-
catch (DataFlowClientException dfe) {
1673-
logger.info(dfe.getMessage(), dfe);
1674-
}
1920+
try {
1921+
appRegistryOperations.info("timestamp", ApplicationType.task, false);
16751922
}
1676-
else {
1677-
try {
1678-
appRegistryOperations.register("timestamp", ApplicationType.task,
1679-
"docker:springcloudtask/timestamp-task:2.1.0.RELEASE",
1680-
null, false);
1923+
catch (DataFlowClientException dfe) {
1924+
if(dfe.getMessage().equals("The 'task:timestamp' application could not be found.")) {
1925+
registerTimestamp(CURRENT_VERSION_NUMBER);
16811926
}
1682-
catch (DataFlowClientException dfe) {
1683-
logger.info(dfe.getMessage(), dfe);
1927+
else {
1928+
throw dfe;
16841929
}
16851930
}
1686-
1687-
long launchId2 = task.launch(Collections.singletonMap("version.timestamp", "2.1.0.RELEASE"), null);
1688-
Awaitility.await().until(() -> task.executionStatus(launchId2) == TaskExecutionStatus.COMPLETE);
1689-
assertThat(task.executions().size()).isEqualTo(2);
1690-
assertThat(task.executions().stream().filter(
1691-
taskExecutionResource -> taskExecutionResource.getResourceUrl().
1692-
contains("2.1.0.RELEASE")).collect(Collectors.toList()).size()).
1693-
isEqualTo(1);
1931+
setDefaultVersionForTimestamp(CURRENT_VERSION_NUMBER);
1932+
appRegistryOperations.unregister("timestamp", ApplicationType.task, TEST_VERSION_NUMBER);
1933+
}
1934+
catch (DataFlowClientException dfe) {
1935+
logger.trace(dfe.getMessage(), dfe);
16941936
}
1937+
1938+
}
1939+
1940+
private void validateSpecifiedVersion(Task task, String version) {
1941+
validateSpecifiedVersion(task, version, 1);
1942+
}
1943+
1944+
private void validateSpecifiedVersion(Task task, String version, int countExpected) {
1945+
assertThat(task.executions().stream().filter(
1946+
taskExecutionResource -> taskExecutionResource.getResourceUrl().
1947+
contains(version)).collect(Collectors.toList()).size()).
1948+
isEqualTo(countExpected);
16951949
}
16961950

16971951
@Test

0 commit comments

Comments
 (0)