stella 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/README.textile +14 -10
  2. data/Rakefile +22 -36
  3. data/lib/daemonize.rb +56 -0
  4. data/lib/stella/adapter/ab.rb +49 -39
  5. data/lib/stella/adapter/base.rb +17 -8
  6. data/lib/stella/adapter/httperf.rb +24 -18
  7. data/lib/stella/adapter/pcap_watcher.rb +1 -1
  8. data/lib/stella/adapter/siege.rb +15 -12
  9. data/lib/stella/cli/localtest.rb +2 -3
  10. data/lib/stella/cli/sysinfo.rb +0 -1
  11. data/lib/stella/cli.rb +10 -55
  12. data/lib/stella/command/base.rb +0 -62
  13. data/lib/stella/command/localtest.rb +35 -36
  14. data/lib/stella/data/domain.rb +18 -11
  15. data/lib/stella/data/http.rb +23 -16
  16. data/lib/stella/logger.rb +29 -19
  17. data/lib/stella/response.rb +5 -2
  18. data/lib/stella/storable.rb +138 -52
  19. data/lib/stella/support.rb +107 -8
  20. data/lib/stella/sysinfo.rb +26 -16
  21. data/lib/stella/test/definition.rb +1 -1
  22. data/lib/stella/test/run/summary.rb +23 -13
  23. data/lib/stella/test/stats.rb +114 -0
  24. data/lib/stella/text/resource.rb +1 -1
  25. data/lib/stella.rb +29 -4
  26. data/lib/utils/mathutil.rb +0 -76
  27. data/lib/utils/stats.rb +88 -0
  28. data/lib/win32/Console/ANSI.rb +305 -305
  29. data/lib/win32/Console.rb +970 -970
  30. data/support/ruby-pcap-takuma-patch.txt +13 -13
  31. data/support/text/en.yaml +11 -8
  32. data/support/text/nl.yaml +7 -1
  33. data/{spec/show-agents_spec.rb → tests/01-util_test.rb} +0 -0
  34. data/tests/02-stella-util_test.rb +42 -0
  35. data/tests/10-stella_test.rb +104 -0
  36. data/tests/11-stella-storable_test.rb +68 -0
  37. data/tests/60-stella-command_test.rb +248 -0
  38. data/tests/80-stella-cli_test.rb +45 -0
  39. data/tests/spec-helper.rb +31 -0
  40. data/vendor/{frylock/README.textile → drydock/LICENSE.txt} +2 -52
  41. data/vendor/drydock/README.textile +57 -0
  42. data/vendor/{frylock → drydock}/bin/example +14 -14
  43. data/vendor/{frylock/frylock.gemspec → drydock/drydock.gemspec} +1 -1
  44. data/vendor/{frylock/lib/frylock → drydock/lib/drydock}/exceptions.rb +1 -1
  45. data/vendor/{frylock/lib/frylock.rb → drydock/lib/drydock.rb} +8 -8
  46. data/vendor/{frylock → drydock}/test/command_test.rb +0 -0
  47. metadata +34 -61
  48. data/lib/stella/test/base.rb +0 -38
  49. data/lib/stella/test/summary.rb +0 -82
  50. data/vendor/hitimes-0.4.0/HISTORY +0 -28
  51. data/vendor/hitimes-0.4.0/LICENSE.txt +0 -19
  52. data/vendor/hitimes-0.4.0/README +0 -80
  53. data/vendor/hitimes-0.4.0/Rakefile +0 -63
  54. data/vendor/hitimes-0.4.0/examples/benchmarks.rb +0 -86
  55. data/vendor/hitimes-0.4.0/examples/stats.rb +0 -29
  56. data/vendor/hitimes-0.4.0/ext/extconf.rb +0 -15
  57. data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +0 -21
  58. data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +0 -20
  59. data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +0 -16
  60. data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +0 -27
  61. data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +0 -340
  62. data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +0 -73
  63. data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +0 -242
  64. data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +0 -30
  65. data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +0 -178
  66. data/vendor/hitimes-0.4.0/ext/rbconfig.rb +0 -178
  67. data/vendor/hitimes-0.4.0/gemspec.rb +0 -54
  68. data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +0 -23
  69. data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +0 -54
  70. data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +0 -29
  71. data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +0 -223
  72. data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +0 -42
  73. data/vendor/hitimes-0.4.0/lib/hitimes.rb +0 -24
  74. data/vendor/hitimes-0.4.0/spec/interval_spec.rb +0 -115
  75. data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +0 -34
  76. data/vendor/hitimes-0.4.0/spec/paths_spec.rb +0 -14
  77. data/vendor/hitimes-0.4.0/spec/spec_helper.rb +0 -6
  78. data/vendor/hitimes-0.4.0/spec/stats_spec.rb +0 -72
  79. data/vendor/hitimes-0.4.0/spec/timer_spec.rb +0 -105
  80. data/vendor/hitimes-0.4.0/spec/version_spec.rb +0 -27
  81. data/vendor/hitimes-0.4.0/tasks/announce.rake +0 -39
  82. data/vendor/hitimes-0.4.0/tasks/config.rb +0 -107
  83. data/vendor/hitimes-0.4.0/tasks/distribution.rake +0 -53
  84. data/vendor/hitimes-0.4.0/tasks/documentation.rake +0 -33
  85. data/vendor/hitimes-0.4.0/tasks/extension.rake +0 -64
  86. data/vendor/hitimes-0.4.0/tasks/rspec.rake +0 -31
  87. data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +0 -52
  88. data/vendor/hitimes-0.4.0/tasks/utils.rb +0 -80
@@ -1,22 +1,22 @@
1
- diff -ur pcap-0.6/Pcap.c pcap-working/Pcap.c
2
- --- pcap-0.6/Pcap.c 2008-02-10 19:10:30.000000000 +0900
3
- +++ pcap-working/Pcap.c 2008-02-10 18:58:49.000000000 +0900
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
- 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")));
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-0.6/packet.c pcap-working/packet.c
18
- --- pcap-0.6/packet.c 2008-02-10 19:10:30.000000000 +0900
19
- +++ pcap-working/packet.c 2008-02-10 18:55:13.000000000 +0900
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 50 users, 20 requests each. Repeat 5 times.
33
- $ stella -x 5 -w 0.5 ab -n 1000 -c 50 http://stellaaahhhh.com/
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 100 users, 10 requests each with a Linux FireFox 3 user agent
36
- $ stella --rampup=25,200 --agent=firefox-3-linux siege -c 100 -r 10 http://stellaaahhhh.com/
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. Record requests to a flatfile.
42
- $ stella -vv watch -W -p 3114 -r uri.txt
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 -P dns
46
- $ stella watch -P -p 9000 http
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
@@ -1 +1,7 @@
1
- ---
1
+ :info:
2
+ :language: nl
3
+ :fullname: nederlands
4
+ :updated: 2009-01-10
5
+ :enabled: false
6
+
7
+ :stellaaahhhh: "Stellaaahhhh!"
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
- h1. Frylock - Easy Command line apps
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.