| 1 | use tracing::subscriber::with_default; |
| 2 | use tracing::Level; |
| 3 | use tracing_attributes::instrument; |
| 4 | use tracing_mock::*; |
| 5 | use tracing_subscriber::filter::EnvFilter; |
| 6 | use tracing_subscriber::layer::SubscriberExt; |
| 7 | |
| 8 | use std::convert::TryFrom; |
| 9 | use std::num::TryFromIntError; |
| 10 | |
| 11 | #[instrument (err)] |
| 12 | fn err() -> Result<u8, TryFromIntError> { |
| 13 | u8::try_from(1234) |
| 14 | } |
| 15 | |
| 16 | #[instrument (err)] |
| 17 | fn err_suspicious_else() -> Result<u8, TryFromIntError> { |
| 18 | {} |
| 19 | u8::try_from(1234) |
| 20 | } |
| 21 | |
| 22 | #[test] |
| 23 | fn test() { |
| 24 | let span = expect::span().named("err" ); |
| 25 | let (subscriber, handle) = subscriber::mock() |
| 26 | .new_span(span.clone()) |
| 27 | .enter(span.clone()) |
| 28 | .event(expect::event().at_level(Level::ERROR)) |
| 29 | .exit(span.clone()) |
| 30 | .drop_span(span) |
| 31 | .only() |
| 32 | .run_with_handle(); |
| 33 | with_default(subscriber, || err().ok()); |
| 34 | handle.assert_finished(); |
| 35 | } |
| 36 | |
| 37 | #[instrument (err)] |
| 38 | fn err_early_return() -> Result<u8, TryFromIntError> { |
| 39 | u8::try_from(1234)?; |
| 40 | Ok(5) |
| 41 | } |
| 42 | |
| 43 | #[test] |
| 44 | fn test_early_return() { |
| 45 | let span = expect::span().named("err_early_return" ); |
| 46 | let (subscriber, handle) = subscriber::mock() |
| 47 | .new_span(span.clone()) |
| 48 | .enter(span.clone()) |
| 49 | .event(expect::event().at_level(Level::ERROR)) |
| 50 | .exit(span.clone()) |
| 51 | .drop_span(span) |
| 52 | .only() |
| 53 | .run_with_handle(); |
| 54 | with_default(subscriber, || err_early_return().ok()); |
| 55 | handle.assert_finished(); |
| 56 | } |
| 57 | |
| 58 | #[instrument (err)] |
| 59 | async fn err_async(polls: usize) -> Result<u8, TryFromIntError> { |
| 60 | let future = PollN::new_ok(polls); |
| 61 | tracing::trace!(awaiting = true); |
| 62 | future.await.ok(); |
| 63 | u8::try_from(1234) |
| 64 | } |
| 65 | |
| 66 | #[test] |
| 67 | fn test_async() { |
| 68 | let span = expect::span().named("err_async" ); |
| 69 | let (subscriber, handle) = subscriber::mock() |
| 70 | .new_span(span.clone()) |
| 71 | .enter(span.clone()) |
| 72 | .event( |
| 73 | expect::event() |
| 74 | .with_fields(expect::field("awaiting" ).with_value(&true)) |
| 75 | .at_level(Level::TRACE), |
| 76 | ) |
| 77 | .exit(span.clone()) |
| 78 | .enter(span.clone()) |
| 79 | .event(expect::event().at_level(Level::ERROR)) |
| 80 | .exit(span.clone()) |
| 81 | .enter(span.clone()) |
| 82 | .exit(span.clone()) |
| 83 | .drop_span(span) |
| 84 | .only() |
| 85 | .run_with_handle(); |
| 86 | with_default(subscriber, || { |
| 87 | block_on_future(async { err_async(2).await }).ok(); |
| 88 | }); |
| 89 | handle.assert_finished(); |
| 90 | } |
| 91 | |
| 92 | #[instrument (err)] |
| 93 | fn err_mut(out: &mut u8) -> Result<(), TryFromIntError> { |
| 94 | *out = u8::try_from(1234)?; |
| 95 | Ok(()) |
| 96 | } |
| 97 | |
| 98 | #[test] |
| 99 | fn test_mut() { |
| 100 | let span = expect::span().named("err_mut" ); |
| 101 | let (subscriber, handle) = subscriber::mock() |
| 102 | .new_span(span.clone()) |
| 103 | .enter(span.clone()) |
| 104 | .event(expect::event().at_level(Level::ERROR)) |
| 105 | .exit(span.clone()) |
| 106 | .drop_span(span) |
| 107 | .only() |
| 108 | .run_with_handle(); |
| 109 | with_default(subscriber, || err_mut(&mut 0).ok()); |
| 110 | handle.assert_finished(); |
| 111 | } |
| 112 | |
| 113 | #[instrument (err)] |
| 114 | async fn err_mut_async(polls: usize, out: &mut u8) -> Result<(), TryFromIntError> { |
| 115 | let future = PollN::new_ok(polls); |
| 116 | tracing::trace!(awaiting = true); |
| 117 | future.await.ok(); |
| 118 | *out = u8::try_from(1234)?; |
| 119 | Ok(()) |
| 120 | } |
| 121 | |
| 122 | #[test] |
| 123 | fn test_mut_async() { |
| 124 | let span = expect::span().named("err_mut_async" ); |
| 125 | let (subscriber, handle) = subscriber::mock() |
| 126 | .new_span(span.clone()) |
| 127 | .enter(span.clone()) |
| 128 | .event( |
| 129 | expect::event() |
| 130 | .with_fields(expect::field("awaiting" ).with_value(&true)) |
| 131 | .at_level(Level::TRACE), |
| 132 | ) |
| 133 | .exit(span.clone()) |
| 134 | .enter(span.clone()) |
| 135 | .event(expect::event().at_level(Level::ERROR)) |
| 136 | .exit(span.clone()) |
| 137 | .enter(span.clone()) |
| 138 | .exit(span.clone()) |
| 139 | .drop_span(span) |
| 140 | .only() |
| 141 | .run_with_handle(); |
| 142 | with_default(subscriber, || { |
| 143 | block_on_future(async { err_mut_async(2, &mut 0).await }).ok(); |
| 144 | }); |
| 145 | handle.assert_finished(); |
| 146 | } |
| 147 | |
| 148 | #[test] |
| 149 | fn impl_trait_return_type() { |
| 150 | // Reproduces https://github.com/tokio-rs/tracing/issues/1227 |
| 151 | |
| 152 | #[instrument (err)] |
| 153 | fn returns_impl_trait(x: usize) -> Result<impl Iterator<Item = usize>, String> { |
| 154 | Ok(0..x) |
| 155 | } |
| 156 | |
| 157 | let span = expect::span().named("returns_impl_trait" ); |
| 158 | |
| 159 | let (subscriber, handle) = subscriber::mock() |
| 160 | .new_span( |
| 161 | span.clone() |
| 162 | .with_field(expect::field("x" ).with_value(&10usize).only()), |
| 163 | ) |
| 164 | .enter(span.clone()) |
| 165 | .exit(span.clone()) |
| 166 | .drop_span(span) |
| 167 | .only() |
| 168 | .run_with_handle(); |
| 169 | |
| 170 | with_default(subscriber, || { |
| 171 | for _ in returns_impl_trait(10).unwrap() { |
| 172 | // nop |
| 173 | } |
| 174 | }); |
| 175 | |
| 176 | handle.assert_finished(); |
| 177 | } |
| 178 | |
| 179 | #[instrument (err(Debug))] |
| 180 | fn err_dbg() -> Result<u8, TryFromIntError> { |
| 181 | u8::try_from(1234) |
| 182 | } |
| 183 | |
| 184 | #[test] |
| 185 | fn test_err_dbg() { |
| 186 | let span = expect::span().named("err_dbg" ); |
| 187 | let (subscriber, handle) = subscriber::mock() |
| 188 | .new_span(span.clone()) |
| 189 | .enter(span.clone()) |
| 190 | .event( |
| 191 | expect::event().at_level(Level::ERROR).with_fields( |
| 192 | expect::field("error" ) |
| 193 | // use the actual error value that will be emitted, so |
| 194 | // that this test doesn't break if the standard library |
| 195 | // changes the `fmt::Debug` output from the error type |
| 196 | // in the future. |
| 197 | .with_value(&tracing::field::debug(u8::try_from(1234).unwrap_err())), |
| 198 | ), |
| 199 | ) |
| 200 | .exit(span.clone()) |
| 201 | .drop_span(span) |
| 202 | .only() |
| 203 | .run_with_handle(); |
| 204 | with_default(subscriber, || err_dbg().ok()); |
| 205 | handle.assert_finished(); |
| 206 | } |
| 207 | |
| 208 | #[test] |
| 209 | fn test_err_display_default() { |
| 210 | let span = expect::span().named("err" ); |
| 211 | let (subscriber, handle) = subscriber::mock() |
| 212 | .new_span(span.clone()) |
| 213 | .enter(span.clone()) |
| 214 | .event( |
| 215 | expect::event().at_level(Level::ERROR).with_fields( |
| 216 | expect::field("error" ) |
| 217 | // by default, errors will be emitted with their display values |
| 218 | .with_value(&tracing::field::display(u8::try_from(1234).unwrap_err())), |
| 219 | ), |
| 220 | ) |
| 221 | .exit(span.clone()) |
| 222 | .drop_span(span) |
| 223 | .only() |
| 224 | .run_with_handle(); |
| 225 | with_default(subscriber, || err().ok()); |
| 226 | handle.assert_finished(); |
| 227 | } |
| 228 | |
| 229 | #[test] |
| 230 | fn test_err_custom_target() { |
| 231 | let filter: EnvFilter = "my_target=error" .parse().expect("filter should parse" ); |
| 232 | let span = expect::span().named("error_span" ).with_target("my_target" ); |
| 233 | |
| 234 | let (subscriber, handle) = subscriber::mock() |
| 235 | .new_span(span.clone()) |
| 236 | .enter(span.clone()) |
| 237 | .event( |
| 238 | expect::event() |
| 239 | .at_level(Level::ERROR) |
| 240 | .with_target("my_target" ), |
| 241 | ) |
| 242 | .exit(span.clone()) |
| 243 | .drop_span(span) |
| 244 | .only() |
| 245 | .run_with_handle(); |
| 246 | |
| 247 | let subscriber = subscriber.with(filter); |
| 248 | |
| 249 | with_default(subscriber, || { |
| 250 | let error_span = tracing::error_span!(target: "my_target" , "error_span" ); |
| 251 | |
| 252 | { |
| 253 | let _enter = error_span.enter(); |
| 254 | tracing::error!(target: "my_target" , "This should display" ) |
| 255 | } |
| 256 | }); |
| 257 | handle.assert_finished(); |
| 258 | } |
| 259 | |
| 260 | #[instrument (err(level = "info" ))] |
| 261 | fn err_info() -> Result<u8, TryFromIntError> { |
| 262 | u8::try_from(1234) |
| 263 | } |
| 264 | |
| 265 | #[test] |
| 266 | fn test_err_info() { |
| 267 | let span = expect::span().named("err_info" ); |
| 268 | let (subscriber, handle) = subscriber::mock() |
| 269 | .new_span(span.clone()) |
| 270 | .enter(span.clone()) |
| 271 | .event(expect::event().at_level(Level::INFO)) |
| 272 | .exit(span.clone()) |
| 273 | .drop_span(span) |
| 274 | .only() |
| 275 | .run_with_handle(); |
| 276 | with_default(subscriber, || err_info().ok()); |
| 277 | handle.assert_finished(); |
| 278 | } |
| 279 | |
| 280 | #[instrument (err(Debug, level = "info" ))] |
| 281 | fn err_dbg_info() -> Result<u8, TryFromIntError> { |
| 282 | u8::try_from(1234) |
| 283 | } |
| 284 | |
| 285 | #[test] |
| 286 | fn test_err_dbg_info() { |
| 287 | let span = expect::span().named("err_dbg_info" ); |
| 288 | let (subscriber, handle) = subscriber::mock() |
| 289 | .new_span(span.clone()) |
| 290 | .enter(span.clone()) |
| 291 | .event( |
| 292 | expect::event().at_level(Level::INFO).with_fields( |
| 293 | expect::field("error" ) |
| 294 | // use the actual error value that will be emitted, so |
| 295 | // that this test doesn't break if the standard library |
| 296 | // changes the `fmt::Debug` output from the error type |
| 297 | // in the future. |
| 298 | .with_value(&tracing::field::debug(u8::try_from(1234).unwrap_err())), |
| 299 | ), |
| 300 | ) |
| 301 | .exit(span.clone()) |
| 302 | .drop_span(span) |
| 303 | .only() |
| 304 | .run_with_handle(); |
| 305 | with_default(subscriber, || err_dbg_info().ok()); |
| 306 | handle.assert_finished(); |
| 307 | } |
| 308 | |
| 309 | #[instrument (level = "warn" , err(level = "info" ))] |
| 310 | fn err_warn_info() -> Result<u8, TryFromIntError> { |
| 311 | u8::try_from(1234) |
| 312 | } |
| 313 | |
| 314 | #[test] |
| 315 | fn test_err_warn_info() { |
| 316 | let span = expect::span().named("err_warn_info" ).at_level(Level::WARN); |
| 317 | let (subscriber, handle) = subscriber::mock() |
| 318 | .new_span(span.clone()) |
| 319 | .enter(span.clone()) |
| 320 | .event(expect::event().at_level(Level::INFO)) |
| 321 | .exit(span.clone()) |
| 322 | .drop_span(span) |
| 323 | .only() |
| 324 | .run_with_handle(); |
| 325 | with_default(subscriber, || err_warn_info().ok()); |
| 326 | handle.assert_finished(); |
| 327 | } |
| 328 | |