use std::sync::Arc;
use lash_core::ProcessExecutionEnvStore;
use lash_core::testing::conformance::{
ReopenableProcessExecutionEnvStore, process_execution_env_store_reopenable,
};
use lashlang::testing::conformance::{
ReopenableLashlangArtifactStore, lashlang_artifact_store_reopenable,
};
use lashlang::{LashlangArtifactStore, ModuleArtifact, parse};
pub struct ArtifactStoreHandles {
pub artifacts: Arc<dyn LashlangArtifactStore>,
pub process_env: Arc<dyn ProcessExecutionEnvStore>,
}
pub struct ReopenableArtifactStore {
pub open: ArtifactStoreHandles,
pub reopen: ArtifactStoreHandles,
}
fn sample_module_artifact(source: &str) -> ModuleArtifact {
let program = parse(source).expect("parse sample lashlang module");
ModuleArtifact::from_program(program).expect("build sample module artifact")
}
pub async fn artifact_store_reopenable<F>(make: F)
where
F: Fn() -> ReopenableArtifactStore,
{
lashlang_artifact_store_reopenable(|| {
let handles = make();
ReopenableLashlangArtifactStore {
open: handles.open.artifacts,
reopen: handles.reopen.artifacts,
}
})
.await;
process_execution_env_store_reopenable(|| {
let handles = make();
ReopenableProcessExecutionEnvStore {
open: handles.open.process_env,
reopen: handles.reopen.process_env,
}
})
.await;
cross_namespace_isolation(make().open).await;
}
async fn cross_namespace_isolation(handles: ArtifactStoreHandles) {
let artifact = sample_module_artifact("process delta(root: str) -> str { finish root }");
let colliding_key = artifact.module_ref.as_str().to_string();
handles
.artifacts
.put_module_artifact(&artifact)
.await
.expect("put module artifact");
handles
.artifacts
.put_artifact_bytes(&colliding_key, "generic", b"raw-bytes")
.await
.expect("put raw bytes at the shared key");
handles
.process_env
.put_process_execution_env(
&lash_core::ProcessExecutionEnvRef::new(colliding_key.clone()),
b"env-bytes",
)
.await
.expect("put env at the shared key");
let module = handles
.artifacts
.get_module_artifact(&artifact.module_ref)
.await
.expect("module artifact isolated from raw + env writes")
.expect("module artifact present");
assert_eq!(*module, artifact);
assert_eq!(
handles
.artifacts
.get_artifact_bytes(&colliding_key)
.await
.expect("raw bytes isolated"),
Some(b"raw-bytes".to_vec()),
);
assert_eq!(
handles
.process_env
.get_process_execution_env(&lash_core::ProcessExecutionEnvRef::new(colliding_key))
.await
.expect("env bytes isolated"),
Some(b"env-bytes".to_vec()),
);
}