Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

import version publique du client de test de mont�e en charge.

SVN Revision: 2
  • Loading branch information...
commit da16c35c496b39621e104655b4c10ffcd8d3838b 1 parent cf947d6
Nicolas Niclausse nniclausse authored
Showing with 4,414 additions and 0 deletions.
  1. +8 −0 CONTRIBUTORS
  2. +340 −0 COPYING
  3. +123 −0 LISEZMOI
  4. +83 −0 Makefile
  5. +116 −0 README
  6. +21 −0 TODO
  7. +102 −0 doc/Desing.txt
  8. +108 −0 doc/Desing_fr.txt
  9. +51 −0 doc/Jabber.txt
  10. +62 −0 idx-tsunamirc
  11. +36 −0 include/ts_jabber.hrl
  12. +79 −0 include/ts_profile.hrl
  13. +410 −0 src/analyse_msg.pl.src
  14. +246 −0 src/idx-tsunami.pl.src
  15. +44 −0 src/jabber_auth.erl
  16. +226 −0 src/jabber_common.erl
  17. +47 −0 src/jabber_dynamic.erl
  18. +68 −0 src/jabber_offline.erl
  19. +64 −0 src/jabber_online.erl
  20. +36 −0 src/jabber_register.erl
  21. +90 −0 src/jabber_roster.erl
  22. +90 −0 src/jabber_unique.erl
  23. +41 −0 src/make_boot.erl
  24. +217 −0 src/ts_client.erl
  25. +166 −0 src/ts_client_rcv.erl
  26. +65 −0 src/ts_client_sup.erl
  27. +141 −0 src/ts_launcher.erl
  28. +198 −0 src/ts_mon.erl
  29. +130 −0 src/ts_msg_server.erl
  30. +65 −0 src/ts_profile.erl
  31. +161 −0 src/ts_req_server.erl
  32. +73 −0 src/ts_stats.erl
  33. +75 −0 src/ts_sup.erl
  34. +155 −0 src/ts_timer.erl
  35. +276 −0 src/ts_user_server.erl
  36. +57 −0 src/ts_utils.erl
  37. +85 −0 src/tsunami.app.src
  38. +53 −0 src/tsunami.erl
  39. +4 −0 src/tsunami.rel.src
  40. +2 −0  vsn.mk
8 CONTRIBUTORS
View
@@ -0,0 +1,8 @@
+$Id$
+
+AUTHORS OF IDX-TSUNAMI:
+======================
+
+o Nicolas Niclausse <nicolas.niclausse@IDEALX.com>: Maintainer; idea and initial
+ implementation; OTP redesign.
+o Jean Fran�ois Lecomte <jflecomte@IDEALX.com>: several enhancements.
340 COPYING
View
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program 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 2 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
123 LISEZMOI
View
@@ -0,0 +1,123 @@
+# $Id$
+
+ IDX-TSUNAMI LISEZMOI
+ IDEALX
+ ____________________________________________________________
+
+ Table des mati�res
+
+
+ 1. Introduction
+
+ 1.1 G�n�ralit�s
+ 1.2 Qu'est-ce que ce logiciel fait
+
+ 2. Installation
+
+ 2.1 D�pendances
+ 2.2 Compilation et Installation
+ 2.3 Probl�mes/Bugs
+ 2.4 Portabilit�
+
+ ______________________________________________________________________
+
+ 1. Introduction
+
+ 1.1. G�n�ralit�s
+
+ Ce document donne un rapide descriptifs de IDX-TSUNAMI.
+
+ Les information de Copyright sont disponibles dans le fichier "COPYING."
+
+ 1.2. Qu'est-ce que ce logiciel fait
+
+ Le propos de IDX-TSUNAMI est de simuler des utilisateurs afin de
+ tester la mont�e en charge et les performances d'applications
+ client/serveur (bas�es sur IP). Actuellement, seul le protocole
+ Jabber est impl�ment� et test�, mais IDX-TSUNAMI est tr�s facilement
+ extensible (voir le fichier doc/Design_fr.txt pour une description
+ de l'impl�mentation et des possibilit�s d'extensions). IDX-TSUNAMI
+ utilise le langage Erlang.
+
+ Ce logiciel est capable de simuler plusieurs milliers d'utilisateurs
+ simultan�ment, et ceux-ci peuvent �tre r�partis sur plusieurs
+ machines. Plus de 10000 utilisateurs peuvent �tre simul�s sur une
+ seule machine; la limite sup�rieure d�pend du type de hardware et
+ �galement de l'activit� des clients simul�s.
+
+ L'id�e est de simuler le comportement d'un client r�el en utilisant
+ un mod�le de type stochastique, ceci afin de reproduire le trafic
+ plus fid�lement que peuvent le faire de simple mod�les d�terministes.
+
+ Un utilisateur est caract�ris� par:
+ - le temps �coul� entre chacun de ses messages/requ�tes ("think time")
+ - le nombre de requ�tes effectu�es lors d'une session
+ - le type et les param�tres param�tres des requ�tes (par exemple
+ le type et la taille du message pour Jabber)
+
+ Un autre param�tre est le taux d'arriv�s des clients (ie. le nombre
+ de clients arrivant sur le syst�me -- d�marrant leur session -- par
+ unit� de temps).
+
+ Dans l'impl�mentation actuelle, la taux d'arriv� des clients et le
+ temps entre message d'un m�me client ("think time") sont mod�lis�s
+ par une distribution exponentielle (par cons�quent, le processus
+ d'arriv� est un processus de Poisson).
+
+ La trafic peut �tre "loggu�" dans des fichiers, afin de pouvoir
+ calculer toutes sorte de mesures (temps de r�ponse) apr�s coup. Un
+ script (calculant notamment les moyennes, �cart-type et m�diane des
+ temps de r�ponse) est fourni pour le protocole Jabber.
+
+ 2. Installation
+
+ 2.1. D�pendances
+
+ - n�cessite Erlang/OTP R7B-0 ou sup�rieur (test� avec la version R7B-2)
+ (http://www.erlang.org/download.html)
+
+ - perl5 (pour utiliser les scripts)
+
+ - gnuplot (optionnel, utilis� pour les sorties graphiques du script
+ analyse_msg.pl)
+
+ 2.2. Compilation et Installation
+
+ �diter les fichiers Makefile et idx-tsunami.pl si vous voulez
+ changer le chemin par d�faut (/usr/local/idx-tsunami/).
+
+ �diter src/tsunami.rel.src si votre version d'Erlang n'est pas R7B-2
+ (les num�ros de version des modules erts, kernel et stdlib sont
+ diff�rents d'une version d'Erlang � l'autre)
+
+ make
+ make install
+
+ Comment l'utiliser:
+ 1a/ �diter le fichier etc/idx-tsunamirc (toutes les options sont
+ d�crites en commentaires)
+
+ 1b/ Lire le fichier doc/Jabber.txt pour des informations sp�cifiques �
+ Jabber
+
+ 2/ utilisez le script "idx-tsunami.pl --start" pour d�marrer les
+ clients simul�s.
+
+ 3/ Lorsque c'est termin� (idx-tsunami.pl --stop pour forcer) Le
+ script analyse_msg.pl g�n�re une synth�se des temps de r�ponses
+ (n�cessite un monitoring full ou light); ce script peut �galement
+ g�n�rer des graphes avec l'option --plot.
+
+ 2.3. Probl�mes/Bugs
+
+ Envoyez vos questions/rapports de bugs aux auteurs (cf. fichier
+ CONTRIBUTORS).
+
+ 2.4. Portabilit�
+
+ Ce logiciel n'a �t� test� que sous Linux. Il devrait n�anmoins
+ fonctionner sus toute plateforme support� par Erlang (Solaris et
+ FreeBSD en particulier)
+
+
+
83 Makefile
View
@@ -0,0 +1,83 @@
+# $Id$
+
+
+include vsn.mk
+VSN = $(IDX-TSUNAMI_VSN)
+TSUNAMIPATH = .
+TARDIR = idx-tsunami-$(VSN)
+PA = -pa ./ebin -pa ./src -pa . -pa ./system -pa ../ebin -pa .. -pa ../system -pa ../src
+
+prefix = /usr/local/idx-tsunami
+
+ERLC = erlc
+OUTDIR = ebin
+OBJS = \
+ $(OUTDIR)/tsunami.beam \
+ $(OUTDIR)/ts_launcher.beam \
+ $(OUTDIR)/ts_client.beam \
+ $(OUTDIR)/ts_client.beam \
+ $(OUTDIR)/ts_mon.beam \
+ $(OUTDIR)/ts_client_rcv.beam \
+ $(OUTDIR)/ts_utils.beam \
+ $(OUTDIR)/ts_profile.beam \
+ $(OUTDIR)/ts_stats.beam \
+ $(OUTDIR)/ts_user_server.beam \
+ $(OUTDIR)/ts_msg_server.beam \
+ $(OUTDIR)/ts_req_server.beam \
+ $(OUTDIR)/ts_timer.beam \
+ $(OUTDIR)/ts_client_sup.beam \
+ $(OUTDIR)/ts_sup.beam \
+ $(OUTDIR)/jabber_common.beam \
+ $(OUTDIR)/jabber_dynamic.beam \
+ $(OUTDIR)/jabber_roster.beam \
+ $(OUTDIR)/jabber_online.beam \
+ $(OUTDIR)/jabber_offline.beam \
+ $(OUTDIR)/jabber_auth.beam \
+ $(OUTDIR)/jabber_unique.beam \
+ $(OUTDIR)/jabber_register.beam \
+ $(OUTDIR)/make_boot.beam
+
+all: tsunami.boot
+
+tarball:
+ mkdir -p $(TARDIR)
+ tar zcf tmp.tgz src/*.erl src/*.src include/*.hrl doc/*.txt LISEZMOI README CONTRIBUTORS COPYING src/idx-tsunami.pl.src idx-tsunamirc TODO Makefile vsn.mk src/analyse_msg.pl.src
+ tar -C $(TARDIR) -zxf tmp.tgz
+ mkdir $(TARDIR)/ebin
+ tar zvcf idx-tsunami-$(VSN).tar.gz $(TARDIR)
+ rm -fr $(TARDIR)
+ rm -fr tmp.tgz
+
+
+clean:
+ rm -f $(OBJS) tsunami.boot tsunami.script ebin/tsunami.app ebin/tsunami.rel ebin/idx-tsunami.pl ebin/analyse_msg.pl
+
+tsunami.boot: $(OBJS) $(UTILS) src/tsunami.rel.src src/tsunami.app.src src/analyse_msg.pl.src src/idx-tsunami.pl.src
+ sed -e 's;%VSN%;$(VSN);' ./src/tsunami.app.src > ./ebin/tsunami.app
+ sed -e 's;%VSN%;$(VSN);' ./src/tsunami.rel.src > ./ebin/tsunami.rel
+ sed -e 's;%VSN%;$(VSN);' ./src/idx-tsunami.pl.src > ./ebin/idx-tsunami.pl
+ sed -e 's;%VSN%;$(VSN);' ./src/analyse_msg.pl.src > ./ebin/analyse_msg.pl
+ erl -noshell $(PA) ./src -s make_boot make_boot tsunami
+
+$(OUTDIR)/%.beam: ebin/%.erl
+ $(ERLC) -o $(OUTDIR) $<
+
+$(OUTDIR)/%.beam: src/%.erl include/*.hrl
+ $(ERLC) -o $(OUTDIR) $<
+
+install: tsunami.boot
+ mkdir -p $(DESTDIR)/$(prefix)
+ mkdir -p $(DESTDIR)/$(prefix)/bin
+ mkdir -p $(DESTDIR)/$(prefix)/log
+ mkdir -p $(DESTDIR)/$(prefix)/etc
+ mkdir -p $(DESTDIR)/$(prefix)/bin
+ install -m 0644 tsunami.boot $(DESTDIR)/$(prefix)/bin
+ install -m 0644 idx-tsunamirc $(DESTDIR)/$(prefix)/etc
+ install ebin/idx-tsunami.pl $(DESTDIR)/${prefix}/bin
+ install ebin/analyse_msg.pl $(DESTDIR)/${prefix}/bin
+ mkdir -p $(DESTDIR)/$(prefix)
+ mkdir -p $(DESTDIR)/$(prefix)/erlang
+ mkdir -p $(DESTDIR)/$(prefix)/erlang/tsunami-$(VSN)
+ mkdir -p $(DESTDIR)/$(prefix)/erlang/tsunami-$(VSN)/ebin
+ install $(OBJS) $(DESTDIR)/$(prefix)/erlang/tsunami-$(VSN)/ebin
+
116 README
View
@@ -0,0 +1,116 @@
+# $Id$
+
+ IDX-TSUNAMI README
+ IDEALX
+ ____________________________________________________________
+
+ Table of Contents
+
+
+ 1. Introduction
+
+ 1.1 General
+ 1.2 What This Package Is
+
+ 2. Getting Things Installed
+
+ 2.1 Dependencies
+ 2.2 Compilation and Installation
+ 2.3 Problems/Bugs
+ 2.4 Platform Issues
+
+ ______________________________________________________________________
+
+ 1. Introduction
+
+ 1.1. General
+
+ This document gives pointers for information on this package.
+
+ Copyright information can be found in the file "COPYING."
+
+ 1.2. What This Package Is
+
+ The purpose of this package is to simulate users in order to test
+ the scalability and performances of IP based client/server
+ applications. Currently, only the Jabber protocol has been
+ implemented and tested, but it can be easily extended (see
+ doc/Design.txt). IDX-TSUNAMI use the Erlang language.
+
+ This tool can simulate thousands of users concurrently, and can be
+ distributed on several client machines. Up to 10000 users can be
+ simulated on a single machine (the limit depends on the hardware and
+ also on the activity of the simulated clients).
+
+ The idea is to simulate the behavior of a real world client using a
+ stochastic model, in order to achieve a more realistic traffic than
+ other simple models (deterministics).
+
+ In this context, a client is characterize by:
+ - the time elapsed between each request ("think time")
+ - the number of requests during a session
+ - the type and parameters of requests (including, for example,
+ message size for Jabber)
+
+ Another key parameter is the arrival rate of clients.
+
+ In the current implementation, the client arrival rate and the user
+ "think time" are represented by an exponential distribution
+ (therefore, the arrival process is a Poisson process)
+
+ The traffic can be logged to a file and, after completion of
+ all the clients, these files can be analyzed by scripts to get
+ useful measurements of responses time. An small script is furnished
+ for the Jabber protocol (mean, median, standard variation, and so on
+ are computed, for different types of messages: authentication,
+ chat, offline messages ...)
+
+ This software is currently under development and can be enhanced
+ in many ways (see TODO file).
+
+ 2. Getting Things Installed
+
+ 2.1. Dependencies
+
+ - requires Erlang/OTP R7B-0 or up (tested with R7B-2)
+ (http://www.erlang.org/download.html)
+
+ - perl5 (if you want tu use the scripts)
+
+ - gnuplot (optional; for graphical output with analyse_msg.pl script)
+
+ 2.2. Compilation and Installation
+
+ Edit Makefile and idx-tsunami.pl if you want to change the install
+ path (/usr/local/idx-tsunami by default)
+
+ Edit src/tsunami.rel.src if your Erlang version is not R7B-2 and set
+ erts, kernel and stdlib version according to your Erlang
+ distribution.
+
+ make
+ make install
+
+ How to use it:
+ 1a/ Edit etc/idx-tsunamirc file (read the comments for explanation on
+ the parameters)
+
+ 1b/ Read the doc/Jabber.txt file for Jabber-specific information.
+
+ 2/ use the script "idx-tsunami.pl --start" to launch the simulated clients.
+
+ 3/ When it's finished, you can use analyse_msg.pl to get
+ statistical results from the logfiles (require at least 'light'
+ monitoring, see comments in 'idx-tsunamirc' )
+
+ 2.3. Problems/Bugs
+
+ Submit bug reports/ask questions to the authors (see CONTRIBUTORS)
+
+ 2.4. Platform Issues
+
+ This package has only be tested on Linux. It should work
+ on Erlang supported platforms (Solaris, *BSD)
+
+
+
21 TODO
View
@@ -0,0 +1,21 @@
+- groupchat for Jabber
+
+- Maybe use a single gen_server instead of 4 (msg, user, request, timer)
+
+- instead of logging everything, let the client (or the monitor)
+ compute stats ?
+
+- Maybe use a single monitor process for all beams ? this allow us to
+centralise the results, (but it can be a bottleneck if too much
+logging data are sent to it ?)
+
+- implement client parsing server response (needed for some protocols)
+
+- clients may do a checksum to control integrity of responses ?
+
+- implement http protocol:
+ - reuse already existing erlang modules.
+ - handle non persistant connections (http/1.0) within a user session
+ - how to handle http/1.1 pipelining ?
+
+- other useful protocols: ftp, ldap, sql ... ?
102 doc/Desing.txt
View
@@ -0,0 +1,102 @@
+
+OTP Supervision tree:
+====================
+
+ * ts_mon (gen_server)
+
+ * ts_timer (used by ts_client_rcv when ack is global) (gen_fsm)
+
+ * ts_client_sup -> ts_client, ts_client_rcv
+
+ servers used to construct messages:
+
+ * ts_req_server (gen_server) can generate messages extracted from an external file
+ * ts_msg_server (gen_server)
+ * ts_user_server (gen_server) used by ts_launcher and jabber_* for unicity of users id
+
+ main server
+
+ * ts_launcher (gen_fsm) launch simulated users.
+
+Main modules:
+============
+
+ 1/ ts_launcher. the master process that spawns other processes:
+
+ 1.1/ client processes: at each simulated client correspond 2 erlang
+ process:
+
+ a/one that will initiate TCP (UDP) connection and will send
+ messages (ts_client module). These process are spawns by
+ ts_launcher (using an sleeping time between two clients
+ following an exponential distribution).
+
+ b/ Each of these process will spawn a new process to handle
+ incoming data from the server (ts_client_rcv module).
+
+ The total number of clients (NCLIENTS) can be changed in the
+ config file. It represent the total number of clients that
+ will be launched, and not the maximal simultaneous number of
+ client.
+
+ Warning: All the messages for a user session are computed by
+ ts_launcher, just before spawning the user process (in a
+ list). Therefore, if the number of messages is huge, it can
+ takes A LOT of memory. If you want to do very long experiments,
+ use a single 'dynamic' messages (see jabber_dynamic and
+ Jabber.txt for an exemple), which will be send over and over by
+ the user.
+
+ Important parameters for Jabber :
+ 1/ chat messages size, in bytes (250 by default)
+
+ 2/ mean time elapsed between two consecutives messages sent by a user
+
+ 3/ number of messages sent by a user during a session
+
+ 1.2/ monitoring process (ts_mon)
+
+ 2/ statistical module (ts_stats)
+
+ 3/ a generic module for building user sessions (ts_profile)
+
+ 4/ protocol-specific modules (jabber_online for example).
+
+How to add a new protocol, or extend an existing one:
+====================================================
+
+ A protocol has to implement the API defined in profile.erl, ie.
+ must implement these functions:
+ - get_client/2
+ - get_random_message/1
+
+References:
+==========
+
+ - Erlang
+
+ http://www.erlang.org/
+
+ Design principles:
+ http://www.erlang.org/doc/r7b/doc/design_principles/part_first.html
+
+ - Jabber
+
+ http://docs.jabber.org/general/html/protocol.html
+
+
+ - Stochastics models:
+
+ For more details on stochastics models and application to Web
+ workload generators, take a look at:
+
+ Nicolas Niclausse. Mod�lisation, analyse de performance et
+ dimensionnement du World Wide Web. Th�se de Doctorat (PhD), Universit�
+ de Nice - Sophia Antipolis, Juin 1999.
+ http://www-sop.inria.fr/mistral/personnel/Nicolas.Niclausse/these.html
+
+ Z. Liu, N. Niclausse, C. Jalpa-Villanueva & S. Barbier. Traffic
+ Model and Performance Evaluation of Web Servers Rapport de
+ recherche INRIA, RR-3840 (http://www.inria.fr/rrrt/rr-3840.html)
+
+
108 doc/Desing_fr.txt
View
@@ -0,0 +1,108 @@
+Arbre de supervision OTP:
+========================
+
+ * ts_mon (gen_server)
+
+ * ts_timer (utilis� par ts_client_rcv en global) (gen_fsm)
+
+ * ts_client_sup -> ts_client, ts_client_rcv
+
+ serveurs utilis�s pour construire les messages:
+
+ * ts_req_server (gen_server) permet de g�n�rer des messages � partir
+ d'un fichier externe
+
+ * ts_msg_server (gen_server)
+
+ * ts_user_server (gen_server) utilis� par ts_launcher et jabber_*
+ pour l'unicit� des utilisateurs
+
+ * ts_launcher (gen_fsm) lance les clients simul�s (selon un processus de
+ Poisson).
+
+
+
+Le principaux modules sont:
+==========================
+
+ 1/ ts_launcher. Le processus ma�tre qui va lancer les autres processus :
+
+ 1.1/ processus clients initiant les connexions TCP
+ (module ts_client). Ces processus sont lanc�s par le processus
+ ma�tre avec un intervalle de temps suivant une distribution de
+ probabilit� exponentielle d'intensit� param�trable au d�marrage
+ (unit� = sec). Chaque processus client va lancer un processus
+ pour recevoir et traiter les messages (module
+ ts_client_rcv). Le nombre de clients total est �galement
+ param�trable au d�marrage du processus ma�tre (il s'agit bien du
+ nombre de client total et non du nombre de clients simultan�s)
+
+ Warning: Tous les messages d'une session d'un utilisateur sont
+ construits par ts_launcher, juste avant de lancer le processus
+ client (dans une liste). Par cons�quent, si le nombre de
+ messages est tr�s grand, cela peut prendre BEAUCOUP de
+ m�moire. Pour r�aliser de tr�s long tests, if faut utiliser un
+ message de type 'dynamic' (voir jabber_dynamic et Jabber.txt
+ pour un exemple d'utilisation), qui sera construit � la vol�e
+ par le client autant de fois que n�cessaire.
+
+ Les param�tres importants r�gissant le comportement des
+ utilisateurs (pour Jabber) sont:
+
+ 1/ taille des messages de chat en octets (250 par d�faut)
+
+ 2/ distribution de probabilit� des intervalles de temps
+ entre chaque envoi de message de chat (loi
+ exponentielle).
+
+ 3/ Le nombre de messages de chat envoy�s par chaque
+ client. La valeur par d�faut est de 20.
+
+ 1.2/ Le processus de monitoring (module ts_mon)
+
+ 2/ Un module pour g�rer les �chantillons al�atoire (module ts_stats)
+
+ 3/ Un module (ts_profile) g�n�rique pour g�rer les sessions des clients
+
+ 4/ Les modules sp�cifiques pour g�rer les diff�rents protocoles (module
+ jabber_online par ex.).
+
+Comment rajouter un nouveau protocole ou �tendre un existant:
+============================================================
+
+ Tout protocole doit impl�menter l'API d�finie dans profile.erl, ie.
+ doit impl�menter les fonctions suivantes:
+ - get_client/2
+ - get_random_message/1
+
+
+R�f�rences:
+==========
+
+ - Erlang
+
+ http://www.erlang.org/
+
+ Design principles:
+ http://www.erlang.org/doc/r7b/doc/design_principles/part_first.html
+
+ - Jabber
+
+ http://docs.jabber.org/general/html/protocol.html
+
+
+ - mod�lisation stochastiques :
+
+ Plus de d�tails sur ce type de mod�lisation sont disponibles dans les
+ documents suivants (dans le contexte du protocole HTTP)
+
+ Nicolas Niclausse. Mod�lisation, analyse de performance et
+ dimensionnement du World Wide Web. Th�se de Doctorat, Universit�
+ de Nice - Sophia Antipolis, Juin 1999.
+ http://www-sop.inria.fr/mistral/personnel/Nicolas.Niclausse/these.html
+
+ Z. Liu, N. Niclausse, C. Jalpa-Villanueva & S. Barbier. Traffic
+ Model and Performance Evaluation of Web Servers Rapport de
+ recherche INRIA, RR-3840 (http://www.inria.fr/rrrt/rr-3840.html)
+
+
51 doc/Jabber.txt
View
@@ -0,0 +1,51 @@
+Requirements:
+============
+
+users has to be already registered:
+
+IDX-TSUNAMI users name : cXX
+ passwd: pasXX
+
+where XX is a integer between 1 and the maximum number of users (say 1000000).
+
+
+optional parameters: (can be set in idx-tsunamirc file)
+==================
+
+JABBER_DOMAIN=mydomain.com
+N_ROSTER_CLIENTS=6 (see above)
+
+modules implemented for the Jabber protocole:
+============================================
+
+- jabber_common: module regrouping common functions for
+ build messages
+
+- jabber_online: simulate users sending 'chat' messages to online clients only.
+
+- jabber_unique: simulate users sending 'chat' messages to a single user.
+ %% REM: kesquisepasse avec plusieurs beams ???
+
+- jabber_offline: simulate users sending 'chat' messages to offline clients
+ only.
+
+- jabber_auth: simulate users that connects to ther server and then
+ leave without sending messages.
+
+- jabber_roster: simulate users sending presence, roster:set and
+ roster:get messages.
+ Each client send N_ROSTER_CLIENTS type='subscribed' messages, and
+ after upload their roster MESSAGES_NUMBER times.
+ the variable N_ROSTER_CLIENTS (6 by default) can be changed in the
+ config file.
+
+- jabber_register: each simultated user send a jabber:iq:register,
+ type=set message to the server.
+
+- jabber_dynamic: simulate users sending dynamic messages (messages
+ are build on the fly by the process, and not at the startup time like
+ other messages. This allow you to use a really big value for
+ MESSAGES_NUMBER without taking too much memory).
+
+
+NOTE: currently, no XML parsing is done by the receiving process.
62 idx-tsunamirc
View
@@ -0,0 +1,62 @@
+# $Id$
+
+# server IP and port (several IP separated by a ":" can be entered: it
+# will be distributed across all clients beam)
+SERVER_ADR=127.0.0.1
+SERVER_PORT=5222
+
+# type of client
+# possible values: jabber_online, jabber_unique, jabber_offline, jabber_auth,
+# jabber_roster, jabber_dynamic
+CLIENT_TYPE=jabber_online
+
+# type of acknoledgment, 'global' means clients start to send messages
+# when all of them are connected (for each beam), 'local' means they
+# wait for a response from the server ("auth ok" for ex.), 'no_ack' means
+# they didn't wait for a response.
+MESSAGE_ACK=local
+
+# mean client intearrival (in sec, can be a float) for ex. a value of
+# 0.01 sec will lead to 100 new clients every second (on average).
+INTERARRIVAL=0.1
+
+# number of message/request sent by each client during a session.
+MESSAGES_NUMBER=10
+
+# average elapsed time between two messages/requests sent by a client, in sec.
+MESSAGES_INTERARRIVAL=120
+
+# Total number of clients (distributed across all machines)
+NCLIENTS=20
+
+# list of machines (hostname or IP), separated by a ":"
+MACHINES=localhost
+
+# config file access (needed to copy dynamically generated config
+# files to remote machines). Possible values are: nfs or scp.
+# Not used if a machine is localhost
+FILE_ACCES=nfs
+
+# monitoring (full,light or none). Use 'full' is you want to have a
+# full dump of all the traffic (warning: use more RAM, and can use a
+# lot of disk space). Using 'light', you will have only the first bytes of
+# every packets, and 'none' will log nothing at all.
+MONITORING=full
+
+# logfile name
+LOG_FILE=/usr/local/idx-tsunami/log/idx-tsunami.log
+
+# verbosity level: 7 mean lots of debugging info; 4 by default. min = 0
+DEBUG_LEVEL=4
+
+# erlang cookie.
+COOKIE=tsunami
+
+###
+### Jabber specific parameters
+###
+# JABBER_DOMAIN=mydomain.com
+
+# used by jabber_roster
+# size of the roster to be set (must be a multiple of 2)
+# N_ROSTER_CLIENTS=6
36 include/ts_jabber.hrl
View
@@ -0,0 +1,36 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-record(jabber, {dest, size, type, jud_param, cle, id = 0}).
+
+-define(jabber_users, ts_utils:get_val(jabber_users)).
+-define(jabber_domain, ts_utils:get_val(jabber_domain)).
+-define(jabber_server, ts_utils:get_val(jabber_server)).
+-define(jabber_username, ts_utils:get_val(jabber_username)).
+-define(jabber_password, ts_utils:get_val(jabber_password)).
+-define(n_roster_clients, ts_utils:get_val(n_roster_clients)).
+-define(setroster_intensity, 1/(ts_utils:get_val(setroster)*1000)).
+-define(req_filename, ts_utils:get_val(req_filename)).
+-define(presence_delay, ts_utils:get_val(presence_delay)).
+-define(boucle1_percent, ts_utils:get_val(boucle1_percent)).
+-define(boucle2_percent, ts_utils:get_val(boucle2_percent)).
+-define(boucle3_percent, ts_utils:get_val(boucle3_percent)).
79 include/ts_profile.hrl
View
@@ -0,0 +1,79 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-record(message, {thinktime, ack, param, type=static}).
+
+-define(restart_sleep, 2000).
+-define(retries, 4).
+
+-define(restart_try, 3).
+-define(debug_level, ts_utils:get_val(debug_level)).
+
+-define(messages_intensity, 1/(ts_utils:get_val(messages_interarrival)*1000)).
+-define(clients_intensity, 1/(ts_utils:get_val(interarrival)*1000)).
+
+-define(messages_ack, ts_utils:get_val(messages_ack)).
+-define(messages_size, ts_utils:get_val(messages_size)).
+-define(messages_number, ts_utils:get_val(messages_number)).
+-define(messages_last_time, ts_utils:get_val(messages_last_time)).
+
+-define(nclients, ts_utils:get_val(nclients)).
+-define(nclients_deb, ts_utils:get_val(nclients_deb)).
+-define(nclients_fin, ts_utils:get_val(nclients_fin)).
+-define(client_type, ts_utils:get_val(client_type)).
+-define(parse_type, ts_utils:get_val(parse_type)).
+-define(mes_type, ts_utils:get_val(mes_type)).
+
+-define(snd_size, ts_utils:get_val(snd_size)).
+-define(rcv_size, ts_utils:get_val(rcv_size)).
+-define(tcp_timeout, ts_utils:get_val(tcp_timeout)).
+
+-define(log_file, ts_utils:get_val(log_file)).
+-define(monitoring, ts_utils:get_val(monitoring)).
+-define(monitor_timeout, ts_utils:get_val(monitor_timeout)).
+-define(clients_timeout, ts_utils:get_val(clients_timeout)).
+
+-define(server_adr, ts_utils:get_val(server_adr)).
+-define(server_port, ts_utils:get_val(server_port)).
+
+
+%% errors messages
+-define(DEBUG, TRUE).
+
+-ifdef(DEBUG).
+ -define(PRINTDEBUG(Msg, Args, Level),
+ ts_utils:debug(?MODULE, Msg, Args, Level)).
+ -define(PRINTDEBUG2(Msg, Level),
+ ts_utils:debug(?MODULE, Msg, Level)).
+-else.
+ -define(PRINTDEBUG(Msg, Args, Level), ok).
+ -define(PRINTDEBUG2(Msg, Level), ok).
+-endif.
+
+-define(EMERG, 0). % The system is unusable.
+-define(ALERT, 1). % Action should be taken immediately to address the problem.
+-define(CRIT, 2). % A critical condition has occurred.
+-define(ERR, 3). % An error has occurred.
+-define(WARN, 4). % A significant event that may require attention has occurred.
+-define(NOTICE, 5).% An event that does not affect system operation has occurred.
+-define(INFO, 6). % An normal operation has occurred.
+-define(DEB, 7). % Debugging info
410 src/analyse_msg.pl.src
View
@@ -0,0 +1,410 @@
+#!/usr/bin/perl -w
+#
+# This code was developped by IDEALX (http://IDEALX.org/) and
+# contributors (their names can be found in the CONTRIBUTORS file).
+# Copyright (C) 2000-2001 IDEALX
+#
+# This program 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 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+# Version: $Id$
+
+# purpose: quick and dirty ugly hack to compute stats and plots graph
+# given a (set of) log file(s) from the benchmark tool.
+
+
+# offline_send : time between <message>.....MESSAGE OFFLINE
+# offline_rcv : time between <presence>....<message type='offline'>
+# deconnexion : time between </stream:stream>......</stream:stream>
+# roster : durée de réception presence (y compris à travers le stockage offline -> pas représentatif et potentiellement très long)
+# error : time to receive an error notification
+# auth: time for authentication <iq auth>....<iq result>
+# online: time for message transmission
+
+use strict;
+use Getopt::Long;
+use vars qw ($help @files $verbose $debug $plot $version);
+my $tagvsn = '%VSN%';
+
+GetOptions( "help",\$help,
+ "verbose",\$verbose,
+ "debug",\$debug,
+ "version",\$version,
+ "plot",\$plot
+ );
+
+&usage if $help || $Getopt::Long::error;
+&version if $version;
+
+
+my $debut = 0;
+my $fin = 0;
+my $online = 0;
+my $online_real = 0;
+my $auth = 0;
+my $offline = 0;
+my $offline_send = 0;
+my $offline_rcv = 0;
+my $deconnexion = 0;
+my $finsend = 0;
+my $roster = 0;
+my $error = 0;
+my %fin;
+my (%offline_id, %online_id);
+my %offline_rcv;
+my %offline_send;
+my %presence;
+my %esperance;
+my %deconnexion;
+my %var;
+my %roster;
+my %jud;
+my ($message_number,$delta,$tmp,@online,@auth,@offline_rcv,@offline_send,@deconnexion,@roster,@error);
+# ugly, we should use a hash of table ...
+my (@online_time,@auth_time,@offline_rcv_time,@offline_send_time,@deconnexion_time,@roster_time,@error_time);
+
+$esperance{'online'} = $esperance{'auth'}= $esperance{'deconnexion'}= $esperance{'offline_send'}= $esperance{'offline_rcv'} =$esperance{'roster'}=$esperance{'error'} = 0;
+
+foreach (@ARGV) {
+ &parse_file($_);
+}
+
+if ($debug) {
+ foreach (keys %offline_id) {
+ unless ($online_id{$_}) {
+ print "#$offline_id{$_}\n";
+ }
+ }
+}
+
+if ($verbose) {
+ foreach (keys %jud) {
+ print "$jud{$_} $_\n";
+ }
+}
+
+if ($plot) {
+ open (PLOT,"> stats.data");
+ select PLOT;
+ # first, find the max number of items in each array
+ my ($max) = sort {$b <=> $a} ($#online, $#auth, $#offline_rcv, $#offline_send, $#deconnexion, $#error);
+ my $i;
+
+ my @title= ("Messages (Online, ...)","Authentications"," Offline Messages","Offline Notifications ","Deconnexion","Error");
+ my @max= ($#online,$#auth,$#offline_rcv,$#offline_send,$#deconnexion,$#error);
+ print "# " . join ("\t", @title) . "\n";
+
+ # trick (otherwise, gnuplot stop if a column is full of '-')
+ foreach $i (0..$#title*2) {
+ print "0\t";
+ }
+ print "\n";
+ foreach $i (0..$max) {
+ print defined($online_time[$i])?$online_time[$i]:"-";
+ print "\t";
+ print defined($online[$i])?$online[$i]:"-";
+ print "\t";
+ print defined($auth_time[$i])?$auth_time[$i]:"-";
+ print "\t";
+ print defined($auth[$i])?$auth[$i]:"-";
+ print "\t";
+ print defined($offline_rcv_time[$i])?$offline_rcv_time[$i]:"-";
+ print "\t";
+ print defined($offline_rcv[$i])?$offline_rcv[$i]:"-";
+ print "\t";
+ print defined($offline_send_time[$i])?$offline_send_time[$i]:"-";
+ print "\t";
+ print defined($offline_send[$i])?$offline_send[$i]:"-";
+ print "\t";
+ print defined($deconnexion_time[$i])?$deconnexion_time[$i]:"-";
+ print "\t";
+ print defined($deconnexion[$i])?$deconnexion[$i]:"-";
+ print "\t";
+# print defined($roster_time[$i])?$roster_time[$i]:"-";
+# print "\t";
+# print defined($roster[$i])?$roster[$i]:"-";
+# print "\t";
+ print defined($error_time[$i])?$error_time[$i]:"-";
+ print "\t";
+ print defined($error[$i])?$error[$i]:"-";
+ print "\n";
+ }
+ select STDOUT;
+ &plot(\@title,"stats",\@max);
+
+} else {
+ &print_res();
+}
+
+sub plot {
+ my $data = shift;
+ my $fic = shift;
+ my $maxx= shift;
+ my $style ="point";
+ my $m;
+ my $d;
+
+ open(GP,">graphes-$fic.gplot");
+ select GP;
+
+ print "set data style $style\n";
+ print "set terminal postscript color\n";
+ print "set output \"graphes-$fic.ps\"\n";
+ print "set grid\n";
+
+ for ($d=0;$d<=$#{$data}*2;$d+=2) {
+ print "set title \" " .@{$data}[$d/2] . "\"\n";
+ print "show title\n";
+ print "set key right top\n";
+ print "plot [0:" . ($fin-$debut) ."] ";
+ print " \"$fic.data\" using " .($d+1).":".($d+2) . " title \".@{$data}[$d/2]\"" ;
+ print "\n";
+ }
+
+ # everything in a single graph (broken ?)
+ print "set title \"Summary\"\n";
+ print "show title\n";
+ print "set key right top\n";
+ print "plot [0:" . ($fin-$debut) ."] ";
+ for ($d=0;$d<=$#{$data}*2;$d+=2) {
+ print " \"$fic.data\" using " .($d+1).":".($d+2) . " title \".@{$data}[$d/2]\"" ;
+ print "," unless ($d>=$#{$data}*2); # unless last occurence
+ }
+ print "\n";
+
+ close GP;
+ system("gnuplot graphes-$fic.gplot")
+}
+
+#
+sub parse_file {
+ my $file = shift;
+ my ($type,$d1,$d2,$d3,$pid,$message,$date,%recv,%send,%dat,$id,%mes);
+
+ %presence =();
+ %fin =();
+ %dat=();
+ %mes = ();
+
+ if ($file =~ /\.gz$/) {
+ open(LOG, "zcat $file|" ) or die("Error, can't open file $file");
+ } else {
+ open(LOG, "< $file" ) or die("Error, can't open file $file");
+ }
+ print "# Analysing $file ...\n#\n";
+ while (<LOG>) {
+ if (/(\w+):{(\d+),(\d+),(\d+)}:<0.(\d+).0>:([^\n]+)\n/) {
+ ($type,$d1,$d2,$d3,$pid,$message) = ($1,$2,$3,$4,$5,$6);
+ next if ($message =~ /\?xml/);
+ $date = $d1*1000000+ $d2+ $d3/1000000 ;
+ $debut = $date unless $debut;
+ $fin = $date if ($date > $fin);
+ if ($message =~ /^<presence/) { # presence
+ $presence{$pid} = $date;
+ }
+ next if ($message =~ /^\<stream\:stream/); # connection statup
+ if ($message =~ /^\<\/stream\:stream/) {
+ if ($type eq "Send") {
+ $fin{$pid}= $date;
+ $finsend ++;
+ } else {
+
+ # yuck, ugly !
+ # here we assume that the receiver pid is n+1
+ # where n is the emmiter's pid. This assumption is
+ # not true in all cases. We should use a more
+ # robust algorithm !
+
+ unless ($fin{$pid-1}) {
+ print "# warn, no pid ! $pid\n";
+ next;
+ }
+ $delta = $date - $fin{$pid-1};
+ $tmp = $delta-$esperance{'deconnexion'};
+ $esperance{'deconnexion'} += $tmp/($deconnexion+1);
+ $var{'deconnexion'} += $tmp*($delta-$esperance{'deconnexion'});
+ $deconnexion++;
+ push @deconnexion, $delta;
+ push @deconnexion_time, $fin{$pid-1}-$debut;
+ }
+ next;
+ }
+ if ($message =~ / id='(\d+)'/) {
+ $id = $1;
+ if ((defined $dat{$id}) and ($message !~ /Offline Storage/)) {
+ $delta = $date-$dat{$id};
+ printf "%.3f # %.3f # %.3f # %s # %s\n",$delta,$dat{$id},$date,$mes{$id},$message if ($verbose);
+ if (/<iq id=\'\d+\' type=\'result\'\/>/) { # authentication ack
+ $tmp = $delta-$esperance{'auth'};
+ $esperance{'auth'} += $tmp/($auth+1);
+ $var{'auth'} += $tmp*($delta-$esperance{'auth'});
+ $auth++;
+ push @auth, $delta;
+ push @auth_time, $dat{$id}-$debut;
+ }
+ elsif (/type=\'error\'/) { # error
+ $tmp = $delta-$esperance{'error'};
+ $esperance{'error'} += $tmp/($error+1);
+ $var{'error'} += $tmp*($delta-$esperance{'error'});
+ $error++;
+ push @error, $delta;
+ push @error_time, $dat{$id}-$debut;
+ }
+ elsif (/MESSAGE OFFLINE/) { # offline notification
+ $tmp = $delta-$esperance{'offline_send'};
+ $esperance{'offline_send'} += $tmp/($offline_send+1);
+ $var{'offline_send'} += $tmp*($delta-$esperance{'offline_send'});
+ $offline_send++;
+ push @offline_send, $delta;
+ push @offline_send_time, $dat{$id}-$debut;
+ $offline_id{$id} = $message;
+ }
+ elsif (/presence/) { # roster
+ $tmp = $delta-$esperance{'roster'};
+ $esperance{'roster'} += $tmp/($roster+1);
+ $var{'roster'} += $tmp*($delta-$esperance{'roster'});
+ $roster++;
+ push @roster, $delta;
+ push @roster_time, $dat{$id}-$debut;
+ }
+ else { # online message
+ $message_number = 0;
+ while ($message =~ /<message /g) { $message_number++ }
+ $online_real += $message_number;
+ print "#$message_number\n" if ($verbose);
+ $tmp = $delta-$esperance{'online'};
+ $esperance{'online'} += $tmp/($online+1);
+ $var{'online'} += $tmp*($delta-$esperance{'online'});
+ $online++;
+ push @online, $delta;
+ push @online_time, $dat{$id}-$debut;
+ }
+ undef $dat{$id} ;
+ }
+ elsif ($type eq "Send") {
+ $dat{$id} = $date;
+ $mes{$id} = $message;
+ }
+ elsif (/Offline Storage/){ # offline messages (-> presence)
+ # several messages in a single packet is possible
+ unless ($presence{$pid-1}) {
+ print "# warn, no pid ! $pid\n";
+ next;
+ }
+ $online_id{$id} = $message;
+ $message_number = 0;
+ $delta = $date - $presence{$pid-1};
+ printf "%.3f # %.3f # %.3f # presence # %s ",$delta,$presence{$pid-1},$date,$message if ($verbose);
+ while ($message =~ /<message /g) { $message_number++ }
+ $offline += $message_number;
+ print "#$message_number\n" if ($verbose);
+ $tmp = $delta-$esperance{'offline_rcv'};
+ $esperance{'offline_rcv'} += $tmp/($offline_rcv+1);
+ $var{'offline_rcv'} += $tmp*($delta-$esperance{'offline_rcv'});
+ $offline_rcv++;
+ push @offline_rcv, $delta;
+ push @offline_rcv_time, $presence{$pid-1}-$debut;
+ }
+ else {
+ print "## single # $type # $date # $message\n" if ($debug);
+ }
+ }
+ else { # if the message is fragmented in reveral IP packets
+ print "#\n## unknown # $type # $date # $message\n" if ($debug);
+ }
+ }
+ else {
+ next if (/NewClient/);
+ next if (/EndClient/);
+ next if (/load:/);
+ next if (/timeout monitor/);
+ print "# bad match : $_\n" if ($debug);
+ }
+ }
+}
+
+
+sub print_res {
+ &stats("# Messages (real = $online_real):",'online', $online, \@online);
+ &stats("# Error:",'error', $error, \@error);
+ &stats("# Authentication:",'auth', $auth, \@auth);
+ &stats("# Offline Notification:",'offline_send', $offline_send, \@offline_send);
+ &stats("# Offline Messages (real = $offline):",'offline_rcv', $offline_rcv, \@offline_rcv);
+
+# &stats("# Presence info:",'roster', $roster, \@roster);
+ &stats("# Deconnexions (sent = $finsend) :",'deconnexion', $deconnexion, \@deconnexion);
+}
+
+sub stats {
+ my $title = shift;
+ my $type = shift;
+ my $count = shift;
+ my $data = shift;
+
+ print "# $title ". ($count) ."\n";
+ if ($count) {
+ @_ = sort {$a <=> $b} @{$data};
+ print affiche("min",$_[0]) . "\n";
+ print affiche("max",$_[$#_]) . "\n";
+ print affiche("mean",$esperance{$type}) . "\n";
+ print affiche("median",$_[$#_/2]) . "\n";
+ print affiche("stdvar",sqrt($var{$type}/$count)) . "\n";
+ print "#\n";
+ }
+}
+
+sub usage {
+ print "this script is part of IDX-TSUNAMI version $tagvsn,
+Copyright (C) 2001 IDEALX (http://IDEALX.org/)\n\n";
+ print "IDX-TSUNAMI comes with ABSOLUTELY NO WARRANTY; This is free software, and
+ou are welcome to redistribute it under certain conditions
+type `idx-tsunami.pl --version` for details.\n\n";
+
+ print "Usage: $0 [<options>]\n","Available options:\n\t",
+ "[--help] (this help text)\n\t",
+ "[--verbose] (print all messages)\n\t",
+ "[--debug] (print receive without send messages)\n\t",
+ "[file1 [file2 [...]]] (log files to analyse)\n\t";
+ exit;
+ }
+
+sub affiche() {
+ my $name = shift;
+ my $value = shift;
+ return sprintf "#%7s = %.3f",$name,$value;
+}
+
+sub version {
+print "this script is part of IDX-TSUNAMI version $tagvsn
+
+Written by Nicolas Niclausse and Jean François Lecomte
+
+Copyright (C) 2001 IDEALX (http://IDEALX.org/)
+
+This program 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 2
+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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program (see COPYING); if not, write to the
+Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.";
+exit;
+}
246 src/idx-tsunami.pl.src
View
@@ -0,0 +1,246 @@
+#! /usr/bin/perl -w
+#
+# This code was developped by IDEALX (http://IDEALX.org/) and
+# contributors (their names can be found in the CONTRIBUTORS file).
+# Copyright (C) 2000-2001 IDEALX
+#
+# This program 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 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+# Created by : Nicolas Niclausse <nniclausse@idealx.com>
+
+my $vsn = '$Id$ ';
+my $tagvsn = '%VSN%';
+
+use strict;
+use POSIX;
+use Getopt::Long;
+use vars qw /$help $start $config $stop $version/;
+
+my $erl = "/usr/bin/erl";
+my $ssh = "ssh -x";
+my $scp = "scp ";
+my %config;
+
+my $rootdir = "/usr/local/idx-tsunami";
+my $utilsdir = $rootdir . "/etc";
+my $rcfile = $utilsdir . "/idx-tsunamirc";
+
+my ($nbeams, $ndeb, $nfin);
+my $monitor ;
+my $nodename ;
+my $maxclients = 1000 ;
+my $range = 2000 ;
+my $nfirst = 0 ;
+my $totalclient = 0 ;
+my $currentclient = 0 ;
+my ($key,$nmachines,$interarrival) ; # tocheck
+my ($host,@hosts);
+my ($debug,$i,$appfile,$cookie);
+my @servers;
+my $server_id=0;
+
+GetOptions( "h|help",\$help,
+ "start",\$start,
+ "config",\$config,
+ "version",\$version,
+ "stop",\$stop
+ );
+
+&usage if ($help);
+&version if ($version);
+
+
+if ($config or $start) {
+ &read_rc;
+
+ print "Config: $totalclient clients will be launched from $nmachines machines ($nbeams beams per machine)\n";
+ my $session_duration = $config{'messages_number'}*$config{'messages_interarrival'}/60;
+ my $launching_duration = $interarrival*$totalclient/60;
+ print "Estimated minimum duration : ". POSIX::ceil($session_duration+$launching_duration) ." mn\n" ;
+ print "single session min duration : ". POSIX::ceil($session_duration) ." mn\n" ;
+ print "last client will be launched after : ". POSIX::ceil($launching_duration) ." mn\n" ;
+
+ my $j=0;
+ foreach $host (@hosts) {
+ foreach $i ($j..$j+$nbeams-1) {
+ $ndeb = $nfirst + $i*$range ;
+ $nfin = $nfirst + ($i+1)*$range - 1;
+ $currentclient += $config{'nclients'};
+ if ($currentclient > $totalclient) {
+ # remove exceeding client (caused by ceiling)
+ $config{'nclients'} -= ($currentclient - $totalclient);
+ }
+ # create .config file
+ $appfile = "$rootdir/etc/tsunami$i.config";
+ open (APP,">$appfile") or die("Impossible d'ouvrir le fichier $appfile");
+ select APP;
+ print "[{tsunami,
+ [\n";
+ foreach $key (sort keys %config) {
+ if ($key eq "server_adr") {
+ # if multiple servers are set, we choose one using a
+ # round robin algorithm
+ @servers = split(/:/,$config{$key});
+ print "{$key, \"". $servers[$server_id] . "\"},\n";
+ $server_id = ($server_id + 1) % ($#servers+1) ;
+ }
+ else {
+ # if contains ':' ,'.' or '-' , put quotes, otherwise,
+ # Erlang is not happy
+ if (($config{$key} =~ /[:|-|\.]/) and ($config{$key} !~ /^\d+\.\d+$/)){
+ print "{$key, \"". $config{$key} . "\"},\n";
+ }
+ else {
+ print "{$key, ". $config{$key} . "},\n";
+ }
+ }
+ }
+ print "{nclients_deb, ". $ndeb . "},\n";
+ print "{nclients_fin, ". $nfin . "},\n";
+ if ($config{'client_type'} =~ /dynamic/) {
+ print "{mes_type, dynamic}\n";
+ } else {
+ print "{mes_type, static}\n";
+ }
+ print " ]
+ }].\n";
+
+ close APP ;
+ select STDOUT;
+ if ($start and not $config) {
+ $nodename = "tsunami$i";
+ print "launching Beam $nodename on host $host\n";
+ unless ($config{'nfs'} or $host eq "localhost") {
+ print "copying config file to remote host ...\n";
+ system("$scp $appfile $host:$appfile");
+ }
+ if ($host eq "localhost") {
+ print "$erl -sname $nodename -setcookie \'$config{'cookie'}\' -detached -boot $rootdir/bin/tsunami -boot_var TSUNAMIPATH $rootdir/erlang -config $rootdir/etc/tsunami$i\.config\n" ;#and die "system failed: $?" ;
+ system("$erl -sname $nodename -setcookie \'$config{'cookie'}\' -detached -boot $rootdir/bin/tsunami -boot_var TSUNAMIPATH $rootdir/erlang -config $rootdir/etc/tsunami$i\.config" ) ;#and die "system failed: $?" ;
+ }
+ else {
+ system("$ssh $host \" $erl -sname $nodename -setcookie \'$config{'cookie'}\' -detached -boot $rootdir/bin/tsunami -boot_var TSUNAMIPATH $rootdir/erlang -config $rootdir/etc/tsunami$i\.config\"" ); # and die "system failed: $?" ;
+ }
+ }
+ }
+ $j += $nbeams;
+ }
+} elsif ($stop) {
+ &read_rc;
+ &stop;
+} else {
+ print "Nothing to do ... aborting (try --help)\n";
+}
+
+sub read_rc {
+ my $value;
+ my $name;
+
+ open (RC,"<$rcfile") or die("Impossible d'ouvrir le fichier $rcfile");
+ while (<RC>) {
+ next if /^\#/; #remove comments
+ if (/(\w+)\s*=\s*([^\n]+)\n/) {
+ $value = $2;
+ $value =~ s/\"//g;
+ $name = lc($1);
+ $config{$name} = $value;
+ }
+ }
+
+ $totalclient = $config{'nclients'};
+ $nmachines = ($config{'machines'} =~ tr/:/:/) +1; # TODO
+ $nbeams = POSIX::ceil($config{'nclients'}/($nmachines*$maxclients));
+ $config{'nclients'} = POSIX::ceil($config{'nclients'}/($nmachines*$nbeams));
+ $interarrival = $config{'interarrival'};
+ $config{'interarrival'} = $interarrival *($nbeams*$nmachines);
+
+
+ @hosts = split (/:/,$config{'machines'});
+}
+
+sub stop {
+ # apply function application:stop() by rpc
+ &rpc(1,"application","stop",("tsunami"));
+}
+
+sub rpc {
+ my $stop= shift;
+ my $module= shift;
+ my $function=shift;
+ my @args=@_;
+ my ($host,$i,$j,$sname,$nodename);
+
+ my @hostnames;
+
+ foreach (@hosts) {
+ if (/localhost/) { # erlang beam use the real name, not localhost
+ $_ = $ENV{HOSTNAME};
+ }
+ push @hostnames, $_;
+ }
+
+ open(ERL,"| $erl -sname rpcnode -setcookie $config{'cookie'} >/dev/null");
+ select ERL;
+ print "net_adm:world_list(\['". join("','", @hostnames) . "'\]).\n";
+ $j = 0;
+ foreach $host (@hostnames) {
+ foreach $i ($j..$j+$nbeams-1) {
+ $nodename = "tsunami$i";
+ $sname="$nodename\@$host";
+ print "rpc:cast(\'$sname\',$module,$function,\[". join(",
+", @args) ."\]).\n";
+ print "slave:stop(\'$sname\').\n" if $stop;
+ }
+ $j += $nbeams;
+ }
+ close ERL;
+}
+
+sub usage {
+ print "IDX-TSUNAMI version $tagvsn, Copyright (C) 2001 IDEALX (http://IDEALX.org/)\n\n";
+ print "IDX-TSUNAMI comes with ABSOLUTELY NO WARRANTY; This is free software, and
+ou are welcome to redistribute it under certain conditions
+type `idx-tsunami.pl --version` for details.\n";
+ print "\n";
+ print "options: [--start] start clients\n";
+ print " : [--stop] stop clients (not yet implemented)\n";
+ print " : [--config] only generate config files\n";
+ print " : [-h] help\n";
+ exit;
+}
+
+sub version {
+print "IDX-TSUNAMI version $tagvsn
+
+Written by Nicolas Niclausse and Jean François Lecomte
+
+Copyright (C) 2001 IDEALX (http://IDEALX.org/)
+
+This program 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 2
+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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program (see COPYING); if not, write to the
+Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.";
+exit;
+}
44 src/jabber_auth.erl
View
@@ -0,0 +1,44 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_auth).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+
+get_random_message (Args) ->
+ jabber_common:get_random_message(Args).
+
+
+%%generate a client session which only connects clients send one
+%%message and wait for all the other client to be connected before
+%%quitting
+
+get_client(N, Id) ->
+ [Message] = jabber_common:get_random_params(infinity, 1 ,?messages_size,'chat'),
+ [#message{ack = no_ack, thinktime=1000, param = #jabber {type = 'connect'}},
+ #message{ack = local, thinktime=infinity, param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=?presence_delay, param = #jabber {type = 'presence'}}] ++
+ [Message#message{ack = global}] ++
+ [#message{ack = local, thinktime = infinity, param = #jabber {type = 'close'}}].
226 src/jabber_common.erl
View
@@ -0,0 +1,226 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_common).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-export([connect/0, close/0,
+ get_random_params/4,
+ get_random_message/1
+ ]).
+
+-export([auth/0,
+ message/2,
+ message/3,
+ presence/0,
+ presence/2,
+ registration/0,
+ requete/3
+ ]).
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+%%Liste des différents feeling
+
+%get_random_message (#jabber{type = connect, size = Size, dest = Dest}) ->
+get_random_message (#jabber{type = 'connect'}) ->
+ connect();
+get_random_message (#jabber{type = 'close'}) ->
+ close();
+get_random_message (#jabber{type = 'register', id = Id}) when integer(Id), Id > 0 ->
+ registration(Id);
+get_random_message (#jabber{type = 'register'}) ->
+ registration();
+get_random_message (#jabber{type = 'presence'}) ->
+ presence();
+get_random_message (#jabber{type = 'presence:roster', dest=Dest}) ->
+ presence(roster, Dest);
+
+get_random_message (#jabber{type = 'authenticate', id = Id}) when integer(Id), Id > 0 ->
+ auth(Id);
+get_random_message (#jabber{type = 'authenticate'}) ->
+ auth();
+
+get_random_message (#jabber{type = 'chat', size = Size, id = Id, dest = undefined}) ->
+ message(Size, ?jabber_domain);
+get_random_message (#jabber{type = 'chat', size = Size, id =Id, dest = Dest}) ->
+ ?PRINTDEBUG("~w -> ~w ~n", [Id, Dest], ?DEB),
+ message(Dest, Size, ?jabber_domain);
+
+
+
+get_random_message (#jabber{type = 'iq:roster:set', dest = Dest}) ->
+ requete(roster, "set", Dest);
+get_random_message (#jabber{type = 'iq:roster:get', id = Id}) ->
+ requete(roster, "get", Id).
+
+
+%%%%%%%%%%%
+%% Connect messages
+connect() ->
+ list_to_binary(
+ "<stream:stream id='" ++
+ integer_to_list(ts_msg_server:get_id()) ++
+ "' to='" ++
+ ?jabber_domain ++
+ "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>").
+
+%% Close session
+close () -> list_to_binary("</stream:stream>").
+
+%% generic Authentication message (auth or register)
+auth(Username, Passwd, Type) ->
+ list_to_binary(
+ "<iq id='" ++integer_to_list(ts_msg_server:get_id()) ++
+ "' type='set' >" ++
+ "<query xmlns='jabber:iq:" ++ Type ++ "'>" ++
+ "<username>" ++ Username ++ "</username>" ++
+ "<resource>tsunami</resource>" ++
+ "<password>"++ Passwd ++ "</password></query></iq>").
+
+%% auth message
+auth(Username, Passwd) ->
+ auth(Username, Passwd, "auth").
+
+%% auth message from a random client
+auth() ->
+ Id = integer_to_list(ts_user_server:get_id()),
+ Name = ?jabber_username ++ Id,
+ Passwd = ?jabber_password ++ Id,
+ auth(Name, Passwd).
+
+
+%% auth message from a given client
+auth(Id) ->
+ Name = ?jabber_username ++ integer_to_list(Id) ,
+ Passwd = ?jabber_password ++ integer_to_list(Id),
+ auth(Name, Passwd).
+
+
+%% register message
+registration(Username, Passwd) ->
+ auth(Username, Passwd, "register").
+
+
+%% register message from an random client
+registration() ->
+ Id = integer_to_list(random:uniform(?jabber_users)),
+ Name = ?jabber_username ++ Id,
+ Passwd = ?jabber_password ++ Id,
+ registration(Name, Passwd).
+
+%% register message from an given client number
+registration(Id) when integer(Id)->
+ Name = ?jabber_username ++ integer_to_list(Id),
+ Passwd = ?jabber_password ++ integer_to_list(Id),
+ registration(Name, Passwd).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% <message>
+%%
+%
+
+%% send message to another random user
+message(Size, Service) ->
+ message(ts_user_server:get_id(),Size, Service).
+
+
+%% send message to defined user at the Service (aim, ...)
+message(Dest, Size, Service) when integer(Size), Size >= 10 ->
+ list_to_binary(
+ "<message id='" ++integer_to_list(ts_msg_server:get_id()) ++
+ "' to='" ++
+ ?jabber_username ++ integer_to_list(Dest) ++ "@" ++ Service ++
+ "'><body>" ++ lists:duplicate(Size div 10, "acnkdiejnf") ++
+ "</body></message>");
+
+message(Dest, Size, Service) when integer(Size), Size >= 0 ->
+ list_to_binary(
+ "<message id='" ++integer_to_list(ts_msg_server:get_id()) ++
+ "' to='" ++
+ ?jabber_username ++ integer_to_list(Dest) ++ "@" ++ Service ++
+ "'><body>" ++ lists:duplicate(Size, "a") ++
+ "</body></message>").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% <presence>
+%%
+%
+
+%% presence
+presence () ->
+ list_to_binary(
+ "<presence id='" ++integer_to_list(ts_msg_server:get_id()) ++ "' />").
+
+
+presence(roster, Dest)->
+ Name = ?jabber_username ++ integer_to_list(Dest),
+ list_to_binary(
+ "<presence id='" ++integer_to_list(ts_msg_server:get_id()) ++
+ "' to='" ++
+ Name ++ "@" ++ ?jabber_domain ++
+ "' type='subscribed'/>").
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% <iq>
+
+requete(roster, Type, Id)->
+ case Type of
+ "set"->
+ Name = ?jabber_username ++ integer_to_list(Id),
+ list_to_binary(
+ "<iq id='" ++integer_to_list(ts_msg_server:get_id()) ++
+ "' type='set'>" ++ "<query xmlns='jabber:iq:roster'><item jid='" ++
+ Name ++ "@" ++ ?jabber_domain ++
+ "' name='gg1000'/></query></iq>");
+ "get"->
+ list_to_binary(
+ "<iq id='" ++integer_to_list(ts_msg_server:get_id()) ++
+ "' type='get'><query xmlns='jabber:iq:roster'></query></iq>")
+ end.
+
+%% In : Intensity : inverse of the mean of inter arrival of messages
+%% N : number of messages
+%% Out:
+get_random_params(Intensity, 1, Size, Type, L) ->
+ L ++ [#message{ ack = no_ack,
+ thinktime = ?messages_last_time,
+ param = #jabber {size=Size, type=Type}}];
+
+get_random_params(Intensity, N, Size, Type, L) ->
+ get_random_params(Intensity, N-1, Size, Type,
+ [#message{ ack = no_ack,
+ thinktime = round(ts_stats:exponential(Intensity)),
+ param = #jabber {size=Size, type=Type}}
+ | L]).
+
+get_random_params(Intensity, N, Size, Type) when integer(N), N >= 0 ->
+ get_random_params(Intensity, N, Size, Type, []).
+
+affiche_id([])->
+ ok;
+affiche_id([H|T])->
+ Id = (H#message.param)#jabber.id,
+ io:format("~w~n", [Id]),
+ affiche_id(T).
+
47 src/jabber_dynamic.erl
View
@@ -0,0 +1,47 @@
+%%%
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_dynamic).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+
+get_random_message(Args) ->
+ jabber_common:get_random_message(Args).
+
+get_client(N, Id)->
+ List_Fin =
+ [#message{ack = no_ack, thinktime=3000, param = #jabber{type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=infinity,
+ param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=2000+random:uniform(?presence_delay),
+ param = #jabber {type = 'presence'}},
+ #message{type= dynamic, ack = no_ack, thinktime=
+ round(ts_stats:exponential(?messages_intensity)),
+ param = #jabber {type = 'chat', size= ?messages_size, id =Id}},
+ #message{ack=local, thinktime=infinity, param=#jabber{type = 'close'}}
+ ],
+ ?PRINTDEBUG("~w~n", [List_Fin], ?DEB),
+ List_Fin.
68 src/jabber_offline.erl
View
@@ -0,0 +1,68 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_offline).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+
+get_random_message(Args) ->
+ jabber_common:get_random_message(Args).
+
+%% generate a client session for jabber which only send messages to offline users
+%% currently, parameters are included from profile.hrl
+get_client(N, Id) ->
+ List_Fin = [#message{ack = no_ack, thinktime=3000, param = #jabber {type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=infinity, param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=random:uniform(?presence_delay), param = #jabber {type = 'presence'}}] ++
+ profile_jabber:get_offline_params(?messages_intensity,
+ N,
+ ?messages_size,'chat', Id) ++
+ [ #message{ack = no_ack, thinktime = 100, param = #jabber {type = 'close'}}],
+ List_Fin.
+
+%%%
+get_offline_params(Intensity, 1, Size, Type, Id, L) ->
+ Dest = ts_user_server:get_offline() ,
+ L ++ [#message{ ack = no_ack,
+ thinktime = ?messages_last_time,
+ param = #jabber {size=Size,
+ type=Type,
+ id =Id,
+ dest = Dest}}];
+
+get_offline_params(Intensity, N, Size, Type, Id, L) ->
+ Dest = ts_user_server:get_offline(),
+ get_offline_params(Intensity, N-1, Size, Type, Id,
+ [#message{ ack = no_ack,
+ thinktime = round(ts_stats:exponential(Intensity)),
+ param = #jabber {size=Size,
+ type=Type,
+ id = Id,
+ dest = Dest}
+ }
+ | L]).
+get_offline_params(Intensity, N, Size, Type, Id) when integer(N), N >= 0 ->
+ get_offline_params(Intensity, N, Size, Type, Id ,[]).
+
64 src/jabber_online.erl
View
@@ -0,0 +1,64 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_online).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+
+get_random_message(Args) ->
+ jabber_common:get_random_message(Args).
+
+%% generate a client session for jabber which only send messages to online users
+%% currently, parameters are included from profile.hrl
+get_client(N, Id)->
+ List_Fin = [#message{ack = no_ack, thinktime=3000, param = #jabber {type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=infinity, param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=2000+random:uniform(?presence_delay), param = #jabber {type = 'presence'}} ] ++
+ get_online_params(?messages_intensity,N,
+ ?messages_size,'chat', Id) ++
+ [ #message{ack = local, thinktime = infinity, param = #jabber {type = 'close'}}],
+ ?PRINTDEBUG("~w~n", [List_Fin], ?DEB),
+ List_Fin.
+
+%%%
+get_online_params(Intensity, 1, Size, Type, Id, L) ->
+ L ++ [#message{ ack = no_ack,
+ thinktime = ?messages_last_time,
+ param = #jabber {size=Size,
+ type=Type,
+ id =Id,
+ dest = ts_user_server:get_one_connected(Id)}}];
+
+get_online_params(Intensity, N, Size, Type, Id, L) ->
+ get_online_params(Intensity, N-1, Size, Type, Id,
+ [#message{ ack = no_ack,
+ thinktime = round(ts_stats:exponential(Intensity)),
+ param = #jabber {size=Size,
+ type=Type,
+ id = Id,
+ dest = ts_user_server:get_one_connected(Id)}}
+ | L]).
+get_online_params(Intensity, N, Size, Type, Id) when integer(N), N >= 0 ->
+ get_online_params(Intensity, N, Size, Type, Id ,[]).
36 src/jabber_register.erl
View
@@ -0,0 +1,36 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_register).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+
+get_random_message (Args) ->
+ jabber_common:get_random_message(Args).
+
+get_client(N, Id) ->
+ [#message{ack = no_ack, thinktime=1000, param = #jabber {type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=1000, param = #jabber {type = 'register', id = Id}},
+ #message{ack = local, thinktime= infinity, param = #jabber {type = 'close'}}].
90 src/jabber_roster.erl
View
@@ -0,0 +1,90 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_roster).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+get_random_message(Args) ->
+ jabber_common:get_random_message(Args).
+
+get_client(N, Id)->
+ [#message{ack = no_ack, thinktime=3000, param = #jabber {type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=infinity, param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=random:uniform(?presence_delay), param = #jabber {type = 'presence'}}] ++
+ set_roster_params(?n_roster_clients, both, Id) ++
+ get_roster_params(N, Id) ++
+ [ #message{ack = local, thinktime = infinity, param = #jabber {type = 'close'}}].
+
+
+get_roster_params(1, Id, L) ->
+ L ++ [#message{ack = no_ack,
+ thinktime = ?messages_last_time,
+ param = #jabber {
+ id = Id,
+ type = 'iq:roster:get'}}];
+get_roster_params(N, Id, L) ->
+ get_roster_params(N-1, Id, [#message{ack = no_ack,
+ thinktime = round(ts_stats:exponential(?messages_intensity)),
+ param = #jabber {
+ id = Id,
+ type = 'iq:roster:get'}}| L]).
+
+%%To build a list in order to establish roster of this client.
+get_roster_params(N, Id) when integer(N), N>=0 ->
+ get_roster_params(N, Id, []).
+
+%%
+set_roster_params(0, Status, Id, L) ->
+ L;
+set_roster_params(N, Status, Id, L) ->
+ case Status of
+ online ->
+ Roster1 = ts_user_server:get_one_connected(Id),
+ Roster2 = ts_user_server:get_one_connected(Id);
+ offline ->
+ Roster1 = ts_user_server:get_offline(),
+ Roster2 = ts_user_server:get_offline();
+ both ->
+ Roster1 = ts_user_server:get_one_connected(Id),
+ Roster2 = ts_user_server:get_offline()
+ end,
+
+ List = [#message{ack = no_ack,
+ thinktime = round(ts_stats:exponential(?setroster_intensity)),
+ param = #jabber { dest = Roster1, type = 'iq:roster:set'}},
+ #message{ack = no_ack,
+ thinktime = round(ts_stats:exponential(?setroster_intensity)),
+ param = #jabber { dest = Roster1, type = 'presence:roster'}},
+ #message{ack = no_ack,
+ thinktime = round(ts_stats:exponential(?setroster_intensity)),
+ param = #jabber { dest = Roster2, type = 'iq:roster:set'}},
+ #message{ack = no_ack,
+ thinktime = round(ts_stats:exponential(?setroster_intensity)),
+ param = #jabber { dest = Roster2, type = 'presence:roster'}}],
+ set_roster_params(N-2, Status, Id, List ++ L).
+
+%%To build a list of messages to retrieve roster of Id client
+set_roster_params(N, Status, Id) when integer(N), N>=0 ->
+ set_roster_params(N, Status, Id, []).
90 src/jabber_unique.erl
View
@@ -0,0 +1,90 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and
+%%% contributors (their names can be found in the CONTRIBUTORS file).
+%%% Copyright (C) 2000-2001 IDEALX
+%%%
+%%% This program 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 2 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 General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+%%%
+
+-module(jabber_unique).
+-vc('$Id$ ').
+-author('nicolas.niclausse@IDEALX.com').
+
+-include("../include/ts_profile.hrl").
+-include("../include/ts_jabber.hrl").
+
+-export([get_client/2, get_random_message/1]).
+
+
+get_random_message(Args) ->
+ jabber_common:get_random_message(Args).
+
+
+%% generate a client session for one first client jabber who never disconnects
+%% currently, parameters are included from profile.hrl
+jabber_first()->
+ {Id, _} = ts_user_server:get_first(),
+ io:format("First client ~w~n", [Id]),
+ List_Fin = [#message{ack = no_ack, thinktime=3000, param = #jabber {type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=infinity, param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=infinity, param = #jabber {type = 'presence'}}],
+ List_Fin.
+
+
+%Send only messages to one client (6.3)
+get_client(N, Id)->
+ case ts_user_server:get_first() of
+ {Fid, not_connected} ->
+ ts_user_server:connect_first(),
+ jabber_first();
+ {Fid, connected} ->
+ get_client2(N, Id)
+ end.
+
+%%Create a client session where all messages will be sent to an unique client connected with first_jabber_client
+get_client2(N, Id)->
+ List_Fin = [#message{ack = no_ack, thinktime=3000, param = #jabber {type = 'connect'}},
+ #message{ack = ?messages_ack, thinktime=infinity, param = #jabber {type = 'authenticate', id = Id}},
+ #message{ack = no_ack, thinktime=random:uniform(2000), param = #jabber {type = 'presence'}}] ++
+ get_unique_params(?messages_intensity,
+ N,
+ ?messages_size,'chat', Id) ++
+ [ #message{ack = local, thinktime = infinity, param = #jabber {type = 'close'}}],
+ List_Fin.
+
+%%%
+get_unique_params(Intensity, 1, Size, Type, Id, L) ->
+ {Fid, _} = ts_user_server:get_first(),
+ L ++ [#message{ ack = no_ack,
+ thinktime = ?messages_last_time,
+ param = #jabber {size=Size,
+ type=Type,
+ id =Id,
+ dest = Fid}}];
+
+
+get_unique_params(Intensity, N, Size, Type, Id, L) ->
+ {Fid, _} = ts_user_server:get_first(),
+ get_unique_params(Intensity, N-1, Size, Type, Id,
+ [#message{ ack = no_ack,
+ thinktime = round(ts_stats:exponential(Intensity)),
+ param = #jabber {size=Size,
+ type=Type,
+ id = Id,
+ dest = Fid}
+ }
+ | L]).
+get_unique_params(Intensity, N, Size, Type, Id) when integer(N), N >= 0 ->
+ get_unique_params(Intensity, N, Size, Type, Id ,[]).
+
41 src/make_boot.erl
View
@@ -0,0 +1,41 @@
+%%% This code was developped by IDEALX (http://IDEALX.org/) and