Skip to content

Commit

Permalink
Merge pull request #2150 from fermyon/outbound-postgres-runtime-test
Browse files Browse the repository at this point in the history
Outbound postgres runtime tests
  • Loading branch information
rylev authored Dec 11, 2023
2 parents 45987c0 + dfab4ec commit de7d847
Show file tree
Hide file tree
Showing 22 changed files with 215 additions and 1,913 deletions.
7 changes: 7 additions & 0 deletions test-components/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test-components/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
members = ["sqlite", "helper", "outbound-mysql", "outbound-redis", "key-value"]
members = ["*"]
resolver = "2"
10 changes: 10 additions & 0 deletions test-components/outbound-postgres/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "outbound-postgres"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
helper = { path = "../helper" }
9 changes: 9 additions & 0 deletions test-components/outbound-postgres/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Outbound PostgreSQL

Tests the outbound PostgreSQL interface.

## Expectations

This test component expects the following to be true:
* It can connect to a PostgreSQL database using the connection string stored in the environment variable `DB_URL`
* It does not have access to a PostgreSQL database at localhost:10000
Binary file added test-components/outbound-postgres/component.wasm
Binary file not shown.
153 changes: 153 additions & 0 deletions test-components/outbound-postgres/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use helper::{ensure, ensure_eq, ensure_matches, ensure_ok};

use bindings::fermyon::spin2_0_0::{postgres, rdbms_types};

helper::define_component!(Component);
const DB_URL_ENV: &str = "DB_URL";

impl Component {
fn main() -> Result<(), String> {
ensure_matches!(
postgres::Connection::open("hello"),
Err(postgres::Error::ConnectionFailed(_))
);
ensure_matches!(
postgres::Connection::open("localhost:10000"),
Err(postgres::Error::ConnectionFailed(_))
);

let address = ensure_ok!(std::env::var(DB_URL_ENV));
let conn = ensure_ok!(postgres::Connection::open(&address));

let rowset = ensure_ok!(numeric_types(&conn));
ensure!(rowset.rows.iter().all(|r| r.len() == 12));
ensure_matches!(rowset.rows[0][11], rdbms_types::DbValue::Floating64(f) if f == 1.0);

let rowset = ensure_ok!(character_types(&conn));
ensure!(rowset.rows.iter().all(|r| r.len() == 3));
ensure!(matches!(rowset.rows[0][0], rdbms_types::DbValue::Str(ref s) if s == "rvarchar"));

let rowset = ensure_ok!(nullable(&conn));
ensure!(rowset.rows.iter().all(|r| r.len() == 1));
ensure!(matches!(rowset.rows[0][0], rdbms_types::DbValue::DbNull));

let pid1 = format!("{:?}", ensure_ok!(pg_backend_pid(&conn)));
let pid2 = format!("{:?}", ensure_ok!(pg_backend_pid(&conn)));
ensure_eq!(pid1, pid2);

Ok(())
}
}

fn numeric_types(conn: &postgres::Connection) -> Result<postgres::RowSet, postgres::Error> {
let create_table_sql = r#"
CREATE TEMPORARY TABLE test_numeric_types (
intid integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
rsmallserial smallserial NOT NULL,
rsmallint smallint NOT NULL,
rint2 int2 NOT NULL,
rserial serial NOT NULL,
rint int NOT NULL,
rint4 int4 NOT NULL,
rbigserial bigserial NOT NULL,
rbigint bigint NOT NULL,
rint8 int8 NOT NULL,
rreal real NOT NULL,
rdouble double precision NOT NULL
);
"#;

conn.execute(create_table_sql, &[])?;

let insert_sql = r#"
INSERT INTO test_numeric_types
(rsmallint, rint2, rint, rint4, rbigint, rint8, rreal, rdouble)
VALUES
(0, 0, 0, 0, 0, 0, 0, 1);
"#;

conn.execute(insert_sql, &[])?;

let sql = r#"
SELECT
intid,
rsmallserial,
rsmallint,
rint2,
rserial,
rint,
rint4,
rbigserial,
rbigint,
rint8,
rreal,
rdouble
FROM test_numeric_types;
"#;

conn.query(sql, &[])
}

fn character_types(conn: &postgres::Connection) -> Result<postgres::RowSet, postgres::Error> {
let create_table_sql = r#"
CREATE TEMPORARY TABLE test_character_types (
rvarchar varchar(40) NOT NULL,
rtext text NOT NULL,
rchar char(10) NOT NULL
);
"#;

conn.execute(create_table_sql, &[])?;

let insert_sql = r#"
INSERT INTO test_character_types
(rvarchar, rtext, rchar)
VALUES
('rvarchar', 'rtext', 'rchar');
"#;

conn.execute(insert_sql, &[])?;

let sql = r#"
SELECT
rvarchar, rtext, rchar
FROM test_character_types;
"#;

conn.query(sql, &[])
}

fn nullable(conn: &postgres::Connection) -> Result<postgres::RowSet, postgres::Error> {
let create_table_sql = r#"
CREATE TEMPORARY TABLE test_nullable (
rvarchar varchar(40)
);
"#;

conn.execute(create_table_sql, &[])?;

let insert_sql = r#"
INSERT INTO test_nullable
(rvarchar)
VALUES
($1);
"#;

conn.execute(insert_sql, &[rdbms_types::ParameterValue::DbNull])?;

let sql = r#"
SELECT
rvarchar
FROM test_nullable;
"#;

conn.query(sql, &[])
}

fn pg_backend_pid(conn: &postgres::Connection) -> Result<rdbms_types::DbValue, postgres::Error> {
let sql = "SELECT pg_backend_pid()";

let rowset = conn.query(sql, &[])?;

Ok(rowset.rows[0][0].clone())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error::ConnectionFailed("address postgres://spin:spin@postgres:5432/spin_dev is not permitted")
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
spin_manifest_version = 2

[application]
name = "outbound-postgres"
authors = ["Fermyon Engineering <[email protected]>"]
version = "0.1.0"

[[trigger.http]]
route = "/"
component = "test"

[component.test]
source = "{{outbound-postgres}}"
environment = { DB_URL = "postgres://spin:spin@postgres:5432/spin_dev" }
15 changes: 15 additions & 0 deletions tests/runtime-tests/tests/outbound-postgres/spin.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
spin_manifest_version = 2

[application]
name = "outbound-postgres"
authors = ["Fermyon Engineering <[email protected]>"]
version = "0.1.0"

[[trigger.http]]
route = "/"
component = "test"

[component.test]
source = "{{outbound-postgres}}"
allowed_outbound_hosts = ["postgres://postgres:5432"]
environment = { DB_URL = "postgres://postgres:postgres@postgres:5432/spin_dev" }
5 changes: 5 additions & 0 deletions tests/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ mod runtime_tests {

test!(outbound_mysql, "outbound-mysql");
test!(outbound_mysql_no_permission, "outbound-mysql-no-permission");
test!(outbound_postgres, "outbound-postgres");
test!(
outbound_postgres_no_permission,
"outbound-postgres-no-permission"
);
test!(outbound_redis, "outbound-redis");
test!(outbound_redis_no_permission, "outbound-redis-no-permission");
test!(sqlite, "sqlite");
Expand Down
10 changes: 0 additions & 10 deletions tests/spinup_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,6 @@ mod spinup_tests {
testcases::header_dynamic_env_works(CONTROLLER).await
}

#[tokio::test]
async fn http_rust_outbound_mysql_works() {
testcases::http_rust_outbound_mysql_works(CONTROLLER).await
}

#[tokio::test]
async fn http_rust_outbound_pg_works() {
testcases::http_rust_outbound_pg_works(CONTROLLER).await
}

#[tokio::test]
async fn redis_go_works() {
testcases::redis_go_works(CONTROLLER).await
Expand Down
2 changes: 0 additions & 2 deletions tests/testcases/http-rust-outbound-mysql/.cargo/config.toml

This file was deleted.

Loading

0 comments on commit de7d847

Please sign in to comment.