blob: ecf9c5c10f6b6a35c86ec453fcd0b5f97614a989 [file] [log] [blame]
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +01001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Eric Seckler178094e2019-10-24 14:03:04 +010017#include "perfetto/ext/trace_processor/export_json.h"
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010018#include "src/trace_processor/export_json.h"
19
Eric Seckler178094e2019-10-24 14:03:04 +010020#include <string.h>
21
22#include <limits>
23
24#include <json/reader.h>
25#include <json/value.h>
26
Primiano Tucci2c5488f2019-06-01 03:27:28 +010027#include "perfetto/ext/base/temp_file.h"
Eric Secklerc34c8fc2019-08-02 10:57:59 +010028#include "src/trace_processor/args_tracker.h"
Lalit Magantiededb0e2020-01-08 12:50:34 +000029#include "src/trace_processor/metadata_tracker.h"
Lalit Magantieac7fff2020-01-10 16:42:54 +000030#include "src/trace_processor/process_tracker.h"
Eric Secklerc34c8fc2019-08-02 10:57:59 +010031#include "src/trace_processor/trace_processor_context.h"
Eric Seckler4b861052019-10-23 14:50:28 +010032#include "src/trace_processor/track_tracker.h"
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010033
Primiano Tucci919ca1e2019-08-21 20:26:58 +020034#include "test/gtest_and_gmock.h"
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010035
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010036namespace perfetto {
37namespace trace_processor {
38namespace json {
39namespace {
40
41std::string ReadFile(FILE* input) {
42 fseek(input, 0, SEEK_SET);
Eric Secklere2b4e5c2019-12-06 14:37:29 +000043 const int kBufSize = 10000;
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010044 char buffer[kBufSize];
Lalit Magantid9983462019-05-09 18:10:09 +010045 size_t ret = fread(buffer, sizeof(char), kBufSize, input);
Primiano Tucci225a4e62019-06-06 11:13:57 +010046 EXPECT_GT(ret, 0u);
Lalit Magantid9983462019-05-09 18:10:09 +010047 return std::string(buffer, ret);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010048}
49
Eric Seckler178094e2019-10-24 14:03:04 +010050class StringOutputWriter : public OutputWriter {
51 public:
52 StringOutputWriter() { str_.reserve(1024); }
53 ~StringOutputWriter() override {}
54
55 util::Status AppendString(const std::string& str) override {
56 str_ += str;
57 return util::OkStatus();
58 }
59
60 std::string TakeStr() { return std::move(str_); }
61
62 private:
63 std::string str_;
64};
65
Eric Seckler4b861052019-10-23 14:50:28 +010066class ExportJsonTest : public ::testing::Test {
67 public:
68 ExportJsonTest() {
Lalit Maganti1908e262020-01-09 14:33:19 +000069 context_.global_args_tracker.reset(new GlobalArgsTracker(&context_));
Eric Seckler4b861052019-10-23 14:50:28 +010070 context_.args_tracker.reset(new ArgsTracker(&context_));
71 context_.storage.reset(new TraceStorage());
72 context_.track_tracker.reset(new TrackTracker(&context_));
Lalit Magantiededb0e2020-01-08 12:50:34 +000073 context_.metadata_tracker.reset(new MetadataTracker(&context_));
Lalit Magantieac7fff2020-01-10 16:42:54 +000074 context_.process_tracker.reset(new ProcessTracker(&context_));
Eric Seckler4b861052019-10-23 14:50:28 +010075 }
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010076
Eric Seckler178094e2019-10-24 14:03:04 +010077 std::string ToJson(ArgumentFilterPredicate argument_filter = nullptr,
78 MetadataFilterPredicate metadata_filter = nullptr,
79 LabelFilterPredicate label_filter = nullptr) {
80 StringOutputWriter writer;
81 util::Status status =
82 ExportJson(context_.storage.get(), &writer, argument_filter,
83 metadata_filter, label_filter);
84 EXPECT_TRUE(status.ok());
85 return writer.TakeStr();
86 }
87
88 Json::Value ToJsonValue(const std::string& json) {
89 Json::Reader reader;
90 Json::Value result;
Eric Secklere2b4e5c2019-12-06 14:37:29 +000091 EXPECT_TRUE(reader.parse(json, result)) << json;
Eric Seckler178094e2019-10-24 14:03:04 +010092 return result;
93 }
94
Eric Seckler4b861052019-10-23 14:50:28 +010095 protected:
96 TraceProcessorContext context_;
97};
98
99TEST_F(ExportJsonTest, EmptyStorage) {
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100100 base::TempFile temp_file = base::TempFile::Create();
101 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100102 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100103
Eric Seckler7fb1d232019-10-23 14:42:43 +0100104 EXPECT_TRUE(status.ok());
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100105
Eric Seckler178094e2019-10-24 14:03:04 +0100106 Json::Value result = ToJsonValue(ReadFile(output));
Primiano Tucci225a4e62019-06-06 11:13:57 +0100107 EXPECT_EQ(result["traceEvents"].size(), 0u);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100108}
109
Eric Seckler4b861052019-10-23 14:50:28 +0100110TEST_F(ExportJsonTest, StorageWithOneSlice) {
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100111 const int64_t kTimestamp = 10000000;
112 const int64_t kDuration = 10000;
Mikhail Khokhlov7db04912019-07-18 16:11:11 +0100113 const int64_t kThreadTimestamp = 20000000;
114 const int64_t kThreadDuration = 20000;
Eric Seckler77fb1d22019-07-31 17:02:51 +0100115 const int64_t kThreadInstructionCount = 30000000;
116 const int64_t kThreadInstructionDelta = 30000;
Eric Secklerbb0e1542020-01-16 13:44:13 +0000117 const uint32_t kThreadID = 100;
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100118 const char* kCategory = "cat";
119 const char* kName = "name";
120
Lalit Magantieac7fff2020-01-10 16:42:54 +0000121 UniqueTid utid = context_.process_tracker->GetOrCreateThread(kThreadID);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000122 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100123 context_.args_tracker->Flush(); // Flush track args.
124 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
125 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Magantic7ea02e2019-12-12 14:06:49 +0000126 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000127 {kTimestamp, kDuration, track, cat_id, name_id, 0, 0, 0});
Eric Seckler4b861052019-10-23 14:50:28 +0100128 context_.storage->mutable_thread_slices()->AddThreadSlice(
Eric Seckler77fb1d22019-07-31 17:02:51 +0100129 0, kThreadTimestamp, kThreadDuration, kThreadInstructionCount,
130 kThreadInstructionDelta);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100131
132 base::TempFile temp_file = base::TempFile::Create();
133 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100134 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100135
Eric Seckler7fb1d232019-10-23 14:42:43 +0100136 EXPECT_TRUE(status.ok());
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100137
Eric Seckler178094e2019-10-24 14:03:04 +0100138 Json::Value result = ToJsonValue(ReadFile(output));
Primiano Tucci225a4e62019-06-06 11:13:57 +0100139 EXPECT_EQ(result["traceEvents"].size(), 1u);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100140
141 Json::Value event = result["traceEvents"][0];
142 EXPECT_EQ(event["ph"].asString(), "X");
143 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
144 EXPECT_EQ(event["dur"].asInt64(), kDuration / 1000);
Mikhail Khokhlov7db04912019-07-18 16:11:11 +0100145 EXPECT_EQ(event["tts"].asInt64(), kThreadTimestamp / 1000);
146 EXPECT_EQ(event["tdur"].asInt64(), kThreadDuration / 1000);
Eric Seckler77fb1d22019-07-31 17:02:51 +0100147 EXPECT_EQ(event["ticount"].asInt64(), kThreadInstructionCount);
148 EXPECT_EQ(event["tidelta"].asInt64(), kThreadInstructionDelta);
Eric Seckler88cab6f2020-01-16 18:33:45 +0000149 EXPECT_EQ(event["tid"].asInt(), static_cast<int>(kThreadID));
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100150 EXPECT_EQ(event["cat"].asString(), kCategory);
151 EXPECT_EQ(event["name"].asString(), kName);
Eric Secklerf91236e2019-11-04 10:25:45 +0000152 EXPECT_TRUE(event["args"].isObject());
153 EXPECT_EQ(event["args"].size(), 0u);
Eric Seckler206db472019-07-25 12:05:27 +0100154}
Eric Seckler6f13e332019-10-15 12:14:04 +0100155
Eric Seckler4b861052019-10-23 14:50:28 +0100156TEST_F(ExportJsonTest, StorageWithOneUnfinishedSlice) {
Eric Seckler206db472019-07-25 12:05:27 +0100157 const int64_t kTimestamp = 10000000;
158 const int64_t kDuration = -1;
159 const int64_t kThreadTimestamp = 20000000;
160 const int64_t kThreadDuration = -1;
Eric Seckler77fb1d22019-07-31 17:02:51 +0100161 const int64_t kThreadInstructionCount = 30000000;
162 const int64_t kThreadInstructionDelta = -1;
Eric Secklerbb0e1542020-01-16 13:44:13 +0000163 const uint32_t kThreadID = 100;
Eric Seckler206db472019-07-25 12:05:27 +0100164 const char* kCategory = "cat";
165 const char* kName = "name";
166
Lalit Magantieac7fff2020-01-10 16:42:54 +0000167 UniqueTid utid = context_.process_tracker->GetOrCreateThread(kThreadID);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000168 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100169 context_.args_tracker->Flush(); // Flush track args.
170 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
171 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Magantic7ea02e2019-12-12 14:06:49 +0000172 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000173 {kTimestamp, kDuration, track, cat_id, name_id, 0, 0, 0});
Eric Seckler4b861052019-10-23 14:50:28 +0100174 context_.storage->mutable_thread_slices()->AddThreadSlice(
Eric Seckler77fb1d22019-07-31 17:02:51 +0100175 0, kThreadTimestamp, kThreadDuration, kThreadInstructionCount,
176 kThreadInstructionDelta);
Eric Seckler206db472019-07-25 12:05:27 +0100177
178 base::TempFile temp_file = base::TempFile::Create();
179 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100180 util::Status status = ExportJson(context_.storage.get(), output);
Eric Seckler206db472019-07-25 12:05:27 +0100181
Eric Seckler7fb1d232019-10-23 14:42:43 +0100182 EXPECT_TRUE(status.ok());
Eric Seckler206db472019-07-25 12:05:27 +0100183
Eric Seckler178094e2019-10-24 14:03:04 +0100184 Json::Value result = ToJsonValue(ReadFile(output));
Eric Seckler206db472019-07-25 12:05:27 +0100185 EXPECT_EQ(result["traceEvents"].size(), 1u);
186
187 Json::Value event = result["traceEvents"][0];
188 EXPECT_EQ(event["ph"].asString(), "B");
189 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
190 EXPECT_FALSE(event.isMember("dur"));
191 EXPECT_EQ(event["tts"].asInt64(), kThreadTimestamp / 1000);
192 EXPECT_FALSE(event.isMember("tdur"));
Eric Seckler77fb1d22019-07-31 17:02:51 +0100193 EXPECT_EQ(event["ticount"].asInt64(), kThreadInstructionCount);
194 EXPECT_FALSE(event.isMember("tidelta"));
Eric Seckler88cab6f2020-01-16 18:33:45 +0000195 EXPECT_EQ(event["tid"].asInt(), static_cast<int>(kThreadID));
Eric Seckler206db472019-07-25 12:05:27 +0100196 EXPECT_EQ(event["cat"].asString(), kCategory);
197 EXPECT_EQ(event["name"].asString(), kName);
Eric Secklerf91236e2019-11-04 10:25:45 +0000198 EXPECT_TRUE(event["args"].isObject());
199 EXPECT_EQ(event["args"].size(), 0u);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100200}
201
Eric Seckler4b861052019-10-23 14:50:28 +0100202TEST_F(ExportJsonTest, StorageWithThreadName) {
Eric Secklerbb0e1542020-01-16 13:44:13 +0000203 const uint32_t kThreadID = 100;
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100204 const char* kName = "thread";
205
Lalit Magantieac7fff2020-01-10 16:42:54 +0000206 tables::ThreadTable::Row row(kThreadID);
207 row.name = context_.storage->InternString(base::StringView(kName));
208 context_.storage->mutable_thread_table()->Insert(row);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100209
210 base::TempFile temp_file = base::TempFile::Create();
211 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100212 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100213
Eric Seckler7fb1d232019-10-23 14:42:43 +0100214 EXPECT_TRUE(status.ok());
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100215
Eric Seckler178094e2019-10-24 14:03:04 +0100216 Json::Value result = ToJsonValue(ReadFile(output));
Primiano Tucci225a4e62019-06-06 11:13:57 +0100217 EXPECT_EQ(result["traceEvents"].size(), 1u);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100218
219 Json::Value event = result["traceEvents"][0];
220 EXPECT_EQ(event["ph"].asString(), "M");
Eric Seckler88cab6f2020-01-16 18:33:45 +0000221 EXPECT_EQ(event["tid"].asInt(), static_cast<int>(kThreadID));
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100222 EXPECT_EQ(event["name"].asString(), "thread_name");
223 EXPECT_EQ(event["args"]["name"].asString(), kName);
224}
225
Eric Seckler3183c6d2020-01-14 15:45:20 +0000226TEST_F(ExportJsonTest, SystemEventsIgnored) {
Eric Seckler4b861052019-10-23 14:50:28 +0100227 constexpr int64_t kCookie = 22;
228 TrackId track = context_.track_tracker->InternAndroidAsyncTrack(
Lalit Magantif0599a02020-01-15 15:45:20 +0000229 /*name=*/kNullStringId, /*upid=*/0, kCookie);
Eric Seckler4b861052019-10-23 14:50:28 +0100230 context_.args_tracker->Flush(); // Flush track args.
Lalit Maganti21b21632019-09-28 16:50:23 +0100231
Eric Seckler3183c6d2020-01-14 15:45:20 +0000232 // System events have no category.
233 StringId cat_id = kNullStringId;
Eric Seckler4b861052019-10-23 14:50:28 +0100234 StringId name_id = context_.storage->InternString("name");
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000235 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000236 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100237
238 base::TempFile temp_file = base::TempFile::Create();
239 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100240 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100241
Eric Seckler4b861052019-10-23 14:50:28 +0100242 EXPECT_TRUE(status.ok());
243
Eric Seckler178094e2019-10-24 14:03:04 +0100244 Json::Value result = ToJsonValue(ReadFile(output));
Eric Seckler4b861052019-10-23 14:50:28 +0100245 EXPECT_EQ(result["traceEvents"].size(), 0u);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100246}
247
Eric Seckler4b861052019-10-23 14:50:28 +0100248TEST_F(ExportJsonTest, StorageWithMetadata) {
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100249 const char* kDescription = "description";
250 const char* kBenchmarkName = "benchmark name";
251 const char* kStoryName = "story name";
252 const char* kStoryTag1 = "tag1";
253 const char* kStoryTag2 = "tag2";
254 const int64_t kBenchmarkStart = 1000000;
255 const int64_t kStoryStart = 2000000;
256 const bool kHadFailures = true;
257
Eric Seckler4b861052019-10-23 14:50:28 +0100258 StringId desc_id =
259 context_.storage->InternString(base::StringView(kDescription));
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100260 Variadic description = Variadic::String(desc_id);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000261 context_.metadata_tracker->SetMetadata(metadata::benchmark_description,
262 description);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100263
264 StringId benchmark_name_id =
Eric Seckler4b861052019-10-23 14:50:28 +0100265 context_.storage->InternString(base::StringView(kBenchmarkName));
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100266 Variadic benchmark_name = Variadic::String(benchmark_name_id);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000267 context_.metadata_tracker->SetMetadata(metadata::benchmark_name,
268 benchmark_name);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100269
Eric Seckler4b861052019-10-23 14:50:28 +0100270 StringId story_name_id =
271 context_.storage->InternString(base::StringView(kStoryName));
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100272 Variadic story_name = Variadic::String(story_name_id);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000273 context_.metadata_tracker->SetMetadata(metadata::benchmark_story_name,
274 story_name);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100275
Eric Seckler4b861052019-10-23 14:50:28 +0100276 StringId tag1_id =
277 context_.storage->InternString(base::StringView(kStoryTag1));
278 StringId tag2_id =
279 context_.storage->InternString(base::StringView(kStoryTag2));
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100280 Variadic tag1 = Variadic::String(tag1_id);
281 Variadic tag2 = Variadic::String(tag2_id);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000282 context_.metadata_tracker->AppendMetadata(metadata::benchmark_story_tags,
283 tag1);
284 context_.metadata_tracker->AppendMetadata(metadata::benchmark_story_tags,
285 tag2);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100286
287 Variadic benchmark_start = Variadic::Integer(kBenchmarkStart);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000288 context_.metadata_tracker->SetMetadata(metadata::benchmark_start_time_us,
289 benchmark_start);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100290
291 Variadic story_start = Variadic::Integer(kStoryStart);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000292 context_.metadata_tracker->SetMetadata(metadata::benchmark_story_run_time_us,
293 story_start);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100294
295 Variadic had_failures = Variadic::Integer(kHadFailures);
Lalit Magantiededb0e2020-01-08 12:50:34 +0000296 context_.metadata_tracker->SetMetadata(metadata::benchmark_had_failures,
297 had_failures);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100298
299 base::TempFile temp_file = base::TempFile::Create();
300 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100301 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100302
Eric Seckler7fb1d232019-10-23 14:42:43 +0100303 EXPECT_TRUE(status.ok());
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100304
Eric Seckler178094e2019-10-24 14:03:04 +0100305 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100306
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100307 EXPECT_TRUE(result.isMember("metadata"));
308 EXPECT_TRUE(result["metadata"].isMember("telemetry"));
309 Json::Value telemetry_metadata = result["metadata"]["telemetry"];
310
Primiano Tucci225a4e62019-06-06 11:13:57 +0100311 EXPECT_EQ(telemetry_metadata["benchmarkDescriptions"].size(), 1u);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100312 EXPECT_EQ(telemetry_metadata["benchmarkDescriptions"][0].asString(),
313 kDescription);
314
Primiano Tucci225a4e62019-06-06 11:13:57 +0100315 EXPECT_EQ(telemetry_metadata["benchmarks"].size(), 1u);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100316 EXPECT_EQ(telemetry_metadata["benchmarks"][0].asString(), kBenchmarkName);
317
Primiano Tucci225a4e62019-06-06 11:13:57 +0100318 EXPECT_EQ(telemetry_metadata["stories"].size(), 1u);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100319 EXPECT_EQ(telemetry_metadata["stories"][0].asString(), kStoryName);
320
Primiano Tucci225a4e62019-06-06 11:13:57 +0100321 EXPECT_EQ(telemetry_metadata["storyTags"].size(), 2u);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100322 EXPECT_EQ(telemetry_metadata["storyTags"][0].asString(), kStoryTag1);
323 EXPECT_EQ(telemetry_metadata["storyTags"][1].asString(), kStoryTag2);
324
Primiano Tucci919ca1e2019-08-21 20:26:58 +0200325 EXPECT_DOUBLE_EQ(telemetry_metadata["benchmarkStart"].asInt(),
326 kBenchmarkStart / 1000.0);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100327
Primiano Tucci919ca1e2019-08-21 20:26:58 +0200328 EXPECT_DOUBLE_EQ(telemetry_metadata["traceStart"].asInt(),
329 kStoryStart / 1000.0);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100330
Primiano Tucci225a4e62019-06-06 11:13:57 +0100331 EXPECT_EQ(telemetry_metadata["hadFailures"].size(), 1u);
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100332 EXPECT_EQ(telemetry_metadata["hadFailures"][0].asBool(), kHadFailures);
333}
334
Eric Seckler4b861052019-10-23 14:50:28 +0100335TEST_F(ExportJsonTest, StorageWithStats) {
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100336 int64_t kProducers = 10;
337 int64_t kBufferSize0 = 1000;
338 int64_t kBufferSize1 = 2000;
Eric Secklere2b4e5c2019-12-06 14:37:29 +0000339 int64_t kFtraceBegin = 3000;
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100340
Eric Seckler4b861052019-10-23 14:50:28 +0100341 context_.storage->SetStats(stats::traced_producers_connected, kProducers);
342 context_.storage->SetIndexedStats(stats::traced_buf_buffer_size, 0,
343 kBufferSize0);
344 context_.storage->SetIndexedStats(stats::traced_buf_buffer_size, 1,
345 kBufferSize1);
Eric Secklere2b4e5c2019-12-06 14:37:29 +0000346 context_.storage->SetIndexedStats(stats::ftrace_cpu_bytes_read_begin, 0,
347 kFtraceBegin);
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100348
349 base::TempFile temp_file = base::TempFile::Create();
350 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100351 util::Status status = ExportJson(context_.storage.get(), output);
Eric Seckler7fb1d232019-10-23 14:42:43 +0100352 EXPECT_TRUE(status.ok());
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100353
Eric Seckler178094e2019-10-24 14:03:04 +0100354 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100355
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100356 EXPECT_TRUE(result.isMember("metadata"));
Eric Secklere2b4e5c2019-12-06 14:37:29 +0000357 EXPECT_TRUE(result["metadata"].isMember("trace_processor_stats"));
358 Json::Value stats = result["metadata"]["trace_processor_stats"];
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100359
Eric Secklere2b4e5c2019-12-06 14:37:29 +0000360 EXPECT_EQ(stats["traced_producers_connected"].asInt(), kProducers);
361 EXPECT_EQ(stats["traced_buf"].size(), 2u);
362 EXPECT_EQ(stats["traced_buf"][0]["buffer_size"].asInt(), kBufferSize0);
363 EXPECT_EQ(stats["traced_buf"][1]["buffer_size"].asInt(), kBufferSize1);
364 EXPECT_EQ(stats["ftrace_cpu_bytes_read_begin"].size(), 1u);
365 EXPECT_EQ(stats["ftrace_cpu_bytes_read_begin"][0].asInt(), kFtraceBegin);
Mikhail Khokhlova6f97242019-08-08 13:48:31 +0100366}
367
Eric Seckler4b861052019-10-23 14:50:28 +0100368TEST_F(ExportJsonTest, StorageWithChromeMetadata) {
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100369 const char* kName1 = "name1";
370 const char* kName2 = "name2";
371 const char* kValue1 = "value1";
372 const int kValue2 = 222;
373
Eric Seckler4b861052019-10-23 14:50:28 +0100374 TraceStorage* storage = context_.storage.get();
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100375
Lalit Maganti8d770f72020-01-30 15:44:04 +0000376 RawId id =
377 storage->mutable_raw_table()
378 ->Insert({0, storage->InternString("chrome_event.metadata"), 0, 0})
379 .id;
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100380
381 StringId name1_id = storage->InternString(base::StringView(kName1));
382 StringId name2_id = storage->InternString(base::StringView(kName2));
383 StringId value1_id = storage->InternString(base::StringView(kValue1));
Lalit Maganti5228f362020-01-15 13:45:56 +0000384
385 context_.args_tracker->AddArgsTo(id)
386 .AddArg(name1_id, Variadic::String(value1_id))
387 .AddArg(name2_id, Variadic::Integer(kValue2));
Eric Seckler4b861052019-10-23 14:50:28 +0100388 context_.args_tracker->Flush();
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100389
390 base::TempFile temp_file = base::TempFile::Create();
391 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler7fb1d232019-10-23 14:42:43 +0100392 util::Status status = ExportJson(storage, output);
393 EXPECT_TRUE(status.ok());
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100394
Eric Seckler178094e2019-10-24 14:03:04 +0100395 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100396
Mikhail Khokhlov8fefc5b2019-08-08 17:53:53 +0100397 EXPECT_TRUE(result.isMember("metadata"));
398 Json::Value metadata = result["metadata"];
399
400 EXPECT_EQ(metadata[kName1].asString(), kValue1);
401 EXPECT_EQ(metadata[kName2].asInt(), kValue2);
402}
403
Eric Seckler4b861052019-10-23 14:50:28 +0100404TEST_F(ExportJsonTest, StorageWithArgs) {
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100405 const char* kCategory = "cat";
406 const char* kName = "name";
407 const char* kSrc = "source_file.cc";
408
Lalit Magantieac7fff2020-01-10 16:42:54 +0000409 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000410 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100411 context_.args_tracker->Flush(); // Flush track args.
412 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
413 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000414 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000415 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100416
Eric Seckler4b861052019-10-23 14:50:28 +0100417 StringId arg_key_id = context_.storage->InternString(
418 base::StringView("task.posted_from.file_name"));
419 StringId arg_value_id =
420 context_.storage->InternString(base::StringView(kSrc));
Lalit Maganti1908e262020-01-09 14:33:19 +0000421 GlobalArgsTracker::Arg arg;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100422 arg.flat_key = arg_key_id;
423 arg.key = arg_key_id;
424 arg.value = Variadic::String(arg_value_id);
Lalit Maganti1908e262020-01-09 14:33:19 +0000425 ArgSetId args = context_.global_args_tracker->AddArgSet({arg}, 0, 1);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000426 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100427
428 base::TempFile temp_file = base::TempFile::Create();
429 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100430 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100431
Eric Seckler7fb1d232019-10-23 14:42:43 +0100432 EXPECT_TRUE(status.ok());
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100433
Eric Seckler178094e2019-10-24 14:03:04 +0100434 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100435 EXPECT_EQ(result["traceEvents"].size(), 1u);
436
437 Json::Value event = result["traceEvents"][0];
438 EXPECT_EQ(event["cat"].asString(), kCategory);
439 EXPECT_EQ(event["name"].asString(), kName);
440 EXPECT_EQ(event["args"]["src"].asString(), kSrc);
441}
442
Eric Seckler4b861052019-10-23 14:50:28 +0100443TEST_F(ExportJsonTest, StorageWithSliceAndFlowEventArgs) {
Eric Seckler6f13e332019-10-15 12:14:04 +0100444 const char* kCategory = "cat";
445 const char* kName = "name";
Eric Seckler6f13e332019-10-15 12:14:04 +0100446 const uint64_t kBindId = 0xaa00aa00aa00aa00;
447 const char* kFlowDirection = "inout";
448 const char* kArgName = "arg_name";
449 const int kArgValue = 123;
450
Eric Seckler4b861052019-10-23 14:50:28 +0100451 TraceStorage* storage = context_.storage.get();
Eric Seckler6f13e332019-10-15 12:14:04 +0100452
Lalit Magantieac7fff2020-01-10 16:42:54 +0000453 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000454 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100455 context_.args_tracker->Flush(); // Flush track args.
Eric Seckler6f13e332019-10-15 12:14:04 +0100456 StringId cat_id = storage->InternString(base::StringView(kCategory));
457 StringId name_id = storage->InternString(base::StringView(kName));
Lalit Maganti8d770f72020-01-30 15:44:04 +0000458 SliceId id = storage->mutable_slice_table()
459 ->Insert({0, 0, track, cat_id, name_id, 0, 0, 0})
460 .id;
Lalit Maganti5228f362020-01-15 13:45:56 +0000461 auto inserter = context_.args_tracker->AddArgsTo(id);
Eric Seckler6f13e332019-10-15 12:14:04 +0100462
Eric Seckler6f13e332019-10-15 12:14:04 +0100463 auto add_arg = [&](const char* key, Variadic value) {
Lalit Maganti5228f362020-01-15 13:45:56 +0000464 inserter.AddArg(storage->InternString(key), value);
Eric Seckler6f13e332019-10-15 12:14:04 +0100465 };
466
467 add_arg("legacy_event.bind_id", Variadic::UnsignedInteger(kBindId));
468 add_arg("legacy_event.bind_to_enclosing", Variadic::Boolean(true));
469 StringId flow_direction_id = storage->InternString(kFlowDirection);
470 add_arg("legacy_event.flow_direction", Variadic::String(flow_direction_id));
471
472 add_arg(kArgName, Variadic::Integer(kArgValue));
473
Eric Seckler4b861052019-10-23 14:50:28 +0100474 context_.args_tracker->Flush();
Eric Seckler6f13e332019-10-15 12:14:04 +0100475
476 base::TempFile temp_file = base::TempFile::Create();
477 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler7fb1d232019-10-23 14:42:43 +0100478 util::Status status = ExportJson(storage, output);
Eric Seckler6f13e332019-10-15 12:14:04 +0100479
Eric Seckler7fb1d232019-10-23 14:42:43 +0100480 EXPECT_TRUE(status.ok());
Eric Seckler6f13e332019-10-15 12:14:04 +0100481
Eric Seckler178094e2019-10-24 14:03:04 +0100482 Json::Value result = ToJsonValue(ReadFile(output));
Eric Seckler6f13e332019-10-15 12:14:04 +0100483 EXPECT_EQ(result["traceEvents"].size(), 1u);
484
485 Json::Value event = result["traceEvents"][0];
486 EXPECT_EQ(event["cat"].asString(), kCategory);
487 EXPECT_EQ(event["name"].asString(), kName);
488 EXPECT_EQ(event["bind_id"].asString(), "0xaa00aa00aa00aa00");
489 EXPECT_EQ(event["bp"].asString(), "e");
490 EXPECT_EQ(event["flow_in"].asBool(), true);
491 EXPECT_EQ(event["flow_out"].asBool(), true);
492 EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
Eric Secklerc36f22e2019-10-28 10:08:12 +0000493 EXPECT_FALSE(event["args"].isMember("legacy_event"));
Eric Seckler6f13e332019-10-15 12:14:04 +0100494}
495
Eric Seckler4b861052019-10-23 14:50:28 +0100496TEST_F(ExportJsonTest, StorageWithListArgs) {
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100497 const char* kCategory = "cat";
498 const char* kName = "name";
499 double kValues[] = {1.234, 2.345};
500
Lalit Magantieac7fff2020-01-10 16:42:54 +0000501 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000502 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100503 context_.args_tracker->Flush(); // Flush track args.
504 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
505 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000506 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000507 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100508
Eric Seckler4b861052019-10-23 14:50:28 +0100509 StringId arg_flat_key_id = context_.storage->InternString(
510 base::StringView("debug.draw_duration_ms"));
511 StringId arg_key0_id = context_.storage->InternString(
512 base::StringView("debug.draw_duration_ms[0]"));
513 StringId arg_key1_id = context_.storage->InternString(
514 base::StringView("debug.draw_duration_ms[1]"));
Lalit Maganti1908e262020-01-09 14:33:19 +0000515 GlobalArgsTracker::Arg arg0;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100516 arg0.flat_key = arg_flat_key_id;
517 arg0.key = arg_key0_id;
518 arg0.value = Variadic::Real(kValues[0]);
Lalit Maganti1908e262020-01-09 14:33:19 +0000519 GlobalArgsTracker::Arg arg1;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100520 arg1.flat_key = arg_flat_key_id;
521 arg1.key = arg_key1_id;
522 arg1.value = Variadic::Real(kValues[1]);
Lalit Maganti1908e262020-01-09 14:33:19 +0000523 ArgSetId args = context_.global_args_tracker->AddArgSet({arg0, arg1}, 0, 2);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000524 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100525
526 base::TempFile temp_file = base::TempFile::Create();
527 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100528 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100529
Eric Seckler7fb1d232019-10-23 14:42:43 +0100530 EXPECT_TRUE(status.ok());
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100531
Eric Seckler178094e2019-10-24 14:03:04 +0100532 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100533 EXPECT_EQ(result["traceEvents"].size(), 1u);
534
535 Json::Value event = result["traceEvents"][0];
536 EXPECT_EQ(event["cat"].asString(), kCategory);
537 EXPECT_EQ(event["name"].asString(), kName);
Mikhail Khokhlovc4544ea2019-07-10 14:41:25 +0100538 EXPECT_EQ(event["args"]["draw_duration_ms"].size(), 2u);
Primiano Tucci919ca1e2019-08-21 20:26:58 +0200539 EXPECT_DOUBLE_EQ(event["args"]["draw_duration_ms"][0].asDouble(), kValues[0]);
540 EXPECT_DOUBLE_EQ(event["args"]["draw_duration_ms"][1].asDouble(), kValues[1]);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100541}
542
Eric Seckler4b861052019-10-23 14:50:28 +0100543TEST_F(ExportJsonTest, StorageWithMultiplePointerArgs) {
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100544 const char* kCategory = "cat";
545 const char* kName = "name";
546 uint64_t kValue0 = 1;
547 uint64_t kValue1 = std::numeric_limits<uint64_t>::max();
548
Lalit Magantieac7fff2020-01-10 16:42:54 +0000549 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000550 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100551 context_.args_tracker->Flush(); // Flush track args.
552 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
553 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000554 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000555 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100556
Eric Seckler4b861052019-10-23 14:50:28 +0100557 StringId arg_key0_id =
558 context_.storage->InternString(base::StringView("arg0"));
559 StringId arg_key1_id =
560 context_.storage->InternString(base::StringView("arg1"));
Lalit Maganti1908e262020-01-09 14:33:19 +0000561 GlobalArgsTracker::Arg arg0;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100562 arg0.flat_key = arg_key0_id;
563 arg0.key = arg_key0_id;
564 arg0.value = Variadic::Pointer(kValue0);
Lalit Maganti1908e262020-01-09 14:33:19 +0000565 GlobalArgsTracker::Arg arg1;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100566 arg1.flat_key = arg_key1_id;
567 arg1.key = arg_key1_id;
568 arg1.value = Variadic::Pointer(kValue1);
Lalit Maganti1908e262020-01-09 14:33:19 +0000569 ArgSetId args = context_.global_args_tracker->AddArgSet({arg0, arg1}, 0, 2);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000570 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100571
572 base::TempFile temp_file = base::TempFile::Create();
573 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100574 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100575
Eric Seckler7fb1d232019-10-23 14:42:43 +0100576 EXPECT_TRUE(status.ok());
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100577
Eric Seckler178094e2019-10-24 14:03:04 +0100578 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100579 EXPECT_EQ(result["traceEvents"].size(), 1u);
580
581 Json::Value event = result["traceEvents"][0];
582 EXPECT_EQ(event["cat"].asString(), kCategory);
583 EXPECT_EQ(event["name"].asString(), kName);
584 EXPECT_EQ(event["args"]["arg0"].asString(), "0x1");
585 EXPECT_EQ(event["args"]["arg1"].asString(), "0xffffffffffffffff");
586}
587
Eric Seckler4b861052019-10-23 14:50:28 +0100588TEST_F(ExportJsonTest, StorageWithObjectListArgs) {
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100589 const char* kCategory = "cat";
590 const char* kName = "name";
591 int kValues[] = {123, 234};
592
Lalit Magantieac7fff2020-01-10 16:42:54 +0000593 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000594 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100595 context_.args_tracker->Flush(); // Flush track args.
596 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
597 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000598 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000599 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100600
Eric Seckler4b861052019-10-23 14:50:28 +0100601 StringId arg_flat_key_id =
602 context_.storage->InternString(base::StringView("a.b"));
603 StringId arg_key0_id =
604 context_.storage->InternString(base::StringView("a[0].b"));
605 StringId arg_key1_id =
606 context_.storage->InternString(base::StringView("a[1].b"));
Lalit Maganti1908e262020-01-09 14:33:19 +0000607 GlobalArgsTracker::Arg arg0;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100608 arg0.flat_key = arg_flat_key_id;
609 arg0.key = arg_key0_id;
610 arg0.value = Variadic::Integer(kValues[0]);
Lalit Maganti1908e262020-01-09 14:33:19 +0000611 GlobalArgsTracker::Arg arg1;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100612 arg1.flat_key = arg_flat_key_id;
613 arg1.key = arg_key1_id;
614 arg1.value = Variadic::Integer(kValues[1]);
Lalit Maganti1908e262020-01-09 14:33:19 +0000615 ArgSetId args = context_.global_args_tracker->AddArgSet({arg0, arg1}, 0, 2);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000616 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100617
618 base::TempFile temp_file = base::TempFile::Create();
619 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100620 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100621
Eric Seckler7fb1d232019-10-23 14:42:43 +0100622 EXPECT_TRUE(status.ok());
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100623
Eric Seckler178094e2019-10-24 14:03:04 +0100624 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100625 EXPECT_EQ(result["traceEvents"].size(), 1u);
626
627 Json::Value event = result["traceEvents"][0];
628 EXPECT_EQ(event["cat"].asString(), kCategory);
629 EXPECT_EQ(event["name"].asString(), kName);
Mikhail Khokhlovc4544ea2019-07-10 14:41:25 +0100630 EXPECT_EQ(event["args"]["a"].size(), 2u);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100631 EXPECT_EQ(event["args"]["a"][0]["b"].asInt(), kValues[0]);
632 EXPECT_EQ(event["args"]["a"][1]["b"].asInt(), kValues[1]);
633}
634
Eric Seckler4b861052019-10-23 14:50:28 +0100635TEST_F(ExportJsonTest, StorageWithNestedListArgs) {
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100636 const char* kCategory = "cat";
637 const char* kName = "name";
638 int kValues[] = {123, 234};
639
Lalit Magantieac7fff2020-01-10 16:42:54 +0000640 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000641 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100642 context_.args_tracker->Flush(); // Flush track args.
643 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
644 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000645 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000646 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100647
Eric Seckler4b861052019-10-23 14:50:28 +0100648 StringId arg_flat_key_id =
649 context_.storage->InternString(base::StringView("a"));
650 StringId arg_key0_id =
651 context_.storage->InternString(base::StringView("a[0][0]"));
652 StringId arg_key1_id =
653 context_.storage->InternString(base::StringView("a[0][1]"));
Lalit Maganti1908e262020-01-09 14:33:19 +0000654 GlobalArgsTracker::Arg arg0;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100655 arg0.flat_key = arg_flat_key_id;
656 arg0.key = arg_key0_id;
657 arg0.value = Variadic::Integer(kValues[0]);
Lalit Maganti1908e262020-01-09 14:33:19 +0000658 GlobalArgsTracker::Arg arg1;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100659 arg1.flat_key = arg_flat_key_id;
660 arg1.key = arg_key1_id;
661 arg1.value = Variadic::Integer(kValues[1]);
Lalit Maganti1908e262020-01-09 14:33:19 +0000662 ArgSetId args = context_.global_args_tracker->AddArgSet({arg0, arg1}, 0, 2);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000663 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100664
665 base::TempFile temp_file = base::TempFile::Create();
666 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100667 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100668
Eric Seckler7fb1d232019-10-23 14:42:43 +0100669 EXPECT_TRUE(status.ok());
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100670
Eric Seckler178094e2019-10-24 14:03:04 +0100671 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100672 EXPECT_EQ(result["traceEvents"].size(), 1u);
673
674 Json::Value event = result["traceEvents"][0];
675 EXPECT_EQ(event["cat"].asString(), kCategory);
676 EXPECT_EQ(event["name"].asString(), kName);
Mikhail Khokhlovc4544ea2019-07-10 14:41:25 +0100677 EXPECT_EQ(event["args"]["a"].size(), 1u);
678 EXPECT_EQ(event["args"]["a"][0].size(), 2u);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100679 EXPECT_EQ(event["args"]["a"][0][0].asInt(), kValues[0]);
680 EXPECT_EQ(event["args"]["a"][0][1].asInt(), kValues[1]);
681}
682
Eric Seckler4b861052019-10-23 14:50:28 +0100683TEST_F(ExportJsonTest, StorageWithLegacyJsonArgs) {
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100684 const char* kCategory = "cat";
685 const char* kName = "name";
686
Lalit Magantieac7fff2020-01-10 16:42:54 +0000687 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000688 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100689 context_.args_tracker->Flush(); // Flush track args.
690 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
691 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000692 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000693 {0, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100694
Eric Seckler4b861052019-10-23 14:50:28 +0100695 StringId arg_key_id = context_.storage->InternString(base::StringView("a"));
696 StringId arg_value_id =
697 context_.storage->InternString(base::StringView("{\"b\":123}"));
Lalit Maganti1908e262020-01-09 14:33:19 +0000698 GlobalArgsTracker::Arg arg;
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100699 arg.flat_key = arg_key_id;
700 arg.key = arg_key_id;
701 arg.value = Variadic::Json(arg_value_id);
Lalit Maganti1908e262020-01-09 14:33:19 +0000702 ArgSetId args = context_.global_args_tracker->AddArgSet({arg}, 0, 1);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000703 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100704
705 base::TempFile temp_file = base::TempFile::Create();
706 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100707 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100708
Eric Seckler7fb1d232019-10-23 14:42:43 +0100709 EXPECT_TRUE(status.ok());
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100710
Eric Seckler178094e2019-10-24 14:03:04 +0100711 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlovc8344972019-07-09 15:46:57 +0100712 EXPECT_EQ(result["traceEvents"].size(), 1u);
713
714 Json::Value event = result["traceEvents"][0];
715 EXPECT_EQ(event["cat"].asString(), kCategory);
716 EXPECT_EQ(event["name"].asString(), kName);
717 EXPECT_EQ(event["args"]["a"]["b"].asInt(), 123);
718}
719
Eric Seckler4b861052019-10-23 14:50:28 +0100720TEST_F(ExportJsonTest, InstantEvent) {
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100721 const int64_t kTimestamp = 10000000;
Eric Secklerc64e19c2020-01-28 15:47:56 +0000722 const int64_t kTimestamp2 = 10001000;
723 const int64_t kTimestamp3 = 10002000;
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100724 const char* kCategory = "cat";
725 const char* kName = "name";
726
Eric Secklerc64e19c2020-01-28 15:47:56 +0000727 // Global legacy track.
Eric Seckler4b861052019-10-23 14:50:28 +0100728 TrackId track =
729 context_.track_tracker->GetOrCreateLegacyChromeGlobalInstantTrack();
730 context_.args_tracker->Flush(); // Flush track args.
731 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
732 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000733 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000734 {kTimestamp, 0, track, cat_id, name_id, 0, 0, 0});
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100735
Eric Secklerc64e19c2020-01-28 15:47:56 +0000736 // Global track.
737 TrackId track2 = context_.track_tracker->GetOrCreateDefaultDescriptorTrack();
738 context_.args_tracker->Flush(); // Flush track args.
739 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000740 {kTimestamp2, 0, track2, cat_id, name_id, 0, 0, 0});
Eric Secklerc64e19c2020-01-28 15:47:56 +0000741
742 // Async event track.
743 context_.track_tracker->ReserveDescriptorChildTrack(1234, 0);
744 TrackId track3 = *context_.track_tracker->GetDescriptorTrack(1234);
745 context_.args_tracker->Flush(); // Flush track args.
746 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000747 {kTimestamp3, 0, track3, cat_id, name_id, 0, 0, 0});
Eric Secklerc64e19c2020-01-28 15:47:56 +0000748
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100749 base::TempFile temp_file = base::TempFile::Create();
750 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100751 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100752
Eric Seckler7fb1d232019-10-23 14:42:43 +0100753 EXPECT_TRUE(status.ok());
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100754
Eric Seckler178094e2019-10-24 14:03:04 +0100755 Json::Value result = ToJsonValue(ReadFile(output));
Eric Secklerc64e19c2020-01-28 15:47:56 +0000756 EXPECT_EQ(result["traceEvents"].size(), 3u);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100757
758 Json::Value event = result["traceEvents"][0];
Eric Seckler9dc34462019-11-06 14:44:20 +0000759 EXPECT_EQ(event["ph"].asString(), "I");
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100760 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
761 EXPECT_EQ(event["s"].asString(), "g");
762 EXPECT_EQ(event["cat"].asString(), kCategory);
763 EXPECT_EQ(event["name"].asString(), kName);
Eric Secklerc64e19c2020-01-28 15:47:56 +0000764
765 Json::Value event2 = result["traceEvents"][1];
766 EXPECT_EQ(event2["ph"].asString(), "I");
767 EXPECT_EQ(event2["ts"].asInt64(), kTimestamp2 / 1000);
768 EXPECT_EQ(event2["s"].asString(), "g");
769 EXPECT_EQ(event2["cat"].asString(), kCategory);
770 EXPECT_EQ(event2["name"].asString(), kName);
771
772 Json::Value event3 = result["traceEvents"][2];
773 EXPECT_EQ(event3["ph"].asString(), "n");
774 EXPECT_EQ(event3["ts"].asInt64(), kTimestamp3 / 1000);
775 EXPECT_EQ(event3["id"].asString(), "0x2");
776 EXPECT_EQ(event3["cat"].asString(), kCategory);
777 EXPECT_EQ(event3["name"].asString(), kName);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100778}
779
Eric Seckler4b861052019-10-23 14:50:28 +0100780TEST_F(ExportJsonTest, InstantEventOnThread) {
781 const int64_t kTimestamp = 10000000;
Eric Secklerbb0e1542020-01-16 13:44:13 +0000782 const uint32_t kThreadID = 100;
Eric Seckler4b861052019-10-23 14:50:28 +0100783 const char* kCategory = "cat";
784 const char* kName = "name";
785
Lalit Magantieac7fff2020-01-10 16:42:54 +0000786 UniqueTid utid = context_.process_tracker->GetOrCreateThread(kThreadID);
Eric Seckler3183c6d2020-01-14 15:45:20 +0000787 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler4b861052019-10-23 14:50:28 +0100788 context_.args_tracker->Flush(); // Flush track args.
789 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
790 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000791 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000792 {kTimestamp, 0, track, cat_id, name_id, 0, 0, 0});
Eric Seckler4b861052019-10-23 14:50:28 +0100793
794 base::TempFile temp_file = base::TempFile::Create();
795 FILE* output = fopen(temp_file.path().c_str(), "w+");
796 util::Status status = ExportJson(context_.storage.get(), output);
797
798 EXPECT_TRUE(status.ok());
799
Eric Seckler178094e2019-10-24 14:03:04 +0100800 Json::Value result = ToJsonValue(ReadFile(output));
Eric Seckler4b861052019-10-23 14:50:28 +0100801 EXPECT_EQ(result["traceEvents"].size(), 1u);
802
803 Json::Value event = result["traceEvents"][0];
Eric Seckler88cab6f2020-01-16 18:33:45 +0000804 EXPECT_EQ(event["tid"].asInt(), static_cast<int>(kThreadID));
Eric Seckler9dc34462019-11-06 14:44:20 +0000805 EXPECT_EQ(event["ph"].asString(), "I");
Eric Seckler4b861052019-10-23 14:50:28 +0100806 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
807 EXPECT_EQ(event["s"].asString(), "t");
808 EXPECT_EQ(event["cat"].asString(), kCategory);
809 EXPECT_EQ(event["name"].asString(), kName);
810}
811
Eric Secklerbb0e1542020-01-16 13:44:13 +0000812TEST_F(ExportJsonTest, DuplicatePidAndTid) {
813 UniqueTid upid1 = context_.process_tracker->StartNewProcess(
814 base::nullopt, base::nullopt, 1, kNullStringId);
815 UniqueTid utid1a = context_.process_tracker->UpdateThread(1, 1);
816 UniqueTid utid1b = context_.process_tracker->UpdateThread(2, 1);
817 UniqueTid utid1c =
818 context_.process_tracker->StartNewThread(base::nullopt, 2, kNullStringId);
819 // Associate the new thread with its process.
820 ASSERT_EQ(utid1c, context_.process_tracker->UpdateThread(2, 1));
821
822 UniqueTid upid2 = context_.process_tracker->StartNewProcess(
823 base::nullopt, base::nullopt, 1, kNullStringId);
824 UniqueTid utid2a = context_.process_tracker->UpdateThread(1, 1);
825 UniqueTid utid2b = context_.process_tracker->UpdateThread(2, 1);
826
827 ASSERT_NE(upid1, upid2);
828 ASSERT_NE(utid1b, utid1c);
829 ASSERT_NE(utid1a, utid2a);
830 ASSERT_NE(utid1b, utid2b);
831 ASSERT_NE(utid1c, utid2b);
832
833 ASSERT_EQ(upid1, *context_.storage->thread_table().upid()[utid1a]);
834 ASSERT_EQ(upid1, *context_.storage->thread_table().upid()[utid1b]);
835 ASSERT_EQ(upid1, *context_.storage->thread_table().upid()[utid1c]);
836 ASSERT_EQ(upid2, *context_.storage->thread_table().upid()[utid2a]);
837 ASSERT_EQ(upid2, *context_.storage->thread_table().upid()[utid2b]);
838
839 TrackId track1a = context_.track_tracker->InternThreadTrack(utid1a);
840 TrackId track1b = context_.track_tracker->InternThreadTrack(utid1b);
841 TrackId track1c = context_.track_tracker->InternThreadTrack(utid1c);
842 TrackId track2a = context_.track_tracker->InternThreadTrack(utid2a);
843 TrackId track2b = context_.track_tracker->InternThreadTrack(utid2b);
844 context_.args_tracker->Flush(); // Flush track args.
845
846 StringId cat_id = context_.storage->InternString(base::StringView("cat"));
847 StringId name1a_id =
848 context_.storage->InternString(base::StringView("name1a"));
849 StringId name1b_id =
850 context_.storage->InternString(base::StringView("name1b"));
851 StringId name1c_id =
852 context_.storage->InternString(base::StringView("name1c"));
853 StringId name2a_id =
854 context_.storage->InternString(base::StringView("name2a"));
855 StringId name2b_id =
856 context_.storage->InternString(base::StringView("name2b"));
857
858 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000859 {10000, 0, track1a, cat_id, name1a_id, 0, 0, 0});
Eric Secklerbb0e1542020-01-16 13:44:13 +0000860 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000861 {20000, 1000, track1b, cat_id, name1b_id, 0, 0, 0});
Eric Secklerbb0e1542020-01-16 13:44:13 +0000862 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000863 {30000, 0, track1c, cat_id, name1c_id, 0, 0, 0});
Eric Secklerbb0e1542020-01-16 13:44:13 +0000864 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000865 {40000, 0, track2a, cat_id, name2a_id, 0, 0, 0});
Eric Secklerbb0e1542020-01-16 13:44:13 +0000866 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000867 {50000, 1000, track2b, cat_id, name2b_id, 0, 0, 0});
Eric Secklerbb0e1542020-01-16 13:44:13 +0000868
869 base::TempFile temp_file = base::TempFile::Create();
870 FILE* output = fopen(temp_file.path().c_str(), "w+");
871 util::Status status = ExportJson(context_.storage.get(), output);
872
873 EXPECT_TRUE(status.ok());
874
875 Json::Value result = ToJsonValue(ReadFile(output));
876 EXPECT_EQ(result["traceEvents"].size(), 5u);
877
Eric Seckler88cab6f2020-01-16 18:33:45 +0000878 EXPECT_EQ(result["traceEvents"][0]["pid"].asInt(), 1);
879 EXPECT_EQ(result["traceEvents"][0]["tid"].asInt(), 1);
Eric Secklerbb0e1542020-01-16 13:44:13 +0000880 EXPECT_EQ(result["traceEvents"][0]["ph"].asString(), "I");
881 EXPECT_EQ(result["traceEvents"][0]["ts"].asInt64(), 10);
882 EXPECT_EQ(result["traceEvents"][0]["cat"].asString(), "cat");
883 EXPECT_EQ(result["traceEvents"][0]["name"].asString(), "name1a");
884
Eric Seckler88cab6f2020-01-16 18:33:45 +0000885 EXPECT_EQ(result["traceEvents"][1]["pid"].asInt(), 1);
886 EXPECT_EQ(result["traceEvents"][1]["tid"].asInt(), 2);
Eric Secklerbb0e1542020-01-16 13:44:13 +0000887 EXPECT_EQ(result["traceEvents"][1]["ph"].asString(), "X");
888 EXPECT_EQ(result["traceEvents"][1]["ts"].asInt64(), 20);
889 EXPECT_EQ(result["traceEvents"][1]["dur"].asInt64(), 1);
890 EXPECT_EQ(result["traceEvents"][1]["cat"].asString(), "cat");
891 EXPECT_EQ(result["traceEvents"][1]["name"].asString(), "name1b");
892
Eric Seckler88cab6f2020-01-16 18:33:45 +0000893 EXPECT_EQ(result["traceEvents"][2]["pid"].asInt(), 1);
894 EXPECT_EQ(result["traceEvents"][2]["tid"].asInt(),
895 static_cast<int>(std::numeric_limits<uint32_t>::max() - 1u));
Eric Secklerbb0e1542020-01-16 13:44:13 +0000896 EXPECT_EQ(result["traceEvents"][2]["ph"].asString(), "I");
897 EXPECT_EQ(result["traceEvents"][2]["ts"].asInt64(), 30);
898 EXPECT_EQ(result["traceEvents"][2]["cat"].asString(), "cat");
899 EXPECT_EQ(result["traceEvents"][2]["name"].asString(), "name1c");
900
Eric Seckler88cab6f2020-01-16 18:33:45 +0000901 EXPECT_EQ(result["traceEvents"][3]["pid"].asInt(),
902 static_cast<int>(std::numeric_limits<uint32_t>::max()));
903 EXPECT_EQ(result["traceEvents"][3]["tid"].asInt(), 1);
Eric Secklerbb0e1542020-01-16 13:44:13 +0000904 EXPECT_EQ(result["traceEvents"][3]["ph"].asString(), "I");
905 EXPECT_EQ(result["traceEvents"][3]["ts"].asInt64(), 40);
906 EXPECT_EQ(result["traceEvents"][3]["cat"].asString(), "cat");
907 EXPECT_EQ(result["traceEvents"][3]["name"].asString(), "name2a");
908
Eric Seckler88cab6f2020-01-16 18:33:45 +0000909 EXPECT_EQ(result["traceEvents"][4]["pid"].asInt(),
910 static_cast<int>(std::numeric_limits<uint32_t>::max()));
911 EXPECT_EQ(result["traceEvents"][4]["tid"].asInt(), 2);
Eric Secklerbb0e1542020-01-16 13:44:13 +0000912 EXPECT_EQ(result["traceEvents"][4]["ph"].asString(), "X");
913 EXPECT_EQ(result["traceEvents"][4]["ts"].asInt64(), 50);
914 EXPECT_EQ(result["traceEvents"][1]["dur"].asInt64(), 1);
915 EXPECT_EQ(result["traceEvents"][4]["cat"].asString(), "cat");
916 EXPECT_EQ(result["traceEvents"][4]["name"].asString(), "name2b");
917}
918
Eric Seckler5f2907d2020-01-06 14:44:05 +0000919TEST_F(ExportJsonTest, AsyncEvents) {
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100920 const int64_t kTimestamp = 10000000;
921 const int64_t kDuration = 100000;
Eric Seckler37d69c12020-01-22 13:59:54 +0000922 const int64_t kTimestamp3 = 10005000;
923 const int64_t kDuration3 = 100000;
Eric Secklerbb0e1542020-01-16 13:44:13 +0000924 const uint32_t kProcessID = 100;
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100925 const char* kCategory = "cat";
926 const char* kName = "name";
Eric Seckler5f2907d2020-01-06 14:44:05 +0000927 const char* kName2 = "name2";
Eric Seckler37d69c12020-01-22 13:59:54 +0000928 const char* kName3 = "name3";
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100929 const char* kArgName = "arg_name";
930 const int kArgValue = 123;
931
Lalit Magantieac7fff2020-01-10 16:42:54 +0000932 UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
Eric Seckler4b861052019-10-23 14:50:28 +0100933 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
934 StringId name_id = context_.storage->InternString(base::StringView(kName));
Eric Seckler5f2907d2020-01-06 14:44:05 +0000935 StringId name2_id = context_.storage->InternString(base::StringView(kName2));
Eric Seckler37d69c12020-01-22 13:59:54 +0000936 StringId name3_id = context_.storage->InternString(base::StringView(kName3));
Lalit Maganti4ea78d92019-09-20 20:20:41 +0100937
Eric Seckler4b861052019-10-23 14:50:28 +0100938 constexpr int64_t kSourceId = 235;
939 TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
940 name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
Lalit Magantif0599a02020-01-15 15:45:20 +0000941 /*source_scope=*/kNullStringId);
Eric Seckler37d69c12020-01-22 13:59:54 +0000942 constexpr int64_t kSourceId2 = 236;
943 TrackId track2 = context_.track_tracker->InternLegacyChromeAsyncTrack(
944 name3_id, upid, kSourceId2, /*source_id_is_process_scoped=*/true,
945 /*source_scope=*/kNullStringId);
Eric Seckler4b861052019-10-23 14:50:28 +0100946 context_.args_tracker->Flush(); // Flush track args.
Lalit Maganti4ea78d92019-09-20 20:20:41 +0100947
Lalit Magantic7ea02e2019-12-12 14:06:49 +0000948 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000949 {kTimestamp, kDuration, track, cat_id, name_id, 0, 0, 0});
Eric Seckler4b861052019-10-23 14:50:28 +0100950 StringId arg_key_id =
951 context_.storage->InternString(base::StringView(kArgName));
Lalit Maganti1908e262020-01-09 14:33:19 +0000952 GlobalArgsTracker::Arg arg;
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100953 arg.flat_key = arg_key_id;
954 arg.key = arg_key_id;
955 arg.value = Variadic::Integer(kArgValue);
Lalit Maganti1908e262020-01-09 14:33:19 +0000956 ArgSetId args = context_.global_args_tracker->AddArgSet({arg}, 0, 1);
Lalit Maganti1308e3f2019-12-09 20:24:20 +0000957 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100958
Eric Seckler5f2907d2020-01-06 14:44:05 +0000959 // Child event with same timestamps as first one.
960 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000961 {kTimestamp, kDuration, track, cat_id, name2_id, 0, 0, 0});
Eric Seckler5f2907d2020-01-06 14:44:05 +0000962
Eric Seckler37d69c12020-01-22 13:59:54 +0000963 // Another overlapping async event on a different track.
964 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +0000965 {kTimestamp3, kDuration3, track2, cat_id, name3_id, 0, 0, 0});
Eric Seckler37d69c12020-01-22 13:59:54 +0000966
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100967 base::TempFile temp_file = base::TempFile::Create();
968 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +0100969 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100970
Eric Seckler7fb1d232019-10-23 14:42:43 +0100971 EXPECT_TRUE(status.ok());
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100972
Eric Seckler178094e2019-10-24 14:03:04 +0100973 Json::Value result = ToJsonValue(ReadFile(output));
Eric Seckler37d69c12020-01-22 13:59:54 +0000974 EXPECT_EQ(result["traceEvents"].size(), 6u);
975
976 // Events should be sorted by timestamp, with child slice's end before its
977 // parent.
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100978
Eric Seckler5f2907d2020-01-06 14:44:05 +0000979 Json::Value begin_event1 = result["traceEvents"][0];
980 EXPECT_EQ(begin_event1["ph"].asString(), "b");
981 EXPECT_EQ(begin_event1["ts"].asInt64(), kTimestamp / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +0000982 EXPECT_EQ(begin_event1["pid"].asInt(), static_cast<int>(kProcessID));
Eric Seckler5f2907d2020-01-06 14:44:05 +0000983 EXPECT_EQ(begin_event1["id2"]["local"].asString(), "0xeb");
984 EXPECT_EQ(begin_event1["cat"].asString(), kCategory);
985 EXPECT_EQ(begin_event1["name"].asString(), kName);
986 EXPECT_EQ(begin_event1["args"][kArgName].asInt(), kArgValue);
987 EXPECT_FALSE(begin_event1.isMember("tts"));
988 EXPECT_FALSE(begin_event1.isMember("use_async_tts"));
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +0100989
Eric Seckler5f2907d2020-01-06 14:44:05 +0000990 Json::Value begin_event2 = result["traceEvents"][1];
991 EXPECT_EQ(begin_event2["ph"].asString(), "b");
992 EXPECT_EQ(begin_event2["ts"].asInt64(), kTimestamp / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +0000993 EXPECT_EQ(begin_event2["pid"].asInt(), static_cast<int>(kProcessID));
Eric Seckler5f2907d2020-01-06 14:44:05 +0000994 EXPECT_EQ(begin_event2["id2"]["local"].asString(), "0xeb");
995 EXPECT_EQ(begin_event2["cat"].asString(), kCategory);
996 EXPECT_EQ(begin_event2["name"].asString(), kName2);
997 EXPECT_TRUE(begin_event2["args"].isObject());
998 EXPECT_EQ(begin_event2["args"].size(), 0u);
999 EXPECT_FALSE(begin_event2.isMember("tts"));
1000 EXPECT_FALSE(begin_event2.isMember("use_async_tts"));
1001
Eric Seckler37d69c12020-01-22 13:59:54 +00001002 Json::Value begin_event3 = result["traceEvents"][2];
1003 EXPECT_EQ(begin_event3["ph"].asString(), "b");
1004 EXPECT_EQ(begin_event3["ts"].asInt64(), kTimestamp3 / 1000);
1005 EXPECT_EQ(begin_event3["pid"].asInt(), static_cast<int>(kProcessID));
1006 EXPECT_EQ(begin_event3["id2"]["local"].asString(), "0xec");
1007 EXPECT_EQ(begin_event3["cat"].asString(), kCategory);
1008 EXPECT_EQ(begin_event3["name"].asString(), kName3);
1009 EXPECT_TRUE(begin_event3["args"].isObject());
1010 EXPECT_EQ(begin_event3["args"].size(), 0u);
1011 EXPECT_FALSE(begin_event3.isMember("tts"));
1012 EXPECT_FALSE(begin_event3.isMember("use_async_tts"));
1013
Eric Seckler5f2907d2020-01-06 14:44:05 +00001014 Json::Value end_event2 = result["traceEvents"][3];
1015 EXPECT_EQ(end_event2["ph"].asString(), "e");
1016 EXPECT_EQ(end_event2["ts"].asInt64(), (kTimestamp + kDuration) / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001017 EXPECT_EQ(end_event2["pid"].asInt(), static_cast<int>(kProcessID));
Eric Seckler5f2907d2020-01-06 14:44:05 +00001018 EXPECT_EQ(end_event2["id2"]["local"].asString(), "0xeb");
1019 EXPECT_EQ(end_event2["cat"].asString(), kCategory);
Eric Seckler37d69c12020-01-22 13:59:54 +00001020 EXPECT_EQ(end_event2["name"].asString(), kName2);
Eric Seckler5f2907d2020-01-06 14:44:05 +00001021 EXPECT_TRUE(end_event2["args"].isObject());
1022 EXPECT_EQ(end_event2["args"].size(), 0u);
1023 EXPECT_FALSE(end_event2.isMember("tts"));
1024 EXPECT_FALSE(end_event2.isMember("use_async_tts"));
1025
Eric Seckler37d69c12020-01-22 13:59:54 +00001026 Json::Value end_event1 = result["traceEvents"][4];
Eric Seckler5f2907d2020-01-06 14:44:05 +00001027 EXPECT_EQ(end_event1["ph"].asString(), "e");
1028 EXPECT_EQ(end_event1["ts"].asInt64(), (kTimestamp + kDuration) / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001029 EXPECT_EQ(end_event1["pid"].asInt(), static_cast<int>(kProcessID));
Eric Seckler5f2907d2020-01-06 14:44:05 +00001030 EXPECT_EQ(end_event1["id2"]["local"].asString(), "0xeb");
1031 EXPECT_EQ(end_event1["cat"].asString(), kCategory);
1032 EXPECT_EQ(end_event1["name"].asString(), kName);
1033 EXPECT_TRUE(end_event1["args"].isObject());
1034 EXPECT_EQ(end_event1["args"].size(), 0u);
1035 EXPECT_FALSE(end_event1.isMember("tts"));
1036 EXPECT_FALSE(end_event1.isMember("use_async_tts"));
Eric Seckler37d69c12020-01-22 13:59:54 +00001037
1038 Json::Value end_event3 = result["traceEvents"][5];
1039 EXPECT_EQ(end_event3["ph"].asString(), "e");
1040 EXPECT_EQ(end_event3["ts"].asInt64(), (kTimestamp3 + kDuration3) / 1000);
1041 EXPECT_EQ(end_event3["pid"].asInt(), static_cast<int>(kProcessID));
1042 EXPECT_EQ(end_event3["id2"]["local"].asString(), "0xec");
1043 EXPECT_EQ(end_event3["cat"].asString(), kCategory);
1044 EXPECT_EQ(end_event3["name"].asString(), kName3);
1045 EXPECT_TRUE(end_event3["args"].isObject());
1046 EXPECT_EQ(end_event3["args"].size(), 0u);
1047 EXPECT_FALSE(end_event3.isMember("tts"));
1048 EXPECT_FALSE(end_event3.isMember("use_async_tts"));
Eric Secklerc63a3af2019-07-25 11:17:37 +01001049}
1050
Eric Seckler4b861052019-10-23 14:50:28 +01001051TEST_F(ExportJsonTest, AsyncEventWithThreadTimestamp) {
Eric Secklerc63a3af2019-07-25 11:17:37 +01001052 const int64_t kTimestamp = 10000000;
1053 const int64_t kDuration = 100000;
1054 const int64_t kThreadTimestamp = 10000001;
1055 const int64_t kThreadDuration = 99998;
Eric Secklerbb0e1542020-01-16 13:44:13 +00001056 const uint32_t kProcessID = 100;
Eric Secklerc63a3af2019-07-25 11:17:37 +01001057 const char* kCategory = "cat";
1058 const char* kName = "name";
1059
Lalit Magantieac7fff2020-01-10 16:42:54 +00001060 UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
Eric Seckler4b861052019-10-23 14:50:28 +01001061 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
1062 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti4ea78d92019-09-20 20:20:41 +01001063
Eric Seckler4b861052019-10-23 14:50:28 +01001064 constexpr int64_t kSourceId = 235;
1065 TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
1066 name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
Lalit Magantif0599a02020-01-15 15:45:20 +00001067 /*source_scope=*/kNullStringId);
Eric Seckler4b861052019-10-23 14:50:28 +01001068 context_.args_tracker->Flush(); // Flush track args.
Lalit Maganti4ea78d92019-09-20 20:20:41 +01001069
Lalit Maganti8d770f72020-01-30 15:44:04 +00001070 auto* slices = context_.storage->mutable_slice_table();
1071 auto id_and_row =
1072 slices->Insert({kTimestamp, kDuration, track, cat_id, name_id, 0, 0, 0});
Eric Seckler4b861052019-10-23 14:50:28 +01001073 context_.storage->mutable_virtual_track_slices()->AddVirtualTrackSlice(
Lalit Maganti8d770f72020-01-30 15:44:04 +00001074 id_and_row.id.value, kThreadTimestamp, kThreadDuration, 0, 0);
Eric Secklerc63a3af2019-07-25 11:17:37 +01001075
1076 base::TempFile temp_file = base::TempFile::Create();
1077 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +01001078 util::Status status = ExportJson(context_.storage.get(), output);
Eric Secklerc63a3af2019-07-25 11:17:37 +01001079
Eric Seckler7fb1d232019-10-23 14:42:43 +01001080 EXPECT_TRUE(status.ok());
Eric Secklerc63a3af2019-07-25 11:17:37 +01001081
Eric Seckler178094e2019-10-24 14:03:04 +01001082 Json::Value result = ToJsonValue(ReadFile(output));
Eric Secklerc63a3af2019-07-25 11:17:37 +01001083 EXPECT_EQ(result["traceEvents"].size(), 2u);
1084
1085 Json::Value begin_event = result["traceEvents"][0];
1086 EXPECT_EQ(begin_event["ph"].asString(), "b");
1087 EXPECT_EQ(begin_event["ts"].asInt64(), kTimestamp / 1000);
1088 EXPECT_EQ(begin_event["tts"].asInt64(), kThreadTimestamp / 1000);
1089 EXPECT_EQ(begin_event["use_async_tts"].asInt(), 1);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001090 EXPECT_EQ(begin_event["pid"].asInt(), static_cast<int>(kProcessID));
Eric Secklerf91236e2019-11-04 10:25:45 +00001091 EXPECT_EQ(begin_event["id2"]["local"].asString(), "0xeb");
Eric Secklerc63a3af2019-07-25 11:17:37 +01001092 EXPECT_EQ(begin_event["cat"].asString(), kCategory);
1093 EXPECT_EQ(begin_event["name"].asString(), kName);
1094
1095 Json::Value end_event = result["traceEvents"][1];
1096 EXPECT_EQ(end_event["ph"].asString(), "e");
1097 EXPECT_EQ(end_event["ts"].asInt64(), (kTimestamp + kDuration) / 1000);
1098 EXPECT_EQ(end_event["tts"].asInt64(),
1099 (kThreadTimestamp + kThreadDuration) / 1000);
1100 EXPECT_EQ(end_event["use_async_tts"].asInt(), 1);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001101 EXPECT_EQ(end_event["pid"].asInt(), static_cast<int>(kProcessID));
Eric Secklerf91236e2019-11-04 10:25:45 +00001102 EXPECT_EQ(end_event["id2"]["local"].asString(), "0xeb");
Eric Secklerc63a3af2019-07-25 11:17:37 +01001103 EXPECT_EQ(end_event["cat"].asString(), kCategory);
1104 EXPECT_EQ(end_event["name"].asString(), kName);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001105}
1106
Eric Seckler4b861052019-10-23 14:50:28 +01001107TEST_F(ExportJsonTest, UnfinishedAsyncEvent) {
Eric Seckler206db472019-07-25 12:05:27 +01001108 const int64_t kTimestamp = 10000000;
1109 const int64_t kDuration = -1;
1110 const int64_t kThreadTimestamp = 10000001;
1111 const int64_t kThreadDuration = -1;
Eric Secklerbb0e1542020-01-16 13:44:13 +00001112 const uint32_t kProcessID = 100;
Eric Seckler206db472019-07-25 12:05:27 +01001113 const char* kCategory = "cat";
1114 const char* kName = "name";
1115
Lalit Magantieac7fff2020-01-10 16:42:54 +00001116 UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
Eric Seckler4b861052019-10-23 14:50:28 +01001117 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
1118 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti4ea78d92019-09-20 20:20:41 +01001119
Eric Seckler4b861052019-10-23 14:50:28 +01001120 constexpr int64_t kSourceId = 235;
1121 TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
1122 name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
Lalit Magantif0599a02020-01-15 15:45:20 +00001123 /*source_scope=*/kNullStringId);
Eric Seckler4b861052019-10-23 14:50:28 +01001124 context_.args_tracker->Flush(); // Flush track args.
Lalit Maganti4ea78d92019-09-20 20:20:41 +01001125
Lalit Maganti8d770f72020-01-30 15:44:04 +00001126 auto slice_id =
1127 context_.storage->mutable_slice_table()
1128 ->Insert({kTimestamp, kDuration, track, cat_id, name_id, 0, 0, 0})
1129 .id;
Eric Seckler4b861052019-10-23 14:50:28 +01001130 context_.storage->mutable_virtual_track_slices()->AddVirtualTrackSlice(
Lalit Magantib0e11f62020-01-02 14:17:58 +00001131 slice_id.value, kThreadTimestamp, kThreadDuration, 0, 0);
Eric Seckler206db472019-07-25 12:05:27 +01001132
1133 base::TempFile temp_file = base::TempFile::Create();
1134 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +01001135 util::Status status = ExportJson(context_.storage.get(), output);
Eric Seckler206db472019-07-25 12:05:27 +01001136
Eric Seckler7fb1d232019-10-23 14:42:43 +01001137 EXPECT_TRUE(status.ok());
Eric Seckler206db472019-07-25 12:05:27 +01001138
Eric Seckler178094e2019-10-24 14:03:04 +01001139 Json::Value result = ToJsonValue(ReadFile(output));
Eric Seckler206db472019-07-25 12:05:27 +01001140 EXPECT_EQ(result["traceEvents"].size(), 1u);
1141
1142 Json::Value begin_event = result["traceEvents"][0];
1143 EXPECT_EQ(begin_event["ph"].asString(), "b");
1144 EXPECT_EQ(begin_event["ts"].asInt64(), kTimestamp / 1000);
1145 EXPECT_EQ(begin_event["tts"].asInt64(), kThreadTimestamp / 1000);
1146 EXPECT_EQ(begin_event["use_async_tts"].asInt(), 1);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001147 EXPECT_EQ(begin_event["pid"].asInt(), static_cast<int>(kProcessID));
Eric Secklerf91236e2019-11-04 10:25:45 +00001148 EXPECT_EQ(begin_event["id2"]["local"].asString(), "0xeb");
Eric Seckler206db472019-07-25 12:05:27 +01001149 EXPECT_EQ(begin_event["cat"].asString(), kCategory);
1150 EXPECT_EQ(begin_event["name"].asString(), kName);
1151}
1152
Eric Seckler4b861052019-10-23 14:50:28 +01001153TEST_F(ExportJsonTest, AsyncInstantEvent) {
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001154 const int64_t kTimestamp = 10000000;
Eric Secklerbb0e1542020-01-16 13:44:13 +00001155 const uint32_t kProcessID = 100;
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001156 const char* kCategory = "cat";
1157 const char* kName = "name";
1158 const char* kArgName = "arg_name";
1159 const int kArgValue = 123;
1160
Lalit Magantieac7fff2020-01-10 16:42:54 +00001161 UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
Eric Seckler4b861052019-10-23 14:50:28 +01001162 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
1163 StringId name_id = context_.storage->InternString(base::StringView(kName));
Lalit Maganti4ea78d92019-09-20 20:20:41 +01001164
Eric Seckler4b861052019-10-23 14:50:28 +01001165 constexpr int64_t kSourceId = 235;
1166 TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
1167 name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
Lalit Magantif0599a02020-01-15 15:45:20 +00001168 /*source_scope=*/kNullStringId);
Eric Seckler4b861052019-10-23 14:50:28 +01001169 context_.args_tracker->Flush(); // Flush track args.
Lalit Maganti4ea78d92019-09-20 20:20:41 +01001170
Lalit Maganti1308e3f2019-12-09 20:24:20 +00001171 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +00001172 {kTimestamp, 0, track, cat_id, name_id, 0, 0, 0});
Eric Seckler4b861052019-10-23 14:50:28 +01001173 StringId arg_key_id =
1174 context_.storage->InternString(base::StringView("arg_name"));
Lalit Maganti1908e262020-01-09 14:33:19 +00001175 GlobalArgsTracker::Arg arg;
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001176 arg.flat_key = arg_key_id;
1177 arg.key = arg_key_id;
1178 arg.value = Variadic::Integer(kArgValue);
Lalit Maganti1908e262020-01-09 14:33:19 +00001179 ArgSetId args = context_.global_args_tracker->AddArgSet({arg}, 0, 1);
Lalit Maganti1308e3f2019-12-09 20:24:20 +00001180 context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001181
1182 base::TempFile temp_file = base::TempFile::Create();
1183 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler4b861052019-10-23 14:50:28 +01001184 util::Status status = ExportJson(context_.storage.get(), output);
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001185
Eric Seckler7fb1d232019-10-23 14:42:43 +01001186 EXPECT_TRUE(status.ok());
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001187
Eric Seckler178094e2019-10-24 14:03:04 +01001188 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001189 EXPECT_EQ(result["traceEvents"].size(), 1u);
1190
1191 Json::Value event = result["traceEvents"][0];
1192 EXPECT_EQ(event["ph"].asString(), "n");
1193 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001194 EXPECT_EQ(event["pid"].asInt(), static_cast<int>(kProcessID));
Eric Secklerf91236e2019-11-04 10:25:45 +00001195 EXPECT_EQ(event["id2"]["local"].asString(), "0xeb");
Mikhail Khokhlov1fad8952019-07-11 14:18:33 +01001196 EXPECT_EQ(event["cat"].asString(), kCategory);
1197 EXPECT_EQ(event["name"].asString(), kName);
1198 EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
1199}
1200
Eric Seckler4b861052019-10-23 14:50:28 +01001201TEST_F(ExportJsonTest, RawEvent) {
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001202 const int64_t kTimestamp = 10000000;
1203 const int64_t kDuration = 10000;
1204 const int64_t kThreadTimestamp = 20000000;
1205 const int64_t kThreadDuration = 20000;
1206 const int64_t kThreadInstructionCount = 30000000;
1207 const int64_t kThreadInstructionDelta = 30000;
Eric Secklerbb0e1542020-01-16 13:44:13 +00001208 const uint32_t kProcessID = 100;
1209 const uint32_t kThreadID = 200;
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001210 const char* kCategory = "cat";
1211 const char* kName = "name";
1212 const char* kPhase = "?";
1213 const uint64_t kGlobalId = 0xaaffaaffaaffaaff;
1214 const char* kIdScope = "my_id";
1215 const uint64_t kBindId = 0xaa00aa00aa00aa00;
1216 const char* kFlowDirection = "inout";
1217 const char* kArgName = "arg_name";
1218 const int kArgValue = 123;
1219
Eric Seckler4b861052019-10-23 14:50:28 +01001220 TraceStorage* storage = context_.storage.get();
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001221
Lalit Magantieac7fff2020-01-10 16:42:54 +00001222 UniqueTid utid = context_.process_tracker->GetOrCreateThread(kThreadID);
1223 UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
1224 context_.storage->mutable_thread_table()->mutable_upid()->Set(utid, upid);
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001225
Lalit Maganti8d770f72020-01-30 15:44:04 +00001226 auto id_and_row = storage->mutable_raw_table()->Insert(
Lalit Maganti679b29d2020-01-13 13:26:28 +00001227 {kTimestamp, storage->InternString("track_event.legacy_event"), /*cpu=*/0,
1228 utid});
Lalit Maganti8d770f72020-01-30 15:44:04 +00001229 auto inserter = context_.args_tracker->AddArgsTo(id_and_row.id);
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001230
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001231 auto add_arg = [&](const char* key, Variadic value) {
1232 StringId key_id = storage->InternString(key);
Lalit Maganti5228f362020-01-15 13:45:56 +00001233 inserter.AddArg(key_id, value);
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001234 };
1235
1236 StringId cat_id = storage->InternString(base::StringView(kCategory));
1237 add_arg("legacy_event.category", Variadic::String(cat_id));
1238 StringId name_id = storage->InternString(base::StringView(kName));
1239 add_arg("legacy_event.name", Variadic::String(name_id));
1240 StringId phase_id = storage->InternString(base::StringView(kPhase));
1241 add_arg("legacy_event.phase", Variadic::String(phase_id));
1242
1243 add_arg("legacy_event.duration_ns", Variadic::Integer(kDuration));
1244 add_arg("legacy_event.thread_timestamp_ns",
1245 Variadic::Integer(kThreadTimestamp));
1246 add_arg("legacy_event.thread_duration_ns",
1247 Variadic::Integer(kThreadDuration));
1248 add_arg("legacy_event.thread_instruction_count",
1249 Variadic::Integer(kThreadInstructionCount));
1250 add_arg("legacy_event.thread_instruction_delta",
1251 Variadic::Integer(kThreadInstructionDelta));
1252 add_arg("legacy_event.use_async_tts", Variadic::Boolean(true));
1253 add_arg("legacy_event.global_id", Variadic::UnsignedInteger(kGlobalId));
1254 StringId scope_id = storage->InternString(base::StringView(kIdScope));
1255 add_arg("legacy_event.id_scope", Variadic::String(scope_id));
1256 add_arg("legacy_event.bind_id", Variadic::UnsignedInteger(kBindId));
1257 add_arg("legacy_event.bind_to_enclosing", Variadic::Boolean(true));
1258 StringId flow_direction_id = storage->InternString(kFlowDirection);
1259 add_arg("legacy_event.flow_direction", Variadic::String(flow_direction_id));
1260
1261 add_arg(kArgName, Variadic::Integer(kArgValue));
1262
Eric Seckler4b861052019-10-23 14:50:28 +01001263 context_.args_tracker->Flush();
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001264
1265 base::TempFile temp_file = base::TempFile::Create();
1266 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler7fb1d232019-10-23 14:42:43 +01001267 util::Status status = ExportJson(storage, output);
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001268
Eric Seckler7fb1d232019-10-23 14:42:43 +01001269 EXPECT_TRUE(status.ok());
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001270
Eric Seckler178094e2019-10-24 14:03:04 +01001271 Json::Value result = ToJsonValue(ReadFile(output));
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001272 EXPECT_EQ(result["traceEvents"].size(), 1u);
1273
1274 Json::Value event = result["traceEvents"][0];
1275 EXPECT_EQ(event["ph"].asString(), kPhase);
1276 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
1277 EXPECT_EQ(event["dur"].asInt64(), kDuration / 1000);
1278 EXPECT_EQ(event["tts"].asInt64(), kThreadTimestamp / 1000);
1279 EXPECT_EQ(event["tdur"].asInt64(), kThreadDuration / 1000);
1280 EXPECT_EQ(event["ticount"].asInt64(), kThreadInstructionCount);
1281 EXPECT_EQ(event["tidelta"].asInt64(), kThreadInstructionDelta);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001282 EXPECT_EQ(event["tid"].asInt(), static_cast<int>(kThreadID));
Eric Secklerc34c8fc2019-08-02 10:57:59 +01001283 EXPECT_EQ(event["cat"].asString(), kCategory);
1284 EXPECT_EQ(event["name"].asString(), kName);
1285 EXPECT_EQ(event["use_async_tts"].asInt(), 1);
1286 EXPECT_EQ(event["id2"]["global"].asString(), "0xaaffaaffaaffaaff");
1287 EXPECT_EQ(event["scope"].asString(), kIdScope);
1288 EXPECT_EQ(event["bind_id"].asString(), "0xaa00aa00aa00aa00");
1289 EXPECT_EQ(event["bp"].asString(), "e");
1290 EXPECT_EQ(event["flow_in"].asBool(), true);
1291 EXPECT_EQ(event["flow_out"].asBool(), true);
1292 EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
1293}
1294
Eric Seckler4b861052019-10-23 14:50:28 +01001295TEST_F(ExportJsonTest, LegacyRawEvents) {
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001296 const char* kLegacyFtraceData = "some \"data\"\nsome :data:";
Eric Seckler13b84b32019-10-04 12:00:38 +01001297 const char* kLegacyJsonData1 = "{\"us";
Eric Seckler178094e2019-10-24 14:03:04 +01001298 const char* kLegacyJsonData2 = "er\": 1},{\"user\": 2}";
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001299
Eric Seckler4b861052019-10-23 14:50:28 +01001300 TraceStorage* storage = context_.storage.get();
Lalit Maganti8d770f72020-01-30 15:44:04 +00001301 auto* raw = storage->mutable_raw_table();
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001302
Lalit Maganti8d770f72020-01-30 15:44:04 +00001303 auto id_and_row = raw->Insert(
Lalit Maganti679b29d2020-01-13 13:26:28 +00001304 {0, storage->InternString("chrome_event.legacy_system_trace"), 0, 0});
Lalit Maganti8d770f72020-01-30 15:44:04 +00001305 auto inserter = context_.args_tracker->AddArgsTo(id_and_row.id);
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001306
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001307 StringId data_id = storage->InternString("data");
1308 StringId ftrace_data_id = storage->InternString(kLegacyFtraceData);
Lalit Maganti5228f362020-01-15 13:45:56 +00001309 inserter.AddArg(data_id, Variadic::String(ftrace_data_id));
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001310
Lalit Maganti8d770f72020-01-30 15:44:04 +00001311 id_and_row = raw->Insert(
Lalit Maganti679b29d2020-01-13 13:26:28 +00001312 {0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0});
Lalit Maganti8d770f72020-01-30 15:44:04 +00001313 inserter = context_.args_tracker->AddArgsTo(id_and_row.id);
Eric Seckler13b84b32019-10-04 12:00:38 +01001314 StringId json_data1_id = storage->InternString(kLegacyJsonData1);
Lalit Maganti5228f362020-01-15 13:45:56 +00001315 inserter.AddArg(data_id, Variadic::String(json_data1_id));
Eric Seckler13b84b32019-10-04 12:00:38 +01001316
Lalit Maganti8d770f72020-01-30 15:44:04 +00001317 id_and_row = raw->Insert(
Lalit Maganti679b29d2020-01-13 13:26:28 +00001318 {0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0});
Lalit Maganti8d770f72020-01-30 15:44:04 +00001319 inserter = context_.args_tracker->AddArgsTo(id_and_row.id);
Eric Seckler13b84b32019-10-04 12:00:38 +01001320 StringId json_data2_id = storage->InternString(kLegacyJsonData2);
Lalit Maganti5228f362020-01-15 13:45:56 +00001321 inserter.AddArg(data_id, Variadic::String(json_data2_id));
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001322
Eric Seckler4b861052019-10-23 14:50:28 +01001323 context_.args_tracker->Flush();
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001324
1325 base::TempFile temp_file = base::TempFile::Create();
1326 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler7fb1d232019-10-23 14:42:43 +01001327 util::Status status = ExportJson(storage, output);
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001328
Eric Seckler7fb1d232019-10-23 14:42:43 +01001329 EXPECT_TRUE(status.ok());
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001330
Eric Seckler178094e2019-10-24 14:03:04 +01001331 Json::Value result = ToJsonValue(ReadFile(output));
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001332
Eric Seckler178094e2019-10-24 14:03:04 +01001333 EXPECT_EQ(result["traceEvents"].size(), 2u);
1334 EXPECT_EQ(result["traceEvents"][0]["user"].asInt(), 1);
1335 EXPECT_EQ(result["traceEvents"][1]["user"].asInt(), 2);
Mikhail Khokhlov9983e162019-08-15 12:04:08 +01001336 EXPECT_EQ(result["systemTraceEvents"].asString(), kLegacyFtraceData);
1337}
1338
Eric Seckler4b861052019-10-23 14:50:28 +01001339TEST_F(ExportJsonTest, CpuProfileEvent) {
Eric Secklerbb0e1542020-01-16 13:44:13 +00001340 const uint32_t kProcessID = 100;
1341 const uint32_t kThreadID = 200;
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001342 const int64_t kTimestamp = 10000000;
1343
Eric Seckler4b861052019-10-23 14:50:28 +01001344 TraceStorage* storage = context_.storage.get();
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001345
Lalit Magantieac7fff2020-01-10 16:42:54 +00001346 UniqueTid utid = context_.process_tracker->GetOrCreateThread(kThreadID);
1347 UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
1348 context_.storage->mutable_thread_table()->mutable_upid()->Set(utid, upid);
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001349
Lalit Maganti8d770f72020-01-30 15:44:04 +00001350 auto* mappings = storage->mutable_stack_profile_mapping_table();
1351 auto* frames = storage->mutable_stack_profile_frame_table();
1352 auto* callsites = storage->mutable_stack_profile_callsite_table();
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001353
Lalit Maganti8d770f72020-01-30 15:44:04 +00001354 auto module_1 =
1355 mappings->Insert({storage->InternString("foo_module_id"), 0, 0, 0, 0, 0,
1356 storage->InternString("foo_module_name")});
1357
1358 auto module_2 =
1359 mappings->Insert({storage->InternString("bar_module_id"), 0, 0, 0, 0, 0,
1360 storage->InternString("bar_module_name")});
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001361
Oystein Eftevaag2ba96d22019-10-14 11:36:56 -07001362 // TODO(140860736): Once we support null values for
1363 // stack_profile_frame.symbol_set_id remove this hack
Lalit Magantif0599a02020-01-15 15:45:20 +00001364 storage->mutable_symbol_table()->Insert({0, kNullStringId, kNullStringId, 0});
Oystein Eftevaag2ba96d22019-10-14 11:36:56 -07001365
Lalit Maganti8d770f72020-01-30 15:44:04 +00001366 auto frame_1 = frames->Insert({/*name_id=*/kNullStringId, module_1.id, 0x42});
Lalit Maganti0a29f6f2020-01-06 12:01:14 +00001367
Lalit Maganti7e24f062019-12-17 18:10:35 +00001368 uint32_t symbol_set_id = storage->symbol_table().row_count();
Oystein Eftevaag2ba96d22019-10-14 11:36:56 -07001369 storage->mutable_symbol_table()->Insert(
1370 {symbol_set_id, storage->InternString("foo_func"),
1371 storage->InternString("foo_file"), 66});
Lalit Maganti8d770f72020-01-30 15:44:04 +00001372 frames->mutable_symbol_set_id()->Set(frame_1.row, symbol_set_id);
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001373
Lalit Maganti8d770f72020-01-30 15:44:04 +00001374 auto frame_2 =
1375 frames->Insert({/*name_id=*/kNullStringId, module_2.id, 0x4242});
Lalit Maganti0a29f6f2020-01-06 12:01:14 +00001376
Lalit Maganti7e24f062019-12-17 18:10:35 +00001377 symbol_set_id = storage->symbol_table().row_count();
Oystein Eftevaag2ba96d22019-10-14 11:36:56 -07001378 storage->mutable_symbol_table()->Insert(
1379 {symbol_set_id, storage->InternString("bar_func"),
1380 storage->InternString("bar_file"), 77});
Lalit Maganti8d770f72020-01-30 15:44:04 +00001381 frames->mutable_symbol_set_id()->Set(frame_2.row, symbol_set_id);
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001382
Lalit Maganti8d770f72020-01-30 15:44:04 +00001383 auto frame_callsite_1 = callsites->Insert({0, base::nullopt, frame_1.id});
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001384
Lalit Maganti8d770f72020-01-30 15:44:04 +00001385 auto frame_callsite_2 =
1386 callsites->Insert({1, frame_callsite_1.id, frame_2.id});
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001387
Lalit Maganti0fd14ef2019-12-18 18:18:44 +00001388 storage->mutable_cpu_profile_stack_sample_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +00001389 {kTimestamp, frame_callsite_2.id, utid});
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001390
1391 base::TempFile temp_file = base::TempFile::Create();
1392 FILE* output = fopen(temp_file.path().c_str(), "w+");
Eric Seckler7fb1d232019-10-23 14:42:43 +01001393 util::Status status = ExportJson(storage, output);
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001394
Eric Seckler7fb1d232019-10-23 14:42:43 +01001395 EXPECT_TRUE(status.ok());
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001396
Eric Seckler178094e2019-10-24 14:03:04 +01001397 Json::Value result = ToJsonValue(ReadFile(output));
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001398
1399 EXPECT_EQ(result["traceEvents"].size(), 1u);
1400 Json::Value event = result["traceEvents"][0];
Oystein Eftevaaga33094d2019-11-12 10:48:15 -08001401 EXPECT_EQ(event["ph"].asString(), "n");
1402 EXPECT_EQ(event["id"].asString(), "0x1");
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001403 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001404 EXPECT_EQ(event["tid"].asInt(), static_cast<int>(kThreadID));
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001405 EXPECT_EQ(event["cat"].asString(), "disabled_by_default-cpu_profiler");
1406 EXPECT_EQ(event["name"].asString(), "StackCpuSampling");
Eric Seckler9dc34462019-11-06 14:44:20 +00001407 EXPECT_EQ(event["s"].asString(), "t");
Oystein Eftevaag85a4cf52019-09-05 11:10:26 -07001408 EXPECT_EQ(event["args"]["frames"].asString(),
1409 "foo_func - foo_module_name [foo_module_id]\nbar_func - "
1410 "bar_module_name [bar_module_id]\n");
1411}
1412
Eric Seckler178094e2019-10-24 14:03:04 +01001413TEST_F(ExportJsonTest, ArgumentFilter) {
Lalit Magantieac7fff2020-01-10 16:42:54 +00001414 UniqueTid utid = context_.process_tracker->GetOrCreateThread(0);
Eric Seckler3183c6d2020-01-14 15:45:20 +00001415 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler178094e2019-10-24 14:03:04 +01001416 context_.args_tracker->Flush(); // Flush track args.
1417
1418 StringId cat_id = context_.storage->InternString(base::StringView("cat"));
1419 std::array<StringId, 3> name_ids{
1420 context_.storage->InternString(base::StringView("name1")),
1421 context_.storage->InternString(base::StringView("name2")),
1422 context_.storage->InternString(base::StringView("name3"))};
1423 StringId arg1_id = context_.storage->InternString(base::StringView("arg1"));
1424 StringId arg2_id = context_.storage->InternString(base::StringView("arg2"));
1425 StringId val_id = context_.storage->InternString(base::StringView("val"));
1426
Lalit Maganti8d770f72020-01-30 15:44:04 +00001427 auto* slices = context_.storage->mutable_slice_table();
Lalit Maganti5228f362020-01-15 13:45:56 +00001428 std::vector<ArgsTracker::BoundInserter> slice_inserters;
Eric Seckler178094e2019-10-24 14:03:04 +01001429 for (size_t i = 0; i < name_ids.size(); i++) {
Lalit Maganti8d770f72020-01-30 15:44:04 +00001430 auto id = slices->Insert({0, 0, track, cat_id, name_ids[i], 0, 0, 0}).id;
1431 slice_inserters.emplace_back(context_.args_tracker->AddArgsTo(id));
Eric Seckler178094e2019-10-24 14:03:04 +01001432 }
1433
Lalit Maganti5228f362020-01-15 13:45:56 +00001434 for (auto& inserter : slice_inserters) {
1435 inserter.AddArg(arg1_id, Variadic::Integer(5))
1436 .AddArg(arg2_id, Variadic::String(val_id));
Eric Seckler178094e2019-10-24 14:03:04 +01001437 }
1438 context_.args_tracker->Flush();
1439
1440 auto arg_filter = [](const char* category_group_name, const char* event_name,
1441 ArgumentNameFilterPredicate* arg_name_filter) {
1442 EXPECT_TRUE(strcmp(category_group_name, "cat") == 0);
1443 if (strcmp(event_name, "name1") == 0) {
1444 // Filter all args for name1.
1445 return false;
1446 } else if (strcmp(event_name, "name2") == 0) {
1447 // Filter only the second arg for name2.
1448 *arg_name_filter = [](const char* arg_name) {
1449 if (strcmp(arg_name, "arg1") == 0) {
1450 return true;
1451 }
1452 EXPECT_TRUE(strcmp(arg_name, "arg2") == 0);
1453 return false;
1454 };
1455 return true;
1456 }
1457 // Filter no args for name3.
1458 EXPECT_TRUE(strcmp(event_name, "name3") == 0);
1459 return true;
1460 };
1461
1462 Json::Value result = ToJsonValue(ToJson(arg_filter));
1463
1464 EXPECT_EQ(result["traceEvents"].size(), 3u);
1465
1466 EXPECT_EQ(result["traceEvents"][0]["cat"].asString(), "cat");
1467 EXPECT_EQ(result["traceEvents"][0]["name"].asString(), "name1");
1468 EXPECT_EQ(result["traceEvents"][0]["args"].asString(), "__stripped__");
1469
1470 EXPECT_EQ(result["traceEvents"][1]["cat"].asString(), "cat");
1471 EXPECT_EQ(result["traceEvents"][1]["name"].asString(), "name2");
1472 EXPECT_EQ(result["traceEvents"][1]["args"]["arg1"].asInt(), 5);
1473 EXPECT_EQ(result["traceEvents"][1]["args"]["arg2"].asString(),
1474 "__stripped__");
1475
1476 EXPECT_EQ(result["traceEvents"][2]["cat"].asString(), "cat");
1477 EXPECT_EQ(result["traceEvents"][2]["name"].asString(), "name3");
1478 EXPECT_EQ(result["traceEvents"][2]["args"]["arg1"].asInt(), 5);
1479 EXPECT_EQ(result["traceEvents"][2]["args"]["arg2"].asString(), "val");
1480}
1481
1482TEST_F(ExportJsonTest, MetadataFilter) {
1483 const char* kName1 = "name1";
1484 const char* kName2 = "name2";
1485 const char* kValue1 = "value1";
1486 const int kValue2 = 222;
1487
1488 TraceStorage* storage = context_.storage.get();
1489
Lalit Maganti8d770f72020-01-30 15:44:04 +00001490 auto* raw = storage->mutable_raw_table();
1491 RawId id =
1492 raw->Insert({0, storage->InternString("chrome_event.metadata"), 0, 0}).id;
Eric Seckler178094e2019-10-24 14:03:04 +01001493
1494 StringId name1_id = storage->InternString(base::StringView(kName1));
1495 StringId name2_id = storage->InternString(base::StringView(kName2));
1496 StringId value1_id = storage->InternString(base::StringView(kValue1));
Lalit Maganti5228f362020-01-15 13:45:56 +00001497
1498 context_.args_tracker->AddArgsTo(id)
1499 .AddArg(name1_id, Variadic::String(value1_id))
1500 .AddArg(name2_id, Variadic::Integer(kValue2));
Eric Seckler178094e2019-10-24 14:03:04 +01001501 context_.args_tracker->Flush();
1502
1503 auto metadata_filter = [](const char* metadata_name) {
1504 // Only allow name1.
1505 return strcmp(metadata_name, "name1") == 0;
1506 };
1507
1508 Json::Value result = ToJsonValue(ToJson(nullptr, metadata_filter));
1509
1510 EXPECT_TRUE(result.isMember("metadata"));
1511 Json::Value metadata = result["metadata"];
1512
1513 EXPECT_EQ(metadata[kName1].asString(), kValue1);
1514 EXPECT_EQ(metadata[kName2].asString(), "__stripped__");
1515}
1516
1517TEST_F(ExportJsonTest, LabelFilter) {
1518 const int64_t kTimestamp1 = 10000000;
1519 const int64_t kTimestamp2 = 20000000;
1520 const int64_t kDuration = 10000;
Eric Secklerbb0e1542020-01-16 13:44:13 +00001521 const uint32_t kThreadID = 100;
Eric Seckler178094e2019-10-24 14:03:04 +01001522 const char* kCategory = "cat";
1523 const char* kName = "name";
1524
Lalit Magantieac7fff2020-01-10 16:42:54 +00001525 UniqueTid utid = context_.process_tracker->GetOrCreateThread(kThreadID);
Eric Seckler3183c6d2020-01-14 15:45:20 +00001526 TrackId track = context_.track_tracker->InternThreadTrack(utid);
Eric Seckler178094e2019-10-24 14:03:04 +01001527 context_.args_tracker->Flush(); // Flush track args.
1528 StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
1529 StringId name_id = context_.storage->InternString(base::StringView(kName));
1530
Lalit Magantic7ea02e2019-12-12 14:06:49 +00001531 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +00001532 {kTimestamp1, kDuration, track, cat_id, name_id, 0, 0, 0});
Lalit Magantic7ea02e2019-12-12 14:06:49 +00001533 context_.storage->mutable_slice_table()->Insert(
Lalit Maganti8d770f72020-01-30 15:44:04 +00001534 {kTimestamp2, kDuration, track, cat_id, name_id, 0, 0, 0});
Eric Seckler178094e2019-10-24 14:03:04 +01001535
1536 auto label_filter = [](const char* label_name) {
1537 return strcmp(label_name, "traceEvents") == 0;
1538 };
1539
1540 Json::Value result =
1541 ToJsonValue("[" + ToJson(nullptr, nullptr, label_filter) + "]");
1542
1543 EXPECT_TRUE(result.isArray());
1544 EXPECT_EQ(result.size(), 2u);
1545
1546 EXPECT_EQ(result[0]["ph"].asString(), "X");
1547 EXPECT_EQ(result[0]["ts"].asInt64(), kTimestamp1 / 1000);
1548 EXPECT_EQ(result[0]["dur"].asInt64(), kDuration / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001549 EXPECT_EQ(result[0]["tid"].asInt(), static_cast<int>(kThreadID));
Eric Seckler178094e2019-10-24 14:03:04 +01001550 EXPECT_EQ(result[0]["cat"].asString(), kCategory);
1551 EXPECT_EQ(result[0]["name"].asString(), kName);
1552 EXPECT_EQ(result[1]["ph"].asString(), "X");
1553 EXPECT_EQ(result[1]["ts"].asInt64(), kTimestamp2 / 1000);
1554 EXPECT_EQ(result[1]["dur"].asInt64(), kDuration / 1000);
Eric Seckler88cab6f2020-01-16 18:33:45 +00001555 EXPECT_EQ(result[1]["tid"].asInt(), static_cast<int>(kThreadID));
Eric Seckler178094e2019-10-24 14:03:04 +01001556 EXPECT_EQ(result[1]["cat"].asString(), kCategory);
1557 EXPECT_EQ(result[1]["name"].asString(), kName);
1558}
Eric Seckler7fb1d232019-10-23 14:42:43 +01001559
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +01001560} // namespace
1561} // namespace json
1562} // namespace trace_processor
1563} // namespace perfetto