stella 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/README.txt +135 -0
  2. data/Rakefile +100 -0
  3. data/bin/stella +12 -0
  4. data/lib/stella.rb +58 -0
  5. data/lib/stella/adapter/ab.rb +303 -0
  6. data/lib/stella/adapter/base.rb +87 -0
  7. data/lib/stella/adapter/httperf.rb +296 -0
  8. data/lib/stella/adapter/siege.rb +321 -0
  9. data/lib/stella/cli.rb +291 -0
  10. data/lib/stella/cli/agents.rb +73 -0
  11. data/lib/stella/cli/base.rb +19 -0
  12. data/lib/stella/cli/language.rb +18 -0
  13. data/lib/stella/cli/localtest.rb +80 -0
  14. data/lib/stella/command/base.rb +111 -0
  15. data/lib/stella/command/localtest.rb +339 -0
  16. data/lib/stella/logger.rb +63 -0
  17. data/lib/stella/response.rb +82 -0
  18. data/lib/stella/storable.rb +116 -0
  19. data/lib/stella/support.rb +106 -0
  20. data/lib/stella/test/base.rb +34 -0
  21. data/lib/stella/test/definition.rb +79 -0
  22. data/lib/stella/test/run/summary.rb +50 -0
  23. data/lib/stella/test/summary.rb +82 -0
  24. data/lib/stella/text.rb +64 -0
  25. data/lib/stella/text/resource.rb +39 -0
  26. data/lib/utils/crypto-key.rb +84 -0
  27. data/lib/utils/escape.rb +302 -0
  28. data/lib/utils/fileutil.rb +59 -0
  29. data/lib/utils/httputil.rb +210 -0
  30. data/lib/utils/mathutil.rb +78 -0
  31. data/lib/utils/textgraph.rb +267 -0
  32. data/lib/utils/timerutil.rb +58 -0
  33. data/support/text/en.yaml +54 -0
  34. data/support/text/nl.yaml +1 -0
  35. data/support/useragents.txt +75 -0
  36. data/vendor/useragent/MIT-LICENSE +20 -0
  37. data/vendor/useragent/README +21 -0
  38. data/vendor/useragent/init.rb +1 -0
  39. data/vendor/useragent/lib/user_agent.rb +83 -0
  40. data/vendor/useragent/lib/user_agent/browsers.rb +24 -0
  41. data/vendor/useragent/lib/user_agent/browsers/all.rb +69 -0
  42. data/vendor/useragent/lib/user_agent/browsers/gecko.rb +43 -0
  43. data/vendor/useragent/lib/user_agent/browsers/internet_explorer.rb +40 -0
  44. data/vendor/useragent/lib/user_agent/browsers/opera.rb +49 -0
  45. data/vendor/useragent/lib/user_agent/browsers/webkit.rb +94 -0
  46. data/vendor/useragent/lib/user_agent/comparable.rb +25 -0
  47. data/vendor/useragent/lib/user_agent/operating_systems.rb +19 -0
  48. data/vendor/useragent/spec/browsers/gecko_user_agent_spec.rb +209 -0
  49. data/vendor/useragent/spec/browsers/internet_explorer_user_agent_spec.rb +99 -0
  50. data/vendor/useragent/spec/browsers/opera_user_agent_spec.rb +59 -0
  51. data/vendor/useragent/spec/browsers/other_user_agent_spec.rb +19 -0
  52. data/vendor/useragent/spec/browsers/webkit_user_agent_spec.rb +373 -0
  53. data/vendor/useragent/spec/spec_helper.rb +1 -0
  54. data/vendor/useragent/spec/user_agent_spec.rb +331 -0
  55. data/vendor/useragent/useragent.gemspec +12 -0
  56. metadata +139 -0
data/lib/stella/cli.rb ADDED
@@ -0,0 +1,291 @@
1
+
2
+ require 'optparse'
3
+ require 'ostruct'
4
+
5
+ require 'stella/cli/base'
6
+
7
+ module Stella
8
+
9
+ # Stella::Config
10
+ #
11
+ # This Config class manages the content of ENV['HOME]/.stella. The functionality
12
+ # is currently disabled so stella is stateless.
13
+ class Config < Storable
14
+ DEFAULT_HOME = File.join(ENV['HOME'], '.stella').freeze unless defined? DEFAULT_HOME
15
+ DEFAULT_DATA_HOME = File.join(Dir.getwd, 'stella').freeze unless defined? DEFAULT_DATA_HOME
16
+
17
+ attr_accessor :conf_path, :data_path
18
+ attr_accessor :agents
19
+
20
+ def initialize(args={:conf_path => DEFAULT_HOME})
21
+
22
+ end
23
+
24
+ def working_directory
25
+ 'stella'
26
+ end
27
+
28
+ # Copy the default useragents file to the config directory.
29
+ #unless File.exists? uafile_path
30
+ # default_uafile = File.join(STELLA_HOME, 'support', 'useragents.txt')
31
+ # STDERR.puts "There's no useragents.txt file. Supplied agents will be ignored" unless File.exists?(default_uafile)
32
+ # File.copy(default_uafile, @config.uafile_path, true)
33
+ #end
34
+
35
+ #def load
36
+ # puts self.methods
37
+ # loaded_config = Config.undump('yaml', FileUtil.read_file_to_array(@config_filepath))
38
+ # current_config = @config.marshal_dump
39
+ # current_config.merge! loaded_config if loaded_config.is_a? Hash
40
+ #
41
+ # @config = OpenStruct.new(current_config)
42
+ #end
43
+
44
+ end
45
+
46
+ # Stella::CLI
47
+ #
48
+ # The is the front-end class for the command-line implementation. The stella script
49
+ # creates an instance of this class which is the glue between the command-line
50
+ # and the Stella command classes.
51
+ # Note: All Stella::CLI classes are autoloaded and they add themselves to @@commands.
52
+ class CLI
53
+
54
+ # Auto populated with 'command' => Stella::CLI::[class] by each cli class on 'require'.
55
+ @@commands = {}
56
+
57
+ attr_reader :options
58
+ attr_reader :logger
59
+
60
+
61
+
62
+ def initialize(arguments=[], stdin=nil)
63
+ @arguments = arguments
64
+ @stdin = stdin
65
+
66
+ @config = Stella::Config.new
67
+ @options = OpenStruct.new
68
+ @options.verbose = 0
69
+ @options.data_path = @config.working_directory
70
+ @options.agents = []
71
+
72
+ end
73
+
74
+ def commands
75
+ @@commands
76
+ end
77
+
78
+ def run
79
+ process_arguments
80
+ process_options
81
+
82
+ unless (@command_name)
83
+ process_options(:display)
84
+ exit 0
85
+ end
86
+
87
+ # Pull the requested command object out of the list
88
+ # and tell it what shortname that was used to call it.
89
+ command = @@commands[@command_name].new(@command_name)
90
+
91
+ # Give the command object access to the config and runtime options
92
+ #command.global_config = @config
93
+ command.stella_options = @options
94
+ command.arguments = @command_arguments
95
+ command.working_directory = @options.data_path
96
+
97
+ command.run
98
+
99
+
100
+ rescue => ex
101
+ Stella::LOGGER.error(ex)
102
+ end
103
+
104
+
105
+ protected
106
+
107
+
108
+ # process_arguments
109
+ #
110
+ # Split the arguments into stella args and command args
111
+ # i.e. stella -H push -f (-H is a stella arg, -f is a command arg)
112
+ # True if required arguments were provided
113
+ def process_arguments
114
+
115
+ @command_name = nil
116
+ @arguments.each do |arg|
117
+ if (@@commands.has_key? arg)
118
+ @command_name = arg
119
+ index = @arguments.index(@command_name)
120
+ @command_arguments = @arguments[index + 1..@arguments.size]
121
+ @stella_arguments = @arguments[0..index - 1] if index > 0
122
+ break
123
+ end
124
+ end
125
+
126
+ @command_arguments = [] if @command_arguments.nil?
127
+ @stella_arguments = [] if @stella_arguments.nil?
128
+
129
+ # If there's no command we'll assume all the options are for Stella
130
+ unless @command_name
131
+ @stella_arguments = @arguments
132
+ @arguments = []
133
+ end
134
+
135
+ end
136
+
137
+ # process_options
138
+ #
139
+ # Handle the command-line options for stella. Note: The command specific
140
+ # options are handled by the command/*.rb classes
141
+ # display:: When true, it'll print out the options and not parse the arguments
142
+ def process_options(display=false)
143
+
144
+ opts = OptionParser.new
145
+ opts.banner = Stella::TEXT.msg(:option_help_usage)
146
+ opts.on Stella::TEXT.msg(:option_help_preamble, @@commands.keys.join(', '))
147
+
148
+ opts.on(Stella::TEXT.msg(:option_help_options_title))
149
+ opts.on('-V', '--version', Stella::TEXT.msg(:option_help_version)) do
150
+ output_version
151
+ exit 0
152
+ end
153
+ opts.on('-h', '--help', Stella::TEXT.msg(:option_help_help)) { puts opts; exit 0 }
154
+
155
+ opts.on('-v', '--verbose', Stella::TEXT.msg(:option_help_verbose)) do
156
+ @options.verbose ||= 0
157
+ @options.verbose += 1
158
+ end
159
+ opts.on('-q', '--quiet', Stella::TEXT.msg(:option_help_quiet)) do
160
+ @options.quiet = true
161
+ end
162
+
163
+ # Overhead is interesting for development and auditing but we're not
164
+ # currently tracking this. It needed to be re-implemented from scratch
165
+ # so we'll redo this soon. It's also useful for comparing Ruby/JRuby/IronRuby
166
+ #opts.on('--overhead', String, Stella::TEXT.msg(:option_help_overhead)) do
167
+ # @options.showoverhead = true
168
+ #end
169
+
170
+ opts.on('-O', '--stdout', Stella::TEXT.msg(:option_help_stdout)) do
171
+ @options.stdout = true
172
+ end
173
+ opts.on('-E', '--stderr', Stella::TEXT.msg(:option_help_stderr)) do
174
+ @options.stdout = true
175
+ end
176
+
177
+ opts.on('-m', '--message=M', String, Stella::TEXT.msg(:option_help_message)) do |v|
178
+ @options.message = v.to_s
179
+ end
180
+ opts.on('-s', '--sleep=N', Float, Stella::TEXT.msg(:option_help_sleep)) do |v|
181
+ @options.sleep = v.to_f
182
+ end
183
+
184
+ # Ramp up, establish default and enforce limits
185
+ opts.on('-r [R,U]', '--rampup', String, Stella::TEXT.msg(:option_help_rampup)) do |v|
186
+ amount = (v) ? Stella::Util::expand_str(v) : [10,100]
187
+ amount[0] = MathUtil.enforce_limit(amount[0].to_i, 1, 100)
188
+ amount[1] = MathUtil.enforce_limit((amount[1]) ? amount[1].to_i : 0, (amount[0]*2), 1000)
189
+ @options.rampup = amount
190
+ end
191
+
192
+ opts.on('-x', '--testreps=N', Integer, Stella::TEXT.msg(:option_help_testreps)) do |v|
193
+ @options.testreps = MathUtil.enforce_limit(v,1,10)
194
+ end
195
+
196
+ opts.on('-w [N]', '--warmup', Float, Stella::TEXT.msg(:option_help_warmup, 0.1)) do |v|
197
+ @options.warmup = MathUtil.enforce_limit(((v) ? v : 0), 0.1, 1)
198
+ end
199
+
200
+ opts.on('-a', '--agent=[S]', String, Stella::TEXT.msg(:option_help_agent)) do |v|
201
+ @options.agents ||= []
202
+ agent_ary = Stella::Util::expand_str(v || 'random')
203
+ @options.agents.push(agent_ary)
204
+ end
205
+
206
+ # The following options are considered "repeatable" so they're stored in
207
+ # the config file and used as defaults for the next run.
208
+ opts.on('-d', '--datapath=S', String, Stella::TEXT.msg(:option_help_datapath, ".#{File::SEPARATOR}stella")) do |v|
209
+ @options.data_path = v.to_s
210
+ end
211
+ opts.on('-f', '--format=S', String, Stella::TEXT.msg(:option_help_format)) do |v|
212
+ @options.format = v.to_s
213
+ end
214
+
215
+ # This is used for printing the help from other parts of this class
216
+ if display
217
+ Stella::LOGGER.info opts
218
+ return
219
+ end
220
+
221
+ # This applies the configuration above to the arguments provided.
222
+ # It also removes the discovered options from @stella_arguments
223
+ # leaving only the unnamed arguments.
224
+ opts.parse!(@stella_arguments)
225
+
226
+ # Quiet supercedes verbose
227
+ @options.verbose = 0 if @options.quiet
228
+
229
+
230
+ # This outputs when debugging is enabled.
231
+ dump_inputs
232
+
233
+
234
+ rescue OptionParser::InvalidOption => ex
235
+ # We want to replace this text so we grab just the name of the argument
236
+ badarg = ex.message.gsub('invalid option: ', '')
237
+ raise InvalidArgument.new(badarg)
238
+ end
239
+
240
+ #
241
+ # Process data sent to STDIN (a pipe for example).
242
+ # We assume each line is a URI and add it to @arguments.
243
+ def process_standard_input
244
+ return if @stdin.tty? # We only want piped data
245
+
246
+ while !@stdin.eof? do
247
+ line = @stdin.readline
248
+ line.chomp!
249
+ @arguments << line
250
+ end
251
+
252
+ end
253
+
254
+ def output_version
255
+ Stella::LOGGER.info(:cli_print_version, Stella::VERSION.to_s)
256
+ end
257
+
258
+ def dump_inputs
259
+
260
+ #ENV.each_pair do |n,v|
261
+ # Stella::LOGGER.debug("ENV[#{n}]=#{v}")
262
+ #end
263
+
264
+ Stella::LOGGER.debug("Commands (#{@command_name}): #{@@commands.keys.join(',')}")
265
+
266
+ #Stella::LOGGER.debug("Configs: ")
267
+ #@config.to_hash.each_pair do |n,v|
268
+ # Stella::LOGGER.debug(" #{n}=#{v}")
269
+ #end
270
+
271
+ Stella::LOGGER.debug("Options: ")
272
+ @options.marshal_dump.each_pair do |n,v|
273
+ v = [v] unless v.is_a? Array
274
+ Stella::LOGGER.debug(" #{n} = #{v.join(',')}")
275
+ end
276
+
277
+ Stella::LOGGER.debug("Stella Arguments: #{@stella_arguments.join(',')}")
278
+ Stella::LOGGER.debug("Command Arguments: #{@command_arguments.join(',')}" )
279
+ end
280
+ end
281
+ end
282
+
283
+ # Autoload CLI classes. These classes add themselves to the class variable @@commands.
284
+ begin
285
+ cli_classes = Dir.glob(File.join(STELLA_HOME, 'lib', 'stella', 'cli', "*.rb"))
286
+ cli_classes.each do |path|
287
+ require path
288
+ end
289
+ rescue LoadError => ex
290
+ Stella::LOGGER.info("Error loading #{path}: #{ex.message}")
291
+ end
@@ -0,0 +1,73 @@
1
+
2
+
3
+
4
+ module Stella
5
+ class CLI
6
+
7
+ class Agents < Stella::CLI::Base
8
+
9
+ attr_accessor :full
10
+ attr_accessor :list
11
+ attr_accessor :search
12
+ attr_accessor :help
13
+
14
+ def initialize(adapter)
15
+ super(adapter)
16
+ @full = false
17
+ @list = false
18
+ @help = false
19
+ end
20
+
21
+ def run
22
+ process_options
23
+
24
+ if @help
25
+ process_options(:display)
26
+ return
27
+ end
28
+
29
+ # The LocalTest command is the keeper of the user agents
30
+ localtest = Stella::LocalTest.new
31
+
32
+ agents = []
33
+ all_agents = localtest.available_agents
34
+ all_agents.each_pair do |key,value|
35
+ if (@full)
36
+ value.each do |full_value|
37
+ agent = full_value.join(' ')
38
+ agents << agent if (!@search || agent.to_s.match(/#{search}/i))
39
+ end
40
+ else
41
+ agents << key.to_s if (!@search || key.to_s.match(/#{search}/i))
42
+ end
43
+ end
44
+
45
+ puts (@list) ? agents.uniq.sort.join("\n") : Stella::TEXT.msg(:agents_count_message, agents.uniq.size)
46
+
47
+ end
48
+
49
+ def process_options(display=false)
50
+
51
+ opts = OptionParser.new
52
+ opts.banner = Stella::TEXT.msg(:option_help_usage)
53
+ opts.on('-h', '--help', Stella::TEXT.msg(:option_help_help)) { @help = true }
54
+ opts.on('-f', '--full', Stella::TEXT.msg(:agents_option_full)) { @full = true }
55
+ opts.on('-l', '--list', Stella::TEXT.msg(:agents_option_list)) { @list = true }
56
+ # TODO: display agents based on shortnames. This is important to maintain continuity with the stella option.
57
+ #opts.on('-a', '--agent', Stella::TEXT.msg(:agents_option_list)) { @list = true }
58
+ opts.on('-s', '--search=S', String, Stella::TEXT.msg(:agents_option_search)) { |v| @search = v }
59
+
60
+ opts.parse!(@arguments)
61
+
62
+ if display
63
+ Stella::LOGGER.info opts
64
+ return
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ @@commands['agents'] = Stella::CLI::Agents
72
+ end
73
+ end
@@ -0,0 +1,19 @@
1
+ module Stella
2
+ class CLI
3
+ # Stella::CLI::Base
4
+ #
5
+ # A base case for the command line interface classes. All Stella::CLI
6
+ # classes should be based on this class. Otherwise great destruction could occur.
7
+ class Base
8
+ attr_reader :adapter
9
+ attr_accessor :stella_options
10
+ attr_accessor :arguments
11
+ attr_accessor :working_directory
12
+
13
+ def initialize(adapter)
14
+ @adapter_name = adapter
15
+ @options = OpenStruct.new
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+
2
+
3
+
4
+ module Stella
5
+ class CLI
6
+ class Language < Stella::CLI::Base
7
+
8
+
9
+ def run
10
+ languages = Stella::TEXT.available_languages
11
+ puts Stella::TEXT.msg(:text_available_languages, languages.map { |l| "#{l[:language]} " })
12
+ end
13
+
14
+ end
15
+
16
+ @@commands['lang'] = Stella::CLI::Language
17
+ end
18
+ end
@@ -0,0 +1,80 @@
1
+
2
+
3
+ module Stella
4
+ class CLI
5
+ # Stella::CLI::LocalTest
6
+ #
7
+ # A wrapper that takes the command line input and makes it appropriate for
8
+ # calling an instance of Stella::LocalTest. Then it calls that instance!
9
+ class LocalTest < Stella::CLI::Base
10
+
11
+ attr_reader :testdef
12
+
13
+ def initialize(adapter)
14
+ super(adapter)
15
+ @testdef = Stella::Test::Definition.new
16
+
17
+ if (adapter == 'ab')
18
+ @adapter = Stella::Adapter::ApacheBench.new
19
+ elsif (adapter == 'siege')
20
+ @adapter = Stella::Adapter::Siege.new
21
+ elsif (adapter == 'httperf')
22
+ @adapter = Stella::Adapter::Httperf.new
23
+ else
24
+ raise UnknownValue.new(adapter)
25
+ end
26
+
27
+ @driver = Stella::LocalTest.new
28
+ end
29
+
30
+
31
+ def run
32
+ process_stella_options
33
+
34
+ options = @adapter.process_options(@arguments)
35
+
36
+ @adapter.options = options
37
+ @adapter.arguments = @arguments
38
+
39
+ @testdef.vusers = @adapter.vusers
40
+ @testdef.requests = @adapter.requests
41
+
42
+ @driver.adapter = @adapter
43
+ @driver.testdef = @testdef
44
+
45
+ @driver.working_directory = @working_directory
46
+
47
+ @driver.run
48
+
49
+ end
50
+
51
+
52
+
53
+ # process_stella_options
54
+ #
55
+ # Populates @testdef with values from @stella_options
56
+ def process_stella_options
57
+ @testdef.repetitions = @stella_options.testreps
58
+ @testdef.sleep = @stella_options.sleep
59
+ @testdef.warmup = @stella_options.warmup
60
+ @testdef.rampup = @stella_options.rampup
61
+ @testdef.agents = @stella_options.agents
62
+ @testdef.message = @stella_options.message
63
+
64
+
65
+ @driver.quiet = @stella_options.quiet
66
+ @driver.verbose = @stella_options.verbose
67
+ @driver.format = @stella_options.format || 'yaml'
68
+
69
+ end
70
+
71
+
72
+
73
+ end
74
+
75
+
76
+ @@commands['ab'] = Stella::CLI::LocalTest
77
+ @@commands['siege'] = Stella::CLI::LocalTest
78
+ @@commands['httperf'] = Stella::CLI::LocalTest
79
+ end
80
+ end