Skip to content

Commit

Permalink
Merge pull request #138 from HerodotusDev/tests/hdp-server
Browse files Browse the repository at this point in the history
Add server integration tests for dry run, fetch proofs, and sound run…
  • Loading branch information
Okm165 authored Jan 29, 2025
2 parents da696df + 8c0a4af commit dd9d2ab
Show file tree
Hide file tree
Showing 8 changed files with 4,701 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ target
.snfoundry_cache/
.cargo

!examples/*.json
!examples/*.json
!crates/server/tests/*.json
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ clap = { version = "4.3.10", features = ["derive"] }
eth-trie-proofs = { git = "https://github.com/HerodotusDev/eth-trie-proofs.git" }
futures = "0.3.31"
hex = "0.4.3"
http-body-util = "=0.1.0"
indicatif = "0.17.9"
num-bigint = "0.4.6"
num-traits = "0.2.19"
Expand Down
6 changes: 6 additions & 0 deletions crates/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ tokio.workspace = true
tower-http.workspace = true
tracing-subscriber.workspace = true
types.workspace = true
utoipa.workspace = true
utoipa-swagger-ui.workspace = true

[dev-dependencies]
http-body-util.workspace = true
serde_json.workspace = true
tower = "0.5.2"
utoipa.workspace = true
178 changes: 178 additions & 0 deletions crates/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,181 @@ async fn shutdown_signal() {
_ = terminate => {},
}
}

#[cfg(test)]
mod tests {
use axum::{
body::Body,
http::{Request, StatusCode},
};
use dry_hint_processor::syscall_handler::SyscallHandler;
use http_body_util::BodyExt;
use tower::ServiceExt;
use types::{ChainProofs, HDPDryRunInput, HDPInput};

use super::*;

fn build_test_app() -> Router {
Router::new()
.route("/dry_run", post(dry_run::root))
.route("/fetch_proofs", post(fetch_proofs::root))
.route("/sound_run", post(sound_run::root))
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_dry_run_endpoint() {
let app = build_test_app();
let input = serde_json::json!({
"params": Option::<()>::None,
"layout": "starknet_with_keccak",
"input": serde_json::from_str::<HDPDryRunInput>(
&std::fs::read_to_string("tests/hdp_input.json").unwrap()
).unwrap()
});

let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/dry_run")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&input).unwrap()))
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), StatusCode::OK);
let body = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap();
let output: serde_json::Value = serde_json::from_slice(&body).unwrap();
assert_eq!(
output,
serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string("tests/hdp_keys.json").unwrap()).unwrap()
);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_fetch_proofs_endpoint() {
let app = build_test_app();
let input = serde_json::from_str::<SyscallHandler>(&std::fs::read_to_string("tests/hdp_keys.json").unwrap()).unwrap();

let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/fetch_proofs")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&input).unwrap()))
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), StatusCode::OK);
let body = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap();
let output: serde_json::Value = serde_json::from_slice(&body).unwrap();
assert_eq!(
output,
serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string("tests/hdp_proofs.json").unwrap()).unwrap()
);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_sound_run_endpoint() {
let app = build_test_app();
let sub_input = serde_json::from_str::<HDPDryRunInput>(&std::fs::read_to_string("tests/hdp_input.json").unwrap()).unwrap();
let input = serde_json::json!({
"params": Option::<()>::None,
"layout": "starknet_with_keccak",
"input": HDPInput {
chain_proofs: serde_json::from_str::<Vec<ChainProofs>>(
&std::fs::read_to_string("tests/hdp_proofs.json").unwrap()
).unwrap(),
params: sub_input.params,
compiled_class: sub_input.compiled_class,
}
});

let response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/sound_run")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&input).unwrap()))
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), StatusCode::OK);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_pipeline_integration() {
let app = build_test_app();

// 1. First dry run
let sub_input = serde_json::from_str::<HDPDryRunInput>(&std::fs::read_to_string("tests/hdp_input.json").unwrap()).unwrap();
let dry_run_input = serde_json::json!({
"params": Option::<()>::None,
"layout": "starknet_with_keccak",
"input": sub_input
});
let dry_run_response = app
.clone()
.oneshot(
Request::builder()
.method("POST")
.uri("/dry_run")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&dry_run_input).unwrap()))
.unwrap(),
)
.await
.unwrap();
assert_eq!(dry_run_response.status(), StatusCode::OK);

// 2. Then fetch proofs
let fetch_input =
serde_json::from_slice::<SyscallHandler>(&dry_run_response.into_body().collect().await.unwrap().to_bytes()).unwrap();
let fetch_response = app
.clone()
.oneshot(
Request::builder()
.method("POST")
.uri("/fetch_proofs")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&fetch_input).unwrap()))
.unwrap(),
)
.await
.unwrap();
assert_eq!(fetch_response.status(), StatusCode::OK);

// 3. Finally sound run
let sound_run_input = serde_json::json!({
"params": Option::<()>::None,
"layout": "starknet_with_keccak",
"input": HDPInput {
chain_proofs: serde_json::from_slice::<Vec<ChainProofs>>(
&fetch_response.into_body().collect().await.unwrap().to_bytes()
).unwrap(),
params: sub_input.params,
compiled_class: sub_input.compiled_class,
}
});
let sound_run_response = app
.oneshot(
Request::builder()
.method("POST")
.uri("/sound_run")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&sound_run_input).unwrap()))
.unwrap(),
)
.await
.unwrap();
assert_eq!(sound_run_response.status(), StatusCode::OK);
}
}
Loading

0 comments on commit dd9d2ab

Please sign in to comment.