Bug 28617: Remove kohalib.pl and rely on PERL5LIB
[koha.git] / misc / load_testing / benchmark_circulation.pl
1 #!/usr/bin/perl
2 # This script implements a basic benchmarking and regression testing
3 # utility for Koha
4
5 use strict;
6 use warnings;
7
8 use HTTPD::Bench::ApacheBench;
9 use LWP::UserAgent;
10 use HTTP::Cookies;
11 use C4::Context;
12
13 my $baseurl= C4::Context->preference("staffClientBaseURL")."/cgi-bin/koha/";
14 my $max_tries = 200;
15 my $concurrency = 10;
16 my $debug;
17 my $user = 'kados';
18 my $password = 'kados';
19
20 # Authenticate via our handy dandy RESTful services
21 # and grab a cookie
22 my $ua = LWP::UserAgent->new();
23 my $cookie_jar = HTTP::Cookies->new();
24 my $cookie;
25 $ua->cookie_jar($cookie_jar);
26 my $resp = $ua->post( "$baseurl"."/svc/authentication" , {userid =>$user, password => $password} );
27 if( $resp->is_success ) {
28     $cookie_jar->extract_cookies( $resp );
29     $cookie = $cookie_jar->as_string;
30     print "Authentication successful\n";
31     print "Auth:\n $resp->content" if $debug;
32 }
33 # remove some unnecessary garbage from the cookie
34 $cookie =~ s/ path_spec; discard; version=0//;
35 $cookie =~ s/Set-Cookie3: //;
36
37 # Get some data to work with
38 my $dbh=C4::Context->dbh();
39 my $sth = $dbh->prepare("select max(borrowernumber) from borrowers");
40 $sth->execute;
41 my ($borrowernumber_max) = $sth->fetchrow;
42
43 $sth = $dbh->prepare("select max(biblionumber) from biblio");
44 $sth->execute;
45 my ($biblionumber_max) = $sth->fetchrow;
46
47 $sth = $dbh->prepare("select max(itemnumber) from items");
48 $sth->execute;
49 my ($itemnumber_max) = $sth->fetchrow;
50
51 $|=1;
52 #
53 # the global benchmark we do at the end...
54 #
55 my $b = HTTPD::Bench::ApacheBench->new;
56 $b->concurrency( $concurrency );
57 #
58 # mainpage : (very) low RDBMS dependency
59 #
60 my $b0 = HTTPD::Bench::ApacheBench->new;
61 $b0->concurrency( $concurrency );
62
63 my @mainpage;
64 print "--------------\n";
65 print "Koha circulation benchmarking utility\n";
66 print "--------------\n";
67 print "Benchmarking with $max_tries occurrences of each operation and $concurrency concurrent sessions \n";
68 print "Load testing staff interface dashboard page";
69 for (my $i=1;$i<=$max_tries;$i++) {
70     push @mainpage,"$baseurl/mainpage.pl";
71 }
72 my $run0 = HTTPD::Bench::ApacheBench::Run->new
73     ({ urls => \@mainpage,
74        cookies => [$cookie],
75     });
76 $b0->add_run($run0);
77 $b->add_run($run0);
78
79 # send HTTP request sequences to server and time responses
80 my $ro = $b0->execute;
81 # calculate hits/sec
82 print ("\t".$b0->total_time."ms\t".(1000*$b0->total_requests/$b0->total_time)." pages/sec\n");
83 print "ALERT : ".$b0->total_responses_failed." failures\n" if $b0->total_responses_failed;
84
85 #
86 # biblios
87 #
88 my $b1 = HTTPD::Bench::ApacheBench->new;
89 $b1->concurrency( $concurrency );
90
91 my @biblios;
92 print "Load testing catalog detail page";
93 for (my $i=1;$i<=$max_tries;$i++) {
94     my $rand_biblionumber = int(rand($biblionumber_max)+1);
95     push @biblios,"$baseurl/catalogue/detail.pl?biblionumber=$rand_biblionumber";
96 }
97 my $run1 = HTTPD::Bench::ApacheBench::Run->new
98     ({ urls => \@biblios,
99     });
100 $b1->add_run($run1);
101 $b->add_run($run1);
102
103 # send HTTP request sequences to server and time responses
104 $ro = $b1->execute;
105 # calculate hits/sec
106 print ("\t".$b1->total_time."ms\t".(1000*$b1->total_requests/$b1->total_time)." biblios/sec\n");
107 print "ALERT : ".$b1->total_responses_failed." failures\n" if $b1->total_responses_failed;
108
109 #
110 # borrowers
111 #
112 my $b2 = HTTPD::Bench::ApacheBench->new;
113 $b2->concurrency( $concurrency );
114
115 my @borrowers;
116 print "Load testing patron detail page";
117 for (my $i=1;$i<=$max_tries;$i++) {
118     my $rand_borrowernumber = int(rand($borrowernumber_max)+1);
119 #     print "$baseurl/members/moremember.pl?borrowernumber=$rand_borrowernumber\n";
120     push @borrowers,"$baseurl/members/moremember.pl?borrowernumber=$rand_borrowernumber";
121 }
122 my $run2 = HTTPD::Bench::ApacheBench::Run->new
123     ({ urls => \@borrowers,
124        cookies => [$cookie],
125     });
126 $b2->add_run($run2);
127 $b->add_run($run2);
128
129 # send HTTP request sequences to server and time responses
130 $ro = $b2->execute;
131 # calculate hits/sec
132 print ("\t".$b2->total_time."ms\t".(1000*$b2->total_requests/$b2->total_time)." borrowers/sec\n");
133
134
135 #
136 # issue (& then return) books
137 #
138 my $b3 = HTTPD::Bench::ApacheBench->new;
139 $b3->concurrency( $concurrency );
140 my $b4 = HTTPD::Bench::ApacheBench->new;
141 $b4->concurrency( $concurrency );
142
143 my @issues;
144 my @returns;
145 print "Load testing circulation transaction (checkouts)";
146 $sth = $dbh->prepare("SELECT barcode FROM items WHERE itemnumber=?");
147 my $sth2 = $dbh->prepare("SELECT borrowernumber FROM borrowers WHERE borrowernumber=?");
148 for (my $i=1;$i<=$max_tries;$i++) {
149     my $rand_borrowernumber;
150     # check that the borrowernumber exist
151     until ($rand_borrowernumber) {
152         $rand_borrowernumber = int(rand($borrowernumber_max)+1);
153         $sth2->execute($rand_borrowernumber);
154         ($rand_borrowernumber) = $sth2->fetchrow;
155     }
156     # find a barcode & check it exists
157     my $rand_barcode;
158     until ($rand_barcode) {
159         my $rand_itemnumber = int(rand($itemnumber_max)+1);
160         $sth->execute($rand_itemnumber);
161         ($rand_barcode) = $sth->fetchrow();
162     }
163     print "borrowernumber=$rand_borrowernumber&barcode=$rand_barcode\n";
164     push @issues,"$baseurl/circ/circulation.pl?borrowernumber=$rand_borrowernumber&barcode=$rand_barcode&issueconfirmed=1";
165     push @returns,"$baseurl/circ/returns.pl?barcode=$rand_barcode";
166 }
167 my $run3 = HTTPD::Bench::ApacheBench::Run->new
168     ({ urls => \@issues,
169        cookies => [$cookie],
170     });
171 $b3->add_run($run3);
172 $b->add_run($run3);
173
174 # send HTTP request sequences to server and time responses
175 $ro = $b3->execute;
176 # calculate hits/sec
177 print ("\t".$b3->total_time."ms\t".(1000*$b3->total_requests/$b3->total_time)." checkouts/sec\n");
178
179 print "Load testing circulation transaction (checkins)";
180 my $run4 = HTTPD::Bench::ApacheBench::Run->new
181     ({ urls => \@returns,
182        cookies => [$cookie],
183     });
184 $b4->add_run($run4);
185 $b->add_run($run4);
186
187 # send HTTP request sequences to server and time responses
188 $ro = $b4->execute;
189 # calculate hits/sec
190 print ("\t".$b4->total_time."ms\t".(1000*$b4->total_requests/$b4->total_time)." checkins/sec\n");
191
192 print "Load testing all transactions at once";
193 $ro = $b->execute;
194 print ("\t".$b->total_time."ms\t".(1000*$b->total_requests/$b->total_time)." operations/sec\n");