From 3fa541ffd054dfb7d0506fc6283f8a996c2ae243 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Fri, 26 Jun 2026 17:52:49 +0930 Subject: [PATCH 1/4] Test: check the XML returned by occ commands in acceptance tests Before trying to parse the return XML of remote occ commands that are done in the acceptance test setup and teardown script, first check that the string is valid XML. If it is not valid XML, then echo the string to the console so that the problem can be seen. --- tests/acceptance/run.sh | 119 +++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 39 deletions(-) diff --git a/tests/acceptance/run.sh b/tests/acceptance/run.sh index 81f6d7401ed..bad6e4812a2 100755 --- a/tests/acceptance/run.sh +++ b/tests/acceptance/run.sh @@ -210,18 +210,30 @@ export LANG=C function remote_occ() { COMMAND=`echo $3 | xargs` CURL_OCC_RESULT=`curl -k -s -u $1 $2 -d "command=${COMMAND}"` - # xargs is (miss)used to trim the output - RETURN=`echo ${CURL_OCC_RESULT} | xmllint --xpath "string(ocs/data/code)" - | xargs` - # We could not find a proper return of the testing app, so something went wrong - if [ -z "${RETURN}" ] + if echo "${CURL_OCC_RESULT}" | xmllint --noout - > /dev/null 2>&1; then + # xargs is (miss)used to trim the output + RETURN=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "string(ocs/data/code)" - | xargs` + # We could not find a proper return of the testing app, so something went wrong + if [ -z "${RETURN}" ] + then + RETURN=1 + REMOTE_OCC_STDERR=${CURL_OCC_RESULT} + else + REMOTE_OCC_STDOUT=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "string(ocs/data/stdOut)" - | xargs` + REMOTE_OCC_STDERR=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "string(ocs/data/stdErr)" - | xargs` + fi + else + # The CURL_OCC_RESULT was not valid XML, so echo it to the running console. + # That will give the caller a chance to understand what is wrong. + echo "The result of the remote_occ cURL command '${COMMAND}' was not valid XML" + echo "--------" + echo $CURL_OCC_RESULT + echo "--------" RETURN=1 REMOTE_OCC_STDERR=${CURL_OCC_RESULT} - else - REMOTE_OCC_STDOUT=`echo ${CURL_OCC_RESULT} | xmllint --xpath "string(ocs/data/stdOut)" - | xargs` - REMOTE_OCC_STDERR=`echo ${CURL_OCC_RESULT} | xmllint --xpath "string(ocs/data/stdErr)" - | xargs` fi - return ${RETURN} + return "${RETURN}" } # @param $1 admin authentication string username:password @@ -230,21 +242,33 @@ function remote_occ() { # exists with 1 and sets $REMOTE_OCC_STDERR if any of the occ commands returned a non-zero code function remote_bulk_occ() { CURL_OCC_RESULT=`curl -k -s -u $1 $2/bulk -d "${3}"` - COUNT_RESULTS=`echo ${CURL_OCC_RESULT} | xmllint --xpath "ocs/data/element/code" - | wc -l` + if echo "${CURL_OCC_RESULT}" | xmllint --noout - > /dev/null 2>&1; + then + COUNT_RESULTS=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "ocs/data/element/code" - | wc -l` - RETURN=0 - REMOTE_OCC_STDERR="" - for ((n=1;n<=${COUNT_RESULTS};n++)) - do - EXIT_CODE=`echo ${CURL_OCC_RESULT} | xmllint --xpath "string((ocs/data/element/code)[${n}])" -` - if [ ${EXIT_CODE} -ne 0 ] - then - REMOTE_OCC_STDERR+=`echo ${CURL_OCC_RESULT} | xmllint --xpath "string((ocs/data/element/stdErr)[${n}])" - | xargs` - REMOTE_OCC_STDERR+="\n" - RETURN=1 - fi + RETURN=0 + REMOTE_OCC_STDERR="" + for ((n=1;n<=${COUNT_RESULTS};n++)) + do + EXIT_CODE=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "string((ocs/data/element/code)[${n}])" -` + if [ ${EXIT_CODE} -ne 0 ] + then + REMOTE_OCC_STDERR+=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "string((ocs/data/element/stdErr)[${n}])" - | xargs` + REMOTE_OCC_STDERR+="\n" + RETURN=1 + fi - done + done + else + # The CURL_OCC_RESULT was not valid XML, so echo it to the running console. + # That will give the caller a chance to understand what is wrong. + echo "The result of the remote_bulk_occ cURL command '${3}' was not valid XML" + echo "--------" + echo "${CURL_OCC_RESULT}" + echo "--------" + RETURN=1 + REMOTE_OCC_STDERR=${CURL_OCC_RESULT} + fi return ${RETURN} } @@ -256,21 +280,33 @@ function remote_bulk_occ() { function remote_dir() { COMMAND=`echo $3 | xargs` CURL_OCC_RESULT=`curl -k -s -u $1 $2 -d "dir=${COMMAND}"` - # xargs is (miss)used to trim the output - HTTP_STATUS=`echo ${CURL_OCC_RESULT} | xmllint --xpath "string(ocs/meta/statuscode)" - | xargs` - # We could not find a proper return of the testing app, so something went wrong - if [ -z "${HTTP_STATUS}" ] + if echo "${CURL_OCC_RESULT}" | xmllint --noout - > /dev/null 2>&1; then - RETURN=1 - REMOTE_OCC_STDERR=${CURL_OCC_RESULT} - else - if [ "${HTTP_STATUS}" = 200 ] + # xargs is (miss)used to trim the output + HTTP_STATUS=`echo "${CURL_OCC_RESULT}" | xmllint --xpath "string(ocs/meta/statuscode)" - | xargs` + # We could not find a proper return of the testing app, so something went wrong + if [ -z "${HTTP_STATUS}" ] then - RETURN=0 - else RETURN=1 REMOTE_OCC_STDERR=${CURL_OCC_RESULT} + else + if [ "${HTTP_STATUS}" = 200 ] + then + RETURN=0 + else + RETURN=1 + REMOTE_OCC_STDERR=${CURL_OCC_RESULT} + fi fi + else + # The CURL_OCC_RESULT was not valid XML, so echo it to the running console. + # That will give the caller a chance to understand what is wrong. + echo "The result of the remote_dir cURL command '${COMMAND}' was not valid XML" + echo "--------" + echo "${CURL_OCC_RESULT}" + echo "--------" + RETURN=1 + REMOTE_OCC_STDERR=${CURL_OCC_RESULT} fi return ${RETURN} } @@ -835,15 +871,20 @@ else php -S localhost:${PORT} -t "${OC_PATH}" & PHPPID=$! echo ${PHPPID} - - PORT_FED=$((8180 + ${EXECUTOR_NUMBER})) - echo ${PORT_FED} - php -S localhost:${PORT_FED} -t ../.. & - PHPPID_FED=$! - echo ${PHPPID_FED} - export TEST_SERVER_URL="http://localhost:${PORT}" - export TEST_SERVER_FED_URL="http://localhost:${PORT_FED}" + + if [ "${TEST_WITH_FED_PHPDEVSERVER}" == "true" ] + then + # This runs a 2nd server, but serving the code from the same location + # as the 1st server at TEST_SERVER_URL. It cannot operate reliably, because + # it will share the filesystem, database etc. + PORT_FED=$((8180 + ${EXECUTOR_NUMBER})) + echo ${PORT_FED} + php -S localhost:${PORT_FED} -t ../.. & + PHPPID_FED=$! + echo ${PHPPID_FED} + export TEST_SERVER_FED_URL="http://localhost:${PORT_FED}" + fi # The endpoint to use to do occ commands via the testing app TESTING_APP_URL="${TEST_SERVER_URL}/ocs/v2.php/apps/testing/api/v1/" From a7358d957de072f8617fca5e99e3decf4c9d7d86 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Fri, 26 Jun 2026 19:10:08 +0930 Subject: [PATCH 2/4] test: enhance error output --- tests/acceptance/run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/run.sh b/tests/acceptance/run.sh index bad6e4812a2..7f97c673fc5 100755 --- a/tests/acceptance/run.sh +++ b/tests/acceptance/run.sh @@ -226,7 +226,7 @@ function remote_occ() { else # The CURL_OCC_RESULT was not valid XML, so echo it to the running console. # That will give the caller a chance to understand what is wrong. - echo "The result of the remote_occ cURL command '${COMMAND}' was not valid XML" + echo "The result of the remote_occ cURL command '${COMMAND}' to '${2}' with auth '${1}' was not valid XML" echo "--------" echo $CURL_OCC_RESULT echo "--------" @@ -262,7 +262,7 @@ function remote_bulk_occ() { else # The CURL_OCC_RESULT was not valid XML, so echo it to the running console. # That will give the caller a chance to understand what is wrong. - echo "The result of the remote_bulk_occ cURL command '${3}' was not valid XML" + echo "The result of the remote_bulk_occ cURL commands '${3}' to '${2}/bulk' with auth '${1}' was not valid XML" echo "--------" echo "${CURL_OCC_RESULT}" echo "--------" @@ -301,7 +301,7 @@ function remote_dir() { else # The CURL_OCC_RESULT was not valid XML, so echo it to the running console. # That will give the caller a chance to understand what is wrong. - echo "The result of the remote_dir cURL command '${COMMAND}' was not valid XML" + echo "The result of the remote_dir cURL command 'dir=${COMMAND}' to '${2}' with auth '${1}' was not valid XML" echo "--------" echo "${CURL_OCC_RESULT}" echo "--------" From 78968f4474f941cebf60d7dea95bfa6ad9e999e1 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Fri, 26 Jun 2026 19:13:24 +0930 Subject: [PATCH 3/4] test: reduce workflow pipelines for debugging --- .github/workflows/ci.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 854d2b73149..79f9f7f51cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: acceptance-api-smoke: if: ${{ !contains(github.event.pull_request.title, 'full-ci') }} name: API Smoke Tests - needs: [semantic-git-messages, php-unit, calens] + needs: [semantic-git-messages] uses: ./.github/workflows/acceptance.yml with: do-api-tests: true @@ -54,12 +54,7 @@ jobs: additional-app: 'notifications' additional-packages: 'imagemagick' filter-tags: '@smokeTest' - test-suites: "[ - 'apiAuth,apiAuthOcs,apiAuthWebDav,apiCapabilities,apiComments,apiFavorites,apiFederationToRoot1,apiFederationToRoot2,apiFederationToShares1,apiFederationToShares2,apiMain', - 'apiProvisioning-v1,apiProvisioning-v2,apiProvisioningGroups-v1,apiProvisioningGroups-v2,apiShareCreateSpecialToRoot1,apiShareCreateSpecialToRoot2,apiShareCreateSpecialToShares1,apiShareCreateSpecialToShares2,apiSharees,apiShareManagementBasicToRoot,apiShareManagementBasicToShares', - 'apiShareManagementToRoot,apiShareManagementToShares,apiShareOperationsToRoot1,apiShareOperationsToRoot2,apiShareOperationsToShares1,apiShareOperationsToShares2,apiSharePublicLink1,apiSharePublicLink2,apiSharePublicLink3,apiShareReshareToRoot1,apiShareReshareToRoot2,apiShareReshareToRoot3', - 'apiShareReshareToShares1,apiShareReshareToShares2,apiShareReshareToShares3,apiShareUpdateToRoot,apiShareUpdateToShares,apiSharingNotificationsToRoot,apiSharingNotificationsToShares,apiTags,apiTranslation,apiTrashbin,apiTrashbinRestore,apiVersions,apiWebdavDelete,apiWebdavEtagPropagation1,apiWebdavEtagPropagation2,apiWebdavLocks', - 'apiWebdavLocks2,apiWebdavLocks3,apiWebdavLocksUnlock,apiWebdavMove1,apiWebdavMove2,apiWebdavOperations,apiWebdavPreviews,apiWebdavProperties1,apiWebdavProperties2,apiWebdavUpload1,apiWebdavUpload2,apiWebdavUploadTUS']" + test-suites: "['apiComments,apiFavorites,apiFederationToRoot1,apiFederationToRoot2,apiMain']" acceptance-api: if: contains(github.event.pull_request.title, 'full-ci') From ebc696f56544f9cc64a7fbe5e0bdee8caff74503 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Fri, 26 Jun 2026 19:51:05 +0930 Subject: [PATCH 4/4] test: do not quote the space-separated string --- tests/acceptance/run.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/run.sh b/tests/acceptance/run.sh index 7f97c673fc5..cb314855e5b 100755 --- a/tests/acceptance/run.sh +++ b/tests/acceptance/run.sh @@ -742,14 +742,14 @@ function teardown() { # Enable any apps that were disabled for the test run for i in "${!APPS_TO_REENABLE[@]}" do - read -r -a APP <<< "${APPS_TO_REENABLE[$i]}" + read -r -a APP <<< ${APPS_TO_REENABLE[$i]} remote_occ ${ADMIN_AUTH} ${APP[0]} "--no-warnings app:enable ${APP[1]}" done # Disable any apps that were enabled for the test run for i in "${!APPS_TO_REDISABLE[@]}" do - read -r -a APP <<< "${APPS_TO_REDISABLE[$i]}" + read -r -a APP <<< ${APPS_TO_REDISABLE[$i]} remote_occ ${ADMIN_AUTH} ${APP[0]} "--no-warnings app:disable ${APP[1]}" done