mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-26 10:26:30 +00:00
Add failing tests
This commit is contained in:
@@ -16,10 +16,14 @@ describe "Portocol handling" do
|
||||
end
|
||||
|
||||
def run_comparison(sequence, socket_a, socket_b)
|
||||
sequence.each do |msg, *args|
|
||||
socket_a.send(msg, *args)
|
||||
socket_b.send(msg, *args)
|
||||
|
||||
sequence.each do |msg|
|
||||
if msg.is_a?(Symbol)
|
||||
socket_a.send(msg)
|
||||
socket_b.send(msg)
|
||||
else
|
||||
socket_a.send_message(msg)
|
||||
socket_b.send_message(msg)
|
||||
end
|
||||
compare_messages(
|
||||
socket_a.read_from_server,
|
||||
socket_b.read_from_server
|
||||
@@ -83,9 +87,9 @@ describe "Portocol handling" do
|
||||
|
||||
context "Cancel Query" do
|
||||
let(:sequence) {
|
||||
[
|
||||
[:send_query_message, "SELECT pg_sleep(5)"],
|
||||
[:cancel_query]
|
||||
[
|
||||
SimpleQueryMessage.new("SELECT pg_sleep(5)"),
|
||||
:cancel_query
|
||||
]
|
||||
}
|
||||
|
||||
@@ -95,12 +99,12 @@ describe "Portocol handling" do
|
||||
xcontext "Simple query after parse" do
|
||||
let(:sequence) {
|
||||
[
|
||||
[:send_parse_message, "SELECT 5"],
|
||||
[:send_query_message, "SELECT 1"],
|
||||
[:send_bind_message],
|
||||
[:send_describe_message, "P"],
|
||||
[:send_execute_message],
|
||||
[:send_sync_message],
|
||||
ParseMessage.new("", "SELECT 5", []),
|
||||
SimpleQueryMessage.new("SELECT 1"),
|
||||
BindMessage.new("", "", [], [], [0]),
|
||||
DescribeMessage.new("P", ""),
|
||||
ExecuteMessage.new("", 1),
|
||||
SyncMessage.new
|
||||
]
|
||||
}
|
||||
|
||||
@@ -111,8 +115,8 @@ describe "Portocol handling" do
|
||||
xcontext "Flush message" do
|
||||
let(:sequence) {
|
||||
[
|
||||
[:send_parse_message, "SELECT 1"],
|
||||
[:send_flush_message]
|
||||
ParseMessage.new("", "SELECT 1", []),
|
||||
FlushMessage.new
|
||||
]
|
||||
}
|
||||
|
||||
@@ -122,9 +126,7 @@ describe "Portocol handling" do
|
||||
|
||||
xcontext "Bind without parse" do
|
||||
let(:sequence) {
|
||||
[
|
||||
[:send_bind_message]
|
||||
]
|
||||
[BindMessage.new("", "", [], [], [0])]
|
||||
}
|
||||
# This is known to fail.
|
||||
# Server responds immediately, Proxy buffers the message
|
||||
@@ -133,23 +135,155 @@ describe "Portocol handling" do
|
||||
|
||||
context "Simple message" do
|
||||
let(:sequence) {
|
||||
[[:send_query_message, "SELECT 1"]]
|
||||
[SimpleQueryMessage.new("SELECT 1")]
|
||||
}
|
||||
|
||||
it_behaves_like "at parity with database"
|
||||
end
|
||||
|
||||
10.times do |i|
|
||||
context "Extended protocol" do
|
||||
let(:sequence) {
|
||||
[
|
||||
ParseMessage.new("", "SELECT 1", []),
|
||||
BindMessage.new("", "", [], [], [0]),
|
||||
DescribeMessage.new("S", ""),
|
||||
ExecuteMessage.new("", 1),
|
||||
SyncMessage.new
|
||||
]
|
||||
}
|
||||
|
||||
context "Extended protocol" do
|
||||
let(:sequence) {
|
||||
[
|
||||
[:send_parse_message, "SELECT 1"],
|
||||
[:send_bind_message],
|
||||
[:send_describe_message, "P"],
|
||||
[:send_execute_message],
|
||||
[:send_sync_message],
|
||||
]
|
||||
}
|
||||
|
||||
it_behaves_like "at parity with database"
|
||||
it_behaves_like "at parity with database"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Protocol-level prepared statements" do
|
||||
let(:processes) { Helpers::Pgcat.single_instance_setup("sharded_db", 1, "transaction") }
|
||||
before do
|
||||
q_sock = PostgresSocket.new('localhost', processes.pgcat.port)
|
||||
q_sock.send_startup_message("sharding_user", "sharded_db", "sharding_user")
|
||||
table_query = "CREATE TABLE IF NOT EXISTS employees (employee_id SERIAL PRIMARY KEY, salary NUMERIC(10, 2) CHECK (salary > 0));"
|
||||
q_sock.send_message(SimpleQueryMessage.new(table_query))
|
||||
q_sock.close
|
||||
|
||||
current_configs = processes.pgcat.current_config
|
||||
current_configs["pools"]["sharded_db"]["prepared_statements_cache_size"] = 500
|
||||
processes.pgcat.update_config(current_configs)
|
||||
processes.pgcat.reload_config
|
||||
end
|
||||
after do
|
||||
q_sock = PostgresSocket.new('localhost', processes.pgcat.port)
|
||||
q_sock.send_startup_message("sharding_user", "sharded_db", "sharding_user")
|
||||
table_query = "DROP TABLE IF EXISTS employees;"
|
||||
q_sock.send_message(SimpleQueryMessage.new(table_query))
|
||||
q_sock.close
|
||||
end
|
||||
|
||||
context "When unnamed prepared statements are used" do
|
||||
it "does not cache them" do
|
||||
socket = PostgresSocket.new('localhost', processes.pgcat.port)
|
||||
socket.send_startup_message("sharding_user", "sharded_db", "sharding_user")
|
||||
|
||||
socket.send_message(SimpleQueryMessage.new("DISCARD ALL"))
|
||||
socket.read_from_server
|
||||
|
||||
10.times do |i|
|
||||
socket.send_message(ParseMessage.new("", "SELECT #{i}", []))
|
||||
socket.send_message(BindMessage.new("", "", [], [], [0]))
|
||||
socket.send_message(DescribeMessage.new("S", ""))
|
||||
socket.send_message(ExecuteMessage.new("", 1))
|
||||
socket.send_message(SyncMessage.new)
|
||||
socket.read_from_server
|
||||
end
|
||||
|
||||
socket.send_message(SimpleQueryMessage.new("SELECT name, statement, prepare_time, parameter_types FROM pg_prepared_statements"))
|
||||
result = socket.read_from_server
|
||||
number_of_saved_statements = result.count { |m| m[:code] == 'D' }
|
||||
expect(number_of_saved_statements).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "When named prepared statements are used" do
|
||||
it "caches them" do
|
||||
socket = PostgresSocket.new('localhost', processes.pgcat.port)
|
||||
socket.send_startup_message("sharding_user", "sharded_db", "sharding_user")
|
||||
|
||||
socket.send_message(SimpleQueryMessage.new("DISCARD ALL"))
|
||||
socket.read_from_server
|
||||
|
||||
3.times do
|
||||
socket.send_message(ParseMessage.new("my_query", "SELECT * FROM employees WHERE employee_id in ($1,$2,$3)", [0,0,0]))
|
||||
socket.send_message(BindMessage.new("", "my_query", [0,0,0], [0,0,0].map(&:to_s), [0,0,0,0,0,0]))
|
||||
socket.send_message(SyncMessage.new)
|
||||
socket.read_from_server
|
||||
end
|
||||
|
||||
3.times do
|
||||
socket.send_message(ParseMessage.new("my_other_query", "SELECT * FROM employees WHERE salary in ($1,$2,$3)", [0,0,0]))
|
||||
socket.send_message(BindMessage.new("", "my_other_query", [0,0,0], [0,0,0].map(&:to_s), [0,0,0,0,0,0]))
|
||||
socket.send_message(SyncMessage.new)
|
||||
socket.read_from_server
|
||||
end
|
||||
|
||||
socket.send_message(SimpleQueryMessage.new("SELECT name, statement, prepare_time, parameter_types FROM pg_prepared_statements"))
|
||||
result = socket.read_from_server
|
||||
number_of_saved_statements = result.count { |m| m[:code] == 'D' }
|
||||
expect(number_of_saved_statements).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context "When DISCARD ALL/DEALLOCATE ALL are called" do
|
||||
it "resets server and client caches" do
|
||||
socket = PostgresSocket.new('localhost', processes.pgcat.port)
|
||||
socket.send_startup_message("sharding_user", "sharded_db", "sharding_user")
|
||||
|
||||
20.times do |i|
|
||||
socket.send_message(ParseMessage.new("my_query_#{i}", "SELECT * FROM employees WHERE employee_id in ($1,$2,$3)", [0,0,0]))
|
||||
end
|
||||
|
||||
20.times do |i|
|
||||
socket.send_message(BindMessage.new("", "my_query_#{i}", [0,0,0], [0,0,0].map(&:to_s), [0,0,0,0,0,0]))
|
||||
end
|
||||
|
||||
socket.send_message(SyncMessage.new)
|
||||
socket.read_from_server
|
||||
|
||||
socket.send_message(SimpleQueryMessage.new("DISCARD ALL"))
|
||||
socket.read_from_server
|
||||
responses = []
|
||||
4.times do |i|
|
||||
socket.send_message(ParseMessage.new("my_query_#{i}", "SELECT * FROM employees WHERE employee_id in ($1,$2,$3)", [0,0,0]))
|
||||
socket.send_message(BindMessage.new("", "my_query_#{i}", [0,0,0], [0,0,0].map(&:to_s), [0,0,0,0,0,0]))
|
||||
socket.send_message(SyncMessage.new)
|
||||
|
||||
responses += socket.read_from_server
|
||||
end
|
||||
|
||||
errors = responses.select { |message| message[:code] == 'E' }
|
||||
error_message = errors.map { |message| message[:bytes].map(&:chr).join("") }.join("\n")
|
||||
raise StandardError, "Encountered the following errors: #{error_message}" if errors.length > 0
|
||||
end
|
||||
end
|
||||
|
||||
context "Maximum number of bound paramters" do
|
||||
it "does not crash" do
|
||||
test_socket = PostgresSocket.new('localhost', processes.pgcat.port)
|
||||
test_socket.send_startup_message("sharding_user", "sharded_db", "sharding_user")
|
||||
|
||||
types = Array.new(65_535) { |i| 0 }
|
||||
|
||||
params = Array.new(65_535) { |i| "$#{i+1}" }.join(",")
|
||||
test_socket.send_message(ParseMessage.new("my_query", "SELECT * FROM employees WHERE employee_id in (#{params})", types))
|
||||
|
||||
test_socket.send_message(BindMessage.new("my_query", "my_query", types, types.map(&:to_s), types))
|
||||
|
||||
test_socket.send_message(SyncMessage.new)
|
||||
|
||||
# If the proxy crashes, this will raise an error
|
||||
expect { test_socket.read_from_server }.to_not raise_error
|
||||
|
||||
test_socket.close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user