module BigBench
# The configuration is configured in the test reciepts and looks like this:
#
# BigBench.configure = {
# :duration => 10.seconds,
# :output => "test.ljson",
# :users => 20,
# :basic_auth => ['username', 'secret']
# }
#
# Single values can be set and retrieved like this:
#
# BigBench.config.duration = 20.minutes
# BigBench.config.duration # => 1200 (seconds)
#
# The following configuration values are possible - stared configurations need to be present:
#
# [duration*] How long will the benchmark take by default. This value can be overridden by every benchmark.
# [output*] The file where the results should be written to. Usually one takes the *.ljson format which is simply a file
# that contains a fully valid JSON object on every line. This makes it easy to process the results later on, because there's
# no need to parse the whole results JSON, which can get huge, at once.
# [users] How many users execute the benchmarks concurrently. This can be overridden by every benchmark and defaults to 1.
# [basic_auth] A basic authentication that is used by ALL requests. This can be overridden per fragment in every benchmark.
#
# BigBench.config.basic_auth = ['username', 'password']
#
module Configuration
# The main config object for BigBench. It allows config options to
# be added and forces some default values before it is valid?
class Config
attr_accessor :duration
attr_accessor :output
attr_accessor :users
attr_accessor :mode
attr_accessor :bot_checks_every
attr_accessor :basic_auth
VALIDATE_OPTIONS = [:duration, :output, :users]
def initialize
@users, @duration, @mode, @bot_checks_every = 1, 1.second, :local, 1.minute
end
def self.add_option(name)
attr_accessor name unless self.respond_to?(name)
end
def valid?
VALIDATE_OPTIONS.each{ |option| return false if send(option).nil? }
true
end
end
# Is returned if the configuration is not filled sufficiently
class InvalidOptions < StandardError
def message
"At least: #{Config::VALIDATE_OPTIONS.join(', ')} are required"
end
end
@config = Config.new
# Configures the benchmarks with a hash. If the config methods are not present yet,
# they are added to the config object
def self.configure=(config)
raise "Config must be a Hash" unless config.is_a?(Hash)
config.each { |option, value|
@config.class.add_option(option)
@config.send "#{option}=", value
}
end
# Returns the current config object
def self.config
@config
end
# Resets the config object
def self.reset!
@config = Config.new
end
end
# Configure the benchmark by supplying a hash of options like this:
#
# BigBench.configure = {
# :duration => 10.seconds,
# :output => "test.ljson",
# :users => 20,
# :basic_auth => ['username', 'secret']
# }
#
# Those values can then be set and retreived with BigBench.config.duration, ...
def self.configure=(config)
Configuration.configure=(config)
end
# Set and retreive the config values like this:
#
# BigBench.config.duration # => 10.seconds
# BigBench.config.duration = 20.minutes
#
def self.config
Configuration.config
end
# Checks if all necessary config options are set and raises an InvalidOptions exception if not
def self.check_config!
raise Configuration::InvalidOptions.new unless config.valid?
true
end
end