package_check/package_check.sh
Maniack Crudelis f663f69f27 Snapshots instead of multiple installations
Usage de snapshot pour les installations de base.
Réduit la durée des tests en évitant de réinstaller l'application plusieurs fois avec les mêmes paramètres.
2017-05-10 22:47:23 +02:00

1288 lines
36 KiB
Bash
Executable file

#!/bin/bash
#=================================================
# Grab the script directory
#=================================================
if [ "${0:0:1}" == "/" ]; then script_dir="$(dirname "$0")"; else script_dir="$(echo $PWD/$(dirname "$0" | cut -d '.' -f2) | sed 's@/$@@')"; fi
#=================================================
# Starting and checking
#=================================================
# Generic functions
#=================================================
clean_exit () {
# Exit and remove all temp files
# $1 = exit code
# Deactivate LXC network
LXC_TURNOFF
# Remove temporary files
rm -f "$temp_log"
rm -f "$temp_result"
rm -f "$script_dir/url_output"
rm -f "$script_dir/curl_print"
rm -f "$script_dir/manifest_extract"
# Remove the application which been tested
if [ -n "$package_path" ]; then
rm -rf "$package_path"
fi
# Remove the lock file
rm -f "$lock_file"
exit $1
}
#=================================================
# Check and read CLI arguments
#=================================================
echo ""
# Init arguments value
gitbranch=""
force_install_ok=0
interrupt=0
notice=0
build_lxc=0
bash_mode=0
# If no arguments provided
if [ "$#" -eq 0 ]
then
# Print the help and exit
notice=1
else
# Reduce the arguments for getopts
arguments="$*"
arguments=${arguments//--branch=/-b }
arguments=${arguments//--force-install-ok/-f}
arguments=${arguments//--interrupt/-i}
arguments=${arguments//--help/-h}
arguments=${arguments//--build-lxc/-l}
arguments=${arguments//--bash-mode/-y}
# Read and parse all the arguments
# Use a function here, to use standart arguments $@ and use more simply getopts and shift.
parse_arg () {
while [ $# -ne 0 ]
do
# Initialize the index of getopts
OPTIND=1
# Parse with getopts only if the argument begin by -
if [ ${1:0:1} = "-" ]
then
getopts ":b:fihly " parameter
case $parameter in
b)
# --branch=branch-name
gitbranch="$OPTARG"
;;
f)
# --force-install-ok
force_install_ok=1
;;
i)
# --interrupt
interrupt=1
;;
h)
# --help
notice=1
;;
l)
# --build-lxc
build_lxc=1
;;
y)
# --bash-mode
bash_mode=1
;;
\?)
echo "Invalid argument: -$OPTARG" >&2
notice=1
;;
:)
echo "-$OPTARG parameter requires an argument." >&2
notice=1
;;
esac
else
app_arg="$1"
fi
shift
done
}
# Call parse_arg and pass the modified list of args.
parse_arg $arguments
fi
# Prevent a conflict between --interrupt and --bash-mode
if [ $interrupt -eq 1 ] && [ $bash_mode -eq 1 ]
then
echo "You can't use --interrupt and --bash-mode together !"
notice=1
fi
# Print help
if [ $notice -eq 1 ]
then
cat << EOF
Usage:
package_check.sh [OPTION]... PACKAGE_TO_CHECK
-b, --branch=BRANCH
Specify a branch to check.
-f, --force-install-ok
Force following test even if all install have failed.
-i, --interrupt
Force auto_remove value, break before each remove.
-h, --help
Display this notice.
-l, --build-lxc
Install LXC and build the container if necessary.
-y, --bash-mode
Do not ask for continue check. Ignore auto_remove.
EOF
exit 0
fi
#=================================================
# Check if the lock file exist
#=================================================
lock_file="$script_dir/pcheck.lock"
if test -e "$lock_file"
then
# If the lock file exist
echo "The lock file $lock_file is present. Package check would not continue."
if [ $bash_mode -ne 1 ]; then
echo -n "Do you want to continue anymore? (y/n) :"
read answer
fi
# Set the answer at lowercase only
answer=${answer,,}
if [ "${answer:0:1}" != "y" ]
then
echo "Cancel Package check execution"
exit 0
fi
fi
# Create the lock file
touch "$lock_file"
#=================================================
# Check the internet connectivity
#=================================================
# Try to ping yunohost.org
ping -q -c 2 yunohost.org > /dev/null 2>&1
if [ "$?" -ne 0 ]; then
# If fail, try to ping another domain
ping -q -c 2 framasoft.org > /dev/null 2>&1
if [ "$?" -ne 0 ]; then
# If ping failed twice, it's seems the internet connection is down.
echo "\e[91mUnable to connect to internet.\e[0m"
# Remove the lock file
rm -f "$lock_file"
# And exit
exit 1
fi
fi
#=================================================
# Upgrade Package check
#=================================================
git_repository=https://github.com/YunoHost/package_check
version_file="$script_dir/pcheck_version"
check_version="$(git ls-remote $git_repository | cut -f 1 | head -n1)"
# If the version file exist, check for an upgrade
if [ -e "$version_file" ]
then
# Check if the last commit on the repository match with the current version
if [ "$check_version" != "$(cat "$version_file")" ]
then
# If the versions don't matches. Do an upgrade
echo -e "\e[97m\e[1mUpgrade Package check...\n\e[0m"
# Build the upgrade script
cat > "$script_dir/upgrade_script.sh" << EOF
#!/bin/bash
# Clone in another directory
git clone --quiet $git_repository "$script_dir/upgrade"
cp -a "$script_dir/upgrade/." "$script_dir/."
rm -r "$script_dir/upgrade"
# Update the version file
echo "$check_version" > "$version_file"
rm "$script_dir/pcheck.lock"
# Execute package check by replacement of this process
exec "$script_dir/package_check.sh" "$arguments"
EOF
# Give the execution right
chmod +x "$script_dir/upgrade_script.sh"
# Start the upgrade script by replacement of this process
exec "$script_dir/upgrade_script.sh"
fi
fi
# Update the version file
echo "$check_version" > "$version_file"
#=================================================
# Upgrade Package linter
#=================================================
git_repository=https://github.com/YunoHost/package_linter
version_file="$script_dir/plinter_version"
check_version="$(git ls-remote $git_repository | cut -f 1 | head -n1)"
# If the version file exist, check for an upgrade
if [ -e "$version_file" ]
then
# Check if the last commit on the repository match with the current version
if [ "$check_version" != "$(cat "$version_file")" ]
then
# If the versions don't matches. Do an upgrade
echo -e "\e[97m\e[1mUpgrade Package linter...\n\e[0m"
# Clone in another directory
git clone --quiet https://github.com/YunoHost/package_linter "$script_dir/package_linter_tmp"
# And replace
cp -a "$script_dir/package_linter_tmp/." "$script_dir/package_linter/."
sudo rm -r "$script_dir/package_linter_tmp"
fi
else
echo -e "\e[97mInstall Package linter.\n\e[0m"
git clone --quiet $git_repository "$script_dir/package_linter"
fi
# Update the version file
echo "$check_version" > "$version_file"
#=================================================
# Get variables from the config file
#=================================================
pcheck_config="$script_dir/config"
build_script="$script_dir/sub_scripts/lxc_build.sh"
if [ -e "$pcheck_config" ]
then
# Read the config file if it exists
ip_range=$(grep PLAGE_IP= "$pcheck_config" | cut -d '=' -f2)
main_domain=$(grep DOMAIN= "$pcheck_config" | cut -d '=' -f2)
yuno_pwd=$(grep YUNO_PWD= "$pcheck_config" | cut -d '=' -f2)
lxc_name=$(grep LXC_NAME= "$pcheck_config" | cut -d '=' -f2)
lxc_bridge=$(grep LXC_BRIDGE= "$pcheck_config" | cut -d '=' -f2)
main_iface=$(grep iface= "$pcheck_config" | cut -d '=' -f2)
fi
# Use default value from the build script if needed
if [ -z "$ip_range" ]; then
ip_range=$(grep "|| PLAGE_IP=" "$build_script" | cut -d '"' -f4)
echo -e "# Ip range for the container\nPLAGE_IP=$ip_range\n" >> "$pcheck_config"
fi
if [ -z "$main_domain" ]; then
main_domain=$(grep "|| DOMAIN=" "$build_script" | cut -d '=' -f2)
echo -e "# Test domain\nDOMAIN=$main_domain\n" >> "$pcheck_config"
fi
if [ -z "$yuno_pwd" ]; then
yuno_pwd=$(grep "|| YUNO_PWD=" "$build_script" | cut -d '=' -f2)
echo -e "# YunoHost password, in the container\nYUNO_PWD=$yuno_pwd\n" >> "$pcheck_config"
fi
if [ -z "$lxc_name" ]; then
lxc_name=$(grep "|| LXC_NAME=" "$build_script" | cut -d '=' -f2)
echo -e "# Container name\nLXC_NAME=$lxc_name\n" >> "$pcheck_config"
fi
if [ -z "$lxc_bridge" ]; then
lxc_bridge=$(grep "|| LXC_BRIDGE=" "$build_script" | cut -d '=' -f2)
echo -e "# Bridge name\nLXC_BRIDGE=$lxc_bridge\n" >> "$pcheck_config"
fi
if [ -z "$main_iface" ]; then
# Try to determine the main iface
main_iface=$(sudo route | grep default | awk '{print $8;}')
if [ -z $main_iface ]
then
echo -e "\e[91mUnable to find the name of the main iface.\e[0m"
# Remove the lock file
rm -f "$lock_file"
# And exit
exit 1
fi
# Store the main iface in the config file
echo -e "# Main host iface\niface=$main_iface\n" >> "$pcheck_config"
fi
#=================================================
# Check the user who try to execute this script
#=================================================
setup_user_file="$script_dir/sub_scripts/setup_user"
if [ -e "$setup_user_file" ]
then
# Compare the current user and the user stored in $setup_user_file
authorised_user="$(cat "$setup_user_file")"
if [ "$(whoami)" != "$authorised_user" ]
then
echo -e "\e[91mThis script need to be executed by the user $setup_user_file !\nThe current user is $(whoami).\e[0m"
clean_exit 1
fi
else
echo -e "\e[93mUnable to define the user who authorised to use package check. Please fill the file $setup_user_file\e[0m"
fi
#=================================================
# Define globals variables
#=================================================
# Complete result log. Complete log of YunoHost
complete_log="$script_dir/Complete.log"
# Partial YunoHost log, just the log for the current test
temp_log="$script_dir/temp_yunohost-cli.log"
# Temporary result log
temp_result="$script_dir/temp_result.log"
# Result log with warning and error only
test_result="$script_dir/Test_results.log"
# Real YunoHost log
yunohost_log="/var/lib/lxc/$lxc_name/rootfs/var/log/yunohost/yunohost-cli.log"
sub_domain="sous.$main_domain"
test_user=package_checker
#=================================================
# Load all functions
#=================================================
source "$script_dir/sub_scripts/launcher.sh"
source "$script_dir/sub_scripts/testing_process.sh"
source "$script_dir/sub_scripts/log_extractor.sh"
source /usr/share/yunohost/helpers
#=================================================
# Check LXC
#=================================================
# Check if lxc is already installed
if dpkg-query -W -f '${Status}' "lxc" 2>/dev/null | grep -q "ok installed"
then
# If lxc is installed, check if the container is already built.
if ! sudo lxc-ls | grep -q "$lxc_name"
then
if [ $build_lxc -eq 1 ]
then
# If lxc's not installed and build_lxc set. Asks to build the container.
build_lxc=2
else
ECHO_FORMAT "LXC is not installed or the container $lxc_name doesn't exist.\n" "red"
ECHO_FORMAT "Use the script 'lxc_build.sh' to fix them.\n" "red"
clean_exit 1
fi
fi
elif [ $build_lxc -eq 1 ]
then
# If lxc's not installed and build_lxc set. Asks to build the container.
build_lxc=2
fi
if [ $build_lxc -eq 2 ]
then
# Install LXC and build the container before continue.
"$script_dir/sub_scripts/lxc_build.sh"
fi
# Stop and restore the LXC container. In case of previous incomplete execution.
LXC_STOP
# Deactivate LXC network
LXC_TURNOFF
#=================================================
# Determine if it's a CI environment
#=================================================
# By default, it's a standalone execution.
type_exec_env=0
if [ -e "$script_dir/../config" ]
then
# CI environment
type_exec_env=1
fi
if [ -e "$script_dir/../auto_build/auto.conf" ]
then
# Official CI environment
type_exec_env=2
fi
#=================================================
# Pick up the package
#=================================================
echo "Pick up the package which will be tested."
# Remove the previous package if it's still here.
rm -rf "$script_dir"/*_check
package_dir="$(basename "$app_arg")_check"
package_path="$script_dir/$package_dir"
# If the package is in a git repository
if echo "$app_arg" | grep -Eq "https?:\/\/"
then
# Clone the repository
git clone $app_arg $gitbranch "$package_path"
# If it's a local directory
else
# Do a copy in the directory of Package check
cp -a "$app_arg" "$package_path"
fi
# Check if the package directory is really here.
if [ ! -d "$package_path" ]; then
ECHO_FORMAT "Unable to find the directory $package_path for the package...\n" "red"
clean_exit 1
fi
# Remove the .git directory.
rm -rf "$package_path/.git"
#=================================================
# Determine and print the results
#=================================================
TEST_RESULTS () {
# Print the test result
print_result () {
# Print the name of the test
ECHO_FORMAT "$1: "
# Complete with spaces according to the lenght of the previous string. To align the results
local i=0
for i in `seq ${#1} 30`
do
echo -n " "
done
# Print the result of this test
if [ $2 -eq 1 ]
then
ECHO_FORMAT "SUCCESS\n" "lgreen"
elif [ $2 -eq -1 ]
then
ECHO_FORMAT "FAIL\n" "red"
else
ECHO_FORMAT "Not evaluated.\n" "white"
fi
}
# Print the result for each test
echo -e "\n\n"
print_result "Package linter" $RESULT_linter
print_result "Installation" $RESULT_global_setup
print_result "Deleting" $RESULT_global_remove
print_result "Installation in a sub path" $RESULT_check_sub_dir
print_result "Deleting from a sub path" $RESULT_check_remove_sub_dir
print_result "Installation on the root" $RESULT_check_root
print_result "Deleting from root" $RESULT_check_remove_root
print_result "Upgrade" $RESULT_check_upgrade
print_result "Installation in private mode" $RESULT_check_private
print_result "Installation in public mode" $RESULT_check_public
print_result "Multi-instance installations" $RESULT_check_multi_instance
print_result "Malformed path" $RESULT_check_path
print_result "Port already used" $RESULT_check_port
print_result "Backup" $RESULT_check_backup
print_result "Restore" $RESULT_check_restore
print_result "Change URL" $RESULT_change_url
# Determine the level for this app
# Each level can has 5 different values
# 0 -> If this level can't be validated
# 1 -> If this level is forced. Even if the tests fails
# 2 -> Indicates the tests had previously validated this level
# auto -> This level has not a value yet.
# na -> This level will not checked, but it'll be ignored in the final sum
# Set default values for level, if they're empty.
test -n "${level[1]}" || level[1]=auto
test -n "${level[2]}" || level[2]=auto
test -n "${level[3]}" || level[3]=auto
test -n "${level[4]}" || level[4]=0
test -n "${level[5]}" || level[5]=auto
test -n "${level[6]}" || level[6]=auto
test -n "${level[7]}" || level[7]=auto
test -n "${level[8]}" || level[8]=0
test -n "${level[9]}" || level[9]=0
test -n "${level[10]}" || level[10]=0
# Check if the level can be changed
level_can_change () {
# If the level is set at auto, it's waiting for a change
# And if it's set at 2, its value can be modified by a new result
if [ "${level[$1]}" == "auto" ] || [ "${level[$1]}" -eq 2 ]
then
return 0
fi
return 1
}
# Evaluate the first level
# -> The package can be install and remove.
if level_can_change 1
then
# Validated if at least one install and remove work fine
if [ $RESULT_global_setup -eq 1 ] && \
[ $RESULT_global_remove -eq 1 ]
then level[1]=2
else level[1]=0
fi
fi
# Evaluate the second level
# -> The package can be install and remove in all tested configurations.
if level_can_change 2
then
# Validated if none install failed
if [ $RESULT_check_sub_dir -ne -1 ] && \
[ $RESULT_check_remove_sub_dir -ne -1 ] && \
[ $RESULT_check_root -ne -1 ] && \
[ $RESULT_check_remove_root -ne -1 ] && \
[ $RESULT_check_private -ne -1 ] && \
[ $RESULT_check_public -ne -1 ] && \
[ $RESULT_check_multi_instance -ne -1 ]
then level[2]=2
else level[2]=0
fi
fi
# Evaluate the third level
# -> The package can be upgraded from the same version.
if level_can_change 3
then
# Validated if the upgrade is ok. Or if the upgrade has been not tested but already validated before.
if [ $RESULT_check_upgrade -eq 1 ] || \
( [ $RESULT_check_upgrade -ne -1 ] && \
[ "${level[3]}" == "2" ] )
then level[3]=2
else level[3]=0
fi
fi
# Evaluate the fifth level
# -> The package have no error with package linter
if level_can_change 5
then
# Validated if Linter is ok. Or if Linter has been not tested but already validated before.
if [ $RESULT_linter -eq 1 ] || \
( [ $RESULT_linter -ne -1 ] && \
[ "${level[5]}" == "2" ] )
then level[5]=2
else level[5]=0
fi
fi
# Evaluate the sixth level
# -> The package can be backup and restore without error
if level_can_change 6
then
# Check the YEP 1.7 (https://github.com/YunoHost/doc/blob/master/packaging_apps_guidelines_fr.md#yep-17---ajouter-lapp-%C3%A0-lorganisation-yunohost-apps---valid%C3%A9--manuel--official-)
# Default value, YEP 1.7 not checked
YEP17=-1
if echo "$app_arg" | grep --extended-regexp --quiet "https?:\/\/"
then
# If the app have been picked from github, check if this app was under the YunoHost-Apps organisation
# YEP17 will be equal to 1 if the app was under the YunoHost-Apps organisation
YEP17=$(echo "$app_arg" | grep --ignore-case --count "github.com/YunoHost-Apps/")
[ $YEP17 -eq 1 ] || ECHO_FORMAT "This app doesn't respect the YEP 1.7 ! (https://yunohost.org/#/packaging_apps_guidelines_fr)\n" "red"
fi
# Validated if backup and restore are ok. Or if backup and restore have been not tested but already validated before.
if ( [ $RESULT_check_backup -eq 1 ] && \
[ $RESULT_check_restore -eq 1 ] ) || \
( [ $RESULT_check_backup -ne -1 ] && \
[ $RESULT_check_restore -ne -1 ] && \
[ "${level[6]}" == "2" ] ) && \
[ $YEP17 -ne 0 ]
then level[6]=2
else level[6]=0
fi
fi
# Evaluate the seventh level
# -> None errors in all tests performed
if level_can_change 7
then
# Validated if none errors is happened.
if [ $RESULT_global_setup -ne -1 ] && \
[ $RESULT_global_remove -ne -1 ] && \
[ $RESULT_check_sub_dir -ne -1 ] && \
[ $RESULT_check_remove_sub_dir -ne -1 ] && \
[ $RESULT_check_remove_root -ne -1 ] && \
[ $RESULT_check_upgrade -ne -1 ] && \
[ $RESULT_check_private -ne -1 ] && \
[ $RESULT_check_public -ne -1 ] && \
[ $RESULT_check_multi_instance -ne -1 ] && \
[ $RESULT_check_path -ne -1 ] && \
[ $RESULT_check_port -ne -1 ] && \
[ $RESULT_check_backup -ne -1 ] && \
[ $RESULT_check_restore -ne -1 ] && \
[ $RESULT_change_url -ne -1 ]
then level[7]=2
else level[7]=0
fi
fi
# Initialize the global level
global_level=0
# Calculate the final level
for i in `seq 1 10`
do
# If there is a level still at 'auto', it's a mistake.
if [ "${level[i]}" == "auto" ]
then
# So this level will set at 0.
level[i]=0
# If the level is at 'na', it will be ignored
elif [ "${level[i]}" == "na" ]
then
continue
# If the level is at 1 or 2. The global level will be set at this level
elif [ "${level[i]}" -ge 1 ]
then
global_level=$i
# But, if the level is at 0, the loop stop here
# Like that, the global level rise while none level have failed
else
break
fi
done
# If some witness files was missing, it's a big error ! So, the level fall immediately at 0.
if [ $RESULT_witness -eq 1 ]
then
ECHO_FORMAT "Some witness files has been deleted during those tests ! It's a very bad thing !\n" "red" "bold"
global_level=0
fi
# Then, print the levels
# Print the global level
ECHO_FORMAT "Level of this application: $global_level\n" "white" "bold"
# And print the value for each level
for i in `seq 1 10`
do
ECHO_FORMAT "\t Level $i: "
if [ "${level[$i]}" == "na" ]; then
ECHO_FORMAT "N/A\n"
elif [ "${level[$i]}" -ge 1 ]; then
ECHO_FORMAT "1\n" "white" "bold"
else
ECHO_FORMAT "0\n"
fi
done
}
#=================================================
# Parsing and performing tests
#=================================================
# Check if a check_process file exist
#=================================================
check_file=1
check_process="$package_path/check_process"
if [ ! -e "$check_process" ]
then
ECHO_FORMAT "\nUnable to find a check_process file.\n" "red"
ECHO_FORMAT "Package check will be used in lower mode.\n" "lyellow"
check_file=0
fi
#=================================================
# Initialize tests
#=================================================
# Purge some log files
> "$complete_log"
> "$test_result"
> "$script_dir/lxc_boot.log"
# Initialize LXC network
LXC_INIT
# Default values for check_process and TESTING_PROCESS
initialize_values() {
# Test results
RESULT_witness=0
RESULT_linter=0
RESULT_global_setup=0
RESULT_global_remove=0
RESULT_check_sub_dir=0
RESULT_check_root=0
RESULT_check_remove_sub_dir=0
RESULT_check_remove_root=0
RESULT_check_upgrade=0
RESULT_check_backup=0
RESULT_check_restore=0
RESULT_check_private=0
RESULT_check_public=0
RESULT_check_multi_instance=0
RESULT_check_path=0
RESULT_check_port=0
RESULT_change_url=0
# auto_remove parameter
if [ $interrupt -eq 1 ]; then
auto_remove=0
else
auto_remove=1
fi
# Number of tests to proceed
all_test=0
# Default path
test_path=/check
}
#=================================================
# Parse the check_process
#=================================================
# Parse the check_process only if it's exist
if [ $check_file -eq 1 ]
then
ECHO_FORMAT "Parsing of check_process file\n"
# Remove all commented lines in the check_process
sed --in-place '/^#/d' "$check_process"
# Remove all spaces at the beginning of the lines
sed --in-place 's/^[ \t]*//g' "$check_process"
# Check if a string can be find in the current line
check_line () {
return $(echo "$line" | grep -q "$1")
}
# Search a string in the partial check_process
find_string () {
echo $(grep "$1" "$partial_check_process")
}
# Extract a section found between $1 and $2 from the file $3
extract_section () {
# Erase the partial check_process
> "$partial_check_process"
local source_file="$3"
local extract=0
local line=""
while read line
do
# Extract the line
if [ $extract -eq 1 ]
then
# Check if the line is the second line to found
if check_line "$2"; then
# Break the loop to finish the extract process
break;
fi
# Copy the line in the partial check_process
echo $line >> "$partial_check_process"
fi
# Search for the first line
if check_line "$1"; then
# Activate the extract process
extract=1
fi
done < "$source_file"
}
# Use 2 partial files, to keep one for a whole tests serie
partial1="${check_process}_part1"
partial2="${check_process}_part2"
# Extract the level section
partial_check_process=$partial1
extract_section "^;;; Levels" ";; " "$check_process"
# Get the value associated to each level
for i in `seq 1 10`
do
# Find the line for this level
line=$(find_string "^Level $i=")
# And get the value
level[$i]=$(echo "$line" | cut -d'=' -f2)
done
# Extract the Options section
partial_check_process=$partial1
extract_section "^;;; Options" ";; " "$check_process"
# Try to find a optionnal email address to notify the maintainer
# In this case, this email will be used instead of the email from the manifest.
dest="$(echo $(find_string "^Email=") | cut -d '=' -f2)"
# Try to find a optionnal option for the grade of notification
notification_grade="$(echo $(find_string "^Notification=") | cut -d '=' -f2)"
# Parse each tests serie
while read tests_serie
do
# Initialize the values for this serie of tests
initialize_values
# Break after the first tests serie
if [ $all_test -ne 0 ] && [ $bash_mode -ne 1 ]; then
read -p "Press a key to start the next tests serie..." < /dev/tty
fi
# Use the second file to extract the whole section of a tests serie
partial_check_process=$partial2
# Extract the section of the current tests serie
extract_section "^$tests_serie" "^;;" "$check_process"
# Parse all infos about arguments of manifest
# Extract the manifest arguments section from the second partial file
partial_check_process=$partial1
extract_section "^; Manifest" "^; " "$partial2"
# Initialize the arguments list
manifest_arguments=""
# Read each arguments and store them
while read line
do
# Extract each argument by removing spaces or tabulations before a parenthesis
add_arg="$(echo $line | sed 's/[ *|\t*](.*//')"
# Remove all double quotes
add_arg="${add_arg//\"/}"
# Then add this argument and follow it by &
manifest_arguments="${manifest_arguments}${add_arg}&"
done < "$partial_check_process"
# Try to find all specific arguments needed for the tests
keep_name_arg_only () {
# Find the line for the given argument
local argument=$(find_string "($1")
# If a line exist for this argument
if [ -n "$argument" ]; then
# Keep only the name of the argument
echo "$(echo "$argument" | cut -d '=' -f1)"
fi
}
domain_arg=$(keep_name_arg_only "DOMAIN")
user_arg=$(keep_name_arg_only "USER")
port_arg=$(keep_name_arg_only "PORT")
path_arg=$(keep_name_arg_only "PATH")
# Get the path value
if [ -n "$path_arg" ]
then
line="$(find_string "(PATH")"
# Keep only the part after the =
line="$(echo "$line" | grep -o "path=.* " | cut -d "=" -f2)"
# And remove " et spaces to keep only the path.
line="${line//[\" ]/}"
# If this path is not empty or equal to /. It's become the new default path value.
if [ ${#line} -gt 1 ]; then
test_path="$line"
fi
fi
public_arg=$(keep_name_arg_only "PUBLIC")
# Find the values for public and private
if [ -n "$public_arg" ]
then
line=$(find_string "(PUBLIC")
public_public_arg=$(echo "$line" | grep -o "|public=[[:alnum:]]*" | cut -d "=" -f2)
public_private_arg=$(echo "$line" | grep -o "|private=[[:alnum:]]*" | cut -d "=" -f2)
fi
if echo "$LIGNE" | grep -q "(PATH)"; then # Path dans le manifest
MANIFEST_PATH=$(echo "$LIGNE" | cut -d '=' -f1) # Récupère la clé du manifest correspondant au path
parse_path=$(echo "$LIGNE" | cut -d '"' -f2) # Lit le path du check_process
if [ -n "$parse_path" ]; then # Si le path n'est pas null, utilise ce path au lieu de la valeur par défaut.
PATH_TEST=$(echo "$LIGNE" | cut -d '"' -f2)
fi
LIGNE=$(echo "$LIGNE" | cut -d '(' -f1) # Retire l'indicateur de clé de manifest à la fin de la ligne
fi
# Parse all tests to perform
# Extract the checks options section from the second partial file
extract_section "^; Checks" "^; " "$partial2"
read_check_option () {
# Find the line for the given check option
local line=$(find_string "^$1=")
# Get only the value
local value=$(echo "$line" | cut -d '=' -f2)
# And return this value
if [ "${value:0:1}" = "1" ]
then
echo 1
else
echo 0
fi
}
count_test () {
# Increase the number of test, if this test is set at 1.
test "$1" -eq 1 && all_test=$((all_test+1))
}
pkg_linter=$(read_check_option pkg_linter)
count_test $pkg_linter
setup_sub_dir=$(read_check_option setup_sub_dir)
count_test $setup_sub_dir
setup_root=$(read_check_option setup_root)
count_test $setup_root
setup_nourl=$(read_check_option setup_nourl)
count_test $setup_nourl
setup_private=$(read_check_option setup_private)
count_test $setup_private
setup_public=$(read_check_option setup_public)
count_test $setup_public
upgrade=$(read_check_option upgrade)
count_test $upgrade
backup_restore=$(read_check_option backup_restore)
count_test $backup_restore
multi_instance=$(read_check_option multi_instance)
count_test $multi_instance
incorrect_path=$(read_check_option incorrect_path)
count_test $incorrect_path
port_already_use=$(read_check_option port_already_use)
count_test $port_already_use
change_url=$(read_check_option change_url)
count_test $change_url
# For port_already_use, check if there is also a port number
if [ $port_already_use -eq 1 ]
then
line=$(find_string "^port_already_use=")
# If there is port number
if echo "$line" | grep -q "([0-9]*)"
then
# Store the port number in port_arg and prefix it by # to means that not really a manifest arg
port_arg="#$(echo "$line" | cut -d '(' -f2 | cut -d ')' -f1)"
fi
fi
# Launch all tests successively
TESTING_PROCESS
# Print the final results of the tests
TEST_RESULTS
# Destroy all snapshots other than snap0
destroy_temporary_snapshot
done <<< "$(grep "^;; " "$check_process")"
# No check_process file. Try to parse the manifest.
else
# Initialize the values for this serie of tests
initialize_values
manifest_extract="$script_dir/manifest_extract"
# Extract the informations from the manifest with the Bram's sly snake script.
python "$script_dir/sub_scripts/manifest_parsing.py" "$package_path/manifest.json" > "$manifest_extract"
# Default tests
pkg_linter=1
setup_sub_dir=1
setup_root=1
setup_nourl=0
upgrade=1
setup_private=1
setup_public=1
backup_restore=1
multi_instance=1
incorrect_path=1
port_already_use=0
change_url=0
all_test=$((all_test+9))
# Read each arguments and store them
while read line
do
# Read each argument and pick up the first value. Then replace : by =
add_arg="$(echo $line | cut -d ':' -f1,2 | sed s/:/=/)"
# Then add this argument and follow it by &
manifest_arguments="${manifest_arguments}${add_arg}&"
done < "$manifest_extract"
# Search a string in the partial check_process
find_string () {
echo $(grep "$1" "$manifest_extract")
}
# Try to find all specific arguments needed for the tests
keep_name_arg_only () {
# Find the line for the given argument
local argument=$(find_string "$1")
# If a line exist for this argument
if [ -n "$argument" ]; then
# Keep only the name of the argument
echo "$(echo "$argument" | cut -d ':' -f1)"
fi
}
domain_arg=$(keep_name_arg_only ":ynh.local")
path_arg=$(keep_name_arg_only "path:")
user_arg=$(keep_name_arg_only "user:\|admin:")
public_arg=$(keep_name_arg_only "is_public:")
# Find the values for public and private
if [ -n "$public_arg" ]
then
line=$(find_string "is_public:")
# Assume the first value is public and the second is private.
public_public_arg=$(echo "$line" | cut -d ":" -f2)
public_private_arg=$(echo "$line" | cut -d ":" -f3)
fi
count_test () {
# Decrease the number of test, if this test is not already removed.
if [ $1 -eq 1 ]; then
all_test=$((all_test-1))
return 1
fi
}
# Disable some tests if the manifest key doesn't be found
if [ -z "$domain_arg" ]
then
ECHO_FORMAT "The manifest key for domain didn't be find.\n" "lyellow"
setup_sub_dir=0
count_test "$setup_root" || setup_root=0
count_test "$multi_instance" || multi_instance=0
count_test "$incorrect_path" || incorrect_path=0
setup_nourl=1
fi
if [ -z "$path_arg" ]
then
ECHO_FORMAT "The manifest key for path didn't be find.\n" "lyellow"
count_test "$setup_root" || setup_root=0
count_test "$multi_instance" || multi_instance=0
count_test "$incorrect_path" || incorrect_path=0
fi
if [ -z "$public_arg" ]
then
ECHO_FORMAT "The manifest key for public didn't be find.\n" "lyellow"
setup_private=0
setup_public=0
all_test=$((all_test-2))
fi
# Remove the multi-instance test if this parameter is set at false in the manifest.
if grep multi_instance "$package_path/manifest.json" | grep -q false
then
count_test "$multi_instance" || multi_instance=0
fi
# Launch all tests successively
TESTING_PROCESS
# Print the final results of the tests
TEST_RESULTS
fi
echo "You can find the complete log of these tests in $complete_log"
#=================================================
# Notification grade
#=================================================
notif_grade () {
# Check the level of notification from the check_process.
# Echo 1 if the grade is reached
compare_grade ()
{
if echo "$notification_grade" | grep -q "$1"; then
echo 1
else
echo 0
fi
}
case "$1" in
all)
# If 'all' is needed, only a grade of notification at 'all' can match
compare_grade "^all$"
;;
change)
# If 'change' is needed, notification at 'all' or 'change' can match
compare_grade "^all$\|^change$"
;;
down)
# If 'down' is needed, notification at 'all', 'change' or 'down' match
compare_grade "^all$\|^change$\|^down$"
;;
*)
echo 0
;;
esac
}
#=================================================
# Inform of the results by XMPP and/or by mail
#=================================================
send_mail=0
# Keep only the name of the app
app_name=${package_dir%_ynh_check}
# If package check it's in the official CI environment
# Check the level variation
if [ $type_exec_env -eq 2 ]
then
# Get the job name, stored in the work_list
job=$(head -n1 "$script_dir/../work_list" | cut -d ';' -f 3)
# Identify the type of test, stable (0), testing (1) or unstable (2)
# Default stable
test_type=0
message=""
if echo "$job" | grep -q "(testing)"
then
message="(TESTING) "
test_type=1
elif echo "$job" | grep -q "(unstable)"
then
message="(UNSTABLE) "
test_type=2
fi
# Build the log path (and replace all space by %20 in the job name)
if [ -n "$job" ]; then
job_log="/job/${job// /%20}/lastBuild/console"
fi
# If it's a test on testing or unstable
if [ $test_type -gt 0 ]
then
# Remove unstable or testing of the job name to find its stable version in the level list
job="${job% (*)}"
fi
# Get the previous level, found in the file list_level_stable
previous_level=$(grep "$job" "$script_dir/../auto_build/list_level_stable" | cut -d: -f2)
# Print the variation of the level. If this level is different than 0
if [ $global_level -gt 0 ]
then
message="${message}Application $app_name"
# If non previous level was found
if [ -z "$previous_level" ]; then
message="$message just reach the level $global_level"
send_mail=$(notif_grade all)
# If the level stays the same
elif [ $global_level -eq $previous_level ]; then
message="$message stays at level $global_level"
# Need notification at 'all' to notify by email
send_mail=$(notif_grade all)
# If the level go up
elif [ $global_level -gt $previous_level ]; then
message="$message rise from level $previous_level to level $global_level"
# Need notification at 'change' to notify by email
send_mail=$(notif_grade change)
# If the level go down
elif [ $global_level -lt $previous_level ]; then
message="$message go down from level $previous_level to level $global_level"
# Need notification at 'down' to notify by email
send_mail=$(notif_grade down)
fi
fi
fi
# If the app completely failed and obtained 0
if [ $global_level -eq 0 ]
then
message="${message}Application $app_name has completely failed the continuous integration tests"
# Always send an email if the app failed
send_mail=1
fi
# The mail subject is the message to send, before any logs informations
subject="[YunoHost] $message"
# If the test was perform in the official CI environment
# Add the log address
# And inform with xmpp
if [ $type_exec_env -eq 2 ]
then
# Build the address of the server from auto.conf
ci_path=$(grep "DOMAIN=" "$script_dir/../auto_build/auto.conf" | cut -d= -f2)/$(grep "CI_PATH=" "$script_dir/../auto_build/auto.conf" | cut -d= -f2)
# Add the log adress to the message
message="$message on https://$ci_path$job_log"
# Send a xmpp notification on the chat room "apps"
# Only for a test with the stable version of YunoHost
if [ $test_type -eq 0 ]
then
"$script_dir/../auto_build/xmpp_bot/xmpp_post.sh" "$message" > /dev/null 2>&1
fi
fi
# Send a mail to main maintainer according to notification option in the check_process.
# Only if package check is in a CI environment (Official or not)
if [ $type_exec_env -ge 1 ] && [ $send_mail -eq 1 ]
then
# Add a 'from' header for the official CI only.
if [ $type_exec_env -eq 2 ]; then
from_yuno="-a \"From: yunohost@yunohost.org\""
fi
# Get the maintainer email from the manifest. If it doesn't found if the check_process
if [ -z "$dest" ]; then
dest=$(grep '\"email\": ' "$package_path/manifest.json" | cut -d '"' -f 4)
fi
# Send the message by mail, if a address has been find
if [ -n "$dest" ]; then
mail $from_yuno -s "$subject" "$dest" <<< "$message"
fi
fi
#=================================================
# Clean and exit
#=================================================
clean_exit 0