performance_tester 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/performance_tester/csv_logger.rb +55 -0
- data/lib/performance_tester/environment.rb +31 -0
- data/lib/performance_tester/outcome.rb +92 -0
- data/lib/performance_tester/puts_aggregate_logger.rb +30 -0
- data/lib/performance_tester/runner.rb +68 -0
- data/lib/performance_tester/scenario.rb +14 -0
- data/lib/performance_tester/version.rb +1 -1
- data/lib/performance_tester.rb +4 -205
- metadata +7 -1
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
module PerformanceTester
|
5
|
+
class CsvLogger
|
6
|
+
attr_reader :outcome, :path
|
7
|
+
|
8
|
+
def initialize(outcome, options = {})
|
9
|
+
@outcome = outcome
|
10
|
+
@path = options.fetch(:path) { 'performance_test.csv' }
|
11
|
+
end
|
12
|
+
|
13
|
+
def log
|
14
|
+
with_csv do |csv|
|
15
|
+
outcome.requests.each do |request|
|
16
|
+
csv << request_line(request)
|
17
|
+
end
|
18
|
+
csv << total_line
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def header_line
|
23
|
+
[
|
24
|
+
'Run datetime',
|
25
|
+
'Host alias',
|
26
|
+
'Path',
|
27
|
+
'Content type',
|
28
|
+
'Elapsed time'
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def request_line(request)
|
33
|
+
[
|
34
|
+
outcome.started_at,
|
35
|
+
request.host_alias,
|
36
|
+
request.path,
|
37
|
+
request.content_type,
|
38
|
+
request.time_elapsed
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
def total_line
|
43
|
+
[outcome.started_at, '', '', '', outcome.total_time_elapsed]
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_csv
|
47
|
+
append = File.exists?(path)
|
48
|
+
flags = append ? 'ab' : 'wb'
|
49
|
+
CSV.open(path, flags) do |csv|
|
50
|
+
csv << header_line unless append
|
51
|
+
yield csv
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "capybara"
|
3
|
+
require "capybara/poltergeist"
|
4
|
+
|
5
|
+
module PerformanceTester
|
6
|
+
# Describe an execution environment - server, credentials, etc.
|
7
|
+
class Environment
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = options
|
12
|
+
browser.run_server = false
|
13
|
+
browser.current_driver = :poltergeist
|
14
|
+
browser.register_driver :poltergeist do |app|
|
15
|
+
driver.new(app, :debug => false)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def hosts
|
20
|
+
options.fetch(:hosts) { {} }
|
21
|
+
end
|
22
|
+
|
23
|
+
def browser
|
24
|
+
options.fetch(:browser) { Capybara }
|
25
|
+
end
|
26
|
+
|
27
|
+
def driver
|
28
|
+
options.fetch(:driver) { Capybara::Poltergeist::Driver }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module PerformanceTester
|
5
|
+
# Documents the outcome of a scenario
|
6
|
+
class Outcome
|
7
|
+
attr_reader :requests, :error, :period
|
8
|
+
|
9
|
+
def initialize(network_traffic, period, hosts, error = false)
|
10
|
+
@requests = network_traffic.map { |request| Request.new(request, hosts) }
|
11
|
+
@period = period
|
12
|
+
@error = error
|
13
|
+
end
|
14
|
+
|
15
|
+
def total_time_elapsed
|
16
|
+
finished_at - started_at
|
17
|
+
end
|
18
|
+
|
19
|
+
def started_at
|
20
|
+
period.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def finished_at
|
24
|
+
period.last
|
25
|
+
end
|
26
|
+
|
27
|
+
def success?
|
28
|
+
!error
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
error ? error.to_s : requests.map(&:to_s).inspect
|
33
|
+
end
|
34
|
+
|
35
|
+
class Request
|
36
|
+
attr_reader :url, :request_time, :response, :host_aliases
|
37
|
+
|
38
|
+
def initialize(request, hosts)
|
39
|
+
@url = URI.parse(request.url)
|
40
|
+
@request_time = request.time
|
41
|
+
@response = parse_response(request.response_parts)
|
42
|
+
@host_aliases = hosts.invert
|
43
|
+
end
|
44
|
+
|
45
|
+
def host_alias
|
46
|
+
host_aliases.fetch(host) { host }
|
47
|
+
end
|
48
|
+
|
49
|
+
def host
|
50
|
+
url.host
|
51
|
+
end
|
52
|
+
|
53
|
+
def path
|
54
|
+
url.path
|
55
|
+
end
|
56
|
+
|
57
|
+
def time_elapsed
|
58
|
+
response_time - request_time
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
[host_alias, path, status, content_type, time_elapsed].inspect
|
63
|
+
end
|
64
|
+
|
65
|
+
def response_time
|
66
|
+
response.time
|
67
|
+
end
|
68
|
+
|
69
|
+
def status
|
70
|
+
response.status
|
71
|
+
end
|
72
|
+
|
73
|
+
def content_type
|
74
|
+
response.content_type
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse_response(response_parts)
|
78
|
+
if response_parts && !response_parts.empty?
|
79
|
+
response_parts.last
|
80
|
+
else
|
81
|
+
null_response
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def null_response
|
86
|
+
NullResponse.new(request_time, 0, '')
|
87
|
+
end
|
88
|
+
|
89
|
+
class NullResponse < Struct.new(:time, :status, :content_type); end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module PerformanceTester
|
4
|
+
class PutsAggregateLogger
|
5
|
+
attr_reader :outcome
|
6
|
+
|
7
|
+
def initialize(outcome)
|
8
|
+
@outcome = outcome
|
9
|
+
end
|
10
|
+
|
11
|
+
def log
|
12
|
+
puts "Success: #{outcome.success?}"
|
13
|
+
puts "Number of requests: #{number_of_requests}"
|
14
|
+
puts "Sum of request times: #{sprintf("%.02f", sum_of_times_of_all_requests)}"
|
15
|
+
puts "Total time elapsed: #{sprintf("%.02f", total_time_elapsed)}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def total_time_elapsed
|
19
|
+
outcome.total_time_elapsed
|
20
|
+
end
|
21
|
+
|
22
|
+
def number_of_requests
|
23
|
+
outcome.requests.length
|
24
|
+
end
|
25
|
+
|
26
|
+
def sum_of_times_of_all_requests
|
27
|
+
outcome.requests.map(&:time_elapsed).reduce(&:+)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'capybara'
|
3
|
+
require 'capybara/dsl'
|
4
|
+
require 'performance_tester/outcome'
|
5
|
+
require 'performance_tester/puts_aggregate_logger'
|
6
|
+
require 'performance_tester/csv_logger'
|
7
|
+
|
8
|
+
module PerformanceTester
|
9
|
+
# Executes a scenario in an environment and creates outcomes
|
10
|
+
class Runner
|
11
|
+
include Capybara::DSL
|
12
|
+
|
13
|
+
attr_reader :environment, :options
|
14
|
+
|
15
|
+
def initialize(environment, options = {})
|
16
|
+
@environment = environment
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(scenario)
|
21
|
+
start = time_now
|
22
|
+
begin
|
23
|
+
instance_eval(&scenario)
|
24
|
+
rescue => error
|
25
|
+
end
|
26
|
+
stop = time_now
|
27
|
+
period = (start .. stop)
|
28
|
+
outcome = create_outcome(period, error)
|
29
|
+
log_outcome(outcome)
|
30
|
+
outcome
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_outcome(period, error)
|
34
|
+
network_traffic = page.driver.network_traffic
|
35
|
+
outcome.new(network_traffic, period, hosts, error)
|
36
|
+
end
|
37
|
+
|
38
|
+
def outcome
|
39
|
+
options.fetch(:outcome) { Outcome }
|
40
|
+
end
|
41
|
+
|
42
|
+
def log_outcome(outcome)
|
43
|
+
loggers.each do |logger|
|
44
|
+
logger.new(outcome).log
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def loggers
|
49
|
+
options.fetch(:loggers) { [PutsAggregateLogger, CsvLogger] }
|
50
|
+
end
|
51
|
+
|
52
|
+
def time_now
|
53
|
+
clock.now
|
54
|
+
end
|
55
|
+
|
56
|
+
def clock
|
57
|
+
options.fetch(:clock) { Time }
|
58
|
+
end
|
59
|
+
|
60
|
+
def env
|
61
|
+
environment.options
|
62
|
+
end
|
63
|
+
|
64
|
+
def hosts
|
65
|
+
environment.hosts
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/performance_tester.rb
CHANGED
@@ -1,206 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require "delegate"
|
7
|
-
|
8
|
-
module PerformanceTester
|
9
|
-
# Describe an execution environment - server, credentials, etc.
|
10
|
-
class Environment
|
11
|
-
attr_reader :options
|
12
|
-
|
13
|
-
def initialize(options = {})
|
14
|
-
@options = options
|
15
|
-
browser.run_server = false
|
16
|
-
browser.current_driver = :poltergeist
|
17
|
-
browser.register_driver :poltergeist do |app|
|
18
|
-
driver.new(app, :debug => false)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def hosts
|
23
|
-
options.fetch(:hosts) { {} }
|
24
|
-
end
|
25
|
-
|
26
|
-
def browser
|
27
|
-
options.fetch(:browser) { Capybara }
|
28
|
-
end
|
29
|
-
|
30
|
-
def driver
|
31
|
-
options.fetch(:driver) { Capybara::Poltergeist::Driver }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Describes a sequence of browser actions
|
36
|
-
class Scenario
|
37
|
-
def initialize(&block)
|
38
|
-
@block = block
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_proc
|
42
|
-
@block
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Executes a scenario in an environment and creates outcomes
|
47
|
-
class Runner
|
48
|
-
include Capybara::DSL
|
49
|
-
|
50
|
-
attr_reader :environment, :options
|
51
|
-
|
52
|
-
def initialize(environment, options = {})
|
53
|
-
@environment = environment
|
54
|
-
@options = options
|
55
|
-
end
|
56
|
-
|
57
|
-
def run(scenario)
|
58
|
-
start = time_now
|
59
|
-
begin
|
60
|
-
instance_eval(&scenario)
|
61
|
-
rescue => error
|
62
|
-
end
|
63
|
-
stop = time_now
|
64
|
-
outcome = create_outcome(start, stop, error)
|
65
|
-
log_outcome(outcome)
|
66
|
-
outcome
|
67
|
-
end
|
68
|
-
|
69
|
-
def create_outcome(start, stop, error)
|
70
|
-
network_traffic = page.driver.network_traffic
|
71
|
-
total_time_elapsed = stop - start
|
72
|
-
outcome.new(network_traffic, total_time_elapsed, hosts, error)
|
73
|
-
end
|
74
|
-
|
75
|
-
def outcome
|
76
|
-
options.fetch(:outcome) { Outcome }
|
77
|
-
end
|
78
|
-
|
79
|
-
def log_outcome(outcome)
|
80
|
-
logger.new(outcome).log
|
81
|
-
end
|
82
|
-
|
83
|
-
def logger
|
84
|
-
options.fetch(:logger) { PutsAggregateLogger }
|
85
|
-
end
|
86
|
-
|
87
|
-
def time_now
|
88
|
-
clock.now
|
89
|
-
end
|
90
|
-
|
91
|
-
def clock
|
92
|
-
options.fetch(:clock) { Time }
|
93
|
-
end
|
94
|
-
|
95
|
-
def env
|
96
|
-
environment.options
|
97
|
-
end
|
98
|
-
|
99
|
-
def hosts
|
100
|
-
environment.hosts
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
class PutsAggregateLogger
|
105
|
-
attr_reader :outcome
|
106
|
-
|
107
|
-
def initialize(outcome)
|
108
|
-
@outcome = outcome
|
109
|
-
end
|
110
|
-
|
111
|
-
def log
|
112
|
-
puts "Success: #{outcome.success?}"
|
113
|
-
puts "Number of requests: #{number_of_requests}"
|
114
|
-
puts "Sum of request times: #{sprintf("%.02f", sum_of_times_of_all_requests)}"
|
115
|
-
puts "Total time elapsed: #{sprintf("%.02f", total_time_elapsed)}"
|
116
|
-
end
|
117
|
-
|
118
|
-
def total_time_elapsed
|
119
|
-
outcome.total_time_elapsed
|
120
|
-
end
|
121
|
-
|
122
|
-
def number_of_requests
|
123
|
-
outcome.requests.length
|
124
|
-
end
|
125
|
-
|
126
|
-
def sum_of_times_of_all_requests
|
127
|
-
outcome.requests.map(&:time_elapsed).reduce(&:+)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Documents the outcome of a scenario
|
132
|
-
class Outcome
|
133
|
-
attr_reader :requests, :error, :total_time_elapsed
|
134
|
-
|
135
|
-
def initialize(network_traffic, total_time_elapsed, hosts, error = false)
|
136
|
-
@requests = network_traffic.map { |request| Request.new(request, hosts) }
|
137
|
-
@total_time_elapsed = total_time_elapsed
|
138
|
-
@error = error
|
139
|
-
end
|
140
|
-
|
141
|
-
def success?
|
142
|
-
!error
|
143
|
-
end
|
144
|
-
|
145
|
-
def to_s
|
146
|
-
error ? error.to_s : requests.map(&:to_s).inspect
|
147
|
-
end
|
148
|
-
|
149
|
-
class Request
|
150
|
-
attr_reader :url, :request_time, :response, :host_aliases
|
151
|
-
|
152
|
-
def initialize(request, hosts)
|
153
|
-
@url = URI.parse(request.url)
|
154
|
-
@request_time = request.time
|
155
|
-
@response = parse_response(request.response_parts)
|
156
|
-
@host_aliases = hosts.invert
|
157
|
-
end
|
158
|
-
|
159
|
-
def host_alias
|
160
|
-
host_aliases.fetch(host) { host }
|
161
|
-
end
|
162
|
-
|
163
|
-
def host
|
164
|
-
url.host
|
165
|
-
end
|
166
|
-
|
167
|
-
def path
|
168
|
-
url.path
|
169
|
-
end
|
170
|
-
|
171
|
-
def time_elapsed
|
172
|
-
response_time - request_time
|
173
|
-
end
|
174
|
-
|
175
|
-
def to_s
|
176
|
-
[host_alias, path, status, content_type, time_elapsed].inspect
|
177
|
-
end
|
178
|
-
|
179
|
-
def response_time
|
180
|
-
response.time
|
181
|
-
end
|
182
|
-
|
183
|
-
def status
|
184
|
-
response.status
|
185
|
-
end
|
186
|
-
|
187
|
-
def content_type
|
188
|
-
response.content_type
|
189
|
-
end
|
190
|
-
|
191
|
-
def parse_response(response_parts)
|
192
|
-
if response_parts && !response_parts.empty?
|
193
|
-
response_parts.last
|
194
|
-
else
|
195
|
-
null_response
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def null_response
|
200
|
-
NullResponse.new(request_time, 0, '')
|
201
|
-
end
|
202
|
-
|
203
|
-
class NullResponse < Struct.new(:time, :status, :content_type); end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
2
|
+
require 'performance_tester/environment'
|
3
|
+
require 'performance_tester/runner'
|
4
|
+
require 'performance_tester/scenario'
|
5
|
+
require 'performance_tester/version'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: performance_tester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -40,6 +40,12 @@ files:
|
|
40
40
|
- README.md
|
41
41
|
- Rakefile
|
42
42
|
- lib/performance_tester.rb
|
43
|
+
- lib/performance_tester/csv_logger.rb
|
44
|
+
- lib/performance_tester/environment.rb
|
45
|
+
- lib/performance_tester/outcome.rb
|
46
|
+
- lib/performance_tester/puts_aggregate_logger.rb
|
47
|
+
- lib/performance_tester/runner.rb
|
48
|
+
- lib/performance_tester/scenario.rb
|
43
49
|
- lib/performance_tester/version.rb
|
44
50
|
- performance_tester.gemspec
|
45
51
|
homepage: ''
|