computron 0.1.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/.bundle/config +2 -0
- data/.document +5 -0
- data/.gitignore +21 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +13 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/bin/computron +15 -0
- data/computron.gemspec +76 -0
- data/lib/computron/client.rb +186 -0
- data/lib/computron/dsl.rb +47 -0
- data/lib/computron/report.rb +48 -0
- data/lib/computron.rb +5 -0
- data/spec/computron_spec.rb +7 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- data/test.rb +34 -0
- metadata +147 -0
data/.bundle/config
ADDED
data/.document
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Brad Gessler
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
= computron
|
2
|
+
|
3
|
+
Computron is like ab on steroids, implemented in Ruby using em-http-request. It was designed out of a need to simulate real users on a website. It also does a few smart things like decode JSON into a Ruby hash so you can use those responses in your next requests.
|
4
|
+
|
5
|
+
= The DSL
|
6
|
+
|
7
|
+
Computron is a simple DLS around HTTP em that makes more sense to write user tests.
|
8
|
+
|
9
|
+
= Report Summary
|
10
|
+
|
11
|
+
== Copyright
|
12
|
+
|
13
|
+
Copyright (c) 2010 Brad Gessler. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "computron"
|
8
|
+
gem.summary = %Q{An evented HTTP computron}
|
9
|
+
gem.description = %Q{Computron was created to help Poll Everywhere peform load tests that simulate how real users work.}
|
10
|
+
gem.email = "brad@bradgessler.com"
|
11
|
+
gem.homepage = "http://github.com/bradgessler/computron"
|
12
|
+
gem.authors = ["Brad Gessler"]
|
13
|
+
gem.add_dependency "eventmachine", ">= 0.12.10"
|
14
|
+
gem.add_dependency "em-http-request", ">= 0.2.7"
|
15
|
+
gem.add_dependency "colored", ">= 1.1"
|
16
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
17
|
+
gem.add_development_dependency "yard", ">= 0"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
34
|
+
spec.rcov = true
|
35
|
+
end
|
36
|
+
|
37
|
+
task :spec => :check_dependencies
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
begin
|
42
|
+
require 'yard'
|
43
|
+
YARD::Rake::YardocTask.new
|
44
|
+
rescue LoadError
|
45
|
+
task :yardoc do
|
46
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
47
|
+
end
|
48
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/computron
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
computron_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
$LOAD_PATH.unshift(computron_dir) unless $LOAD_PATH.include?(computron_dir)
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'computron'
|
8
|
+
|
9
|
+
simulation = Computron::DSL.new(File.read(ARGV.last))
|
10
|
+
|
11
|
+
Signal.trap('INT'){
|
12
|
+
EM.stop
|
13
|
+
}
|
14
|
+
|
15
|
+
simulation.run!
|
data/computron.gemspec
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{computron}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Brad Gessler"]
|
12
|
+
s.date = %q{2010-05-24}
|
13
|
+
s.default_executable = %q{computron}
|
14
|
+
s.description = %q{Computron was created to help Poll Everywhere peform load tests that simulate how real users work.}
|
15
|
+
s.email = %q{brad@bradgessler.com}
|
16
|
+
s.executables = ["computron"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".bundle/config",
|
23
|
+
".document",
|
24
|
+
".gitignore",
|
25
|
+
"Gemfile",
|
26
|
+
"LICENSE",
|
27
|
+
"README.rdoc",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"bin/computron",
|
31
|
+
"computron.gemspec",
|
32
|
+
"lib/computron.rb",
|
33
|
+
"lib/computron/client.rb",
|
34
|
+
"lib/computron/dsl.rb",
|
35
|
+
"lib/computron/report.rb",
|
36
|
+
"spec/computron_spec.rb",
|
37
|
+
"spec/spec.opts",
|
38
|
+
"spec/spec_helper.rb",
|
39
|
+
"test.rb"
|
40
|
+
]
|
41
|
+
s.homepage = %q{http://github.com/bradgessler/computron}
|
42
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = %q{1.3.6}
|
45
|
+
s.summary = %q{An evented HTTP computron}
|
46
|
+
s.test_files = [
|
47
|
+
"spec/computron_spec.rb",
|
48
|
+
"spec/spec_helper.rb"
|
49
|
+
]
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
53
|
+
s.specification_version = 3
|
54
|
+
|
55
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
56
|
+
s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
|
57
|
+
s.add_runtime_dependency(%q<em-http-request>, [">= 0.2.7"])
|
58
|
+
s.add_runtime_dependency(%q<colored>, [">= 1.1"])
|
59
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
60
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
63
|
+
s.add_dependency(%q<em-http-request>, [">= 0.2.7"])
|
64
|
+
s.add_dependency(%q<colored>, [">= 1.1"])
|
65
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
66
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
67
|
+
end
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
70
|
+
s.add_dependency(%q<em-http-request>, [">= 0.2.7"])
|
71
|
+
s.add_dependency(%q<colored>, [">= 1.1"])
|
72
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
73
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'em-http'
|
4
|
+
require 'colored'
|
5
|
+
|
6
|
+
module Computron
|
7
|
+
class Client
|
8
|
+
class Response
|
9
|
+
|
10
|
+
attr_reader :status
|
11
|
+
|
12
|
+
def initialize(opts={})
|
13
|
+
@status = {}
|
14
|
+
yield self if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(http)
|
18
|
+
if callback = status[http.response_header.status]
|
19
|
+
callback.call(decode_response(http))
|
20
|
+
end
|
21
|
+
@finished.call if @finished
|
22
|
+
end
|
23
|
+
|
24
|
+
# A shortcut for specifying a callback on an HTTP code if you don't know the status name.
|
25
|
+
def code(code, &block)
|
26
|
+
status[code] = block
|
27
|
+
end
|
28
|
+
|
29
|
+
# Runs after every HTTP request
|
30
|
+
def finished(&block)
|
31
|
+
@finished = block
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a hash containing the response code to the status like {200 => ok}.
|
35
|
+
def self.http_status_codes
|
36
|
+
@http_status_codes ||= %(100 continue
|
37
|
+
101 switching_protocols
|
38
|
+
200 ok
|
39
|
+
201 created
|
40
|
+
202 accepted
|
41
|
+
203 non_authoritive_information
|
42
|
+
204 no_content
|
43
|
+
205 reset_content
|
44
|
+
206 partial_content
|
45
|
+
300 multiple_choices
|
46
|
+
301 moved_permanently
|
47
|
+
302 found
|
48
|
+
303 see_other
|
49
|
+
304 not_modified
|
50
|
+
305 use_proxy
|
51
|
+
307 temporary_redirect
|
52
|
+
400 bad_request
|
53
|
+
401 unauthorized
|
54
|
+
402 payment_required
|
55
|
+
403 forbidden
|
56
|
+
404 not_found
|
57
|
+
405 method_not_allowed
|
58
|
+
406 not_acceptable
|
59
|
+
407 proxy_authentication_required
|
60
|
+
408 request_timeout
|
61
|
+
409 conflict
|
62
|
+
410 gone
|
63
|
+
411 length_required
|
64
|
+
412 precondition_failed
|
65
|
+
413 request_entity_too_large
|
66
|
+
414 request_uri_too_long
|
67
|
+
415 unsupported_media_type
|
68
|
+
416 request_range_not_satisfiable
|
69
|
+
417 expectation_failed
|
70
|
+
500 internal_server_error
|
71
|
+
501 not_implemented
|
72
|
+
502 bad_gateway
|
73
|
+
503 service_unavailable
|
74
|
+
504 gateway_timeout
|
75
|
+
505 http_version_not_supported).inject({}) do |hash, line|
|
76
|
+
code, status = line.split(' ')
|
77
|
+
hash[code.to_i] = status
|
78
|
+
hash
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
http_status_codes.each do |code, status|
|
83
|
+
eval %(
|
84
|
+
def #{status}(&block)
|
85
|
+
status[#{code}] = block
|
86
|
+
end)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def decode_response(http)
|
91
|
+
content_type = http.response_header['CONTENT_TYPE']
|
92
|
+
|
93
|
+
case content_type
|
94
|
+
when %r{^application/json}
|
95
|
+
response = ActiveSupport::JSON.decode(http.response)
|
96
|
+
else
|
97
|
+
response = http.response # Do nothing, just return text
|
98
|
+
end
|
99
|
+
|
100
|
+
rescue
|
101
|
+
raise StandardError.new("Problem decoding '#{content_type}': \n#{http.response}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
attr_accessor :cookie, :name, :logger
|
106
|
+
|
107
|
+
def initialize
|
108
|
+
@logger = Logger.new($stdout)
|
109
|
+
yield self if block_given?
|
110
|
+
end
|
111
|
+
|
112
|
+
def long_poll(url, opts={}, &block)
|
113
|
+
response = Response.new
|
114
|
+
request = EM::HttpRequest.new(url).get(opts)
|
115
|
+
|
116
|
+
request.callback {|http|
|
117
|
+
persist_cookie(http)
|
118
|
+
repoll = Struct.new(:url).new(url)
|
119
|
+
block.call(response, repoll) if block_given?
|
120
|
+
response.call(http)
|
121
|
+
log_request(http, "Repolling")
|
122
|
+
long_poll(repoll.url, &block)
|
123
|
+
}
|
124
|
+
request.errback {|http|
|
125
|
+
log_request(http, "Long poll timed-out. Repolling.", 'yellow')
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
# get url do |response|
|
130
|
+
# repoll = Struct.new(:url).new(url)
|
131
|
+
# block.call(response, repoll)
|
132
|
+
# response.finished {
|
133
|
+
# logger.info "Repolling".yellow
|
134
|
+
# long_poll(repoll.url, &block)
|
135
|
+
# }
|
136
|
+
# end
|
137
|
+
end
|
138
|
+
|
139
|
+
# HTTP requests
|
140
|
+
%w[get put post delete head].each do |http_meth|
|
141
|
+
eval %{
|
142
|
+
def #{http_meth}(*args, &block)
|
143
|
+
request(:#{http_meth}, *args, &block)
|
144
|
+
end}
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
def log_request(http, extra=nil, color=nil)
|
149
|
+
status = http.response_header.status.to_s
|
150
|
+
if color
|
151
|
+
status = status.send(color)
|
152
|
+
else
|
153
|
+
case status
|
154
|
+
when 500
|
155
|
+
status = status.red
|
156
|
+
when 0, 400..499
|
157
|
+
status = status.yellow
|
158
|
+
else
|
159
|
+
status = status.green
|
160
|
+
end
|
161
|
+
end
|
162
|
+
logger.info "#{status.ljust(3)} #{http.method.ljust(4)} #{http.uri}#{" (#{extra})".magenta if extra}\n #{http.response}\n"
|
163
|
+
end
|
164
|
+
|
165
|
+
# Simplifies em-http-client into something more suitable for tests. Interpets JSON, etc.
|
166
|
+
def request(http_meth, url, opts={}, &block)
|
167
|
+
response = Response.new
|
168
|
+
request = EM::HttpRequest.new(url).send(http_meth, opts)
|
169
|
+
|
170
|
+
request.callback {|http|
|
171
|
+
persist_cookie(http)
|
172
|
+
block.call(response) if block_given?
|
173
|
+
response.call(http)
|
174
|
+
log_request(http)
|
175
|
+
}
|
176
|
+
request.errback {|http|
|
177
|
+
log_request(http, "Network error or timeout.")
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
# Maintains session for mock users
|
182
|
+
def persist_cookie(http)
|
183
|
+
self.cookie = http.response_header['SET_COOKIE'] if http.response_header.include?('SET_COOKIE')
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Computron
|
2
|
+
class DSL
|
3
|
+
|
4
|
+
attr_reader :client
|
5
|
+
|
6
|
+
def initialize(code=nil, &block)
|
7
|
+
@client = Client.new
|
8
|
+
@simulation = Proc.new { code ? eval(code, self.send(:binding)) : instance_eval(&block) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def run!
|
12
|
+
EM::run { @simulation.call }
|
13
|
+
end
|
14
|
+
|
15
|
+
def halt!
|
16
|
+
EM::stop
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_host(host=nil)
|
20
|
+
host ? @default_host = host : @default_host
|
21
|
+
end
|
22
|
+
|
23
|
+
def every(seconds, opts={}, &block)
|
24
|
+
timer = EventMachine::PeriodicTimer.new(0) do
|
25
|
+
timer.interval = seconds
|
26
|
+
block.call(timer)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# HTTP utility methods. These are not meant to behave like a client
|
31
|
+
%w[get put post delete head].each do |http_meth|
|
32
|
+
eval %{
|
33
|
+
def #{http_meth}(*args, &block)
|
34
|
+
client.send(:#{http_meth}, *args, &block)
|
35
|
+
end}
|
36
|
+
end
|
37
|
+
|
38
|
+
# Deal with paths and URLs
|
39
|
+
def url(path)
|
40
|
+
url = String.new
|
41
|
+
url.concat "http://#{default_host}" unless url =~ %r{^(\w+)://} if default_host
|
42
|
+
url.concat path =~ /^\// ? path : "/#{path}" # Deal with leading /\
|
43
|
+
url
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# TODO integrate this puppy into the runner
|
2
|
+
module Computron
|
3
|
+
class Report
|
4
|
+
|
5
|
+
class Request
|
6
|
+
|
7
|
+
class Response
|
8
|
+
attr_accessor :headers, :status, :at
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :uri, :response, :headers, :at, :method
|
12
|
+
|
13
|
+
def response
|
14
|
+
yield @response if block_given?
|
15
|
+
@response
|
16
|
+
end
|
17
|
+
|
18
|
+
def duration
|
19
|
+
@duration ||= response.at.to_f - at.to_f if at and response.at
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@response = Response.new
|
24
|
+
yield self if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :requests
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@requests = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def by_status
|
36
|
+
requests.inject({}) do |memo, request|
|
37
|
+
memo[request.response.status] ||= []
|
38
|
+
memo[request.response.status] << request
|
39
|
+
memo
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def sample(&block)
|
44
|
+
requests << Request.new(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
data/lib/computron.rb
ADDED
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
data/test.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require '/Users/bgessler/Projects/imprezo/web/config/environment.rb'
|
2
|
+
require 'lib/computron'
|
3
|
+
|
4
|
+
clients_count = 2
|
5
|
+
post_interval = 10
|
6
|
+
|
7
|
+
clients = clients_count.times.map{ Computron::Client.new }
|
8
|
+
|
9
|
+
default_host 'localhost:3000'
|
10
|
+
|
11
|
+
get url('/events/1.json') do |response|
|
12
|
+
response.ok {|json|
|
13
|
+
event_id = json['event']['id']
|
14
|
+
ticks_url = url("/events/#{event_id}/ticks/stream.json")
|
15
|
+
|
16
|
+
clients.each do |client|
|
17
|
+
client.long_poll ticks_url do |response, repoll|
|
18
|
+
response.ok {|ticks|
|
19
|
+
if last_tick = ticks.last
|
20
|
+
repoll.url = "#{ticks_url}?since_id=#{last_tick['routing']['id']}"
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
every post_interval do
|
26
|
+
client.post url("/events/#{event_id}/comments"), :body => Comment.new(:response => 'Hey!').to_json, :head => {'Content-Type' => 'application/json'} do |response|
|
27
|
+
# response.ok { p "Super fun" }
|
28
|
+
# response.found { p "Redirected" }
|
29
|
+
# response.code(405) { p "Method not supported jagoff" }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: computron
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Brad Gessler
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-24 00:00:00 -07:00
|
18
|
+
default_executable: computron
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: eventmachine
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 12
|
30
|
+
- 10
|
31
|
+
version: 0.12.10
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: em-http-request
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 2
|
44
|
+
- 7
|
45
|
+
version: 0.2.7
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: colored
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 1
|
58
|
+
version: "1.1"
|
59
|
+
type: :runtime
|
60
|
+
version_requirements: *id003
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
prerelease: false
|
64
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 1
|
70
|
+
- 2
|
71
|
+
- 9
|
72
|
+
version: 1.2.9
|
73
|
+
type: :development
|
74
|
+
version_requirements: *id004
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: yard
|
77
|
+
prerelease: false
|
78
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
type: :development
|
86
|
+
version_requirements: *id005
|
87
|
+
description: Computron was created to help Poll Everywhere peform load tests that simulate how real users work.
|
88
|
+
email: brad@bradgessler.com
|
89
|
+
executables:
|
90
|
+
- computron
|
91
|
+
extensions: []
|
92
|
+
|
93
|
+
extra_rdoc_files:
|
94
|
+
- LICENSE
|
95
|
+
- README.rdoc
|
96
|
+
files:
|
97
|
+
- .bundle/config
|
98
|
+
- .document
|
99
|
+
- .gitignore
|
100
|
+
- Gemfile
|
101
|
+
- LICENSE
|
102
|
+
- README.rdoc
|
103
|
+
- Rakefile
|
104
|
+
- VERSION
|
105
|
+
- bin/computron
|
106
|
+
- computron.gemspec
|
107
|
+
- lib/computron.rb
|
108
|
+
- lib/computron/client.rb
|
109
|
+
- lib/computron/dsl.rb
|
110
|
+
- lib/computron/report.rb
|
111
|
+
- spec/computron_spec.rb
|
112
|
+
- spec/spec.opts
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- test.rb
|
115
|
+
has_rdoc: true
|
116
|
+
homepage: http://github.com/bradgessler/computron
|
117
|
+
licenses: []
|
118
|
+
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options:
|
121
|
+
- --charset=UTF-8
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
segments:
|
129
|
+
- 0
|
130
|
+
version: "0"
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
version: "0"
|
138
|
+
requirements: []
|
139
|
+
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 1.3.6
|
142
|
+
signing_key:
|
143
|
+
specification_version: 3
|
144
|
+
summary: An evented HTTP computron
|
145
|
+
test_files:
|
146
|
+
- spec/computron_spec.rb
|
147
|
+
- spec/spec_helper.rb
|