build(rust): vendor googletest crate
This commit was merged in pull request #76.
This commit is contained in:
1 parent
a6fe84190e
commit
6887b104d6
576 files changed
+284290
-2
No files matched your search
@@ -0,0 +1,126 @@
|
||||
// Copyright 2026 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
static NEXT_TRACE_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
/// Information about a scoped trace.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TraceInfo {
|
||||
pub id: usize,
|
||||
pub file: &'static str,
|
||||
pub line: u32,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static TRACE_STACK: RefCell<Vec<TraceInfo>> = const { RefCell::new(Vec::new()) };
|
||||
}
|
||||
|
||||
/// RAII guard to manage the push and pop of trace information.
|
||||
///
|
||||
/// This struct is `!Send` and `!Sync` to prevent it from being held across
|
||||
/// `.await` points in async tests, which would cause incorrect trace tracking
|
||||
/// if the task moves between threads.
|
||||
#[doc(hidden)]
|
||||
pub struct ScopedTraceGuard {
|
||||
id: usize,
|
||||
_phantom: std::marker::PhantomData<*mut ()>,
|
||||
}
|
||||
|
||||
impl ScopedTraceGuard {
|
||||
#[doc(hidden)]
|
||||
#[track_caller]
|
||||
pub fn new(message: String) -> Self {
|
||||
let caller = std::panic::Location::caller();
|
||||
let id = NEXT_TRACE_ID.fetch_add(1, Ordering::Relaxed);
|
||||
TRACE_STACK.with(|stack| {
|
||||
// Use try_borrow_mut to avoid double panic if called during unwinding.
|
||||
if let Ok(mut s) = stack.try_borrow_mut() {
|
||||
s.push(TraceInfo { id, file: caller.file(), line: caller.line(), message });
|
||||
}
|
||||
});
|
||||
Self { id, _phantom: std::marker::PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ScopedTraceGuard {
|
||||
fn drop(&mut self) {
|
||||
TRACE_STACK.with(|stack| {
|
||||
// Use try_borrow_mut to avoid double panic if called during unwinding.
|
||||
if let Ok(mut s) = stack.try_borrow_mut() {
|
||||
if let Some(pos) = s.iter().rposition(|t| t.id == self.id) {
|
||||
s.remove(pos);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves a clone of the current thread's trace stack.
|
||||
pub fn get_scoped_traces() -> Vec<TraceInfo> {
|
||||
TRACE_STACK.with(|stack| stack.try_borrow().map(|s| s.clone()).unwrap_or_default())
|
||||
}
|
||||
|
||||
// Test-only state and helpers, hidden from production API.
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_helpers {
|
||||
use super::*;
|
||||
use std::cell::Cell;
|
||||
|
||||
thread_local! {
|
||||
pub static CAPTURED_TRACES_IN_HOOK: RefCell<Vec<TraceInfo>> = const { RefCell::new(Vec::new()) };
|
||||
pub static USE_CAPTURE_HOOK: Cell<bool> = const { Cell::new(false) };
|
||||
}
|
||||
|
||||
pub fn enable_capture_in_hook(enable: bool) {
|
||||
USE_CAPTURE_HOOK.with(|v| v.set(enable));
|
||||
}
|
||||
|
||||
pub fn get_captured_traces_in_hook() -> Vec<TraceInfo> {
|
||||
CAPTURED_TRACES_IN_HOOK.with(|v| v.borrow().clone())
|
||||
}
|
||||
|
||||
pub fn clear_captured_traces_in_hook() {
|
||||
CAPTURED_TRACES_IN_HOOK.with(|v| v.borrow_mut().clear());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::test_helpers::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_scoped_trace_fatal() {
|
||||
enable_capture_in_hook(true);
|
||||
clear_captured_traces_in_hook();
|
||||
|
||||
// Ensure hook is installed
|
||||
crate::internal::test_outcome::TestOutcome::init_current_test_outcome();
|
||||
|
||||
let _ = std::panic::catch_unwind(|| {
|
||||
let _guard = ScopedTraceGuard::new("Second trace".to_string());
|
||||
panic!("Intentional panic");
|
||||
});
|
||||
|
||||
let captured = get_captured_traces_in_hook();
|
||||
assert_eq!(captured.len(), 1);
|
||||
assert_eq!(captured[0].message, "Second trace");
|
||||
|
||||
enable_capture_in_hook(false);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user