mirror of
https://github.com/roapi/roapi.git
synced 2026-06-05 21:04:02 +08:00
286 lines
9.3 KiB
Rust
286 lines
9.3 KiB
Rust
mod helpers;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use anyhow::Result;
|
|
use async_process::Command;
|
|
use columnq::arrow::datatypes::Schema;
|
|
use tokio;
|
|
|
|
#[tokio::test]
|
|
async fn test_schema() -> Result<()> {
|
|
let json_table = helpers::get_spacex_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![json_table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_get(&format!("{}/api/schema", address), None).await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
let body = response.json::<HashMap<String, Schema>>().await?;
|
|
assert!(body.contains_key("spacex_launches"));
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_uk_cities_sql_post() -> Result<()> {
|
|
let table = helpers::get_uk_cities_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_post(
|
|
&format!("{}/api/sql", address),
|
|
"SELECT city FROM uk_cities WHERE lat > 52 and lat < 53 and lng < -1",
|
|
)
|
|
.await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
let data = response.json::<serde_json::Value>().await?;
|
|
assert_eq!(
|
|
data,
|
|
serde_json::json!([
|
|
{"city": "Solihull, Birmingham, UK"},
|
|
{"city": "Rugby, Warwickshire, UK"},
|
|
{"city": "Sutton Coldfield, West Midlands, UK"},
|
|
{"city": "Wolverhampton, West Midlands, UK"},
|
|
{"city": "Frankton, Warwickshire, UK"}
|
|
])
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_sql_invalid_post() -> Result<()> {
|
|
let table = helpers::get_uk_cities_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_post(&format!("{}/api/sql", address), "SELECT city FROM").await;
|
|
|
|
assert_eq!(response.status(), 400);
|
|
let data = response.json::<serde_json::Value>().await?;
|
|
assert_eq!(
|
|
data,
|
|
serde_json::json!({
|
|
"code": 400,
|
|
"error": "plan_sql",
|
|
"message": "Failed to plan execution from SQL query: SQL error: ParserError(\"Expected identifier, found: EOF\")"
|
|
})
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_ubuntu_ami_sql_post() -> Result<()> {
|
|
let table = helpers::get_ubuntu_ami_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_post(
|
|
&format!("{}/api/sql", address),
|
|
"SELECT ami_id FROM ubuntu_ami \
|
|
WHERE version='12.04 LTS' \
|
|
AND arch = 'amd64' \
|
|
AND zone='us-west-2' \
|
|
AND instance_type='hvm:ebs-ssd'",
|
|
)
|
|
.await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
let data = response.json::<serde_json::Value>().await?;
|
|
assert_eq!(
|
|
data,
|
|
serde_json::json!([
|
|
{"ami_id":"<a href=\"https://console.aws.amazon.com/ec2/home?region=us-west-2#launchAmi=ami-270f9747\">ami-270f9747</a>"}
|
|
])
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_rest_get() -> Result<()> {
|
|
let table = helpers::get_ubuntu_ami_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
let accept_headers = vec![
|
|
None,
|
|
Some("application/json"),
|
|
Some("text/html,application/xhtml+xml,application/xml;q=0.9"),
|
|
Some("text/html,application/xhtml+xml,application/xml;q=0.9,application/json;q=0.5"),
|
|
];
|
|
|
|
for accept_header in accept_headers {
|
|
let response = helpers::http_get(
|
|
&format!(
|
|
"{}/api/tables/ubuntu_ami?\
|
|
columns=name,version,release&\
|
|
filter[arch]='amd64'&\
|
|
filter[zone]eq='us-west-2'&\
|
|
filter[instance_type]eq='hvm:ebs-ssd'&\
|
|
sort=-version,release\
|
|
",
|
|
address
|
|
),
|
|
accept_header,
|
|
)
|
|
.await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
let data = response.json::<serde_json::Value>().await?;
|
|
assert_eq!(
|
|
data,
|
|
serde_json::json!([
|
|
{ "release": "20201205", "version": "20.10", "name": "groovy" },
|
|
{ "release": "20201201", "version": "20.04 LTS", "name": "focal" },
|
|
{ "release": "20200716.1", "version": "19.10", "name": "eoan" },
|
|
{ "release": "20200115", "version": "19.04", "name": "disco" },
|
|
{ "release": "20201201", "version": "18.04 LTS", "name": "bionic" },
|
|
{ "release": "20201202.1", "version": "16.04 LTS", "name": "xenial" },
|
|
{ "release": "20191107", "version": "14.04 LTS", "name": "trusty" },
|
|
{ "release": "20170502", "version": "12.04 LTS", "name": "precise" }
|
|
])
|
|
);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_graphql_post_query_op() -> Result<()> {
|
|
let table = helpers::get_ubuntu_ami_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_post(
|
|
&format!("{}/api/graphql", address),
|
|
r#"query {
|
|
ubuntu_ami(
|
|
filter: {
|
|
arch: "amd64"
|
|
zone: { eq: "us-west-2" }
|
|
instance_type: { eq: "hvm:ebs-ssd" }
|
|
}
|
|
sort: [
|
|
{ field: "version", order: "desc" }
|
|
{ field: "release" }
|
|
]
|
|
) {
|
|
name
|
|
version
|
|
release
|
|
}
|
|
}"#,
|
|
)
|
|
.await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
let data = response.json::<serde_json::Value>().await?;
|
|
assert_eq!(
|
|
data,
|
|
serde_json::json!([
|
|
{ "release": "20201205", "version": "20.10", "name": "groovy" },
|
|
{ "release": "20201201", "version": "20.04 LTS", "name": "focal" },
|
|
{ "release": "20200716.1", "version": "19.10", "name": "eoan" },
|
|
{ "release": "20200115", "version": "19.04", "name": "disco" },
|
|
{ "release": "20201201", "version": "18.04 LTS", "name": "bionic" },
|
|
{ "release": "20201202.1", "version": "16.04 LTS", "name": "xenial" },
|
|
{ "release": "20191107", "version": "14.04 LTS", "name": "trusty" },
|
|
{ "release": "20170502", "version": "12.04 LTS", "name": "precise" }
|
|
])
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_graphql_post_selection() -> Result<()> {
|
|
let table = helpers::get_ubuntu_ami_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_post(
|
|
&format!("{}/api/graphql", address),
|
|
r#"{
|
|
ubuntu_ami(
|
|
filter: {
|
|
arch: "amd64"
|
|
zone: { eq: "us-west-2" }
|
|
instance_type: { eq: "hvm:ebs-ssd" }
|
|
}
|
|
sort: [
|
|
{ field: "version", order: "desc" }
|
|
]
|
|
) {
|
|
name
|
|
version
|
|
}
|
|
}"#,
|
|
)
|
|
.await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
let data = response.json::<serde_json::Value>().await?;
|
|
assert_eq!(
|
|
data,
|
|
serde_json::json!([
|
|
{ "version": "20.10", "name": "groovy" },
|
|
{ "version": "20.04 LTS", "name": "focal" },
|
|
{ "version": "19.10", "name": "eoan" },
|
|
{ "version": "19.04", "name": "disco" },
|
|
{ "version": "18.04 LTS", "name": "bionic" },
|
|
{ "version": "16.04 LTS", "name": "xenial" },
|
|
{ "version": "14.04 LTS", "name": "trusty" },
|
|
{ "version": "12.04 LTS", "name": "precise" }
|
|
])
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_http2() -> Result<()> {
|
|
let table = helpers::get_uk_cities_table();
|
|
let (app, address) = helpers::test_api_app_with_tables(vec![table]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
// ~ % curl -sI --http2-prior-knowledge localhost:8080/api/schema -o/dev/null -w '%{http_version}\n'
|
|
// 2
|
|
|
|
let http_version = Command::new("curl")
|
|
.arg("-s")
|
|
.arg("-I")
|
|
.arg("--http2-prior-knowledge")
|
|
.arg(format!("{}/api/schema", address))
|
|
.arg("-o")
|
|
.arg("/dev/null")
|
|
.arg("-w")
|
|
.arg("'%{http_version}\n'")
|
|
.output()
|
|
.await?
|
|
.stdout;
|
|
|
|
let two = vec!['\'', '2', '\n', '\'']
|
|
.iter()
|
|
.map(|c| *c as u8)
|
|
.collect::<Vec<_>>();
|
|
|
|
assert_eq!(http_version, two);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_kvstore_get() -> Result<()> {
|
|
let store = helpers::get_spacex_launch_name_kvstore();
|
|
let (app, address) = helpers::test_api_app_with_kvstores(vec![store]).await;
|
|
tokio::spawn(app.run_until_stopped());
|
|
|
|
let response = helpers::http_get(
|
|
&format!(
|
|
"{}/api/kv/spacex_launch_name/600f9a8d8f798e2a4d5f979e",
|
|
address
|
|
),
|
|
None,
|
|
)
|
|
.await;
|
|
|
|
assert_eq!(response.status(), 200);
|
|
assert_eq!(response.text().await?, "Starlink-21 (v1.0)");
|
|
Ok(())
|
|
}
|