stella 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +14 -10
- data/Rakefile +22 -36
- data/lib/daemonize.rb +56 -0
- data/lib/stella/adapter/ab.rb +49 -39
- data/lib/stella/adapter/base.rb +17 -8
- data/lib/stella/adapter/httperf.rb +24 -18
- data/lib/stella/adapter/pcap_watcher.rb +1 -1
- data/lib/stella/adapter/siege.rb +15 -12
- data/lib/stella/cli/localtest.rb +2 -3
- data/lib/stella/cli/sysinfo.rb +0 -1
- data/lib/stella/cli.rb +10 -55
- data/lib/stella/command/base.rb +0 -62
- data/lib/stella/command/localtest.rb +35 -36
- data/lib/stella/data/domain.rb +18 -11
- data/lib/stella/data/http.rb +23 -16
- data/lib/stella/logger.rb +29 -19
- data/lib/stella/response.rb +5 -2
- data/lib/stella/storable.rb +138 -52
- data/lib/stella/support.rb +107 -8
- data/lib/stella/sysinfo.rb +26 -16
- data/lib/stella/test/definition.rb +1 -1
- data/lib/stella/test/run/summary.rb +23 -13
- data/lib/stella/test/stats.rb +114 -0
- data/lib/stella/text/resource.rb +1 -1
- data/lib/stella.rb +29 -4
- data/lib/utils/mathutil.rb +0 -76
- data/lib/utils/stats.rb +88 -0
- data/lib/win32/Console/ANSI.rb +305 -305
- data/lib/win32/Console.rb +970 -970
- data/support/ruby-pcap-takuma-patch.txt +13 -13
- data/support/text/en.yaml +11 -8
- data/support/text/nl.yaml +7 -1
- data/{spec/show-agents_spec.rb → tests/01-util_test.rb} +0 -0
- data/tests/02-stella-util_test.rb +42 -0
- data/tests/10-stella_test.rb +104 -0
- data/tests/11-stella-storable_test.rb +68 -0
- data/tests/60-stella-command_test.rb +248 -0
- data/tests/80-stella-cli_test.rb +45 -0
- data/tests/spec-helper.rb +31 -0
- data/vendor/{frylock/README.textile → drydock/LICENSE.txt} +2 -52
- data/vendor/drydock/README.textile +57 -0
- data/vendor/{frylock → drydock}/bin/example +14 -14
- data/vendor/{frylock/frylock.gemspec → drydock/drydock.gemspec} +1 -1
- data/vendor/{frylock/lib/frylock → drydock/lib/drydock}/exceptions.rb +1 -1
- data/vendor/{frylock/lib/frylock.rb → drydock/lib/drydock.rb} +8 -8
- data/vendor/{frylock → drydock}/test/command_test.rb +0 -0
- metadata +34 -61
- data/lib/stella/test/base.rb +0 -38
- data/lib/stella/test/summary.rb +0 -82
- data/vendor/hitimes-0.4.0/HISTORY +0 -28
- data/vendor/hitimes-0.4.0/LICENSE.txt +0 -19
- data/vendor/hitimes-0.4.0/README +0 -80
- data/vendor/hitimes-0.4.0/Rakefile +0 -63
- data/vendor/hitimes-0.4.0/examples/benchmarks.rb +0 -86
- data/vendor/hitimes-0.4.0/examples/stats.rb +0 -29
- data/vendor/hitimes-0.4.0/ext/extconf.rb +0 -15
- data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +0 -21
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +0 -20
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +0 -16
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +0 -27
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +0 -340
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +0 -73
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +0 -242
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +0 -30
- data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +0 -178
- data/vendor/hitimes-0.4.0/ext/rbconfig.rb +0 -178
- data/vendor/hitimes-0.4.0/gemspec.rb +0 -54
- data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +0 -23
- data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +0 -54
- data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +0 -29
- data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +0 -223
- data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +0 -42
- data/vendor/hitimes-0.4.0/lib/hitimes.rb +0 -24
- data/vendor/hitimes-0.4.0/spec/interval_spec.rb +0 -115
- data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +0 -34
- data/vendor/hitimes-0.4.0/spec/paths_spec.rb +0 -14
- data/vendor/hitimes-0.4.0/spec/spec_helper.rb +0 -6
- data/vendor/hitimes-0.4.0/spec/stats_spec.rb +0 -72
- data/vendor/hitimes-0.4.0/spec/timer_spec.rb +0 -105
- data/vendor/hitimes-0.4.0/spec/version_spec.rb +0 -27
- data/vendor/hitimes-0.4.0/tasks/announce.rake +0 -39
- data/vendor/hitimes-0.4.0/tasks/config.rb +0 -107
- data/vendor/hitimes-0.4.0/tasks/distribution.rake +0 -53
- data/vendor/hitimes-0.4.0/tasks/documentation.rake +0 -33
- data/vendor/hitimes-0.4.0/tasks/extension.rake +0 -64
- data/vendor/hitimes-0.4.0/tasks/rspec.rake +0 -31
- data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +0 -52
- data/vendor/hitimes-0.4.0/tasks/utils.rb +0 -80
@@ -1,22 +1,22 @@
|
|
1
|
-
diff -ur pcap
|
2
|
-
--- pcap
|
3
|
-
+++ pcap-
|
1
|
+
diff -ur pcap/Pcap.c pcap-modified/Pcap.c
|
2
|
+
--- pcap/Pcap.c 2000-08-13 01:56:31.000000000 -0400
|
3
|
+
+++ pcap-modified/Pcap.c 2009-01-02 10:55:49.000000000 -0500
|
4
4
|
@@ -782,9 +782,9 @@
|
5
5
|
/* define class PcapStat */
|
6
6
|
cPcapStat = rb_funcall(rb_cStruct, rb_intern("new"), 4,
|
7
|
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
-
|
11
|
-
+
|
12
|
-
+
|
13
|
-
+
|
7
|
+
Qnil,
|
8
|
+
- INT2NUM(rb_intern("recv")),
|
9
|
+
- INT2NUM(rb_intern("drop")),
|
10
|
+
- INT2NUM(rb_intern("ifdrop")));
|
11
|
+
+ ID2SYM(rb_intern("recv")),
|
12
|
+
+ ID2SYM(rb_intern("drop")),
|
13
|
+
+ ID2SYM(rb_intern("ifdrop")));
|
14
14
|
rb_define_const(mPcap, "Stat", cPcapStat);
|
15
15
|
|
16
16
|
/* define exception classes */
|
17
|
-
diff -ur pcap
|
18
|
-
--- pcap
|
19
|
-
+++ pcap-
|
17
|
+
diff -ur pcap/packet.c pcap-modified/packet.c
|
18
|
+
--- pcap/packet.c 2000-08-13 02:56:15.000000000 -0400
|
19
|
+
+++ pcap-modified/packet.c 2009-01-02 10:56:07.000000000 -0500
|
20
20
|
@@ -17,8 +17,8 @@
|
21
21
|
|
22
22
|
VALUE cPacket;
|
data/support/text/en.yaml
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
:fullname: english
|
4
4
|
:updated: 2008-12-20
|
5
5
|
:enabled: true
|
6
|
+
|
7
|
+
:stellaaahhhh: "Stellaaahhhh!"
|
8
|
+
|
6
9
|
:text_available_languages: "Available languages: %s"
|
7
10
|
|
8
11
|
|
@@ -29,21 +32,21 @@
|
|
29
32
|
|
30
33
|
Examples:
|
31
34
|
|
32
|
-
# Run Apache Bench with
|
33
|
-
$ stella -x 5 -w 0.5 ab -n
|
35
|
+
# Run Apache Bench with 5 users, 20 requests each. Repeat 5 times.
|
36
|
+
$ stella -x 5 -w 0.5 ab -n 100 -c 5 http://stellaaahhhh.com/
|
34
37
|
|
35
|
-
# Run Siege with
|
36
|
-
$ stella --rampup=
|
38
|
+
# Run Siege with 10 users ramping up to 25, 1 requests each with a Linux FireFox 3 user agent
|
39
|
+
$ stella --rampup=5,20 --agent=firefox-3-linux siege -c 10 -r 1 -b http://stellaaahhhh.com/
|
37
40
|
|
38
41
|
# Display available user agent strings
|
39
42
|
$ stella agents -l
|
40
43
|
|
41
|
-
# Launch a proxy to monitor HTTP traffic.
|
42
|
-
$ stella -vv watch -
|
44
|
+
# Launch a proxy to monitor HTTP traffic.
|
45
|
+
$ stella -vv watch -P -p 3114
|
43
46
|
|
44
47
|
# Monitor network traffic with packet sniffer (requires unix and root access)
|
45
|
-
$ stella watch -
|
46
|
-
$ stella watch -
|
48
|
+
$ stella watch -C dns
|
49
|
+
$ stella watch -C -p 3456 http
|
47
50
|
|
48
51
|
|
49
52
|
User-Agent Examples (--agent):
|
data/support/text/nl.yaml
CHANGED
File without changes
|
@@ -0,0 +1,42 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
require 'spec-helper'
|
3
|
+
|
4
|
+
#require 'stella/support'
|
5
|
+
|
6
|
+
|
7
|
+
describe "Stella::Util" do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
load 'stella.rb'
|
11
|
+
load 'stella/cli.rb'
|
12
|
+
Stella.debug = false
|
13
|
+
end
|
14
|
+
|
15
|
+
it "knows how to convert ff-3.2-osx and ff,3.2,osx into an array" do
|
16
|
+
Stella::Util.expand_str("opera,3.2,linux").should.be.kind_of Array
|
17
|
+
Stella::Util.expand_str("ff,3.2,osx").should.equal %w{ff 3.2 osx}
|
18
|
+
Stella::Util.expand_str("ie-2-win").should.equal %w{ie 2 win}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can read and index the useragents.txt file" do
|
22
|
+
ua_index = Stella::Util.process_useragents(File.join(STELLA_HOME, 'support', 'useragents.txt'))
|
23
|
+
ua = Stella::Util.find_agent(ua_index, :ff, 3, :linux)
|
24
|
+
ua.should.be.kind_of String
|
25
|
+
ua.should.match /Firefox\/3/i
|
26
|
+
ua.should.match /linux/i
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can capture STDOUT and STDERR output from a command" do
|
30
|
+
command = (Stella::SYSINFO.impl == :windows) ? "dir" : "ls"
|
31
|
+
Stella::Util.capture_output("#{command}") do |stdout, stderr|
|
32
|
+
stdout.should.be.instance_of Array
|
33
|
+
stdout.size.should.be > 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can generate random strings of specified length (29)" do
|
38
|
+
str = Stella::Util.strand(29)
|
39
|
+
str.should.be.kind_of String
|
40
|
+
str.size.should.equal 29
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
require 'spec-helper'
|
3
|
+
|
4
|
+
|
5
|
+
describe 'Stella' do
|
6
|
+
before(:all) do
|
7
|
+
require 'stella'
|
8
|
+
Stella.debug = false
|
9
|
+
end
|
10
|
+
|
11
|
+
it "determine basic system information" do
|
12
|
+
|
13
|
+
Stella.sysinfo.should.be.instance_of Stella::SystemInfo
|
14
|
+
Stella.sysinfo.uptime.should.be.instance_of Float
|
15
|
+
Stella.sysinfo.uptime.should.be > 0
|
16
|
+
Stella.sysinfo.hostname.should.be.instance_of String
|
17
|
+
Stella.sysinfo.hostname.size.should.be > 0
|
18
|
+
Stella.sysinfo.ipaddress.should.be.instance_of String
|
19
|
+
Stella.sysinfo.ipaddress.size.should.be > 0
|
20
|
+
end
|
21
|
+
|
22
|
+
it "create a working global logger" do
|
23
|
+
Stella::LOGGER.should.be.instance_of Stella::Logger
|
24
|
+
infos = capture(:stdout) do
|
25
|
+
Stella.info("Stella has a kind heart")
|
26
|
+
end
|
27
|
+
infos.should.be.instance_of String
|
28
|
+
infos.chomp.should.equal "Stella has a kind heart"
|
29
|
+
|
30
|
+
errors = capture(:stderr) do
|
31
|
+
Stella.error("and loves the unexpected!", "ERROR: ")
|
32
|
+
end
|
33
|
+
errors.should.be.instance_of String
|
34
|
+
errors.chomp.should.equal "ERROR: and loves the unexpected!"
|
35
|
+
end
|
36
|
+
|
37
|
+
#it "have at least one language available" do
|
38
|
+
# Stella::TEXT.available_language?('en')
|
39
|
+
#end
|
40
|
+
|
41
|
+
it "provide a convenient text interface" do
|
42
|
+
Stella.text(:stellaaahhhh).should.equal "Stellaaahhhh!"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
#describe 'Options' do
|
50
|
+
# include Sinatra::Test
|
51
|
+
#
|
52
|
+
# before do
|
53
|
+
# @app = Class.new(Sinatra::Base)
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# it 'sets options to literal values' do
|
57
|
+
# @app.set(:foo, 'bar')
|
58
|
+
# @app.should.respond_to? :foo
|
59
|
+
# @app.foo.should.equal 'bar'
|
60
|
+
# end
|
61
|
+
#end
|
62
|
+
|
63
|
+
# it 'includes Rack::Utils' do
|
64
|
+
# Sinatra::Base.should.include Rack::Utils
|
65
|
+
# end
|
66
|
+
|
67
|
+
__END__
|
68
|
+
|
69
|
+
TEST-SPEC NOTES
|
70
|
+
|
71
|
+
Test/Unit wrappers:
|
72
|
+
|
73
|
+
assert_equal: should.equal, ==
|
74
|
+
assert_not_equal: should.not.equal, should.not ==
|
75
|
+
assert_same: should.be
|
76
|
+
assert_not_same: should.not.be
|
77
|
+
assert_nil: should.be.nil
|
78
|
+
assert_not_nil: should.not.be.nil
|
79
|
+
assert_in_delta: should.be.close
|
80
|
+
assert_match: should.match, =~
|
81
|
+
assert_no_match: should.not.match, should.not =~
|
82
|
+
assert_instance_of: should.be.an.instance_of
|
83
|
+
assert_kind_of: should.be.a.kind_of
|
84
|
+
assert_respond_to: should.respond_to
|
85
|
+
assert_raise: should.raise
|
86
|
+
assert_nothing_raised: should.not.raise
|
87
|
+
assert_throws: should.throw
|
88
|
+
assert_nothing_thrown: should.not.throw
|
89
|
+
assert_block: should.satisfy
|
90
|
+
|
91
|
+
Test/Spec convenience:
|
92
|
+
* should.not.satisfy
|
93
|
+
* should.include
|
94
|
+
* a.should.predicate (works like assert a.predicate?)
|
95
|
+
* a.should.be operator (where operator is one of >, >=, <, <= or ===)
|
96
|
+
* should.output (require test/spec/should-output)
|
97
|
+
|
98
|
+
Messaging/Blaming:
|
99
|
+
RUBY_VERSION.should.messaging("Ruby too old.").be > "1.8.4"
|
100
|
+
(1 + 1).should.blaming("weird math").not.equal 11
|
101
|
+
|
102
|
+
Disable tests with xspecify/xit:
|
103
|
+
When you use xspecify/xit, you also can drop the block
|
104
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
require 'spec-helper'
|
3
|
+
|
4
|
+
require 'time'
|
5
|
+
require 'date'
|
6
|
+
require 'stella/storable'
|
7
|
+
|
8
|
+
class TeaCup < Stella::Storable
|
9
|
+
|
10
|
+
field :owner => String
|
11
|
+
field :volume => Float
|
12
|
+
field :washed => TrueClass
|
13
|
+
field :last_used => Time
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
describe 'Stella::Storable' do
|
19
|
+
FILE_PATH = File.join(STELLA_HOME, "test-spec-tmp", "tc")
|
20
|
+
RECORD = {
|
21
|
+
:owner => "stella",
|
22
|
+
:volume => 97.01,
|
23
|
+
:washed => true,
|
24
|
+
:last_used => (Time.now-100).utc
|
25
|
+
}
|
26
|
+
|
27
|
+
before(:all) do
|
28
|
+
FileUtil.create_dir(File.dirname(FILE_PATH), '.')
|
29
|
+
end
|
30
|
+
|
31
|
+
before(:each) do
|
32
|
+
@generated_files ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
after(:each) do
|
36
|
+
end
|
37
|
+
|
38
|
+
after(:all) do
|
39
|
+
(@generated_files || []).each do |file|
|
40
|
+
File.unlink(@file) if File.exists?(@file)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Stella::Storable::SUPPORTED_FORMATS.each do |format|
|
45
|
+
next if format == 'json' && !::HAS_JSON
|
46
|
+
it "creates object from hash and saves in #{format} format" do
|
47
|
+
teacup = TeaCup.from_hash(RECORD)
|
48
|
+
path = "#{FILE_PATH}.#{format}"
|
49
|
+
@generated_files << path
|
50
|
+
teacup.to_file(path)
|
51
|
+
File.exists?(path).should.equal true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Stella::Storable::SUPPORTED_FORMATS.each do |format|
|
56
|
+
next if format == 'json' && !::HAS_JSON
|
57
|
+
it "loads object from #{format} file" do
|
58
|
+
teacup = TeaCup.from_file("#{FILE_PATH}.#{format}")
|
59
|
+
tchash = teacup.to_hash
|
60
|
+
tchash.should.be.instance_of Hash
|
61
|
+
tchash.keys.should.equal RECORD.keys
|
62
|
+
tchash[:volume].should.equal RECORD[:volume]
|
63
|
+
tchash[:last_used].to_i.should.equal RECORD[:last_used].to_i
|
64
|
+
tchash[:washed].should.equal RECORD[:washed]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'spec-helper'
|
4
|
+
require 'stella'
|
5
|
+
require 'mongrel'
|
6
|
+
require 'uri'
|
7
|
+
require 'net/http'
|
8
|
+
|
9
|
+
class TestHandler < Mongrel::HttpHandler
|
10
|
+
attr_reader :ran_test
|
11
|
+
attr_accessor :server
|
12
|
+
def process(request, response)
|
13
|
+
@ran_test = true
|
14
|
+
response.start do |head,out|
|
15
|
+
head["Content-Type"] = "text/plain"
|
16
|
+
results = "Stellaaahhhh!#{$/}"
|
17
|
+
results << 'X'*1000 # Pump up the volume (1KB)
|
18
|
+
out << results
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def get(uri)
|
25
|
+
uri = URI.parse(uri) unless uri.kind_of? URI
|
26
|
+
Net::HTTP.get(uri)
|
27
|
+
end
|
28
|
+
|
29
|
+
at_exit do
|
30
|
+
@server.stop(true) if @server
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "Stella::Command::LoadTest" do
|
34
|
+
WORKDIR = File.join(STELLA_HOME, 'test-spec-tmp')
|
35
|
+
HOST = '127.0.0.1'
|
36
|
+
PORT = 3114 + $$ % 1000
|
37
|
+
TVUSERS = 10
|
38
|
+
TCOUNT = 120 # This needs to be divisible evenly by TVUSERS
|
39
|
+
TREPS = 3
|
40
|
+
TMSG = "This is a build test"
|
41
|
+
|
42
|
+
|
43
|
+
before(:all) do
|
44
|
+
Stella.debug = false
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
after(:all) do
|
49
|
+
# remove_dir does not seem to work on Windows
|
50
|
+
FileUtils.remove_entry(WORKDIR, true) if File.exists? WORKDIR
|
51
|
+
end
|
52
|
+
|
53
|
+
it "start a local test server" do
|
54
|
+
begin
|
55
|
+
capture(:stdout) do
|
56
|
+
@server = Mongrel::HttpServer.new(HOST, PORT)
|
57
|
+
@handler = TestHandler.new
|
58
|
+
@server.register("/test", @handler)
|
59
|
+
@server.run
|
60
|
+
res = get("http://#{HOST}:#{PORT}/test")
|
61
|
+
res.should.be.kind_of String
|
62
|
+
res.split($/).first.should.equal "Stellaaahhhh!" # We can ignore the other content
|
63
|
+
end
|
64
|
+
rescue Interrupt
|
65
|
+
@server.stop(true) if @server
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
it "run a local performance test with Apache Bench" do
|
72
|
+
puts
|
73
|
+
testdef = Stella::Test::Definition.new
|
74
|
+
adapter = Stella::Adapter::ApacheBench.new(["-c", "#{TVUSERS}", "-n", "#{TCOUNT}", "http://#{HOST}:#{PORT}/test"])
|
75
|
+
lt = Stella::LocalTest.new
|
76
|
+
files = %w{ab-percentiles.log ab-requests.log}
|
77
|
+
execute_load_test(lt, testdef, adapter, files)
|
78
|
+
lt.test_stats.transactions_total.should.equal TCOUNT * TREPS
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
it "run a local performance test with Siege (unix only)" do
|
83
|
+
return if Stella.sysinfo.impl == :windows
|
84
|
+
puts
|
85
|
+
testdef = Stella::Test::Definition.new
|
86
|
+
adapter = Stella::Adapter::Siege.new(["-c", "#{TVUSERS}", "-r", "#{TCOUNT / TVUSERS}", "--benchmark", "http://#{HOST}:#{PORT}/test"])
|
87
|
+
lt = Stella::LocalTest.new
|
88
|
+
files = %w{siege.log siegerc}
|
89
|
+
execute_load_test(lt, testdef, adapter, files)
|
90
|
+
lt.test_stats.transactions_total.should.equal TCOUNT * TREPS
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
it "run a local performance test with Httperf (unix only)" do
|
95
|
+
return if Stella.sysinfo.impl == :windows
|
96
|
+
puts
|
97
|
+
testdef = Stella::Test::Definition.new
|
98
|
+
adapter = Stella::Adapter::Httperf.new(
|
99
|
+
["--wsess=#{(TCOUNT / TVUSERS).to_i},#{TVUSERS},0", "--rate=#{TCOUNT / TVUSERS}", "--uri=/test", "--server=#{HOST}", "--port=#{PORT}"]
|
100
|
+
)
|
101
|
+
lt = Stella::LocalTest.new
|
102
|
+
files = %w{}
|
103
|
+
execute_load_test(lt, testdef, adapter, files)
|
104
|
+
lt.test_stats.transactions_total.should.equal TCOUNT * TREPS
|
105
|
+
end
|
106
|
+
|
107
|
+
it "create a symlink to the latest test directory (unix only)" do
|
108
|
+
return if Stella.sysinfo.impl == :windows
|
109
|
+
puts
|
110
|
+
testdef = Stella::Test::Definition.new
|
111
|
+
adapter = Stella::Adapter::ApacheBench.new(["-c", TVUSERS.to_s, "-n", TCOUNT.to_s, "http://#{HOST}:#{PORT}/test"])
|
112
|
+
lt = Stella::LocalTest.new
|
113
|
+
execute_load_test(lt, testdef, adapter)
|
114
|
+
File.symlink?(lt.test_path_symlink).should.equal true
|
115
|
+
lt.test_stats.transactions_total.should.equal TREPS * TCOUNT
|
116
|
+
end
|
117
|
+
|
118
|
+
it "run in quiet mode" do
|
119
|
+
puts
|
120
|
+
testdef = Stella::Test::Definition.new
|
121
|
+
adapter = Stella::Adapter::ApacheBench.new(["-c", TVUSERS.to_s, "-n", TCOUNT.to_s, "http://#{HOST}:#{PORT}/test"])
|
122
|
+
lt = Stella::LocalTest.new
|
123
|
+
lt.quiet = true
|
124
|
+
output = capture(:stdout) do
|
125
|
+
execute_load_test(lt, testdef, adapter)
|
126
|
+
end
|
127
|
+
output.split($/).size.should.equal 2
|
128
|
+
lt.test_stats.transactions_total.should.equal TREPS * TCOUNT
|
129
|
+
end
|
130
|
+
|
131
|
+
Stella::Storable::SUPPORTED_FORMATS.each do |format|
|
132
|
+
next if format == 'json' && !HAS_JSON
|
133
|
+
it "create summaries in #{format}" do
|
134
|
+
puts
|
135
|
+
testdef = Stella::Test::Definition.new
|
136
|
+
adapter = Stella::Adapter::ApacheBench.new(["-c", TVUSERS.to_s, "-n", TCOUNT.to_s, "http://#{HOST}:#{PORT}/test"])
|
137
|
+
lt = Stella::LocalTest.new
|
138
|
+
lt.format = format
|
139
|
+
execute_load_test(lt, testdef, adapter)
|
140
|
+
File.exists?(File.join(lt.test_path, "STATS.#{format}")).should.equal true
|
141
|
+
lt.test_stats.transactions_total.should.equal TREPS * TCOUNT
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "run with a warmup with a 50% load factor" do
|
146
|
+
puts
|
147
|
+
testdef = Stella::Test::Definition.new
|
148
|
+
adapter = Stella::Adapter::ApacheBench.new(["-c", TVUSERS.to_s, "-n", TCOUNT.to_s, "http://#{HOST}:#{PORT}/test"])
|
149
|
+
lt = Stella::LocalTest.new
|
150
|
+
testdef.warmup = 0.5 # this means half of the number of requests
|
151
|
+
execute_load_test(lt, testdef, adapter)
|
152
|
+
File.exists?(File.join(lt.test_path, "STATS.yaml")).should.equal true
|
153
|
+
|
154
|
+
summary_file = File.join(lt.test_path, "warmup", "SUMMARY.yaml")
|
155
|
+
File.exists?(summary_file).should.blaming("Summary file").equal true
|
156
|
+
summary = Stella::Test::Run::Summary.from_file(summary_file)
|
157
|
+
summary.transactions.should.blaming("Warmup transaction count").equal(TCOUNT * 0.5)
|
158
|
+
lt.test_stats.transactions_total.should.equal TREPS * TCOUNT
|
159
|
+
end
|
160
|
+
|
161
|
+
it "run with a rampup" do
|
162
|
+
puts
|
163
|
+
testdef = Stella::Test::Definition.new
|
164
|
+
adapter = Stella::Adapter::ApacheBench.new(["-c", TVUSERS.to_s, "-n", TCOUNT.to_s, "http://#{HOST}:#{PORT}/test"])
|
165
|
+
lt = Stella::LocalTest.new
|
166
|
+
testdef.rampup = [TVUSERS,TVUSERS*2]
|
167
|
+
execute_load_test(lt, testdef, adapter)
|
168
|
+
File.exists?(File.join(lt.test_path, "STATS.yaml")).should.equal true
|
169
|
+
lt.rampup_test_stats.transactions_total.should.equal TREPS * (TCOUNT) + (TREPS * TCOUNT*2)
|
170
|
+
end
|
171
|
+
|
172
|
+
xit "accept a sleep period between test runs"
|
173
|
+
xit "run with specified agents"
|
174
|
+
|
175
|
+
|
176
|
+
# +lt+ is an instance of Stella::Command::LoadTest
|
177
|
+
# +adapter+ is a Stella::Adapter object
|
178
|
+
# +files+ (optional) is a list of filenames that should exist in the
|
179
|
+
# testrun/2009-01-01/run01 directory after a test. When files is empty
|
180
|
+
# we return without running any tests. Note that when adding file names
|
181
|
+
# you don't need to include the standard files (STDOUT.txt, etc...).
|
182
|
+
# Return value is the Stella::Command::LoadTest instance
|
183
|
+
def execute_load_test(lt, testdef, adapter, files=nil)
|
184
|
+
testdef.message = TMSG
|
185
|
+
testdef.repetitions = TREPS
|
186
|
+
|
187
|
+
lt.working_directory = WORKDIR
|
188
|
+
lt.adapter = adapter
|
189
|
+
lt.testdef = testdef
|
190
|
+
|
191
|
+
files.push(%w{COMMAND.txt STDERR.txt STDOUT.txt}).flatten! unless files.nil?
|
192
|
+
|
193
|
+
begin
|
194
|
+
|
195
|
+
lt.run
|
196
|
+
|
197
|
+
lt.test_stats.should.be.instance_of Stella::Test::Stats
|
198
|
+
|
199
|
+
%w{
|
200
|
+
elapsed_time_avg throughput_avg response_time_avg
|
201
|
+
response_time_avg transaction_rate_avg vusers_avg
|
202
|
+
data_transferred_total transactions_total elapsed_time_total
|
203
|
+
}.each do |field|
|
204
|
+
lt.test_stats.send(field).should.blaming("Field: #{field}").be > 0
|
205
|
+
end
|
206
|
+
|
207
|
+
%w{
|
208
|
+
elapsed_time_sdev throughput_sdev transaction_rate_sdev
|
209
|
+
vusers_sdev response_time_sdev
|
210
|
+
}.each do |field|
|
211
|
+
lt.test_stats.send(field).should.blaming("Field: #{field}").be >= 0
|
212
|
+
end
|
213
|
+
|
214
|
+
total_check = lt.test_stats.failed_total + lt.test_stats.successful_total
|
215
|
+
total = lt.test_stats.transactions_total
|
216
|
+
|
217
|
+
total.should.blaming("Successful and Failed transaction count").equal total_check
|
218
|
+
lt.test_stats.availability.should.blaming("Field: availability").equal 100
|
219
|
+
|
220
|
+
unless files.nil?
|
221
|
+
# The test directory was created
|
222
|
+
File.exists?(lt.test_path).should.equal true
|
223
|
+
|
224
|
+
# The message was recorded
|
225
|
+
msg_path = File.join(lt.test_path, "MESSAGE.txt")
|
226
|
+
File.exists?(msg_path).should.equal true
|
227
|
+
File.read(msg_path).chomp.should.equal TMSG
|
228
|
+
|
229
|
+
# And all run output files were created
|
230
|
+
runnum = "00"
|
231
|
+
TREPS.times do
|
232
|
+
runnum = runnum.succ
|
233
|
+
files.each do |file|
|
234
|
+
file_short = File.join("run#{runnum}", file)
|
235
|
+
file_path = File.join(lt.test_path, file_short)
|
236
|
+
File.exists?(file_path).should.blaming("Cannot find: #{file_short}").equal true
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
rescue Interrupt
|
242
|
+
@server.stop(true) if @server
|
243
|
+
end
|
244
|
+
|
245
|
+
lt
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
require 'spec-helper'
|
3
|
+
|
4
|
+
#require 'stella/cli'
|
5
|
+
|
6
|
+
describe "Stella::CLI" do
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
Stella.debug = false
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
ARGV.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
it "auto-require CLI classes" do
|
17
|
+
cli_count = Dir.glob(File.join(STELLA_HOME, 'lib', 'stella', 'cli', "*.rb")).size - 1 # Minus base class
|
18
|
+
app = Stella::CLI.new(ARGV, STDIN)
|
19
|
+
app.commands.size.should.be >= cli_count # There can be multiple command aliases per class
|
20
|
+
end
|
21
|
+
|
22
|
+
xit "process STDIN"
|
23
|
+
|
24
|
+
it "split ARGV into global options, command name, and command-specific arguments" do
|
25
|
+
ARGV.push *%w{ -vv sysinfo -h --list localhost}
|
26
|
+
app = Stella::CLI.new(ARGV, STDIN)
|
27
|
+
app.should.be.kind_of Stella::CLI
|
28
|
+
app.options.verbose.should.equal 2
|
29
|
+
app.command_name.should.equal "sysinfo"
|
30
|
+
app.command_arguments.size.should.equal 3
|
31
|
+
end
|
32
|
+
|
33
|
+
it "run command and write to STDOUT" do
|
34
|
+
ARGV << "lang"
|
35
|
+
words = capture(:stdout) do
|
36
|
+
app = Stella::CLI.new(ARGV, STDIN)
|
37
|
+
app.should.be.kind_of Stella::CLI
|
38
|
+
app.command_name.should.equal "lang"
|
39
|
+
app.run
|
40
|
+
end
|
41
|
+
words.should.be.kind_of String
|
42
|
+
words.should.match "Available languages"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'test/spec'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
unless defined? STELLA_HOME
|
7
|
+
STELLA_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
8
|
+
$:.unshift(File.join(STELLA_HOME, 'lib')) # Make sure our local lib is first in line
|
9
|
+
end
|
10
|
+
|
11
|
+
# Stolen from http://github.com/wycats/thor
|
12
|
+
def capture(stream)
|
13
|
+
begin
|
14
|
+
stream = stream.to_s
|
15
|
+
eval "$#{stream} = StringIO.new"
|
16
|
+
yield
|
17
|
+
result = eval("$#{stream}").string
|
18
|
+
ensure
|
19
|
+
eval("$#{stream} = #{stream.upcase}")
|
20
|
+
end
|
21
|
+
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'json'
|
27
|
+
rescue LoadError
|
28
|
+
::HAS_JSON = false
|
29
|
+
else
|
30
|
+
::HAS_JSON = true
|
31
|
+
end
|
@@ -1,54 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Inspired by "github-gem":http://github.com/defunkt/github-gem
|
4
|
-
|
5
|
-
*Install:*
|
6
|
-
|
7
|
-
gem install bmizerany-sinatra
|
8
|
-
|
9
|
-
*Example:*
|
10
|
-
|
11
|
-
Let's say we want to run our app like this:
|
12
|
-
|
13
|
-
<pre><code>ruby script.rb hello</pre></code>
|
14
|
-
|
15
|
-
Then we write this:
|
16
|
-
|
17
|
-
<pre><code>require 'rubygems'
|
18
|
-
require 'bmizerany-frylock'
|
19
|
-
|
20
|
-
command :hello do
|
21
|
-
puts "Hello!"
|
22
|
-
end</pre></code>
|
23
|
-
|
24
|
-
If we want and optional name:
|
25
|
-
|
26
|
-
<pre><code>ruby script.rb hello Blake</pre></code>
|
27
|
-
|
28
|
-
Add a command with proc that has an arity of 1 and it will be matched instead of the first command
|
29
|
-
|
30
|
-
<pre><code>require 'rubygems'
|
31
|
-
require 'bmizerany-frylock'
|
32
|
-
|
33
|
-
command :hello do
|
34
|
-
puts "Hello!"
|
35
|
-
end
|
36
|
-
|
37
|
-
command :hello do |name|
|
38
|
-
puts "Hello #{name}!"
|
39
|
-
end</pre></code>
|
40
|
-
|
41
|
-
|
42
|
-
For further examples see: bin/example
|
43
|
-
|
44
|
-
|
45
|
-
*Contribute:*
|
46
|
-
|
47
|
-
I'm very open to patches! Please fork and send a pull request.
|
48
|
-
|
49
|
-
*LICENSE*
|
50
|
-
|
51
|
-
Copyright (c) 2008 Blake Mizerany
|
1
|
+
Copyright (c) 2008 Delano Mandelbaum
|
52
2
|
|
53
3
|
Permission is hereby granted, free of charge, to any person
|
54
4
|
obtaining a copy of this software and associated documentation
|
@@ -69,4 +19,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
69
19
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
70
20
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
71
21
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
72
|
-
OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|