diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acf2ffc7c2..743ed87fc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,10 +14,10 @@ jobs: fail-fast: false matrix: version: - - "1.6" + - "1.6" # LTS (64-bit Linux) - "1.7" - "1.8" - - '1' # latest stable 1.x Julia release (Linux) + - '1' # latest stable 1.x Julia release (Linux) os: - ubuntu-latest arch: @@ -29,19 +29,19 @@ jobs: allow_failure: true steps: - uses: actions/checkout@v3 - - name: Create a new branch for test logs + - name: Create a new branch and pull test logs from repo run: | - if [[ ${{ matrix.version }} == '1' ]]; then - git config --local user.name lbonaldo - git config --local user.email "39280783+lbonaldo@users.noreply.github.com" - git checkout -b ${GITHUB_REF#refs/heads/}-testlogs - git ls-remote --exit-code --heads origin ${GITHUB_REF#refs/heads/}-testlogs - if [ "$?" == "2" ] ; then # exit-code 2 if the branch doesn't exist - echo "Branch doesn't exist. Skip fetching." - else # if a branch exists, fetch it - git fetch origin ${GITHUB_REF#refs/heads/}-testlogs - git cherry-pick $(git log -n 1 origin/${GITHUB_REF#refs/heads/}-testlogs --pretty=format:"%H") - fi + git checkout -b ${GITHUB_REF#refs/heads/}-testlogs + mkdir test/Logs; cd test/Logs + git init + git config --local user.name GenXProject + git config --local user.email "84470580+GenXProject@users.noreply.github.com" + git remote add testlog https://github.com/GenXProject/GenX-testlog.git + git pull testlog main + if [ -d Logs_v${{ matrix.version }} ]; then + mv Logs_v${{ matrix.version }}/*.log . + else + mkdir Logs_v${{ matrix.version }} fi - uses: julia-actions/setup-julia@v1 with: @@ -50,13 +50,12 @@ jobs: - uses: julia-actions/cache@v1 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - - name: Commit logs and push to repo # only for 1.x versions + - name: Commit logs and push back to repo run: | - if [[ ${{ matrix.version }} == '1' ]]; then - git add -f test/Logs - git commit -m "Update test logs" - git push -f origin ${GITHUB_REF#refs/heads/}-testlogs - fi + mv *.log Logs_v${{ matrix.version }} + git add -f Logs_v${{ matrix.version }} + git commit -m "Update test logs for Julia v${{ matrix.version }}" + git push testlog main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: julia-actions/julia-processcoverage@v1 diff --git a/test/Logs/Electrolyzer.log b/test/Logs/Electrolyzer.log new file mode 100644 index 0000000000..8f5798d275 --- /dev/null +++ b/test/Logs/Electrolyzer.log @@ -0,0 +1,4 @@ +2023-10-11 02:37:37 | 6946.981912630803 ± 0.0001 | Test Passed + Expression: ≈(obj_test, obj_true, atol = optimal_tol) + Evaluated: ≈(6946.981912630803, 6946.9819126; atol = 0.0001) +2023-10-11 03:01:00 | 6946.981912630803 ± 0.0001 | Test Passed diff --git a/test/Logs/MethodofMorris.log b/test/Logs/MethodofMorris.log new file mode 100644 index 0000000000..dd23446d99 --- /dev/null +++ b/test/Logs/MethodofMorris.log @@ -0,0 +1,4 @@ +2023-10-11 02:37:51 | Build and Run | Test Broken + Expression: built +2023-10-11 03:01:13 | Build and Run | Test Broken + Expression: built diff --git a/test/Logs/MultiStage.log b/test/Logs/MultiStage.log new file mode 100644 index 0000000000..8f0ff0bb7e --- /dev/null +++ b/test/Logs/MultiStage.log @@ -0,0 +1,3 @@ +2023-10-11 02:38:03 | 79734.8003171703 ± 1.0e-5, 41630.03494225143 ± 1.0e-5, 27855.20631474678 ± 1.0e-5 | Test Passed + Expression: all(obj_true .- optimal_tol .<= obj_test .<= obj_true .+ optimal_tol) +2023-10-11 03:01:23 | 79734.80031717036 ± 1.0e-5, 41630.034942251485 ± 1.0e-5, 27855.206314746796 ± 1.0e-5 | Test Passed diff --git a/test/Logs/PiecewiseFuel_CO2.log b/test/Logs/PiecewiseFuel_CO2.log new file mode 100644 index 0000000000..7466c75b06 --- /dev/null +++ b/test/Logs/PiecewiseFuel_CO2.log @@ -0,0 +1,4 @@ +2023-10-11 02:36:57 | 2341.8230753008047 ± 1.0e-5 | Test Passed + Expression: ≈(obj_test, obj_true, atol = optimal_tol) + Evaluated: ≈(2341.8230753008047, 2341.8230753; atol = 1.0e-5) +2023-10-11 03:00:24 | 2341.8230753008047 ± 1.0e-5 | Test Passed diff --git a/test/Logs/VREStor.log b/test/Logs/VREStor.log new file mode 100644 index 0000000000..0c4a88778e --- /dev/null +++ b/test/Logs/VREStor.log @@ -0,0 +1,4 @@ +2023-10-11 02:37:34 | 92081.91504226513 ± 1.0e-5 | Test Passed + Expression: ≈(obj_test, obj_true, atol = optimal_tol) + Evaluated: ≈(92081.91504226513, 92081.915042; atol = 1.0e-5) +2023-10-11 03:00:57 | 92081.91504226513 ± 1.0e-5 | Test Passed diff --git a/test/runtests.jl b/test/runtests.jl index f2cd896b91..59093d9103 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,6 +17,10 @@ end include("expression_manipulation_test.jl") end +@testset "Utilities" begin + include("test_utilities.jl") +end + # Test GenX modules @testset verbose=true "GenX modules" begin @testset "Three zones" begin diff --git a/test/test_VREStor.jl b/test/test_VREStor.jl index cbc4ac7196..4ce9a9852f 100644 --- a/test/test_VREStor.jl +++ b/test/test_VREStor.jl @@ -3,7 +3,7 @@ module TestVREStor using Test include(joinpath(@__DIR__, "utilities.jl")) -obj_true = 9.2081915042e+04 +obj_true = 92081.91504 test_path = "VREStor" # Define test inputs @@ -41,6 +41,9 @@ end obj_test = objective_value(EP) optimal_tol = get_attribute(EP, "dual_feasibility_tolerance") +# Round the objective value to the same number of digits as the tolerance +obj_test = round_objfromtol!(obj_test, optimal_tol) + # Test the objective value test_result = @test obj_test ≈ obj_true atol=optimal_tol diff --git a/test/test_electrolyzer.jl b/test/test_electrolyzer.jl index c6e566f1fb..f8d7b0b8ba 100644 --- a/test/test_electrolyzer.jl +++ b/test/test_electrolyzer.jl @@ -4,7 +4,7 @@ using Test include(joinpath(@__DIR__, "utilities.jl")) -obj_true = 6.9469819126e+03 +obj_true = 6946.9819 test_path = "Electrolyzer" # Define test inputs @@ -38,6 +38,9 @@ end obj_test = objective_value(EP) optimal_tol = get_attribute(EP, "dual_feasibility_tolerance") +# Round the objective value to the same number of digits as the tolerance +obj_test = round_objfromtol!(obj_test, optimal_tol) + # Test the objective value test_result = @test obj_test ≈ obj_true atol=optimal_tol diff --git a/test/test_methodofmorris.jl b/test/test_methodofmorris.jl index c852054a90..bcf39cc5ff 100644 --- a/test/test_methodofmorris.jl +++ b/test/test_methodofmorris.jl @@ -8,7 +8,6 @@ test_path = "MethodofMorris" # Define test inputs genx_setup = Dict( - "MacOrWindows" => "Mac", "PrintModel" => 0, "NetworkExpansion" => 0, "Trans_Loss_Segments" => 1, diff --git a/test/test_multistage.jl b/test/test_multistage.jl index 510095aeab..73b9b5a659 100644 --- a/test/test_multistage.jl +++ b/test/test_multistage.jl @@ -4,7 +4,7 @@ using Test include(joinpath(@__DIR__, "utilities.jl")) -obj_true = [7.9734800317e+04, 4.1630034942e+04, 2.7855206315e+04] +obj_true = [79734.80032, 41630.03494, 27855.20632] test_path = "MultiStage" # Define test inputs @@ -51,6 +51,9 @@ end obj_test = objective_value.([EP[i] for i in 1:3]) optimal_tol = get_attribute.([EP[i] for i in 1:3], "dual_feasibility_tolerance") +# Round the objective value to the same number of digits as the tolerance +obj_test = round_objfromtol!.(obj_test, optimal_tol) + # Test the objective value test_result = @test all(obj_true .- optimal_tol .<= obj_test .<= obj_true .+ optimal_tol) diff --git a/test/test_piecewisefuel_CO2.jl b/test/test_piecewisefuel_CO2.jl index ef16208856..5271e3009e 100644 --- a/test/test_piecewisefuel_CO2.jl +++ b/test/test_piecewisefuel_CO2.jl @@ -3,7 +3,7 @@ module TestPiecewiseFuelCO2 using Test include(joinpath(@__DIR__, "utilities.jl")) -obj_true = 2.3418230753e+03 +obj_true = 2341.82308 test_path = "PiecewiseFuel_CO2" # Define test inputs @@ -34,6 +34,9 @@ end obj_test = objective_value(EP) optimal_tol = get_attribute(EP, "dual_feasibility_tolerance") +# Round the objective value to the same number of digits as the tolerance +obj_test = round_objfromtol!(obj_test, optimal_tol) + # Test the objective value test_result = @test obj_test ≈ obj_true atol=optimal_tol diff --git a/test/test_threezones.jl b/test/test_threezones.jl index a97c930baf..9755817f69 100644 --- a/test/test_threezones.jl +++ b/test/test_threezones.jl @@ -4,7 +4,7 @@ using Test include(joinpath(@__DIR__, "utilities.jl")) -obj_true = 6.9602085499e+03 +obj_true = 6960.20855 test_path = "ThreeZones" # Define test inputs @@ -43,6 +43,9 @@ end obj_test = objective_value(EP) optimal_tol = get_attribute(EP, "dual_feasibility_tolerance") +# Round the objective value to the same number of digits as the tolerance +obj_test = round_objfromtol!(obj_test, optimal_tol) + # Test the objective value test_result = @test obj_test ≈ obj_true atol=optimal_tol diff --git a/test/test_utilities.jl b/test/test_utilities.jl new file mode 100644 index 0000000000..38ef32de0a --- /dev/null +++ b/test/test_utilities.jl @@ -0,0 +1,39 @@ +module TestUtilities + +using Test + +include(joinpath(@__DIR__, "utilities.jl")) + +@testset "get_exponent_sciform" begin + @test get_exponent_sciform(0) == 0 + @test get_exponent_sciform(0.005) == -3 + @test get_exponent_sciform(0.0531) == -2 + @test get_exponent_sciform(1) == 0 + @test get_exponent_sciform(1.0000) == 0 + @test get_exponent_sciform(1.0005) == 0 + @test get_exponent_sciform(64.000) == 1 + @test get_exponent_sciform(64.03) == 1 + @test get_exponent_sciform(100) == 2 +end + +@testset "round_objfromtol" begin + @test round_objfromtol!(0, 0) == 0 + @test round_objfromtol!(0.005, 1) == 0 + @test round_objfromtol!(0.005, 0.1) == 0.0 + @test round_objfromtol!(0.005, 0.01) == 0.0 + @test round_objfromtol!(0.005, 0.001) == 0.005 + @test round_objfromtol!(0.005, 0.0001) == 0.005 + @test round_objfromtol!(1.005, 1) == 1 + @test round_objfromtol!(1.005, 0.1) == 1.0 + @test round_objfromtol!(1.005, 0.01) == 1.0 + @test round_objfromtol!(1.005, 0.001) == 1.005 + @test round_objfromtol!(2.006, 0.01) == 2.01 + @test round_objfromtol!(10.65, 10) == 10 + @test round_objfromtol!(10.65, 1) == 11 + @test round_objfromtol!(10.65, 0.1) == 10.6 + @test round_objfromtol!(10.65, 0.01) == 10.65 + @test round_objfromtol!(10.65, 0.001) == 10.65 +end + + +end # module TestUtilities \ No newline at end of file diff --git a/test/utilities.jl b/test/utilities.jl index f5290efa3e..4825025600 100644 --- a/test/utilities.jl +++ b/test/utilities.jl @@ -4,7 +4,7 @@ using Dates using Logging, LoggingExtras -const TestResult = Union{Test.Result, String} +const TestResult = Union{Test.Result,String} function run_genx_case_testing(test_path::AbstractString, genx_setup::Dict) @assert genx_setup["MultiStage"] ∈ [0, 1] @@ -56,17 +56,17 @@ end function write_testlog(test_path::AbstractString, message::AbstractString, test_result::TestResult) # Save the results to a log file - # Format: datetime, objective value, tolerance, test result + # Format: datetime, message, test result - if !isdir(joinpath("Logs")) - mkdir(joinpath("Logs")) + if !isdir("Logs") + mkdir("Logs") end log_file_path = joinpath("Logs", "$(test_path).log") logger = FormatLogger(open(log_file_path, "a")) do io, args # Write only if the test passed or failed - println(io, split(args.message,"\n")[1]) + println(io, split(args.message, "\n")[1]) end with_logger(logger) do @@ -76,12 +76,26 @@ function write_testlog(test_path::AbstractString, message::AbstractString, test_ end function write_testlog(test_path::AbstractString, obj_test::Real, optimal_tol::Real, test_result::TestResult) + # Save the results to a log file + # Format: datetime, objective value ± tolerance, test result message = "$obj_test ± $optimal_tol" write_testlog(test_path, message, test_result) end function write_testlog(test_path::AbstractString, obj_test::Vector{<:Real}, optimal_tol::Vector{<:Real}, test_result::TestResult) + # Save the results to a log file + # Format: datetime, [objective value ± tolerance], test result @assert length(obj_test) == length(optimal_tol) - message = join(join.(zip(obj_test,optimal_tol), " ± "), ", ") + message = join(join.(zip(obj_test, optimal_tol), " ± "), ", ") write_testlog(test_path, message, test_result) end + +function get_exponent_sciform(number::Real) + # Get the exponent of a number in scientific notation + return number == 0.0 ? 0 : Int(floor(log10(abs(number)))) +end + +function round_objfromtol!(obj::Real, tol::Real) + # Round the objective value to the same number of digits as the tolerance + return round(obj, digits=(-1)*get_exponent_sciform(tol)) +end \ No newline at end of file