stella 0.5.3 → 0.5.4

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.txt → README.textile} +63 -40
  2. data/Rakefile +7 -5
  3. data/bin/stella +1 -1
  4. data/bin/stella.bat +12 -0
  5. data/lib/pcaplet.rb +180 -0
  6. data/lib/stella/adapter/ab.rb +57 -33
  7. data/lib/stella/adapter/base.rb +11 -1
  8. data/lib/stella/adapter/httperf.rb +13 -10
  9. data/lib/stella/adapter/pcap_watcher.rb +221 -0
  10. data/lib/stella/adapter/proxy_watcher.rb +76 -0
  11. data/lib/stella/adapter/siege.rb +28 -11
  12. data/lib/stella/cli/agents.rb +2 -2
  13. data/lib/stella/cli/base.rb +37 -1
  14. data/lib/stella/cli/localtest.rb +1 -2
  15. data/lib/stella/cli/sysinfo.rb +17 -0
  16. data/lib/stella/cli/watch.rb +278 -0
  17. data/lib/stella/cli.rb +23 -11
  18. data/lib/stella/command/base.rb +1 -10
  19. data/lib/stella/command/localtest.rb +43 -23
  20. data/lib/stella/data/domain.rb +75 -0
  21. data/lib/stella/data/http.rb +124 -0
  22. data/lib/stella/logger.rb +16 -5
  23. data/lib/stella/storable.rb +4 -2
  24. data/lib/stella/support.rb +71 -0
  25. data/lib/stella/sysinfo.rb +247 -0
  26. data/lib/stella/test/base.rb +5 -1
  27. data/lib/stella/test/definition.rb +1 -1
  28. data/lib/stella/test/run/summary.rb +14 -4
  29. data/lib/stella/text/resource.rb +0 -1
  30. data/lib/stella.rb +28 -10
  31. data/lib/utils/domainutil.rb +47 -0
  32. data/lib/utils/fileutil.rb +22 -3
  33. data/lib/utils/httputil.rb +184 -128
  34. data/lib/utils/mathutil.rb +20 -7
  35. data/lib/win32/Console/ANSI.rb +305 -0
  36. data/lib/win32/Console.rb +970 -0
  37. data/spec/show-agents_spec.rb +0 -0
  38. data/support/kvm.h +91 -0
  39. data/support/ruby-pcap-takuma-notes.txt +19 -0
  40. data/support/ruby-pcap-takuma-patch.txt +30 -0
  41. data/support/text/en.yaml +26 -3
  42. data/vendor/frylock/README.textile +72 -0
  43. data/vendor/frylock/bin/example +170 -0
  44. data/vendor/frylock/frylock.gemspec +18 -0
  45. data/vendor/frylock/lib/frylock/exceptions.rb +24 -0
  46. data/vendor/frylock/lib/frylock.rb +232 -0
  47. data/vendor/frylock/test/command_test.rb +33 -0
  48. data/vendor/hitimes-0.4.0/HISTORY +28 -0
  49. data/vendor/hitimes-0.4.0/LICENSE.txt +19 -0
  50. data/vendor/hitimes-0.4.0/README +80 -0
  51. data/vendor/hitimes-0.4.0/Rakefile +63 -0
  52. data/vendor/hitimes-0.4.0/examples/benchmarks.rb +86 -0
  53. data/vendor/hitimes-0.4.0/examples/stats.rb +29 -0
  54. data/vendor/hitimes-0.4.0/ext/extconf.rb +15 -0
  55. data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +21 -0
  56. data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +20 -0
  57. data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +16 -0
  58. data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +27 -0
  59. data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +340 -0
  60. data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +73 -0
  61. data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +242 -0
  62. data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +30 -0
  63. data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +178 -0
  64. data/vendor/hitimes-0.4.0/ext/rbconfig.rb +178 -0
  65. data/vendor/hitimes-0.4.0/gemspec.rb +54 -0
  66. data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +23 -0
  67. data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +54 -0
  68. data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +29 -0
  69. data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +223 -0
  70. data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +42 -0
  71. data/vendor/hitimes-0.4.0/lib/hitimes.rb +24 -0
  72. data/vendor/hitimes-0.4.0/spec/interval_spec.rb +115 -0
  73. data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +34 -0
  74. data/vendor/hitimes-0.4.0/spec/paths_spec.rb +14 -0
  75. data/vendor/hitimes-0.4.0/spec/spec_helper.rb +6 -0
  76. data/vendor/hitimes-0.4.0/spec/stats_spec.rb +72 -0
  77. data/vendor/hitimes-0.4.0/spec/timer_spec.rb +105 -0
  78. data/vendor/hitimes-0.4.0/spec/version_spec.rb +27 -0
  79. data/vendor/hitimes-0.4.0/tasks/announce.rake +39 -0
  80. data/vendor/hitimes-0.4.0/tasks/config.rb +107 -0
  81. data/vendor/hitimes-0.4.0/tasks/distribution.rake +53 -0
  82. data/vendor/hitimes-0.4.0/tasks/documentation.rake +33 -0
  83. data/vendor/hitimes-0.4.0/tasks/extension.rake +64 -0
  84. data/vendor/hitimes-0.4.0/tasks/rspec.rake +31 -0
  85. data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +52 -0
  86. data/vendor/hitimes-0.4.0/tasks/utils.rb +80 -0
  87. data/vendor/useragent/lib/user_agent.rb +1 -1
  88. metadata +87 -8
@@ -0,0 +1,124 @@
1
+
2
+ require 'utils/httputil'
3
+ require 'base64'
4
+
5
+ module Stella::Data
6
+
7
+ # TODO: Implement HTTPHeaders. We should be printing untouched headers.
8
+ # HTTPUtil should split the HTTP event lines and that's it. Replace
9
+ # parse_header_body with split_header_body
10
+ class HTTPHeaders < Stella::Storable
11
+ attr_reader :raw_data
12
+
13
+ def to_s
14
+ @raw_data
15
+ end
16
+
17
+ end
18
+
19
+ class HTTPRequest < Stella::Storable
20
+ attr_accessor :time, :client_ip, :server_ip, :header, :body, :method, :http_version
21
+ attr_reader :raw_data
22
+ attr_writer :uri, :body
23
+ attr_accessor :response
24
+
25
+ def has_body?
26
+ @body && !@body.nil & !@body.empty?
27
+ end
28
+ def has_request?
29
+ false
30
+ end
31
+ def has_response?
32
+ (@response && @response.status && !@response.status.nil?)
33
+ end
34
+
35
+ def initialize(raw_data=nil)
36
+ @raw_data = raw_data
37
+ if @raw_data
38
+ @method, @http_version, @uri, @header, @body = HTTPUtil::parse_http_request(raw_data)
39
+ end
40
+ @response = Stella::Data::HTTPResponse.new
41
+ end
42
+
43
+ def uri
44
+ @uri.host = @server_ip.to_s if @uri && (@uri.host == 'unknown' || @uri.host.empty?)
45
+ @uri
46
+ end
47
+
48
+ def body
49
+ return nil unless @body
50
+ @body
51
+ #(!header || header[:Content_Type] || header[:Content_Type] !~ /text/) ? Base64.encode64(@body) : @body
52
+ end
53
+
54
+ def field_names
55
+ [ :time, :client_ip, :server_ip, :header, :uri, :body, :method, :http_version ]
56
+ end
57
+
58
+ def inspect
59
+ headers = []
60
+ header.each_pair do |n,v|
61
+ headers << "#{n.to_s.gsub('_', '-')}: #{v[0]}"
62
+ end
63
+ str = "%s %s HTTP/%s" % [method, uri.to_s, http_version]
64
+ str << $/ + headers.join($/)
65
+ str << $/ + $/ + body if body
66
+ str
67
+ end
68
+
69
+ def to_s
70
+ str = "%s: %s %s HTTP/%s" % [time.strftime(NICE_TIME_FORMAT), method, uri.to_s, http_version]
71
+ str
72
+ end
73
+
74
+ end
75
+
76
+ class HTTPResponse < Stella::Storable
77
+ attr_accessor :time, :client_ip, :server_ip, :header, :status, :message, :http_version
78
+ attr_reader :raw_data
79
+ attr_writer :body
80
+
81
+ def initialize(raw_data=nil)
82
+ @raw_data = raw_data
83
+ if @raw_data
84
+ @status, @http_version, @message, @header, @body = HTTPUtil::parse_http_response(@raw_data)
85
+ end
86
+ end
87
+
88
+ def has_body?
89
+ @body && !@body.nil & !@body.empty?
90
+ end
91
+ def has_request?
92
+ false
93
+ end
94
+ def has_response?
95
+ false
96
+ end
97
+
98
+ def body
99
+ return nil unless @body
100
+ #Base64.encode64(@body)
101
+ (!header || !header[:Content_Type] || header[:Content_Type] !~ /text/) ? '' : @body
102
+ end
103
+
104
+ def field_names
105
+ [ :time, :client_ip, :server_ip, :header, :body, :status, :message, :http_version ]
106
+ end
107
+
108
+ def inspect
109
+ headers = []
110
+ header.each_pair do |n,v|
111
+ headers << "#{n.to_s.gsub('_', '-')}: #{v[0]}"
112
+ end
113
+ str = "HTTP/%s %s (%s)" % [@http_version, @status, @message]
114
+ str << $/ + headers.join($/)
115
+ str << $/ + $/ + body if body
116
+ str
117
+ end
118
+
119
+ def to_s
120
+ str = "%s: HTTP/%s %s (%s)" % [time.strftime(NICE_TIME_FORMAT), @http_version, @status, @message]
121
+ str
122
+ end
123
+ end
124
+ end
data/lib/stella/logger.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Stella
4
4
  class Logger
5
- attr_accessor :debug
5
+ attr_accessor :debug_level
6
6
 
7
7
  # +args+ is a hash of initialization arguments
8
8
  # * <tt>:info_logger</tt> The IO class for info level logging. Default: STDOUT
@@ -10,7 +10,7 @@ module Stella
10
10
  # * <tt>:debug_logger</tt> The IO class for error level logging. Default: STDERR
11
11
  # * <tt>:debug</tt> Log debugging output, true or false (default)
12
12
  def initialize(args={})
13
- @debug = args[:debug] || false
13
+ @debug_level = args[:debug] || false
14
14
  @info_logger = args[:info_logger] || STDOUT
15
15
  @error_logger = args[:error_logger] || STDERR
16
16
  @debug_logger = args[:debug_logger] || STDERR
@@ -31,6 +31,12 @@ module Stella
31
31
  @info_logger.flush
32
32
  end
33
33
 
34
+ def flush
35
+ @info_logger.flush
36
+ @error_logger.flush
37
+ @debug_logger.flush
38
+ end
39
+
34
40
  # Print all messages on a single line.
35
41
  def info_print(*msgs)
36
42
  msgs.each do |m|
@@ -46,15 +52,20 @@ module Stella
46
52
  end
47
53
 
48
54
  def debug(*msgs)
49
- return unless @debug
55
+ return unless @debug_level
50
56
  msgs.each do |m|
51
57
  @debug_logger.puts "DEBUG: #{m}"
52
58
  end
53
59
  @debug_logger.flush
54
60
  end
61
+ def warn(ex, prefix="WARN: ")
62
+ error(ex, prefix)
63
+ end
64
+
55
65
  def error(ex, prefix="ERR: ")
56
- @error_logger.puts "#{prefix}#{ex.message}"
57
- return unless @debug
66
+ msg = (ex.kind_of? String) ? ex : ex.message
67
+ @error_logger.puts "#{prefix}#{msg}"
68
+ return unless @debug_level && ex.kind_of?(Exception)
58
69
  @error_logger.puts("#{prefix}------------------------------------------")
59
70
  @error_logger.puts("#{prefix}#{ex.backtrace.join("\n")}")
60
71
  @error_logger.puts("#{prefix}------------------------------------------")
@@ -1,8 +1,10 @@
1
1
 
2
+ # TODO: Handle nested hashes and arrays.
2
3
 
3
4
  module Stella
4
5
  class Storable
5
-
6
+ NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze unless defined? NICE_TIME_FORMAT
7
+
6
8
  SupportedFormats= {
7
9
  'yaml' => 'yml', # format name => file extension
8
10
  'yml' => 'yml',
@@ -96,7 +98,7 @@ module Stella
96
98
  end
97
99
 
98
100
  def self.from_hash(from={})
99
- return if from.empty?
101
+ return if !from || from.empty?
100
102
  me = self.new
101
103
  fnames = me.to_hash.keys
102
104
  fnames.each do |key|
@@ -11,6 +11,7 @@ module Stella
11
11
  def message
12
12
  Stella::TEXT.err(:error_invalid_argument, @name)
13
13
  end
14
+
14
15
  end
15
16
 
16
17
  class UnavailableAdapter < RuntimeError
@@ -36,6 +37,27 @@ module Stella
36
37
  class UnsupportedLanguage < RuntimeError
37
38
  end
38
39
 
40
+ class MissingDependency < RuntimeError
41
+ attr_accessor :dependency, :reason
42
+ def initialize(dependency, reason=:error_generic)
43
+ @dependency = dependency
44
+ @reason = (reason.kind_of? Symbol) ? Stella::TEXT.err(reason) : reason
45
+ end
46
+ def message
47
+ Stella::TEXT.err(:error_missing_dependency, @dependency, @reason)
48
+ end
49
+ end
50
+
51
+ class AdapterError < MissingDependency
52
+ def initialize(adapter, reason=:error_generic)
53
+ @adapter = adapter
54
+ @reason = (reason.kind_of? Symbol) ? Stella::TEXT.err(reason) : reason
55
+ end
56
+ def message
57
+ Stella::TEXT.err(:error_adapter_runtime, @adapter, @reason)
58
+ end
59
+ end
60
+
39
61
  class Util
40
62
 
41
63
  # process_useragents
@@ -101,6 +123,55 @@ module Stella
101
123
  str.split(/\s*[,\-]\s*/) # remove extra spaces at the same time.
102
124
  end
103
125
 
126
+
127
+ # capture_output
128
+ #
129
+ # +cmd+ is a shell command to run with Kernel.` It will be appended with
130
+ # redirects to send STDOUT and STDERR to temp files. If the command already
131
+ # contains redirects they will be removed and replaced.
132
+ # The tempfiles are sent to yield as arrays of lines (using file_sout.readlines)
133
+ # and deleted before returning.
134
+ #
135
+ # We use files because popen and open3 are not implemented on Windows.
136
+ def self.capture_output(cmd)
137
+ return unless cmd
138
+ file_sout = Tempfile.new("stdout" << strand(6)) # We add a strand to be super sure it doesn't exist
139
+ file_serr = Tempfile.new("stderr" << strand(6))
140
+ cmd.gsub!(/1>.+/, '')
141
+ cmd.gsub!(/2>.+/, '')
142
+ cmd = "#{cmd} 1> \"#{file_sout.path}\" 2> \"#{file_serr.path}\""
143
+ begin
144
+ # Windows will have a conniption because the tempfiles are already open.
145
+ # We close them here and then open them to read them.
146
+ file_sout.close
147
+ file_serr.close
148
+
149
+ system(cmd)
150
+
151
+ file_sout.open
152
+ file_serr.open
153
+ sout, serr = file_sout.readlines, file_serr.readlines
154
+ file_sout.close
155
+ file_serr.close
156
+
157
+ yield(sout, serr)
158
+
159
+ ensure
160
+ file_sout.delete
161
+ file_serr.delete
162
+ end
163
+ end
164
+
165
+ #
166
+ # Generates a string of random alphanumeric characters
167
+ # These are used as IDs throughout the system
168
+ def self.strand( len )
169
+ chars = ("a".."z").to_a + ("0".."9").to_a
170
+ newpass = ""
171
+ 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
172
+ return newpass
173
+ end
174
+
104
175
  end
105
176
 
106
177
  end
@@ -0,0 +1,247 @@
1
+
2
+
3
+ module Stella
4
+ # Stella::SystemInfo
5
+ #
6
+ # A container for the system platform information.
7
+ # Portions of this code is from Amazon's EC2 AMI tools, lib/platform.rb.
8
+ class SystemInfo < Stella::Storable
9
+ IMPLEMENTATIONS = [
10
+ # These are for JRuby, System.getproperty('os.name').
11
+ # For a list of all values, see: http://lopica.sourceforge.net/os.html
12
+ [/mac\s*os\s*x/i, :unix, :osx ],
13
+ [/sunos/i, :unix, :solaris ],
14
+ [/windows\s*ce/i, :win32, :windows ],
15
+ [/windows/i, :win32, :windows ],
16
+ [/osx/i, :unix, :osx ],
17
+
18
+ # These are for RUBY_PLATFORM and JRuby
19
+ [/java/i, :java, :java ],
20
+ [/darwin/i, :unix, :osx ],
21
+ [/linux/i, :unix, :linux ],
22
+ [/freebsd/i, :unix, :freebsd ],
23
+ [/netbsd/i, :unix, :netbsd ],
24
+ [/solaris/i, :unix, :solaris ],
25
+ [/irix/i, :unix, :irix ],
26
+ [/cygwin/i, :unix, :cygwin ],
27
+ [/mswin/i, :win32, :windows ],
28
+ [/mingw/i, :win32, :mingw ],
29
+ [/bccwin/i, :win32, :bccwin ],
30
+ [/wince/i, :win32, :wince ],
31
+ [/vms/i, :vms, :vms ],
32
+ [/os2/i, :os2, :os2 ],
33
+ [nil, :unknown, :unknown ],
34
+ ]
35
+
36
+ ARCHITECTURES = [
37
+ [/(i\d86)/i, :i386 ],
38
+ [/x86_64/i, :x86_64 ],
39
+ [/x86/i, :i386 ], # JRuby
40
+ [/ia64/i, :ia64 ],
41
+ [/alpha/i, :alpha ],
42
+ [/sparc/i, :sparc ],
43
+ [/mips/i, :mips ],
44
+ [/powerpc/i, :powerpc ],
45
+ [/universal/i,:universal ],
46
+ [nil, :unknown ],
47
+ ]
48
+
49
+ attr_reader :os
50
+ attr_reader :implementation
51
+ attr_reader :architecture
52
+ attr_reader :hostname
53
+ attr_reader :ipaddress
54
+ attr_reader :uptime
55
+
56
+ def field_names
57
+ [
58
+ :os, :implementation, :architecture, :hostname, :ipaddress, :uptime
59
+ ]
60
+ end
61
+
62
+ def initialize
63
+ @os, @implementation, @architecture = guess
64
+ @hostname, @ipaddress, @uptime = get_info
65
+ end
66
+
67
+ # guess
68
+ #
69
+ # This is called at require-time in stella.rb. It guesses
70
+ # the current operating system, implementation, architecture.
71
+ # Returns [os, impl, arch]
72
+ def guess
73
+ os = :unknown
74
+ impl = :unknown
75
+ arch = :unknown
76
+ IMPLEMENTATIONS.each do |r, o, i|
77
+ if r and RUBY_PLATFORM =~ r
78
+ os, impl = [o, i]
79
+ break
80
+ end
81
+ end
82
+ ARCHITECTURES.each do |r, a|
83
+ if r and RUBY_PLATFORM =~ r
84
+ arch = a
85
+ break
86
+ end
87
+ end
88
+
89
+ #
90
+ if os == :win32
91
+ require 'Win32API'
92
+
93
+ # If we're running in java, we'll need to look elsewhere
94
+ # for the implementation and architecture.
95
+ # We'll replace IMPL and ARCH with what we find.
96
+ elsif os == :java
97
+ require 'java'
98
+ include_class java.lang.System
99
+
100
+ osname = System.getProperty("os.name")
101
+ IMPLEMENTATIONS.each do |r, o, i|
102
+ if r and osname =~ r
103
+ impl = i
104
+ break
105
+ end
106
+ end
107
+
108
+ osarch = System.getProperty("os.arch")
109
+ ARCHITECTURES.each do |r, a|
110
+ if r and osarch =~ r
111
+ arch = a
112
+ break
113
+ end
114
+ end
115
+
116
+ end
117
+
118
+ [os, impl, arch]
119
+ end
120
+
121
+ # get_info
122
+ #
123
+ # Returns [hostname, ipaddr, uptime] for the local machine
124
+ def get_info
125
+ hostname = :unknown
126
+ ipaddr = :unknown
127
+ uptime = :unknown
128
+
129
+ begin
130
+ hostname = Socket.gethostname
131
+ ipaddr = local_ip_address
132
+ uptime = local_uptime
133
+ rescue => ex
134
+ end
135
+
136
+ [hostname, ipaddr, uptime]
137
+ end
138
+
139
+
140
+ # local_uptime
141
+ #
142
+ #
143
+ # Returns the local uptime in hours. Use Win32API in Windows,
144
+ # 'sysctl -b kern.boottime' os osx, and 'who -b' on unix.
145
+ # Based on Ruby Quiz solutions by: Matthias Reitinger
146
+ # On Windows, see also: net statistics server
147
+ def local_uptime
148
+
149
+ # Each method must return uptime in seconds
150
+ methods = {
151
+
152
+ :win32_windows => lambda {
153
+ # Win32API is required in self.guess
154
+ getTickCount = Win32API.new("kernel32", "GetTickCount", nil, 'L')
155
+ ((getTickCount.call()).to_f / 1000).to_f
156
+ },
157
+
158
+ # Ya, this is kinda wack. Ruby -> Java -> Kernel32. See:
159
+ # http://www.oreillynet.com/ruby/blog/2008/01/jruby_meets_the_windows_api_1.html
160
+ # http://msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx
161
+ # Ruby 1.9.1: Win32API is now deprecated in favor of using the DL library.
162
+ :java_windows => lambda {
163
+ kernel32 = com.sun.jna.NativeLibrary.getInstance('kernel32')
164
+ buf = java.nio.ByteBuffer.allocate(256)
165
+ (kernel32.getFunction('GetTickCount').invokeInt([256, buf].to_java).to_f / 1000).to_f
166
+ },
167
+
168
+ :unix_osx => lambda {
169
+ # This is faster than who and could work on BSD also.
170
+ (Time.now.to_f - Time.at(`sysctl -b kern.boottime 2>/dev/null`.unpack('L').first).to_f).to_f
171
+
172
+ },
173
+ # This should work for most unix flavours.
174
+ :unix => lambda {
175
+ # who is sloooooow. Use File.read('/proc/uptime')
176
+ (Time.now.to_f - Time.parse(`who -b 2>/dev/null`).to_f)
177
+ }
178
+ }
179
+
180
+ hours = 0
181
+
182
+ begin
183
+ key = platform
184
+ method = (methods.has_key? key) ? methods[key] : methods[:unix]
185
+ hours = (method.call) / 3600 # seconds to hours
186
+ rescue => ex
187
+ end
188
+ hours
189
+ end
190
+
191
+
192
+ # local_ip_address
193
+ #
194
+ # Return the local IP address which receives external traffic
195
+ # from: http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
196
+ # NOTE: This <em>does not</em> open a connection to the IP address.
197
+ def local_ip_address
198
+ # turn off reverse DNS resolution temporarily
199
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
200
+ UDPSocket.open {|s| s.connect('75.101.137.7', 1); s.addr.last } # Solutious IP
201
+ ensure
202
+ Socket.do_not_reverse_lookup = orig
203
+ end
204
+
205
+ # local_ip_address_alt
206
+ #
207
+ # Returns the local IP address based on the hostname.
208
+ # According to coderrr (see comments on blog link above), this implementation
209
+ # doesn't guarantee that it will return the address for the interface external
210
+ # traffic goes through. It's also possible the hostname isn't resolvable to the
211
+ # local IP.
212
+ def local_ip_address_alt
213
+ ipaddr = :unknown
214
+ begin
215
+ saddr = Socket.getaddrinfo( Socket.gethostname, nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)
216
+ ipaddr = saddr.select{|type| type[0] == 'AF_INET' }[0][3]
217
+ rescue => ex
218
+ end
219
+ ipaddr
220
+ end
221
+
222
+ # platform
223
+ #
224
+ # returns a symbol in the form: os_implementation. This is used throughout Stella
225
+ # for platform specific support.
226
+ def platform
227
+ "#{@os}_#{@implementation}".to_sym
228
+ end
229
+
230
+ # ruby
231
+ #
232
+ # Returns Ruby version as an array
233
+ def ruby
234
+ RUBY_VERSION.split('.').map { |v| v.to_i }
235
+ end
236
+
237
+ # to_s
238
+ #
239
+ # Print friendly system information.
240
+ def to_s
241
+ sprintf("Hostname: %s#{$/}IP Address: %s#{$/}System: %s#{$/}Uptime: %.2f (hours)#{$/}Ruby: #{ruby.join('.')}",
242
+ @hostname, @ipaddress, "#{@os}-#{@implementation}-#{@architecture}", @uptime)
243
+ end
244
+
245
+
246
+ end
247
+ end
@@ -11,7 +11,11 @@ module Stella::Test
11
11
 
12
12
  def availability
13
13
  return 0 if @successful_total == 0
14
- (@transactions_total / @successful_total).to_f * 100
14
+ begin
15
+ (@transactions_total / @successful_total).to_f * 100
16
+ rescue => ex
17
+ 0.0
18
+ end
15
19
  end
16
20
 
17
21
 
@@ -45,7 +45,7 @@ module Stella
45
45
  attr_accessor :warmup
46
46
  # Contains an interval and maximum threshold to increase virtual users.
47
47
  # Rampup object, [R,M] where R is the interval and M is the maximum.
48
- attr_accessor :rampup
48
+ attr_reader :rampup
49
49
  # An array of string appropriate for a User-Agent HTTP header
50
50
  attr_accessor :agents
51
51
  # A short reminder to yourself what you're testing
@@ -25,15 +25,21 @@ module Stella::Test::Run
25
25
  end
26
26
 
27
27
  def availability
28
- return 0 if @successful == 0
29
- (@transactions / @successful).to_f * 100
28
+ begin
29
+ (@transactions / @successful).to_f * 100
30
+ rescue => ex
31
+ return 0.0
32
+ end
30
33
  end
31
34
 
32
35
  # We calculate the throughput because Apache Bench does not provide this
33
36
  # value in the output.
34
37
  def throughput
35
- return 0 if !@elapsed_time || @elapsed_time == 0
36
- (@data_transferred / @elapsed_time).to_f
38
+ begin
39
+ return (@data_transferred / @elapsed_time).to_f
40
+ rescue => ex
41
+ return 0.0
42
+ end
37
43
  end
38
44
 
39
45
  def field_names
@@ -44,6 +50,10 @@ module Stella::Test::Run
44
50
  ]
45
51
  end
46
52
 
53
+ def available?
54
+ @successful && @transactions && @elapsed_time && @vusers && @response_time
55
+ end
56
+
47
57
  end
48
58
 
49
59
 
@@ -7,7 +7,6 @@ module Stella
7
7
  require 'yaml'
8
8
 
9
9
  attr_reader :lang, :country, :encoding
10
- attr_reader :messages, :path
11
10
 
12
11
  def initialize(path, lang)
13
12
  @path = path
data/lib/stella.rb CHANGED
@@ -1,26 +1,35 @@
1
1
 
2
- $: << File.join(STELLA_HOME, 'vendor', 'useragent', 'lib')
3
-
4
2
 
5
3
  require 'date'
6
- require 'open3'
4
+ require 'time'
5
+ require 'tempfile'
6
+ require 'socket'
7
7
 
8
8
  # Common utilities
9
+ require 'utils/domainutil'
9
10
  require 'utils/httputil'
10
- require 'utils/crypto-key'
11
11
  require 'utils/fileutil'
12
12
  require 'utils/mathutil'
13
13
  require 'utils/escape'
14
14
 
15
15
  # Common dependencies
16
+ $: << File.join(STELLA_HOME, 'vendor', 'useragent', 'lib')
17
+ require 'user_agent'
18
+
19
+ # Common Stella dependencies
16
20
  require 'stella/support'
17
21
  require 'stella/storable'
18
- require 'user_agent'
19
22
 
20
- # Common objects
23
+ # Common Stella Data Objects
24
+ require 'stella/data/http'
25
+ require 'stella/data/domain'
26
+
27
+ # Common Stella objects
21
28
  require 'stella/text'
29
+
22
30
  require 'stella/logger'
23
31
  require 'stella/response'
32
+ require 'stella/sysinfo'
24
33
  require 'stella/test/definition'
25
34
  require 'stella/test/run/summary'
26
35
  require 'stella/test/summary'
@@ -38,14 +47,23 @@ require 'stella/adapter/httperf'
38
47
  # = Stella
39
48
  # A friend in performance testing.
40
49
  #
50
+ # This class ties Stella together. It must be required because it defines
51
+ # several constants which are used througout the other classes. +SYSINFO+
52
+ # is particularly important because it detects the platform and requires
53
+ # platform specific modules.
41
54
  module Stella
42
- LOGGER = Stella::Logger.new(:debug=>false)
43
- TEXT = Stella::Text.new('en')
55
+ # Autodetecets information about the local system,
56
+ # including OS (unix), implementation (freebsd), and architecture (x64)
57
+ SYSINFO = Stella::SystemInfo.new unless defined? SYSINFO
58
+ # A global logger for info, error, and debug messages.
59
+ LOGGER = Stella::Logger.new(:debug=>true) unless defined? LOGGER
60
+ # A global resource for all interface text.
61
+ TEXT = Stella::Text.new('en') unless defined? TEXT
44
62
 
45
63
  module VERSION #:nodoc:
46
64
  MAJOR = 0.freeze unless defined? MAJOR
47
65
  MINOR = 5.freeze unless defined? MINOR
48
- TINY = 3.freeze unless defined? TINY
66
+ TINY = 4.freeze unless defined? TINY
49
67
  def self.to_s
50
68
  [MAJOR, MINOR, TINY].join('.')
51
69
  end
@@ -53,6 +71,6 @@ module Stella
53
71
  self.to_s.to_f
54
72
  end
55
73
  end
56
-
74
+
57
75
  end
58
76