lib/stella/client.rb in solutious-stella-0.7.0.004 vs lib/stella/client.rb in solutious-stella-0.7.0.005

- old
+ new

@@ -1,8 +1,7 @@ require "observer" require "tempfile" -require 'httpclient' require 'nokogiri' module Stella class Client include Observable @@ -12,47 +11,56 @@ attr_reader :stats def initialize(base_uri=nil, client_id=1) @base_uri, @client_id = base_uri, client_id @cookie_file = Tempfile.new('stella-cookie') @stats = Stella::Stats.new("Client #{@client_id}") + @proxy = OpenStruct.new end - def execute(usecase) - http_client = generate_http_client + http_client = create_http_client container = Container.new(usecase) counter = 0 usecase.requests.each do |req| counter += 1 + update(:prepare_request, usecase, req, counter) + uri_obj = URI.parse(req.uri) params = prepare_params(usecase, req.params) + headers = prepare_headers(usecase, req.headers) uri = build_request_uri uri_obj, params, container raise NoHostDefined, uri_obj if uri.host.nil? || uri.host.empty? + unique_id = [req, params, headers, counter].gibbler + req_id = req.gibbler + meth = req.http_method.to_s.downcase - Stella.ld "#{meth}: " << "#{uri_obj.to_s} " << req.params.inspect + Stella.ld "#{req.http_method}: " << "#{uri_obj.to_s} " << params.inspect begin - update(:send_request, usecase, meth, uri, req, params, counter) - container.response = http_client.send(meth, uri, params) # booya! - update(:receive_response, usecase, meth, uri, req, params, container) + update(:send_request, usecase, uri, req, params, container) + container.response = http_client.send(meth, uri, params, headers) # booya! + update(:receive_response, usecase, uri, req, params, container) rescue => ex - update(:request_error, usecase, meth, uri, req, params, ex) + update(:request_error, usecase, uri, req, params, ex) next end ret = execute_response_handler container, req - Drydock::Screen.flush + Stella.lflush - if ret.kind_of?(ResponseModifier) - case ret.class.to_s - when "Stella::Client::Repeat" - Stella.ld "REPETITION: #{counter} of #{ret.times+1}" - redo if counter <= ret.times - end + # TODO: consider throw/catch + case ret.class.to_s + when "Stella::Client::Repeat" + Stella.ld "REPETITION: #{counter} of #{ret.times+1}" + redo if counter <= ret.times + when "Stella::Client::Quit" + Stella.ld "QUIT USECASE: #{ret.message}" + break end + counter = 0 # reset run_sleeper(req.wait) if req.wait && !benchmark? end end @@ -61,12 +69,11 @@ def disable_benchmark_mode; @bm = false; end def benchmark?; @bm == true; end private def update(kind, *args) - changed - notify_observers(kind, @client_id, *args) + changed and notify_observers(kind, @client_id, *args) end def run_sleeper(wait) if wait.is_a?(Range) ms = rand(wait.last * 1000).to_f @@ -75,30 +82,40 @@ ms = wait * 1000 end sleep ms / 1000 end - def generate_http_client - if @proxy - http_client = HTTPClient.new(@proxy.uri) - http_client.set_proxy_auth(@proxy.user, @proxy.pass) if @proxy.user - else - http_client = HTTPClient.new - end + def create_http_client + opts = { + :proxy => @proxy.uri || nil, # a tautology for clarity + :agent_name => "Stella/#{Stella::VERSION}", + :from => nil + } + http_client = HTTPClient.new opts + http_client.set_proxy_auth(@proxy.user, @proxy.pass) if @proxy.user + http_client.debug_dev = STDOUT if Stella.debug? && Stella.loglev > 3 http_client.set_cookie_store @cookie_file.to_s + #http_client.redirect_uri_callback = ?? http_client end def prepare_params(usecase, params) newparams = {} params.each_pair do |n,v| + Stella.ld "PREPARE PARAM: #{n}" v = usecase.instance_eval &v if v.is_a?(Proc) newparams[n] = v end newparams end + def prepare_headers(usecase, headers) + Stella.ld "PREPARE HEADERS: #{headers}" + headers = usecase.instance_eval &headers if headers.is_a?(Proc) + headers + end + # Testplan URIs can be relative or absolute. Either one can # contain variables in the form <tt>:varname</tt>, as in: # # http://example.com/product/:productid # @@ -144,12 +161,12 @@ # HTTP response status against the configured handlers. # If several match, the first one is used. def execute_response_handler(container, req) handler = nil req.response.each_pair do |regex,h| + Stella.ld "HANDLER REGEX: #{regex.to_s} (#{container.status})" regex = /#{regex}/ unless regex.is_a? Regexp - Stella.ld "HANDLER REGEX: #{regex} (#{container.status})" handler = h and break if container.status.to_s =~ regex end ret = nil unless handler.nil? begin @@ -202,18 +219,24 @@ alias_method :header, :headers def status; @response.status; end def set(n, v); usecase.resource n, v; end def resource(n); usecase.resource n; end def wait(t); sleep t; end - + def quit(msg=nil); Quit.new(msg); end def repeat(t=1); Repeat.new(t); end end class ResponseModifier; end class Repeat < ResponseModifier; attr_accessor :times def initialize(times) @times = times + end + end + class Quit < ResponseModifier; + attr_accessor :message + def initialize(msg=nil) + @message = msg end end end end \ No newline at end of file