From 177f2ad8e72da01cc73cac29973c2e00e61a5dab Mon Sep 17 00:00:00 2001 From: goose Date: Sun, 22 Feb 2026 10:58:15 -0300 Subject: [PATCH] test: Add minimal test binary to verify Docker execution --- backend/src/main.rs | 183 ++++---------------------------------------- 1 file changed, 15 insertions(+), 168 deletions(-) diff --git a/backend/src/main.rs b/backend/src/main.rs index 37fca62..12ed1f7 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,181 +1,28 @@ -mod config; -mod db; -mod models; -mod auth; -mod handlers; -mod middleware; - -use axum::{ - routing::{get, post, put, delete}, - Router, - middleware as axum_middleware, -}; -use tower::ServiceBuilder; -use tower_http::{ - cors::CorsLayer, - trace::TraceLayer, -}; -use config::Config; use std::fs::OpenOptions; use std::io::Write; -// Helper function to log to both file and stdout -fn log(msg: &str) { - let timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S%.3f"); - let full_msg = format!("[{}] {}\n", timestamp, msg); +fn main() { + let msg = format!("BINARY STARTED: {}\n", chrono::Utc::now().to_rfc3339()); // Try to write to file if let Ok(mut file) = OpenOptions::new() .create(true) - .append(true) - .open("/tmp/normogen-startup.log") + .write(true) + .truncate(true) + .open("/tmp/test-startup.log") { - let _ = file.write_all(full_msg.as_bytes()); + let _ = file.write_all(msg.as_bytes()); let _ = file.flush(); } - // Also print to stdout - print!("{}", full_msg); + // Try to print to stdout + println!("BINARY STARTED"); let _ = std::io::stdout().flush(); -} - -// Wrapper to catch when main returns -async fn run() -> anyhow::Result<()> { - log("=== NORMOGEN STARTING ==="); - log("[1/7] Loading environment variables..."); - - match dotenv::dotenv() { - Ok(path) => { - log(&format!("[1/7] Loaded .env from: {:?}", path)); - } - Err(_) => { - log("[1/7] No .env file found (OK in Docker)"); - } - } - - log("[2/7] Initializing logging..."); - tracing_subscriber::fmt() - .with_env_filter( - tracing_subscriber::EnvFilter::try_from_default_env() - .unwrap_or_else(|_| "normogen_backend=debug,tower_http=debug,axum=debug".into()) - ) - .init(); - - log("[3/7] Loading configuration..."); - let config = match Config::from_env() { - Ok(cfg) => { - log(&format!("[3/7] Config loaded: DB={}, Port={}", cfg.database.database, cfg.server.port)); - cfg - } - Err(e) => { - log(&format!("[FATAL] Failed to load configuration: {}", e)); - return Err(e); - } - }; - - log(&format!("[4/7] Connecting to MongoDB at {}...", config.database.uri)); - log("[4/7] Starting MongoDB connection (this may hang)..."); - - let db = match db::MongoDb::new(&config.database.uri, &config.database.database).await { - Ok(db) => { - log("[4/7] MongoDB connection successful!"); - db - } - Err(e) => { - log(&format!("[FATAL] Failed to connect to MongoDB: {}", e)); - return Err(e); - } - }; - - log("[5/7] Performing health check..."); - match db.health_check().await { - Ok(_) => { - log("[5/7] MongoDB health check: OK"); - } - Err(e) => { - log(&format!("[FATAL] MongoDB health check failed: {}", e)); - return Err(e); - } - } - - log("[6/7] Building application..."); - let jwt_service = auth::JwtService::new(config.jwt.clone()); - - let app_state = config::AppState { - db, - jwt_service, - config: config.clone(), - }; - - let public_routes = Router::new() - .route("/health", get(handlers::health_check)) - .route("/ready", get(handlers::ready_check)) - .route("/api/auth/register", post(handlers::register)) - .route("/api/auth/login", post(handlers::login)) - .route("/api/auth/recover-password", post(handlers::recover_password)) - .layer( - ServiceBuilder::new() - .layer(TraceLayer::new_for_http()) - .layer(CorsLayer::new()) - ); - - let protected_routes = Router::new() - .route("/api/users/me", get(handlers::get_profile)) - .route("/api/users/me", put(handlers::update_profile)) - .route("/api/users/me", delete(handlers::delete_account)) - .route("/api/users/me/settings", get(handlers::get_settings)) - .route("/api/users/me/settings", put(handlers::update_settings)) - .route("/api/users/me/change-password", post(handlers::change_password)) - .route("/api/shares", post(handlers::create_share)) - .route("/api/shares", get(handlers::list_shares)) - .route("/api/shares/:id", get(handlers::get_share)) - .route("/api/shares/:id", put(handlers::update_share)) - .route("/api/shares/:id", delete(handlers::delete_share)) - .route("/api/permissions/check", post(handlers::check_permission)) - .layer( - ServiceBuilder::new() - .layer(TraceLayer::new_for_http()) - .layer(CorsLayer::new()) - ) - .route_layer(axum_middleware::from_fn_with_state( - app_state.clone(), - crate::middleware::auth::jwt_auth_middleware - )); - - let app = public_routes.merge(protected_routes).with_state(app_state); - - log(&format!("[7/7] Starting server on {}:{}...", config.server.host, config.server.port)); - let listener = tokio::net::TcpListener::bind(&format!("{}:{}", config.server.host, config.server.port)) - .await?; - - log("=== SERVER READY ==="); - log(&format!("Listening on http://{}:{}", config.server.host, config.server.port)); - log("About to call axum::serve (this blocks forever)..."); - - tracing::info!("Server listening on {}:{}", config.server.host, config.server.port); - - // This should block forever - axum::serve(listener, app).await?; - - // This should never be reached - log("[UNEXPECTED] Server stopped!"); - - Ok(()) -} - -#[tokio::main] -async fn main() { - log("MAIN ENTERED"); - let result = run().await; - log(&format!("MAIN EXITING: {:?}", result)); - std::process::exit(match result { - Ok(_) => { - log("EXIT CODE 0"); - 0 - } - Err(e) => { - log(&format!("EXIT CODE 1: {}", e)); - 1 - } - }); + + // Try to print to stderr + eprintln!("BINARY STARTED (stderr)"); + let _ = std::io::stderr().flush(); + + // Sleep to keep container alive + std::thread::sleep(std::time::Duration::from_secs(60)); }