Skip to content

Commit 2c97cc6

Browse files
prefix output from worker's subprocesses too
1 parent fb30365 commit 2c97cc6

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

test/runtests.jl

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,51 @@ include("buildkitetestjson.jl")
1414
const longrunning_delay = parse(Int, get(ENV, "JULIA_TEST_LONGRUNNING_DELAY", "45")) * 60 # minutes
1515
const longrunning_interval = parse(Int, get(ENV, "JULIA_TEST_LONGRUNNING_INTERVAL", "15")) * 60 # minutes
1616

17+
# IO wrapper that prefixes each line with a test name
18+
mutable struct PrefixedIO <: IO
19+
io::IO
20+
lock::ReentrantLock
21+
prefix::Base.RefValue{String}
22+
at_line_start::Bool
23+
end
24+
PrefixedIO(io::IO, lock::ReentrantLock, prefix::Base.RefValue{String}) = PrefixedIO(io, lock, prefix, true)
25+
26+
function Base.unsafe_write(pio::PrefixedIO, p::Ptr{UInt8}, n::UInt)
27+
@lock pio.lock begin
28+
written = UInt(0)
29+
i = 1
30+
while i <= n
31+
if pio.at_line_start && !isempty(pio.prefix[])
32+
printstyled(pio.io, " ", pio.prefix[], ": ", color=:light_black)
33+
pio.at_line_start = false
34+
end
35+
# Find next newline
36+
j = i
37+
while j <= n && unsafe_load(p, j) != UInt8('\n')
38+
j += 1
39+
end
40+
# Write up to and including newline (or end)
41+
if j <= n
42+
written += Base.unsafe_write(pio.io, p + i - 1, UInt(j - i + 1))
43+
pio.at_line_start = true
44+
i = j + 1
45+
else
46+
written += Base.unsafe_write(pio.io, p + i - 1, UInt(j - i))
47+
i = j
48+
end
49+
end
50+
return written
51+
end
52+
end
53+
54+
Base.write(pio::PrefixedIO, x::UInt8) = Base.unsafe_write(pio, Ref(x), 1)
55+
Base.flush(pio::PrefixedIO) = flush(pio.io)
56+
Base.isopen(pio::PrefixedIO) = isopen(pio.io)
57+
Base.displaysize(pio::PrefixedIO) = displaysize(pio.io)
58+
Base.get(pio::PrefixedIO, key, default) = get(pio.io, key, default)
59+
Base.get(pio::PrefixedIO, key::Symbol, default) = get(pio.io, key, default)
60+
Base.haskey(pio::PrefixedIO, key) = haskey(pio.io, key)
61+
1762
(; tests, net_on, exit_on_error, use_revise, buildroot, seed) = choosetests(ARGS)
1863
tests = unique(tests)
1964

@@ -163,6 +208,13 @@ cd(@__DIR__) do
163208
stderr.lock = print_lock
164209
end
165210

211+
# Prefix for test output (used by both worker hook and node1 tests)
212+
test_output_prefix = Ref("")
213+
214+
# Create prefixed IO wrappers for node1 tests
215+
prefixed_stdout = PrefixedIO(stdout, print_lock, test_output_prefix)
216+
prefixed_stderr = PrefixedIO(stderr, print_lock, test_output_prefix)
217+
166218
# Set up hook to display test name with worker output
167219
Distributed.worker_output_hook[] = (ident, line) -> begin
168220
wrkr_id = tryparse(Int, ident)
@@ -380,12 +432,20 @@ cd(@__DIR__) do
380432
isolate = true
381433
t == "SharedArrays" && (isolate = false)
382434
before = time()
435+
# Set prefix and redirect stdout/stderr to prefixed wrappers
436+
test_output_prefix[] = "$t (1)"
383437
resp, duration = try
384-
r = @invokelatest runtests(t, test_path(t), isolate, seed=seed) # runtests is defined by the include above
385-
r, time() - before
438+
redirect_stdout(prefixed_stdout) do
439+
redirect_stderr(prefixed_stderr) do
440+
r = @invokelatest runtests(t, test_path(t), isolate, seed=seed) # runtests is defined by the include above
441+
r, time() - before
442+
end
443+
end
386444
catch e
387445
isa(e, InterruptException) && rethrow()
388446
Any[CapturedException(e, catch_backtrace())], time() - before
447+
finally
448+
test_output_prefix[] = ""
389449
end
390450
if length(resp) == 1
391451
print_testworker_errored(t, 1, resp[1])

0 commit comments

Comments
 (0)