benchtool 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []