Load world extensions from commit snapshots with last-good recovery
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
//! Commit snapshots and last-good recovery with world git and a faux model.
|
||||
use sausage::{
|
||||
exec::{Command, Exec, Options, Stream},
|
||||
world::World,
|
||||
};
|
||||
use std::{path::Path, sync::Arc};
|
||||
const BUNDLE: &str = include_str!("../js/extensions-test-bundle.js");
|
||||
struct Author(Arc<dyn Exec>);
|
||||
#[async_trait::async_trait]
|
||||
impl Exec for Author {
|
||||
async fn exec(
|
||||
&self,
|
||||
command: Command,
|
||||
mut options: Options,
|
||||
output: &mut (dyn for<'a> FnMut(Stream, &'a [u8]) + Send),
|
||||
) -> anyhow::Result<i32> {
|
||||
for (key, value) in [
|
||||
("GIT_AUTHOR_NAME", "Test"),
|
||||
("GIT_AUTHOR_EMAIL", "test@example.com"),
|
||||
("GIT_COMMITTER_NAME", "Test"),
|
||||
("GIT_COMMITTER_EMAIL", "test@example.com"),
|
||||
] {
|
||||
options.env.push((key.into(), value.into()));
|
||||
}
|
||||
self.0.exec(command, options, output).await
|
||||
}
|
||||
}
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn commits_and_restart() -> anyhow::Result<()> {
|
||||
let userland = Path::new(env!("CARGO_MANIFEST_DIR")).join("../userland");
|
||||
let target = std::env::var_os("CARGO_TARGET_DIR")
|
||||
.map(std::path::PathBuf::from)
|
||||
.expect("CARGO_TARGET_DIR must name the executor's shared target directory");
|
||||
if !userland.join("cwd-init/init.o").is_file() {
|
||||
assert!(
|
||||
std::process::Command::new("nu")
|
||||
.args(["--no-config-file", "cwd-init/build.nu"])
|
||||
.current_dir(&userland)
|
||||
.status()?
|
||||
.success()
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
std::process::Command::new("cargo")
|
||||
.args([
|
||||
"build",
|
||||
"--release",
|
||||
"-p",
|
||||
"git",
|
||||
"-p",
|
||||
"sausage-exec-tools",
|
||||
"--manifest-path"
|
||||
])
|
||||
.arg(userland.join("Cargo.toml"))
|
||||
.args(["--target", "wasm32-wasip2", "--target-dir"])
|
||||
.arg(&target)
|
||||
.args(["-j", "2", "--locked"])
|
||||
.current_dir(&userland)
|
||||
.status()?
|
||||
.success()
|
||||
);
|
||||
let dir = tempfile::tempdir()?;
|
||||
let world = World::open(dir.path())?;
|
||||
let disk = dir.path().join("world");
|
||||
std::fs::create_dir_all(disk.join("bin"))?;
|
||||
std::fs::copy(
|
||||
target.join("wasm32-wasip2/release/git.wasm"),
|
||||
disk.join("bin/git.wasm"),
|
||||
)?;
|
||||
for name in ["extensions-revert", "env"] {
|
||||
std::fs::copy(
|
||||
target.join(format!("wasm32-wasip2/release/{name}.wasm")),
|
||||
disk.join(format!("bin/{name}.wasm")),
|
||||
)?;
|
||||
}
|
||||
let repo = disk.join("src/sausage");
|
||||
std::fs::create_dir_all(&repo)?;
|
||||
assert!(
|
||||
std::process::Command::new("git")
|
||||
.args(["init", "-b", "main"])
|
||||
.arg(&repo)
|
||||
.status()?
|
||||
.success()
|
||||
);
|
||||
assert!(
|
||||
std::process::Command::new("git")
|
||||
.args([
|
||||
"-c",
|
||||
"user.name=Test",
|
||||
"-c",
|
||||
"user.email=test@example.com",
|
||||
"commit",
|
||||
"--no-gpg-sign",
|
||||
"--allow-empty",
|
||||
"-m",
|
||||
"empty"
|
||||
])
|
||||
.current_dir(&repo)
|
||||
.status()?
|
||||
.success()
|
||||
);
|
||||
let exec: Arc<dyn Exec> = Arc::new(Author(sausage::process::exec(World {
|
||||
root: world.root.clone(),
|
||||
host_dir: world.host_dir.clone(),
|
||||
processes: world.processes.clone(),
|
||||
})?));
|
||||
sausage::harness::run_module(world, exec, BUNDLE).await?;
|
||||
let good = std::fs::read_to_string(repo.join("good.txt"))?;
|
||||
let world = World::open(dir.path())?;
|
||||
let exec: Arc<dyn Exec> = Arc::new(Author(sausage::process::exec(World {
|
||||
root: world.root.clone(),
|
||||
host_dir: world.host_dir.clone(),
|
||||
processes: world.processes.clone(),
|
||||
})?));
|
||||
sausage::harness::run_module(
|
||||
world,
|
||||
exec,
|
||||
&format!("globalThis.extensionRestart=true;globalThis.extensionGood={good:?};\n{BUNDLE}"),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -24,7 +24,10 @@ fn git(cwd: &Path, args: &[&str]) {
|
||||
async fn several_mb_git_push() {
|
||||
static BUILT: OnceLock<std::path::PathBuf> = OnceLock::new();
|
||||
let component = BUILT.get_or_init(|| {
|
||||
let target = Path::new(env!("CARGO_TARGET_TMPDIR")).join("hook-git");
|
||||
let target = std::path::PathBuf::from(
|
||||
std::env::var_os("CARGO_TARGET_DIR")
|
||||
.expect("CARGO_TARGET_DIR must name the executor's shared target directory"),
|
||||
);
|
||||
let userland = Path::new(env!("CARGO_MANIFEST_DIR")).join("../userland");
|
||||
if !userland.join("cwd-init/init.o").is_file() {
|
||||
assert!(
|
||||
|
||||
@@ -12,6 +12,7 @@ fn write(path: PathBuf, text: &str) -> std::io::Result<()> {
|
||||
pub fn component() -> &'static Path {
|
||||
static PATH: OnceLock<PathBuf> = OnceLock::new();
|
||||
PATH.get_or_init(|| {
|
||||
let target = PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").expect("CARGO_TARGET_DIR must name the executor's shared target directory"));
|
||||
let directory = Path::new(env!("CARGO_TARGET_TMPDIR")).join("hook-guest");
|
||||
std::fs::create_dir_all(directory.join("src")).unwrap();
|
||||
std::fs::create_dir_all(directory.join("wit/deps")).unwrap();
|
||||
@@ -67,7 +68,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
"#).unwrap();
|
||||
assert!(std::process::Command::new("cargo").args(["build", "--manifest-path"]).arg(directory.join("Cargo.toml")).args(["--target", "wasm32-wasip2", "--release", "-j", "2"]).env("CARGO_TARGET_DIR", directory.join("target")).status().unwrap().success(), "test guest build failed");
|
||||
directory.join("target/wasm32-wasip2/release/hook-guest.wasm")
|
||||
assert!(std::process::Command::new("cargo").args(["build", "--manifest-path"]).arg(directory.join("Cargo.toml")).args(["--target", "wasm32-wasip2", "--release", "-j", "2"]).env("CARGO_TARGET_DIR", &target).status().unwrap().success(), "test guest build failed");
|
||||
target.join("wasm32-wasip2/release/hook-guest.wasm")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user