|
| 1 | +# This file is a part of Julia. License is MIT: https://julialang.org/license |
| 2 | + |
| 3 | +# Test that interactive mode starts up without error when history file is bad |
| 4 | + |
| 5 | +using Test |
| 6 | + |
| 7 | +const BASE_TEST_PATH = joinpath(Sys.BINDIR, "..", "share", "julia", "test") |
| 8 | +isdefined(Main, :FakePTYs) || @eval Main include(joinpath($(BASE_TEST_PATH), "testhelpers", "FakePTYs.jl")) |
| 9 | +import .Main.FakePTYs: with_fake_pty |
| 10 | + |
| 11 | +@testset "Bad history file startup" begin |
| 12 | + mktempdir() do tmpdir |
| 13 | + # Create a bad history file |
| 14 | + hist_file = joinpath(tmpdir, "repl_history.jl") |
| 15 | + write(hist_file, "{ invalid json content\nmore bad content\n") |
| 16 | + |
| 17 | + julia_exe = Base.julia_cmd()[1] |
| 18 | + |
| 19 | + # Test interactive Julia startup with bad history file |
| 20 | + with_fake_pty() do pts, ptm |
| 21 | + # Set up environment with our bad history file |
| 22 | + nENV = copy(ENV) |
| 23 | + nENV["JULIA_HISTORY"] = hist_file |
| 24 | + |
| 25 | + # Start Julia in interactive mode |
| 26 | + p = run(detach(setenv(`$julia_exe --startup-file=no --color=no -q`, nENV)), pts, pts, pts, wait=false) |
| 27 | + Base.close_stdio(pts) |
| 28 | + |
| 29 | + # Read output until we get the prompt, which indicates successful startup |
| 30 | + output = readuntil(ptm, "julia> ", keep=true) |
| 31 | + # println("====== subprocess output ======") |
| 32 | + # println(output) |
| 33 | + # println("====== end subprocess output ======") |
| 34 | + |
| 35 | + # Test conditions: |
| 36 | + # 1. We should see the invalid history file error |
| 37 | + has_history_error = occursin("Invalid history file", output) || |
| 38 | + occursin("Invalid character", output) |
| 39 | + @test has_history_error |
| 40 | + |
| 41 | + # 2. We should NOT see UndefRefError (the bug being fixed) |
| 42 | + has_undef_error = occursin("UndefRefError", output) |
| 43 | + @test !has_undef_error |
| 44 | + |
| 45 | + # 3. We should see the "Disabling history file" message if the fix works |
| 46 | + has_disable_message = occursin("Disabling history file for this session", output) |
| 47 | + @test has_disable_message |
| 48 | + |
| 49 | + # Send exit command to clean shutdown |
| 50 | + if isopen(ptm) |
| 51 | + write(ptm, "exit()\n") |
| 52 | + else |
| 53 | + @warn "PTY master is already closed before sending exit command" |
| 54 | + end |
| 55 | + |
| 56 | + # Read any remaining output until the process exits |
| 57 | + try |
| 58 | + read(ptm, String) |
| 59 | + catch ex |
| 60 | + # Handle platform-specific EOF behavior |
| 61 | + if ex isa Base.IOError && ex.code == Base.UV_EIO |
| 62 | + # This is expected on some platforms (e.g., Linux) |
| 63 | + else |
| 64 | + rethrow() |
| 65 | + end |
| 66 | + end |
| 67 | + |
| 68 | + # Wait for process to finish |
| 69 | + wait(p) |
| 70 | + |
| 71 | + @test p.exitcode == 0 |
| 72 | + end |
| 73 | + end |
| 74 | +end |
0 commit comments