aboutsummaryrefslogtreecommitdiff
path: root/planetwars-server/tests/integration.rs
blob: 487a25e7f80eb7cdac71b174e3250b0463b4d10a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use axum::{
    body::Body,
    http::{self, Request, StatusCode},
};
use diesel::{PgConnection, RunQueryDsl};
use planetwars_server::{create_db_pool, create_pw_api, GlobalConfig};
use serde_json::{self, json, Value as JsonValue};
use std::{io, path::Path, sync::Arc};
use tempfile::TempDir;
use tower::ServiceExt;

// Used to serialize tests that access the database.
// TODO: see to what degree we could support transactional testing.
static DB_LOCK: parking_lot::Mutex<()> = parking_lot::Mutex::new(());

fn create_subdir<P: AsRef<Path>>(base_path: &Path, p: P) -> io::Result<String> {
    let dir_path = base_path.join(p);
    std::fs::create_dir(&dir_path)?;
    let dir_path_string = dir_path.into_os_string().into_string().unwrap();
    Ok(dir_path_string)
}

fn clear_database(conn: &PgConnection) {
    diesel::sql_query(
        "TRUNCATE TABLE
        bots,
        bot_versions,
        maps,
        matches,
        match_players,
        ratings,
        sessions,
        users",
    )
    .execute(conn)
    .expect("failed to clear database");
}

#[tokio::test(flavor = "multi_thread")]
async fn test_application() -> io::Result<()> {
    let _db_guard = DB_LOCK.lock();
    let data_dir = TempDir::new().expect("failed to create temp dir");
    let config = Arc::new(GlobalConfig {
        database_url: "postgresql://planetwars:planetwars@localhost/planetwars-test".to_string(),
        python_runner_image: "python:3.10-slim-buster".to_string(),
        container_registry_url: "localhost:9001".to_string(),
        root_url: "localhost:3000".to_string(),
        bots_directory: create_subdir(data_dir.path(), "bots")?,
        match_logs_directory: create_subdir(data_dir.path(), "matches")?,
        maps_directory: create_subdir(data_dir.path(), "maps")?,
        registry_directory: create_subdir(data_dir.path(), "registry")?,
        registry_admin_password: "secret_admin_password".to_string(),
        ranker_enabled: false,
    });
    let db_pool = create_db_pool(&config).await;
    {
        let db_conn = db_pool.get().await.expect("failed to get db connection");
        clear_database(&db_conn);
    }
    let app = create_pw_api(config, db_pool);

    let response = app
        .oneshot(
            Request::builder()
                .method(http::Method::GET)
                .uri("/api/bots")
                .body(Body::empty())
                .unwrap(),
        )
        .await
        .unwrap();

    assert_eq!(response.status(), StatusCode::OK);
    let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
    let resp: JsonValue = serde_json::from_slice(&body).unwrap();
    assert_eq!(resp, json!([]));
    Ok(())
}