mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-07 08:27:12 +00:00
Keep daemon-dependent Docker lifecycle coverage as an ignored integration test so the default unit path remains runnable without Docker.
89 lines
2.5 KiB
Rust
89 lines
2.5 KiB
Rust
#![cfg(feature = "docker")]
|
|
|
|
use std::sync::Arc;
|
|
|
|
use bollard::Docker;
|
|
use fabro_sandbox::{CommandOutputCallback, DockerSandbox, DockerSandboxOptions, Sandbox};
|
|
use tokio::sync::Mutex;
|
|
|
|
#[tokio::test]
|
|
#[ignore = "requires real Docker container lifecycle; run explicitly when changing Docker exec integration"]
|
|
async fn streaming_timeout_terminates_docker_exec_before_returning() {
|
|
let image = "buildpack-deps:noble";
|
|
let Ok(docker) = Docker::connect_with_local_defaults() else {
|
|
return;
|
|
};
|
|
if docker.inspect_image(image).await.is_err() {
|
|
return;
|
|
}
|
|
|
|
let sandbox = DockerSandbox::new(
|
|
DockerSandboxOptions {
|
|
image: image.to_string(),
|
|
auto_pull: false,
|
|
skip_clone: true,
|
|
..DockerSandboxOptions::default()
|
|
},
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
.expect("docker sandbox should construct");
|
|
sandbox
|
|
.initialize()
|
|
.await
|
|
.expect("docker sandbox should initialize");
|
|
|
|
let chunks = Arc::new(Mutex::new(Vec::new()));
|
|
let callback_chunks = Arc::clone(&chunks);
|
|
let callback: CommandOutputCallback = Arc::new(move |_stream, bytes| {
|
|
let callback_chunks = Arc::clone(&callback_chunks);
|
|
Box::pin(async move {
|
|
callback_chunks.lock().await.extend(bytes);
|
|
Ok(())
|
|
})
|
|
});
|
|
|
|
let marker = "fabro_streaming_timeout_sentinel";
|
|
let result = sandbox
|
|
.exec_command_streaming(
|
|
&format!("trap '' HUP TERM; echo start; sleep 5 # {marker}"),
|
|
200,
|
|
None,
|
|
None,
|
|
None,
|
|
callback,
|
|
)
|
|
.await
|
|
.expect("streaming command should return a timeout result");
|
|
|
|
assert!(result.result.is_timed_out());
|
|
assert!(
|
|
String::from_utf8_lossy(&chunks.lock().await).contains("start"),
|
|
"stream should include output emitted before timeout"
|
|
);
|
|
|
|
let probe = sandbox
|
|
.exec_command(
|
|
"marker='fabro_streaming_timeout_''sentinel'; \
|
|
ps -eo pid,args | awk -v marker=\"$marker\" \
|
|
'index($0, marker) && $0 !~ /awk/ && $0 !~ /ps -eo/ { print }'",
|
|
1_000,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
.await
|
|
.expect("process probe should run");
|
|
sandbox
|
|
.cleanup()
|
|
.await
|
|
.expect("docker cleanup should succeed");
|
|
|
|
assert!(
|
|
!probe.stdout.contains(marker),
|
|
"timed-out docker exec should be terminated before returning, found: {}",
|
|
probe.stdout
|
|
);
|
|
}
|