|
92 | 92 | import org.springframework.web.util.UriComponentsBuilder;
|
93 | 93 |
|
94 | 94 | import static org.assertj.core.api.Assertions.assertThat;
|
| 95 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
95 | 96 | import static org.junit.jupiter.api.Assertions.assertThrows;
|
96 | 97 | import static org.junit.jupiter.api.Assertions.assertTrue;
|
97 | 98 |
|
@@ -213,6 +214,7 @@ public class DataFlowIT {
|
213 | 214 | public void before() {
|
214 | 215 | Awaitility.setDefaultPollInterval(Duration.ofSeconds(5));
|
215 | 216 | Awaitility.setDefaultTimeout(Duration.ofMinutes(15));
|
| 217 | + resetTimestampVersion(); |
216 | 218 | }
|
217 | 219 |
|
218 | 220 | @AfterEach
|
@@ -975,6 +977,9 @@ protected StreamApplication app(String appName) {
|
975 | 977 | // -----------------------------------------------------------------------
|
976 | 978 | public static final int EXIT_CODE_SUCCESS = 0;
|
977 | 979 | 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 | + |
978 | 983 |
|
979 | 984 | private List<String> composedTaskLaunchArguments(String... additionalArguments) {
|
980 | 985 | // 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
|
1546 | 1551 | }
|
1547 | 1552 |
|
1548 | 1553 | private void validateSuccessfulTaskLaunch(Task task, long launchId) {
|
| 1554 | + validateSuccessfulTaskLaunch(task, launchId, 1); |
| 1555 | + } |
| 1556 | + |
| 1557 | + private void validateSuccessfulTaskLaunch(Task task, long launchId, int sizeExpected) { |
1549 | 1558 | Awaitility.await().until(() -> task.executionStatus(launchId) == TaskExecutionStatus.COMPLETE);
|
1550 |
| - assertThat(task.executions().size()).isEqualTo(1); |
| 1559 | + assertThat(task.executions().size()).isEqualTo(sizeExpected); |
1551 | 1560 | assertThat(task.execution(launchId).isPresent()).isTrue();
|
1552 | 1561 | assertThat(task.execution(launchId).get().getExitCode()).isEqualTo(EXIT_CODE_SUCCESS);
|
1553 | 1562 | }
|
@@ -1645,53 +1654,298 @@ public void basicBatchFailRestartTest() {
|
1645 | 1654 | }
|
1646 | 1655 |
|
1647 | 1656 | @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 |
1649 | 1665 | 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"); |
1652 | 1667 |
|
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) |
1654 | 1871 | .name(randomTaskName())
|
1655 | 1872 | .definition("timestamp")
|
1656 | 1873 | .description("Test scenario batch app that will fail on first pass")
|
1657 |
| - .build()) { |
| 1874 | + .build() ; |
| 1875 | + } |
1658 | 1876 |
|
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 { |
1664 | 1919 | 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); |
1675 | 1922 | }
|
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); |
1681 | 1926 | }
|
1682 |
| - catch (DataFlowClientException dfe) { |
1683 |
| - logger.info(dfe.getMessage(), dfe); |
| 1927 | + else { |
| 1928 | + throw dfe; |
1684 | 1929 | }
|
1685 | 1930 | }
|
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); |
1694 | 1936 | }
|
| 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); |
1695 | 1949 | }
|
1696 | 1950 |
|
1697 | 1951 | @Test
|
|
0 commit comments