tests/large_blob.rs 2.7 KiB 76 lines Raw
1 //! f0rge #66: build must not read every blob fully into memory. A blob2 //! over the inline cap is streamed to `raw/`; its page is a placeholder3 //! and the build still succeeds.4 5 use std::sync::atomic::{AtomicU64, Ordering};6 7 static SEQ: AtomicU64 = AtomicU64::new(0);8 9 use std::path::{Path, PathBuf};10 use std::process::Command;11 12 fn git(repo: &Path, args: &[&str]) {13     let st = Command::new("git")14         .arg("-C")15         .arg(repo)16         .args(args)17         .status()18         .expect("spawn git");19     assert!(st.success(), "git {args:?} failed");20 }21 22 fn fresh_dir(prefix: &str) -> PathBuf {23     let dir = std::env::temp_dir().join(format!(24         "hu13-large-{prefix}-{}-{}",25         std::process::id(),26         std::time::SystemTime::now()27             .duration_since(std::time::UNIX_EPOCH)28             .map(|d| d.as_nanos())29             .unwrap_or(0)30             .wrapping_add(u128::from(SEQ.fetch_add(1, Ordering::Relaxed)))31     ));32     std::fs::create_dir_all(&dir).unwrap();33     dir34 }35 36 #[test]37 fn oversized_blob_is_streamed_and_never_aborts() {38     let repo = fresh_dir("repo");39     let out = fresh_dir("out");40     git(&repo, &["init", "-b", "main"]);41     git(&repo, &["config", "user.name", "hu13-test"]);42     git(&repo, &["config", "user.email", "[email protected]"]);43     git(&repo, &["config", "commit.gpgsign", "false"]);44     std::fs::write(repo.join("README.md"), "# large blob\n").unwrap();45     // 12 MiB of text: above MAX_INLINE_BLOB (8 MiB), compressible enough46     // for the test to stay fast.47     let big = vec![b'a'; 12 * 1024 * 1024];48     std::fs::write(repo.join("big.txt"), &big).unwrap();49     git(&repo, &["add", "-A"]);50     git(&repo, &["commit", "-m", "big"]);51 52     let produced = Command::new(env!("CARGO_BIN_EXE_hu13"))53         .arg("build")54         .arg(&repo)55         .arg("-o")56         .arg(&out)57         .output()58         .expect("spawn hu13 build");59     let stderr = String::from_utf8_lossy(&produced.stderr);60     assert!(produced.status.success(), "build failed: {stderr}");61 62     // Raw copy is byte-identical.63     let raw = std::fs::read(out.join("raw/big.txt")).expect("raw big.txt");64     assert_eq!(raw.len(), big.len());65     assert!(raw.iter().all(|b| *b == b'a'));66 67     // Page is a placeholder, not 12 MiB of spans.68     let page = std::fs::read_to_string(out.join("files/big.txt.html")).expect("page");69     assert!(page.contains("too large to preview"), "placeholder shown");70     assert!(page.contains("download the raw file"));71     assert!(page.len() < 200_000, "page stayed small: {}", page.len());72 73     // A normal file still gets a real preview.74     let readme = std::fs::read_to_string(out.join("files/README.md.html")).expect("readme");75     assert!(readme.contains("<h1>README.md</h1>") || readme.contains("README.md"));76 }