module BigBench # A fragment represents a single http request inside a benchmark. It is executed by the benchmark and resides inside the benchmark block in the test # reciepts: # # benchmark "index page" => "http://localhost:3000" do # # Fragments # end # # Possible fragment types are the HTTP verbs, like GET, POST, PUT and DELETE. They look like this: # # get "/" # post "/login/new" # put "/books" # delete "/books/5", :params => { :token => '87bas67dfjgbrjbbgbi6ica7s0b3t0' } # get "/admin", :basic_auth => ['username', 'password'] # # After any fragment an options hash can be appended. Possible options are: # # [:basic_auth] Supply a basic auth user and password for the request. The request then looks like this: # # get "/", :basic_auth => ['username', 'password'] # # [:params] Supply params for the request body, like e.g. form data: # # post "/books/new", :params => { :book => { :title => "Metaprogramming Ruby", :publisher => "O'Reilly" } } # post "/trackings/add", :params => { :name => "Tommy" } # module Fragment @fragments = [] @benchmark = nil class Fragment attr_accessor :benchmark attr_accessor :path attr_accessor :method attr_accessor :options attr_accessor :uri def initialize benchmark, path, method, options = {} @benchmark, @path, @method, @options, @request_options = benchmark, path, method, options, {} @uri = URI(@benchmark.uri.to_s + @path) configure_options end # Initiates the request in the context of a Net::HTTP.start block def run! randomize_params EventMachine::HttpRequest.new(@uri.to_s).send(@method, @request_options) end # Adds the current tracking result as a hash to the benchmark's tracker def track!(start, stop, http) @benchmark.tracker.track( { :elapsed => (stop - benchmark.start).to_f, :start => start.to_f, :stop => stop.to_f, :duration => (stop - start).to_milliseconds, :benchmark => @benchmark.name, :url => @uri.to_s, :path => @uri.request_uri, :method => @method, :status => (s = http.response_header.status.to_i; s > 0 ? s : 404) } ) end private def randomize_params @request_options[:body] = @options[:params].sample if @options[:params].kind_of?(Array) end def configure_options # Basic Auth @request_options[:head] = { 'authorization' => BigBench.config.basic_auth } unless BigBench.config.basic_auth.nil? @request_options[:head] = { 'authorization' => @options[:basic_auth] } unless @options[:basic_auth].nil? # Body @request_options[:body] = @options[:params] unless @options[:params].nil? randomize_params end end # Performs a GET request to the given url, e.g. # # get "/some/page" # def self.get(path, options = {}) @fragments << Fragment.new(@benchmark, path, :get, options) end # Performs a POST request to the given url, e.g. # # post "/login" # def self.post(path, options = {}) @fragments << Fragment.new(@benchmark, path, :post, options) end # Performs a PUT request to the given url, e.g. # # put "/books" # def self.put(path, options = {}) @fragments << Fragment.new(@benchmark, path, :put, options) end # Performs a DELETE request to the given url, e.g. # # delete "/books/5" # def self.delete(path, options = {}) @fragments << Fragment.new(@benchmark, path, :delete, options) end # Evaluates a benchmark block full of puts and gets and returns an array of fully configured fragments for it def self.parse(benchmark, &block) reset! return [] if block.nil? @benchmark = benchmark module_exec(&block) @fragments end # Reset all fragments def self.reset! @benchmark = nil @fragments = [] end end end