jmeter-reports 0.0.1alpha

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.
@@ -0,0 +1 @@
1
+ jmeter-reports*.gem
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.8.7
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gem 'rake'
4
+
5
+ group :test do
6
+ gem 'minitest'
7
+ gem 'minitest-colorize'
8
+ end
@@ -0,0 +1,15 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ minitest (2.12.1)
5
+ minitest-colorize (0.0.4)
6
+ minitest (~> 2.0)
7
+ rake (10.0.2)
8
+
9
+ PLATFORMS
10
+ ruby
11
+
12
+ DEPENDENCIES
13
+ minitest
14
+ minitest-colorize
15
+ rake
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2012 Marcos Hack <marcoshack@gmail.com>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1,10 @@
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
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rake'
10
+ require 'rake/testtask'
11
+
12
+ Rake::TestTask.new do |t|
13
+ t.libs << "test"
14
+ t.libs << "lib"
15
+ t.test_files = FileList['test/**/test_*.rb', 'test/**/*_spec.rb']
16
+ t.verbose = false
17
+ end
18
+
19
+ task :default => :test
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.join(File.dirname(__FILE__), '..'), File.join(File.dirname(__FILE__), '..','lib')
4
+ require 'jmeter/reports'
5
+
6
+ if ARGV[0] == nil || ARGV[0].empty?
7
+ puts "Usage: #{File.basename(__FILE__)} <report_file>"
8
+ exit 1
9
+ end
10
+
11
+ begin
12
+ report = Jmeter::SummaryReport::Report.create(ARGV[0])
13
+ puts "Test time: #{report.elapsed} secs"
14
+ puts "Average throughput: #{report.avg_throughput} RPS"
15
+ puts "Test plan:"
16
+ report.items.each do |item|
17
+ puts "\t#{item.text_summary}"
18
+ end
19
+ rescue Exception => e
20
+ puts e.message
21
+ exit 1
22
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "jmeter-reports"
7
+ gem.version = "0.0.1alpha"
8
+ gem.authors = ["Marcos Hack"]
9
+ gem.email = ["marcos.hack@gmail.com"]
10
+ gem.description = %q{JMeter Reports}
11
+ gem.summary = %q{Basic tools for JMeter reports processing.}
12
+ gem.homepage = "https://github.com/marcoshack/jmeter-reports"
13
+
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_development_dependency "rake"
20
+ gem.add_development_dependency "minitest", "~> 3"
21
+ end
@@ -0,0 +1,3 @@
1
+ require 'jmeter/summary_report/report'
2
+ require 'jmeter/summary_report/report_item'
3
+ require 'jmeter/summary_report/result_line'
@@ -0,0 +1,52 @@
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 = line.timestamp if @start.nil? || line.timestamp < @start
32
+ @end = line.timestamp if @end.nil? || line.timestamp > @end
33
+ end
34
+
35
+ def elapsed_in_ms
36
+ @end - @start
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
+ end
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ module Jmeter
2
+ module SummaryReport
3
+ class ReportItem
4
+ def initialize(label)
5
+ @label = label
6
+ @items = []
7
+ @error_count = 0
8
+ end
9
+
10
+ def add(item)
11
+ @error_count += 1 if item.error?
12
+ @items << item.elapsed
13
+ end
14
+
15
+ def size
16
+ @items.size
17
+ end
18
+
19
+ def errors
20
+ @error_count
21
+ end
22
+
23
+ def error_rate
24
+ @error_count / self.size.to_f
25
+ end
26
+
27
+ def text_summary
28
+ sorted_items = @items.sort
29
+ p90 = sorted_items[(self.size * 0.90).round]
30
+ p95 = sorted_items[(self.size * 0.95).round]
31
+ err_rate = round(self.error_rate, 3) * 100
32
+ "#{@label}: #{self.size}/#{self.errors} reqs/err(#{round(self.error_rate, 3)}%), " +
33
+ "90% <= #{p90}ms, 95% <= #{p95}ms"
34
+ end
35
+
36
+ private
37
+ def round(float_number, dec)
38
+ (float_number * 10**dec).to_i / (10**dec).to_f
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,32 @@
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
+ module Jmeter
12
+ module SummaryReport
13
+ class ResultLine
14
+ attr_accessor :timestamp, :elapsed, :label, :error, :latency
15
+
16
+ def self.parse(line)
17
+ t,e,l,rc,rm,_,_,s,_,_,_,_,lt = line.split(",")
18
+ res = Jmeter::SummaryReport::ResultLine.new
19
+ res.timestamp = t.to_i
20
+ res.elapsed = e.to_i
21
+ res.label = l
22
+ res.error = (s == "false" ? true : false)
23
+ res.latency = lt.to_i
24
+ return res
25
+ end
26
+
27
+ def error?
28
+ self.error
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,10 @@
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&current_instance_id=aiwwidgets&current_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&current_instance_id=aiwwidgets&current_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&current_instance_id=aiwwidgets&current_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472&provedores=facebook%2Ctwitter%2Cgoogle,64
5
+ 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&current_instance_id=aiwwidgets&current_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9390679&provedores=facebook%2Ctwitter%2Cgoogle,69
6
+ 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&current_instance_id=aiwwidgets&current_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=1773635&provedores=facebook%2Ctwitter%2Cgoogle,65
7
+ 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&current_instance_id=aiwwidgets&current_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=6634952&provedores=facebook%2Ctwitter%2Cgoogle,71
8
+ 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&current_instance_id=aiwwidgets&current_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=8134350&provedores=facebook%2Ctwitter%2Cgoogle,67
9
+ 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
10
+ 1355230054902,27,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&current_instance_id=aiwwidgets&current_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472,27
@@ -0,0 +1,2 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/colorize'
@@ -0,0 +1,25 @@
1
+ require File.expand_path('helper', File.dirname(__FILE__))
2
+ require 'jmeter/reports'
3
+
4
+ class TestSummaryReport < MiniTest::Unit::TestCase
5
+ def setup
6
+ fixture = File.expand_path('fixtures/summary_report.csv', File.dirname(__FILE__))
7
+ @report = Jmeter::SummaryReport::Report.create(fixture)
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
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jmeter-reports
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1alpha
5
+ prerelease: 5
6
+ platform: ruby
7
+ authors:
8
+ - Marcos Hack
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3'
46
+ description: JMeter Reports
47
+ email:
48
+ - marcos.hack@gmail.com
49
+ executables:
50
+ - jmeter-reports
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .travis.yml
56
+ - Gemfile
57
+ - Gemfile.lock
58
+ - LICENSE
59
+ - README.rdoc
60
+ - Rakefile
61
+ - bin/jmeter-reports
62
+ - jmeter-reports.gemspec
63
+ - lib/jmeter/reports.rb
64
+ - lib/jmeter/summary_report/report.rb
65
+ - lib/jmeter/summary_report/report_item.rb
66
+ - lib/jmeter/summary_report/result_line.rb
67
+ - test/fixtures/summary_report.csv
68
+ - test/helper.rb
69
+ - test/test_summary_report.rb
70
+ homepage: https://github.com/marcoshack/jmeter-reports
71
+ licenses: []
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>'
86
+ - !ruby/object:Gem::Version
87
+ version: 1.3.1
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.23
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Basic tools for JMeter reports processing.
94
+ test_files:
95
+ - test/fixtures/summary_report.csv
96
+ - test/helper.rb
97
+ - test/test_summary_report.rb
98
+ has_rdoc: