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
173 changes: 173 additions & 0 deletions integration_test/cases/cursor_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
defmodule CursorTest do
use ExUnit.Case, async: true

alias TestPool, as: P
alias TestAgent, as: A
alias TestQuery, as: Q
alias TestCursor, as: C
alias TestResult, as: R

test "declare/fetch/deallocate return result" do
stack = [
{:ok, :state},
{:ok, %C{}, :new_state},
{:ok, %C{}, :newer_state},
{:cont, %R{}, :newest_state},
{:halt, %R{}, :state2},
{:ok, :deallocated, :new_state2},
{:ok, :deallocated, :newer_state2}
]
{:ok, agent} = A.start_link(stack)

opts = [agent: agent, parent: self()]
{:ok, pool} = P.start_link(opts)
assert P.declare(pool, %Q{}, [:param]) == {:ok, %C{}}
assert P.declare!(pool, %Q{}, [:param], [key: :value]) == %C{}

assert P.fetch(pool, %Q{}, %C{}) == {:cont, %R{}}
assert P.fetch!(pool, %Q{}, %C{}, [key: :value]) == {:halt, %R{}}

assert P.deallocate(pool, %Q{}, %C{}) == {:ok, :deallocated}
assert P.deallocate!(pool, %Q{}, %C{}, [key: :value]) == :deallocated

assert [
connect: [_],
handle_declare: [%Q{}, [:param], _, :state],
handle_declare: [%Q{}, [:param], [{:key, :value} | _], :new_state],
handle_fetch: [%Q{}, %C{}, _, :newer_state],
handle_fetch: [%Q{}, %C{}, [{:key, :value} | _], :newest_state],
handle_deallocate: [%Q{}, %C{}, _, :state2],
handle_deallocate: [%Q{}, %C{}, [{:key, :value} | _], :new_state2]
] = A.record(agent)
end

test "declare encodes params" do
stack = [
{:ok, :state},
{:ok, %C{}, :new_state},
]
{:ok, agent} = A.start_link(stack)

opts = [agent: agent, parent: self()]
{:ok, pool} = P.start_link(opts)

opts2 = [encode: fn([:param]) -> :encoded end]
assert P.declare(pool, %Q{}, [:param], opts2) == {:ok, %C{}}

assert [
connect: [_],
handle_declare: [%Q{}, :encoded, _, :state]] = A.record(agent)
end

test "fetch decodes result" do
stack = [
{:ok, :state},
{:cont, %R{}, :new_state},
{:halt, %R{}, :newer_state}
]
{:ok, agent} = A.start_link(stack)

opts = [agent: agent, parent: self()]
{:ok, pool} = P.start_link(opts)

opts2 = [decode: fn(%R{}) -> :decoded end]
assert P.fetch(pool, %Q{}, %C{}, opts2) == {:cont, :decoded}
assert P.fetch(pool, %Q{}, %C{}, opts2) == {:halt, :decoded}

assert [
connect: [_],
handle_fetch: [%Q{}, %C{}, _, :state],
handle_fetch: [%Q{}, %C{}, _, :new_state]
] = A.record(agent)
end

test "declare/fetch/deallocate logs result" do
stack = [
{:ok, :state},
{:ok, %C{}, :new_state},
{:cont, %R{}, :newer_state},
{:halt, %R{}, :newest_state},
{:ok, :deallocated, :state2}
]
{:ok, agent} = A.start_link(stack)

parent = self()
opts = [agent: agent, parent: parent]
{:ok, pool} = P.start_link(opts)

log = &send(parent, &1)
assert P.declare(pool, %Q{}, [:param], [log: log]) == {:ok, %C{}}

assert_receive %DBConnection.LogEntry{call: :declare, query: %Q{},
params: [:param], result: {:ok, %C{}}} = entry
assert is_integer(entry.pool_time)
assert entry.pool_time >= 0
assert is_integer(entry.connection_time)
assert entry.connection_time >= 0
assert is_nil(entry.decode_time)

assert P.fetch(pool, %Q{}, %C{}, [log: log]) == {:cont, %R{}}

assert_receive %DBConnection.LogEntry{call: :fetch, query: %Q{},
params: %C{}, result: {:ok, %R{}}} = entry
assert is_integer(entry.pool_time)
assert entry.pool_time >= 0
assert is_integer(entry.connection_time)
assert entry.connection_time >= 0
assert is_integer(entry.decode_time)
assert entry.decode_time >= 0

assert P.fetch(pool, %Q{}, %C{}, [log: log]) == {:halt, %R{}}

assert_receive %DBConnection.LogEntry{call: :fetch, query: %Q{},
params: %C{}, result: {:ok, %R{}}} = entry
assert is_integer(entry.pool_time)
assert entry.pool_time >= 0
assert is_integer(entry.connection_time)
assert entry.connection_time >= 0
assert is_integer(entry.decode_time)
assert entry.decode_time >= 0

assert P.deallocate(pool, %Q{}, %C{}, [log: log]) == {:ok, :deallocated}

assert_receive %DBConnection.LogEntry{call: :deallocate, query: %Q{},
params: %C{}, result: {:ok, :deallocated}} = entry
assert is_integer(entry.pool_time)
assert entry.pool_time >= 0
assert is_integer(entry.connection_time)
assert entry.connection_time >= 0
assert is_nil(entry.decode_time)

assert [
connect: [_],
handle_declare: [%Q{}, [:param], _, :state],
handle_fetch: [%Q{}, %C{}, _, :new_state],
handle_fetch: [%Q{}, %C{}, _, :newer_state],
handle_deallocate: [%Q{}, %C{}, _, :newest_state]
] = A.record(agent)
end

test "declare/fetch/deallocate error returns error" do
err = RuntimeError.exception("oops")
stack = [
{:ok, :state},
{:error, err, :new_state},
{:error, err, :newer_state},
{:error, err, :newesr_state}
]
{:ok, agent} = A.start_link(stack)

opts = [agent: agent, parent: self()]
{:ok, pool} = P.start_link(opts)
assert P.declare(pool, %Q{}, [:param]) == {:error, err}
assert P.fetch(pool, %Q{}, %C{}) == {:error, err}
assert P.deallocate(pool, %Q{}, %C{}) == {:error, err}

assert [
connect: [_],
handle_declare: [%Q{}, [:param], _, :state],
handle_fetch: [%Q{}, %C{}, _, :new_state],
handle_deallocate: [%Q{}, %C{}, _, :newer_state]
] = A.record(agent)
end
end
2 changes: 1 addition & 1 deletion integration_test/cases/prepare_stream_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ defmodule PrepareStreamTest do
assert entry.connection_time >= 0
assert is_nil(entry.decode_time)

assert_received %DBConnection.LogEntry{call: :first} = entry
assert_received %DBConnection.LogEntry{call: :fetch} = entry
assert %{query: %Q{}, params: %C{}, result: {:ok, %R{}}} = entry
assert is_nil(entry.pool_time)
assert is_integer(entry.connection_time)
Expand Down
15 changes: 10 additions & 5 deletions integration_test/cases/stream_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ defmodule StreamTest do
assert entry.connection_time >= 0
assert is_nil(entry.decode_time)

assert_received %DBConnection.LogEntry{call: :first} = entry
assert_received %DBConnection.LogEntry{call: :fetch} = entry
assert %{query: %Q{}, params: %C{}, result: {:ok, %R{}}} = entry
assert is_nil(entry.pool_time)
assert is_integer(entry.connection_time)
Expand Down Expand Up @@ -221,14 +221,19 @@ defmodule StreamTest do

assert_received %DBConnection.LogEntry{call: :declare}

assert_received %DBConnection.LogEntry{call: :first} = entry
assert_received %DBConnection.LogEntry{call: :fetch} = entry
assert %{query: %Q{}, params: %C{}, result: {:error, ^err}} = entry
assert is_nil(entry.pool_time)
assert is_integer(entry.connection_time)
assert entry.connection_time >= 0
assert is_nil(entry.decode_time)

refute_received %DBConnection.LogEntry{call: :deallocate}
assert_received %DBConnection.LogEntry{call: :deallocate} = entry
closed = DBConnection.ConnectionError.exception("connection is closed")
assert %{query: %Q{}, params: %C{}, result: {:error, ^closed}} = entry
assert is_nil(entry.pool_time)
assert is_nil(entry.connection_time)
assert is_nil(entry.decode_time)

assert_receive :reconnected

Expand Down Expand Up @@ -297,12 +302,12 @@ defmodule StreamTest do

assert P.transaction(pool, fn(conn) ->
stream = P.stream(conn, %Q{}, [:param], [log: &send(parent, &1)])
assert_raise RuntimeError, "oops", fn() -> Enum.take(stream, 1) end
assert Enum.take(stream, 1) == [%R{}]
:hi
end) == {:error, :rollback}

assert_received %DBConnection.LogEntry{call: :declare}
assert_received %DBConnection.LogEntry{call: :first}
assert_received %DBConnection.LogEntry{call: :fetch}

assert_received %DBConnection.LogEntry{call: :deallocate} = entry
assert %{query: %Q{}, params: %C{}, result: {:error, ^err}} = entry
Expand Down
1 change: 1 addition & 0 deletions integration_test/tests.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Code.require_file "cases/after_connect_test.exs", __DIR__
Code.require_file "cases/backoff_test.exs", __DIR__
Code.require_file "cases/client_test.exs", __DIR__
Code.require_file "cases/close_test.exs", __DIR__
Code.require_file "cases/cursor_test.exs", __DIR__
Code.require_file "cases/execute_test.exs", __DIR__
Code.require_file "cases/idle_test.exs", __DIR__
Code.require_file "cases/overflow_test.exs", __DIR__
Expand Down
Loading