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.
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +15 -0
- data/LICENSE +13 -0
- data/README.rdoc +10 -0
- data/Rakefile +19 -0
- data/bin/jmeter-reports +22 -0
- data/jmeter-reports.gemspec +21 -0
- data/lib/jmeter/reports.rb +3 -0
- data/lib/jmeter/summary_report/report.rb +52 -0
- data/lib/jmeter/summary_report/report_item.rb +42 -0
- data/lib/jmeter/summary_report/result_line.rb +32 -0
- data/test/fixtures/summary_report.csv +10 -0
- data/test/helper.rb +2 -0
- data/test/test_summary_report.rb +25 -0
- metadata +98 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
jmeter-reports*.gem
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
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.
|
data/README.rdoc
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
data/bin/jmeter-reports
ADDED
@@ -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,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¤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
|
+
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
|
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¤t_instance_id=aiwwidgets¤t_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¤t_instance_id=aiwwidgets¤t_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¤t_instance_id=aiwwidgets¤t_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¤t_instance_id=aiwwidgets¤t_box_id=abril-id-load_test-login&confirmation_url=http://example.com/&_=9723472,27
|
data/test/helper.rb
ADDED
@@ -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:
|