stella 0.5.4 → 0.5.5
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/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.
|