benchtool 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rvmrc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ config/**/*
20
+ config
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Brad Landers
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.txt ADDED
@@ -0,0 +1,67 @@
1
+ INTRODUCTION
2
+
3
+ Benchtool provides a method to store a list of 'targets', which you can then
4
+ benchmark using the Apache Bench web server benchmarking tool.
5
+
6
+ This tool expects a configuration file at config/configuration.yml. If not
7
+ found, one will be created for you. This tool also outputs Apache Bench data
8
+ to a gnuplot file in a directory named 'output'. If it is not present, it will
9
+ be created. Both of these can be overriden using options.
10
+
11
+ PREREQUISITES
12
+
13
+ Because benchtool is a simple wrapper script, you must install Apache Bench
14
+ and Curl prior to running this utility. You can check to see if you have
15
+ these tools installed by executing the following at a shell prompt:
16
+
17
+ which ab
18
+ which curl
19
+
20
+ These commands should return paths to the binaries for each. If nothing is
21
+ returned, you must install the utility using your preferred package manager.
22
+
23
+ BASIC USAGE
24
+
25
+ benchtool [options] <command>
26
+
27
+ options - optional switches passed to the utility (see OPTIONS)
28
+
29
+ command - required command parameter tells the utility what action to take
30
+
31
+ See EXAMPLES for more details.
32
+
33
+ COMMANDS
34
+
35
+ benchmark Execute Apache Benchmark against a target. Builds and executes an
36
+ Apache Bench command, specifying cookies and headers from the
37
+ configuration file.
38
+ test Test a target to determine if it is valid and responding. Builds
39
+ and executes a Curl command, specifying cookies and headers from
40
+ the configuration file.
41
+
42
+ OPTIONS
43
+
44
+ -c, --concurrency [INT] Apache Bench concurrency level (overrides config).
45
+ -o, --output-dir [PATH] Output directory for Apache Bench gnuplot files.
46
+ -n, --number [INT] Apache Bench number of requests (overrides config).
47
+ --no-plotfile Apache Bench will not write a gnuplot file.
48
+ -p, --print Print the command and exit; does not execute.
49
+ -t, --target [INT] Specify the index (1-based) of the target.
50
+
51
+ EXAMPLES
52
+
53
+ benchtool benchmark - Displays a menu list of targets and executes
54
+ Apache Bench against the selected target.
55
+
56
+ benchtool test - Displays a menu list of targets and executes
57
+ a brief test showing the first 30 lines of
58
+ the HTTP response.
59
+
60
+ benchtool -c 100 benchmark - Override the configuration.yml concurrency
61
+ setting for Apache Bench.
62
+
63
+ benchtool -p benchmark - Prints the resulting bash shell command, rather
64
+ than executing. Also works for the test command.
65
+
66
+ Author: Brad Landers <brad@bradlanders.com>
67
+ Source: http://github.com/bradland/benchtool/
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/benchtool.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/benchtool/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Brad Landers"]
6
+ gem.email = ["brad@bradlanders.com"]
7
+ gem.description = %q{A simple wrapper tool for Apache Bench.}
8
+ gem.summary = %q{A simple wrapper tool for Apache Bench.}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "benchtool"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = BenchTool::VERSION
17
+
18
+ gem.add_dependency "highline"
19
+ gem.add_dependency "open4"
20
+
21
+ gem.add_development_dependency "awesome_print"
22
+ end
data/bin/benchtool ADDED
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require 'benchtool'
5
+ require 'optparse'
6
+
7
+ banner = %{
8
+ INTRODUCTION
9
+
10
+ Benchtool provides a method to store a list of 'targets', which you can then
11
+ benchmark using the Apache Bench web server benchmarking tool.
12
+
13
+ This tool expects a configuration file at config/configuration.yml. If not
14
+ found, one will be created for you. This tool also outputs Apache Bench data
15
+ to a gnuplot file in a directory named 'output'. If it is not present, it will
16
+ be created. Both of these can be overriden using options.
17
+
18
+ PREREQUISITES
19
+
20
+ Because benchtool is a simple wrapper script, you must install Apache Bench
21
+ and Curl prior to running this utility. You can check to see if you have
22
+ these tools installed by executing the following at a shell prompt:
23
+
24
+ which ab
25
+ which curl
26
+
27
+ These commands should return paths to the binaries for each. If nothing is
28
+ returned, you must install the utility using your preferred package manager.
29
+
30
+ BASIC USAGE
31
+
32
+ benchtool [options] <command>
33
+
34
+ options - optional switches passed to the utility (see OPTIONS)
35
+
36
+ command - required command parameter tells the utility what action to take
37
+
38
+ See EXAMPLES for more details.
39
+
40
+ COMMANDS
41
+
42
+ benchmark Execute Apache Benchmark against a target. Builds and executes an
43
+ Apache Bench command, specifying cookies and headers from the
44
+ configuration file.
45
+ test Test a target to determine if it is valid and responding. Builds
46
+ and executes a Curl command, specifying cookies and headers from
47
+ the configuration file.
48
+
49
+ OPTIONS
50
+
51
+ }
52
+ summary = []
53
+ footer = %{
54
+ EXAMPLES
55
+
56
+ benchtool benchmark - Displays a menu list of targets and executes
57
+ Apache Bench against the selected target.
58
+
59
+ benchtool test - Displays a menu list of targets and executes
60
+ a brief test showing the first 30 lines of
61
+ the HTTP response.
62
+
63
+ benchtool -c 100 benchmark - Override the configuration.yml concurrency
64
+ setting for Apache Bench.
65
+
66
+ benchtool -p benchmark - Prints the resulting bash shell command, rather
67
+ than executing. Also works for the test command.
68
+
69
+ Author: Brad Landers <brad@bradlanders.com>
70
+ Source: http://github.com/bradland/benchtool/
71
+ }
72
+
73
+ options = {}
74
+ OptionParser.new do |opts|
75
+ opts.banner = banner
76
+
77
+ opts.on('-c', '--concurrency [INT]', Integer, "Apache Bench concurrency level (overrides config).") do |concurrency|
78
+ options[:ab_concurrency] = concurrency
79
+ end
80
+
81
+ opts.on('-o', '--output-dir [PATH]', String, "Output directory for Apache Bench gnuplot files.") do |string|
82
+ options[:ab_output]
83
+ end
84
+
85
+ opts.on('-n', '--number [INT]', Integer, "Apache Bench number of requests (overrides config).") do |requests|
86
+ options[:ab_requests] = requests
87
+ end
88
+
89
+ opts.on('--no-plotfile', "Apache Bench will not write a gnuplot file.") do |boolean|
90
+ options[:no_plotfile] = boolean
91
+ end
92
+
93
+ opts.on('-p', '--print', "Print the command and exit; does not execute.") do |boolean|
94
+ options[:print_no_exec] = boolean
95
+ end
96
+
97
+ opts.on('-t', '--target [INT]', Integer, "Specify the index (1-based) of the target.") do |target_idx|
98
+ options[:target_idx] = target_idx
99
+ end
100
+
101
+ opts.summarize(summary)
102
+ end.parse!
103
+
104
+ command = ARGV[0]
105
+
106
+ case command
107
+ when nil
108
+ puts banner
109
+ puts summary
110
+ puts footer
111
+ exit 1
112
+ when "benchmark"
113
+ BenchTool::Dispatcher.new(options).benchmark
114
+ exit 0
115
+ when "test"
116
+ BenchTool::Dispatcher.new(options).test
117
+ exit 0
118
+ end
119
+
120
+ # SshForever::SecureShellForever.new(login, options).run
data/lib/benchtool.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'deep-symbolizable/deep-symbolize'
2
+ require 'fileutils'
3
+ require 'highline/import'
4
+ require 'open4'
5
+ require 'pathname'
6
+ require 'pty'
7
+ require 'rubygems'
8
+ require 'yaml'
9
+
10
+ require 'benchtool/app-config'
11
+ require 'benchtool/ab-cmd-builder'
12
+ require 'benchtool/curl-cmd-builder'
13
+ require 'benchtool/dispatcher'
14
+ require 'benchtool/extensions'
15
+ require 'benchtool/helpers'
16
+ require 'benchtool/version'
17
+ require 'benchtool'
@@ -0,0 +1,36 @@
1
+ module BenchTool
2
+ class ABCmdBuilder
3
+
4
+ def initialize(params, options = {})
5
+ @params = params
6
+ @options = options
7
+ # Sample ab cmd
8
+ # ab -n #{requests} -c #{concurrency} -g '#{plotfile}' -C '#{cookies}' -H '#{header}' '#{url}'
9
+ @parts = {
10
+ :base => "ab ",
11
+ :requests => "-n %s ",
12
+ :concurrency => "-c %s ",
13
+ :plotfile => "-g '%s' ",
14
+ :cookies => "-C '%s' ",
15
+ :header => "-H '%s' ",
16
+ :url => "'%s'",
17
+ }
18
+ end
19
+
20
+ def to_str
21
+ cmd = ""
22
+ cmd << @parts[:base]
23
+ cmd << @parts[:requests] % @params[:requests]
24
+ cmd << @parts[:concurrency] % @params[:concurrency]
25
+ cmd << @parts[:plotfile] % @params[:plotfile] unless @options[:no_plotfile] == false
26
+ cmd << @parts[:cookies] % @params[:cookies]
27
+ unless @params[:headers].empty?
28
+ @params[:headers].each do |header|
29
+ cmd << @parts[:header] % header
30
+ end
31
+ end
32
+ cmd << @parts[:url] % @params[:url]
33
+ end
34
+
35
+ end # class ABCmdBuilder
36
+ end # module BenchTool
@@ -0,0 +1,45 @@
1
+ module BenchTool
2
+ class AppConfig
3
+
4
+ CONFIG_DIR = File.expand_path('./config')
5
+ CONFIG_FILE = 'configuration.yml'
6
+ CONFIG_PATH = File.join(CONFIG_DIR, CONFIG_FILE)
7
+ APP_CONFIG_DIR = File.expand_path(File.dirname(__FILE__))
8
+
9
+ def initialize
10
+ @options ||= fetch
11
+ end
12
+
13
+ # Return config as hash
14
+ def to_hash
15
+ @options
16
+ end
17
+
18
+ private
19
+
20
+ # Get options from configuration file
21
+ def fetch
22
+ setup unless config_exists?
23
+ console "Loading config from #{CONFIG_PATH}"
24
+ @options = YAML::load(File.open(CONFIG_PATH))
25
+ @options.deep_symbolize
26
+ end
27
+
28
+ def config_exists?
29
+ File.exists?(CONFIG_PATH)
30
+ end
31
+
32
+ def setup
33
+ FileUtils.mkdir_p(CONFIG_DIR)
34
+ FileUtils.cp(File.join(APP_CONFIG_DIR, 'configuration.yml.base'), CONFIG_PATH)
35
+ console "Default configuration was established in the cwd!"
36
+ console ""
37
+ console "NOTICE: The application will exit now. Edit the contents of the config file before proceeeding!"
38
+ console ""
39
+ console "Config file path:"
40
+ console " #{CONFIG_PATH}"
41
+ exit 0
42
+ end
43
+
44
+ end # module AppConfig
45
+ end # module BenchTool
@@ -0,0 +1,28 @@
1
+ # This is the configuration file. It is intended to be edited by hand. Examples provided.
2
+ targets:
3
+ - name: "Label for the target"
4
+ url: "http://yourdomainhere.com"
5
+ cookies: "token=value"
6
+ headers: [
7
+ "Accept:application/json, text/javascript, */*; q=0.01",
8
+ "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3",
9
+ "Accept-Encoding:",
10
+ "Accept-Language:en-US,en;q=0.8",
11
+ "Cache-Control:max-age=0",
12
+ "Connection:keep-alive"
13
+ ]
14
+ - name: "Label for the target"
15
+ url: "http://yourdomainhere.com"
16
+ cookies: "token=value"
17
+ headers: [
18
+ "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
19
+ "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3",
20
+ "Accept-Encoding:",
21
+ "Accept-Language:en-US,en;q=0.8",
22
+ "Cache-Control:max-age=0",
23
+ "Connection:keep-alive"
24
+ ]
25
+ configuration:
26
+ ab_requests: 10
27
+ ab_concurrency: 1
28
+ ab_output: ./benchtool_output
@@ -0,0 +1,30 @@
1
+ module BenchTool
2
+ class CurlCmdBuilder
3
+
4
+ def initialize(params, options = {})
5
+ @params = params
6
+ @options = options
7
+ # Sample curl status cmd
8
+ # curl -IL --cookies '#{cookies}' --header '#{header}' "#{url}"
9
+ @parts = {
10
+ :base => "curl -siL ",
11
+ :cookies => "--cookie '%s' ",
12
+ :header => "--header '%s' ",
13
+ :url => "'%s'",
14
+ }
15
+ end
16
+
17
+ def to_str
18
+ cmd = ""
19
+ cmd << @parts[:base]
20
+ cmd << @parts[:cookies] % @params[:cookies]
21
+ unless @params[:headers].empty?
22
+ @params[:headers].each do |header|
23
+ cmd << @parts[:header] % header
24
+ end
25
+ end
26
+ cmd << @parts[:url] % @params[:url]
27
+ end
28
+
29
+ end # class ABCmdBuilder
30
+ end # module BenchTool
@@ -0,0 +1,118 @@
1
+ module BenchTool
2
+ class Dispatcher
3
+
4
+ def initialize(options = {})
5
+ @appconfig = AppConfig.new.to_hash
6
+ @config = @appconfig[:configuration]
7
+ @targets = @appconfig[:targets]
8
+ @options = options
9
+ # Overwrite app config with options (usually passed as CLI options)
10
+ unless options.nil?
11
+ @config.merge!(options)
12
+ end
13
+ end
14
+
15
+ # Each command gets a method here
16
+
17
+ def benchmark
18
+ setup_output
19
+ benchmark_target(select_target)
20
+ end
21
+
22
+ def test
23
+ test_target(select_target)
24
+ end
25
+
26
+ private
27
+
28
+ # The methods below do the actual work. If this utility grows, these should be moved out to their own classes
29
+ def benchmark_target(target)
30
+ # Set up the params we'll send to the Apache Bench cmd builder
31
+ ab_params = {
32
+ :requests => @config[:ab_requests],
33
+ :concurrency => @config[:ab_concurrency],
34
+ :plotfile => File.expand_path(File.join(@config[:ab_output], "apache-#{Time.now.strftime('%Y%m%d-%H%M%S')}.tsv")),
35
+ :cookies => target[:cookies],
36
+ :headers => target[:headers],
37
+ :url => target[:url]
38
+ }
39
+
40
+ # Output to inform the user what is about to happen
41
+ console ""
42
+ console "Benchmarking:"
43
+ console " URL: #{ab_params[:url]}"
44
+ console " Concurrency: #{ab_params[:concurrency]}"
45
+ console " Requests: #{ab_params[:requests]}"
46
+ console ""
47
+
48
+ # Build the command and execute or print
49
+ cmd = ABCmdBuilder.new(ab_params, @options).to_str
50
+ if @options[:print_no_exec]
51
+ console "Print cmd requested; no exec:"
52
+ console ""
53
+ console
54
+ else
55
+ console "Apache Bench output follows [#{Time.now.strftime('%F %T')}]================================"
56
+ run_shell_cmd cmd
57
+ end
58
+ end
59
+
60
+ def test_target(target)
61
+ # Set up the params we'll send to the curl cmd builder
62
+ curl_params = {
63
+ :cookies => target[:cookies],
64
+ :headers => target[:headers],
65
+ :url => target[:url]
66
+ }
67
+
68
+ # Output to inform the user what is about to happen
69
+ console ""
70
+ console "Testing:"
71
+ console " URL: #{curl_params[:url]}"
72
+ console ""
73
+
74
+ # Build the command and execute or print
75
+ cmd = CurlCmdBuilder.new(curl_params, @options).to_str
76
+ if @options[:print_no_exec]
77
+ console "Print cmd requested; no exec:"
78
+ console ""
79
+ console cmd
80
+ else
81
+ console "Curl output follows [#{Time.now.strftime('%F %T')}]================================"
82
+ result = `#{cmd}`
83
+ puts result.split("\n").first(30)
84
+ end
85
+ end
86
+
87
+ def select_target
88
+ # Return a target immediately if specified as an option
89
+ if @options.key?(:target_idx)
90
+ return @targets[@options[:target_idx]]
91
+ end
92
+ # Otherwise present a menu and return the choice
93
+ begin
94
+ selection = choose do |menu|
95
+ menu.prompt = "Select a target:"
96
+ @targets.each_with_index do |target, i|
97
+ menu.choice target[:name] { i }
98
+ end
99
+ end
100
+ rescue Interrupt
101
+ console ""
102
+ console "SIGINT received, Goodbye!"
103
+ exit 1
104
+ end
105
+ @targets[selection]
106
+ end
107
+
108
+ def setup_output
109
+ output_dir = File.expand_path(@config[:ab_output])
110
+ unless Dir.exists?(output_dir)
111
+ console "Creating output directory because it didn't exist."
112
+ FileUtils.mkdir_p(output_dir)
113
+ end
114
+ console "Using output dir: #{output_dir}"
115
+ end
116
+
117
+ end # class Dispatcher
118
+ end # module BenchTool
@@ -0,0 +1,4 @@
1
+ # This file loads extensions to Core and Stdlib classes and modules
2
+
3
+ # Mix-in to provide deep_symbolize method to Hash
4
+ class Hash; include DeepSymbolizable; end
@@ -0,0 +1,32 @@
1
+ # Writes msg to STDERR (helps with bash shell redirection)
2
+ def console(msg)
3
+ STDERR.puts msg
4
+ end
5
+
6
+ # Open4 version (doesn't write output in real time)
7
+ # def run_shell_cmd(cmd)
8
+ # status = Open4::popen4('sh') do |pid, stdin, stdout, stderr|
9
+ # # puts "debug: #{cmd}" if @options[:debug]
10
+ # stdin.puts cmd
11
+ # stdin.close
12
+ # puts stdout.read
13
+ # end
14
+ # status
15
+ # end
16
+
17
+ # PTY version (writes to output in real time)
18
+ def run_shell_cmd(cmd)
19
+ begin
20
+ PTY.spawn(cmd) do |r, w, pid|
21
+ begin
22
+ r.each { |line| print line;}
23
+ rescue Errno::EIO
24
+ rescue Interrupt
25
+ console ""
26
+ console "Goodbye!"
27
+ end
28
+ end
29
+ rescue PTY::ChildExited => e
30
+ puts "The child process exited!"
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module BenchTool
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,62 @@
1
+ # Symbolizes all of hash's keys and subkeys.
2
+ # Also allows for custom pre-processing of keys (e.g. downcasing, etc)
3
+ # if the block is given:
4
+ #
5
+ # somehash.deep_symbolize { |key| key.downcase }
6
+ #
7
+ # Usage: either include it into global Hash class to make it available to
8
+ # to all hashes, or extend only your own hash objects with this
9
+ # module.
10
+ # E.g.:
11
+ # 1) class Hash; include DeepSymbolizable; end
12
+ # 2) myhash.extend DeepSymbolizable
13
+ #
14
+ # From: https://gist.github.com/998709/aafd65c5780a2ce3cda3ef020b6e5dead7cef1d0
15
+
16
+ module DeepSymbolizable
17
+ def deep_symbolize(&block)
18
+ method = self.class.to_s.downcase.to_sym
19
+ syms = DeepSymbolizable::Symbolizers
20
+ syms.respond_to?(method) ? syms.send(method, self, &block) : self
21
+ end
22
+
23
+ module Symbolizers
24
+ extend self
25
+
26
+ # the primary method - symbolizes keys of the given hash,
27
+ # preprocessing them with a block if one was given, and recursively
28
+ # going into all nested enumerables
29
+ def hash(hash, &block)
30
+ hash.inject({}) do |result, (key, value)|
31
+ # Recursively deep-symbolize subhashes
32
+ value = _recurse_(value, &block)
33
+
34
+ # Pre-process the key with a block if it was given
35
+ key = yield key if block_given?
36
+ # Symbolize the key string if it responds to to_sym
37
+ sym_key = key.to_sym rescue key
38
+
39
+ # write it back into the result and return the updated hash
40
+ result[sym_key] = value
41
+ result
42
+ end
43
+ end
44
+
45
+ # walking over arrays and symbolizing all nested elements
46
+ def array(ary, &block)
47
+ ary.map { |v| _recurse_(v, &block) }
48
+ end
49
+
50
+ # handling recursion - any Enumerable elements (except String)
51
+ # is being extended with the module, and then symbolized
52
+ def _recurse_(value, &block)
53
+ if value.is_a?(Enumerable) && !value.is_a?(String)
54
+ # support for a use case without extended core Hash
55
+ value.extend DeepSymbolizable unless value.class.include?(DeepSymbolizable)
56
+ value = value.deep_symbolize(&block)
57
+ end
58
+ value
59
+ end
60
+ end
61
+
62
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: benchtool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brad Landers
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: highline
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: open4
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: awesome_print
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A simple wrapper tool for Apache Bench.
63
+ email:
64
+ - brad@bradlanders.com
65
+ executables:
66
+ - benchtool
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE
73
+ - README.txt
74
+ - Rakefile
75
+ - benchtool.gemspec
76
+ - bin/benchtool
77
+ - lib/benchtool.rb
78
+ - lib/benchtool/ab-cmd-builder.rb
79
+ - lib/benchtool/app-config.rb
80
+ - lib/benchtool/configuration.yml.base
81
+ - lib/benchtool/curl-cmd-builder.rb
82
+ - lib/benchtool/dispatcher.rb
83
+ - lib/benchtool/extensions.rb
84
+ - lib/benchtool/helpers.rb
85
+ - lib/benchtool/version.rb
86
+ - lib/deep-symbolizable/deep-symbolize.rb
87
+ homepage: ''
88
+ licenses: []
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.24
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: A simple wrapper tool for Apache Bench.
111
+ test_files: []