Skip to content

Commit

Permalink
Add support to run bisect sessions to the phpunit job
Browse files Browse the repository at this point in the history
If GOOD_COMMIT and BAD_COMMIT are set, then a phpunit
bisect happens between the 2 commits, using the exact
configuration provided (filter, database, ... everything).
  • Loading branch information
stronk7 committed Apr 12, 2024
1 parent 9b46db1 commit b1eef26
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 10 deletions.
108 changes: 103 additions & 5 deletions runner/main/jobtypes/phpunit/phpunit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ function phpunit_to_summary() {
echo "== PHPUNIT_FILTER: ${PHPUNIT_FILTER}"
echo "== PHPUNIT_TESTSUITE: ${PHPUNIT_TESTSUITE}"
echo "== MOODLE_CONFIG: ${MOODLE_CONFIG}"
if [[ -n "${GOOD_COMMIT}" ]] || [[ -n "${BAD_COMMIT}" ]]; then
echo "== GOOD_COMMIT: ${GOOD_COMMIT}"
echo "== BAD_COMMIT: ${BAD_COMMIT}"
fi
}

# This job type defines the following env variables
Expand Down Expand Up @@ -106,7 +110,7 @@ function phpunit_check() {
verify_modules $(phpunit_modules)

# These env variables must be set for the job to work.
verify_env UUID ENVIROPATH WEBSERVER
verify_env UUID ENVIROPATH WEBSERVER GOOD_COMMIT BAD_COMMIT
}

# PHPUnit job type init.
Expand All @@ -116,23 +120,62 @@ function phpunit_config() {
PHPUNIT_FILTER="${PHPUNIT_FILTER:-}"
PHPUNIT_TESTSUITE="${PHPUNIT_TESTSUITE:-}"
EXITCODE=0

# If GOOD_COMMIT and BAD_COMMIT are set, it means that we are going to run a bisect
# session, so we need to enable FULLGIT (to get access to complete repository clone).
if [[ -n "${GOOD_COMMIT}" ]] && [[ -n "${BAD_COMMIT}" ]]; then
FULLGIT="yes"
# Also, we don't want to allow repetitions in the bisect session.
RUNCOUNT=1
fi
}

# PHPUnit job type setup.
function phpunit_setup() {
# If one of GOOD_COMMIT or BAD_COMMIT are not set, but the other is, error out.
if [[ -n "${GOOD_COMMIT}" ]] && [[ -z "${BAD_COMMIT}" ]]; then
exit_error "GOOD_COMMIT is set but BAD_COMMIT is not set."
fi
if [[ -z "${GOOD_COMMIT}" ]] && [[ -n "${BAD_COMMIT}" ]]; then
exit_error "BAD_COMMIT is set but GOOD_COMMIT is not set."
fi
# If both GOOD_COMMIT and BAD_COMMIT are set and they are the same, error out.
if [[ -n "${GOOD_COMMIT}" ]] && [[ -n "${BAD_COMMIT}" ]] && [[ "${GOOD_COMMIT}" == "${BAD_COMMIT}" ]]; then
exit_error "GOOD_COMMIT and BAD_COMMIT are set, but they are the same."
fi

# If both GOOD_COMMIT and BAD_COMMIT are not set, we are going to run a normal session.
# (for bisect sessions we don't have to setup the environment).
if [[ -z "${GOOD_COMMIT}" ]] && [[ -z "${BAD_COMMIT}" ]]; then
phpunit_setup_normal
fi
}

# PHPUnit job type setup for normal mode.
function phpunit_setup_normal() {
# Init the PHPUnit site.
echo
echo ">>> startsection Initialising PHPUnit environment at $(date)<<<"
echo "============================================================================"
docker exec -t -u www-data "${WEBSERVER}" \
php admin/tool/phpunit/cli/init.php \
--force
php admin/tool/phpunit/cli/init.php
echo "============================================================================"
echo ">>> stopsection <<<"
}

# PHPUnit job type run.
function phpunit_run() {
# If both GOOD_COMMIT and BAD_COMMIT are not set, we are going to run a normal session.
if [[ -z "${GOOD_COMMIT}" ]] && [[ -z "${BAD_COMMIT}" ]]; then
phpunit_run_normal
else
# If GOOD_COMMIT and BAD_COMMIT are set, we are going to run a bisect session.
phpunit_run_bisect
fi
}

# PHPUnit job tye run for normal mode.
function phpunit_run_normal() {
# Run the job type.
echo
if [[ RUNCOUNT -gt 1 ]]; then
Expand Down Expand Up @@ -163,11 +206,66 @@ function phpunit_run() {
while [[ ${iter} -le ${RUNCOUNT} ]]; do
echo
echo ">>> PHPUnit run ${iter} at $(date) <<<"
docker exec -t "${WEBSERVER}" "${cmd[@]}"
docker exec -t -u www-data "${WEBSERVER}" "${cmd[@]}"
EXITCODE=$((EXITCODE + $?))
iter=$((iter+1))
done

echo "============================================================================"
echo ">>> stopsection <<<"
}
}

# PHPUnit job tye run for bisect mode.
function phpunit_run_bisect() {
# Run the job type.
echo
echo ">>> startsection Starting PHPUnit bisect session at $(date) <<<"
echo "=== Good commit: ${GOOD_COMMIT}"
echo "=== Bad commit: ${BAD_COMMIT}"
echo "============================================================================"
# Start the bisect session.
docker exec -t -u www-data "${WEBSERVER}" \
git bisect start "${BAD_COMMIT}" "${GOOD_COMMIT}"

# Build the int command.
local initcmd=(
php admin/tool/phpunit/cli/init.php
)
# Build the run command.
local runcmd=(
php vendor/bin/phpunit
--disallow-test-output
--fail-on-risky
--verbose
)
if [[ -n "${PHPUNIT_FILTER}" ]]; then
runcmd+=(--filter "${PHPUNIT_FILTER}")
fi
if [[ -n "${PHPUNIT_TESTSUITE}" ]]; then
runcmd+=(--testsuite "${PHPUNIT_TESTSUITE}")
fi

# Generate the bisect.sh script that we are going to use to run the phpunit bisect session.
# (it runs both init and run commands together).
docker exec -i -u www-data "${WEBSERVER}" \
bash -c "cat > bisect.sh" <<- EOF
#!/bin/bash
${initcmd[*]} >/dev/null 2>&1; ${runcmd[*]}
exitcode=\$?
echo "============================================================================"
exit \$exitcode
EOF

# Run the bisect session.
echo "============================================================================"
docker exec -u www-data "${WEBSERVER}" \
git bisect run bash bisect.sh
EXITCODE=$?

# Finish the bisect session.
docker exec -u www-data "${WEBSERVER}" \
git bisect reset

echo "============================================================================"
echo ">>> stopsection <<<"
}
3 changes: 3 additions & 0 deletions runner/main/modules/docker-php/docker-php.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ function docker-php_setup() {
-v "${SHAREDDIR}":/shared \
"${DOCKER_PHP}"

# Ensure that the whole .composer directory is writable to all (www-data needs to write there).
docker exec "${WEBSERVER}" chmod -R go+rw /var/www/.composer

echo
echo "Webserver logs:"
docker logs "${WEBSERVER}"
Expand Down
2 changes: 2 additions & 0 deletions runner/main/modules/git/git.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
function git_env() {
env=(
GIT_COMMIT
GOOD_COMMIT
BAD_COMMIT
)
echo "${env[@]}"
}
Expand Down
13 changes: 8 additions & 5 deletions runner/main/modules/moodle-core-copy/moodle-core-copy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function moodle-core-copy_setup() {
fi

# If the repository was cloned shallow (--depth), un-shallow it.
if (docker exec -u www-data "${WEBSERVER}" git rev-parse --is-shallow-repository); then
if (docker exec -u www-data "${WEBSERVER}" git rev-parse --is-shallow-repository | grep -q 'true'); then
echo "== Unshallowing the repository."
docker exec -u www-data "${WEBSERVER}" git fetch --unshallow
fi
Expand All @@ -91,17 +91,20 @@ function moodle-core-copy_setup() {
# Copy the config.php in place
echo "== Copying configuration in place."
docker cp "${BASEDIR}/modules/docker-php/config.template.php" "${WEBSERVER}":/var/www/html/config.php
docker exec "${WEBSERVER}" chown -R www-data:www-data /var/www/html/config.php

# Copy the plugins in place.
if [[ -n "$PLUGINSTOINSTALL" ]]; then
echo "== Copying external plugins in place."
docker cp "${PLUGINSDIR}"/. "${WEBSERVER}":/var/www/html
echo "== Copying external plugins in place."
docker cp "${PLUGINSDIR}"/. "${WEBSERVER}":/var/www/html
docker exec "${WEBSERVER}" chown -R www-data:www-data /var/www/html
fi

# Copy composer-phar if available in caches.
if [[ -f "${COMPOSERCACHE}/composer.phar" ]]; then
echo "== Copying composer.phar in place."
docker cp "${COMPOSERCACHE}/composer.phar" "${WEBSERVER}":/var/www/html/composer.phar
echo "== Copying composer.phar in place."
docker cp "${COMPOSERCACHE}/composer.phar" "${WEBSERVER}":/var/www/html/composer.phar
docker exec "${WEBSERVER}" chown -R www-data:www-data /var/www/html/composer.phar
fi

echo "============================================================================"
Expand Down

0 comments on commit b1eef26

Please sign in to comment.