groonga-query-log 1.4.4 → 1.4.5
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/groonga-query-log-check-performance-regression +22 -0
- data/doc/text/news.md +14 -0
- data/lib/groonga-query-log/command/check-performance-regression.rb +447 -0
- data/lib/groonga-query-log/command/run-regression-test.rb +1 -1
- data/lib/groonga-query-log/statistic.rb +6 -0
- data/lib/groonga-query-log/version.rb +1 -1
- data/test/command/test-check-performance-regression.rb +311 -0
- data/test/fixtures/check-performance-regression/cache.log +3 -0
- data/test/fixtures/check-performance-regression/nquery.log +10 -0
- data/test/fixtures/check-performance-regression/nquery2.log +10 -0
- data/test/fixtures/check-performance-regression/query1.log +4 -0
- data/test/fixtures/check-performance-regression/query2.log +4 -0
- metadata +45 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bc397a48e26c377cab3315458cc8da30cb80cd7efd00bdea36595d7f6cb8bd7
|
4
|
+
data.tar.gz: 142b467fd6d1b809e4ca2c8b06c826084488dc6cf48aabc387e2dbe22edf0688
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49862f644474605b03c770c8bd88ca4469a1d234f6b13fc707147ea6ff3c1d82b3f8aa883b35e9fefc09e6c4f58b12c66e9f899a1daf96f4342cc03ffa4969fd
|
7
|
+
data.tar.gz: cd8283475cab0a4cfdd4f3d2ae6d8d5b42ecc9b09b8877185a07a660fd44819910a372cb472620e0e65444ac762ec729387c5d53dee299eba1f3dbade445b2d5
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Copyright (C) 2019 Kentaro hayashi <hayashi@clear-code.com>
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library 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 GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
|
19
|
+
require "groonga-query-log/command/check-performance-regression"
|
20
|
+
|
21
|
+
checker = GroongaQueryLog::Command::CheckPerformanceRegression.new
|
22
|
+
exit(checker.run(ARGV))
|
data/doc/text/news.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 1.4.5: 2019-08-15
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* `groonga-query-log-check-performance-regression`:
|
8
|
+
|
9
|
+
* Added feature for checking deterioration of performance.
|
10
|
+
|
11
|
+
### Fixes
|
12
|
+
|
13
|
+
* `groonga-query-log-run-regression-test`:
|
14
|
+
|
15
|
+
* Fixed a bug that `--rewrite-and-not-operator` option doesn't work.
|
16
|
+
|
3
17
|
## 1.4.4: 2019-08-05
|
4
18
|
|
5
19
|
### Improvements
|
@@ -0,0 +1,447 @@
|
|
1
|
+
# Copyright (C) 2019 Kentaro Hayashi <hayashi@clear-code.com>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License as published by the Free Software Foundation; either
|
6
|
+
# version 2.1 of the License, or (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This library 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 GNU
|
11
|
+
# Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
14
|
+
# License along with this library; if not, write to the Free Software
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
16
|
+
|
17
|
+
require "optparse"
|
18
|
+
require "json"
|
19
|
+
|
20
|
+
require "groonga-query-log"
|
21
|
+
require "groonga-query-log/command-line"
|
22
|
+
|
23
|
+
require "groonga-query-log/command/analyzer"
|
24
|
+
require "groonga-query-log/command/analyzer/sized-statistics"
|
25
|
+
|
26
|
+
module GroongaQueryLog
|
27
|
+
module Command
|
28
|
+
class CheckPerformanceRegression < CommandLine
|
29
|
+
NSEC_IN_SECONDS = (1000 * 1000 * 1000)
|
30
|
+
USEC_IN_SECONDS = (1000 * 1000)
|
31
|
+
MSEC_IN_SECONDS = 1000
|
32
|
+
|
33
|
+
def initialize(options={})
|
34
|
+
setup_options(options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def run(arguments)
|
38
|
+
paths = []
|
39
|
+
begin
|
40
|
+
paths = @option_parser.parse!(arguments)
|
41
|
+
rescue OptionParser::InvalidOption => error
|
42
|
+
$stderr.puts(error)
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
|
46
|
+
if paths.size != 2
|
47
|
+
$stderr.puts("old query log and new query log must be specified.")
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
|
51
|
+
old_query_paths = resolve_path(paths[0])
|
52
|
+
return false if old_query_paths.nil?
|
53
|
+
new_query_paths = resolve_path(paths[1])
|
54
|
+
return false if new_query_paths.nil?
|
55
|
+
|
56
|
+
old_statistics = analyze(old_query_paths)
|
57
|
+
return false if old_statistics.nil?
|
58
|
+
new_statistics = analyze(new_query_paths)
|
59
|
+
return false if new_statistics.nil?
|
60
|
+
|
61
|
+
open_output do |output|
|
62
|
+
checker = Checker.new(old_statistics,
|
63
|
+
new_statistics,
|
64
|
+
output,
|
65
|
+
@threshold,
|
66
|
+
@target_queries)
|
67
|
+
checker.check
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def resolve_path(path)
|
73
|
+
if File.directory?(path)
|
74
|
+
Dir.glob("#{path}/*.log")
|
75
|
+
elsif File.exist?(path)
|
76
|
+
[path]
|
77
|
+
else
|
78
|
+
$stderr.puts("query log path doesn't exist: <#{path}>")
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def open_output(&block)
|
84
|
+
case @output
|
85
|
+
when "-"
|
86
|
+
yield($stdout)
|
87
|
+
when String
|
88
|
+
File.open(@output, "w", &block)
|
89
|
+
else
|
90
|
+
yield(@output)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def setup_options(options)
|
95
|
+
@output = options[:output] || "-"
|
96
|
+
@n_entries = 1000
|
97
|
+
@threshold = Threshold.new
|
98
|
+
@target_queries = []
|
99
|
+
|
100
|
+
@option_parser = OptionParser.new do |parser|
|
101
|
+
parser.version = VERSION
|
102
|
+
parser.banner += " OLD_QUERY_LOG NEW_QUERY_LOG"
|
103
|
+
|
104
|
+
parser.on("-n", "--n-entries=N",
|
105
|
+
Integer,
|
106
|
+
"Analyze N query log entries",
|
107
|
+
"(#{@n_entries})") do |n|
|
108
|
+
@n_entries = n
|
109
|
+
end
|
110
|
+
|
111
|
+
if @output == "-"
|
112
|
+
default_output = "stdout"
|
113
|
+
else
|
114
|
+
default_output = @output
|
115
|
+
end
|
116
|
+
parser.on("--output=PATH",
|
117
|
+
"Output to PATH.",
|
118
|
+
"(#{default_output})") do |output|
|
119
|
+
@output = output
|
120
|
+
end
|
121
|
+
|
122
|
+
parser.on("--target-query-file=TARGET_QUERY_FILE",
|
123
|
+
"Analyze matched queries which are listed " +
|
124
|
+
"in specified TARGET_QUERY_FILE.") do |path|
|
125
|
+
if File.exist?(path)
|
126
|
+
@target_queries = File.readlines(path, chomp: true)
|
127
|
+
else
|
128
|
+
message = "target query file doesn't exist: <#{path}>"
|
129
|
+
raise OptionParser::InvalidOption.new(message)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
parser.on("--slow-query-ratio=RATIO",
|
134
|
+
Float,
|
135
|
+
"Use RATIO as threshold to detect slow queries.",
|
136
|
+
"If MEAN_NEW_ELAPSED_TIME / MEAN_OLD_ELAPSED_TIME AVERAGE",
|
137
|
+
"is larger than RATIO, the query is slow.",
|
138
|
+
"(#{@threshold.query_ratio})") do |ratio|
|
139
|
+
@threshold.query_ratio = ratio
|
140
|
+
end
|
141
|
+
|
142
|
+
parser.on("--slow-query-second=SECOND",
|
143
|
+
Float,
|
144
|
+
"Use SECOND as threshold to detect slow queries.",
|
145
|
+
"If MEAN_NEW_ELAPSED_TIME - MEAN_OLD_ELAPSED_TIME AVERAGE",
|
146
|
+
"is larger than SECOND, the query is slow.",
|
147
|
+
"(#{@threshold.query_second})") do |second|
|
148
|
+
@threshold.query_second = second
|
149
|
+
end
|
150
|
+
|
151
|
+
parser.on("--slow-operation-ratio=RATIO",
|
152
|
+
Float,
|
153
|
+
"Use RATIO as threshold to detect slow operations.",
|
154
|
+
"If MEAN_NEW_ELAPSED_TIME / MEAN_OLD_ELAPSED_TIME AVERAGE",
|
155
|
+
"is larger than RATIO, the operation is slow.",
|
156
|
+
"(#{@threshold.operation_ratio})") do |ratio|
|
157
|
+
@threshold.operation_ratio = ratio
|
158
|
+
end
|
159
|
+
|
160
|
+
parser.on("--slow-operation-second=SECOND",
|
161
|
+
Float,
|
162
|
+
"Use SECOND as threshold to detect slow operations.",
|
163
|
+
"If MEAN_NEW_ELAPSED_TIME - MEAN_OLD_ELAPSED_TIME AVERAGE",
|
164
|
+
"is larger than SECOND, the operation is slow.",
|
165
|
+
"(#{@threshold.operation_second})") do |second|
|
166
|
+
@threshold.operation_second = second
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
def analyze(log_paths)
|
173
|
+
full_statistics = []
|
174
|
+
begin
|
175
|
+
n = 1
|
176
|
+
parser = Parser.new
|
177
|
+
parse_log(parser, log_paths) do |statistic|
|
178
|
+
next if n > @n_entries
|
179
|
+
full_statistics << statistic
|
180
|
+
n += 1
|
181
|
+
end
|
182
|
+
rescue Error
|
183
|
+
$stderr.puts($!.message)
|
184
|
+
return nil
|
185
|
+
end
|
186
|
+
full_statistics
|
187
|
+
end
|
188
|
+
|
189
|
+
class Threshold
|
190
|
+
attr_accessor :query_ratio
|
191
|
+
attr_accessor :query_second
|
192
|
+
attr_accessor :operation_ratio
|
193
|
+
attr_accessor :operation_second
|
194
|
+
def initialize
|
195
|
+
@query_ratio = 0
|
196
|
+
@query_second = 0.2
|
197
|
+
@operation_ratio = 0.1
|
198
|
+
@operation_second = 0.1
|
199
|
+
end
|
200
|
+
|
201
|
+
def slow_query?(diff_sec, diff_ratio)
|
202
|
+
return false if diff_sec.zero?
|
203
|
+
(diff_sec >= @query_second) and
|
204
|
+
(diff_ratio >= @query_ratio)
|
205
|
+
end
|
206
|
+
|
207
|
+
def slow_operation?(diff_sec, diff_ratio)
|
208
|
+
return false if diff_sec.zero?
|
209
|
+
(diff_sec >= @operation_second) and
|
210
|
+
(diff_ratio >= @operation_ratio)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class Statistic
|
215
|
+
def initialize(old, new, threshold)
|
216
|
+
@old = old
|
217
|
+
@new = new
|
218
|
+
@threshold = threshold
|
219
|
+
end
|
220
|
+
|
221
|
+
def old_elapsed_time
|
222
|
+
@old_elapsed_time ||= compute_mean(@old)
|
223
|
+
end
|
224
|
+
|
225
|
+
def new_elapsed_time
|
226
|
+
@new_elapsed_time ||= compute_mean(@new)
|
227
|
+
end
|
228
|
+
|
229
|
+
def diff_elapsed_time
|
230
|
+
new_elapsed_time - old_elapsed_time
|
231
|
+
end
|
232
|
+
|
233
|
+
def ratio
|
234
|
+
@ratio ||= compute_ratio
|
235
|
+
end
|
236
|
+
|
237
|
+
private
|
238
|
+
def compute_ratio
|
239
|
+
if old_elapsed_time.zero?
|
240
|
+
if new_elapsed_time.zero?
|
241
|
+
0.0
|
242
|
+
else
|
243
|
+
Float::INIFINITY
|
244
|
+
end
|
245
|
+
else
|
246
|
+
new_elapsed_time / old_elapsed_time
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
class OperationStatistic < Statistic
|
252
|
+
attr_reader :index
|
253
|
+
def initialize(operation, index, old, new, threshold)
|
254
|
+
super(old, new, threshold)
|
255
|
+
@operation = operation
|
256
|
+
@index = index
|
257
|
+
end
|
258
|
+
|
259
|
+
def name
|
260
|
+
@operation[:name]
|
261
|
+
end
|
262
|
+
|
263
|
+
def context
|
264
|
+
@operation[:context]
|
265
|
+
end
|
266
|
+
|
267
|
+
def slow?
|
268
|
+
@threshold.slow_operation?(diff_elapsed_time, ratio)
|
269
|
+
end
|
270
|
+
|
271
|
+
private
|
272
|
+
def compute_mean(operations)
|
273
|
+
elapsed_times = operations.collect do |operation|
|
274
|
+
operation[:relative_elapsed] / 1000.0 / 1000.0 / 1000.0
|
275
|
+
end
|
276
|
+
elapsed_times.inject(:+) / elapsed_times.size
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
class QueryStatistic < Statistic
|
281
|
+
attr_reader :query
|
282
|
+
def initialize(query, old, new, threshold)
|
283
|
+
super(old, new, threshold)
|
284
|
+
@query = query
|
285
|
+
end
|
286
|
+
|
287
|
+
def slow?
|
288
|
+
@threshold.slow_query?(diff_elapsed_time, ratio)
|
289
|
+
end
|
290
|
+
|
291
|
+
def each_operation_statistic
|
292
|
+
@old.first.operations.each_with_index do |operation, i|
|
293
|
+
old_operations = @old.collect do |statistic|
|
294
|
+
statistic.operations[i]
|
295
|
+
end
|
296
|
+
# TODO: old and new may use different index
|
297
|
+
new_operations = @new.collect do |statistic|
|
298
|
+
statistic.operations[i]
|
299
|
+
end
|
300
|
+
operation_statistic = OperationStatistic.new(operation,
|
301
|
+
i,
|
302
|
+
old_operations,
|
303
|
+
new_operations,
|
304
|
+
@threshold)
|
305
|
+
yield(operation_statistic)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
private
|
310
|
+
def compute_mean(statistics)
|
311
|
+
elapsed_times = statistics.collect do |statistic|
|
312
|
+
statistic.elapsed / 1000.0 / 1000.0 / 1000.0
|
313
|
+
end
|
314
|
+
elapsed_times.inject(:+) / elapsed_times.size
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
class Checker
|
319
|
+
def initialize(old_statistics,
|
320
|
+
new_statistics,
|
321
|
+
output,
|
322
|
+
threshold,
|
323
|
+
target_queries)
|
324
|
+
@old_statistics = old_statistics
|
325
|
+
@new_statistics = new_statistics
|
326
|
+
@output = output
|
327
|
+
@threshold = threshold
|
328
|
+
@target_queries = target_queries
|
329
|
+
end
|
330
|
+
|
331
|
+
def check
|
332
|
+
old_statistics = filter_statistics(@old_statistics)
|
333
|
+
new_statistics = filter_statistics(@new_statistics)
|
334
|
+
old_queries = old_statistics.group_by(&:raw_command)
|
335
|
+
new_queries = new_statistics.group_by(&:raw_command)
|
336
|
+
|
337
|
+
query_statistics = []
|
338
|
+
old_queries.each_key do |query|
|
339
|
+
query_statistic = QueryStatistic.new(query,
|
340
|
+
old_queries[query],
|
341
|
+
new_queries[query],
|
342
|
+
@threshold)
|
343
|
+
next unless query_statistic.slow?
|
344
|
+
query_statistics << query_statistic
|
345
|
+
end
|
346
|
+
|
347
|
+
n_slow_queries = 0
|
348
|
+
n_target_operations = 0
|
349
|
+
n_slow_operations = 0
|
350
|
+
query_statistics.sort_by(&:ratio).each do |query_statistic|
|
351
|
+
n_slow_queries += 1
|
352
|
+
@output.puts(<<-REPORT)
|
353
|
+
Query: #{query_statistic.query}
|
354
|
+
Mean (old): #{format_elapsed_time(query_statistic.old_elapsed_time)}
|
355
|
+
Mean (new): #{format_elapsed_time(query_statistic.new_elapsed_time)}
|
356
|
+
Diff: #{format_diff(query_statistic)}
|
357
|
+
Operations:
|
358
|
+
REPORT
|
359
|
+
query_statistic.each_operation_statistic do |operation_statistic|
|
360
|
+
n_target_operations += 1
|
361
|
+
next unless operation_statistic.slow?
|
362
|
+
|
363
|
+
n_slow_operations += 1
|
364
|
+
index = operation_statistic.index
|
365
|
+
name = operation_statistic.name
|
366
|
+
context = operation_statistic.context
|
367
|
+
label = [name, context].compact.join(" ")
|
368
|
+
old_elapsed_time = operation_statistic.old_elapsed_time
|
369
|
+
new_elapsed_time = operation_statistic.new_elapsed_time
|
370
|
+
@output.puts(<<-REPORT)
|
371
|
+
Operation[#{index}]: #{label}
|
372
|
+
Mean (old): #{format_elapsed_time(old_elapsed_time)}
|
373
|
+
Mean (new): #{format_elapsed_time(new_elapsed_time)}
|
374
|
+
Diff: #{format_diff(operation_statistic)}
|
375
|
+
REPORT
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
n_all_queries = @old_statistics.size
|
380
|
+
n_target_queries = old_queries.size
|
381
|
+
n_old_cached_queries = count_cached_queries(@old_statistics)
|
382
|
+
n_new_cached_queries = count_cached_queries(@new_statistics)
|
383
|
+
@output.puts(<<-REPORT)
|
384
|
+
Summary:
|
385
|
+
Slow queries: #{format_summary(n_slow_queries, n_target_queries)}
|
386
|
+
Slow operations: #{format_summary(n_slow_operations, n_target_operations)}
|
387
|
+
Caches (old): #{format_summary(n_old_cached_queries, n_all_queries)}
|
388
|
+
Caches (new): #{format_summary(n_new_cached_queries, n_all_queries)}
|
389
|
+
REPORT
|
390
|
+
true
|
391
|
+
end
|
392
|
+
|
393
|
+
private
|
394
|
+
def count_cached_queries(statistics)
|
395
|
+
n_cached_queries = 0
|
396
|
+
statistics.each do |statistic|
|
397
|
+
n_cached_queries += 1 if statistic.cache_used?
|
398
|
+
end
|
399
|
+
n_cached_queries
|
400
|
+
end
|
401
|
+
|
402
|
+
def filter_statistics(statistics)
|
403
|
+
statistics.find_all do |statistic|
|
404
|
+
target_statistic?(statistic)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def target_statistic?(statistic)
|
409
|
+
return false if statistic.cache_used?
|
410
|
+
return true if @target_queries.empty?
|
411
|
+
@target_queries.include?(statistic.raw_command)
|
412
|
+
end
|
413
|
+
|
414
|
+
def format_elapsed_time(elapsed_time)
|
415
|
+
if elapsed_time < (1 / 1000.0 / 1000.0)
|
416
|
+
"%.1fnsec" % (elapsed_time * 1000 * 1000)
|
417
|
+
elsif elapsed_time < (1 / 1000.0)
|
418
|
+
"%.1fusec" % (elapsed_time * 1000 * 1000)
|
419
|
+
elsif elapsed_time < 1
|
420
|
+
"%.1fmsec" % (elapsed_time * 1000)
|
421
|
+
elsif elapsed_time < 60
|
422
|
+
"%.1fsec" % elapsed_time
|
423
|
+
else
|
424
|
+
"%.1fmin" % (elapsed_time / 60)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def format_diff(statistic)
|
429
|
+
"%s%s/%+.2f" % [
|
430
|
+
statistic.diff_elapsed_time < 0 ? "-" : "+",
|
431
|
+
format_elapsed_time(statistic.diff_elapsed_time),
|
432
|
+
statistic.ratio,
|
433
|
+
]
|
434
|
+
end
|
435
|
+
|
436
|
+
def format_summary(n_slows, total)
|
437
|
+
if total.zero?
|
438
|
+
percentage = 0.0
|
439
|
+
else
|
440
|
+
percentage = (n_slows / total.to_f) * 100
|
441
|
+
end
|
442
|
+
"%d/%d(%6.2f%%)" % [n_slows, total, percentage]
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
@@ -338,7 +338,7 @@ module GroongaQueryLog
|
|
338
338
|
@nullable_reference_number_accessors,
|
339
339
|
:rewrite_not_or_regular_expression =>
|
340
340
|
@rewrite_not_or_regular_expression,
|
341
|
-
:
|
341
|
+
:rewrite_and_not_operator =>
|
342
342
|
@rewrite_and_not_operator,
|
343
343
|
:target_command_names => @target_command_names,
|
344
344
|
:read_timeout => @read_timeout,
|
@@ -61,6 +61,12 @@ module GroongaQueryLog
|
|
61
61
|
elapsed_in_seconds >= @slow_response_threshold
|
62
62
|
end
|
63
63
|
|
64
|
+
def cache_used?
|
65
|
+
each_operation.any? do |operation|
|
66
|
+
operation[:name] == "cache"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
64
70
|
def each_operation
|
65
71
|
return to_enum(__method__) unless block_given?
|
66
72
|
|
@@ -0,0 +1,311 @@
|
|
1
|
+
# Copyright (C) 2019 Kentaro Hayashi <hayashi@clear-code.com>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License as published by the Free Software Foundation; either
|
6
|
+
# version 2.1 of the License, or (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This library 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 GNU
|
11
|
+
# Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
14
|
+
# License along with this library; if not, write to the Free Software
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
16
|
+
|
17
|
+
require "groonga-query-log/command/check-performance-regression"
|
18
|
+
|
19
|
+
class CheckPerformanceRegressionCommandTest < Test::Unit::TestCase
|
20
|
+
include Helper::Path
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@command = GroongaQueryLog::Command::CheckPerformanceRegression.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def fixture_path(*components)
|
27
|
+
super("check-performance-regression", *components)
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_command(*arguments)
|
31
|
+
output = StringIO.new
|
32
|
+
options = {:output => output}
|
33
|
+
command = GroongaQueryLog::Command::CheckPerformanceRegression.new(options)
|
34
|
+
command.run(arguments)
|
35
|
+
output.string
|
36
|
+
end
|
37
|
+
|
38
|
+
sub_test_case("options") do
|
39
|
+
MISSING_QUERY_LOG_ERROR = <<-OUTPUT
|
40
|
+
old query log and new query log must be specified.
|
41
|
+
OUTPUT
|
42
|
+
|
43
|
+
def run_command_with_stderr
|
44
|
+
begin
|
45
|
+
output = StringIO.new
|
46
|
+
$stderr = output
|
47
|
+
yield
|
48
|
+
output.string
|
49
|
+
ensure
|
50
|
+
$stderr = STDERR
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_no_option
|
55
|
+
actual = run_command_with_stderr do
|
56
|
+
@command.run([])
|
57
|
+
end
|
58
|
+
assert_equal(MISSING_QUERY_LOG_ERROR, actual)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_too_few_query_logs
|
62
|
+
actual = run_command_with_stderr do
|
63
|
+
@command.run([
|
64
|
+
fixture_path("query1.log")
|
65
|
+
])
|
66
|
+
end
|
67
|
+
assert_equal(MISSING_QUERY_LOG_ERROR, actual)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_too_many_query_logs
|
71
|
+
actual = run_command_with_stderr do
|
72
|
+
@command.run([
|
73
|
+
fixture_path("query1.log"),
|
74
|
+
fixture_path("query2.log"),
|
75
|
+
fixture_path("query1.log")
|
76
|
+
])
|
77
|
+
end
|
78
|
+
assert_equal(MISSING_QUERY_LOG_ERROR, actual)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_nonexistent_input_old_query
|
82
|
+
actual = run_command_with_stderr do
|
83
|
+
@command.run([
|
84
|
+
fixture_path("nonexsistent.log"),
|
85
|
+
fixture_path("query2.log")
|
86
|
+
])
|
87
|
+
end
|
88
|
+
assert_equal(<<-OUTPUT, actual)
|
89
|
+
query log path doesn't exist: <#{fixture_path("nonexsistent.log")}>
|
90
|
+
OUTPUT
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_nonexistent_input_new_query
|
94
|
+
actual = run_command_with_stderr do
|
95
|
+
@command.run([
|
96
|
+
fixture_path("query1.log"),
|
97
|
+
fixture_path("nonexsistent.log")
|
98
|
+
])
|
99
|
+
end
|
100
|
+
assert_equal(<<-OUTPUT, actual)
|
101
|
+
query log path doesn't exist: <#{fixture_path("nonexsistent.log")}>
|
102
|
+
OUTPUT
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_output
|
106
|
+
Tempfile.open('test_output') do |output|
|
107
|
+
@command.run([
|
108
|
+
"--slow-query-ratio=0",
|
109
|
+
"--slow-query-second=0",
|
110
|
+
"--slow-operation-ratio=0",
|
111
|
+
"--slow-operation-second=0",
|
112
|
+
"--output=#{output.path}",
|
113
|
+
fixture_path("query1.log"),
|
114
|
+
fixture_path("query2.log")
|
115
|
+
])
|
116
|
+
expected = <<-OUTPUT
|
117
|
+
Query: select --table Site --limit 0
|
118
|
+
Mean (old): 12.0msec
|
119
|
+
Mean (new): 14.0msec
|
120
|
+
Diff: +2.0msec/+1.17
|
121
|
+
Operations:
|
122
|
+
Operation[0]: select
|
123
|
+
Mean (old): 5.0msec
|
124
|
+
Mean (new): 6.0msec
|
125
|
+
Diff: +1.0msec/+1.20
|
126
|
+
Summary:
|
127
|
+
Slow queries: 1/1(100.00%)
|
128
|
+
Slow operations: 1/2( 50.00%)
|
129
|
+
Caches (old): 0/1( 0.00%)
|
130
|
+
Caches (new): 0/1( 0.00%)
|
131
|
+
OUTPUT
|
132
|
+
assert_equal(expected, output.read)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_n_query
|
137
|
+
actual = run_command("--n-entries=1",
|
138
|
+
"--slow-query-ratio=0",
|
139
|
+
"--slow-query-second=0",
|
140
|
+
"--slow-operation-ratio=0",
|
141
|
+
"--slow-operation-second=0",
|
142
|
+
fixture_path("nquery.log"),
|
143
|
+
fixture_path("nquery2.log"))
|
144
|
+
expected = <<-OUTPUT
|
145
|
+
Query: select --table Site --filter "_id >= 4 && _id <= 6"
|
146
|
+
Mean (old): 70.0msec
|
147
|
+
Mean (new): 90.0msec
|
148
|
+
Diff: +20.0msec/+1.29
|
149
|
+
Operations:
|
150
|
+
Operation[0]: filter #<accessor _id(Site)> greater_equal 4
|
151
|
+
Mean (old): 40.0msec
|
152
|
+
Mean (new): 80.0msec
|
153
|
+
Diff: +40.0msec/+2.00
|
154
|
+
Operation[1]: filter #<accessor _id(Site)> less_equal 6
|
155
|
+
Mean (old): 10.0msec
|
156
|
+
Mean (new): 20.0msec
|
157
|
+
Diff: +10.0msec/+2.00
|
158
|
+
Operation[2]: select
|
159
|
+
Mean (old): 10.0msec
|
160
|
+
Mean (new): 20.0msec
|
161
|
+
Diff: +10.0msec/+2.00
|
162
|
+
Operation[3]: output
|
163
|
+
Mean (old): 10.0msec
|
164
|
+
Mean (new): 20.0msec
|
165
|
+
Diff: +10.0msec/+2.00
|
166
|
+
Summary:
|
167
|
+
Slow queries: 1/1(100.00%)
|
168
|
+
Slow operations: 4/4(100.00%)
|
169
|
+
Caches (old): 0/1( 0.00%)
|
170
|
+
Caches (new): 0/1( 0.00%)
|
171
|
+
OUTPUT
|
172
|
+
assert_equal(expected, actual)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
sub_test_case(".new") do
|
177
|
+
def test_output
|
178
|
+
actual = run_command("--slow-query-ratio=0.0",
|
179
|
+
"--slow-query-second=0.0",
|
180
|
+
"--slow-operation-ratio=0.0",
|
181
|
+
"--slow-operation-second=0.0",
|
182
|
+
fixture_path("query1.log"),
|
183
|
+
fixture_path("query2.log"))
|
184
|
+
expected = <<-OUTPUT
|
185
|
+
Query: select --table Site --limit 0
|
186
|
+
Mean (old): 12.0msec
|
187
|
+
Mean (new): 14.0msec
|
188
|
+
Diff: +2.0msec/+1.17
|
189
|
+
Operations:
|
190
|
+
Operation[0]: select
|
191
|
+
Mean (old): 5.0msec
|
192
|
+
Mean (new): 6.0msec
|
193
|
+
Diff: +1.0msec/+1.20
|
194
|
+
Summary:
|
195
|
+
Slow queries: 1/1(100.00%)
|
196
|
+
Slow operations: 1/2( 50.00%)
|
197
|
+
Caches (old): 0/1( 0.00%)
|
198
|
+
Caches (new): 0/1( 0.00%)
|
199
|
+
OUTPUT
|
200
|
+
assert_equal(expected, actual)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
sub_test_case("query-ratio") do
|
205
|
+
def test_filtered
|
206
|
+
actual = run_command("--slow-query-ratio=2",
|
207
|
+
"--slow-query-second=0",
|
208
|
+
"--slow-operation-ratio=0",
|
209
|
+
"--slow-operation-second=0",
|
210
|
+
fixture_path("query1.log"),
|
211
|
+
fixture_path("query2.log"))
|
212
|
+
expected = <<-OUTPUT
|
213
|
+
Summary:
|
214
|
+
Slow queries: 0/1( 0.00%)
|
215
|
+
Slow operations: 0/0( 0.00%)
|
216
|
+
Caches (old): 0/1( 0.00%)
|
217
|
+
Caches (new): 0/1( 0.00%)
|
218
|
+
OUTPUT
|
219
|
+
assert_equal(expected, actual)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
sub_test_case("operation-ratio") do
|
224
|
+
def test_filtered
|
225
|
+
actual = run_command("--slow-query-ratio=0",
|
226
|
+
"--slow-query-second=0",
|
227
|
+
"--slow-operation-ratio=2",
|
228
|
+
"--slow-operation-second=0",
|
229
|
+
fixture_path("query1.log"),
|
230
|
+
fixture_path("query2.log"))
|
231
|
+
expected = <<-OUTPUT
|
232
|
+
Query: select --table Site --limit 0
|
233
|
+
Mean (old): 12.0msec
|
234
|
+
Mean (new): 14.0msec
|
235
|
+
Diff: +2.0msec/+1.17
|
236
|
+
Operations:
|
237
|
+
Summary:
|
238
|
+
Slow queries: 1/1(100.00%)
|
239
|
+
Slow operations: 0/2( 0.00%)
|
240
|
+
Caches (old): 0/1( 0.00%)
|
241
|
+
Caches (new): 0/1( 0.00%)
|
242
|
+
OUTPUT
|
243
|
+
assert_equal(expected, actual)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
sub_test_case("query-second") do
|
248
|
+
def test_filtered
|
249
|
+
actual = run_command("--slow-query-ratio=0",
|
250
|
+
"--slow-query-second=0.02",
|
251
|
+
"--slow-operation-ratio=0",
|
252
|
+
"--slow-operation-second=0",
|
253
|
+
fixture_path("query1.log"),
|
254
|
+
fixture_path("query2.log"))
|
255
|
+
expected = <<-OUTPUT
|
256
|
+
Summary:
|
257
|
+
Slow queries: 0/1( 0.00%)
|
258
|
+
Slow operations: 0/0( 0.00%)
|
259
|
+
Caches (old): 0/1( 0.00%)
|
260
|
+
Caches (new): 0/1( 0.00%)
|
261
|
+
OUTPUT
|
262
|
+
assert_equal(expected, actual)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
sub_test_case("operation-second") do
|
267
|
+
def test_filtered
|
268
|
+
actual = run_command("--slow-query-ratio=0",
|
269
|
+
"--slow-query-second=0",
|
270
|
+
"--slow-operation-ratio=0",
|
271
|
+
"--slow-operation-second=0.001",
|
272
|
+
fixture_path("query1.log"),
|
273
|
+
fixture_path("query2.log"))
|
274
|
+
expected = <<-OUTPUT
|
275
|
+
Query: select --table Site --limit 0
|
276
|
+
Mean (old): 12.0msec
|
277
|
+
Mean (new): 14.0msec
|
278
|
+
Diff: +2.0msec/+1.17
|
279
|
+
Operations:
|
280
|
+
Operation[0]: select
|
281
|
+
Mean (old): 5.0msec
|
282
|
+
Mean (new): 6.0msec
|
283
|
+
Diff: +1.0msec/+1.20
|
284
|
+
Summary:
|
285
|
+
Slow queries: 1/1(100.00%)
|
286
|
+
Slow operations: 1/2( 50.00%)
|
287
|
+
Caches (old): 0/1( 0.00%)
|
288
|
+
Caches (new): 0/1( 0.00%)
|
289
|
+
OUTPUT
|
290
|
+
assert_equal(expected, actual)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
sub_test_case("cache") do
|
295
|
+
def test_ignored_cache
|
296
|
+
actual = run_command("--slow-query-ratio=0",
|
297
|
+
"--slow-operation-ratio=0",
|
298
|
+
"--slow-query-second=0",
|
299
|
+
fixture_path("cache.log"),
|
300
|
+
fixture_path("cache.log"))
|
301
|
+
expected = <<-OUTPUT
|
302
|
+
Summary:
|
303
|
+
Slow queries: 0/0( 0.00%)
|
304
|
+
Slow operations: 0/0( 0.00%)
|
305
|
+
Caches (old): 1/1(100.00%)
|
306
|
+
Caches (new): 1/1(100.00%)
|
307
|
+
OUTPUT
|
308
|
+
assert_equal(expected, actual)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
2019-01-24 08:18:33.921596|0x7ffd9e258a40|>select --table Site --filter "_id >= 4 && _id <= 6"
|
2
|
+
2019-01-24 08:18:33.968258|0x7ffd9e258a40|:000000040000000 filter(6): #<accessor _id(Site)> greater_equal 4
|
3
|
+
2019-01-24 08:18:33.968917|0x7ffd9e258a40|:000000050000000 filter(3): #<accessor _id(Site)> less_equal 6
|
4
|
+
2019-01-24 08:18:33.968940|0x7ffd9e258a40|:000000060000000 select(3)
|
5
|
+
2019-01-24 08:18:33.969085|0x7ffd9e258a40|:000000070000000 output(3)
|
6
|
+
2019-01-24 08:18:33.969311|0x7ffd9e258a40|<000000070000000 rc=0
|
7
|
+
2019-01-24 08:19:05.449799|0x7ffe40eafa50|>select --table Site
|
8
|
+
2019-01-24 08:19:05.450416|0x7ffe40eafa50|:000000000600000 select(9)
|
9
|
+
2019-01-24 08:19:05.450706|0x7ffe40eafa50|:000000000900000 output(9)
|
10
|
+
2019-01-24 08:19:05.451271|0x7ffe40eafa50|<000000001400000 rc=0
|
@@ -0,0 +1,10 @@
|
|
1
|
+
2019-01-24 08:18:33.921596|0x7ffd9e258a40|>select --table Site --filter "_id >= 4 && _id <= 6"
|
2
|
+
2019-01-24 08:18:33.968258|0x7ffd9e258a40|:000000080000000 filter(6): #<accessor _id(Site)> greater_equal 4
|
3
|
+
2019-01-24 08:18:33.968917|0x7ffd9e258a40|:000000100000000 filter(3): #<accessor _id(Site)> less_equal 6
|
4
|
+
2019-01-24 08:18:33.968940|0x7ffd9e258a40|:000000120000000 select(3)
|
5
|
+
2019-01-24 08:18:33.969085|0x7ffd9e258a40|:000000140000000 output(3)
|
6
|
+
2019-01-24 08:18:33.969311|0x7ffd9e258a40|<000000090000000 rc=0
|
7
|
+
2019-01-24 08:19:05.449799|0x7ffe40eafa50|>select --table Site
|
8
|
+
2019-01-24 08:19:05.450416|0x7ffe40eafa50|:000000000600000 select(9)
|
9
|
+
2019-01-24 08:19:05.450706|0x7ffe40eafa50|:000000000900000 output(9)
|
10
|
+
2019-01-24 08:19:05.451271|0x7ffe40eafa50|<000000001400000 rc=0
|
@@ -0,0 +1,4 @@
|
|
1
|
+
2019-01-22 15:00:57.466438|0x7ffc70f60080|>select --table Site --limit 0
|
2
|
+
2019-01-22 15:00:57.472248|0x7ffc70f60080|:000000005000000 select(1)
|
3
|
+
2019-01-22 15:00:57.475195|0x7ffc70f60080|:000000007000000 output(0)
|
4
|
+
2019-01-22 15:00:57.475480|0x7ffc70f60080|<000000012000000 rc=0
|
@@ -0,0 +1,4 @@
|
|
1
|
+
2019-01-22 16:00:00.000000|0x7ffc70f60080|>select --table Site --limit 0
|
2
|
+
2019-01-22 16:00:01.500000|0x7ffc70f60080|:000000006000000 select(1)
|
3
|
+
2019-01-22 16:00:02.000000|0x7ffc70f60080|:000000008000000 output(0)
|
4
|
+
2019-01-22 16:00:03.000000|0x7ffc70f60080|<000000014000000 rc=0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groonga-query-log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: groonga-command-parser
|
@@ -154,17 +154,18 @@ description: ''
|
|
154
154
|
email:
|
155
155
|
- kou@clear-code.com
|
156
156
|
executables:
|
157
|
-
- groonga-query-log-
|
158
|
-
- groonga-query-log-
|
157
|
+
- groonga-query-log-detect-memory-leak
|
158
|
+
- groonga-query-log-analyze
|
159
159
|
- groonga-query-log-check-crash
|
160
160
|
- groonga-query-log-replay
|
161
|
+
- groonga-query-log-extract
|
162
|
+
- groonga-query-log-show-running-queries
|
161
163
|
- groonga-query-log-check-command-version-compatibility
|
164
|
+
- groonga-query-log-run-regression-test
|
162
165
|
- groonga-query-log-verify-server
|
163
|
-
- groonga-query-log-show-running-queries
|
164
|
-
- groonga-query-log-analyze
|
165
|
-
- groonga-query-log-extract
|
166
|
-
- groonga-query-log-detect-memory-leak
|
167
166
|
- groonga-query-log-analyze-load
|
167
|
+
- groonga-query-log-format-regression-test-logs
|
168
|
+
- groonga-query-log-check-performance-regression
|
168
169
|
extensions: []
|
169
170
|
extra_rdoc_files: []
|
170
171
|
files:
|
@@ -176,6 +177,7 @@ files:
|
|
176
177
|
- bin/groonga-query-log-analyze-load
|
177
178
|
- bin/groonga-query-log-check-command-version-compatibility
|
178
179
|
- bin/groonga-query-log-check-crash
|
180
|
+
- bin/groonga-query-log-check-performance-regression
|
179
181
|
- bin/groonga-query-log-detect-memory-leak
|
180
182
|
- bin/groonga-query-log-extract
|
181
183
|
- bin/groonga-query-log-format-regression-test-logs
|
@@ -203,6 +205,7 @@ files:
|
|
203
205
|
- lib/groonga-query-log/command/analyzer/streamer.rb
|
204
206
|
- lib/groonga-query-log/command/check-command-version-compatibility.rb
|
205
207
|
- lib/groonga-query-log/command/check-crash.rb
|
208
|
+
- lib/groonga-query-log/command/check-performance-regression.rb
|
206
209
|
- lib/groonga-query-log/command/detect-memory-leak.rb
|
207
210
|
- lib/groonga-query-log/command/extract.rb
|
208
211
|
- lib/groonga-query-log/command/format-regression-test-logs.rb
|
@@ -230,9 +233,15 @@ files:
|
|
230
233
|
- lib/groonga/query-log/command/show-running-queries.rb
|
231
234
|
- lib/groonga/query-log/command/verify-server.rb
|
232
235
|
- test/command/test-analyzer.rb
|
236
|
+
- test/command/test-check-performance-regression.rb
|
233
237
|
- test/command/test-extract.rb
|
234
238
|
- test/command/test-format-regression-test-logs.rb
|
235
239
|
- test/command/test-run-regression-test.rb
|
240
|
+
- test/fixtures/check-performance-regression/cache.log
|
241
|
+
- test/fixtures/check-performance-regression/nquery.log
|
242
|
+
- test/fixtures/check-performance-regression/nquery2.log
|
243
|
+
- test/fixtures/check-performance-regression/query1.log
|
244
|
+
- test/fixtures/check-performance-regression/query2.log
|
236
245
|
- test/fixtures/multi.expected
|
237
246
|
- test/fixtures/n_entries.expected
|
238
247
|
- test/fixtures/no-report-summary.expected
|
@@ -289,36 +298,42 @@ summary: Groonga-query-log is a collection of library and tools to process [Groo
|
|
289
298
|
as a library. You can analyze your Groonga's queries and test with your Groonga's
|
290
299
|
query log by using groonga-query-log as a tool.
|
291
300
|
test_files:
|
292
|
-
- test/
|
293
|
-
- test/fixtures/
|
294
|
-
- test/fixtures/
|
295
|
-
- test/fixtures/
|
296
|
-
- test/fixtures/
|
301
|
+
- test/run-test.rb
|
302
|
+
- test/fixtures/n_entries.expected
|
303
|
+
- test/fixtures/check-performance-regression/query1.log
|
304
|
+
- test/fixtures/check-performance-regression/cache.log
|
305
|
+
- test/fixtures/check-performance-regression/nquery2.log
|
306
|
+
- test/fixtures/check-performance-regression/nquery.log
|
307
|
+
- test/fixtures/check-performance-regression/query2.log
|
308
|
+
- test/fixtures/target-tables.expected
|
309
|
+
- test/fixtures/no-report-summary.expected
|
297
310
|
- test/fixtures/order/-start-time.expected
|
298
311
|
- test/fixtures/order/-elapsed.expected
|
312
|
+
- test/fixtures/order/start-time.expected
|
299
313
|
- test/fixtures/order/elapsed.expected
|
300
|
-
- test/fixtures/no-report-summary.expected
|
301
|
-
- test/fixtures/target-commands.expected
|
302
|
-
- test/fixtures/run-regression-test/data/data.grn
|
303
|
-
- test/fixtures/run-regression-test/query-logs/query.log
|
304
|
-
- test/fixtures/run-regression-test/indexes/indexes.grn
|
305
|
-
- test/fixtures/run-regression-test/schema/schema.grn
|
306
|
-
- test/fixtures/other-query.log
|
307
|
-
- test/fixtures/query.log
|
308
|
-
- test/fixtures/target-tables.expected
|
309
|
-
- test/fixtures/n_entries.expected
|
310
|
-
- test/fixtures/multi.expected
|
311
|
-
- test/fixtures/regression-test-logs/command-format.log
|
312
314
|
- test/fixtures/regression-test-logs/url-format.log
|
315
|
+
- test/fixtures/regression-test-logs/command-format.log
|
313
316
|
- test/fixtures/regression-test-logs/error.log
|
317
|
+
- test/fixtures/multi.expected
|
318
|
+
- test/fixtures/query.log
|
319
|
+
- test/fixtures/other-query.log
|
320
|
+
- test/fixtures/reporter/json-stream.expected
|
321
|
+
- test/fixtures/reporter/console.expected
|
322
|
+
- test/fixtures/reporter/json.expected
|
323
|
+
- test/fixtures/reporter/html.expected
|
324
|
+
- test/fixtures/run-regression-test/schema/schema.grn
|
325
|
+
- test/fixtures/run-regression-test/data/data.grn
|
326
|
+
- test/fixtures/run-regression-test/indexes/indexes.grn
|
327
|
+
- test/fixtures/run-regression-test/query-logs/query.log
|
328
|
+
- test/fixtures/target-commands.expected
|
329
|
+
- test/test-parser.rb
|
330
|
+
- test/helper.rb
|
331
|
+
- test/test-replayer.rb
|
332
|
+
- test/test-response-comparer.rb
|
314
333
|
- test/command/test-run-regression-test.rb
|
334
|
+
- test/command/test-check-performance-regression.rb
|
315
335
|
- test/command/test-format-regression-test-logs.rb
|
316
336
|
- test/command/test-analyzer.rb
|
317
337
|
- test/command/test-extract.rb
|
318
|
-
- test/test-response-comparer.rb
|
319
|
-
- test/test-replayer.rb
|
320
338
|
- test/test-incompatibility-detector.rb
|
321
339
|
- test/test-filter-rewriter.rb
|
322
|
-
- test/test-parser.rb
|
323
|
-
- test/helper.rb
|
324
|
-
- test/run-test.rb
|