#[path = "common/registry.rs"] mod fixture; use avril_runtime::registry::{Options, PackageStore, artifact_key}; use fixture::Registry; use futures::executor::block_on; fn warm_package(registry: &Registry, options: &Options) -> (PackageStore, String) { registry.package( "@test/pkg", "1.0.0", &[("mod.ts", "export const value = 42;")], &[(".", "./mod.ts")], ); let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap(); let module = block_on(store.resolve("jsr:@test/pkg@1")).unwrap(); assert_eq!( block_on(store.source(&module)).unwrap(), "export const value = 42;" ); store.save().unwrap(); (store, module) } #[test] fn verified_warm_artifacts_do_not_require_writable_lock_directory() { let registry = Registry::new(); let dir = tempfile::tempdir().unwrap(); let mut options = registry.options(dir.path()); let (store, module) = warm_package(®istry, &options); drop(store); let locks = options.cache.join("locks"); std::fs::remove_dir_all(&locks).unwrap(); std::fs::write(&locks, "not a directory").unwrap(); let warm_requests = registry.requests.lock().unwrap().len(); let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap(); assert_eq!(block_on(store.resolve("jsr:@test/pkg@1")).unwrap(), module); assert_eq!( block_on(store.source(&module)).unwrap(), "export const value = 42;" ); drop(store); assert_eq!(registry.requests.lock().unwrap().len(), warm_requests); options.offline = true; options.frozen = true; let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap(); assert_eq!(block_on(store.resolve("jsr:@test/pkg@1")).unwrap(), module); assert_eq!( block_on(store.source(&module)).unwrap(), "export const value = 42;" ); drop(store); assert_eq!(registry.requests.lock().unwrap().len(), warm_requests); let cache_source = options.cache.join("files").join(artifact_key(&module)); std::fs::write(&cache_source, "corrupt").unwrap(); let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap(); let error = block_on(store.source(&module)).unwrap_err(); assert!(error.to_string().contains("integrity mismatch"), "{error}"); drop(store); std::fs::remove_file(&cache_source).unwrap(); options.offline = false; let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap(); assert!(block_on(store.source(&module)).is_err()); assert_eq!(registry.requests.lock().unwrap().len(), warm_requests); drop(store); options.frozen = false; options.update = true; let store = PackageStore::new(fixture::runtime_handle(), options).unwrap(); assert!(block_on(store.resolve("jsr:@test/pkg@1")).is_err()); assert_eq!(registry.requests.lock().unwrap().len(), warm_requests); } #[test] fn vendored_frozen_offline_artifacts_need_no_cache_directory() { let registry = Registry::new(); let dir = tempfile::tempdir().unwrap(); let options = registry.options(dir.path()); let (store, module) = warm_package(®istry, &options); let vendor = dir.path().join("vendor"); store.vendor(&vendor).unwrap(); drop(store); let mut options = options; options.cache = dir.path().join("missing-cache"); options.vendor = Some(vendor); options.offline = true; options.frozen = true; let store = PackageStore::new(fixture::runtime_handle(), options.clone()).unwrap(); assert_eq!(block_on(store.resolve("jsr:@test/pkg@1")).unwrap(), module); assert_eq!( block_on(store.source(&module)).unwrap(), "export const value = 42;" ); assert!(!options.cache.exists()); } #[test] fn corrupt_vendor_artifact_fails_instead_of_falling_back_to_valid_cache() { let registry = Registry::new(); let dir = tempfile::tempdir().unwrap(); let mut options = registry.options(dir.path()); let (store, module) = warm_package(®istry, &options); let vendor = dir.path().join("vendor"); store.vendor(&vendor).unwrap(); drop(store); let vendor_source = vendor.join("@test/pkg/1.0.0/mod.ts"); std::fs::write(&vendor_source, "export const value = 0;").unwrap(); let locks = options.cache.join("locks"); std::fs::remove_dir_all(&locks).unwrap(); std::fs::write(&locks, "not a directory").unwrap(); options.vendor = Some(vendor); options.offline = true; options.frozen = true; let store = PackageStore::new(fixture::runtime_handle(), options).unwrap(); let error = block_on(store.source(&module)).unwrap_err(); assert!(error.to_string().contains("integrity mismatch"), "{error}"); let cache_source = store .options() .cache .join("files") .join(artifact_key(&module)); assert_eq!( std::fs::read(cache_source).unwrap(), b"export const value = 42;" ); }