root/lang/perl/XMPP-Bomber/trunk/lib/XMPP/Bomber.pm @ 13216

Revision 13216, 5.4 kB (checked in by daisuke, 6 years ago)

fix config handling

  • Property svn:keywords set to Id
Line 
1# $Id$
2
3package XMPP::Bomber;
4use Moose;
5use XMPP::Bomber::Types;
6
7has 'clients' => (
8    is => 'rw',
9    isa => 'ClientList',
10    auto_deref => 1,
11    coerce => 1,
12    required => 1,
13);
14
15has 'condvar' => (
16    is => 'rw',
17    default => sub { AnyEvent->condvar(cb => \&child_exited) }
18);
19
20no Moose;
21
22use AnyEvent;
23# use AnyEvent::Impl::Perl;
24use Net::XMPP2;
25use Net::XMPP2::Client;
26use XMPP::Bomber::Account;
27use XMPP::Bomber::Sender;
28use XMPP::Bomber::Receiver;
29
30our $VERSION = '0.00001';
31
32sub run
33{
34    my ($self) = @_;
35
36    $self->run_clients;
37
38    wait();
39}
40
41sub run_clients
42{
43    my $self = shift;
44
45    foreach my $client ($self->clients) {
46        my $pid = fork();
47        if (! defined $pid) {
48            die "Failed to fork!";
49        }
50
51        if (! $pid ) {
52            eval {
53                $client->run;
54            };
55            exit $@ ? 1 : 0;
56        }
57    }
58}
59
60sub start_receivers
61{
62    my $self = shift;
63
64    my $provider = $self->receiver_provider;
65    while (my $account = $provider->create) {
66        my $receiver = XMPP::Bomber::Receiver->new(
67            hostname => $self->hostname,
68            port     => $self->port,
69            domain   => $self->domain,
70            account  => $account
71        );
72
73        $receiver->start;
74
75        AnyEvent->child(
76            pid => $receiver->pid,
77            cb  => sub { $self->condvar->send($self) }
78        );
79        push @{$self->receivers}, $receiver;
80    }
81}
82
83sub stop_receivers
84{
85    my $self = shift;
86    my $receiver_count = $self->receiver_count;
87    foreach my $receiver ( @{ $self->receivers } ) {
88        $receiver->stop;
89    }
90       
91}
92
93sub child_exited { die "exited @_" }
94
95sub start_senders
96{
97    my $self = shift;
98
99    my $provider = $self->sender_provider;
100    while (my $account = $provider->create) {
101        my $sender = XMPP::Bomber::Sender->new(
102            hostname => $self->hostname,
103            port     => $self->port,
104            domain   => $self->domain,
105            content_provider => $self->content_provider,
106            receivers        => $self->receivers,
107            account => $account,
108        );
109        $sender->start;
110
111        AnyEvent->child(
112            pid => $sender->pid,
113            cb  => sub { $self->condvar->send($self) }
114        );
115        push @{$self->senders}, $sender;
116       
117    }
118}
119
120sub stop_senders
121{
122    my $self = shift;
123    my $sender_count = 1;
124    foreach my $sender ( @{ $self->senders } ) {
125        $sender->stop;
126    }
127}
128
129sub make_par
130{
131    my (%args) = @_;
132
133    my $find_cmd = sub {
134        my ($name, $default) = @_;
135
136        my $cmd = $default;
137        if (! $cmd) {
138            foreach my $path (split(/:/, $ENV{PATH})) {
139                my $fqpath = File::Spec->catfile($path, $name);
140                if (-x $fqpath) {
141                    $cmd = $fqpath;
142                    last;
143                }
144            }
145        }
146
147        if (! $cmd || ! -x $cmd) {
148            die "Could not find a suitable '$name' executable";
149        }
150        return $cmd;
151    };
152
153    my $pp = $find_cmd->('pp', $ENV{PAR_PACKER});
154    my $xmpp_bomber = $find_cmd->('xmpp-bomber', $ENV{XMPP_BOMBER});
155
156    # Now pack all this stuff
157    my @modules = (
158        'DateTime::Locale::en', # need to add this manually
159        'XMPP::Bomber',
160        'XMPP::Bomber::Sender',
161        'XMPP::Bomber::Receiver',
162        'XMPP::Bomber::Account',
163        'XMPP::Bomber::Role::ContentProvider',
164        'XMPP::Bomber::Role::UserProvider',
165        'XMPP::Bomber::UserProvider::Static',
166        'XMPP::Bomber::UserProvider::OpenFire::Random',
167        'XMPP::Bomber::ContentProvider::Gibberish',
168        @{ $args{extra_modules} || [] }
169    );
170
171    my $outfile = $args{outfile} || 'xmpp-bomber.par';
172    my @cmd = (
173        $pp,
174        '-I' => 'lib',
175        "-o" => $outfile,
176        (map { ("-M" => $_) } @modules ),
177        $xmpp_bomber
178    );
179    system(@cmd);
180    if ($? != 0 || ! -e $outfile) {
181        die "Failed to execute @cmd";
182    }
183}
184
1851;
186
187__END__
188
189=head1 NAME
190
191XMPP::Bomber - Stretch The Limit Of Your XMPP Servers
192
193=head1 SYNOPSIS
194
195  use XMPP::Bomber;
196
197  my $hostname = ...;
198  my $password = ...;
199
200  # First, create the "senders" you want to use
201  # In this case we only want one sender, and the sender is a static one
202  my $senders = XMPP::Bomber::Default::StaticUserProvider->new(
203    users => [
204      XMPP::Bomber::Account->new(
205        username => $opts{username},
206        password => $opts{password},
207        domain   => $opts{domain},
208      )
209    ]
210  );
211
212  # Now, define the "receivers".
213  # We will be generating 100 users with random usernames directly into the
214  # OpenFire database
215  my $receivers = XMPP::Bomber::OpenFire::RandomUserProvider->new(
216    domain       => $opts{domain},
217    count        => 100,
218    connect_info => [
219      $opts{dsn},
220      $opts{dbuser},
221      $opts{dbpass},
222      { RaiseError => 1, AutoCommit => 1 }
223    ],
224  );
225
226  # Define the content provider
227  my $content = XMPP::Bomber::Default::GibberishContentProvider->new(
228    max_length => 512,
229  );
230
231  my $bomber = XMPP::Bomber->new(
232    hostname          => '192.168.0.5',
233    domain            => 'endeworks.jp',
234    sender_provider   => $senders,
235    receiver_provider => $receivers,
236    content_provider  => $content
237  );
238
239  $bomber->run;
240
241=head1 DESCRIPTION
242
243This module exists solely to test the amount of messages that your XMPP
244server can handle. It creates one or more "senders", and one or more
245"receivers". There's also a
246
247You can specify how these se
248
249=head1
250
251
252=cut
Note: See TracBrowser for help on using the browser.