grntest 1.2.2 → 1.2.3
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/doc/text/news.md +24 -0
- data/lib/grntest/execution-context.rb +4 -0
- data/lib/grntest/executors/base-executor.rb +83 -46
- data/lib/grntest/executors/http-executor.rb +3 -4
- data/lib/grntest/executors/standard-io-executor.rb +1 -1
- data/lib/grntest/reporters/inplace-reporter.rb +3 -0
- data/lib/grntest/reporters/mark-reporter.rb +6 -0
- data/lib/grntest/reporters/stream-reporter.rb +4 -0
- data/lib/grntest/template-evaluator.rb +26 -0
- data/lib/grntest/test-runner.rb +111 -64
- data/lib/grntest/variable-expander.rb +35 -0
- data/lib/grntest/version.rb +1 -1
- data/lib/grntest/worker.rb +3 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cd44715730b214bd92dd2c6d77b236f3a9d97c4
|
4
|
+
data.tar.gz: 63dc616b531e5613bf7dfe1ec6c2e6fe04d8fe9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 898f8874c0efb5dc04159ac2224a81688dc88a0c5c081933a5bfb2d8675273f4ff63e27f53dcaa275d68c9b7f6ef16aae226669cd7db49f12ab58ef49a092fe0
|
7
|
+
data.tar.gz: 955f66d7a2a2333275ded2148ae49d64853a5fe66ccfe55ea3d98ae580ad97116e673b240e062d0d86ba30a9ccafbd062df8ab2cd6f06d152a563eb5030b16e3
|
data/doc/text/news.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 1.2.3: 2016-07-19
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* Disabled read time on GDB mode.
|
8
|
+
|
9
|
+
* Supported object literal based response introduced by command version 3.
|
10
|
+
|
11
|
+
* Suppressed omissions from report.
|
12
|
+
|
13
|
+
* Added `generate-series` directive.
|
14
|
+
|
15
|
+
* Added `read-timeout` directive.
|
16
|
+
|
17
|
+
* Added `long-read-timeout` directive.
|
18
|
+
|
19
|
+
* Removed `long-timeout` directive. Use `long-read-timeout` directive instead.
|
20
|
+
|
21
|
+
* Supported `#{base_directory}` expansion in variable value.
|
22
|
+
|
23
|
+
* Supported variable expansion in environment variable value.
|
24
|
+
|
25
|
+
* Supported normalizing plugin path in `object_list`.
|
26
|
+
|
3
27
|
## 1.2.2: 2016-05-18
|
4
28
|
|
5
29
|
### Improvements
|
@@ -22,6 +22,8 @@ module Grntest
|
|
22
22
|
attr_accessor :output_type
|
23
23
|
attr_accessor :on_error
|
24
24
|
attr_accessor :abort_tag
|
25
|
+
attr_accessor :timeout
|
26
|
+
attr_accessor :default_timeout
|
25
27
|
attr_writer :collect_query_log
|
26
28
|
attr_writer :debug
|
27
29
|
def initialize
|
@@ -37,6 +39,8 @@ module Grntest
|
|
37
39
|
@query_log = nil
|
38
40
|
@on_error = :default
|
39
41
|
@abort_tag = nil
|
42
|
+
@timeout = 0
|
43
|
+
@default_timeout = 0
|
40
44
|
@omitted = false
|
41
45
|
@collect_query_log = false
|
42
46
|
@debug = false
|
@@ -24,6 +24,8 @@ require "grntest/log-parser"
|
|
24
24
|
require "grntest/query-log-parser"
|
25
25
|
require "grntest/execution-context"
|
26
26
|
require "grntest/response-parser"
|
27
|
+
require "grntest/template-evaluator"
|
28
|
+
require "grntest/variable-expander"
|
27
29
|
|
28
30
|
module Grntest
|
29
31
|
module Executors
|
@@ -39,8 +41,8 @@ module Grntest
|
|
39
41
|
@pending_load_command = nil
|
40
42
|
@current_command_name = nil
|
41
43
|
@output_type = nil
|
42
|
-
@
|
43
|
-
@
|
44
|
+
@read_timeout = default_read_timeout
|
45
|
+
@long_read_timeout = default_long_read_timeout
|
44
46
|
@context = context
|
45
47
|
@custom_important_log_levels = []
|
46
48
|
end
|
@@ -75,7 +77,9 @@ module Grntest
|
|
75
77
|
|
76
78
|
def shutdown(pid)
|
77
79
|
begin
|
78
|
-
|
80
|
+
Timeout.timeout(@context.timeout) do
|
81
|
+
send_command(command("shutdown"))
|
82
|
+
end
|
79
83
|
rescue
|
80
84
|
return false
|
81
85
|
end
|
@@ -122,7 +126,7 @@ module Grntest
|
|
122
126
|
parser.on_comment do |comment|
|
123
127
|
if /\A@/ =~ comment
|
124
128
|
directive_content = $POSTMATCH
|
125
|
-
execute_directive("\##{comment}", directive_content)
|
129
|
+
execute_directive(parser, "\##{comment}", directive_content)
|
126
130
|
end
|
127
131
|
end
|
128
132
|
parser
|
@@ -157,14 +161,8 @@ module Grntest
|
|
157
161
|
end
|
158
162
|
|
159
163
|
def expand_variables(string)
|
160
|
-
|
161
|
-
|
162
|
-
when "db_path"
|
163
|
-
@context.db_path.to_s
|
164
|
-
else
|
165
|
-
matched
|
166
|
-
end
|
167
|
-
end
|
164
|
+
expander = VariableExpander.new(@context)
|
165
|
+
expander.expand(string)
|
168
166
|
end
|
169
167
|
|
170
168
|
def execute_directive_copy_path(line, content, options)
|
@@ -184,17 +182,18 @@ module Grntest
|
|
184
182
|
FileUtils.cp_r(source.to_s, destination.to_s)
|
185
183
|
end
|
186
184
|
|
187
|
-
def
|
188
|
-
|
185
|
+
def timeout_value(key, line, input, default)
|
186
|
+
new_value = nil
|
187
|
+
|
189
188
|
invalid_value_p = false
|
190
|
-
case
|
189
|
+
case input
|
191
190
|
when "default"
|
192
|
-
|
191
|
+
new_value = default
|
193
192
|
when nil
|
194
193
|
invalid_value_p = true
|
195
194
|
else
|
196
195
|
begin
|
197
|
-
|
196
|
+
new_value = Float(input)
|
198
197
|
rescue ArgumentError
|
199
198
|
invalid_value_p = true
|
200
199
|
end
|
@@ -202,32 +201,39 @@ module Grntest
|
|
202
201
|
|
203
202
|
if invalid_value_p
|
204
203
|
log_input(line)
|
205
|
-
message = "
|
206
|
-
log_error("#|e| [
|
204
|
+
message = "#{key} must be number or 'default': <#{input}>"
|
205
|
+
log_error("#|e| [#{key}] #{message}")
|
206
|
+
nil
|
207
|
+
else
|
208
|
+
new_value
|
207
209
|
end
|
208
210
|
end
|
209
211
|
|
210
|
-
def
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
else
|
219
|
-
begin
|
220
|
-
@long_timeout = Float(long_timeout)
|
221
|
-
rescue ArgumentError
|
222
|
-
invalid_value_p = true
|
223
|
-
end
|
224
|
-
end
|
212
|
+
def execute_directive_timeout(line, content, options)
|
213
|
+
timeout, = options
|
214
|
+
new_value = timeout_value("timeout",
|
215
|
+
line,
|
216
|
+
timeout,
|
217
|
+
@context.default_timeout)
|
218
|
+
@context.timeout = new_value unless new_value.nil?
|
219
|
+
end
|
225
220
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
221
|
+
def execute_directive_read_timeout(line, content, options)
|
222
|
+
timeout, = options
|
223
|
+
new_value = timeout_value("read-timeout",
|
224
|
+
line,
|
225
|
+
timeout,
|
226
|
+
default_read_timeout)
|
227
|
+
@read_timeout = new_value unless new_value.nil?
|
228
|
+
end
|
229
|
+
|
230
|
+
def execute_directive_long_read_timeout(line, content, options)
|
231
|
+
timeout, = options
|
232
|
+
new_value = timeout_value("long-read-timeout",
|
233
|
+
line,
|
234
|
+
timeout,
|
235
|
+
default_long_read_timeout)
|
236
|
+
@long_read_timeout = new_value unless new_value.nil?
|
231
237
|
end
|
232
238
|
|
233
239
|
def execute_directive_on_error(line, content, options)
|
@@ -286,7 +292,27 @@ module Grntest
|
|
286
292
|
@context.collect_query_log = (options[0] == "true")
|
287
293
|
end
|
288
294
|
|
289
|
-
def
|
295
|
+
def execute_directive_generate_series(parser, line, content, options)
|
296
|
+
start, stop, table, template, = options
|
297
|
+
evaluator = TemplateEvaluator.new(template)
|
298
|
+
parser << "load --table #{table}\n"
|
299
|
+
parser << "["
|
300
|
+
first_record = true
|
301
|
+
Integer(start).step(Integer(stop)) do |i|
|
302
|
+
record = ""
|
303
|
+
if first_record
|
304
|
+
first_record = false
|
305
|
+
else
|
306
|
+
record << ","
|
307
|
+
end
|
308
|
+
record << "\n"
|
309
|
+
record << evaluator.evaluate(i).to_json
|
310
|
+
parser << record
|
311
|
+
end
|
312
|
+
parser << "\n]\n"
|
313
|
+
end
|
314
|
+
|
315
|
+
def execute_directive(parser, line, content)
|
290
316
|
command, *options = Shellwords.split(content)
|
291
317
|
case command
|
292
318
|
when "disable-logging"
|
@@ -301,8 +327,10 @@ module Grntest
|
|
301
327
|
execute_directive_copy_path(line, content, options)
|
302
328
|
when "timeout"
|
303
329
|
execute_directive_timeout(line, content, options)
|
304
|
-
when "
|
305
|
-
|
330
|
+
when "read-timeout"
|
331
|
+
execute_directive_read_timeout(line, content, options)
|
332
|
+
when "long-read-timeout"
|
333
|
+
execute_directive_long_read_timeout(line, content, options)
|
306
334
|
when "on-error"
|
307
335
|
execute_directive_on_error(line, content, options)
|
308
336
|
when "omit"
|
@@ -315,6 +343,8 @@ module Grntest
|
|
315
343
|
execute_directive_sleep(line, content, options)
|
316
344
|
when "collect-query-log"
|
317
345
|
execute_directive_collect_query_log(line, content, options)
|
346
|
+
when "generate-series"
|
347
|
+
execute_directive_generate_series(parser, line, content, options)
|
318
348
|
else
|
319
349
|
log_input(line)
|
320
350
|
log_error("#|e| unknown directive: <#{command}>")
|
@@ -360,8 +390,15 @@ module Grntest
|
|
360
390
|
def execute_command(command)
|
361
391
|
extract_command_info(command)
|
362
392
|
log_input("#{command.original_source}\n")
|
393
|
+
timeout = @context.timeout
|
394
|
+
response = nil
|
363
395
|
begin
|
364
|
-
|
396
|
+
Timeout.timeout(timeout) do
|
397
|
+
response = send_command(command)
|
398
|
+
end
|
399
|
+
rescue Timeout::Error
|
400
|
+
log_error("# error: timeout (#{timeout}s)")
|
401
|
+
@context.error
|
365
402
|
rescue => error
|
366
403
|
log_error("# error: #{error.class}: #{error.message}")
|
367
404
|
error.backtrace.each do |line|
|
@@ -399,7 +436,7 @@ module Grntest
|
|
399
436
|
|
400
437
|
def read_all_readable_content(output, options={})
|
401
438
|
content = ""
|
402
|
-
first_timeout = options[:first_timeout] || @
|
439
|
+
first_timeout = options[:first_timeout] || @read_timeout
|
403
440
|
timeout = first_timeout
|
404
441
|
while IO.select([output], [], [], timeout)
|
405
442
|
break if output.eof?
|
@@ -499,11 +536,11 @@ module Grntest
|
|
499
536
|
output
|
500
537
|
end
|
501
538
|
|
502
|
-
def
|
539
|
+
def default_read_timeout
|
503
540
|
3
|
504
541
|
end
|
505
542
|
|
506
|
-
def
|
543
|
+
def default_long_read_timeout
|
507
544
|
180
|
508
545
|
end
|
509
546
|
end
|
@@ -22,11 +22,10 @@ require "grntest/executors/base-executor"
|
|
22
22
|
module Grntest
|
23
23
|
module Executors
|
24
24
|
class HTTPExecutor < BaseExecutor
|
25
|
-
def initialize(host, port, context
|
25
|
+
def initialize(host, port, context)
|
26
26
|
super(context)
|
27
27
|
@host = host
|
28
28
|
@port = port
|
29
|
-
@read_timeout = options[:read_timeout] || 3
|
30
29
|
end
|
31
30
|
|
32
31
|
def send_command(command)
|
@@ -75,7 +74,7 @@ module Grntest
|
|
75
74
|
request.content_type = "application/json; charset=UTF-8"
|
76
75
|
request.body = body
|
77
76
|
response = Net::HTTP.start(@host, @port) do |http|
|
78
|
-
http.read_timeout = @
|
77
|
+
http.read_timeout = @context.timeout
|
79
78
|
http.request(request)
|
80
79
|
end
|
81
80
|
normalize_response_data(command, response.body)
|
@@ -84,7 +83,7 @@ module Grntest
|
|
84
83
|
def send_normal_command(command)
|
85
84
|
url = "http://#{@host}:#{@port}#{command.to_uri_format}"
|
86
85
|
begin
|
87
|
-
open(url, :read_timeout => @
|
86
|
+
open(url, :read_timeout => @context.timeout) do |response|
|
88
87
|
normalize_response_data(command, response.read)
|
89
88
|
end
|
90
89
|
rescue SystemCallError
|
@@ -73,6 +73,12 @@ module Grntest
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
def on_test_omission_suppressed(worker, result)
|
77
|
+
synchronize do
|
78
|
+
report_test_result_mark("O", result)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
76
82
|
def on_test_no_check(worker, result)
|
77
83
|
synchronize do
|
78
84
|
report_test_result_mark("N", result)
|
@@ -63,6 +63,10 @@ module Grntest
|
|
63
63
|
report_actual(result)
|
64
64
|
end
|
65
65
|
|
66
|
+
def on_test_omission_suppressed(worker, result)
|
67
|
+
report_test_result(result, worker.status)
|
68
|
+
end
|
69
|
+
|
66
70
|
def on_test_no_check(worker, result)
|
67
71
|
report_test_result(result, worker.status)
|
68
72
|
report_actual(result)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module Grntest
|
17
|
+
class TemplateEvaluator
|
18
|
+
def initialize(template)
|
19
|
+
@template = template
|
20
|
+
end
|
21
|
+
|
22
|
+
def evaluate(i)
|
23
|
+
eval(@template)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/grntest/test-runner.rb
CHANGED
@@ -136,16 +136,12 @@ module Grntest
|
|
136
136
|
context.groonga_suggest_create_dataset =
|
137
137
|
@tester.groonga_suggest_create_dataset
|
138
138
|
context.output_type = @tester.output_type
|
139
|
+
context.timeout = @tester.timeout
|
140
|
+
context.timeout = 0 if @tester.gdb
|
141
|
+
context.default_timeout = context.timeout
|
139
142
|
context.debug = @tester.debug?
|
140
143
|
run_groonga(context) do |executor|
|
141
|
-
|
142
|
-
Timeout.timeout(@tester.timeout) do
|
143
|
-
executor.execute(test_script_path)
|
144
|
-
end
|
145
|
-
rescue Timeout::Error
|
146
|
-
message = "# error: timeout (#{@tester.timeout}s)"
|
147
|
-
context.result << [:error, message, {}]
|
148
|
-
end
|
144
|
+
executor.execute(test_script_path)
|
149
145
|
end
|
150
146
|
check_memory_leak(context)
|
151
147
|
result.omitted = context.omitted?
|
@@ -198,7 +194,7 @@ module Grntest
|
|
198
194
|
groonga_input = input_write
|
199
195
|
groonga_output = output_read
|
200
196
|
|
201
|
-
env = extract_custom_env
|
197
|
+
env = extract_custom_env(context)
|
202
198
|
spawn_options = {}
|
203
199
|
command_line = groonga_command_line(context, spawn_options)
|
204
200
|
if Platform.windows?
|
@@ -338,21 +334,16 @@ call chdir("#{context.temporary_directory_path}")
|
|
338
334
|
port = 50041 + @worker.id
|
339
335
|
pid_file_path = context.temporary_directory_path + "groonga.pid"
|
340
336
|
|
341
|
-
env = extract_custom_env
|
337
|
+
env = extract_custom_env(context)
|
342
338
|
spawn_options = {}
|
343
339
|
command_line = groonga_http_command(host, port, pid_file_path, context,
|
344
340
|
spawn_options)
|
345
341
|
pid = nil
|
346
|
-
options = {
|
347
|
-
:read_timeout => @tester.timeout,
|
348
|
-
}
|
349
|
-
if @tester.gdb
|
350
|
-
options[:read_timeout] = 60 * 10
|
351
|
-
end
|
352
342
|
begin
|
353
343
|
pid = Process.spawn(env, *command_line, spawn_options)
|
344
|
+
executor = nil
|
354
345
|
begin
|
355
|
-
executor = Executors::HTTPExecutor.new(host, port, context
|
346
|
+
executor = Executors::HTTPExecutor.new(host, port, context)
|
356
347
|
begin
|
357
348
|
executor.ensure_groonga_ready
|
358
349
|
rescue
|
@@ -381,6 +372,11 @@ call chdir("#{context.temporary_directory_path}")
|
|
381
372
|
def ensure_process_finished(pid)
|
382
373
|
return if pid.nil?
|
383
374
|
|
375
|
+
if @tester.gdb
|
376
|
+
Process.waitpid(pid)
|
377
|
+
return
|
378
|
+
end
|
379
|
+
|
384
380
|
[:TERM, :KILL].each do |signal|
|
385
381
|
n_retries = 0
|
386
382
|
loop do
|
@@ -392,6 +388,7 @@ call chdir("#{context.temporary_directory_path}")
|
|
392
388
|
Process.kill(signal, pid)
|
393
389
|
rescue SystemCallError
|
394
390
|
$stderr.puts("#{signal} -> #{pid}: #{$!.class}: #{$!}")
|
391
|
+
return
|
395
392
|
end
|
396
393
|
sleep(0.1)
|
397
394
|
end
|
@@ -463,7 +460,7 @@ events {
|
|
463
460
|
}
|
464
461
|
GLOBAL
|
465
462
|
|
466
|
-
env = ENV.to_hash.merge(extract_custom_env)
|
463
|
+
env = ENV.to_hash.merge(extract_custom_env(context))
|
467
464
|
env.each do |key, value|
|
468
465
|
next unless key.start_with?("GRN_")
|
469
466
|
config_file.puts(<<-ENV)
|
@@ -549,35 +546,7 @@ http {
|
|
549
546
|
type = options[:type]
|
550
547
|
case type
|
551
548
|
when "json", "msgpack"
|
552
|
-
|
553
|
-
values = nil
|
554
|
-
content = content.chomp
|
555
|
-
if type == "json" and /\A([^(]+\()(.+)(\);)\z/ =~ content
|
556
|
-
jsonp = true
|
557
|
-
jsonp_start = $1
|
558
|
-
content = $2
|
559
|
-
jsonp_end = $3
|
560
|
-
else
|
561
|
-
jsonp = false
|
562
|
-
end
|
563
|
-
begin
|
564
|
-
status, *values = ResponseParser.parse(content, type)
|
565
|
-
rescue ParseError
|
566
|
-
return $!.message
|
567
|
-
end
|
568
|
-
normalized_status = normalize_status(status)
|
569
|
-
normalized_values = normalize_values(values)
|
570
|
-
normalized_output_content = [normalized_status, *normalized_values]
|
571
|
-
normalized_output = JSON.generate(normalized_output_content)
|
572
|
-
if normalized_output.bytesize > @max_n_columns
|
573
|
-
normalized_output = JSON.pretty_generate(normalized_output_content)
|
574
|
-
end
|
575
|
-
normalized_raw_content = normalize_raw_content(normalized_output)
|
576
|
-
if jsonp
|
577
|
-
"#{jsonp_start}#{normalized_raw_content.chomp}#{jsonp_end}\n"
|
578
|
-
else
|
579
|
-
normalized_raw_content
|
580
|
-
end
|
549
|
+
normalize_output_structured(type, content, options)
|
581
550
|
when "xml"
|
582
551
|
normalized_xml = normalize_output_xml(content, options)
|
583
552
|
normalize_raw_content(normalized_xml)
|
@@ -588,35 +557,108 @@ http {
|
|
588
557
|
end
|
589
558
|
end
|
590
559
|
|
560
|
+
def normalize_output_structured(type, content, options)
|
561
|
+
response = nil
|
562
|
+
content = content.chomp
|
563
|
+
if type == "json" and /\A([^(]+\()(.+)(\);)\z/ =~ content
|
564
|
+
jsonp = true
|
565
|
+
jsonp_start = $1
|
566
|
+
content = $2
|
567
|
+
jsonp_end = $3
|
568
|
+
else
|
569
|
+
jsonp = false
|
570
|
+
end
|
571
|
+
begin
|
572
|
+
response = ResponseParser.parse(content, type)
|
573
|
+
rescue ParseError
|
574
|
+
return $!.message
|
575
|
+
end
|
576
|
+
|
577
|
+
if response.is_a?(Hash)
|
578
|
+
normalized_response =
|
579
|
+
response.merge({
|
580
|
+
"header" => normalize_header(response["header"]),
|
581
|
+
"body" => normalize_body(response["body"]),
|
582
|
+
})
|
583
|
+
else
|
584
|
+
header, *values = response
|
585
|
+
normalized_header = normalize_header(header)
|
586
|
+
normalized_values = values.collect do |value|
|
587
|
+
normalize_body(value)
|
588
|
+
end
|
589
|
+
normalized_response = [normalized_header, *normalized_values]
|
590
|
+
end
|
591
|
+
normalized_output = JSON.generate(normalized_response)
|
592
|
+
if normalized_output.bytesize > @max_n_columns
|
593
|
+
normalized_output = JSON.pretty_generate(normalized_response)
|
594
|
+
end
|
595
|
+
normalized_raw_content = normalize_raw_content(normalized_output)
|
596
|
+
|
597
|
+
if jsonp
|
598
|
+
"#{jsonp_start}#{normalized_raw_content.chomp}#{jsonp_end}\n"
|
599
|
+
else
|
600
|
+
normalized_raw_content
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
591
604
|
def normalize_output_xml(content, options)
|
592
605
|
content.sub(/^<RESULT .+?>/) do |result|
|
593
606
|
result.gsub(/( (?:UP|ELAPSED))="\d+\.\d+(?:e[+-]?\d+)?"/, '\1="0.0"')
|
594
607
|
end
|
595
608
|
end
|
596
609
|
|
597
|
-
def
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
610
|
+
def normalize_header(header)
|
611
|
+
if header.is_a?(Hash)
|
612
|
+
return_code = header["return_code"]
|
613
|
+
if return_code.zero?
|
614
|
+
header.merge({
|
615
|
+
"start_time" => 0.0,
|
616
|
+
"elapsed_time" => 0.0,
|
617
|
+
})
|
618
|
+
else
|
619
|
+
error = header["error"]
|
620
|
+
message = error["message"]
|
621
|
+
message = normalize_path_in_error_message(message)
|
622
|
+
header.merge({
|
623
|
+
"start_time" => 0.0,
|
624
|
+
"elapsed_time" => 0.0,
|
625
|
+
"error" => error.merge({"message" => message})
|
626
|
+
})
|
627
|
+
end
|
602
628
|
else
|
603
|
-
|
604
|
-
_ =
|
605
|
-
|
606
|
-
|
629
|
+
return_code, started_time, elapsed_time, *rest = header
|
630
|
+
_ = started_time = elapsed_time # for suppress warnings
|
631
|
+
if return_code.zero?
|
632
|
+
[0, 0.0, 0.0]
|
633
|
+
else
|
634
|
+
message, backtrace = rest
|
635
|
+
_ = backtrace # for suppress warnings
|
636
|
+
message = normalize_path_in_error_message(message)
|
637
|
+
[[return_code, 0.0, 0.0], message]
|
638
|
+
end
|
607
639
|
end
|
608
640
|
end
|
609
641
|
|
610
|
-
def
|
611
|
-
|
612
|
-
|
613
|
-
|
642
|
+
def normalize_body(body)
|
643
|
+
case body
|
644
|
+
when Hash
|
645
|
+
if body["exception"]
|
646
|
+
exception = Marshal.load(Marshal.dump(body["exception"]))
|
614
647
|
message = exception["message"]
|
615
648
|
exception["message"] = normalize_path_in_error_message(message)
|
616
|
-
|
649
|
+
body.merge("exception" => exception)
|
617
650
|
else
|
618
|
-
value
|
651
|
+
body.each do |key, value|
|
652
|
+
case value
|
653
|
+
when Hash
|
654
|
+
path = value["path"]
|
655
|
+
value["path"] = normalize_plugin_path(path) if path
|
656
|
+
end
|
657
|
+
end
|
658
|
+
body
|
619
659
|
end
|
660
|
+
else
|
661
|
+
body
|
620
662
|
end
|
621
663
|
end
|
622
664
|
|
@@ -636,19 +678,24 @@ http {
|
|
636
678
|
end
|
637
679
|
end
|
638
680
|
|
681
|
+
def normalize_plugin_path(path)
|
682
|
+
path.gsub(/\.libs\//, "").gsub(/\.dll\z/, ".so")
|
683
|
+
end
|
684
|
+
|
639
685
|
def test_script_path
|
640
686
|
@worker.test_script_path
|
641
687
|
end
|
642
688
|
|
643
|
-
def extract_custom_env
|
689
|
+
def extract_custom_env(context)
|
644
690
|
return {} unless test_script_path.exist?
|
645
691
|
|
646
692
|
env = {}
|
647
693
|
test_script_path.open("r:ascii-8bit") do |script_file|
|
694
|
+
expander = VariableExpander.new(context)
|
648
695
|
script_file.each_line do |line|
|
649
696
|
case line
|
650
697
|
when /\A\#\$([a-zA-Z_\d]+)=(.*)/
|
651
|
-
env[$1] = $2.strip
|
698
|
+
env[$1] = expander.expand($2.strip)
|
652
699
|
end
|
653
700
|
end
|
654
701
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module Grntest
|
17
|
+
class VariableExpander
|
18
|
+
def initialize(context)
|
19
|
+
@context = context
|
20
|
+
end
|
21
|
+
|
22
|
+
def expand(string)
|
23
|
+
string.gsub(/\#{(.+?)}/) do |matched|
|
24
|
+
case $1
|
25
|
+
when "db_path"
|
26
|
+
@context.db_path.to_s
|
27
|
+
when "base_directory"
|
28
|
+
@context.base_directory.to_s
|
29
|
+
else
|
30
|
+
matched
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/grntest/version.rb
CHANGED
data/lib/grntest/worker.rb
CHANGED
@@ -146,7 +146,9 @@ module Grntest
|
|
146
146
|
def on_test_omission(result)
|
147
147
|
@status = "omitted"
|
148
148
|
@result.on_test_omission
|
149
|
-
|
149
|
+
if @tester.suppress_omit_log?
|
150
|
+
@reporter.on_test_omission_suppressed(self, result)
|
151
|
+
else
|
150
152
|
@reporter.on_test_omission(self, result)
|
151
153
|
end
|
152
154
|
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.2.
|
4
|
+
version: 1.2.3
|
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: 2016-
|
12
|
+
date: 2016-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -188,9 +188,11 @@ files:
|
|
188
188
|
- lib/grntest/reporters/mark-reporter.rb
|
189
189
|
- lib/grntest/reporters/stream-reporter.rb
|
190
190
|
- lib/grntest/response-parser.rb
|
191
|
+
- lib/grntest/template-evaluator.rb
|
191
192
|
- lib/grntest/test-runner.rb
|
192
193
|
- lib/grntest/test-suites-runner.rb
|
193
194
|
- lib/grntest/tester.rb
|
195
|
+
- lib/grntest/variable-expander.rb
|
194
196
|
- lib/grntest/version.rb
|
195
197
|
- lib/grntest/worker.rb
|
196
198
|
- test/executors/test-base-executor.rb
|