wakoopa-trample 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +42 -0
- data/Rakefile +57 -0
- data/VERSION.yml +4 -0
- data/bin/trample +7 -0
- data/lib/trample.rb +22 -0
- data/lib/trample/cli.rb +12 -0
- data/lib/trample/configuration.rb +49 -0
- data/lib/trample/logging.rb +14 -0
- data/lib/trample/page.rb +39 -0
- data/lib/trample/runner.rb +28 -0
- data/lib/trample/session.rb +47 -0
- data/lib/trample/timer.rb +9 -0
- data/test/cli_test.rb +17 -0
- data/test/configuration_test.rb +81 -0
- data/test/fixtures/basic_config.rb +5 -0
- data/test/integration/trample_a_single_url_test.rb +9 -0
- data/test/logging_test.rb +16 -0
- data/test/page_test.rb +59 -0
- data/test/runner_test.rb +35 -0
- data/test/session_test.rb +81 -0
- data/test/test_helper.rb +43 -0
- data/test/timer_test.rb +23 -0
- data/test/trample_test.rb +16 -0
- metadata +160 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 James Golick
|
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,42 @@
|
|
1
|
+
= trample
|
2
|
+
|
3
|
+
Trample is a flexible load simulation tool.
|
4
|
+
|
5
|
+
Most load sim tools make requests to a static list of urls. They spawn n threads and make requests to the urls on the list in succession, in each thread. Unfortunately, though, if your applicaition makes use of any kind of caching (including your database's internal caching facilities), this kind of load simulation is unrealistic.
|
6
|
+
|
7
|
+
The data required to serve a single set of urls is likely to fit nicely in the database server's cache (even on a small server). So, having a single user hammer a finite set of pages will make your application look much faster than it really is.
|
8
|
+
|
9
|
+
Trample allows you to provide parameter values inside of a block (a lambda function, for non-rubyists). The block is executed each time the parameters are needed. So, if you use randomization in the block, you should (theoretically) get different values every time.
|
10
|
+
|
11
|
+
That way, you can have trample log in as several different users and request different data in each session.
|
12
|
+
|
13
|
+
= How To
|
14
|
+
|
15
|
+
Trample uses a ruby DSL for configuration.
|
16
|
+
|
17
|
+
Trample.configure do
|
18
|
+
concurrency 5
|
19
|
+
iterations 10
|
20
|
+
login do
|
21
|
+
post "http://yoursite.com/login" do
|
22
|
+
{:username => User.random.username, :password => "swordfish"}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
get "http://yoursite.com/somewhere"
|
26
|
+
post "http://yoursite.com/something" do
|
27
|
+
{:a_parameter => "a value"}
|
28
|
+
end
|
29
|
+
get "http://yoursite.com/someresources/:id" do
|
30
|
+
{:id => SomeResource.random.id}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
The above configuration will start 5 (concurrency) sessions by logging in as a random user at the url in the login block. Then, it'll hit the two urls underneath it 10 (iterations) times during each session.
|
35
|
+
|
36
|
+
To run trample, save your configuration somewhere and run:
|
37
|
+
|
38
|
+
trample start /path/to/your/trample/config.rb
|
39
|
+
|
40
|
+
== Copyright
|
41
|
+
|
42
|
+
Copyright (c) 2009 James Golick. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "wakoopa-trample"
|
8
|
+
gem.summary = "A fork of giraffesoft-trample with added functionality for sleeping between requests"
|
9
|
+
gem.email = "wouter@wakoopa.com"
|
10
|
+
gem.homepage = "http://github.com/giraffesoft/trample"
|
11
|
+
gem.authors = ["James Golick", "Wouter Broekhof"]
|
12
|
+
|
13
|
+
gem.add_dependency "sevenwire-rest-client"
|
14
|
+
gem.add_dependency "thor"
|
15
|
+
gem.add_dependency "log4r"
|
16
|
+
gem.add_development_dependency "rake"
|
17
|
+
gem.add_development_dependency "shoulda"
|
18
|
+
gem.add_development_dependency "rr"
|
19
|
+
gem.add_development_dependency "jeweler"
|
20
|
+
|
21
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'rake/rdoctask'
|
28
|
+
Rake::RDocTask.new do |rdoc|
|
29
|
+
rdoc.rdoc_dir = 'rdoc'
|
30
|
+
rdoc.title = 'trample'
|
31
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
32
|
+
rdoc.rdoc_files.include('README*')
|
33
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rake/testtask'
|
37
|
+
Rake::TestTask.new(:test) do |test|
|
38
|
+
test.libs << 'lib' << 'test'
|
39
|
+
test.pattern = 'test/**/*_test.rb'
|
40
|
+
test.verbose = false
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'rcov/rcovtask'
|
45
|
+
Rcov::RcovTask.new do |test|
|
46
|
+
test.libs << 'test'
|
47
|
+
test.pattern = 'test/**/*_test.rb'
|
48
|
+
test.verbose = true
|
49
|
+
end
|
50
|
+
rescue LoadError
|
51
|
+
task :rcov do
|
52
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
task :default => :test
|
data/VERSION.yml
ADDED
data/bin/trample
ADDED
data/lib/trample.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
gem 'sevenwire-rest-client'
|
2
|
+
require 'log4r'
|
3
|
+
require 'rest_client'
|
4
|
+
|
5
|
+
module Trample
|
6
|
+
autoload :Configuration, File.dirname(__FILE__) + "/trample/configuration"
|
7
|
+
autoload :Page, File.dirname(__FILE__) + "/trample/page"
|
8
|
+
autoload :Session, File.dirname(__FILE__) + "/trample/session"
|
9
|
+
autoload :Runner, File.dirname(__FILE__) + "/trample/runner"
|
10
|
+
autoload :Cli, File.dirname(__FILE__) + "/trample/cli"
|
11
|
+
autoload :Logging, File.dirname(__FILE__) + "/trample/logging"
|
12
|
+
autoload :Timer, File.dirname(__FILE__) + "/trample/timer"
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_reader :current_configuration
|
16
|
+
|
17
|
+
def configure(&block)
|
18
|
+
@current_configuration = Configuration.new(&block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/trample/cli.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Trample
|
2
|
+
class Configuration
|
3
|
+
attr_reader :pages
|
4
|
+
|
5
|
+
def initialize(&block)
|
6
|
+
@pages = []
|
7
|
+
instance_eval(&block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def concurrency(*value)
|
11
|
+
@concurrency = value.first unless value.empty?
|
12
|
+
@concurrency
|
13
|
+
end
|
14
|
+
|
15
|
+
def iterations(*value)
|
16
|
+
@iterations = value.first unless value.empty?
|
17
|
+
@iterations
|
18
|
+
end
|
19
|
+
|
20
|
+
def sleep(*value)
|
21
|
+
@sleep = value.first unless value.empty?
|
22
|
+
@sleep
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(url, &block)
|
26
|
+
@pages << Page.new(:get, url, block || {})
|
27
|
+
end
|
28
|
+
|
29
|
+
def post(url, params = nil, &block)
|
30
|
+
@pages << Page.new(:post, url, params || block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def login
|
34
|
+
if block_given?
|
35
|
+
yield
|
36
|
+
@login = pages.pop
|
37
|
+
end
|
38
|
+
|
39
|
+
@login
|
40
|
+
end
|
41
|
+
|
42
|
+
def ==(other)
|
43
|
+
other.is_a?(Configuration) &&
|
44
|
+
other.pages == pages &&
|
45
|
+
other.concurrency == concurrency &&
|
46
|
+
other.iterations == iterations
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Trample
|
2
|
+
module Logging
|
3
|
+
def logger
|
4
|
+
init_logger if Log4r::Logger['main'].nil?
|
5
|
+
Log4r::Logger['main']
|
6
|
+
end
|
7
|
+
|
8
|
+
protected
|
9
|
+
def init_logger
|
10
|
+
logger = Log4r::Logger.new('main')
|
11
|
+
logger.outputters = Log4r::Outputter.stdout
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/trample/page.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Trample
|
2
|
+
class Page
|
3
|
+
attr_reader :request_method
|
4
|
+
|
5
|
+
def initialize(request_method, url, parameters = {})
|
6
|
+
@request_method = request_method
|
7
|
+
@url = url
|
8
|
+
@parameters = parameters
|
9
|
+
end
|
10
|
+
|
11
|
+
def parameters
|
12
|
+
proc_params? ? @parameters.call : @parameters
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.is_a?(Page) &&
|
17
|
+
other.request_method == request_method &&
|
18
|
+
other.url == url
|
19
|
+
end
|
20
|
+
|
21
|
+
def url
|
22
|
+
proc_params? ? interpolated_url : @url
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def proc_params?
|
27
|
+
@parameters.is_a?(Proc)
|
28
|
+
end
|
29
|
+
|
30
|
+
def interpolated_url
|
31
|
+
params = parameters # cache called proc
|
32
|
+
url = @url.dup
|
33
|
+
url.scan(/\:\w+/).each do |m|
|
34
|
+
url.gsub!(m, params[m.gsub(/:/, '').to_sym].to_s)
|
35
|
+
end
|
36
|
+
url
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Trample
|
2
|
+
class Runner
|
3
|
+
include Logging
|
4
|
+
|
5
|
+
attr_reader :config, :threads
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
@threads = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def trample
|
13
|
+
logger.info "Starting trample..."
|
14
|
+
|
15
|
+
config.concurrency.times do
|
16
|
+
thread = Thread.new(@config) do |c|
|
17
|
+
Session.new(c).trample
|
18
|
+
end
|
19
|
+
threads << thread
|
20
|
+
end
|
21
|
+
|
22
|
+
threads.each { |t| t.join }
|
23
|
+
|
24
|
+
logger.info "Trample completed..."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Trample
|
2
|
+
class Session
|
3
|
+
include Logging
|
4
|
+
include Timer
|
5
|
+
|
6
|
+
attr_reader :config, :response_times, :cookies, :last_response
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
@response_times = []
|
11
|
+
@cookies = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def trample
|
15
|
+
hit @config.login unless @config.login.nil?
|
16
|
+
@config.iterations.times do
|
17
|
+
@config.pages.each do |p|
|
18
|
+
hit p
|
19
|
+
end
|
20
|
+
end
|
21
|
+
sleep @config.sleep unless @config.sleep.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def hit(page)
|
26
|
+
response_times << request(page)
|
27
|
+
# this is ugly, but it's the only way that I could get the test to pass
|
28
|
+
# because rr keeps a reference to the arguments, not a copy. ah well.
|
29
|
+
@cookies = cookies.merge(last_response.cookies)
|
30
|
+
logger.info "#{page.request_method.to_s.upcase} #{page.url} #{response_times.last}s #{last_response.code}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def request(page)
|
34
|
+
time do
|
35
|
+
@last_response = send(page.request_method, page)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def get(page)
|
40
|
+
RestClient.get(page.url, :cookies => cookies)
|
41
|
+
end
|
42
|
+
|
43
|
+
def post(page)
|
44
|
+
RestClient.post(page.url, page.parameters, :cookies => cookies)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/test/cli_test.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CliTest < Test::Unit::TestCase
|
4
|
+
context "Running the CLI" do
|
5
|
+
setup do
|
6
|
+
Trample::Cli.new.start('test/fixtures/basic_config.rb')
|
7
|
+
end
|
8
|
+
|
9
|
+
before_should "start a trample with the current_config" do
|
10
|
+
load('test/fixtures/basic_config.rb')
|
11
|
+
stub.proxy(Trample::Runner).new(Trample.current_configuration) do |r|
|
12
|
+
mock(r).trample
|
13
|
+
r
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ConfigurationTest < Test::Unit::TestCase
|
4
|
+
context "Configuring trample" do
|
5
|
+
setup do
|
6
|
+
@params_proc = lambda { { :q => "the meaning of life" } }
|
7
|
+
@config = Trample::Configuration.new do
|
8
|
+
concurrency 2
|
9
|
+
iterations 1
|
10
|
+
sleep 1
|
11
|
+
|
12
|
+
get "http://google.com/" do
|
13
|
+
{:a => 'b'}
|
14
|
+
end
|
15
|
+
post "http://google.com/", {:q => "something"}
|
16
|
+
post "http://google.com/", &@params_proc
|
17
|
+
login do
|
18
|
+
post "http://google.com/login" do
|
19
|
+
{ :q => "whatever" }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
should "set concurrency" do
|
26
|
+
assert_equal 2, @config.concurrency
|
27
|
+
end
|
28
|
+
|
29
|
+
should "set iterations" do
|
30
|
+
assert_equal 1, @config.iterations
|
31
|
+
end
|
32
|
+
|
33
|
+
should "set sleep" do
|
34
|
+
assert_equal 1, @config.sleep
|
35
|
+
end
|
36
|
+
|
37
|
+
should "add get requests to an array of pages" do
|
38
|
+
assert_equal Trample::Page.new(:get, "http://google.com/"), @config.pages.first
|
39
|
+
end
|
40
|
+
|
41
|
+
should "add get params to the array of pages" do
|
42
|
+
assert_equal({:a => "b"}, @config.pages.first.parameters)
|
43
|
+
end
|
44
|
+
|
45
|
+
should "add post requests to the array of pages, including their params" do
|
46
|
+
expected = Trample::Page.new(:post, "http://google.com/", {:q => "something"})
|
47
|
+
assert_equal expected, @config.pages[1]
|
48
|
+
end
|
49
|
+
|
50
|
+
should "add post requests to the array of pages, including their block-based params" do
|
51
|
+
expected = Trample::Page.new(:post, "http://google.com/", @params_proc)
|
52
|
+
assert_equal expected, @config.pages[2]
|
53
|
+
end
|
54
|
+
|
55
|
+
should "support a login parameter which contains a page to hit with params" do
|
56
|
+
assert_equal "http://google.com/login", @config.login.url
|
57
|
+
assert_equal({:q => "whatever"}, @config.login.parameters)
|
58
|
+
end
|
59
|
+
|
60
|
+
should "be equal if all the objects are the same" do
|
61
|
+
identical_config = Trample::Configuration.new do
|
62
|
+
concurrency 2
|
63
|
+
iterations 1
|
64
|
+
get "http://google.com/"
|
65
|
+
post "http://google.com/", {:q => "something"}
|
66
|
+
post "http://google.com/", &@params_proc
|
67
|
+
end
|
68
|
+
assert_equal identical_config, @config
|
69
|
+
end
|
70
|
+
|
71
|
+
should "not be equal if any of the objects are different" do
|
72
|
+
non_identical_config = Trample::Configuration.new do
|
73
|
+
concurrency 3
|
74
|
+
iterations 1
|
75
|
+
get "http://google.com/"
|
76
|
+
end
|
77
|
+
assert_not_equal non_identical_config, @config
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class LoggingTest < Test::Unit::TestCase
|
4
|
+
context "The logging module" do
|
5
|
+
setup do
|
6
|
+
@object = Class.new do
|
7
|
+
include Trample::Logging
|
8
|
+
end.new
|
9
|
+
@object.send(:init_logger)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "return Log4r::Logger['main'] for #logger" do
|
13
|
+
assert_equal Log4r::Logger['main'], @object.logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/test/page_test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PageTest < Test::Unit::TestCase
|
4
|
+
context "A page" do
|
5
|
+
setup do
|
6
|
+
@page = Trample::Page.new(:get, "http://google.com/", :username => "joetheuser")
|
7
|
+
end
|
8
|
+
|
9
|
+
should "have a request_method" do
|
10
|
+
assert_equal :get, @page.request_method
|
11
|
+
end
|
12
|
+
|
13
|
+
should "have a url" do
|
14
|
+
assert_equal "http://google.com/", @page.url
|
15
|
+
end
|
16
|
+
|
17
|
+
should "have request parameters" do
|
18
|
+
assert_equal({:username => "joetheuser"}, @page.parameters)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "be equal with the same request_method and url" do
|
22
|
+
assert_equal Trample::Page.new(:get, "http://google.com"), Trample::Page.new(:get, "http://google.com")
|
23
|
+
end
|
24
|
+
|
25
|
+
should "not be equal with a different request_method or url" do
|
26
|
+
assert_not_equal Trample::Page.new(:get, "http://google.com"), Trample::Page.new(:get, "http://google.com/asdf")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "Block-based request parameters for POST requests" do
|
31
|
+
setup do
|
32
|
+
@page = Trample::Page.new(:post, "http://google.com/:id", lambda { { :id => 1, :username => "joetheuser" } })
|
33
|
+
end
|
34
|
+
|
35
|
+
should "be resolved at call time" do
|
36
|
+
assert_equal({:username => "joetheuser", :id => 1}, @page.parameters)
|
37
|
+
end
|
38
|
+
|
39
|
+
should "interpolate parameters into the url" do
|
40
|
+
assert_equal "http://google.com/1", @page.url
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "Block based parameters for GET requests" do
|
45
|
+
setup do
|
46
|
+
@page = Trample::Page.new(:get, "http://mysite.com/somethings/:id", lambda { {:id => 5} })
|
47
|
+
end
|
48
|
+
|
49
|
+
should "interpolate those parameters with the url string" do
|
50
|
+
assert_equal "http://mysite.com/somethings/5", @page.url
|
51
|
+
end
|
52
|
+
|
53
|
+
should "interpolate a different parameter each time" do
|
54
|
+
page = Trample::Page.new(:get, "http://mysite.com/somethings/:id", lambda { {:id => rand(10)} })
|
55
|
+
assert_not_equal page.url, page.url
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
data/test/runner_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RunnerTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@config = Trample::Configuration.new do |t|
|
6
|
+
t.concurrency 2
|
7
|
+
t.iterations 5
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "Running a trample" do
|
12
|
+
setup do
|
13
|
+
@runner = Trample::Runner.new(@config)
|
14
|
+
@runner.trample
|
15
|
+
end
|
16
|
+
|
17
|
+
before_should "spawn <concurrency> threads" do
|
18
|
+
mock.proxy(Thread).new(@config).times(2)
|
19
|
+
end
|
20
|
+
|
21
|
+
before_should "start <concurrency> sessions trampling" do
|
22
|
+
stub.proxy(Trample::Session).new(@config).times(2) do |s|
|
23
|
+
mock(s).trample
|
24
|
+
s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
before_should "block until all the threads terminate" do
|
29
|
+
stub.proxy(Thread).new(@config) do |t|
|
30
|
+
mock(t).join
|
31
|
+
t
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SessionTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@config = Trample::Configuration.new do
|
6
|
+
iterations 2
|
7
|
+
get "http://google.com/"
|
8
|
+
get "http://amazon.com/"
|
9
|
+
post "http://google.com/"
|
10
|
+
end
|
11
|
+
@session = Trample::Session.new(@config)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "Starting a trample session" do
|
15
|
+
setup do
|
16
|
+
@session.trample
|
17
|
+
end
|
18
|
+
|
19
|
+
before_should "visit the pages iterations times each" do
|
20
|
+
mock_get("http://google.com/", :times => 2)
|
21
|
+
mock_get("http://amazon.com/", :times => 2)
|
22
|
+
mock_post("http://google.com/", :times => 2)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "Visiting a page" do
|
27
|
+
setup do
|
28
|
+
stub(@session).time { 1.4 }
|
29
|
+
stub(@session).last_response do
|
30
|
+
response = RestClient::Response.new("", stub!)
|
31
|
+
stub(response).cookies { {} }
|
32
|
+
stub(response).code { 200 }
|
33
|
+
end
|
34
|
+
@session.trample
|
35
|
+
end
|
36
|
+
|
37
|
+
should "record the length of time it took to visit that page" do
|
38
|
+
assert_equal [1.4, 1.4, 1.4, 1.4, 1.4, 1.4], @session.response_times
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "If a page responds with a cookie" do
|
43
|
+
should "pass that cookie on to the next page" do
|
44
|
+
stub(RestClient).get(anything, anything) do
|
45
|
+
response = RestClient::Response.new("", stub!)
|
46
|
+
stub(response).cookies { {"xyz" => "abc"} }
|
47
|
+
stub(response).code { 200 }
|
48
|
+
end
|
49
|
+
|
50
|
+
@config = Trample::Configuration.new do
|
51
|
+
iterations 2
|
52
|
+
get "http://amazon.com/"
|
53
|
+
end
|
54
|
+
|
55
|
+
@session = Trample::Session.new(@config)
|
56
|
+
@session.trample
|
57
|
+
|
58
|
+
assert_received(RestClient) { |c| c.get("http://amazon.com/", :cookies => {"xyz" => "abc"}) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "A session with login" do
|
63
|
+
# TODO: the order of the requests isn't being tested here. not
|
64
|
+
# sure if it's possible with rr
|
65
|
+
should "hit the login once at the beginning of the session" do
|
66
|
+
@config = Trample::Configuration.new do
|
67
|
+
iterations 2
|
68
|
+
login do
|
69
|
+
post "http://google.com/login" do
|
70
|
+
{:user => "xyz", :password => "swordfish"}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
get "http://google.com/"
|
74
|
+
end
|
75
|
+
stub_get(anything, :times => 2)
|
76
|
+
mock_post("http://google.com/login", :payload => {:user => "xyz", :password => "swordfish"}, :times => 1)
|
77
|
+
Trample::Session.new(@config).trample
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'rr'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'trample'
|
9
|
+
|
10
|
+
class Test::Unit::TestCase
|
11
|
+
include RR::Adapters::TestUnit unless include?(RR::Adapters::TestUnit)
|
12
|
+
|
13
|
+
protected
|
14
|
+
def trample(config)
|
15
|
+
Trample::Cli.new.start(config)
|
16
|
+
end
|
17
|
+
|
18
|
+
def mock_get(url, opts={})
|
19
|
+
mock(RestClient).get(url, :cookies => opts[:cookies] || {}).times(opts[:times]) do
|
20
|
+
response = RestClient::Response.new("", stub!)
|
21
|
+
stub(response).cookies { opts[:return_cookies] || {} }
|
22
|
+
stub(response).code { 200 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def mock_post(url, opts={})
|
27
|
+
mock(RestClient).post(url, opts[:payload],
|
28
|
+
:cookies => opts[:cookies] || {}).times(opts[:times]) do
|
29
|
+
response = RestClient::Response.new("", stub!)
|
30
|
+
stub(response).cookies { opts[:return_cookies] || {} }
|
31
|
+
stub(response).code { 200 }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def stub_get(url, opts = {})
|
36
|
+
stub(RestClient).get(url, :cookies => opts[:cookies] || {}).times(opts[:times]) do
|
37
|
+
response = RestClient::Response.new("", stub!)
|
38
|
+
stub(response).cookies { opts[:return_cookies] || {} }
|
39
|
+
stub(response).code { 200 }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
data/test/timer_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TimerTest < Test::Unit::TestCase
|
4
|
+
context "Timing the execution of a block" do
|
5
|
+
setup do
|
6
|
+
now = Time.now
|
7
|
+
invocations = 0
|
8
|
+
stub(Time).now do
|
9
|
+
invocations += 1
|
10
|
+
# not sure why we have to start at 1,
|
11
|
+
# but this seems to get called somewhere
|
12
|
+
invocations == 2 ? now : (now + 1.5)
|
13
|
+
end
|
14
|
+
|
15
|
+
@obj = Class.new { include Trample::Timer }.new
|
16
|
+
end
|
17
|
+
|
18
|
+
should "return the amount of time elapsed while the block was run" do
|
19
|
+
assert_equal(1.5, @obj.time {})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TrampleTest < Test::Unit::TestCase
|
4
|
+
context "Configuring Trample" do
|
5
|
+
setup do
|
6
|
+
Trample.configure do |t|
|
7
|
+
t.concurrency 5
|
8
|
+
t.iterations 1
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
should "assign the configuration to Trample.current_configuration" do
|
13
|
+
assert_equal 5, Trample.current_configuration.concurrency
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wakoopa-trample
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Golick
|
8
|
+
- Wouter Broekhof
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-12-23 00:00:00 +01:00
|
14
|
+
default_executable: trample
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: sevenwire-rest-client
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: thor
|
28
|
+
type: :runtime
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0"
|
35
|
+
version:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: log4r
|
38
|
+
type: :runtime
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
type: :development
|
49
|
+
version_requirement:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: shoulda
|
58
|
+
type: :development
|
59
|
+
version_requirement:
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: rr
|
68
|
+
type: :development
|
69
|
+
version_requirement:
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: jeweler
|
78
|
+
type: :development
|
79
|
+
version_requirement:
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
description:
|
87
|
+
email: wouter@wakoopa.com
|
88
|
+
executables:
|
89
|
+
- trample
|
90
|
+
extensions: []
|
91
|
+
|
92
|
+
extra_rdoc_files:
|
93
|
+
- LICENSE
|
94
|
+
- README.rdoc
|
95
|
+
files:
|
96
|
+
- .gitignore
|
97
|
+
- LICENSE
|
98
|
+
- README.rdoc
|
99
|
+
- Rakefile
|
100
|
+
- VERSION.yml
|
101
|
+
- bin/trample
|
102
|
+
- lib/trample.rb
|
103
|
+
- lib/trample/cli.rb
|
104
|
+
- lib/trample/configuration.rb
|
105
|
+
- lib/trample/logging.rb
|
106
|
+
- lib/trample/page.rb
|
107
|
+
- lib/trample/runner.rb
|
108
|
+
- lib/trample/session.rb
|
109
|
+
- lib/trample/timer.rb
|
110
|
+
- test/cli_test.rb
|
111
|
+
- test/configuration_test.rb
|
112
|
+
- test/fixtures/basic_config.rb
|
113
|
+
- test/integration/trample_a_single_url_test.rb
|
114
|
+
- test/logging_test.rb
|
115
|
+
- test/page_test.rb
|
116
|
+
- test/runner_test.rb
|
117
|
+
- test/session_test.rb
|
118
|
+
- test/test_helper.rb
|
119
|
+
- test/timer_test.rb
|
120
|
+
- test/trample_test.rb
|
121
|
+
has_rdoc: true
|
122
|
+
homepage: http://github.com/giraffesoft/trample
|
123
|
+
licenses: []
|
124
|
+
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options:
|
127
|
+
- --charset=UTF-8
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: "0"
|
135
|
+
version:
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: "0"
|
141
|
+
version:
|
142
|
+
requirements: []
|
143
|
+
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 1.3.5
|
146
|
+
signing_key:
|
147
|
+
specification_version: 3
|
148
|
+
summary: A fork of giraffesoft-trample with added functionality for sleeping between requests
|
149
|
+
test_files:
|
150
|
+
- test/cli_test.rb
|
151
|
+
- test/configuration_test.rb
|
152
|
+
- test/fixtures/basic_config.rb
|
153
|
+
- test/integration/trample_a_single_url_test.rb
|
154
|
+
- test/logging_test.rb
|
155
|
+
- test/page_test.rb
|
156
|
+
- test/runner_test.rb
|
157
|
+
- test/session_test.rb
|
158
|
+
- test/test_helper.rb
|
159
|
+
- test/timer_test.rb
|
160
|
+
- test/trample_test.rb
|