Class | Stella::Adapter::Siege |
In: |
lib/stella/adapter/siege.rb
|
Parent: | Stella::Adapter::Base |
SIEGE Usage: siege [options]
siege [options] URL siege -g URL
Options:
-V, --version VERSION, prints version number to screen. -h, --help HELP, prints this section. -C, --config CONFIGURATION, show the current configuration. -v, --verbose VERBOSE, prints notification to screen. -g, --get GET, pull down headers from the server and display HTTP transaction. Great for web application debugging. -c, --concurrent=NUM CONCURRENT users, default is 10 -u, --url="URL" Deprecated. Set URL as the last argument. -i, --internet INTERNET user simulation, hits the URLs randomly. -b, --benchmark BENCHMARK, signifies no delay for time testing. -t, --time=NUMm TIME based testing where "m" is the modifier S, M, or H no space between NUM and "m", ex: --time=1H, one hour test. -r, --reps=NUM REPS, number of times to run the test, default is 25 -f, --file=FILE FILE, change the configuration file to file. -R, --rc=FILE RC, change the siegerc file to file. Overrides the SIEGERC environmental variable. -l, --log LOG, logs the transaction to PREFIX/var/siege.log -m, --mark="text" MARK, mark the log file with a string separator. -d, --delay=NUM Time DELAY, random delay between 1 and num designed to simulate human activity. Default value is 3 -H, --header="text" Add a header to request (can be many) -A, --user-agent="text" Sets User-Agent in request
benchmark | [RW] | |
concurrent | [RW] | |
config | [RW] | |
delay | [RW] | |
file | [RW] | |
get | [RW] | |
header | [RW] | |
help | [RW] | |
internet | [RW] | |
log | [RW] | |
mark | [RW] | |
rc | [RW] | |
reps | [RW] | |
time | [RW] | |
user_agent | [RW] | |
verbose | [RW] | |
version | [RW] |
# File lib/stella/adapter/siege.rb, line 39 39: def initialize(options={}, arguments=[]) 40: super(options, arguments) 41: @name = 'siege' 42: @reps = 1 43: @concurrent = 1 44: @rc = File.join(ENV['HOME'], '.siegerc') 45: @private_variables = ['private_variables', 'name', 'arguments', 'load_factor', 'working_directory', 'orig_logfile'] 46: @load_factor = 1 47: end
After calling run
# File lib/stella/adapter/siege.rb, line 110 110: def after 111: 112: update_orig_logfile if @orig_logfile 113: 114: save_stats 115: end
Before calling run
# File lib/stella/adapter/siege.rb, line 75 75: def before 76: 77: # Keep a copy of the configuration file. 78: copy_siegerc 79: 80: # Keep a copy of the URLs file. 81: copy_urls_file if @file 82: 83: # TODO: Print message about neither --benchmark or --internet 84: end
# File lib/stella/adapter/siege.rb, line 85 85: def command 86: raise CommandNotReady.new(self.class.to_s) unless ready? 87: 88: command = "#{@name} " 89: 90: instance_variables.each do |name| 91: canon = name.tr('@', '') # instance_variables returns '@name' 92: next if @private_variables.member?(canon) 93: 94: # It's important that we take the value from the getter method 95: # because it applies the load factor. 96: value = self.send(canon) 97: if (value.is_a? Array) 98: value.each { |el| command << "--#{cannon.tr('_', '-')} '#{el}' " } 99: else 100: command << "--#{canon.tr('_', '-')} '#{value}' " 101: end 102: 103: end 104: 105: command << (@arguments.map { |uri| "'#{uri}'" }).join(' ') unless @arguments.empty? 106: command 107: end
# File lib/stella/adapter/siege.rb, line 170 170: def concurrent 171: (@concurrent * @load_factor).to_i 172: end
# File lib/stella/adapter/siege.rb, line 173 173: def concurrent_f 174: (@concurrent * @load_factor).to_f 175: end
We want to keep a copy of the configuration file and also modify it a little bit to make sure we get all the mad info from siege
# File lib/stella/adapter/siege.rb, line 200 200: def copy_siegerc 201: 202: # Read in the siegerc file so we can manipulate it 203: siegerc_str = FileUtil.read_file(File.expand_path(@rc)) 204: 205: siegerc_vars = { 206: :verbose => [false, true], # We want to maximize the data output by siege 207: :logging => [false, true], 208: :csv => [false, true] 209: } 210: 211: #if (@agent) 212: # siegerc_vars['user-agent'] = ['.*', 'dogs2'] 213: #end 214: 215: # We'll set the variables in the siegerc file 216: siegerc_vars.each_pair do |var,value| 217: siegerc_str.gsub!(/#{var}\s*=\s*#{value[0]}/, "#{var} = #{value[1]}") # make true 218: siegerc_str.gsub!(/^\#+\s*#{var}/, "#{var}") # remove comment 219: end 220: 221: # Look for the enabled logile path 222: # We will use this later to update it from the last line in our copy 223: siegerc_str =~ /^\s*logfile\s*=\s*(.+?)$/ 224: @orig_logfile = $1 || nil 225: 226: # Replace all environment variables with literal values 227: @orig_logfile.gsub!(/\$\{#{$1}\}/, ENV[$1]) while (@orig_logfile =~ /\$\{(.+?)\}/ && ENV.has_key?($1)) 228: 229: @orig_logfile = File.expand_path(@orig_logfile) if @orig_logfile 230: 231: 232: siegerc_str.gsub!(/^\#*\s*logfile\s*=\s*.*?$/, "logfile = " + log_file) 233: 234: FileUtil.write_file(rc_file, siegerc_str, true) 235: @rc = rc_file 236: end
We want to keep a copy of the URLs file too
# File lib/stella/adapter/siege.rb, line 239 239: def copy_urls_file 240: if @file 241: File.copy(File.expand_path(@file), uris_file) 242: @file = uris_file 243: end 244: end
loadtest
True or false: is the call to siege a load test? If it‘s a call to help or version or to display the config this with return false. It‘s no reason for someone to make this call through Stella but it‘s here for goodness sake.
# File lib/stella/adapter/siege.rb, line 65 65: def loadtest? 66: !@arguments.empty? # The argument is a URI 67: end
# File lib/stella/adapter/siege.rb, line 255 255: def log_file 256: File.join(@working_directory, "siege.log") 257: end
# File lib/stella/adapter/siege.rb, line 118 118: def process_options(arguments) 119: options = OpenStruct.new 120: opts = OptionParser.new 121: opts.on('-V', '--version') do |v| options.version = v end 122: opts.on('-h', '--help') do |v| options.help = v end 123: opts.on('-C', '--config') do |v| options.config = v end 124: opts.on('-v', '--verbose') do |v| options.verbose = v end 125: opts.on('-g', '--get') do |v| options.get = v end 126: opts.on('-l', '--log') do |v| options.log = v end 127: opts.on('-m S', '--mark=S', String) do |v| options.mark = v end 128: opts.on('-d N', '--delay=N', Float) do |v| options.delay = v end 129: opts.on('-H S', '--header=S', String) do |v| options.header ||= []; options.header << v end 130: 131: opts.on('-r N', '--reps=N', Integer) do |v| options.reps = v.to_i end 132: opts.on('-c N', '--concurrent=N', Integer) do |v| options.concurrent = v.to_i end 133: opts.on('-R S', '--rc=S', String) do |v| options.rc = v end 134: opts.on('-f S', '--file=S', String) do |v| options.file = v end 135: opts.on('-t S', '--time=S', String) do |v| options.time = v end 136: opts.on('-b', '--benchmark') do |v| options.benchmark = true; end 137: opts.on('-i', '--internet') do |v| options.internet = true; end 138: opts.on('-A S', '--user-agent=S', String) do |v| options.user_agent = v end 139: 140: raise "You cannot select both --internet and --benchmark" if options.internet && options.benchmark 141: 142: # parse! removes the options it finds. 143: # It also fails when it finds unknown switches (i.e. -X) 144: # Which should leave only the remaining arguments (URIs in this case) 145: opts.parse!(arguments) 146: options 147: rescue OptionParser::InvalidOption => ex 148: # We want to replace this text so we grab just the name of the argument 149: badarg = ex.message.gsub('invalid option: ', '') 150: raise InvalidArgument.new(badarg) 151: end
# File lib/stella/adapter/siege.rb, line 251 251: def rc_file 252: File.join(@working_directory, "siegerc") 253: end
# File lib/stella/adapter/siege.rb, line 69 69: def ready? 70: @name && !instance_variables.empty? 71: end
# File lib/stella/adapter/siege.rb, line 160 160: def requests 161: (@reps * concurrent_f).to_i 162: end
# File lib/stella/adapter/siege.rb, line 163 163: def requests=(v) 164: @reps = (v / concurrent_f).to_i 165: end
# File lib/stella/adapter/siege.rb, line 263 263: def stats 264: return unless stats_file 265: raw = {} 266: stats_file.each_line { |l| 267: l.chomp! 268: nvpair = l.split(':') 269: next unless nvpair && nvpair.size == 2 270: n = nvpair[0].strip.tr(' ', '_').downcase[/\w+/] 271: v = nvpair[1].strip[/[\.\d]+/] 272: raw[n.to_sym] = v.to_f 273: } 274: 275: stats = Stella::Test::RunSummary.new 276: 277: stats.vusers = raw[:concurrency] 278: stats.data_transferred = raw[:data_transferred] 279: 280: 281: stats.elapsed_time = raw[:elapsed_time] 282: stats.response_time = raw[:response_time] 283: 284: #stats.shortest_transaction = raw[:shortest_transaction] 285: #stats.longest_transaction = raw[:longest_transaction] 286: 287: stats.transactions = raw[:transactions].to_i 288: stats.transaction_rate = raw[:transaction_rate] 289: stats.failed = raw[:failed_transactions].to_i 290: stats.successful = raw[:successful_transactions].to_i 291: #stats.raw = raw if @global_options.debug 292: stats 293: end
Take the last line of the siege.log file and write it to the log file specified by the user. We don‘t this so running with Stella is identical to running it standalone
# File lib/stella/adapter/siege.rb, line 184 184: def update_orig_logfile 185: 186: return unless (@orig_logfile) 187: log_str = FileUtil.read_file_to_array(log_file) || '' 188: return if log_str.empty? 189: 190: if File.exists?(@orig_logfile) 191: FileUtil.append_file(@orig_logfile, log_str[-1], true) 192: else 193: FileUtil.write_file(@orig_logfile, log_str.join(''), true) 194: end 195: 196: end
# File lib/stella/adapter/siege.rb, line 259 259: def uris_file 260: File.join(@working_directory, File.basename(@file)) 261: end
# File lib/stella/adapter/siege.rb, line 50 50: def version 51: vsn = 0 52: text = "" 53: Open3.popen3("#{@name} --version") do |stdin, stdout, stderr| 54: text = stderr.readlines.join 55: text.scan(/SIEGE (\d+?\.\d+)/) { |v| vsn = v[0] } 56: end 57: vsn 58: end