diff --git a/.buildkite/pipelines/experimental/0_webui.yml b/.buildkite/pipelines/experimental/0_webui.yml index 54dbbc59d42562..a49ecc56ee6cf9 100644 --- a/.buildkite/pipelines/experimental/0_webui.yml +++ b/.buildkite/pipelines/experimental/0_webui.yml @@ -21,4 +21,4 @@ steps: # verifies the treehash of the pipeline itself and the inputs listed in `inputs` # signed_pipelines: # - pipeline: .buildkite/pipelines/experimental/misc/foo_bar_baz.yml - # signature: "my_signature" + # signature_file: .buildkite/pipelines/experimental/misc/foo_bar_baz.yml.signature diff --git a/.buildkite/pipelines/main/launch_unsigned_builders.yml b/.buildkite/pipelines/main/launch_unsigned_builders.yml index 6e9f0f0d8fa23b..4353d3089d9ea2 100644 --- a/.buildkite/pipelines/main/launch_unsigned_builders.yml +++ b/.buildkite/pipelines/main/launch_unsigned_builders.yml @@ -23,7 +23,8 @@ steps: buildkite-agent pipeline upload .buildkite/pipelines/main/misc/embedding.yml buildkite-agent pipeline upload .buildkite/pipelines/main/misc/llvmpasses.yml - # Finally, we launch the platform builders (`package_*`) and (`tester_*`) in alphabetical order. - buildkite-agent pipeline upload .buildkite/pipelines/main/platforms/linux64.yml + # Finally, we launch all of the platform builders. + bash .buildkite/pipelines/main/platforms/platforms.sh package_linux + bash .buildkite/pipelines/main/platforms/platforms.sh tester_linux agents: queue: julia diff --git a/.buildkite/pipelines/main/platforms/linux64.yml b/.buildkite/pipelines/main/platforms/linux64.yml deleted file mode 100644 index ad5d32a20b3a03..00000000000000 --- a/.buildkite/pipelines/main/platforms/linux64.yml +++ /dev/null @@ -1,95 +0,0 @@ -agents: - queue: "julia" - # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing - sandbox.jl: "true" - os: "linux" - -steps: - - label: "package_linux64" - key: package_linux64 - plugins: - - JuliaCI/julia#v1: - # Drop default "registries" directory, so it is not persisted from execution to execution - persist_depot_dirs: packages,artifacts,compiled - version: 1.6 - - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz - rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" - uid: 1000 - gid: 1000 - workspaces: - # Include `/cache/repos` so that our `git` version introspection works. - - "/cache/repos:/cache/repos" - commands: | - echo "--- Print the short and long commit hashes" - SHORT_COMMIT_LENGTH=10 - SHORT_COMMIT=`echo $$BUILDKITE_COMMIT | cut -c1-$$SHORT_COMMIT_LENGTH` - JULIA_DIRECTORY_NAME="julia-$$SHORT_COMMIT" - JULIA_BINARYDIST_FILENAME=`make print-JULIA_BINARYDIST_FILENAME | cut -c27-` - ARTIFACT_FILE_EXTENSION="tar.gz" - ARTIFACT_FILENAME="$$JULIA_BINARYDIST_FILENAME.$$ARTIFACT_FILE_EXTENSION" - echo "The full commit is $$BUILDKITE_COMMIT" - echo "The Julia directory name will be $$JULIA_DIRECTORY_NAME" - echo "The artifact filename will be $$ARTIFACT_FILENAME" - - echo "--- Build Julia from source" - make -j 6 - make release - make install - - echo "--- Make sure that the working directory is clean" - if [ -z "$(git status --short)" ]; then echo "INFO: The working directory is clean."; else echo "ERROR: The working directory is dirty."; echo "Output of git status:"; git status; exit 1; fi - - echo "--- Print Julia version info" - ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' - - echo "--- Compress build artifacts" - ls -ld $$JULIA_DIRECTORY_NAME/ - rm -rf $$ARTIFACT_FILENAME - tar czf $$ARTIFACT_FILENAME $$JULIA_DIRECTORY_NAME/ - ls -l $$ARTIFACT_FILENAME - - echo "--- Upload build artifacts" - buildkite-agent artifact upload $$ARTIFACT_FILENAME - timeout_in_minutes: 60 - notify: - - github_commit_status: - context: "package_linux64" - - # TODO: uncomment the following lines in order to enable the `tester_linux64` builder - # - label: "tester_linux64" - # key: tester_linux64 - # depends_on: package_linux64 - # plugins: - # - JuliaCI/julia#v1: - # version: 1.6 - # - staticfloat/sandbox#v1: - # # TODO: use a separate `tester_linux` image, instead of using the `package_linux` image. - # rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz - # rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" - # uid: 1000 - # gid: 1000 - # workspaces: - # # Include `/cache/repos` so that our `git` version introspection works. - # - "/cache/repos:/cache/repos" - # env: - # JULIA_SHELL: "/bin/bash" - # commands: | - # echo "--- Download build artifacts" - # rm -rf julia-linux64.tar.gz - # buildkite-agent artifact download julia-linux64.tar.gz . - # - # echo "--- Extract build artifacts" - # rm -rf julia-artifact/ - # tar xzf julia-linux64.tar.gz julia-artifact/ - # - # echo "--- Print Julia version info" - # julia-artifact/bin/julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' - # - # echo "--- Run the Julia test suite" - # unset JULIA_DEPOT_PATH - # julia-artifact/bin/julia .buildkite/utilities/rr/rr_capture.jl julia-artifact/bin/julia -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)' - # timeout_in_minutes: 120 - # notify: - # - github_commit_status: - # context: "tester_linux64" diff --git a/.buildkite/pipelines/main/platforms/package_linux.arches b/.buildkite/pipelines/main/platforms/package_linux.arches new file mode 100644 index 00000000000000..d83bd798242acc --- /dev/null +++ b/.buildkite/pipelines/main/platforms/package_linux.arches @@ -0,0 +1,6 @@ +# ARCH ARCH_LABEL ROOTFS_ARCH TIMEOUT ROOTFS_TAG ROOTFS_TREE +# aarch64 aarch64 aarch64 60 v3.2 0566841e29f0f9880541c26a6595fd5ce0beb5ff +# armv7l armv7l armv7l 60 v3.2 fb359370b052a47ce5c84cc6b4a7a03ed7053b25 +32 32 i686 60 v3.2 209c4db679a515befd7fb50ecc6bfbecf7ec3d32 +# ppc64le ppc64le powerpc64le 60 v3.2 c03a0158b19d48ac84b426834fce0d3584cdd0c7 +64 64 x86_64 60 v3.2 474bf61a926b2d7fcf202284d59d4b11a04601d7 diff --git a/.buildkite/pipelines/main/platforms/package_linux.yml b/.buildkite/pipelines/main/platforms/package_linux.yml new file mode 100644 index 00000000000000..2df1cdf61aef74 --- /dev/null +++ b/.buildkite/pipelines/main/platforms/package_linux.yml @@ -0,0 +1,53 @@ +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "package_linux$ARCH_LABEL" + key: package_linux$ARCH_LABEL + plugins: + - JuliaCI/julia#v1: + # Drop default "registries" directory, so it is not persisted from execution to execution + persist_depot_dirs: packages,artifacts,compiled + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/$ROOTFS_TAG/package_linux.${ROOTFS_ARCH}.tar.gz + rootfs_treehash: "$ROOTFS_TREE" + uid: 1000 + gid: 1000 + workspaces: + # Include `/cache/repos` so that our `git` version introspection works. + - "/cache/repos:/cache/repos" + timeout_in_minutes: $TIMEOUT + notify: + - github_commit_status: + context: "package_linux$ARCH_LABEL" + commands: | + echo "--- Print the full and short commit hashes" + SHORT_COMMIT_LENGTH=10 + SHORT_COMMIT=`echo $$BUILDKITE_COMMIT | cut -c1-$$SHORT_COMMIT_LENGTH` + JULIA_BINARYDIST_FILENAME=`make print-JULIA_BINARYDIST_FILENAME | cut -c27-` + ARTIFACT_FILE_EXTENSION="tar.gz" + ARTIFACT_FILENAME="$$JULIA_BINARYDIST_FILENAME.$$ARTIFACT_FILE_EXTENSION" + echo "The full commit is: $$BUILDKITE_COMMIT" + echo "The short commit is: $$SHORT_COMMIT" + echo "The artifact filename will be: $$ARTIFACT_FILENAME" + + echo "--- Build Julia from source" + rm -rf $$ARTIFACT_FILENAME + make -j 8 + + echo "--- Make sure that the working directory is clean" + if [ -z "$(git status --short)" ]; then echo "INFO: The working directory is clean."; else echo "ERROR: The working directory is dirty."; echo "Output of git status:"; git status; exit 1; fi + + echo "--- Print Julia version info" + ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + + echo "--- Create build artifacts" + make -j 8 binary-dist + ls -l $$ARTIFACT_FILENAME + + echo "--- Upload build artifacts" + buildkite-agent artifact upload $$ARTIFACT_FILENAME diff --git a/.buildkite/pipelines/main/platforms/platforms.sh b/.buildkite/pipelines/main/platforms/platforms.sh new file mode 100755 index 00000000000000..d58daeb2a9929c --- /dev/null +++ b/.buildkite/pipelines/main/platforms/platforms.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +PLATFORM="$1" + +cat "$SCRIPT_DIR/$PLATFORM.arches" | tr -s ' ' | while read _line; do + # Remove whitespace from the beginning and end of each line + line=`echo $_line | tr -s ' '` + + # Skip all lines that begin with `#` + if [[ $line == \#* ]]; then + continue + fi + + export ARCH=`echo $line | cut -d ' ' -f 1` + export ARCH_LABEL=`echo $line | cut -d ' ' -f 2` + export ROOTFS_ARCH=`echo $line | cut -d ' ' -f 3` + export TIMEOUT=`echo $line | cut -d ' ' -f 4` + export ROOTFS_TAG=`echo $line | cut -d ' ' -f 5` + export ROOTFS_TREE=`echo $line | cut -d ' ' -f 6` + echo "Launching: $PLATFORM $ARCH $ARCH_LABEL $ROOTFS_ARCH $TIMEOUT" + buildkite-agent pipeline upload "$SCRIPT_DIR/$PLATFORM.yml" +done diff --git a/.buildkite/pipelines/main/platforms/tester_linux.arches b/.buildkite/pipelines/main/platforms/tester_linux.arches new file mode 100644 index 00000000000000..a0527722cfb866 --- /dev/null +++ b/.buildkite/pipelines/main/platforms/tester_linux.arches @@ -0,0 +1,9 @@ +# ARCH ARCH_LABEL ROOTFS_ARCH TIMEOUT ROOTFS_TAG ROOTFS_TREE +# aarch64 aarch64 aarch64 60 v3.2 0566841e29f0f9880541c26a6595fd5ce0beb5ff +# armv7l armv7l armv7l 60 v3.2 fb359370b052a47ce5c84cc6b4a7a03ed7053b25 +32 32 i686 60 v3.2 209c4db679a515befd7fb50ecc6bfbecf7ec3d32 +# ppc64le ppc64le powerpc64le 60 v3.2 c03a0158b19d48ac84b426834fce0d3584cdd0c7 +64 64_mt x86_64 60 v3.2 474bf61a926b2d7fcf202284d59d4b11a04601d7 +64 64_st x86_64 60 v3.2 474bf61a926b2d7fcf202284d59d4b11a04601d7 +64 64_rr_mt x86_64 180 v3.2 474bf61a926b2d7fcf202284d59d4b11a04601d7 +64 64_rr_st x86_64 180 v3.2 474bf61a926b2d7fcf202284d59d4b11a04601d7 diff --git a/.buildkite/pipelines/main/platforms/tester_linux.yml b/.buildkite/pipelines/main/platforms/tester_linux.yml new file mode 100644 index 00000000000000..ec8b37da960988 --- /dev/null +++ b/.buildkite/pipelines/main/platforms/tester_linux.yml @@ -0,0 +1,67 @@ +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "tester_linux$ARCH_LABEL" + key: tester_linux$ARCH_LABEL + depends_on: package_linux$ARCH + plugins: + - JuliaCI/julia#v1: + # Drop default "registries" directory, so it is not persisted from execution to execution + persist_depot_dirs: packages,artifacts,compiled + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/$ROOTFS_TAG/package_linux.${ROOTFS_ARCH}.tar.gz + rootfs_treehash: "$ROOTFS_TREE" + uid: 1000 + gid: 1000 + workspaces: + # Include `/cache/repos` so that our `git` version introspection works. + - "/cache/repos:/cache/repos" + env: + JULIA_SHELL: "/bin/bash" + timeout_in_minutes: $TIMEOUT + notify: + - github_commit_status: + context: "tester_linux$ARCH_LABEL" + commands: | + echo "--- Print the full and short commit hashes" + SHORT_COMMIT_LENGTH=10 + SHORT_COMMIT=`echo $$BUILDKITE_COMMIT | cut -c1-$$SHORT_COMMIT_LENGTH` + JULIA_DIR="julia-$$SHORT_COMMIT" + JULIA_BINARY="$$JULIA_DIR/bin/julia" + ARTIFACT_FILE_EXTENSION="tar.gz" + ARTIFACT_FILENAME="julia-$$SHORT_COMMIT-linux$ARCH.$$ARTIFACT_FILE_EXTENSION" + echo "The full commit is: $$BUILDKITE_COMMIT" + echo "The short commit is: $$SHORT_COMMIT" + echo "The artifact filename will be: $$ARTIFACT_FILENAME" + echo "The Julia directory name will be: $$JULIA_DIR" + echo "The Julia binary will be: $$JULIA_BINARY" + + echo "--- Download build artifacts" + rm -rf $$ARTIFACT_FILENAME + buildkite-agent artifact download $$ARTIFACT_FILENAME . + + echo "--- Extract build artifacts" + rm -rf $$JULIA_DIR/ + tar xzf $$ARTIFACT_FILENAME $$JULIA_DIR/ + + echo "--- Print Julia version info" + $$JULIA_BINARY -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + + echo "--- Run the Julia test suite" + unset JULIA_DEPOT_PATH + # TODO: do not skip any test sets + if [[ "$$BUILDKITE_STEP_KEY" == "tester_linux64_rr_mt" ]]; then + $$JULIA_BINARY .buildkite/utilities/rr/buildkite.jl $$JULIA_BINARY -e 'Base.runtests(["all", "--skip", "cmdlineargs"]; ncores = parse(Int, ENV["JULIA_RRCAPTURE_NUM_CORES"]))' + elif [[ "$$BUILDKITE_STEP_KEY" == "tester_linux64_rr_st" ]]; then + $$JULIA_BINARY .buildkite/utilities/rr/buildkite.jl $$JULIA_BINARY -e 'Base.runtests(["all"]; ncores = parse(Int, ENV["JULIA_RRCAPTURE_NUM_CORES"]))' + elif [[ "$$BUILDKITE_STEP_KEY" == "tester_linux64_st" ]]; then + export JULIA_NUM_THREADS=1 + $$JULIA_BINARY -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)' + else + $$JULIA_BINARY -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)' + fi diff --git a/.buildkite/utilities/rr/buildkite.jl b/.buildkite/utilities/rr/buildkite.jl new file mode 100644 index 00000000000000..6a0ba2e5c1cc01 --- /dev/null +++ b/.buildkite/utilities/rr/buildkite.jl @@ -0,0 +1,53 @@ +if length(ARGS) < 1 + throw(ErrorException("Usage: julia $(basename(@__FILE__)) [command...]")) +end + +const is_buildkite = tryparse(Bool, lowercase(strip(get(ENV, "BUILDKITE", "")))) === true +if !is_buildkite + msg = string( + "The `$(basename(@__FILE__))` script only works on Buildkite. ", + "If you are running locally, you should use the `rr_capture.jl` script instead.", + ) + throw(ErrorException(msg)) +end + +# We only use `rr` on certain Buildkite jobs +const rr_job_list = String[ + # "tester_linux64", + "tester_linux64_rr", + "tester_linux64_rr_mt", + "tester_linux64_rr_st", +] +const this_job = ENV["BUILDKITE_STEP_KEY"] + +if !(this_job in rr_job_list) + @info "We will not run the tests under rr" this_job rr_job_list + run(`$ARGS`) + @info "Finished running the tests (not under rr)" + exit(0) +end + +@info "This Buildkite job is in the list of `rr` jobs" this_job rr_job_list + +const env_mappings = Dict{String, String}() +env_mappings["JULIA_RRCAPTURE_BUILD_NUMBER"] = ENV["BUILDKITE_BUILD_NUMBER"] +env_mappings["JULIA_RRCAPTURE_COMMIT"] = ENV["BUILDKITE_COMMIT"] +env_mappings["JULIA_RRCAPTURE_JOB_NAME"] = this_job +env_mappings["JULIA_RRCAPTURE_IS_BUILDKITE"] = "true" + +const single_threaded_rr_jobs = String[ + "tester_linux64_rr_st" +] +if this_job in single_threaded_rr_jobs + @info "Setting JULIA_NUM_THREADS to 1" + env_mappings["JULIA_NUM_THREADS"] = "1" +end + +rr_capture = joinpath(@__DIR__, "rr_capture.jl") + +cmd = addenv( + `$(Base.julia_cmd().exec[1]) $(rr_capture) $ARGS`, + env_mappings, +) + +run(cmd) diff --git a/.buildkite/utilities/rr/rr_capture.jl b/.buildkite/utilities/rr/rr_capture.jl index 07d57f31ff29cf..02ee275455be66 100644 --- a/.buildkite/utilities/rr/rr_capture.jl +++ b/.buildkite/utilities/rr/rr_capture.jl @@ -1,44 +1,113 @@ -using Dates -using Pkg -using Tar +import Dates +import Pkg +import Tar + +function my_exit(process::Base.Process) + wait(process) + + @info( + "", + process.exitcode, + process.termsignal, + success(process), + Base.process_signaled(process), + ) + + # Pass the exit code back up + if process.termsignal != 0 + ccall(:raise, Cvoid, (Cint,), process.termsignal) + + # If for some reason the signal did not cause an exit, we'll exit manually. + # We need to make sure that we exit with a non-zero exit code. + if process.exitcode != 0 + exit(process.exitcode) + else + exit(1) + end + end + exit(process.exitcode) +end -if Base.VERSION < v"1.6" - throw(ErrorException("The `rr_capture.jl` script requires Julia 1.6 or greater")) +function directory_has_files(dir::AbstractString) + if !isabspath(dir) + throw(ArgumentError("The directory path must be an absolute path")) + end + if !isdir(dir) + throw(ArgumentError("`$(dir)` is not a directory")) + end + + for (root, dirs, files) in walkdir(dir) + for file in files + return true + end + end + return false end if length(ARGS) < 1 - throw(ErrorException("Usage: rr_capture.jl [command...]")) + throw(ErrorException("Usage: julia $(basename(@__FILE__)) [command...]")) +end +if Base.VERSION < v"1.6" + throw(ErrorException("The `$(basename(@__FILE__))` script requires Julia 1.6 or greater")) end -const TIMEOUT = 2 * 60 * 60 # timeout in seconds - -# We only use `rr` on the `tester_linux64` builder -const use_rr_if_builder_is = "tester_linux64" - -const run_id = get(ENV, "BUILDKITE_JOB_ID", "unknown") -const shortcommit = get(ENV, "BUILDKITE_COMMIT", "unknown") -const builder = get(ENV, "BUILDKITE_STEP_KEY", use_rr_if_builder_is) -const use_rr = builder == use_rr_if_builder_is +@info "We will run the tests under rr" -@info "" run_id shortcommit builder use_rr -@info "" ARGS +const JULIA_RRCAPTURE_BUILD_NUMBER = get(ENV, "JULIA_RRCAPTURE_BUILD_NUMBER", "unknownbuildnumber") +const JULIA_RRCAPTURE_IS_BUILDKITE = get(ENV, "JULIA_RRCAPTURE_IS_BUILDKITE", "false") +const JULIA_RRCAPTURE_JOB_NAME = get(ENV, "JULIA_RRCAPTURE_JOB_NAME", "unknownjobname") +const JULIA_RRCAPTURE_TIMEOUT_MINUTES = get(ENV, "JULIA_RRCAPTURE_TIMEOUT_MINUTES", "120") +const JULIA_TEST_NUM_CORES = get(ENV, "JULIA_TEST_NUM_CORES", "8") -# if !use_rr # TODO: uncomment this line -if true # TODO: delete this line - @info "We will not run the tests under rr" - p = run(`$ARGS`) - exit(p.exitcode) +if haskey(ENV, "JULIA_RRCAPTURE_COMMIT") + const JULIA_RRCAPTURE_COMMIT = ENV["JULIA_RRCAPTURE_COMMIT"] + const julia_rrcapture_commit_short = first(JULIA_RRCAPTURE_COMMIT, 10) +else + const JULIA_RRCAPTURE_COMMIT = "unknowncommit" + const julia_rrcapture_commit_short = "unknowncommit" end -@info "We will run the tests under rr" - -const num_cores = min(Sys.CPU_THREADS, 8, parse(Int, get(ENV, "JULIA_TEST_NUM_CORES", "8")) + 1) -@info "" num_cores +@info "ENV[\"JULIA_RRCAPTURE_BUILD_NUMBER\"] = \"$(JULIA_RRCAPTURE_BUILD_NUMBER)\"" +@info "ENV[\"JULIA_RRCAPTURE_COMMIT\"] = \"$(JULIA_RRCAPTURE_COMMIT)\"" +@info "ENV[\"JULIA_RRCAPTURE_IS_BUILDKITE\"] = \"$(JULIA_RRCAPTURE_IS_BUILDKITE)\"" +@info "ENV[\"JULIA_RRCAPTURE_JOB_NAME\"] = \"$(JULIA_RRCAPTURE_JOB_NAME)\"" +@info "ENV[\"JULIA_RRCAPTURE_TIMEOUT_MINUTES\"] = \"$(JULIA_RRCAPTURE_TIMEOUT_MINUTES)\"" +@info "ENV[\"JULIA_TEST_NUM_CORES\"] = \"$(JULIA_TEST_NUM_CORES)\"" + +const build_number = JULIA_RRCAPTURE_BUILD_NUMBER +const commit_full = JULIA_RRCAPTURE_COMMIT +const commit_short = julia_rrcapture_commit_short +const is_buildkite = parse(Bool, JULIA_RRCAPTURE_IS_BUILDKITE) +const job_name = JULIA_RRCAPTURE_JOB_NAME +const julia_test_num_cores_int = parse(Int, JULIA_TEST_NUM_CORES) +const num_cores = min( + 8, + Sys.CPU_THREADS, + julia_test_num_cores_int + 1, +) +const timeout_minutes = parse(Int, JULIA_RRCAPTURE_TIMEOUT_MINUTES) + +ENV["JULIA_RRCAPTURE_NUM_CORES"] = "$(num_cores)" + +@info( + "", + build_number, + commit_full, + commit_short, + is_buildkite, + job_name, + num_cores, + timeout_minutes, +) + +const dumps_dir = joinpath(pwd(), "dumps") +const temp_parent_dir = joinpath(pwd(), "temp_for_rr") +mkpath(dumps_dir) +mkpath(temp_parent_dir) proc = nothing -new_env = copy(ENV) -mktempdir() do dir +mktempdir(temp_parent_dir) do dir Pkg.activate(dir) Pkg.add("rr_jll") Pkg.add("Zstd_jll") @@ -68,18 +137,22 @@ mktempdir() do dir # Start asynchronous timer that will kill `rr` @async begin - sleep(TIMEOUT) + sleep(timeout_minutes * 60) # If we've exceeded the timeout and `rr` is still running, kill it. if isopen(proc) - println(stderr, "\n\nProcess timed out. Signalling `rr` for force-cleanup!") + println(stderr, "\n\nProcess timed out (with a timeout of $(timeout_minutes) minutes). Signalling `rr` for force-cleanup!") kill(proc, Base.SIGTERM) - # Give `rr` a chance to cleanup - sleep(60) + # Give `rr` a chance to cleanup and upload. + # Note: this time period includes the time to upload the `rr` trace files + # as Buildkite artifacts, so make sure it is long enough to allow the + # uploads to finish. + cleanup_minutes = 30 + sleep(cleanup_minutes * 60) if isopen(proc) - println(stderr, "\n\n`rr` failed to cleanup within one minute, killing and exiting immediately!") + println(stderr, "\n\n`rr` failed to cleanup and upload within $(cleanup_minutes) minutes, killing and exiting immediately!") kill(proc, Base.SIGKILL) exit(1) end @@ -87,11 +160,11 @@ mktempdir() do dir end # Wait for `rr` to finish, either through naturally finishing its run, or `SIGTERM`. - # If we have to `SIGKILL` wait(proc) # On a non-zero exit code, upload the `rr` trace - if !success(proc) + # if !success(proc) + if true println(stderr, "`rr` returned $(proc.exitcode), packing and uploading traces...") if !isdir(joinpath(dir, "rr_traces")) @@ -113,9 +186,12 @@ mktempdir() do dir run(ignorestatus(`$(rr_path) pack --pack-dir=$pack_dir $(trace_dirs)`)) # Tar it up - mkpath("dumps") - datestr = Dates.format(now(), dateformat"yyyy-mm-dd_HH_MM_SS") - dst_path = "dumps/rr-run_$(run_id)-gitsha_$(shortcommit)-$(datestr).tar.zst" + mkpath(dumps_dir) + date_str = Dates.format(Dates.now(), Dates.dateformat"yyyy_mm_dd_HH_MM_SS") + dst_path = joinpath( + dumps_dir, + "rr--build_$(build_number)--gitsha_$(commit_short)--$(job_name)--$(date_str).tar.zst", + ) zstd_jll.zstdmt() do zstdp tarproc = open(`$zstdp -o $dst_path`, "w") Tar.create(dir, tarproc) @@ -125,10 +201,23 @@ mktempdir() do dir end end -# Pass the exit code back up to Buildkite -if proc.termsignal != 0 - ccall(:raise, Cvoid, (Cint,), proc.termsignal) - exit(1) # Just in case the signal did not cause an exit +if directory_has_files(dumps_dir) + @info "There are one or more `rr` trace files" + for (root, dirs, files) in walkdir(dumps_dir) + for file in files + full_path_to_file = joinpath(root, file) + if is_buildkite + cd(root) do + run(`buildkite-agent artifact upload $(file)`) + end + else + @info "Found `rr` trace file: $(full_path_to_file)" + end + end + end else - exit(proc.exitcode) + @info "There are no `rr` trace files" end + +@info "Finished running the tests under rr" +my_exit(proc)