grntest 1.3.5 → 1.3.6

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: c74faa2722964ab0d9f2f78a7fea2e3e1275d28e0639c10f9bfaef7597d3e73f
4
- data.tar.gz: b0462e4805ec8c3c04b81a3330be27ad8af703a1dbcdb95db08ef28e954f6a95
3
+ metadata.gz: 4a454a43f204e50c72ce0470713ee3dbcdd7c3b0f210f8fc37eb8c858dc5794f
4
+ data.tar.gz: 5f5a5dfdab82eefc86318b7a09e66c97979cb68fed0c498369117c0c98666a6a
5
5
  SHA512:
6
- metadata.gz: 3d10fa6674ffa249bc0555fad4b460d48505b4cc8abdc640956ebd403b3784ac1bf80f52a5bd39e5956167904bd0eb4624e8b0dc3f3fe1cfc9c923bad88d9ad5
7
- data.tar.gz: 60133bca88d982074f54cc3426298d692fb34c3432e800c1f1427c4de2af2ca158a28415456b670d81502f1fc87fc26cb5b7e11c09a1df4770dec34b44602ca1
6
+ metadata.gz: 707db0020a332057b06ce4822edb4fd1cac2226e88f23a642fd071e2bda2457747f54fd22b16198b629badaee7e865753d60d0c713f35c40b1b718f1248a8866
7
+ data.tar.gz: 88653342fa0366047c2ecf080cc6d4bbab2f7c43186c9df4173fbeeb7814bf5a9143442ed1df7e4144674a2b0c977b109d0cfa2cf7927c20f489a74fc234370a
data/.yardopts CHANGED
@@ -1,5 +1,5 @@
1
1
  --output-dir doc/reference/en
2
2
  --markup markdown
3
- --markup-provider redcarpet
3
+ --markup-provider kramdown
4
4
  -
5
5
  doc/text/*
data/doc/text/news.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # News
2
2
 
3
+ ## 1.3.6: 2020-03-26
4
+
5
+ ### Improvements
6
+
7
+ * standard-io: Added support for stream output
8
+
9
+ * Added `require-testee` directive.
10
+
11
+ * Added `require-interface` directive.
12
+
13
+ * Added support for Apache Arrow.
14
+
15
+ * Added `require-apache-arrow` directive.
16
+
17
+ * http: Added support for debug log by `GRNTEST_HTTP_DEBUG`
18
+ environment variable.
19
+
20
+ * Added `--use-http-chunked` option.
21
+
22
+ * Stopped counting test failures on retry.
23
+
3
24
  ## 1.3.5: 2020-03-02
4
25
 
5
26
  ### Improvements
data/grntest.gemspec CHANGED
@@ -53,9 +53,9 @@ Gem::Specification.new do |spec|
53
53
  spec.add_runtime_dependency("rexml")
54
54
 
55
55
  spec.add_development_dependency("bundler")
56
+ spec.add_development_dependency("kramdown")
57
+ spec.add_development_dependency("packnga")
56
58
  spec.add_development_dependency("rake")
57
59
  spec.add_development_dependency("test-unit", ">= 3.0.0")
58
60
  spec.add_development_dependency("test-unit-rr")
59
- spec.add_development_dependency("packnga")
60
- spec.add_development_dependency("redcarpet")
61
61
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2019 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -20,8 +20,11 @@ module Grntest
20
20
  attr_accessor :plugins_directory
21
21
  attr_accessor :plugin_extension
22
22
  attr_accessor :groonga_suggest_create_dataset
23
+ attr_accessor :testee
24
+ attr_accessor :interface
23
25
  attr_accessor :result
24
26
  attr_writer :use_http_post
27
+ attr_writer :use_http_chunked
25
28
  attr_accessor :input_type
26
29
  attr_accessor :output_type
27
30
  attr_accessor :on_error
@@ -42,9 +45,12 @@ module Grntest
42
45
  @plugins_directory = nil
43
46
  @plugin_extension = guess_plugin_extension
44
47
  @groonga_suggest_create_dataset = "groonga-suggest-create-dataset"
48
+ @testee = "groonga"
49
+ @interface = "stdio"
45
50
  @n_nested = 0
46
51
  @result = []
47
52
  @use_http_post = false
53
+ @use_http_chunked = false
48
54
  @input_type = "json"
49
55
  @output_type = "json"
50
56
  @log = nil
@@ -70,6 +76,10 @@ module Grntest
70
76
  @use_http_post
71
77
  end
72
78
 
79
+ def use_http_chunked?
80
+ @use_http_chunked
81
+ end
82
+
73
83
  def suppress_backtrace?
74
84
  @suppress_backtrace or debug?
75
85
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2019 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -327,6 +327,26 @@ module Grntest
327
327
  end
328
328
  end
329
329
 
330
+ def execute_directive_require_testee(parser, line, content, options)
331
+ testee, = options
332
+ unless @context.testee == testee
333
+ omit("require testee: #{testee}")
334
+ end
335
+ end
336
+
337
+ def execute_directive_require_interface(parser, line, content, options)
338
+ interface, = options
339
+ unless @context.interface == interface
340
+ omit("require interface: #{interface}")
341
+ end
342
+ end
343
+
344
+ def execute_directive_require_apache_arrow(parser, line, content, options)
345
+ unless defined?(::Arrow)
346
+ omit("require Apache Arrow")
347
+ end
348
+ end
349
+
330
350
  def execute_directive(parser, line, content)
331
351
  command, *options = Shellwords.split(content)
332
352
  case command
@@ -364,6 +384,12 @@ module Grntest
364
384
  execute_directive_eval(parser, line, content, options)
365
385
  when "require-input-type"
366
386
  execute_directive_require_input_type(parser, line, content, options)
387
+ when "require-testee"
388
+ execute_directive_require_testee(parser, line, content, options)
389
+ when "require-interface"
390
+ execute_directive_require_interface(parser, line, content, options)
391
+ when "require-apache-arrow"
392
+ execute_directive_require_apache_arrow(parser, line, content, options)
367
393
  else
368
394
  log_input(line)
369
395
  log_error("#|e| unknown directive: <#{command}>")
@@ -402,11 +428,12 @@ module Grntest
402
428
  if @current_command.name == "dump"
403
429
  @output_type = "groonga-command"
404
430
  else
405
- @output_type = @current_command[:output_type] || @context.output_type
431
+ @output_type = @current_command[:output_type]
406
432
  end
407
433
  end
408
434
 
409
435
  def execute_command(command)
436
+ command[:output_type] ||= @context.output_type
410
437
  extract_command_info(command)
411
438
  log_input("#{command.original_source}\n")
412
439
  timeout = @context.timeout
@@ -423,6 +450,7 @@ module Grntest
423
450
  error.backtrace.each do |line|
424
451
  log_error("# error: #{line}")
425
452
  end
453
+ log_error(read_all_log)
426
454
  @context.error
427
455
  else
428
456
  type = @output_type
@@ -491,7 +519,13 @@ module Grntest
491
519
  read_content = output.readpartial(request_bytes)
492
520
  debug_output(read_content)
493
521
  content << read_content
494
- timeout = 0 if read_content.bytesize < request_bytes
522
+ if read_content.bytesize < request_bytes
523
+ if options[:stream_output]
524
+ timeout = 0.1
525
+ else
526
+ timeout = 0
527
+ end
528
+ end
495
529
  end
496
530
  content
497
531
  end
@@ -21,6 +21,29 @@ require "grntest/executors/base-executor"
21
21
  module Grntest
22
22
  module Executors
23
23
  class HTTPExecutor < BaseExecutor
24
+ class SlowBodyStream
25
+ def initialize(body)
26
+ @body = body || ""
27
+ @offset = 0
28
+ end
29
+
30
+ def read(length=nil, output="")
31
+ if @offset >= @body.bytesize
32
+ nil
33
+ else
34
+ if length.nil?
35
+ output.replace(@body.byteslice(@offset..-1))
36
+ @offset = @body.bytesize
37
+ output
38
+ else
39
+ output.replace(@body.byteslice(@offset, 1))
40
+ @offset += 1
41
+ output
42
+ end
43
+ end
44
+ end
45
+ end
46
+
24
47
  def initialize(host, port, context)
25
48
  super(context)
26
49
  @host = host
@@ -52,6 +75,9 @@ module Grntest
52
75
  end
53
76
 
54
77
  private
78
+ DEBUG = (ENV["GRNTEST_HTTP_DEBUG"] == "yes")
79
+ LOAD_DEBUG = (DEBUG or (ENV["GRNTEST_HTTP_LOAD_DEBUG"] == "yes"))
80
+
55
81
  MAX_URI_SIZE = 4096
56
82
  def send_load_command(command)
57
83
  lines = command.original_source.lines
@@ -84,14 +110,20 @@ module Grntest
84
110
  body = values
85
111
  end
86
112
  end
87
- request = Net::HTTP::Post.new(command.to_uri_format)
113
+ path = command.to_uri_format
114
+ url = "http://#{@host}:#{@port}#{path}"
115
+ request = Net::HTTP::Post.new(path)
88
116
  request.content_type = content_type
89
- request.body = body
90
- response = Net::HTTP.start(@host, @port) do |http|
91
- http.read_timeout = read_timeout
92
- http.request(request)
117
+ set_request_body(request, body)
118
+ run_http_request(url) do
119
+ http = Net::HTTP.new(@host, @port)
120
+ http.set_debug_output($stderr) if LOAD_DEBUG
121
+ response = http.start do
122
+ http.read_timeout = read_timeout
123
+ http.request(request)
124
+ end
125
+ normalize_response_data(command, response.body)
93
126
  end
94
- normalize_response_data(command, response.body)
95
127
  end
96
128
 
97
129
  def send_normal_command(command)
@@ -100,20 +132,40 @@ module Grntest
100
132
  path, query = path_with_query.split("?", 2)
101
133
  request = Net::HTTP::Post.new(path)
102
134
  request.content_type = "application/x-www-form-urlencoded"
103
- request.body = query
135
+ set_request_body(request, query)
104
136
  else
105
137
  request = Net::HTTP::Get.new(path_with_query)
106
138
  end
107
139
  url = "http://#{@host}:#{@port}#{path_with_query}"
108
- begin
109
- response = Net::HTTP.start(@host, @port) do |http|
140
+ run_http_request(url) do
141
+ http = Net::HTTP.new(@host, @port)
142
+ http.set_debug_output($stderr) if DEBUG
143
+ response = http.start do
110
144
  http.read_timeout = read_timeout
111
145
  http.request(request)
112
146
  end
113
147
  normalize_response_data(command, response.body)
148
+ end
149
+ end
150
+
151
+ def set_request_body(request, body)
152
+ if @context.use_http_chunked?
153
+ request["Transfer-Encoding"] = "chunked"
154
+ request.body_stream = SlowBodyStream.new(body)
155
+ else
156
+ request.body = body
157
+ end
158
+ end
159
+
160
+ def run_http_request(url)
161
+ begin
162
+ yield
114
163
  rescue SystemCallError
115
164
  message = "failed to read response from Groonga: <#{url}>: #{$!}"
116
165
  raise Error.new(message)
166
+ rescue EOFError
167
+ message = "unexpected EOF response from Groonga: <#{url}>: #{$!}"
168
+ raise Error.new(message)
117
169
  rescue Net::HTTPBadResponse
118
170
  message = "bad response from Groonga: <#{url}>: "
119
171
  message << "#{$!.class}: #{$!.message}"
@@ -126,11 +178,10 @@ module Grntest
126
178
  end
127
179
 
128
180
  def normalize_response_data(command, raw_response_data)
129
- if raw_response_data.empty? or command.output_type == :none
130
- raw_response_data
131
- else
132
- "#{raw_response_data}\n"
133
- end
181
+ return raw_response_data if raw_response_data.empty?
182
+ return raw_response_data if command.output_type == :none
183
+ return raw_response_data if command.output_type == :"apache-arrow"
184
+ "#{raw_response_data}\n"
134
185
  end
135
186
 
136
187
  def read_timeout
@@ -57,6 +57,9 @@ module Grntest
57
57
  if may_slow_command?(command)
58
58
  options[:first_timeout] = @long_read_timeout
59
59
  end
60
+ if may_stream_output_command?(command)
61
+ options[:stream_output] = true
62
+ end
60
63
  read_all_readable_content(@output, options)
61
64
  end
62
65
 
@@ -70,6 +73,14 @@ module Grntest
70
73
  def may_slow_command?(command)
71
74
  MAY_SLOW_COMMANDS.include?(command.name)
72
75
  end
76
+
77
+ MAY_STREAM_OUTPUT_COMMANDS = [
78
+ "dump",
79
+ "logical_range_filter",
80
+ ]
81
+ def may_stream_output_command?(command)
82
+ MAY_STREAM_OUTPUT_COMMANDS.include?(command.name)
83
+ end
73
84
  end
74
85
  end
75
86
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2019 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -137,7 +137,10 @@ module Grntest
137
137
  context.plugins_directory = @tester.plugins_directory.expand_path
138
138
  context.groonga_suggest_create_dataset =
139
139
  @tester.groonga_suggest_create_dataset
140
+ context.testee = @tester.testee
141
+ context.interface = @tester.interface
140
142
  context.use_http_post = @tester.use_http_post?
143
+ context.use_http_chunked = @tester.use_http_chunked?
141
144
  context.input_type = @tester.input_type
142
145
  context.output_type = @tester.output_type
143
146
  context.timeout = @tester.timeout
@@ -187,9 +190,9 @@ module Grntest
187
190
  catch do |tag|
188
191
  context.abort_tag = tag
189
192
  case @tester.interface
190
- when :stdio
193
+ when "stdio"
191
194
  run_groonga_stdio(context, &block)
192
- when :http
195
+ when "http"
193
196
  run_groonga_http(context, &block)
194
197
  end
195
198
  end
@@ -580,6 +583,8 @@ http {
580
583
  case type
581
584
  when "json", "msgpack"
582
585
  normalize_output_structured(type, content, options)
586
+ when "apache-arrow"
587
+ normalize_apache_arrow_content(content, options)
583
588
  when "xml"
584
589
  normalized_xml = normalize_output_xml(content, options)
585
590
  normalize_raw_content(normalized_xml)
@@ -634,6 +639,54 @@ http {
634
639
  end
635
640
  end
636
641
 
642
+ def normalize_apache_arrow_content(content, options)
643
+ normalized = ""
644
+ buffer = Arrow::Buffer.new(content)
645
+ Arrow::BufferInputStream.open(buffer) do |input|
646
+ while input.tell < content.bytesize
647
+ reader = Arrow::RecordBatchStreamReader.new(input)
648
+ schema = reader.schema
649
+ record_batches = reader.to_a
650
+ table = Arrow::Table.new(schema, record_batches)
651
+ unless normalized.empty?
652
+ normalized << "=" * 40
653
+ normalized << "\n"
654
+ end
655
+ if schema.respond_to?(:to_string_metadata)
656
+ normalized << schema.to_string_metadata(true)
657
+ else
658
+ normalized << schema.to_s
659
+ end
660
+ normalized << "\n"
661
+ if apache_arrow_metadata?(schema)
662
+ normalized_records = table.each_record.collect do |record|
663
+ normalized_record = []
664
+ record.to_h.each do |name, value|
665
+ case name
666
+ when "start_time", "elapsed_time"
667
+ value = 0
668
+ end
669
+ normalized_record << value
670
+ end
671
+ normalized_record
672
+ end
673
+ noramlized_table = Arrow::Table.new(schema, normalized_records)
674
+ normalized << noramlized_table.to_s
675
+ else
676
+ normalized << table.to_s
677
+ end
678
+ end
679
+ end
680
+ normalized
681
+ end
682
+
683
+ def apache_arrow_metadata?(schema)
684
+ # TODO: Use schema.metadata with gobject-introspection 3.4.2 and
685
+ # Red Arrow 0.17.0.
686
+ schema.fields.collect(&:name) ==
687
+ ["return_code", "start_time", "elapsed_time"]
688
+ end
689
+
637
690
  def normalize_output_xml(content, options)
638
691
  content.sub(/^<RESULT .+?>/) do |result|
639
692
  result.gsub(/( (?:UP|ELAPSED))="\d+\.\d+(?:e[+-]?\d+)?"/, '\1="0.0"')
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2019 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@ module Grntest
56
56
  tester.groonga_suggest_create_dataset = normalize_command(command)
57
57
  end
58
58
 
59
- available_interfaces = [:stdio, :http]
59
+ available_interfaces = ["stdio", "http"]
60
60
  available_interface_labels = available_interfaces.join(", ")
61
61
  parser.on("--interface=INTERFACE", available_interfaces,
62
62
  "Use INTERFACE for communicating Groonga",
@@ -71,6 +71,12 @@ module Grntest
71
71
  tester.use_http_post = boolean
72
72
  end
73
73
 
74
+ parser.on("--[no-]use-http-chunked",
75
+ "Use chunked Transfer-Encoding to send body by HTTP",
76
+ "(#{tester.use_http_chunked?})") do |boolean|
77
+ tester.use_http_chunked = boolean
78
+ end
79
+
74
80
  available_input_types = ["json", "apache-arrow"]
75
81
  available_input_type_labels = available_input_types.join(", ")
76
82
  parser.on("--input-type=TYPE", available_input_types,
@@ -80,7 +86,7 @@ module Grntest
80
86
  tester.input_type = type
81
87
  end
82
88
 
83
- available_output_types = ["json", "msgpack"]
89
+ available_output_types = ["json", "msgpack", "apache-arrow"]
84
90
  available_output_type_labels = available_output_types.join(", ")
85
91
  parser.on("--output-type=TYPE", available_output_types,
86
92
  "Use TYPE as the output type",
@@ -97,7 +103,7 @@ module Grntest
97
103
  "(#{tester.testee})") do |testee|
98
104
  tester.testee = testee
99
105
  if tester.testee == "groonga-httpd"
100
- tester.interface = :http
106
+ tester.interface = "http"
101
107
  end
102
108
  end
103
109
 
@@ -294,6 +300,7 @@ module Grntest
294
300
  attr_accessor :groonga, :groonga_httpd, :groonga_suggest_create_dataset
295
301
  attr_accessor :interface
296
302
  attr_writer :use_http_post
303
+ attr_writer :use_http_chunked
297
304
  attr_accessor :input_type
298
305
  attr_accessor :output_type
299
306
  attr_accessor :testee
@@ -321,8 +328,9 @@ module Grntest
321
328
  unless command_exist?(@groonga_suggest_create_dataset)
322
329
  @groonga_suggest_create_dataset = nil
323
330
  end
324
- @interface = :stdio
331
+ @interface = "stdio"
325
332
  @use_http_post = false
333
+ @use_http_chunked = false
326
334
  @input_type = "json"
327
335
  @output_type = "json"
328
336
  @testee = "groonga"
@@ -374,6 +382,10 @@ module Grntest
374
382
  @use_http_post
375
383
  end
376
384
 
385
+ def use_http_chunked?
386
+ @use_http_chunked
387
+ end
388
+
377
389
  def keep_database?
378
390
  @keep_database
379
391
  end
@@ -14,5 +14,5 @@
14
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
16
  module Grntest
17
- VERSION = "1.3.5"
17
+ VERSION = "1.3.6"
18
18
  end
@@ -47,6 +47,10 @@ module Grntest
47
47
  @failed_tests << name
48
48
  end
49
49
 
50
+ def cancel_test_failure(name)
51
+ @failed_tests.delete(name)
52
+ end
53
+
50
54
  def on_test_leak(name)
51
55
  @n_leaked_tests += 1
52
56
  end
@@ -179,6 +183,7 @@ module Grntest
179
183
  return true if runner.run
180
184
 
181
185
  if n < @tester.n_retries and not interruptted?
186
+ @result.cancel_test_failure(test_name)
182
187
  @test_suites_result.n_total_tests += 1
183
188
  next
184
189
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grntest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-03-02 00:00:00.000000000 Z
12
+ date: 2020-03-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: diff-lcs
@@ -138,7 +138,7 @@ dependencies:
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  - !ruby/object:Gem::Dependency
141
- name: rake
141
+ name: kramdown
142
142
  requirement: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - ">="
@@ -152,21 +152,21 @@ dependencies:
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
154
  - !ruby/object:Gem::Dependency
155
- name: test-unit
155
+ name: packnga
156
156
  requirement: !ruby/object:Gem::Requirement
157
157
  requirements:
158
158
  - - ">="
159
159
  - !ruby/object:Gem::Version
160
- version: 3.0.0
160
+ version: '0'
161
161
  type: :development
162
162
  prerelease: false
163
163
  version_requirements: !ruby/object:Gem::Requirement
164
164
  requirements:
165
165
  - - ">="
166
166
  - !ruby/object:Gem::Version
167
- version: 3.0.0
167
+ version: '0'
168
168
  - !ruby/object:Gem::Dependency
169
- name: test-unit-rr
169
+ name: rake
170
170
  requirement: !ruby/object:Gem::Requirement
171
171
  requirements:
172
172
  - - ">="
@@ -180,21 +180,21 @@ dependencies:
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
182
  - !ruby/object:Gem::Dependency
183
- name: packnga
183
+ name: test-unit
184
184
  requirement: !ruby/object:Gem::Requirement
185
185
  requirements:
186
186
  - - ">="
187
187
  - !ruby/object:Gem::Version
188
- version: '0'
188
+ version: 3.0.0
189
189
  type: :development
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
192
192
  requirements:
193
193
  - - ">="
194
194
  - !ruby/object:Gem::Version
195
- version: '0'
195
+ version: 3.0.0
196
196
  - !ruby/object:Gem::Dependency
197
- name: redcarpet
197
+ name: test-unit-rr
198
198
  requirement: !ruby/object:Gem::Requirement
199
199
  requirements:
200
200
  - - ">="