drnbench 1.0.0 → 1.0.1
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 +4 -4
- data/bin/drnbench-request-response +4 -0
- data/doc/text/news.md +8 -0
- data/lib/drnbench/chart/gnuplot.rb +64 -0
- data/lib/drnbench/client/http.rb +5 -0
- data/lib/drnbench/reporters/throughput-reporter.rb +55 -0
- data/lib/drnbench/request-response/configuration.rb +2 -1
- data/lib/drnbench/request-response/gradual-runner.rb +2 -1
- data/lib/drnbench/request-response/result.rb +26 -6
- data/lib/drnbench/request-response/runner.rb +17 -7
- data/lib/drnbench/version.rb +1 -1
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 029ac85e0d002dfaf7636ea8031f29fd811deb42
|
4
|
+
data.tar.gz: dfa72f28ebe5c95ad0dfa38f3bedd124fcf4c108
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/drnbench/client/http.rb
CHANGED
@@ -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, :
|
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.
|
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
|
-
|
139
|
+
final_status_percentages = {}
|
120
140
|
status_percentages.each do |status|
|
121
|
-
|
141
|
+
final_status_percentages[status[:status]] = status[:percentage]
|
122
142
|
end
|
123
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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
|
data/lib/drnbench/version.rb
CHANGED
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.
|
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-
|
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/
|
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/
|
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
|
-
-
|
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
|