mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 13:33:19 +00:00
Merge pull request #6679 from dotCooCoo/fix/plugin-grants-delete-test-portable
Plug-ins: the failed delete of grants.json is tested on every platform
This commit is contained in:
@@ -191,6 +191,9 @@ fn lock_disabled(_: &Path) -> Option<std::fs::File> {
|
||||
thread_local! {
|
||||
/// Tests: [`Session::put_back_plugin`] fails on this thread, as on a full volume.
|
||||
pub(crate) static PUT_BACK_FAILS: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
|
||||
/// Tests: removing [`GRANTS_FILE`] fails on this thread while the file still reads, as when
|
||||
/// another program holds it open.
|
||||
pub(crate) static GRANTS_DELETE_FAILS: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
|
||||
/// Tests: [`Session::put_back_plugin`] writes the old module back on this thread and then
|
||||
/// reports a failure, as when the last flush of a copy fails.
|
||||
pub(crate) static PUT_BACK_FAILS_AFTER_WRITE: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
|
||||
@@ -205,7 +208,15 @@ thread_local! {
|
||||
/// Remove `dir/file` → whether it is gone; a file that isn't there is what was wanted.
|
||||
fn take(dir: &Path, file: &str) -> bool {
|
||||
let path = dir.join(file);
|
||||
match std::fs::remove_file(&path) {
|
||||
#[cfg(test)]
|
||||
let removed = if file == GRANTS_FILE && GRANTS_DELETE_FAILS.get() {
|
||||
Err(std::io::Error::from(std::io::ErrorKind::PermissionDenied))
|
||||
} else {
|
||||
std::fs::remove_file(&path)
|
||||
};
|
||||
#[cfg(not(test))]
|
||||
let removed = std::fs::remove_file(&path);
|
||||
match removed {
|
||||
Err(e) if e.kind() != std::io::ErrorKind::NotFound => {
|
||||
log::warn!("can't remove {}: {e}", path.display());
|
||||
false
|
||||
|
||||
@@ -2123,6 +2123,35 @@ fn a_grants_file_that_cannot_be_deleted_keeps_the_stored_module() {
|
||||
run(&mut s, "plugin.remove", json!({"id": id}));
|
||||
}
|
||||
|
||||
/// When the last grant can't be removed because `grants.json` can't be deleted, a replacing module
|
||||
/// that asks for no permissions doesn't stay in the store: the store gets back the module the grant
|
||||
/// still covers, and the grant is left as it was.
|
||||
#[test]
|
||||
fn a_grants_file_whose_deletion_fails_keeps_the_stored_module() {
|
||||
let folder = crate::tests_links::Folder::new("plugin-store-undeletable-grants");
|
||||
let id = "test.engine.permissions.undeletablegrants";
|
||||
let empty = json!({"objects": []});
|
||||
let approved = asking(id, r#"["doc.read"]"#, &empty);
|
||||
let approved_data = vectorcraft_format::base64_encode(&approved);
|
||||
let plain = asking(id, "null", &empty);
|
||||
let grants = folder.0.join("grants.json");
|
||||
let mut s = session();
|
||||
s.attach_plugin_store(folder.0.clone());
|
||||
run(&mut s, "plugin.install", json!({"dataBase64": approved_data, "grant": ["doc.read"]}));
|
||||
let file = s.stored_plugin_file(id).unwrap();
|
||||
let recorded = std::fs::read(&grants).unwrap();
|
||||
|
||||
crate::store::GRANTS_DELETE_FAILS.set(true);
|
||||
run(&mut s, "plugin.install", json!({"dataBase64": vectorcraft_format::base64_encode(&plain), "replace": true}));
|
||||
crate::store::GRANTS_DELETE_FAILS.set(false);
|
||||
assert_eq!(std::fs::read(&file).unwrap(), approved, "the store gets the module the grant covers back");
|
||||
assert_eq!(std::fs::read(&grants).unwrap(), recorded, "the grant stays as it was");
|
||||
assert_eq!(run(&mut s, "plugin.inspect", json!({"dataBase64": approved_data}))["needsApproval"], false, "the grant still covers the module");
|
||||
|
||||
run(&mut s, "plugin.remove", json!({"id": id}));
|
||||
assert!(!grants.exists(), "a removal that can delete the file forgets the grant");
|
||||
}
|
||||
|
||||
/// A plug-in folder that leaves a module listing no permissions under an id forgets the process's
|
||||
/// grant for it, unless a later file in the folder leaves a granted module there. A grant kept in
|
||||
/// the plug-in store stays, with the stored module it covers.
|
||||
|
||||
Reference in New Issue
Block a user