Skip to content

Commit 6dea545

Browse files
committed
improve unit-test comments
1 parent c7ba0fc commit 6dea545

File tree

1 file changed

+47
-20
lines changed

1 file changed

+47
-20
lines changed

opentelemetry-sdk/src/logs/log_processor.rs

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,24 +1140,24 @@ mod tests {
11401140
);
11411141
}
11421142

1143-
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
1144-
async fn test_simple_processor_async_exporter_with_runtime() {
1145-
let exporter = LogExporterThatRequiresTokio::new();
1146-
let processor = SimpleLogProcessor::new(Box::new(exporter.clone()));
1147-
1148-
let mut record: LogRecord = Default::default();
1149-
let instrumentation: InstrumentationLibrary = Default::default();
1150-
1151-
processor.emit(&mut record, &instrumentation);
1152-
1153-
assert_eq!(exporter.len(), 1);
1154-
}
1155-
11561143
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
11571144
#[ignore]
1158-
// All worker threads except one are blocked, waiting for the export operation to complete.
1159-
// The exporter, which isn't blocked, requires the runtime to proceed, but no free worker threads are available, resulting in a deadlock.
1160-
// This mimics the scenario where the
1145+
// This test demonstrates a potential deadlock scenario in a multi-threaded Tokio runtime.
1146+
// It spawns Tokio tasks equal to the number of runtime worker threads (4) to emit log events.
1147+
// Each task attempts to acquire a mutex on the SimpleLogProcessor. Only one task obtains the lock,
1148+
// while the others are blocked, waiting for its release.
1149+
//
1150+
// The task holding the lock invokes the LogExporterThatRequiresTokio, which performs an
1151+
// asynchronous operation (e.g., network I/O simulated by `tokio::sleep`). This operation
1152+
// requires yielding control back to the Tokio runtime to make progress.
1153+
//
1154+
// However, all worker threads are occupied:
1155+
// - One thread is executing the async exporter operation
1156+
// - Three threads are blocked waiting for the mutex
1157+
//
1158+
// This leads to a deadlock as there are no available threads to drive the async operation
1159+
// to completion, preventing the mutex from being released. Consequently, neither the blocked
1160+
// tasks nor the exporter can proceed.
11611161
async fn test_simple_processor_async_exporter_with_all_runtime_worker_threads_blocked() {
11621162
let exporter = LogExporterThatRequiresTokio::new();
11631163
let processor = Arc::new(Mutex::new(SimpleLogProcessor::new(Box::new(
@@ -1181,13 +1181,37 @@ mod tests {
11811181
handles.push(handle);
11821182
}
11831183

1184+
// below code won't get executed
11841185
for handle in handles {
11851186
handle.await.unwrap();
11861187
}
1187-
assert_eq!(exporter.len(), 4);
1188+
assert_eq!(exporter.len(), concurrent_emit);
1189+
}
1190+
1191+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
1192+
// This test uses a multi-threaded runtime setup with a single worker thread. Note that even
1193+
// though only one worker thread is created, it is distinct from the main thread. The processor
1194+
// emits a log event, and the exporter performs an async operation that requires the runtime.
1195+
// The single worker thread handles this operation without deadlocking, as long as no other
1196+
// tasks occupy the runtime.
1197+
async fn test_simple_processor_async_exporter_with_runtime() {
1198+
let exporter = LogExporterThatRequiresTokio::new();
1199+
let processor = SimpleLogProcessor::new(Box::new(exporter.clone()));
1200+
1201+
let mut record: LogRecord = Default::default();
1202+
let instrumentation: InstrumentationLibrary = Default::default();
1203+
1204+
processor.emit(&mut record, &instrumentation);
1205+
1206+
assert_eq!(exporter.len(), 1);
11881207
}
11891208

11901209
#[tokio::test(flavor = "multi_thread")]
1210+
// This test uses a multi-threaded runtime setup with the default number of worker threads.
1211+
// The processor emits a log event, and the exporter, which requires the runtime for its async
1212+
// operations, can access one of the available worker threads to complete its task. As there
1213+
// are multiple threads, the exporter can proceed without blocking other tasks, ensuring the
1214+
// test completes successfully.
11911215
async fn test_simple_processor_async_exporter_with_multi_thread_runtime() {
11921216
let exporter = LogExporterThatRequiresTokio::new();
11931217

@@ -1202,9 +1226,12 @@ mod tests {
12021226
}
12031227

12041228
#[tokio::test(flavor = "current_thread")]
1205-
#[ignore] // the current thread is blocked with futures::block_on to
1206-
// complete the export, and the exporter further needs tokio runtime to progress
1207-
// on this blocked thread, resulting in deadlock.
1229+
#[ignore]
1230+
// This test uses a current-thread runtime, where all operations run on the main thread.
1231+
// The processor emits a log event while the runtime is blocked using `futures::block_on`
1232+
// to complete the export operation. The exporter, which performs an async operation and
1233+
// requires the runtime, cannot progress because the main thread is already blocked.
1234+
// This results in a deadlock, as the runtime cannot move forward.
12081235
async fn test_simple_processor_async_exporter_with_current_thread_runtime() {
12091236
let exporter = LogExporterThatRequiresTokio::new();
12101237

0 commit comments

Comments
 (0)