polyrun 2.1.2 → 2.2.0
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/CHANGELOG.md +17 -1
- data/CONTRIBUTING.md +23 -0
- data/docs/SETUP_PROFILE.md +29 -0
- data/ext/polyrun_coverage_merge/coverage_merge.c +492 -0
- data/ext/polyrun_coverage_merge/extconf.rb +3 -0
- data/lib/polyrun/benchmark/profile.rb +191 -0
- data/lib/polyrun/benchmark/report.rb +87 -0
- data/lib/polyrun/cli/benchmark_commands.rb +66 -0
- data/lib/polyrun/cli/coverage_commands.rb +4 -4
- data/lib/polyrun/cli/coverage_merge_io.rb +30 -4
- data/lib/polyrun/cli/failure_commands.rb +10 -3
- data/lib/polyrun/cli/help.rb +14 -7
- data/lib/polyrun/cli/report_commands.rb +25 -11
- data/lib/polyrun/cli/run_queue_command.rb +5 -32
- data/lib/polyrun/cli/run_shards_parallel_children.rb +7 -0
- data/lib/polyrun/cli/run_shards_parallel_wait.rb +3 -0
- data/lib/polyrun/cli/run_shards_plan_options.rb +1 -1
- data/lib/polyrun/cli/run_shards_run.rb +1 -0
- data/lib/polyrun/cli/run_shards_worker_interrupt.rb +9 -1
- data/lib/polyrun/cli/spec_quality_commands.rb +16 -7
- data/lib/polyrun/cli.rb +8 -1
- data/lib/polyrun/coverage/example_diff.rb +127 -60
- data/lib/polyrun/coverage/example_diff_snapshot.rb +44 -0
- data/lib/polyrun/coverage/example_diff_track_filter.rb +51 -0
- data/lib/polyrun/coverage/file_stats_report.rb +36 -0
- data/lib/polyrun/coverage/formatter.rb +22 -1
- data/lib/polyrun/coverage/merge/formatters.rb +11 -3
- data/lib/polyrun/coverage/merge_merge_two.rb +112 -63
- data/lib/polyrun/coverage/merge_native.rb +37 -0
- data/lib/polyrun/coverage/reporting.rb +1 -1
- data/lib/polyrun/export/csv.rb +25 -0
- data/lib/polyrun/export/markdown.rb +47 -0
- data/lib/polyrun/hooks/shell_runner.rb +33 -0
- data/lib/polyrun/hooks.rb +4 -7
- data/lib/polyrun/partition/paths_build.rb +8 -0
- data/lib/polyrun/queue/worker_loop.rb +39 -0
- data/lib/polyrun/reporting/failure_merge.rb +48 -12
- data/lib/polyrun/reporting/junit.rb +8 -7
- data/lib/polyrun/reporting/junit_report.rb +87 -0
- data/lib/polyrun/rspec/example_debug.rb +158 -0
- data/lib/polyrun/rspec/example_debug_instrumentation.rb +73 -0
- data/lib/polyrun/rspec/sharded_formatter_compat.rb +57 -0
- data/lib/polyrun/rspec.rb +34 -0
- data/lib/polyrun/spec_quality/profile.rb +24 -12
- data/lib/polyrun/spec_quality/report.rb +93 -0
- data/lib/polyrun/spec_quality.rb +19 -11
- data/lib/polyrun/timing/summary.rb +55 -5
- data/lib/polyrun/version.rb +1 -1
- data/lib/polyrun/worker_output.rb +159 -0
- data/lib/polyrun/worker_output_forwarders.rb +90 -0
- data/polyrun.gemspec +8 -1
- data/sig/polyrun/rspec.rbs +10 -0
- data/sig/polyrun/worker_output.rbs +11 -0
- metadata +65 -2
|
@@ -1,26 +1,76 @@
|
|
|
1
1
|
require_relative "stats"
|
|
2
|
+
require_relative "../export/csv"
|
|
3
|
+
require_relative "../export/markdown"
|
|
2
4
|
|
|
3
5
|
module Polyrun
|
|
4
6
|
module Timing
|
|
5
7
|
# Human-readable slow-file list from merged timing JSON (per-file cost).
|
|
6
8
|
module Summary
|
|
9
|
+
CSV_HEADERS = %w[rank path last_seconds min max mean p95 runs failures timeouts].freeze
|
|
10
|
+
MARKDOWN_HEADERS = %w[rank path seconds].freeze
|
|
11
|
+
|
|
7
12
|
module_function
|
|
8
13
|
|
|
14
|
+
def ranked_entries(merged, top: 30)
|
|
15
|
+
return [] if merged.nil? || merged.empty?
|
|
16
|
+
|
|
17
|
+
merged.map { |path, entry| [path, Stats.normalize_entry(entry)] }
|
|
18
|
+
.sort_by { |(_, entry)| -Stats.binpack_weight(entry) }
|
|
19
|
+
.first(Integer(top))
|
|
20
|
+
end
|
|
21
|
+
|
|
9
22
|
# +merged+ is path (String) => seconds (Float) or stats Hash, as produced by +Timing::Merge.merge_files+.
|
|
10
23
|
def format_slow_files(merged, top: 30, title: "Polyrun slowest files (by wall time, seconds)")
|
|
11
24
|
return "#{title}\n (no data)\n" if merged.nil? || merged.empty?
|
|
12
25
|
|
|
13
|
-
pairs = merged.map { |path, sec| [path, Stats.binpack_weight(sec)] }
|
|
14
|
-
.sort_by { |(_, sec)| -sec.to_f }.first(Integer(top))
|
|
15
26
|
lines = [title, ""]
|
|
16
|
-
|
|
17
|
-
lines << format(" %2d. %s %.4f",
|
|
27
|
+
ranked_entries(merged, top: top).each_with_index do |(path, entry), index|
|
|
28
|
+
lines << format(" %2d. %s %.4f", index + 1, path, Stats.binpack_weight(entry).to_f)
|
|
18
29
|
end
|
|
19
30
|
lines.join("\n") + "\n"
|
|
20
31
|
end
|
|
21
32
|
|
|
33
|
+
def format_csv(merged, top: 30)
|
|
34
|
+
rows = ranked_entries(merged, top: top).each_with_index.map do |(path, entry), index|
|
|
35
|
+
[
|
|
36
|
+
index + 1,
|
|
37
|
+
path,
|
|
38
|
+
entry["last_seconds"],
|
|
39
|
+
entry["min"],
|
|
40
|
+
entry["max"],
|
|
41
|
+
entry["mean"],
|
|
42
|
+
entry["p95"],
|
|
43
|
+
entry["runs"],
|
|
44
|
+
entry["failures"],
|
|
45
|
+
entry["timeouts"]
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
Export::Csv.generate(CSV_HEADERS, rows)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def format_markdown(merged, top: 30, title: "Polyrun slowest files")
|
|
52
|
+
rows = ranked_entries(merged, top: top).each_with_index.map do |(path, entry), index|
|
|
53
|
+
[index + 1, path, format("%.4f", Stats.binpack_weight(entry).to_f)]
|
|
54
|
+
end
|
|
55
|
+
Export::Markdown.document(
|
|
56
|
+
title,
|
|
57
|
+
[{heading: "Slow files", headers: MARKDOWN_HEADERS, rows: rows}]
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def render(merged, format: "text", **kwargs)
|
|
62
|
+
case format.to_s.downcase
|
|
63
|
+
when "text", "console", "txt" then format_slow_files(merged, **kwargs)
|
|
64
|
+
when "csv" then format_csv(merged, **kwargs)
|
|
65
|
+
when "markdown", "md" then format_markdown(merged, **kwargs)
|
|
66
|
+
else
|
|
67
|
+
raise Polyrun::Error, "report-timing: unknown format #{format.inspect} (use text, csv, or markdown)"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
22
71
|
def write_file(merged, path, **kwargs)
|
|
23
|
-
|
|
72
|
+
format = kwargs.delete(:format) || "text"
|
|
73
|
+
File.write(path, render(merged, format: format, **kwargs))
|
|
24
74
|
path
|
|
25
75
|
end
|
|
26
76
|
end
|
data/lib/polyrun/version.rb
CHANGED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require_relative "worker_output_forwarders"
|
|
3
|
+
|
|
4
|
+
module Polyrun
|
|
5
|
+
# Routes parallel worker stdout/stderr through per-shard log files with optional prefixed TTY echo.
|
|
6
|
+
#
|
|
7
|
+
# Opt-in: +POLYRUN_WORKER_OUTPUT_ROUTING=1+ (or set +POLYRUN_WORKER_LOG_DIR+).
|
|
8
|
+
# +POLYRUN_WORKER_OUTPUT_ROUTING=0+ keeps inherited stdio (default polyrun behavior).
|
|
9
|
+
# +POLYRUN_WORKER_OUTPUT_PREFIX=0+ writes logs only (no live prefixed echo).
|
|
10
|
+
module WorkerOutput
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def routing_enabled?
|
|
14
|
+
return false if disabled_by_env?
|
|
15
|
+
|
|
16
|
+
truthy?(ENV["POLYRUN_WORKER_OUTPUT_ROUTING"]) || !log_directory.nil?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def log_directory
|
|
20
|
+
value = ENV["POLYRUN_WORKER_LOG_DIR"]
|
|
21
|
+
return nil if value.nil?
|
|
22
|
+
|
|
23
|
+
stripped = value.to_s.strip
|
|
24
|
+
stripped.empty? ? nil : stripped
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def prefix_live?
|
|
28
|
+
return true if ENV["POLYRUN_WORKER_OUTPUT_PREFIX"].nil?
|
|
29
|
+
|
|
30
|
+
truthy?(ENV["POLYRUN_WORKER_OUTPUT_PREFIX"])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def log_path_for(shard)
|
|
34
|
+
File.expand_path("shard-#{shard}.log", log_directory || default_log_directory)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def worker_log_directory_label
|
|
38
|
+
log_directory || default_log_directory
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def prepare_log_dir!
|
|
42
|
+
directory = log_directory || default_log_directory
|
|
43
|
+
FileUtils.mkdir_p(directory)
|
|
44
|
+
Dir.glob(File.join(directory, "shard-*.log")).each { |path| File.delete(path) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def warn_shard_log(shard)
|
|
48
|
+
return unless routing_enabled?
|
|
49
|
+
|
|
50
|
+
Polyrun::Log.warn "polyrun run-shards: shard #{shard} worker log → #{log_path_for(shard)}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def spawn_worker(child_env, cmd, paths, hook_cfg)
|
|
54
|
+
shard = child_env.fetch("POLYRUN_SHARD_INDEX", "?")
|
|
55
|
+
out_read, out_write = IO.pipe
|
|
56
|
+
err_read, err_write = IO.pipe
|
|
57
|
+
|
|
58
|
+
pid =
|
|
59
|
+
if hook_cfg.worker_hooks? && !Polyrun::Hooks.disabled?
|
|
60
|
+
Process.spawn(
|
|
61
|
+
child_env,
|
|
62
|
+
"sh",
|
|
63
|
+
"-c",
|
|
64
|
+
hook_cfg.build_worker_shell_script(cmd, paths),
|
|
65
|
+
out: out_write,
|
|
66
|
+
err: err_write
|
|
67
|
+
)
|
|
68
|
+
else
|
|
69
|
+
Process.spawn(child_env, *cmd, *paths, out: out_write, err: err_write)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
out_write.close
|
|
73
|
+
err_write.close
|
|
74
|
+
|
|
75
|
+
start_forwarders(
|
|
76
|
+
pid: pid,
|
|
77
|
+
shard: shard,
|
|
78
|
+
stdout_io: out_read,
|
|
79
|
+
stderr_io: err_read,
|
|
80
|
+
log_path: log_path_for(shard)
|
|
81
|
+
)
|
|
82
|
+
pid
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def start_forwarders(pid:, shard:, stdout_io:, stderr_io:, log_path:)
|
|
86
|
+
forwarder = WorkerForwarder.new(
|
|
87
|
+
shard: shard,
|
|
88
|
+
pid: pid,
|
|
89
|
+
log_path: log_path,
|
|
90
|
+
prefix_live: prefix_live?
|
|
91
|
+
)
|
|
92
|
+
threads = [
|
|
93
|
+
forwarder_thread(stdout_io, forwarder, :stdout),
|
|
94
|
+
forwarder_thread(stderr_io, forwarder, :stderr)
|
|
95
|
+
]
|
|
96
|
+
registry[pid] = {threads: threads, ios: [stdout_io, stderr_io], forwarder: forwarder}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def finish_worker(pid)
|
|
100
|
+
entry = registry.delete(pid)
|
|
101
|
+
return unless entry
|
|
102
|
+
|
|
103
|
+
drain_forwarders(entry)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def shutdown_all!
|
|
107
|
+
registry.each_value { |entry| drain_forwarders(entry) }
|
|
108
|
+
registry.clear
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def default_log_directory
|
|
112
|
+
"tmp/polyrun/workers"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def disabled_by_env?
|
|
116
|
+
%w[0 false no off].include?(ENV["POLYRUN_WORKER_OUTPUT_ROUTING"].to_s.strip.downcase)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def truthy?(value)
|
|
120
|
+
return false if value.nil?
|
|
121
|
+
|
|
122
|
+
%w[1 true yes on].include?(value.to_s.strip.downcase)
|
|
123
|
+
end
|
|
124
|
+
private_class_method :truthy?
|
|
125
|
+
|
|
126
|
+
# rubocop:disable ThreadSafety/ClassInstanceVariable -- per-parent-process worker forwarder registry
|
|
127
|
+
def registry
|
|
128
|
+
@registry ||= {}
|
|
129
|
+
end
|
|
130
|
+
private_class_method :registry
|
|
131
|
+
# rubocop:enable ThreadSafety/ClassInstanceVariable
|
|
132
|
+
|
|
133
|
+
def forwarder_thread(io, forwarder, stream)
|
|
134
|
+
# rubocop:disable ThreadSafety/NewThread -- one reader thread per worker pipe
|
|
135
|
+
Thread.new do
|
|
136
|
+
loop do
|
|
137
|
+
forwarder.consume(stream, io.readpartial(4096))
|
|
138
|
+
end
|
|
139
|
+
rescue IOError, Errno::EPIPE
|
|
140
|
+
# worker closed the pipe
|
|
141
|
+
ensure
|
|
142
|
+
io.close unless io.closed?
|
|
143
|
+
end
|
|
144
|
+
# rubocop:enable ThreadSafety/NewThread
|
|
145
|
+
end
|
|
146
|
+
private_class_method :forwarder_thread
|
|
147
|
+
|
|
148
|
+
def drain_forwarders(entry)
|
|
149
|
+
entry[:ios].each do |io|
|
|
150
|
+
io.close unless io.closed?
|
|
151
|
+
rescue IOError
|
|
152
|
+
nil
|
|
153
|
+
end
|
|
154
|
+
entry[:threads].each(&:join)
|
|
155
|
+
entry[:forwarder].close
|
|
156
|
+
end
|
|
157
|
+
private_class_method :drain_forwarders
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require "time"
|
|
2
|
+
|
|
3
|
+
module Polyrun
|
|
4
|
+
module WorkerOutput
|
|
5
|
+
class LineForwarder
|
|
6
|
+
def initialize(shard:, pid:, log_io:, prefix_live:, tty_io:)
|
|
7
|
+
@shard = shard
|
|
8
|
+
@pid = pid
|
|
9
|
+
@log_io = log_io
|
|
10
|
+
@prefix_live = prefix_live
|
|
11
|
+
@tty_io = tty_io
|
|
12
|
+
@buffer = +""
|
|
13
|
+
@mutex = Mutex.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def consume(chunk)
|
|
17
|
+
return if chunk.nil? || chunk.empty?
|
|
18
|
+
|
|
19
|
+
@mutex.synchronize do
|
|
20
|
+
if progress_chunk?(chunk)
|
|
21
|
+
write_tty(chunk)
|
|
22
|
+
@log_io&.write(chunk)
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@buffer << chunk
|
|
27
|
+
while (newline_index = @buffer.index("\n"))
|
|
28
|
+
emit_line(@buffer.slice!(0, newline_index + 1))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def flush
|
|
34
|
+
@mutex.synchronize do
|
|
35
|
+
next if @buffer.empty?
|
|
36
|
+
|
|
37
|
+
emit_line(@buffer)
|
|
38
|
+
@buffer.clear
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def progress_chunk?(chunk)
|
|
45
|
+
chunk.include?("\r") && !chunk.include?("\n")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def emit_line(line)
|
|
49
|
+
prefixed = "#{prefix}#{line}"
|
|
50
|
+
@log_io&.write(prefixed)
|
|
51
|
+
write_tty(prefixed) if @prefix_live
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def prefix
|
|
55
|
+
"[#{Time.now.strftime("%Y-%m-%dT%H:%M:%S")} shard=#{@shard} pid=#{@pid}] "
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def write_tty(text)
|
|
59
|
+
@tty_io.write(text)
|
|
60
|
+
@tty_io.flush
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class WorkerForwarder
|
|
65
|
+
def initialize(shard:, pid:, log_path:, prefix_live:)
|
|
66
|
+
@shard = shard
|
|
67
|
+
@pid = pid
|
|
68
|
+
@log_io = File.open(log_path, "wb")
|
|
69
|
+
@stdout = LineForwarder.new(shard: shard, pid: pid, log_io: @log_io, prefix_live: prefix_live, tty_io: Polyrun::Log.stdout)
|
|
70
|
+
@stderr = LineForwarder.new(shard: shard, pid: pid, log_io: @log_io, prefix_live: prefix_live, tty_io: Polyrun::Log.stderr)
|
|
71
|
+
@write_mutex = Mutex.new
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def consume(stream, chunk)
|
|
75
|
+
@write_mutex.synchronize do
|
|
76
|
+
case stream
|
|
77
|
+
when :stdout then @stdout.consume(chunk)
|
|
78
|
+
when :stderr then @stderr.consume(chunk)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def close
|
|
84
|
+
@stdout.flush
|
|
85
|
+
@stderr.flush
|
|
86
|
+
@log_io.close
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
data/polyrun.gemspec
CHANGED
|
@@ -10,10 +10,14 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.license = "MIT"
|
|
11
11
|
spec.required_ruby_version = ">= 3.1.0"
|
|
12
12
|
|
|
13
|
-
spec.files =
|
|
13
|
+
spec.files = (
|
|
14
|
+
Dir["lib/**/*", "sig/**/*.rbs", "bin/polyrun", "README.md", "CHANGELOG.md", "docs/SETUP_PROFILE.md", "LICENSE", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "SECURITY.md", "polyrun.gemspec"] +
|
|
15
|
+
Dir["ext/**/extconf.rb", "ext/**/*.c", "ext/**/*.h"]
|
|
16
|
+
).uniq.reject { |f| File.directory?(f) }
|
|
14
17
|
spec.bindir = "bin"
|
|
15
18
|
spec.executables = ["polyrun"]
|
|
16
19
|
spec.require_paths = ["lib"]
|
|
20
|
+
spec.extensions = ["ext/polyrun_coverage_merge/extconf.rb"]
|
|
17
21
|
|
|
18
22
|
spec.metadata = {
|
|
19
23
|
"homepage_uri" => spec.homepage,
|
|
@@ -25,6 +29,9 @@ Gem::Specification.new do |spec|
|
|
|
25
29
|
# Normative: zero runtime dependencies (stdlib + vendored/native code only).
|
|
26
30
|
# Ruby 3.5+: `benchmark` is no longer a default gem; keep scripts and `rake bench_merge` warning-free.
|
|
27
31
|
spec.add_development_dependency "benchmark", ">= 0.3"
|
|
32
|
+
spec.add_development_dependency "benchmark-ips", "~> 2"
|
|
33
|
+
spec.add_development_dependency "memory_profiler", "~> 1"
|
|
34
|
+
spec.add_development_dependency "stackprof", "~> 0.2"
|
|
28
35
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
29
36
|
spec.add_development_dependency "rspec", "~> 3.12"
|
|
30
37
|
spec.add_development_dependency "appraisal", "~> 2.5"
|
data/sig/polyrun/rspec.rbs
CHANGED
|
@@ -7,5 +7,15 @@ module Polyrun
|
|
|
7
7
|
def self.install_failure_fragments!: (?only_if: untyped?) -> void
|
|
8
8
|
|
|
9
9
|
def self.install_worker_ping!: () -> void
|
|
10
|
+
|
|
11
|
+
def self.install_example_debug!: (?rspec_config: untyped?) -> void
|
|
12
|
+
|
|
13
|
+
def self.install_example_timeout!: (?rspec_config: untyped?, ?seconds: Float) -> void
|
|
14
|
+
|
|
15
|
+
def self.install_example_rails_logging!: (?rspec_config: untyped?) -> void
|
|
16
|
+
|
|
17
|
+
def self.install_example_prosopite!: (?rspec_config: untyped?) -> void
|
|
18
|
+
|
|
19
|
+
def self.install_sharded_formatter_compat!: (?rspec_config: untyped?) -> void
|
|
10
20
|
end
|
|
11
21
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Polyrun
|
|
2
|
+
module WorkerOutput
|
|
3
|
+
def self.routing_enabled?: () -> bool
|
|
4
|
+
def self.log_path_for: (Integer | String shard) -> String
|
|
5
|
+
def self.prepare_log_dir!: () -> void
|
|
6
|
+
def self.warn_shard_log: (Integer | String shard) -> void
|
|
7
|
+
def self.spawn_worker: (Hash[Symbol, untyped] child_env, Array[String] cmd, Array[String] paths, untyped hook_cfg) -> Integer
|
|
8
|
+
def self.finish_worker: (Integer pid) -> void
|
|
9
|
+
def self.shutdown_all!: () -> void
|
|
10
|
+
end
|
|
11
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: polyrun
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -23,6 +23,48 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0.3'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: benchmark-ips
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: memory_profiler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: stackprof
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.2'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.2'
|
|
26
68
|
- !ruby/object:Gem::Dependency
|
|
27
69
|
name: rake
|
|
28
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -153,7 +195,8 @@ email:
|
|
|
153
195
|
- contact@kiskolabs.com
|
|
154
196
|
executables:
|
|
155
197
|
- polyrun
|
|
156
|
-
extensions:
|
|
198
|
+
extensions:
|
|
199
|
+
- ext/polyrun_coverage_merge/extconf.rb
|
|
157
200
|
extra_rdoc_files: []
|
|
158
201
|
files:
|
|
159
202
|
- CHANGELOG.md
|
|
@@ -164,8 +207,13 @@ files:
|
|
|
164
207
|
- SECURITY.md
|
|
165
208
|
- bin/polyrun
|
|
166
209
|
- docs/SETUP_PROFILE.md
|
|
210
|
+
- ext/polyrun_coverage_merge/coverage_merge.c
|
|
211
|
+
- ext/polyrun_coverage_merge/extconf.rb
|
|
167
212
|
- lib/polyrun.rb
|
|
213
|
+
- lib/polyrun/benchmark/profile.rb
|
|
214
|
+
- lib/polyrun/benchmark/report.rb
|
|
168
215
|
- lib/polyrun/cli.rb
|
|
216
|
+
- lib/polyrun/cli/benchmark_commands.rb
|
|
169
217
|
- lib/polyrun/cli/ci_shard_hooks.rb
|
|
170
218
|
- lib/polyrun/cli/ci_shard_run_command.rb
|
|
171
219
|
- lib/polyrun/cli/ci_shard_run_parse.rb
|
|
@@ -208,6 +256,9 @@ files:
|
|
|
208
256
|
- lib/polyrun/coverage/collector_finish.rb
|
|
209
257
|
- lib/polyrun/coverage/collector_fragment_meta.rb
|
|
210
258
|
- lib/polyrun/coverage/example_diff.rb
|
|
259
|
+
- lib/polyrun/coverage/example_diff_snapshot.rb
|
|
260
|
+
- lib/polyrun/coverage/example_diff_track_filter.rb
|
|
261
|
+
- lib/polyrun/coverage/file_stats_report.rb
|
|
211
262
|
- lib/polyrun/coverage/filter.rb
|
|
212
263
|
- lib/polyrun/coverage/formatter.rb
|
|
213
264
|
- lib/polyrun/coverage/merge.rb
|
|
@@ -222,6 +273,7 @@ files:
|
|
|
222
273
|
- lib/polyrun/coverage/merge/html/template.html.erb
|
|
223
274
|
- lib/polyrun/coverage/merge_fragment_meta.rb
|
|
224
275
|
- lib/polyrun/coverage/merge_merge_two.rb
|
|
276
|
+
- lib/polyrun/coverage/merge_native.rb
|
|
225
277
|
- lib/polyrun/coverage/rails.rb
|
|
226
278
|
- lib/polyrun/coverage/reporting.rb
|
|
227
279
|
- lib/polyrun/coverage/result.rb
|
|
@@ -242,8 +294,11 @@ files:
|
|
|
242
294
|
- lib/polyrun/database/url_builder/template_prepare.rb
|
|
243
295
|
- lib/polyrun/debug.rb
|
|
244
296
|
- lib/polyrun/env/ci.rb
|
|
297
|
+
- lib/polyrun/export/csv.rb
|
|
298
|
+
- lib/polyrun/export/markdown.rb
|
|
245
299
|
- lib/polyrun/hooks.rb
|
|
246
300
|
- lib/polyrun/hooks/dsl.rb
|
|
301
|
+
- lib/polyrun/hooks/shell_runner.rb
|
|
247
302
|
- lib/polyrun/hooks/worker_runner.rb
|
|
248
303
|
- lib/polyrun/hooks/worker_shell.rb
|
|
249
304
|
- lib/polyrun/log.rb
|
|
@@ -266,6 +321,7 @@ files:
|
|
|
266
321
|
- lib/polyrun/queue/duration.rb
|
|
267
322
|
- lib/polyrun/queue/file_store.rb
|
|
268
323
|
- lib/polyrun/queue/file_store_pending.rb
|
|
324
|
+
- lib/polyrun/queue/worker_loop.rb
|
|
269
325
|
- lib/polyrun/quick.rb
|
|
270
326
|
- lib/polyrun/quick/assertions.rb
|
|
271
327
|
- lib/polyrun/quick/errors.rb
|
|
@@ -278,9 +334,13 @@ files:
|
|
|
278
334
|
- lib/polyrun/reporting/failure_merge.rb
|
|
279
335
|
- lib/polyrun/reporting/junit.rb
|
|
280
336
|
- lib/polyrun/reporting/junit_emit.rb
|
|
337
|
+
- lib/polyrun/reporting/junit_report.rb
|
|
281
338
|
- lib/polyrun/reporting/rspec_failure_fragment_formatter.rb
|
|
282
339
|
- lib/polyrun/reporting/rspec_junit.rb
|
|
283
340
|
- lib/polyrun/rspec.rb
|
|
341
|
+
- lib/polyrun/rspec/example_debug.rb
|
|
342
|
+
- lib/polyrun/rspec/example_debug_instrumentation.rb
|
|
343
|
+
- lib/polyrun/rspec/sharded_formatter_compat.rb
|
|
284
344
|
- lib/polyrun/spec_quality.rb
|
|
285
345
|
- lib/polyrun/spec_quality/config.rb
|
|
286
346
|
- lib/polyrun/spec_quality/fragment.rb
|
|
@@ -303,6 +363,8 @@ files:
|
|
|
303
363
|
- lib/polyrun/timing/summary.rb
|
|
304
364
|
- lib/polyrun/timing/variance_report.rb
|
|
305
365
|
- lib/polyrun/version.rb
|
|
366
|
+
- lib/polyrun/worker_output.rb
|
|
367
|
+
- lib/polyrun/worker_output_forwarders.rb
|
|
306
368
|
- lib/polyrun/worker_ping.rb
|
|
307
369
|
- polyrun.gemspec
|
|
308
370
|
- sig/polyrun.rbs
|
|
@@ -313,6 +375,7 @@ files:
|
|
|
313
375
|
- sig/polyrun/minitest.rbs
|
|
314
376
|
- sig/polyrun/quick.rbs
|
|
315
377
|
- sig/polyrun/rspec.rbs
|
|
378
|
+
- sig/polyrun/worker_output.rbs
|
|
316
379
|
- sig/polyrun/worker_ping.rbs
|
|
317
380
|
homepage: https://github.com/amkisko/polyrun.rb
|
|
318
381
|
licenses:
|