groonga-query-log 1.5.8 → 1.5.9

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
  SHA256:
3
- metadata.gz: d28dfe11ea122d12976b21d879671c2dc2246c87bff662a41212c3247865a4c1
4
- data.tar.gz: dd32fada8401876fa9ca27942c0e0f8145bcbf92162c03483aea166e66351cd8
3
+ metadata.gz: 99da1139f30806bb7ead68b469c2122368bcad8ea91586160096751e3919b4ab
4
+ data.tar.gz: ab791f07d33e784531372dd3c4cad59e57e1ae38d778529a3b65dbd8ea1d4466
5
5
  SHA512:
6
- metadata.gz: 9bdc0879550bce0f87030702979315ea127c70bcfcf8fa8817f84e92924d2577c8e4263f87209d756abc804a0b4d2b2edf09b75a31253854edf0e30f00c3237e
7
- data.tar.gz: c3730562b6415c493631598af4e73cb1e1da6ad3aabd6ad6c19ed87200a11dd74cf14400e4c624ad99720d179b0ddc8f696e9454a63b4d15fb8edbd0987f1fdc
6
+ metadata.gz: 9ae76dd7338c155860f1b74dea49fc202baeaa4216018dda0e2c22144663c4ea93db08a4042f3487c429bd565281876d46d9348a4fa27e510c082f9dcb065507
7
+ data.tar.gz: 6d4f6912e00abd0a0ff41c18bcbbd3c251dab17a9d142974ab0719e5dbb5309e97f7fe174ec7cd239cddd0cf1b15c8940b7da2d31e4f8c7c723337d0902940a7
@@ -1,5 +1,28 @@
1
1
  # News
2
2
 
3
+ ## 1.5.9: 2020-04-06
4
+
5
+ ### Fixes
6
+
7
+ * `replay`: Added `--output-type` option.
8
+
9
+ * `replay`: Added support for outputting logs to stdout.
10
+
11
+ * `replay`: Fixed a bug that command name isn't processed correctly.
12
+
13
+ * `replay`: Added support for inputting from stdin.
14
+
15
+ * `run-regression-test`: Added `--old-groonga-env` option.
16
+
17
+ * `run-regression-test`: Added `--new-groonga-env` option.
18
+
19
+ * `run-regression-test`: Added support for checking the number of
20
+ leaked objects.
21
+
22
+ * `replay`: Added `--output-error-responses` option.
23
+
24
+ * `run-regression-test`: Added `--omit-rate` option.
25
+
3
26
  ## 1.5.8: 2020-02-14
4
27
 
5
28
  ### Fixes
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2013-2020 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -29,9 +29,13 @@ module GroongaQueryLog
29
29
  def run(command_line)
30
30
  input_paths = create_parser.parse(command_line)
31
31
  replayer = Replayer.new(@options)
32
- input_paths.each do |input_path|
33
- File.open(input_path) do |input|
34
- replayer.replay(input)
32
+ if input_paths.empty?
33
+ replayer.replay($stdin)
34
+ else
35
+ input_paths.each do |input_path|
36
+ File.open(input_path) do |input|
37
+ replayer.replay(input)
38
+ end
35
39
  end
36
40
  end
37
41
  true
@@ -117,6 +121,21 @@ module GroongaQueryLog
117
121
  "[not output]") do |path|
118
122
  @options.responses_path = path
119
123
  end
124
+
125
+ parser.on("--output-error-responses=PATH",
126
+ "Output only error responses to PATH",
127
+ "[not output]") do |path|
128
+ @options.error_responses_path = path
129
+ end
130
+
131
+ available_output_types = ["json", "msgpack", "apache-arrow"]
132
+ available_output_type_labels = available_output_types.join(", ")
133
+ parser.on("--output-type=TYPE", available_output_types,
134
+ "Use TYPE as the output type",
135
+ "(#{available_output_type_labels})",
136
+ "[use the original output type]") do |type|
137
+ @options.output_type = type
138
+ end
120
139
  end
121
140
  end
122
141
  end
@@ -1,5 +1,5 @@
1
- # Copyright (C) 2014-2019 Kouhei Sutou <kou@clear-code.com>
2
- # Copyright (C) 2019 Horimoto Yasuhiro <horimoto@clear-code.com>
1
+ # Copyright (C) 2014-2020 Sutou Kouhei <kou@clear-code.com>
2
+ # Copyright (C) 2019-2020 Horimoto Yasuhiro <horimoto@clear-code.com>
3
3
  #
4
4
  # This library is free software; you can redistribute it and/or
5
5
  # modify it under the terms of the GNU Lesser General Public
@@ -41,10 +41,12 @@ module GroongaQueryLog
41
41
  @old_groonga = "groonga"
42
42
  @old_database = "db.old/db"
43
43
  @old_groonga_options = []
44
+ @old_groonga_env = {}
44
45
 
45
46
  @new_groonga = "groonga"
46
47
  @new_database = "db.new/db"
47
48
  @new_groonga_options = []
49
+ @new_groonga_env = {}
48
50
 
49
51
  @recreate_database = false
50
52
  @load_data = true
@@ -60,6 +62,7 @@ module GroongaQueryLog
60
62
  @rewrite_not_or_regular_expression = false
61
63
  @rewrite_and_not_operator = false
62
64
  @debug_rewrite = false
65
+ @omit_rate = 0.0
63
66
 
64
67
  @care_order = true
65
68
  @ignored_drilldown_keys = []
@@ -102,12 +105,16 @@ module GroongaQueryLog
102
105
  tester_options)
103
106
  success = tester.run
104
107
  elapsed_time = Time.now - start_time
108
+ n_leaked_objects = tester.new.n_leaked_objects
105
109
 
106
- report = format_report(success, elapsed_time)
110
+ report = format_report(success,
111
+ elapsed_time,
112
+ n_leaked_objects,
113
+ tester.n_executed_commands)
107
114
  notifier.notify_finished(success, report)
108
115
  puts(report)
109
116
 
110
- success
117
+ success and n_leaked_objects.zero?
111
118
  end
112
119
 
113
120
  private
@@ -153,11 +160,21 @@ module GroongaQueryLog
153
160
 
154
161
  parser.on("--old-groonga-option=OPTION",
155
162
  "Add an additional old groonga option",
156
- "You can specify this option multiple times to specify multiple groonga options",
163
+ "You can specify this option multiple times",
164
+ "to specify multiple groonga options",
157
165
  "(no options)") do |groonga_option|
158
166
  @old_groonga_options << groonga_option
159
167
  end
160
168
 
169
+ parser.on("--old-groonga-env=KEY=VALUE",
170
+ "Use KEY=VALUE environment variable for old groonga",
171
+ "You can specify this option multiple times",
172
+ "to specify multiple environment variables",
173
+ "(no environment variables)") do |env|
174
+ key, value = env.split("=", 2)
175
+ @old_groonga_env[key] = value
176
+ end
177
+
161
178
  parser.separator("")
162
179
  parser.separator("New Groonga:")
163
180
  parser.on("--new-groonga=GROONGA",
@@ -168,11 +185,21 @@ module GroongaQueryLog
168
185
 
169
186
  parser.on("--new-groonga-option=OPTION",
170
187
  "Add an additional new groonga option",
171
- "You can specify this option multiple times to specify multiple groonga options",
188
+ "You can specify this option multiple times",
189
+ "to specify multiple groonga options",
172
190
  "(no options)") do |groonga_option|
173
191
  @new_groonga_options << groonga_option
174
192
  end
175
193
 
194
+ parser.on("--new-groonga-env=KEY=VALUE",
195
+ "Use KEY=VALUE environment variable for new groonga",
196
+ "You can specify this option multiple times",
197
+ "to specify multiple environment variables",
198
+ "(no environment variables)") do |env|
199
+ key, value = env.split("=", 2)
200
+ @new_groonga_env[key] = value
201
+ end
202
+
176
203
  parser.separator("")
177
204
  parser.separator("Operations:")
178
205
  parser.on("--recreate-database",
@@ -252,6 +279,13 @@ module GroongaQueryLog
252
279
  "(#{@debug_rewrite})") do |boolean|
253
280
  @debug_rewrite = boolean
254
281
  end
282
+ parser.on("--omit-rate=RATE", Float,
283
+ "You can specify rate for omitting execution queries." +
284
+ "For example, if you specify 0.9 in this option, " +
285
+ "execute queries with the probability of 1/10.",
286
+ "(#{@omit_rate})") do |rate|
287
+ @omit_rate = rate
288
+ end
255
289
 
256
290
  parser.separator("")
257
291
  parser.separator("Comparisons:")
@@ -398,6 +432,7 @@ module GroongaQueryLog
398
432
  :rewrite_and_not_operator =>
399
433
  @rewrite_and_not_operator,
400
434
  :debug_rewrite => @debug_rewrite,
435
+ :omit_rate => @omit_rate,
401
436
  :target_command_names => @target_command_names,
402
437
  :verify_performance => @verify_performance,
403
438
  :performance_verfifier_options => @performance_verfifier_options,
@@ -409,6 +444,7 @@ module GroongaQueryLog
409
444
  def old_groonga_server
410
445
  GroongaServer.new(@old_groonga,
411
446
  @old_groonga_options,
447
+ @old_groonga_env,
412
448
  @old_database,
413
449
  server_options)
414
450
  end
@@ -416,16 +452,26 @@ module GroongaQueryLog
416
452
  def new_groonga_server
417
453
  GroongaServer.new(@new_groonga,
418
454
  @new_groonga_options,
455
+ @new_groonga_env,
419
456
  @new_database,
420
457
  server_options)
421
458
  end
422
459
 
423
- def format_report(success, elapsed_time)
460
+ def format_report(success,
461
+ elapsed_time,
462
+ n_leaked_objects,
463
+ n_executed_commands)
424
464
  formatted = format_elapsed_time(elapsed_time)
465
+ formatted << "Number of executed commands: #{n_executed_commands}\n"
425
466
  if success
426
- formatted << "Success"
467
+ formatted << "Success\n"
427
468
  else
428
469
  formatted << "Failure"
470
+ end
471
+ unless n_leaked_objects.zero?
472
+ formatted << "\nLeaked: #{n_leaked_objects}"
473
+ end
474
+ unless success
429
475
  output = StringIO.new
430
476
  formetter = FormatRegressionTestLogs.new(output: output)
431
477
  formetter.run([results_directory])
@@ -459,11 +505,16 @@ module GroongaQueryLog
459
505
  include Loggable
460
506
 
461
507
  attr_reader :host, :port
462
- def initialize(groonga, groonga_options, database_path, options)
508
+ def initialize(groonga,
509
+ groonga_options,
510
+ groonga_env,
511
+ database_path,
512
+ options)
463
513
  @input_directory = options[:input_directory] || Pathname.new(".")
464
514
  @working_directory = options[:working_directory] || Pathname.new(".")
465
515
  @groonga = groonga
466
516
  @groonga_options = groonga_options
517
+ @groonga_env = groonga_env
467
518
  @database_path = @working_directory + database_path
468
519
  @host = "127.0.0.1"
469
520
  @port = find_unused_port
@@ -473,17 +524,20 @@ module GroongaQueryLog
473
524
  def run
474
525
  return unless @options[:run_queries]
475
526
 
476
- arguments = @groonga_options.dup
477
- arguments.concat(["--bind-address", @host])
478
- arguments.concat(["--port", @port.to_s])
479
- arguments.concat(["--protocol", "http"])
480
- arguments.concat(["--log-path", log_path.to_s])
527
+ spawn_args = []
528
+ spawn_args << @groonga_env if @groonga_env
529
+ spawn_args << @groonga
530
+ spawn_args.concat(@groonga_options)
531
+ spawn_args.concat(["--bind-address", @host])
532
+ spawn_args.concat(["--port", @port.to_s])
533
+ spawn_args.concat(["--protocol", "http"])
534
+ spawn_args.concat(["--log-path", log_path.to_s])
481
535
  if @options[:output_query_log]
482
- arguments.concat(["--query-log-path", query_log_path.to_s])
536
+ spawn_args.concat(["--query-log-path", query_log_path.to_s])
483
537
  end
484
- arguments << "-s"
485
- arguments << @database_path.to_s
486
- @pid = spawn(@groonga, *arguments)
538
+ spawn_args << "-s"
539
+ spawn_args << @database_path.to_s
540
+ @pid = spawn(*spawn_args)
487
541
 
488
542
  n_retries = 10
489
543
  begin
@@ -552,6 +606,19 @@ module GroongaQueryLog
552
606
  Process.waitpid(@pid)
553
607
  end
554
608
 
609
+ def n_leaked_objects
610
+ n = 0
611
+ File.open(log_path) do |log|
612
+ log.each_line do |line|
613
+ case line
614
+ when /grn_fin \((\d+)\)/
615
+ n += Integer($1, 10)
616
+ end
617
+ end
618
+ end
619
+ n
620
+ end
621
+
555
622
  private
556
623
  def find_unused_port
557
624
  server = TCPServer.new(@host, 0)
@@ -600,6 +667,8 @@ module GroongaQueryLog
600
667
  class Tester
601
668
  include Loggable
602
669
 
670
+ attr_reader :old
671
+ attr_reader :new
603
672
  def initialize(old, new, options)
604
673
  @old = old
605
674
  @new = new
@@ -611,6 +680,7 @@ module GroongaQueryLog
611
680
  @stop_on_failure = options[:stop_on_failure]
612
681
  @options = options
613
682
  @n_ready_waits = 2
683
+ @n_executed_commands = 0
614
684
  end
615
685
 
616
686
  def run
@@ -634,6 +704,10 @@ module GroongaQueryLog
634
704
  old_thread_success and new_thread_success
635
705
  end
636
706
 
707
+ def n_executed_commands
708
+ @n_executed_commands
709
+ end
710
+
637
711
  private
638
712
  def run_test
639
713
  @n_ready_waits -= 1
@@ -737,6 +811,10 @@ module GroongaQueryLog
737
811
  if @options[:debug_rewrite]
738
812
  command_line << "--debug-rewrite"
739
813
  end
814
+ if @options[:omit_rate] < 1.0
815
+ command_line << "--omit-rate"
816
+ command_line << @options[:omit_rate].to_s
817
+ end
740
818
  if @options[:target_command_names]
741
819
  command_line << "--target-command-names"
742
820
  command_line << @options[:target_command_names].join(",")
@@ -752,7 +830,9 @@ module GroongaQueryLog
752
830
  command_line << @options[:read_timeout].to_s
753
831
  end
754
832
  verify_server = VerifyServer.new
755
- verify_server.run(command_line, &callback)
833
+ same = verify_server.run(command_line, &callback)
834
+ @n_executed_commands = verify_server.n_executed_commands
835
+ same
756
836
  end
757
837
 
758
838
  def query_log_paths
@@ -1,4 +1,5 @@
1
1
  # Copyright (C) 2013-2018 Kouhei Sutou <kou@clear-code.com>
2
+ # Copyright (C) 2020 Horimoto Yasuhiro <horimoto@clear-code.com>
2
3
  #
3
4
  # This library is free software; you can redistribute it and/or
4
5
  # modify it under the terms of the GNU Lesser General Public
@@ -22,8 +23,10 @@ require "groonga-query-log"
22
23
  module GroongaQueryLog
23
24
  module Command
24
25
  class VerifyServer
26
+ attr_reader :n_executed_commands
25
27
  def initialize
26
28
  @options = ServerVerifier::Options.new
29
+ @n_executed_commands = 0
27
30
  end
28
31
 
29
32
  def run(command_line, &callback)
@@ -50,6 +53,7 @@ module GroongaQueryLog
50
53
  end
51
54
  end
52
55
  end
56
+ @n_executed_commands = verifier.n_executed_commands
53
57
  same
54
58
  end
55
59
 
@@ -254,6 +258,14 @@ module GroongaQueryLog
254
258
  @options.debug_rewrite = boolean
255
259
  end
256
260
 
261
+ parser.on("--omit-rate=RATE", Float,
262
+ "You can specify rate for omitting execution queries." +
263
+ "For example, if you specify 0.9 in this option, " +
264
+ "execute queries with the probability of 1/10.",
265
+ "(#{@options.omit_rate})") do |rate|
266
+ @options.omit_rate = rate
267
+ end
268
+
257
269
  parser.on("--nullable-reference-number-accessor=ACCESSOR",
258
270
  "Mark ACCESSOR as rewrite nullable reference number targets",
259
271
  "You can specify multiple accessors by",
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2017 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2013-2020 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -22,186 +22,218 @@ require "groonga/client"
22
22
  require "groonga-query-log/parser"
23
23
 
24
24
  module GroongaQueryLog
25
- class Replayer
26
- def initialize(options)
27
- @options = options
28
- @queue = SizedQueue.new(@options.request_queue_size)
29
- @responses = Queue.new
30
- end
25
+ class Replayer
26
+ def initialize(options)
27
+ @options = options
28
+ @queue = SizedQueue.new(@options.request_queue_size)
29
+ @responses = Queue.new
30
+ end
31
31
 
32
- def replay(input)
33
- producer = run_producer(input)
34
- consumers = run_consumers
35
- response_logger = run_response_logger
36
- producer.join
37
- consumers.each(&:join)
38
- response_logger.join
39
- end
32
+ def replay(input)
33
+ producer = run_producer(input)
34
+ consumers = run_consumers
35
+ response_logger = run_response_logger
36
+ producer.join
37
+ consumers.each(&:join)
38
+ response_logger.join
39
+ end
40
40
 
41
- private
42
- def run_producer(input)
43
- Thread.new do
44
- parser = Parser.new
45
- id = 0
46
- @options.create_request_output do |output|
47
- parser.parse(input) do |statistic|
48
- next if statistic.command.nil?
49
- next unless target_command?(statistic.command)
50
- # TODO: validate orignal_source is one line
51
- output.puts(statistic.command.original_source)
52
- @queue.push([id, statistic])
53
- id += 1
41
+ private
42
+ def run_producer(input)
43
+ Thread.new do
44
+ parser = Parser.new
45
+ id = 0
46
+ @options.create_request_output do |output|
47
+ parser.parse(input) do |statistic|
48
+ next if statistic.command.nil?
49
+ next unless target_command?(statistic.command)
50
+ # TODO: validate orignal_source is one line
51
+ output.puts(statistic.command.original_source)
52
+ output.flush
53
+ if @options.output_type
54
+ statistic.command[:output_type] ||= @options.output_type
54
55
  end
55
- end
56
- @options.n_clients.times do
57
- @queue.push(nil)
56
+ @queue.push([id, statistic])
57
+ id += 1
58
58
  end
59
59
  end
60
+ @options.n_clients.times do
61
+ @queue.push(nil)
62
+ end
60
63
  end
64
+ end
61
65
 
62
- def run_consumers
63
- @options.n_clients.times.collect do
64
- Thread.new do
65
- loop do
66
- break if run_consumer
67
- end
66
+ def run_consumers
67
+ @options.n_clients.times.collect do
68
+ Thread.new do
69
+ loop do
70
+ break if run_consumer
68
71
  end
69
72
  end
70
73
  end
74
+ end
71
75
 
72
- def run_consumer
73
- @options.create_client do |client|
74
- loop do
75
- id, statistic = @queue.pop
76
- if id.nil?
77
- @responses.push(nil)
78
- return true
79
- end
80
- begin
81
- replay_command(client, id, statistic.command)
82
- rescue Groonga::Client::Error
83
- # TODO: add error log mechanism
84
- $stderr.puts(Time.now.iso8601(6))
85
- $stderr.puts(statistic.command.original_source)
86
- $stderr.puts($!.raw_error.message)
87
- $stderr.puts($!.raw_error.backtrace)
88
- return false
89
- rescue
90
- # TODO: add error log mechanism
91
- $stderr.puts(Time.now.iso8601(6))
92
- $stderr.puts(statistic.command.original_source)
93
- $stderr.puts($!.message)
94
- $stderr.puts($!.backtrace)
95
- return false
96
- end
76
+ def run_consumer
77
+ @options.create_client do |client|
78
+ loop do
79
+ id, statistic = @queue.pop
80
+ if id.nil?
81
+ @responses.push(nil)
82
+ return true
83
+ end
84
+ begin
85
+ replay_command(client, id, statistic.command)
86
+ rescue Groonga::Client::Error
87
+ # TODO: add error log mechanism
88
+ $stderr.puts(Time.now.iso8601(6))
89
+ $stderr.puts(statistic.command.original_source)
90
+ $stderr.puts($!.raw_error.message)
91
+ $stderr.puts($!.raw_error.backtrace)
92
+ return false
93
+ rescue
94
+ # TODO: add error log mechanism
95
+ $stderr.puts(Time.now.iso8601(6))
96
+ $stderr.puts(statistic.command.original_source)
97
+ $stderr.puts($!.message)
98
+ $stderr.puts($!.backtrace)
99
+ return false
97
100
  end
98
101
  end
99
102
  end
103
+ end
100
104
 
101
- def replay_command(client, id, command)
102
- command["cache"] = "no" if @options.disable_cache?
103
- response = client.execute(command)
104
- @responses.push(response)
105
+ def replay_command(client, id, command)
106
+ command["cache"] = "no" if @options.disable_cache?
107
+ response = client.execute(command)
108
+ case command.output_type
109
+ when :json, :xml, :tsv
110
+ response.raw << "\n" unless response.raw.end_with?("\n")
105
111
  end
112
+ @responses.push(response)
113
+ end
106
114
 
107
- def run_response_logger
108
- Thread.new do
109
- @options.create_responses_output do |output|
115
+ def run_response_logger
116
+ Thread.new do
117
+ @options.create_responses_output do |output|
118
+ @options.create_responses_output do |error_output|
110
119
  loop do
111
120
  response = @responses.pop
112
121
  break if response.nil?
113
- # TODO: ensure response is one line
114
122
  # TODO: reorder by ID
115
- output.puts(response.raw)
123
+ output.print(response.raw)
124
+ output.flush
125
+ unless response.success?
126
+ error_output.print(response.raw)
127
+ error_output.flush
128
+ end
116
129
  end
117
130
  end
118
131
  end
119
132
  end
133
+ end
120
134
 
121
- def target_command?(command)
122
- @options.target_command_name?(command.name)
123
- end
135
+ def target_command?(command)
136
+ @options.target_command_name?(command.command_name)
137
+ end
124
138
 
125
- class NullOutput
126
- class << self
127
- def open
128
- output = new
129
- if block_given?
130
- yield(output)
131
- else
132
- output
133
- end
139
+ class NullOutput
140
+ class << self
141
+ def open
142
+ output = new
143
+ if block_given?
144
+ yield(output)
145
+ else
146
+ output
134
147
  end
135
148
  end
149
+ end
136
150
 
137
- def puts(string)
138
- end
151
+ def puts(string)
139
152
  end
140
153
 
141
- class Options
142
- attr_accessor :host
143
- attr_accessor :port
144
- attr_accessor :protocol
145
- attr_accessor :read_timeout
146
- attr_accessor :n_clients
147
- attr_writer :request_queue_size
148
- attr_writer :disable_cache
149
- attr_accessor :target_command_names
150
- attr_accessor :requests_path
151
- attr_accessor :responses_path
152
- def initialize
153
- @host = "127.0.0.1"
154
- @port = 10041
155
- @protocol = :http
156
- @read_timeout = Groonga::Client::Default::READ_TIMEOUT
157
- @n_clients = 8
158
- @request_queue_size = nil
159
- @disable_cache = false
160
- @requests_path = nil
161
- @responses_path = nil
162
- @target_command_names = []
163
- end
154
+ def print(string)
155
+ end
164
156
 
165
- def create_client(&block)
166
- Groonga::Client.open(:host => @host,
167
- :port => @port,
168
- :protocol => @protocol,
169
- :read_timeout => @read_timeout,
170
- &block)
171
- end
157
+ def flush
158
+ end
159
+ end
172
160
 
173
- def create_request_output(&block)
174
- if @requests_path
175
- File.open(@requests_path, "w", &block)
176
- else
177
- NullOutput.open(&block)
178
- end
179
- end
161
+ class Options
162
+ attr_accessor :host
163
+ attr_accessor :port
164
+ attr_accessor :protocol
165
+ attr_accessor :read_timeout
166
+ attr_accessor :n_clients
167
+ attr_writer :request_queue_size
168
+ attr_writer :disable_cache
169
+ attr_accessor :target_command_names
170
+ attr_accessor :requests_path
171
+ attr_accessor :responses_path
172
+ attr_accessor :error_responses_path
173
+ attr_accessor :output_type
174
+ def initialize
175
+ @host = "127.0.0.1"
176
+ @port = 10041
177
+ @protocol = :http
178
+ @read_timeout = Groonga::Client::Default::READ_TIMEOUT
179
+ @n_clients = 8
180
+ @request_queue_size = nil
181
+ @disable_cache = false
182
+ @target_command_names = []
183
+ @requests_path = nil
184
+ @responses_path = nil
185
+ @error_responses_path = nil
186
+ @output_type = nil
187
+ end
180
188
 
181
- def create_responses_output(&block)
182
- if @responses_path
183
- File.open(@responses_path, "w", &block)
184
- else
185
- NullOutput.open(&block)
186
- end
187
- end
189
+ def create_client(&block)
190
+ Groonga::Client.open(:host => @host,
191
+ :port => @port,
192
+ :protocol => @protocol,
193
+ :read_timeout => @read_timeout,
194
+ &block)
195
+ end
188
196
 
189
- def request_queue_size
190
- @request_queue_size || @n_clients * 3
191
- end
197
+ def create_request_output(&block)
198
+ create_output(@requests_path, &block)
199
+ end
200
+
201
+ def create_responses_output(&block)
202
+ create_output(@responses_path, &block)
203
+ end
192
204
 
193
- def disable_cache?
194
- @disable_cache
205
+ def create_error_responses_output(&block)
206
+ create_output(@error_responses_path, &block)
207
+ end
208
+
209
+ def request_queue_size
210
+ @request_queue_size || @n_clients * 3
211
+ end
212
+
213
+ def disable_cache?
214
+ @disable_cache
215
+ end
216
+
217
+ def target_command_name?(name)
218
+ return true if @target_command_names.empty?
219
+ @target_command_names.any? do |name_pattern|
220
+ flags = 0
221
+ flags |= File::FNM_EXTGLOB if File.const_defined?(:FNM_EXTGLOB)
222
+ File.fnmatch(name_pattern, name, flags)
195
223
  end
224
+ end
196
225
 
197
- def target_command_name?(name)
198
- return true if @target_command_names.empty?
199
- @target_command_names.any? do |name_pattern|
200
- flags = 0
201
- flags |= File::FNM_EXTGLOB if File.const_defined?(:FNM_EXTGLOB)
202
- File.fnmatch(name_pattern, name, flags)
203
- end
226
+ private
227
+ def create_output(path, &block)
228
+ case path
229
+ when nil
230
+ NullOutput.open(&block)
231
+ when "-"
232
+ yield($stdout)
233
+ else
234
+ File.open(path, "w", &block)
204
235
  end
205
236
  end
206
237
  end
238
+ end
207
239
  end
@@ -1,4 +1,5 @@
1
1
  # Copyright (C) 2013-2018 Kouhei Sutou <kou@clear-code.com>
2
+ # Copyright (C) 2020 Horimoto Yasuhiro <horimoto@clear-code.com>
2
3
  #
3
4
  # This library is free software; you can redistribute it and/or
4
5
  # modify it under the terms of the GNU Lesser General Public
@@ -26,10 +27,12 @@ require "groonga-query-log/response-comparer"
26
27
 
27
28
  module GroongaQueryLog
28
29
  class ServerVerifier
30
+ attr_reader :n_executed_commands
29
31
  def initialize(options)
30
32
  @options = options
31
33
  @queue = SizedQueue.new(@options.request_queue_size)
32
34
  @events = Queue.new
35
+ @n_executed_commands = 0
33
36
  end
34
37
 
35
38
  def verify(input, &callback)
@@ -50,7 +53,6 @@ module GroongaQueryLog
50
53
  consumers = run_consumers
51
54
 
52
55
  parser = Parser.new
53
- n_commands = 0
54
56
  callback_per_n_commands = 100
55
57
  parser.parse(input) do |statistic|
56
58
  break if stop?
@@ -58,10 +60,11 @@ module GroongaQueryLog
58
60
  command = statistic.command
59
61
  next if command.nil?
60
62
  next unless target_command?(command)
61
- n_commands += 1
63
+ next if rand < @options.omit_rate
64
+ @n_executed_commands += 1
62
65
  @queue.push(statistic)
63
66
 
64
- if callback and (n_commands % callback_per_n_commands).zero?
67
+ if callback and (@n_executed_commands % callback_per_n_commands).zero?
65
68
  @options.n_clients.times do
66
69
  @queue.push(nil)
67
70
  end
@@ -283,6 +286,7 @@ module GroongaQueryLog
283
286
  attr_writer :verify_performance
284
287
  attr_reader :performance_verifier_options
285
288
  attr_writer :debug_rewrite
289
+ attr_writer :omit_rate
286
290
  def initialize
287
291
  @groonga1 = GroongaOptions.new
288
292
  @groonga2 = GroongaOptions.new
@@ -316,6 +320,7 @@ module GroongaQueryLog
316
320
  @verify_performance = false
317
321
  @performance_verifier_options = PerformanceVerifier::Options.new
318
322
  @debug_rewrite = false
323
+ @omit_rate = 0.0
319
324
  end
320
325
 
321
326
  def request_queue_size
@@ -411,6 +416,10 @@ module GroongaQueryLog
411
416
  def debug_rewrite?
412
417
  @debug_rewrite
413
418
  end
419
+
420
+ def omit_rate
421
+ @omit_rate
422
+ end
414
423
  end
415
424
 
416
425
  class GroongaOptions
@@ -15,5 +15,5 @@
15
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
  module GroongaQueryLog
18
- VERSION = "1.5.8"
18
+ VERSION = "1.5.9"
19
19
  end
@@ -1,5 +1,5 @@
1
1
  # Copyright (C) 2019 Kentaro Hayashi <hayashi@clear-code.com>
2
- # Copyright (C) 2019 Horimoto Yasuhiro <horimoto@clear-code.com>
2
+ # Copyright (C) 2019-2020 Horimoto Yasuhiro <horimoto@clear-code.com>
3
3
  #
4
4
  # This library is free software; you can redistribute it and/or
5
5
  # modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@ class RunRegressionTestCommandTest < Test::Unit::TestCase
26
26
  FileUtils.rm_rf(fixture_path("db.old"))
27
27
  FileUtils.rm_rf(fixture_path("db.new"))
28
28
  setup_smtp_server
29
+ @n_commands = 238
29
30
  end
30
31
 
31
32
  def teardown
@@ -90,6 +91,10 @@ class RunRegressionTestCommandTest < Test::Unit::TestCase
90
91
  .gsub(/^Elapsed: \d+days \d{2}:\d{2}:\d{2}$/, "Elapsed: 0days 00:00:00")
91
92
  end
92
93
 
94
+ def n_executed_commands(output)
95
+ output.slice(/^Number of executed commands:\s+(\d+)/, 1).to_i
96
+ end
97
+
93
98
  def fixture_path(*components)
94
99
  super("run-regression-test", *components)
95
100
  end
@@ -105,11 +110,20 @@ class RunRegressionTestCommandTest < Test::Unit::TestCase
105
110
  assert_equal([
106
111
  true,
107
112
  "Elapsed: 0days 00:00:00\n" +
113
+ "Number of executed commands: #{@n_commands}\n" +
108
114
  "Success\n"
109
115
  ],
110
116
  [success, normalize_output(output)])
111
117
  end
112
118
 
119
+ def test_reduce_execution_query
120
+ command_line = ["--omit-rate=0.9"]
121
+ _success, output = run_command(command_line)
122
+ assert do
123
+ n_executed_commands(output) < (@n_commands * 0.2)
124
+ end
125
+ end
126
+
113
127
  def test_mail_from
114
128
  success, _output = run_command(["--smtp-server", @smtp_host,
115
129
  "--smtp-port", @smtp_port.to_s,
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.5.8
4
+ version: 1.5.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-14 00:00:00.000000000 Z
11
+ date: 2020-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: charty
@@ -169,17 +169,17 @@ email:
169
169
  - kou@clear-code.com
170
170
  executables:
171
171
  - groonga-query-log-analyze
172
- - groonga-query-log-verify-server
173
- - groonga-query-log-replay
174
- - groonga-query-log-check-crash
175
- - groonga-query-log-run-regression-test
176
172
  - groonga-query-log-analyze-load
177
- - groonga-query-log-show-running-queries
178
173
  - groonga-query-log-check-command-version-compatibility
174
+ - groonga-query-log-check-crash
175
+ - groonga-query-log-check-performance-regression
179
176
  - groonga-query-log-detect-memory-leak
180
177
  - groonga-query-log-extract
181
178
  - groonga-query-log-format-regression-test-logs
182
- - groonga-query-log-check-performance-regression
179
+ - groonga-query-log-replay
180
+ - groonga-query-log-run-regression-test
181
+ - groonga-query-log-show-running-queries
182
+ - groonga-query-log-verify-server
183
183
  extensions: []
184
184
  extra_rdoc_files: []
185
185
  files:
@@ -314,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
314
314
  - !ruby/object:Gem::Version
315
315
  version: '0'
316
316
  requirements: []
317
- rubygems_version: 3.1.2
317
+ rubygems_version: 3.2.0.pre1
318
318
  signing_key:
319
319
  specification_version: 4
320
320
  summary: Groonga-query-log is a collection of library and tools to process [Groonga](http://groonga.org/)'s
@@ -322,49 +322,49 @@ summary: Groonga-query-log is a collection of library and tools to process [Groo
322
322
  as a library. You can analyze your Groonga's queries and test with your Groonga's
323
323
  query log by using groonga-query-log as a tool.
324
324
  test_files:
325
- - test/helper.rb
326
- - test/test-filter-rewriter.rb
327
- - test/test-parser.rb
325
+ - test/command/test-analyzer.rb
326
+ - test/command/test-check-performance-regression.rb
327
+ - test/command/test-extract.rb
328
+ - test/command/test-format-regression-test-logs.rb
329
+ - test/command/test-run-regression-test.rb
330
+ - test/fixtures/check-performance-regression/cache.log
331
+ - test/fixtures/check-performance-regression/different_operations1.log
332
+ - test/fixtures/check-performance-regression/different_operations2.log
333
+ - test/fixtures/check-performance-regression/nquery.log
334
+ - test/fixtures/check-performance-regression/nquery2.log
335
+ - test/fixtures/check-performance-regression/query1.log
336
+ - test/fixtures/check-performance-regression/query2.log
337
+ - test/fixtures/multi.expected
328
338
  - test/fixtures/n_entries.expected
329
- - test/fixtures/order/elapsed.expected
339
+ - test/fixtures/no-report-summary.expected
330
340
  - test/fixtures/order/-elapsed.expected
331
341
  - test/fixtures/order/-start-time.expected
342
+ - test/fixtures/order/elapsed.expected
332
343
  - test/fixtures/order/start-time.expected
333
- - test/fixtures/target-tables.expected
334
344
  - test/fixtures/other-query.log
335
- - test/fixtures/check-performance-regression/different_operations2.log
336
- - test/fixtures/check-performance-regression/query2.log
337
- - test/fixtures/check-performance-regression/nquery.log
338
- - test/fixtures/check-performance-regression/query1.log
339
- - test/fixtures/check-performance-regression/different_operations1.log
340
- - test/fixtures/check-performance-regression/nquery2.log
341
- - test/fixtures/check-performance-regression/cache.log
342
- - test/fixtures/regression-test-logs/url-format.log
345
+ - test/fixtures/query.log
346
+ - test/fixtures/regression-test-logs/command-format.log
343
347
  - test/fixtures/regression-test-logs/error.log
344
348
  - test/fixtures/regression-test-logs/slow.log
345
- - test/fixtures/regression-test-logs/command-format.log
349
+ - test/fixtures/regression-test-logs/url-format.log
350
+ - test/fixtures/reporter/console.expected
351
+ - test/fixtures/reporter/html.expected
352
+ - test/fixtures/reporter/json-stream.expected
353
+ - test/fixtures/reporter/json.expected
354
+ - test/fixtures/run-regression-test/data/data.grn
346
355
  - test/fixtures/run-regression-test/indexes/indexes.grn
356
+ - test/fixtures/run-regression-test/mail-notifier/failure.log
357
+ - test/fixtures/run-regression-test/mail-notifier/success.log
358
+ - test/fixtures/run-regression-test/query-logs/query.log
347
359
  - test/fixtures/run-regression-test/results/query.log.log
348
- - test/fixtures/run-regression-test/data/data.grn
349
360
  - test/fixtures/run-regression-test/schema/schema.grn
350
- - test/fixtures/run-regression-test/query-logs/query.log
351
- - test/fixtures/run-regression-test/mail-notifier/success.log
352
- - test/fixtures/run-regression-test/mail-notifier/failure.log
353
361
  - test/fixtures/target-commands.expected
354
- - test/fixtures/query.log
355
- - test/fixtures/multi.expected
356
- - test/fixtures/no-report-summary.expected
357
- - test/fixtures/reporter/html.expected
358
- - test/fixtures/reporter/json.expected
359
- - test/fixtures/reporter/console.expected
360
- - test/fixtures/reporter/json-stream.expected
362
+ - test/fixtures/target-tables.expected
363
+ - test/helper.rb
361
364
  - test/run-test.rb
362
- - test/test-performance-verifier.rb
365
+ - test/test-filter-rewriter.rb
363
366
  - test/test-incompatibility-detector.rb
367
+ - test/test-parser.rb
368
+ - test/test-performance-verifier.rb
364
369
  - test/test-replayer.rb
365
- - test/command/test-run-regression-test.rb
366
- - test/command/test-format-regression-test-logs.rb
367
- - test/command/test-extract.rb
368
- - test/command/test-analyzer.rb
369
- - test/command/test-check-performance-regression.rb
370
370
  - test/test-response-comparer.rb