From 2aab3c0ceb444031096f82d774b7cf9d279f1374 Mon Sep 17 00:00:00 2001 From: phoenix Date: Mon, 31 Mar 2025 20:32:47 -0400 Subject: [PATCH 01/32] Added config file for db --- config.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 config.json diff --git a/config.json b/config.json new file mode 100644 index 0000000..62f535a --- /dev/null +++ b/config.json @@ -0,0 +1,6 @@ +{ + "host": "localhost", + "database": "icarus", + "username": "username", + "password": "password" +} -- 2.43.0 From 06256af3244efcd602ea7cd1c243615ea030e6c3 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:06:23 -0400 Subject: [PATCH 02/32] Added .env to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 96ef6c0..e551aa3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +.env -- 2.43.0 From afbdb2fed4c7783ca3b3fb869c62ea9f16dc4136 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:07:39 -0400 Subject: [PATCH 03/32] Added .env.sample --- .env.sample | 1 + 1 file changed, 1 insertion(+) create mode 100644 .env.sample diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..871db80 --- /dev/null +++ b/.env.sample @@ -0,0 +1 @@ +DATABASE_URL=postgres:://username:password@localhost/database_name \ No newline at end of file -- 2.43.0 From ecf8ff543b47b38f647a0328f644742055e9781c Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:31:50 -0400 Subject: [PATCH 04/32] Corrected .env.sample file --- .env.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.sample b/.env.sample index 871db80..669e014 100644 --- a/.env.sample +++ b/.env.sample @@ -1 +1 @@ -DATABASE_URL=postgres:://username:password@localhost/database_name \ No newline at end of file +DATABASE_URL=postgres://username:password@localhost/database_name \ No newline at end of file -- 2.43.0 From 7fe868ec309de0540aa793cc0c2a5fdbc3f95905 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:31:59 -0400 Subject: [PATCH 05/32] Added dependencies --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index ce7a653..bc1d557 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,6 @@ tokio = { version = "1.44.1", features = ["rt-multi-thread"] } tracing-subscriber = { version = "0.3.19" } tower = { version = "0.5.2" } hyper = { version = "1.6.0" } +sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } +dotenv = { version = "0.15" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } -- 2.43.0 From d5071ab768a4cc804c3197463cde3c23f1e604ad Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:32:43 -0400 Subject: [PATCH 06/32] Database connectivity works --- src/callers/mod.rs | 2 +- src/lib.rs | 16 ++++++++++++++++ src/main.rs | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/callers/mod.rs b/src/callers/mod.rs index 79b9089..ada84ab 100644 --- a/src/callers/mod.rs +++ b/src/callers/mod.rs @@ -3,5 +3,5 @@ pub mod register; pub mod endpoints { pub const ROOT: &str = "/"; - pub const REGISTER: &str = "api/v2/register"; + pub const REGISTER: &str = "/api/v2/register"; } diff --git a/src/lib.rs b/src/lib.rs index 231cc1e..0a095cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,19 @@ pub mod callers; pub mod config; pub mod models; + +pub mod db_pool { + + use sqlx::postgres::PgPoolOptions; + use std::env; + + pub async fn create_pool() -> Result { + dotenv::dotenv().ok(); + let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set in .env"); + + PgPoolOptions::new() + .max_connections(10) + .connect(&database_url) + .await + } +} diff --git a/src/main.rs b/src/main.rs index 036d622..4560611 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use axum::{ Router, routing::{get, post}, }; +// use std::net::SocketAddr; use icarus_auth::callers; use icarus_auth::config; @@ -11,8 +12,13 @@ async fn main() { // initialize tracing tracing_subscriber::fmt::init(); + let pool = icarus_auth::db_pool::create_pool() + .await + .expect("Failed to create pool"); + // build our application with a route let app = Router::new() + .layer(axum::Extension(pool)) .route(callers::endpoints::ROOT, get(callers::common::root)) .route( callers::endpoints::REGISTER, -- 2.43.0 From 3f282b01d980fc2f5a975758316a50e87c9bc35f Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:44:29 -0400 Subject: [PATCH 07/32] Removing config.json file --- config.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 config.json diff --git a/config.json b/config.json deleted file mode 100644 index 62f535a..0000000 --- a/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "host": "localhost", - "database": "icarus", - "username": "username", - "password": "password" -} -- 2.43.0 From 47623d7dd0b92328ba577f7cafb849f74a8f0b51 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:45:06 -0400 Subject: [PATCH 08/32] db pooling settings --- src/lib.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0a095cc..c3c562c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,17 +2,31 @@ pub mod callers; pub mod config; pub mod models; +mod keys { + pub const DBURL: &str = "DATABASE_URL"; + + pub mod error { + pub const ERROR: &str = "DATABASE_URL must be set in .env"; + } +} + +mod connection_settings { + pub const MAXCONN: u32 = 5; +} + pub mod db_pool { use sqlx::postgres::PgPoolOptions; use std::env; + use crate::{connection_settings, keys}; + pub async fn create_pool() -> Result { dotenv::dotenv().ok(); - let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set in .env"); + let database_url = env::var(keys::DBURL).expect(keys::error::ERROR); PgPoolOptions::new() - .max_connections(10) + .max_connections(connection_settings::MAXCONN) .connect(&database_url) .await } -- 2.43.0 From f9a31036165ffa39550183038cbb9242a7994046 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:56:11 -0400 Subject: [PATCH 09/32] Added dependencies --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index bc1d557..5bd450a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,6 @@ tower = { version = "0.5.2" } hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } dotenv = { version = "0.15" } +testcontainers = { version = "0.23.3" } +testcontainers-modules = { version = "0.11.6" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } -- 2.43.0 From e17a304896959ca040bb7c0e0959627e0f7d3cb5 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 20:56:25 -0400 Subject: [PATCH 10/32] Added more code --- src/callers/common.rs | 17 +++++++++++++++++ src/callers/mod.rs | 1 + src/main.rs | 1 + 3 files changed, 19 insertions(+) diff --git a/src/callers/common.rs b/src/callers/common.rs index c39654b..bdf5e0b 100644 --- a/src/callers/common.rs +++ b/src/callers/common.rs @@ -1,4 +1,21 @@ +use axum::{Json, http::StatusCode}; + +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +pub struct TestResult { + message: String, +} + // basic handler that responds with a static string pub async fn root() -> &'static str { "Hello, World!" } + +pub async fn db_ping() -> (StatusCode, Json) { + let tr = TestResult { + message: String::from("Should work"), + }; + + (StatusCode::OK, Json(tr)) +} diff --git a/src/callers/mod.rs b/src/callers/mod.rs index ada84ab..33ddec1 100644 --- a/src/callers/mod.rs +++ b/src/callers/mod.rs @@ -4,4 +4,5 @@ pub mod register; pub mod endpoints { pub const ROOT: &str = "/"; pub const REGISTER: &str = "/api/v2/register"; + pub const DBTEST: &str = "/api/v2/test/db"; } diff --git a/src/main.rs b/src/main.rs index 4560611..db3d182 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ async fn main() { // build our application with a route let app = Router::new() .layer(axum::Extension(pool)) + .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) .route(callers::endpoints::ROOT, get(callers::common::root)) .route( callers::endpoints::REGISTER, -- 2.43.0 From 401fb94b6bfd055c7b8c05a53422b200f5a49a63 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 21:05:36 -0400 Subject: [PATCH 11/32] Filled out endpoint to test db --- src/callers/common.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/callers/common.rs b/src/callers/common.rs index bdf5e0b..0e29287 100644 --- a/src/callers/common.rs +++ b/src/callers/common.rs @@ -1,4 +1,4 @@ -use axum::{Json, http::StatusCode}; +use axum::{Json, extract::Extension, http::StatusCode}; use serde::{Deserialize, Serialize}; @@ -12,10 +12,19 @@ pub async fn root() -> &'static str { "Hello, World!" } -pub async fn db_ping() -> (StatusCode, Json) { - let tr = TestResult { - message: String::from("Should work"), - }; - - (StatusCode::OK, Json(tr)) +pub async fn db_ping(Extension(pool): Extension) -> (StatusCode, Json) { + match sqlx::query("SELECT 1").execute(&pool).await { + Ok(_) => { + let tr = TestResult { + message: String::from("This works"), + }; + (StatusCode::OK, Json(tr)) + } + Err(e) => ( + StatusCode::BAD_REQUEST, + Json(TestResult { + message: e.to_string(), + }), + ), + } } -- 2.43.0 From 470ee220c8f3cf7d22d5a208ef4a43ee1e726c46 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 21:12:32 -0400 Subject: [PATCH 12/32] test db is working --- src/callers/common.rs | 2 +- src/main.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callers/common.rs b/src/callers/common.rs index 0e29287..afb5ffb 100644 --- a/src/callers/common.rs +++ b/src/callers/common.rs @@ -1,4 +1,4 @@ -use axum::{Json, extract::Extension, http::StatusCode}; +use axum::{Extension, Json, http::StatusCode}; use serde::{Deserialize, Serialize}; diff --git a/src/main.rs b/src/main.rs index db3d182..bfd25b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,13 +18,13 @@ async fn main() { // build our application with a route let app = Router::new() - .layer(axum::Extension(pool)) .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) .route(callers::endpoints::ROOT, get(callers::common::root)) .route( callers::endpoints::REGISTER, post(callers::register::register_user), - ); + ) + .layer(axum::Extension(pool)); // run our app with hyper, listening globally on port 3000 let url = config::get_full(); -- 2.43.0 From 74e6a298759588a9260d27d2c1aabbff55238e58 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 21:48:58 -0400 Subject: [PATCH 13/32] Updated workflow --- .gitea/workflows/workflow.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index d216362..15597bd 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -32,6 +32,14 @@ jobs: test: name: Test Suite runs-on: ubuntu-24.04 + services: + postgres: + image: postgres:latest + env: + POSTGRES_PASSWORD:postgres + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 -- 2.43.0 From 313f03d5003692ed4345d9a41ffdc965381b3fe7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 21:53:01 -0400 Subject: [PATCH 14/32] Removed docker in workflow --- .gitea/workflows/workflow.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 15597bd..d216362 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -32,14 +32,6 @@ jobs: test: name: Test Suite runs-on: ubuntu-24.04 - services: - postgres: - image: postgres:latest - env: - POSTGRES_PASSWORD:postgres - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 -- 2.43.0 From bdf674828bed0a5de51c6e315b2142af708cfb0e Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 21:53:18 -0400 Subject: [PATCH 15/32] Updated dependencies --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5bd450a..c6d3641 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,5 @@ hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } dotenv = { version = "0.15" } testcontainers = { version = "0.23.3" } -testcontainers-modules = { version = "0.11.6" } +testcontainers-modules = { version = "0.11.6", features = ["blocking", "postgres"] } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } -- 2.43.0 From b6c4e074ff3ee8fa759e0a17a12652cfe24b7072 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 21:53:52 -0400 Subject: [PATCH 16/32] Updated tests --- tests/auth_tests.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 19e08fe..4329563 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -1,5 +1,8 @@ extern crate icarus_auth; +use crate::icarus_auth::callers; + +use axum::Extension; use axum::body::Body; // use axum::response::Response; use axum::{ @@ -7,12 +10,23 @@ use axum::{ http::{Request, StatusCode}, routing::get, }; +use hyper::client::conn; +use sqlx::PgPool; +use sqlx::postgres::PgPoolOptions; +use testcontainers_modules::{postgres, testcontainers::runners::AsyncRunner}; +// use hyper::client; +// use sqlx::postgres; // use http::{Request, StatusCode}; // use serde_json::json; // use tower::ServiceExt; // for `.oneshot()` use tower::util::ServiceExt; +// use testcontainers_modules::testcontainers::core::client:: -use crate::icarus_auth::callers; +async fn setup_test(pool: sqlx::PgPool) -> Router { + Router::new() + .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) + .layer(Extension(pool)) +} #[tokio::test] async fn test_hello_world() { @@ -40,3 +54,21 @@ async fn test_hello_world() { assert_eq!(body, "Hello, World!"); } + +#[tokio::test] +async fn test_db_health_check() { + let container = testcontainers_modules::postgres::Postgres::default() + .start() + .await + .unwrap(); + let host_ip = container.get_host().await.unwrap(); + let host_port = container.get_host_port_ipv4(5432).await.unwrap(); + let conn_string = &format!( + "postgres://postgres:postgres@localhost:{}/postgres", + host_port + ); + + println!("Test Database: {}", conn_string); + + let test_pool = PgPoolOptions::new().connect(conn_string).await.unwrap(); +} -- 2.43.0 From 2db28fc0dac5065441a38a931c000c6b9c32b8a0 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 22:06:12 -0400 Subject: [PATCH 17/32] Test correction --- tests/auth_tests.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 4329563..bc284f0 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -2,7 +2,7 @@ extern crate icarus_auth; use crate::icarus_auth::callers; -use axum::Extension; +// use axum::Extension; use axum::body::Body; // use axum::response::Response; use axum::{ @@ -10,10 +10,10 @@ use axum::{ http::{Request, StatusCode}, routing::get, }; -use hyper::client::conn; -use sqlx::PgPool; +// use hyper::client::conn; +// use sqlx::PgPool; use sqlx::postgres::PgPoolOptions; -use testcontainers_modules::{postgres, testcontainers::runners::AsyncRunner}; +use testcontainers_modules::{testcontainers::runners::AsyncRunner}; // use hyper::client; // use sqlx::postgres; // use http::{Request, StatusCode}; @@ -22,11 +22,13 @@ use testcontainers_modules::{postgres, testcontainers::runners::AsyncRunner}; use tower::util::ServiceExt; // use testcontainers_modules::testcontainers::core::client:: +/* async fn setup_test(pool: sqlx::PgPool) -> Router { Router::new() .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) .layer(Extension(pool)) } +*/ #[tokio::test] async fn test_hello_world() { @@ -61,7 +63,7 @@ async fn test_db_health_check() { .start() .await .unwrap(); - let host_ip = container.get_host().await.unwrap(); + let _host_ip = container.get_host().await.unwrap(); let host_port = container.get_host_port_ipv4(5432).await.unwrap(); let conn_string = &format!( "postgres://postgres:postgres@localhost:{}/postgres", @@ -70,5 +72,5 @@ async fn test_db_health_check() { println!("Test Database: {}", conn_string); - let test_pool = PgPoolOptions::new().connect(conn_string).await.unwrap(); + let _test_pool = PgPoolOptions::new().connect(conn_string).await.unwrap(); } -- 2.43.0 From 20e3d30ef19c462efa0c42afb5408f72342f736e Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 22:09:14 -0400 Subject: [PATCH 18/32] Updated dependencies --- Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c6d3641..112e2b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ tower = { version = "0.5.2" } hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } dotenv = { version = "0.15" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } + +[dev-dependencies] testcontainers = { version = "0.23.3" } testcontainers-modules = { version = "0.11.6", features = ["blocking", "postgres"] } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } -- 2.43.0 From b3283c9e17149dd7310668ce6d0c8121d2a1a178 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 22:09:23 -0400 Subject: [PATCH 19/32] Formatted tests --- tests/auth_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index bc284f0..48143d5 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -13,7 +13,7 @@ use axum::{ // use hyper::client::conn; // use sqlx::PgPool; use sqlx::postgres::PgPoolOptions; -use testcontainers_modules::{testcontainers::runners::AsyncRunner}; +use testcontainers_modules::testcontainers::runners::AsyncRunner; // use hyper::client; // use sqlx::postgres; // use http::{Request, StatusCode}; -- 2.43.0 From 4ed57b94a9e3b4fef1f5d7e632c6e49aa7b52856 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 23:09:48 -0400 Subject: [PATCH 20/32] Added docker check --- .gitea/workflows/workflow.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index d216362..bedf50d 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -37,6 +37,20 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: 1.85.0 + # --- Add this step for explicit verification --- + - name: Verify Docker Environment + run: | + echo "Runner User Info:" + id + echo "Checking Docker Version:" + docker --version + echo "Checking Docker Daemon Status (info):" + docker info + echo "Checking Docker Daemon Status (ps):" + docker ps -a + echo "Docker environment check complete." + # NOTE: Do NOT use continue-on-error here. + # If Docker isn't working as expected, the job SHOULD fail here. - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key -- 2.43.0 From e4dc04ba96f3f060841b2640004f5b5e92345ded Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 23:19:27 -0400 Subject: [PATCH 21/32] Updated tests --- tests/auth_tests.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 48143d5..c5b103c 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -64,7 +64,8 @@ async fn test_db_health_check() { .await .unwrap(); let _host_ip = container.get_host().await.unwrap(); - let host_port = container.get_host_port_ipv4(5432).await.unwrap(); + let port = 5432; + let host_port = container.get_host_port_ipv4(port).await.unwrap(); let conn_string = &format!( "postgres://postgres:postgres@localhost:{}/postgres", host_port @@ -72,5 +73,13 @@ async fn test_db_health_check() { println!("Test Database: {}", conn_string); - let _test_pool = PgPoolOptions::new().connect(conn_string).await.unwrap(); + let _test_pool = + match PgPoolOptions::new().connect(conn_string).await { + Ok(_) => { + assert!(true, "Success"); + } + Err(err) => { + assert!(false, "Error: {:?}", err.to_string()); + } + }; } -- 2.43.0 From 945dd5f73e27bee3e0e4371b561a52864b64a379 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 23:20:16 -0400 Subject: [PATCH 22/32] Removed variable --- tests/auth_tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index c5b103c..359033e 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -73,7 +73,6 @@ async fn test_db_health_check() { println!("Test Database: {}", conn_string); - let _test_pool = match PgPoolOptions::new().connect(conn_string).await { Ok(_) => { assert!(true, "Success"); -- 2.43.0 From 2252ff8ec62a6af3bd23c9e2250e722913db163e Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 23:32:19 -0400 Subject: [PATCH 23/32] Commenting out test code for now --- tests/auth_tests.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 359033e..22efc5a 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -12,7 +12,7 @@ use axum::{ }; // use hyper::client::conn; // use sqlx::PgPool; -use sqlx::postgres::PgPoolOptions; +use sqlx::postgres::{self, PgPoolOptions}; use testcontainers_modules::testcontainers::runners::AsyncRunner; // use hyper::client; // use sqlx::postgres; @@ -57,8 +57,9 @@ async fn test_hello_world() { assert_eq!(body, "Hello, World!"); } +/* #[tokio::test] -async fn test_db_health_check() { +async fn _test_db_health_check() { let container = testcontainers_modules::postgres::Postgres::default() .start() .await @@ -73,6 +74,20 @@ async fn test_db_health_check() { println!("Test Database: {}", conn_string); + let app = Router::new().route(callers::endpoints::DBTEST, get(callers::common::db_ping)); // Replace with your handler + + let response = app + .oneshot( + Request::builder() + .uri(callers::endpoints::DBTEST) + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + match PgPoolOptions::new().connect(conn_string).await { Ok(_) => { assert!(true, "Success"); @@ -82,3 +97,4 @@ async fn test_db_health_check() { } }; } + */ -- 2.43.0 From 5a07510b9dd971bbc9dce1440def8a2e622aa066 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 1 Apr 2025 23:37:49 -0400 Subject: [PATCH 24/32] Test fix --- tests/auth_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 22efc5a..947972b 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -12,8 +12,8 @@ use axum::{ }; // use hyper::client::conn; // use sqlx::PgPool; -use sqlx::postgres::{self, PgPoolOptions}; -use testcontainers_modules::testcontainers::runners::AsyncRunner; +// use sqlx::postgres::{self, PgPoolOptions}; +// use testcontainers_modules::testcontainers::runners::AsyncRunner; // use hyper::client; // use sqlx::postgres; // use http::{Request, StatusCode}; -- 2.43.0 From ab03ab800aa22115171c27938124bb7506b870ba Mon Sep 17 00:00:00 2001 From: KD Date: Wed, 2 Apr 2025 18:24:30 -0400 Subject: [PATCH 25/32] Saving this for later Commands to run migrations --- run_migrations.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 run_migrations.txt diff --git a/run_migrations.txt b/run_migrations.txt new file mode 100644 index 0000000..ae8892a --- /dev/null +++ b/run_migrations.txt @@ -0,0 +1,3 @@ +cargo install sqlx-cli +sqlx migrate add init_migration +sqlx migrate run -- 2.43.0 From 55378156aecb3e7dc7249697b9d9208e0e081cc3 Mon Sep 17 00:00:00 2001 From: KD Date: Wed, 2 Apr 2025 18:39:50 -0400 Subject: [PATCH 26/32] Added helper functions --- tests/auth_tests.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 947972b..538b79b 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -22,6 +22,28 @@ use axum::{ use tower::util::ServiceExt; // use testcontainers_modules::testcontainers::core::client:: +const TEST_DATABASE_URL_ENV: &str = "TEST_DATABASE_URL"; +const DEFAULT_TEST_DATABASE_URL: &str = + "postgres://icarus_op_test:password@localhost:5432/icarus_auth_test"; + +static SETUP: std::sync::Once = std::sync::Once::new(); + +async fn setup_database() -> sqlx::PgPool { + let database_url = std::env::var(TEST_DATABASE_URL_ENV) + .unwrap_or_else(|_| DEFAULT_TEST_DATABASE_URL.to_string()); + let pool = sqlx::PgPool::connect(&database_url) + .await + .expect("Failed to connect to test database"); + + let migrator = sqlx::migrate::Migrator::new(std::path::Path::new("./migrations")) + .await + .expect("Failed to create migrator"); + migrator.run(&pool).await.expect("Failed to run migrations"); + + // Seed here if needed + pool +} + /* async fn setup_test(pool: sqlx::PgPool) -> Router { Router::new() -- 2.43.0 From 5749216d7d45506f8d6a5fb17b44083f5575164a Mon Sep 17 00:00:00 2001 From: KD Date: Wed, 2 Apr 2025 18:43:04 -0400 Subject: [PATCH 27/32] Updated .env.sample --- .env.sample | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.sample b/.env.sample index 669e014..1625b7a 100644 --- a/.env.sample +++ b/.env.sample @@ -1 +1,2 @@ -DATABASE_URL=postgres://username:password@localhost/database_name \ No newline at end of file +DATABASE_URL=postgres://username:password@localhost/database_name +TEST_DATABASE_URL=postgres://username:password@localhost/database_name_test -- 2.43.0 From 4fc15810f4c210bf0533cda58050a742a26e76f6 Mon Sep 17 00:00:00 2001 From: KD Date: Wed, 2 Apr 2025 18:52:00 -0400 Subject: [PATCH 28/32] Saving changes --- migrations/20250402221858_init_migrate.sql | 1 + tests/auth_tests.rs | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 migrations/20250402221858_init_migrate.sql diff --git a/migrations/20250402221858_init_migrate.sql b/migrations/20250402221858_init_migrate.sql new file mode 100644 index 0000000..8ddc1d3 --- /dev/null +++ b/migrations/20250402221858_init_migrate.sql @@ -0,0 +1 @@ +-- Add migration script here diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index 538b79b..d97ba49 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -35,15 +35,26 @@ async fn setup_database() -> sqlx::PgPool { .await .expect("Failed to connect to test database"); + /* let migrator = sqlx::migrate::Migrator::new(std::path::Path::new("./migrations")) .await .expect("Failed to create migrator"); migrator.run(&pool).await.expect("Failed to run migrations"); + */ // Seed here if needed pool } +#[tokio::test] +async fn test_db_health() { + SETUP.call_once(|| { + tokio::runtime::Runtime::new().unwrap().block_on(async { + setup_database().await; + }); + }); +} + /* async fn setup_test(pool: sqlx::PgPool) -> Router { Router::new() -- 2.43.0 From 8a5430662e6ec8a0af4426d6d1c0bb7cc8b8dad9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 2 Apr 2025 21:04:38 -0400 Subject: [PATCH 29/32] Added test --- Cargo.toml | 3 ++ src/main.rs | 85 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 112e2b2..489e626 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,11 @@ tower = { version = "0.5.2" } hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } dotenv = { version = "0.15" } +http-body-util = "0.1.3" icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } [dev-dependencies] testcontainers = { version = "0.23.3" } testcontainers-modules = { version = "0.11.6", features = ["blocking", "postgres"] } +reqwest = { version = "0.12", features = ["json"] } # For making HTTP requests in tests +once_cell = "1.19" # Useful for lazy initialization in tests/app setup \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index bfd25b9..489ae66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,28 +6,87 @@ use axum::{ use icarus_auth::callers; use icarus_auth::config; +// use sqlx::Postgres; #[tokio::main] async fn main() { // initialize tracing tracing_subscriber::fmt::init(); - let pool = icarus_auth::db_pool::create_pool() - .await - .expect("Failed to create pool"); - - // build our application with a route - let app = Router::new() - .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) - .route(callers::endpoints::ROOT, get(callers::common::root)) - .route( - callers::endpoints::REGISTER, - post(callers::register::register_user), - ) - .layer(axum::Extension(pool)); + let app = app().await; // run our app with hyper, listening globally on port 3000 let url = config::get_full(); let listener = tokio::net::TcpListener::bind(url).await.unwrap(); axum::serve(listener, app).await.unwrap(); } + +async fn app() -> Router { + let pool = icarus_auth::db_pool::create_pool() + .await + .expect("Failed to create pool"); + + // build our application with a route + Router::new() + .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) + .route(callers::endpoints::ROOT, get(callers::common::root)) + .route( + callers::endpoints::REGISTER, + post(callers::register::register_user), + ) + .layer(axum::Extension(pool)) +} + +#[cfg(test)] +mod tests { + use super::*; + use axum::{ + body::Body, + extract::connect_info::MockConnectInfo, + http::{self, Request, StatusCode}, + }; + use http_body_util::BodyExt; + // use http_body_util::BodyExt; // for `collect` + use serde_json::{Value, json}; + use tokio::net::TcpListener; + use tower::{Service, ServiceExt}; // for `call`, `oneshot`, and `ready` + + #[tokio::test] + async fn hello_world() { + let app = app().await; + + // `Router` implements `tower::Service>` so we can + // call it like any tower service, no need to run an HTTP server. + let response = app + .oneshot( + Request::builder() + .uri(callers::endpoints::ROOT) + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + + /* + match response.into_body().collect().await { + Ok(o) => { + let parsed: String = match String::from_utf8(o.to_bytes()) { + Ok(s) => s, + Err(err) => { + String::new() + } + }; + } + Err(err) => { + assert!(false, + "Error: {:?}", err.to_string()); + } + } + */ + + let body = response.into_body().collect().await.unwrap().to_bytes(); + assert_eq!(&body[..], b"Hello, World!"); + } +} -- 2.43.0 From c03e90725ff2f2849b7f255da3e098f18bbcd72a Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 2 Apr 2025 21:04:55 -0400 Subject: [PATCH 30/32] Commenting out code --- tests/auth_tests.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/auth_tests.rs b/tests/auth_tests.rs index d97ba49..7268c22 100644 --- a/tests/auth_tests.rs +++ b/tests/auth_tests.rs @@ -28,6 +28,23 @@ const DEFAULT_TEST_DATABASE_URL: &str = static SETUP: std::sync::Once = std::sync::Once::new(); +// Ensure tracing is initialized only once for all tests in this file +/* +static TRACING_INIT: Lazy<()> = Lazy::new(|| { + if std::env::var("RUST_LOG").is_err() { + // Set default log level if not provided + unsafe { + std::env::set_var("RUST_LOG", "info,tower_http=debug,your_project_name=debug"); + } + } + tracing_subscriber::fmt() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .with_test_writer() // Write logs to the test output capture + .init(); +}); +*/ + +/* async fn setup_database() -> sqlx::PgPool { let database_url = std::env::var(TEST_DATABASE_URL_ENV) .unwrap_or_else(|_| DEFAULT_TEST_DATABASE_URL.to_string()); @@ -35,17 +52,17 @@ async fn setup_database() -> sqlx::PgPool { .await .expect("Failed to connect to test database"); - /* let migrator = sqlx::migrate::Migrator::new(std::path::Path::new("./migrations")) .await .expect("Failed to create migrator"); migrator.run(&pool).await.expect("Failed to run migrations"); - */ // Seed here if needed pool } + */ +/* #[tokio::test] async fn test_db_health() { SETUP.call_once(|| { @@ -54,6 +71,7 @@ async fn test_db_health() { }); }); } +*/ /* async fn setup_test(pool: sqlx::PgPool) -> Router { @@ -63,6 +81,7 @@ async fn setup_test(pool: sqlx::PgPool) -> Router { } */ +/* #[tokio::test] async fn test_hello_world() { let app = Router::new().route(callers::endpoints::ROOT, get(callers::common::root)); // Replace with your handler @@ -89,6 +108,7 @@ async fn test_hello_world() { assert_eq!(body, "Hello, World!"); } +*/ /* #[tokio::test] -- 2.43.0 From e94707399030db03dbe207a83c91cb33e2626d79 Mon Sep 17 00:00:00 2001 From: KD Date: Thu, 3 Apr 2025 09:46:10 -0400 Subject: [PATCH 31/32] Test cleanup --- src/main.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 489ae66..be4da83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,13 +43,14 @@ mod tests { use axum::{ body::Body, extract::connect_info::MockConnectInfo, - http::{self, Request, StatusCode}, + http::{Request, StatusCode}, }; use http_body_util::BodyExt; // use http_body_util::BodyExt; // for `collect` - use serde_json::{Value, json}; - use tokio::net::TcpListener; - use tower::{Service, ServiceExt}; // for `call`, `oneshot`, and `ready` + // use serde_json::{Value, json}; + // use tokio::net::TcpListener; + // use tower::{Service, ServiceExt}; // for `call`, `oneshot`, and `ready` + use tower::ServiceExt; // for `call`, `oneshot`, and `ready` #[tokio::test] async fn hello_world() { -- 2.43.0 From 74587cff26311b7e9958a012e9790261fca8982f Mon Sep 17 00:00:00 2001 From: KD Date: Thu, 3 Apr 2025 09:50:35 -0400 Subject: [PATCH 32/32] Updated packages --- Cargo.toml | 8 +++----- src/main.rs | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 489e626..45a6f29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,9 @@ tower = { version = "0.5.2" } hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } dotenv = { version = "0.15" } -http-body-util = "0.1.3" icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } [dev-dependencies] -testcontainers = { version = "0.23.3" } -testcontainers-modules = { version = "0.11.6", features = ["blocking", "postgres"] } -reqwest = { version = "0.12", features = ["json"] } # For making HTTP requests in tests -once_cell = "1.19" # Useful for lazy initialization in tests/app setup \ No newline at end of file +http-body-util = "0.1.3" +reqwest = { version = "0.12.5", features = ["json"] } # For making HTTP requests in tests +once_cell = "1.19" # Useful for lazy initialization in tests/app setup diff --git a/src/main.rs b/src/main.rs index be4da83..80e37ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,7 @@ mod tests { use super::*; use axum::{ body::Body, - extract::connect_info::MockConnectInfo, + // extract::connect_info::MockConnectInfo, http::{Request, StatusCode}, }; use http_body_util::BodyExt; -- 2.43.0