#!/bin/bash echo -e "Loads functions from testing_process.sh" #================================================= # Globals variables #================================================= # A complete list of backup hooks is available at /usr/share/yunohost/hooks/backup/ backup_hooks="conf_ssowat data_home conf_ynh_firewall conf_cron" #================================================= break_before_continue () { # Make a break if auto_remove is set if [ $auto_remove -eq 0 ] && [ $bash_mode -ne 1 ] then LXC_CONNECT_INFO # Print access information read -p "Press a key to delete the application and continue...." < /dev/tty fi } check_false_positive_error () { # Check if FALSE_ERRORS_DETECTION has detected an false positive error. # We will use # check_false_positive_error || return $? # to check the result of the function of propagate the result to parent functions. if [ $false_positive_error -eq 1 ] && [ $false_positive_error_loop -lt $max_false_positive_error_loop ]; then # Return 75, for EX_TEMPFAIL from sysexits.h return 75 fi } #================================================= PRINT_YUNOHOST_VERSION () { ECHO_FORMAT ">> YunoHost versions:\n" "white" "bold" clog # Be sure that the container is running LXC_START "true" # Print the version of YunoHost from the LXC container ssh $arg_ssh $lxc_name "sudo yunohost --version" # Get the version of YunoHost from the LXC container ynh_version=$(ssh -q $lxc_name "sudo yunohost --version --output-as plain | grep -A4 moulinette | tail -n1 | sed 's@\.@@g' | cut -d+ -f1") } #================================================= # Install and remove an app #================================================= SETUP_APP () { # Install an application in a LXC container # Uses the default snapshot current_snapshot=snap0 # Exec the pre-install instruction, if there one if [ -n "$pre_install" ] then ECHO_FORMAT "Pre installation request\n" "white" "bold" clog # Start the lxc container LXC_START "true" # Copy all the instructions into a script echo "$pre_install" > "$script_dir/preinstall.sh" chmod +x "$script_dir/preinstall.sh" # Replace variables sed -i "s/\$USER/$test_user/" "$script_dir/preinstall.sh" sed -i "s/\$DOMAIN/$main_domain/" "$script_dir/preinstall.sh" sed -i "s/\$SUBDOMAIN/$sub_domain/" "$script_dir/preinstall.sh" sed -i "s/\$PASSWORD/$yuno_pwd/" "$script_dir/preinstall.sh" # Copy the pre-install script into the container. scp -rq "$script_dir/preinstall.sh" "$lxc_name": # Then execute the script to execute the pre-install commands. LXC_START "./preinstall.sh >&2" # Print the log to print the results ECHO_FORMAT "$(cat "$temp_log")\n" clog fi # Install the application in a LXC container LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app install --force \"$package_dir\" -a \"$manifest_args_mod\"" # yunohost_result gets the return code of the installation yunohost_result=$? # Print the result of the install command if [ $yunohost_result -eq 0 ]; then ECHO_FORMAT "Installation successful. ($yunohost_result)\n" "white" clog else ECHO_FORMAT "Installation failed. ($yunohost_result)\n" "white" clog fi # Check all the witness files, to verify if them still here check_witness_files # Retrieve the app id in the log. To manage the app after ynh_app_id=$(sudo tac "$yunohost_log" | grep --only-matching --max-count=1 "YNH_APP_INSTANCE_NAME=[^ ]*" | cut --delimiter='=' --fields=2) # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? } STANDARD_SETUP_APP () { # Try to find an existing snapshot for this install, or make an install # If it's a root install if [ "$check_path" = "/" ] then # Check if a snapshot already exist for this install if [ -z "$root_snapshot" ] then # Make an installation SETUP_APP check_false_positive_error || return $? # Create a snapshot for this installation, to be able to reuse it instead of a new installation. # But only if this installation has worked fine if [ $yunohost_result -eq 0 ]; then # Check if a snapshot already exist for a root install if [ -z "$root_snapshot" ] then ECHO_FORMAT "\nCreate a snapshot for root installation.\n" "white" clog create_temp_backup 2 root_snapshot=snap2 fi fi else # Or uses an existing snapshot ECHO_FORMAT "Uses an existing snapshot for root installation.\n" "white" clog use_temp_snapshot $root_snapshot fi # In case of sub path install, use another snapshot else # Check if a snapshot already exist for this install if [ -z "$subpath_snapshot" ] then # Make an installation SETUP_APP check_false_positive_error || return $? # Create a snapshot for this installation, to be able to reuse it instead of a new installation. # But only if this installation has worked fine if [ $yunohost_result -eq 0 ]; then # Check if a snapshot already exist for a subpath (or no_url) install if [ -z "$subpath_snapshot" ] then ECHO_FORMAT "\nCreate a snapshot for sub path installation.\n" "white" clog create_temp_backup 1 root_snapshot=snap1 fi fi else # Or uses an existing snapshot ECHO_FORMAT "Uses an existing snapshot for sub path installation.\n" "white" clog use_temp_snapshot $subpath_snapshot fi fi } REMOVE_APP () { # Remove an application # Make a break if auto_remove is set break_before_continue ECHO_FORMAT "\nDeleting...\n" "white" "bold" clog # Remove the application from the LXC container LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app remove \"$ynh_app_id\"" # yunohost_remove gets the return code of the deletion yunohost_remove=$? # Print the result of the remove command if [ "$yunohost_remove" -eq 0 ]; then ECHO_FORMAT "Deleting successful. ($yunohost_remove)\n" "white" clog else ECHO_FORMAT "Deleting failed. ($yunohost_remove)\n" "white" clog fi # Check all the witness files, to verify if them still here check_witness_files } #================================================= # Try to access the app by its url #================================================= CHECK_URL () { # Try to access the app by its url if [ $use_curl -eq 1 ] then ECHO_FORMAT "\nTry to access by url...\n" "white" "bold" # Force a skipped_uris if public mode is not set if [ "$install_type" != "private" ] && [ "$install_type" != "public" ] && [ -z "$public_arg" ] then # Add a skipped_uris on / for the app LXC_START "sudo yunohost app setting \"$ynh_app_id\" skipped_uris -v \"/\"" # Regen the config of sso LXC_START "sudo yunohost app ssowatconf" ECHO_FORMAT "Public access forced by a skipped_uris to check.\n" "lyellow" "bold" fi # Inform /etc/hosts with the IP of LXC to resolve the domain. # This is set only here and not before to prevent to help the app's scripts echo -e "$ip_range.2 $main_domain #package_check\n$ip_range.2 $sub_domain #package_check" | sudo tee --append /etc/hosts > /dev/null # Try to resolv the domain during 10 seconds maximum. local i=0 for i in `seq 1 10`; do curl --location --insecure $check_domain > /dev/null 2>&1 # If curl return 6, it's an error "Could not resolve host" if [ $? -ne 6 ]; then # If not, curl is ready to work. break fi echo -n . sleep 1 done # curl_error indicate the result of curl test curl_error=0 # 503 Service Unavailable can would have some time to work. local http503=0 # yuno_portal equal 1 if the test fall on the portal yuno_portal=0 # Try to access to the url in 2 times, with a final / and without i=1; while [ $i -ne 3 ] do # First time, try without final / if [ $i -eq 1 ] then # If the last character is / if [ "${check_path: -1}" = "/" ] then # Remove it local curl_check_path="${check_path:0:${#check_path}-1}" else curl_check_path=$check_path fi # The next loop will try the second test i=2 elif [ $i -eq 2 ] then # Second time, try with the final / # If the last character isn't / if [ "${check_path: -1}" != "/" ] then # Add it curl_check_path="$check_path/" else curl_check_path=$check_path fi # The next loop will break the while loop i=3 fi # Remove the previous curl output rm -f "$script_dir/url_output" # Call curl to try to access to the url of the app curl --location --insecure --silent --show-error --write-out "%{http_code};%{url_effective}\n" $check_domain$curl_check_path --output "$script_dir/url_output" > "$script_dir/curl_print" # Analyze the result of curl command if [ $? -ne 0 ] then ECHO_FORMAT "Connection error...\n" "red" "bold" curl_error=1 fi # Print informations about the connection ECHO_FORMAT "Test url: $check_domain$curl_check_path\n" "white" ECHO_FORMAT "Real url: $(cat "$script_dir/curl_print" | cut --delimiter=';' --fields=2)\n" "white" local http_code=$(cat "$script_dir/curl_print" | cut -d ';' -f1) ECHO_FORMAT "HTTP code: $http_code\n" "white" # Analyze the http code if [ "${http_code:0:1}" = "0" ] || [ "${http_code:0:1}" = "4" ] || [ "${http_code:0:1}" = "5" ] then # If the http code is a 0xx 4xx or 5xx, it's an error code. curl_error=1 # 401 is "Unauthorized", so is a answer of the server. So, it works! test "${http_code}" = "401" && curl_error=0 # 503 is Service Unavailable, it's a temporary error. if [ "${http_code}" = "503" ] then curl_error=0 ECHO_FORMAT "Service temporarily unavailable\n" "lyellow" "bold" # 3 successive error are allowed http503=$(( http503 + 1 )) if [ $http503 -ge 3 ]; then # Over 3, it's definitively an error curl_error=1 else # Below 3 times, retry. # Decrease the value of 'i' to retry the same test i=$(( i - 1 )) # Wait 1 second to let's some time to the 503 error sleep 1 # And retry immediately continue fi fi if [ $curl_error -eq 1 ]; then ECHO_FORMAT "The HTTP code show an error.\n" "white" "bold" clog fi fi # Analyze the output of curl if [ -e "$script_dir/url_output" ] then # Print the title of the page local url_title=$(grep "" "$script_dir/url_output" | cut --delimiter='>' --fields=2 | cut --delimiter='<' --fields=1) ECHO_FORMAT "Title of the page: $url_title\n" "white" # Check if the page title is neither the YunoHost portail or default nginx page if [ "$url_title" = "YunoHost Portal" ] then ECHO_FORMAT "The connection attempt fall on the YunoHost portal.\n" "white" "bold" clog yuno_portal=1 else yuno_portal=0 if [ "$url_title" = "Welcome to nginx on Debian!" ] then # Falling on nginx default page is an error. curl_error=1 ECHO_FORMAT "The connection attempt fall on nginx default page.\n" "white" "bold" clog fi # Print the first 20 lines of the page ECHO_FORMAT "Extract of the page:\n" "white" echo -en "\e[37m" # Write in 'light grey' lynx -dump -force_html "$script_dir/url_output" | head --lines 20 | tee --append "$test_result" echo -e "\e[0m" if [ $show_resources -eq 1 ] then # Get all the resources for the main page of the app. local HTTP_return local moved=0 local ignored=0 while read HTTP_return do # Ignore robots.txt and ynhpanel.js. They always redirect to the portal. if echo "$HTTP_return" | grep --quiet "$check_domain/robots.txt\|$check_domain/ynhpanel.js"; then ECHO_FORMAT "Ressource ignored:" "white" ECHO_FORMAT " ${HTTP_return##*http*://}\n" ignored=1 fi # If it's the line with the resource to get if echo "$HTTP_return" | grep --quiet "^--.*-- http" then # Get only the resource itself. local resource=${HTTP_return##*http*://} # Else, if would be the HTTP return code. else # If the return code is different than 200. if ! echo "$HTTP_return" | grep --quiet "200 OK$" then # Skipped the check of ignored ressources. if [ $ignored -eq 1 ] then ignored=0 continue fi # Isolate the http return code. http_code="${HTTP_return##*awaiting response... }" http_code="${http_code:0:3}" # If the return code is 301 or 302, let's check the redirection. if echo "$HTTP_return" | grep --quiet "30[12] Moved" then ECHO_FORMAT "Ressource moved:" "white" ECHO_FORMAT " $resource\n" moved=1 else ECHO_FORMAT "Resource unreachable (Code $http_code)" "red" "bold" ECHO_FORMAT " $resource\n" # curl_error=1 moved=0 fi else if [ $moved -eq 1 ] then if echo "$resource" | grep --quiet "/yunohost/sso/" then ECHO_FORMAT "The previous resource is redirected to the YunoHost portal\n" "red" # curl_error=1 fi fi moved=0 fi fi done <<< "$(cd "$package_path"; LC_ALL=C wget --adjust-extension --page-requisites --no-check-certificate $check_domain$curl_check_path 2>&1 | grep "^--.*-- http\|^HTTP request sent")" fi echo "" fi fi done # Detect the issue alias_traversal, https://github.com/yandex/gixy/blob/master/docs/en/plugins/aliastraversal.md # Create a file to get for alias_traversal echo "<!DOCTYPE html><html><head> <title>alias_traversal test

alias_traversal test

If you see this page, you have failed the test for alias_traversal issue." \ | sudo tee /var/lib/lxc/$lxc_name/rootfs/var/www/html/alias_traversal.html > /dev/null curl --location --insecure --silent $check_domain$check_path../html/alias_traversal.html \ | grep "title" | grep --quiet "alias_traversal test" \ && ECHO_FORMAT "Issue alias_traversal detected ! Please see here https://github.com/YunoHost/example_ynh/pull/45 to fix that.\n" "red" "bold" && RESULT_alias_traversal=1 # Remove the entries in /etc/hosts for the test domain sudo sed --in-place '/#package_check/d' /etc/hosts else # If use_curl is set to 0, the url will not tried ECHO_FORMAT "Connexion attempt aborted.\n" "white" curl_error=0 yuno_portal=0 fi } #================================================= # Generic functions for unit tests #================================================= unit_test_title () { # Print a title for the test # $1 = Name of the test ECHO_FORMAT "\n\n>> $1 [Test $cur_test/$all_test]\n" "white" "bold" clog # Increment the value of the current test cur_test=$((cur_test+1)) } check_manifest_key () { # Check if a manifest key is set # $1 = manifest key if [ -z "${1}_arg" ] then ECHO_FORMAT "Unable to find a manifest key for '${1,,}' in the check_process file. Impossible to perform this test\n" "red" clog return 1 fi } replace_manifest_key () { # Replace a generic manifest key by another # $1 = Manifest key # $2 = Replacement value # Build the variable name by concatenate $1 and _arg local manifest_key=$(eval echo \$${1}_arg) if [ -n "$manifest_key" ] then manifest_args_mod=$(echo $manifest_args_mod | sed "s@$manifest_key=[^&]*\&@${manifest_key}=${2}\&@") fi } check_success () { ECHO_FORMAT "--- SUCCESS ---\n" "lgreen" "bold" } check_failed () { ECHO_FORMAT "--- FAIL ---\n" "red" "bold" } check_test_result () { # Check the result and print SUCCESS or FAIL if [ $yunohost_result -eq 0 ] && [ $curl_error -eq 0 ] && [ $yuno_portal -eq 0 ] then check_success return 0 else check_failed return 1 fi } check_test_result_remove () { # Check the result of a remove and print SUCCESS or FAIL if [ $yunohost_remove -eq 0 ] then check_success return 0 else check_failed return 1 fi } is_install_failed () { # Check if an install have previously work # If the test for install in sub dir isn't desactivated sub_dir_install=0 if [ $setup_sub_dir -ne 0 ] then # If a test succeed or if force_install_ok is set # Or if $setup_sub_dir isn't set in the check_process if [ $RESULT_check_sub_dir -eq 1 ] || [ $force_install_ok -eq 1 ] || [ $setup_sub_dir -eq -1 ] then # Validate installation in sub dir. sub_dir_install=1 fi else sub_dir_install=0 fi # If the test for install on root isn't desactivated root_install=0 if [ $setup_root -ne 0 ] || [ $setup_nourl -eq 1 ] then # If a test succeed or if force_install_ok is set # Or if $setup_root isn't set in the check_process if [ $RESULT_check_root -eq 1 ] || [ $force_install_ok -eq 1 ] || [ $setup_root -eq -1 ] then # Validate installation on root. root_install=1 fi else root_install=0 fi if [ $sub_dir_install -eq 0 ] && [ $root_install -eq 0 ] then ECHO_FORMAT "All installs have failed, impossible to perform this test...\n" "red" clog return 1 fi } #================================================= # Unit tests #================================================= CHECK_SETUP () { # Try to install in a sub path, on root or without url access # $1 = install type local install_type=$1 if [ "$install_type" = "subdir" ]; then unit_test_title "Installation in a sub path..." elif [ "$install_type" = "root" ]; then unit_test_title "Installation on the root..." else unit_test_title "Installation without url access..." # Disable the curl test use_curl=0 fi # Check if the needed manifest key are set or abort the test if [ "$install_type" != "no_url" ]; then check_manifest_key "domain" || return check_manifest_key "path" || return fi # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" if [ "$install_type" = "subdir" ]; then local check_path=$test_path elif [ "$install_type" = "root" ]; then local check_path=/ fi replace_manifest_key "path" "$check_path" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Install the application in a LXC container SETUP_APP check_false_positive_error || return $? # Try to access the app by its url CHECK_URL # Check the result and print SUCCESS or FAIL if check_test_result then # Success RESULT_global_setup=1 # Installation succeed local check_result_setup=1 # Installation succeed else # Fail # The global success for a installation can't be failed if another installation succeed if [ $RESULT_global_setup -ne 1 ]; then RESULT_global_setup=-1 # Installation failed fi local check_result_setup=-1 # Installation failed fi # Create a snapshot for this installation, to be able to reuse it instead of a new installation. # But only if this installation has worked fine if [ $check_result_setup -eq 1 ]; then if [ "$check_path" = "/" ] then # Check if a snapshot already exist for a root install if [ -z "$root_snapshot" ] then ECHO_FORMAT "Create a snapshot for root installation.\n" "white" clog create_temp_backup 2 root_snapshot=snap2 fi else # Check if a snapshot already exist for a subpath (or no_url) install if [ -z "$subpath_snapshot" ] then # Then create a snapshot ECHO_FORMAT "Create a snapshot for sub path installation.\n" "white" clog create_temp_backup 1 subpath_snapshot=snap1 fi fi fi # Remove the application REMOVE_APP # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? # Check the result and print SUCCESS or FAIL if check_test_result_remove then # Success local check_result_remove=1 # Remove in sub path succeed RESULT_global_remove=1 # Remove succeed else # Fail # The global success for a deletion can't be failed if another remove succeed if [ $RESULT_global_remove -ne 1 ]; then RESULT_global_remove=-1 # Remove failed fi local check_result_remove=-1 # Remove in sub path failed fi # Reinstall the application after the removing # Try to resintall only if the first install is a success. if [ $check_result_setup -eq 1 ] then ECHO_FORMAT "\nReinstall the application after a removing.\n" "white" "bold" clog SETUP_APP check_false_positive_error || return $? # Try to access the app by its url CHECK_URL # Check the result and print SUCCESS or FAIL if check_test_result then # Success local check_result_setup=1 # Installation succeed else # Fail local check_result_setup=-1 # Installation failed fi fi # Fill the correct variable depend on the type of test if [ "$install_type" = "subdir" ] then RESULT_check_sub_dir=$check_result_setup RESULT_check_remove_sub_dir=$check_result_remove else # root and no_url RESULT_check_root=$check_result_setup RESULT_check_remove_root=$check_result_remove fi # Make a break if auto_remove is set break_before_continue } CHECK_UPGRADE () { # Try the upgrade script # Do an upgrade test for each commit in the upgrade list while read <&4 commit do if [ "$commit" == "current" ] then unit_test_title "Upgrade from the same version..." else # Get the specific section for this upgrade from the check_process extract_section "^; commit=$commit" "^;" "$check_process" # Get the name for this upgrade. upgrade_name=$(grep "^name=" "$partial_check_process" | cut -d'=' -f2) # Or use the commit if there's no name. if [ -z "$upgrade_name" ]; then unit_test_title "Upgrade from the commit $commit..." else unit_test_title "Upgrade from $upgrade_name..." fi fi # Check if an install have previously work # Abort if none install worked is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" # Use a path according to previous succeeded installs if [ $sub_dir_install -eq 1 ]; then local check_path=$test_path else local check_path=/ fi replace_manifest_key "path" "$check_path" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Install the application in a LXC container ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog if [ "$commit" == "current" ] then # If no commit is specified, use the current version. STANDARD_SETUP_APP check_false_positive_error || return $? else # Otherwise, use a specific commit # Backup the modified arguments update_manifest_args="$manifest_args_mod" # Get the arguments of the manifest for this upgrade. manifest_args_mod="$(grep "^manifest_arg=" "$partial_check_process" | cut -d'=' -f2-)" if [ -z "$manifest_args_mod" ]; then # If there's no specific arguments, use the previous one. manifest_args_mod="$update_manifest_args" else # Otherwise, keep the new arguments, and replace the variables. manifest_args_mod="${manifest_args_mod//DOMAIN/$check_domain}" manifest_args_mod="${manifest_args_mod//PATH/$check_path}" manifest_args_mod="${manifest_args_mod//USER/$test_user}" fi # Make a backup of the directory sudo cp -a "$package_path" "${package_path}_back" # Change to the specified commit (cd "$package_path"; git checkout --force --quiet "$commit") # Install the application SETUP_APP check_false_positive_error || return $? # Then replace the backup sudo rm -r "$package_path" sudo mv "${package_path}_back" "$package_path" # And restore the arguments for the manifest manifest_args_mod="$update_manifest_args" fi # Check if the install had work if [ $yunohost_result -ne 0 ] then ECHO_FORMAT "\nInstallation failed...\n" "red" "bold" ECHO_FORMAT "\nUpgrade test ignored...\n" "red" "bold" else ECHO_FORMAT "\nUpgrade...\n" "white" "bold" clog # Upgrade the application in a LXC container LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app upgrade $ynh_app_id -f \"$package_dir\"" # yunohost_result gets the return code of the upgrade yunohost_result=$? # Print the result of the upgrade command if [ $yunohost_result -eq 0 ]; then ECHO_FORMAT "Upgrade successful. ($yunohost_result)\n" "white" clog else ECHO_FORMAT "Upgrade failed. ($yunohost_result)\n" "white" clog fi # Check all the witness files, to verify if them still here check_witness_files # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? # Try to access the app by its url CHECK_URL # Check the result and print SUCCESS or FAIL if check_test_result then # Success # The global success for an upgrade can't be a success if another upgrade failed if [ $RESULT_check_upgrade -ne -1 ]; then RESULT_check_upgrade=1 # Upgrade succeed fi else # Fail RESULT_check_upgrade=-1 # Upgrade failed fi # Remove the application REMOVE_APP fi # Uses the default snapshot current_snapshot=snap0 # Stop and restore the LXC container LXC_STOP done 4< "$script_dir/upgrade_list" } CHECK_PUBLIC_PRIVATE () { # Try to install in public or private mode # $1 = install type local install_type=$1 if [ "$install_type" = "private" ]; then unit_test_title "Installation in private mode..." else [ "$install_type" = "public" ] unit_test_title "Installation in public mode..." fi # Check if the needed manifest key are set or abort the test check_manifest_key "public" || return check_manifest_key "public_public" || return check_manifest_key "public_private" || return # Check if an install have previously work is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" replace_manifest_key "user" "$test_user" # Set public or private according to type of test requested if [ "$install_type" = "private" ]; then replace_manifest_key "public" "$public_private_arg" elif [ "$install_type" = "public" ]; then replace_manifest_key "public" "$public_public_arg" fi # Initialize the value local check_result_public_private=0 # Try in 2 times, first in root and second in sub path. local i=0 for i in 0 1 do # First, try with a root install if [ $i -eq 0 ] then # Check if root installation worked if [ $root_install -eq 1 ] then # Replace manifest key for path local check_path=/ replace_manifest_key "path" "$check_path" else # Jump to the second path if this check cannot be do ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog continue fi # Second, try with a sub path install elif [ $i -eq 1 ] then # Check if sub path installation worked, or if force_install_ok is setted. if [ $sub_dir_install -eq 1 ] then # Replace manifest key for path local check_path=$test_path replace_manifest_key "path" "$check_path" else # Jump to the second path if this check cannot be do ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog return fi fi # Install the application in a LXC container SETUP_APP check_false_positive_error || return $? # Try to access the app by its url CHECK_URL # Change the result according to the results of the curl test if [ "$install_type" = "private" ] then # In private mode, if curl doesn't fell on the ynh portal, it's a fail. if [ $yuno_portal -eq 0 ]; then ECHO_FORMAT "App is not private: it should redirect to the Yunohost portal, but is publicly accessible instead\n" "lyellow" clog yunohost_result=1 fi elif [ "$install_type" = "public" ] then # In public mode, if curl fell on the ynh portal, it's a fail. if [ $yuno_portal -eq 1 ]; then ECHO_FORMAT "App page is not public: it should be publicly accessible, but redirects to the Yunohost portal instead\n" "lyellow" clog yunohost_result=1 fi fi # Check the result and print SUCCESS or FAIL if [ $yunohost_result -eq 0 ] && [ $curl_error -eq 0 ] then # Success check_success # The global success for public/private mode can't be a success if another installation failed if [ $check_result_public_private -ne -1 ]; then check_result_public_private=1 # Installation succeed fi else # Fail check_failed check_result_public_private=-1 # Installation failed fi # Fill the correct variable depend on the type of test if [ "$install_type" = "private" ] then RESULT_check_private=$check_result_public_private else # public RESULT_check_public=$check_result_public_private fi # Make a break if auto_remove is set break_before_continue # Stop and restore the LXC container LXC_STOP done } CHECK_MULTI_INSTANCE () { # Try multi-instance installations unit_test_title "Multi-instance installations..." # Check if an install have previously work is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test if [ $sub_dir_install -eq 1 ]; then local check_path=$test_path else local check_path=/ fi replace_manifest_key "path" "$check_path" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Install 2 times the same app local i=0 for i in 1 2 do # First installation if [ $i -eq 1 ] then check_domain=$main_domain ECHO_FORMAT "First installation: path=$check_domain$check_path\n" clog # Second installation elif [ $i -eq 2 ] then check_domain=$sub_domain ECHO_FORMAT "Second installation: path=$check_domain$check_path\n" clog fi # Replace path and domain manifest keys for the test replace_manifest_key "domain" "$check_domain" # Install the application in a LXC container SETUP_APP check_false_positive_error || return $? # Store the result in the correct variable # First installation if [ $i -eq 1 ] then local multi_yunohost_result_1=$yunohost_result local ynh_app_id_1=$ynh_app_id # Second installation elif [ $i -eq 2 ] then local multi_yunohost_result_2=$yunohost_result local ynh_app_id_2=$ynh_app_id fi done # Try to access to the 2 apps by theirs url for i in 1 2 do # First app if [ $i -eq 1 ] then check_domain=$main_domain ynh_app_id=$ynh_app_id_1 # Second app elif [ $i -eq 2 ] then check_domain=$sub_domain ynh_app_id=$ynh_app_id_2 fi # Try to access the app by its url CHECK_URL # Check the result of curl test if [ $curl_error -ne 0 ] || [ $yuno_portal -ne 0 ] then # The test failed if curl fell on ynh portal or had an error. # First app if [ $i -eq 1 ] then multi_yunohost_result_1=1 # Second app elif [ $i -eq 2 ] then multi_yunohost_result_2=1 fi fi done # Check the result and print SUCCESS or FAIL # Succeed if the 2 installations work; if [ $multi_yunohost_result_1 -eq 0 ] && [ $multi_yunohost_result_2 -eq 0 ] then # Success check_success RESULT_check_multi_instance=1 else # Fail check_failed RESULT_check_multi_instance=-1 fi # Make a break if auto_remove is set break_before_continue } CHECK_COMMON_ERROR () { # Try to install with specific complications # $1 = install type local install_type=$1 if [ "$install_type" = "incorrect_path" ]; then unit_test_title "Malformed path..." # Check if the needed manifest key are set or abort the test check_manifest_key "path" || return else [ "$install_type" = "port_already_use" ] unit_test_title "Port already used..." # Check if the needed manifest key are set or abort the test check_manifest_key "port" || return fi # Check if an install have previously work is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Replace path manifest key for the test if [ "$install_type" = "incorrect_path" ]; then # Change the path from /path to path/ local wrong_path=${test_path#/}/ # Use this wrong path only for the arguments that will give to yunohost for installation. replace_manifest_key "path" "$wrong_path" local check_path=$test_path else [ "$install_type" = "port_already_use" ] # Use a path according to previous succeeded installs if [ $sub_dir_install -eq 1 ]; then local check_path=$test_path else local check_path=/ fi replace_manifest_key "path" "$check_path" fi # Open the specified port to force the script to find another if [ "$install_type" = "port_already_use" ] then # If the first character is a #, that means it this port number is not in the manifest if [ "${port_arg:0:1}" = "#" ] then # Retrieve the port number local check_port="${port_arg:1}" # Else, the port number is in the manifest. So the port number is set at a fixed value. else local check_port=6660 # Replace port manifest key for the test replace_manifest_key "port" "$check_port" fi # Build a service with netcat for use this port before the app. echo -e "[Service]\nExecStart=/bin/netcat -l -k -p $check_port\n [Install]\nWantedBy=multi-user.target" | \ sudo tee "/var/lib/lxc/$lxc_name/rootfs/etc/systemd/system/netcat.service" \ > /dev/null # Then start this service to block this port. LXC_START "sudo systemctl enable netcat & sudo systemctl start netcat" fi # Install the application in a LXC container SETUP_APP check_false_positive_error || return $? # Try to access the app by its url CHECK_URL # Check the result and print SUCCESS or FAIL if check_test_result then # Success local check_result_setup=1 else # Fail local check_result_setup=-1 fi # Fill the correct variable depend on the type of test if [ "$install_type" = "incorrect_path" ] then RESULT_check_path=$check_result_setup elif [ "$install_type" = "port_already_use" ]; then RESULT_check_port=$check_result_setup fi # Make a break if auto_remove is set break_before_continue } CHECK_BACKUP_RESTORE () { # Try to backup then restore the app unit_test_title "Backup/Restore..." # Check if an install have previously work is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Try in 2 times, first in root and second in sub path. local i=0 for i in 0 1 do # First, try with a root install if [ $i -eq 0 ] then # Check if root installation worked, or if force_install_ok is setted. if [ $root_install -eq 1 ] then # Replace manifest key for path local check_path=/ replace_manifest_key "path" "$check_path" ECHO_FORMAT "\nPreliminary installation on the root...\n" "white" "bold" clog else # Jump to the second path if this check cannot be do ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog continue fi # Second, try with a sub path install elif [ $i -eq 1 ] then # Check if sub path installation worked, or if force_install_ok is setted. if [ $sub_dir_install -eq 1 ] then # Replace manifest key for path local check_path=$test_path replace_manifest_key "path" "$check_path" ECHO_FORMAT "\nPreliminary installation in a sub path...\n" "white" "bold" clog else # Jump to the second path if this check cannot be do ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog return fi fi # Install the application in a LXC container STANDARD_SETUP_APP check_false_positive_error || return $? # Remove the previous residual backups sudo rm -rf /var/lib/lxc/$lxc_name/rootfs/home/yunohost.backup/archives sudo rm -rf /var/lib/lxcsnaps/$lxc_name/$current_snapshot/rootfs/home/yunohost.backup/archives # BACKUP # Made a backup if the installation succeed if [ $yunohost_result -ne 0 ] then ECHO_FORMAT "\nInstallation failed...\n" "red" "bold" else ECHO_FORMAT "\nBackup of the application...\n" "white" "bold" clog # Made a backup of the application LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug backup create -n Backup_test --apps $ynh_app_id --system $backup_hooks" # yunohost_result gets the return code of the backup yunohost_result=$? # Print the result of the backup command if [ $yunohost_result -eq 0 ]; then ECHO_FORMAT "Backup successful. ($yunohost_result)\n" "white" clog else ECHO_FORMAT "Backup failed. ($yunohost_result)\n" "white" clog fi # Check all the witness files, to verify if them still here check_witness_files # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? fi # Check the result and print SUCCESS or FAIL if [ $yunohost_result -eq 0 ] then # Success check_success # The global success for a backup can't be a success if another backup failed if [ $RESULT_check_backup -ne -1 ]; then RESULT_check_backup=1 # Backup succeed fi else # Fail check_failed RESULT_check_backup=-1 # Backup failed fi # Grab the backup archive into the LXC container, and keep a copy sudo cp -a /var/lib/lxc/$lxc_name/rootfs/home/yunohost.backup/archives ./ # RESTORE # Try the restore process in 2 times, first after removing the app, second after a restore of the container. local j=0 for j in 0 1 do # First, simply remove the application if [ $j -eq 0 ] then # Remove the application REMOVE_APP ECHO_FORMAT "\nRestore after removing the application...\n" "white" "bold" clog # Second, restore the whole container to remove completely the application elif [ $j -eq 1 ] then # Uses the default snapshot current_snapshot=snap0 # Remove the previous residual backups sudo rm -rf /var/lib/lxcsnaps/$lxc_name/$current_snapshot/rootfs/home/yunohost.backup/archives # Place the copy of the backup archive in the container. sudo mv -f ./archives /var/lib/lxcsnaps/$lxc_name/$current_snapshot/rootfs/home/yunohost.backup/ # Stop and restore the LXC container LXC_STOP ECHO_FORMAT "\nRestore on a clean YunoHost system...\n" "white" "bold" clog fi # Restore the application from the previous backup LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug backup restore Backup_test --force --apps $ynh_app_id" # yunohost_result gets the return code of the restore yunohost_result=$? # Print the result of the backup command if [ $yunohost_result -eq 0 ]; then ECHO_FORMAT "Restore successful. ($yunohost_result)\n" "white" clog else ECHO_FORMAT "Restore failed. ($yunohost_result)\n" "white" clog fi # Check all the witness files, to verify if them still here check_witness_files # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? # Try to access the app by its url CHECK_URL # Check the result and print SUCCESS or FAIL if check_test_result then # Success # The global success for a restore can't be a success if another restore failed if [ $RESULT_check_restore -ne -1 ]; then RESULT_check_restore=1 # Restore succeed fi else # Fail RESULT_check_restore=-1 # Restore failed fi # Make a break if auto_remove is set break_before_continue # Stop and restore the LXC container LXC_STOP done done } CHECK_CHANGE_URL () { # Try the change_url script unit_test_title "Change URL..." # Check if the needed manifest key are set or abort the test check_manifest_key "domain" || return # Check if an install have previously work is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Try in 6 times ! # Without modify the domain, root to path, path to path and path to root. # And then, same with a domain change local i=0 for i in `seq 1 7` do if [ $i -eq 1 ]; then # Same domain, root to path check_path=/ local new_path=$test_path local new_domain=$sub_domain elif [ $i -eq 2 ]; then # Same domain, path to path check_path=$test_path local new_path=${test_path}_2 local new_domain=$sub_domain elif [ $i -eq 3 ]; then # Same domain, path to root check_path=$test_path local new_path=/ local new_domain=$sub_domain elif [ $i -eq 4 ]; then # Other domain, root to path check_path=/ local new_path=$test_path local new_domain=$main_domain elif [ $i -eq 5 ]; then # Other domain, path to path check_path=$test_path local new_path=${test_path}_2 local new_domain=$main_domain elif [ $i -eq 6 ]; then # Other domain, path to root check_path=$test_path local new_path=/ local new_domain=$main_domain elif [ $i -eq 7 ]; then # Other domain, root to root check_path=/ local new_path=/ local new_domain=$main_domain fi replace_manifest_key "path" "$check_path" # Ignore the test if it tries to move to the same address if [ "$check_path" == "$new_path" ] && [ "$new_domain" == "$sub_domain" ]; then continue fi # Check if root or subpath installation worked, or if force_install_ok is setted. # Try with a sub path install if [ "$check_path" = "/" ] then if [ $root_install -eq 0 ] then # Jump this test ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog continue elif [ "$new_path" != "/" ] && [ $sub_dir_install -eq 0 ] then # Jump this test ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog continue fi # And with a sub path install else if [ $sub_dir_install -eq 0 ] then # Jump this test ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog continue elif [ "$new_path" = "/" ] && [ $root_install -eq 0 ] then # Jump this test ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog continue fi fi # Install the application in a LXC container ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog STANDARD_SETUP_APP check_false_positive_error || return $? # Check if the install had work if [ $yunohost_result -ne 0 ] then ECHO_FORMAT "Installation failed...\n" "red" "bold" else ECHO_FORMAT "Change the url from $sub_domain$check_path to $new_domain$new_path...\n" "white" "bold" clog # Change the url LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app change-url $ynh_app_id -d \"$new_domain\" -p \"$new_path\"" # yunohost_result gets the return code of the change-url script yunohost_result=$? # Print the result of the change_url command if [ $yunohost_result -eq 0 ]; then ECHO_FORMAT "Change_url script successful. ($yunohost_result)\n" "white" clog else ECHO_FORMAT "Change_url script failed. ($yunohost_result)\n" "white" clog fi # Check all the witness files, to verify if them still here check_witness_files # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? # Try to access the app by its url check_path=$new_path check_domain=$new_domain CHECK_URL fi # Check the result and print SUCCESS or FAIL if check_test_result then # Success # The global success for a change_url can't be a success if another change_url failed if [ $RESULT_change_url -ne -1 ]; then RESULT_change_url=1 # Change_url succeed fi else # Fail RESULT_change_url=-1 # Change_url failed fi # Make a break if auto_remove is set break_before_continue # Uses the default snapshot current_snapshot=snap0 # Stop and restore the LXC container LXC_STOP done } # Define a function to split a file in multiple parts. Used for actions and config-panel toml splitterAA() { local bound="$1" local file="$2" # If $2 is a real file if [ -e "$file" ] then # Replace name of the file by its content file="$(cat "$file")" fi local file_lenght=$(echo "$file" | wc --lines | awk '{print $1}') bounds=($(echo "$file" | grep --line-number --extended-regexp "$bound" | cut -d':' -f1)) # Go for each line number (boundary) into the array for line_number in $(seq 0 $(( ${#bounds[@]} -1 ))) do # The first bound is the next line number in the array # That the low bound on which we cut first_bound=$(( ${bounds[$line_number+1]} - 1 )) # If there's no next cell in the array, we got -1, in such case, use the lenght of the file. # We cut at the end of the file test $first_bound -lt 0 && first_bound=$file_lenght # The second bound is the current line number in the array minus the next one. # The the upper bound in the file. second_bound=$(( ${bounds[$line_number]} - $first_bound - 1 )) # Cut the file a first time from the beginning to the first bound # And a second time from the end, back to the second bound. parts[line_number]="$(echo "$file" | head --lines=$first_bound \ | tail --lines=$second_bound)" done } ACTIONS_CONFIG_PANEL () { # Try the actions and config-panel features test_type=$1 if [ "$test_type" == "actions" ] then unit_test_title "Actions..." toml_file="$package_path/actions.toml" if [ ! -e "$toml_file" ] then ECHO_FORMAT "\nNo actions.toml found !\n" "red" "bold" return 1 fi elif [ "$test_type" == "config_panel" ] then unit_test_title "Config-panel..." toml_file="$package_path/config_panel.toml" if [ ! -e "$toml_file" ] then ECHO_FORMAT "\nNo config_panel.toml found !\n" "red" "bold" return 1 fi fi # Check if the needed manifest key are set or abort the test check_manifest_key "domain" || return # Check if an install have previously work is_install_failed || return # Copy original arguments local manifest_args_mod="$manifest_arguments" # Replace manifest key for the test check_domain=$sub_domain replace_manifest_key "domain" "$check_domain" replace_manifest_key "user" "$test_user" replace_manifest_key "public" "$public_public_arg" # Use a path according to previous succeeded installs if [ $sub_dir_install -eq 1 ]; then local check_path=$test_path else local check_path=/ fi replace_manifest_key "path" "$check_path" # Install the application in a LXC container ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog STANDARD_SETUP_APP check_false_positive_error || return $? validate_action_config_panel() { # yunohost_result gets the return code of the command yunohost_result=$? local message="$1" # Print the result of the command if [ $yunohost_result -eq 0 ]; then ECHO_FORMAT "$message succeed. ($yunohost_result)\n" "white" clog else ECHO_FORMAT "$message failed. ($yunohost_result)\n" "white" clog fi # Check all the witness files, to verify if they're still there check_witness_files # Analyse the log to extract "warning" and "error" lines LOG_EXTRACTOR check_false_positive_error || return $? # Check the result and print SUCCESS or FAIL if check_test_result then # Success # The global success for a actions can't be a success if another iteration failed if [ $RESULT_action_config_panel -ne -1 ]; then RESULT_action_config_panel=1 # Actions succeed fi else # Fail RESULT_action_config_panel=-1 # Actions failed fi # Make a break if auto_remove is set break_before_continue } # List first, then execute local i=0 for i in `seq 1 2` do # Do a test if the installation succeed if [ $yunohost_result -ne 0 ] then ECHO_FORMAT "\nThe previous test has failed...\n" "red" "bold" else if [ $i -eq 1 ] then if [ "$test_type" == "actions" ] then ECHO_FORMAT "\n> List the available actions...\n" "white" "bold" clog # List the actions LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app action list $ynh_app_id" validate_action_config_panel "yunohost app action list" elif [ "$test_type" == "config_panel" ] then ECHO_FORMAT "\n> Show the config panel...\n" "white" "bold" clog # Show the config-panel LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app config show-panel $ynh_app_id" validate_action_config_panel "yunohost app config show-panel" fi elif [ $i -eq 2 ] then local parts if [ "$test_type" == "actions" ] then ECHO_FORMAT "\n> Execute the actions...\n" "white" "bold" clog # Split the actions.toml file to separate each actions splitterAA "^[[:blank:]]*\[[^.]*\]" "$toml_file" elif [ "$test_type" == "config_panel" ] then ECHO_FORMAT "\n> Apply configurations...\n" "white" "bold" clog # Split the config_panel.toml file to separate each configurations splitterAA "^[[:blank:]]*\[.*\]" "$toml_file" fi # Read each part, each action, one by one for part in $(seq 0 $(( ${#parts[@]} -1 ))) do local action_config_argument_name="" local action_config_argument_type="" local action_config_argument_default="" local actions_config_arguments_specifics="" local nb_actions_config_arguments_specifics=1 # Ignore part of the config_panel which are only titles if [ "$test_type" == "config_panel" ] then # A real config_panel part should have a `ask = ` line. Ignore the part if not. if ! echo "${parts[$part]}" | grep --quiet --extended-regexp "^[[:blank:]]*ask =" then continue fi # Get the name of the config. ask = "Config ?" local action_config_name="$(echo "${parts[$part]}" | grep "ask *= *" | sed 's/^.* = \"\(.*\)\"/\1/')" # Get the config argument name "YNH_CONFIG_part1_part2.part3.partx" local action_config_argument_name="$(echo "${parts[$part]}" | grep "^[[:blank:]]*\[.*\]$")" # Remove [] action_config_argument_name="${action_config_argument_name//[\[\]]/}" # And remove spaces action_config_argument_name="${action_config_argument_name// /}" elif [ "$test_type" == "actions" ] then # Get the name of the action. name = "Name of the action" local action_config_name="$(echo "${parts[$part]}" | grep "name" | sed 's/^.* = \"\(.*\)\"/\1/')" # Get the action. [action] local action_config_action="$(echo "${parts[$part]}" | grep "^\[.*\]$" | sed 's/\[\(.*\)\]/\1/')" fi # Check if there's any [action.arguments] # config_panel always have arguments. if echo "${parts[$part]}" | grep --quiet "$action_config_action\.arguments" || [ "$test_type" == "config_panel" ] then local action_config_has_arguments=1 else local action_config_has_arguments=0 fi # If there's arguments for this action. if [ $action_config_has_arguments -eq 1 ] then if [ "$test_type" == "actions" ] then # Get the argument [action.arguments.name_of_the_argument] action_config_argument_name="$(echo "${parts[$part]}" | grep "$action_config_action\.arguments\." | sed 's/.*\.\(.*\)]/\1/')" fi # Get the type of the argument. type = "type" action_config_argument_type="$(echo "${parts[$part]}" | grep "type" | sed 's/^.* = \"\(.*\)\"/\1/')" # Get the default value of this argument. default = true action_config_argument_default="$(echo "${parts[$part]}" | grep "default" | sed 's/^.* = \(.*\)/\1/')" # Do not use true or false, use 1/0 instead if [ "$action_config_argument_default" == "true" ] && [ "$action_config_argument_type" == "boolean" ]; then action_config_argument_default=1 elif [ "$action_config_argument_default" == "false" ] && [ "$action_config_argument_type" == "boolean" ]; then action_config_argument_default=0 fi if [ "$test_type" == "config_panel" ] then local check_process_arguments="$config_panel_arguments" elif [ "$test_type" == "actions" ] then local check_process_arguments="$actions_arguments" fi # Look for arguments into the check_process if echo "$check_process_arguments" | grep --quiet "$action_config_argument_name" then # If there's arguments for this actions into the check_process # Isolate the values actions_config_arguments_specifics="$(echo "$check_process_arguments" | sed "s/.*$action_config_argument_name=\(.*\)/\1/")" # And remove values of the following action actions_config_arguments_specifics="${actions_config_arguments_specifics%%\:*}" nb_actions_config_arguments_specifics=$(( $(echo "$actions_config_arguments_specifics" | tr --complement --delete "|" | wc --chars) + 1 )) fi if [ "$test_type" == "config_panel" ] then # Finish to format the name # Remove . by _ action_config_argument_name="${action_config_argument_name//./_}" # Move all characters to uppercase action_config_argument_name="${action_config_argument_name^^}" # Add YNH_CONFIG_ action_config_argument_name="YNH_CONFIG_$action_config_argument_name" fi fi # Loop on the number of values into the check_process. # Or loop once for the default value for j in `seq 1 $nb_actions_config_arguments_specifics` do local action_config_argument_built="" if [ $action_config_has_arguments -eq 1 ] then # If there's values into the check_process if [ -n "$actions_config_arguments_specifics" ] then # Build the argument from a value from the check_process local action_config_actual_argument="$(echo "$actions_config_arguments_specifics" | cut -d'|' -f $j)" action_config_argument_built="--args $action_config_argument_name=\"$action_config_actual_argument\"" elif [ -n "$action_config_argument_default" ] then # Build the argument from the default value local action_config_actual_argument="$action_config_argument_default" action_config_argument_built="--args $action_config_argument_name=\"$action_config_actual_argument\"" else ECHO_FORMAT "\n> No argument into the check_process to use or default argument for \"$action_config_name\"..." "lyellow" "bold" clog action_config_actual_argument="" fi if [ "$test_type" == "config_panel" ] then ECHO_FORMAT "\n> Apply the configuration for \"$action_config_name\" with the argument \"$action_config_actual_argument\"...\n" "white" "bold" clog elif [ "$test_type" == "actions" ] then ECHO_FORMAT "\n> Execute the action \"$action_config_name\" with the argument \"$action_config_actual_argument\"...\n" "white" "bold" clog fi else ECHO_FORMAT "\n> Execute the action \"$action_config_name\"...\n" "white" "bold" clog fi if [ "$test_type" == "config_panel" ] then # Aply a configuration LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app config apply $ynh_app_id $action_config_action $action_config_argument_built" elif [ "$test_type" == "actions" ] then # Execute an action LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app action run $ynh_app_id $action_config_action $action_config_argument_built" fi validate_action_config_panel "yunohost action $action_config_action" done done fi fi done # Uses the default snapshot current_snapshot=snap0 # Stop and restore the LXC container LXC_STOP } PACKAGE_LINTER () { # Package linter unit_test_title "Package linter..." # Execute package linter and linter_result gets the return code of the package linter "$script_dir/package_linter/package_linter.py" "$package_path" > "$temp_result" # linter_result gets the return code of the package linter local linter_result=$? # Print the results of package linter and copy these result in the complete log cat "$temp_result" | tee --append "$complete_log" # Check the result and print SUCCESS or FAIL if [ $linter_result -eq 0 ] then # Success check_success RESULT_linter=1 else # Fail check_failed RESULT_linter=-1 # If return code is 2, this is critical failure, app should be considered as broken (level 0) if [ $linter_result -eq 2 ] then RESULT_linter=-2 fi fi } TEST_LAUNCHER () { # Abstract for test execution. # $1 = Name of the function to execute # $2 = Argument for the function # Intialize values yunohost_result=-1 yunohost_remove=-1 false_positive_error=0 max_false_positive_error_loop=3 for false_positive_error_loop in $( seq 1 $max_false_positive_error_loop ) do # Start the timer for this test start_timer # And keep this value separately local global_start_timer=$starttime # Execute the test $1 $2 if [ $false_positive_error -eq 1 ] then ECHO_FORMAT "This test was aborted because of a $false_positive_error_cond error.\n" "red" "bold" clog if [ $false_positive_error_loop -lt $max_false_positive_error_loop ] then ECHO_FORMAT "The test will restart.\n" "lyellow" "bold" clog cur_test=$((cur_test-1)) fi fi # Uses the default snapshot current_snapshot=snap0 # Stop and restore the LXC container LXC_STOP # Restore the started time for the timer starttime=$global_start_timer # End the timer for the test stop_timer 2 # Update the lock file with the date of the last finished test. # $$ is the PID of package_check itself. echo "$1 $2:$(date +%s):$$" > "$lock_file" # Exit the loop if there's no temporary errors detected. if [ $false_positive_error -eq 0 ] then break fi done } set_witness_files () { # Create files to check if the remove script does not remove them accidentally echo "Create witness files..." | tee --append "$test_result" lxc_dir="/var/lib/lxc/$lxc_name/rootfs" create_witness_file () { [ "$2" = "file" ] && local action="touch" || local action="mkdir -p" sudo $action "${lxc_dir}${1}" } # Nginx conf create_witness_file "/etc/nginx/conf.d/$main_domain.d/witnessfile.conf" file create_witness_file "/etc/nginx/conf.d/$sub_domain.d/witnessfile.conf" file # /etc create_witness_file "/etc/witnessfile" file # /opt directory create_witness_file "/opt/witnessdir" directory # /var/www directory create_witness_file "/var/www/witnessdir" directory # /home/yunohost.app/ create_witness_file "/home/yunohost.app/witnessdir" directory # /var/log create_witness_file "/var/log/witnessfile" file # Config fpm if [ -d "${lxc_dir}/etc/php5/fpm" ]; then create_witness_file "/etc/php5/fpm/pool.d/witnessfile.conf" file fi if [ -d "${lxc_dir}/etc/php/7.0/fpm" ]; then create_witness_file "/etc/php/7.0/fpm/pool.d/witnessfile.conf" file fi if [ -d "${lxc_dir}/etc/php/7.3/fpm" ]; then create_witness_file "/etc/php/7.3/fpm/pool.d/witnessfile.conf" file fi # Config logrotate create_witness_file "/etc/logrotate.d/witnessfile" file # Config systemd create_witness_file "/etc/systemd/system/witnessfile.service" file # Database sudo lxc-attach --name=$lxc_name -- mysqladmin --user=root --password=$(sudo cat "$lxc_dir/etc/yunohost/mysql") --wait status > /dev/null 2>&1 sudo lxc-attach --name=$lxc_name -- mysql --user=root --password=$(sudo cat "$lxc_dir/etc/yunohost/mysql") --wait --execute="CREATE DATABASE witnessdb" > /dev/null 2>&1 } check_witness_files () { # Check all the witness files, to verify if them still here lxc_dir="/var/lib/lxc/$lxc_name/rootfs" check_file_exist () { if sudo test ! -e "${lxc_dir}${1}" then ECHO_FORMAT "The file $1 is missing ! Something gone wrong !\n" "red" "bold" RESULT_witness=1 fi } # Nginx conf check_file_exist "/etc/nginx/conf.d/$main_domain.d/witnessfile.conf" check_file_exist "/etc/nginx/conf.d/$sub_domain.d/witnessfile.conf" # /etc check_file_exist "/etc/witnessfile" # /opt directory check_file_exist "/opt/witnessdir" # /var/www directory check_file_exist "/var/www/witnessdir" # /home/yunohost.app/ check_file_exist "/home/yunohost.app/witnessdir" # /var/log check_file_exist "/var/log/witnessfile" # Config fpm if [ -d "${lxc_dir}/etc/php5/fpm" ]; then check_file_exist "/etc/php5/fpm/pool.d/witnessfile.conf" file fi if [ -d "${lxc_dir}/etc/php/7.0/fpm" ]; then check_file_exist "/etc/php/7.0/fpm/pool.d/witnessfile.conf" file fi if [ -d "${lxc_dir}/etc/php/7.3/fpm" ]; then check_file_exist "/etc/php/7.3/fpm/pool.d/witnessfile.conf" file fi # Config logrotate check_file_exist "/etc/logrotate.d/witnessfile" # Config systemd check_file_exist "/etc/systemd/system/witnessfile.service" # Database if ! sudo lxc-attach --name=$lxc_name -- mysqlshow --user=root --password=$(sudo cat "$lxc_dir/etc/yunohost/mysql") | grep --quiet '^| witnessdb' > /dev/null 2>&1 then ECHO_FORMAT "The database witnessdb is missing ! Something gone wrong !\n" "red" "bold" RESULT_witness=1 fi if [ $RESULT_witness -eq 1 ] then yunohost_result=1 yunohost_remove=1 fi } TESTING_PROCESS () { # Launch all tests successively ECHO_FORMAT "\nTests serie: ${tests_serie#;; }\n\n" "white" "underlined" clog PRINT_YUNOHOST_VERSION # Init the value for the current test cur_test=1 # By default, all tests will try to access the app with curl use_curl=1 # Check the package with package linter if [ $pkg_linter -eq 1 ]; then PACKAGE_LINTER fi # Try to install in a sub path if [ $setup_sub_dir -eq 1 ]; then TEST_LAUNCHER CHECK_SETUP subdir fi # Try to install on root if [ $setup_root -eq 1 ]; then TEST_LAUNCHER CHECK_SETUP root fi # Try to install without url access if [ $setup_nourl -eq 1 ]; then TEST_LAUNCHER CHECK_SETUP no_url fi # Try the upgrade script if [ $upgrade -eq 1 ]; then TEST_LAUNCHER CHECK_UPGRADE fi # Try to install in private mode if [ $setup_private -eq 1 ]; then TEST_LAUNCHER CHECK_PUBLIC_PRIVATE private fi # Try to install in public mode if [ $setup_public -eq 1 ]; then TEST_LAUNCHER CHECK_PUBLIC_PRIVATE public fi # Try multi-instance installations if [ $multi_instance -eq 1 ]; then TEST_LAUNCHER CHECK_MULTI_INSTANCE fi # Try to install with an malformed path if [ $incorrect_path -eq 1 ]; then TEST_LAUNCHER CHECK_COMMON_ERROR incorrect_path fi # Try to install with a port already used if [ $port_already_use -eq 1 ]; then TEST_LAUNCHER CHECK_COMMON_ERROR port_already_use fi # Try to backup then restore the app if [ $backup_restore -eq 1 ]; then TEST_LAUNCHER CHECK_BACKUP_RESTORE fi # Try the change_url script if [ $change_url -eq 1 ]; then TEST_LAUNCHER CHECK_CHANGE_URL fi # Try the actions if [ $actions -eq 1 ]; then TEST_LAUNCHER ACTIONS_CONFIG_PANEL actions fi # Try the config-panel if [ $config_panel -eq 1 ]; then TEST_LAUNCHER ACTIONS_CONFIG_PANEL config_panel fi }