9c90ccaccc3fa5be3e1b4cd6c7b9408fcebf1543
[Packages/TYPO3.CMS.git] / Build / Scripts / runTests.sh
1 #!/usr/bin/env bash
2
3 #
4 # TYPO3 core test runner based on docker and docker-compose.
5 #
6
7 # Function to write a .env file in Build/testing-docker/local
8 # This is read by docker-compose and vars defined here are
9 # used in Build/testing-docker/local/docker-compose.yml
10 setUpDockerComposeDotEnv() {
11 # Delete possibly existing local .env file if exists
12 [ -e .env ] && rm .env
13 # Set up a new .env file for docker-compose
14 echo "COMPOSE_PROJECT_NAME=local" >> .env
15 # To prevent access rights of files created by the testing, the docker image later
16 # runs with the same user that is currently executing the script. docker-compose can't
17 # use $UID directly itself since it is a shell variable and not an env variable, so
18 # we have to set it explicitly here.
19 echo "HOST_UID=`id -u`" >> .env
20 # Your local home directory for composer and npm caching
21 echo "HOST_HOME=${HOME}" >> .env
22 # Your local user
23 echo "CORE_ROOT"=${CORE_ROOT} >> .env
24 echo "HOST_USER=${USER}" >> .env
25 echo "TEST_FILE=${TEST_FILE}" >> .env
26 echo "PHP_XDEBUG_ON=${PHP_XDEBUG_ON}" >> .env
27 echo "PHP_XDEBUG_PORT=${PHP_XDEBUG_PORT}" >> .env
28 echo "DOCKER_PHP_IMAGE=${DOCKER_PHP_IMAGE}" >> .env
29 echo "EXTRA_TEST_OPTIONS=${EXTRA_TEST_OPTIONS}" >> .env
30 echo "SCRIPT_VERBOSE=${SCRIPT_VERBOSE}" >> .env
31 echo "PHPUNIT_RANDOM=${PHPUNIT_RANDOM}" >> .env
32 echo "CGLCHECK_DRY_RUN=${CGLCHECK_DRY_RUN}" >> .env
33 }
34
35 # Load help text into $HELP
36 read -r -d '' HELP <<EOF
37 TYPO3 core test runner. Execute acceptance, unit, functional and other test suites in
38 a docker based test environment. Handles execution of single test files, sending
39 xdebug information to a local IDE and more.
40
41 Successfully tested with docker version 18.06.1-ce and docker-compose 1.21.2.
42
43 Usage: $0 [options] [file]
44
45 No arguments: Run all unit tests with PHP 7.2
46
47 Options:
48 -s <...>
49 Specifies which test suite to run
50 - acceptance: backend acceptance tests
51 - buildCss: execute scss to css builder
52 - buildJavascript: execute typescript to javascript builder
53 - cglGit: test and fix latest committed patch for CGL compliance
54 - cglAll: test and fix all core php files
55 - checkAnnotations: check php code for allowed annotations
56 - checkComposer: check composer.json files for version integrity
57 - checkCsvFixtures: test integrity of functional test csv fixtures
58 - checkExceptionCodes: test core for duplicate exception codes
59 - checkExtensionScannerRst: test all .rst files referenced by extension scanner exist
60 - checkFilePathLength: test core file paths do not exceed maximum length
61 - checkGitSubmodule: test core git has no sub modules defined
62 - checkPermissions: test some core files for correct executable bits
63 - checkRst: test .rst files for integrity
64 - checkXlf: test .xlf files for integrity
65 - composerInstall: "composer install", handy if host has no PHP, uses composer cache of users home
66 - composerValidate: "composer validate"
67 - functional: functional tests
68 - install: installation acceptance tests, only with -d mariadb|postgres|sqlite
69 - lint: PHP linting
70 - lintScss: SCSS linting
71 - lintTypescript: TS linting
72 - unit (default): PHP unit tests
73 - unitDeprecated: deprecated PHP unit tests
74 - unitJavascript: JavaScript unit tests
75 - unitRandom: PHP unit tests in random order, add -o <number> to use specific seed
76
77 -d <mariadb|mssql|postgres|sqlite>
78 Only with -s install|functional
79 Specifies on which DBMS tests are performed
80 - mariadb (default): use mariadb
81 - mssql: use mssql microsoft sql server
82 - postgres: use postgres
83 - sqlite: use sqlite
84
85 -p <7.2|7.3>
86 Specifies the PHP minor version to be used
87 - 7.2 (default): use PHP 7.2
88 - 7.3: use PHP 7.3
89
90 -e "<phpunit or codeception options>"
91 Only with -s functional|unit|unitDeprecated|unitRandom
92 Additional options to send to phpunit (unit & functional tests) or codeception (acceptance
93 tests). For phpunit, options starting with "--" must be added after options starting with "-".
94 Example -e "-v --filter canRetrieveValueWithGP" to enable verbose output AND filter tests
95 named "canRetrieveValueWithGP"
96
97 -x
98 Only with -s functional|unit|unitDeprecated|unitRandom
99 Send information to host instance for test or system under test break points. This is especially
100 useful if a local PhpStorm instance is listening on default xdebug port 9000. A different port
101 can be selected with -y
102
103 -y <port>
104 Send xdebug information to a different port than default 9000 if an IDE like PhpStorm
105 is not listening on default port.
106
107 -o <number>
108 Only with -s unitRandom
109 Set specific random seed to replay a random run in this order again. The phpunit randomizer
110 outputs the used seed at the end (in bamboo core testing logs, too). Use that number to
111 replay the unit tests in that order.
112
113 -n
114 Only with -s cglGit|cglAll
115 Activate dry-run in CGL check that does not actively change files and only prints broken ones.
116
117 -u
118 Update existing typo3gmbh/phpXY:latest docker images. Maintenance call to docker pull latest
119 versions of the main php images. The images are updated once in a while and only the youngest
120 ones are supported by core testing. Use this if weird test errors occur. Also removes obsolete
121 image versions of typo3gmbh/phpXY.
122
123 -v
124 Enable verbose script output. Shows variables and docker commands.
125
126 -h
127 Show this help.
128
129 Examples:
130 # Run all core unit tests using PHP 7.2
131 ./Build/Scripts/runTests.sh
132 ./Build/Scripts/runTests.sh -s unit
133
134 # Run all core units tests and enable xdebug (have a PhpStorm listening on port 9000!)
135 ./Build/Scripts/runTests.sh -x
136
137 # Run unit tests in phpunit verbose mode with xdebug on PHP 7.3 and filter for test canRetrieveValueWithGP
138 ./Build/Scripts/runTests.sh -x -p 7.3 -e "-v --filter canRetrieveValueWithGP"
139
140 # Run unit tests with PHP 7.3 and have xdebug enabled
141 ./Build/Scripts/runTests.sh -x -p 7.3
142
143 # Run functional tests on postgres with xdebug, php 7.3 and execute a restricted set of tests
144 ./Build/Scripts/runTests.sh -x -p 7.3 -s functional -d postgres typo3/sysext/core/Tests/Functional/Authentication
145
146 # Run restricted set of backend acceptance tests
147 ./Build/Scripts/runTests.sh -s acceptance typo3/sysext/core/Tests/Acceptance/Backend/Login/BackendLoginCest.php
148
149 # Run installer tests of a new instance on sqlite
150 ./Build/Scripts/runTests.sh -s install -d sqlite
151 EOF
152
153 # Test if docker-compose exists, else exit out with error
154 if ! type "docker-compose" > /dev/null; then
155 echo "This script relies on docker and docker-compose. Please install" >&2
156 exit 1
157 fi
158
159 # Go to the directory this script is located, so everything else is relative
160 # to this dir, no matter from where this script is called.
161 THIS_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
162 cd "$THIS_SCRIPT_DIR" || exit 1
163
164 # Go to directory that contains the local docker-compose.yml file
165 cd ../testing-docker/local || exit 1
166
167 # Option defaults
168 CORE_ROOT="${PWD}/../../../"
169 TEST_SUITE="unit"
170 DBMS="mariadb"
171 PHP_VERSION="7.2"
172 PHP_XDEBUG_ON=0
173 PHP_XDEBUG_PORT=9000
174 EXTRA_TEST_OPTIONS=""
175 SCRIPT_VERBOSE=0
176 PHPUNIT_RANDOM="--order rand"
177 CGLCHECK_DRY_RUN=""
178
179 # Option parsing
180 # Reset in case getopts has been used previously in the shell
181 OPTIND=1
182 # Array for invalid options
183 INVALID_OPTIONS=();
184 # Simple option parsing based on getopts (! not getopt)
185 while getopts ":s:d:p:e:xy:o:nhuv" OPT; do
186 case ${OPT} in
187 s)
188 TEST_SUITE=${OPTARG}
189 ;;
190 d)
191 DBMS=${OPTARG}
192 ;;
193 p)
194 PHP_VERSION=${OPTARG}
195 ;;
196 e)
197 EXTRA_TEST_OPTIONS=${OPTARG}
198 ;;
199 x)
200 PHP_XDEBUG_ON=1
201 ;;
202 y)
203 PHP_XDEBUG_PORT=${OPTARG}
204 ;;
205 o)
206 PHPUNIT_RANDOM="--order :${OPTARG}"
207 ;;
208 n)
209 CGLCHECK_DRY_RUN="-n"
210 ;;
211 h)
212 echo "${HELP}"
213 exit 0
214 ;;
215 u)
216 TEST_SUITE=update
217 ;;
218 v)
219 SCRIPT_VERBOSE=1
220 ;;
221 \?)
222 INVALID_OPTIONS+=(${OPTARG})
223 ;;
224 :)
225 INVALID_OPTIONS+=(${OPTARG})
226 ;;
227 esac
228 done
229
230 # Exit on invalid options
231 if [ ${#INVALID_OPTIONS[@]} -ne 0 ]; then
232 echo "Invalid option(s):" >&2
233 for I in "${INVALID_OPTIONS[@]}"; do
234 echo "-"${I} >&2
235 done
236 echo >&2
237 echo "${HELP}" >&2
238 exit 1
239 fi
240
241 # Move "7.2" to "php72", the latter is the docker container name
242 DOCKER_PHP_IMAGE=`echo "php${PHP_VERSION}" | sed -e 's/\.//'`
243
244 # Set $1 to first mass argument, this is the optional test file or test directory to execute
245 shift $((OPTIND - 1))
246 TEST_FILE=${1}
247
248 if [ ${SCRIPT_VERBOSE} -eq 1 ]; then
249 set -x
250 fi
251
252 # Suite execution
253 case ${TEST_SUITE} in
254 acceptance)
255 setUpDockerComposeDotEnv
256 docker-compose run prepare_acceptance_backend_mariadb10
257 docker-compose run acceptance_backend_mariadb10
258 SUITE_EXIT_CODE=$?
259 docker-compose down
260 ;;
261 buildCss)
262 setUpDockerComposeDotEnv
263 docker-compose run build_css
264 SUITE_EXIT_CODE=$?
265 docker-compose down
266 ;;
267 buildJavascript)
268 setUpDockerComposeDotEnv
269 docker-compose run build_javascript
270 SUITE_EXIT_CODE=$?
271 docker-compose down
272 ;;
273 cglGit)
274 setUpDockerComposeDotEnv
275 docker-compose run cgl_git
276 SUITE_EXIT_CODE=$?
277 docker-compose down
278 ;;
279 cglAll)
280 # Active dry-run for cglAll needs not "-n" but specific options
281 if [[ ! -z ${CGLCHECK_DRY_RUN} ]]; then
282 CGLCHECK_DRY_RUN="--dry-run --diff --diff-format udiff"
283 fi
284 setUpDockerComposeDotEnv
285 docker-compose run cgl_all
286 SUITE_EXIT_CODE=$?
287 docker-compose down
288 ;;
289 checkAnnotations)
290 setUpDockerComposeDotEnv
291 docker-compose run check_annotations
292 SUITE_EXIT_CODE=$?
293 docker-compose down
294 ;;
295 checkComposer)
296 setUpDockerComposeDotEnv
297 docker-compose run check_composer
298 SUITE_EXIT_CODE=$?
299 docker-compose down
300 ;;
301 checkCsvFixtures)
302 setUpDockerComposeDotEnv
303 docker-compose run check_csv_fixtures
304 SUITE_EXIT_CODE=$?
305 docker-compose down
306 ;;
307 checkExceptionCodes)
308 setUpDockerComposeDotEnv
309 docker-compose run check_exception_codes
310 SUITE_EXIT_CODE=$?
311 docker-compose down
312 ;;
313 checkExtensionScannerRst)
314 setUpDockerComposeDotEnv
315 docker-compose run check_extension_scanner_rst
316 SUITE_EXIT_CODE=$?
317 docker-compose down
318 ;;
319 checkFilePathLength)
320 setUpDockerComposeDotEnv
321 docker-compose run check_file_path_length
322 SUITE_EXIT_CODE=$?
323 docker-compose down
324 ;;
325 checkGitSubmodule)
326 setUpDockerComposeDotEnv
327 docker-compose run check_git_submodule
328 SUITE_EXIT_CODE=$?
329 docker-compose down
330 ;;
331 checkPermissions)
332 setUpDockerComposeDotEnv
333 docker-compose run check_permissions
334 SUITE_EXIT_CODE=$?
335 docker-compose down
336 ;;
337 checkRst)
338 setUpDockerComposeDotEnv
339 docker-compose run check_rst
340 SUITE_EXIT_CODE=$?
341 docker-compose down
342 ;;
343 checkXlf)
344 setUpDockerComposeDotEnv
345 docker-compose run check_xlf
346 SUITE_EXIT_CODE=$?
347 docker-compose down
348 ;;
349 composerInstall)
350 setUpDockerComposeDotEnv
351 docker-compose run composer_install
352 SUITE_EXIT_CODE=$?
353 docker-compose down
354 ;;
355 composerValidate)
356 setUpDockerComposeDotEnv
357 docker-compose run composer_validate
358 SUITE_EXIT_CODE=$?
359 docker-compose down
360 ;;
361 functional)
362 setUpDockerComposeDotEnv
363 case ${DBMS} in
364 mariadb)
365 docker-compose run prepare_functional_mariadb10
366 docker-compose run functional_mariadb10
367 SUITE_EXIT_CODE=$?
368 ;;
369 mssql)
370 docker-compose run prepare_functional_mssql2017cu9
371 docker-compose run functional_mssql2017cu9
372 SUITE_EXIT_CODE=$?
373 ;;
374 postgres)
375 docker-compose run prepare_functional_postgres10
376 docker-compose run functional_postgres10
377 SUITE_EXIT_CODE=$?
378 ;;
379 sqlite)
380 docker-compose run prepare_functional_sqlite
381 docker-compose run functional_sqlite
382 SUITE_EXIT_CODE=$?
383 ;;
384 *)
385 echo "Invalid -d option argument ${DBMS}" >&2
386 echo >&2
387 echo "${HELP}" >&2
388 exit 1
389 esac
390 docker-compose down
391 ;;
392 install)
393 setUpDockerComposeDotEnv
394 case ${DBMS} in
395 mariadb)
396 docker-compose run prepare_acceptance_install_mariadb10
397 docker-compose run acceptance_install_mariadb10
398 SUITE_EXIT_CODE=$?
399 ;;
400 postgres)
401 docker-compose run prepare_acceptance_install_postgres10
402 docker-compose run acceptance_install_postgres10
403 SUITE_EXIT_CODE=$?
404 ;;
405 sqlite)
406 docker-compose run prepare_acceptance_install_sqlite
407 docker-compose run acceptance_install_sqlite
408 SUITE_EXIT_CODE=$?
409 ;;
410 *)
411 echo "Invalid -d option argument ${DBMS}" >&2
412 echo >&2
413 echo "${HELP}" >&2
414 exit 1
415 esac
416 docker-compose down
417 ;;
418 lint)
419 setUpDockerComposeDotEnv
420 docker-compose run lint
421 SUITE_EXIT_CODE=$?
422 docker-compose down
423 ;;
424 lintScss)
425 setUpDockerComposeDotEnv
426 docker-compose run lint_scss
427 SUITE_EXIT_CODE=$?
428 docker-compose down
429 ;;
430 lintTypescript)
431 setUpDockerComposeDotEnv
432 docker-compose run lint_typescript
433 SUITE_EXIT_CODE=$?
434 docker-compose down
435 ;;
436 unit)
437 setUpDockerComposeDotEnv
438 docker-compose run unit
439 SUITE_EXIT_CODE=$?
440 docker-compose down
441 ;;
442 unitDeprecated)
443 setUpDockerComposeDotEnv
444 docker-compose run unitDeprecated
445 SUITE_EXIT_CODE=$?
446 docker-compose down
447 ;;
448 unitJavascript)
449 setUpDockerComposeDotEnv
450 docker-compose run unitJavascript
451 SUITE_EXIT_CODE=$?
452 docker-compose down
453 ;;
454 unitRandom)
455 setUpDockerComposeDotEnv
456 docker-compose run unitRandom
457 SUITE_EXIT_CODE=$?
458 docker-compose down
459 ;;
460 update)
461 # pull typo3gmbh/phpXY:latest versions of those ones that exist locally
462 docker images typo3gmbh/php*:latest --format "{{.Repository}}:latest" | xargs -I {} docker pull {}
463 # remove "dangling" typo3gmbh/phpXY images (those tagged as <none>)
464 docker images typo3gmbh/php* --filter "dangling=true" --format "{{.ID}}" | xargs -I {} docker rmi {}
465 ;;
466 *)
467 echo "Invalid -s option argument ${TEST_SUITE}" >&2
468 echo >&2
469 echo "${HELP}" >&2
470 exit 1
471 esac
472
473 exit $SUITE_EXIT_CODE