mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-15 23:32:46 +00:00
fix(test): eliminate session lock race and openssl /dev/stdin flake
Two flake sources identified across 100+ full-suite runs: 1. Session lock EINVAL race: cleanup_session_root's remove_dir_all could delete the session root between with_session_lock's create_dir_all and File::create, causing EINVAL. Fix: retry the create-dir + create-file sequence as a unit. 2. mTLS cert generation: openssl req -key /dev/stdin failed under fd pressure with "Bad file descriptor". Fix: read from the already- written server.key file path instead of piping through /dev/stdin. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
15ccf9aef9
commit
cbcc0dad62
2 changed files with 19 additions and 8 deletions
|
|
@ -139,16 +139,17 @@ fn generate_mtls_certs(dir: &Path) -> Result<()> {
|
|||
let server_key_path = dir.join("server.key");
|
||||
std::fs::write(&server_key_path, &server_key)?;
|
||||
|
||||
let csr = run_openssl_with_stdin(
|
||||
let csr = run_openssl(
|
||||
&[
|
||||
"req",
|
||||
"-new",
|
||||
"-key",
|
||||
"/dev/stdin",
|
||||
server_key_path
|
||||
.to_str()
|
||||
.context("server key path is not valid UTF-8")?,
|
||||
"-subj",
|
||||
"/CN=localhost",
|
||||
],
|
||||
&server_key,
|
||||
"generate server CSR",
|
||||
)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -262,13 +262,23 @@ fn ensure_parent_dir(path: &Path) {
|
|||
}
|
||||
|
||||
fn with_session_lock<T>(root: &Path, f: impl FnOnce() -> T) -> T {
|
||||
std::fs::create_dir_all(root)
|
||||
.unwrap_or_else(|err| panic!("failed to create {}: {err}", root.display()));
|
||||
let lock_path = session_lock_path(root);
|
||||
ensure_parent_dir(&lock_path);
|
||||
let lock_file = File::create(&lock_path)
|
||||
.unwrap_or_else(|err| panic!("failed to create {}: {err}", lock_path.display()));
|
||||
// Retry create-dir + create-file as a unit: another process's
|
||||
// cleanup_session_root can remove_dir_all between the two calls.
|
||||
let deadline = std::time::Instant::now() + SESSION_LOCK_TIMEOUT;
|
||||
let lock_file = loop {
|
||||
std::fs::create_dir_all(root)
|
||||
.unwrap_or_else(|err| panic!("failed to create {}: {err}", root.display()));
|
||||
ensure_parent_dir(&lock_path);
|
||||
match File::create(&lock_path) {
|
||||
Ok(f) => break f,
|
||||
Err(err) if std::time::Instant::now() < deadline => {
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
continue;
|
||||
}
|
||||
Err(err) => panic!("failed to create {}: {err}", lock_path.display()),
|
||||
}
|
||||
};
|
||||
while !fabro_proc::try_flock_exclusive(&lock_file)
|
||||
.unwrap_or_else(|err| panic!("failed to lock {}: {err}", lock_path.display()))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue