No Load Runner? No problems!

15 January, 2007 – 1:14 pm

Often you will find yourself just out of reach of some load test tools like LoadRunner, but don’t let that stop you generating load for your web apps. With enough patience and some careful use of live http headers you can achieve the same effect, albeit in a manually defined way. My BOLoader.pl script was written in perl to simulate logging on to a Business Objects server and pulling down canned reports. Simple enough when you use perl (WWW::Mechanize).


#!/usr/bin/perl -w
# #########################################################################
# BO Reports Loader
# Usage: BOLoader.pl [options]
# Options:
#  -u  user ID
#  -P  user password
#  -s   server IP or DNS
#  -r  report name
#  -n  number of reports to fetch
#  -p  pacing
#  -c   number of connections to thread
#  -s  sla for report generation in seconds
#
# Last edited: 9 Jan 07 10.09
# Author: Tim Koopmans
# #########################################################################
use threads;
use Getopt::Long;
use POSIX qw(strftime);
use WWW::Mechanize;
 
my %opts=();
GetOptions(
  "user:s"  =>\$opts{user},    #user name
  "Password:s"=>\$opts{password},  #user password
  "server:s"  =>\$opts{server},  #server to connect to
  "report:s"  =>\$opts{report},  #report name to request
  "num:i"    =>\$opts{num},    #number of reports to request per connection
  "conns:i"  =>\$opts{conns},  #number of simultaneous connections to thread
  "pacing:i"  =>\$opts{pacing},  #pacing in seconds between each report
  "sla:i"    =>\$opts{sla},    #sla for report generation in seconds
  "debug!"  =>\$opts{debug}    #optional debug mode (more verbose)
);
 
$user    = $opts{user}     || "Koopmans";      
$password  = $opts{password}   || "";        
$server    = $opts{server}   || "your.intranet.com:29080";    
$report    = $opts{report}   || "Report 1";      
$num    = $opts{num}    || 1;        
$pacing   = $opts{pacing}    || 1;  
$conns     = $opts{conns}    || 1;
$sla     = $opts{sla}    || 30;
$debug     = $opts{debug};
 
if($debug) {
  print   "User\t\t: $user\n".
    "Password\t: $password\n".
    "Server\t\t: $server\n".
    "Report Name\t: $report\n".
    "Num Reports\t: $num\n".
    "Pacing\t\t: $pacing\n".  
    "Conns\t\t: $conns\n\n";
}
 
#MAIN
for($i=1;$i<=$conns;$i++) {
  $startInterval = int(rand(10000))/1000;
  select(undef, undef, undef, $startInterval);
  my $thread= threads->create("start_workerThread"); #$thread->detach();
  if($debug) { print "\nThread ID".$thread->tid." started in $startInterval seconds ...\n"; }
  
}
my $threadMain = threads->create("start_bossThread"); $threadMain->join();
 
#SUBS
sub start_bossThread {
  
  my @threadList = threads->list;
  my $runningThreads = $#threadList;
  while($runningThreads > 0) {
    select(undef, undef, undef, 1);
    @threadList = threads->list;
    $runningThreads = $#threadList;
  }
  
  
}
 
sub start_workerThread {
  $mech = WWW::Mechanize->new();
  my $thread = threads->self();
  &doLogin;
  
  for($i=1;$i<=$num;$i++) {
    $reportURL = "http://$server/businessobjects/enterprise115/desktoplaunch/viewers/cdz_adv/viewDocument.jsp?id=836&kind=Webi&iventrystore=widtoken&ViewType=H&entSession=CE_ENTERPRISESESSION&lang=en";
    
    &formatDTG;
    print "\t$DG\t $TG\t$conns\t$pacing\t$num\tBO\t".$thread->tid."\t$i/$num\t";
    my $minS  = strftime "%M", gmtime;
    my $secS  = strftime "%S", gmtime;
    &getReport;
    my $minE  = strftime "%M", gmtime;
    my $secE  = strftime "%S", gmtime;
    
    my $timeDiff = ( ($minE * 60) + ($secE)- ($pacing) ) - ( ($minS * 60) + ($secS) ) ;
    if ($timeDiff<1) { $timeDiff = 1; }
    print $timeDiff."\n";
    
    select(undef, undef, undef, $pacing); #sleep for n seconds
  }
  
  &doLogoff;
  $thread->detach();
}
      
 
sub doLogin
{
  #BO REPORT SERVER LOGON
  my $thread = threads->self();
  my $logonURL = "http://$server/businessobjects/enterprise115/desktoplaunch/InfoView/logon/logon.object";
  my $result = $mech->get( $logonURL );
  die "Could not connect to server!\n" unless $result->is_success;
  my $title=$mech->title();
  if($title =~ m/^Log On to InfoView/) {
    if($debug) { print "\nThread ID".$thread->tid." Connected ...\n"; }
    my $result = $mech->submit_form(
      form_name   => 'logonForm',
      fields     => {
      cms    => 'nus740pi:26400',
      username  => 'koops'
      }
    );
    my $title=$mech->title();
    if($debug) { if($title =~ m/^InfoView/) { print "\nThread ID".$thread->tid." Logged in ...\n\n"; } }
  }
}
 
sub doLogoff
{
  #BO REPORT SERVER LOGOFF
  my $thread = threads->self();
  my $logonURL = "http://$server/businessobjects/enterprise115/desktoplaunch/InfoView/logon/logoff.do";
  my $result = $mech->get( $logonURL );
  die "Could not logoff!\n" unless $result->is_success;
  my $title=$mech->title();
  if($debug) { if($title =~ m/^Log On to InfoView/) { print "\nThread ID".$thread->tid." Logged off ...\n\n"; } }
}
 
sub getReport
{
  my $attempts = 0;
  my $canExit = 0;
  
  while(($canExit == 0) && ($attempts < $sla/$pacing)) {
    #GET REPORT
    $result = $mech->post($reportURL);
    die "GET report failed~\n" unless $result->is_success;
        
    foreach (split(/\n/, $result->content)) {
      if($_ =~ m/var strURL = "(.*)";/) {
        $reportURL="http://$server/businessobjects/enterprise115/desktoplaunch/viewers/cdz_adv/$1";
      }
    }
  
    #PARSE REPORT
    $result = $mech->get($reportURL);
    die "PARSE report failed~\n" unless $result->is_success;
    #print $result->status_line()."\t";
    
    foreach (split(/\n/, $result->content)) {
      #print $_."\n";
      if($_ =~ m/$report/) {
        $canExit = 1;
      }
      if($_ =~ m/maximum number of simultaneous connections/) {
        $canExit = 239;
      }
    }
    select(undef, undef, undef, $pacing); #sleep for n seconds
    $attempts++;
  }
  
  if($canExit == 1) {
    print  "PASSED ATTEMPT\t$attempts\t";    
  } elsif($canExit == 239) {
    print "MAX CONNECTIONS\t$attempts\t";
  } else {
    print "FAILED ATTEMPT\t$attempts\t";
  }
}
 
sub formatDTG
{
  $year  = strftime "%Y", gmtime;
  $month  = strftime "%m", gmtime;
  $day  = strftime "%d", gmtime;
  $hour  = strftime "%H", gmtime;
  $min  = strftime "%M", gmtime;
  $sec  = strftime "%S", gmtime;
  $DG="$year$month$day";
  $TG="$hour$min$sec"."00";
}

Share it: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Netscape
  • Reddit
  • Slashdot
  • Technorati
  • YahooMyWeb

Post a Comment

*
To prove that you're not a bot, enter this code
Anti-Spam Image