From c7134f4be80fb04a792bf9facc7cd63d03612fa1 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 16 Jul 2026 11:00:32 -0400 Subject: [PATCH 1/2] runtests: prefix worker output with the testsuite and worker number Label each line of a test worker's output with the test it is currently running instead of just its worker id, making it much easier to tell which suite a stray log line or precompile message came from. Worker output is routed through Distributed, so an internal `Distributed.worker_output_hook` is installed that transforms each line into a de-emphasized `" (): "` prefix (falling back to the worker id when the worker is between tests). The node-1 tests run in-process and do not pass through that redirection, so their stdout/stderr are captured with a `Pipe` and prefixed the same way via `with_output_prefix`. Prefixes are styled with `StyledStrings` so they are only colorized on IOs that support it. The embedding test is updated for the reduced single-space default worker prefix introduced in the corresponding Distributed change. Depends on JuliaLang/Distributed.jl#157. Co-Authored-By: Claude Opus 4.8 (1M context) --- test/embedding/embedding-test.jl | 2 +- test/runtests.jl | 51 ++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/test/embedding/embedding-test.jl b/test/embedding/embedding-test.jl index 0744cac679698..a9fb01fd75146 100644 --- a/test/embedding/embedding-test.jl +++ b/test/embedding/embedding-test.jl @@ -31,6 +31,6 @@ end @test lines[4] == "sqrt(2.0) in C: 1.414214e+00" @test lines[9] == "called bar" @test lines[10] == "calling new bar" - @test lines[11] == " From worker 2:\tTaking over the world..." + @test lines[11] == " From worker 2:\tTaking over the world..." @test "exception caught from C" in readlines(err) end diff --git a/test/runtests.jl b/test/runtests.jl index 1babbd7e0daec..d54684f14ee75 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,7 @@ using Test using Distributed using Dates using Printf: @sprintf +using StyledStrings: @styled_str using Base: Experimental using Base.ScopedValues @@ -14,6 +15,34 @@ include("buildkitetestjson.jl") const longrunning_delay = parse(Int, get(ENV, "JULIA_TEST_LONGRUNNING_DELAY", "45")) * 60 # minutes const longrunning_interval = parse(Int, get(ENV, "JULIA_TEST_LONGRUNNING_INTERVAL", "15")) * 60 # minutes +# Run `f()` with its stdout/stderr captured and re-emitted to `io`, each line prefixed +# with a de-emphasized `prefix`. Used for the node-1 tests, whose output does not flow +# through Distributed's worker-output redirection (and so its `worker_output_hook`). +# `prefix` is styled with `StyledStrings`, so it is only colorized when `io` supports it. +function with_output_prefix(f, prefix::AbstractString, io::IO, lock::ReentrantLock) + pipe = Pipe() + Base.link_pipe!(pipe; reader_supports_async=true, writer_supports_async=true) + + reader_task = @async while !eof(pipe) + line = readline(pipe; keep=true) + @lock lock begin + print(io, styled"{bright_black: $prefix: }") + print(io, line) + endswith(line, '\n') || println(io) + end + end + + try + redirect_stdio(; stdout=pipe, stderr=pipe) do + f() + end + finally + close(pipe.in) + wait(reader_task) + close(pipe) + end +end + (; tests, net_on, exit_on_error, use_revise, buildroot, seed) = choosetests(ARGS) tests = unique(tests) @@ -161,6 +190,19 @@ cd(@__DIR__) do stderr.lock = print_lock end + # Track which test each worker is currently running (worker id => test name), so + # that worker output can be labeled with the test rather than just the worker id. + worker_current_test = Dict{Int, String}() + + # Transform each line of worker output into a de-emphasized, test-labeled prefix. + # Distributed still owns the actual printing; see `Distributed.worker_output_hook`. + Distributed.worker_output_hook[] = (ident, line) -> begin + wrkr_id = tryparse(Int, ident) + test_name = wrkr_id === nothing ? nothing : get(worker_current_test, wrkr_id, nothing) + label = test_name === nothing ? "From worker $ident" : "$test_name ($ident)" + return styled"{bright_black: $label: }$line" + end + function print_testworker_stats(test, wrkr, resp) @nospecialize resp lock(print_lock) @@ -272,6 +314,7 @@ cd(@__DIR__) do test = popfirst!(tests) running_tests[test] = now() wrkr = p + worker_current_test[wrkr] = test # Create a timer for this test to report long-running status test_timers[test] = Timer(longrunning_delay, interval=longrunning_interval) do timer @@ -308,6 +351,7 @@ cd(@__DIR__) do Any[CapturedException(e, catch_backtrace())], time() - before end delete!(running_tests, test) + delete!(worker_current_test, wrkr) if haskey(test_timers, test) close(test_timers[test]) delete!(test_timers, test) @@ -365,8 +409,10 @@ cd(@__DIR__) do t == "SharedArrays" && (isolate = false) before = time() resp, duration = try - r = @invokelatest runtests(t, test_path(t), isolate, seed=seed) # runtests is defined by the include above - r, time() - before + with_output_prefix("$t (1)", stdout, print_lock) do + r = @invokelatest runtests(t, test_path(t), isolate, seed=seed) # runtests is defined by the include above + r, time() - before + end catch e isa(e, InterruptException) && rethrow() Any[CapturedException(e, catch_backtrace())], time() - before @@ -399,6 +445,7 @@ cd(@__DIR__) do if @isdefined test_timers foreach(close, values(test_timers)) end + Distributed.worker_output_hook[] = nothing end #= From 63d1d8acb5604fd1cb830047b597eb32e1a733f8 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 16 Jul 2026 11:04:27 -0400 Subject: [PATCH 2/2] stdlib: bump Distributed to the worker_output_hook branch Point the bundled Distributed at JuliaLang/Distributed.jl#157, which adds the internal `worker_output_hook` used by the test harness. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/Distributed.version | 4 ++-- 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/md5 create mode 100644 deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/sha512 delete mode 100644 deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/md5 delete mode 100644 deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/sha512 diff --git a/deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/md5 b/deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/md5 new file mode 100644 index 0000000000000..3eda97501cbb8 --- /dev/null +++ b/deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/md5 @@ -0,0 +1 @@ +c41a5090f7bbfcee8810cb4edc3ec585 diff --git a/deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/sha512 b/deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/sha512 new file mode 100644 index 0000000000000..43483aa3a3acf --- /dev/null +++ b/deps/checksums/Distributed-14f81291c8a60ca4c6a1d78cf372ba45017b7e47.tar.gz/sha512 @@ -0,0 +1 @@ +6d8f734d7068c38634bc79be32dd1eddc39e46361b0578028a4854feaffcbab22de1b36932e929582b0dc162c81345fdb6fe0aac90508f0f928b18a74de35e78 diff --git a/deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/md5 b/deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/md5 deleted file mode 100644 index e62ea721075ef..0000000000000 --- a/deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -66a4594f6921c7f2ba4c8297ffc80150 diff --git a/deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/sha512 b/deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/sha512 deleted file mode 100644 index 6125c67f2243d..0000000000000 --- a/deps/checksums/Distributed-fde987fbb05c65bb6bd183396137383931107059.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -1c98cc4ae5c8e1200e402d54d3b6f546bec6cb38c29ed58b1ac36cd8572410870053c5bed297bb5215742e14268508f89f2d2324c306c57f6400b179dfe0a472 diff --git a/stdlib/Distributed.version b/stdlib/Distributed.version index 3780365f38b42..ca12d4c3ab6dc 100644 --- a/stdlib/Distributed.version +++ b/stdlib/Distributed.version @@ -1,4 +1,4 @@ -DISTRIBUTED_BRANCH = master -DISTRIBUTED_SHA1 = fde987fbb05c65bb6bd183396137383931107059 +DISTRIBUTED_BRANCH = ib/worker_output_customization +DISTRIBUTED_SHA1 = 14f81291c8a60ca4c6a1d78cf372ba45017b7e47 DISTRIBUTED_GIT_URL := https://github.com/JuliaLang/Distributed.jl DISTRIBUTED_TAR_URL = https://api.github.com/repos/JuliaLang/Distributed.jl/tarball/$1