solutious-stella 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
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
+