rspec-tracer 1.0.3 → 1.0.5
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 +104 -0
- data/lib/rspec_tracer/example.rb +55 -6
- data/lib/rspec_tracer/remote_cache/cache.rb +4 -0
- data/lib/rspec_tracer/version.rb +1 -1
- data/lib/rspec_tracer.rb +120 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 67309438f6000ac9913b4d3f48b3e7ba66c56e09674b2bf191b75d0d8134401c
|
|
4
|
+
data.tar.gz: e10e5253987938b6467920a7adda07dbbce152849373b1c8a4355e771007c196
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 80b3e75b07083b15e179fa4d108afbf31271ee15c3b87d48625ccfa481a6fa24a70114246fe9644b6d2d743732515029e9ec93e078a9207ed1c4c98ba61964ca
|
|
7
|
+
data.tar.gz: 8ac718e348b8cc6559b87b45d117cb20ddbca819687208124e1c8e7df557e97528d0da93823fe502e9d689646457037ce9be4c7529f3bdf853ecbcbb6f7a98e7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,107 @@
|
|
|
1
|
+
## [1.0.5] - 2026-05-17
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- **`example_id` is now stable across runs and across no-op edits** —
|
|
6
|
+
`Example.from` previously fed `example.example_group.name` and
|
|
7
|
+
line numbers into the identity-hash payload. Two unrelated effects
|
|
8
|
+
shifted the resulting MD5 across runs that should have been
|
|
9
|
+
identical:
|
|
10
|
+
|
|
11
|
+
- `example_group.name` is RSpec's generated class name with a
|
|
12
|
+
load-order-dependent `_2` / `_3` suffix when two spec files share
|
|
13
|
+
a `describe` name (very common — e.g. `describe User do` in
|
|
14
|
+
`user_spec.rb` and `models/user_spec.rb`). The same example got
|
|
15
|
+
a different id depending on rspec's file load order, silently
|
|
16
|
+
thrashing the cache and breaking failed / pending always-re-run
|
|
17
|
+
guarantees.
|
|
18
|
+
- For unnamed examples (`it { }` / `specify { }` / `example { }`),
|
|
19
|
+
`example.description` falls back to RSpec's line-bearing
|
|
20
|
+
`"example at <path>:<line>"` string, so a no-op blank-line edit
|
|
21
|
+
above the example flipped its id and orphaned its cache entry.
|
|
22
|
+
|
|
23
|
+
The digest now uses `example_group.description` (the user's
|
|
24
|
+
string, not the generated class name), strips the trailing `:LINE`
|
|
25
|
+
from `shared_group_inclusion_backtrace` entries, and for unnamed
|
|
26
|
+
examples substitutes a line-independent positional discriminator
|
|
27
|
+
(the example's 0-based ordinal among the unnamed examples of its
|
|
28
|
+
group). `line_number` / `rerun_file_name` / `rerun_line_number`
|
|
29
|
+
still ride along in the stored payload for the reporter's location
|
|
30
|
+
columns but no longer enter the digest. Contract: *rename = new
|
|
31
|
+
identity; restructure = same identity.*
|
|
32
|
+
|
|
33
|
+
Affected since v1.0.0 (2021). One-time cold run on upgrade: every
|
|
34
|
+
cached `example_id` changes shape, so the first 1.0.5 run misses
|
|
35
|
+
the 1.0.4 cache uniformly and treats every example as no-cache;
|
|
36
|
+
the second run is warm again. Surfaced by the 2.0.0.pre.1 field
|
|
37
|
+
test against third-party Rails apps; ports
|
|
38
|
+
[#209](https://github.com/avmnu-sng/rspec-tracer/pull/209) and
|
|
39
|
+
[#211](https://github.com/avmnu-sng/rspec-tracer/pull/211) onto
|
|
40
|
+
this 1.0.x line. Closes
|
|
41
|
+
[#196](https://github.com/avmnu-sng/rspec-tracer/issues/196) and
|
|
42
|
+
[#210](https://github.com/avmnu-sng/rspec-tracer/issues/210).
|
|
43
|
+
|
|
44
|
+
- **`RSpecTracer.start` no longer crashes when the user pre-started
|
|
45
|
+
`::Coverage`** — users who want branch coverage typically call
|
|
46
|
+
`Coverage.start(lines: true, branches: true)` before loading the
|
|
47
|
+
tracer. On the previous code path, `setup_coverage` called bare
|
|
48
|
+
`::Coverage.start` unconditionally, which raised
|
|
49
|
+
`RuntimeError: coverage measurement is already setup` and crashed
|
|
50
|
+
the tracer init. `setup_coverage` now guards on `Coverage.running?`
|
|
51
|
+
(Ruby 2.7+) and rescues `RuntimeError` for older Rubies; the
|
|
52
|
+
tracer attaches to the already-running `::Coverage` instance
|
|
53
|
+
instead of raising. Ports
|
|
54
|
+
[#207](https://github.com/avmnu-sng/rspec-tracer/pull/207)'s
|
|
55
|
+
Coverage-guard half (the 2.0-only `coverage_modes` DSL is not
|
|
56
|
+
backported). Closes
|
|
57
|
+
[#195](https://github.com/avmnu-sng/rspec-tracer/issues/195).
|
|
58
|
+
|
|
59
|
+
- **`remote_cache` download and upload now log on success** — the
|
|
60
|
+
success paths on `RemoteCache::Cache#download` / `#upload` returned
|
|
61
|
+
silently, so a successful `rake rspec_tracer:remote_cache:download`
|
|
62
|
+
produced zero output and users couldn't tell from CI logs whether
|
|
63
|
+
the cache restored. Two `puts` lines now announce success:
|
|
64
|
+
`rspec-tracer remote_cache: restored cache from <sha>` after a
|
|
65
|
+
successful download, and `rspec-tracer remote_cache: uploaded cache
|
|
66
|
+
to <ref>` after a successful upload. Ports the basic-INFO portion of
|
|
67
|
+
[#201](https://github.com/avmnu-sng/rspec-tracer/pull/201) (the
|
|
68
|
+
cross-branch-fallback qualifier and `prune_all!` line are
|
|
69
|
+
2.0-only — 1.x has neither a multi-tier cache nor a prune_all
|
|
70
|
+
path). Closes
|
|
71
|
+
[#188](https://github.com/avmnu-sng/rspec-tracer/issues/188).
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
|
|
75
|
+
- **Gemspec now requires MFA for publishing** — adds
|
|
76
|
+
`spec.metadata['rubygems_mfa_required'] = 'true'`. Pure packaging
|
|
77
|
+
metadata; no runtime impact for gem consumers. Ports
|
|
78
|
+
[#214](https://github.com/avmnu-sng/rspec-tracer/pull/214).
|
|
79
|
+
|
|
80
|
+
## [1.0.4] - 2026-05-06
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- **Parallel-tests purge race when a sibling worker is still mid-flush**
|
|
85
|
+
— the elected worker trusted only `parallel_tests`'s pid-file barrier
|
|
86
|
+
(`ParallelTests.wait_for_other_processes_to_finish`), which under
|
|
87
|
+
specific scheduling/I/O timing on GHA Linux x86_64 can return while a
|
|
88
|
+
sibling's `parallel_tests_N/` dir hasn't fully flushed. The elected
|
|
89
|
+
then merged + purged, racing the in-progress sibling. Symptoms:
|
|
90
|
+
intermittent leftover `parallel_tests_N/` dir post-purge AND/OR
|
|
91
|
+
silently dropped peer caches in the merge.
|
|
92
|
+
|
|
93
|
+
Backport of upstream PR
|
|
94
|
+
[#168](https://github.com/avmnu-sng/rspec-tracer/pull/168). Adds a
|
|
95
|
+
filesystem barrier layered on top of the pid-file wait. Each worker
|
|
96
|
+
writes a `.rspec_tracer_boot` marker at `RSpecTracer.start` time and
|
|
97
|
+
a `.rspec_tracer_done` marker as the first step of its at_exit tasks;
|
|
98
|
+
the elected worker waits for every booted peer's `.done` to
|
|
99
|
+
materialize before proceeding to merge + purge. Two independent
|
|
100
|
+
signals (pid file + filesystem) must agree before the elected worker
|
|
101
|
+
declares the peer set stable. Bounded at 5 s with a graceful warn
|
|
102
|
+
for crashed peers — their dirs are purged regardless of completion
|
|
103
|
+
state, and the merge accepts whatever's on disk.
|
|
104
|
+
|
|
1
105
|
## [1.0.3] - 2026-05-04
|
|
2
106
|
|
|
3
107
|
### Fixed
|
data/lib/rspec_tracer/example.rb
CHANGED
|
@@ -4,16 +4,64 @@ module RSpecTracer
|
|
|
4
4
|
module Example
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
+
# Identity-keyed cache of `<example_group> => Array<unnamed sibling>`
|
|
8
|
+
# populated lazily by `unnamed_description`. A group with N unnamed
|
|
9
|
+
# examples computes the sibling list once per group rather than N
|
|
10
|
+
# times. Memory is bounded by the live group set, which RSpec
|
|
11
|
+
# retains for the run anyway.
|
|
12
|
+
@unnamed_siblings_cache = {}.compare_by_identity
|
|
13
|
+
|
|
7
14
|
def from(example)
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
location = example_location(example)
|
|
16
|
+
identity = {
|
|
17
|
+
example_group: example.example_group.description,
|
|
10
18
|
description: example.description,
|
|
11
19
|
full_description: example.full_description,
|
|
12
20
|
shared_group: example.metadata[:shared_group_inclusion_backtrace]
|
|
13
|
-
.map(
|
|
14
|
-
|
|
21
|
+
.map { |frame| frame.formatted_inclusion_location.sub(/:\d+\z/, '') },
|
|
22
|
+
file_name: location[:file_name]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
identity
|
|
26
|
+
.merge(location)
|
|
27
|
+
.merge(example_id: Digest::MD5.hexdigest(digest_identity(example, identity).to_json))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# The Hash actually fed to the MD5. For a named example this is
|
|
31
|
+
# `identity` unchanged. For an unnamed example (`it { }` /
|
|
32
|
+
# `specify { }` / `example { }`) RSpec's `description` is the
|
|
33
|
+
# line-bearing `"example at <path>:<line>"` fallback, so
|
|
34
|
+
# `description` is swapped for a line-independent positional
|
|
35
|
+
# discriminator before hashing. The returned/stored payload still
|
|
36
|
+
# carries RSpec's `description` / `full_description` untouched —
|
|
37
|
+
# only the digest input differs.
|
|
38
|
+
def digest_identity(example, identity)
|
|
39
|
+
return identity unless unnamed?(example)
|
|
40
|
+
|
|
41
|
+
identity.merge(description: unnamed_description(example))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# RSpec's raw `metadata[:description]` is `""` for `it { }` /
|
|
45
|
+
# `specify { }` / `example { }`; the `description` *method* would
|
|
46
|
+
# instead return the line-bearing `"example at <path>:<line>"`
|
|
47
|
+
# fallback, so the raw metadata value is what cleanly tells named
|
|
48
|
+
# from unnamed.
|
|
49
|
+
def unnamed?(example)
|
|
50
|
+
example.metadata[:description].to_s.strip.empty?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# 0-based ordinal of the example among the *unnamed* examples of
|
|
54
|
+
# its group. Stable across blank-line / comment edits and across
|
|
55
|
+
# adding or renaming *named* siblings; changes only when the
|
|
56
|
+
# unnamed examples are reordered or one is inserted / removed
|
|
57
|
+
# ahead of it. The Ruby-inspect-style `#<...>` form makes spoofing
|
|
58
|
+
# by a real user description implausible.
|
|
59
|
+
def unnamed_description(example)
|
|
60
|
+
group = example.example_group
|
|
61
|
+
unnamed_siblings = @unnamed_siblings_cache[group] ||=
|
|
62
|
+
group.examples.select { |sibling| unnamed?(sibling) }
|
|
15
63
|
|
|
16
|
-
|
|
64
|
+
"#<rspec-tracer unnamed example #{unnamed_siblings.index(example)}>"
|
|
17
65
|
end
|
|
18
66
|
|
|
19
67
|
def example_location(example)
|
|
@@ -53,6 +101,7 @@ module RSpecTracer
|
|
|
53
101
|
RSpecTracer::SourceFile.file_name(file_path)
|
|
54
102
|
end
|
|
55
103
|
|
|
56
|
-
private_class_method :
|
|
104
|
+
private_class_method :digest_identity, :unnamed?, :unnamed_description,
|
|
105
|
+
:example_location, :example_rerun_location, :location_file_name
|
|
57
106
|
end
|
|
58
107
|
end
|
|
@@ -19,6 +19,8 @@ module RSpecTracer
|
|
|
19
19
|
|
|
20
20
|
@aws.download_file(@cache_sha, 'last_run.json')
|
|
21
21
|
@aws.download_dir(@cache_sha, last_run_id)
|
|
22
|
+
|
|
23
|
+
puts "rspec-tracer remote_cache: restored cache from #{@cache_sha}"
|
|
22
24
|
rescue StandardError => e
|
|
23
25
|
puts "Error: #{e.message}"
|
|
24
26
|
puts e.backtrace.first(5).join("\n")
|
|
@@ -32,6 +34,8 @@ module RSpecTracer
|
|
|
32
34
|
|
|
33
35
|
write_branch_refs(file_name)
|
|
34
36
|
@aws.upload_branch_refs(@repo.branch_name, file_name)
|
|
37
|
+
|
|
38
|
+
puts "rspec-tracer remote_cache: uploaded cache to #{@repo.branch_ref}"
|
|
35
39
|
rescue StandardError => e
|
|
36
40
|
puts "Error: #{e.message}"
|
|
37
41
|
puts e.backtrace.first(5).join("\n")
|
data/lib/rspec_tracer/version.rb
CHANGED
data/lib/rspec_tracer.rb
CHANGED
|
@@ -32,6 +32,17 @@ require_relative 'rspec_tracer/time_formatter'
|
|
|
32
32
|
require_relative 'rspec_tracer/version'
|
|
33
33
|
|
|
34
34
|
module RSpecTracer
|
|
35
|
+
# Filesystem barrier markers, layered on top of parallel_tests's
|
|
36
|
+
# pid-file wait to defend against the GHA-observed race where the
|
|
37
|
+
# gem's `wait_for_other_processes_to_finish` returns while a sibling
|
|
38
|
+
# worker hasn't fully flushed its `parallel_tests_N/` dir yet. Each
|
|
39
|
+
# worker writes BOOT at setup-time and DONE as the first step of its
|
|
40
|
+
# at_exit tasks; the elected worker waits for every booted peer's
|
|
41
|
+
# DONE marker (deadline-bounded) before proceeding to merge + purge.
|
|
42
|
+
PARALLEL_TESTS_BOOT_MARKER_FILENAME = '.rspec_tracer_boot'
|
|
43
|
+
PARALLEL_TESTS_DONE_MARKER_FILENAME = '.rspec_tracer_done'
|
|
44
|
+
PARALLEL_TESTS_PEER_DONE_DEADLINE_SECONDS = 5
|
|
45
|
+
|
|
35
46
|
class << self
|
|
36
47
|
attr_accessor :running, :pid, :no_examples
|
|
37
48
|
|
|
@@ -191,6 +202,27 @@ module RSpecTracer
|
|
|
191
202
|
puts "Failed to load parallel tests (Error: #{e.message})"
|
|
192
203
|
ensure
|
|
193
204
|
track_parallel_tests_test_env_number
|
|
205
|
+
parallel_tests_touch_boot!
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Per-worker boot marker. Source-of-truth for "this worker booted
|
|
209
|
+
# past `RSpecTracer.start`", consumed by the elected worker's
|
|
210
|
+
# finalize-time peer enumeration. Idempotent; failures are warned
|
|
211
|
+
# and absorbed (boot-marker write must never block test execution).
|
|
212
|
+
def parallel_tests_touch_boot!
|
|
213
|
+
return unless parallel_tests?
|
|
214
|
+
|
|
215
|
+
FileUtils.mkdir_p(RSpecTracer.cache_path)
|
|
216
|
+
File.write(
|
|
217
|
+
File.join(RSpecTracer.cache_path, PARALLEL_TESTS_BOOT_MARKER_FILENAME),
|
|
218
|
+
JSON.generate(
|
|
219
|
+
pid: Process.pid,
|
|
220
|
+
test_env_number: ENV.fetch('TEST_ENV_NUMBER', ''),
|
|
221
|
+
started_at: Time.now.utc.iso8601
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
rescue StandardError => e
|
|
225
|
+
puts "RSpec tracer: failed to write boot marker (#{e.class}: #{e.message})"
|
|
194
226
|
end
|
|
195
227
|
|
|
196
228
|
def track_parallel_tests_test_env_number
|
|
@@ -231,7 +263,15 @@ module RSpecTracer
|
|
|
231
263
|
|
|
232
264
|
require 'coverage'
|
|
233
265
|
|
|
266
|
+
return if ::Coverage.respond_to?(:running?) && ::Coverage.running?
|
|
267
|
+
|
|
234
268
|
::Coverage.start
|
|
269
|
+
rescue RuntimeError
|
|
270
|
+
# Ruby < 2.7 has no Coverage.running? predicate; the rescue
|
|
271
|
+
# catches the "user pre-started Coverage themselves" path on
|
|
272
|
+
# those Rubies. Safe to absorb — the tracer attaches to the
|
|
273
|
+
# already-running ::Coverage instance.
|
|
274
|
+
nil
|
|
235
275
|
end
|
|
236
276
|
|
|
237
277
|
def setup_trace_point
|
|
@@ -324,6 +364,15 @@ module RSpecTracer
|
|
|
324
364
|
end
|
|
325
365
|
|
|
326
366
|
def run_parallel_tests_exit_tasks
|
|
367
|
+
# Every worker — elected or not — drops its `.done` marker as the
|
|
368
|
+
# first thing in finalize so the elected worker's
|
|
369
|
+
# `parallel_tests_wait_for_peer_done_markers!` can observe it.
|
|
370
|
+
# Non-elected workers stop here; the elected worker proceeds to
|
|
371
|
+
# the merge + purge sequence (gated by `parallel_tests_executed?`,
|
|
372
|
+
# which now layers the peer-done barrier on top of the existing
|
|
373
|
+
# pid-file wait).
|
|
374
|
+
parallel_tests_touch_done!
|
|
375
|
+
|
|
327
376
|
return unless parallel_tests_executed?
|
|
328
377
|
|
|
329
378
|
merge_parallel_tests_reports
|
|
@@ -333,6 +382,24 @@ module RSpecTracer
|
|
|
333
382
|
purge_parallel_tests_reports
|
|
334
383
|
end
|
|
335
384
|
|
|
385
|
+
# Per-worker done marker. Written by every worker (elected or not)
|
|
386
|
+
# as the first step of `run_parallel_tests_exit_tasks`. Pairs with
|
|
387
|
+
# the boot marker for the elected worker's peer-done barrier:
|
|
388
|
+
# presence of `.done` means "this worker has signalled completion
|
|
389
|
+
# of its own writes"; absence (with `.boot` present) means "still
|
|
390
|
+
# mid-flush or crashed". Idempotent; failures are warned + absorbed.
|
|
391
|
+
def parallel_tests_touch_done!
|
|
392
|
+
return unless parallel_tests?
|
|
393
|
+
|
|
394
|
+
FileUtils.mkdir_p(RSpecTracer.cache_path)
|
|
395
|
+
File.write(
|
|
396
|
+
File.join(RSpecTracer.cache_path, PARALLEL_TESTS_DONE_MARKER_FILENAME),
|
|
397
|
+
Time.now.utc.iso8601
|
|
398
|
+
)
|
|
399
|
+
rescue StandardError => e
|
|
400
|
+
puts "RSpec tracer: failed to write done marker (#{e.class}: #{e.message})"
|
|
401
|
+
end
|
|
402
|
+
|
|
336
403
|
def merge_parallel_tests_reports
|
|
337
404
|
return unless parallel_tests_executed?
|
|
338
405
|
|
|
@@ -432,9 +499,62 @@ module RSpecTracer
|
|
|
432
499
|
|
|
433
500
|
ParallelTests.wait_for_other_processes_to_finish
|
|
434
501
|
|
|
502
|
+
# Belt-and-suspenders barrier: pid-file said everyone's done, but
|
|
503
|
+
# the gem's `wait_for_other_processes_to_finish` has been observed
|
|
504
|
+
# on GHA Linux x86_64 to return while a sibling's `parallel_tests_N/`
|
|
505
|
+
# is still mid-flush. Cross-check via the `.boot`/`.done` filesystem
|
|
506
|
+
# markers before declaring the peer set stable. Idempotent: once
|
|
507
|
+
# all peers have flushed, subsequent calls just glob, find nothing
|
|
508
|
+
# missing, and return.
|
|
509
|
+
parallel_tests_wait_for_peer_done_markers!
|
|
510
|
+
|
|
435
511
|
true
|
|
436
512
|
end
|
|
437
513
|
|
|
514
|
+
# Block until every peer that wrote `.boot` has also written `.done`,
|
|
515
|
+
# or the deadline elapses. Polled at 50ms — fine enough to close the
|
|
516
|
+
# typical "barrier returned a tick early" case within a poll or two,
|
|
517
|
+
# coarse enough not to dominate CPU.
|
|
518
|
+
#
|
|
519
|
+
# On timeout we log and proceed: a peer that never wrote `.done`
|
|
520
|
+
# either crashed (then its dir is orphan content; the subsequent
|
|
521
|
+
# purge cleans it) or is genuinely hung (the elected can't fix that
|
|
522
|
+
# — we choose merge correctness over indefinite wait).
|
|
523
|
+
def parallel_tests_wait_for_peer_done_markers!
|
|
524
|
+
base_dir = File.dirname(RSpecTracer.cache_path)
|
|
525
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + PARALLEL_TESTS_PEER_DONE_DEADLINE_SECONDS
|
|
526
|
+
|
|
527
|
+
loop do
|
|
528
|
+
missing = parallel_tests_peer_dirs_missing_done(base_dir)
|
|
529
|
+
return if missing.empty?
|
|
530
|
+
|
|
531
|
+
if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
532
|
+
puts 'RSpec tracer: peers booted without finishing within ' \
|
|
533
|
+
"#{PARALLEL_TESTS_PEER_DONE_DEADLINE_SECONDS}s: #{missing.inspect}; " \
|
|
534
|
+
'proceeding (peer dirs will be purged regardless of completion state)'
|
|
535
|
+
return
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
sleep 0.05
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
# Set difference of `.boot`-bearing peer dirs and `.done`-bearing
|
|
543
|
+
# peer dirs under `base_dir`. A returned entry means "this peer
|
|
544
|
+
# registered but has not signalled completion yet" — either still
|
|
545
|
+
# mid-flush or crashed.
|
|
546
|
+
def parallel_tests_peer_dirs_missing_done(base_dir)
|
|
547
|
+
boot_dirs = parallel_tests_peer_dirs_with_marker(base_dir, PARALLEL_TESTS_BOOT_MARKER_FILENAME)
|
|
548
|
+
done_dirs = parallel_tests_peer_dirs_with_marker(base_dir, PARALLEL_TESTS_DONE_MARKER_FILENAME)
|
|
549
|
+
boot_dirs - done_dirs
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
def parallel_tests_peer_dirs_with_marker(base_dir, marker_filename)
|
|
553
|
+
Dir.glob(File.join(base_dir, 'parallel_tests_*', marker_filename)).map do |path|
|
|
554
|
+
File.dirname(path)
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
438
558
|
# Elects the worker that performs the per-run merge. Delegates to
|
|
439
559
|
# `::ParallelTests.first_process?`, which returns true iff
|
|
440
560
|
# `TEST_ENV_NUMBER.to_i <= 1` — i.e. for exactly one worker per run,
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rspec-tracer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abhimanyu Singh
|
|
@@ -118,9 +118,10 @@ licenses:
|
|
|
118
118
|
- MIT
|
|
119
119
|
metadata:
|
|
120
120
|
homepage_uri: https://github.com/avmnu-sng/rspec-tracer
|
|
121
|
-
source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v1.0.
|
|
121
|
+
source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v1.0.5
|
|
122
122
|
changelog_uri: https://github.com/avmnu-sng/rspec-tracer/blob/main/CHANGELOG.md
|
|
123
123
|
bug_tracker_uri: https://github.com/avmnu-sng/rspec-tracer/issues
|
|
124
|
+
rubygems_mfa_required: 'true'
|
|
124
125
|
rdoc_options: []
|
|
125
126
|
require_paths:
|
|
126
127
|
- lib
|