aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2022-10-04 07:02:46 +0200
committerIlion Beyst <ilion.beyst@gmail.com>2022-10-04 07:02:46 +0200
commit790da3cf1a44a397f340583320841cf459d188a6 (patch)
treee5ad23927a6854b89d8f6f38f03f2288a77813ab
parentf6da362f94622d1c0d09d1fdbef84997ad8dc7c0 (diff)
downloadplanetwars.dev-790da3cf1a44a397f340583320841cf459d188a6.tar.xz
planetwars.dev-790da3cf1a44a397f340583320841cf459d188a6.zip
rough but functional integration test
-rw-r--r--maps/hex.json43
-rw-r--r--planetwars-server/tests/integration.rs88
2 files changed, 121 insertions, 10 deletions
diff --git a/maps/hex.json b/maps/hex.json
new file mode 100644
index 0000000..5ef4f31
--- /dev/null
+++ b/maps/hex.json
@@ -0,0 +1,43 @@
+{
+ "planets": [
+ {
+ "name": "protos",
+ "x": -6,
+ "y": 0,
+ "owner": 1,
+ "ship_count": 6
+ },
+ {
+ "name": "duteros",
+ "x": -3,
+ "y": 5,
+ "ship_count": 6
+ },
+ {
+ "name": "tritos",
+ "x": 3,
+ "y": 5,
+ "ship_count": 6
+ },
+ {
+ "name": "tetartos",
+ "x": 6,
+ "y": 0,
+ "owner": 2,
+ "ship_count": 6
+ },
+ {
+ "name": "pemptos",
+ "x": 3,
+ "y": -5,
+ "ship_count": 6
+ },
+ {
+ "name": "extos",
+ "x": -3,
+ "y": -5,
+ "ship_count": 6
+ }
+ ]
+}
+
diff --git a/planetwars-server/tests/integration.rs b/planetwars-server/tests/integration.rs
index 487a25e..b9d2170 100644
--- a/planetwars-server/tests/integration.rs
+++ b/planetwars-server/tests/integration.rs
@@ -3,11 +3,16 @@ use axum::{
http::{self, Request, StatusCode},
};
use diesel::{PgConnection, RunQueryDsl};
-use planetwars_server::{create_db_pool, create_pw_api, GlobalConfig};
+use planetwars_server::{create_db_pool, create_pw_api, db, modules, GlobalConfig};
use serde_json::{self, json, Value as JsonValue};
-use std::{io, path::Path, sync::Arc};
+use std::{
+ io,
+ path::{Path, PathBuf},
+ sync::Arc,
+ time::Duration,
+};
use tempfile::TempDir;
-use tower::ServiceExt;
+use tower::Service;
// Used to serialize tests that access the database.
// TODO: see to what degree we could support transactional testing.
@@ -56,15 +61,51 @@ async fn test_application() -> io::Result<()> {
{
let db_conn = db_pool.get().await.expect("failed to get db connection");
clear_database(&db_conn);
+
+ let bot = db::bots::create_bot(
+ &db::bots::NewBot {
+ owner_id: None,
+ name: "simplebot",
+ },
+ &db_conn,
+ )
+ .expect("could not create simplebot");
+
+ let simplebot_code = std::fs::read_to_string("../simplebot/simplebot.py")
+ .expect("could not read simplebot code");
+ let _bot_version =
+ modules::bots::save_code_string(&simplebot_code, Some(bot.id), &db_conn, &config)
+ .expect("could not save bot version");
+
+ std::fs::copy(
+ "../maps/hex.json",
+ PathBuf::from(&config.maps_directory).join("hex.json"),
+ )
+ .expect("could not copy map");
+ db::maps::create_map(
+ db::maps::NewMap {
+ name: "hex",
+ file_path: "hex.json",
+ },
+ &db_conn,
+ )
+ .expect("could not save map");
}
- let app = create_pw_api(config, db_pool);
+ let mut app = create_pw_api(config, db_pool);
+ let simplebot_code = std::fs::read_to_string("../simplebot/simplebot.py")
+ .expect("could not read simplebot code");
+
+ let payload = json!({
+ "code": simplebot_code,
+ });
let response = app
- .oneshot(
+ .call(
Request::builder()
- .method(http::Method::GET)
- .uri("/api/bots")
- .body(Body::empty())
+ .method(http::Method::POST)
+ .header("Content-Type", "application/json")
+ .uri("/api/submit_bot")
+ .body(serde_json::to_vec(&payload).unwrap().into())
.unwrap(),
)
.await
@@ -73,6 +114,33 @@ async fn test_application() -> io::Result<()> {
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(())
+
+ let match_id = &resp["match"]["id"];
+ let mut num_tries = 0;
+ loop {
+ num_tries += 1;
+ assert!(num_tries <= 100, "time limit exceeded");
+ tokio::time::sleep(Duration::from_millis(100)).await;
+
+ let response = app
+ .call(
+ Request::builder()
+ .method(http::Method::GET)
+ .header("Content-Type", "application/json")
+ .uri(format!("/api/matches/{}", match_id))
+ .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();
+ match resp["state"].as_str() {
+ Some("Playing") => (), // continue,
+ Some("Finished") => return Ok(()), // success
+ value => panic!("got unexpected match state {:?}", value),
+ }
+ }
}