char/avril

(wip) why'd you have to go and make things so complicaaaaated?

git clone https://git.t4t.associates/char/avril

Charlotte Somjsr: read cache before taking artifact lockbce30ee

main
4.9 KiB134 linesraw
1#[path = "common/registry.rs"]
2mod fixture;
3
4use avril_runtime::registry::{Options, PackageStore, artifact_key};
5use fixture::Registry;
6use futures::executor::block_on;
7
8fn warm_package(registry: &Registry, options: &Options) -> (PackageStore, String) {
9    registry.package(
10        "@test/pkg",
11        "1.0.0",
12        &[("mod.ts", "export const value = 42;")],
13        &[(".", "./mod.ts")],
14    );
15    let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap();
16    let module = block_on(store.resolve("jsr:@test/pkg@1")).unwrap();
17    assert_eq!(
18        block_on(store.source(&module)).unwrap(),
19        "export const value = 42;"
20    );
21    store.save().unwrap();
22    (store, module)
23}
24
25#[test]
26fn verified_warm_artifacts_do_not_require_writable_lock_directory() {
27    let registry = Registry::new();
28    let dir = tempfile::tempdir().unwrap();
29    let mut options = registry.options(dir.path());
30    let (store, module) = warm_package(&registry, &options);
31    drop(store);
32
33    let locks = options.cache.join("locks");
34    std::fs::remove_dir_all(&locks).unwrap();
35    std::fs::write(&locks, "not a directory").unwrap();
36    let warm_requests = registry.requests.lock().unwrap().len();
37
38    let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap();
39    assert_eq!(block_on(store.resolve("jsr:@test/pkg@1")).unwrap(), module);
40    assert_eq!(
41        block_on(store.source(&module)).unwrap(),
42        "export const value = 42;"
43    );
44    drop(store);
45    assert_eq!(registry.requests.lock().unwrap().len(), warm_requests);
46
47    options.offline = true;
48    options.frozen = true;
49    let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap();
50    assert_eq!(block_on(store.resolve("jsr:@test/pkg@1")).unwrap(), module);
51    assert_eq!(
52        block_on(store.source(&module)).unwrap(),
53        "export const value = 42;"
54    );
55    drop(store);
56    assert_eq!(registry.requests.lock().unwrap().len(), warm_requests);
57
58    let cache_source = options.cache.join("files").join(artifact_key(&module));
59    std::fs::write(&cache_source, "corrupt").unwrap();
60    let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap();
61    let error = block_on(store.source(&module)).unwrap_err();
62    assert!(error.to_string().contains("integrity mismatch"), "{error}");
63    drop(store);
64
65    std::fs::remove_file(&cache_source).unwrap();
66    options.offline = false;
67    let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap();
68    assert!(block_on(store.source(&module)).is_err());
69    assert_eq!(registry.requests.lock().unwrap().len(), warm_requests);
70    drop(store);
71
72    options.frozen = false;
73    options.update = true;
74    let store = PackageStore::new(fixture::runtime_handle(), options).unwrap();
75    assert!(block_on(store.resolve("jsr:@test/pkg@1")).is_err());
76    assert_eq!(registry.requests.lock().unwrap().len(), warm_requests);
77}
78
79#[test]
80fn vendored_frozen_offline_artifacts_need_no_cache_directory() {
81    let registry = Registry::new();
82    let dir = tempfile::tempdir().unwrap();
83    let options = registry.options(dir.path());
84    let (store, module) = warm_package(&registry, &options);
85    let vendor = dir.path().join("vendor");
86    store.vendor(&vendor).unwrap();
87    drop(store);
88
89    let mut options = options;
90    options.cache = dir.path().join("missing-cache");
91    options.vendor = Some(vendor);
92    options.offline = true;
93    options.frozen = true;
94    let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap();
95    assert_eq!(block_on(store.resolve("jsr:@test/pkg@1")).unwrap(), module);
96    assert_eq!(
97        block_on(store.source(&module)).unwrap(),
98        "export const value = 42;"
99    );
100    assert!(!options.cache.exists());
101}
102
103#[test]
104fn corrupt_vendor_artifact_fails_instead_of_falling_back_to_valid_cache() {
105    let registry = Registry::new();
106    let dir = tempfile::tempdir().unwrap();
107    let mut options = registry.options(dir.path());
108    let (store, module) = warm_package(&registry, &options);
109    let vendor = dir.path().join("vendor");
110    store.vendor(&vendor).unwrap();
111    drop(store);
112
113    let vendor_source = vendor.join("@test/pkg/1.0.0/mod.ts");
114    std::fs::write(&vendor_source, "export const value = 0;").unwrap();
115    let locks = options.cache.join("locks");
116    std::fs::remove_dir_all(&locks).unwrap();
117    std::fs::write(&locks, "not a directory").unwrap();
118    options.vendor = Some(vendor);
119    options.offline = true;
120    options.frozen = true;
121    let store = PackageStore::new(fixture::runtime_handle(), options).unwrap();
122    let error = block_on(store.source(&module)).unwrap_err();
123    assert!(error.to_string().contains("integrity mismatch"), "{error}");
124
125    let cache_source = store
126        .options()
127        .cache
128        .join("files")
129        .join(artifact_key(&module));
130    assert_eq!(
131        std::fs::read(cache_source).unwrap(),
132        b"export const value = 42;"
133    );
134}