| 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()); |
| assert_eq!( |
| super::managed_codex_bin(home.path()), |
| home.path() |
| .join("packages/app-server-daemon/current/bin") |
| .join(super::managed_codex_file_name()) |
| ); |
| std::fs::create_dir_all(¤t).expect("current directory"); |
| std::fs::write(&legacy, b"legacy").expect("legacy executable"); |
| let state = home.path().join("app-server-daemon"); |
| std::fs::create_dir(&state).unwrap(); |
| for name in ["settings.json", "daemon.lock", "app-server.pid.lock"] { |
| std::fs::write(state.join(name), b"").unwrap(); |
| } |
| |
| assert_eq!( |
| super::package_root(home.path()), |
| home.path().join("packages/app-server-daemon") |
| ); |
| std::fs::write(state.join("app-server.stderr.log"), b"").unwrap(); |
| 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); |
|
|
| std::fs::remove_dir_all(home.path().join("packages/standalone")).unwrap(); |
| assert_eq!( |
| super::package_root(home.path()), |
| home.path().join("packages/standalone") |
| ); |
| std::fs::remove_file(state.join("app-server.stderr.log")).unwrap(); |
| std::fs::write(state.join("app-server.pid"), b"running daemon").unwrap(); |
| assert_eq!( |
| super::package_root(home.path()), |
| home.path().join("packages/standalone") |
| ); |
|
|
| std::fs::write(state.join("daemon.pid"), b"running dedicated daemon").unwrap(); |
| assert_eq!( |
| super::package_root(home.path()), |
| home.path().join("packages/app-server-daemon") |
| ); |
| std::fs::remove_file(state.join("daemon.pid")).unwrap(); |
| std::fs::write(state.join("daemon.stderr.log"), b"").unwrap(); |
| assert_eq!( |
| super::package_root(home.path()), |
| home.path().join("packages/app-server-daemon") |
| ); |
|
|
| #[cfg(unix)] |
| { |
| let dedicated = home.path().join("packages/app-server-daemon"); |
| std::fs::write(&dedicated, b"not a directory").expect("unreadable selection"); |
| assert_eq!(super::package_root(home.path()), dedicated); |
| } |
| } |
|
|
| #[cfg(unix)] |
| #[test] |
| fn updater_only_runs_for_stable_installer_owned_releases() { |
| let home = tempfile::TempDir::new().expect("home"); |
| let state = home.path().join("app-server-daemon"); |
| std::fs::create_dir(&state).unwrap(); |
| std::fs::write(state.join("app-server.stderr.log"), b"").unwrap(); |
| 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); |
| } |
|
|