Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Last gitlab ci #2825

Merged
merged 8 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 41 additions & 23 deletions .github/jobs/baseinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@

export version="$1"
db=${2:-install}
phpversion="${3:-8.1}"
# If this script is called from unit-tests.sh, we use the test environment
export APP_ENV="${4:-prod}"

# In the test environment, we need to use a different database
[ "$APP_ENV" = "prod" ] && DATABASE_NAME=domjudge || DATABASE_NAME=domjudge_test

MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-root}

set -eux

PHPVERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION."\n";')
export PHPVERSION
if [ -z "$phpversion" ]; then
phpversion=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION."\n";')
fi

show_phpinfo "$phpversion"

section_start "Run composer"
export APP_ENV="dev"
Expand Down Expand Up @@ -41,22 +52,24 @@ else
--enable-judgehost-build=no | tee "$ARTIFACTS"/configure.txt
make domserver
make install-domserver
rm -rf /opt/domjudge/domserver/webapp/public/doc
cp -r doc /opt/domjudge/domserver/webapp/public/
find /opt/domjudge/domserver -name DOMjudgelogo.pdf
fi

section_end

section_start "SQL settings"
cat > ~/.my.cnf <<EOF
[client]
host=sqlserver
user=root
password=root
password=${MYSQL_ROOT_PASSWORD}
EOF
cat ~/.my.cnf

mysql_root "CREATE DATABASE IF NOT EXISTS \`domjudge\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql_root "CREATE DATABASE IF NOT EXISTS \`$DATABASE_NAME\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql_root "CREATE USER IF NOT EXISTS \`domjudge\`@'%' IDENTIFIED BY 'domjudge';"
mysql_root "GRANT SELECT, INSERT, UPDATE, DELETE ON \`domjudge\`.* TO 'domjudge'@'%';"
mysql_root "GRANT SELECT, INSERT, UPDATE, DELETE ON \`$DATABASE_NAME\`.* TO 'domjudge'@'%';"
mysql_root "FLUSH PRIVILEGES;"

# Show some MySQL debugging
Expand All @@ -65,18 +78,20 @@ mysql_root "SELECT CURRENT_USER();"
mysql_root "SELECT USER();"
mysql_root "SELECT user,host FROM mysql.user"
mysql_root "SET GLOBAL max_allowed_packet=1073741824"
echo "unused:sqlserver:domjudge:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret
mysql_root "SHOW GLOBAL STATUS LIKE 'Connection_errors_%'"
mysql_root "SHOW VARIABLES LIKE '%_timeout'"
echo "unused:sqlserver:$DATABASE_NAME:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret
mysql_user "SELECT CURRENT_USER();"
mysql_user "SELECT USER();"
section_end

if [ "${db}" = "install" ]; then
section_start "Install DOMjudge database"
/opt/domjudge/domserver/bin/dj_setup_database -uroot -proot bare-install
/opt/domjudge/domserver/bin/dj_setup_database -uroot -p${MYSQL_ROOT_PASSWORD} bare-install
section_end
elif [ "${db}" = "upgrade" ]; then
section_start "Upgrade DOMjudge database"
/opt/domjudge/domserver/bin/dj_setup_database -uroot -proot upgrade
/opt/domjudge/domserver/bin/dj_setup_database -uroot -p${MYSQL_ROOT_PASSWORD} upgrade
section_end
fi

Expand All @@ -92,7 +107,7 @@ cp /proc/cmdline "$ARTIFACTS"/cmdline.txt
section_end

section_start "Setup webserver"
cp /opt/domjudge/domserver/etc/domjudge-fpm.conf /etc/php/"$PHPVERSION"/fpm/pool.d/domjudge.conf
cp /opt/domjudge/domserver/etc/domjudge-fpm.conf /etc/php/"$phpversion"/fpm/pool.d/domjudge.conf

rm -f /etc/nginx/sites-enabled/*
cp /opt/domjudge/domserver/etc/nginx-conf /etc/nginx/sites-enabled/domjudge
Expand All @@ -106,38 +121,41 @@ nginx -t
section_end

section_start "Show webserver is up"
for service in nginx php${PHPVERSION}-fpm; do
for service in nginx php${phpversion}-fpm; do
service "$service" restart
service "$service" status
done
section_end

if [ "${db}" = "install" ]; then
section_start "Install the example data"
/opt/domjudge/domserver/bin/dj_setup_database -uroot -proot install-examples | tee -a "$ARTIFACTS/mysql.txt"
if [ "$version" = "unit" ]; then
# Make sure admin has no team associated so we will not insert submissions during unit tests.
mysql_root "UPDATE user SET teamid=null WHERE userid=1;" $DATABASE_NAME
fi
/opt/domjudge/domserver/bin/dj_setup_database -uroot -p${MYSQL_ROOT_PASSWORD} install-examples | tee -a "$ARTIFACTS/mysql.txt"
section_end
fi

section_start "Setup user"
# We're using the admin user in all possible roles
mysql_root "DELETE FROM userrole WHERE userid=1;" domjudge
mysql_root "DELETE FROM userrole WHERE userid=1;" $DATABASE_NAME
if [ "$version" = "team" ]; then
# Add team to admin user
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" domjudge
mysql_root "UPDATE user SET teamid = 1 WHERE userid = 1;" domjudge
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" $DATABASE_NAME
mysql_root "UPDATE user SET teamid = 1 WHERE userid = 1;" $DATABASE_NAME
elif [ "$version" = "jury" ]; then
# Add jury to admin user
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 2);" domjudge
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 2);" $DATABASE_NAME
elif [ "$version" = "balloon" ]; then
# Add balloon to admin user
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 4);" domjudge
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 4);" $DATABASE_NAME
elif [ "$version" = "admin" ]; then
# Add admin to admin user
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" domjudge
elif [ "$version" = "all" ]; then
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" domjudge
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" domjudge
mysql_root "UPDATE user SET teamid = 1 WHERE userid = 1;" domjudge
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" $DATABASE_NAME
elif [ "$version" = "all" ] || [ "$version" = "unit" ]; then
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" $DATABASE_NAME
mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" $DATABASE_NAME
mysql_root "UPDATE user SET teamid = 1 WHERE userid = 1;" $DATABASE_NAME
fi
section_end

9 changes: 9 additions & 0 deletions .github/jobs/ci_settings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ mysql_user () {
echo "$1" | mysql -udomjudge -pdomjudge ${2:-} | tee -a "$ARTIFACTS"/mysql.txt
}

show_phpinfo() {
phpversion=$1
section_start "Show the new PHP info"
update-alternatives --set php /usr/bin/php"${phpversion}"
php -v
php -m
section_end
}

section_start () {
if [ "$#" -ne 1 ]; then
echo "Only 1 argument is needed for GHA, 2 was needed for GitLab."
Expand Down
59 changes: 59 additions & 0 deletions .github/jobs/jsontogha.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import json
import sys
import time
import hashlib

storage1 = {}
storage2 = {}


def cleanHash(toHash):
return hashlib.sha224(toHash).hexdigest()


def sec_start(job, header):
print('section_start\r\033[0K'+header)


def sec_end(job):
print('section_end\r\033[0K')


with open(sys.argv[1], 'r') as f:
data = json.load(f)
for message in data['messages']:
mtyp = message['type'].encode('utf-8', 'ignore')
murl = message['url'].encode('utf-8', 'ignore')
mmes = message['message'].encode('utf-8', 'ignore')
if mtyp not in storage1.keys():
storage1[mtyp] = {"messages": {}, "cnt": 0}
storage2[mtyp] = {"urls": {}, "cnt": 0}
if mmes not in storage1[mtyp]["messages"].keys():
storage1[mtyp]["messages"][mmes] = {"urls": {}, "cnt": 0}
if murl not in storage2[mtyp]["urls"].keys():
storage2[mtyp]["urls"][murl] = {"messages": {}, "cnt": 0}
if murl not in storage1[mtyp]["messages"][mmes]["urls"].keys():
storage1[mtyp]["messages"][mmes]["urls"][murl] = 0
if mmes not in storage2[mtyp]["urls"][murl]["messages"].keys():
storage2[mtyp]["urls"][murl]["messages"][mmes] = 0
storage1[mtyp]["messages"][mmes]["urls"][murl] += 1
storage1[mtyp]["messages"][mmes]["cnt"] += 1
storage1[mtyp]["cnt"] += 1
storage2[mtyp]["urls"][murl]["messages"][mmes] += 1
storage2[mtyp]["urls"][murl]["cnt"] += 1
storage2[mtyp]["cnt"] += 1

for key, value in sorted(storage1.items(), key=lambda x: x[1]['cnt']):
print("Type: {}, Totalfound: {}".format(key, value["cnt"]))
for key2, value2 in sorted(storage1[key]["messages"].items(), key=lambda x: x[1]['cnt'], reverse=True):
sec_start(key+key2, key2)
print("[{}] [{}%] Message: {}".format(key, round(100*value2["cnt"]/value["cnt"], 2), key2))
for key3, value3 in sorted(storage1[key]["messages"][key2]["urls"].items(), key=lambda x: x[1], reverse=True):
print("[{}%] URL: {}".format(round(100*value3/value2["cnt"], 2), key3))
sec_end(key+key2)
for key2, value2 in sorted(storage2[key]["urls"].items(), key=lambda x: x[1]['cnt'], reverse=True):
sec_start(key+key2, key2)
print("[{}] [{}%] URL: {}".format(key, round(100*value2["cnt"]/value["cnt"], 2), key2))
for key3, value3 in sorted(storage2[key]["urls"][key2]["messages"].items(), key=lambda x: x[1], reverse=True):
print("[{}%] Message: {}".format(round(100*value3/value2["cnt"], 2), key3))
sec_end(key+key2)
63 changes: 63 additions & 0 deletions .github/jobs/unit-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash

. .github/jobs/ci_settings.sh

DIR="$PWD"

export version=$1
unittest=$2
[ "$version" = "8.1" ] && CODECOVERAGE=1 || CODECOVERAGE=0

# Set up
export unit=1

# Add team to admin user
echo "UPDATE user SET teamid = 1 WHERE userid = 1;" | mysql domjudge_test

# Copy the .env.test file, as this is normally not done during
# installation and we need it.
cp webapp/.env.test /opt/domjudge/domserver/webapp/

# We also need the composer.json for PHPunit to detect the correct directory.
cp webapp/composer.json /opt/domjudge/domserver/webapp/

cd /opt/domjudge/domserver

# Run phpunit tests.
pcov=""
phpcov=""
if [ "$CODECOVERAGE" -eq 1 ]; then
phpcov="-dpcov.enabled=1 -dpcov.directory=webapp/src"
pcov="--coverage-html=${DIR}/coverage-html --coverage-clover coverage.xml"
fi
set +e
echo "unused:sqlserver:domjudge:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret
php $phpcov webapp/bin/phpunit -c webapp/phpunit.xml.dist webapp/tests/$unittest --log-junit ${ARTIFACTS}/unit-tests.xml --colors=never $pcov > "$ARTIFACTS"/phpunit.out
UNITSUCCESS=$?

# Store the unit tests also in the root for the GHA
cp $ARTIFACTS/unit-tests.xml $DIR/

# Make sure the log exists before copy
touch ${DIR}/webapp/var/log/test.log
cp ${DIR}/webapp/var/log/*.log "$ARTIFACTS"/

set -e
CNT=0
THRESHOLD=32
if [ $CODECOVERAGE -eq 1 ]; then
CNT=$(sed -n '/Generating code coverage report/,$p' "$ARTIFACTS"/phpunit.out | grep -v DoctrineTestBundle | grep -cv ^$)
fi

if [ $UNITSUCCESS -ne 0 ] || [ $CNT -gt $THRESHOLD ]; then
exit 1
fi

if [ $CODECOVERAGE -eq 1 ]; then
section_start "Upload code coverage"
# Only upload when we got working unit-tests.
set +u # Uses some variables which are not set
# shellcheck disable=SC1090
. $DIR/.github/jobs/uploadcodecov.sh &>> "$ARTIFACTS"/codecov.log
section_end
fi
2 changes: 1 addition & 1 deletion .github/jobs/webstandard.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ if [ "$TEST" = "w3cval" ]; then
NEWFOUNDERRORS=$("$DIR"/vnu-runtime-image/bin/vnu --errors-only --exit-zero-always --skip-non-$typ --format gnu $FLTR "$URL" 2>&1 | wc -l)
FOUNDERR=$((NEWFOUNDERRORS+FOUNDERR))
python3 -m "json.tool" < result.json > "$ARTIFACTS/w3c$typ$URL.json"
trace_off; python3 gitlab/jsontogitlab.py "$ARTIFACTS/w3c$typ$URL.json"; trace_on
trace_off; python3 .github/jobs/jsontogha.py "$ARTIFACTS/w3c$typ$URL.json"; trace_on
section_end
done
else
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/database-upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ jobs:
run: echo "pass" > /opt/domjudge/domserver/etc/initial_admin_password.secret
- name: Check for Errors in the Upgrade
run: mysql -hsqlserver -uroot -proot -e "SHOW TABLES FROM domjudge;"
- name: Check for Errors in Domjudge Web
- name: Check for Errors in DOMjudge Webinterface
run: .github/jobs/webstandard.sh none admin
65 changes: 64 additions & 1 deletion .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name: Unit tests
# We can speedup with: https://github.com/actions/cache
on:
merge_group:
pull_request:
Expand All @@ -8,11 +9,73 @@ on:

jobs:
check-static-codecov:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Download latest codecov upload script
run: wget https://codecov.io/bash -O newcodecov
- name: Detect changes to manually verify
run: diff newcodecov .github/jobs/uploadcodecov.sh

unit-tests:
runs-on: ubuntu-24.04
timeout-minutes: 20
container:
image: domjudge/gitlabci:24.04
services:
sqlserver:
image: mariadb
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: domjudge
MYSQL_PASSWORD: domjudge
options: --health-cmd="healthcheck.sh --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
PHPVERSION: [8.1, 8.4]
TEST: [Unit, E2E]
steps:
- uses: actions/checkout@v4
- name: info
run: |
cat /proc/cmdline && echo &&
cat /proc/mounts && echo &&
ls -al /sys/fs/cgroup && echo &&
uname -a && echo &&
stat -fc %T /sys/fs/cgroup && echo &&
cat /proc/self/cgroup && echo &&
cat /proc/cpuinfo
- name: pstree
run: pstree -p
- name: Install DOMjudge
run: .github/jobs/baseinstall.sh unit install ${{ matrix.PHPVERSION }} test
- name: Check nginx
run: curl -v https://localhost/domjudge/
- name: Run the unit-tests
run: .github/jobs/unit-tests.sh ${{ matrix.PHPVERSION }} ${{ matrix.TEST }}
- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: ${{ !cancelled() }}
with:
comment_mode: changes in failures
check_name: unit-tests-${{ matrix.PHPVERSION }}-${{ matrix.TEST }}.xml
files: unit-tests-${{ matrix.PHPVERSION }}-${{ matrix.TEST }}.xml
- name: Get SQL logs
run: docker logs "${{ job.services.sqlserver.id }}"
- name: Collect docker logs on failure
if: ${{ !cancelled() }}
uses: jwalton/gh-docker-logs@v1
with:
dest: '/tmp/docker-logs'
- name: Upload all logs/artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: Logs-${{ matrix.PHPVERSION }}-${{ matrix.TEST }}
path: |
/var/log/nginx
/opt/domjudge/domserver/webapp/var/log/*.log
/tmp/docker-logs
/tmp/artifacts
11 changes: 0 additions & 11 deletions .gitlab-ci.yml

This file was deleted.

Loading
Loading