mirror of
https://github.com/openai/codex.git
synced 2026-09-13 11:47:17 +00:00
## Why The PID-managed daemon updater downloaded the standalone installer directly, bypassing Codex's configured outbound proxy policy. ## What changed - Build the updater's HTTP client from the effective Codex configuration so `features.respect_system_proxy` also applies to installer downloads. - Use the route-aware client pool for the installer request. - Warn and fall back to the default `reqwest` proxy behavior when configuration cannot be loaded, allowing updates to continue. ## Testing Added tests for proxy-policy selection, configuration-load fallback, exact installer URL usage, byte preservation, and non-success HTTP responses. GitOrigin-RevId: 559668eb40314d43afa6512da66e59e32cc1b93c
95 lines
2.6 KiB
Rust
95 lines
2.6 KiB
Rust
use std::sync::Mutex;
|
|
|
|
use pretty_assertions::assert_eq;
|
|
|
|
use super::INSTALL_URL;
|
|
use super::InstallerHttp;
|
|
use super::InstallerResponse;
|
|
use super::fetch_installer_script;
|
|
use super::update_modes_for_identities;
|
|
use crate::RestartMode;
|
|
use crate::UpdaterRefreshMode;
|
|
use crate::managed_install::executable_identity_from_bytes;
|
|
|
|
#[test]
|
|
fn unchanged_updater_uses_version_based_restart() {
|
|
assert_eq!(
|
|
update_modes_for_identities(
|
|
&executable_identity_from_bytes(b"same"),
|
|
&executable_identity_from_bytes(b"same"),
|
|
),
|
|
(RestartMode::IfVersionChanged, UpdaterRefreshMode::None)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn changed_updater_forces_refresh_even_when_version_may_match() {
|
|
assert_eq!(
|
|
update_modes_for_identities(
|
|
&executable_identity_from_bytes(b"old"),
|
|
&executable_identity_from_bytes(b"new"),
|
|
),
|
|
(
|
|
RestartMode::Always,
|
|
UpdaterRefreshMode::ReexecIfManagedBinaryChanged,
|
|
)
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn installer_fetch_uses_exact_url_and_preserves_bytes() {
|
|
let script = b"#!/bin/sh\nprintf 'update bytes'\n".to_vec();
|
|
let http = FakeInstallerHttp::new(InstallerResponse::Success(script.clone()));
|
|
|
|
assert_eq!(
|
|
fetch_installer_script(&http)
|
|
.await
|
|
.expect("installer fetch should succeed"),
|
|
script
|
|
);
|
|
assert_eq!(http.requested_urls(), vec![INSTALL_URL.to_string()]);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn installer_fetch_rejects_non_success_status() {
|
|
let http = FakeInstallerHttp::new(InstallerResponse::Unsuccessful { status: 503 });
|
|
|
|
let error = fetch_installer_script(&http)
|
|
.await
|
|
.expect_err("non-success response should fail");
|
|
|
|
assert!(error.to_string().contains("503"));
|
|
assert_eq!(http.requested_urls(), vec![INSTALL_URL.to_string()]);
|
|
}
|
|
|
|
struct FakeInstallerHttp {
|
|
response: InstallerResponse,
|
|
requested_urls: Mutex<Vec<String>>,
|
|
}
|
|
|
|
impl FakeInstallerHttp {
|
|
fn new(response: InstallerResponse) -> Self {
|
|
Self {
|
|
response,
|
|
requested_urls: Mutex::new(Vec::new()),
|
|
}
|
|
}
|
|
|
|
fn requested_urls(&self) -> Vec<String> {
|
|
self.requested_urls
|
|
.lock()
|
|
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
|
.clone()
|
|
}
|
|
}
|
|
|
|
impl InstallerHttp for FakeInstallerHttp {
|
|
async fn get(&self, url: &str) -> anyhow::Result<InstallerResponse> {
|
|
self.requested_urls
|
|
.lock()
|
|
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
|
.push(url.to_string());
|
|
Ok(self.response.clone())
|
|
}
|
|
}
|