trace_ut.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. #include "all.h"
  2. #include <library/cpp/lwtrace/protos/lwtrace.pb.h>
  3. #include <library/cpp/testing/unittest/registar.h>
  4. #include <google/protobuf/text_format.h>
  5. enum ESimpleEnum {
  6. ValueA,
  7. ValueB,
  8. };
  9. enum class EEnumClass {
  10. ValueC,
  11. ValueD,
  12. };
  13. #define LWTRACE_UT_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \
  14. PROBE(NoParam, GROUPS("Group"), TYPES(), NAMES()) \
  15. PROBE(IntParam, GROUPS("Group"), TYPES(ui32), NAMES("value")) \
  16. PROBE(StringParam, GROUPS("Group"), TYPES(TString), NAMES("value")) \
  17. PROBE(SymbolParam, GROUPS("Group"), TYPES(NLWTrace::TSymbol), NAMES("symbol")) \
  18. PROBE(CheckParam, GROUPS("Group"), TYPES(NLWTrace::TCheck), NAMES("value")) \
  19. PROBE(EnumParams, GROUPS("Group"), TYPES(ESimpleEnum, EEnumClass), NAMES("simpleEnum", "enumClass")) \
  20. PROBE(InstantParam, GROUPS("Group"), TYPES(TInstant), NAMES("value")) \
  21. PROBE(DurationParam, GROUPS("Group"), TYPES(TDuration), NAMES("value")) \
  22. PROBE(ProtoEnum, GROUPS("Group"), TYPES(NLWTrace::EOperatorType), NAMES("value")) \
  23. PROBE(IntIntParams, GROUPS("Group"), TYPES(ui32, ui64), NAMES("value1", "value2")) \
  24. /**/
  25. LWTRACE_DECLARE_PROVIDER(LWTRACE_UT_PROVIDER)
  26. LWTRACE_DEFINE_PROVIDER(LWTRACE_UT_PROVIDER)
  27. LWTRACE_USING(LWTRACE_UT_PROVIDER)
  28. using namespace NLWTrace;
  29. Y_UNIT_TEST_SUITE(LWTraceTrace) {
  30. #ifndef LWTRACE_DISABLE
  31. Y_UNIT_TEST(Smoke) {
  32. TManager mngr(*Singleton<TProbeRegistry>(), true);
  33. TQuery q;
  34. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  35. Blocks {
  36. ProbeDesc {
  37. Name: "NoParam"
  38. Provider: "LWTRACE_UT_PROVIDER"
  39. }
  40. Action {
  41. LogAction { }
  42. }
  43. }
  44. )END",
  45. &q);
  46. UNIT_ASSERT(parsed);
  47. mngr.New("Query1", q);
  48. LWPROBE(NoParam);
  49. struct {
  50. void Push(TThread::TId, const TLogItem& item) {
  51. UNIT_ASSERT(TString(item.Probe->Event.Name) == "NoParam");
  52. }
  53. } reader;
  54. mngr.ReadLog("Query1", reader);
  55. LWPROBE(EnumParams, ValueA, EEnumClass::ValueC);
  56. LWPROBE(InstantParam, TInstant::Seconds(42));
  57. LWPROBE(DurationParam, TDuration::MilliSeconds(146));
  58. LWPROBE(ProtoEnum, OT_EQ);
  59. }
  60. Y_UNIT_TEST(Predicate) {
  61. TManager mngr(*Singleton<TProbeRegistry>(), true);
  62. TQuery q;
  63. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  64. Blocks {
  65. ProbeDesc {
  66. Name: "IntParam"
  67. Provider: "LWTRACE_UT_PROVIDER"
  68. }
  69. Predicate {
  70. Operators {
  71. Type: OT_NE
  72. Argument { Param: "value" }
  73. Argument { Value: "1" }
  74. }
  75. }
  76. Action {
  77. LogAction { }
  78. }
  79. }
  80. )END", &q);
  81. UNIT_ASSERT(parsed);
  82. mngr.New("QueryName", q);
  83. LWPROBE(IntParam, 3);
  84. LWPROBE(IntParam, 1);
  85. LWPROBE(IntParam, 4);
  86. LWPROBE(IntParam, 1);
  87. LWPROBE(IntParam, 1);
  88. LWPROBE(IntParam, 5);
  89. struct {
  90. ui32 expected = 3;
  91. ui32 logsCount = 0;
  92. void Push(TThread::TId, const TLogItem& item) {
  93. UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntParam");
  94. ui32 value = item.GetParam("value").GetParam().Get<ui32>();
  95. UNIT_ASSERT(value == expected);
  96. expected++;
  97. logsCount++;
  98. }
  99. } reader;
  100. mngr.ReadLog("QueryName", reader);
  101. UNIT_ASSERT(reader.logsCount == 3);
  102. }
  103. Y_UNIT_TEST(StatementAction) {
  104. TManager mngr(*Singleton<TProbeRegistry>(), true);
  105. TQuery q;
  106. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  107. Blocks {
  108. ProbeDesc {
  109. Name: "IntParam"
  110. Provider: "LWTRACE_UT_PROVIDER"
  111. }
  112. Action {
  113. StatementAction {
  114. Type: ST_INC
  115. Argument { Variable: "varInc" }
  116. }
  117. }
  118. Action {
  119. StatementAction {
  120. Type: ST_DEC
  121. Argument { Variable: "varDec" }
  122. }
  123. }
  124. Action {
  125. StatementAction {
  126. Type: ST_MOV
  127. Argument { Variable: "varMov" }
  128. Argument { Value: "3" }
  129. }
  130. }
  131. Action {
  132. StatementAction {
  133. Type: ST_ADD_EQ
  134. Argument { Variable: "varAddEq" }
  135. Argument { Value: "2" }
  136. }
  137. }
  138. Action {
  139. StatementAction {
  140. Type: ST_ADD_EQ
  141. Argument { Variable: "varAddEq" }
  142. Argument { Value: "3" }
  143. }
  144. }
  145. Action {
  146. StatementAction {
  147. Type: ST_SUB_EQ
  148. Argument { Variable: "varSubEq" }
  149. Argument { Value: "5" }
  150. }
  151. }
  152. Action {
  153. StatementAction {
  154. Type: ST_ADD
  155. Argument { Variable: "varAdd" }
  156. Argument { Value: "3" }
  157. Argument { Value: "2" }
  158. }
  159. }
  160. Action {
  161. StatementAction {
  162. Type: ST_SUB
  163. Argument { Variable: "varSub" }
  164. Argument { Value: "3" }
  165. Argument { Value: "2" }
  166. }
  167. }
  168. Action {
  169. StatementAction {
  170. Type: ST_MUL
  171. Argument { Variable: "varMul" }
  172. Argument { Value: "6" }
  173. Argument { Value: "2" }
  174. }
  175. }
  176. Action {
  177. StatementAction {
  178. Type: ST_DIV
  179. Argument { Variable: "varDiv" }
  180. Argument { Value: "6" }
  181. Argument { Value: "2" }
  182. }
  183. }
  184. Action {
  185. StatementAction {
  186. Type: ST_MOD
  187. Argument { Variable: "varMod" }
  188. Argument { Value: "17" }
  189. Argument { Value: "5" }
  190. }
  191. }
  192. }
  193. Blocks {
  194. ProbeDesc {
  195. Name: "IntParam"
  196. Provider: "LWTRACE_UT_PROVIDER"
  197. }
  198. Predicate {
  199. Operators {
  200. Type: OT_EQ
  201. Argument { Variable: "varInc" }
  202. Argument { Value: "1" }
  203. }
  204. Operators {
  205. Type: OT_EQ
  206. Argument { Variable: "varDec" }
  207. Argument { Value: "-1" }
  208. }
  209. Operators {
  210. Type: OT_EQ
  211. Argument { Variable: "varMov" }
  212. Argument { Value: "3" }
  213. }
  214. Operators {
  215. Type: OT_EQ
  216. Argument { Variable: "varAddEq" }
  217. Argument { Value: "5" }
  218. }
  219. Operators {
  220. Type: OT_EQ
  221. Argument { Variable: "varSubEq" }
  222. Argument { Value: "-5" }
  223. }
  224. Operators {
  225. Type: OT_EQ
  226. Argument { Variable: "varAdd" }
  227. Argument { Value: "5" }
  228. }
  229. Operators {
  230. Type: OT_EQ
  231. Argument { Variable: "varSub" }
  232. Argument { Value: "1" }
  233. }
  234. Operators {
  235. Type: OT_EQ
  236. Argument { Variable: "varMul" }
  237. Argument { Value: "12" }
  238. }
  239. Operators {
  240. Type: OT_EQ
  241. Argument { Variable: "varDiv" }
  242. Argument { Value: "3" }
  243. }
  244. Operators {
  245. Type: OT_EQ
  246. Argument { Variable: "varMod" }
  247. Argument { Value: "2" }
  248. }
  249. }
  250. Action {
  251. LogAction { }
  252. }
  253. }
  254. )END", &q);
  255. UNIT_ASSERT(parsed);
  256. mngr.New("QueryName", q);
  257. LWPROBE(IntParam, 1);
  258. LWPROBE(IntParam, 2);
  259. struct {
  260. int logsCount = 0;
  261. void Push(TThread::TId, const TLogItem& item) {
  262. UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntParam");
  263. ui32 value = item.GetParam("value").GetParam().Get<ui32>();
  264. UNIT_ASSERT(value == 1);
  265. logsCount++;
  266. }
  267. } reader;
  268. mngr.ReadLog("QueryName", reader);
  269. UNIT_ASSERT(reader.logsCount == 1);
  270. }
  271. Y_UNIT_TEST(StatementActionWithParams) {
  272. TManager mngr(*Singleton<TProbeRegistry>(), true);
  273. TQuery q;
  274. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  275. Blocks {
  276. ProbeDesc {
  277. Name: "IntIntParams"
  278. Provider: "LWTRACE_UT_PROVIDER"
  279. }
  280. Action {
  281. StatementAction {
  282. Type: ST_MOV
  283. Argument { Variable: "varMov" }
  284. Argument { Param: "value1" }
  285. }
  286. }
  287. Action {
  288. StatementAction {
  289. Type: ST_ADD_EQ
  290. Argument { Variable: "varAddEq" }
  291. Argument { Param: "value1" }
  292. }
  293. }
  294. Action {
  295. StatementAction {
  296. Type: ST_SUB_EQ
  297. Argument { Variable: "varSubEq" }
  298. Argument { Param: "value1" }
  299. }
  300. }
  301. Action {
  302. StatementAction {
  303. Type: ST_ADD
  304. Argument { Variable: "varAdd" }
  305. Argument { Param: "value1" }
  306. Argument { Param: "value2" }
  307. }
  308. }
  309. Action {
  310. StatementAction {
  311. Type: ST_SUB
  312. Argument { Variable: "varSub" }
  313. Argument { Param: "value1" }
  314. Argument { Param: "value2" }
  315. }
  316. }
  317. Action {
  318. StatementAction {
  319. Type: ST_MUL
  320. Argument { Variable: "varMul" }
  321. Argument { Param: "value1" }
  322. Argument { Param: "value2" }
  323. }
  324. }
  325. Action {
  326. StatementAction {
  327. Type: ST_DIV
  328. Argument { Variable: "varDiv" }
  329. Argument { Param: "value1" }
  330. Argument { Param: "value2" }
  331. }
  332. }
  333. Action {
  334. StatementAction {
  335. Type: ST_MOD
  336. Argument { Variable: "varMod" }
  337. Argument { Param: "value1" }
  338. Argument { Param: "value2" }
  339. }
  340. }
  341. }
  342. Blocks {
  343. ProbeDesc {
  344. Name: "IntIntParams"
  345. Provider: "LWTRACE_UT_PROVIDER"
  346. }
  347. Predicate {
  348. Operators {
  349. Type: OT_EQ
  350. Argument { Variable: "varMov" }
  351. Argument { Param: "value1" }
  352. }
  353. Operators {
  354. Type: OT_EQ
  355. Argument { Variable: "varAddEq" }
  356. Argument { Param: "value1" }
  357. }
  358. Operators {
  359. Type: OT_EQ
  360. Argument { Variable: "varSubEq" }
  361. Argument { Value: "-22" }
  362. }
  363. Operators {
  364. Type: OT_EQ
  365. Argument { Variable: "varAdd" }
  366. Argument { Value: "25" }
  367. }
  368. Operators {
  369. Type: OT_EQ
  370. Argument { Variable: "varSub" }
  371. Argument { Value: "19" }
  372. }
  373. Operators {
  374. Type: OT_EQ
  375. Argument { Variable: "varMul" }
  376. Argument { Value: "66" }
  377. }
  378. Operators {
  379. Type: OT_EQ
  380. Argument { Variable: "varDiv" }
  381. Argument { Value: "7" }
  382. }
  383. Operators {
  384. Type: OT_EQ
  385. Argument { Variable: "varMod" }
  386. Argument { Value: "1" }
  387. }
  388. }
  389. Action {
  390. LogAction { }
  391. }
  392. }
  393. )END", &q);
  394. UNIT_ASSERT(parsed);
  395. mngr.New("QueryName", q);
  396. LWPROBE(IntIntParams, 22, 3);
  397. struct {
  398. int logsCount = 0;
  399. void Push(TThread::TId, const TLogItem& item) {
  400. UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntIntParams");
  401. logsCount++;
  402. }
  403. } reader;
  404. mngr.ReadLog("QueryName", reader);
  405. UNIT_ASSERT(reader.logsCount == 1);
  406. }
  407. Y_UNIT_TEST(PerThreadLogSize) {
  408. TManager mngr(*Singleton<TProbeRegistry>(), true);
  409. TQuery q;
  410. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  411. PerThreadLogSize: 3
  412. Blocks {
  413. ProbeDesc {
  414. Name: "IntParam"
  415. Provider: "LWTRACE_UT_PROVIDER"
  416. }
  417. Action {
  418. LogAction { }
  419. }
  420. }
  421. )END", &q);
  422. UNIT_ASSERT(parsed);
  423. mngr.New("QueryRandom", q);
  424. LWPROBE(IntParam, 1);
  425. LWPROBE(IntParam, 2);
  426. LWPROBE(IntParam, 3);
  427. LWPROBE(IntParam, 4);
  428. struct {
  429. ui32 logsCount = 0;
  430. ui32 expected = 2;
  431. void Push(TThread::TId, const TLogItem& item) {
  432. UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntParam");
  433. ui32 value = item.GetParam("value").GetParam().Get<ui32>();
  434. UNIT_ASSERT(value == expected);
  435. logsCount++;
  436. expected++;
  437. }
  438. } reader;
  439. mngr.ReadLog("QueryRandom", reader);
  440. UNIT_ASSERT(reader.logsCount == 3);
  441. }
  442. Y_UNIT_TEST(CustomAction) {
  443. static ui32 nCustomActionsCalls = 0;
  444. class TMyActionExecutor: public TCustomActionExecutor {
  445. public:
  446. TMyActionExecutor(TProbe* probe, const TCustomAction&, TSession*)
  447. : TCustomActionExecutor(probe, false /* not destructive */)
  448. {}
  449. private:
  450. bool DoExecute(TOrbit&, const TParams& params) override {
  451. (void)params;
  452. nCustomActionsCalls++;
  453. return true;
  454. }
  455. };
  456. TManager mngr(*Singleton<TProbeRegistry>(), true);
  457. mngr.RegisterCustomAction("MyCustomAction", [](TProbe* probe,
  458. const TCustomAction& action,
  459. TSession* session) {
  460. return new TMyActionExecutor(probe, action, session);
  461. }
  462. );
  463. TQuery q;
  464. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  465. Blocks {
  466. ProbeDesc {
  467. Name: "NoParam"
  468. Provider: "LWTRACE_UT_PROVIDER"
  469. }
  470. Action {
  471. CustomAction {
  472. Name: "MyCustomAction"
  473. }
  474. }
  475. }
  476. )END", &q);
  477. UNIT_ASSERT(parsed);
  478. mngr.New("Query1", q);
  479. LWPROBE(NoParam);
  480. UNIT_ASSERT(nCustomActionsCalls == 1);
  481. }
  482. Y_UNIT_TEST(SafeModeSleepException) {
  483. TManager mngr(*Singleton<TProbeRegistry>(), false);
  484. TQuery q;
  485. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  486. Blocks {
  487. ProbeDesc {
  488. Name: "NoParam"
  489. Provider: "LWTRACE_UT_PROVIDER"
  490. }
  491. Action {
  492. SleepAction {
  493. NanoSeconds: 1000000000
  494. }
  495. }
  496. }
  497. )END", &q);
  498. UNIT_ASSERT(parsed);
  499. UNIT_ASSERT_EXCEPTION(mngr.New("QueryName", q), yexception);
  500. }
  501. Y_UNIT_TEST(Sleep) {
  502. TManager mngr(*Singleton<TProbeRegistry>(), true);
  503. TQuery q;
  504. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  505. Blocks {
  506. ProbeDesc {
  507. Name: "NoParam"
  508. Provider: "LWTRACE_UT_PROVIDER"
  509. }
  510. Action {
  511. SleepAction {
  512. NanoSeconds: 1000
  513. }
  514. }
  515. }
  516. )END", &q);
  517. UNIT_ASSERT(parsed);
  518. mngr.New("QueryName", q);
  519. const ui64 sleepTimeNs = 1000; // 1 us
  520. TInstant t0 = Now();
  521. LWPROBE(NoParam);
  522. TInstant t1 = Now();
  523. UNIT_ASSERT(t1.NanoSeconds() - t0.NanoSeconds() >= sleepTimeNs);
  524. }
  525. Y_UNIT_TEST(ProtoEnumTraits) {
  526. using TPbEnumTraits = TParamTraits<EOperatorType>;
  527. TString str;
  528. TPbEnumTraits::ToString(TPbEnumTraits::ToStoreType(OT_EQ), &str);
  529. UNIT_ASSERT_STRINGS_EQUAL(str, "OT_EQ (0)");
  530. }
  531. Y_UNIT_TEST(Track) {
  532. TManager mngr(*Singleton<TProbeRegistry>(), true);
  533. TQuery q;
  534. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  535. Blocks {
  536. ProbeDesc {
  537. Name: "IntParam"
  538. Provider: "LWTRACE_UT_PROVIDER"
  539. }
  540. Action {
  541. RunLogShuttleAction { }
  542. }
  543. }
  544. )END", &q);
  545. UNIT_ASSERT(parsed);
  546. mngr.New("Query1", q);
  547. {
  548. TOrbit orbit;
  549. LWTRACK(IntParam, orbit, 1);
  550. LWTRACK(StringParam, orbit, "str");
  551. }
  552. struct {
  553. void Push(TThread::TId, const TTrackLog& tl) {
  554. UNIT_ASSERT(tl.Items.size() == 2);
  555. UNIT_ASSERT(TString(tl.Items[0].Probe->Event.Name) == "IntParam");
  556. UNIT_ASSERT(TString(tl.Items[1].Probe->Event.Name) == "StringParam");
  557. }
  558. } reader;
  559. mngr.ReadDepot("Query1", reader);
  560. }
  561. Y_UNIT_TEST(ShouldSerializeTracks)
  562. {
  563. TManager manager(*Singleton<TProbeRegistry>(), false);
  564. TOrbit orbit;
  565. TTraceRequest req;
  566. req.SetIsTraced(true);
  567. manager.HandleTraceRequest(req, orbit);
  568. LWTRACK(NoParam, orbit);
  569. LWTRACK(IntParam, orbit, 1);
  570. LWTRACK(StringParam, orbit, "str");
  571. LWTRACK(EnumParams, orbit, ValueA, EEnumClass::ValueC);
  572. LWTRACK(InstantParam, orbit, TInstant::Seconds(42));
  573. LWTRACK(DurationParam, orbit, TDuration::MilliSeconds(146));
  574. LWTRACK(ProtoEnum, orbit, OT_EQ);
  575. LWTRACK(IntIntParams, orbit, 1, 2);
  576. TTraceResponse resp;
  577. orbit.Serialize(0, *resp.MutableTrace());
  578. auto& r = resp.GetTrace();
  579. UNIT_ASSERT_VALUES_EQUAL(8, r.EventsSize());
  580. const auto& p0 = r.GetEvents(0);
  581. UNIT_ASSERT_VALUES_EQUAL("NoParam", p0.GetName());
  582. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p0.GetProvider());
  583. UNIT_ASSERT_VALUES_EQUAL(0 , p0.ParamsSize());
  584. const auto& p1 = r.GetEvents(1);
  585. UNIT_ASSERT_VALUES_EQUAL("IntParam", p1.GetName());
  586. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p1.GetProvider());
  587. UNIT_ASSERT_VALUES_EQUAL(1, p1.GetParams(0).GetUintValue());
  588. const auto& p2 = r.GetEvents(2);
  589. UNIT_ASSERT_VALUES_EQUAL("StringParam", p2.GetName());
  590. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p2.GetProvider());
  591. UNIT_ASSERT_VALUES_EQUAL("str", p2.GetParams(0).GetStrValue());
  592. const auto& p3 = r.GetEvents(3);
  593. UNIT_ASSERT_VALUES_EQUAL("EnumParams", p3.GetName());
  594. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p3.GetProvider());
  595. UNIT_ASSERT_VALUES_EQUAL((ui32)ValueA, p3.GetParams(0).GetIntValue());
  596. UNIT_ASSERT_VALUES_EQUAL((ui32)EEnumClass::ValueC, p3.GetParams(1).GetIntValue());
  597. const auto& p4 = r.GetEvents(4);
  598. UNIT_ASSERT_VALUES_EQUAL("InstantParam", p4.GetName());
  599. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p4.GetProvider());
  600. UNIT_ASSERT_VALUES_EQUAL(42, p4.GetParams(0).GetDoubleValue());
  601. const auto& p5 = r.GetEvents(5);
  602. UNIT_ASSERT_VALUES_EQUAL("DurationParam", p5.GetName());
  603. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p5.GetProvider());
  604. UNIT_ASSERT_VALUES_EQUAL(146, p5.GetParams(0).GetDoubleValue());
  605. const auto& p6 = r.GetEvents(6);
  606. UNIT_ASSERT_VALUES_EQUAL("ProtoEnum", p6.GetName());
  607. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p6.GetProvider());
  608. UNIT_ASSERT_VALUES_EQUAL((int)OT_EQ, p6.GetParams(0).GetIntValue());
  609. const auto& p7 = r.GetEvents(7);
  610. UNIT_ASSERT_VALUES_EQUAL("IntIntParams", p7.GetName());
  611. UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p7.GetProvider());
  612. UNIT_ASSERT_VALUES_EQUAL(1, p7.GetParams(0).GetUintValue());
  613. UNIT_ASSERT_VALUES_EQUAL(2, p7.GetParams(1).GetUintValue());
  614. }
  615. Y_UNIT_TEST(ShouldDeserializeTracks)
  616. {
  617. TManager manager(*Singleton<TProbeRegistry>(), false);
  618. TTraceResponse resp;
  619. auto& r = *resp.MutableTrace()->MutableEvents();
  620. auto& p0 = *r.Add();
  621. p0.SetName("NoParam");
  622. p0.SetProvider("LWTRACE_UT_PROVIDER");
  623. auto& p1 = *r.Add();
  624. p1.SetName("IntParam");
  625. p1.SetProvider("LWTRACE_UT_PROVIDER");
  626. auto& p1param = *p1.MutableParams()->Add();
  627. p1param.SetUintValue(1);
  628. auto& p2 = *r.Add();
  629. p2.SetName("StringParam");
  630. p2.SetProvider("LWTRACE_UT_PROVIDER");
  631. auto& p2param = *p2.MutableParams()->Add();
  632. p2param.SetStrValue("str");
  633. auto& p3 = *r.Add();
  634. p3.SetName("EnumParams");
  635. p3.SetProvider("LWTRACE_UT_PROVIDER");
  636. auto& p3param1 = *p3.MutableParams()->Add();
  637. p3param1.SetUintValue((ui64)EEnumClass::ValueC);
  638. auto& p3param2 = *p3.MutableParams()->Add();
  639. p3param2.SetIntValue((ui64)EEnumClass::ValueC);
  640. auto& p4 = *r.Add();
  641. p4.SetName("InstantParam");
  642. p4.SetProvider("LWTRACE_UT_PROVIDER");
  643. auto& p4param = *p4.MutableParams()->Add();
  644. p4param.SetDoubleValue(42);
  645. auto& p5 = *r.Add();
  646. p5.SetName("DurationParam");
  647. p5.SetProvider("LWTRACE_UT_PROVIDER");
  648. auto& p5param = *p5.MutableParams()->Add();
  649. p5param.SetDoubleValue(146);
  650. auto& p6 = *r.Add();
  651. p6.SetName("ProtoEnum");
  652. p6.SetProvider("LWTRACE_UT_PROVIDER");
  653. auto& p6param = *p6.MutableParams()->Add();
  654. p6param.SetIntValue((i64)OT_EQ);
  655. auto& p7 = *r.Add();
  656. p7.SetName("IntIntParams");
  657. p7.SetProvider("LWTRACE_UT_PROVIDER");
  658. auto& p7param1 = *p7.MutableParams()->Add();
  659. p7param1.SetIntValue(1);
  660. auto& p7param2 = *p7.MutableParams()->Add();
  661. p7param2.SetIntValue(2);
  662. TOrbit orbit;
  663. UNIT_ASSERT_VALUES_EQUAL(
  664. manager.HandleTraceResponse(resp, manager.GetProbesMap(), orbit).IsSuccess,
  665. true);
  666. }
  667. Y_UNIT_TEST(ShouldDeserializeWhatSerialized)
  668. {
  669. TManager manager(*Singleton<TProbeRegistry>(), false);
  670. TOrbit orbit;
  671. TOrbit child;
  672. TTraceRequest req;
  673. req.SetIsTraced(true);
  674. bool traced = manager.HandleTraceRequest(req, orbit);
  675. UNIT_ASSERT(traced);
  676. LWTRACK(NoParam, orbit);
  677. orbit.Fork(child);
  678. LWTRACK(IntParam, orbit, 1);
  679. LWTRACK(IntParam, child, 2);
  680. LWTRACK(StringParam, orbit, "str1");
  681. LWTRACK(StringParam, child, "str2");
  682. LWTRACK(EnumParams, orbit, ValueA, EEnumClass::ValueC);
  683. LWTRACK(InstantParam, orbit, TInstant::Seconds(42));
  684. LWTRACK(DurationParam, orbit, TDuration::MilliSeconds(146));
  685. LWTRACK(ProtoEnum, orbit, OT_EQ);
  686. LWTRACK(IntIntParams, orbit, 1, 2);
  687. orbit.Join(child);
  688. TTraceResponse resp1;
  689. auto& r1 = *resp1.MutableTrace();
  690. orbit.Serialize(0, r1);
  691. UNIT_ASSERT_VALUES_EQUAL(r1.EventsSize(), 12);
  692. TOrbit other;
  693. traced = manager.HandleTraceRequest(req, other);
  694. UNIT_ASSERT(traced);
  695. UNIT_ASSERT_VALUES_EQUAL(
  696. manager.HandleTraceResponse(resp1, manager.GetProbesMap(), other).IsSuccess,
  697. true);
  698. TTraceResponse resp2;
  699. auto& r2 = *resp2.MutableTrace();
  700. other.Serialize(0, r2);
  701. UNIT_ASSERT_VALUES_EQUAL(r2.EventsSize(), 12);
  702. TString proto1;
  703. bool parsed = NProtoBuf::TextFormat::PrintToString(resp1, &proto1);
  704. UNIT_ASSERT(parsed);
  705. TString proto2;
  706. parsed = NProtoBuf::TextFormat::PrintToString(resp2, &proto2);
  707. UNIT_ASSERT(parsed);
  708. UNIT_ASSERT_VALUES_EQUAL(proto1, proto2);
  709. }
  710. Y_UNIT_TEST(TrackForkJoin) {
  711. TManager mngr(*Singleton<TProbeRegistry>(), true);
  712. TQuery q;
  713. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  714. Blocks {
  715. ProbeDesc {
  716. Name: "NoParam"
  717. Provider: "LWTRACE_UT_PROVIDER"
  718. }
  719. Action {
  720. RunLogShuttleAction { }
  721. }
  722. }
  723. )END", &q);
  724. UNIT_ASSERT(parsed);
  725. mngr.New("Query1", q);
  726. {
  727. TOrbit a, b, c, d;
  728. // Graph:
  729. // c
  730. // / \
  731. // b-f-b-j-b
  732. // / \
  733. // a-f-a-f-a-j-a-j-a
  734. // \ /
  735. // d
  736. //
  737. // Merged track:
  738. // a-f(b)-a-f(d)-a-j(d,1)-d-a-j(b,6)-b-f(c)-b-j(c,1)-c-b-a
  739. LWTRACK(NoParam, a);
  740. a.Fork(b);
  741. LWTRACK(IntParam, a, 1);
  742. a.Fork(d);
  743. LWTRACK(IntParam, a, 2);
  744. LWTRACK(IntParam, b, 3);
  745. b.Fork(c);
  746. LWTRACK(IntParam, b, 4);
  747. LWTRACK(IntParam, c, 5);
  748. b.Join(c);
  749. LWTRACK(IntParam, b, 6);
  750. LWTRACK(IntParam, d, 7);
  751. a.Join(d);
  752. LWTRACK(IntParam, a, 8);
  753. a.Join(b);
  754. LWTRACK(IntParam, a, 9);
  755. }
  756. struct {
  757. void Push(TThread::TId, const TTrackLog& tl) {
  758. UNIT_ASSERT(tl.Items.size() == 16);
  759. UNIT_ASSERT(TString(tl.Items[0].Probe->Event.Name) == "NoParam");
  760. UNIT_ASSERT(TString(tl.Items[1].Probe->Event.Name) == "Fork");
  761. UNIT_ASSERT(tl.Items[2].Params.Param[0].Get<ui64>() == 1);
  762. UNIT_ASSERT(TString(tl.Items[3].Probe->Event.Name) == "Fork");
  763. UNIT_ASSERT(tl.Items[4].Params.Param[0].Get<ui64>() == 2);
  764. UNIT_ASSERT(TString(tl.Items[5].Probe->Event.Name) == "Join");
  765. UNIT_ASSERT(tl.Items[6].Params.Param[0].Get<ui64>() == 7);
  766. UNIT_ASSERT(tl.Items[7].Params.Param[0].Get<ui64>() == 8);
  767. UNIT_ASSERT(TString(tl.Items[8].Probe->Event.Name) == "Join");
  768. UNIT_ASSERT(tl.Items[9].Params.Param[0].Get<ui64>() == 3);
  769. UNIT_ASSERT(TString(tl.Items[10].Probe->Event.Name) == "Fork");
  770. UNIT_ASSERT(tl.Items[11].Params.Param[0].Get<ui64>() == 4);
  771. UNIT_ASSERT(TString(tl.Items[12].Probe->Event.Name) == "Join");
  772. UNIT_ASSERT(tl.Items[13].Params.Param[0].Get<ui64>() == 5);
  773. UNIT_ASSERT(tl.Items[14].Params.Param[0].Get<ui64>() == 6);
  774. UNIT_ASSERT(tl.Items[15].Params.Param[0].Get<ui64>() == 9);
  775. }
  776. } reader;
  777. mngr.ReadDepot("Query1", reader);
  778. }
  779. Y_UNIT_TEST(TrackForkError) {
  780. TManager mngr(*Singleton<TProbeRegistry>(), true);
  781. TQuery q;
  782. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  783. Blocks {
  784. ProbeDesc {
  785. Name: "NoParam"
  786. Provider: "LWTRACE_UT_PROVIDER"
  787. }
  788. Action {
  789. RunLogShuttleAction {
  790. MaxTrackLength: 100
  791. }
  792. }
  793. }
  794. )END", &q);
  795. UNIT_ASSERT(parsed);
  796. mngr.New("Query1", q);
  797. constexpr size_t n = (100 + 2) / 3 + 1;
  798. {
  799. TVector<TVector<TOrbit>> span;
  800. while (1) {
  801. TVector<TOrbit> orbit(n);
  802. LWTRACK(NoParam, orbit[0]);
  803. if (!orbit[0].HasShuttles()) {
  804. break;
  805. }
  806. for (size_t i = 1; i < n; i++) {
  807. if (!orbit[i - 1].Fork(orbit[i])) {
  808. break;
  809. }
  810. LWTRACK(IntParam, orbit[i], i);
  811. }
  812. span.emplace_back(std::move(orbit));
  813. }
  814. for (auto& orbit: span) {
  815. for (auto it = orbit.rbegin(); it + 1 != orbit.rend(); it++) {
  816. (it + 1)->Join(*it);
  817. }
  818. }
  819. }
  820. struct {
  821. void Push(TThread::TId, const TTrackLog& tl) {
  822. UNIT_ASSERT(tl.Items.size() == 100);
  823. UNIT_ASSERT(tl.Truncated);
  824. }
  825. } reader;
  826. mngr.ReadDepot("Query1", reader);
  827. }
  828. Y_UNIT_TEST(ShouldResetFailedForksCounterUponShuttleParking) {
  829. TManager mngr(*Singleton<TProbeRegistry>(), true);
  830. TQuery q;
  831. bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
  832. Blocks {
  833. ProbeDesc {
  834. Name: "NoParam"
  835. Provider: "LWTRACE_UT_PROVIDER"
  836. }
  837. Action {
  838. RunLogShuttleAction {
  839. MaxTrackLength: 100
  840. ShuttlesCount: 2
  841. }
  842. }
  843. }
  844. )END", &q);
  845. UNIT_ASSERT(parsed);
  846. mngr.New("Query1", q);
  847. struct {
  848. ui32 cnt = 0;
  849. void Push(TThread::TId, const TTrackLog&) {
  850. ++cnt;
  851. }
  852. } reader;
  853. {
  854. // Run shuttle ans fail fork
  855. TOrbit initial;
  856. TOrbit fork1;
  857. TOrbit fork2;
  858. LWTRACK(NoParam, initial);
  859. UNIT_ASSERT_VALUES_EQUAL(initial.HasShuttles(), true);
  860. UNIT_ASSERT_VALUES_EQUAL(initial.Fork(fork1), true);
  861. LWTRACK(IntParam, fork1, 1);
  862. UNIT_ASSERT_VALUES_EQUAL(fork1.Fork(fork2), false);
  863. initial.Join(fork1);
  864. }
  865. mngr.ReadDepot("Query1", reader);
  866. UNIT_ASSERT_VALUES_EQUAL(reader.cnt, 0);
  867. reader.cnt = 0;
  868. {
  869. TOrbit initial;
  870. LWTRACK(NoParam, initial);
  871. UNIT_ASSERT_VALUES_EQUAL(initial.HasShuttles(), true);
  872. }
  873. mngr.ReadDepot("Query1", reader);
  874. UNIT_ASSERT_VALUES_EQUAL(reader.cnt, 1);
  875. }
  876. #endif // LWTRACE_DISABLE
  877. }