Skip to content

Commit e8bee92

Browse files
ci: download bench input from gcs
1 parent 85b40ae commit e8bee92

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bench_tools/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ tokio = { workspace = true, features = ["full"] }
1515
[dev-dependencies]
1616
glob.workspace = true
1717
serde_json.workspace = true
18+
tempfile.workspace = true
1819

1920
[[bench]]
2021
harness = false

bench_tools/src/gcs.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,95 @@ pub async fn upload_inputs(benchmark_name: &str, input_dir: &Path) {
3535
println!("{}", String::from_utf8_lossy(&output.stdout).trim());
3636
println!("Input files uploaded successfully!");
3737
}
38+
39+
/// Downloads all input files for a benchmark from Google Cloud Storage.
40+
///
41+
/// Uses gcloud CLI to download files. Before running, authenticate with:
42+
/// `gcloud auth application-default login`
43+
///
44+
/// Downloads from: `gs://{BENCHMARKS_BUCKET}/{benchmark_name}/input/` to the output directory.
45+
pub async fn download_inputs(benchmark_name: &str, output_dir: &Path) {
46+
println!(
47+
"Downloading inputs from gs://{}/{}/input/ to {}",
48+
BENCHMARKS_BUCKET,
49+
benchmark_name,
50+
output_dir.display()
51+
);
52+
53+
let source = format!("gs://{}/{}/input/*", BENCHMARKS_BUCKET, benchmark_name);
54+
let dest = output_dir.display().to_string();
55+
56+
// Use gcloud storage cp command to download files.
57+
let output = tokio::process::Command::new("gcloud")
58+
.args(["storage", "cp", "-r", &source, &dest])
59+
.output()
60+
.await
61+
.expect("Failed to cp inputs from GCS");
62+
63+
if !output.status.success() {
64+
let stderr = String::from_utf8_lossy(&output.stderr);
65+
panic!("Failed to download inputs from GCS: {}", stderr);
66+
}
67+
68+
println!("{}", String::from_utf8_lossy(&output.stdout).trim());
69+
println!("Input files downloaded successfully!");
70+
}
71+
72+
#[cfg(test)]
73+
mod tests {
74+
use std::path::PathBuf;
75+
76+
use tempfile::TempDir;
77+
use tokio::fs;
78+
79+
use super::*;
80+
81+
#[tokio::test]
82+
#[ignore] // Run with: cargo test -p bench_tools -- --ignored
83+
async fn test_upload_and_download_inputs() {
84+
let benchmark_name = "dummy_benchmark";
85+
86+
// Get paths relative to workspace root.
87+
let workspace_root = std::env::var("CARGO_MANIFEST_DIR").unwrap();
88+
let source_dir = PathBuf::from(&workspace_root).join("data/dummy_bench_input");
89+
90+
// Ensure source files exist.
91+
assert!(source_dir.exists(), "Source directory does not exist: {}", source_dir.display());
92+
93+
// Upload inputs/
94+
println!("Testing upload...");
95+
upload_inputs(benchmark_name, &source_dir).await;
96+
97+
// Create temp directory for download.
98+
let temp_dir = TempDir::new().unwrap();
99+
let download_dir = temp_dir.path();
100+
101+
println!("\nDownload directory: {}", download_dir.display());
102+
103+
// Verify temp directory is empty initially.
104+
assert!(
105+
fs::read_dir(download_dir).await.unwrap().next_entry().await.unwrap().is_none(),
106+
"Temp directory should be empty initially"
107+
);
108+
109+
// Download inputs to temp directory.
110+
println!("\nTesting download...");
111+
download_inputs(benchmark_name, download_dir).await;
112+
113+
// Verify files were downloaded
114+
let small_input = download_dir.join("small_input.json");
115+
let large_input = download_dir.join("large_input.json");
116+
117+
assert!(small_input.exists(), "small_input.json was not downloaded");
118+
assert!(large_input.exists(), "large_input.json was not downloaded");
119+
120+
// Verify content matches original.
121+
let original_small = fs::read_to_string(source_dir.join("small_input.json")).await.unwrap();
122+
let downloaded_small = fs::read_to_string(&small_input).await.unwrap();
123+
assert_eq!(original_small, downloaded_small, "small_input.json content does not match");
124+
125+
let original_large = fs::read_to_string(source_dir.join("large_input.json")).await.unwrap();
126+
let downloaded_large = fs::read_to_string(&large_input).await.unwrap();
127+
assert_eq!(original_large, downloaded_large, "large_input.json content does not match");
128+
}
129+
}

0 commit comments

Comments
 (0)