grntest 1.6.6 → 1.6.8

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: cb9c21dbf97a69dcd226668ff67f8443bf8ab3e57559137c78180ec07c85a147
4
- data.tar.gz: 5aa1f037756aa689fff0e5d665fe747ed65d9b2a9f0953015feca997b460a300
3
+ metadata.gz: f4c390d442cedfaff26e03d35e62f35c2958146f7bea7a8a2e6257004fc38338
4
+ data.tar.gz: 24bbae078beddc9704797ee722e34480d1724fa0f9a494007f1967fb7e0199d3
5
5
  SHA512:
6
- metadata.gz: eb052fcb4fd03ca1b757cb4fe96f341e9214efd522f8269463267f1be16a6556f1a489e4c1fca6c94934eceff00cdd03002f32e83e6595d4ca4ae941b61ca6d2
7
- data.tar.gz: 838ca099c5ea3db31f6754f4b78ec6c5d76de23fe1fd184a5579b0e4eeba399d32c779e4057dc7a6571aa6e011bcbf538b30b25ba2c50191cf278c5495430d12
6
+ metadata.gz: ef8e9f5d58cde904e3673cbe778849f2ff902bf21739d6a361e4121a775faeec1ce4bd1bb0a8f3420f64c6ebcbd379db10253aa99e9a0cdcee33950e5d896fd7
7
+ data.tar.gz: 33bd84602a4c5715e8cffdbcf72ef1efb2320881fe206dba457f229a457864592b7dc8544efaeadb3bf42cd614786fbe158217cfbeedf53079618c2bffecd43a
data/doc/text/news.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # News
2
2
 
3
+ ## 1.6.8: 2024-02-05
4
+
5
+ ### Fixes
6
+
7
+ * reporter: benchmark-json: Fixed a bug that invalid JSON is
8
+ generated.
9
+
10
+ ## 1.6.7: 2024-02-05
11
+
12
+ ### Improvements
13
+
14
+ * Added benchmark mode. It uses Google Benchmark compatible JSON
15
+ output.
16
+
3
17
  ## 1.6.6: 2023-10-24
4
18
 
5
19
  ### Improvements
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 Sutou Kouhei <kou@clear-code.com>
4
2
  #
5
3
  # This program is free software: you can redistribute it and/or modify
6
4
  # it under the terms of the GNU General Public License as published by
@@ -17,16 +15,26 @@
17
15
 
18
16
  module Grntest
19
17
  class BaseResult
20
- attr_accessor :elapsed_time
18
+ attr_accessor :cpu_elapsed_time
19
+ attr_accessor :real_elapsed_time
21
20
  def initialize
22
- @elapsed_time = 0
21
+ @cpu_elapsed_time = 0
22
+ @real_elapsed_time = 0
23
23
  end
24
24
 
25
25
  def measure
26
- start_time = Time.now
26
+ cpu_start_time = Process.times
27
+ real_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
27
28
  yield
28
29
  ensure
29
- @elapsed_time = Time.now - start_time
30
+ cpu_finish_time = Process.times
31
+ real_finish_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
32
+ @cpu_elapsed_time =
33
+ (cpu_finish_time.utime - cpu_start_time.utime) +
34
+ (cpu_finish_time.stime - cpu_start_time.stime) +
35
+ (cpu_finish_time.cutime - cpu_start_time.cutime) +
36
+ (cpu_finish_time.cstime - cpu_start_time.cstime)
37
+ @real_elapsed_time = real_finish_time - real_start_time
30
38
  end
31
39
  end
32
40
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2021 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -39,6 +39,7 @@ module Grntest
39
39
  attr_writer :collect_query_log
40
40
  attr_writer :debug
41
41
  attr_accessor :platform
42
+ attr_accessor :benchmarks
42
43
  def initialize
43
44
  @logging = true
44
45
  @base_directory = Pathname(".")
@@ -70,6 +71,7 @@ module Grntest
70
71
  @collect_query_log = false
71
72
  @debug = false
72
73
  @platform = guess_platform
74
+ @benchmarks = []
73
75
  end
74
76
 
75
77
  def logging?
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -48,6 +48,8 @@ module Grntest
48
48
  @raw_status_response = nil
49
49
  @features = nil
50
50
  @substitutions = {}
51
+ @noop_benchmark_result = BenchmarkResult.new("noop", 1, 1)
52
+ @benchmark_result = @noop_benchmark_result
51
53
  end
52
54
 
53
55
  def execute(script_path)
@@ -520,6 +522,18 @@ module Grntest
520
522
  @substitutions.delete(pattern)
521
523
  end
522
524
 
525
+ def execute_directive_start_benchmark(line, content, options)
526
+ _, n_items, n_iterations, name = content.split(" ", 4)
527
+ n_items = Integer(n_items, 10)
528
+ n_iterations = Integer(n_iterations, 10)
529
+ @benchmark_result = BenchmarkResult.new(name, n_items, n_iterations)
530
+ @context.benchmarks << @benchmark_result
531
+ end
532
+
533
+ def execute_directive_finish_benchmark(line, content, options)
534
+ @benchmark_result = @noop_benchmark_result
535
+ end
536
+
523
537
  def execute_directive(parser, line, content)
524
538
  command, *options = Shellwords.split(content)
525
539
  case command
@@ -579,6 +593,10 @@ module Grntest
579
593
  execute_directive_add_substitution(line, content, options)
580
594
  when "remove-substitution"
581
595
  execute_directive_remove_substitution(line, content, options)
596
+ when "start-benchmark"
597
+ execute_directive_start_benchmark(line, content, options)
598
+ when "finish-benchmark"
599
+ execute_directive_finish_benchmark(line, content, options)
582
600
  else
583
601
  log_input(line)
584
602
  log_error("#|e| unknown directive: <#{command}>")
@@ -628,8 +646,12 @@ module Grntest
628
646
  timeout = @context.timeout
629
647
  response = nil
630
648
  begin
631
- Timeout.timeout(timeout) do
632
- response = send_command(command)
649
+ @benchmark_result.measure do
650
+ @benchmark_result.n_iterations.times do
651
+ Timeout.timeout(timeout) do
652
+ response = send_command(command)
653
+ end
654
+ end
633
655
  end
634
656
  rescue Timeout::Error
635
657
  log_error("# error: timeout (#{timeout}s)")
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -45,7 +45,7 @@ module Grntest
45
45
  puts(statistics_header)
46
46
  puts(colorize(statistics(result), result))
47
47
  pass_ratio = result.pass_ratio
48
- elapsed_time = result.elapsed_time
48
+ elapsed_time = result.real_elapsed_time
49
49
  summary = "%.4g%% passed in %.4fs." % [pass_ratio, elapsed_time]
50
50
  puts(colorize(summary, result))
51
51
  end
@@ -78,10 +78,10 @@ module Grntest
78
78
  end
79
79
 
80
80
  def throughput(result)
81
- if result.elapsed_time.zero?
81
+ if result.real_elapsed_time.zero?
82
82
  tests_per_second = 0
83
83
  else
84
- tests_per_second = result.n_tests / result.elapsed_time
84
+ tests_per_second = result.n_tests / result.real_elapsed_time
85
85
  end
86
86
  tests_per_second
87
87
  end
@@ -160,7 +160,7 @@ module Grntest
160
160
  end
161
161
 
162
162
  def test_result_message(result, label)
163
- elapsed_time = result.elapsed_time
163
+ elapsed_time = result.real_elapsed_time
164
164
  formatted_elapsed_time = "%.4fs" % elapsed_time
165
165
  formatted_elapsed_time = colorize(formatted_elapsed_time,
166
166
  elapsed_time_status(elapsed_time))
@@ -0,0 +1,128 @@
1
+ # Copyright (C) 2024 Sutou Kouhei <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
+ require "json"
17
+ require "time"
18
+
19
+ require "grntest/reporters/base-reporter"
20
+
21
+ module Grntest
22
+ module Reporters
23
+ class BenchmarkJSONReporter < BaseReporter
24
+ def initialize(tester)
25
+ super
26
+ end
27
+
28
+ def on_start(result)
29
+ puts(<<-JSON)
30
+ {
31
+ "context": {
32
+ "date": #{Time.now.iso8601.to_json},
33
+ "host_name": #{Socket.gethostname.to_json},
34
+ "executable": #{@tester.testee.to_json},
35
+ "num_cpus": #{Etc.nprocessors},
36
+ JSON
37
+ cpu_cycles_per_second = detect_cpu_cycles_per_second
38
+ if cpu_cycles_per_second
39
+ puts(<<-JSON)
40
+ "mhz_per_cpu": #{cpu_cycles_per_second / 1_000_000.0},
41
+ JSON
42
+ end
43
+ puts(<<-JSON)
44
+ "caches": []
45
+ },
46
+ "benchmarks": [
47
+ JSON
48
+ end
49
+
50
+ def on_worker_start(worker)
51
+ end
52
+
53
+ def on_suite_start(worker)
54
+ end
55
+
56
+ def on_test_start(worker)
57
+ end
58
+
59
+ def on_test_success(worker, result)
60
+ end
61
+
62
+ def on_test_failure(worker, result)
63
+ output, @output = @output, $stderr
64
+ begin
65
+ report_failure(result)
66
+ ensure
67
+ @output = output
68
+ end
69
+ end
70
+
71
+ def on_test_leak(worker, result)
72
+ end
73
+
74
+ def on_test_omission(worker, result)
75
+ end
76
+
77
+ def on_test_no_check(worker, result)
78
+ end
79
+
80
+ def on_test_finish(worker, result)
81
+ return if result.benchmarks.empty?
82
+ benchmarks = result.benchmarks.collect do |benchmark|
83
+ <<-JSON.chomp
84
+ {
85
+ "name": #{result.test_name.to_json},
86
+ "run_name": #{benchmark.name.to_json},
87
+ "run_type": "iteration",
88
+ "iterations": #{benchmark.n_iterations},
89
+ "real_time": #{benchmark.real_elapsed_time},
90
+ "cpu_time": #{benchmark.cpu_elapsed_time},
91
+ "time_unit": "s",
92
+ "items_per_second": #{benchmark.items_per_second}
93
+ }
94
+ JSON
95
+ end
96
+ puts(benchmarks.join(",\n"))
97
+ end
98
+
99
+ def on_suite_finish(worker)
100
+ end
101
+
102
+ def on_worker_finish(worker)
103
+ end
104
+
105
+ def on_finish(result)
106
+ puts(<<-JSON)
107
+ ]
108
+ }
109
+ JSON
110
+ end
111
+
112
+ private
113
+ def detect_cpu_cycles_per_second
114
+ if File.exist?("/proc/cpuinfo")
115
+ File.open("/proc/cpuinfo") do |cpuinfo|
116
+ cpuinfo.each_line do |line|
117
+ case line
118
+ when /\Acpu MHz\s+: ([\d.]+)/
119
+ return Float($1)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ nil
125
+ end
126
+ end
127
+ end
128
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -13,27 +13,30 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
- require "grntest/reporters/mark-reporter"
16
+ require "grntest/reporters/benchmark-json-reporter"
17
17
  require "grntest/reporters/buffered-mark-reporter"
18
- require "grntest/reporters/stream-reporter"
19
18
  require "grntest/reporters/inplace-reporter"
19
+ require "grntest/reporters/mark-reporter"
20
20
  require "grntest/reporters/progress-reporter"
21
+ require "grntest/reporters/stream-reporter"
21
22
 
22
23
  module Grntest
23
24
  module Reporters
24
25
  class << self
25
26
  def create_reporter(tester)
26
27
  case tester.reporter
27
- when :mark
28
- MarkReporter.new(tester)
28
+ when :"benchmark-json"
29
+ BenchmarkJSONReporter.new(tester)
29
30
  when :"buffered-mark"
30
31
  BufferedMarkReporter.new(tester)
31
- when :stream
32
- StreamReporter.new(tester)
33
32
  when :inplace
34
33
  InplaceReporter.new(tester)
34
+ when :mark
35
+ MarkReporter.new(tester)
35
36
  when :progress
36
37
  ProgressReporter.new(tester)
38
+ when :stream
39
+ StreamReporter.new(tester)
37
40
  end
38
41
  end
39
42
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2022 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -28,10 +28,27 @@ require "grntest/executors"
28
28
  require "grntest/base-result"
29
29
 
30
30
  module Grntest
31
+ class BenchmarkResult < BaseResult
32
+ attr_reader :name
33
+ attr_reader :n_items
34
+ attr_reader :n_iterations
35
+ def initialize(name, n_items, n_iterations)
36
+ super()
37
+ @name = name
38
+ @n_items = n_items
39
+ @n_iterations = n_iterations
40
+ end
41
+
42
+ def items_per_second
43
+ @n_items / @real_elapsed_time
44
+ end
45
+ end
46
+
31
47
  class TestResult < BaseResult
32
48
  attr_accessor :worker_id, :test_name
33
49
  attr_accessor :expected, :actual, :n_leaked_objects
34
50
  attr_writer :omitted
51
+ attr_accessor :benchmarks
35
52
  def initialize(worker)
36
53
  super()
37
54
  @worker_id = worker.id
@@ -40,6 +57,7 @@ module Grntest
40
57
  @expected = nil
41
58
  @n_leaked_objects = 0
42
59
  @omitted = false
60
+ @benchmarks = []
43
61
  end
44
62
 
45
63
  def status
@@ -159,6 +177,7 @@ module Grntest
159
177
  check_memory_leak(context)
160
178
  result.omitted = context.omitted?
161
179
  result.actual = context.result
180
+ result.benchmarks = context.benchmarks
162
181
  context.close_logs
163
182
  end
164
183
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -161,6 +161,7 @@ module Grntest
161
161
  :stream,
162
162
  :inplace,
163
163
  :progress,
164
+ :"benchmark-json",
164
165
  ]
165
166
  available_reporter_labels = available_reporters.join(", ")
166
167
  parser.on("--reporter=REPORTER", available_reporters,
@@ -299,6 +300,14 @@ module Grntest
299
300
  srand(seed)
300
301
  end
301
302
 
303
+ parser.on("--[no-]benchmark",
304
+ "Set options for benchmark") do |benchmark|
305
+ if benchmark
306
+ tester.n_workers = 1
307
+ tester.reporter = :"benchmark-json"
308
+ end
309
+ end
310
+
302
311
  parser.on("--version",
303
312
  "Show version and exit") do
304
313
  puts(VERSION)
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2024 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
@@ -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.6.6"
17
+ VERSION = "1.6.8"
18
18
  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.6.6
4
+ version: 1.6.8
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: 2023-10-24 00:00:00.000000000 Z
12
+ date: 2024-02-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: diff-lcs
@@ -249,6 +249,7 @@ files:
249
249
  - lib/grntest/platform.rb
250
250
  - lib/grntest/reporters.rb
251
251
  - lib/grntest/reporters/base-reporter.rb
252
+ - lib/grntest/reporters/benchmark-json-reporter.rb
252
253
  - lib/grntest/reporters/buffered-mark-reporter.rb
253
254
  - lib/grntest/reporters/inplace-reporter.rb
254
255
  - lib/grntest/reporters/mark-reporter.rb
@@ -284,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
285
  - !ruby/object:Gem::Version
285
286
  version: '0'
286
287
  requirements: []
287
- rubygems_version: 3.5.0.dev
288
+ rubygems_version: 3.5.1
288
289
  signing_key:
289
290
  specification_version: 4
290
291
  summary: Grntest is a testing framework for Groonga. You can write a test for Groonga