This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-git / tests / config_isolation.rs
4.8 kB 142 lines
1use std::path::Path; 2use std::sync::atomic::AtomicBool; 3 4use knot_git::{ArchiveFormat, ArchiveLimit}; 5use knot_types::Oid; 6 7mod common; 8use common::{commit_file, contains, git_ok as git, seeded}; 9 10fn archive_without_isolation(bare_path: &Path, head: Oid) -> Vec<u8> { 11 let permissive = gix::open_opts(bare_path, gix::open::Options::default()).unwrap(); 12 let tree = permissive 13 .find_object(head.object_id()) 14 .unwrap() 15 .peel_to_tree() 16 .unwrap(); 17 let (stream, _index) = permissive.worktree_stream(tree.id).unwrap(); 18 let mut out = std::io::Cursor::new(Vec::new()); 19 permissive 20 .worktree_archive( 21 stream, 22 &mut out, 23 gix::progress::Discard, 24 &AtomicBool::new(false), 25 gix_archive::Options { 26 format: gix_archive::Format::Tar, 27 tree_prefix: None, 28 modification_time: 0, 29 }, 30 ) 31 .unwrap(); 32 out.into_inner() 33} 34 35#[test] 36fn a_filter_driver_pulled_in_by_an_include_never_runs_for_a_served_archive() { 37 let (_scan, work_dir, layout, did) = seeded(); 38 let work = work_dir.path(); 39 let bare_path = layout.repo_path(&did).unwrap(); 40 std::fs::write(work.join(".gitattributes"), "payload.txt filter=knotpwn\n").unwrap(); 41 commit_file(work, "payload.txt", "kelp\n", "seed"); 42 git(work, &["push", "-q", bare_path.to_str().unwrap(), "main"]); 43 let head = Oid::from_hex(&git(work, &["rev-parse", "HEAD"])).unwrap(); 44 45 let ambient = tempfile::tempdir().unwrap(); 46 let driver = ambient.path().join("driver.cfg"); 47 std::fs::write( 48 &driver, 49 "[filter \"knotpwn\"]\n\tsmudge = sed s/kelp/pwned/\n\trequired = true\n", 50 ) 51 .unwrap(); 52 let config_path = bare_path.join("config"); 53 let local = std::fs::read_to_string(&config_path).unwrap(); 54 std::fs::write( 55 &config_path, 56 format!("{local}[include]\n\tpath = {}\n", driver.display()), 57 ) 58 .unwrap(); 59 60 let via_git = knot_fixtures::command(&bare_path) 61 .args(["archive", "--format=tar", "main"]) 62 .output() 63 .unwrap(); 64 assert!( 65 via_git.status.success(), 66 "git archive failed:\n{}", 67 String::from_utf8_lossy(&via_git.stderr) 68 ); 69 assert!( 70 contains(&via_git.stdout, b"pwned"), 71 "git archived with the include in place and its output has no pwned in it, so the driver \ 72 never ran" 73 ); 74 assert!( 75 contains(&archive_without_isolation(&bare_path, head), b"pwned"), 76 "gix archived the same repo under default permissions and its output has no pwned in it, \ 77 so worktree_stream no longer applies filters" 78 ); 79 80 let bare = layout.open(&did).unwrap(); 81 let tree = bare.peel_to_tree(head).unwrap(); 82 let mut out = std::io::Cursor::new(Vec::new()); 83 bare.write_archive( 84 tree, 85 ArchiveFormat::Tar, 86 None, 87 ArchiveLimit::new(u64::MAX), 88 &mut out, 89 ) 90 .unwrap(); 91 let served = out.into_inner(); 92 93 assert!( 94 std::fs::read_to_string(&config_path) 95 .unwrap() 96 .contains("[include]"), 97 "opening the repo rewrote its config and removed the include, so gix never read the \ 98 driver definition for the archive below" 99 ); 100 assert!( 101 contains(&served, b"kelp"), 102 "the served archive contains the blob as it was pushed" 103 ); 104 assert!( 105 !contains(&served, b"pwned"), 106 "the knot ran a filter driver defined by config outside the repository" 107 ); 108} 109 110#[test] 111fn a_pushed_replace_ref_never_substitutes_an_object_the_knot_reads() { 112 let (_scan, work_dir, layout, did) = seeded(); 113 let work = work_dir.path(); 114 let bare_path = layout.repo_path(&did).unwrap(); 115 116 commit_file(work, "payload.txt", "kelp\n", "seed"); 117 git(work, &["push", "-q", bare_path.to_str().unwrap(), "main"]); 118 let original = Oid::from_hex(&git(work, &["rev-parse", "HEAD:payload.txt"])).unwrap(); 119 commit_file(work, "payload.txt", "pwned\n", "second"); 120 git(work, &["push", "-q", bare_path.to_str().unwrap(), "main"]); 121 let substitute = Oid::from_hex(&git(work, &["rev-parse", "HEAD:payload.txt"])).unwrap(); 122 123 git( 124 &bare_path, 125 &[ 126 "update-ref", 127 &format!("refs/replace/{}", original.to_hex()), 128 &substitute.to_hex(), 129 ], 130 ); 131 132 assert_eq!( 133 git(&bare_path, &["cat-file", "blob", &original.to_hex()]), 134 "pwned", 135 "git read the replaced object as itself, so this fixture never armed the substitution" 136 ); 137 assert_eq!( 138 layout.open(&did).unwrap().read_blob(original).unwrap(), 139 b"kelp\n", 140 "a pushed replace ref rewrote what the knot serves for an object" 141 ); 142}