diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d6b6a5e..e597d11c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -227,6 +227,7 @@ jobs: FOREVER_PAUSE: 100 ITERATION_COUNT: 2 TOMCAT_CYCLE_COUNT: 2 + CODE_COVERAGE: 1 steps: - name: Checkout uses: actions/checkout@v4 @@ -253,9 +254,16 @@ jobs: if: always() with: name: Test logs - path: | - test/logs/* + path: test/logs/* retention-days: 7 + # Preserve coverage data if defined + - name: Preserve coverage files + if: env.CODE_COVERAGE + uses: actions/upload-artifact@v4 + with: + name: Coverage + path: test/coverage/* + retention-days: 7 perl-tests: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 3092828b..c7665aa2 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,12 @@ test/httpd/mod_proxy_cluster # Log files **/*.log +# Coverage files +test/coverage/ +*.gcno +*.gcda +*.gcov + # build files *.slo *.so diff --git a/test/httpd/Containerfile b/test/httpd/Containerfile index 17ff736b..dfa89a44 100644 --- a/test/httpd/Containerfile +++ b/test/httpd/Containerfile @@ -1,11 +1,18 @@ FROM fedora:41 ARG HTTPD_SOURCES="https://dlcdn.apache.org/httpd/httpd-2.4.63.tar.gz" +ARG CFLAGS="" +ARG LDFLAGS="" +ARG HTTPD_DEFAULT_FLAGS="--enable-proxy --enable-proxy-http --enable-proxy-ajp --enable-proxy-wstunnel --enable-proxy-hcheck --with-port=8000" +ARG HTTPD_EXTRA_FLAGS="" -RUN yum install gcc wget apr-devel apr-util-devel openssl-devel pcre-devel redhat-rpm-config wcstools git autoconf -y +RUN yum install gcc wget apr-devel apr-util-devel openssl-devel pcre-devel redhat-rpm-config wcstools git autoconf gcovr lcov -y ENV CONF=httpd/mod_proxy_cluster.conf ENV HTTPD=${HTTPD_SOURCES} +ENV CFLAGS="${CFLAGS}" +ENV LDFLAGS="${LDFLAGS}" +ENV HTTPD_FLAGS="${HTTPD_DEFAULT_FLAGS} ${HTTPD_EXTRA_FLAGS}" # make sure you have copy of the local repository at place # (our function "httpd_create" takes care of that) @@ -17,12 +24,7 @@ RUN mkdir httpd RUN tar xvf $(filename $HTTPD) --strip 1 -C httpd RUN ls WORKDIR /httpd -RUN ./configure --enable-proxy \ - --enable-proxy-http \ - --enable-proxy-ajp \ - --enable-proxy-wstunnel \ - --enable-proxy-hcheck \ - --with-port=8000 +RUN ./configure ${HTTPD_FLAGS} RUN make RUN make install @@ -37,7 +39,7 @@ RUN for m in advertise mod_proxy_cluster balancers mod_manager; \ ./configure --with-apxs=/usr/local/apache2/bin/apxs; \ make clean; \ make || exit 1; \ - cp *.so /usr/local/apache2/modules; \ + for f in *.so; do ln -s "$PWD/$f" /usr/local/apache2/modules/$f; done; \ cd $OLDPWD; \ done; diff --git a/test/httpd/run.sh b/test/httpd/run.sh index 0579e764..117dc7ef 100755 --- a/test/httpd/run.sh +++ b/test/httpd/run.sh @@ -1,8 +1,5 @@ #!/bin/sh -pwd -ls -lt - # wget and copy the prepared conf file and include it cd /test/ if [ -f $CONF ]; then @@ -14,6 +11,8 @@ else exit 1 fi +mkdir /coverage + # start apache httpd server in foreground echo "Starting httpd..." /usr/local/apache2/bin/apachectl start diff --git a/test/includes/common.sh b/test/includes/common.sh index 91940553..7c63243b 100644 --- a/test/includes/common.sh +++ b/test/includes/common.sh @@ -4,6 +4,12 @@ IMG=${IMG:-mod_proxy_cluster-testsuite-tomcat} HTTPD_IMG=${HTTPD_IMG:-mod_proxy_cluster-testsuite-httpd} MPC_NAME=${MPC_NAME:-httpd-mod_proxy_cluster} +if [ $CODE_COVERAGE ]; then + MPC_CFLAGS="$MPC_CFLAGS --coverage -fprofile-arcs -ftest-coverage -fPIC -g -O0" + MPC_LDFLAGS="$MPC_LDFLAGS -lgcov" + HTTPD_EXTRA_FLAGS="$HTTPD_EXTRA_FLAGS --enable-debugger-mode" +fi + # Runs a test file ($1) under given name ($2, if given) run_test() { local ret=0 @@ -23,12 +29,27 @@ run_test() { echo " NOK" ret=1 fi + + local httpd_cont=$(docker ps -a | grep $HTTPD_IMG | cut -f 1 -d' ') # preserve httpd's logs too if DEBUG if [ $DEBUG ]; then - local httpd_cont=$(docker ps -a | grep $HTTPD_IMG | cut -f 1 -d' ') - docker logs $httpd_cont > "logs/${2:-$1}-httpd.log" 2>&1 + docker logs ${httpd_cont} > "logs/${2:-$1}-httpd.log" 2>&1 docker cp ${httpd_cont}:/usr/local/apache2/logs/access_log "logs/${2:-$1}-httpd_access.log" 2> /dev/null || true fi + + if [ $CODE_COVERAGE ]; then + docker exec ${httpd_cont} /usr/local/apache2/bin/apachectl stop + # preserve the coverage files + # docker has problems with names containing spaces + f=$(echo ${2:-1} | sed 's/ /-/g') + docker exec ${httpd_cont} sh -c "cd /native; gcovr --gcov-ignore-errors=no_working_dir_found --json /coverage/coverage-$f.json > /coverage/coverage-$f.log 2>&1" + docker exec ${httpd_cont} sh -c "cd /native; lcov --capture --directory . --output-file /coverage/coverage-$f.info > /coverage/coverage-lcov-$f.log 2>&1" + + for f in $(docker exec ${httpd_cont} ls /coverage/); do + docker cp ${httpd_cont}:/coverage/$f $PWD/coverage/$f > /dev/null + done + fi + # Clean all after run httpd_remove > /dev/null 2>&1 tomcat_all_remove > /dev/null 2>&1 @@ -54,7 +75,11 @@ httpd_create() { done cp -r ../native ../test /tmp/mod_proxy_cluster/ mv /tmp/mod_proxy_cluster httpd/ - docker build -t $HTTPD_IMG -f httpd/Containerfile httpd/ + + docker build -t $HTTPD_IMG --build-arg CFLAGS="$MPC_CFLAGS" \ + --build-arg LDFLAGS="$MPC_LDFLAGS" \ + --build-arg HTTPD_EXTRA_FLAGS="$HTTPD_EXTRA_FLAGS" \ + -f httpd/Containerfile httpd/ } # Build and run httpd container diff --git a/test/testsuite.sh b/test/testsuite.sh index de307743..195667fb 100644 --- a/test/testsuite.sh +++ b/test/testsuite.sh @@ -34,6 +34,15 @@ fi if [ ! -d logs ]; then mkdir logs + rm logs/* +fi + +if [ $CODE_COVERAGE ]; then + if [ ! -d coverage ]; then + mkdir coverage + fi + + rm coverage/* fi . includes/common.sh @@ -45,11 +54,11 @@ fi echo -n "Creating docker containers..." if [ ! -z ${DEBUG+x} ]; then - httpd_create || exit 2 - tomcat_create || exit 3 + httpd_create || exit 2 + tomcat_create || exit 3 else - httpd_create > /dev/null 2>&1 || exit 2 - tomcat_create > /dev/null 2>&1 || exit 3 + httpd_create > /dev/null 2>&1 || exit 2 + tomcat_create > /dev/null 2>&1 || exit 3 fi echo " Done" @@ -114,4 +123,22 @@ else res=1 fi +# if we're interessed in code coverage, run an httpd container with the already obtained +# coverage files and generate the report from within the container with all the sources +if [ $CODE_COVERAGE ]; then + echo "Generating test coverage..." + httpd_start > /dev/null 2>&1 + docker exec $MPC_NAME /usr/local/apache2/bin/apachectl stop + + for f in $(ls coverage/*.json coverage/*.info); do + docker cp $f $MPC_NAME:/coverage/ > /dev/null + done + + docker exec $MPC_NAME sh -c 'cd /native; gcovr --add-tracefile "/coverage/coverage-*.json" --html-details /coverage/test-coverage.html > /coverage/test-coverage.log 2>&1' + docker exec $MPC_NAME sh -c 'cd /coverage; mkdir lcov; genhtml *.info --output-directory lcov > /coverage/lcov/test-coverage-lcov.log 2>&1' + docker cp $MPC_NAME:/coverage/ . > /dev/null + + httpd_remove +fi + exit $res