solutious-stella 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.
Files changed (60) hide show
  1. data/CHANGES.txt +36 -0
  2. data/README.textile +162 -0
  3. data/Rakefile +88 -0
  4. data/bin/stella +12 -0
  5. data/bin/stella.bat +12 -0
  6. data/lib/daemonize.rb +56 -0
  7. data/lib/pcaplet.rb +180 -0
  8. data/lib/stella.rb +101 -0
  9. data/lib/stella/adapter/ab.rb +337 -0
  10. data/lib/stella/adapter/base.rb +106 -0
  11. data/lib/stella/adapter/httperf.rb +305 -0
  12. data/lib/stella/adapter/pcap_watcher.rb +221 -0
  13. data/lib/stella/adapter/proxy_watcher.rb +76 -0
  14. data/lib/stella/adapter/siege.rb +341 -0
  15. data/lib/stella/cli.rb +258 -0
  16. data/lib/stella/cli/agents.rb +73 -0
  17. data/lib/stella/cli/base.rb +55 -0
  18. data/lib/stella/cli/language.rb +18 -0
  19. data/lib/stella/cli/localtest.rb +78 -0
  20. data/lib/stella/cli/sysinfo.rb +16 -0
  21. data/lib/stella/cli/watch.rb +278 -0
  22. data/lib/stella/command/base.rb +40 -0
  23. data/lib/stella/command/localtest.rb +358 -0
  24. data/lib/stella/data/domain.rb +82 -0
  25. data/lib/stella/data/http.rb +131 -0
  26. data/lib/stella/logger.rb +84 -0
  27. data/lib/stella/response.rb +85 -0
  28. data/lib/stella/storable.rb +201 -0
  29. data/lib/stella/support.rb +276 -0
  30. data/lib/stella/sysinfo.rb +257 -0
  31. data/lib/stella/test/definition.rb +79 -0
  32. data/lib/stella/test/run/summary.rb +70 -0
  33. data/lib/stella/test/stats.rb +114 -0
  34. data/lib/stella/text.rb +64 -0
  35. data/lib/stella/text/resource.rb +38 -0
  36. data/lib/utils/crypto-key.rb +84 -0
  37. data/lib/utils/domainutil.rb +47 -0
  38. data/lib/utils/escape.rb +302 -0
  39. data/lib/utils/fileutil.rb +78 -0
  40. data/lib/utils/httputil.rb +266 -0
  41. data/lib/utils/mathutil.rb +15 -0
  42. data/lib/utils/stats.rb +88 -0
  43. data/lib/utils/textgraph.rb +267 -0
  44. data/lib/utils/timerutil.rb +58 -0
  45. data/lib/win32/Console.rb +970 -0
  46. data/lib/win32/Console/ANSI.rb +305 -0
  47. data/support/kvm.h +91 -0
  48. data/support/ruby-pcap-takuma-notes.txt +19 -0
  49. data/support/ruby-pcap-takuma-patch.txt +30 -0
  50. data/support/text/en.yaml +80 -0
  51. data/support/text/nl.yaml +7 -0
  52. data/support/useragents.txt +75 -0
  53. data/tests/01-util_test.rb +0 -0
  54. data/tests/02-stella-util_test.rb +42 -0
  55. data/tests/10-stella_test.rb +104 -0
  56. data/tests/11-stella-storable_test.rb +68 -0
  57. data/tests/60-stella-command_test.rb +248 -0
  58. data/tests/80-stella-cli_test.rb +45 -0
  59. data/tests/spec-helper.rb +31 -0
  60. metadata +165 -0
@@ -0,0 +1,80 @@
1
+ :info:
2
+ :language: en
3
+ :fullname: english
4
+ :updated: 2008-12-20
5
+ :enabled: true
6
+
7
+ :stellaaahhhh: "Stellaaahhhh!"
8
+
9
+ :text_available_languages: "Available languages: %s"
10
+
11
+
12
+ :agents_option_full: Return complete user-agent strings.
13
+ :agents_option_list: List available user-agent shortnames.
14
+ :agents_option_search: Return only user agents which match the search term.
15
+ :agents_count_message: "There are %d user agent strings matching your query"
16
+
17
+ :option_help_stdout: Print STDOUT output from load tool for each test run
18
+ :option_help_stderr: Print STDERR output from load tool for each test run
19
+ :option_help_verbose: Specify the output verbosity (level 1, 2 or 3)
20
+ :option_help_testreps: Number of test repetitions to execute (testruns).
21
+ :cli_print_version: "Stella version: %s"
22
+ :option_help_quiet: Demand only the essential output for each run.
23
+ :option_help_warmup: "Include a warmup run, a factor N of the test load. Default: %f"
24
+ :option_help_usage: "Usage: stella [OPTIONS] COMMAND [COMMAND OPTIONS]"
25
+ :option_help_options_title: "Options:"
26
+ :option_help_overhead: Show the time used by Stella before and after the run.
27
+ :option_help_datapath: "Directory path to store test data. Default: %s"
28
+ :option_help_preamble: |
29
+
30
+ Commands:
31
+ %s
32
+
33
+ Examples:
34
+
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/
37
+
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/
40
+
41
+ # Display available user agent strings
42
+ $ stella agents -l
43
+
44
+ # Launch a proxy to monitor HTTP traffic.
45
+ $ stella -vv watch -P -p 3114
46
+
47
+ # Monitor network traffic with packet sniffer (requires unix and root access)
48
+ $ stella watch -C dns
49
+ $ stella watch -C -p 3456 http
50
+
51
+
52
+ User-Agent Examples (--agent):
53
+ ff-3-linux, ie-7-win, opera-10, chrome-0.2-osx
54
+
55
+ :option_help_message: A short note about the test (i.e. 'new cache enabled')
56
+ :option_help_format: "Output file format. One of: csv [default], yaml, tsv, json"
57
+ :option_help_force: "Force the command to ignore non-fatal errors. CAREFUL!"
58
+ :option_help_version: Display the version, then exit
59
+ :option_help_sleep: Number of seconds to sleep between runs
60
+ :option_help_agent: Specify a User-Agent. Can be a short string or complete agent string. Defaults to 'random'.
61
+ :option_help_help: Displays this message
62
+ :option_help_rampup: Execute multiple tests, incremented by R users every test, up to U users
63
+
64
+ :error_unavailable_adapter: "The adapter %s is not available. Check your PATH."
65
+ :error_class_must_override: "You must override the method: %s"
66
+ :error_class_unknown_argument: "Ignoring unknown argument: %s"
67
+ :error_adapter_command_not_ready: "Incomplete options or arguments for %s"
68
+ :error_adapter_runtime: "%s had a problem: %s"
69
+ :error_watch_proxy: "The proxy has a problem: %s"
70
+
71
+ :error_invalid_argument: "%s is not a valid argument"
72
+ :error_unknown_value: "I don't know what to do with %s"
73
+ :error_missing_dependency: "%s is not available: %s"
74
+ :error_generic: "Oops, there was an unidentified problem (consider reporting it as a bug)"
75
+
76
+ :error_sysinfo_notunix: "Sorry, Unix only"
77
+ :error_sysinfo_notwindows: "Sorry, Windows only"
78
+ :error_sysinfo_notroot: "You need to be root to do that"
79
+
80
+ :error_watch_norubypcap: "Ruby-Pcap not installed (http://www.goto.info.waseda.ac.jp/~fukusima/ruby/pcap-e.html)"
@@ -0,0 +1,7 @@
1
+ :info:
2
+ :language: nl
3
+ :fullname: nederlands
4
+ :updated: 2009-01-10
5
+ :enabled: false
6
+
7
+ :stellaaahhhh: "Stellaaahhhh!"
@@ -0,0 +1,75 @@
1
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
2
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
4
+ Opera/9.50 (X11; Linux i686; U; en)
5
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en; rv:1.8.1.16) Gecko/20080827 Epiphany/2.22 Firefox/2.0.0.16
6
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.8.1.16) Gecko/20080827 Firefox/2.0.0.16
7
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.9.0.2) Gecko/2008100107 Firefox/3.0.2
8
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008111318 Ubuntu/8.10 (intrepid) Firefox/3.0.4
9
+ Opera/9.52 (X11; FreeBSD 7.0-RELEASE amd64; U; en)
10
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.13) Gecko/20080311 (Debian-1.8.1.13+nobinonly-0ubuntu1) Galeon/2.0.4 (Ubuntu 2.0.4-1ubuntu1)
11
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.8.1.16) Gecko/20080827 Galeon/2.0.6 Firefox/2.0.0.16
12
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3
13
+ Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.8.1.16) Gecko/20080827 SeaMonkey/1.1.11
14
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.18) Gecko/20081112 Fedora/1.1.13-1.fc10 SeaMonkey/1.1.13
15
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.4.154.29 Safari/525.19
16
+ Opera/9.51 (X11; Linux i686; U; en)
17
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; de; rv:1.8) Gecko/20051111 Firefox/1.5
18
+ Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
19
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1a2) Gecko/20080829082037 Shiretoko/3.1a2
20
+ Dillo/0.8.6-i18n-misc
21
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061302 Firefox/3.0 Flock/2.0b1
22
+ Opera/9.27 (X11; Linux i686; U; en)
23
+ Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0
24
+ Opera/9.27 (Windows NT 5.0; U; de)
25
+ Opera/9.62 (X11; Linux i686; U; de) Presto/2.1.1
26
+ Opera/9.62 (Windows NT 5.1; U; en) Presto/2.1.1
27
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b1pre) Gecko/20080911002759 SeaMonkey/2.0a1pre
28
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.17) Gecko/20080910 Firefox/2.0.0.17 Flock/1.2.6
29
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.8.1.12) Gecko/20080203 K-Meleon/1.1.4
30
+ Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
31
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.18) Gecko/20081031 SeaMonkey/1.1.13
32
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; de; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4
33
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
34
+ Opera/8.53 (Windows NT 5.1; U; en)
35
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.4) Gecko/2008112016 Firefox/3.0.4 Flock/2.0.2
36
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.18) Gecko/20081030 Iceape/1.1.13 (Debian-1.1.13-1)
37
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008112309 Iceweasel/3.0.4 (Debian-3.0.4-1)
38
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.17pre) Gecko/20080716 K-Meleon/1.5.0
39
+ Opera/9.26 (Windows NT 5.0; U; de)
40
+ Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.10 (like Gecko) (Debian)
41
+ Mozilla/5.0 (X11; U; Linux i686; en; rv:1.9.0.4) Gecko/20080528 Epiphany/2.22
42
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1
43
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.14eol) Gecko/20070505 (Debian-1.8.0.15~pre080614d-0etch1) Epiphany/2.14
44
+ Opera/9.52 (X11; Linux i686; U; en)
45
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8.1.11pre) Gecko/20071206 Firefox/2.0.0.11 Navigator/9.0.0.5
46
+ Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
47
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20081206 Minefield/3.2a1pre
48
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko Kazehakase/0.5.4 Debian/0.5.4-2.1ubuntu3
49
+ Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)
50
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.36 Safari/525.19
51
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.14eol) Gecko/20070505 Iceape/1.0.9 (Debian-1.0.13~pre080323b-0etch3)
52
+ Opera/9.25 (Windows NT 5.1; U; de)
53
+ Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.11 [en]
54
+ Mozilla/4.0 (compatible; MSIE 4.01; Windows NT 5.0; SV1)
55
+ Opera/9.51 (Windows NT 5.1; U; en)
56
+ Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
57
+ Opera/9.61 (Windows NT 5.1; U; en) Presto/2.1.1
58
+ Opera/9.50 (Windows NT 5.1; U; en)
59
+ Opera/9.52 (Windows NT 5.1; U; en)
60
+ Opera/9.24 (Windows NT 5.1; U; it)
61
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/523.12.9 (KHTML, like Gecko) Version/3.0 Safari/523.12.9
62
+ Opera/9.23 (Windows NT 5.1; U; it)
63
+ Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1)
64
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.18) Gecko/20081030 Iceweasel/2.0.0.18 (Debian-2.0.0.18-0etch1)
65
+ Mozilla/5.0 (X11; Linux i686; U;) Gecko/0 Kazehakase/0.4.2 Debian/0.4.2-1etch1
66
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008031501 SeaMonkey/2.0a1pre
67
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Flock/1.1d
68
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Navigator/9.0.0.6
69
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1a1) Gecko/2008072306 Shiretoko/3.1a1
70
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080211 Firefox/2.0.0.12 Flock/1.0.9
71
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.30 Safari/525.13
72
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3pre) Gecko/20081201 Minefield/3.1b3pre
73
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.18) Gecko/20081030 Iceweasel/2.0.0.18 (Debian-2.0.0.18-0etch1)
74
+ Opera/10.00 (X11; Linux i686 ; U; en) Presto/2.2.0
75
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; nl-NL) AppleWebKit/525.19 (KHTML, like Gecko) Version/3.1.2 Safari/525.21
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
+