aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2022-09-30 17:28:24 +0200
committerIlion Beyst <ilion.beyst@gmail.com>2022-09-30 17:28:24 +0200
commit8f6b34db10c591507271845150314be7a07cee19 (patch)
tree3eacb3ee6d8f00387e2eab7555d1737a3d65c1f1
parent81781489963dca8488607ef9c0e61fdde2cfd25b (diff)
downloadplanetwars.dev-8f6b34db10c591507271845150314be7a07cee19.tar.xz
planetwars.dev-8f6b34db10c591507271845150314be7a07cee19.zip
add integration test stub
-rw-r--r--planetwars-server/Cargo.toml4
-rw-r--r--planetwars-server/src/lib.rs23
-rw-r--r--planetwars-server/tests/integration.rs57
3 files changed, 75 insertions, 9 deletions
diff --git a/planetwars-server/Cargo.toml b/planetwars-server/Cargo.toml
index 2b3916c..6fb46d5 100644
--- a/planetwars-server/Cargo.toml
+++ b/planetwars-server/Cargo.toml
@@ -49,4 +49,6 @@ shlex = "1.1"
tonic-build = "0.7.2"
[dev-dependencies]
-parking_lot = "0.11"
+tower = { version = "0.4", features = ["util"] }
+parking_lot = "0.12"
+tempfile = "3" \ No newline at end of file
diff --git a/planetwars-server/src/lib.rs b/planetwars-server/src/lib.rs
index 6018eee..1301adb 100644
--- a/planetwars-server/src/lib.rs
+++ b/planetwars-server/src/lib.rs
@@ -112,7 +112,8 @@ fn init_directories(config: &GlobalConfig) -> std::io::Result<()> {
Ok(())
}
-pub fn api() -> Router {
+// just the routes, without connecting state
+fn api() -> Router {
Router::new()
.route("/register", post(routes::users::register))
.route("/login", post(routes::users::login))
@@ -140,6 +141,14 @@ pub fn api() -> Router {
.route("/save_bot", post(routes::bots::save_bot))
}
+// full service
+pub fn create_pw_api(global_config: Arc<GlobalConfig>, db_pool: DbPool) -> Router {
+ Router::new()
+ .nest("/api", api())
+ .layer(Extension(db_pool))
+ .layer(Extension(global_config))
+}
+
pub fn get_config() -> Result<GlobalConfig, ConfigError> {
config::Config::builder()
.add_source(config::File::with_name("configuration.toml"))
@@ -175,16 +184,14 @@ pub async fn run_app() {
tokio::spawn(run_registry(global_config.clone(), db_pool.clone()));
tokio::spawn(run_client_api(global_config.clone(), db_pool.clone()));
- let api_service = Router::new()
- .nest("/api", api())
- .layer(Extension(db_pool))
- .layer(Extension(global_config))
- .into_make_service();
-
// TODO: put in config
let addr = SocketAddr::from(([127, 0, 0, 1], 9000));
- axum::Server::bind(&addr).serve(api_service).await.unwrap();
+ let pw_api_service = create_pw_api(global_config, db_pool).into_make_service();
+ axum::Server::bind(&addr)
+ .serve(pw_api_service)
+ .await
+ .unwrap();
}
// we can also write a custom extractor that grabs a connection from the pool
diff --git a/planetwars-server/tests/integration.rs b/planetwars-server/tests/integration.rs
new file mode 100644
index 0000000..29589ad
--- /dev/null
+++ b/planetwars-server/tests/integration.rs
@@ -0,0 +1,57 @@
+use axum::{
+ body::Body,
+ http::{self, Request, StatusCode},
+};
+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)
+}
+
+#[tokio::test]
+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 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(())
+}