Skip to content

Commit 38bf275

Browse files
authored
Add more server tests (#568)
1 parent 4098571 commit 38bf275

File tree

4 files changed

+134
-19
lines changed

4 files changed

+134
-19
lines changed

pgdog/src/backend/pool/cleanup.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ impl Cleanup {
7171
clean
7272
}
7373

74+
/// Number of queries to run for cleanup.
75+
pub fn len(&self) -> usize {
76+
self.queries.len()
77+
}
78+
7479
/// Cleanup prepared statements.
7580
pub fn prepared_statements() -> Self {
7681
Self {

pgdog/src/backend/pool/guard.rs

Lines changed: 85 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ impl Guard {
127127

128128
if cleanup.needed() {
129129
debug!(
130-
"[cleanup] {}, server in \"{}\" state [{}]",
131-
cleanup,
130+
"[cleanup] running {} cleanup queries, server in \"{}\" state [{}]",
131+
cleanup.len(),
132132
server.stats().state,
133133
server.addr()
134134
);
@@ -191,11 +191,16 @@ impl Drop for Guard {
191191
mod test {
192192
use std::time::Duration;
193193

194-
use tokio::time::sleep;
194+
use tokio::time::{sleep, timeout, Instant};
195195

196196
use crate::{
197-
backend::pool::{test::pool, Address, Config, Pool, PoolConfig, Request},
198-
net::{Describe, Flush, Parse, Protocol, Query, Sync},
197+
backend::{
198+
pool::{
199+
cleanup::Cleanup, test::pool, Address, Config, Guard, Pool, PoolConfig, Request,
200+
},
201+
server::test::test_server,
202+
},
203+
net::{Describe, Flush, Parse, Protocol, ProtocolMessage, Query, Sync},
199204
};
200205

201206
#[tokio::test]
@@ -292,14 +297,7 @@ mod test {
292297
};
293298

294299
let pool = Pool::new(&PoolConfig {
295-
address: Address {
296-
host: "127.0.0.1".into(),
297-
port: 5432,
298-
database_name: "pgdog".into(),
299-
user: "pgdog".into(),
300-
password: "pgdog".into(),
301-
..Default::default()
302-
},
300+
address: Address::new_test(),
303301
config,
304302
});
305303
pool.launch();
@@ -318,10 +316,79 @@ mod test {
318316

319317
sleep(Duration::from_millis(500)).await;
320318

321-
let state = pool.lock();
322-
assert_eq!(state.errors, 0);
323-
assert_eq!(state.idle(), 0);
324-
assert_eq!(state.total(), 0);
325-
assert_eq!(state.force_close, 1);
319+
{
320+
let state = pool.lock();
321+
assert_eq!(state.errors, 0);
322+
assert_eq!(state.idle(), 0);
323+
assert_eq!(state.total(), 0);
324+
assert_eq!(state.force_close, 1);
325+
}
326+
327+
// Will create new connection.
328+
let mut server = pool.get(&Request::default()).await.unwrap();
329+
let one: Vec<i32> = server.fetch_all("SELECT 1").await.unwrap();
330+
assert_eq!(one[0], 1);
331+
}
332+
333+
#[tokio::test]
334+
async fn test_cleanup_close_drain() {
335+
crate::logger();
336+
337+
let mut server = Guard::new(
338+
Pool::new_test(),
339+
Box::new(test_server().await),
340+
Instant::now(),
341+
);
342+
server.prepared_statements_mut().set_capacity(1);
343+
344+
for i in 0..5 {
345+
server
346+
.send(
347+
&vec![
348+
ProtocolMessage::from(Parse::named(format!("test_{}", i), "SELECT 1")),
349+
Flush.into(),
350+
]
351+
.into(),
352+
)
353+
.await
354+
.unwrap();
355+
356+
let ok = server.read().await.unwrap();
357+
assert_eq!(ok.code(), '1');
358+
assert!(server.done());
359+
}
360+
assert_eq!(server.prepared_statements().len(), 5);
361+
server
362+
.send(&vec![Query::new("SHOW prepared_statements").into()].into())
363+
.await
364+
.unwrap();
365+
let mut guard = server;
366+
let mut server = guard.server.take().unwrap();
367+
let cleanup = Cleanup::new(&guard, &mut server);
368+
assert_eq!(cleanup.close().len(), 4);
369+
assert!(server.needs_drain());
370+
371+
Guard::cleanup_internal(&mut server, cleanup).await.unwrap();
372+
373+
assert!(server.done());
374+
assert!(!server.needs_drain());
375+
376+
let one: Vec<i32> = server.fetch_all("SELECT 1").await.unwrap();
377+
assert_eq!(one[0], 1);
378+
}
379+
380+
#[tokio::test]
381+
async fn test_cancel_safety_partial_send() {
382+
let mut server = test_server().await;
383+
let select = (0..50_000_000).into_iter().map(|_| 'b').collect::<String>();
384+
let select = Query::new(format!("SELECT '{}'", select));
385+
let res = timeout(
386+
Duration::from_millis(1),
387+
server.send(&vec![select.into()].into()),
388+
)
389+
.await;
390+
assert!(res.is_err());
391+
assert!(server.force_close());
392+
assert!(server.io_in_progress())
326393
}
327394
}

pgdog/src/backend/server.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,11 @@ impl Server {
362362
}
363363
Err(err) => {
364364
error!(
365-
"{:?} got: {}, extended buffer: {:?}",
365+
"{:?} got: {}, extended buffer: {:?}, state: {}",
366366
err,
367367
message.code(),
368368
self.prepared_statements.state(),
369+
self.stats.state,
369370
);
370371
return Err(err);
371372
}
@@ -1352,6 +1353,9 @@ pub mod test {
13521353
.unwrap();
13531354
for c in ['T', 'D', 'C', 'T', 'D', 'C', 'Z'] {
13541355
let msg = server.read().await.unwrap();
1356+
if c != 'Z' {
1357+
assert!(!server.done());
1358+
}
13551359
assert_eq!(c, msg.code());
13561360
}
13571361
}
@@ -1854,6 +1858,36 @@ pub mod test {
18541858
assert!(server.in_sync());
18551859
}
18561860

1861+
#[tokio::test]
1862+
async fn test_copy_client_fail() {
1863+
let mut server = test_server().await;
1864+
server.execute("BEGIN").await.unwrap();
1865+
server
1866+
.execute("CREATE TABLE IF NOT EXISTS test_copy_t (id BIGINT)")
1867+
.await
1868+
.unwrap();
1869+
server
1870+
.send(
1871+
&vec![
1872+
Query::new("COPY test_copy_t(id) FROM STDIN CSV").into(),
1873+
CopyData::new(b"1\n").into(),
1874+
CopyFail::new("something went wrong").into(),
1875+
]
1876+
.into(),
1877+
)
1878+
.await
1879+
.unwrap();
1880+
for c in ['G', 'E', 'Z'] {
1881+
if c != 'Z' {
1882+
assert!(!server.done());
1883+
assert!(server.has_more_messages());
1884+
}
1885+
assert_eq!(server.read().await.unwrap().code(), c);
1886+
}
1887+
1888+
server.execute("ROLLBACK").await.unwrap();
1889+
}
1890+
18571891
#[tokio::test]
18581892
async fn test_query_stats() {
18591893
let mut server = test_server().await;

pgdog/src/net/messages/copy_fail.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ pub struct CopyFail {
55
error: Bytes,
66
}
77

8+
impl CopyFail {
9+
pub fn new(error: impl ToString) -> Self {
10+
let error = error.to_string();
11+
Self {
12+
error: Bytes::from(format!("{}\0", error)),
13+
}
14+
}
15+
}
16+
817
impl FromBytes for CopyFail {
918
fn from_bytes(mut bytes: Bytes) -> Result<Self, Error> {
1019
code!(bytes, 'f');

0 commit comments

Comments
 (0)