|
1 |
+ |
//! Seal: every file in `static/bases/` still hashes to the name it is filed
|
|
2 |
+ |
//! under, and the README table lists exactly those files.
|
|
3 |
+ |
//!
|
|
4 |
+ |
//! The directory is a content-addressed mirror of the font bases `quasi-type`
|
|
5 |
+ |
//! pins, served by the `/static` `ServeDir` with no route of its own. Nothing
|
|
6 |
+ |
//! else in the server reads it, so a rename, a truncation or a flipped byte
|
|
7 |
+ |
//! ships without a compile error and without a failing request: the mirror
|
|
8 |
+ |
//! answers 404 or serves bytes that fail `quasi-type`'s own digest check, and
|
|
9 |
+ |
//! every Alloy build silently falls back to the upstream host the mirror exists
|
|
10 |
+ |
//! to stop depending on.
|
|
11 |
+ |
//!
|
|
12 |
+ |
//! Hashing four files costs nothing, and the name already states the expected
|
|
13 |
+ |
//! answer, so the check needs no fixture and no constant to maintain.
|
|
14 |
+ |
//!
|
|
15 |
+ |
//! Run with: cargo test --test bases_mirror
|
|
16 |
+ |
|
|
17 |
+ |
use std::fmt::Write as _;
|
|
18 |
+ |
use std::fs;
|
|
19 |
+ |
use std::path::{Path, PathBuf};
|
|
20 |
+ |
|
|
21 |
+ |
use sha2::{Digest, Sha256};
|
|
22 |
+ |
|
|
23 |
+ |
const BASES_DIR: &str = "static/bases";
|
|
24 |
+ |
|
|
25 |
+ |
/// The mirror's files, README excluded, sorted by name.
|
|
26 |
+ |
fn mirrored_files() -> Vec<PathBuf> {
|
|
27 |
+ |
let dir = Path::new(env!("CARGO_MANIFEST_DIR")).join(BASES_DIR);
|
|
28 |
+ |
let mut out: Vec<PathBuf> = fs::read_dir(&dir)
|
|
29 |
+ |
.expect("static/bases/ is readable")
|
|
30 |
+ |
.map(|entry| entry.expect("readable dir entry").path())
|
|
31 |
+ |
.filter(|path| path.is_file())
|
|
32 |
+ |
.filter(|path| path.file_name().is_some_and(|n| n != "README.md"))
|
|
33 |
+ |
.collect();
|
|
34 |
+ |
out.sort();
|
|
35 |
+ |
out
|
|
36 |
+ |
}
|
|
37 |
+ |
|
|
38 |
+ |
fn sha256_hex(bytes: &[u8]) -> String {
|
|
39 |
+ |
Sha256::digest(bytes)
|
|
40 |
+ |
.iter()
|
|
41 |
+ |
.fold(String::new(), |mut out, b| {
|
|
42 |
+ |
let _ = write!(out, "{b:02x}");
|
|
43 |
+ |
out
|
|
44 |
+ |
})
|
|
45 |
+ |
}
|
|
46 |
+ |
|
|
47 |
+ |
fn file_name(path: &Path) -> String {
|
|
48 |
+ |
path.file_name()
|
|
49 |
+ |
.expect("mirror path has a file name")
|
|
50 |
+ |
.to_string_lossy()
|
|
51 |
+ |
.into_owned()
|
|
52 |
+ |
}
|
|
53 |
+ |
|
|
54 |
+ |
#[test]
|
|
55 |
+ |
fn every_mirrored_base_is_named_by_its_digest() {
|
|
56 |
+ |
let files = mirrored_files();
|
|
57 |
+ |
assert!(
|
|
58 |
+ |
!files.is_empty(),
|
|
59 |
+ |
"static/bases/ holds no mirrored files. An empty mirror sends every \
|
|
60 |
+ |
Alloy build back to the upstream host.",
|
|
61 |
+ |
);
|
|
62 |
+ |
|
|
63 |
+ |
let mut wrong: Vec<String> = Vec::new();
|
|
64 |
+ |
for path in &files {
|
|
65 |
+ |
let name = file_name(path);
|
|
66 |
+ |
let bytes = fs::read(path).expect("read mirrored base");
|
|
67 |
+ |
let digest = sha256_hex(&bytes);
|
|
68 |
+ |
if digest != name {
|
|
69 |
+ |
wrong.push(format!("{name} hashes to {digest}"));
|
|
70 |
+ |
}
|
|
71 |
+ |
}
|
|
72 |
+ |
|
|
73 |
+ |
assert!(
|
|
74 |
+ |
wrong.is_empty(),
|
|
75 |
+ |
"mirrored files whose name is not their sha256: {wrong:?}\n\
|
|
76 |
+ |
`quasi-type` fetches by digest, so a file filed under any other name \
|
|
77 |
+ |
is unreachable. Rename it to the digest reported here, or restore the \
|
|
78 |
+ |
bytes if they were corrupted.",
|
|
79 |
+ |
);
|
|
80 |
+ |
}
|
|
81 |
+ |
|
|
82 |
+ |
#[test]
|
|
83 |
+ |
fn readme_table_lists_exactly_the_mirrored_files() {
|
|
84 |
+ |
let readme = Path::new(env!("CARGO_MANIFEST_DIR"))
|
|
85 |
+ |
.join(BASES_DIR)
|
|
86 |
+ |
.join("README.md");
|
|
87 |
+ |
let text = fs::read_to_string(&readme).expect("static/bases/README.md is readable");
|
|
88 |
+ |
|
|
89 |
+ |
// Table rows are `| `<digest>` | <upstream file> |`; the digest is the only
|
|
90 |
+ |
// backticked field on a row that starts one.
|
|
91 |
+ |
let mut documented: Vec<String> = text
|
|
92 |
+ |
.lines()
|
|
93 |
+ |
.filter_map(|line| line.strip_prefix("| `"))
|
|
94 |
+ |
.filter_map(|rest| rest.split('`').next())
|
|
95 |
+ |
.map(str::to_owned)
|
|
96 |
+ |
.collect();
|
|
97 |
+ |
documented.sort();
|
|
98 |
+ |
|
|
99 |
+ |
let present: Vec<String> = mirrored_files().iter().map(|p| file_name(p)).collect();
|
|
100 |
+ |
|
|
101 |
+ |
assert_eq!(
|
|
102 |
+ |
documented, present,
|
|
103 |
+ |
"the README table and static/bases/ disagree.\n\
|
|
104 |
+ |
Adding a base to `pins.toml` means adding its files here and a row \
|
|
105 |
+ |
each; the row says which upstream file the digest is.",
|
|
106 |
+ |
);
|
|
107 |
+ |
}
|