This repository has no description
0

Configure Feed

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

knot2/idxwrite,shuttle/exec,.tangled: fix rust CI test fails

Lewis: May this revision serve well! <did:plc:3fwecdnvtcscjnrx2p4n7alz>

author did:plc:3fwecdnvtcscjnrx2p4n7a… date (Aug 1, 2026, 11:48 PM +0300) commit 25d3c23e parent 45582cdb change-id puuyxzst
+69 -55
+2
.tangled/workflows/rust-test-knot.yml
··· 47 47 48 48 - name: knot tests 49 49 command: | 50 + ulimit -n "$(ulimit -Hn)" && 50 51 cargo test --locked -p 'knot-*' 51 52 52 53 - name: knot instrumented tests 53 54 command: | 55 + ulimit -n "$(ulimit -Hn)" && 54 56 cd knot2 && just instrument-tests
+34 -27
knot2/crates/knot-pack/src/idxwrite.rs
··· 22 22 offset: PackOffset, 23 23 } 24 24 25 + type Bucket = Mutex<Option<BufWriter<std::fs::File>>>; 26 + 25 27 pub(crate) struct Spool { 26 - buckets: Vec<Mutex<BufWriter<std::fs::File>>>, 28 + buckets: Vec<Bucket>, 27 29 record_len: usize, 28 30 hash_len: usize, 29 31 } 30 32 31 33 impl Spool { 32 - pub(crate) fn new(kind: gix::hash::Kind) -> io::Result<Self> { 34 + pub(crate) fn new(kind: gix::hash::Kind) -> Self { 33 35 let hash_len = kind.len_in_bytes(); 34 - let buckets = (0..BUCKETS) 35 - .map(|_| { 36 - tempfile::tempfile() 37 - .map(|file| Mutex::new(BufWriter::with_capacity(BUCKET_BUF, file))) 38 - }) 39 - .collect::<io::Result<Vec<_>>>()?; 40 - Ok(Self { 41 - buckets, 36 + Self { 37 + buckets: (0..BUCKETS).map(|_| Mutex::new(None)).collect(), 42 38 record_len: hash_len + CRC_LEN + OFFSET_LEN, 43 39 hash_len, 44 - }) 40 + } 45 41 } 46 42 47 43 pub(crate) fn push(&self, id: ObjectId, crc32: Crc32, offset: PackOffset) -> io::Result<()> { 48 44 let mut guard = self.buckets[id.first_byte() as usize] 49 45 .lock() 50 46 .expect("spool bucket poisoned"); 51 - guard.write_all(id.as_slice())?; 52 - guard.write_all(&crc32.get().to_be_bytes())?; 53 - guard.write_all(&offset.get().to_be_bytes()) 47 + let writer = match guard.as_mut() { 48 + Some(writer) => writer, 49 + None => guard.insert(BufWriter::with_capacity(BUCKET_BUF, tempfile::tempfile()?)), 50 + }; 51 + writer.write_all(id.as_slice())?; 52 + writer.write_all(&crc32.get().to_be_bytes())?; 53 + writer.write_all(&offset.get().to_be_bytes()) 54 54 } 55 55 56 56 fn cumulative_fanout(&self) -> Result<[u32; 256], PackError> { ··· 58 58 self.buckets.iter().enumerate().try_for_each( 59 59 |(bucket, cell)| -> Result<(), PackError> { 60 60 let mut guard = cell.lock().expect("spool bucket poisoned"); 61 - guard.flush()?; 62 - let len = guard.get_ref().metadata()?.len() as usize; 63 - fanout[bucket] = (len / self.record_len) as u32; 61 + fanout[bucket] = match guard.as_mut() { 62 + None => 0, 63 + Some(writer) => { 64 + writer.flush()?; 65 + (writer.get_ref().metadata()?.len() as usize / self.record_len) as u32 66 + } 67 + }; 64 68 Ok(()) 65 69 }, 66 70 )?; ··· 82 86 }) 83 87 } 84 88 85 - fn read_bucket( 86 - &self, 87 - cell: &Mutex<BufWriter<std::fs::File>>, 88 - ) -> Result<Vec<Record>, PackError> { 89 + fn read_bucket(&self, cell: &Bucket) -> Result<Vec<Record>, PackError> { 89 90 let mut guard = cell.lock().expect("spool bucket poisoned"); 90 - guard.flush()?; 91 - let file = guard.get_ref(); 92 - let len = file.metadata()?.len() as usize; 93 - let mut bytes = vec![0u8; len]; 94 - file.read_exact_at(&mut bytes, 0)?; 91 + let bytes = match guard.as_mut() { 92 + None => Vec::new(), 93 + Some(writer) => { 94 + writer.flush()?; 95 + let file = writer.get_ref(); 96 + let len = file.metadata()?.len() as usize; 97 + let mut bytes = vec![0u8; len]; 98 + file.read_exact_at(&mut bytes, 0)?; 99 + bytes 100 + } 101 + }; 95 102 drop(guard); 96 103 bytes 97 104 .chunks_exact(self.record_len) ··· 179 186 (oid(0x80), 0x3333_3333, 0x1_2345_6789), 180 187 (oid(0xc0), 0x4444_4444, LARGE_OFFSET_THRESHOLD + 1), 181 188 ]; 182 - let spool = Spool::new(gix::hash::Kind::Sha1).unwrap(); 189 + let spool = Spool::new(gix::hash::Kind::Sha1); 183 190 records.iter().for_each(|(id, crc32, offset)| { 184 191 spool 185 192 .push(*id, Crc32::new(*crc32), PackOffset::new(*offset))
+1 -1
knot2/crates/knot-pack/src/objects.rs
··· 742 742 .map_err(|error| PackError::Pack(error.to_string()))?; 743 743 let stored = gix_pack::data::File::at(pack_path, kind) 744 744 .map_err(|error| PackError::Pack(error.to_string()))?; 745 - let spool = crate::idxwrite::Spool::new(kind)?; 745 + let spool = crate::idxwrite::Spool::new(kind); 746 746 run_ingest_traverse( 747 747 tree, 748 748 &stored,
+32 -27
shuttle/src/exec.rs
··· 167 167 } 168 168 169 169 fn lookup_user(name: &str) -> Result<ResolvedUser, String> { 170 - match User::from_name(name) { 171 - Ok(Some(user)) => Ok(ResolvedUser { 170 + match name.parse::<u32>() { 171 + Ok(uid) => Ok(ResolvedUser { 172 172 name: name.to_owned(), 173 - uid: user.uid.as_raw(), 174 - gid: user.gid.as_raw(), 175 - home: user.dir.into_os_string(), 176 - shell: user.shell.into_os_string(), 173 + uid, 174 + gid: uid, 175 + home: OsString::from("/"), 176 + shell: OsString::from("/bin/sh"), 177 177 }), 178 - Ok(None) => { 179 - let uid = name 180 - .parse::<u32>() 181 - .map_err(|_| format!("workflow user {name:?} was not found"))?; 182 - Ok(ResolvedUser { 178 + Err(_) => match User::from_name(name) { 179 + Ok(Some(user)) => Ok(ResolvedUser { 183 180 name: name.to_owned(), 184 - uid, 185 - gid: uid, 186 - home: OsString::from("/"), 187 - shell: OsString::from("/bin/sh"), 188 - }) 189 - } 190 - Err(error) => Err(format!("lookup workflow user {name:?}: {error}")), 181 + uid: user.uid.as_raw(), 182 + gid: user.gid.as_raw(), 183 + home: user.dir.into_os_string(), 184 + shell: user.shell.into_os_string(), 185 + }), 186 + Ok(None) => Err(format!("workflow user {name:?} was not found")), 187 + Err(error) => Err(format!("lookup workflow user {name:?}: {error}")), 188 + }, 191 189 } 192 190 } 193 191 194 192 fn lookup_group(name: &str) -> Result<u32, String> { 195 - match Group::from_name(name) { 196 - Ok(Some(group)) => Ok(group.gid.as_raw()), 197 - Ok(None) => name 198 - .parse::<u32>() 199 - .map_err(|_| format!("workflow group {name:?} was not found")), 200 - Err(error) => Err(format!("lookup workflow group {name:?}: {error}")), 193 + match name.parse::<u32>() { 194 + Ok(gid) => Ok(gid), 195 + Err(_) => match Group::from_name(name) { 196 + Ok(Some(group)) => Ok(group.gid.as_raw()), 197 + Ok(None) => Err(format!("workflow group {name:?} was not found")), 198 + Err(error) => Err(format!("lookup workflow group {name:?}: {error}")), 199 + }, 201 200 } 202 201 } 203 202 ··· 214 213 use super::*; 215 214 216 215 #[test] 217 - fn refuses_root_exec_user() { 218 - let err = resolve_user("root").unwrap_err(); 216 + fn refuses_exec_as_uid_zero() { 217 + let err = resolve_user("0").unwrap_err(); 219 218 assert!(err.contains("refusing to run exec as privileged user")); 220 219 } 221 220 222 221 #[test] 223 - fn refuses_root_exec_group() { 222 + fn refuses_exec_as_gid_zero() { 224 223 let err = resolve_user("65534:0").unwrap_err(); 225 224 assert!(err.contains("refusing to run exec as privileged user")); 225 + } 226 + 227 + #[test] 228 + fn resolves_numeric_spec_without_a_user_database() { 229 + let user = resolve_user("65534:65533").unwrap(); 230 + assert_eq!((user.uid, user.gid), (65534, 65533)); 226 231 } 227 232 }