jmeter-reports 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -2
- data/Gemfile.lock +8 -1
- data/README.md +51 -0
- data/bin/jmeter-reports +31 -29
- data/jmeter-reports.gemspec +3 -3
- data/lib/jmeter/reports.rb +9 -4
- data/lib/jmeter/reports/summary.rb +62 -0
- data/lib/jmeter/reports/summary_item.rb +68 -0
- data/lib/jmeter/reports/summary_line.rb +33 -0
- data/lib/jmeter/reports/views/ascii_summary.rb +45 -0
- data/lib/jmeter/reports/views/ascii_summary_list.rb +30 -0
- data/test/fixtures/{summary_report.csv → summary_report1.csv} +0 -0
- data/test/fixtures/summary_report2.csv +17 -0
- data/test/helper.rb +7 -1
- data/test/test_ascii_summary.rb +16 -0
- data/test/test_ascii_summary_list.rb +16 -0
- data/test/test_jmeter_reports_version.rb +5 -7
- data/test/test_summary.rb +34 -0
- data/test/test_summary_line.rb +14 -0
- metadata +24 -17
- data/README.rdoc +0 -10
- data/lib/jmeter/reports/version.rb +0 -5
- data/lib/jmeter/summary_report/report.rb +0 -68
- data/lib/jmeter/summary_report/report_item.rb +0 -68
- data/lib/jmeter/summary_report/result_line.rb +0 -35
- data/test/test_report.rb +0 -37
- data/test/test_result_line.rb +0 -16
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -12,10 +12,17 @@ GEM | |
| 12 12 | 
             
                  coderay (~> 1.0.5)
         | 
| 13 13 | 
             
                  method_source (~> 0.8)
         | 
| 14 14 | 
             
                  slop (~> 3.3.1)
         | 
| 15 | 
            -
                 | 
| 15 | 
            +
                pry (0.9.10-java)
         | 
| 16 | 
            +
                  coderay (~> 1.0.5)
         | 
| 17 | 
            +
                  method_source (~> 0.8)
         | 
| 18 | 
            +
                  slop (~> 3.3.1)
         | 
| 19 | 
            +
                  spoon (~> 0.0)
         | 
| 20 | 
            +
                rake (10.0.3)
         | 
| 16 21 | 
             
                slop (3.3.3)
         | 
| 22 | 
            +
                spoon (0.0.1)
         | 
| 17 23 |  | 
| 18 24 | 
             
            PLATFORMS
         | 
| 25 | 
            +
              java
         | 
| 19 26 | 
             
              ruby
         | 
| 20 27 |  | 
| 21 28 | 
             
            DEPENDENCIES
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            # JMeter Reports [](https://travis-ci.org/marcoshack/jmeter-reports)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Command-line tools for JMeter report processing. Right now it supports only CSV summary reports processing to show:
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Test execution time
         | 
| 6 | 
            +
            * Total and transaction throughputs
         | 
| 7 | 
            +
            * Transaction samples/errors
         | 
| 8 | 
            +
            * Min / Avg / Max / Standard Deviation
         | 
| 9 | 
            +
            * 90 and 95 response time percentiles
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            # Install
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            Requires Ruby >= 1.9
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                gem install jmeter-reports
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
            # Usage
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                jmeter-reports <path_to_summary_report_file.csv>
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            will show you something like this:
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                             Start: 2012-12-14 16:22:53 -0200
         | 
| 24 | 
            +
                               End: 2012-12-14 16:28:33 -0200
         | 
| 25 | 
            +
                          Duration: 340 secs
         | 
| 26 | 
            +
                    Total requests: 10520
         | 
| 27 | 
            +
                Average throughput: 30 RPS
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                +--------------------------+------+--------+---------+-----+------+-------+--------+------------+
         | 
| 30 | 
            +
                | label                    | reqs | errors | err_pct | min | avg  | max   | sd     | avg_thrput |
         | 
| 31 | 
            +
                +--------------------------+------+--------+---------+-----+------+-------+--------+------------+
         | 
| 32 | 
            +
                | GET session/new          | 2651 | 18     | 0.6     | 49  | 742  | 10062 | 1576ms | 7.797 RPS  |
         | 
| 33 | 
            +
                +--------------------------+------+--------+---------+-----+------+-------+--------+------------+
         | 
| 34 | 
            +
                | POST session             | 2629 | 562    | 21.3    | 272 | 3104 | 10093 | 3882ms | 7.732 RPS  |
         | 
| 35 | 
            +
                +--------------------------+------+--------+---------+-----+------+-------+--------+------------+
         | 
| 36 | 
            +
                | GET session/:id          | 2620 | 0      | 0.0     | 21  | 227  | 8099  | 682ms  | 7.705 RPS  |
         | 
| 37 | 
            +
                +--------------------------+------+--------+---------+-----+------+-------+--------+------------+
         | 
| 38 | 
            +
                | Login                    | 2620 | 570    | 21.7    | 377 | 4185 | 25724 | 4401ms | 7.705 RPS  |
         | 
| 39 | 
            +
                +--------------------------+------+--------+---------+-----+------+-------+--------+------------+
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            you can also pass a list of summary report files to get an overview of each one. Let say you've a bunch of summary files named _summary\_report\_N.csv_:
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                jmeter-reports summary_report_*
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                +----------------------+---------------------------+---------------------------+---------+------------+
         | 
| 46 | 
            +
                | filename             | start                     | end                       | samples | avg_thrput |
         | 
| 47 | 
            +
                +----------------------+---------------------------+---------------------------+---------+------------+
         | 
| 48 | 
            +
                | summary_report_1.csv | 2012-12-11 10:47:32 -0200 | 2012-12-11 10:47:34 -0200 | 9       | 3 RPS      |
         | 
| 49 | 
            +
                +----------------------+---------------------------+---------------------------+---------+------------+
         | 
| 50 | 
            +
                | summary_report_2.csv | 2012-12-11 10:47:32 -0200 | 2012-12-11 10:47:35 -0200 | 16      | 4 RPS      |
         | 
| 51 | 
            +
                +----------------------+---------------------------+---------------------------+---------+------------+
         | 
    
        data/bin/jmeter-reports
    CHANGED
    
    | @@ -1,41 +1,43 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'formatador'
         | 
| 4 | 
            +
            require 'descriptive_statistics'
         | 
| 5 | 
            +
             | 
| 3 6 | 
             
            $:.push File.join(File.dirname(__FILE__), '..'), File.join(File.dirname(__FILE__), '..','lib')
         | 
| 7 | 
            +
            require 'jmeter/reports'
         | 
| 4 8 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
               | 
| 7 | 
            -
              Bundler.require(:default)
         | 
| 8 | 
            -
            rescue LoadError
         | 
| 9 | 
            -
              puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
         | 
| 9 | 
            +
            def version_message
         | 
| 10 | 
            +
              "JMeter Reports version #{JmeterReports::VERSION}"
         | 
| 10 11 | 
             
            end
         | 
| 11 12 |  | 
| 12 | 
            -
             | 
| 13 | 
            +
            def usage_message
         | 
| 14 | 
            +
              """#{version_message}
         | 
| 13 15 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 16 | 
            +
            Usage: 
         | 
| 17 | 
            +
                #{File.basename(__FILE__)} <report_file>        | show the summary report for the given file
         | 
| 18 | 
            +
                #{File.basename(__FILE__)} <report_file_list>   | show a overview list of all report files
         | 
| 19 | 
            +
                #{File.basename(__FILE__)} --version            | show jmeter-reports version
         | 
| 20 | 
            +
                #{File.basename(__FILE__)} --help               | show this help page
         | 
| 21 | 
            +
              """
         | 
| 17 22 | 
             
            end
         | 
| 18 23 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
              if  | 
| 21 | 
            -
                 | 
| 22 | 
            -
                ARGV.each do |filename|
         | 
| 23 | 
            -
                  r = Jmeter::SummaryReport::Report.create(filename)
         | 
| 24 | 
            -
                  puts "#{filename},#{r.elapsed},#{r.total_requests},#{r.avg_throughput}"
         | 
| 25 | 
            -
                end
         | 
| 24 | 
            +
            def process_report(file_list)
         | 
| 25 | 
            +
              if file_list.size > 1
         | 
| 26 | 
            +
                JmeterReports::Views::AsciiSummaryList.new(file_list).render
         | 
| 26 27 | 
             
              else
         | 
| 27 | 
            -
                 | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 28 | 
            +
                JmeterReports::Views::AsciiSummary.new(JmeterReports::Summary.create(file_list.first)).render
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            if ARGV.empty? || ARGV[0] == '--help'
         | 
| 33 | 
            +
              puts usage_message
         | 
| 34 | 
            +
            elsif ARGV[0] == "--version"
         | 
| 35 | 
            +
              puts version_message
         | 
| 36 | 
            +
            else
         | 
| 37 | 
            +
              begin
         | 
| 38 | 
            +
                process_report(ARGV)
         | 
| 39 | 
            +
              rescue Exception => e
         | 
| 40 | 
            +
                puts e.message
         | 
| 41 | 
            +
                exit 2
         | 
| 37 42 | 
             
              end
         | 
| 38 | 
            -
            rescue Exception => e
         | 
| 39 | 
            -
              puts e.message
         | 
| 40 | 
            -
              exit 2
         | 
| 41 43 | 
             
            end
         | 
    
        data/jmeter-reports.gemspec
    CHANGED
    
    | @@ -5,7 +5,7 @@ require 'jmeter/reports' | |
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |gem|
         | 
| 7 7 | 
             
              gem.name          = "jmeter-reports"
         | 
| 8 | 
            -
              gem.version       =  | 
| 8 | 
            +
              gem.version       = JmeterReports::VERSION
         | 
| 9 9 | 
             
              gem.authors       = ["Marcos Hack"]
         | 
| 10 10 | 
             
              gem.email         = ["marcos.hack@gmail.com"]
         | 
| 11 11 | 
             
              gem.description   = %q{JMeter Reports}
         | 
| @@ -19,10 +19,10 @@ Gem::Specification.new do |gem| | |
| 19 19 |  | 
| 20 20 | 
             
              gem.required_ruby_version = '>= 1.9'
         | 
| 21 21 |  | 
| 22 | 
            -
              gem.add_runtime_dependency "bundler"
         | 
| 23 22 | 
             
              gem.add_runtime_dependency "descriptive_statistics"
         | 
| 24 23 | 
             
              gem.add_runtime_dependency "formatador"
         | 
| 25 | 
            -
             | 
| 24 | 
            +
             | 
| 25 | 
            +
              gem.add_development_dependency "bundler"  
         | 
| 26 26 | 
             
              gem.add_development_dependency "rake"
         | 
| 27 27 | 
             
              gem.add_development_dependency "minitest", "~> 3"
         | 
| 28 28 | 
             
              gem.add_development_dependency "minitest-colorize"
         | 
    
        data/lib/jmeter/reports.rb
    CHANGED
    
    | @@ -1,4 +1,9 @@ | |
| 1 | 
            -
            require 'jmeter/ | 
| 2 | 
            -
            require 'jmeter/ | 
| 3 | 
            -
            require 'jmeter/ | 
| 4 | 
            -
            require 'jmeter/reports/ | 
| 1 | 
            +
            require 'jmeter/reports/summary'
         | 
| 2 | 
            +
            require 'jmeter/reports/summary_item'
         | 
| 3 | 
            +
            require 'jmeter/reports/summary_line'
         | 
| 4 | 
            +
            require 'jmeter/reports/views/ascii_summary'
         | 
| 5 | 
            +
            require 'jmeter/reports/views/ascii_summary_list'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module JmeterReports
         | 
| 8 | 
            +
              VERSION = "0.0.6"
         | 
| 9 | 
            +
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            module JmeterReports
         | 
| 2 | 
            +
              class Summary
         | 
| 3 | 
            +
                CSV_HEADER = "timeStamp,elapsed,label,responseCode,responseMessage,threadName,"+
         | 
| 4 | 
            +
                             "dataType,success,bytes,grpThreads,allThreads,URL,Latency\n"
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                def initialize
         | 
| 7 | 
            +
                  @items = {}
         | 
| 8 | 
            +
                  @req_count = 0
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
                
         | 
| 11 | 
            +
                def self.create(summary_report_file_path)
         | 
| 12 | 
            +
                  report = Summary.new
         | 
| 13 | 
            +
                  csv_report = File.open(summary_report_file_path,'r')
         | 
| 14 | 
            +
                  
         | 
| 15 | 
            +
                  unless csv_report.readline == CSV_HEADER
         | 
| 16 | 
            +
                    raise Exception.new("Invalid CSV report: #{summary_report_file_path}")
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  
         | 
| 19 | 
            +
                  csv_report.each_line do |line|
         | 
| 20 | 
            +
                    next if line.start_with?("timeStamp,") # ignore header
         | 
| 21 | 
            +
                    report.add(SummaryLine.parse(line))
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                  return report
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                def add(line)
         | 
| 27 | 
            +
                  @items[line.label] = SummaryItem.new(line.label) if @items[line.label].nil?
         | 
| 28 | 
            +
                  @items[line.label].add(line)
         | 
| 29 | 
            +
                  @req_count += 1
         | 
| 30 | 
            +
                  @start_ms = line.timestamp if @start_ms.nil? || line.timestamp < @start_ms
         | 
| 31 | 
            +
                  @end_ms   = line.timestamp if @end_ms.nil?   || line.timestamp > @end_ms
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
                
         | 
| 34 | 
            +
                def elapsed_in_ms
         | 
| 35 | 
            +
                  @end_ms - @start_ms
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                def elapsed
         | 
| 39 | 
            +
                  (self.elapsed_in_ms / 1000.0).ceil
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                
         | 
| 42 | 
            +
                def avg_throughput
         | 
| 43 | 
            +
                  @req_count / self.elapsed
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
                
         | 
| 46 | 
            +
                def items
         | 
| 47 | 
            +
                  @items.values
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                
         | 
| 50 | 
            +
                def total_requests
         | 
| 51 | 
            +
                  @req_count
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
                
         | 
| 54 | 
            +
                def start_date
         | 
| 55 | 
            +
                  Time.at(@start_ms / 1000.0)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
                
         | 
| 58 | 
            +
                def end_date
         | 
| 59 | 
            +
                  Time.at(@end_ms / 1000.0)
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,68 @@ | |
| 1 | 
            +
            require 'descriptive_statistics'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module JmeterReports
         | 
| 4 | 
            +
              class SummaryItem
         | 
| 5 | 
            +
                def initialize(label)
         | 
| 6 | 
            +
                  @label       = label
         | 
| 7 | 
            +
                  @items       = []
         | 
| 8 | 
            +
                  @error_count = 0
         | 
| 9 | 
            +
                  @req_count   = 0
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                def add(line)
         | 
| 13 | 
            +
                  @error_count += 1 if line.error?
         | 
| 14 | 
            +
                  @items       << line.elapsed
         | 
| 15 | 
            +
                  @req_count   += 1
         | 
| 16 | 
            +
                  @start_ms    = line.timestamp if @start_ms.nil? || line.timestamp < @start_ms
         | 
| 17 | 
            +
                  @end_ms      = line.timestamp if @end_ms.nil?   || line.timestamp > @end_ms
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                def elapsed_in_ms
         | 
| 21 | 
            +
                  @end_ms - @start_ms
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                def elapsed
         | 
| 25 | 
            +
                  (self.elapsed_in_ms / 1000.0).ceil
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                def avg_throughput
         | 
| 29 | 
            +
                  @req_count > 1 ? @req_count / self.elapsed.to_f : 0.0
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                def size
         | 
| 33 | 
            +
                  @items.size
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                def errors
         | 
| 37 | 
            +
                  @error_count
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                def error_rate
         | 
| 41 | 
            +
                  @error_count / self.size.to_f
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
                
         | 
| 44 | 
            +
                def percentil(percentil)
         | 
| 45 | 
            +
                  @items.sort[((percentil / 100.0) * @items.size).ceil]
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
                
         | 
| 48 | 
            +
                def min
         | 
| 49 | 
            +
                  @items.min
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                def avg
         | 
| 53 | 
            +
                  @items.reduce { |n,s| s += n } / @items.size
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
                
         | 
| 56 | 
            +
                def max
         | 
| 57 | 
            +
                  @items.max
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                def sd
         | 
| 61 | 
            +
                  @items.standard_deviation.to_i
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def label
         | 
| 65 | 
            +
                  @label
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            # Representation of a summary report result line.
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Header:
         | 
| 4 | 
            +
            #   timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,
         | 
| 5 | 
            +
            #   success,bytes,grpThreads,allThreads,URL,Latency
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # Line example:
         | 
| 8 | 
            +
            #   1355164382383,97,Tela de Login,200,"Number of samples in transaction : 1, 
         | 
| 9 | 
            +
            #   number of failing samples : 0",Thread Group 1-1,,true,5168,1,1,null,0
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            require 'csv'
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            module JmeterReports
         | 
| 15 | 
            +
              class SummaryLine
         | 
| 16 | 
            +
                attr_accessor :timestamp, :elapsed, :label, :error, :latency
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                def self.parse(line)
         | 
| 19 | 
            +
                  t,e,l,rc,rm,_,_,s,_,_,_,_,lt = CSV.parse_line(line)
         | 
| 20 | 
            +
                  res = JmeterReports::SummaryLine.new
         | 
| 21 | 
            +
                  res.timestamp = t.to_i
         | 
| 22 | 
            +
                  res.elapsed   = e.to_i
         | 
| 23 | 
            +
                  res.label     = l
         | 
| 24 | 
            +
                  res.error     = (s == "false" ? true : false)
         | 
| 25 | 
            +
                  res.latency   = lt.to_i
         | 
| 26 | 
            +
                  return res
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
                
         | 
| 29 | 
            +
                def error?
         | 
| 30 | 
            +
                  self.error
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            module JmeterReports
         | 
| 2 | 
            +
              module Views
         | 
| 3 | 
            +
                class AsciiSummary
         | 
| 4 | 
            +
                  HEADERS = [:label,:reqs,:errors,:err_pct,:min,:avg,:max,:sd,:avg_thrput,:pct_90,:pct_95]
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                  def initialize(report)
         | 
| 7 | 
            +
                    @report = report
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                  def report_data(color = true)
         | 
| 11 | 
            +
                    data = []
         | 
| 12 | 
            +
                    @report.items.each do |i|
         | 
| 13 | 
            +
                      data << {
         | 
| 14 | 
            +
                        :label      => (color ? "[green]#{i.label}[/]" : i.label), 
         | 
| 15 | 
            +
                        :reqs       => i.size, 
         | 
| 16 | 
            +
                        :errors     => (i.errors > 0 && color ? "[red]#{i.errors}[/]" : i.errors),
         | 
| 17 | 
            +
                        :err_pct    => (i.error_rate * 100).round(1),
         | 
| 18 | 
            +
                        :avg_thrput => "[yellow]#{i.avg_throughput.round(3)}[/]", 
         | 
| 19 | 
            +
                        :min        => i.min,
         | 
| 20 | 
            +
                        :avg        => "[yellow]#{i.avg}[/]", 
         | 
| 21 | 
            +
                        :max        => i.max,
         | 
| 22 | 
            +
                        :sd         => color ? "[yellow]#{i.sd}[/]" : i.sd, 
         | 
| 23 | 
            +
                        :pct_90     => i.percentil(90),
         | 
| 24 | 
            +
                        :pct_95     => i.percentil(95)
         | 
| 25 | 
            +
                      }
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    return data
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                
         | 
| 30 | 
            +
                  def render
         | 
| 31 | 
            +
                    puts ""
         | 
| 32 | 
            +
                    puts "             Start: #{@report.start_date}"
         | 
| 33 | 
            +
                    puts "               End: #{@report.end_date}"
         | 
| 34 | 
            +
                    puts "          Duration: #{@report.elapsed} secs"
         | 
| 35 | 
            +
                    puts "    Total requests: #{@report.total_requests}"
         | 
| 36 | 
            +
                    puts "Overall throughput: #{@report.avg_throughput} RPS"
         | 
| 37 | 
            +
                    puts ""
         | 
| 38 | 
            +
                    Formatador.display_compact_table(report_data, HEADERS)
         | 
| 39 | 
            +
                    puts ""
         | 
| 40 | 
            +
                    puts "  Time values in milliseconds and throughput in Requests Per Second."
         | 
| 41 | 
            +
                    puts ""
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module JmeterReports
         | 
| 2 | 
            +
              module Views
         | 
| 3 | 
            +
                class AsciiSummaryList
         | 
| 4 | 
            +
                  HEADERS = [:filename,:start,:end,:samples,:avg_thrput]
         | 
| 5 | 
            +
                  
         | 
| 6 | 
            +
                  def initialize(files)
         | 
| 7 | 
            +
                    @files = files
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                  
         | 
| 10 | 
            +
                  def report_data(color = true)
         | 
| 11 | 
            +
                    data = []
         | 
| 12 | 
            +
                    @files.each do |filename|
         | 
| 13 | 
            +
                      r = JmeterReports::Summary.create(filename)
         | 
| 14 | 
            +
                      data << { 
         | 
| 15 | 
            +
                        :filename   => (color ? "[yellow]#{File.basename(filename)}[/]" : File.basename(filename)), 
         | 
| 16 | 
            +
                        :start      => r.start_date, 
         | 
| 17 | 
            +
                        :end        => r.end_date, 
         | 
| 18 | 
            +
                        :samples    => (color ? "[blue]#{r.total_requests}[/]" : r.total_requests), 
         | 
| 19 | 
            +
                        :avg_thrput => "#{r.avg_throughput} RPS" 
         | 
| 20 | 
            +
                      }
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                    return data
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  def render
         | 
| 26 | 
            +
                    Formatador.display_compact_table(report_data, HEADERS)
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,grpThreads,allThreads,URL,Latency
         | 
| 2 | 
            +
            1355230052183,75,GET retrieve_gui,200,OK,Thread Group 1-1,text,true,5168,1,1,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2820887356_2820887356&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=3887356&provedores=facebook%2Ctwitter%2Cgoogle,74
         | 
| 3 | 
            +
            1355230052256,72,GET retrieve_gui,200,OK,Thread Group 1-3,text,true,5168,3,3,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2464809911_2464809911&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=8771784&provedores=facebook%2Ctwitter%2Cgoogle,70
         | 
| 4 | 
            +
            1355230052460,65,GET retrieve_gui,200,OK,Thread Group 1-5,text,true,5168,5,5,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2880723472_2880723472&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472&provedores=facebook%2Ctwitter%2Cgoogle,64
         | 
| 5 | 
            +
            1355230052560,65,GET retrieve_gui,200,OK,Thread Group 1-5,text,true,5168,5,5,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2880723472_2880723472&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472&provedores=facebook%2Ctwitter%2Cgoogle,64
         | 
| 6 | 
            +
            1355230053060,71,GET retrieve_gui,200,OK,Thread Group 1-6,text,true,5168,6,6,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2808390679_2808390679&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9390679&provedores=facebook%2Ctwitter%2Cgoogle,69
         | 
| 7 | 
            +
            1355230053262,66,GET retrieve_gui,200,OK,Thread Group 1-7,text,true,5168,7,7,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2692773635_2692773635&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=1773635&provedores=facebook%2Ctwitter%2Cgoogle,65
         | 
| 8 | 
            +
            1355230053660,73,GET retrieve_gui,200,OK,Thread Group 1-8,text,true,5168,8,8,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2625634952_2625634952&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=6634952&provedores=facebook%2Ctwitter%2Cgoogle,71
         | 
| 9 | 
            +
            1355230053760,73,GET retrieve_gui,200,OK,Thread Group 1-8,text,true,5168,8,8,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery2625634952_2625634952&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=6634952&provedores=facebook%2Ctwitter%2Cgoogle,71
         | 
| 10 | 
            +
            1355230054465,68,GET retrieve_gui,200,OK,Thread Group 1-9,text,true,5168,9,9,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery1205134350_1205134350&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=8134350&provedores=facebook%2Ctwitter%2Cgoogle,67
         | 
| 11 | 
            +
            1355230054867,434,POST execute,200,OK,Thread Group 1-5,text,true,1468,10,10,http://stage.id.abril.com.br/widgets/login/execute,434
         | 
| 12 | 
            +
            1355230054967,434,POST execute,200,OK,Thread Group 1-5,text,true,1468,10,10,http://stage.id.abril.com.br/widgets/login/execute,434
         | 
| 13 | 
            +
            1355230054987,434,POST execute,200,OK,Thread Group 1-5,text,true,1468,10,10,http://stage.id.abril.com.br/widgets/login/execute,434
         | 
| 14 | 
            +
            1355230055102,22,GET retrieve_success_gui,200,OK,Thread Group 1-5,text,true,2084,10,10,http://stage.id.abril.com.br/widgets/login/retrieve_success_gui?callback=AbrilIdJQuery2880723472_2880723472&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472,27
         | 
| 15 | 
            +
            1355230055465,85,GET retrieve_gui,200,OK,Thread Group 1-9,text,true,5168,9,9,http://stage.id.abril.com.br/widgets/login/retrieve_gui?callback=AbrilIdJQuery1205134350_1205134350&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=8134350&provedores=facebook%2Ctwitter%2Cgoogle,67
         | 
| 16 | 
            +
            1355230055867,628,POST execute,200,OK,Thread Group 1-5,text,true,1468,10,10,http://stage.id.abril.com.br/widgets/login/execute,434
         | 
| 17 | 
            +
            1355230055902,98,GET retrieve_success_gui,200,OK,Thread Group 1-5,text,true,2084,10,10,http://stage.id.abril.com.br/widgets/login/retrieve_success_gui?callback=AbrilIdJQuery2880723472_2880723472&application_login=PLAYBOY¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472,27
         | 
    
        data/test/helper.rb
    CHANGED
    
    | @@ -1,4 +1,10 @@ | |
| 1 1 | 
             
            require 'minitest/autorun'
         | 
| 2 2 | 
             
            require 'minitest/colorize'
         | 
| 3 3 |  | 
| 4 | 
            -
             | 
| 4 | 
            +
            begin
         | 
| 5 | 
            +
              require 'bundler/setup'
         | 
| 6 | 
            +
              Bundler.require(:default, :development, :test)
         | 
| 7 | 
            +
            rescue LoadError
         | 
| 8 | 
            +
              puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            +
            require 'jmeter/reports/views/ascii_summary'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module JmeterReports
         | 
| 5 | 
            +
              module Views
         | 
| 6 | 
            +
                class TestAsciiSummary < MiniTest::Unit::TestCase
         | 
| 7 | 
            +
                  def setup
         | 
| 8 | 
            +
                    @report = ::JmeterReports::Summary.create(File.expand_path('fixtures/summary_report1.csv', File.dirname(__FILE__)))
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  def test_render
         | 
| 12 | 
            +
                    AsciiSummary.new(@report).render
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            +
            require 'jmeter/reports/views/ascii_summary_list'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module JmeterReports
         | 
| 5 | 
            +
              module Views
         | 
| 6 | 
            +
                class TestAsciiSummaryList < MiniTest::Unit::TestCase
         | 
| 7 | 
            +
                  def setup
         | 
| 8 | 
            +
                    @files = Dir.glob(File.expand_path('fixtures/*', File.dirname(__FILE__)))
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  def test_render
         | 
| 12 | 
            +
                    AsciiSummaryList.new(@files).render
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -1,12 +1,10 @@ | |
| 1 1 | 
             
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            -
            require 'jmeter/reports | 
| 2 | 
            +
            require 'jmeter/reports'
         | 
| 3 3 |  | 
| 4 | 
            -
            module  | 
| 5 | 
            -
               | 
| 6 | 
            -
                 | 
| 7 | 
            -
                   | 
| 8 | 
            -
                    assert Jmeter::Reports::VERSION != nil
         | 
| 9 | 
            -
                  end
         | 
| 4 | 
            +
            module JmeterReports
         | 
| 5 | 
            +
              class TestVersion < MiniTest::Unit::TestCase
         | 
| 6 | 
            +
                def test_version
         | 
| 7 | 
            +
                  assert JmeterReports::VERSION != nil
         | 
| 10 8 | 
             
                end
         | 
| 11 9 | 
             
              end
         | 
| 12 10 | 
             
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            +
            require 'jmeter/reports'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module JmeterReports
         | 
| 5 | 
            +
              class TestSummary < MiniTest::Unit::TestCase
         | 
| 6 | 
            +
                def setup
         | 
| 7 | 
            +
                  @report = Summary.create(File.expand_path('fixtures/summary_report1.csv', File.dirname(__FILE__)))
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def test_report_items
         | 
| 11 | 
            +
                  assert_equal 3, @report.items.size
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def test_avg_throughput
         | 
| 15 | 
            +
                  assert_equal 3, @report.avg_throughput
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def test_elapsed_in_ms
         | 
| 19 | 
            +
                  assert_equal 2719, @report.elapsed_in_ms
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def test_elapsed
         | 
| 23 | 
            +
                  assert_equal 3, @report.elapsed
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                def test_start_date
         | 
| 27 | 
            +
                  assert_equal Time.new(2012,12,11,12,47,32,"+00:00").to_i, @report.start_date.utc.to_i, 'invalid start date'
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                
         | 
| 30 | 
            +
                def test_end_date
         | 
| 31 | 
            +
                  assert_equal Time.new(2012,12,11,12,47,34,"+00:00").to_i, @report.end_date.utc.to_i, 'invalid end date'
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            +
            require 'jmeter/reports/summary_line'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module JmeterReports
         | 
| 5 | 
            +
              class TestSummaryLine < MiniTest::Unit::TestCase
         | 
| 6 | 
            +
                def test_parse_simple_error_line
         | 
| 7 | 
            +
                  assert SummaryLine.parse('1355332336591,4850,POST execute,500,Internal Server Error,Thread Group 1-70,text,false,15535,75,75,http://stage.id.abril.com.br/widgets/login/execute,4847').error?
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                def test_parse_transaction_error_line
         | 
| 11 | 
            +
                  assert SummaryLine.parse('1355163053904,5933,Login,,"Number of samples in transaction : 2, number of failing samples : 1",Thread Group 1-15,,false,2836,20,20,null,0').error?
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: jmeter-reports
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.6
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,10 +9,10 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2012-12- | 
| 12 | 
            +
            date: 2012-12-18 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            -
              name:  | 
| 15 | 
            +
              name: descriptive_statistics
         | 
| 16 16 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| @@ -28,7 +28,7 @@ dependencies: | |
| 28 28 | 
             
                  - !ruby/object:Gem::Version
         | 
| 29 29 | 
             
                    version: '0'
         | 
| 30 30 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 31 | 
            -
              name:  | 
| 31 | 
            +
              name: formatador
         | 
| 32 32 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 33 33 | 
             
                none: false
         | 
| 34 34 | 
             
                requirements:
         | 
| @@ -44,14 +44,14 @@ dependencies: | |
| 44 44 | 
             
                  - !ruby/object:Gem::Version
         | 
| 45 45 | 
             
                    version: '0'
         | 
| 46 46 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 47 | 
            -
              name:  | 
| 47 | 
            +
              name: bundler
         | 
| 48 48 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 49 49 | 
             
                none: false
         | 
| 50 50 | 
             
                requirements:
         | 
| 51 51 | 
             
                - - ! '>='
         | 
| 52 52 | 
             
                  - !ruby/object:Gem::Version
         | 
| 53 53 | 
             
                    version: '0'
         | 
| 54 | 
            -
              type: : | 
| 54 | 
            +
              type: :development
         | 
| 55 55 | 
             
              prerelease: false
         | 
| 56 56 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 57 57 | 
             
                none: false
         | 
| @@ -136,20 +136,24 @@ files: | |
| 136 136 | 
             
            - Gemfile
         | 
| 137 137 | 
             
            - Gemfile.lock
         | 
| 138 138 | 
             
            - LICENSE
         | 
| 139 | 
            -
            - README. | 
| 139 | 
            +
            - README.md
         | 
| 140 140 | 
             
            - Rakefile
         | 
| 141 141 | 
             
            - bin/jmeter-reports
         | 
| 142 142 | 
             
            - jmeter-reports.gemspec
         | 
| 143 143 | 
             
            - lib/jmeter/reports.rb
         | 
| 144 | 
            -
            - lib/jmeter/reports/ | 
| 145 | 
            -
            - lib/jmeter/ | 
| 146 | 
            -
            - lib/jmeter/ | 
| 147 | 
            -
            - lib/jmeter/ | 
| 148 | 
            -
            -  | 
| 144 | 
            +
            - lib/jmeter/reports/summary.rb
         | 
| 145 | 
            +
            - lib/jmeter/reports/summary_item.rb
         | 
| 146 | 
            +
            - lib/jmeter/reports/summary_line.rb
         | 
| 147 | 
            +
            - lib/jmeter/reports/views/ascii_summary.rb
         | 
| 148 | 
            +
            - lib/jmeter/reports/views/ascii_summary_list.rb
         | 
| 149 | 
            +
            - test/fixtures/summary_report1.csv
         | 
| 150 | 
            +
            - test/fixtures/summary_report2.csv
         | 
| 149 151 | 
             
            - test/helper.rb
         | 
| 152 | 
            +
            - test/test_ascii_summary.rb
         | 
| 153 | 
            +
            - test/test_ascii_summary_list.rb
         | 
| 150 154 | 
             
            - test/test_jmeter_reports_version.rb
         | 
| 151 | 
            -
            - test/ | 
| 152 | 
            -
            - test/ | 
| 155 | 
            +
            - test/test_summary.rb
         | 
| 156 | 
            +
            - test/test_summary_line.rb
         | 
| 153 157 | 
             
            homepage: https://github.com/marcoshack/jmeter-reports
         | 
| 154 158 | 
             
            licenses: []
         | 
| 155 159 | 
             
            post_install_message: 
         | 
| @@ -175,9 +179,12 @@ signing_key: | |
| 175 179 | 
             
            specification_version: 3
         | 
| 176 180 | 
             
            summary: Basic tools for JMeter reports processing.
         | 
| 177 181 | 
             
            test_files:
         | 
| 178 | 
            -
            - test/fixtures/ | 
| 182 | 
            +
            - test/fixtures/summary_report1.csv
         | 
| 183 | 
            +
            - test/fixtures/summary_report2.csv
         | 
| 179 184 | 
             
            - test/helper.rb
         | 
| 185 | 
            +
            - test/test_ascii_summary.rb
         | 
| 186 | 
            +
            - test/test_ascii_summary_list.rb
         | 
| 180 187 | 
             
            - test/test_jmeter_reports_version.rb
         | 
| 181 | 
            -
            - test/ | 
| 182 | 
            -
            - test/ | 
| 188 | 
            +
            - test/test_summary.rb
         | 
| 189 | 
            +
            - test/test_summary_line.rb
         | 
| 183 190 | 
             
            has_rdoc: 
         | 
    
        data/README.rdoc
    DELETED
    
    | @@ -1,10 +0,0 @@ | |
| 1 | 
            -
            == JMeter Reports {<img src="https://travis-ci.org/marcoshack/jmeter-reports.png?branch=master" alt="Build Status" />}[https://travis-ci.org/marcoshack/jmeter-reports]
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            Basic tools for JMeter reports processing.
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            Right now it supports only CSV summary reports processing to show:
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            * Test execution time
         | 
| 8 | 
            -
            * Average request throughput
         | 
| 9 | 
            -
            * Number of requests/errors for each request and/or transaction
         | 
| 10 | 
            -
            * 90 and 95 response time percentiles
         | 
| @@ -1,68 +0,0 @@ | |
| 1 | 
            -
            module Jmeter
         | 
| 2 | 
            -
              module SummaryReport
         | 
| 3 | 
            -
                class Report
         | 
| 4 | 
            -
                  CSV_HEADER = "timeStamp,elapsed,label,responseCode,responseMessage,threadName,"+
         | 
| 5 | 
            -
                               "dataType,success,bytes,grpThreads,allThreads,URL,Latency\n"
         | 
| 6 | 
            -
                  
         | 
| 7 | 
            -
                  def initialize
         | 
| 8 | 
            -
                    @items = {}
         | 
| 9 | 
            -
                    @req_count = 0
         | 
| 10 | 
            -
                  end
         | 
| 11 | 
            -
                  
         | 
| 12 | 
            -
                  def self.create(summary_report_file_path)
         | 
| 13 | 
            -
                    report = Report.new
         | 
| 14 | 
            -
                    csv_report = File.open(summary_report_file_path,'r')
         | 
| 15 | 
            -
                    
         | 
| 16 | 
            -
                    unless csv_report.readline == CSV_HEADER
         | 
| 17 | 
            -
                      raise Exception.new("Invalid CSV report: #{summary_report_file_path}")
         | 
| 18 | 
            -
                    end
         | 
| 19 | 
            -
                    
         | 
| 20 | 
            -
                    csv_report.each_line do |line|
         | 
| 21 | 
            -
                      next if line.start_with?("timeStamp,") # ignore header
         | 
| 22 | 
            -
                      report.add(ResultLine.parse(line))
         | 
| 23 | 
            -
                    end
         | 
| 24 | 
            -
                    return report
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
                  
         | 
| 27 | 
            -
                  def add(line)
         | 
| 28 | 
            -
                    @items[line.label] = ReportItem.new(line.label) if @items[line.label].nil?
         | 
| 29 | 
            -
                    @items[line.label].add(line)
         | 
| 30 | 
            -
                    @req_count += 1
         | 
| 31 | 
            -
                    @start_ms = line.timestamp if @start_ms.nil? || line.timestamp < @start_ms
         | 
| 32 | 
            -
                    @end_ms   = line.timestamp if @end_ms.nil?   || line.timestamp > @end_ms
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
                  
         | 
| 35 | 
            -
                  def elapsed_in_ms
         | 
| 36 | 
            -
                    @end_ms - @start_ms
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
                  
         | 
| 39 | 
            -
                  def elapsed
         | 
| 40 | 
            -
                    (self.elapsed_in_ms / 1000.0).ceil
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
                  
         | 
| 43 | 
            -
                  def avg_throughput
         | 
| 44 | 
            -
                    @req_count / self.elapsed
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
                  
         | 
| 47 | 
            -
                  def items
         | 
| 48 | 
            -
                    @items.values
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
                  
         | 
| 51 | 
            -
                  def total_requests
         | 
| 52 | 
            -
                    @req_count
         | 
| 53 | 
            -
                  end
         | 
| 54 | 
            -
                  
         | 
| 55 | 
            -
                  def start_date
         | 
| 56 | 
            -
                    Time.at(@start_ms / 1000.0)
         | 
| 57 | 
            -
                  end
         | 
| 58 | 
            -
                  
         | 
| 59 | 
            -
                  def end_date
         | 
| 60 | 
            -
                    Time.at(@end_ms / 1000.0)
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
                  
         | 
| 63 | 
            -
                  def table_data
         | 
| 64 | 
            -
                    @items.values.collect { |i| i.table_data }
         | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
              end
         | 
| 68 | 
            -
            end
         | 
| @@ -1,68 +0,0 @@ | |
| 1 | 
            -
            require 'descriptive_statistics'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Jmeter
         | 
| 4 | 
            -
              module SummaryReport
         | 
| 5 | 
            -
                class ReportItem
         | 
| 6 | 
            -
                  def initialize(label)
         | 
| 7 | 
            -
                    @label = label
         | 
| 8 | 
            -
                    @items = []
         | 
| 9 | 
            -
                    @error_count = 0
         | 
| 10 | 
            -
                    @req_count   = 0
         | 
| 11 | 
            -
                  end
         | 
| 12 | 
            -
                  
         | 
| 13 | 
            -
                  def add(line)
         | 
| 14 | 
            -
                    @error_count += 1 if line.error?
         | 
| 15 | 
            -
                    @items       << line.elapsed
         | 
| 16 | 
            -
                    @req_count   += 1
         | 
| 17 | 
            -
                    @start_ms    = line.timestamp if @start_ms.nil? || line.timestamp < @start_ms
         | 
| 18 | 
            -
                    @end_ms      = line.timestamp if @end_ms.nil?   || line.timestamp > @end_ms
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                  
         | 
| 21 | 
            -
                  def elapsed_in_ms
         | 
| 22 | 
            -
                    @end_ms - @start_ms
         | 
| 23 | 
            -
                  end
         | 
| 24 | 
            -
                  
         | 
| 25 | 
            -
                  def elapsed
         | 
| 26 | 
            -
                    (self.elapsed_in_ms / 1000.0).ceil
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                  
         | 
| 29 | 
            -
                  def avg_throughput
         | 
| 30 | 
            -
                    @req_count / self.elapsed.to_f
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
                  
         | 
| 33 | 
            -
                  def size
         | 
| 34 | 
            -
                    @items.size
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
                  
         | 
| 37 | 
            -
                  def errors
         | 
| 38 | 
            -
                    @error_count
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
                  
         | 
| 41 | 
            -
                  def error_rate
         | 
| 42 | 
            -
                    @error_count / self.size.to_f
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
                  
         | 
| 45 | 
            -
                  def table_data
         | 
| 46 | 
            -
                    sorted_items = @items.sort
         | 
| 47 | 
            -
                    {
         | 
| 48 | 
            -
                      :label      => @label, 
         | 
| 49 | 
            -
                      :reqs       => self.size, 
         | 
| 50 | 
            -
                      :errors     => self.errors, 
         | 
| 51 | 
            -
                      :err_pct    => round(self.error_rate * 100, 1),
         | 
| 52 | 
            -
                      :avg_thrput => "#{round(self.avg_throughput, 3)} RPS", 
         | 
| 53 | 
            -
                      :min        => @items.min,
         | 
| 54 | 
            -
                      :avg        => @items.reduce { |n,s| s += n } / @items.size, 
         | 
| 55 | 
            -
                      :max        => @items.max,
         | 
| 56 | 
            -
                      :sd         => "#{@items.standard_deviation.to_i}ms", 
         | 
| 57 | 
            -
                      :pct_90     => "#{sorted_items[(self.size * 0.90).round]}ms",
         | 
| 58 | 
            -
                      :pct_95     => "#{sorted_items[(self.size * 0.95).round]}ms"
         | 
| 59 | 
            -
                    }
         | 
| 60 | 
            -
                  end
         | 
| 61 | 
            -
                  
         | 
| 62 | 
            -
                  private
         | 
| 63 | 
            -
                  def round(float_number, dec)
         | 
| 64 | 
            -
                    (float_number * 10**dec).to_i / (10**dec).to_f
         | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
              end
         | 
| 68 | 
            -
            end
         | 
| @@ -1,35 +0,0 @@ | |
| 1 | 
            -
            # Representation of a summary report result line.
         | 
| 2 | 
            -
            #
         | 
| 3 | 
            -
            # Header:
         | 
| 4 | 
            -
            #   timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,
         | 
| 5 | 
            -
            #   success,bytes,grpThreads,allThreads,URL,Latency
         | 
| 6 | 
            -
            #
         | 
| 7 | 
            -
            # Line example:
         | 
| 8 | 
            -
            #   1355164382383,97,Tela de Login,200,"Number of samples in transaction : 1, 
         | 
| 9 | 
            -
            #   number of failing samples : 0",Thread Group 1-1,,true,5168,1,1,null,0
         | 
| 10 | 
            -
            #
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            require 'csv'
         | 
| 13 | 
            -
             | 
| 14 | 
            -
            module Jmeter
         | 
| 15 | 
            -
              module SummaryReport
         | 
| 16 | 
            -
                class ResultLine
         | 
| 17 | 
            -
                  attr_accessor :timestamp, :elapsed, :label, :error, :latency
         | 
| 18 | 
            -
                  
         | 
| 19 | 
            -
                  def self.parse(line)
         | 
| 20 | 
            -
                    t,e,l,rc,rm,_,_,s,_,_,_,_,lt = CSV.parse_line(line)
         | 
| 21 | 
            -
                    res = Jmeter::SummaryReport::ResultLine.new
         | 
| 22 | 
            -
                    res.timestamp = t.to_i
         | 
| 23 | 
            -
                    res.elapsed   = e.to_i
         | 
| 24 | 
            -
                    res.label     = l
         | 
| 25 | 
            -
                    res.error     = (s == "false" ? true : false)
         | 
| 26 | 
            -
                    res.latency   = lt.to_i
         | 
| 27 | 
            -
                    return res
         | 
| 28 | 
            -
                  end
         | 
| 29 | 
            -
                  
         | 
| 30 | 
            -
                  def error?
         | 
| 31 | 
            -
                    self.error
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
            end
         | 
    
        data/test/test_report.rb
    DELETED
    
    | @@ -1,37 +0,0 @@ | |
| 1 | 
            -
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            -
            require 'jmeter/reports'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            module Jmeter
         | 
| 5 | 
            -
              module SummaryReport
         | 
| 6 | 
            -
                class TestReport < MiniTest::Unit::TestCase
         | 
| 7 | 
            -
                  def setup
         | 
| 8 | 
            -
                    fixture = File.expand_path('fixtures/summary_report.csv', File.dirname(__FILE__))
         | 
| 9 | 
            -
                    @report = Report.create(fixture)
         | 
| 10 | 
            -
                  end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  def test_report_items
         | 
| 13 | 
            -
                    assert_equal 3, @report.items.size
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
              
         | 
| 16 | 
            -
                  def test_avg_throughput
         | 
| 17 | 
            -
                    assert_equal 3, @report.avg_throughput
         | 
| 18 | 
            -
                  end
         | 
| 19 | 
            -
              
         | 
| 20 | 
            -
                  def test_elapsed_in_ms
         | 
| 21 | 
            -
                    assert_equal 2719, @report.elapsed_in_ms
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
              
         | 
| 24 | 
            -
                  def test_elapsed
         | 
| 25 | 
            -
                    assert_equal 3, @report.elapsed
         | 
| 26 | 
            -
                  end
         | 
| 27 | 
            -
                  
         | 
| 28 | 
            -
                  def test_start_date
         | 
| 29 | 
            -
                    assert_equal Time.new(2012,12,11,12,47,32,"+00:00").to_i, @report.start_date.utc.to_i, 'invalid start date'
         | 
| 30 | 
            -
                  end
         | 
| 31 | 
            -
                  
         | 
| 32 | 
            -
                  def test_end_date
         | 
| 33 | 
            -
                    assert_equal Time.new(2012,12,11,12,47,34,"+00:00").to_i, @report.end_date.utc.to_i, 'invalid end date'
         | 
| 34 | 
            -
                  end
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
              end
         | 
| 37 | 
            -
            end
         | 
    
        data/test/test_result_line.rb
    DELETED
    
    | @@ -1,16 +0,0 @@ | |
| 1 | 
            -
            require File.expand_path('helper', File.dirname(__FILE__))
         | 
| 2 | 
            -
            require 'jmeter/summary_report/result_line'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            module Jmeter
         | 
| 5 | 
            -
              module SummaryReport
         | 
| 6 | 
            -
                class TestResultLine < MiniTest::Unit::TestCase
         | 
| 7 | 
            -
                  def test_parse_simple_error_line
         | 
| 8 | 
            -
                    assert ResultLine.parse('1355332336591,4850,POST execute,500,Internal Server Error,Thread Group 1-70,text,false,15535,75,75,http://stage.id.abril.com.br/widgets/login/execute,4847').error?
         | 
| 9 | 
            -
                  end
         | 
| 10 | 
            -
                  
         | 
| 11 | 
            -
                  def test_parse_transaction_error_line
         | 
| 12 | 
            -
                    assert ResultLine.parse('1355163053904,5933,Login,,"Number of samples in transaction : 2, number of failing samples : 1",Thread Group 1-15,,false,2836,20,20,null,0').error?
         | 
| 13 | 
            -
                  end
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
              end
         | 
| 16 | 
            -
            end
         |