span.rs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. // These tests require the thread-local scoped dispatcher, which only works when
  2. // we have a standard library. The behaviour being tested should be the same
  3. // with the standard lib disabled.
  4. #![cfg(feature = "std")]
  5. use std::thread;
  6. use tracing::{
  7. field::{debug, display},
  8. subscriber::with_default,
  9. Level, Span,
  10. };
  11. use tracing_mock::*;
  12. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  13. #[test]
  14. fn handles_to_the_same_span_are_equal() {
  15. // Create a mock subscriber that will return `true` on calls to
  16. // `Subscriber::enabled`, so that the spans will be constructed. We
  17. // won't enter any spans in this test, so the subscriber won't actually
  18. // expect to see any spans.
  19. with_default(subscriber::mock().run(), || {
  20. let foo1 = tracing::span!(Level::TRACE, "foo");
  21. let foo2 = foo1.clone();
  22. // Two handles that point to the same span are equal.
  23. assert_eq!(foo1, foo2);
  24. });
  25. }
  26. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  27. #[test]
  28. fn handles_to_different_spans_are_not_equal() {
  29. with_default(subscriber::mock().run(), || {
  30. // Even though these spans have the same name and fields, they will have
  31. // differing metadata, since they were created on different lines.
  32. let foo1 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false);
  33. let foo2 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false);
  34. assert_ne!(foo1, foo2);
  35. });
  36. }
  37. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  38. #[test]
  39. fn handles_to_different_spans_with_the_same_metadata_are_not_equal() {
  40. // Every time time this function is called, it will return a _new
  41. // instance_ of a span with the same metadata, name, and fields.
  42. fn make_span() -> Span {
  43. tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false)
  44. }
  45. with_default(subscriber::mock().run(), || {
  46. let foo1 = make_span();
  47. let foo2 = make_span();
  48. assert_ne!(foo1, foo2);
  49. // assert_ne!(foo1.data(), foo2.data());
  50. });
  51. }
  52. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  53. #[test]
  54. fn spans_always_go_to_the_subscriber_that_tagged_them() {
  55. let subscriber1 = subscriber::mock()
  56. .enter(span::mock().named("foo"))
  57. .exit(span::mock().named("foo"))
  58. .enter(span::mock().named("foo"))
  59. .exit(span::mock().named("foo"))
  60. .drop_span(span::mock().named("foo"))
  61. .done()
  62. .run();
  63. let subscriber2 = subscriber::mock().run();
  64. let foo = with_default(subscriber1, || {
  65. let foo = tracing::span!(Level::TRACE, "foo");
  66. foo.in_scope(|| {});
  67. foo
  68. });
  69. // Even though we enter subscriber 2's context, the subscriber that
  70. // tagged the span should see the enter/exit.
  71. with_default(subscriber2, move || foo.in_scope(|| {}));
  72. }
  73. // This gets exempt from testing in wasm because of: `thread::spawn` which is
  74. // not yet possible to do in WASM. There is work going on see:
  75. // <https://rustwasm.github.io/2018/10/24/multithreading-rust-and-wasm.html>
  76. //
  77. // But for now since it's not possible we don't need to test for it :)
  78. #[test]
  79. fn spans_always_go_to_the_subscriber_that_tagged_them_even_across_threads() {
  80. let subscriber1 = subscriber::mock()
  81. .enter(span::mock().named("foo"))
  82. .exit(span::mock().named("foo"))
  83. .enter(span::mock().named("foo"))
  84. .exit(span::mock().named("foo"))
  85. .drop_span(span::mock().named("foo"))
  86. .done()
  87. .run();
  88. let foo = with_default(subscriber1, || {
  89. let foo = tracing::span!(Level::TRACE, "foo");
  90. foo.in_scope(|| {});
  91. foo
  92. });
  93. // Even though we enter subscriber 2's context, the subscriber that
  94. // tagged the span should see the enter/exit.
  95. thread::spawn(move || {
  96. with_default(subscriber::mock().run(), || {
  97. foo.in_scope(|| {});
  98. })
  99. })
  100. .join()
  101. .unwrap();
  102. }
  103. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  104. #[test]
  105. fn dropping_a_span_calls_drop_span() {
  106. let (subscriber, handle) = subscriber::mock()
  107. .enter(span::mock().named("foo"))
  108. .exit(span::mock().named("foo"))
  109. .drop_span(span::mock().named("foo"))
  110. .done()
  111. .run_with_handle();
  112. with_default(subscriber, || {
  113. let span = tracing::span!(Level::TRACE, "foo");
  114. span.in_scope(|| {});
  115. drop(span);
  116. });
  117. handle.assert_finished();
  118. }
  119. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  120. #[test]
  121. fn span_closes_after_event() {
  122. let (subscriber, handle) = subscriber::mock()
  123. .enter(span::mock().named("foo"))
  124. .event(event::mock())
  125. .exit(span::mock().named("foo"))
  126. .drop_span(span::mock().named("foo"))
  127. .done()
  128. .run_with_handle();
  129. with_default(subscriber, || {
  130. tracing::span!(Level::TRACE, "foo").in_scope(|| {
  131. tracing::event!(Level::DEBUG, {}, "my tracing::event!");
  132. });
  133. });
  134. handle.assert_finished();
  135. }
  136. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  137. #[test]
  138. fn new_span_after_event() {
  139. let (subscriber, handle) = subscriber::mock()
  140. .enter(span::mock().named("foo"))
  141. .event(event::mock())
  142. .exit(span::mock().named("foo"))
  143. .drop_span(span::mock().named("foo"))
  144. .enter(span::mock().named("bar"))
  145. .exit(span::mock().named("bar"))
  146. .drop_span(span::mock().named("bar"))
  147. .done()
  148. .run_with_handle();
  149. with_default(subscriber, || {
  150. tracing::span!(Level::TRACE, "foo").in_scope(|| {
  151. tracing::event!(Level::DEBUG, {}, "my tracing::event!");
  152. });
  153. tracing::span!(Level::TRACE, "bar").in_scope(|| {});
  154. });
  155. handle.assert_finished();
  156. }
  157. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  158. #[test]
  159. fn event_outside_of_span() {
  160. let (subscriber, handle) = subscriber::mock()
  161. .event(event::mock())
  162. .enter(span::mock().named("foo"))
  163. .exit(span::mock().named("foo"))
  164. .drop_span(span::mock().named("foo"))
  165. .done()
  166. .run_with_handle();
  167. with_default(subscriber, || {
  168. tracing::debug!("my tracing::event!");
  169. tracing::span!(Level::TRACE, "foo").in_scope(|| {});
  170. });
  171. handle.assert_finished();
  172. }
  173. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  174. #[test]
  175. fn cloning_a_span_calls_clone_span() {
  176. let (subscriber, handle) = subscriber::mock()
  177. .clone_span(span::mock().named("foo"))
  178. .run_with_handle();
  179. with_default(subscriber, || {
  180. let span = tracing::span!(Level::TRACE, "foo");
  181. // Allow the "redundant" `.clone` since it is used to call into the `.clone_span` hook.
  182. #[allow(clippy::redundant_clone)]
  183. let _span2 = span.clone();
  184. });
  185. handle.assert_finished();
  186. }
  187. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  188. #[test]
  189. fn drop_span_when_exiting_dispatchers_context() {
  190. let (subscriber, handle) = subscriber::mock()
  191. .clone_span(span::mock().named("foo"))
  192. .drop_span(span::mock().named("foo"))
  193. .drop_span(span::mock().named("foo"))
  194. .run_with_handle();
  195. with_default(subscriber, || {
  196. let span = tracing::span!(Level::TRACE, "foo");
  197. let _span2 = span.clone();
  198. drop(span);
  199. });
  200. handle.assert_finished();
  201. }
  202. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  203. #[test]
  204. fn clone_and_drop_span_always_go_to_the_subscriber_that_tagged_the_span() {
  205. let (subscriber1, handle1) = subscriber::mock()
  206. .enter(span::mock().named("foo"))
  207. .exit(span::mock().named("foo"))
  208. .clone_span(span::mock().named("foo"))
  209. .enter(span::mock().named("foo"))
  210. .exit(span::mock().named("foo"))
  211. .drop_span(span::mock().named("foo"))
  212. .drop_span(span::mock().named("foo"))
  213. .run_with_handle();
  214. let subscriber2 = subscriber::mock().done().run();
  215. let foo = with_default(subscriber1, || {
  216. let foo = tracing::span!(Level::TRACE, "foo");
  217. foo.in_scope(|| {});
  218. foo
  219. });
  220. // Even though we enter subscriber 2's context, the subscriber that
  221. // tagged the span should see the enter/exit.
  222. with_default(subscriber2, move || {
  223. let foo2 = foo.clone();
  224. foo.in_scope(|| {});
  225. drop(foo);
  226. drop(foo2);
  227. });
  228. handle1.assert_finished();
  229. }
  230. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  231. #[test]
  232. fn span_closes_when_exited() {
  233. let (subscriber, handle) = subscriber::mock()
  234. .enter(span::mock().named("foo"))
  235. .exit(span::mock().named("foo"))
  236. .drop_span(span::mock().named("foo"))
  237. .done()
  238. .run_with_handle();
  239. with_default(subscriber, || {
  240. let foo = tracing::span!(Level::TRACE, "foo");
  241. foo.in_scope(|| {});
  242. drop(foo);
  243. });
  244. handle.assert_finished();
  245. }
  246. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  247. #[test]
  248. fn enter() {
  249. let (subscriber, handle) = subscriber::mock()
  250. .enter(span::mock().named("foo"))
  251. .event(event::mock())
  252. .exit(span::mock().named("foo"))
  253. .drop_span(span::mock().named("foo"))
  254. .done()
  255. .run_with_handle();
  256. with_default(subscriber, || {
  257. let foo = tracing::span!(Level::TRACE, "foo");
  258. let _enter = foo.enter();
  259. tracing::debug!("dropping guard...");
  260. });
  261. handle.assert_finished();
  262. }
  263. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  264. #[test]
  265. fn entered() {
  266. let (subscriber, handle) = subscriber::mock()
  267. .enter(span::mock().named("foo"))
  268. .event(event::mock())
  269. .exit(span::mock().named("foo"))
  270. .drop_span(span::mock().named("foo"))
  271. .done()
  272. .run_with_handle();
  273. with_default(subscriber, || {
  274. let _span = tracing::span!(Level::TRACE, "foo").entered();
  275. tracing::debug!("dropping guard...");
  276. });
  277. handle.assert_finished();
  278. }
  279. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  280. #[test]
  281. fn entered_api() {
  282. let (subscriber, handle) = subscriber::mock()
  283. .enter(span::mock().named("foo"))
  284. .event(event::mock())
  285. .exit(span::mock().named("foo"))
  286. .drop_span(span::mock().named("foo"))
  287. .done()
  288. .run_with_handle();
  289. with_default(subscriber, || {
  290. let span = tracing::span!(Level::TRACE, "foo").entered();
  291. let _derefs_to_span = span.id();
  292. tracing::debug!("exiting span...");
  293. let _: Span = span.exit();
  294. });
  295. handle.assert_finished();
  296. }
  297. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  298. #[test]
  299. fn moved_field() {
  300. let (subscriber, handle) = subscriber::mock()
  301. .new_span(
  302. span::mock().named("foo").with_field(
  303. field::mock("bar")
  304. .with_value(&display("hello from my span"))
  305. .only(),
  306. ),
  307. )
  308. .enter(span::mock().named("foo"))
  309. .exit(span::mock().named("foo"))
  310. .drop_span(span::mock().named("foo"))
  311. .done()
  312. .run_with_handle();
  313. with_default(subscriber, || {
  314. let from = "my span";
  315. let span = tracing::span!(
  316. Level::TRACE,
  317. "foo",
  318. bar = display(format!("hello from {}", from))
  319. );
  320. span.in_scope(|| {});
  321. });
  322. handle.assert_finished();
  323. }
  324. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  325. #[test]
  326. fn dotted_field_name() {
  327. let (subscriber, handle) = subscriber::mock()
  328. .new_span(
  329. span::mock()
  330. .named("foo")
  331. .with_field(field::mock("fields.bar").with_value(&true).only()),
  332. )
  333. .done()
  334. .run_with_handle();
  335. with_default(subscriber, || {
  336. tracing::span!(Level::TRACE, "foo", fields.bar = true);
  337. });
  338. handle.assert_finished();
  339. }
  340. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  341. #[test]
  342. fn borrowed_field() {
  343. let (subscriber, handle) = subscriber::mock()
  344. .new_span(
  345. span::mock().named("foo").with_field(
  346. field::mock("bar")
  347. .with_value(&display("hello from my span"))
  348. .only(),
  349. ),
  350. )
  351. .enter(span::mock().named("foo"))
  352. .exit(span::mock().named("foo"))
  353. .drop_span(span::mock().named("foo"))
  354. .done()
  355. .run_with_handle();
  356. with_default(subscriber, || {
  357. let from = "my span";
  358. let mut message = format!("hello from {}", from);
  359. let span = tracing::span!(Level::TRACE, "foo", bar = display(&message));
  360. span.in_scope(|| {
  361. message.insert_str(10, " inside");
  362. });
  363. });
  364. handle.assert_finished();
  365. }
  366. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  367. #[test]
  368. // If emitting log instrumentation, this gets moved anyway, breaking the test.
  369. #[cfg(not(feature = "log"))]
  370. fn move_field_out_of_struct() {
  371. use tracing::field::debug;
  372. #[derive(Debug)]
  373. struct Position {
  374. x: f32,
  375. y: f32,
  376. }
  377. let pos = Position {
  378. x: 3.234,
  379. y: -1.223,
  380. };
  381. let (subscriber, handle) = subscriber::mock()
  382. .new_span(
  383. span::mock().named("foo").with_field(
  384. field::mock("x")
  385. .with_value(&debug(3.234))
  386. .and(field::mock("y").with_value(&debug(-1.223)))
  387. .only(),
  388. ),
  389. )
  390. .new_span(
  391. span::mock()
  392. .named("bar")
  393. .with_field(field::mock("position").with_value(&debug(&pos)).only()),
  394. )
  395. .run_with_handle();
  396. with_default(subscriber, || {
  397. let pos = Position {
  398. x: 3.234,
  399. y: -1.223,
  400. };
  401. let foo = tracing::span!(Level::TRACE, "foo", x = debug(pos.x), y = debug(pos.y));
  402. let bar = tracing::span!(Level::TRACE, "bar", position = debug(pos));
  403. foo.in_scope(|| {});
  404. bar.in_scope(|| {});
  405. });
  406. handle.assert_finished();
  407. }
  408. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  409. #[test]
  410. fn float_values() {
  411. let (subscriber, handle) = subscriber::mock()
  412. .new_span(
  413. span::mock().named("foo").with_field(
  414. field::mock("x")
  415. .with_value(&3.234)
  416. .and(field::mock("y").with_value(&-1.223))
  417. .only(),
  418. ),
  419. )
  420. .run_with_handle();
  421. with_default(subscriber, || {
  422. let foo = tracing::span!(Level::TRACE, "foo", x = 3.234, y = -1.223);
  423. foo.in_scope(|| {});
  424. });
  425. handle.assert_finished();
  426. }
  427. // TODO(#1138): determine a new syntax for uninitialized span fields, and
  428. // re-enable these.
  429. /*
  430. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  431. #[test]
  432. fn add_field_after_new_span() {
  433. let (subscriber, handle) = subscriber::mock()
  434. .new_span(
  435. span::mock()
  436. .named("foo")
  437. .with_field(field::mock("bar").with_value(&5)
  438. .and(field::mock("baz").with_value).only()),
  439. )
  440. .record(
  441. span::mock().named("foo"),
  442. field::mock("baz").with_value(&true).only(),
  443. )
  444. .enter(span::mock().named("foo"))
  445. .exit(span::mock().named("foo"))
  446. .drop_span(span::mock().named("foo"))
  447. .done()
  448. .run_with_handle();
  449. with_default(subscriber, || {
  450. let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false);
  451. span.record("baz", &true);
  452. span.in_scope(|| {})
  453. });
  454. handle.assert_finished();
  455. }
  456. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  457. #[test]
  458. fn add_fields_only_after_new_span() {
  459. let (subscriber, handle) = subscriber::mock()
  460. .new_span(span::mock().named("foo"))
  461. .record(
  462. span::mock().named("foo"),
  463. field::mock("bar").with_value(&5).only(),
  464. )
  465. .record(
  466. span::mock().named("foo"),
  467. field::mock("baz").with_value(&true).only(),
  468. )
  469. .enter(span::mock().named("foo"))
  470. .exit(span::mock().named("foo"))
  471. .drop_span(span::mock().named("foo"))
  472. .done()
  473. .run_with_handle();
  474. with_default(subscriber, || {
  475. let span = tracing::span!(Level::TRACE, "foo", bar = _, baz = _);
  476. span.record("bar", &5);
  477. span.record("baz", &true);
  478. span.in_scope(|| {})
  479. });
  480. handle.assert_finished();
  481. }
  482. */
  483. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  484. #[test]
  485. fn record_new_value_for_field() {
  486. let (subscriber, handle) = subscriber::mock()
  487. .new_span(
  488. span::mock().named("foo").with_field(
  489. field::mock("bar")
  490. .with_value(&5)
  491. .and(field::mock("baz").with_value(&false))
  492. .only(),
  493. ),
  494. )
  495. .record(
  496. span::mock().named("foo"),
  497. field::mock("baz").with_value(&true).only(),
  498. )
  499. .enter(span::mock().named("foo"))
  500. .exit(span::mock().named("foo"))
  501. .drop_span(span::mock().named("foo"))
  502. .done()
  503. .run_with_handle();
  504. with_default(subscriber, || {
  505. let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false);
  506. span.record("baz", &true);
  507. span.in_scope(|| {})
  508. });
  509. handle.assert_finished();
  510. }
  511. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  512. #[test]
  513. fn record_new_values_for_fields() {
  514. let (subscriber, handle) = subscriber::mock()
  515. .new_span(
  516. span::mock().named("foo").with_field(
  517. field::mock("bar")
  518. .with_value(&4)
  519. .and(field::mock("baz").with_value(&false))
  520. .only(),
  521. ),
  522. )
  523. .record(
  524. span::mock().named("foo"),
  525. field::mock("bar").with_value(&5).only(),
  526. )
  527. .record(
  528. span::mock().named("foo"),
  529. field::mock("baz").with_value(&true).only(),
  530. )
  531. .enter(span::mock().named("foo"))
  532. .exit(span::mock().named("foo"))
  533. .drop_span(span::mock().named("foo"))
  534. .done()
  535. .run_with_handle();
  536. with_default(subscriber, || {
  537. let span = tracing::span!(Level::TRACE, "foo", bar = 4, baz = false);
  538. span.record("bar", &5);
  539. span.record("baz", &true);
  540. span.in_scope(|| {})
  541. });
  542. handle.assert_finished();
  543. }
  544. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  545. #[test]
  546. fn new_span_with_target_and_log_level() {
  547. let (subscriber, handle) = subscriber::mock()
  548. .new_span(
  549. span::mock()
  550. .named("foo")
  551. .with_target("app_span")
  552. .at_level(Level::DEBUG),
  553. )
  554. .done()
  555. .run_with_handle();
  556. with_default(subscriber, || {
  557. tracing::span!(target: "app_span", Level::DEBUG, "foo");
  558. });
  559. handle.assert_finished();
  560. }
  561. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  562. #[test]
  563. fn explicit_root_span_is_root() {
  564. let (subscriber, handle) = subscriber::mock()
  565. .new_span(span::mock().named("foo").with_explicit_parent(None))
  566. .done()
  567. .run_with_handle();
  568. with_default(subscriber, || {
  569. tracing::span!(parent: None, Level::TRACE, "foo");
  570. });
  571. handle.assert_finished();
  572. }
  573. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  574. #[test]
  575. fn explicit_root_span_is_root_regardless_of_ctx() {
  576. let (subscriber, handle) = subscriber::mock()
  577. .new_span(span::mock().named("foo"))
  578. .enter(span::mock().named("foo"))
  579. .new_span(span::mock().named("bar").with_explicit_parent(None))
  580. .exit(span::mock().named("foo"))
  581. .done()
  582. .run_with_handle();
  583. with_default(subscriber, || {
  584. tracing::span!(Level::TRACE, "foo").in_scope(|| {
  585. tracing::span!(parent: None, Level::TRACE, "bar");
  586. })
  587. });
  588. handle.assert_finished();
  589. }
  590. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  591. #[test]
  592. fn explicit_child() {
  593. let (subscriber, handle) = subscriber::mock()
  594. .new_span(span::mock().named("foo"))
  595. .new_span(span::mock().named("bar").with_explicit_parent(Some("foo")))
  596. .done()
  597. .run_with_handle();
  598. with_default(subscriber, || {
  599. let foo = tracing::span!(Level::TRACE, "foo");
  600. tracing::span!(parent: foo.id(), Level::TRACE, "bar");
  601. });
  602. handle.assert_finished();
  603. }
  604. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  605. #[test]
  606. fn explicit_child_at_levels() {
  607. let (subscriber, handle) = subscriber::mock()
  608. .new_span(span::mock().named("foo"))
  609. .new_span(span::mock().named("a").with_explicit_parent(Some("foo")))
  610. .new_span(span::mock().named("b").with_explicit_parent(Some("foo")))
  611. .new_span(span::mock().named("c").with_explicit_parent(Some("foo")))
  612. .new_span(span::mock().named("d").with_explicit_parent(Some("foo")))
  613. .new_span(span::mock().named("e").with_explicit_parent(Some("foo")))
  614. .done()
  615. .run_with_handle();
  616. with_default(subscriber, || {
  617. let foo = tracing::span!(Level::TRACE, "foo");
  618. tracing::trace_span!(parent: foo.id(), "a");
  619. tracing::debug_span!(parent: foo.id(), "b");
  620. tracing::info_span!(parent: foo.id(), "c");
  621. tracing::warn_span!(parent: foo.id(), "d");
  622. tracing::error_span!(parent: foo.id(), "e");
  623. });
  624. handle.assert_finished();
  625. }
  626. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  627. #[test]
  628. fn explicit_child_regardless_of_ctx() {
  629. let (subscriber, handle) = subscriber::mock()
  630. .new_span(span::mock().named("foo"))
  631. .new_span(span::mock().named("bar"))
  632. .enter(span::mock().named("bar"))
  633. .new_span(span::mock().named("baz").with_explicit_parent(Some("foo")))
  634. .exit(span::mock().named("bar"))
  635. .done()
  636. .run_with_handle();
  637. with_default(subscriber, || {
  638. let foo = tracing::span!(Level::TRACE, "foo");
  639. tracing::span!(Level::TRACE, "bar")
  640. .in_scope(|| tracing::span!(parent: foo.id(), Level::TRACE, "baz"))
  641. });
  642. handle.assert_finished();
  643. }
  644. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  645. #[test]
  646. fn contextual_root() {
  647. let (subscriber, handle) = subscriber::mock()
  648. .new_span(span::mock().named("foo").with_contextual_parent(None))
  649. .done()
  650. .run_with_handle();
  651. with_default(subscriber, || {
  652. tracing::span!(Level::TRACE, "foo");
  653. });
  654. handle.assert_finished();
  655. }
  656. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  657. #[test]
  658. fn contextual_child() {
  659. let (subscriber, handle) = subscriber::mock()
  660. .new_span(span::mock().named("foo"))
  661. .enter(span::mock().named("foo"))
  662. .new_span(
  663. span::mock()
  664. .named("bar")
  665. .with_contextual_parent(Some("foo")),
  666. )
  667. .exit(span::mock().named("foo"))
  668. .done()
  669. .run_with_handle();
  670. with_default(subscriber, || {
  671. tracing::span!(Level::TRACE, "foo").in_scope(|| {
  672. tracing::span!(Level::TRACE, "bar");
  673. })
  674. });
  675. handle.assert_finished();
  676. }
  677. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  678. #[test]
  679. fn display_shorthand() {
  680. let (subscriber, handle) = subscriber::mock()
  681. .new_span(
  682. span::mock().named("my_span").with_field(
  683. field::mock("my_field")
  684. .with_value(&display("hello world"))
  685. .only(),
  686. ),
  687. )
  688. .done()
  689. .run_with_handle();
  690. with_default(subscriber, || {
  691. tracing::span!(Level::TRACE, "my_span", my_field = %"hello world");
  692. });
  693. handle.assert_finished();
  694. }
  695. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  696. #[test]
  697. fn debug_shorthand() {
  698. let (subscriber, handle) = subscriber::mock()
  699. .new_span(
  700. span::mock().named("my_span").with_field(
  701. field::mock("my_field")
  702. .with_value(&debug("hello world"))
  703. .only(),
  704. ),
  705. )
  706. .done()
  707. .run_with_handle();
  708. with_default(subscriber, || {
  709. tracing::span!(Level::TRACE, "my_span", my_field = ?"hello world");
  710. });
  711. handle.assert_finished();
  712. }
  713. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
  714. #[test]
  715. fn both_shorthands() {
  716. let (subscriber, handle) = subscriber::mock()
  717. .new_span(
  718. span::mock().named("my_span").with_field(
  719. field::mock("display_field")
  720. .with_value(&display("hello world"))
  721. .and(field::mock("debug_field").with_value(&debug("hello world")))
  722. .only(),
  723. ),
  724. )
  725. .done()
  726. .run_with_handle();
  727. with_default(subscriber, || {
  728. tracing::span!(Level::TRACE, "my_span", display_field = %"hello world", debug_field = ?"hello world");
  729. });
  730. handle.assert_finished();
  731. }