Skip to content

Commit

Permalink
test(LibPQ): run the async result test with both types of connections…
Browse files Browse the repository at this point in the history
…, and option to run all with any type
  • Loading branch information
pankgeorg committed Sep 6, 2023
1 parent 4b6c77c commit 385b681
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/asyncresults.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ function async_execute(
string_params = string_parameters(parameters)
pointer_params = parameter_pointers(string_params)

async_result = _async_execute(jl_conn; binary_format=binary_format, kwargs...) do jl_conn
async_result =
_async_execute(jl_conn; binary_format=binary_format, kwargs...) do jl_conn
GC.@preserve string_params _async_submit(
jl_conn, query, pointer_params; binary_format=binary_format
)
Expand Down
51 changes: 49 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ function count_allocs(f, args...)
return Base.gc_alloc_count(stats.gcstats)
end

@testset "LibPQ" begin
usenonblocking = get(ENV, "LIBPQJL_CONNECTION_NONBLOCKING", false)
@testset "LibPQ $(usenonblocking ? "(nonblocking connection)" : "")" begin

@testset "ConninfoDisplay" begin
@test parse(LibPQ.ConninfoDisplay, "") == LibPQ.Normal
Expand Down Expand Up @@ -82,6 +83,7 @@ end

@testset "Example SELECT" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=false)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)
@test conn isa LibPQ.Connection
@test isopen(conn)
@test status(conn) == LibPQ.libpq_c.CONNECTION_OK
Expand Down Expand Up @@ -190,6 +192,7 @@ end

@testset "Example INSERT and DELETE" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, """
CREATE TEMPORARY TABLE libpqjl_test (
Expand Down Expand Up @@ -333,6 +336,7 @@ end
@testset "load!" begin
@testset "issue #204" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

close(execute(conn, """
CREATE TEMPORARY TABLE libpqjl_test (
Expand All @@ -357,6 +361,7 @@ end
@testset "COPY FROM" begin
@testset "Example COPY FROM" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, """
CREATE TEMPORARY TABLE libpqjl_test (
Expand Down Expand Up @@ -401,6 +406,7 @@ end

@testset "Wrong column order" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, """
CREATE TEMPORARY TABLE libpqjl_test (
Expand Down Expand Up @@ -458,6 +464,7 @@ end
local saved_conn

was_open = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true) do jl_conn
LibPQ.setnonblocking(jl_conn, nonblock=usenonblocking)
saved_conn = jl_conn
return isopen(jl_conn)
end
Expand All @@ -466,6 +473,7 @@ end
@test !isopen(saved_conn)

@test_throws LibPQ.Errors.PQConnectionError LibPQ.Connection("dbname=123fake user=$DATABASE_USER"; throw_error=true) do jl_conn
LibPQ.setnonblocking(conn, nonblock=usenonblocking)
saved_conn = jl_conn
@test false
end
Expand All @@ -475,13 +483,15 @@ end

@testset "Version Numbers" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

# update this test before PostgreSQL 20.0 ;)
@test LibPQ.pqv"7" <= LibPQ.server_version(conn) <= LibPQ.pqv"20"
end

@testset "Encoding" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

@test LibPQ.encoding(conn) == "UTF8"

Expand Down Expand Up @@ -513,6 +523,7 @@ end
throw_error=true,
type_map=Dict(:interval => String),
)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

conn_info = LibPQ.conninfo(conn)
options = first(filter(conn_info) do conn_opt
Expand Down Expand Up @@ -632,6 +643,8 @@ end
@testset "Finalizer" begin
closed_flags = map(1:50) do _
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

closed = conn.closed
finalize(conn)
return closed
Expand All @@ -646,6 +659,8 @@ end

closed_flags = map(1:50) do _
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

push!(results, execute(conn, "SELECT 1;"))
return conn.closed
end
Expand All @@ -661,6 +676,8 @@ end
# with AsyncResults, which hold a reference to Connection
closed_flags = asyncmap(1:50) do _
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

wait(async_execute(conn, "SELECT pg_sleep(1);"))
return conn.closed
end
Expand Down Expand Up @@ -707,6 +724,8 @@ end

@testset "throw_error=false" begin
conn = LibPQ.Connection("dbname=123fake user=$DATABASE_USER"; throw_error=false)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

@test conn isa LibPQ.Connection
@test status(conn) == LibPQ.libpq_c.CONNECTION_BAD
@test isopen(conn)
Expand All @@ -725,6 +744,8 @@ end
@test_throws LibPQ.Errors.PQConnectionError LibPQ.Connection("dbname=123fake user=$DATABASE_USER"; throw_error=true)

conn = LibPQ.Connection("dbname=123fake user=$DATABASE_USER"; throw_error=false)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

@test conn isa LibPQ.Connection
@test status(conn) == LibPQ.libpq_c.CONNECTION_BAD
@test isopen(conn)
Expand All @@ -740,6 +761,7 @@ end
@testset "Results" begin
@testset "Nulls" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELECT NULL"; throw_error=true)
@test status(result) == LibPQ.libpq_c.PGRES_TUPLES_OK
Expand Down Expand Up @@ -824,6 +846,7 @@ end

@testset "Not Nulls" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELECT NULL"; not_null=[false], throw_error=true)
@test status(result) == LibPQ.libpq_c.PGRES_TUPLES_OK
Expand Down Expand Up @@ -949,6 +972,7 @@ end

@testset "Tables.jl" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, """
SELECT no_nulls, yes_nulls FROM (
Expand Down Expand Up @@ -991,6 +1015,7 @@ end

@testset "Duplicate names" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELECT 1 AS col, 2 AS col;", not_null=true, throw_error=true)
columns = Tables.columns(result)
Expand All @@ -1007,6 +1032,7 @@ end

@testset "Uppercase Columns" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELECT 1 AS \"Column\";")
@test num_columns(result) == 1
Expand All @@ -1025,6 +1051,7 @@ end

@testset "PQResultError" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

try
execute(conn, "SELECT log(-1);")
Expand Down Expand Up @@ -1072,6 +1099,7 @@ end
@testset "Type Conversions" begin
@testset "Deprecations" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELECT 'infinity'::timestamp;")

Expand All @@ -1089,6 +1117,7 @@ end

@testset "Automatic" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, """
SELECT oid, typname, typlen, typbyval, typcategory
Expand Down Expand Up @@ -1120,6 +1149,7 @@ end

@testset "Overrides" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELECT 4::bigint;")
@test first(first(result)) === Int64(4)
Expand Down Expand Up @@ -1169,6 +1199,7 @@ end
@testset for binary_format in (LibPQ.TEXT, LibPQ.BINARY)
@testset "Default Types" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

test_data = [
("3", Cint(3)),
Expand Down Expand Up @@ -1335,6 +1366,7 @@ end

@testset "Specified Types" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

test_data = [
("3", UInt, UInt(3)),
Expand Down Expand Up @@ -1428,6 +1460,7 @@ end

@testset "Parameters" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

@testset "Arrays" begin
tests = (
Expand Down Expand Up @@ -1542,6 +1575,7 @@ end

@testset "SQLString" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

execute(conn, sql```
CREATE TEMPORARY TABLE libpq_test_users (
Expand Down Expand Up @@ -1577,6 +1611,7 @@ end
@testset "Query Errors" begin
@testset "Syntax Errors" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELORCT NUUL;"; throw_error=false)
@test status(result) == LibPQ.libpq_c.PGRES_FATAL_ERROR
Expand All @@ -1595,6 +1630,7 @@ end

@testset "Wrong No. Parameters" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(conn, "SELORCT \$1;", String[]; throw_error=false)
@test status(result) == LibPQ.libpq_c.PGRES_FATAL_ERROR
Expand All @@ -1619,6 +1655,7 @@ end

@testset "Interface Errors" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = execute(
conn,
Expand Down Expand Up @@ -1652,6 +1689,7 @@ end

# Establish connection and construct temporary table.
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER")
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

# Get the column.
result = execute(
Expand All @@ -1678,6 +1716,7 @@ end
@testset "Statements" begin
@testset "No Params, Output" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

stmt = prepare(conn, "SELECT oid, typname FROM pg_type")

Expand All @@ -1699,6 +1738,7 @@ end

@testset "Params, Output" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

stmt = prepare(conn, "SELECT oid, typname FROM pg_type WHERE oid = \$1")

Expand All @@ -1723,11 +1763,12 @@ end
end
end

@testset "AsyncResults" begin
@testset "AsyncResults (usenonblocking connection=$usenonblocking)" for usenonblocking in [true, false]
trywait(ar::LibPQ.AsyncResult) = (try wait(ar) catch end; nothing)

@testset "Basic" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

ar = async_execute(conn, "SELECT pg_sleep(2);"; throw_error=false)
yield()
Expand All @@ -1750,6 +1791,7 @@ end

@testset "Parameters" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

ar = async_execute(
conn,
Expand Down Expand Up @@ -1782,6 +1824,7 @@ end
# Ensures queries wait for previous query completion before starting
@testset "Wait in line to complete" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

first_ar = async_execute(conn, "SELECT pg_sleep(4);")
yield()
Expand Down Expand Up @@ -1811,6 +1854,7 @@ end

@testset "Cancel" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

# final query needs to be one that actually does something
# on Windows, first query also needs to do something
Expand Down Expand Up @@ -1843,6 +1887,7 @@ end

@testset "Canceled by closing connection" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

# final query needs to be one that actually does something
# on Windows, first query also needs to do something
Expand Down Expand Up @@ -1875,6 +1920,7 @@ end

@testset "FDWatcher: bad file descriptor (EBADF)" begin
conn = LibPQ.Connection("dbname=postgres user=$DATABASE_USER"; throw_error=true)
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

ar = async_execute(conn, "SELECT pg_sleep(3); SELECT * FROM pg_type;")
yield()
Expand All @@ -1898,6 +1944,7 @@ end
@testset "DBInterface integration" begin
conn = DBInterface.connect(LibPQ.Connection, "dbname=postgres user=$DATABASE_USER")
@test conn isa LibPQ.Connection
LibPQ.setnonblocking(conn, nonblock=usenonblocking)

result = DBInterface.execute(
conn,
Expand Down

0 comments on commit 385b681

Please sign in to comment.