-
Notifications
You must be signed in to change notification settings - Fork 3
/
benchmark.pl
executable file
·192 lines (151 loc) · 4.84 KB
/
benchmark.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/usr/bin/env perl
use common::sense; #new features in perl(not for 5.8.8 and older (; )
use AnyEvent::HTTP; # main module
use Getopt::Long; # to command line parsing
use POSIX;
use Data::Dumper; # to see the date in debug
my $DEBUG = 0; #Debug mode. Default is false (0)
my $verbose = 0; #to view the each connection result
my $timeout = 60;
my $count = 30000; #number of requests
my $concurency = 20; # number of parralle requests
my $done = 0;
my $url;
my $method = 'GET'; #http method
my $proxy; # proxy server
my $file; #scenario file
my $max_recurse = 10; # the default recurse number;
my $useragent = 'Mozilla/5.0 (compatible; U; AnyEvent::HTTPBenchmark/0.05; +http://github.com/shafiev/AnyEvent-HTTPBenchmark)';
#arrays
my @reqs_time; # the times of requests
parse_command_line(); #parsing the command line arguments
$AnyEvent::VERBOSE = 10 if $DEBUG;
$AnyEvent::HTTP::MAX_PER_HOST = $concurency;
$AnyEvent::HTTP::set_proxy = $proxy;
$AnyEvent::HTTP::USERAGENT = $useragent;
# Caching results of AnyEvent::DNS::a
my $orig_anyeventdnsa = \&AnyEvent::DNS::a;
my %cache;
*AnyEvent::DNS::a = sub($$) {
my ($domain, $cb) = @_;
if ($cache{$domain}) {
$cb->( @{ $cache{$domain} } );
return;
}
warn "asd";
$orig_anyeventdnsa->( $domain,
sub {
$cache{$domain} = [ @_ ];
$cb->( @_ );
}
);
return;
};
# End of caching
#on ctrl-c break run the end_bench sub.
$SIG{'INT'} = 'end_bench';
my $cv = AnyEvent->condvar;
#start measuring time
my $start_time = AnyEvent->time;
print 'Started at ' . format_time($start_time) . "\n";
#starting requests
for ( 1 .. $concurency ) {
add_request( $_, $url );
}
$cv->recv; # begin receiving message and make callbacks magic ;)
end_bench(); # call the end
#subs
sub parse_command_line {
if (not defined @ARGV)
{
print <<HEREDOC;
AnyEvent::HTTPBenchmark http://github.com/shafiev/AnyEvent-HTTPBenchmark
-url url to test,
-number number of requests,
-c number of parrallel clients
-verbose verbose mode
-debug debug mode
-proxy proxy
-useragent useragent string
Example :
./benchmark.pl -url=http://myfavouritesite.com -n=number_of_requests -c=number_of_parrallel clients
Another example :
./benchmark.pl --url=http://example.com -n=100 -c=10 -v
HEREDOC
exit;
}
#get options which ovveride the default values
my $result = GetOptions(
"url=s" => \$url,
"n=i" => \$count,
"c=i" => \$concurency,
"verbose|v+" => \$verbose,
"debug" => \$DEBUG,
"proxy=s" => \$proxy,
"useragent=s" => \$useragent
);
if ($concurency > $count) {
$concurency = $count;
}
unless ($url) {
if (@ARGV) {
$url = shift @ARGV;
}
else {
#set the default site elementa.su
$url = 'http://elementa.su/';
}
}
}
sub add_request {
my ( $id, $url ) = @_;
my $req_time = AnyEvent->time;
http_request $method => $url,
timeout => $timeout,
sub {
my $completed = AnyEvent->time;
my $req_time = format_seconds( $completed - $req_time );
print "Got answer in $req_time seconds\n" if $verbose;
push @reqs_time, $req_time;
$done++;
if ($verbose >= 2) {
print "=========== HTTP RESPONCE ===========\n";
print @_[0];
}
my $hdr = @_[1];
if ( $hdr->{Status} =~ /^2/ ) {
print "done $done\n" if $verbose;
}
else {
print STDERR "Oops we get problem in request . $done . ($hdr->{Status}) . ($hdr->{Reason}) \n";
}
return add_request( $done, $url ) if $done < $count;
$cv->send;
}
}
sub end_bench {
my $end_time = AnyEvent->time;
my $overall_time = format_seconds( $end_time - $start_time );
print "It takes the $overall_time seconds\n";
my $sum;
print 'Requests per second: ' . sprintf( "%.2f", $count / $overall_time ) . "\n";
#sort by time
@reqs_time = sort (@reqs_time);
for my $i ( 0 .. scalar(@reqs_time) ) {
#calculate average time
$sum += $reqs_time[$i];
}
print "\nShortest is : $reqs_time[0] sec. \n";
print "Average time is : " . format_seconds( $sum / $count ) . " sec. \n";
print "Longest is : $reqs_time[scalar(@reqs_time)-1] sec. \n";
exit;
}
sub format_time {
my ( $microsec, $seconds ) = modf(shift);
my ( $sec, $min, $hour ) = localtime($seconds);
return sprintf "%02d:%02d:%02d.%04d", $hour, $min, $sec, int( $microsec * 10000 );
}
sub format_seconds {
return sprintf "%.4f", shift;
}
1;