mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
## Why Bootstrapping the app-server daemon should preserve an explicitly selected release, even when that version is currently `latest`. Older managed binaries should also be able to serve app-server without supporting the updater command. ## What changed - Record `latest` selections in `auto-update-version` in both standalone installers and clear the marker for explicit releases. - Start the daemon updater only for a marked stable release whose binary supports `pid-update-loop`. Existing installs without a marker require a new `latest` installation to enable automatic updates. - Recheck the selected release under the install lock so an in-flight update cannot overwrite a new pin, including installer calls from older updaters. Recheck selection before restarting app-server or replacing the updater. - Cancel Unix installer process groups and clean up their owned fallback locks when the updater stops. ## Testing Add coverage for channel markers, explicit pins of the current latest version, older updater guards, updater command support, and Unix installer cancellation with child-process and lock cleanup. GitOrigin-RevId: 4d275237bd77d896bf64dc1b85a5bca3608142c7
83 lines
3.8 KiB
Rust
83 lines
3.8 KiB
Rust
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn discovers_package_and_legacy_installs() {
|
|
let home = tempfile::TempDir::new().expect("home");
|
|
let current = home.path().join("packages/standalone/current");
|
|
let legacy = current.join(super::managed_codex_file_name());
|
|
let expected = if cfg!(windows) {
|
|
current.join("bin").join("codex.exe")
|
|
} else {
|
|
legacy.clone()
|
|
};
|
|
assert_eq!(super::managed_codex_bin(home.path()), expected);
|
|
std::fs::create_dir_all(¤t).expect("current directory");
|
|
std::fs::write(&legacy, b"legacy").expect("legacy executable");
|
|
assert_eq!(super::managed_codex_bin(home.path()), legacy);
|
|
let packaged = current.join("bin").join(super::managed_codex_file_name());
|
|
std::fs::create_dir(current.join("bin")).expect("bin directory");
|
|
std::fs::write(&packaged, b"packaged").expect("packaged executable");
|
|
assert_eq!(super::managed_codex_bin(home.path()), packaged);
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
#[test]
|
|
fn updater_only_runs_for_stable_installer_owned_releases() {
|
|
let home = tempfile::TempDir::new().expect("home");
|
|
let standalone = home.path().join("packages/standalone");
|
|
let current = standalone.join("current");
|
|
let release = standalone.join("releases/0.150.0-aarch64-apple-darwin");
|
|
let managed = release.join("bin/codex");
|
|
std::fs::create_dir_all(managed.parent().expect("bin parent")).expect("release");
|
|
std::fs::write(&managed, b"stable").expect("managed bin");
|
|
std::os::unix::fs::symlink(&release, ¤t).expect("current release");
|
|
assert!(!super::is_stable_standalone_release(home.path(), &managed));
|
|
let marker = standalone.join("auto-update-version");
|
|
let release_name = release.file_name().expect("release name");
|
|
std::fs::write(&marker, release_name.as_encoded_bytes()).expect("latest selection");
|
|
assert!(super::is_stable_standalone_release(home.path(), &managed));
|
|
std::fs::write(&marker, b"0.149.0-aarch64-apple-darwin").expect("stale selection");
|
|
assert!(!super::is_stable_standalone_release(home.path(), &managed));
|
|
std::fs::remove_file(&marker).expect("pinned selection");
|
|
assert!(!super::is_stable_standalone_release(home.path(), &managed));
|
|
|
|
let alpha = standalone.join("releases/0.151.0-alpha.1-aarch64-apple-darwin");
|
|
let alpha_managed = alpha.join("bin/codex");
|
|
std::fs::create_dir_all(alpha_managed.parent().expect("alpha bin parent"))
|
|
.expect("alpha release");
|
|
std::fs::write(&alpha_managed, b"alpha").expect("alpha bin");
|
|
std::fs::remove_file(¤t).expect("remove current");
|
|
std::os::unix::fs::symlink(alpha, ¤t).expect("current alpha");
|
|
assert!(!super::is_stable_standalone_release(
|
|
home.path(),
|
|
&alpha_managed
|
|
));
|
|
|
|
let local = standalone.join("local-main");
|
|
let local_managed = local.join("bin/codex");
|
|
std::fs::create_dir_all(local_managed.parent().expect("local bin parent"))
|
|
.expect("local build");
|
|
std::fs::write(&local_managed, b"local").expect("local bin");
|
|
std::fs::remove_file(¤t).expect("remove current");
|
|
std::os::unix::fs::symlink(local, ¤t).expect("current local build");
|
|
assert!(!super::is_stable_standalone_release(
|
|
home.path(),
|
|
&local_managed
|
|
));
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
#[tokio::test]
|
|
async fn older_managed_binary_does_not_claim_updater_support() {
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
let temp = tempfile::TempDir::new().expect("home");
|
|
let binary = temp.path().join("codex");
|
|
std::fs::write(&binary, b"#!/bin/sh\nexit 2\n").expect("older binary");
|
|
std::fs::set_permissions(&binary, std::fs::Permissions::from_mode(0o755))
|
|
.expect("executable binary");
|
|
assert!(!super::supports_daemon_update_loop(&binary).await);
|
|
std::fs::write(&binary, b"#!/bin/sh\nexit 0\n").expect("newer binary");
|
|
assert!(super::supports_daemon_update_loop(&binary).await);
|
|
}
|