sreda, 2. december 2015

Jmeter create graphs with CMDRunner with powershell parallel execution



Creating reporting files with CMDRunner is fast and easy to use. When a lot of call web services is call it needed to write a lot of code to create different graphs and tables. So i have decide to share with you how are graph generated in my automation framework. From first blog i wrote, now i taking parts of the code and presenting to you how is done complete performance automation in powershell and how to create a word document.

Structure

Structure is simple a you now i like driving powershell with XML files, because you write once and use more times.
First, XML is created and then powershell code is generating command lines and run all in threads to save time.
  

XML

XML structure are included in main elements <graph>. Element <graph> defines .jtl file and what should be exclude or included when report is generating. Attributes 'exclude' or 'include'  are regular expression what should be include in exclude in graphs. Element 'graphtype' defines which type of graph should be generated, attributes 'includesuccess' means if only success or failed or both are include in report. Attribute 'aggregaterows' defined if all services will be displayed as one or separate. XML structure of file:

<!-- file.xml -->
<config>
    <jmeter>
        <generategraphs>
            <graph name="ALL"  jtlfile="PPperformance-output.jtl" exclude="" include="" >
                <graphtype type="SynthesisReport" includeseccess="all" aggregaterows="yes"/>
                <graphtype type="AggregateReport" includeseccess="all" aggregaterows="yes"/>
                <graphtype type="TransactionsPerSecond" includeseccess="true" aggregaterows="yes"/>
                <graphtype type="ResponseCodesPerSecond" includeseccess="" aggregaterows="no"/>
                <graphtype type="ThreadsStateOverTime" includeseccess="" aggregaterows="no"/>
            </graph>          
            <graph name="API" jtlfile="PPperformance-output.jtl" exclude="" include="/FacadeAPI/*" >
                <graphtype type="SynthesisReport" includeseccess="all" aggregaterows="no"/>
                <graphtype type="AggregateReport" includeseccess="all" aggregaterows="no"/>
                <graphtype type="TransactionsPerSecond" includeseccess="true" aggregaterows="no"/>
                <graphtype type="ResponseCodesPerSecond" includeseccess="" aggregaterows="no"/>
                <graphtype type="ThreadsStateOverTime" includeseccess="" aggregaterows="no"/>
            </graph>
        </generategraphs>
    </jmeter>
</config>

 
Save file in folder with name config.xml.

Powershell

Powershell job is to read data from XML and translate it to cmd and execute all commands in parallel. Open powershell ISE and set path to XML location. All code which is below copy in powershell ISE and should work.

Function 'runcmd' is used to call dos command.
function runcmd($path)
{
     Invoke-Expression $path

  }

Function 'JmeterGenerateGraphs' is use to prepare attributes for CMDrunner.exe get from input variable hash table. Main par of function is executed all jobs in parallel. Command which create a execution in parallel is :


  $jobs = Invoke-Command -computer localhost -ScriptBlock ${function:runcmd} -ArgumentList $ps  -AsJob

Complete function is displayed below:

function JmeterGenerateGraphs ($Arraygraphs) {
$prepareJobs = @()
    foreach ($graph in $Arraygraphs)
    {

           $parameters =""
          if($graph[3].length -gt 0){
                $parameters += "--exclude-label-regex yes --exclude-labels ""$($graph[3])"""
          }
          if($graph[4].length -gt 0){
                $parameters += "--include-label-regex yes --include-labels ""$($graph[4])"""
          }
          if($graph[5].length -gt 0){
                $parameters += "$($graph[5])"
          }

          if($graph[0].contains("png") -gt 0){
                $parameters += "--width 800 --height 600 "
          }
          $ps="cmd /c java -jar e:\aps\apache-jmeter\lib\ext\CMDRunner.jar --tool Reporter $($graph[0]) --input-jtl ""$($graph[2])"" --plugin-type $($graph[1]) --aggregate-rows $($graph[6]) $parameters"         
          $ps
          $jobs = Invoke-Command -computer localhost -ScriptBlock ${function:runcmd} -ArgumentList $ps  -AsJob
         
    $prepareJobs += $jobs
  
    }
    
      Wait-Job   -Job $prepareJobs  *>&1 


     Foreach ($job in $prepareJobs)
    {
      if( $job.HasMoreData -eq $true)
        {
          ("Receiving job id $($job.id) which executes $($job.command) on $($job.Location)")
          Receive-Job -Id $job.id
        }
        if( $job.Status -eq "Failed")   
        {
         " FAILED JOB !!!  Job id $($job.id) which executes $($job.command) on $($job.Location)"       

  " $job.ChildJobs[0].JobStateInfo.Reason.Message ")        }
    }
}



This is a main part which read XML file and prepare CMDRunner graphs which are going to be generated. Depend on attributes in XML, CMDRunner commands are prepared and seved into hash table. Hash table is used to store all data about reports which are further processed in function JmeterGenerategraphs.

Code below:
 $configpath = "."
$configfile = [xml] (Get-Content $configpath\config.xml)

$arraygraphlist= @(@())

$generategraphs = @()
$generategraphs = $configfile.SelectNodes("/config/jmeter/generategraphs/graph")
$JMeterReportFileFolder ="c:\test"

foreach($generategraph in $generategraphs)
{
    #$generategraph

    $name = $generategraph.GetAttribute("name")
    $jtlfile = $generategraph.GetAttribute("jtlfile")
    $exclude = $generategraph.GetAttribute("exclude")
    $include = $generategraph.GetAttribute("include")

    $graphs = $generategraph.ChildNodes

    foreach($graph in $graphs){

        #if ($name -eq 'ALL')
        $type = $graph.GetAttribute("type")
        $includeseccess = $graph.GetAttribute("includeseccess")
        $aggregaterows  =$graph.GetAttribute("aggregaterows")
      
        $postfix = "_"+$name
        if ($name -eq "ALL")
        {
            $postfix=""   
        }       

        $suffixpatter="png"
        if($type -eq "SynthesisReport" -or $type -eq "AggregateReport")
        {           
            $suffixpatter="csv"                      
        }
        $savefile="--generate-$suffixpatter ""$JMeterReportFileFolder\$type$postfix.$suffixpatter"""
   
        $arraygraphlist += ,@("$savefile","$type","$JMeterReportFileFolder\$jtlfile",$exclude,$include,"",$aggregaterows)
        if ($includeseccess -eq "true" -or  $includeseccess -eq "all")
            {
            $filename ="$JMeterReportFileFolder\$type$postfix"+"_true."+"$suffixpatter"
            $savefile="--generate-$suffixpatter ""$filename"""
            $arraygraphlist += ,@("$savefile","$type","$JMeterReportFileFolder\$jtlfile",$exclude,$include,"--success-filter ""true""",$aggregaterows)           
        }
        if ($includeseccess -eq "false" -or $includeseccess -eq "all")
        {
            $filename ="$JMeterReportFileFolder\$type$postfix"+"_false."+"$suffixpatter"
            $savefile="--generate-$suffixpatter ""$filename"""
            $arraygraphlist += ,@($savefile,$type,"$JMeterReportFileFolder\$jtlfile",$exclude,$include,"--success-filter ""false""",$aggregaterows)
        }
    }     
}
"-----------------------------------------------"
$arraygraphlist | Format-Table
"-----------------------------------------------"

JmeterGenerateGraphs -Arraygraphs $arraygraphlist



Summary

I hope i show you an easy way how to generate graphs with XML, powershell and parallel execution. Generating graphs is very time consuming  job, running in parallel makes faster, but resources of computer are more under pressure.
To configure XML once and it easy to add new graphs without changing or adding code in powershell and it is easy to manage XML and everything in shape.

How to add these graph into word docuemnt you can find in blog:
http://performancewebautoamtionother.blogspot.si/2016/03/jmeter-creating-reports-word-reports-in.html
Enjoy!

Ni komentarjev:

Objavite komentar