Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory issues #65

Open
epolack opened this issue Mar 8, 2024 · 2 comments
Open

Memory issues #65

epolack opened this issue Mar 8, 2024 · 2 comments

Comments

@epolack
Copy link

epolack commented Mar 8, 2024

When using TestItemRunner interactively, there are memory issues that I cannot solve.

@testitem "tt" begin
    a = ones(1000, 1000, 1000)
end

If I run @run_package_tests multiple times, then the memory fills up to crashing the computer.
To keep it low, I need to manually set the variable to nothing:

@testitem "tt" begin
    a = ones(1000, 1000, 1000)
    a = nothing
end

This does not happen for example with

using Test
@testset "tt" begin
    a = ones(1000, 1000, 1000)
end
@davidanthoff
Copy link
Member

We create a new module every time you run a test, and I think they stick around... I think (but not sure) there is no way in Julia to unload a module, but I might be wrong. Maybe we could do something to iterate over all global names in a module that is no longer needed and at least set all mutable global variables to something like nothing so that some memory is freed? Not sure...

@epolack
Copy link
Author

epolack commented Mar 8, 2024

This seems to work:

using TestItemRunner

function TestItemRunner.run_testitem(filepath, use_default_usings, setups, package_name, original_code, line, column, test_setup_module_set)
    # with fixed module name (no gensym)
    mod = Core.eval(Main, :(module AA end))

    if use_default_usings
        Core.eval(mod, :(using Test))

        if package_name!=""
            Core.eval(mod, :(using $(Symbol(package_name))))
        end
    end

    for m in setups
        Core.eval(mod, Expr(:using, Expr(:., :., :., nameof(test_setup_module_set.setupmodule), m)))
    end

    code = string('\n'^line, ' '^column, original_code)

    TestItemRunner.withpath(filepath) do
        Base.invokelatest(include_string, mod, code, filepath)
    end

    for name in names(Main.AA; all=true)
        contains("$(name)", "#") && continue
        eval(:(Main.AA.$name isa Function ? Base.delete_method.(methods(Main.AA.$name)) : Main.AA.$name isa Module || (Main.AA.$name = nothing)))
    end
end

@testitem "tt" begin
    a = ones(1000, 1000, 100)
end

@run_package_tests

I do not know how to use the gensymed name. So far I got something like this:

using TestItemRunner

function TestItemRunner.run_testitem(filepath, use_default_usings, setups, package_name, original_code, line, column, test_setup_module_set)
    mod = Core.eval(Main, :(module $(gensym()) end))

    if use_default_usings
        Core.eval(mod, :(using Test))

        if package_name!=""
            Core.eval(mod, :(using $(Symbol(package_name))))
        end
    end

    for m in setups
        Core.eval(mod, Expr(:using, Expr(:., :., :., nameof(test_setup_module_set.setupmodule), m)))
    end

    code = string('\n'^line, ' '^column, original_code)

    TestItemRunner.withpath(filepath) do
        Base.invokelatest(include_string, mod, code, filepath)
    end

    for name in names(mod; all=true)
        contains("$(name)", "#") && continue
        "$(name)" == "eval" && continue
        "$(name)" == "include" && continue
        setproperty!(mod, name, nothing)
    end
end

@testitem "tt" begin
    a = ones(1000, 1000, 100)
end

@run_package_tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants