From 27b9bb19b353c222ce5b37975903fdab3f4b0091 Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski <t.motylewski@gmail.com> Date: Wed, 15 Feb 2017 23:40:42 +0100 Subject: [PATCH] [TASK] Run acceptance tests in parallel Provide script for generating files with acceptance tests groups to allow running them in parallel on different hosts. Very useful for bamboo. Usage: Generating 5 dynamic group files: ./components/testing_framework/Resources/Core/Build/Scripts/splitAcceptanceTests.sh 5 Run tests of group 1: ./bin/codecept run Acceptance -g AcceptanceTests-Job-1 -c ... Note group numbers start from 1, not 0. Resolves: #79845 Releases: master Change-Id: Ib74ec0b457ee927a906a77e648041ae15dc727d2 Reviewed-on: https://review.typo3.org/51713 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../Resources/Core/Build/AcceptanceTests.yml | 3 + .../Build/Scripts/splitAcceptanceTests.sh | 95 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100755 components/testing_framework/Resources/Core/Build/Scripts/splitAcceptanceTests.sh diff --git a/components/testing_framework/Resources/Core/Build/AcceptanceTests.yml b/components/testing_framework/Resources/Core/Build/AcceptanceTests.yml index 923883b05afb..15be77c06e40 100644 --- a/components/testing_framework/Resources/Core/Build/AcceptanceTests.yml +++ b/components/testing_framework/Resources/Core/Build/AcceptanceTests.yml @@ -14,3 +14,6 @@ extensions: - Codeception\Extension\RunFailed - Codeception\Extension\Recorder - TYPO3\TestingFramework\Core\Acceptance\AcceptanceCoreEnvironment +groups: + AcceptanceTests-Job-*: Configuration/Acceptance/AcceptanceTests-Job-* + diff --git a/components/testing_framework/Resources/Core/Build/Scripts/splitAcceptanceTests.sh b/components/testing_framework/Resources/Core/Build/Scripts/splitAcceptanceTests.sh new file mode 100755 index 000000000000..e7b51f7907bb --- /dev/null +++ b/components/testing_framework/Resources/Core/Build/Scripts/splitAcceptanceTests.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +######################### +# +# This file is typically executed by bamboo, but could be +# used locally, too. +# +# It expects to be run from the core root. +# +# ./components/testing_framework/core/Build/Scripts/splitAcceptanceTests.sh <numberOfConfigs> +# +# The script finds all acceptance tests and creates <numberOfConfigs> number +# of codeception group files, each containing a sub set of Cest files to execute. +# +# components/testing_framework/Resources/Core/Build/Configuration/Acceptance/AcceptanceTests-Job-<counter> +# +# Those sub-groups can then be executed with a command like (example for files in group 2 here) +# ./bin/codecept run Acceptance -d -g AcceptanceTests-Job-2 -c components/testing_framework/Resources/Core/Build/AcceptanceTests.yml +# +######################### + +numberOfAcceptanceTestJobs=${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 acceptance test files +find . -name \*Cest.php -path \*typo3/sysext/*/Tests/Acceptance* > buildTemp/testFiles.txt + +# File with test files of format "42 ./path/to/file" +while read testFile; do + numberOfTestsInTestFile=`grep "public function [^\_].*" ${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 + +groupFilePath="components/testing_framework/Resources/Core/Build/Configuration/Acceptance" +# Config file boilerplate per job +for (( i=1; i<=${numberOfAcceptanceTestJobs}; i++)); do + if [ -f ${groupFilePath}/AcceptanceTests-Job-${i} ]; then + rm ${groupFilePath}/AcceptanceTests-Job-${i} + fi + touch ${groupFilePath}/AcceptanceTests-Job-${i} +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 % numberOfAcceptanceTestJobs )) + if [[ ${direction} == "descending" ]]; then + targetJobNumberForFile=$(( numberOfAcceptanceTestJobs - testFileModuleNumberOfJobs)) + else + targetJobNumberForFile=${testFileModuleNumberOfJobs} + fi + if [ ${testFileModuleNumberOfJobs} -eq ${numberOfAcceptanceTestJobs} ]; then + if [[ ${direction} == "descending" ]]; then + direction=ascending + else + direction=descending + fi + fi + echo "../../../../../${testFile}" >> ${groupFilePath}/AcceptanceTests-Job-$(( targetJobNumberForFile + 1 )) + (( counter ++ )) +done < buildTemp/testFilesWeighted.txt + +# Clean up +rm buildTemp/testFiles.txt +rm buildTemp/testFilesWeighted.txt +rm buildTemp/testFilesWithNumberOfTestFiles.txt +rmdir buildTemp -- GitLab