Skip to content

Commit

Permalink
chore: fresh DBs for mutation tests (#247)
Browse files Browse the repository at this point in the history
<!-- The PR description should answer 2 (maybe 3) important questions:
-->

### What

We want to test mutations. To do this, we need fresh databases we can
mutate and discard. This creates helpers for creating a fresh database.

I think the abstraction could be improved, but hopefully it's not too
arduous for the test writer.

### How

Helpers to 
- make a UUID
- create a DB with UUID as name
- connect to that DB, import chinook
- return new connection string
- delete it afterwards

---------

Co-authored-by: Gil Mizrahi <[email protected]>
  • Loading branch information
danieljharvey and Gil Mizrahi authored Sep 15, 2023
1 parent 3f1e402 commit 01f1d00
Show file tree
Hide file tree
Showing 17 changed files with 362 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ generated/
# nix outputs
/result
/result-*

# deployments created for testing
static/temp-deploys/*.json
108 changes: 108 additions & 0 deletions 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 crates/ndc-citus/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub async fn create_router() -> axum::Router {

// work out where the deployment configs live
let test_deployment_file =
tests_common::deployment::get_deployment_file(CHINOOK_DEPLOYMENT_PATH);
tests_common::deployment::helpers::get_path_from_project_root(CHINOOK_DEPLOYMENT_PATH);

// initialise server state with the static configuration.
let state = ndc_sdk::default_main::init_server_state::<connector::Citus>(
Expand Down
4 changes: 2 additions & 2 deletions crates/ndc-citus/tests/configuration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use similar_asserts::assert_eq;
// it should be switched the to the Citus one later
use ndc_postgres::configuration;

use tests_common::deployment::get_deployment_file;
use tests_common::deployment::helpers::get_path_from_project_root;

const CONFIGURATION_QUERY: &str = include_str!("../../ndc-postgres/src/configuration.sql");

Expand All @@ -26,7 +26,7 @@ async fn test_configure() {
};

let expected_value: serde_json::Value = {
let file = fs::File::open(get_deployment_file(common::CHINOOK_DEPLOYMENT_PATH))
let file = fs::File::open(get_path_from_project_root(common::CHINOOK_DEPLOYMENT_PATH))
.expect("fs::File::open");
let mut result: serde_json::Value =
serde_json::from_reader(file).expect("serde_json::from_reader");
Expand Down
2 changes: 1 addition & 1 deletion crates/ndc-cockroach/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub async fn create_router() -> axum::Router {

// work out where the deployment configs live
let test_deployment_file =
tests_common::deployment::get_deployment_file(CHINOOK_DEPLOYMENT_PATH);
tests_common::deployment::helpers::get_path_from_project_root(CHINOOK_DEPLOYMENT_PATH);

// initialise server state with the static configuration.
let state = ndc_sdk::default_main::init_server_state::<connector::Cockroach>(
Expand Down
4 changes: 2 additions & 2 deletions crates/ndc-cockroach/tests/configuration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::fs;

use similar_asserts::assert_eq;

use tests_common::deployment::get_deployment_file;
use tests_common::deployment::helpers::get_path_from_project_root;

const CONFIGURATION_QUERY: &str = include_str!("../src/configuration.sql");

Expand All @@ -22,7 +22,7 @@ async fn test_configure() {
};

let expected_value: serde_json::Value = {
let file = fs::File::open(get_deployment_file(common::CHINOOK_DEPLOYMENT_PATH))
let file = fs::File::open(get_path_from_project_root(common::CHINOOK_DEPLOYMENT_PATH))
.expect("fs::File::open");
let mut result: serde_json::Value =
serde_json::from_reader(file).expect("serde_json::from_reader");
Expand Down
7 changes: 6 additions & 1 deletion crates/ndc-postgres/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ pub const CHINOOK_DEPLOYMENT_PATH: &str = "static/chinook-deployment.json";

/// Creates a router with a fresh state from the test deployment.
pub async fn create_router() -> axum::Router {
create_router_from_deployment(CHINOOK_DEPLOYMENT_PATH).await
}

/// Creates a router with a fresh state from a deployment file path
pub async fn create_router_from_deployment(deployment_path: &str) -> axum::Router {
let _ = env_logger::builder().is_test(true).try_init();

// work out where the deployment configs live
let test_deployment_file =
tests_common::deployment::get_deployment_file(CHINOOK_DEPLOYMENT_PATH);
tests_common::deployment::helpers::get_path_from_project_root(deployment_path);

// initialise server state with the static configuration.
let state = ndc_sdk::default_main::init_server_state::<connector::Postgres>(
Expand Down
6 changes: 3 additions & 3 deletions crates/ndc-postgres/tests/configuration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use similar_asserts::assert_eq;

use ndc_postgres::configuration;

use tests_common::deployment::get_deployment_file;
use tests_common::deployment::helpers::get_path_from_project_root;

const POSTGRESQL_CONNECTION_STRING: &str = "postgresql://postgres:password@localhost:64002";
const CHINOOK_DEPLOYMENT_PATH: &str = "static/chinook-deployment.json";
Expand All @@ -26,8 +26,8 @@ async fn test_configure() {
};

let expected_value: serde_json::Value = {
let file =
fs::File::open(get_deployment_file(CHINOOK_DEPLOYMENT_PATH)).expect("fs::File::open");
let file = fs::File::open(get_path_from_project_root(CHINOOK_DEPLOYMENT_PATH))
.expect("fs::File::open");
let mut result: serde_json::Value =
serde_json::from_reader(file).expect("serde_json::from_reader");

Expand Down
29 changes: 29 additions & 0 deletions crates/ndc-postgres/tests/mutation_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
pub mod common;
use tests_common::deployment::{clean_up_deployment, create_fresh_deployment};
use tests_common::request::run_query;

pub const POSTGRESQL_CONNECTION_STRING: &str = "postgresql://postgres:password@localhost:64002";
pub const CHINOOK_DEPLOYMENT_PATH: &str = "static/chinook-deployment.json";

/// create a fresh db then run a query against it
mod basic {
use super::{clean_up_deployment, create_fresh_deployment, run_query};

#[tokio::test]
async fn select_by_pk() {
let deployment = create_fresh_deployment(
super::POSTGRESQL_CONNECTION_STRING,
super::CHINOOK_DEPLOYMENT_PATH,
)
.await;

let result = run_query(
super::common::create_router_from_deployment(&deployment.deployment_path).await,
"select_by_pk",
)
.await;

clean_up_deployment(deployment).await;
insta::assert_json_snapshot!(result)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: crates/ndc-postgres/tests/mutation_tests.rs
expression: result
---
[
{
"rows": [
{
"Title": "Garage Inc. (Disc 1)"
}
]
}
]
2 changes: 1 addition & 1 deletion crates/other-db-tests/src/aurora/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub async fn create_router() -> axum::Router {

// work out where the deployment configs live
let test_deployment_file =
tests_common::deployment::get_deployment_file(CHINOOK_DEPLOYMENT_PATH);
tests_common::deployment::helpers::get_path_from_project_root(CHINOOK_DEPLOYMENT_PATH);

// initialise server state with the static configuration.
let state = ndc_sdk::default_main::init_server_state::<connector::Postgres>(
Expand Down
3 changes: 3 additions & 0 deletions crates/tests-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ tracing = "0.1.37"
axum = "0.6.19"
axum-test-helper = "0.3.0"
reqwest = "0.11.20"
tokio-postgres = "0.7.10"
sqlx = { version = "0.7.1", features = [ "json", "postgres", "runtime-tokio-rustls" ] }
uuid = {version = "1.4.1", features = [ "v4", "fast-rng", "macro-diagnostics" ]}
44 changes: 44 additions & 0 deletions crates/tests-common/src/deployment/configuration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! Deployment configuration functions used across test cases.
//! Use via helpers in `mod.rs` rather than directly.
//!
use super::helpers::get_path_from_project_root;
use serde_json::Value;
use std::fs;

/// Load deployment at `main_deployment_path`
/// replace url with `new_postgres_url`
/// save at `new_deployment_path`
pub fn copy_deployment_with_new_postgres_url(
main_deployment_path: &str,
new_postgres_url: &str,
new_deployment_path: &str,
) {
let full_path = get_path_from_project_root(main_deployment_path);

// load and decode deployment
let deployment: Value = serde_json::from_str(&fs::read_to_string(full_path).unwrap()).unwrap();

let new_json = match deployment {
Value::Object(mut map) => {
map.insert(
"postgres_database_url".to_string(),
Value::String(new_postgres_url.to_string()),
);
Value::Object(map)
}
other => other,
};

let new_absolute_deployment_path = get_path_from_project_root(new_deployment_path);

let new_deployment = new_json.to_string();

fs::write(new_absolute_deployment_path, new_deployment).unwrap()
}

/// Erase test deployment file created at `deployment_path`
pub fn delete_deployment(deployment_path: &str) {
let absolute_path = get_path_from_project_root(deployment_path);

fs::remove_file(absolute_path).unwrap()
}
Loading

0 comments on commit 01f1d00

Please sign in to comment.