Boot the shell with a set of `tools` installed (each named by its catalog key; source, aux modules, and install path come from the user catalog) plus extra `files`, drive `session` over UART, and return (outcome, uart). Collapses the compile-shell + elf-ify-tools + build-image + boot boilerplate every toolchain test repeats; tests keep their own assertions.
(
tools: &[&str],
files: &[(&str, &[u8])],
session: &str,
max_steps: u64,
)
| 181 | } |
| 182 | |
| 183 | // Collapses the compile-shell, elf-ify-tools, build-image and boot boilerplate |
| 184 | // every toolchain test repeats. Tests keep their own assertions. |
| 185 | fn run_tool_session( |
| 186 | tools: &[&str], |
| 187 | files: &[(&str, &[u8])], |
| 188 | session: &str, |
| 189 | max_steps: u64, |
| 190 | ) -> (StepOutcome, String) { |
| 191 | let shell = compile_hosted_program("shell"); |
| 192 | let tool_elfs: Vec<(&str, Vec<u8>)> = tools |
| 193 | .iter() |
| 194 | .map(|name| { |
| 195 | let prog = user::program(name).expect("tool not in user catalog"); |
| 196 | let path = prog.install_path.expect("tool has no install path"); |
| 197 | let elf = assembled_to_elf_file(&compile_hosted_program(name)); |
| 198 | (path, elf) |
| 199 | }) |
| 200 | .collect(); |
| 201 | |
| 202 | // Create every parent directory the tool/file paths need, shallowest first. |
| 203 | let mut dirs: Vec<String> = Vec::new(); |
| 204 | for path in tool_elfs |
| 205 | .iter() |
| 206 | .map(|(p, _)| *p) |
| 207 | .chain(files.iter().map(|(p, _)| *p)) |
| 208 | { |
| 209 | let mut idx = 0; |
| 210 | while let Some(slash) = path[idx + 1..].find('/') { |
| 211 | let end = idx + 1 + slash; |
| 212 | let dir = path[..end].to_owned(); |
| 213 | if !dirs.contains(&dir) { |
| 214 | dirs.push(dir); |
| 215 | } |
| 216 | idx = end; |
| 217 | } |
| 218 | } |
| 219 | dirs.sort_by_key(|d| d.matches('/').count()); |
| 220 | |
| 221 | let mut entries: Vec<FsEntry<'_>> = dirs.iter().map(|d| FsEntry::Dir { path: d }).collect(); |
| 222 | for (path, elf) in &tool_elfs { |
| 223 | entries.push(FsEntry::File { path, data: elf }); |
| 224 | } |
| 225 | for (path, data) in files { |
| 226 | entries.push(FsEntry::File { path, data }); |
| 227 | } |
| 228 | let image = build_fs_image(&entries); |
| 229 | |
| 230 | let (_, outcome, uart) = boot_kernel( |
| 231 | cached_kernel(), |
| 232 | Some(&shell), |
| 233 | Some(&image), |
| 234 | session, |
| 235 | max_steps, |
| 236 | ); |
| 237 | (outcome, uart) |
| 238 | } |
| 239 |