[TASK] splitFunctionalTests.sh in 7.6 93/50193/2
authorChristian Kuhn <lolli@schwarzbu.ch>
Wed, 12 Oct 2016 10:49:25 +0000 (12:49 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Wed, 12 Oct 2016 11:23:39 +0000 (13:23 +0200)
To allow parallel execution of functional tests in 7.6, the
splitFunctionalTests.sh is copied over from master with only
a slight modification to cope with a phpunit xml parsing
bug that has been solved somewhere after the current 4.8 branch
that is used in 7.6.

Change-Id: I56ae14f44d4828089e4afc468bb414ceedd086e4
Resolves: #78254
Releases: 7.6
Reviewed-on: https://review.typo3.org/50193
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
.travis.yml
typo3/sysext/core/Build/Scripts/splitFunctionalTests.sh [new file with mode: 0755]

index 67f23d3..f394df7 100644 (file)
@@ -69,7 +69,8 @@ script:
         export typo3DatabaseHost="localhost";
         export typo3DatabaseUsername="root";
         export typo3DatabasePassword="";
-        find . -wholename '*typo3/sysext/*/Tests/Functional/*Test.php' | parallel --gnu 'echo; echo "Running functional test suite {}"; ./bin/phpunit -c typo3/sysext/core/Build/FunctionalTests.xml {}'
+        ./typo3/sysext/core/Build/Scripts/splitFunctionalTests.sh 14
+        parallel --jobs 4 -a <(seq 0 13) --gnu './bin/phpunit -c typo3/sysext/core/Build/FunctionalTests-Job-{}.xml'
     fi
   - >
     if [[ "$PHP_LINT" == "yes" ]]; then
@@ -93,4 +94,4 @@ script:
                   exit 99;
               fi
           "
-      fi
+      fi
\ No newline at end of file
diff --git a/typo3/sysext/core/Build/Scripts/splitFunctionalTests.sh b/typo3/sysext/core/Build/Scripts/splitFunctionalTests.sh
new file mode 100755 (executable)
index 0000000..431b205
--- /dev/null
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+#########################
+#
+# This file is typically executed by travis and / or bamboo.
+# It expects to be run from the core root.
+#
+# ./typo3/sysext/core/Build/Scripts/splitFunctionalTests.sh <numberOfConfigs>
+#
+# The scripts finds all functional tests and creates <numberOfConfigs> number
+# of phpunit .xml configuration files where each configuration lists a weighted
+# number of single functional tests.
+#
+# typo3/sysext/core/Build/FunctionalTests-Job-<counter>.xml
+#
+#########################
+
+numberOfFunctionalTestJobs=${1}
+numberOfFunctionalTestJobsMinusOne=$(( numberOfFunctionalTestJobs - 1 ))
+
+# Have a dir for temp files and clean up possibly existing stuff
+if [ ! -d buildTemp ]; then
+       mkdir buildTemp || exit 1
+fi
+if [ -f buildTemp/testFiles.txt ]; then
+       rm buildTemp/testFiles.txt
+fi
+if [ -f buildTemp/testFilesWithNumberOfTestFiles.txt ]; then
+       rm buildTemp/testFilesWithNumberOfTestFiles.txt
+fi
+if [ -f buildTemp/testFilesWeighted.txt ]; then
+       rm buildTemp/testFilesWeighted.txt
+fi
+
+# A list of all functional test files
+find . -name \*Test.php -path \*typo3/sysext/*/Tests/Functional* > buildTemp/testFiles.txt
+
+# File with test files of format "42 ./path/to/file"
+while read testFile; do
+       numberOfTestsInTestFile=`grep "@test" ${testFile} | wc -l`
+       echo "${numberOfTestsInTestFile} ${testFile}" >> buildTemp/testFilesWithNumberOfTestFiles.txt
+done < buildTemp/testFiles.txt
+
+# Sort list of files numeric
+cat buildTemp/testFilesWithNumberOfTestFiles.txt | sort -n -r > buildTemp/testFilesWeighted.txt
+
+# Config file boilerplate per job
+for (( i=0; i<${numberOfFunctionalTestJobs}; i++)); do
+       if [ -f typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml ]; then
+               rm typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       fi
+       echo '<phpunit' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  backupGlobals="true"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  backupStaticAttributes="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  bootstrap="FunctionalTestsBootstrap.php"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  colors="true"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  convertErrorsToExceptions="true"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  convertWarningsToExceptions="true"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  forceCoversAnnotation="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  processIsolation="true"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  stopOnError="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  stopOnFailure="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  stopOnIncomplete="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  stopOnSkipped="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  verbose="false"' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '>' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  <testsuites>' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '          <testsuite name="Core tests">' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+done
+
+counter=0
+direction=ascending
+while read testFileWeighted; do
+       # test file only, without leading ./
+       testFile=`echo ${testFileWeighted} | cut -f2 -d" " | cut -f2-40 -d"/"`
+
+       # Goal: with 3 jobs, have:
+       # file #0 to job #0 (asc)
+       # file #1 to job #1 (asc)
+       # file #2 to job #2 (asc)
+       # file #3 to job #2 (desc)
+       # file #4 to job #1 (desc)
+       # file #5 to job #0 (desc)
+       # file #6 to job #0 (asc)
+       # ...
+       testFileModuleNumberOfJobs=$(( counter % numberOfFunctionalTestJobs ))
+       if [[ ${direction} == "descending" ]]; then
+               targetJobNumberForFile=$(( numberOfFunctionalTestJobs - testFileModuleNumberOfJobs))
+       else
+               targetJobNumberForFile=${testFileModuleNumberOfJobs}
+       fi
+       if [ ${testFileModuleNumberOfJobs} -eq ${numberOfFunctionalTestJobs} ]; then
+               if [[ ${direction} == "descending" ]]; then
+                       direction=ascending
+               else
+                       direction=descending
+               fi
+       fi
+
+       echo "                  <directory>../../../../${testFile}</directory>" >> typo3/sysext/core/Build/FunctionalTests-Job-${targetJobNumberForFile}.xml
+       (( counter ++ ))
+done < buildTemp/testFilesWeighted.txt
+
+# Final part of config file
+for (( i=0; i<${numberOfFunctionalTestJobs}; i++)); do
+       echo '          </testsuite>' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '  </testsuites>' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+       echo '</phpunit>' >> typo3/sysext/core/Build/FunctionalTests-Job-${i}.xml
+done
+
+# Clean up
+rm buildTemp/testFiles.txt
+rm buildTemp/testFilesWeighted.txt
+rm buildTemp/testFilesWithNumberOfTestFiles.txt
+rmdir buildTemp
\ No newline at end of file