diff --git a/Build/Scripts/runTests.sh b/Build/Scripts/runTests.sh index a6c6c4d8e32b877251de6bc0e28b2a9bd2c1c7e0..084b3bbf438790f08f5b2b687171e3c99f875b25 100755 --- a/Build/Scripts/runTests.sh +++ b/Build/Scripts/runTests.sh @@ -98,7 +98,6 @@ Options: - mariadb (default): use mariadb - mysql55: use MySQL 5.5 server - mssql: use mssql microsoft sql server - - mssql2017latest: use latest version of microsoft sql server 2017 - postgres: use postgres - sqlite: use sqlite @@ -413,14 +412,8 @@ case ${TEST_SUITE} in ;; mssql) [[ ! -z "$DATABASE_DRIVER" ]] && echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run prepare_functional_mssql2017cu17 - docker-compose run functional_mssql2017cu17 - SUITE_EXIT_CODE=$? - ;; - mssql2017latest) - [[ ! -z "$DATABASE_DRIVER" ]] && echo "Using driver: ${DATABASE_DRIVER}" - docker-compose run prepare_functional_mssql2017latest - docker-compose run functional_mssql2017latest + docker-compose run prepare_functional_mssql2019latest + docker-compose run functional_mssql2019latest SUITE_EXIT_CODE=$? ;; postgres) diff --git a/Build/bamboo/src/main/java/core/AbstractCoreSpec.java b/Build/bamboo/src/main/java/core/AbstractCoreSpec.java index 585a6a10ae2394df87d6ceccca759ed787ea75e8..d38e78b1131ec4e06d74044f7f0d39f1f68f4718 100644 --- a/Build/bamboo/src/main/java/core/AbstractCoreSpec.java +++ b/Build/bamboo/src/main/java/core/AbstractCoreSpec.java @@ -734,7 +734,7 @@ abstract class AbstractCoreSpec { " -e typo3DatabaseHost=localhost \\\n" + " -e typo3DatabasePort=1433 \\\n" + " -e typo3DatabaseCharset=utf-8 \\\n" + - " -e typo3DatabaseHost=mssql2017cu17 \\\n" + + " -e typo3DatabaseHost=mssql2019latest \\\n" + " -e typo3TestingRedisHost=${BAMBOO_COMPOSE_PROJECT_NAME}sib_redis4_1 \\\n" + " -e typo3TestingMemcachedHost=${BAMBOO_COMPOSE_PROJECT_NAME}sib_memcached1-5_1 \\\n" + " --name ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc \\\n" + @@ -801,7 +801,7 @@ abstract class AbstractCoreSpec { " -e typo3DatabaseHost=localhost \\\n" + " -e typo3DatabasePort=1433 \\\n" + " -e typo3DatabaseCharset=utf-8 \\\n" + - " -e typo3DatabaseHost=mssql2017cu17 \\\n" + + " -e typo3DatabaseHost=mssql2019latest \\\n" + " -e typo3TestingRedisHost=${BAMBOO_COMPOSE_PROJECT_NAME}sib_redis4_1 \\\n" + " -e typo3TestingMemcachedHost=${BAMBOO_COMPOSE_PROJECT_NAME}sib_memcached1-5_1 \\\n" + " --name ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc \\\n" + @@ -1603,35 +1603,25 @@ abstract class AbstractCoreSpec { * Task definition to cherry pick a patch set from gerrit on top of cloned core */ private Task getTaskGitCherryPick(Boolean isSecurity) { - if (isSecurity) { - return new ScriptTask() - .description("Gerrit cherry pick") - .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE) - .inlineBody( - this.getScriptTaskBashInlineBody() + - "CHANGEURL=${bamboo.changeUrl}\n" + - "CHANGEURLID=${CHANGEURL#https://review.typo3.org/}\n" + - "PATCHSET=${bamboo.patchset}\n" + - "\n" + - "if [[ $CHANGEURL ]]; then\n" + - " gerrit-cherry-pick https://review.typo3.org/Teams/Security/TYPO3v4-Core $CHANGEURLID/$PATCHSET || exit 1\n" + - "fi\n" - ); - } else { - return new ScriptTask() - .description("Gerrit cherry pick") - .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE) - .inlineBody( - this.getScriptTaskBashInlineBody() + - "CHANGEURL=${bamboo.changeUrl}\n" + - "CHANGEURLID=${CHANGEURL#https://review.typo3.org/}\n" + - "PATCHSET=${bamboo.patchset}\n" + - "\n" + - "if [[ $CHANGEURL ]]; then\n" + - " gerrit-cherry-pick https://review.typo3.org/Packages/TYPO3.CMS $CHANGEURLID/$PATCHSET || exit 1\n" + - "fi\n" - ); - } + String cherryPickRepository = isSecurity ? "Teams/Security/TYPO3v4-Core" : "Packages/TYPO3.CMS"; + + return new ScriptTask() + .description("Gerrit cherry pick") + .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE) + .inlineBody( + this.getScriptTaskBashInlineBody() + + "CHANGEURL=${bamboo.changeUrl}\n" + + "CHANGEURLID=${CHANGEURL#https://review.typo3.org/}\n" + + "PATCHSET=${bamboo.patchset}\n" + + "\n" + + "if [[ $CHANGEURL ]]; then\n" + + " NEXT_WAIT_TIME=0\n" + + " until gerrit-cherry-pick https://review.typo3.org/" + cherryPickRepository + " $CHANGEURLID/$PATCHSET; do\n" + + " [[ $NEXT_WAIT_TIME -eq 5 ]] && exit 1\n" + + " sleep $(( NEXT_WAIT_TIME++ ))\n" + + " done\n" + + "fi\n" + ); } /** @@ -1645,8 +1635,11 @@ abstract class AbstractCoreSpec { .inlineBody( this.getScriptTaskBashInlineBody() + "cd Build/testing-docker/bamboo\n" + - "docker-compose down -v\n" + - "docker rm -f ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc\n" + + "docker inspect -f '{{.State.Running}}' ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc > /dev/null 2>&1\n" + + "if [[ $? -eq 0 ]]; then\n" + + " docker-compose down -v\n" + + " docker rm -f ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc\n" + + "fi\n" + "exit 0\n" ); } diff --git a/Build/bamboo/src/main/java/core/NightlySpec.java b/Build/bamboo/src/main/java/core/NightlySpec.java index 7a261ac4ed00957ffd20d981b7ccd380a7198645..cdf81ad644d1433b8e056b78f429d483a2f32788 100644 --- a/Build/bamboo/src/main/java/core/NightlySpec.java +++ b/Build/bamboo/src/main/java/core/NightlySpec.java @@ -28,11 +28,8 @@ import com.atlassian.bamboo.specs.api.builders.task.Task; import com.atlassian.bamboo.specs.builders.notification.PlanCompletedNotification; import com.atlassian.bamboo.specs.builders.trigger.ScheduledTrigger; import com.atlassian.bamboo.specs.util.BambooServer; -import core.utilities.LimitedChunker; import java.util.ArrayList; -import java.util.Collections; -import java.util.List; /** * Core master nightly test plan. @@ -60,9 +57,6 @@ public class NightlySpec extends AbstractCoreSpec { private String[] sqLiteVersions = {"3.15", "3.20", "3.25", "3.30"}; private String[] postGreSqlVersions = {"9.3", "9.4", "9.5", "9.6", "10.11", "11.6", "12.1"}; - private int totalJobsPerStage = 50; - private int mssqlJobsPerStage = 25; - /** * Run main to publish plan on Bamboo */ @@ -85,51 +79,24 @@ public class NightlySpec extends AbstractCoreSpec { * Returns full Plan definition */ Plan createPlan() { - Stage stagePreparation = getPreparationStage(); - - Stage stageIntegrity = getIntegrityStage(); - ArrayList<Job> jobs = new ArrayList<Job>(); - ArrayList<Job> mssqlJobs = new ArrayList<Job>(); - jobs.addAll(getUnitTestJobs()); - jobs.addAll(getCodeceptionMySqlJobs()); - jobs.addAll(getCodeceptionSqLiteJobs()); - jobs.addAll(getCodeceptionPgSqlJobs()); - jobs.addAll(getFunctionalMySqlJobs()); - jobs.addAll(getFunctionalMySqlPdoJobs()); - jobs.addAll(getFunctionalPGSqlJobs()); - jobs.addAll(getFunctionalSqliteJobs()); - mssqlJobs.addAll(getFunctionalMsSqlJobs()); - mssqlJobs.addAll(getFunctionalMsSqlPdoJobs()); - - Collections.shuffle(jobs); - Collections.shuffle(mssqlJobs); - - ArrayList<Stage> stages = new ArrayList<Stage>(); - stages.add(stagePreparation); - stages.add(stageIntegrity); - - LimitedChunker<Job> chunker = new LimitedChunker<>(mssqlJobsPerStage, totalJobsPerStage); - List<List<Job>> chunks = chunker.chunk(mssqlJobs, jobs); - - int totalNumberOfJobs = jobs.size() + mssqlJobs.size(); - int stageIndex = 0; - for (List<Job> chunk : chunks) { - int firstJobIndex = totalJobsPerStage * stageIndex + 1; - int lastJobIndex = totalJobsPerStage * (stageIndex + 1); - lastJobIndex = Math.min(lastJobIndex, totalNumberOfJobs); - - Collections.shuffle(chunk); - Stage stage = new Stage("Stage " + (stageIndex + 1) + ", Jobs " + firstJobIndex + " - " + lastJobIndex); - stage.jobs(chunk.toArray(new Job[chunk.size()])); - stages.add(stage); - System.out.println("Stage " + (stageIndex + 1) + " got " + chunk.size() + " Jobs"); - stageIndex++; - } + ArrayList<Stage> stages = new ArrayList<>(); + stages.add(getPreparationStage()); + stages.add(getIntegrityStage()); + stages.addAll(getUnitTestStages()); + stages.addAll(getCodeceptionMySqlStages()); + stages.addAll(getCodeceptionSqLiteStages()); + stages.addAll(getCodeceptionPgSqlStages()); + stages.addAll(getFunctionalMySqlStages()); + stages.addAll(getFunctionalMySqlPdoStages()); + stages.addAll(getFunctionalPGSqlStages()); + stages.addAll(getFunctionalSqliteStages()); + stages.addAll(getFunctionalMsSqlStages()); + stages.addAll(getFunctionalMsSqlPdoStages()); // Compile plan return new Plan(project(), planName, planKey).description("Execute TYPO3 core master nightly tests. Auto generated! See Build/bamboo of core git repository.") .pluginConfigurations(this.getDefaultPlanPluginConfiguration()) - .stages(stages.toArray(new Stage[stages.size()])) + .stages(stages.toArray(new Stage[0])) .linkedRepositories("github TYPO3 TYPO3.CMS") .triggers(new ScheduledTrigger().name("Scheduled") .description("once a day") @@ -144,145 +111,165 @@ public class NightlySpec extends AbstractCoreSpec { /** * functional tests in all composer install stages, executed with DBMS Sqlite */ - private ArrayList<Job> getFunctionalSqliteJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getFunctionalSqliteStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobsFunctionalTestsSqlite(stageNumber, numberOfFunctionalSqliteJobs, phpVersion, composerTask, false)); } + stages.add(new Stage("Functionals sqlite " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * functional tests in all composer install stages, executed with DBMS PostgreSql */ - private ArrayList<Job> getFunctionalPGSqlJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getFunctionalPGSqlStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobsFunctionalTestsPgsql(stageNumber, numberOfFunctionalPgsqlJobs, phpVersion, composerTask, false)); } + stages.add(new Stage("Functionals pgsql " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * functional tests in all composer install stages, executed with DBMS MsSQL, driver is pdo_sqlsrv */ - private ArrayList<Job> getFunctionalMsSqlPdoJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getFunctionalMsSqlPdoStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobsFunctionalTestsMssqlWithDriverPdoSqlSrv(stageNumber, numberOfFunctionalMssqlJobs, phpVersion, composerTask, false)); } + stages.add(new Stage("Functionals mssql pdo " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * functional tests in all composer install stages, executed with DBMS MsSQL, driver is sqlsrv */ - private ArrayList<Job> getFunctionalMsSqlJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getFunctionalMsSqlStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobsFunctionalTestsMssqlWithDriverSqlSrv(stageNumber, numberOfFunctionalMssqlJobs, phpVersion, composerTask, false)); } + stages.add(new Stage("Functionals mssql " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * functional tests in all composer install stages, executed with DBMS MySQL, driver is mysqli */ - private ArrayList<Job> getFunctionalMySqlJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getFunctionalMySqlStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerJob = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobsFunctionalTestsMysqlWithDriverMySqli(stageNumber, numberOfFunctionalMysqlJobs, phpVersion, composerJob, false)); } + stages.add(new Stage("Functionals mysql " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * functional tests in all composer install stages, executed with DBMS MySQL, driver is pdo_mysql */ - private ArrayList<Job> getFunctionalMySqlPdoJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getFunctionalMySqlPdoStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerJob = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobsFunctionalTestsMysqlWithDriverPdoMysql(stageNumber, numberOfFunctionalMysqlJobs, phpVersion, composerJob, false)); } + stages.add(new Stage("Functionals mysql pdo " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * all tests run via codeception framework on MySql, for all php versions and each with composer max and min install */ - private ArrayList<Job> getCodeceptionMySqlJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getCodeceptionMySqlStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.add(this.getJobAcceptanceTestInstallMysql(stageNumber, phpVersion, composerTask, false)); jobs.addAll(this.getJobsAcceptanceTestsBackendMysql(stageNumber, numberOfAcceptanceTestJobs, phpVersion, composerTask, false)); jobs.addAll(this.getJobsAcceptanceTestsPageTreeMysql(stageNumber, phpVersion, composerTask, false)); } + stages.add(new Stage("Acceptance mysql " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * all tests run via codeception framework on SqLite, for all php versions and each with composer max and min install */ - private ArrayList<Job> getCodeceptionSqLiteJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getCodeceptionSqLiteStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.add(this.getJobAcceptanceTestInstallSqlite(stageNumber, phpVersion, composerTask, false)); } + stages.add(new Stage("Acceptance sqlite " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * all tests run via codeception framework on PostGreSql, for all php versions and each with composer max and min install */ - private ArrayList<Job> getCodeceptionPgSqlJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getCodeceptionPgSqlStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.add(this.getJobAcceptanceTestInstallPgsql(stageNumber, phpVersion, composerTask, false)); } + stages.add(new Stage("Acceptance pgsql " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** * all unit tests, for all php versions and each with composer max and min install */ - private ArrayList<Job> getUnitTestJobs() { - ArrayList<Job> jobs = new ArrayList<Job>(); + private ArrayList<Stage> getUnitTestStages() { + ArrayList<Stage> stages = new ArrayList<>(); for (String phpVersion : phpVersions) { + ArrayList<Job> jobs = new ArrayList<>(); for (int stageNumber = 0; stageNumber <= 2; stageNumber++) { Task composerTask = getComposerTaskByStageNumber(phpVersion, stageNumber); jobs.addAll(this.getJobUnitPhpRandom(stageNumber, numberOfUnitRandomOrderJobs, phpVersion, composerTask, false)); jobs.add(this.getJobUnitDeprecatedPhp(stageNumber, phpVersion, composerTask, false)); jobs.add(this.getJobUnitPhp(stageNumber, phpVersion, composerTask, false)); } + stages.add(new Stage("Unit Tests " + phpVersion).jobs(jobs.toArray(new Job[0]))); } - return jobs; + return stages; } /** @@ -292,7 +279,7 @@ public class NightlySpec extends AbstractCoreSpec { */ private Stage getIntegrityStage() { String phpVersionForIntegrityStage = phpVersions[0]; // the version is not very important, just use one (except for linting!) - ArrayList<Job> jobs = new ArrayList<Job>(); + ArrayList<Job> jobs = new ArrayList<>(); jobs.add(this.getJobIntegrationAnnotations(phpVersionForIntegrityStage, this.getTaskComposerInstall(phpVersionForIntegrityStage), false)); jobs.add(this.getJobCglCheckFullCore(phpVersionForIntegrityStage, this.getTaskComposerInstall(phpVersionForIntegrityStage), false)); jobs.add(this.getJobIntegrationPhpStan(phpVersionForIntegrityStage, this.getTaskComposerInstall(phpVersionForIntegrityStage), false)); @@ -305,15 +292,15 @@ public class NightlySpec extends AbstractCoreSpec { for (String phpVersion : phpVersions) { jobs.add(this.getJobLintPhp(phpVersion, false)); } - return new Stage("Integrity").jobs(jobs.toArray(new Job[jobs.size()])); + return new Stage("Integrity").jobs(jobs.toArray(new Job[0])); } /** * preparation stage - this will only define labels for later communication of test results */ private Stage getPreparationStage() { - ArrayList<Job> jobs = new ArrayList<Job>(); + ArrayList<Job> jobs = new ArrayList<>(); jobs.add(this.getJobBuildLabels()); - return new Stage("Preparation").jobs(jobs.toArray(new Job[jobs.size()])); + return new Stage("Preparation").jobs(jobs.toArray(new Job[0])); } } diff --git a/Build/bamboo/src/main/java/core/utilities/LimitedChunker.java b/Build/bamboo/src/main/java/core/utilities/LimitedChunker.java deleted file mode 100644 index 6ba171dc100099ebd1266a5d9c18f2668e71a8a4..0000000000000000000000000000000000000000 --- a/Build/bamboo/src/main/java/core/utilities/LimitedChunker.java +++ /dev/null @@ -1,63 +0,0 @@ -package core.utilities; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -/** - * Chunk two lists into chunks of a given size - * where only `numLimitedJobsPerChunk` elements from one list are in each chunk - * - * @param <T> - */ -public class LimitedChunker<T> { - - private final int numLimitedElementsPerChunk; - private final int totalChunkSize; - - public LimitedChunker(int numLimitedElementsPerChunk, int totalChunkSize) { - this.numLimitedElementsPerChunk = numLimitedElementsPerChunk; - this.totalChunkSize = totalChunkSize; - - if (numLimitedElementsPerChunk < 1) { - throw new IllegalArgumentException("Number of limited Elements per Chunk must be greater than one"); - } - if (totalChunkSize < 1) { - throw new IllegalArgumentException("Total chunk size must be greater than one"); - } - if (totalChunkSize < numLimitedElementsPerChunk) { - throw new IllegalArgumentException("Number of limited elements must not be greater than total chunk size"); - } - } - - public List<List<T>> chunk(List<T> limitedElements, List<T> normalElements) { - // chunk the limited elements in sets of limitedChunkSize - LinkedList<List<T>> chunks = new LinkedList<>(prepareChunks(limitedElements, numLimitedElementsPerChunk)); - - // fill up these chunks with normal elements - Iterator<T> normalJobIterator = normalElements.iterator(); - for (List<T> chunk : chunks) { - fillChunkToSize(chunk, totalChunkSize, normalJobIterator); - } - // add chunks for all remaining normal elements, if any - while (normalJobIterator.hasNext()) { - List<T> chunk = new ArrayList<>(totalChunkSize); - fillChunkToSize(chunk, totalChunkSize, normalJobIterator); - chunks.add(chunk); - } - - return chunks; - } - - private void fillChunkToSize(List<T> chunk, int totalChunkSize, Iterator<T> remainingElementsIterator) { - while (remainingElementsIterator.hasNext() && chunk.size() < totalChunkSize) { - chunk.add(remainingElementsIterator.next()); - } - } - - private Collection<List<T>> prepareChunks(List<T> inputList, int chunkSize) { - AtomicInteger counter = new AtomicInteger(); - return inputList.stream().collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize)).values(); - } - -} diff --git a/Build/bamboo/src/test/java/utilities/JobFixture.java b/Build/bamboo/src/test/java/utilities/JobFixture.java deleted file mode 100644 index 8f03fffd88a68514b51d9ce73b53e6b9cd8ddd7a..0000000000000000000000000000000000000000 --- a/Build/bamboo/src/test/java/utilities/JobFixture.java +++ /dev/null @@ -1,13 +0,0 @@ -package utilities; - -public class JobFixture { - private final boolean isLimited; - - public JobFixture(boolean isLimited) { - this.isLimited = isLimited; - } - - public boolean isLimited(){ - return isLimited; - } -} diff --git a/Build/bamboo/src/test/java/utilities/LimitedChunkerTest.java b/Build/bamboo/src/test/java/utilities/LimitedChunkerTest.java deleted file mode 100644 index b3af82f6464c8f3b53e4800e4bd42fc51202cdd0..0000000000000000000000000000000000000000 --- a/Build/bamboo/src/test/java/utilities/LimitedChunkerTest.java +++ /dev/null @@ -1,115 +0,0 @@ -package utilities; - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -import core.utilities.LimitedChunker; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -@RunWith(Parameterized.class) -public class LimitedChunkerTest { - private final int numLimitedJobs; - private final int numNormalJobs; - private final int limitedChunkSize; - private final int totalChunkSize; - private int expectedNumberOfChunks; - - @Test(expected = IllegalArgumentException.class) - public void throwsOnZeroLimitedElementsPerChunk() { - LimitedChunker<JobFixture> chunker = new LimitedChunker<>(0, 25); - } - - @Test(expected = IllegalArgumentException.class) - public void throwsOnZeroTotalChunkSize() { - LimitedChunker<JobFixture> chunker = new LimitedChunker<>(25, 0); - } - - @Test(expected = IllegalArgumentException.class) - public void throwsOnMoreLimitedThanChunkSize() { - LimitedChunker<JobFixture> chunker = new LimitedChunker<>(25, 12); - } - - @Test - public void returnsEmptyChunkListWithEmptyInput() { - LimitedChunker<JobFixture> chunker = new LimitedChunker<>(12, 25); - - ArrayList<JobFixture> jobs = new ArrayList<>(0); - ArrayList<JobFixture> limitedJobs = new ArrayList<>(0); - - List<List<JobFixture>> chunks = chunker.chunk(limitedJobs, jobs); - - assert chunks.size() == 0; - } - - @Parameterized.Parameters - public static Collection<Object[]> data() { - return Arrays.asList( - new Integer[]{25, 25, 25, 50, 1}, - new Integer[]{25, 0, 25, 25, 1}, - new Integer[]{100, 100, 25, 50, 4}, - new Integer[]{110, 100, 25, 50, 5}, - new Integer[]{100, 110, 25, 50, 5} - ); - } - - public LimitedChunkerTest(int numLimitedJobs, int numNormalJobs, int limitedChunkSize, int totalChunkSize, int expectedNumberOfChunks) { - this.numLimitedJobs = numLimitedJobs; - this.numNormalJobs = numNormalJobs; - this.limitedChunkSize = limitedChunkSize; - this.totalChunkSize = totalChunkSize; - this.expectedNumberOfChunks = expectedNumberOfChunks; - } - - @Test - public void chunksCorrectly() { - ArrayList<JobFixture> limitedJobs = getJobs(numLimitedJobs, true); - ArrayList<JobFixture> normalJobs = getJobs(numNormalJobs, false); - - List<List<JobFixture>> chunks = new LimitedChunker<JobFixture>(limitedChunkSize, totalChunkSize).chunk(limitedJobs, normalJobs); - - assert chunks.size() == expectedNumberOfChunks; - - int actualNumberOfJobs = chunks.stream().map(List::size).reduce(0, Integer::sum); - assert actualNumberOfJobs == numLimitedJobs + numNormalJobs; - - - int chunkIndex = 0; - for (List<JobFixture> chunk : chunks) { - long numLimited = chunk.stream().filter(JobFixture::isLimited).count(); - assert(numLimited <= limitedChunkSize); - if (chunkIndex < chunks.size() - 1) { - // all chunks must be full - assert(chunk.size() == totalChunkSize); - } else { - //except the last one - assert(chunk.size() <= totalChunkSize); - } - chunkIndex++; - } - } - - private ArrayList<JobFixture> getJobs(int numLimitedJobs, boolean isLimited) { - ArrayList<JobFixture> jobs = new ArrayList<>(numLimitedJobs); - for (int i = 0; i < numLimitedJobs; i++) { - jobs.add(new JobFixture(isLimited)); - } - return jobs; - } -} diff --git a/Build/testing-docker/bamboo/docker-compose.yml b/Build/testing-docker/bamboo/docker-compose.yml index fdcc88d5fa2a448f461f159d3500ebfdb0422a52..9744ef28b231ad981d0f01634631d6176cc50005 100644 --- a/Build/testing-docker/bamboo/docker-compose.yml +++ b/Build/testing-docker/bamboo/docker-compose.yml @@ -23,13 +23,13 @@ services: - /var/lib/postgresql/data:rw,noexec,nosuid networks: - test - mssql2017cu17: - image: mcr.microsoft.com/mssql/server:2017-CU17-ubuntu + + mssql2019latest: + image: mcr.microsoft.com/mssql/server:2019-latest environment: ACCEPT_EULA: Y SA_PASSWORD: Test1234! MSSQL_PID: Developer - MSSQL_MEMORY_LIMIT_MB: 3584 tmpfs: - /var/lib/mssql:rw,noexec,nosuid volumes: @@ -159,7 +159,7 @@ services: start_dependencies_functional_mssql: image: alpine:3.8 links: - - mssql2017cu17 + - mssql2019latest - redis4 - memcached1-5 networks: @@ -168,7 +168,7 @@ services: /bin/sh -c " echo Waiting for database start COUNT=0 - while ! nc -z mssql2017cu17 1433; do + while ! nc -z mssql2019latest 1433; do if [ "$${COUNT}" -ge "120" ]; then echo Database did not come up exit 1 diff --git a/Build/testing-docker/local/docker-compose.yml b/Build/testing-docker/local/docker-compose.yml index a401c67a81ff570f127275f8bc09990201141be6..27dfc995d083f61cbc061aad628c5f550f9c1bd2 100644 --- a/Build/testing-docker/local/docker-compose.yml +++ b/Build/testing-docker/local/docker-compose.yml @@ -17,23 +17,12 @@ services: tmpfs: - /var/lib/mysql/:rw,noexec,nosuid - mssql2017cu17: - image: mcr.microsoft.com/mssql/server:2017-CU17-ubuntu + mssql2019latest: + image: mcr.microsoft.com/mssql/server:2019-latest environment: ACCEPT_EULA: Y SA_PASSWORD: "Test1234!" MSSQL_PID: Developer - MSSQL_MEMORY_LIMIT_MB: 3584 - tmpfs: - - /var/lib/mssql:rw,noexec,nosuid - - mssql2017latest: - image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu - environment: - ACCEPT_EULA: Y - SA_PASSWORD: "Test1234!" - MSSQL_PID: Developer - MSSQL_MEMORY_LIMIT_MB: 3584 tmpfs: - /var/lib/mssql:rw,noexec,nosuid @@ -642,62 +631,10 @@ services: fi " - prepare_functional_mssql2017cu17: - image: alpine:3.8 - links: - - mssql2017cu17 - - redis4 - - memcached1-5 - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - echo Waiting for database start...; - while ! nc -z mssql2017cu17 1433; do - sleep 1; - done; - echo Database is up; - " - functional_mssql2017cu17: - image: typo3gmbh/${DOCKER_PHP_IMAGE}:latest - user: ${HOST_UID} - volumes: - - ${CORE_ROOT}:${CORE_ROOT} - - ${HOST_HOME}:${HOST_HOME} - - /etc/passwd:/etc/passwd:ro - - /etc/group:/etc/group:ro - environment: - typo3DatabaseDriver: "${DATABASE_DRIVER:-sqlsrv}" - typo3DatabaseName: func - typo3DatabasePassword: "Test1234!" - typo3DatabaseUsername: SA - typo3DatabasePort: 1433 - typo3DatabaseCharset: utf-8 - typo3DatabaseHost: mssql2017cu17 - typo3TestingRedisHost: redis4 - typo3TestingMemcachedHost: memcached1-5 - working_dir: ${CORE_ROOT} - command: > - /bin/sh -c " - if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x - fi - php -v | grep '^PHP' - if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - php -n -c /etc/php/cli-no-xdebug/php.ini \ - vendor/phpunit/phpunit/phpunit -c vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-mssql ${TEST_FILE}; - else - DOCKER_HOST=`route -n | awk '/^0.0.0.0/ { print $$2 }'` - XDEBUG_CONFIG=\"remote_port=${PHP_XDEBUG_PORT} remote_enable=1 remote_host=$${DOCKER_HOST}\" \ - vendor/phpunit/phpunit/phpunit -c vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} --exclude-group not-mssql ${TEST_FILE}; - fi - " - - prepare_functional_mssql2017latest: + prepare_functional_mssql2019latest: image: alpine:3.8 links: - - mssql2017latest + - mssql2019latest - redis4 - memcached1-5 command: > @@ -706,13 +643,13 @@ services: set -x fi echo Waiting for database start...; - while ! nc -z mssql2017latest 1433; do + while ! nc -z mssql2019latest 1433; do sleep 1; done; echo Database is up; " - functional_mssql2017latest: + functional_mssql2019latest: image: typo3gmbh/${DOCKER_PHP_IMAGE}:latest user: ${HOST_UID} volumes: @@ -727,7 +664,7 @@ services: typo3DatabaseUsername: SA typo3DatabasePort: 1433 typo3DatabaseCharset: utf-8 - typo3DatabaseHost: mssql2017latest + typo3DatabaseHost: mssql2019latest typo3TestingRedisHost: redis4 typo3TestingMemcachedHost: memcached1-5 working_dir: ${CORE_ROOT}