autograph 0.2.0 → 0.3.0
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 +2 -0
- data/README.rdoc +2 -44
- data/Rakefile +1 -5
- data/TODO +12 -16
- data/VERSION +1 -1
- data/bin/autograph +2 -11
- data/lib/autograph.rb +3 -7
- data/lib/autograph/autoperf.rb +32 -27
- data/lib/autograph/configuration.rb +3 -9
- data/lib/autograph/graph.rb +9 -0
- data/lib/autograph/graph_series.rb +2 -4
- data/lib/autograph/html_report.rb +0 -3
- data/lib/autograph/report.html.erb +251 -166
- data/lib/autograph/table.rb +66 -0
- data/test/test_configuration.rb +0 -5
- data/test/test_graph.rb +17 -0
- data/test/test_graph_series.rb +6 -10
- data/test/test_table.rb +131 -0
- metadata +11 -65
- data/lib/autograph/graph_renderers/base_renderer.rb +0 -82
- data/lib/autograph/graph_renderers/flot_renderer.rb +0 -50
- data/lib/autograph/graph_renderers/gchart_renderer.rb +0 -82
- data/lib/autograph/graph_renderers/rasterized_scruffy_renderer.rb +0 -20
- data/lib/autograph/graph_renderers/scruffy_renderer.rb +0 -35
@@ -0,0 +1,66 @@
|
|
1
|
+
class Table
|
2
|
+
attr :rows
|
3
|
+
|
4
|
+
def initialize(column_names)
|
5
|
+
@column_names = column_names.map{|n| n.to_s.to_sym}
|
6
|
+
@rows = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def column(name)
|
10
|
+
@rows.map{|r| r[name.to_s.to_sym]}
|
11
|
+
end
|
12
|
+
|
13
|
+
def max(name)
|
14
|
+
@rows.map{|r| r[name.to_s.to_sym].to_i}.max
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(row_hash)
|
18
|
+
# Symbolize keys on the way in
|
19
|
+
@rows << row_hash.inject({}){|x,y| x[y[0].to_s.to_sym] = y[1]; x}
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_html
|
23
|
+
html = "<table>\n";
|
24
|
+
html << " <tr>\n"
|
25
|
+
@column_names.each do |key|
|
26
|
+
html << " <th>#{key}</th>\n"
|
27
|
+
end
|
28
|
+
html << " </tr>\n"
|
29
|
+
rows.each do |r|
|
30
|
+
html << " <tr>\n"
|
31
|
+
@column_names.each do |key|
|
32
|
+
html << " <td>#{r[key]}</td>\n"
|
33
|
+
end
|
34
|
+
html << " </tr>\n"
|
35
|
+
end
|
36
|
+
html << "</table>\n"
|
37
|
+
html
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
width = 20
|
42
|
+
s = ""
|
43
|
+
html = "-"
|
44
|
+
html << "-"*@column_names.size*width;
|
45
|
+
html << "\n"
|
46
|
+
html << "|"
|
47
|
+
@column_names.each do |key|
|
48
|
+
html << sprintf("%#{width-2}s", key)
|
49
|
+
html << " |"
|
50
|
+
end
|
51
|
+
html << "\n"
|
52
|
+
html << "-"
|
53
|
+
html << "-"*@column_names.size*width;
|
54
|
+
html << "\n"
|
55
|
+
rows.each do |r|
|
56
|
+
html << "|"
|
57
|
+
@column_names.each do |key|
|
58
|
+
html << "#{sprintf("%#{width-2}s", r[key.to_sym])} |"
|
59
|
+
end
|
60
|
+
html << "\n"
|
61
|
+
end
|
62
|
+
html << "-"
|
63
|
+
html <<"-"*@column_names.size*width;
|
64
|
+
html
|
65
|
+
end
|
66
|
+
end
|
data/test/test_configuration.rb
CHANGED
@@ -17,11 +17,6 @@ class TestHtmlReport < Test::Unit::TestCase
|
|
17
17
|
assert_equal c['low_rate'], 1
|
18
18
|
end
|
19
19
|
|
20
|
-
def test_graph_render_klazz_helper
|
21
|
-
c = Configuration.new()
|
22
|
-
assert_equal c.graph_renderer_class, GChartRenderer
|
23
|
-
end
|
24
|
-
|
25
20
|
def test_pretty_print_returns_a_string
|
26
21
|
c = Configuration.new().pretty_print
|
27
22
|
assert_equal c.class, String
|
data/test/test_graph.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestGraphSeries < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_title
|
8
|
+
title = "Some Title"
|
9
|
+
g = Graph.new(:title => title)
|
10
|
+
assert_equal g.title, title
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_series_is_empty_by_default
|
14
|
+
g = Graph.new()
|
15
|
+
assert_equal g.series, []
|
16
|
+
end
|
17
|
+
end
|
data/test/test_graph_series.rb
CHANGED
@@ -1,28 +1,24 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
2
|
|
3
3
|
class TestGraphSeries < Test::Unit::TestCase
|
4
|
-
require 'mocha'
|
5
|
-
require 'autograph'
|
6
|
-
|
7
4
|
def setup
|
8
5
|
end
|
9
|
-
|
6
|
+
|
10
7
|
def test_constructor
|
11
8
|
x_values = [1,2,3]
|
12
9
|
y_values = [4,5,6]
|
13
|
-
|
14
|
-
gs = GraphSeries.new(
|
15
|
-
assert_equal(gs.type, :type)
|
10
|
+
|
11
|
+
gs = GraphSeries.new(x_values, y_values, 'label')
|
16
12
|
assert_equal(gs.x_values, x_values)
|
17
13
|
assert_equal(gs.y_values, y_values)
|
18
14
|
assert_equal(gs.label, 'label')
|
19
15
|
end
|
20
|
-
|
16
|
+
|
21
17
|
def test_constructor_converts_to_floats
|
22
18
|
x_values = [1,2,3]
|
23
19
|
y_values = [4,5,6]
|
24
|
-
|
25
|
-
gs = GraphSeries.new(
|
20
|
+
|
21
|
+
gs = GraphSeries.new(x_values, y_values, 'label')
|
26
22
|
gs.y_values.each{|y| assert_equal(y.class, Float) }
|
27
23
|
gs.x_values.each{|x| assert_equal(x.class, Float) }
|
28
24
|
end
|
data/test/test_table.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestGraphSeries < Test::Unit::TestCase
|
4
|
+
COLUMN_NAMES = [:column_a, :column_b]
|
5
|
+
|
6
|
+
def setup
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_column_returns_array
|
10
|
+
assert_equal Table.new(COLUMN_NAMES).column(:some_key).class, Array
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_column_returns_empty_array_by_default
|
14
|
+
assert_equal Table.new(COLUMN_NAMES).column(:some_key).size, 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_column_with_multiple_rows
|
18
|
+
one = {:column_a => 1, :column_b => 222}
|
19
|
+
two = {:column_a => 11, :column_b => 22}
|
20
|
+
three = {:column_a => 111, :column_b => 2}
|
21
|
+
t = Table.new(COLUMN_NAMES)
|
22
|
+
t << one
|
23
|
+
t << two
|
24
|
+
t << three
|
25
|
+
assert_equal t.column(:column_a), [1,11,111]
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_column_with_string_keys
|
29
|
+
one = {:column_b => 2}
|
30
|
+
two = {'column_b' => 222}
|
31
|
+
t = Table.new(COLUMN_NAMES)
|
32
|
+
t << one
|
33
|
+
t << two
|
34
|
+
assert_equal t.column(:column_b), [2,222]
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_column_with_string_key
|
38
|
+
one = {:column_b => 2}
|
39
|
+
two = {'column_b' => 222}
|
40
|
+
t = Table.new(COLUMN_NAMES)
|
41
|
+
t << one
|
42
|
+
t << two
|
43
|
+
assert_equal t.column("column_b"), [2,222]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_max
|
47
|
+
zero = {:column_b => 1}
|
48
|
+
one = {:column_b => 2}
|
49
|
+
two = {'column_b' => 222}
|
50
|
+
t = Table.new(COLUMN_NAMES)
|
51
|
+
t << one
|
52
|
+
t << two
|
53
|
+
assert_equal t.max("column_b"), 222
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_to_html_returns_string
|
57
|
+
assert_equal Table.new(COLUMN_NAMES).to_html.class, String
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_to_html_header
|
61
|
+
html = Table.new(COLUMN_NAMES).to_html
|
62
|
+
assert html.match(Regexp.new(COLUMN_NAMES.join(".*"), Regexp::MULTILINE))
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def test_to_html_contains_correct_tds
|
67
|
+
t = Table.new(COLUMN_NAMES)
|
68
|
+
t << {:column_a => 1, :column_b => 222}
|
69
|
+
t << {:column_a => 111, :column_b => 2}
|
70
|
+
assert t.to_html.match(/<td>1<\/td>/)
|
71
|
+
assert t.to_html.match(/<td>111<\/td>/)
|
72
|
+
assert t.to_html.match(/<td>2<\/td>/)
|
73
|
+
assert t.to_html.match(/<td>222<\/td>/)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_adding_rows
|
77
|
+
t = Table.new(COLUMN_NAMES)
|
78
|
+
t << {:column_a => 1, :column_b => 2}
|
79
|
+
assert_equal t.column(:column_a).size, 1
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_adding_rows_with_missing_key_adds_nil_value
|
83
|
+
t = Table.new(COLUMN_NAMES)
|
84
|
+
t << {:column_a => 1, :column_b => 2}
|
85
|
+
assert_equal t.column(:c).size, 1
|
86
|
+
assert_equal t.column(:c).first, nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_multiple_rows_are_ordered
|
90
|
+
one = {:column_a => 1, :column_b => 222}
|
91
|
+
two = {:column_a => 11, :column_b => 22}
|
92
|
+
three = {:column_a => 111, :column_b => 2}
|
93
|
+
t = Table.new(COLUMN_NAMES)
|
94
|
+
t << one
|
95
|
+
t << two
|
96
|
+
t << three
|
97
|
+
assert_equal t.rows[0], one
|
98
|
+
assert_equal t.rows[1], two
|
99
|
+
assert_equal t.rows[2], three
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_to_s
|
103
|
+
tables = []
|
104
|
+
one = {:column_a => 1, :column_b => 222}
|
105
|
+
two = {:column_a => 11, :column_b => 22}
|
106
|
+
three = {:column_a => 111, :column_b => 2}
|
107
|
+
t = Table.new(COLUMN_NAMES)
|
108
|
+
t << one
|
109
|
+
t << two
|
110
|
+
t << three
|
111
|
+
tables << t
|
112
|
+
one = {:column_a => 1, :column_b => 222, :col_c => 1222}
|
113
|
+
two = {:column_a => 11, :column_b => 22}
|
114
|
+
three = {:column_a => 111, :column_b => 2}
|
115
|
+
t = Table.new([COLUMN_NAMES, [:col_c]].flatten)
|
116
|
+
t << one
|
117
|
+
t << two
|
118
|
+
t << three
|
119
|
+
tables << t
|
120
|
+
tables.each do |table|
|
121
|
+
# puts
|
122
|
+
# puts table.to_s
|
123
|
+
length = nil
|
124
|
+
assert table.to_s.split("\n").size > 3
|
125
|
+
table.to_s.split("\n").each do |l|
|
126
|
+
assert_equal length, l.length if length
|
127
|
+
length = l.length
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nick Stielau
|
@@ -14,65 +14,10 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-29 00:00:00 -07:00
|
18
18
|
default_executable: autograph
|
19
|
-
dependencies:
|
20
|
-
|
21
|
-
name: builder
|
22
|
-
prerelease: false
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - "="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 2
|
29
|
-
- 1
|
30
|
-
- 2
|
31
|
-
version: 2.1.2
|
32
|
-
type: :runtime
|
33
|
-
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: ruport
|
36
|
-
prerelease: false
|
37
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - "="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 1
|
43
|
-
- 6
|
44
|
-
- 3
|
45
|
-
version: 1.6.3
|
46
|
-
type: :runtime
|
47
|
-
version_requirements: *id002
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: scruffy
|
50
|
-
prerelease: false
|
51
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - "="
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
segments:
|
56
|
-
- 0
|
57
|
-
- 2
|
58
|
-
- 5
|
59
|
-
version: 0.2.5
|
60
|
-
type: :runtime
|
61
|
-
version_requirements: *id003
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: gchart
|
64
|
-
prerelease: false
|
65
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - "="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
segments:
|
70
|
-
- 1
|
71
|
-
- 0
|
72
|
-
- 0
|
73
|
-
version: 1.0.0
|
74
|
-
type: :runtime
|
75
|
-
version_requirements: *id004
|
19
|
+
dependencies: []
|
20
|
+
|
76
21
|
description: Autograph wraps httperf, running multiple tests while varying the parameters, graphing the output.
|
77
22
|
email: nick.stielau@gmail.com
|
78
23
|
executables:
|
@@ -93,23 +38,22 @@ files:
|
|
93
38
|
- lib/autograph.rb
|
94
39
|
- lib/autograph/autoperf.rb
|
95
40
|
- lib/autograph/configuration.rb
|
96
|
-
- lib/autograph/
|
97
|
-
- lib/autograph/graph_renderers/flot_renderer.rb
|
98
|
-
- lib/autograph/graph_renderers/gchart_renderer.rb
|
99
|
-
- lib/autograph/graph_renderers/rasterized_scruffy_renderer.rb
|
100
|
-
- lib/autograph/graph_renderers/scruffy_renderer.rb
|
41
|
+
- lib/autograph/graph.rb
|
101
42
|
- lib/autograph/graph_series.rb
|
102
43
|
- lib/autograph/html_report.rb
|
103
44
|
- lib/autograph/report.html.erb
|
45
|
+
- lib/autograph/table.rb
|
104
46
|
- load_test_report_example.html
|
105
47
|
- script/console
|
106
48
|
- script/destroy
|
107
49
|
- script/generate
|
108
50
|
- test/test_autograph.rb
|
109
51
|
- test/test_configuration.rb
|
52
|
+
- test/test_graph.rb
|
110
53
|
- test/test_graph_series.rb
|
111
54
|
- test/test_helper.rb
|
112
55
|
- test/test_html_report.rb
|
56
|
+
- test/test_table.rb
|
113
57
|
has_rdoc: true
|
114
58
|
homepage: http://github.com/nstielau/autograph
|
115
59
|
licenses: []
|
@@ -143,6 +87,8 @@ summary: Simple httperf runner with nice html reports with graphs.
|
|
143
87
|
test_files:
|
144
88
|
- test/test_autograph.rb
|
145
89
|
- test/test_configuration.rb
|
90
|
+
- test/test_graph.rb
|
146
91
|
- test/test_graph_series.rb
|
147
92
|
- test/test_helper.rb
|
148
93
|
- test/test_html_report.rb
|
94
|
+
- test/test_table.rb
|
@@ -1,82 +0,0 @@
|
|
1
|
-
class BaseRenderer
|
2
|
-
attr :title, true
|
3
|
-
attr :width, true
|
4
|
-
attr :height, true
|
5
|
-
attr :path, true
|
6
|
-
attr :series
|
7
|
-
|
8
|
-
AVAILABLE_GRAPH_RENDERERS = %W(ScruffyRenderer GChartRenderer)
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
@series = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def add_series(new_series)
|
15
|
-
series.push(new_series)
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_html
|
19
|
-
return "DATA"
|
20
|
-
end
|
21
|
-
|
22
|
-
def find_max_y_value
|
23
|
-
series.map{|s| s.y_values.max}.max
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.header_html
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.generate_graphs(reports, configuration)
|
30
|
-
graphs = {}
|
31
|
-
reports.each do |uri, report|
|
32
|
-
graphs[uri] = []
|
33
|
-
|
34
|
-
puts "For '#{uri}' the values are #{report.column('reply time').join(', ')}" if configuration['verbose']
|
35
|
-
request_rate_graph = configuration.graph_renderer_class.new
|
36
|
-
request_rate_graph.title = "Demanded vs. Achieved Request Rate (r/s)"
|
37
|
-
request_rate_graph.path = uri
|
38
|
-
request_rate_graph.width = 600
|
39
|
-
request_rate_graph.height = 300
|
40
|
-
|
41
|
-
if reports['Avg']
|
42
|
-
avg_request_rate = GraphSeries.new(:area, report.column('rate'), reports['Avg'].column('conn/s').map{|x| x.to_f}, "Avg")
|
43
|
-
request_rate_graph.add_series(avg_request_rate)
|
44
|
-
end
|
45
|
-
|
46
|
-
request_rate = GraphSeries.new(:line, report.column('rate'), report.column('conn/s').map{|x| x.to_f}, "Requests for '#{uri}'")
|
47
|
-
request_rate_graph.add_series(request_rate)
|
48
|
-
|
49
|
-
graphs[uri] << request_rate_graph
|
50
|
-
|
51
|
-
response_time_graph = configuration.graph_renderer_class.new
|
52
|
-
response_time_graph.path = uri
|
53
|
-
response_time_graph.title = "Demanded Request Rate (r/s) vs. Response Time"
|
54
|
-
response_time_graph.width = 600
|
55
|
-
response_time_graph.height = 300
|
56
|
-
|
57
|
-
if reports['Avg']
|
58
|
-
avg_response_time = GraphSeries.new(:area, report.column('rate'), reports['Avg'].column('reply time').map{|x| x.to_f}, "Avg")
|
59
|
-
response_time_graph.add_series(avg_response_time)
|
60
|
-
end
|
61
|
-
|
62
|
-
response_time = GraphSeries.new(:line, report.column('rate'), report.column('reply time'), "Requests for '#{uri}'")
|
63
|
-
response_time_graph.add_series(response_time)
|
64
|
-
|
65
|
-
graphs[uri] << response_time_graph
|
66
|
-
end
|
67
|
-
|
68
|
-
max_rate_graph = configuration.graph_renderer_class.new
|
69
|
-
max_rate_graph.title = "Max Achieved Connection Rate"
|
70
|
-
max_rate_graph.width = 600
|
71
|
-
max_rate_graph.height = 300
|
72
|
-
|
73
|
-
reports.keys.each do |key|
|
74
|
-
max = reports[key].column('conn/s').map{|x| x.to_i}.max.to_i
|
75
|
-
max_request_rate = GraphSeries.new(:bar, [key], [max], "Max Request Rate for '#{key}'")
|
76
|
-
max_rate_graph.add_series(max_request_rate)
|
77
|
-
end
|
78
|
-
|
79
|
-
graphs['summary_graph'] = max_rate_graph
|
80
|
-
graphs
|
81
|
-
end
|
82
|
-
end
|