celluloid-benchmark 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +132 -0
- data/bin/celluloid-benchmark +16 -0
- data/lib/celluloid_benchmark.rb +5 -0
- data/test/files/runner_test_session.rb +2 -0
- data/test/integration/config.ru +9 -0
- data/test/integration/html/404.html +10 -0
- data/test/integration/html/index.html +10 -0
- data/test/integration/integration_test.rb +55 -0
- data/test/integration/test_session.rb +2 -0
- data/test/unit/benchmark_run_test.rb +130 -0
- data/test/unit/benchmark_test.rb +107 -0
- data/test/unit/runner_test.rb +24 -0
- data/test/unit/visitor_test.rb +64 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8b43cb7f1b3f835c28eef1361299b99b8188a1e
|
4
|
+
data.tar.gz: 2025783e8cc49d76300263cc7df9ba991af36120
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1e1bf981e517e15d3c6698c42b7bd5bc388266203bc7a82f09e2824bef6c95d67fef09d0b213113577c6100528c0e7ed107b43c1b9993c65f0c79d65109ba3ad
|
7
|
+
data.tar.gz: b970a27dba6d16cb152c486077cc879de84d6827444ddf968abbb9cd981a5b6c4a8f056510a6a774efd7bce91bbb36f8978b025fa897f9fdf0037ff0d6864eef
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Scott Willson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
Celluloid Benchmark realistically load tests websites.
|
2
|
+
|
3
|
+
Write expressive, concise load tests in Ruby. Use [Rubinius](http://rubini.us) and [Celluloid](https://github.com/celluloid/celluloid)
|
4
|
+
for high concurrency. Use [Mechanize](http://mechanize.rubyforge.org) for a realistic (albeit non-JavaScript) browser client.
|
5
|
+
|
6
|
+
Getting Started
|
7
|
+
===============
|
8
|
+
celluloid-benchmark test/files/runner_test_session.rb
|
9
|
+
|
10
|
+
Congrats! You just load-tested the project's Github page.
|
11
|
+
|
12
|
+
For your own tests, create a session file and pass its path to celluloid-benchmark.
|
13
|
+
|
14
|
+
Simple scenario
|
15
|
+
---------------
|
16
|
+
benchmark :home_page, 1
|
17
|
+
get "https://github.com/scottwillson/celluloid-benchmark"
|
18
|
+
|
19
|
+
`benchmark :label, duration` means "measure the following requests and group them under 'label'".
|
20
|
+
Duration is optional and defaults to 0.3 seconds.
|
21
|
+
|
22
|
+
Find and click a link
|
23
|
+
---------------------
|
24
|
+
page = get "/offer/1"
|
25
|
+
buy_now_link = page.links_with(class: "buy_button").first
|
26
|
+
|
27
|
+
benchmark :purchase_new
|
28
|
+
page = get(buy_now_link.href)
|
29
|
+
|
30
|
+
Forms
|
31
|
+
-----
|
32
|
+
form = page.forms_with(class: "simple_form purchase_form").first
|
33
|
+
form["CARDNO"] = "4111111111111111"
|
34
|
+
submit(form)
|
35
|
+
|
36
|
+
HTTP auth
|
37
|
+
---------
|
38
|
+
add_auth "https://staging.example.com", "qa", "password"
|
39
|
+
|
40
|
+
|
41
|
+
Simulate AJAX
|
42
|
+
-------------
|
43
|
+
transact do
|
44
|
+
get "https://example.com/post_zones/AAA1NNN", [], nil, {
|
45
|
+
"Accept" => "application/json, text/javascript, */*; q=0.01",
|
46
|
+
"X-Requested-With" => "XMLHttpRequest"
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
Test data
|
51
|
+
---------
|
52
|
+
Because test scenarios are plain Ruby, you can drive tests in many different ways. The
|
53
|
+
[Faker gem](http://rubydoc.info/github/stympy/faker/master/frames) is handy
|
54
|
+
for random, realistic test data:
|
55
|
+
|
56
|
+
require "faker"
|
57
|
+
first_name = Faker::Name.first_name
|
58
|
+
last_name = Faker::Name.last_name
|
59
|
+
post_town = Faker::Address.city
|
60
|
+
|
61
|
+
form["CN"] = "#{first_name} #{last_name}"
|
62
|
+
form["c[addr][post_town]"] = post_town
|
63
|
+
|
64
|
+
The [Forgery gem](http://sevenwire.github.io/forgery/) is good, too.
|
65
|
+
|
66
|
+
Celluloid Benchmark can also pull random test data from CSV files. For example:
|
67
|
+
|
68
|
+
get "https://example.com/post_zones/#{random_data(:post_zone)}"
|
69
|
+
|
70
|
+
`random_data(:post_zone)` pulls a random line from tmp/data/post_zones.csv
|
71
|
+
|
72
|
+
Celluloid Benchmark agents delegate calls to Mechanize. If you need something more complicated
|
73
|
+
than the examples, check out the [Mechanize API](http://mechanize.rubyforge.org/HTTP/Agent.html) and call it directly with `browser.` in your test scenario.
|
74
|
+
|
75
|
+
For a longer test, pass in a second duration argument (seconds):
|
76
|
+
celluloid-benchmark my_test_session.rb 180
|
77
|
+
|
78
|
+
Why
|
79
|
+
===
|
80
|
+
I need to simulate a lot of realistic traffic against preproduction code.
|
81
|
+
There are many good tools that can put a high load on a static URL (e.g., [ab](http://httpd.apache.org/docs/2.2/programs/ab.html)), and there are a few tools
|
82
|
+
(e.g., [Tsung](http://tsung.erlang-projects.org)) that can generate realistic multiple-URL loads. By "realistic" I mean: follow links, maintain
|
83
|
+
session state from one page to the next, simulate different types of simultaneous visitors (5% admin users + 10%
|
84
|
+
business customers + 75% consumers). I found it difficult to maintain complex scenarios. Our Tsung tests,
|
85
|
+
for instance, exploded into many ERB files that concatenated into a giant Tsung XML config (with some custom Erlang
|
86
|
+
functions). I also wanted control over recording and displaying test results.
|
87
|
+
|
88
|
+
Wouldn't it be nice to just write Ruby?
|
89
|
+
|
90
|
+
Yes, expect for that Ruby GIL issue. Which led me to Rubinius and Celluloid.
|
91
|
+
|
92
|
+
Rubinius is a concurrency-friendly implementation of Ruby, and Celluloid is a nice Ruby actor framework.
|
93
|
+
|
94
|
+
Celluloid also works with MRI 1.9 and 2.0, though Celluloid Benchmark can generate more concurrent load with
|
95
|
+
Rubinius. [JRuby](http://jruby.org) should also work well, maybe better.
|
96
|
+
|
97
|
+
I've just added features I need, but it should be easy to add more. For example:
|
98
|
+
|
99
|
+
* Pull specific keys/columns from CSV files
|
100
|
+
* Add random "think times" for visitors to pause on pages
|
101
|
+
|
102
|
+
Alternatives
|
103
|
+
============
|
104
|
+
|
105
|
+
Simple
|
106
|
+
------
|
107
|
+
[ab (Apache Bench)](http://httpd.apache.org/docs/2.2/programs/ab.html)
|
108
|
+
|
109
|
+
[httperf](http://www.hpl.hp.com/research/linux/httperf/)
|
110
|
+
|
111
|
+
[siege](http://freecode.com/projects/siege)
|
112
|
+
|
113
|
+
|
114
|
+
Complex
|
115
|
+
-------
|
116
|
+
[Tsung](http://tsung.erlang-projects.org)
|
117
|
+
|
118
|
+
[The Grinder](http://grinder.sourceforge.net)
|
119
|
+
|
120
|
+
[JMeter](http://jmeter.apache.org)
|
121
|
+
|
122
|
+
|
123
|
+
Develop
|
124
|
+
=======
|
125
|
+
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
|
126
|
+
curl -L https://get.rvm.io | bash
|
127
|
+
rvm install rbx-2.2.1
|
128
|
+
git clone git@github.com:scottwillson/celluloid-benchmark.git
|
129
|
+
cd celluloid-benchmark
|
130
|
+
rvm gemset use celluloid-benchmark --create
|
131
|
+
bundle
|
132
|
+
rake
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/celluloid_benchmark"
|
4
|
+
|
5
|
+
benchmark_run = CelluloidBenchmark::Runner.run ARGV[0], (ARGV[1] || 20).to_i
|
6
|
+
|
7
|
+
p benchmark_run
|
8
|
+
puts
|
9
|
+
p "#{benchmark_run.requests / benchmark_run.elapsed_time} requests per second. #{benchmark_run.requests} requests in #{benchmark_run.elapsed_time} seconds by #{Celluloid::Actor[:visitor_pool].size} visitors."
|
10
|
+
|
11
|
+
puts
|
12
|
+
benchmark_run.benchmarks.each do |trans|
|
13
|
+
puts "#{trans.ok? ? '[ OK ]' : '[FAIL]'} #{trans.label}"
|
14
|
+
end
|
15
|
+
|
16
|
+
exit benchmark_run.ok?
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require_relative "../../lib/celluloid_benchmark"
|
3
|
+
|
4
|
+
module CelluloidBenchmark
|
5
|
+
class IntegrationTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
# minitest and Celluloid both use at_exit
|
8
|
+
Celluloid.boot
|
9
|
+
|
10
|
+
start_target_webserver
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
stop_target_webserver
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_happy_path
|
18
|
+
assert target_webserver_responsive?, "Test web server did not respond OK"
|
19
|
+
|
20
|
+
session_path = File.expand_path(File.dirname(__FILE__) + "/test_session.rb")
|
21
|
+
duration = 5
|
22
|
+
benchmark_run = CelluloidBenchmark::Runner.run(session_path, duration)
|
23
|
+
|
24
|
+
assert benchmark_run.ok?, "Run should be OK"
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_target_webserver
|
28
|
+
`thin --threaded --rackup test/integration/config.ru --daemonize --port 8000 start`
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop_target_webserver
|
32
|
+
`thin stop`
|
33
|
+
end
|
34
|
+
|
35
|
+
def target_webserver_responsive?
|
36
|
+
require "net/http"
|
37
|
+
require "uri"
|
38
|
+
|
39
|
+
uri = URI.parse("http://localhost:8000/")
|
40
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
41
|
+
Timeout::timeout(5) do
|
42
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
43
|
+
begin
|
44
|
+
response = http.request(request)
|
45
|
+
if response.code.to_i == 200
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
rescue Errno::ECONNREFUSED, Net::HTTP::Persistent::Error
|
49
|
+
# Ignore. Server might be starting up.
|
50
|
+
end
|
51
|
+
sleep 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "timecop"
|
3
|
+
require_relative "../../lib/celluloid_benchmark/benchmark_run"
|
4
|
+
|
5
|
+
module CelluloidBenchmark
|
6
|
+
class BenchmarkRunTest < Minitest::Test
|
7
|
+
def setup
|
8
|
+
# minitest and Celluloid both use at_exit
|
9
|
+
Celluloid.boot
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_new
|
13
|
+
BenchmarkRun.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_inspect
|
17
|
+
BenchmarkRun.new.inspect
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_log
|
21
|
+
benchmark_run = BenchmarkRun.new
|
22
|
+
logger = Minitest::Mock.new
|
23
|
+
logger.expect :info, true, [ "200 1 search"]
|
24
|
+
benchmark_run.logger = logger
|
25
|
+
benchmark_run.log 200, 1, 2, "search", 3
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_response_times
|
29
|
+
benchmark_run = BenchmarkRun.new
|
30
|
+
assert_equal Hash.new, benchmark_run.response_times
|
31
|
+
|
32
|
+
benchmark_run.log 200, 3, 4, "search", 0
|
33
|
+
assert_equal({ "search" => [ 1 ] }, benchmark_run.response_times)
|
34
|
+
|
35
|
+
benchmark_run.log 200, 40, 100, "search", 3
|
36
|
+
search_times = benchmark_run.response_times[ "search" ]
|
37
|
+
assert_equal [ 1, 60 ], search_times.sort
|
38
|
+
|
39
|
+
benchmark_run.log 404, 1000, 2000, "home", 3
|
40
|
+
search_times = benchmark_run.response_times[ "search" ]
|
41
|
+
assert_equal [ 1, 60 ], search_times.sort
|
42
|
+
assert_equal [ 1000 ], benchmark_run.response_times[ "home" ]
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_response_codes
|
46
|
+
benchmark_run = BenchmarkRun.new
|
47
|
+
assert_equal Hash.new, benchmark_run.response_codes
|
48
|
+
|
49
|
+
benchmark_run.log 200, 3, 4, "search", 0
|
50
|
+
assert_equal({ "search" => [ 200 ] }, benchmark_run.response_codes)
|
51
|
+
|
52
|
+
benchmark_run.log 302, 40, 100, "search", 3
|
53
|
+
search_codes = benchmark_run.response_codes[ "search" ]
|
54
|
+
assert_equal [ 200, 302 ], search_codes.sort
|
55
|
+
|
56
|
+
benchmark_run.log 404, 1000, 2000, "home", 3
|
57
|
+
search_codes = benchmark_run.response_codes[ "search" ]
|
58
|
+
assert_equal [ 200, 302 ], search_codes.sort
|
59
|
+
assert_equal [ 404 ], benchmark_run.response_codes[ "home" ]
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_requests
|
63
|
+
benchmark_run = BenchmarkRun.new
|
64
|
+
assert_equal 0, benchmark_run.requests
|
65
|
+
|
66
|
+
benchmark_run.log 200, 3, 4, "search", 0
|
67
|
+
assert_equal 1, benchmark_run.requests
|
68
|
+
|
69
|
+
benchmark_run.log 200, 3, 4, "search", 0
|
70
|
+
assert_equal 2, benchmark_run.requests
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_benchmarks
|
74
|
+
benchmark_run = BenchmarkRun.new
|
75
|
+
assert_equal 0, benchmark_run.benchmarks.size
|
76
|
+
assert benchmark_run.benchmarks.empty?
|
77
|
+
|
78
|
+
benchmark_run.log 200, 3, 4, "search", 0.01
|
79
|
+
assert_equal 1, benchmark_run.benchmarks.size
|
80
|
+
benchmark = benchmark_run.benchmarks.first
|
81
|
+
assert_equal "search", benchmark.label, "benchmark label"
|
82
|
+
assert_equal 0.01, benchmark.threshold, "benchmark threshold"
|
83
|
+
assert_equal [ 1 ], benchmark.response_times, "benchmark response_times"
|
84
|
+
assert_equal [ 200 ], benchmark.response_codes, "benchmark response_codes"
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_mark_start
|
88
|
+
benchmark_run = BenchmarkRun.new
|
89
|
+
assert_equal nil, benchmark_run.started_at, "started_at"
|
90
|
+
|
91
|
+
Timecop.freeze(Time.new(2001, 4, 5, 18, 30)) do
|
92
|
+
benchmark_run.mark_start
|
93
|
+
end
|
94
|
+
|
95
|
+
assert_equal Time.new(2001, 4, 5, 18, 30), benchmark_run.started_at
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_mark_end
|
99
|
+
benchmark_run = BenchmarkRun.new
|
100
|
+
assert_equal nil, benchmark_run.ended_at, "ended_at"
|
101
|
+
|
102
|
+
Timecop.freeze(Time.new(2001, 4, 5, 18, 30)) do
|
103
|
+
benchmark_run.mark_end
|
104
|
+
end
|
105
|
+
|
106
|
+
assert_equal Time.new(2001, 4, 5, 18, 30), benchmark_run.ended_at
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_ok
|
110
|
+
benchmark_run = BenchmarkRun.new
|
111
|
+
assert benchmark_run.ok?
|
112
|
+
|
113
|
+
benchmark_run.stub :benchmarks, [ Minitest::Mock.new.expect(:ok?, true) ] do
|
114
|
+
assert benchmark_run.ok?
|
115
|
+
end
|
116
|
+
|
117
|
+
benchmark_run.stub :benchmarks, [ Minitest::Mock.new.expect(:ok?, true), Minitest::Mock.new.expect(:ok?, true) ] do
|
118
|
+
assert benchmark_run.ok?
|
119
|
+
end
|
120
|
+
|
121
|
+
benchmark_run.stub :benchmarks, [ Minitest::Mock.new.expect(:ok?, false), Minitest::Mock.new.expect(:ok?, true) ] do
|
122
|
+
assert !benchmark_run.ok?
|
123
|
+
end
|
124
|
+
|
125
|
+
benchmark_run.stub :benchmarks, [ Minitest::Mock.new.expect(:ok?, false), Minitest::Mock.new.expect(:ok?, false) ] do
|
126
|
+
assert !benchmark_run.ok?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require_relative "../../lib/celluloid_benchmark/benchmark"
|
3
|
+
|
4
|
+
module CelluloidBenchmark
|
5
|
+
class BenchmarkTest < Minitest::Test
|
6
|
+
def test_require_label
|
7
|
+
assert_raises ArgumentError do
|
8
|
+
Benchmark.new(nil, 1, [], [])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_require_threshold_above_zero
|
13
|
+
assert_raises ArgumentError do
|
14
|
+
Benchmark.new("homepage", 0, nil, nil)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_defaults
|
19
|
+
benchmark = Benchmark.new("homepage", nil, nil, nil)
|
20
|
+
|
21
|
+
assert_equal 3, benchmark.threshold, "default threshold"
|
22
|
+
|
23
|
+
assert !benchmark.response_codes.nil?, "response_codes default"
|
24
|
+
assert benchmark.response_codes.empty?, "response_codes default"
|
25
|
+
|
26
|
+
assert !benchmark.response_times.nil?, "response_times default"
|
27
|
+
assert benchmark.response_times.empty?, "response_times default"
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_response_times_ok_for_empty_benchmark
|
31
|
+
benchmark = Benchmark.new("homepage", nil, nil, nil)
|
32
|
+
assert benchmark.ok?, "Empty Benchmark should be OK"
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_ok_if_response_codes_and_times_ok
|
36
|
+
benchmark = Benchmark.new("homepage", nil, nil, nil)
|
37
|
+
|
38
|
+
benchmark.stub(:response_times_ok?, true) do
|
39
|
+
benchmark.stub(:response_codes_ok?, true) do
|
40
|
+
assert benchmark.ok?, "Benchmark.ok? times OK and codes OK"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
benchmark.stub(:response_times_ok?, false) do
|
45
|
+
benchmark.stub(:response_codes_ok?, true) do
|
46
|
+
assert !benchmark.ok?, "Benchmark.ok? times not OK and codes OK"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
benchmark.stub(:response_times_ok?, true) do
|
51
|
+
benchmark.stub(:response_codes_ok?, false) do
|
52
|
+
assert !benchmark.ok?, "Benchmark.ok? times OK and codes not OK"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
benchmark.stub(:response_times_ok?, false) do
|
57
|
+
benchmark.stub(:response_codes_ok?, false) do
|
58
|
+
assert !benchmark.ok?, "Benchmark.ok? times not OK and codes not OK"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_blank_response_time_ok
|
64
|
+
benchmark = Benchmark.new("homepage", nil, nil, nil)
|
65
|
+
assert benchmark.response_times_ok?
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_blank_response_codes_ok
|
69
|
+
benchmark = Benchmark.new("homepage", nil, nil, nil)
|
70
|
+
assert benchmark.response_codes_ok?
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_response_times
|
74
|
+
benchmark = Benchmark.new("test", 1, [ 0.99, 0.9, 1.01 ], nil)
|
75
|
+
assert benchmark.response_times_ok?
|
76
|
+
|
77
|
+
benchmark = Benchmark.new("test", 1, [ 1.000001, 1, 1 ], nil)
|
78
|
+
assert !benchmark.response_times_ok?
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_response_codes
|
82
|
+
benchmark = Benchmark.new("test", nil, [], [])
|
83
|
+
assert benchmark.response_codes_ok?
|
84
|
+
|
85
|
+
benchmark = Benchmark.new("test", nil, [], [ 500 ])
|
86
|
+
assert !benchmark.response_codes_ok?
|
87
|
+
|
88
|
+
benchmark = Benchmark.new("test", nil, [], [ 200 ])
|
89
|
+
assert benchmark.response_codes_ok?
|
90
|
+
|
91
|
+
benchmark = Benchmark.new("test", nil, [], [ 200, 500 ])
|
92
|
+
assert !benchmark.response_codes_ok?
|
93
|
+
|
94
|
+
benchmark = Benchmark.new("test", nil, [], [ 200, 302, 304, 401 ])
|
95
|
+
assert benchmark.response_codes_ok?
|
96
|
+
|
97
|
+
benchmark = Benchmark.new("test", nil, [], [ 403, 200, 302, 401 ])
|
98
|
+
assert !benchmark.response_codes_ok?
|
99
|
+
|
100
|
+
benchmark = Benchmark.new("test", nil, [], [ 410, 200, 302, 401 ])
|
101
|
+
assert !benchmark.response_codes_ok?
|
102
|
+
|
103
|
+
benchmark = Benchmark.new("test", nil, [], [ 309, 200, 302, 401 ])
|
104
|
+
assert !benchmark.response_codes_ok?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require_relative "../../lib/celluloid_benchmark/runner"
|
3
|
+
require "fakeweb"
|
4
|
+
|
5
|
+
FakeWeb.allow_net_connect = false
|
6
|
+
|
7
|
+
module CelluloidBenchmark
|
8
|
+
class BenchmarkRunnerTest < Minitest::Test
|
9
|
+
def setup
|
10
|
+
# minitest and Celluloid both use at_exit
|
11
|
+
Celluloid.boot
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_run
|
15
|
+
FakeWeb.register_uri(:get, "https://github.com/scottwillson/celluloid-benchmark", :body => "<html>OK</html>")
|
16
|
+
benchmark_run = Runner.run(File.dirname(__FILE__) + "/../files/runner_test_session.rb", 0.1)
|
17
|
+
|
18
|
+
benchmarks = benchmark_run.benchmarks
|
19
|
+
assert_equal 1, benchmarks.size
|
20
|
+
benchmark = benchmarks.first
|
21
|
+
assert benchmark.ok?, "benchmark.ok?"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "celluloid"
|
3
|
+
require_relative "../../lib/celluloid_benchmark/visitor"
|
4
|
+
|
5
|
+
module CelluloidBenchmark
|
6
|
+
# Visitor#run_session is the central purpose of this gem, but best tested in an integration test,
|
7
|
+
# not a unit test
|
8
|
+
class VisitorTest < Minitest::Test
|
9
|
+
class MockBrowser
|
10
|
+
attr_accessor :post_connect_hooks, :pre_connect_hooks, :uris
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@pre_connect_hooks = []
|
14
|
+
@post_connect_hooks = []
|
15
|
+
@uris = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(uri)
|
19
|
+
uris << uri
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup
|
24
|
+
# minitest and Celluloid both use at_exit
|
25
|
+
Celluloid.boot
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_run_session
|
29
|
+
browser = MockBrowser.new
|
30
|
+
visitor = Visitor.new(browser)
|
31
|
+
session = File.read(File.dirname(__FILE__) + "/../files/runner_test_session.rb")
|
32
|
+
|
33
|
+
elapsed_time = visitor.run_session(session, nil, 0.01)
|
34
|
+
|
35
|
+
assert !elapsed_time.nil?, "elapsed_time should not be nil"
|
36
|
+
assert elapsed_time > 0, "elapsed_time should be greater than zero, but was #{elapsed_time}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_benchmark
|
40
|
+
browser = MockBrowser.new
|
41
|
+
visitor = Visitor.new(browser)
|
42
|
+
|
43
|
+
visitor.benchmark("purchase_page", 0.25)
|
44
|
+
|
45
|
+
assert_equal "purchase_page", visitor.current_request_label, "current_request_label"
|
46
|
+
assert_equal 0.25, visitor.current_request_threshold, "current_request_threshold"
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_random_data
|
50
|
+
browser = MockBrowser.new
|
51
|
+
visitor = Visitor.new(browser)
|
52
|
+
|
53
|
+
data_sources = Minitest::Mock.new
|
54
|
+
data_source = Minitest::Mock.new
|
55
|
+
|
56
|
+
data_source.expect :sample, 3
|
57
|
+
data_sources.expect :[], data_source, [ String ]
|
58
|
+
|
59
|
+
visitor.data_sources = data_sources
|
60
|
+
|
61
|
+
assert_equal 3, visitor.random_data("ids")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: celluloid-benchmark
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Scott Willson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2014-01-09 00:00:00 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: celluloid
|
16
|
+
prerelease: false
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: "0.15"
|
22
|
+
type: :runtime
|
23
|
+
version_requirements: *id001
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: mechanize
|
26
|
+
prerelease: false
|
27
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: "2.7"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id002
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: racc
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: "1"
|
42
|
+
type: :runtime
|
43
|
+
version_requirements: *id003
|
44
|
+
description: |-
|
45
|
+
Celluloid Benchmark realistically load tests websites. Write expressive, concise load tests in Ruby. Use Rubinius and Celluloid
|
46
|
+
forpec high concurrency. Use Mechanize for a realistic (albeit non-JavaScript) browser client.
|
47
|
+
email: scott.willson@gmail.com
|
48
|
+
executables:
|
49
|
+
- celluloid-benchmark
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files: []
|
53
|
+
|
54
|
+
files:
|
55
|
+
- LICENSE
|
56
|
+
- README.md
|
57
|
+
- bin/celluloid-benchmark
|
58
|
+
- lib/celluloid_benchmark.rb
|
59
|
+
- test/files/runner_test_session.rb
|
60
|
+
- test/integration/config.ru
|
61
|
+
- test/integration/html/404.html
|
62
|
+
- test/integration/html/index.html
|
63
|
+
- test/integration/integration_test.rb
|
64
|
+
- test/integration/test_session.rb
|
65
|
+
- test/unit/benchmark_run_test.rb
|
66
|
+
- test/unit/benchmark_test.rb
|
67
|
+
- test/unit/runner_test.rb
|
68
|
+
- test/unit/visitor_test.rb
|
69
|
+
homepage: https://github.com/scottwillson/celluloid-benchmark
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- &id004
|
82
|
+
- ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- *id004
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.2.1
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Pure Ruby, realistic, website load test tool
|
95
|
+
test_files:
|
96
|
+
- test/files/runner_test_session.rb
|
97
|
+
- test/integration/config.ru
|
98
|
+
- test/integration/integration_test.rb
|
99
|
+
- test/integration/test_session.rb
|
100
|
+
- test/unit/benchmark_run_test.rb
|
101
|
+
- test/unit/benchmark_test.rb
|
102
|
+
- test/unit/runner_test.rb
|
103
|
+
- test/unit/visitor_test.rb
|
104
|
+
- test/integration/html/404.html
|
105
|
+
- test/integration/html/index.html
|