aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/lwtrace/trace_ut.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/lwtrace/trace_ut.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/lwtrace/trace_ut.cpp')
-rw-r--r--library/cpp/lwtrace/trace_ut.cpp880
1 files changed, 880 insertions, 0 deletions
diff --git a/library/cpp/lwtrace/trace_ut.cpp b/library/cpp/lwtrace/trace_ut.cpp
new file mode 100644
index 0000000000..cb03e4fbde
--- /dev/null
+++ b/library/cpp/lwtrace/trace_ut.cpp
@@ -0,0 +1,880 @@
+#include "all.h"
+
+#include <library/cpp/lwtrace/protos/lwtrace.pb.h>
+
+#include <library/cpp/testing/unittest/registar.h>
+
+#include <google/protobuf/text_format.h>
+
+enum ESimpleEnum {
+ ValueA,
+ ValueB,
+};
+
+enum class EEnumClass {
+ ValueC,
+ ValueD,
+};
+
+#define LWTRACE_UT_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \
+ PROBE(NoParam, GROUPS("Group"), TYPES(), NAMES()) \
+ PROBE(IntParam, GROUPS("Group"), TYPES(ui32), NAMES("value")) \
+ PROBE(StringParam, GROUPS("Group"), TYPES(TString), NAMES("value")) \
+ PROBE(SymbolParam, GROUPS("Group"), TYPES(NLWTrace::TSymbol), NAMES("symbol")) \
+ PROBE(CheckParam, GROUPS("Group"), TYPES(NLWTrace::TCheck), NAMES("value")) \
+ PROBE(EnumParams, GROUPS("Group"), TYPES(ESimpleEnum, EEnumClass), NAMES("simpleEnum", "enumClass")) \
+ PROBE(InstantParam, GROUPS("Group"), TYPES(TInstant), NAMES("value")) \
+ PROBE(DurationParam, GROUPS("Group"), TYPES(TDuration), NAMES("value")) \
+ PROBE(ProtoEnum, GROUPS("Group"), TYPES(NLWTrace::EOperatorType), NAMES("value")) \
+ PROBE(IntIntParams, GROUPS("Group"), TYPES(ui32, ui64), NAMES("value1", "value2")) \
+ /**/
+
+LWTRACE_DECLARE_PROVIDER(LWTRACE_UT_PROVIDER)
+LWTRACE_DEFINE_PROVIDER(LWTRACE_UT_PROVIDER)
+LWTRACE_USING(LWTRACE_UT_PROVIDER)
+
+using namespace NLWTrace;
+
+Y_UNIT_TEST_SUITE(LWTraceTrace) {
+#ifndef LWTRACE_DISABLE
+ Y_UNIT_TEST(Smoke) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "NoParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ LogAction { }
+ }
+ }
+ )END",
+ &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("Query1", q);
+ LWPROBE(NoParam);
+ struct {
+ void Push(TThread::TId, const TLogItem& item) {
+ UNIT_ASSERT(TString(item.Probe->Event.Name) == "NoParam");
+ }
+ } reader;
+ mngr.ReadLog("Query1", reader);
+
+ LWPROBE(EnumParams, ValueA, EEnumClass::ValueC);
+ LWPROBE(InstantParam, TInstant::Seconds(42));
+ LWPROBE(DurationParam, TDuration::MilliSeconds(146));
+ LWPROBE(ProtoEnum, OT_EQ);
+ }
+
+ Y_UNIT_TEST(Predicate) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "IntParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Predicate {
+ Operators {
+ Type: OT_NE
+ Argument { Param: "value" }
+ Argument { Value: "1" }
+ }
+ }
+ Action {
+ LogAction { }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("QueryName", q);
+ LWPROBE(IntParam, 3);
+ LWPROBE(IntParam, 1);
+ LWPROBE(IntParam, 4);
+ LWPROBE(IntParam, 1);
+ LWPROBE(IntParam, 1);
+ LWPROBE(IntParam, 5);
+ struct {
+ ui32 expected = 3;
+ ui32 logsCount = 0;
+ void Push(TThread::TId, const TLogItem& item) {
+ UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntParam");
+ ui32 value = item.GetParam("value").GetParam().Get<ui32>();
+ UNIT_ASSERT(value == expected);
+ expected++;
+ logsCount++;
+ }
+ } reader;
+ mngr.ReadLog("QueryName", reader);
+ UNIT_ASSERT(reader.logsCount == 3);
+ }
+
+ Y_UNIT_TEST(StatementAction) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "IntParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ StatementAction {
+ Type: ST_INC
+ Argument { Variable: "varInc" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_DEC
+ Argument { Variable: "varDec" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_MOV
+ Argument { Variable: "varMov" }
+ Argument { Value: "3" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_ADD_EQ
+ Argument { Variable: "varAddEq" }
+ Argument { Value: "2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_ADD_EQ
+ Argument { Variable: "varAddEq" }
+ Argument { Value: "3" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_SUB_EQ
+ Argument { Variable: "varSubEq" }
+ Argument { Value: "5" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_ADD
+ Argument { Variable: "varAdd" }
+ Argument { Value: "3" }
+ Argument { Value: "2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_SUB
+ Argument { Variable: "varSub" }
+ Argument { Value: "3" }
+ Argument { Value: "2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_MUL
+ Argument { Variable: "varMul" }
+ Argument { Value: "6" }
+ Argument { Value: "2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_DIV
+ Argument { Variable: "varDiv" }
+ Argument { Value: "6" }
+ Argument { Value: "2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_MOD
+ Argument { Variable: "varMod" }
+ Argument { Value: "17" }
+ Argument { Value: "5" }
+ }
+ }
+ }
+ Blocks {
+ ProbeDesc {
+ Name: "IntParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Predicate {
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varInc" }
+ Argument { Value: "1" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varDec" }
+ Argument { Value: "-1" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varMov" }
+ Argument { Value: "3" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varAddEq" }
+ Argument { Value: "5" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varSubEq" }
+ Argument { Value: "-5" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varAdd" }
+ Argument { Value: "5" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varSub" }
+ Argument { Value: "1" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varMul" }
+ Argument { Value: "12" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varDiv" }
+ Argument { Value: "3" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varMod" }
+ Argument { Value: "2" }
+ }
+ }
+ Action {
+ LogAction { }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("QueryName", q);
+ LWPROBE(IntParam, 1);
+ LWPROBE(IntParam, 2);
+ struct {
+ int logsCount = 0;
+ void Push(TThread::TId, const TLogItem& item) {
+ UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntParam");
+ ui32 value = item.GetParam("value").GetParam().Get<ui32>();
+ UNIT_ASSERT(value == 1);
+ logsCount++;
+ }
+ } reader;
+ mngr.ReadLog("QueryName", reader);
+ UNIT_ASSERT(reader.logsCount == 1);
+ }
+
+ Y_UNIT_TEST(StatementActionWithParams) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "IntIntParams"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ StatementAction {
+ Type: ST_MOV
+ Argument { Variable: "varMov" }
+ Argument { Param: "value1" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_ADD_EQ
+ Argument { Variable: "varAddEq" }
+ Argument { Param: "value1" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_SUB_EQ
+ Argument { Variable: "varSubEq" }
+ Argument { Param: "value1" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_ADD
+ Argument { Variable: "varAdd" }
+ Argument { Param: "value1" }
+ Argument { Param: "value2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_SUB
+ Argument { Variable: "varSub" }
+ Argument { Param: "value1" }
+ Argument { Param: "value2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_MUL
+ Argument { Variable: "varMul" }
+ Argument { Param: "value1" }
+ Argument { Param: "value2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_DIV
+ Argument { Variable: "varDiv" }
+ Argument { Param: "value1" }
+ Argument { Param: "value2" }
+ }
+ }
+ Action {
+ StatementAction {
+ Type: ST_MOD
+ Argument { Variable: "varMod" }
+ Argument { Param: "value1" }
+ Argument { Param: "value2" }
+ }
+ }
+ }
+ Blocks {
+ ProbeDesc {
+ Name: "IntIntParams"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Predicate {
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varMov" }
+ Argument { Param: "value1" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varAddEq" }
+ Argument { Param: "value1" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varSubEq" }
+ Argument { Value: "-22" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varAdd" }
+ Argument { Value: "25" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varSub" }
+ Argument { Value: "19" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varMul" }
+ Argument { Value: "66" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varDiv" }
+ Argument { Value: "7" }
+ }
+ Operators {
+ Type: OT_EQ
+ Argument { Variable: "varMod" }
+ Argument { Value: "1" }
+ }
+ }
+ Action {
+ LogAction { }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("QueryName", q);
+ LWPROBE(IntIntParams, 22, 3);
+ struct {
+ int logsCount = 0;
+ void Push(TThread::TId, const TLogItem& item) {
+ UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntIntParams");
+ logsCount++;
+ }
+ } reader;
+ mngr.ReadLog("QueryName", reader);
+ UNIT_ASSERT(reader.logsCount == 1);
+ }
+
+ Y_UNIT_TEST(PerThreadLogSize) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ PerThreadLogSize: 3
+ Blocks {
+ ProbeDesc {
+ Name: "IntParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ LogAction { }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("QueryRandom", q);
+ LWPROBE(IntParam, 1);
+ LWPROBE(IntParam, 2);
+ LWPROBE(IntParam, 3);
+ LWPROBE(IntParam, 4);
+ struct {
+ ui32 logsCount = 0;
+ ui32 expected = 2;
+ void Push(TThread::TId, const TLogItem& item) {
+ UNIT_ASSERT(TString(item.Probe->Event.Name) == "IntParam");
+ ui32 value = item.GetParam("value").GetParam().Get<ui32>();
+ UNIT_ASSERT(value == expected);
+ logsCount++;
+ expected++;
+ }
+ } reader;
+ mngr.ReadLog("QueryRandom", reader);
+ UNIT_ASSERT(reader.logsCount == 3);
+ }
+
+ Y_UNIT_TEST(CustomAction) {
+ static ui32 nCustomActionsCalls = 0;
+ class TMyActionExecutor: public TCustomActionExecutor {
+ public:
+ TMyActionExecutor(TProbe* probe, const TCustomAction&, TSession*)
+ : TCustomActionExecutor(probe, false /* not destructive */)
+ {}
+ private:
+ bool DoExecute(TOrbit&, const TParams& params) override {
+ (void)params;
+ nCustomActionsCalls++;
+ return true;
+ }
+ };
+
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ mngr.RegisterCustomAction("MyCustomAction", [](TProbe* probe,
+ const TCustomAction& action,
+ TSession* session) {
+ return new TMyActionExecutor(probe, action, session);
+ }
+ );
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "NoParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ CustomAction {
+ Name: "MyCustomAction"
+ }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("Query1", q);
+ LWPROBE(NoParam);
+ UNIT_ASSERT(nCustomActionsCalls == 1);
+ }
+
+ Y_UNIT_TEST(SafeModeSleepException) {
+ TManager mngr(*Singleton<TProbeRegistry>(), false);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "NoParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ SleepAction {
+ NanoSeconds: 1000000000
+ }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ UNIT_ASSERT_EXCEPTION(mngr.New("QueryName", q), yexception);
+ }
+
+ Y_UNIT_TEST(Sleep) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "NoParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ SleepAction {
+ NanoSeconds: 1000
+ }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("QueryName", q);
+ const ui64 sleepTimeNs = 1000; // 1 us
+
+ TInstant t0 = Now();
+ LWPROBE(NoParam);
+ TInstant t1 = Now();
+ UNIT_ASSERT(t1.NanoSeconds() - t0.NanoSeconds() >= sleepTimeNs);
+ }
+
+ Y_UNIT_TEST(ProtoEnumTraits) {
+ using TPbEnumTraits = TParamTraits<EOperatorType>;
+ TString str;
+ TPbEnumTraits::ToString(TPbEnumTraits::ToStoreType(OT_EQ), &str);
+ UNIT_ASSERT_STRINGS_EQUAL(str, "OT_EQ (0)");
+ }
+
+ Y_UNIT_TEST(Track) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "IntParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ RunLogShuttleAction { }
+ }
+ }
+ )END", &q);
+ UNIT_ASSERT(parsed);
+ mngr.New("Query1", q);
+
+ {
+ TOrbit orbit;
+ LWTRACK(IntParam, orbit, 1);
+ LWTRACK(StringParam, orbit, "str");
+ }
+
+ struct {
+ void Push(TThread::TId, const TTrackLog& tl) {
+ UNIT_ASSERT(tl.Items.size() == 2);
+ UNIT_ASSERT(TString(tl.Items[0].Probe->Event.Name) == "IntParam");
+ UNIT_ASSERT(TString(tl.Items[1].Probe->Event.Name) == "StringParam");
+ }
+ } reader;
+ mngr.ReadDepot("Query1", reader);
+ }
+
+ Y_UNIT_TEST(ShouldSerializeTracks)
+ {
+ TManager manager(*Singleton<TProbeRegistry>(), false);
+
+ TOrbit orbit;
+ TTraceRequest req;
+ req.SetIsTraced(true);
+ manager.HandleTraceRequest(req, orbit);
+
+ LWTRACK(NoParam, orbit);
+ LWTRACK(IntParam, orbit, 1);
+ LWTRACK(StringParam, orbit, "str");
+ LWTRACK(EnumParams, orbit, ValueA, EEnumClass::ValueC);
+ LWTRACK(InstantParam, orbit, TInstant::Seconds(42));
+ LWTRACK(DurationParam, orbit, TDuration::MilliSeconds(146));
+ LWTRACK(ProtoEnum, orbit, OT_EQ);
+ LWTRACK(IntIntParams, orbit, 1, 2);
+
+ TTraceResponse resp;
+ orbit.Serialize(0, *resp.MutableTrace());
+ auto& r = resp.GetTrace();
+
+ UNIT_ASSERT_VALUES_EQUAL(8, r.EventsSize());
+
+ const auto& p0 = r.GetEvents(0);
+ UNIT_ASSERT_VALUES_EQUAL("NoParam", p0.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p0.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL(0 , p0.ParamsSize());
+
+ const auto& p1 = r.GetEvents(1);
+ UNIT_ASSERT_VALUES_EQUAL("IntParam", p1.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p1.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL(1, p1.GetParams(0).GetUintValue());
+
+ const auto& p2 = r.GetEvents(2);
+ UNIT_ASSERT_VALUES_EQUAL("StringParam", p2.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p2.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL("str", p2.GetParams(0).GetStrValue());
+
+ const auto& p3 = r.GetEvents(3);
+ UNIT_ASSERT_VALUES_EQUAL("EnumParams", p3.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p3.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL((ui32)ValueA, p3.GetParams(0).GetIntValue());
+ UNIT_ASSERT_VALUES_EQUAL((ui32)EEnumClass::ValueC, p3.GetParams(1).GetIntValue());
+
+ const auto& p4 = r.GetEvents(4);
+ UNIT_ASSERT_VALUES_EQUAL("InstantParam", p4.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p4.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL(42, p4.GetParams(0).GetDoubleValue());
+
+ const auto& p5 = r.GetEvents(5);
+ UNIT_ASSERT_VALUES_EQUAL("DurationParam", p5.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p5.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL(146, p5.GetParams(0).GetDoubleValue());
+
+ const auto& p6 = r.GetEvents(6);
+ UNIT_ASSERT_VALUES_EQUAL("ProtoEnum", p6.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p6.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL((int)OT_EQ, p6.GetParams(0).GetIntValue());
+
+ const auto& p7 = r.GetEvents(7);
+ UNIT_ASSERT_VALUES_EQUAL("IntIntParams", p7.GetName());
+ UNIT_ASSERT_VALUES_EQUAL("LWTRACE_UT_PROVIDER", p7.GetProvider());
+ UNIT_ASSERT_VALUES_EQUAL(1, p7.GetParams(0).GetUintValue());
+ UNIT_ASSERT_VALUES_EQUAL(2, p7.GetParams(1).GetUintValue());
+ }
+
+ Y_UNIT_TEST(ShouldDeserializeTracks)
+ {
+ TManager manager(*Singleton<TProbeRegistry>(), false);
+
+ TTraceResponse resp;
+ auto& r = *resp.MutableTrace()->MutableEvents();
+
+ auto& p0 = *r.Add();
+ p0.SetName("NoParam");
+ p0.SetProvider("LWTRACE_UT_PROVIDER");
+
+ auto& p1 = *r.Add();
+ p1.SetName("IntParam");
+ p1.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p1param = *p1.MutableParams()->Add();
+ p1param.SetUintValue(1);
+
+ auto& p2 = *r.Add();
+ p2.SetName("StringParam");
+ p2.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p2param = *p2.MutableParams()->Add();
+ p2param.SetStrValue("str");
+
+ auto& p3 = *r.Add();
+ p3.SetName("EnumParams");
+ p3.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p3param1 = *p3.MutableParams()->Add();
+ p3param1.SetUintValue((ui64)EEnumClass::ValueC);
+ auto& p3param2 = *p3.MutableParams()->Add();
+ p3param2.SetIntValue((ui64)EEnumClass::ValueC);
+
+ auto& p4 = *r.Add();
+ p4.SetName("InstantParam");
+ p4.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p4param = *p4.MutableParams()->Add();
+ p4param.SetDoubleValue(42);
+
+ auto& p5 = *r.Add();
+ p5.SetName("DurationParam");
+ p5.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p5param = *p5.MutableParams()->Add();
+ p5param.SetDoubleValue(146);
+
+ auto& p6 = *r.Add();
+ p6.SetName("ProtoEnum");
+ p6.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p6param = *p6.MutableParams()->Add();
+ p6param.SetIntValue((i64)OT_EQ);
+
+ auto& p7 = *r.Add();
+ p7.SetName("IntIntParams");
+ p7.SetProvider("LWTRACE_UT_PROVIDER");
+ auto& p7param1 = *p7.MutableParams()->Add();
+ p7param1.SetIntValue(1);
+ auto& p7param2 = *p7.MutableParams()->Add();
+ p7param2.SetIntValue(2);
+
+ TOrbit orbit;
+ UNIT_ASSERT_VALUES_EQUAL(
+ manager.HandleTraceResponse(resp, manager.GetProbesMap(), orbit).IsSuccess,
+ true);
+ }
+
+ Y_UNIT_TEST(ShouldDeserializeWhatSerialized)
+ {
+ TManager manager(*Singleton<TProbeRegistry>(), false);
+
+ TOrbit orbit;
+ TTraceRequest req;
+ req.SetIsTraced(true);
+ manager.HandleTraceRequest(req, orbit);
+
+ LWTRACK(NoParam, orbit);
+ LWTRACK(IntParam, orbit, 1);
+ LWTRACK(StringParam, orbit, "str");
+ LWTRACK(EnumParams, orbit, ValueA, EEnumClass::ValueC);
+ LWTRACK(InstantParam, orbit, TInstant::Seconds(42));
+ LWTRACK(DurationParam, orbit, TDuration::MilliSeconds(146));
+ LWTRACK(ProtoEnum, orbit, OT_EQ);
+ LWTRACK(IntIntParams, orbit, 1, 2);
+
+ TTraceResponse resp;
+ auto& r = *resp.MutableTrace();
+ orbit.Serialize(0, r);
+
+ TOrbit orbit1;
+ UNIT_ASSERT_VALUES_EQUAL(
+ manager.HandleTraceResponse(resp, manager.GetProbesMap(), orbit1).IsSuccess,
+ true);
+ }
+
+ Y_UNIT_TEST(TrackForkJoin) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "NoParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ RunLogShuttleAction { }
+ }
+ }
+ )END", &q);
+
+ UNIT_ASSERT(parsed);
+ mngr.New("Query1", q);
+
+ {
+ TOrbit a, b, c, d;
+
+ // Graph:
+ // c
+ // / \
+ // b-f-b-j-b
+ // / \
+ // a-f-a-f-a-j-a-j-a
+ // \ /
+ // d
+ //
+ // Merged track:
+ // 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
+
+ LWTRACK(NoParam, a);
+ a.Fork(b);
+ LWTRACK(IntParam, a, 1);
+ a.Fork(d);
+ LWTRACK(IntParam, a, 2);
+
+ LWTRACK(IntParam, b, 3);
+ b.Fork(c);
+ LWTRACK(IntParam, b, 4);
+
+ LWTRACK(IntParam, c, 5);
+ b.Join(c);
+ LWTRACK(IntParam, b, 6);
+
+ LWTRACK(IntParam, d, 7);
+ a.Join(d);
+ LWTRACK(IntParam, a, 8);
+
+ a.Join(b);
+ LWTRACK(IntParam, a, 9);
+ }
+
+ struct {
+ void Push(TThread::TId, const TTrackLog& tl) {
+ UNIT_ASSERT(tl.Items.size() == 16);
+ UNIT_ASSERT(TString(tl.Items[0].Probe->Event.Name) == "NoParam");
+ UNIT_ASSERT(TString(tl.Items[1].Probe->Event.Name) == "Fork");
+ UNIT_ASSERT(tl.Items[2].Params.Param[0].Get<ui64>() == 1);
+ UNIT_ASSERT(TString(tl.Items[3].Probe->Event.Name) == "Fork");
+ UNIT_ASSERT(tl.Items[4].Params.Param[0].Get<ui64>() == 2);
+ UNIT_ASSERT(TString(tl.Items[5].Probe->Event.Name) == "Join");
+ UNIT_ASSERT(tl.Items[6].Params.Param[0].Get<ui64>() == 7);
+ UNIT_ASSERT(tl.Items[7].Params.Param[0].Get<ui64>() == 8);
+ UNIT_ASSERT(TString(tl.Items[8].Probe->Event.Name) == "Join");
+ UNIT_ASSERT(tl.Items[9].Params.Param[0].Get<ui64>() == 3);
+ UNIT_ASSERT(TString(tl.Items[10].Probe->Event.Name) == "Fork");
+ UNIT_ASSERT(tl.Items[11].Params.Param[0].Get<ui64>() == 4);
+ UNIT_ASSERT(TString(tl.Items[12].Probe->Event.Name) == "Join");
+ UNIT_ASSERT(tl.Items[13].Params.Param[0].Get<ui64>() == 5);
+ UNIT_ASSERT(tl.Items[14].Params.Param[0].Get<ui64>() == 6);
+ UNIT_ASSERT(tl.Items[15].Params.Param[0].Get<ui64>() == 9);
+ }
+ } reader;
+ mngr.ReadDepot("Query1", reader);
+ }
+
+ Y_UNIT_TEST(TrackForkError) {
+ TManager mngr(*Singleton<TProbeRegistry>(), true);
+ TQuery q;
+ bool parsed = NProtoBuf::TextFormat::ParseFromString(R"END(
+ Blocks {
+ ProbeDesc {
+ Name: "NoParam"
+ Provider: "LWTRACE_UT_PROVIDER"
+ }
+ Action {
+ RunLogShuttleAction {
+ MaxTrackLength: 100
+ }
+ }
+ }
+ )END", &q);
+
+ UNIT_ASSERT(parsed);
+ mngr.New("Query1", q);
+
+ constexpr size_t n = (100 + 2) / 3 + 1;
+
+ {
+ TVector<TVector<TOrbit>> span;
+
+ while (1) {
+ TVector<TOrbit> orbit(n);
+
+ LWTRACK(NoParam, orbit[0]);
+ if (!orbit[0].HasShuttles()) {
+ break;
+ }
+ for (size_t i = 1; i < n; i++) {
+ if (!orbit[i - 1].Fork(orbit[i])) {
+ break;
+ }
+ LWTRACK(IntParam, orbit[i], i);
+ }
+
+ span.emplace_back(std::move(orbit));
+ }
+
+ for (auto& orbit: span) {
+ for (auto it = orbit.rbegin(); it + 1 != orbit.rend(); it++) {
+ (it + 1)->Join(*it);
+ }
+ }
+ }
+
+ struct {
+ void Push(TThread::TId, const TTrackLog& tl) {
+ UNIT_ASSERT(tl.Items.size() == 100);
+ UNIT_ASSERT(tl.Truncated);
+ }
+ } reader;
+ mngr.ReadDepot("Query1", reader);
+ }
+#endif // LWTRACE_DISABLE
+}