diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/lwtrace/trace_ut.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/lwtrace/trace_ut.cpp')
-rw-r--r-- | library/cpp/lwtrace/trace_ut.cpp | 880 |
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 +} |