No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cbl.sh 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #!/bin/bash
  2. #
  3. # CBL : Curl Benchmark on Lodel
  4. #
  5. # Usage : $0 [HOSTNAME] [INSTANCE_LIST_FILE] [N_CREATE] [N_EDIT] [N_DELETE]
  6. #
  7. # Instance_list_file is expected to be a file containing instances name (1 per
  8. # line). Uses by default /tmp/lodel2_instance_list.txt
  9. #
  10. # Instances base URL are generated given the current webui implementation :
  11. # http://HOST/INSTANCE_NAME/
  12. #
  13. #
  14. # Scenario description :
  15. #
  16. # mass_creation instance_name iteration_count :
  17. # Create iteration_count time a random leobject in given instance_name
  18. # note : do note create relation between objects, only populate content
  19. #
  20. # step 1 : fetch all non abstract class name
  21. # step 2 : loop on creation (using bash function curl_opt_create_CLSNAME)
  22. # that return the POST fields (populated with random values)
  23. #
  24. # mass_deletion instance_name iteration_count :
  25. # Foreach non asbtracty class delete iteration_count time an object of
  26. # current class in current instance
  27. #
  28. # step 1 : fetch all non abstract class name
  29. # step 2 : loop on non abstract class name
  30. # step 3 : loop iteration_count time on deletion
  31. #
  32. # mass_link_edit instance_name iteration_count :
  33. # Foreach non abstract class make iteration_count time edition of an
  34. # object in current class
  35. # note : only implemented for Person for the moment
  36. # note : can maybe ask for invalid modifications
  37. #
  38. # step 1 : fetch all non abstract class name
  39. # step 2 : loop on non abstract class name
  40. # step 3 : depends on curent class :
  41. # - fetch all existing id of current class
  42. # - fetch all existing id in class that can be linked with
  43. # current class
  44. # step 4 : loop iteration_count time :
  45. # - choose a random id in current class
  46. # - choose random ids from linkable classes
  47. # - trigger edition using curl (with datas from the same
  48. # bash function than creation : curl_opt_create_CLSNAME)
  49. #
  50. # Current way to run scenarios :
  51. #
  52. # using the function run_bg_with_param FUNCTION_NAME INSTANCE_LIST_FILE *ARGS
  53. #
  54. # The function name can be one of the scenario functions
  55. # INSTANCE_LIST_FILE is the file containing instances list
  56. # *ARGS are args given as it to FUNCTION_NAME after the instance_name argument
  57. #
  58. # function call : FUN_NAME INSTANCE_NAME *ARGS
  59. #
  60. # The run_bg_with_param run a scenario in background for each instance allowing
  61. # to send a lot of request at the same time
  62. #
  63. #
  64. usage() {
  65. echo "Usage : $0 [HOSTNAME] [INSTANCE_LIST_FILE] [CREATE_COUNT] [EDIT_COUNT] [DELETE_COUNT]"
  66. exit
  67. }
  68. host=$1
  69. host=${host:=localhost}
  70. instance_list=$2
  71. instance_list=${instance_list:=/tmp/lodel2_instance_list.txt}
  72. #A modifier for requests count
  73. n_create=$3
  74. n_create=${n_create:=50}
  75. n_edit=$4
  76. n_edit=${n_edit:=10}
  77. n_delete=$5
  78. n_delete=${n_delete:=10}
  79. for i in $(seq $#)
  80. do
  81. echo $1 |grep -E "^-?-h" &>/dev/null
  82. shift
  83. done
  84. logdir="/tmp/lodel2_cbl_logs"
  85. if [ -d "$logdir" ]
  86. then
  87. echo "WARNING : $logdir allready exists. It's a better idea to delete it before running this script again"
  88. echo "waiting 3s"
  89. sleep 3
  90. fi
  91. mkdir -p $logdir
  92. #curl_options='--silent -o /dev/null -s -w %{http_code}:%{time_connect}:%{time_starttransfer}:%{time_total}\n'
  93. curl_options='--silent -o /dev/null -s -w %{url_effective};%{http_code};%{time_connect};%{time_starttransfer};%{time_total}\n'
  94. curl_debug_opt='-v -w %{url_effective};%{http_code};%{time_connect};%{time_starttransfer};%{time_total}\n'
  95. curl_cmd="curl $curl_options"
  96. curl_raw="curl --silent"
  97. curl_debug="curl $curl_debug_opt"
  98. curcurl="$curl_cmd"
  99. cmktemp="mktemp -t lodel2_cbl_XXXXXXXX"
  100. _base_uri() {
  101. echo -n "http://$host/$1"
  102. }
  103. rnd_str() {
  104. len=$1
  105. cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1
  106. }
  107. rnd_str_len() {
  108. minlen=$1
  109. maxlen=$2
  110. cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $(shuf -i${minlen}-${maxlen} -n1) | head -n 1
  111. }
  112. mass_creation() {
  113. #mass creation scenario
  114. #$1 is instance name
  115. #$2 is iteration count (1 iteration is 1 creation of a random class)
  116. instance_name=$1
  117. iteration_count=$2
  118. base_uri=$(_base_uri $1)
  119. logfile="$logdir/mass_creation_${instance_name}.log"
  120. cls_list_file=$(fetch_all_classes $1)
  121. if [ "$iteration_count" -le "0" ]
  122. then
  123. return
  124. fi
  125. for i in $(seq $iteration_count)
  126. do
  127. cls=$(shuf -n1 $cls_list_file)
  128. $curcurl -d "$(curl_opt_create_$cls)" "${base_uri}$(uri_create $cls)" | tee -a $logfile
  129. done
  130. rm -v $cls_list_file
  131. }
  132. mass_link_edit() {
  133. #mass linking & edition scenarion
  134. #$1 is instance name
  135. #$2 is iteration count
  136. instance_name=$1
  137. iteration_count=$2
  138. base_uri=$(_base_uri $1)
  139. logfile="$logdir/mass_link_edit_${instance_name}.log"
  140. cls_list_file=$(fetch_all_classes $1)
  141. for cls in $(cat $cls_list_file)
  142. do
  143. case $cls in
  144. Person)
  145. person_ids=$(fetch_all_ids $1 Person)
  146. section_ids=$(fetch_all_ids $1 Section)
  147. subsection_ids=$(fetch_all_ids $1 Subsection)
  148. text_ids=$($cmktemp)
  149. cat $section_ids $subsection_ids | shuf > $text_ids
  150. for i in $(seq $iteration_count)
  151. do
  152. cur_id=$(shuf -n1 $person_ids)
  153. alias_count=$(shuf -i1-5 -n1)
  154. ltext_count=$(shuf -i1-5 -n1)
  155. alias_param=$(head -n $(expr $alias_count \* $i) $person_ids| tail -n$alias_count|tr -s "\n" "," | sed 's/,$//')
  156. txt_param=$(head -n $(expr $ltext_count \* $i) $text_ids | tail -n$ltext_count|tr -s "\n" "," | sed 's/,$//')
  157. $curcurl -d "$(curl_opt_create_$cls $alias_param $txt_param)&uid=$cur_id" "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id" | tee -a $logfile
  158. done
  159. rm -v $text_ids $person_ids $section_ids $subsection_ids
  160. ;;
  161. Collection)
  162. collections_ids=$(fetch_all_ids $1 Collection)
  163. publication_ids=$(fetch_all_ids $1 Publication)
  164. for i in $(seq $iteration_count)
  165. do
  166. cur_id=$(shuf -n1 $collections_ids)
  167. publications_count=$(shuf -i1-5 -n1)
  168. publication_param=$(head -n $(expr $publications_count \* $i) $publication_ids| tail -n$publications_count|tr -s "\n" ",")
  169. $curcurl -d "$(curl_opt_create_$cls $publication_param)&uid=$cur_id" "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id" | tee -a $logfile
  170. done
  171. rm -v $collections_ids $publication_ids
  172. ;;
  173. Publication)
  174. publication_ids=$(fetch_all_ids $1 Publication)
  175. collection_ids=$(fetch_all_ids $1 Collection)
  176. for i in $(seq $iteration_count)
  177. do
  178. cur_id=$(shuf -n1 $publication_ids)
  179. collections_count=$(shuf -i1-5 -n1)
  180. collection_param=$(head -n $(expr $collections_count \* $i) $collection_ids| tail -n$collections_count|tr -s "\n" ",")
  181. $curcurl -d "$(curl_opt_create_$cls $collection_param)&uid=$cur_id" "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id" | tee -a $logfile
  182. done
  183. rm -v $publication_ids $collection_ids
  184. ;;
  185. Section)
  186. section_ids=$(fetch_all_ids $1 Section)
  187. child_ids=$(fetch_all_ids $1 Subsection)
  188. person_ids=$(fetch_all_ids $1 Person)
  189. for i in $(seq $iteration_count)
  190. do
  191. cur_id=$(shuf -n1 $section_ids)
  192. child_count=$(shuf -i1-5 -n1)
  193. person_count=$(shuf -i1-5 -n1)
  194. child_param=$(head -n $(expr $child_count \* $i) $child_ids| tail -n$child_count|tr -s "\n" ",")
  195. person_param=$(head -n $(expr $person_count \* $i) $person_ids| tail -n$person_count|tr -s "\n" ",")
  196. $curcurl -d "$(curl_opt_create_$cls $child_param $person_param)&uid=$cur_id" "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id" | tee -a $logfile
  197. done
  198. rm -v $section_ids $child_ids $person_ids
  199. ;;
  200. Subsection)
  201. subsection_ids=$(fetch_all_ids $1 Subsection)
  202. section_ids=$(fetch_all_ids $1 Section)
  203. persons_ids=$(fetch_all_ids $1 Person)
  204. parent_ids=$($cmktemp)
  205. cat $section_ids $subsection_ids | shuf > $parent_ids
  206. child_ids=$subsection_ids
  207. for i in $(seq $iteration_count)
  208. do
  209. cur_id=$(shuf -n1 $subsection_ids)
  210. child_count=$(shuf -i1-5 -n1)
  211. parent_count=$(shuf -i1-5 -n1)
  212. person_count=$(shuf -i1-5 -n1)
  213. child_param=$(head -n $(expr $child_count \* $i) $child_ids| tail -n$child_count|tr -s "\n" ",")
  214. parent_param=$(head -n $(expr $parent_count \* $i) $parent_ids| tail -n$parent_count|tr -s "\n" ",")
  215. person_param=$(head -n $(expr $person_count \* $i) $persons_ids| tail -n$person_count|tr -s "\n" ",")
  216. $curcurl -d "$(curl_opt_create_$cls $child_param $person_param $parent_param)&uid=$cur_id" "$base_uri/admin/update?classname=$cls&lodel_id=$cur_id" | tee -a $logfile
  217. done
  218. rm -v $subsection_ids $parent_ids $section_ids $persons_ids
  219. ;;
  220. *)
  221. ;;
  222. esac
  223. done
  224. rm -v $cls_list_file
  225. }
  226. mass_deletion() {
  227. #mass deletion scenario
  228. #$1 is instance name
  229. #$2 number of deletion per classes !
  230. instance_name=$1
  231. iteration_count=$2
  232. base_uri=$(_base_uri $1)
  233. logfile="$logdir/mass_deletion_${instance_name}.log"
  234. cls_list_file=$(fetch_all_classes $1)
  235. for cls in $(cat $cls_list_file)
  236. do
  237. id_list_file=$(fetch_all_ids $1 $cls)
  238. if [ "$iteration_count" -gt "$(wc -l $id_list_file | cut -d " " -f1)" ]
  239. then
  240. max_iter=$(wc -l $id_list_file | cut -d " " -f1)
  241. else
  242. max_iter="$iteration_count"
  243. fi
  244. for i in $(seq $max_iter)
  245. do
  246. id=$(tail -n $i $id_list_file | head -n1)
  247. $curcurl "${base_uri}/admin/delete?classname=$cls&lodel_id=$id" | tee -a $logfile
  248. done
  249. rm -v $id_list_file
  250. done
  251. rm -v $cls_list_file
  252. }
  253. fetch_all_classes() {
  254. #$1 is intance name
  255. cls_list_file=$($cmktemp)
  256. $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
  257. echo $cls_list_file
  258. }
  259. fetch_all_ids() {
  260. # Fetch all ids of a class in an instance and shuffle them
  261. instance_name=$1
  262. classname=$2
  263. idfile=$($cmktemp)
  264. $curl_raw "$(_base_uri $1)/show_class?classname=$2" | sed -nE 's/^.*<li><a href="[^=]+=[^=]+=([0-9]+)".*$/\1/p' |shuf > $idfile
  265. echo $idfile
  266. }
  267. uri_create() {
  268. clsname=$1
  269. echo -n "/admin/create?classname=$1"
  270. }
  271. curl_opt_create_Person() {
  272. #$1 is alias id
  273. #$2 is linked_texts id (comma separated)
  274. 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"
  275. }
  276. curl_opt_create_User() {
  277. 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"
  278. }
  279. curl_opt_create_Collection() {
  280. #$1 is publications id (comma separated)
  281. echo "field_input_title=$(rnd_str_len 20 50)&field_input_publications=$1&classname=Collection"
  282. }
  283. curl_opt_create_Publication() {
  284. #$1 collections id comma separated
  285. echo "field_input_collection=$1&classname=Publication"
  286. }
  287. curl_opt_create_Section() {
  288. #$1 childs id (comma separated)
  289. #$2 linked_persons id (comma separated)
  290. 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"
  291. }
  292. curl_opt_create_Subsection() {
  293. #$1 childs id (comma separated)
  294. #$2 linked_persons id (comma separated)
  295. #$3 parants id (comma separated)
  296. 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"
  297. }
  298. run_bg_with_param() {
  299. #$1 is the function name to run
  300. #$2 is the instance_list filename
  301. #other parameters are given to the function
  302. fun=$1
  303. instance_list=$2
  304. shift;shift
  305. pidlist=$($cmktemp)
  306. for iname in $(cat $instance_list)
  307. do
  308. $fun $iname $@ &
  309. echo $! >> $pidlist
  310. sleep 1
  311. done
  312. for pid in $(cat $pidlist)
  313. do
  314. wait $pid
  315. done
  316. rm -v $pidlist
  317. }
  318. run_bg_with_param "mass_creation" $instance_list $n_create
  319. run_bg_with_param "mass_link_edit" $instance_list $n_edit
  320. run_bg_with_param "mass_deletion" $instance_list $n_delete
  321. echo ""
  322. echo "Logs can be found in $logdir"