blob: d2180c87030d7c53713f17d61a4799df834ee16d [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
17#include "src/trace_processor/export_json.h"
18
Primiano Tucci2c5488f2019-06-01 03:27:28 +010019#include "perfetto/ext/base/temp_file.h"
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010020
Hector Dearmancdfd85b2019-05-31 16:49:14 +010021#include <gmock/gmock.h>
22#include <gtest/gtest.h>
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010023
24#include <json/reader.h>
25#include <json/value.h>
26
27namespace perfetto {
28namespace trace_processor {
29namespace json {
30namespace {
31
32std::string ReadFile(FILE* input) {
33 fseek(input, 0, SEEK_SET);
34 const int kBufSize = 1000;
35 char buffer[kBufSize];
Lalit Magantid9983462019-05-09 18:10:09 +010036 size_t ret = fread(buffer, sizeof(char), kBufSize, input);
37 EXPECT_GT(ret, 0);
38 return std::string(buffer, ret);
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +010039}
40
41TEST(ExportJsonTest, EmptyStorage) {
42 TraceStorage storage;
43
44 base::TempFile temp_file = base::TempFile::Create();
45 FILE* output = fopen(temp_file.path().c_str(), "w+");
46 int code = ExportJson(&storage, output);
47
48 EXPECT_EQ(code, kResultOk);
49
50 Json::Reader reader;
51 Json::Value result;
52
53 EXPECT_TRUE(reader.parse(ReadFile(output), result));
54 EXPECT_EQ(result["traceEvents"].size(), 0);
55}
56
57TEST(ExportJsonTest, StorageWithOneSlice) {
58 const int64_t kTimestamp = 10000000;
59 const int64_t kDuration = 10000;
60 const int64_t kThreadID = 100;
61 const char* kCategory = "cat";
62 const char* kName = "name";
63
64 TraceStorage storage;
65 UniqueTid utid = storage.AddEmptyThread(kThreadID);
66 StringId cat_id = storage.InternString(base::StringView(kCategory));
67 StringId name_id = storage.InternString(base::StringView(kName));
68 storage.mutable_nestable_slices()->AddSlice(
69 kTimestamp, kDuration, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
70
71 base::TempFile temp_file = base::TempFile::Create();
72 FILE* output = fopen(temp_file.path().c_str(), "w+");
73 int code = ExportJson(&storage, output);
74
75 EXPECT_EQ(code, kResultOk);
76
77 Json::Reader reader;
78 Json::Value result;
79 EXPECT_TRUE(reader.parse(ReadFile(output), result));
80 EXPECT_EQ(result["traceEvents"].size(), 1);
81
82 Json::Value event = result["traceEvents"][0];
83 EXPECT_EQ(event["ph"].asString(), "X");
84 EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
85 EXPECT_EQ(event["dur"].asInt64(), kDuration / 1000);
86 EXPECT_EQ(event["tid"].asUInt(), kThreadID);
87 EXPECT_EQ(event["cat"].asString(), kCategory);
88 EXPECT_EQ(event["name"].asString(), kName);
89}
90
91TEST(ExportJsonTest, StorageWithThreadName) {
92 const int64_t kThreadID = 100;
93 const char* kName = "thread";
94
95 TraceStorage storage;
96 UniqueTid utid = storage.AddEmptyThread(kThreadID);
97 StringId name_id = storage.InternString(base::StringView(kName));
98 storage.GetMutableThread(utid)->name_id = name_id;
99
100 base::TempFile temp_file = base::TempFile::Create();
101 FILE* output = fopen(temp_file.path().c_str(), "w+");
102 int code = ExportJson(&storage, output);
103
104 EXPECT_EQ(code, kResultOk);
105
106 Json::Reader reader;
107 Json::Value result;
108 EXPECT_TRUE(reader.parse(ReadFile(output), result));
109 EXPECT_EQ(result["traceEvents"].size(), 1);
110
111 Json::Value event = result["traceEvents"][0];
112 EXPECT_EQ(event["ph"].asString(), "M");
113 EXPECT_EQ(event["tid"].asUInt(), kThreadID);
114 EXPECT_EQ(event["name"].asString(), "thread_name");
115 EXPECT_EQ(event["args"]["name"].asString(), kName);
116}
117
118TEST(ExportJsonTest, WrongRefType) {
119 TraceStorage storage;
120 storage.mutable_nestable_slices()->AddSlice(0, 0, 0, RefType::kRefCpuId, 0, 0,
121 0, 0, 0);
122
123 base::TempFile temp_file = base::TempFile::Create();
124 FILE* output = fopen(temp_file.path().c_str(), "w+");
125 int code = ExportJson(&storage, output);
126
127 EXPECT_EQ(code, kResultWrongRefType);
128}
129
Mikhail Khokhlovdb84f102019-05-24 15:25:47 +0100130TEST(ExportJsonTest, StorageWithMetadata) {
131 const char* kDescription = "description";
132 const char* kBenchmarkName = "benchmark name";
133 const char* kStoryName = "story name";
134 const char* kStoryTag1 = "tag1";
135 const char* kStoryTag2 = "tag2";
136 const int64_t kBenchmarkStart = 1000000;
137 const int64_t kStoryStart = 2000000;
138 const bool kHadFailures = true;
139
140 TraceStorage storage;
141
142 StringId desc_id = storage.InternString(base::StringView(kDescription));
143 Variadic description = Variadic::String(desc_id);
144 storage.SetMetadata(metadata::benchmark_description, description);
145
146 StringId benchmark_name_id =
147 storage.InternString(base::StringView(kBenchmarkName));
148 Variadic benchmark_name = Variadic::String(benchmark_name_id);
149 storage.SetMetadata(metadata::benchmark_name, benchmark_name);
150
151 StringId story_name_id = storage.InternString(base::StringView(kStoryName));
152 Variadic story_name = Variadic::String(story_name_id);
153 storage.SetMetadata(metadata::benchmark_story_name, story_name);
154
155 StringId tag1_id = storage.InternString(base::StringView(kStoryTag1));
156 StringId tag2_id = storage.InternString(base::StringView(kStoryTag2));
157 Variadic tag1 = Variadic::String(tag1_id);
158 Variadic tag2 = Variadic::String(tag2_id);
159 storage.AppendMetadata(metadata::benchmark_story_tags, tag1);
160 storage.AppendMetadata(metadata::benchmark_story_tags, tag2);
161
162 Variadic benchmark_start = Variadic::Integer(kBenchmarkStart);
163 storage.SetMetadata(metadata::benchmark_start_time_us, benchmark_start);
164
165 Variadic story_start = Variadic::Integer(kStoryStart);
166 storage.SetMetadata(metadata::benchmark_story_run_time_us, story_start);
167
168 Variadic had_failures = Variadic::Integer(kHadFailures);
169 storage.SetMetadata(metadata::benchmark_had_failures, had_failures);
170
171 base::TempFile temp_file = base::TempFile::Create();
172 FILE* output = fopen(temp_file.path().c_str(), "w+");
173 int code = ExportJson(&storage, output);
174
175 EXPECT_EQ(code, kResultOk);
176
177 Json::Reader reader;
178 Json::Value result;
179
180 EXPECT_TRUE(reader.parse(ReadFile(output), result));
181 EXPECT_TRUE(result.isMember("metadata"));
182 EXPECT_TRUE(result["metadata"].isMember("telemetry"));
183 Json::Value telemetry_metadata = result["metadata"]["telemetry"];
184
185 EXPECT_EQ(telemetry_metadata["benchmarkDescriptions"].size(), 1);
186 EXPECT_EQ(telemetry_metadata["benchmarkDescriptions"][0].asString(),
187 kDescription);
188
189 EXPECT_EQ(telemetry_metadata["benchmarks"].size(), 1);
190 EXPECT_EQ(telemetry_metadata["benchmarks"][0].asString(), kBenchmarkName);
191
192 EXPECT_EQ(telemetry_metadata["stories"].size(), 1);
193 EXPECT_EQ(telemetry_metadata["stories"][0].asString(), kStoryName);
194
195 EXPECT_EQ(telemetry_metadata["storyTags"].size(), 2);
196 EXPECT_EQ(telemetry_metadata["storyTags"][0].asString(), kStoryTag1);
197 EXPECT_EQ(telemetry_metadata["storyTags"][1].asString(), kStoryTag2);
198
199 EXPECT_EQ(telemetry_metadata["benchmarkStart"].asInt(),
200 kBenchmarkStart / 1000.0);
201
202 EXPECT_EQ(telemetry_metadata["traceStart"].asInt(), kStoryStart / 1000.0);
203
204 EXPECT_EQ(telemetry_metadata["hadFailures"].size(), 1);
205 EXPECT_EQ(telemetry_metadata["hadFailures"][0].asBool(), kHadFailures);
206}
207
Mikhail Khokhlova8d310d2019-05-07 17:34:21 +0100208} // namespace
209} // namespace json
210} // namespace trace_processor
211} // namespace perfetto