From ef589cee0885905091dfb53ff201c150136aae0b Mon Sep 17 00:00:00 2001 From: Montana Low Date: Thu, 22 Jul 2021 21:28:55 -0700 Subject: [PATCH 1/3] fix test suite --- sqlx-core/src/postgres/connection/mod.rs | 15 +++++++++ tests/README.md | 18 ++++++++++ tests/docker.py | 1 + tests/mysql/macros.rs | 21 +++++++++--- tests/postgres/postgres.rs | 41 +++++++++-------------- tests/postgres/types.rs | 2 +- tests/sqlite/sqlite.db | Bin 36864 -> 36864 bytes tests/x.py | 12 ++++--- 8 files changed, 74 insertions(+), 36 deletions(-) create mode 100644 tests/README.md diff --git a/sqlx-core/src/postgres/connection/mod.rs b/sqlx-core/src/postgres/connection/mod.rs index e0238f5911..fd0cbee7d2 100644 --- a/sqlx-core/src/postgres/connection/mod.rs +++ b/sqlx-core/src/postgres/connection/mod.rs @@ -100,6 +100,21 @@ impl PgConnection { Ok(()) } + + pub async fn server_version(&mut self) -> Result { + let result = self.fetch_one("SHOW server_version;",).await?; + let server_version: String = result.get("server_version"); + + Ok(server_version) + } + + pub async fn server_major_version(&mut self) -> Result { + let server_version = self.server_version().await?; + let first = server_version.split(".").next().unwrap(); + let major_version = first.parse::().unwrap(); + + Ok(major_version) + } } impl Debug for PgConnection { diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000..bc2dc2327c --- /dev/null +++ b/tests/README.md @@ -0,0 +1,18 @@ + + +### Running Tests +SQLx uses docker to run many compatible database systems for integration testing. You'll need to [install docker](https://docs.docker.com/engine/) to run the full suite. You can validate your docker installation with: + + $ docker run hello-world + +Start the databases with `docker-compose` before running tests: + + $ docker-compose up + +Run all tests against all supported databases using: + + $ ./x.py + +If you see test failures, or want to run a more specific set of tests against a specific database, you can specify both the features to be tests and the DATABASE_URL. e.g. + + $ DATABASE_URL=mysql://root:password@127.0.0.1:49183/sqlx cargo test --no-default-features --features macros,offline,any,all-types,mysql,runtime-async-std-native-tls diff --git a/tests/docker.py b/tests/docker.py index b4cdadd650..e664c38c6e 100644 --- a/tests/docker.py +++ b/tests/docker.py @@ -1,4 +1,5 @@ import subprocess +import sys import time from os import path diff --git a/tests/mysql/macros.rs b/tests/mysql/macros.rs index 9b9b436c98..e6fc618cff 100644 --- a/tests/mysql/macros.rs +++ b/tests/mysql/macros.rs @@ -190,12 +190,19 @@ async fn with_test_row<'a>( conn: &'a mut MySqlConnection, ) -> anyhow::Result> { let mut transaction = conn.begin().await?; - sqlx::query!("INSERT INTO tweet(id, text, owner_id) VALUES (1, '#sqlx is pretty cool!', 1)") + sqlx::query!("INSERT INTO tweet(text, owner_id) VALUES ('#sqlx is pretty cool!', 1)") .execute(&mut transaction) .await?; Ok(transaction) } +async fn last_insert_id(conn: &mut MySqlConnection) -> anyhow::Result { + let result = sqlx::query!("SELECT last_insert_id() AS last_insert_id") + .fetch_one(conn) + .await?; + Ok(MyInt(result.last_insert_id as i64)) +} + #[derive(PartialEq, Eq, Debug, sqlx::Type)] #[sqlx(transparent)] struct MyInt(i64); @@ -212,12 +219,13 @@ struct OptionalRecord { async fn test_column_override_wildcard() -> anyhow::Result<()> { let mut conn = new::().await?; let mut conn = with_test_row(&mut conn).await?; + let id = last_insert_id(&mut conn).await?; let record = sqlx::query_as!(Record, "select id as `id: _` from tweet") .fetch_one(&mut conn) .await?; - assert_eq!(record.id, MyInt(1)); + assert_eq!(record.id, id); // this syntax is also useful for expressions let record = sqlx::query_as!(Record, "select * from (select 1 as `id: _`) records") @@ -253,12 +261,13 @@ async fn test_column_override_wildcard_not_null() -> anyhow::Result<()> { async fn test_column_override_wildcard_nullable() -> anyhow::Result<()> { let mut conn = new::().await?; let mut conn = with_test_row(&mut conn).await?; + let id = last_insert_id(&mut conn).await?; let record = sqlx::query_as!(OptionalRecord, "select id as `id?: _` from tweet") .fetch_one(&mut conn) .await?; - assert_eq!(record.id, Some(MyInt(1))); + assert_eq!(record.id, Some(id)); Ok(()) } @@ -267,12 +276,13 @@ async fn test_column_override_wildcard_nullable() -> anyhow::Result<()> { async fn test_column_override_exact() -> anyhow::Result<()> { let mut conn = new::().await?; let mut conn = with_test_row(&mut conn).await?; + let id = last_insert_id(&mut conn).await?; let record = sqlx::query!("select id as `id: MyInt` from tweet") .fetch_one(&mut conn) .await?; - assert_eq!(record.id, MyInt(1)); + assert_eq!(record.id, id); // we can also support this syntax for expressions let record = sqlx::query!("select * from (select 1 as `id: MyInt`) records") @@ -308,12 +318,13 @@ async fn test_column_override_exact_not_null() -> anyhow::Result<()> { async fn test_column_override_exact_nullable() -> anyhow::Result<()> { let mut conn = new::().await?; let mut conn = with_test_row(&mut conn).await?; + let id = last_insert_id(&mut conn).await?; let record = sqlx::query!("select id as `id?: MyInt` from tweet") .fetch_one(&mut conn) .await?; - assert_eq!(record.id, Some(MyInt(1))); + assert_eq!(record.id, Some(id)); Ok(()) } diff --git a/tests/postgres/postgres.rs b/tests/postgres/postgres.rs index 5688aded5f..dbe212a716 100644 --- a/tests/postgres/postgres.rs +++ b/tests/postgres/postgres.rs @@ -968,6 +968,12 @@ async fn test_listener_cleanup() -> anyhow::Result<()> { #[sqlx_macros::test] async fn it_supports_domain_types_in_composite_domain_types() -> anyhow::Result<()> { + // Only supported in Postgres 11+ + let mut conn = new::().await?; + if !(conn.server_major_version().await? >= 11) { + return Ok(()); + } + #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] struct MonthId(i16); @@ -1040,21 +1046,14 @@ async fn it_supports_domain_types_in_composite_domain_types() -> anyhow::Result< } } - let mut conn = new::().await?; - - { - let result = sqlx::query("DELETE FROM heating_bills;") - .execute(&mut conn) - .await; - - let result = result.unwrap(); - assert_eq!(result.rows_affected(), 1); - } + // Ensure the table is empty to begin to avoid CPK violations from repeat runs + sqlx::query("DELETE FROM heating_bills;") + .execute(&mut conn) + .await; - { - let result = sqlx::query( - "INSERT INTO heating_bills(month, cost) VALUES($1::winter_year_month, 100);", - ) + let result = sqlx::query( + "INSERT INTO heating_bills(month, cost) VALUES($1::winter_year_month, 100);", + ) .bind(WinterYearMonth { year: 2021, month: MonthId(1), @@ -1062,18 +1061,8 @@ async fn it_supports_domain_types_in_composite_domain_types() -> anyhow::Result< .execute(&mut conn) .await; - let result = result.unwrap(); - assert_eq!(result.rows_affected(), 1); - } - - { - let result = sqlx::query("DELETE FROM heating_bills;") - .execute(&mut conn) - .await; - - let result = result.unwrap(); - assert_eq!(result.rows_affected(), 1); - } + let result = result.unwrap(); + assert_eq!(result.rows_affected(), 1); Ok(()) } diff --git a/tests/postgres/types.rs b/tests/postgres/types.rs index 5ae5bd217e..932f6b81f3 100644 --- a/tests/postgres/types.rs +++ b/tests/postgres/types.rs @@ -211,7 +211,7 @@ test_type!(ipnetwork_vec>(Postgres, #[cfg(feature = "mac_address")] test_type!(mac_address_vec>(Postgres, - "'{01:02:03:04:05:06,FF:FF:FF:FF:FF:FF}'::inet[]" + "'{01:02:03:04:05:06,FF:FF:FF:FF:FF:FF}'::macaddr[]" == vec![ "01:02:03:04:05:06".parse::().unwrap(), "FF:FF:FF:FF:FF:FF".parse::().unwrap() diff --git a/tests/sqlite/sqlite.db b/tests/sqlite/sqlite.db index 49913441dfd6583610d79217efdf7676d7a20153..d693511079064edcd5e0a6f55efedafe17ab855b 100644 GIT binary patch delta 1062 zcmZY7KS-NF7{~FLH;{UFKG%2Ypi2e?6OBnUe~g;=`adQ^2ImeA6`d5!(&>%5iO|8e z;G%+y4uYD&K^FyG1pf>|=^~1Yw796?VzEDy;gtuDFUN-mj^nPl>MpLjw>)7ZCnguY z;e4j%gL+ao>P+pc4fRvasVVhYWmQ7eD^vcHf8;NDBzNSBT##Som>iLo49Z&R6_4Ut zoQgfME`EqvF}Xc+QEi(!!{slGPfYv%uTfv&%XGoaavJ88;WWf)kkf#J?8=e-4y#Zf zr(RAyoGeb=oYHS(zq@#fk9BeC6<0%eLg|DB(YH8LvIrS9BDj^-D=Rz9PXI;ulDpc}ML*Xd8%)Jl7`n_lRd z9_XI#=$5YNH(k;>ozO8I&_3&WTg>)hvND^sB5=b10AyK5wW5irlt=LA8FcLyqkRZ~GG$8@R Lk2IFj`9td!C$tWy delta 45 zcmZozz|^pSX#b!MEAY|BwR!G0qL! diff --git a/tests/x.py b/tests/x.py index 2133beefe4..832b914ebb 100755 --- a/tests/x.py +++ b/tests/x.py @@ -88,8 +88,6 @@ def run(command, comment=None, env=None, service=None, tag=None, args=None, data # check # -run("cargo c", comment="check with a default set of features", tag="check") - run( "cargo c --no-default-features --features runtime-async-std-native-tls,all-databases,all-types,offline,macros", comment="check with async-std", @@ -113,9 +111,9 @@ def run(command, comment=None, env=None, service=None, tag=None, args=None, data # run( - "cargo test --manifest-path sqlx-core/Cargo.toml --features all-databases,all-types", + "cargo test --no-default-features --manifest-path sqlx-core/Cargo.toml --features all-databases,all-types,runtime-async-std-native-tls", comment="unit test core", - tag="unit" + tag="unit_async_std" ) run( @@ -124,6 +122,12 @@ def run(command, comment=None, env=None, service=None, tag=None, args=None, data tag="unit_tokio" ) +run( + "cargo test --no-default-features --manifest-path sqlx-core/Cargo.toml --features all-databases,all-types,runtime-actix-native-tls", + comment="unit test core", + tag="unit_actix" +) + # # integration tests # From d2f990e0efed53f343534040383afa1ab704bb17 Mon Sep 17 00:00:00 2001 From: Montana Low Date: Mon, 26 Jul 2021 20:00:30 -0700 Subject: [PATCH 2/3] rustfmt --- sqlx-core/src/postgres/connection/mod.rs | 2 +- tests/postgres/postgres.rs | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sqlx-core/src/postgres/connection/mod.rs b/sqlx-core/src/postgres/connection/mod.rs index fd0cbee7d2..6ca1cf3731 100644 --- a/sqlx-core/src/postgres/connection/mod.rs +++ b/sqlx-core/src/postgres/connection/mod.rs @@ -102,7 +102,7 @@ impl PgConnection { } pub async fn server_version(&mut self) -> Result { - let result = self.fetch_one("SHOW server_version;",).await?; + let result = self.fetch_one("SHOW server_version;").await?; let server_version: String = result.get("server_version"); Ok(server_version) diff --git a/tests/postgres/postgres.rs b/tests/postgres/postgres.rs index dbe212a716..b5a0954b98 100644 --- a/tests/postgres/postgres.rs +++ b/tests/postgres/postgres.rs @@ -1051,15 +1051,14 @@ async fn it_supports_domain_types_in_composite_domain_types() -> anyhow::Result< .execute(&mut conn) .await; - let result = sqlx::query( - "INSERT INTO heating_bills(month, cost) VALUES($1::winter_year_month, 100);", - ) - .bind(WinterYearMonth { - year: 2021, - month: MonthId(1), - }) - .execute(&mut conn) - .await; + let result = + sqlx::query("INSERT INTO heating_bills(month, cost) VALUES($1::winter_year_month, 100);") + .bind(WinterYearMonth { + year: 2021, + month: MonthId(1), + }) + .execute(&mut conn) + .await; let result = result.unwrap(); assert_eq!(result.rows_affected(), 1); From 00cfc4a31d283653b70b5082773bd91be2983d00 Mon Sep 17 00:00:00 2001 From: Montana Low Date: Mon, 26 Jul 2021 20:14:02 -0700 Subject: [PATCH 3/3] need Row --- sqlx-core/src/postgres/connection/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sqlx-core/src/postgres/connection/mod.rs b/sqlx-core/src/postgres/connection/mod.rs index 6ca1cf3731..e352923c00 100644 --- a/sqlx-core/src/postgres/connection/mod.rs +++ b/sqlx-core/src/postgres/connection/mod.rs @@ -17,6 +17,7 @@ use crate::postgres::message::{ }; use crate::postgres::statement::PgStatementMetadata; use crate::postgres::{PgConnectOptions, PgTypeInfo, Postgres}; +use crate::row::Row; use crate::transaction::Transaction; pub(crate) mod describe;