1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2026-02-06 18:40:12 +01:00
lodel2_mirror/scripts/cbl.sh
Quentin Bonaventure 02cc999816 Licensing follow up
2017-05-04 08:52:13 +02:00

435 lines
14 KiB
Bash
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
#
# This file is part of Lodel 2 (https://github.com/OpenEdition)
#
# Copyright (C) 2015-2017 Cléo UMS-3287
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# CBL : Curl Benchmark on Lodel
#
# Usage : $0 [HOSTNAME] [INSTANCE_LIST_FILE] [N_CREATE] [N_EDIT] [N_DELETE]
#
# Instance_list_file is expected to be a file containing instances name (1 per
# line). Uses by default /tmp/lodel2_instance_list.txt
#
# Instances base URL are generated given the current webui implementation :
# http://HOST/INSTANCE_NAME/
#
#
# Scenario description :
#
# mass_creation instance_name iteration_count :
# Create iteration_count time a random leobject in given instance_name
# note : do note create relation between objects, only populate content
#
# step 1 : fetch all non abstract class name
# step 2 : loop on creation (using bash function curl_opt_create_CLSNAME)
# that return the POST fields (populated with random values)
#
# mass_get instance_name :
# Create all possible get for an instance
# step 1 : fetch all classes
# step 2 : for each class fetch all id
# step 3 : for all ids generate the gets
#
# mass_deletion instance_name iteration_count :
# Foreach non asbtracty class delete iteration_count time an object of
# current class in current instance
#
# step 1 : fetch all non abstract class name
# step 2 : loop on non abstract class name
# step 3 : loop iteration_count time on deletion
#
# mass_link_edit instance_name iteration_count :
# Foreach non abstract class make iteration_count time edition of an
# object in current class
# note : only implemented for Person for the moment
# note : can maybe ask for invalid modifications
#
# step 1 : fetch all non abstract class name
# step 2 : loop on non abstract class name
# step 3 : depends on curent class :
# - fetch all existing id of current class
# - fetch all existing id in class that can be linked with
# current class
# step 4 : loop iteration_count time :
# - choose a random id in current class
# - choose random ids from linkable classes
# - trigger edition using curl (with datas from the same
# bash function than creation : curl_opt_create_CLSNAME)
#
# Current way to run scenarios :
#
# using the function run_bg_with_param FUNCTION_NAME INSTANCE_LIST_FILE *ARGS
#
# The function name can be one of the scenario functions
# INSTANCE_LIST_FILE is the file containing instances list
# *ARGS are args given as it to FUNCTION_NAME after the instance_name argument
#
# function call : FUN_NAME INSTANCE_NAME *ARGS
#
# The run_bg_with_param run a scenario in background for each instance allowing
# to send a lot of request at the same time
#
#
usage() {
echo "Usage : $0 [HOSTNAME] [INSTANCE_LIST_FILE] [CREATE_COUNT] [EDIT_COUNT] [DELETE_COUNT]"
exit
}
host=$1
host=${host:=localhost}
instance_list=$2
instance_list=${instance_list:=/tmp/lodel2_instance_list.txt}
#A modifier for requests count
n_create=$3
n_create=${n_create:=50}
n_edit=$4
n_edit=${n_edit:=10}
n_delete=$5
n_delete=${n_delete:=10}
for i in $(seq $#)
do
echo $1 |grep -E "^-?-h" &>/dev/null
shift
done
#curl_options='--silent -o /dev/null -s -w %{http_code}:%{time_connect}:%{time_starttransfer}:%{time_total}\n'
curl_options='--silent -o /dev/null -s -w %{url_effective};%{http_code};%{time_connect};%{time_starttransfer};%{time_total}\n'
curl_debug_opt='-v -w %{url_effective};%{http_code};%{time_connect};%{time_starttransfer};%{time_total}\n'
curl_cmd="curl $curl_options"
curl_raw="curl --silent"
curl_debug="curl $curl_debug_opt"
curcurl="$curl_cmd"
cmktemp="mktemp -t lodel2_cbl_XXXXXXXX"
_base_uri() {
echo -n "http://$host/$1"
}
rnd_str() {
len=$1
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1
}
rnd_str_len() {
minlen=$1
maxlen=$2
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $(shuf -i${minlen}-${maxlen} -n1) | head -n 1
}
mass_creation() {
#mass creation scenario
#$1 is instance name
#$2 is iteration count (1 iteration is 1 creation of a random class)
instance_name=$1
iteration_count=$2
base_uri=$(_base_uri $1)
cls_list_file=$(fetch_all_classes $1)
if [ -z "$(cat $cls_list_file)" ]
then
echo "Failed to fetch class list for instance $1. Abording..." >&2
exit
fi
if [ "$iteration_count" -le "0" ]
then
return
fi
for i in $(seq $iteration_count)
do
cls=$(shuf -n1 $cls_list_file)
echo "${base_uri}$(uri_create $cls) POST $(curl_opt_create_$cls)"
done
rm -v $cls_list_file >&2
}
mass_get() {
#mass get scenario
#$1 is instance name
cls_list_file=$(fetch_all_classes $1)
base_uri=$(_base_uri $1)
#Get the site root
echo "$base_uri/"
#Get the site class list
echo "$base_uri/list_classes"
for clsname in $(cat $cls_list_file)
do
#Get instances list for a class
echo "$base_uri/show_class?classname=$clsname"
ids_file=$(fetch_all_ids $1 $clsname)
for id in $(cat $ids_file)
do
#Get details on an instance
echo "$base_uri/show_object_detailled?classname=${clsname}&lodel_id=$id"
#Get base informations on an instance
echo "$base_uri/show_object?classname=${clsname}&lodel_id=$id"
done
done
}
mass_link_edit() {
#mass linking & edition scenarion
#$1 is instance name
#$2 is iteration count
instance_name=$1
iteration_count=$2
base_uri=$(_base_uri $1)
cls_list_file=$(fetch_all_classes $1)
for cls in $(cat $cls_list_file)
do
case $cls in
Person)
person_ids=$(fetch_all_ids $1 Person)
section_ids=$(fetch_all_ids $1 Section)
subsection_ids=$(fetch_all_ids $1 Subsection)
text_ids=$($cmktemp)
cat $section_ids $subsection_ids | shuf > $text_ids
for i in $(seq $iteration_count)
do
cur_id=$(shuf -n1 $person_ids)
alias_count=$(shuf -i1-5 -n1)
ltext_count=$(shuf -i1-5 -n1)
alias_param=$(head -n $(expr $alias_count \* $i) $person_ids| tail -n$alias_count|tr -s "\n" "," | sed 's/,$//')
txt_param=$(head -n $(expr $ltext_count \* $i) $text_ids | tail -n$ltext_count|tr -s "\n" "," | sed 's/,$//')
echo "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id POST $(curl_opt_create_$cls $alias_param $txt_param)&uid=$cur_id"
done
rm -v $text_ids $person_ids $section_ids $subsection_ids >&2
;;
Collection)
collections_ids=$(fetch_all_ids $1 Collection)
publication_ids=$(fetch_all_ids $1 Publication)
for i in $(seq $iteration_count)
do
cur_id=$(shuf -n1 $collections_ids)
publications_count=$(shuf -i1-5 -n1)
publication_param=$(head -n $(expr $publications_count \* $i) $publication_ids| tail -n$publications_count|tr -s "\n" ",")
echo "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id POST $(curl_opt_create_$cls $publication_param)&uid=$cur_id"
done
rm -v $collections_ids $publication_ids >&2
;;
Publication)
publication_ids=$(fetch_all_ids $1 Publication)
collection_ids=$(fetch_all_ids $1 Collection)
for i in $(seq $iteration_count)
do
cur_id=$(shuf -n1 $publication_ids)
collections_count=$(shuf -i1-5 -n1)
collection_param=$(head -n $(expr $collections_count \* $i) $collection_ids| tail -n$collections_count|tr -s "\n" ",")
echo "$base_uri/admin.update?classname=$cls&lodel_id=$cur_id POST $(curl_opt_create_$cls $collection_param)&uid=$cur_id"
done
rm -v $publication_ids $collection_ids >&2
;;
Section)
section_ids=$(fetch_all_ids $1 Section)
child_ids=$(fetch_all_ids $1 Subsection)
person_ids=$(fetch_all_ids $1 Person)
for i in $(seq $iteration_count)
do
cur_id=$(shuf -n1 $section_ids)
child_count=$(shuf -i1-5 -n1)
person_count=$(shuf -i1-5 -n1)
child_param=$(head -n $(expr $child_count \* $i) $child_ids| tail -n$child_count|tr -s "\n" ",")
person_param=$(head -n $(expr $person_count \* $i) $person_ids| tail -n$person_count|tr -s "\n" ",")
echo "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id POST $(curl_opt_create_$cls $child_param $person_param)&uid=$cur_id"
done
rm -v $section_ids $child_ids $person_ids >&2
;;
Subsection)
subsection_ids=$(fetch_all_ids $1 Subsection)
section_ids=$(fetch_all_ids $1 Section)
persons_ids=$(fetch_all_ids $1 Person)
parent_ids=$($cmktemp)
cat $section_ids $subsection_ids | shuf > $parent_ids
child_ids=$subsection_ids
for i in $(seq $iteration_count)
do
cur_id=$(shuf -n1 $subsection_ids)
child_count=$(shuf -i1-5 -n1)
parent_count=$(shuf -i1-5 -n1)
person_count=$(shuf -i1-5 -n1)
child_param=$(head -n $(expr $child_count \* $i) $child_ids| tail -n$child_count|tr -s "\n" ",")
parent_param=$(head -n $(expr $parent_count \* $i) $parent_ids| tail -n$parent_count|tr -s "\n" ",")
person_param=$(head -n $(expr $person_count \* $i) $persons_ids| tail -n$person_count|tr -s "\n" ",")
echo "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id POST $(curl_opt_create_$cls $child_param $person_param $parent_param)&uid=$cur_id"
done
rm -v $subsection_ids $parent_ids $section_ids $persons_ids >&2
;;
*)
;;
esac
done
rm -v $cls_list_file >&2
}
mass_deletion() {
#mass deletion scenario
#$1 is instance name
#$2 number of deletion per classes !
instance_name=$1
iteration_count=$2
base_uri=$(_base_uri $1)
cls_list_file=$(fetch_all_classes $1)
for cls in $(cat $cls_list_file)
do
id_list_file=$(fetch_all_ids $1 $cls)
if [ "$iteration_count" -gt "$(wc -l $id_list_file | cut -d " " -f1)" ]
then
max_iter=$(wc -l $id_list_file | cut -d " " -f1)
else
max_iter="$iteration_count"
fi
for i in $(seq $max_iter)
do
id=$(tail -n $i $id_list_file | head -n1)
echo "${base_uri}/admin/delete?classname=$cls&lodel_id=$id"
done
rm -v $id_list_file >&2
done
rm -v $cls_list_file >&2
}
fetch_all_classes() {
#$1 is intance name
cls_list_file=$($cmktemp)
$curl_raw "$(_base_uri $1)/list_classes" | grep -v Abstract |sed -nE 's/^ *<li> +<a href="show_class([^"]+)".*$/\1/p'|cut -d"=" -f2 > $cls_list_file
if [ -z "$(cat $cls_list_file)" ]
then
echo "Unable to fetch class list for $1" >&2
echo "Request was : $curl_raw '$(_base_uri $1)/list_classes'" >&2
rm $cls_list_file >&2
exit 1
fi
echo $cls_list_file
}
fetch_all_ids() {
# Fetch all ids of a class in an instance and shuffle them
instance_name=$1
classname=$2
idfile=$($cmktemp)
$curl_raw "$(_base_uri $1)/show_class?classname=$2" | sed -nE 's/^.*<li><a href="[^=]+=[^=]+=([0-9]+)".*$/\1/p' |shuf > $idfile
echo $idfile
}
uri_create() {
clsname=$1
echo -n "/admin/create?classname=$1"
}
curl_opt_create_Person() {
#$1 is alias id
#$2 is linked_texts id (comma separated)
echo "field_input_lastname=$(rnd_str_len 10 20)&field_input_firstname=$(rnd_str_len 10 20)&field_input_alias=$1&field_input_linked_texts=$2&classname=Person"
}
curl_opt_create_User() {
echo "field_input_lastname=$(rnd_str_len 10 20)&field_input_firstname=$(rnd_str_len 10 20)&field_input_password=$(rnd_str 50)&field_input_login=$(rnd_str_len 5 20)&classname=User"
}
curl_opt_create_Collection() {
#$1 is publications id (comma separated)
echo "field_input_title=$(rnd_str_len 20 50)&field_input_publications=$1&classname=Collection"
}
curl_opt_create_Publication() {
#$1 collections id comma separated
echo "field_input_collection=$1&classname=Publication"
}
curl_opt_create_Section() {
#$1 childs id (comma separated)
#$2 linked_persons id (comma separated)
echo "field_input_title=$(rnd_str_len 20 50)&field_input_subtitle=$(rnd_str_len 20 50)&field_input_childs=$1&field_input_linked_persons=$2&classname=Section"
}
curl_opt_create_Subsection() {
#$1 childs id (comma separated)
#$2 linked_persons id (comma separated)
#$3 parants id (comma separated)
echo "field_input_title=$(rnd_str_len 20 50)&field_input_subtitle=$(rnd_str_len 20 50)&field_input_childs=$1&field_input_linked_persons=$2&field_input_parent=$3&classname=Subsection"
}
run_bg_with_param() {
#$1 is the function name to run
#$2 is the instance_list filename
#other parameters are given to the function
fun=$1
instance_list=$2
shift;shift
pidlist=$($cmktemp)
for iname in $(cat $instance_list)
do
$fun $iname $@ &
echo $! >> $pidlist
sleep 1
done
for pid in $(cat $pidlist)
do
wait $pid
done
rm -v $pidlist >&2
}
get_queries_with_params() {
#$1 is the function name to run
#$2 is the instance_list filename
#other parameters are given to the function
fun=$1
instance_list=$2
shift;shift
counter=0
for iname in $(cat $instance_list| sort)
do
echo "Running $fun $iname $@" >&2
beg=$(date "+%s")
$fun $iname $@
tsecs=$(expr $(date "+%s") - $beg)
left=$(expr $(cat $instance_list |wc -l) - $counter)
counter=$(expr $counter + 1)
tleft=$(expr $left \* $tsecs)
percent_done=$(echo "2k ${counter}.0 100.0 * $(cat $instance_list |wc -l).0 2k/ f" | dc)
echo -e "Done in ${tsecs}s\t$fun ${percent_done}% done ~$tleft secs" >&2
done | shuf
}
get_queries_with_params "mass_get" $instance_list
[ "$n_create" -gt 0 ] && get_queries_with_params "mass_creation" $instance_list $n_create
[ "$n_edit" -gt 0 ] && get_queries_with_params "mass_link_edit" $instance_list $n_edit
[ "$n_delete" -gt 0 ] && get_queries_with_params "mass_deletion" $instance_list $n_delete