drnbench 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2305ee745be0d42e86eefa96f33550ba45e36980
4
- data.tar.gz: 6f2eeb52b863b766d26393c36b6356a30537e9e9
3
+ metadata.gz: 029ac85e0d002dfaf7636ea8031f29fd811deb42
4
+ data.tar.gz: dfa72f28ebe5c95ad0dfa38f3bedd124fcf4c108
5
5
  SHA512:
6
- metadata.gz: 8690b02b2be5bff090909faddbcd2f5ca699ee17e230ae165b164c306dbf7a0b006bf77f3ee1c5066b3e56bedd573a4d30154e12177b835ef5e2d760910236a6
7
- data.tar.gz: cfcc74f024b912dc92cafe3cc4d913367830ab1e1be72f1aa8833b4d86d46f226e4b2d05410f60ed1fabb87303376117bdf46d09c3462335162f721800a5d521
6
+ metadata.gz: 0c2b179e22d3acb8d4e2c3592789bb5017da991eb17e053431ce5e4a12fd7cca4f7fe4a5ac8a77a5bd5bfbaabd1752147cb8edbf0ee8a34195ae6f49c729c318
7
+ data.tar.gz: 97008b59cc5eb84afc94fce74f62fd89ae9e31b6bbfa1afe463c6404f062304dd8f6339c3271d9722f673491e6206b8428b60e54c3bd0dc05271300ad93d59da
@@ -41,6 +41,10 @@ option_parser = OptionParser.new do |parser|
41
41
  "step to increase number of clients (optional)") do |step|
42
42
  config.step = step
43
43
  end
44
+ parser.on("--n-slow-requests=N", Integer,
45
+ "number of reporting slow requests (optional)") do |n_slow_requests|
46
+ config.n_slow_requests = n_slow_requests
47
+ end
44
48
 
45
49
  parser.on("--mode=MODE", String,
46
50
  "mode of benchmark (optional)",
data/doc/text/news.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # News
2
2
 
3
+ ## 1.0.1: 2014-07-29
4
+
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.
10
+
3
11
  ## 1.0.0: 2014-01-29
4
12
 
5
13
  The first release!!!
@@ -0,0 +1,64 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "tempfile"
17
+
18
+ module Drnbench
19
+ module Chart
20
+ class Gnuplot
21
+ def initialize
22
+ @input = Tempfile.new("drnbench-graph")
23
+ write(preamble)
24
+ end
25
+
26
+ def write(data)
27
+ @input.write(data)
28
+ end
29
+
30
+ def run
31
+ @input.close
32
+ unless system("gnuplot", @input.path)
33
+ @input.open
34
+ puts(@input.read)
35
+ @input.close
36
+ end
37
+ end
38
+
39
+ private
40
+ def preamble
41
+ <<-PREAMBLE
42
+ set terminal pdfcairo enhanced color transparent rounded
43
+
44
+ set key outside center top horizontal reverse Left samplen 2
45
+ unset border
46
+ set xtics scale 0
47
+ set ytics scale 0
48
+ set grid ytics linewidth 1 linetype -1
49
+
50
+ set style line 1 lt 1 lc rgbcolor "#3465a4" lw 2.5 pt 7 ps 1
51
+ set style line 2 lt 1 lc rgbcolor "#edd400" lw 2.5 pt 7 ps 1
52
+ set style line 3 lt 1 lc rgbcolor "#888a85" lw 2.5 pt 5 ps 1
53
+ set style line 4 lt 1 lc rgbcolor "#f57900" lw 2.5 pt 5 ps 1
54
+ set style line 5 lt 1 lc rgbcolor "#ad7fa8" lw 2.5 pt 9 ps 1
55
+ set style line 6 lt 1 lc rgbcolor "#4e9a06" lw 2.5 pt 9 ps 1
56
+ set style line 7 lt 1 lc rgbcolor "#ef2929" lw 2.5 pt 1 ps 1
57
+ set style line 8 lt 1 lc rgbcolor "#5c3566" lw 2.5 pt 1 ps 1
58
+ set style line 9 lt 1 lc rgbcolor "#c17d11" lw 2.5 pt 3 ps 1
59
+ set style line 10 lt 1 lc rgbcolor "#dce775" lw 2.5 pt 3 ps 1
60
+ PREAMBLE
61
+ end
62
+ end
63
+ end
64
+ end
@@ -21,6 +21,8 @@ module Drnbench
21
21
  class HttpClient
22
22
  attr_reader :requests, :results, :wait
23
23
 
24
+ SUPPORTED_HTTP_METHODS = ["GET", "POST"]
25
+
24
26
  def initialize(params, config)
25
27
  @requests = params[:requests]
26
28
  @result = params[:result]
@@ -62,6 +64,9 @@ module Drnbench
62
64
  request["path"] ||= @config.default_path
63
65
  request["method"] ||= @config.default_method
64
66
  request["method"] = request["method"].upcase
67
+ unless SUPPORTED_HTTP_METHODS.include?(request["method"])
68
+ request["method"] = "GET"
69
+ end
65
70
  request
66
71
  end
67
72
  end
@@ -0,0 +1,55 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "tempfile"
17
+ require "fileutils"
18
+
19
+ require "drnbench/chart/gnuplot"
20
+
21
+ module Drnbench
22
+ module Reporters
23
+ class ThroughputReporter
24
+ def initialize(label)
25
+ @label = label
26
+ @data_file = Tempfile.new("drnbench-throughput-data")
27
+ end
28
+
29
+ def add_data(time, qps)
30
+ @data_file.puts([time, qps].join("\t"))
31
+ end
32
+
33
+ def report(output_directory)
34
+ FileUtils.mkdir_p(output_directory)
35
+ generate_chart(output_directory)
36
+ end
37
+
38
+ private
39
+ def generate_chart(output_directory)
40
+ @data_file.flush
41
+ gnuplot = Chart::Gnuplot.new
42
+ gnuplot.write(<<-INPUT)
43
+ set output "#{output_directory}/throughput.pdf"
44
+ set title "Throughput"
45
+
46
+ set xlabel "Time (second)"
47
+ set ylabel "Queries per Second (qps)"
48
+ plot "#{@data_file.path}" using 1:2 with linespoints linestyle 1 \\
49
+ title "#{@label}"
50
+ INPUT
51
+ gnuplot.run
52
+ end
53
+ end
54
+ end
55
+ end
@@ -19,7 +19,7 @@ module Drnbench
19
19
  module RequestResponse
20
20
  class Configuration
21
21
  attr_accessor :duration, :wait, :request_patterns_file
22
- attr_accessor :start_n_clients, :end_n_clients, :step, :n_requests
22
+ attr_accessor :start_n_clients, :end_n_clients, :step, :n_requests, :n_slow_requests
23
23
  attr_accessor :mode
24
24
  attr_accessor :default_host, :default_port, :default_path, :default_method
25
25
  attr_accessor :report_progressively, :output_path
@@ -34,6 +34,7 @@ module Drnbench
34
34
  @step = 1
35
35
  @n_requests = 1000
36
36
  @mode = :http
37
+ @n_slow_requests = 5
37
38
 
38
39
  @default_host = "localhost"
39
40
  @default_port = 80
@@ -41,6 +41,7 @@ module Drnbench
41
41
  benchmark.run
42
42
  if @config.report_progressively
43
43
  puts benchmark.result.to_s
44
+ puts ""
44
45
  end
45
46
  @result << benchmark.result
46
47
  end
@@ -78,7 +79,7 @@ module Drnbench
78
79
  end
79
80
 
80
81
  def csv_header
81
- Drnbench::Result.keys + statuses
82
+ Drnbench::RequestResponse::Result.keys + statuses
82
83
  end
83
84
 
84
85
  def csv_body
@@ -16,7 +16,8 @@
16
16
  module Drnbench
17
17
  module RequestResponse
18
18
  class Result
19
- attr_reader :n_clients, :duration, :statuses
19
+ attr_reader :n_clients, :statuses, :n_slow_requests
20
+ attr_accessor :duration
20
21
 
21
22
  class << self
22
23
  def keys
@@ -34,6 +35,7 @@ module Drnbench
34
35
  def initialize(params)
35
36
  @n_clients = params[:n_clients]
36
37
  @duration = params[:duration]
38
+ @n_slow_requests = params[:n_slow_requests] || 5
37
39
 
38
40
  @results = []
39
41
  @total_elapsed_time = 0.0
@@ -70,13 +72,27 @@ module Drnbench
70
72
  end
71
73
 
72
74
  def max_elapsed_time
73
- @max_elapsed_time ||= @elapsed_times.min
75
+ @max_elapsed_time ||= @elapsed_times.max
74
76
  end
75
77
 
76
78
  def average_elapsed_time
77
79
  @average_elapsed_time ||= @total_elapsed_time / @elapsed_times.size
78
80
  end
79
81
 
82
+ def top_slow_requests
83
+ slow_requests[0..@n_slow_requests-1].collect do |result|
84
+ request = result[:request]
85
+ "#{result[:elapsed_time]} sec: " +
86
+ "#{request["method"]} http://#{request["host"]}:#{request["port"]}#{request["path"]}"
87
+ end
88
+ end
89
+
90
+ def slow_requests
91
+ @results.sort do |a, b|
92
+ b[:elapsed_time] <=> a[:elapsed_time]
93
+ end
94
+ end
95
+
80
96
  def to_s
81
97
  "Total requests: #{total_n_requests} " +
82
98
  "(#{queries_per_second} queries per second)\n" +
@@ -87,7 +103,11 @@ module Drnbench
87
103
  "Elapsed time:\n" +
88
104
  " min: #{min_elapsed_time} sec\n" +
89
105
  " max: #{max_elapsed_time} sec\n" +
90
- " average: #{average_elapsed_time} sec"
106
+ " average: #{average_elapsed_time} sec\n" +
107
+ "Top #{@n_slow_requests} slow requests:\n" +
108
+ top_slow_requests.collect do |request|
109
+ " #{request}"
110
+ end.join("\n")
91
111
  end
92
112
 
93
113
  def values
@@ -116,11 +136,11 @@ module Drnbench
116
136
  status_percentages.sort! do |a, b|
117
137
  (-1) * (a[:percentage] <=> b[:percentage])
118
138
  end
119
- status_percentages = {}
139
+ final_status_percentages = {}
120
140
  status_percentages.each do |status|
121
- status_percentages[status[:status]] = status[:percentage]
141
+ final_status_percentages[status[:status]] = status[:percentage]
122
142
  end
123
- status_percentages
143
+ final_status_percentages
124
144
  end
125
145
  end
126
146
  end
@@ -23,6 +23,7 @@ module Drnbench
23
23
  attr_reader :n_clients, :result
24
24
 
25
25
  def initialize(n_clients, config)
26
+ n_clients = 1 if n_clients.zero?
26
27
  @n_clients = n_clients
27
28
  @config = config
28
29
  populate_requests
@@ -36,8 +37,13 @@ module Drnbench
36
37
  private
37
38
  def process_requests
38
39
  requests_queue = Queue.new
40
+ @requests.each do |request|
41
+ requests_queue.push(request)
42
+ end
43
+
39
44
  @result = Result.new(:n_clients => @n_clients,
40
- :duration => @config.duration)
45
+ :duration => @config.duration,
46
+ :n_slow_requests => @config.n_slow_requests)
41
47
 
42
48
  client_params = {
43
49
  :requests => requests_queue,
@@ -59,12 +65,12 @@ module Drnbench
59
65
 
60
66
  start_time = Time.now
61
67
  while Time.now - start_time < @config.duration
68
+ sleep 1
62
69
  if requests_queue.empty?
63
- @requests.each do |request|
64
- requests_queue.push(request)
65
- end
70
+ puts "WORNING: requests queue becomes empty! (#{Time.now - start_time} sec)"
71
+ @result.duration = Time.now - start_time
72
+ break
66
73
  end
67
- sleep 1
68
74
  end
69
75
 
70
76
  @clients.each do |client|
@@ -92,7 +98,7 @@ module Drnbench
92
98
 
93
99
  def populate_request_pattern(request_pattern)
94
100
  frequency = request_pattern["frequency"].to_f
95
- n_requests = @config.n_requests * frequency
101
+ n_requests = @config.n_requests * @config.end_n_clients * frequency
96
102
 
97
103
  base_patterns = nil
98
104
  if request_pattern["pattern"]
@@ -103,7 +109,11 @@ module Drnbench
103
109
  base_patterns = base_patterns.shuffle
104
110
 
105
111
  n_requests.round.times do |count|
106
- @requests << base_patterns[count % base_patterns.size]
112
+ pattern = base_patterns[count % base_patterns.size]
113
+ pattern["host"] ||= request_pattern["host"]
114
+ pattern["port"] ||= request_pattern["port"]
115
+ pattern["method"] ||= request_pattern["method"]
116
+ @requests << pattern
107
117
  end
108
118
  end
109
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.0"
17
+ VERSION = "1.0.1"
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.0
4
+ version: 1.0.1
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-01-29 00:00:00.000000000 Z
12
+ date: 2014-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -114,8 +114,8 @@ email:
114
114
  - yuki@clear-code.com
115
115
  - kou@clear-code.com
116
116
  executables:
117
- - drnbench-publish-subscribe
118
117
  - drnbench-request-response
118
+ - drnbench-publish-subscribe
119
119
  extensions: []
120
120
  extra_rdoc_files: []
121
121
  files:
@@ -125,23 +125,25 @@ files:
125
125
  - drnbench.gemspec
126
126
  - LICENSE.txt
127
127
  - doc/text/news.md
128
- - lib/drnbench.rb
129
- - lib/drnbench/request-response/result.rb
128
+ - lib/drnbench/client/http.rb
129
+ - lib/drnbench/client/http-droonga.rb
130
+ - lib/drnbench/request-response/gradual-runner.rb
130
131
  - lib/drnbench/request-response/configuration.rb
132
+ - lib/drnbench/request-response/result.rb
131
133
  - lib/drnbench/request-response/runner.rb
132
- - lib/drnbench/request-response/gradual-runner.rb
134
+ - lib/drnbench/reporters/throughput-reporter.rb
135
+ - lib/drnbench/version.rb
136
+ - lib/drnbench/chart/gnuplot.rb
133
137
  - lib/drnbench/publish-subscribe/watch.rb
138
+ - lib/drnbench/publish-subscribe/gradual-runner.rb
134
139
  - lib/drnbench/publish-subscribe/configuration.rb
135
140
  - lib/drnbench/publish-subscribe/runner.rb
136
- - lib/drnbench/publish-subscribe/gradual-runner.rb
137
- - lib/drnbench/version.rb
138
- - lib/drnbench/client/http-droonga.rb
139
- - lib/drnbench/client/http.rb
140
141
  - lib/drnbench/server/protocol-adapter.rb
141
- - lib/drnbench/server/configuration.rb
142
142
  - lib/drnbench/server/engine.rb
143
- - bin/drnbench-publish-subscribe
143
+ - lib/drnbench/server/configuration.rb
144
+ - lib/drnbench.rb
144
145
  - bin/drnbench-request-response
146
+ - bin/drnbench-publish-subscribe
145
147
  homepage: https://github.com/groonga/grntest
146
148
  licenses:
147
149
  - GPLv3 or later