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