12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/Support/Threading.h"
18 #include "llvm/Support/YAMLParser.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
27 using testing::ElementsAre;
28 using testing::SizeIs;
29 using testing::StartsWith;
32 if (arg->getType() != llvm::yaml::Node::NK_Scalar) {
33 *result_listener <<
"is a " << arg->getVerbatimTag();
36 llvm::SmallString<32> S;
37 return Val == static_cast<llvm::yaml::ScalarNode *>(arg)->getValue(S);
42 bool VerifyObject(llvm::yaml::Node &N,
43 std::map<std::string, std::string>
Expected) {
44 auto *M = llvm::dyn_cast<llvm::yaml::MappingNode>(&N);
46 ADD_FAILURE() <<
"Not an object";
50 llvm::SmallString<32> Tmp;
51 for (
auto &Prop : *M) {
52 auto *K = llvm::dyn_cast_or_null<llvm::yaml::ScalarNode>(Prop.getKey());
55 std::string KS = K->getValue(Tmp).str();
60 auto *V = llvm::dyn_cast_or_null<llvm::yaml::ScalarNode>(Prop.getValue());
62 ADD_FAILURE() << KS <<
" is not a string";
65 std::string VS = V->getValue(Tmp).str();
66 if (VS != I->second) {
67 ADD_FAILURE() << KS <<
" expected " << I->second <<
" but actual " << VS;
73 ADD_FAILURE() << P.first <<
" missing, expected " << P.second;
79 TEST(TraceTest, SmokeTest) {
83 llvm::raw_string_ostream
OS(JSON);
94 llvm::yaml::Stream Stream(JSON, SM);
95 auto Doc = Stream.begin();
96 ASSERT_NE(Doc, Stream.end());
97 auto *Root = llvm::dyn_cast_or_null<llvm::yaml::MappingNode>(Doc->getRoot());
98 ASSERT_NE(Root,
nullptr) <<
"Root should be an object";
101 llvm::SmallString<32> ThreadName;
102 get_thread_name(ThreadName);
103 bool ThreadsHaveNames = !ThreadName.empty();
109 auto Prop = Root->begin();
110 ASSERT_NE(Prop, Root->end()) <<
"Expected displayTimeUnit property";
111 ASSERT_THAT(Prop->getKey(), StringNode(
"displayTimeUnit"));
112 EXPECT_THAT(Prop->getValue(), StringNode(
"ns"));
113 ASSERT_NE(++Prop, Root->end()) <<
"Expected traceEvents property";
114 EXPECT_THAT(Prop->getKey(), StringNode(
"traceEvents"));
116 llvm::dyn_cast_or_null<llvm::yaml::SequenceNode>(Prop->getValue());
117 ASSERT_NE(Events,
nullptr) <<
"traceEvents should be an array";
118 auto Event = Events->begin();
119 ASSERT_NE(Event, Events->end()) <<
"Expected process name";
120 EXPECT_TRUE(VerifyObject(*Event, {{
"ph",
"M"}, {
"name",
"process_name"}}));
121 if (ThreadsHaveNames) {
122 ASSERT_NE(++Event, Events->end()) <<
"Expected thread name";
123 EXPECT_TRUE(VerifyObject(*Event, {{
"ph",
"M"}, {
"name",
"thread_name"}}));
125 ASSERT_NE(++Event, Events->end()) <<
"Expected log message";
126 EXPECT_TRUE(VerifyObject(*Event, {{
"ph",
"i"}, {
"name",
"Log"}}));
127 ASSERT_NE(++Event, Events->end()) <<
"Expected span end";
128 EXPECT_TRUE(VerifyObject(*Event, {{
"ph",
"X"}, {
"name",
"A"}}));
129 ASSERT_EQ(++Event, Events->end());
130 ASSERT_EQ(++Prop, Root->end());
133 TEST(MetricsTracer, LatencyTest) {
135 constexpr llvm::StringLiteral MetricName =
"span_latency";
136 constexpr llvm::StringLiteral OpName =
"op_name";
139 trace::Span SpanWithLat(OpName);
140 EXPECT_THAT(
Tracer.takeMetric(MetricName, OpName), SizeIs(0));
142 EXPECT_THAT(
Tracer.takeMetric(MetricName, OpName), SizeIs(1));
145 class CSVMetricsTracerTest :
public ::testing::Test {
147 CSVMetricsTracerTest()
153 std::vector<std::string> outputLines() {
156 llvm::SmallVector<llvm::StringRef, 4>
Lines;
162 llvm::raw_string_ostream
OS;
163 std::unique_ptr<trace::EventTracer>
Tracer;
167 TEST_F(CSVMetricsTracerTest, RecordsValues) {
172 ASSERT_THAT(outputLines(),
173 ElementsAre(
"Kind,Metric,Label,Value,Timestamp",
174 StartsWith(
"d,dist,x,1.000000e+00,"),
175 StartsWith(
"c,cnt,,1.000000e+00,"),
176 StartsWith(
"d,dist,y,2.000000e+00,"),
""));
179 TEST_F(CSVMetricsTracerTest, Escaping) {
184 EXPECT_THAT(outputLines(), ElementsAre(_, StartsWith(R
"(d,dist,",",1)"),
185 StartsWith(R"(d,dist,"a""b",1)"),
186 StartsWith("d,dist,\"a\nb\",1"),
""));