mirror of
https://github.com/openai/codex.git
synced 2026-10-31 19:28:49 +00:00
## Why Concurrent executions accessing the same endpoint can produce duplicate network approval prompts before a session decision is recorded. ## What changed - Queue manual prompts by environment, host, protocol, and port while keeping execution decisions separate. - After a one-time approval or denial, let the next execution prompt. Reuse committed session grants and deny rules without another prompt. - Keep tool results paused while requests are queued and attribute the wait to the triggering tool call. ## Testing Extend coverage for concurrent requests, one-time and session decisions, independent ports, queued cancellation and timing, and isolation between local and remote environments. GitOrigin-RevId: ebf580dddc39a9a9dc3b0d1acfa21438fbc6e100
70 lines
2.2 KiB
Rust
70 lines
2.2 KiB
Rust
use anyhow::Context;
|
|
use opentelemetry::global;
|
|
use opentelemetry::trace::TracerProvider as _;
|
|
use opentelemetry_sdk::propagation::TraceContextPropagator;
|
|
use opentelemetry_sdk::trace::SdkTracerProvider;
|
|
use tracing::dispatcher::DefaultGuard;
|
|
use tracing_subscriber::layer::SubscriberExt;
|
|
use tracing_subscriber::util::SubscriberInitExt;
|
|
|
|
/// Receives named trace events on a test's current-thread runtime.
|
|
pub struct NamedTraceEvents {
|
|
events: tokio::sync::mpsc::UnboundedReceiver<()>,
|
|
_subscriber: DefaultGuard,
|
|
}
|
|
|
|
impl NamedTraceEvents {
|
|
pub fn subscribe(name: &'static str) -> Self {
|
|
struct EventLayer {
|
|
name: &'static str,
|
|
sender: tokio::sync::mpsc::UnboundedSender<()>,
|
|
}
|
|
impl<S: tracing::Subscriber> tracing_subscriber::Layer<S> for EventLayer {
|
|
fn on_event(
|
|
&self,
|
|
event: &tracing::Event<'_>,
|
|
_: tracing_subscriber::layer::Context<'_, S>,
|
|
) {
|
|
if event.metadata().name() == self.name {
|
|
let _ = self.sender.send(());
|
|
}
|
|
}
|
|
}
|
|
|
|
let (sender, events) = tokio::sync::mpsc::unbounded_channel();
|
|
let subscriber = tracing_subscriber::registry()
|
|
.with(EventLayer { name, sender })
|
|
.set_default();
|
|
Self {
|
|
events,
|
|
_subscriber: subscriber,
|
|
}
|
|
}
|
|
|
|
pub async fn next(&mut self) -> anyhow::Result<()> {
|
|
tokio::time::timeout(std::time::Duration::from_secs(10), self.events.recv())
|
|
.await
|
|
.context("timed out waiting for trace event")?
|
|
.context("trace collector closed")
|
|
}
|
|
}
|
|
|
|
pub struct TestTracingContext {
|
|
_provider: SdkTracerProvider,
|
|
_guard: DefaultGuard,
|
|
}
|
|
|
|
pub fn install_test_tracing(tracer_name: &str) -> TestTracingContext {
|
|
global::set_text_map_propagator(TraceContextPropagator::new());
|
|
|
|
let provider = SdkTracerProvider::builder().build();
|
|
let tracer = provider.tracer(tracer_name.to_string());
|
|
let subscriber =
|
|
tracing_subscriber::registry().with(tracing_opentelemetry::layer().with_tracer(tracer));
|
|
|
|
TestTracingContext {
|
|
_provider: provider,
|
|
_guard: subscriber.set_default(),
|
|
}
|
|
}
|