Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
@@ -0,0 +1,122 @@
#!/usr/bin/env bash
log_error() {
if [ -n "${PLAIN_OUTPUT}" ]
then
echo -e "$1"
else
echo -e "\e[31m$1\e[0m"
fi
}
log_info() {
if [ -n "${PLAIN_OUTPUT}" ]
then
echo -e "$1"
else
echo -e "\e[34m$1\e[0m"
fi
}
log_success() {
if [ -n "${PLAIN_OUTPUT}" ]
then
echo -e "$1"
else
echo -e "\e[32m$1\e[0m"
fi
}
declare -A scenarioLines
if [ -n "${EXPECTED_FAILURES_FILE}" ]
then
if [ -f "${EXPECTED_FAILURES_FILE}" ]
then
log_info "Checking expected failures in ${EXPECTED_FAILURES_FILE}"
else
log_error "Expected failures file ${EXPECTED_FAILURES_FILE} not found"
log_error "Check the setting of EXPECTED_FAILURES_FILE environment variable"
exit 1
fi
FINAL_EXIT_STATUS=0
# If the last line of the expected-failures file ends without a newline character
# then that line may not get processed by some of the bash code in this script
# So check that the last character in the file is a newline
if [ "$(tail -c1 "${EXPECTED_FAILURES_FILE}" | wc -l)" -eq 0 ]
then
log_error "Expected failures file ${EXPECTED_FAILURES_FILE} must end with a newline"
log_error "Put a newline at the end of the last line and try again"
FINAL_EXIT_STATUS=1
fi
# Check the expected-failures file to ensure that the lines are self-consistent
LINE_NUMBER=0
while read -r INPUT_LINE
do
LINE_NUMBER=$(("$LINE_NUMBER" + 1))
# Ignore comment lines (starting with hash)
if [[ "${INPUT_LINE}" =~ ^# ]]
then
continue
fi
# Match lines that have "- [someSuite/someName.feature:n]" pattern on start
# the part inside the brackets is the suite, feature and line number of the expected failure.
if [[ "${INPUT_LINE}" =~ ^-[[:space:]]\[([a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+\.feature:[0-9]+)] ]]; then
SUITE_SCENARIO_LINE="${BASH_REMATCH[1]}"
elif [[
# report for lines like: " - someSuite/someName.feature:n"
"${INPUT_LINE}" =~ ^[[:space:]]*-[[:space:]][a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+\.feature:[0-9]+[[:space:]]*$ ||
# report for lines starting with: "[someSuite/someName.feature:n]"
"${INPUT_LINE}" =~ ^[[:space:]]*\[([a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+\.feature:[0-9]+)]
]]; then
log_error "> Line ${LINE_NUMBER}: Not in the correct format."
log_error " + Actual Line : '${INPUT_LINE}'"
log_error " - Expected Format : '- [suite/scenario.feature:line_number](scenario_line_url)'"
FINAL_EXIT_STATUS=1
continue
else
# otherwise, ignore the line
continue
fi
# Find the link in round-brackets that should be after the SUITE_SCENARIO_LINE
if [[ "${INPUT_LINE}" =~ \(([a-zA-Z0-9:/.#_-]+)\) ]]; then
ACTUAL_LINK="${BASH_REMATCH[1]}"
else
log_error "Line ${LINE_NUMBER}: ${INPUT_LINE} : Link is empty"
FINAL_EXIT_STATUS=1
continue
fi
if [[ -n "${scenarioLines[${SUITE_SCENARIO_LINE}]:-}" ]];
then
log_error "> Line ${LINE_NUMBER}: Scenario line ${SUITE_SCENARIO_LINE} is duplicated"
FINAL_EXIT_STATUS=1
fi
scenarioLines[${SUITE_SCENARIO_LINE}]="exists"
OLD_IFS=${IFS}
IFS=':'
read -ra FEATURE_PARTS <<< "${SUITE_SCENARIO_LINE}"
IFS=${OLD_IFS}
SUITE_FEATURE="${FEATURE_PARTS[0]}"
FEATURE_LINE="${FEATURE_PARTS[1]}"
EXPECTED_LINK="https://github.com/qsfera/server/blob/main/tests/acceptance/features/${SUITE_FEATURE}#L${FEATURE_LINE}"
if [[ "${ACTUAL_LINK}" != "${EXPECTED_LINK}" ]]; then
log_error "> Line ${LINE_NUMBER}: Link is not correct for ${SUITE_SCENARIO_LINE}"
log_error " + Actual link : ${ACTUAL_LINK}"
log_error " - Expected link : ${EXPECTED_LINK}"
FINAL_EXIT_STATUS=1
fi
done < "${EXPECTED_FAILURES_FILE}"
else
log_error "Environment variable EXPECTED_FAILURES_FILE must be defined to be the file to check"
exit 1
fi
if [ ${FINAL_EXIT_STATUS} == 1 ]
then
log_error "\nErrors were found in the expected failures file - see the messages above!"
else
log_success "\nNo problems were found in the expected failures file."
fi
exit ${FINAL_EXIT_STATUS}
+707
View File
@@ -0,0 +1,707 @@
#!/usr/bin/env bash
# Terminal colors
if [ -n "${PLAIN_OUTPUT}" ]; then
# No colors
TC_GREEN=""
TC_RED=""
TC_CYAN=""
TC_RESET=""
else
# Colors
TC_GREEN="\033[32m"
TC_RED="\033[31m"
TC_CYAN="\033[36m"
TC_RESET="\033[0m"
fi
function log_failed(){
printf "${TC_RED}[FAILED] %s\n${TC_RESET}" "$1"
}
function log_info(){
printf "${TC_CYAN}[INFO] %s\n${TC_RESET}" "$1"
}
function log_error(){
printf "${TC_RED}[ERROR] %s\n${TC_RESET}" "$1"
}
[[ "${DEBUG}" == "true" ]] && set -x
# from http://stackoverflow.com/a/630387
SCRIPT_PATH="`dirname \"$0\"`" # relative
SCRIPT_PATH="`( cd \"${SCRIPT_PATH}\" && pwd )`" # absolutized and normalized
echo 'Script path: '${SCRIPT_PATH}
# Allow optionally passing in the path to the behat program.
# This gives flexibility for callers that have installed their own behat
if [ -z "${BEHAT_BIN}" ]
then
BEHAT=${SCRIPT_PATH}/../../../vendor-bin/behat/vendor/bin/behat
else
BEHAT=${BEHAT_BIN}
fi
BEHAT_TAGS_OPTION_FOUND=false
if [ -n "${STEP_THROUGH}" ]
then
STEP_THROUGH_OPTION="--step-through"
fi
if [ -n "${STOP_ON_FAILURE}" ]
then
STOP_OPTION="--stop-on-failure"
fi
if [ -n "${PLAIN_OUTPUT}" ]
then
# explicitly tell Behat to not do colored output
COLORS_OPTION="--no-colors"
else
COLORS_OPTION="--colors"
fi
# The following environment variables can be specified:
#
# ACCEPTANCE_TEST_TYPE - see "--type" description
# BEHAT_FEATURE - see "--feature" description
# BEHAT_FILTER_TAGS - see "--tags" description
# BEHAT_SUITE - see "--suite" description
# BEHAT_YML - see "--config" description
# RUN_PART and DIVIDE_INTO_NUM_PARTS - see "--part" description
# SHOW_OC_LOGS - see "--show-oc-logs" description
# TESTING_REMOTE_SYSTEM - see "--remote" description
# EXPECTED_FAILURES_FILE - a file that contains a list of the scenarios that are expected to fail
if [ -n "${EXPECTED_FAILURES_FILE}" ]
then
# Check the expected-failures file
${SCRIPT_PATH}/lint-expected-failures.sh
LINT_STATUS=$?
if [ ${LINT_STATUS} -ne 0 ]
then
log_error "Expected failures file ${EXPECTED_FAILURES_FILE} is invalid"
exit ${LINT_STATUS}
fi
fi
# Default to API tests
# Note: if a specific feature or suite is also specified, then the acceptance
# test type is deduced from the suite name, and this environment variable
# ACCEPTANCE_TEST_TYPE is overridden.
if [ -z "${ACCEPTANCE_TEST_TYPE}" ]
then
ACCEPTANCE_TEST_TYPE="api"
fi
# Look for command line options for:
# -c or --config - specify a behat.yml to use
# --feature - specify a single feature to run
# --suite - specify a single suite to run
# --type - api or core-api - if no individual feature or suite is specified, then
# specify the type of acceptance tests to run. Default api.
# --tags - specify tags for scenarios to run (or not)
# --remote - the server under test is remote, so we cannot locally enable the
# testing app. We have to assume it is already enabled.
# --show-oc-logs - tail the КуСфера log after the test run
# --loop - loop tests for given number of times. Only use it for debugging purposes
# --part - run a subset of scenarios, need two numbers.
# first number: which part to run
# second number: in how many parts to divide the set of scenarios
# --step-through - pause after each test step
# Command line options processed here will override environment variables that
# might have been set by the caller, or in the code above.
while [[ $# -gt 0 ]]
do
key="$1"
case ${key} in
-c|--config)
BEHAT_YML="$2"
shift
;;
--feature)
BEHAT_FEATURE="$2"
shift
;;
--suite)
BEHAT_SUITE="$2"
shift
;;
--loop)
BEHAT_RERUN_TIMES="$2"
shift
;;
--type)
# Lowercase the parameter value, so the user can provide "API", "CORE-API", etc
ACCEPTANCE_TEST_TYPE="${2,,}"
shift
;;
--tags)
BEHAT_FILTER_TAGS="$2"
BEHAT_TAGS_OPTION_FOUND=true
shift
;;
--part)
RUN_PART="$2"
DIVIDE_INTO_NUM_PARTS="$3"
if [ ${RUN_PART} -gt ${DIVIDE_INTO_NUM_PARTS} ]
then
echo "cannot run part ${RUN_PART} of ${DIVIDE_INTO_NUM_PARTS}"
exit 1
fi
shift 2
;;
--step-through)
STEP_THROUGH_OPTION="--step-through"
;;
*)
# A "random" parameter is presumed to be a feature file to run.
# Typically that will be specified at the end, or as the only
# parameter.
BEHAT_FEATURE="$1"
;;
esac
shift
done
# Set the language to "C"
# We want to have it all in english to be able to parse outputs
export LANG=C
# Provide a default admin username and password.
# But let the caller pass them if they wish
if [ -z "${ADMIN_USERNAME}" ]
then
ADMIN_USERNAME="admin"
fi
if [ -z "${ADMIN_PASSWORD}" ]
then
ADMIN_PASSWORD="admin"
fi
export ADMIN_USERNAME
export ADMIN_PASSWORD
if [ -z "${BEHAT_RERUN_TIMES}" ]
then
BEHAT_RERUN_TIMES=1
fi
# expected variables
# --------------------
# $SUITE_FEATURE_TEXT - human readable which test to run
# $BEHAT_SUITE_OPTION - suite setting with "--suite" or empty if all suites have to be run
# $BEHAT_FEATURE - feature file, or empty
# $BEHAT_FILTER_TAGS - list of tags
# $BEHAT_TAGS_OPTION_FOUND
# $TEST_LOG_FILE
# $BEHAT - behat executable
# $BEHAT_YML
#
# set arrays
# ---------------
# $UNEXPECTED_FAILED_SCENARIOS array of scenarios that failed unexpectedly
# $UNEXPECTED_PASSED_SCENARIOS array of scenarios that passed unexpectedly (while running with expected-failures.txt)
# $STOP_ON_FAILURE - aborts the test run after the first failure
declare -a UNEXPECTED_FAILED_SCENARIOS
declare -a UNEXPECTED_PASSED_SCENARIOS
declare -a UNEXPECTED_BEHAT_EXIT_STATUSES
function run_behat_tests() {
echo "Running ${SUITE_FEATURE_TEXT} tests tagged ${BEHAT_FILTER_TAGS}" | tee ${TEST_LOG_FILE}
if [ "${REPLACE_USERNAMES}" == "true" ]
then
echo "Usernames and attributes in tests are being replaced:"
cat ${SCRIPT_PATH}/usernames.json
fi
echo "Using behat config '${BEHAT_YML}'"
${BEHAT} ${COLORS_OPTION} ${STOP_OPTION} --strict ${STEP_THROUGH_OPTION} -c ${BEHAT_YML} -f pretty ${BEHAT_SUITE_OPTION} --tags ${BEHAT_FILTER_TAGS} ${BEHAT_FEATURE} -v 2>&1 | tee -a ${TEST_LOG_FILE}
BEHAT_EXIT_STATUS=${PIPESTATUS[0]}
# remove nullbytes from the test log
sed -i 's/\x0//g' ${TEST_LOG_FILE}
# Find the count of scenarios that passed
SCENARIO_RESULTS_COLORED=`grep -Ea '^[0-9]+[[:space:]]scenario(|s)[[:space:]]\(' ${TEST_LOG_FILE}`
SCENARIO_RESULTS=$(echo "${SCENARIO_RESULTS_COLORED}" | sed "s/\x1b[^m]*m//g")
if [ ${BEHAT_EXIT_STATUS} -eq 0 ]
then
# They (SCENARIO_RESULTS) all passed, so just get the first number.
# The text looks like "1 scenario (1 passed)" or "123 scenarios (123 passed)"
[[ ${SCENARIO_RESULTS} =~ ([0-9]+) ]]
SCENARIOS_THAT_PASSED=$((SCENARIOS_THAT_PASSED + BASH_REMATCH[1]))
else
# "Something went wrong" with the Behat run (non-zero exit status).
# If there were "ordinary" test fails, then we process that later. Maybe they are all "expected failures".
# But if there were steps in a feature file that are undefined, we want to fail immediately.
# So exit the tests and do not lint expected failures when undefined steps exist.
if [[ ${SCENARIO_RESULTS} == *"undefined"* ]]
then
log_error "Undefined steps: There were some undefined steps found."
exit 1
fi
# If there were no scenarios in the requested suite or feature that match
# the requested combination of tags, then Behat exits with an error status
# and reports "No scenarios" in its output.
# This can happen, for example, when running core suites from an app and
# requesting some tag combination that does not happen frequently. Then
# sometimes there may not be any matching scenarios in one of the suites.
# In this case, consider the test has passed.
MATCHING_COUNT=`grep -ca '^No scenarios$' ${TEST_LOG_FILE}`
if [ ${MATCHING_COUNT} -eq 1 ]
then
log_info "No matching scenarios were found."
BEHAT_EXIT_STATUS=0
else
# Find the count of scenarios that passed and failed
SCENARIO_RESULTS_COLORED=`grep -Ea '^[0-9]+[[:space:]]scenario(|s)[[:space:]]\(' ${TEST_LOG_FILE}`
SCENARIO_RESULTS=$(echo "${SCENARIO_RESULTS_COLORED}" | sed "s/\x1b[^m]*m//g")
if [[ ${SCENARIO_RESULTS} =~ [0-9]+[^0-9]+([0-9]+)[^0-9]+([0-9]+)[^0-9]+ ]]
then
# Some passed and some failed, we got the second and third numbers.
# The text looked like "15 scenarios (6 passed, 9 failed)"
SCENARIOS_THAT_PASSED=$((SCENARIOS_THAT_PASSED + BASH_REMATCH[1]))
SCENARIOS_THAT_FAILED=$((SCENARIOS_THAT_FAILED + BASH_REMATCH[2]))
elif [[ ${SCENARIO_RESULTS} =~ [0-9]+[^0-9]+([0-9]+)[^0-9]+ ]]
then
# All failed, we got the second number.
# The text looked like "4 scenarios (4 failed)"
SCENARIOS_THAT_FAILED=$((SCENARIOS_THAT_FAILED + BASH_REMATCH[1]))
fi
fi
fi
FAILED_SCENARIO_PATHS_COLORED=`awk '/Failed (scenarios|hooks):/',0 ${TEST_LOG_FILE} | grep -a feature`
# There will be some ANSI escape codes for color in the FEATURE_COLORED var.
# Strip them out so we can pass just the ordinary feature details to Behat.
# Also strip everything after ".feature:XX", including text such as "(on line xx)" added by Behat indicating the failing step's line number.
# Thanks to https://en.wikipedia.org/wiki/Tee_(command) and
# https://stackoverflow.com/questions/23416278/how-to-strip-ansi-escape-sequences-from-a-variable
# for ideas.
FAILED_SCENARIO_PATHS=$(echo "${FAILED_SCENARIO_PATHS_COLORED}" | sed "s/\x1b[^m]*m//g" | sed "s/AfterScenario \"//g" | sed 's/\(\.feature:[0-9]\+\).*/\1/')
# remove duplicate scenario paths
FAILED_SCENARIO_PATHS=$(echo "$FAILED_SCENARIO_PATHS" | awk '!seen[$0]++')
# If something else went wrong, and there were no failed scenarios,
# then the awk, grep, sed command sequence above ends up with an empty string.
# Unset FAILED_SCENARIO_PATHS to avoid later code thinking that there might be
# one failed scenario.
if [ -z "${FAILED_SCENARIO_PATHS}" ]
then
unset FAILED_SCENARIO_PATHS
fi
if [ -n "${EXPECTED_FAILURES_FILE}" ]
then
if [ -n "${BEHAT_SUITE_TO_RUN}" ]
then
log_info "Checking expected failures for suite: ${BEHAT_SUITE_TO_RUN}"
else
log_info "Checking expected failures..."
fi
# Check that every failed scenario is in the list of expected failures
for FAILED_SCENARIO_PATH in ${FAILED_SCENARIO_PATHS}
do
SUITE_PATH=`dirname ${FAILED_SCENARIO_PATH}`
SUITE=`basename ${SUITE_PATH}`
SCENARIO=`basename ${FAILED_SCENARIO_PATH}`
SUITE_SCENARIO="${SUITE}/${SCENARIO}"
grep "\[${SUITE_SCENARIO}\]" "${EXPECTED_FAILURES_FILE}" > /dev/null
if [ $? -ne 0 ]
then
log_error "Scenario ${SUITE_SCENARIO} failed but was not expected to fail."
UNEXPECTED_FAILED_SCENARIOS+=("${SUITE_SCENARIO}")
fi
done
# Check that every scenario in the list of expected failures did fail
while read SUITE_SCENARIO
do
# Ignore comment lines (starting with hash)
if [[ "${SUITE_SCENARIO}" =~ ^# ]]
then
continue
fi
# Match lines that have [someSuite/someName.feature:n] - the part inside the
# brackets is the suite, feature and line number of the expected failure.
# Else ignore the line.
if [[ "${SUITE_SCENARIO}" =~ \[([a-zA-Z0-9-]+/[a-zA-Z0-9-]+\.feature:[0-9]+)] ]]; then
SUITE_SCENARIO="${BASH_REMATCH[1]}"
else
continue
fi
if [ -n "${BEHAT_SUITE_TO_RUN}" ]
then
# If the expected failure is not in the suite that is currently being run,
# then do not try and check that it failed.
REGEX_TO_MATCH="^${BEHAT_SUITE_TO_RUN}/"
if ! [[ "${SUITE_SCENARIO}" =~ ${REGEX_TO_MATCH} ]]
then
continue
fi
fi
# look for the expected suite-scenario at the end of a line in the
# FAILED_SCENARIO_PATHS - for example looking for apiComments/comments.feature:9
# we want to match lines like:
# tests/acceptance/features/apiComments/comments.feature:9
# but not lines like::
# tests/acceptance/features/apiComments/comments.feature:902
echo "${FAILED_SCENARIO_PATHS}" | grep ${SUITE_SCENARIO}$ > /dev/null
if [ $? -ne 0 ]
then
log_error "Scenario ${SUITE_SCENARIO} was expected to fail but did not fail."
UNEXPECTED_PASSED_SCENARIOS+=("${SUITE_SCENARIO}")
fi
done < ${EXPECTED_FAILURES_FILE}
else
for FAILED_SCENARIO_PATH in ${FAILED_SCENARIO_PATHS}
do
SUITE_PATH=$(dirname "${FAILED_SCENARIO_PATH}")
SUITE=$(basename "${SUITE_PATH}")
SCENARIO=$(basename "${FAILED_SCENARIO_PATH}")
SUITE_SCENARIO="${SUITE}/${SCENARIO}"
UNEXPECTED_FAILED_SCENARIOS+=("${SUITE_SCENARIO}")
done
fi
if [ ${BEHAT_EXIT_STATUS} -ne 0 ] && [ ${#FAILED_SCENARIO_PATHS[@]} -eq 0 ]
then
# Behat had some problem and there were no failed scenarios reported
# So the problem is something else.
# Possibly there were missing step definitions. Or Behat crashed badly, or...
UNEXPECTED_BEHAT_EXIT_STATUSES+=("${SUITE_FEATURE_TEXT} had behat exit status ${BEHAT_EXIT_STATUS}")
fi
if [ "${BEHAT_TAGS_OPTION_FOUND}" != true ]
then
# The behat run specified to skip scenarios tagged @skip
# Report them in a dry-run so they can be seen
# Big red error output is displayed if there are no matching scenarios - send it to null
DRY_RUN_FILE=$(mktemp)
SKIP_TAGS="@skip"
${BEHAT} --dry-run {$COLORS_OPTION} -c ${BEHAT_YML} -f pretty ${BEHAT_SUITE_OPTION} --tags "${SKIP_TAGS}" ${BEHAT_FEATURE} 1>${DRY_RUN_FILE} 2>/dev/null
if grep -q -m 1 'No scenarios' "${DRY_RUN_FILE}"
then
# If there are no skip scenarios, then no need to report that
:
else
echo ""
log_info "The following tests were skipped because they are tagged @skip:"
cat "${DRY_RUN_FILE}" | tee -a ${TEST_LOG_FILE}
fi
rm -f "${DRY_RUN_FILE}"
fi
}
declare -x TEST_SERVER_URL
if [ -z "${IPV4_URL}" ]
then
IPV4_URL="${TEST_SERVER_URL}"
fi
if [ -z "${IPV6_URL}" ]
then
IPV6_URL="${TEST_SERVER_URL}"
fi
# If a feature file has been specified but no suite, then deduce the suite
if [ -n "${BEHAT_FEATURE}" ] && [ -z "${BEHAT_SUITE}" ]
then
SUITE_PATH=`dirname ${BEHAT_FEATURE}`
BEHAT_SUITE=`basename ${SUITE_PATH}`
fi
if [ -z "${BEHAT_YML}" ]
then
# Look for a behat.yml somewhere below the current working directory
# This saves app acceptance tests being forced to specify BEHAT_YML
BEHAT_YML="config/behat.yml"
if [ ! -f "${BEHAT_YML}" ]
then
BEHAT_YML="acceptance/config/behat.yml"
fi
if [ ! -f "${BEHAT_YML}" ]
then
BEHAT_YML="tests/acceptance/config/behat.yml"
fi
# If no luck above, then use the core behat.yml that should live below this script
if [ ! -f "${BEHAT_YML}" ]
then
BEHAT_YML="${SCRIPT_PATH}/config/behat.yml"
fi
fi
BEHAT_CONFIG_DIR=$(dirname "${BEHAT_YML}")
ACCEPTANCE_DIR=$(dirname "${BEHAT_CONFIG_DIR}")
BEHAT_FEATURES_DIR="${ACCEPTANCE_DIR}/features"
declare -a BEHAT_SUITES
function get_behat_suites() {
# $1 type of suites to get "api" or "core-api"
# defaults to "api"
TYPE="$1"
if [[ -z "$TYPE" ]]
then
TYPE="api"
fi
ALL_SUITES=`find ${BEHAT_FEATURES_DIR}/ -type d -iname ${TYPE}* | sort | rev | cut -d"/" -f1 | rev`
COUNT_ALL_SUITES=`echo "${ALL_SUITES}" | wc -l`
#divide the suites letting it round down (could be zero)
MIN_SUITES_PER_RUN=$((${COUNT_ALL_SUITES} / ${DIVIDE_INTO_NUM_PARTS}))
#some jobs might need an extra suite
MAX_SUITES_PER_RUN=$((${MIN_SUITES_PER_RUN} + 1))
# the remaining number of suites that need to be distributed (could be zero)
REMAINING_SUITES=$((${COUNT_ALL_SUITES} - (${DIVIDE_INTO_NUM_PARTS} * ${MIN_SUITES_PER_RUN})))
if [[ ${RUN_PART} -le ${REMAINING_SUITES} ]]
then
SUITES_THIS_RUN=${MAX_SUITES_PER_RUN}
SUITES_IN_PREVIOUS_RUNS=$((${MAX_SUITES_PER_RUN} * (${RUN_PART} - 1)))
else
SUITES_THIS_RUN=${MIN_SUITES_PER_RUN}
SUITES_IN_PREVIOUS_RUNS=$((((${MAX_SUITES_PER_RUN} * ${REMAINING_SUITES}) + (${MIN_SUITES_PER_RUN} * (${RUN_PART} - ${REMAINING_SUITES} - 1)))))
fi
if [ ${SUITES_THIS_RUN} -eq 0 ]
then
echo "there are only ${COUNT_ALL_SUITES} suites, nothing to do in part ${RUN_PART}"
exit 0
fi
COUNT_FINISH_AND_TODO_SUITES=$((${SUITES_IN_PREVIOUS_RUNS} + ${SUITES_THIS_RUN}))
BEHAT_SUITES+=(`echo "${ALL_SUITES}" | head -n ${COUNT_FINISH_AND_TODO_SUITES} | tail -n ${SUITES_THIS_RUN}`)
}
if [[ -n "${BEHAT_SUITE}" ]]
then
BEHAT_SUITES+=("${BEHAT_SUITE}")
else
if [[ -n "${RUN_PART}" ]]; then
if [[ "${ACCEPTANCE_TEST_TYPE}" == "core-api" ]]; then
get_behat_suites "core"
else
get_behat_suites "${ACCEPTANCE_TEST_TYPE}"
fi
else
BEHAT_SUITES=(`echo "$BEHAT_SUITES" | tr "," "\n"`)
fi
fi
TEST_TYPE_TEXT="API"
# Always have "@api"
if [ ! -z "${BEHAT_FILTER_TAGS}" ]
then
# Be nice to the caller
# Remove any extra "&&" at the end of their tags list
BEHAT_FILTER_TAGS="${BEHAT_FILTER_TAGS%&&}"
# Remove any extra "&&" at the beginning of their tags list
BEHAT_FILTER_TAGS="${BEHAT_FILTER_TAGS#&&}"
fi
# EMAIL_HOST defines where the system-under-test can find the email server (inbucket)
# for sending email.
if [ -z "${EMAIL_HOST}" ]
then
EMAIL_HOST="127.0.0.1"
fi
# LOCAL_INBUCKET_HOST defines where this test script can find the Inbucket server
# for sending email. When testing a remote system, the Inbucket server somewhere
# "in the middle" might have a different host name from the point of view of
# the test script.
if [ -z "${LOCAL_EMAIL_HOST}" ]
then
LOCAL_EMAIL_HOST="${EMAIL_HOST}"
fi
if [ -z "${EMAIL_SMTP_PORT}" ]
then
EMAIL_SMTP_PORT="2500"
fi
# If the caller did not mention specific tags, skip the skipped tests by default
if [ "${BEHAT_TAGS_OPTION_FOUND}" = false ]
then
if [[ -z $BEHAT_FILTER_TAGS ]]
then
BEHAT_FILTER_TAGS="~@skip"
# If the caller has already specified specifically to run "@skip" scenarios
# then do not append "not @skip"
elif [[ ! ${BEHAT_FILTER_TAGS} =~ (^|&)@skip(&|$) ]]
then
BEHAT_FILTER_TAGS="${BEHAT_FILTER_TAGS}&&~@skip"
fi
fi
export IPV4_URL
export IPV6_URL
TEST_LOG_FILE=$(mktemp)
SCENARIOS_THAT_PASSED=0
SCENARIOS_THAT_FAILED=0
if [ ${#BEHAT_SUITES[@]} -eq 0 ] && [ -z "${BEHAT_FEATURE}" ]
then
SUITE_FEATURE_TEXT="all ${TEST_TYPE_TEXT}"
run_behat_tests
else
if [ -n "${BEHAT_SUITE}" ]
then
SUITE_FEATURE_TEXT="${BEHAT_SUITE}"
fi
if [ -n "${BEHAT_FEATURE}" ]
then
# If running a whole feature, it will be something like login.feature
# If running just a single scenario, it will also have the line number
# like login.feature:36 - which will be parsed correctly like a "file"
# by basename.
BEHAT_FEATURE_FILE=`basename ${BEHAT_FEATURE}`
SUITE_FEATURE_TEXT="${SUITE_FEATURE_TEXT} ${BEHAT_FEATURE_FILE}"
fi
fi
for i in "${!BEHAT_SUITES[@]}"
do
BEHAT_SUITE_TO_RUN="${BEHAT_SUITES[$i]}"
BEHAT_SUITE_OPTION="--suite=${BEHAT_SUITE_TO_RUN}"
SUITE_FEATURE_TEXT="${BEHAT_SUITES[$i]}"
for rerun_number in $(seq 1 ${BEHAT_RERUN_TIMES})
do
if ((${BEHAT_RERUN_TIMES} > 1))
then
echo -e "\nTest repeat $rerun_number of ${BEHAT_RERUN_TIMES}"
fi
run_behat_tests
done
done
# 3 types of things can have gone wrong:
# - some scenario failed (and it was not expected to fail)
# - some scenario passed (but it was expected to fail)
# - Behat exited with non-zero status because of some other error
# If any of these happened then report about it and exit with status 1 (error)
if [ ${#UNEXPECTED_FAILED_SCENARIOS[@]} -gt 0 ]
then
UNEXPECTED_FAILURE=true
else
UNEXPECTED_FAILURE=false
fi
if [ ${#UNEXPECTED_PASSED_SCENARIOS[@]} -gt 0 ]
then
UNEXPECTED_SUCCESS=true
else
UNEXPECTED_SUCCESS=false
fi
if [ ${#UNEXPECTED_BEHAT_EXIT_STATUSES[@]} -gt 0 ]
then
UNEXPECTED_BEHAT_EXIT_STATUS=true
else
UNEXPECTED_BEHAT_EXIT_STATUS=false
fi
# If we got some unexpected success, and we only ran a single feature or scenario
# then the fact that some expected failures did not happen might be because those
# scenarios were never even run.
# Filter the UNEXPECTED_PASSED_SCENARIOS to remove scenarios that were not run.
if [ "${UNEXPECTED_SUCCESS}" = true ]
then
ACTUAL_UNEXPECTED_PASS=()
# if running a single feature or a single scenario
if [[ -n "${BEHAT_FEATURE}" ]]
then
for unexpected_passed_value in "${UNEXPECTED_PASSED_SCENARIOS[@]}"
do
# check only for the running feature
if [[ $BEHAT_FEATURE == *":"* ]]
then
BEHAT_FEATURE_WITH_LINE_NUM=$BEHAT_FEATURE
else
LINE_NUM=$(echo ${unexpected_passed_value} | cut -d":" -f2)
BEHAT_FEATURE_WITH_LINE_NUM=$BEHAT_FEATURE:$LINE_NUM
fi
if [[ $BEHAT_FEATURE_WITH_LINE_NUM == *"${unexpected_passed_value}" ]]
then
ACTUAL_UNEXPECTED_PASS+=("${unexpected_passed_value}")
fi
done
else
ACTUAL_UNEXPECTED_PASS=("${UNEXPECTED_PASSED_SCENARIOS[@]}")
fi
if [ ${#ACTUAL_UNEXPECTED_PASS[@]} -eq 0 ]
then
UNEXPECTED_SUCCESS=false
fi
fi
if [ "${UNEXPECTED_FAILURE}" = false ] && [ "${UNEXPECTED_SUCCESS}" = false ] && [ "${UNEXPECTED_BEHAT_EXIT_STATUS}" = false ]
then
FINAL_EXIT_STATUS=0
else
FINAL_EXIT_STATUS=1
fi
if [ -n "${EXPECTED_FAILURES_FILE}" ]
then
log_info "Exit code after checking expected failures: ${FINAL_EXIT_STATUS}"
fi
if [ "${UNEXPECTED_FAILURE}" = true ]
then
log_failed "Total unexpected failed scenarios:"
printf "${TC_RED}- %s\n${TC_RESET}" "${UNEXPECTED_FAILED_SCENARIOS[@]}"
echo ""
else
log_info "There were no unexpected failures."
fi
if [ "${UNEXPECTED_SUCCESS}" = true ]
then
log_error "Total unexpected passed scenarios:"
printf "${TC_GREEN}- %s\n${TC_RESET}" "${ACTUAL_UNEXPECTED_PASS[@]}"
echo ""
else
log_info "There were no unexpected success."
fi
if [ "${UNEXPECTED_BEHAT_EXIT_STATUS}" = true ]
then
log_error "The following Behat test runs exited with non-zero status:"
printf "${TC_RED}%s\n${TC_RESET}" "${UNEXPECTED_BEHAT_EXIT_STATUSES[@]}"
fi
TOTAL_SCENARIOS=$((SCENARIOS_THAT_PASSED + SCENARIOS_THAT_FAILED))
printf "Summary: %s scenarios (${TC_GREEN}%s passed${TC_RESET}, ${TC_RED}%s failed${TC_RESET})" "${TOTAL_SCENARIOS}" "${SCENARIOS_THAT_PASSED}" "${SCENARIOS_THAT_FAILED}"
echo ""
# # sync the file-system so all output will be flushed to storage.
# # In CI, we sometimes see that the last lines of output are missing.
# sync
# # If we are running in CI, then sleep for a bit to (hopefully) let the
# # drone agent send all the output to the drone server.
# if [ -n "${CI_REPO}" ]
# then
# echo "sleeping for 30 seconds at end of test run"
# sleep 30
# fi
exit ${FINAL_EXIT_STATUS}
@@ -0,0 +1,161 @@
#!/bin/bash
# Set required environment variables
export START_TIKA=true
export START_EMAIL=true
export WITH_WRAPPER=true
export STORAGE_DRIVER=${STORAGE_DRIVER:-posix}
export TEST_ROOT_PATH="/drone/src/tests"
# LOCAL TEST WITHOUT EXTRA ENVS
TEST_SERVER_URL="https://qsfera-server:9200"
OC_WRAPPER_URL="http://qsfera-server:5200"
if [ "$STORAGE_DRIVER" = "posix" ]; then
EXPECTED_FAILURES_FILE="tests/acceptance/expected-failures-posix-storage.md"
else
EXPECTED_FAILURES_FILE="tests/acceptance/expected-failures-decomposed-storage.md"
fi
# Start server
make -C tests/acceptance/docker start-services
# Wait until the server responds with HTTP 200
echo "Waiting for server to start..."
for i in {1..60}; do
response_code=$(curl -sk -u admin:admin "${TEST_SERVER_URL}/graph/v1.0/users/admin" -w "%{http_code}" -o /dev/null)
echo "Attempt $i: Received response code $response_code" # Debugging line to see the status
if [ "$response_code" == "200" ]; then
echo "✅ Server is up and running!"
break
fi
sleep 1
done
if [ "$response_code" != "200" ]; then
echo "❌ Server is not up after 60 attempts."
exit 1
fi
# List of suites to run
SUITES=(
"apiArchiver"
"apiContract"
"apiCors"
"apiAsyncUpload"
"apiDownloads"
"apiDepthInfinity"
"apiLocks"
"apiActivities"
"apiSettings"
"apiGraph"
"apiServiceAvailability"
"apiGraphUserGroup"
"apiSpaces"
"apiSpacesShares"
"apiSpacesDavOperation"
"apiSearch1"
"apiSearch2"
"apiReshare"
"apiSharingNg1"
"apiSharingNg2"
"apiSharingNgShareInvitation"
"apiSharingNgLinkSharePermission"
"apiSharingNgLinkShareRoot"
"apiSearchContent"
"apiNotification"
)
# List of suites from core
CORE_SUITES=(
"coreApiAuth"
"coreApiCapabilities"
"coreApiMain"
"coreApiShareCreateSpecialToShares1"
"coreApiShareCreateSpecialToShares2"
"coreApiSharees"
"coreApiShareManagementBasicToShares"
"coreApiShareManagementToShares"
"coreApiShareOperationsToShares1"
"coreApiShareOperationsToShares2"
"coreApiSharePublicLink1"
"coreApiSharePublicLink2"
"coreApiShareUpdateToShares"
"coreApiTrashbin"
"coreApiTrashbinRestore"
"coreApiVersions"
"coreApiWebdavDelete"
"coreApiWebdavEtagPropagation1"
"coreApiWebdavEtagPropagation2"
"coreApiWebdavMove"
"coreApiWebdavOperations"
"coreApiWebdavPreviews"
"coreApiWebdavProperties"
"coreApiWebdavUpload"
"coreApiWebdavUploadTUS"
)
EXTRA_SUITE=(
"apiAntivirus"
"apiOcm"
"apiCollaboration"
"apiAuthApp"
"cliCommands"
)
# Create log directory
LOG_DIR="./suite-logs"
mkdir -p "$LOG_DIR"
SUCCESS_COUNT=0
FAILURE_COUNT=0
for SUITE in "${SUITES[@]}"; do
echo "=============================================="
echo "Running suite: $SUITE"
echo "=============================================="
LOG_FILE="$LOG_DIR/${SUITE}.log"
# Run suite
make test-acceptance-api TEST_SERVER_URL=$TEST_SERVER_URL OC_WRAPPER_URL=$OC_WRAPPER_URL EXPECTED_FAILURES_FILE=$EXPECTED_FAILURES_FILE BEHAT_SUITE=$SUITE SEND_SCENARIO_LINE_REFERENCES=true > "$LOG_FILE" 2>&1
# Check if suite was successful
if [ $? -eq 0 ]; then
echo "✅ Suite $SUITE completed successfully."
((SUCCESS_COUNT++))
else
echo "❌ Suite $SUITE failed. Check log: $LOG_FILE"
((FAILURE_COUNT++))
fi
done
for SUITE in "${CORE_SUITES[@]}"; do
echo "=============================================="
echo "Running suite: $SUITE"
echo "=============================================="
LOG_FILE="$LOG_DIR/${SUITE}.log"
# Run suite
make test-acceptance-api TEST_SERVER_URL=$TEST_SERVER_URL EXPECTED_FAILURES_FILE=$EXPECTED_FAILURES_FILE BEHAT_SUITE=$SUITE SEND_SCENARIO_LINE_REFERENCES=true > "$LOG_FILE" 2>&1
# Check if suite was successful
if [ $? -eq 0 ]; then
echo "✅ Suite $SUITE completed successfully."
((SUCCESS_COUNT++))
else
echo "❌ Suite $SUITE failed. Check log: $LOG_FILE"
((FAILURE_COUNT++))
fi
done
# Report summary
echo "=============================================="
echo "Test Summary:"
echo "✅ Successful suites: $SUCCESS_COUNT"
echo "❌ Failed suites: $FAILURE_COUNT"
echo "Logs saved in: $LOG_DIR"
echo "=============================================="
@@ -0,0 +1,94 @@
#!/bin/bash
# Set required environment variables
export START_TIKA=true
export WITH_WRAPPER=false
TEST_SERVER_URL="https://qsfera-server:9200"
# Start server
make -C tests/acceptance/docker start-services
# Wait until the server responds with HTTP 200
echo "Waiting for server to start..."
for i in {1..60}; do
response_code=$(curl -sk -u admin:admin "${TEST_SERVER_URL}/graph/v1.0/users/admin" -w "%{http_code}" -o /dev/null)
echo "Attempt $i: Received response code $response_code" # Debugging line to see the status
if [ "$response_code" == "200" ]; then
echo "✅ Server is up and running!"
break
fi
sleep 1
done
if [ "$response_code" != "200" ]; then
echo "❌ Server is not up after 60 attempts."
exit 1
fi
E2E_SUITES=(
"admin-settings"
"file-action"
"journeys"
"navigation"
"search"
"shares"
"spaces"
"user-settings"
)
EXTRA_E2E_SUITE="app-providerapp-store,keycloak,ocm,oidc"
# Create log directory
LOG_DIR="./suite-logs"
mkdir -p "$LOG_DIR"
SUCCESS_COUNT=0
FAILURE_COUNT=0
# Clone the repository and install dependencies
git clone https://github.com/opencloud-eu/web
cd web || exit 1
pnpm i
echo "Installation complete, moving to tests/e2e directory..."
# Run e2e suites
for SUITE in "${E2E_SUITES[@]}"; do
echo "=============================================="
echo "Running e2e suite: $SUITE"
echo "=============================================="
LOG_FILE="$LOG_DIR/${SUITE}.log"
# Run suite
(
cd tests/e2e || exit 1
OC_BASE_URL=$TEST_SERVER_URL RETRY=1 HEADLESS=true PARALLEL=4 ./run-e2e.sh --suites $SUITE > "../../../$LOG_FILE" 2>&1
)
# Check if suite was successful
if [ $? -eq 0 ]; then
echo "✅ Suite $SUITE completed successfully."
((SUCCESS_COUNT++))
else
echo "❌ Suite $SUITE failed. Check log: $LOG_FILE"
((FAILURE_COUNT++))
fi
done
# Report summary
echo "=============================================="
echo "Test Summary:"
echo "✅ Successful suites: $SUCCESS_COUNT"
echo "❌ Failed suites: $FAILURE_COUNT"
echo "Logs saved in: $LOG_DIR"
echo "=============================================="
# Cleanup: Remove the cloned web directory
echo "🧹 Cleaning up..."
cd ..
rm -rf web
echo "✅ Cleanup complete."