drnbench 1.0.1 → 1.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 029ac85e0d002dfaf7636ea8031f29fd811deb42
4
- data.tar.gz: dfa72f28ebe5c95ad0dfa38f3bedd124fcf4c108
3
+ metadata.gz: bc7f61f1275e4e48a15492d197552728429a7272
4
+ data.tar.gz: fa6bd343d6a874c165dd95ae77bdc1ca7df730b1
5
5
  SHA512:
6
- metadata.gz: 0c2b179e22d3acb8d4e2c3592789bb5017da991eb17e053431ce5e4a12fd7cca4f7fe4a5ac8a77a5bd5bfbaabd1752147cb8edbf0ee8a34195ae6f49c729c318
7
- data.tar.gz: 97008b59cc5eb84afc94fce74f62fd89ae9e31b6bbfa1afe463c6404f062304dd8f6339c3271d9722f673491e6206b8428b60e54c3bd0dc05271300ad93d59da
6
+ metadata.gz: 226d64e8c67139749313e265c3c6be5ac369b2c03f38dfc269dc2f9a105d682aad9830639e86ebef914306027fbf9ae64001773d4058983a14a307a101b352be
7
+ data.tar.gz: a97fea6987677e63f4f6511148cec0c30b98646042d5603c9dc61c10cf81325c117cea3ac5f82b794916ef69a6cc7309276fc90657cc7ce60f5b09d71f8b88ae
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (C) 2014 Droonga Project
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "drnbench"
19
+ require "ostruct"
20
+ require "optparse"
21
+ require "json"
22
+
23
+ options = OpenStruct.new
24
+ options.column_index = 0
25
+
26
+ option_parser = OptionParser.new do |parser|
27
+ parser.version = Drnbench::VERSION
28
+
29
+ parser.on("--column-index=INDEX", Integer,
30
+ "Index number of the column to be extracted.",
31
+ "(#{options.output_column_index})") do |index|
32
+ options.column_index = index
33
+ end
34
+ end
35
+
36
+ groonga_select_result_files = option_parser.parse!(ARGV)
37
+
38
+ def output_column_value(select_result, column_index)
39
+ select_result = JSON.parse(select_result)
40
+ body = select_result[1]
41
+ search_result = body.first
42
+ records = search_result[2..-1]
43
+ records.each do |record|
44
+ puts record[column_index]
45
+ end
46
+ end
47
+
48
+ if groonga_select_result_files.empty?
49
+ output_column_value($stdin.read, options.column_index)
50
+ else
51
+ groonga_select_result_files.each do |select_result_file|
52
+ File.open(select_result_file) do |input|
53
+ output_column_value(input.read, options.column_index)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (C) 2014 Droonga Project
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "drnbench"
19
+ require "ostruct"
20
+ require "optparse"
21
+ require "json"
22
+
23
+ options = {
24
+ :base_params => "limit=10&offset=0",
25
+ :hosts => [],
26
+ }
27
+
28
+ option_parser = OptionParser.new do |parser|
29
+ parser.version = Drnbench::VERSION
30
+
31
+ parser.on("--base-params=PARAMS",
32
+ "Base parameters for each select request",
33
+ "(#{options[:base_params]})") do |params|
34
+ options[:base_params] = params
35
+ end
36
+
37
+ parser.on("--hosts=NAME1,NAME2,...", Array,
38
+ "Target hosts to be requested parallely") do |hosts|
39
+ options[:hosts] = hosts
40
+ end
41
+ end
42
+
43
+ searchterms_files = option_parser.parse!(ARGV)
44
+
45
+ def sanitize_for_param(value)
46
+ value.to_s
47
+ .gsub(/[:;]/, " ")
48
+ .strip
49
+ .gsub(/ +/, "%20")
50
+ end
51
+
52
+ def generate_patterns(params)
53
+ host = params[:host]
54
+ frequency = params[:frequency] || 1.0
55
+ searchterms = params[:searchterms] || []
56
+ base_params = params[:base_params] || ""
57
+
58
+ request_patterns = searchterms.collect do |searchterm|
59
+ query_params = "query=#{sanitize_for_param(searchterm)}"
60
+ unless base_params.empty?
61
+ query_params = "#{base_params}&#{query_params}"
62
+ end
63
+ {
64
+ "path" => "/d/select?#{query_params}",
65
+ }
66
+ end
67
+
68
+ pattern = {
69
+ "frequency" => frequency,
70
+ "method" => "get",
71
+ "patterns" => request_patterns,
72
+ }
73
+
74
+ if host
75
+ pattern["host"] = host
76
+ { "with-query-#{host}" => pattern }
77
+ else
78
+ { "with-query" => pattern }
79
+ end
80
+ end
81
+
82
+ def output_patterns(params)
83
+ patterns = {}
84
+
85
+ hosts = params[:hosts] || []
86
+ if hosts.empty?
87
+ patterns.merge!(generate_patterns(params))
88
+ else
89
+ hosts.each do |host|
90
+ host_params = params.merge(:host => host,
91
+ :frequency => 1.0 / hosts.size)
92
+ host_patterns = generate_patterns(host_params)
93
+ patterns.merge!(host_patterns)
94
+ end
95
+ end
96
+
97
+ puts JSON.pretty_generate(patterns)
98
+ end
99
+
100
+ if searchterms_files.empty?
101
+ searchterms = $stdin.read.split(/\r?\n/)
102
+ output_patterns(options.merge(:searchterms => searchterms))
103
+ else
104
+ searchterms_files.each do |searchterms_file|
105
+ File.open(searchterms_file) do |input|
106
+ searchterms = input.read.split(/\r?\n/)
107
+ output_patterns(options.merge(:searchterms => searchterms))
108
+ end
109
+ end
110
+ end
111
+
112
+
@@ -22,6 +22,8 @@ require "shellwords"
22
22
 
23
23
  config = Drnbench::PublishSubscribe::Configuration.new
24
24
  option_parser = OptionParser.new do |parser|
25
+ parser.version = Drnbench::VERSION
26
+
25
27
  parser.on("--start-n-subscribers=N", Integer,
26
28
  "initial number of subscribers") do |n_subscribers|
27
29
  config.start_n_subscribers = n_subscribers
@@ -21,6 +21,8 @@ require "optparse"
21
21
 
22
22
  config = Drnbench::RequestResponse::Configuration.new
23
23
  option_parser = OptionParser.new do |parser|
24
+ parser.version = Drnbench::VERSION
25
+
24
26
  parser.on("--duration=SECONDS", Float,
25
27
  "duration of the benmark") do |duration|
26
28
  config.duration = duration
@@ -29,6 +31,10 @@ option_parser = OptionParser.new do |parser|
29
31
  "wait for each request") do |wait|
30
32
  config.wait = wait
31
33
  end
34
+ parser.on("--interval=SECONDS", Float,
35
+ "interval for each gradual case") do |interval|
36
+ config.interval = interval
37
+ end
32
38
  parser.on("--start-n-clients=N", Integer,
33
39
  "initial number of clients (optional)") do |n_clients|
34
40
  config.start_n_clients = n_clients
@@ -74,6 +80,10 @@ option_parser = OptionParser.new do |parser|
74
80
  "default HTTP method (optional)") do |method|
75
81
  config.default_method = method
76
82
  end
83
+ parser.on("--default-timeout=SECONDS", Float,
84
+ "default timeout (optional)") do |timeout|
85
+ config.default_timeout = timeout
86
+ end
77
87
 
78
88
  parser.on("--output-path=PATH",
79
89
  "path to output statistics as a CSV file (optional)") do |path|
data/doc/text/news.md CHANGED
@@ -1,12 +1,23 @@
1
1
  # News
2
2
 
3
+ ## 1.0.2: 2014-07-30
4
+
5
+ * 'drnbench-request-response'
6
+ * Report aborted requests as slow requests.
7
+ * Report response status and index for slow requests.
8
+ * Add ability to specify default timeout via the `--default-timeout` option.
9
+ * Add ability to specify interval between each benchamrk via the `--interval` option.
10
+ * New utility command `drnbench-extract-searchterms` to extract values of a specific column from a result of Groonga's select command.
11
+ * New utility command `drnbench-generate-select-patterns` to generate patterns file for benchmark of Groonga's select command via HTTP.
12
+
3
13
  ## 1.0.1: 2014-07-29
4
14
 
5
- * Report throughput more correctly.
6
- * Report percentages of returned HTTP statuses correctly.
7
- * Report max elapsed time correctly.
8
- * Add ability to report slow requests.
9
- * Accept pattern group specific parameters.
15
+ * `drnbench-request-response`
16
+ * Report throughput more correctly.
17
+ * Report percentages of returned HTTP statuses correctly.
18
+ * Report max elapsed time correctly.
19
+ * Add ability to report slow requests via the `--n-slow-requests` option.
20
+ * Accept pattern group specific parameters.
10
21
 
11
22
  ## 1.0.0: 2014-01-29
12
23
 
@@ -23,10 +23,15 @@ module Drnbench
23
23
 
24
24
  SUPPORTED_HTTP_METHODS = ["GET", "POST"]
25
25
 
26
+ @@count = 0
27
+
26
28
  def initialize(params, config)
27
29
  @requests = params[:requests]
28
30
  @result = params[:result]
29
31
  @config = config
32
+ @count = 0
33
+ @id = @@count
34
+ @@count += 1
30
35
  end
31
36
 
32
37
  def run
@@ -37,16 +42,34 @@ module Drnbench
37
42
 
38
43
  client = Droonga::Client.new(:protocol => :http,
39
44
  :host => request["host"],
40
- :port => request["port"])
45
+ :port => request["port"],
46
+ :timeout => request["timeout"])
41
47
  request["headers"] ||= {}
42
48
  request["headers"]["user-agent"] = "Ruby/#{RUBY_VERSION} Droonga::Benchmark::Runner::HttpClient"
43
49
  start_time = Time.now
50
+ @last_request = request
51
+ @last_start_time = start_time
52
+ begin
44
53
  response = client.request(request)
45
- @result << {
46
- :request => request,
47
- :status => response.code,
48
- :elapsed_time => Time.now - start_time,
49
- }
54
+ @result << {
55
+ :request => request,
56
+ :status => response.code,
57
+ :elapsed_time => Time.now - start_time,
58
+ :client => @id,
59
+ :index => @count,
60
+ }
61
+ rescue Timeout::Error
62
+ @result << {
63
+ :request => request,
64
+ :status => "0",
65
+ :elapsed_time => Time.now - start_time,
66
+ :client => @id,
67
+ :index => @count,
68
+ }
69
+ end
70
+ @last_request = nil
71
+ @last_start_time = nil
72
+ @count += 1
50
73
  sleep @config.wait
51
74
  end
52
75
  end
@@ -55,6 +78,17 @@ module Drnbench
55
78
 
56
79
  def stop
57
80
  @thread.exit
81
+
82
+ if @last_request
83
+ @result << {
84
+ :request => @last_request,
85
+ :status => "0",
86
+ :elapsed_time => Time.now - @last_start_time,
87
+ :client => @id,
88
+ :index => @count,
89
+ :last => true,
90
+ }
91
+ end
58
92
  end
59
93
 
60
94
  private
@@ -67,6 +101,7 @@ module Drnbench
67
101
  unless SUPPORTED_HTTP_METHODS.include?(request["method"])
68
102
  request["method"] = "GET"
69
103
  end
104
+ request["timeout"] ||= @config.default_timeout
70
105
  request
71
106
  end
72
107
  end
@@ -18,10 +18,10 @@ require "json"
18
18
  module Drnbench
19
19
  module RequestResponse
20
20
  class Configuration
21
- attr_accessor :duration, :wait, :request_patterns_file
21
+ attr_accessor :duration, :wait, :interval, :request_patterns_file
22
22
  attr_accessor :start_n_clients, :end_n_clients, :step, :n_requests, :n_slow_requests
23
23
  attr_accessor :mode
24
- attr_accessor :default_host, :default_port, :default_path, :default_method
24
+ attr_accessor :default_host, :default_port, :default_path, :default_method, :default_timeout
25
25
  attr_accessor :report_progressively, :output_path
26
26
 
27
27
  MIN_DURATION = 1
@@ -29,6 +29,7 @@ module Drnbench
29
29
 
30
30
  def initialize
31
31
  @wait = 1
32
+ @interval = 5
32
33
  @start_n_clients = 1
33
34
  @end_n_clients = 1
34
35
  @step = 1
@@ -40,6 +41,7 @@ module Drnbench
40
41
  @default_port = 80
41
42
  @default_path = "/"
42
43
  @default_method = "GET"
44
+ @default_timeout = 5.0
43
45
 
44
46
  @report_progressively = true
45
47
  @output_path = "/tmp/drnbench-result.csv"
@@ -34,6 +34,8 @@ module Drnbench
34
34
  def run_benchmarks
35
35
  @result = Result.new
36
36
  @config.start_n_clients.step(@config.end_n_clients, @config.step) do |n_clients|
37
+ sleep @config.interval unless @result.empty?
38
+
37
39
  benchmark = Runner.new(n_clients, @config)
38
40
  if @config.report_progressively
39
41
  puts "Running benchmark with #{n_clients} clients..."
@@ -57,6 +59,10 @@ module Drnbench
57
59
  @results[result.n_clients] = result
58
60
  end
59
61
 
62
+ def empty?
63
+ @results.empty?
64
+ end
65
+
60
66
  def statuses
61
67
  @statuses ||= prepare_statuses
62
68
  end
@@ -55,6 +55,10 @@ module Drnbench
55
55
  @total_elapsed_time += result[:elapsed_time]
56
56
  end
57
57
 
58
+ def empty?
59
+ @results.empty?
60
+ end
61
+
58
62
  def total_n_requests
59
63
  @total_n_requests ||= @results.size
60
64
  end
@@ -82,8 +86,19 @@ module Drnbench
82
86
  def top_slow_requests
83
87
  slow_requests[0..@n_slow_requests-1].collect do |result|
84
88
  request = result[:request]
85
- "#{result[:elapsed_time]} sec: " +
86
- "#{request["method"]} http://#{request["host"]}:#{request["port"]}#{request["path"]}"
89
+ status = result[:status].to_i
90
+ if status.zero?
91
+ status = "#{status}(aborted)"
92
+ end
93
+ index = result[:index]
94
+ index = "#{index}(last)" if result[:last]
95
+ [
96
+ "#{result[:elapsed_time]} sec:",
97
+ request["method"],
98
+ status,
99
+ "<#{result[:client]}>#{index}",
100
+ "http://#{request["host"]}:#{request["port"]}#{request["path"]}",
101
+ ].join(" ")
87
102
  end
88
103
  end
89
104
 
@@ -105,6 +120,7 @@ module Drnbench
105
120
  " max: #{max_elapsed_time} sec\n" +
106
121
  " average: #{average_elapsed_time} sec\n" +
107
122
  "Top #{@n_slow_requests} slow requests:\n" +
123
+ " [time: method status <client>index url]\n" +
108
124
  top_slow_requests.collect do |request|
109
125
  " #{request}"
110
126
  end.join("\n")
@@ -113,6 +113,7 @@ module Drnbench
113
113
  pattern["host"] ||= request_pattern["host"]
114
114
  pattern["port"] ||= request_pattern["port"]
115
115
  pattern["method"] ||= request_pattern["method"]
116
+ pattern["timeout"] ||= request_pattern["timeout"]
116
117
  @requests << pattern
117
118
  end
118
119
  end
@@ -14,5 +14,5 @@
14
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
16
  module Drnbench
17
- VERSION = "1.0.1"
17
+ VERSION = "1.0.2"
18
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drnbench
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - YUKI Hiroshi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-29 00:00:00.000000000 Z
12
+ date: 2014-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -114,6 +114,8 @@ email:
114
114
  - yuki@clear-code.com
115
115
  - kou@clear-code.com
116
116
  executables:
117
+ - drnbench-extract-searchterms
118
+ - drnbench-generate-select-patterns
117
119
  - drnbench-request-response
118
120
  - drnbench-publish-subscribe
119
121
  extensions: []
@@ -142,6 +144,8 @@ files:
142
144
  - lib/drnbench/server/engine.rb
143
145
  - lib/drnbench/server/configuration.rb
144
146
  - lib/drnbench.rb
147
+ - bin/drnbench-extract-searchterms
148
+ - bin/drnbench-generate-select-patterns
145
149
  - bin/drnbench-request-response
146
150
  - bin/drnbench-publish-subscribe
147
151
  homepage: https://github.com/groonga/grntest