Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ else
@info "Testing PETSc.jl with" MPIPreferences.binary MPIPreferences.abi PETSc_jll.host_platform
end

include("testutils.jl") # helpers the test files share; each includes it when run alone

# The test groups, one folder each, in the order they run. `Pkg.test(test_args = ["dm"])`
# runs only the named groups; without arguments every group runs.
const GROUPS = ("core", "vecmat", "solvers", "dm", "lowlevel", "regression", "examples", "mpi")
Expand Down Expand Up @@ -117,7 +119,6 @@ if selected("examples")
include("examples/manual_ts.jl") # the TS examples in the manual
include("examples/manual_viewer.jl") # the PetscViewer examples in the manual

include("testutils.jl")
include("examples/examples.jl") # every script in examples/
include("examples/mpi_examples.jl") # the examples marked `# INCLUDE IN MPI TEST`
end
Expand Down
8 changes: 6 additions & 2 deletions test/solvers/pc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ using MPI
using SparseArrays
using LinearAlgebra
MPI.Initialized() || MPI.Init()
isdefined(Main, :PETScTestUtils) || include(joinpath(@__DIR__, "..", "testutils.jl"))
using .PETScTestUtils: without_petsc_traceback

@testset "PC" begin
comm = MPI.COMM_SELF
Expand Down Expand Up @@ -112,12 +114,14 @@ MPI.Initialized() || MPI.Init()
PETSc.set_shell_apply!(PETSc.pc(ksp)) do y, p, x
throw(DomainError(-1.0, "shell apply! failed on purpose"))
end
@test_throws DomainError ksp \ b
@test_throws DomainError without_petsc_traceback(() -> ksp \ b, petsclib)
# started through LibPETSc there is no high-level call to rethrow it
petsc_b = LibPETSc.VecCreateSeqWithArray(petsclib, comm, 1, n, b)
petsc_x = similar(petsc_b)
@test_logs (:error, r"shell apply!") match_mode = :any begin
@test_throws LibPETSc.PetscError LibPETSc.KSPSolve(petsclib, ksp, petsc_b, petsc_x)
@test_throws LibPETSc.PetscError without_petsc_traceback(petsclib) do
LibPETSc.KSPSolve(petsclib, ksp, petsc_b, petsc_x)
end
end
PETSc.destroy!(petsc_b)
PETSc.destroy!(petsc_x)
Expand Down
6 changes: 4 additions & 2 deletions test/solvers/snes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ using Test
using PETSc
using MPI
MPI.Initialized() || MPI.Init()
isdefined(Main, :PETScTestUtils) || include(joinpath(@__DIR__, "..", "testutils.jl"))
using .PETScTestUtils: without_petsc_traceback

@testset "SNES" begin
comm = MPI.COMM_WORLD
Expand Down Expand Up @@ -323,14 +325,14 @@ MPI.Initialized() || MPI.Init()
throw(DomainError(-1.0, "residual failed on purpose"))
end
x7 = LibPETSc.VecCreateSeqWithArray(petsclib, comm, PetscInt(1), PetscInt(2), PetscScalar.([2, 3]))
@test_throws DomainError PETSc.solve!(x7, snes7)
@test_throws DomainError without_petsc_traceback(() -> PETSc.solve!(x7, snes7), petsclib)

# a nonzero Integer return still fails the call, and warns
PETSc.set_function!(snes7, r7) do fx, snes, x
return 3
end
@test_logs (:warn, r"returned 3") match_mode = :any begin
@test_throws LibPETSc.PetscError PETSc.solve!(x7, snes7)
@test_throws LibPETSc.PetscError without_petsc_traceback(() -> PETSc.solve!(x7, snes7), petsclib)
end

# user_ctx is kept with the PETSc object, and snes.user_ctx forwards to its
Expand Down
17 changes: 16 additions & 1 deletion test/testutils.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module PETScTestUtils

export find_sources
using Libdl
using PETSc: LibPETSc

export find_sources, without_petsc_traceback

function find_sources(path::String, sources = String[])
if isdir(path)
Expand All @@ -13,4 +16,16 @@ function find_sources(path::String, sources = String[])
return sources
end

# Runs `f()` with PETSc's return-only error handler, so an error raised on purpose
# fails the call as usual without printing PETSc's traceback to stderr
function without_petsc_traceback(f, petsclib)
handler = Libdl.dlsym(Libdl.dlopen(petsclib.petsc_library), :PetscReturnErrorHandler)
LibPETSc.PetscPushErrorHandler(petsclib, handler, C_NULL)
try
return f()
finally
LibPETSc.PetscPopErrorHandler(petsclib)
end
end

end # module PETScTestUtils
Loading