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