From d7fb4bb0a1ed9f07da4cec5eecb87ef2a5535fea Mon Sep 17 00:00:00 2001 From: Maarten Pronk Date: Tue, 22 Oct 2024 23:26:04 +0200 Subject: [PATCH] Added DVC, teamcity-messages and Julia TC integration (#1915) Fixes #1879 This does three things - Adds teamcity-messages as a Python test dependency, enabling TC to keep track of pytest tests (number of tests, number of failures, linking to specific logs), making debugging much easier. Screenshot 2024-10-21 at 22 35 54 - Adds teamcity specific logging in Julia (much like teamcity-messages) to keep track of the integration test time and differences with a previous model. These parameters are tracked by TC (and can be failed on), and can be plotted over time. Screenshot 2024-10-21 at 22 38 31 - Finally, and biggest, this adds [DVC](https://dvc.org/) to our project, with the minio repo tracked, and the integration test as stage. It tracks a new default toml for that model (models/integration.toml), and like TC in 2, the time and differences. Once someone changes either the hws model, or the core code, or the integration.toml, the results are outdated and `dvc repro` will rerun the test. We can save these experiments over time, and compare results with the VS Code plugin: Screenshot 2024-10-21 at 22 09 27 This disables the threshold test in the integration test, and opts for monitoring results (could be done automatically) instead. I've also opted for keeping track of results and settings threshold _outside_ of Julia. This is a backwards compatible setup PR. Changes/additions for benchmark tuning can be made in another PR. --------- Co-authored-by: Martijn Visser --- .dvc/.gitignore | 3 + .dvc/config | 8 ++ .dvcignore | 4 + .gitignore | 3 +- Manifest.toml | 2 +- core/Project.toml | 6 +- core/integration_test/hws_integration_test.jl | 33 ++++++- core/regression_test/regression_test.jl | 10 ++ core/src/callback.jl | 4 + core/test/utils.jl | 23 +++++ data/.gitignore | 3 + dvc.lock | 26 +++++ dvc.yaml | 16 ++++ models/benchmark.dvc | 14 +++ models/hws_2024_7_0.dvc | 14 +++ models/hws_migration_test.dvc | 14 +++ models/integration.toml | 12 +++ pixi.lock | 95 +++++++------------ pixi.toml | 1 + python/ribasim/pyproject.toml | 8 +- 20 files changed, 229 insertions(+), 70 deletions(-) create mode 100644 .dvc/.gitignore create mode 100644 .dvc/config create mode 100644 .dvcignore create mode 100644 core/test/utils.jl create mode 100644 data/.gitignore create mode 100644 dvc.lock create mode 100644 dvc.yaml create mode 100644 models/benchmark.dvc create mode 100644 models/hws_2024_7_0.dvc create mode 100644 models/hws_migration_test.dvc create mode 100644 models/integration.toml diff --git a/.dvc/.gitignore b/.dvc/.gitignore new file mode 100644 index 000000000..528f30c71 --- /dev/null +++ b/.dvc/.gitignore @@ -0,0 +1,3 @@ +/config.local +/tmp +/cache diff --git a/.dvc/config b/.dvc/config new file mode 100644 index 000000000..11c50aaa7 --- /dev/null +++ b/.dvc/config @@ -0,0 +1,8 @@ +[core] + remote = minio +['remote "minio"'] # for tracking artifacts with unreadable names + url = s3://ribasim/dvc + endpointurl = https://s3.deltares.nl +['remote "minio_readonly"'] # for readable named models in the top-dir + url = s3://ribasim + endpointurl = https://s3.deltares.nl diff --git a/.dvcignore b/.dvcignore new file mode 100644 index 000000000..7327ccb85 --- /dev/null +++ b/.dvcignore @@ -0,0 +1,4 @@ +# Add patterns of files dvc should ignore, which could improve +# the performance. Learn more at +# https://dvc.org/doc/user-guide/dvcignore +docs diff --git a/.gitignore b/.gitignore index 8f124b7ee..b5e9157cf 100644 --- a/.gitignore +++ b/.gitignore @@ -148,7 +148,8 @@ python/ribasim_api/tests/temp/ report.xml # Designated working dir for working on Ribasim models -models/ +models/* +!models/*.dvc playground/output # Ruff diff --git a/Manifest.toml b/Manifest.toml index f2ca88832..ae5a50b7a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1398,7 +1398,7 @@ uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" version = "3.6.2" [[deps.Ribasim]] -deps = ["Accessors", "Arrow", "BasicModelInterface", "CodecZstd", "ComponentArrays", "Configurations", "DBInterface", "DataInterpolations", "DataStructures", "Dates", "DiffEqBase", "DiffEqCallbacks", "EnumX", "FiniteDiff", "Graphs", "HiGHS", "IterTools", "JuMP", "Legolas", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoggingExtras", "MetaGraphsNext", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqLowOrderRK", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqSDIRK", "OrdinaryDiffEqTsit5", "PreallocationTools", "SQLite", "SciMLBase", "SparseArrays", "SparseConnectivityTracer", "StructArrays", "Tables", "TerminalLoggers", "TranscodingStreams"] +deps = ["Accessors", "Arrow", "BasicModelInterface", "CodecZstd", "ComponentArrays", "Configurations", "DBInterface", "DataInterpolations", "DataStructures", "Dates", "DiffEqBase", "DiffEqCallbacks", "EnumX", "FiniteDiff", "Graphs", "HiGHS", "IterTools", "JuMP", "Legolas", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoggingExtras", "MetaGraphsNext", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqLowOrderRK", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqSDIRK", "OrdinaryDiffEqTsit5", "PreallocationTools", "SQLite", "SciMLBase", "SparseArrays", "SparseConnectivityTracer", "Statistics", "StructArrays", "Tables", "TerminalLoggers", "TranscodingStreams"] path = "core" uuid = "aac5e3d9-0b8f-4d4f-8241-b1a7a9632635" version = "2024.11.0" diff --git a/core/Project.toml b/core/Project.toml index bd85015a6..9e761b65d 100644 --- a/core/Project.toml +++ b/core/Project.toml @@ -78,8 +78,8 @@ IOCapture = "0.2" IterTools = "1.4" JuMP = "1.15" Legolas = "0.5" -LinearAlgebra = "1" LineSearches = "7" +LinearAlgebra = "1" LinearSolve = "2.24" Logging = "1" LoggingExtras = "1" @@ -97,6 +97,7 @@ SQLite = "1.5.1" SciMLBase = "2.36" SparseArrays = "1" SparseConnectivityTracer = "0.6.8" +Statistics = "1" StructArrays = "0.6.13" TOML = "1" Tables = "1" @@ -112,6 +113,7 @@ CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" IOCapture = "b5f81e59-6552-4d32-b1f0-c071b021bf89" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" TerminalLoggers = "5d786b92-1e48-4d6f-9151-6b4477ca9bed" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" @@ -121,4 +123,4 @@ TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a" LoadMKL_JLL = false [targets] -test = ["Aqua", "CSV", "DataFrames", "IOCapture", "Logging", "TerminalLoggers", "Test", "TOML", "TestItemRunner"] +test = ["Aqua", "CSV", "DataFrames", "IOCapture", "Logging", "Statistics", "TerminalLoggers", "Test", "TOML", "TestItemRunner"] diff --git a/core/integration_test/hws_integration_test.jl b/core/integration_test/hws_integration_test.jl index 9dabdfde0..1fc1110f3 100644 --- a/core/integration_test/hws_integration_test.jl +++ b/core/integration_test/hws_integration_test.jl @@ -1,8 +1,12 @@ @testitem "HWS model integration test" begin using SciMLBase: successful_retcode + using Dates + using Statistics using Arrow + using TOML + include(joinpath(@__DIR__, "../test/utils.jl")) - toml_path = normpath(@__DIR__, "../../models/hws_2024_7_0/hws.toml") + toml_path = normpath(@__DIR__, "../../models/integration.toml") @test ispath(toml_path) model = Ribasim.run(toml_path) @test model isa Ribasim.Model @@ -12,7 +16,8 @@ read(normpath(@__DIR__, "../../models/hws_2024_7_0/benchmark/basin_state.arrow")) basin_bench = Arrow.Table(basin_bytes_bench) - basin_bytes = read(normpath(dirname(toml_path), "results/basin_state.arrow")) + basin_bytes = + read(normpath(dirname(toml_path), model.config.results_dir, "basin_state.arrow")) basin = Arrow.Table(basin_bytes) @testset "Results values" begin @@ -20,7 +25,25 @@ @test all(q -> abs(q) < 0.2, basin.level - basin_bench.level) end + diff = basin.level - basin_bench.level + timed = @timed Ribasim.run(toml_path) + dt = Millisecond(round(Int, timed.time * 1000)) + Time(0) + + @tcstatistic "time" timed.time + @tcstatistic "min_diff" minimum(diff) + @tcstatistic "max_diff" maximum(diff) + @tcstatistic "med_diff" median(diff) + + data = Dict( + "time" => timed.time, + "min_diff" => minimum(diff), + "max_diff" => maximum(diff), + "med_diff" => median(diff), + ) + open(joinpath(@__DIR__, "../../data/integration.toml"), "w") do io + TOML.print(io, data) + end # current benchmark in seconds, TeamCity is up to 4x slower than local benchmark_runtime = 32 @@ -28,10 +51,10 @@ round((timed.time - benchmark_runtime) / benchmark_runtime * 100; digits = 2) if performance_diff < 0.0 performance_diff = abs(performance_diff) - @info "Runtime is $(timed.time) and it is $performance_diff % faster than benchmark" + @tcstatus "Runtime is $(dt) and it is $performance_diff % faster than benchmark" elseif performance_diff > 0.0 && performance_diff < 0.2 - @info "Runtime is $(timed.time) and it is $performance_diff % slower than benchmark" + @tcstatus "Runtime is $(dt) and it is $performance_diff % slower than benchmark" else - @warn "Runtime is $(timed.time) and it is $performance_diff % slower than benchmark, close to fail the benchmark" + @tcstatus "Runtime is $(dt) and it is $performance_diff % slower than benchmark, close to fail the benchmark" end end diff --git a/core/regression_test/regression_test.jl b/core/regression_test/regression_test.jl index 6172a5f1e..cb5b4bb91 100644 --- a/core/regression_test/regression_test.jl +++ b/core/regression_test/regression_test.jl @@ -55,6 +55,8 @@ end using SciMLBase: successful_retcode import Arrow using Ribasim + using Statistics + include(joinpath(@__DIR__, "../test/utils.jl")) toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/ribasim.toml") @test ispath(toml_path) @@ -102,6 +104,14 @@ end # Testbench for basin.arrow @test basin.time == basin_bench.time @test basin.node_id == basin_bench.node_id + + # The storage seems to failing the most, so let's report it for now + sdiff = basin.storage - basin_bench.storage + key = "basic.$solver.$sparse_on_off.$autodiff_on_off" + @tcstatistic "$key.min_diff" minimum(sdiff) + @tcstatistic "$key.max_diff" maximum(sdiff) + @tcstatistic "$key.med_diff" median(sdiff) + @test all(q -> abs(q) < 1.0, basin.storage - basin_bench.storage) @test all(q -> abs(q) < 0.5, basin.level - basin_bench.level) @test all(q -> abs(q) < 1e-3, basin.balance_error) diff --git a/core/src/callback.jl b/core/src/callback.jl index 3ec332faf..b1c2b3ad3 100644 --- a/core/src/callback.jl +++ b/core/src/callback.jl @@ -234,6 +234,10 @@ function update_cumulative_flows!(u, t, integrator)::Nothing elseif to_node.type == NodeType.UserDemand basin.mass[from_node.idx, :] .-= user_demand.concentration[to_node.idx, :] .* flow + elseif to_node.type == NodeType.Terminal && to_node.value == 0 + # UserDemand inflow is discoupled from its outflow, + # and the unset flow edge defaults to Terminal #0 + nothing else @warn "Unsupported outflow from $(to_node.type) #$(to_node.value) to $(from_node.type) #$(from_node.value) with flow $flow" end diff --git a/core/test/utils.jl b/core/test/utils.jl new file mode 100644 index 000000000..094a883a5 --- /dev/null +++ b/core/test/utils.jl @@ -0,0 +1,23 @@ +macro tcstatus(message) + if haskey(ENV, "TEAMCITY_VERSION") + return esc(:(println("##teamcity[buildStatus text='", $message, "']"))) + else + return esc(:(println($message))) + end +end + +macro tcstatistic(key, value) + if haskey(ENV, "TEAMCITY_VERSION") + return esc( + :(println( + "##teamcity[buildStatisticValue key='", + $key, + "' value='", + $value, + "']", + )), + ) + else + return esc(:(println($key, '=', $value))) + end +end diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 000000000..4e6f10f4f --- /dev/null +++ b/data/.gitignore @@ -0,0 +1,3 @@ +/predict.dat +/integration.csv +/integration.toml diff --git a/dvc.lock b/dvc.lock new file mode 100644 index 000000000..9b0bac83b --- /dev/null +++ b/dvc.lock @@ -0,0 +1,26 @@ +schema: '2.0' +stages: + integration: + cmd: pixi run model-integration-test + deps: + - path: core/ + hash: md5 + md5: 6228f56acef895eeb5d4fdcd479cd1ee.dir + size: 474129 + nfiles: 45 + - path: models/hws_2024_7_0 + hash: md5 + md5: e88123c69a0f7e3590b94c55dbe0062e.dir + size: 45421022 + nfiles: 10 + params: + models/integration.toml: + solver.abstol: 1e-07 + solver.algorithm: QNDF + solver.autodiff: false + solver.reltol: 1e-07 + outs: + - path: data/integration.toml + hash: md5 + md5: aa6ff2820a6eda91df1073d3bc41755e + size: 109 diff --git a/dvc.yaml b/dvc.yaml new file mode 100644 index 000000000..880c12600 --- /dev/null +++ b/dvc.yaml @@ -0,0 +1,16 @@ +stages: + integration: + cmd: pixi run model-integration-test + deps: + - core/ + - models/hws_2024_7_0 + params: + - models/integration.toml: + - solver.algorithm + - solver.abstol + - solver.reltol + - solver.autodiff + outs: + - data/integration.toml +metrics: + - data/integration.toml diff --git a/models/benchmark.dvc b/models/benchmark.dvc new file mode 100644 index 000000000..9486b764e --- /dev/null +++ b/models/benchmark.dvc @@ -0,0 +1,14 @@ +md5: 2fac758278d29071bb3e4632d69cbb0c +frozen: true +deps: +- md5: 8620613cb3fc380a20bcbbb2bd36b28c.dir + size: 187932 + nfiles: 6 + hash: md5 + path: remote://minio_readonly/benchmark +outs: +- md5: ceb5e5e81c402510497da43d29dce099.dir + size: 187932 + nfiles: 6 + hash: md5 + path: benchmark diff --git a/models/hws_2024_7_0.dvc b/models/hws_2024_7_0.dvc new file mode 100644 index 000000000..dd89be15b --- /dev/null +++ b/models/hws_2024_7_0.dvc @@ -0,0 +1,14 @@ +md5: aa976a0658b5e52b211b9714c93b6a34 +frozen: true +deps: +- md5: 24169f5a25b4c78f1868b8401a367117.dir + size: 43269986 + nfiles: 4 + hash: md5 + path: remote://minio_readonly/hws_2024_7_0 +outs: +- md5: bc02da0ad6e562f31ae8b61d34884a11.dir + size: 43269986 + nfiles: 4 + hash: md5 + path: hws_2024_7_0 diff --git a/models/hws_migration_test.dvc b/models/hws_migration_test.dvc new file mode 100644 index 000000000..03643c3ae --- /dev/null +++ b/models/hws_migration_test.dvc @@ -0,0 +1,14 @@ +md5: bda2339cc165379b0f6da21aa67039d9 +frozen: true +deps: +- md5: ab64e9bee55f9a7524f36ca317ade8fb.dir + size: 43307158 + nfiles: 2 + hash: md5 + path: remote://minio_readonly/hws_migration_test +outs: +- md5: 6ca6218661d0f021bc53bf468000a62b.dir + size: 43307158 + nfiles: 2 + hash: md5 + path: hws_migration_test diff --git a/models/integration.toml b/models/integration.toml new file mode 100644 index 000000000..fc347697d --- /dev/null +++ b/models/integration.toml @@ -0,0 +1,12 @@ +starttime = 2023-01-20 00:00:00 +endtime = 2023-07-01 00:00:00 +crs = "EPSG:28992" +input_dir = "hws_2024_7_0" +results_dir = "hws_2024_7_0/results" +ribasim_version = "2024.10.0" + +[solver] +algorithm = "QNDF" # optional, default "QNDF" +abstol = 1e-7 # optional, default 1e-7 +reltol = 1e-7 # optional, default 1e-7 +autodiff = false # optional, default false diff --git a/pixi.lock b/pixi.lock index 8b9ba1737..ad12c1de5 100644 --- a/pixi.lock +++ b/pixi.lock @@ -283,6 +283,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.1-h9eae976_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -571,6 +572,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.1-h3b4c4e4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -851,6 +853,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -1390,6 +1393,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-h84d6215_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda @@ -1909,6 +1913,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tbb-2021.13.0-h7b3277c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh31c8845_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda @@ -2393,6 +2398,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh5737063_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda @@ -2743,6 +2749,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.1-h9eae976_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -3037,6 +3044,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.1-h3b4c4e4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -3314,6 +3322,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.7.0-h91493d7_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -3645,6 +3654,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.1-h9eae976_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -3938,6 +3948,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.1-h3b4c4e4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -4214,6 +4225,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.7.0-h91493d7_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -4541,6 +4553,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.1-h9eae976_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -4829,6 +4842,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.1-h3b4c4e4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -5109,6 +5123,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 @@ -29829,45 +29844,11 @@ packages: - pkg:pypi/rfc3986-validator?source=hash-mapping size: 7818 timestamp: 1598024297745 -- kind: pypi - name: ribasim - version: 2024.10.0 - path: python/ribasim - sha256: c48692687129085ad19256cbf54c8df9853f6259b31997cc4a282fde86072751 - requires_dist: - - geopandas - - matplotlib - - numpy - - pandas - - pandera>=0.20 - - pyarrow - - pydantic~=2.0 - - pyogrio - - shapely>=2.0 - - tomli - - tomli-w - - jinja2 ; extra == 'all' - - networkx ; extra == 'all' - - pytest ; extra == 'all' - - pytest-cov ; extra == 'all' - - pytest-xdist ; extra == 'all' - - ribasim-testmodels ; extra == 'all' - - xugrid ; extra == 'all' - - jinja2 ; extra == 'delwaq' - - networkx ; extra == 'delwaq' - - xugrid ; extra == 'delwaq' - - xugrid ; extra == 'netcdf' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - - ribasim-testmodels ; extra == 'tests' - requires_python: '>=3.10' - editable: true - kind: pypi name: ribasim version: 2024.11.0 path: python/ribasim - sha256: c48692687129085ad19256cbf54c8df9853f6259b31997cc4a282fde86072751 + sha256: ba8a6a24955e974dd0d7ae81ad59546134417f48eabce10cb280ac5f8c3290db requires_dist: - geopandas - matplotlib @@ -29886,6 +29867,7 @@ packages: - pytest-cov ; extra == 'all' - pytest-xdist ; extra == 'all' - ribasim-testmodels ; extra == 'all' + - teamcity-messages ; extra == 'all' - xugrid ; extra == 'all' - jinja2 ; extra == 'delwaq' - networkx ; extra == 'delwaq' @@ -29895,18 +29877,7 @@ packages: - pytest-cov ; extra == 'tests' - pytest-xdist ; extra == 'tests' - ribasim-testmodels ; extra == 'tests' - requires_python: '>=3.10' - editable: true -- kind: pypi - name: ribasim-api - version: 2024.10.0 - path: python/ribasim_api - sha256: dc882869854e0940ab3a12506f5b9508b04045793f6badb644579c43fa2b6cb9 - requires_dist: - - xmipy - - pytest ; extra == 'tests' - - ribasim ; extra == 'tests' - - ribasim-testmodels ; extra == 'tests' + - teamcity-messages ; extra == 'tests' requires_python: '>=3.10' editable: true - kind: pypi @@ -29934,19 +29905,6 @@ packages: - pytest ; extra == 'tests' requires_python: '>=3.10' editable: true -- kind: pypi - name: ribasim-testmodels - version: 0.5.0 - path: python/ribasim_testmodels - sha256: 2b0165819d6cc5d79b0b65761e8c38b1cc9f34649dea3ed4406013080ea8b112 - requires_dist: - - geopandas - - numpy - - pandas - - ribasim - - pytest ; extra == 'tests' - requires_python: '>=3.10' - editable: true - kind: conda name: rich version: 13.9.2 @@ -31534,6 +31492,23 @@ packages: - pkg:pypi/tblib?source=hash-mapping size: 17386 timestamp: 1702066480361 +- kind: conda + name: teamcity-messages + version: '1.32' + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/teamcity-messages-1.32-pyhd8ed1ab_0.conda + sha256: 004805489f764dbeff2fa4e13aa68fb8218f488060a1acdfa5355053dff5b271 + md5: afd853cdbc44a82a4530af861332a594 + depends: + - python >=3.6 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/teamcity-messages?source=hash-mapping + size: 32473 + timestamp: 1672919644484 - kind: conda name: tenacity version: 9.0.0 diff --git a/pixi.toml b/pixi.toml index 2d6af6992..4e1aed0f8 100644 --- a/pixi.toml +++ b/pixi.toml @@ -192,6 +192,7 @@ tomli-w = "*" xarray = "*" xmipy = "*" xugrid = "*" +teamcity-messages = ">=1.32,<2" [pypi-dependencies] ribasim = { path = "python/ribasim", editable = true } diff --git a/python/ribasim/pyproject.toml b/python/ribasim/pyproject.toml index 5fa7a47b2..7dc36afe0 100644 --- a/python/ribasim/pyproject.toml +++ b/python/ribasim/pyproject.toml @@ -31,7 +31,13 @@ dependencies = [ dynamic = ["version"] [project.optional-dependencies] -tests = ["pytest", "pytest-xdist", "pytest-cov", "ribasim_testmodels"] +tests = [ + "pytest", + "pytest-xdist", + "pytest-cov", + "ribasim_testmodels", + "teamcity-messages", +] netcdf = ["xugrid"] delwaq = ["jinja2", "networkx", "ribasim[netcdf]"] all = ["ribasim[tests]", "ribasim[netcdf]", "ribasim[delwaq]"]