X-Git-Url: http://git.euphorik.ch/?p=euphorik.git;a=blobdiff_plain;f=modules%2Ferl%2Feuphorik_test.erl;h=a166465a89611b38837ccb7aa3d99144ceaa5b6b;hp=2cbc1ec5d898b73124a2aa10c2eca3323ea1a507;hb=5d9992368bb386d2e606ae037c5478fe10ac70e8;hpb=8ee1535f5594573931ddaebee77bf6148a5358cb diff --git a/modules/erl/euphorik_test.erl b/modules/erl/euphorik_test.erl index 2cbc1ec..a166465 100644 --- a/modules/erl/euphorik_test.erl +++ b/modules/erl/euphorik_test.erl @@ -1,212 +1,209 @@ -% coding: utf-8 -% Copyright 2008 Grégory Burri -% -% This file is part of Euphorik. -% -% Euphorik is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% Euphorik 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 General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with Euphorik. If not, see . -% -% Module de test de euphorik. -% Crée un certain nombre d'utilisateur et post des messages aléatoire. - - --module(euphorik_test). --export([ - bench_write_minichat/1, - start/2, - stop/1, - bench_get_messages/0, - bench_get_messages_avec_2_conversations/0 -]). --include("../include/euphorik_bd.hrl"). +% coding: utf-8 +% Copyright 2008 Grégory Burri +% +% This file is part of Euphorik. +% +% Euphorik is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Euphorik 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 General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Euphorik. If not, see . +% +% Module de test de euphorik. +% Crée un certain nombre d'utilisateur et post des messages aléatoire. + + +-module(euphorik_test). +-export([ + bench_write_minichat/1, + start/2, + stop/1, + bench_get_messages/0, + bench_get_messages_avec_2_conversations/0 +]). +-include("../include/euphorik_bd.hrl"). % les intervalles en seconde min en max entre deux postes de message d'un utilisateur % le temps d'attente est choisi au hasard entre ces deux valeurs -define(INTERVALLE_MIN, 2). --define(INTERVALLE_MAX, 5). - - -% N est le nombre d'utilisateur -% M est le nombre de message que chaque utilisateur va poster -start(N, M) -> - Ids = creer_users(N), - lists:map( - fun(Id) -> - timer:sleep(100), - spawn( - fun() -> - {A1, A2, A3} = now(), - random:seed(A1, A2, A3), - loop(Id, M) - end - ) - end, - Ids - ). - -stop(Pids) -> - lists:foreach(fun(Pid) -> exit(Pid, kill) end, Pids). - -% des trucs qui trainent -bench_get_messages() -> - T = [ - {page,"chat"}, - {cookie,"5G84A5CJXMCPEHNI8T5A9"}, - {message_count,40}, - {last_message_id,0}, - {main_page,1}, - {troll_id,0}, - {conversations,{array,[]}} - ], - moyenne_temps(euphorik_protocole, wait_event, [T], 20). -bench_get_messages_avec_2_conversations() -> - T = [ - {page,"chat"}, - {cookie,"5G84A5CJXMCPEHNI8T5A9"}, - {message_count,40}, - {last_message_id,0}, - {main_page,1}, - {troll_id,0}, - {conversations,{array, [ - {struct, [ - {root, 921}, - {page,1}, - {last_message_id,0} - ]}, - {struct, [ - {root, 772}, - {page, 1}, - {last_message_id, 0} - ]} - ]}} - ], - moyenne_temps(euphorik_protocole, wait_event, [T], 20). -moyenne_temps(Module, Fun, Args, N) -> - moyenne_temps(Module, Fun, Args, N, N, 0). -moyenne_temps(_, _, _, 0, Total, Temps_acc) -> - Temps_acc / Total; -moyenne_temps(Module, Fun, Args, N, Total, Temps_acc) -> - {Temps, _} = timer:tc(Module, Fun, Args), - moyenne_temps(Module, Fun, Args, N - 1, Total, Temps_acc + Temps). - - -% Crée N user avec des noms aléatoires et renvoie la liste des id. -creer_users(N) -> - creer_users(N, []). -creer_users(0, Ids) -> lists:map(fun(#user{id = Id}) -> Id end, Ids); -creer_users(N, Ids) -> - creer_users(N - 1, [euphorik_bd:nouveau_user(mot_rand(random:uniform(4) + 4), "", "", #profile{}) | Ids ]). - - -% crée un message aléatoire et le renvoie -message_rand() -> - lists:flatten(message_rand(random:uniform(10), [])). -message_rand(0, Mots) -> Mots; -message_rand(N, Mots) -> - message_rand(N - 1, [mot_rand(random:uniform(2) + 5), $ | Mots]). - - -% Renvoie une succession de lettre aléatoire -mot_rand(L) -> - mot_rand(L, []). -mot_rand(0, Mot) -> Mot; -mot_rand(L, Mot) -> - mot_rand(L - 1, [random:uniform($z - $a + 1) + $a - 1 | Mot]). - - -% Tire au hasard de 0 à 3 messages sur les 10 derniers postés, renvoie une liste de int() -% répartition : -% 0 : 0.1 -% 1 : 0.95 -% 2 : 0.04 -% 3 : 0.01 -messages_id_rand() -> - R = random:uniform(), - if R =< 0.1 -> - []; - true -> - Messages = lists:map(fun(#minichat{id = Id}) -> Id end, euphorik_bd:messages(8)), - if - R > 0.1 andalso R =< 0.95 -> - tire_element_rand(1, Messages); - R > 0.95 andalso R =< 0.99 -> - tire_element_rand(2, Messages); - true -> - tire_element_rand(3, Messages) - end - end. - - -% tire N element distinct parmis la liste L proposée -tire_element_rand(N, L) when N =< length(L) -> - tire_element_rand(N, L, []); -tire_element_rand(_, _) -> - []. -tire_element_rand(0, _, Elements) -> Elements; -tire_element_rand(N, L, Elements) -> - E = lists:nth(random:uniform(length(L)), L), - E_se_trouve_dans_Elements = lists:any(fun(E2) -> E2 =:= E end, Elements), - if E_se_trouve_dans_Elements -> % si E a déjà été tiré on recommence sans rien changer - tire_element_rand(N, L, Elements); - true -> - tire_element_rand(N-1, L, [E | Elements]) - end. - -loop(User_id, 0) -> - io:format("~p a fini~n", [User_id]); -loop(User_id, M) -> - % attend un temp aléatoire compris entre INTERVALLE_MIN sec et INTERVALLE_MAX sec - timer:sleep(1000 * (random:uniform(?INTERVALLE_MAX - ?INTERVALLE_MIN + 1) + ?INTERVALLE_MIN - 1)), - % poste un message aléatoire par une personne aléatoire répondant à des messages aléatoires - {Message, Repond_a} = {message_rand(), messages_id_rand()}, - % io:format("~p poste ~p et repond a ~w~n", [User_id, Message, Repond_a]), - case euphorik_bd:nouveau_message(Message, User_id, Repond_a) of - {erreur, E} -> - io:format("~p : erreur : ~p~n", [User_id, E]), - loop(User_id, M); - _ -> - loop(User_id, M - 1) - end. - - -% Permet de tester la vitesse d'écriture en fonction de la -% taille de la BD -% voir : http://erlang.org/pipermail/erlang-questions/2008-October/038697.html -bench_write_minichat(Filename) -> - Times = bench_write_minichat(1, []), - {ok, File} = file:open(Filename, [write]), - lists:foreach( - fun({Id, Time}) -> - io:format(File, "~w ~w~n", [Id, Time]) - end, - Times - ), - file:close(File). -bench_write_minichat(100000, Temps) -> Temps; -bench_write_minichat(N, Temps) -> - {T, _} = timer:tc(mnesia, transaction, [fun() -> - Id = mnesia:dirty_update_counter(counter, minichat, 1), - mnesia:write(#minichat{ - id = Id, - auteur_id = random:uniform(10000), - date = now(), - pseudo = "Test", - contenu = "Blabla blabla bla.", - racine_id = random:uniform(10000) - }) - end]), - bench_write_minichat(N + 1, if N rem 500 =:= 0 -> [{N, T} | Temps]; true -> Temps end). - - - - \ No newline at end of file +-define(INTERVALLE_MAX, 5). + + +% N est le nombre d'utilisateur +% M est le nombre de message que chaque utilisateur va poster +start(N, M) -> + Ids = creer_users(N), + lists:map( + fun(Id) -> + timer:sleep(100), + spawn( + fun() -> + {A1, A2, A3} = erlang:timestamp(), + random:seed(A1, A2, A3), + loop(Id, M) + end + ) + end, + Ids + ). + +stop(Pids) -> + lists:foreach(fun(Pid) -> exit(Pid, kill) end, Pids). + +% des trucs qui trainent +bench_get_messages() -> + T = [ + {page,"chat"}, + {cookie,"5G84A5CJXMCPEHNI8T5A9"}, + {message_count,40}, + {last_message_id,0}, + {main_page,1}, + {conversations,{array,[]}} + ], + moyenne_temps(euphorik_protocole, wait_event, [T], 20). +bench_get_messages_avec_2_conversations() -> + T = [ + {page,"chat"}, + {cookie,"5G84A5CJXMCPEHNI8T5A9"}, + {message_count,40}, + {last_message_id,0}, + {main_page,1}, + {conversations,{array, [ + {struct, [ + {root, 921}, + {page,1}, + {last_message_id,0} + ]}, + {struct, [ + {root, 772}, + {page, 1}, + {last_message_id, 0} + ]} + ]}} + ], + moyenne_temps(euphorik_protocole, wait_event, [T], 20). +moyenne_temps(Module, Fun, Args, N) -> + moyenne_temps(Module, Fun, Args, N, N, 0). +moyenne_temps(_, _, _, 0, Total, Temps_acc) -> + Temps_acc / Total; +moyenne_temps(Module, Fun, Args, N, Total, Temps_acc) -> + {Temps, _} = timer:tc(Module, Fun, Args), + moyenne_temps(Module, Fun, Args, N - 1, Total, Temps_acc + Temps). + + +% Crée N user avec des noms aléatoires et renvoie la liste des id. +creer_users(N) -> + creer_users(N, []). +creer_users(0, Ids) -> lists:map(fun(#user{id = Id}) -> Id end, Ids); +creer_users(N, Ids) -> + creer_users(N - 1, [euphorik_bd:nouveau_user(mot_rand(random:uniform(4) + 4), "", "", #profile{}) | Ids ]). + + +% crée un message aléatoire et le renvoie +message_rand() -> + lists:flatten(message_rand(random:uniform(10), [])). +message_rand(0, Mots) -> Mots; +message_rand(N, Mots) -> + message_rand(N - 1, [mot_rand(random:uniform(2) + 5), $ | Mots]). + + +% Renvoie une succession de lettre aléatoire +mot_rand(L) -> + mot_rand(L, []). +mot_rand(0, Mot) -> Mot; +mot_rand(L, Mot) -> + mot_rand(L - 1, [random:uniform($z - $a + 1) + $a - 1 | Mot]). + + +% Tire au hasard de 0 à 3 messages sur les 10 derniers postés, renvoie une liste de int() +% répartition : +% 0 : 0.1 +% 1 : 0.95 +% 2 : 0.04 +% 3 : 0.01 +messages_id_rand() -> + R = random:uniform(), + if R =< 0.1 -> + []; + true -> + Messages = lists:map(fun(#minichat{id = Id}) -> Id end, euphorik_bd:messages(8)), + if + R > 0.1 andalso R =< 0.95 -> + tire_element_rand(1, Messages); + R > 0.95 andalso R =< 0.99 -> + tire_element_rand(2, Messages); + true -> + tire_element_rand(3, Messages) + end + end. + + +% tire N element distinct parmis la liste L proposée +tire_element_rand(N, L) when N =< length(L) -> + tire_element_rand(N, L, []); +tire_element_rand(_, _) -> + []. +tire_element_rand(0, _, Elements) -> Elements; +tire_element_rand(N, L, Elements) -> + E = lists:nth(random:uniform(length(L)), L), + E_se_trouve_dans_Elements = lists:any(fun(E2) -> E2 =:= E end, Elements), + if E_se_trouve_dans_Elements -> % si E a déjà été tiré on recommence sans rien changer + tire_element_rand(N, L, Elements); + true -> + tire_element_rand(N-1, L, [E | Elements]) + end. + +loop(User_id, 0) -> + io:format("~p a fini~n", [User_id]); +loop(User_id, M) -> + % attend un temp aléatoire compris entre INTERVALLE_MIN sec et INTERVALLE_MAX sec + timer:sleep(1000 * (random:uniform(?INTERVALLE_MAX - ?INTERVALLE_MIN + 1) + ?INTERVALLE_MIN - 1)), + % poste un message aléatoire par une personne aléatoire répondant à des messages aléatoires + {Message, Repond_a} = {message_rand(), messages_id_rand()}, + % io:format("~p poste ~p et repond a ~w~n", [User_id, Message, Repond_a]), + case euphorik_bd:nouveau_message(Message, User_id, Repond_a) of + {erreur, E} -> + io:format("~p : erreur : ~p~n", [User_id, E]), + loop(User_id, M); + _ -> + loop(User_id, M - 1) + end. + + +% Permet de tester la vitesse d'écriture en fonction de la +% taille de la BD +% voir : http://erlang.org/pipermail/erlang-questions/2008-October/038697.html +bench_write_minichat(Filename) -> + Times = bench_write_minichat(1, []), + {ok, File} = file:open(Filename, [write]), + lists:foreach( + fun({Id, Time}) -> + io:format(File, "~w ~w~n", [Id, Time]) + end, + Times + ), + file:close(File). +bench_write_minichat(100000, Temps) -> Temps; +bench_write_minichat(N, Temps) -> + {T, _} = timer:tc(mnesia, transaction, [fun() -> + Id = mnesia:dirty_update_counter(counter, minichat, 1), + mnesia:write(#minichat{ + id = Id, + auteur_id = random:uniform(10000), + date = erlang:timestamp(), + pseudo = "Test", + contenu = "Blabla blabla bla.", + racine_id = random:uniform(10000) + }) + end]), + bench_write_minichat(N + 1, if N rem 500 =:= 0 -> [{N, T} | Temps]; true -> Temps end). + + +