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
data/lib/stella/logger.rb CHANGED
@@ -11,9 +11,9 @@ module Stella
11
11
  # * <tt>:debug</tt> Log debugging output, true or false (default)
12
12
  def initialize(args={})
13
13
  @debug_level = args[:debug] || false
14
- @info_logger = args[:info_logger] || STDOUT
15
- @error_logger = args[:error_logger] || STDERR
16
- @debug_logger = args[:debug_logger] || STDERR
14
+ @info_logger = args[:info_logger]
15
+ @error_logger = args[:error_logger]
16
+ @debug_logger = args[:debug_logger]
17
17
  end
18
18
 
19
19
  # +msgs+ is an array which can contain a list of messages or a symbol and a list of values
@@ -22,41 +22,51 @@ module Stella
22
22
  return if !msgs || msgs.empty?
23
23
  if msgs[0].is_a? Symbol
24
24
  txtsym = msgs.shift
25
- @info_logger.puts Stella::TEXT.msg(txtsym, msgs)
25
+ info_logger.puts Stella::TEXT.msg(txtsym, msgs)
26
26
  else
27
27
  msgs.each do |m|
28
- @info_logger.puts m
28
+ info_logger.puts m
29
29
  end
30
30
  end
31
- @info_logger.flush
31
+ info_logger.flush
32
+ end
33
+
34
+ def info_logger
35
+ @info_logger || $stdout
36
+ end
37
+ def debug_logger
38
+ @debug_logger || $stderr
39
+ end
40
+ def error_logger
41
+ @error_logger || $stderr
32
42
  end
33
43
 
34
44
  def flush
35
- @info_logger.flush
36
- @error_logger.flush
37
- @debug_logger.flush
45
+ info_logger.flush
46
+ error_logger.flush
47
+ debug_logger.flush
38
48
  end
39
49
 
40
50
  # Print all messages on a single line.
41
51
  def info_print(*msgs)
42
52
  msgs.each do |m|
43
- @info_logger.print m
53
+ info_logger.print m
44
54
  end
45
- @info_logger.flush
55
+ info_logger.flush
46
56
  end
47
57
 
48
58
  # Print all messages on a single line.
49
59
  def info_printf(pattern, *vals)
50
- @info_logger.printf(pattern, *vals)
51
- @info_logger.flush
60
+ info_logger.printf(pattern, *vals)
61
+ info_logger.flush
52
62
  end
53
63
 
54
64
  def debug(*msgs)
55
65
  return unless @debug_level
56
66
  msgs.each do |m|
57
- @debug_logger.puts "DEBUG: #{m}"
67
+ debug_logger.puts "DEBUG: #{m}"
58
68
  end
59
- @debug_logger.flush
69
+ debug_logger.flush
60
70
  end
61
71
  def warn(ex, prefix="WARN: ")
62
72
  error(ex, prefix)
@@ -64,11 +74,11 @@ module Stella
64
74
 
65
75
  def error(ex, prefix="ERR: ")
66
76
  msg = (ex.kind_of? String) ? ex : ex.message
67
- @error_logger.puts "#{prefix}#{msg}"
77
+ error_logger.puts "#{prefix}#{msg}"
68
78
  return unless @debug_level && ex.kind_of?(Exception)
69
- @error_logger.puts("#{prefix}------------------------------------------")
70
- @error_logger.puts("#{prefix}#{ex.backtrace.join("\n")}")
71
- @error_logger.puts("#{prefix}------------------------------------------")
79
+ error_logger.puts("#{prefix}------------------------------------------")
80
+ error_logger.puts("#{prefix}#{ex.backtrace.join("\n")}")
81
+ error_logger.puts("#{prefix}------------------------------------------")
72
82
  end
73
83
  end
74
84
  end
@@ -6,8 +6,11 @@ module Stella
6
6
  # An object for HTTP response content
7
7
  #
8
8
  class Response < Storable
9
- attr_accessor :errors, :content, :messages
10
- attr_writer :success
9
+
10
+ field :errors => Array
11
+ field :content => Hash
12
+ field :messages => Array
13
+ field :success => TrueClass
11
14
 
12
15
  def initialize
13
16
  @success = false
@@ -1,57 +1,160 @@
1
1
 
2
2
  # TODO: Handle nested hashes and arrays.
3
3
 
4
+ require 'yaml'
5
+ require 'utils/fileutil'
6
+
4
7
  module Stella
5
8
  class Storable
6
- NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze unless defined? NICE_TIME_FORMAT
7
-
8
- SupportedFormats= {
9
- 'yaml' => 'yml', # format name => file extension
10
- 'yml' => 'yml',
11
- 'csv' => 'csv',
12
- 'tsv' => 'tsv',
13
- 'json' => 'json'
14
- }.freeze unless defined? SupportedFormats
9
+ NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze unless defined? NICE_TIME_FORMAT
10
+ SUPPORTED_FORMATS = %w{tsv csv yaml json}.freeze unless defined? SUPPORTED_FORMATS
15
11
 
16
12
  attr_reader :format
17
13
 
18
14
  def format=(v)
19
- raise "Unsupported format: #{v}" unless SupportedFormats.has_key?(v)
15
+ raise "Unsupported format: #{v}" unless SUPPORTED_FORMATS.member?(v)
20
16
  @format = v
21
17
  end
22
18
 
19
+ def init
20
+ self.class.send(:class_variable_set, :@@field_names, []) unless class_variable_defined?(:@@field_names)
21
+ self.class.send(:class_variable_set, :@@field_types, []) unless class_variable_defined?(:@@field_types)
22
+ end
23
+
24
+ def self.field(args={})
25
+
26
+ args = {args => nil} unless args.is_a? Hash
27
+
28
+ args.each_pair do |m,t|
29
+
30
+ [[:@@field_names, m], [:@@field_types, t]].each do |tuple|
31
+ class_variable_set(tuple[0], []) unless class_variable_defined?(tuple[0])
32
+ class_variable_set(tuple[0], class_variable_get(tuple[0]) << tuple[1])
33
+ end
34
+
35
+ next if method_defined?(m)
36
+
37
+ # NOTE: I need a way to put these in the caller's namespace... Here's they're shared by all
38
+ # the subclasses which is not helpful. It will likely involve Kernel#caller and binding.
39
+ # Maybe class_eval, wraped around def field.
40
+
41
+
42
+ define_method(m) do instance_variable_get("@#{m}") end
43
+
44
+ define_method("#{m}=") do |val|
45
+ instance_variable_set("@#{m}",val)
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.field_names
51
+ class_variable_get(:@@field_names)
52
+ end
53
+ def self.field_types
54
+ class_variable_get(:@@field_types)
55
+ end
56
+
23
57
  def field_names
24
- raise "You need to override field_names (#{self.class})"
58
+ self.class.send(:class_variable_get, :@@field_names)
25
59
  end
26
60
 
27
- def self.undump(format, file=[])
28
- #raise "Format not defined (#{@format})" unless self.method_defined?("to_#{@format}")
29
- #puts "LOAD: from_#{format}"
30
- send("from_#{format}", file)
61
+ def field_types
62
+ self.class.send(:class_variable_get, :@@field_types)
63
+ end
64
+
65
+ def format=(v)
66
+ raise "Unsupported format: #{v}" unless SUPPORTED_FORMATS.member?(v)
67
+ @format = v
31
68
  end
32
69
 
33
70
 
34
- def dump(format="yaml", with_titles=true)
35
- #raise "Format not defined (#{@format})" unless self.method_defined?("to_#{@format}")
36
- #puts "DUMP: to_#{format}"
37
- self.send("to_#{format}", with_titles)
71
+ def dump(format=nil, with_titles=true)
72
+ format ||= @format
73
+ raise "Format not defined (#{format})" unless SUPPORTED_FORMATS.member?(format)
74
+ send("to_#{format}", with_titles)
38
75
  end
39
76
 
77
+ def self.from_file(file_path=nil, format=nil)
78
+ raise "Cannot read file (#{file_path})" unless File.exists?(file_path)
79
+ format = format || File.extname(file_path).tr('.', '')
80
+ me = send("from_#{format}", FileUtil.read_file_to_array(file_path))
81
+ me.format = format
82
+ me
83
+ end
84
+ def to_file(file_path=nil, with_titles=true)
85
+ raise "Cannot store to nil path" if file_path.nil?
86
+ format = File.extname(file_path).tr('.', '')
87
+ format ||= @format
88
+ FileUtil.write_file(file_path, dump(format, with_titles))
89
+ end
90
+
91
+
92
+ def self.from_hash(from={})
93
+ me = self.new
94
+
95
+ return me if !from || from.empty?
96
+
97
+ fnames = field_names
98
+ fnames.each_with_index do |key,index|
99
+
100
+ value = from[key]
101
+
102
+ # TODO: Correct this horrible implementation (sorry, me. It's just one of those days.)
103
+
104
+ if field_types[index] == Time
105
+ value = Time.parse(from[key].to_s)
106
+ elsif field_types[index] == DateTime
107
+ value = DateTime.parse(from[key].to_s)
108
+ elsif field_types[index] == TrueClass
109
+ value = (from[key].to_s == "true")
110
+ elsif field_types[index] == Float
111
+ value = from[key].to_f
112
+ elsif field_types[index] == Integer
113
+ value = from[key].to_i
114
+ end
115
+
116
+ me.send("#{key}=", value) if self.method_defined?("#{key}=")
117
+ end
118
+ me
119
+ end
40
120
  def to_hash(with_titles=true)
41
121
  tmp = {}
42
-
43
122
  field_names.each do |fname|
44
- tmp[fname] = self.send(fname.to_s)
123
+ tmp[fname] = self.send(fname)
45
124
  end
46
-
47
125
  tmp
48
126
  end
49
127
 
128
+
129
+ def self.from_yaml(from=[])
130
+ # from is an array of strings
131
+ from_str = from.join('')
132
+ hash = YAML::load(from_str)
133
+ hash = from_hash(hash) if hash.is_a? Hash
134
+ hash
135
+ end
50
136
  def to_yaml(with_titles=true)
51
- require 'yaml'
52
137
  to_hash.to_yaml
53
138
  end
54
139
 
140
+
141
+ def self.from_json(from=[])
142
+ require 'json'
143
+ # from is an array of strings
144
+ from_str = from.join('')
145
+ tmp = JSON::load(from_str)
146
+ hash_sym = tmp.keys.inject({}) do |hash, key|
147
+ hash[key.to_sym] = tmp[key]
148
+ hash
149
+ end
150
+ hash_sym = from_hash(hash_sym) if hash_sym.is_a? Hash
151
+ hash_sym
152
+ end
153
+ def to_json(with_titles=true)
154
+ require 'json'
155
+ to_hash.to_json
156
+ end
157
+
55
158
  def to_delimited(with_titles=false, delim=',')
56
159
  values = []
57
160
  field_names.each do |fname|
@@ -67,7 +170,12 @@ module Stella
67
170
  def to_csv(with_titles=false)
68
171
  to_delimited(with_titles, ',')
69
172
  end
70
-
173
+ def self.from_tsv(from=[])
174
+ self.from_delimited(from, "\t")
175
+ end
176
+ def self.from_csv(from=[])
177
+ self.from_delimited(from, ',')
178
+ end
71
179
 
72
180
  def self.from_delimited(from=[],delim=',')
73
181
  return if from.empty?
@@ -79,40 +187,18 @@ module Stella
79
187
  fnames = from[0].chomp.split(delim)
80
188
  values = from[1].chomp.split(delim)
81
189
  else
82
- fnames = self.new.field_names
190
+ fnames = self.field_names
83
191
  values = from[0].chomp.split(delim)
84
192
  end
85
193
 
86
194
  fnames.each_with_index do |key,index|
87
195
  next unless values[index]
88
- number_or_string = (values[index].match(/[\d\.]+/)) ? values[index].to_f : values[index]
89
- hash[key.to_sym] = number_or_string
196
+ hash[key.to_sym] = values[index]
90
197
  end
198
+ hash = from_hash(hash) if hash.is_a? Hash
91
199
  hash
92
200
  end
93
- def self.from_tsv(from=[])
94
- self.from_delimited(from, "\t")
95
- end
96
- def self.from_csv(from=[])
97
- self.from_delimited(from, ',')
98
- end
99
-
100
- def self.from_hash(from={})
101
- return if !from || from.empty?
102
- me = self.new
103
- fnames = me.to_hash.keys
104
- fnames.each do |key|
105
- # NOTE: this will skip generated values b/c they don't have a setter method
106
- me.send("#{key}=", from[key]) if self.method_defined?("#{key}=")
107
- end
108
- me
109
- end
110
- def self.from_yaml(from=[])
111
- require 'yaml'
112
- # from is an array of strings
113
- from_str = from.join('')
114
- YAML::load(from_str)
115
- end
116
-
201
+
202
+
117
203
  end
118
- end
204
+ end
@@ -60,6 +60,20 @@ module Stella
60
60
 
61
61
  class Util
62
62
 
63
+ BrowserNicks = {
64
+ :ff => 'firefox',
65
+ :ie => 'internetexplorer'
66
+ }.freeze unless defined? BrowserNicks
67
+
68
+ OperatingSystemNicks = {
69
+ :win => 'windows',
70
+ :lin => 'linux',
71
+ :osx => 'osx',
72
+ :freebsd => 'bsd',
73
+ :netbsd => 'bsd',
74
+ :openbsd => 'bsd'
75
+ }.freeze unless defined? OperatingSystemNicks
76
+
63
77
  # process_useragents
64
78
  #
65
79
  # We read the useragents.txt file into a hash index which
@@ -71,16 +85,18 @@ module Stella
71
85
  # --agent=ff-2.0.0.2-linux
72
86
  # --agent=chrome-windows
73
87
  # --agent=safari-3.0-osx
74
- #
75
- def self.process_useragents(ua_strs=[])
88
+ #
89
+ def self.process_useragents(path=nil)
90
+ raise "Cannot find #{path}" unless File.exists? path
91
+ ua_strs = FileUtil.read_file_to_array(path)
92
+ return {} if ua_strs.empty?
93
+
76
94
  agents_index = {}
77
- return agents_index if ua_strs.empty?
78
-
79
95
  ua_strs.each do |ua_str|
80
96
  ua_str.chomp! # remove trailing line separator
81
97
 
82
98
  ua = UserAgent.parse(ua_str)
83
-
99
+
84
100
  # Standardize the index values
85
101
  # i.e. firefox-3-windows
86
102
  name = ua.browser.downcase.tr(' ', '')
@@ -115,12 +131,78 @@ module Stella
115
131
  agents_index
116
132
  end
117
133
 
134
+ def self.find_agents(agent_list, possible_agents=[])
135
+ return [] if agent_list.nil? || agent_list.empty?
136
+ return [] if possible_agents.nil? || possible_agents.empty?
137
+
138
+ agents = []
139
+ possible_agents.each do |a|
140
+ agents << Stella::Util.find_agent(agent_list, *a)
141
+ end
142
+
143
+ agents
144
+ end
145
+
146
+ # find_agent
147
+ #
148
+ # Takes an input string which can be either a shortname or a complete
149
+ # user agent string. If the string matches the shortname format, it
150
+ # will select an agent string from useragents.txt based on the shortname.
151
+ # Shortname takes the following format: browser-version-os.
152
+ # Examples: ff-3-linux, ie-5, opera-10-win, chrome-0.2-osx, random
153
+ # If os doesn't match, it will look for the browser and version. If it can't
154
+ # find the version it will look for the browser and apply the version given.
155
+ # If browser doesn't match a known browser, it assumes the string is a
156
+ # complete user agent and simply returns that value.
157
+ def self.find_agent(agent_list, name,second=nil,third=nil)
158
+ return '' if agent_list.nil? || agent_list.empty?
159
+ name = (BrowserNicks.has_key?(name.to_s.to_sym)) ? BrowserNicks[name.to_s.to_sym] : name
160
+ return name unless agent_list.has_key?(name) || name == "random"
161
+
162
+ index = name
163
+ if (second && third) # i.e. opera-9-osx
164
+ os = (OperatingSystemNicks.has_key?(third)) ? OperatingSystemNicks[third] : third
165
+ index = "#{name}-#{second}-#{os}"
166
+ elsif(second && second.to_i > 0) # i.e. opera-9
167
+ index = "#{name}-#{second}"
168
+ elsif(second) # i.e. opera-osx
169
+ os = (OperatingSystemNicks.has_key?(second)) ? OperatingSystemNicks[second] : second
170
+ index = "#{name}-#{os}"
171
+ elsif(name == "random")
172
+ index = agent_list.keys[ rand(agent_list.keys.size) ]
173
+ end
174
+
175
+ # Attempt to find a pool of user agents that match the supplied index
176
+ ua_pool = agent_list[index]
177
+
178
+ # In the event we don't find an agent above (which will only happen
179
+ # when the user provided a version), we'll take a random agent for
180
+ # the same browser and apply the version supplied by the user. We
181
+ # create the index using just the major version number so if the user
182
+ # supplies a specific verswion number, they will always end up here.
183
+ unless ua_pool
184
+ os = (OperatingSystemNicks.has_key?(third)) ? OperatingSystemNicks[third] : third
185
+ index = (os) ? "#{name}-#{os}" : name
186
+ ua_tmp = agent_list[index][ rand(agent_list[index].size) ]
187
+ ua_tmp.version = second if second.to_i > 0
188
+ ua_pool = [ua_tmp]
189
+ end
190
+
191
+ ua = ua_pool[ rand(ua_pool.size) ]
192
+
193
+ ua.to_s
194
+
195
+ end
196
+
118
197
  # expand_str
119
198
  #
120
199
  # Turns a string like ff-4-freebsd into ["ff","4","freebsd"]
121
- # We use this for command-line values liek agent and rampup
122
- def self.expand_str(str)
123
- str.split(/\s*[,\-]\s*/) # remove extra spaces at the same time.
200
+ # We use this for command-line values liek agent and rampup.
201
+ # +str+ is a comma or dash separated string.
202
+ # +type+ is a class type to cast to (optional, default: String)
203
+ def self.expand_str(str, type=String)
204
+ # this removes extra spaces along with the comma
205
+ str.split(/\s*[,\-]\s*/).inject([]) do |list,value| list << eval("#{type}('#{value}')") end
124
206
  end
125
207
 
126
208
 
@@ -162,6 +244,23 @@ module Stella
162
244
  end
163
245
  end
164
246
 
247
+ # NOTE: Not used yet
248
+ # TODO: Use capture instead of capture_output
249
+ # Stolen from http://github.com/wycats/thor
250
+ def capture(stream)
251
+ begin
252
+ stream = stream.to_s
253
+ eval "$#{stream} = StringIO.new"
254
+ yield
255
+ result = eval("$#{stream}").string
256
+ ensure
257
+ eval("$#{stream} = #{stream.upcase}")
258
+ end
259
+
260
+ result
261
+ end
262
+
263
+
165
264
  #
166
265
  # Generates a string of random alphanumeric characters
167
266
  # These are used as IDs throughout the system
@@ -7,6 +7,7 @@ module Stella
7
7
  # Portions of this code is from Amazon's EC2 AMI tools, lib/platform.rb.
8
8
  class SystemInfo < Stella::Storable
9
9
  IMPLEMENTATIONS = [
10
+
10
11
  # These are for JRuby, System.getproperty('os.name').
11
12
  # For a list of all values, see: http://lopica.sourceforge.net/os.html
12
13
  [/mac\s*os\s*x/i, :unix, :osx ],
@@ -14,7 +15,9 @@ module Stella
14
15
  [/windows\s*ce/i, :win32, :windows ],
15
16
  [/windows/i, :win32, :windows ],
16
17
  [/osx/i, :unix, :osx ],
17
-
18
+
19
+ # TODO: implement other windows matches: # /djgpp|(cyg|ms|bcc)win|mingw/ (from mongrel)
20
+
18
21
  # These are for RUBY_PLATFORM and JRuby
19
22
  [/java/i, :java, :java ],
20
23
  [/darwin/i, :unix, :osx ],
@@ -31,6 +34,7 @@ module Stella
31
34
  [/vms/i, :vms, :vms ],
32
35
  [/os2/i, :os2, :os2 ],
33
36
  [nil, :unknown, :unknown ],
37
+
34
38
  ]
35
39
 
36
40
  ARCHITECTURES = [
@@ -46,18 +50,19 @@ module Stella
46
50
  [nil, :unknown ],
47
51
  ]
48
52
 
49
- attr_reader :os
50
- attr_reader :implementation
51
- attr_reader :architecture
52
- attr_reader :hostname
53
- attr_reader :ipaddress
54
- attr_reader :uptime
53
+
54
+
55
+ field :os => String
56
+ field :implementation => String
57
+ field :architecture => String
58
+ field :hostname => String
59
+ field :ipaddress => String
60
+ field :uptime => Float
55
61
 
56
- def field_names
57
- [
58
- :os, :implementation, :architecture, :hostname, :ipaddress, :uptime
59
- ]
60
- end
62
+
63
+ alias :impl :implementation
64
+ alias :arch :architecture
65
+
61
66
 
62
67
  def initialize
63
68
  @os, @implementation, @architecture = guess
@@ -88,7 +93,7 @@ module Stella
88
93
 
89
94
  #
90
95
  if os == :win32
91
- require 'Win32API'
96
+ #require 'Win32API'
92
97
 
93
98
  # If we're running in java, we'll need to look elsewhere
94
99
  # for the implementation and architecture.
@@ -127,7 +132,7 @@ module Stella
127
132
  uptime = :unknown
128
133
 
129
134
  begin
130
- hostname = Socket.gethostname
135
+ hostname = local_hostname
131
136
  ipaddr = local_ip_address
132
137
  uptime = local_uptime
133
138
  rescue => ex
@@ -136,10 +141,15 @@ module Stella
136
141
  [hostname, ipaddr, uptime]
137
142
  end
138
143
 
139
-
144
+ # local_hostname
145
+ #
146
+ # Return the hostname for the local machine
147
+ def local_hostname
148
+ Socket.gethostname
149
+ end
150
+
140
151
  # local_uptime
141
152
  #
142
- #
143
153
  # Returns the local uptime in hours. Use Win32API in Windows,
144
154
  # 'sysctl -b kern.boottime' os osx, and 'who -b' on unix.
145
155
  # Based on Ruby Quiz solutions by: Matthias Reitinger
@@ -44,7 +44,7 @@ module Stella
44
44
  # A warmup factor of 0.5 means run a test run at 50% strength.
45
45
  attr_accessor :warmup
46
46
  # Contains an interval and maximum threshold to increase virtual users.
47
- # Rampup object, [R,M] where R is the interval and M is the maximum.
47
+ # Rampup object, or Array like [R,M] where R is the interval and M is the maximum.
48
48
  attr_reader :rampup
49
49
  # An array of string appropriate for a User-Agent HTTP header
50
50
  attr_accessor :agents
@@ -4,15 +4,31 @@
4
4
  module Stella::Test::Run
5
5
 
6
6
  class Summary < Stella::Storable
7
+ attr_accessor :format
7
8
 
8
- attr_accessor :note
9
- attr_accessor :tool, :version
10
- attr_accessor :test, :transactions, :headers_transferred
11
- attr_accessor :elapsed_time, :data_transferred, :response_time
12
- attr_accessor :successful, :failed, :transaction_rate, :vusers, :raw
13
-
9
+ field :availability => Float
10
+ field :transactions => Integer
11
+ field :elapsed_time => Float
12
+ field :data_transferred => Float
13
+ field :headers_transferred => Float
14
+ field :response_time => Float
15
+ field :transaction_rate => Float
16
+ field :throughput => Float
17
+ field :vusers => Integer
18
+ field :successful => Integer
19
+ field :failed => Integer
20
+ field :note => String
21
+ field :raw => String
22
+ field :tool => String
23
+ field :version => String
24
+
14
25
  def initialize(note="")
26
+ #init
15
27
  @note = note
28
+ reset
29
+ end
30
+
31
+ def reset
16
32
  @transactions = 0
17
33
  @headers_transferred = 0
18
34
  @elapsed_time = 0
@@ -42,13 +58,7 @@ module Stella::Test::Run
42
58
  end
43
59
  end
44
60
 
45
- def field_names
46
- [
47
- :availability, :transactions, :elapsed_time, :data_transferred,
48
- :headers_transferred, :response_time, :transaction_rate, :throughput,
49
- :vusers, :successful, :failed, :note
50
- ]
51
- end
61
+
52
62
 
53
63
  def available?
54
64
  @successful && @transactions && @elapsed_time && @vusers && @response_time