From a25a6e92793537277b796ca9751f77ac4b082d64 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Tue, 8 Jan 2019 17:26:03 -0800 Subject: integrate pg_tmp into tests --- rust/README.md | 4 ++++ rust/src/lib.rs | 26 +++++++++++++++++++++----- rust/tests/pg_tmp.sh | 1 + 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/rust/README.md b/rust/README.md index decfc74d..33249a44 100644 --- a/rust/README.md +++ b/rust/README.md @@ -42,6 +42,10 @@ Build and run: Tests: + cargo test + + # if you get weird postgres errors, try running only one test at a time + # (slow and conservative) cargo test -- --test-threads 1 Note that most "integration" level tests are written in python and run by diff --git a/rust/src/lib.rs b/rust/src/lib.rs index b3e6c813..0d9ef813 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -24,6 +24,7 @@ extern crate regex; extern crate lazy_static; extern crate macaroon; extern crate sha1; +extern crate rand; pub mod api_entity_crud; pub mod api_helpers; @@ -100,7 +101,9 @@ use diesel::r2d2::ConnectionManager; use dotenv::dotenv; use iron::middleware::AfterMiddleware; use iron::{Request, Response}; -use std::env; +use std::{env, thread, time}; +use std::process::Command; +use rand::Rng; #[cfg(feature = "postgres")] embed_migrations!("../migrations/"); @@ -156,22 +159,35 @@ pub fn server() -> Result { }) } +/// Generates a server for testing. Calls an external bash script to generate a random postgres +/// database, which will be unique to this process but common across threads and connections. The +/// database will automagically get cleaned up (deleted) after 60 seconds. +/// Currently, start times are staggered by up to 200ms to prevent internal postgres concurrency +/// errors; if this fails run the tests serially (one at a time), which is slower but more robust. +/// CI should run tests serially. pub fn test_server() -> Result { dotenv().ok(); - let database_url = env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set"); + // sleep a bit so we don't have thundering herd collisions, resuliting in + // "pg_extension_name_index" or "pg_proc_proname_args_nsp_index" or "pg_type_typname_nsp_index" + // duplicate key violations. + thread::sleep(time::Duration::from_millis(rand::thread_rng().gen_range(0, 200))); + let pg_tmp = Command::new("./tests/pg_tmp.sh") + .output() + .expect("run ./tests/pg_tmp.sh to get temporary postgres DB"); + let database_url = String::from_utf8_lossy(&pg_tmp.stdout).to_string(); env::set_var("DATABASE_URL", database_url); let mut server = server()?; server.auth_confectionary = AuthConfectionary::new_dummy(); let conn = server.db_pool.get().expect("db_pool error"); - // run migrations; revert latest (dummy data); re-run latest - diesel_migrations::run_pending_migrations(&conn).unwrap(); - diesel_migrations::revert_latest_migration(&conn).unwrap(); + // run migrations; this is a fresh/bare database diesel_migrations::run_pending_migrations(&conn).unwrap(); Ok(server) } +// TODO: move this to bin/fatcatd + /// HTTP header middleware header! { (XClacksOverhead, "X-Clacks-Overhead") => [String] } diff --git a/rust/tests/pg_tmp.sh b/rust/tests/pg_tmp.sh index c7582477..2036a76c 100755 --- a/rust/tests/pg_tmp.sh +++ b/rust/tests/pg_tmp.sh @@ -40,6 +40,7 @@ while [ $# -gt 0 ]; do done # bnewbold: hack this in to "make it work" on debian/ubuntu +# bnewbold: also note, pg_virtualenv could also work, but is ubuntu/debian specific export PATH="$PATH:/usr/lib/postgresql/9.6/bin:/usr/lib/postgresql/11/bin" initdb -V > /dev/null || exit 1 PGVER=$(psql -V | awk '{print $NF}') -- cgit v1.2.3