groonga-query-log 1.5.8 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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