1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6
7#include "base/basictypes.h"
8#include "base/json/json_writer.h"
9#include "base/process/process_handle.h"
10#include "base/strings/string_number_conversions.h"
11#include "base/tracked_objects.h"
12#include "base/values.h"
13#include "chrome/browser/task_profiler/task_profiler_data_serializer.h"
14#include "content/public/common/process_type.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace {
18
19std::string GetProcessIdString() {
20  return base::IntToString(base::GetCurrentProcId());
21}
22
23void ExpectSerialization(
24    const tracked_objects::ProcessDataSnapshot& process_data,
25    int process_type,
26    const std::string& expected_json) {
27  base::DictionaryValue serialized_value;
28  task_profiler::TaskProfilerDataSerializer::ToValue(
29      process_data, process_type, &serialized_value);
30
31  std::string serialized_json;
32  base::JSONWriter::Write(&serialized_value, &serialized_json);
33
34  EXPECT_EQ(expected_json, serialized_json);
35}
36
37}  // anonymous namespace
38
39// Tests the JSON serialization format for profiled process data.
40TEST(TaskProfilerDataSerializerTest, SerializeProcessDataToJson) {
41  {
42    // Empty data.
43    tracked_objects::ProcessDataSnapshot process_data;
44    int process_type = content::PROCESS_TYPE_BROWSER;
45    ExpectSerialization(process_data, process_type,
46                        "{"
47                          "\"descendants\":["
48                          "],"
49                          "\"list\":["
50                          "],"
51                          "\"process_id\":" + GetProcessIdString() + ","
52                          "\"process_type\":\"Browser\""
53                        "}");
54  }
55
56  {
57    // Non-empty data.
58    tracked_objects::ProcessDataSnapshot process_data;
59
60    tracked_objects::BirthOnThreadSnapshot parent;
61    parent.location.file_name = "path/to/foo.cc";
62    parent.location.function_name = "WhizBang";
63    parent.location.line_number = 101;
64    parent.thread_name = "CrBrowserMain";
65
66    tracked_objects::BirthOnThreadSnapshot child;
67    child.location.file_name = "path/to/bar.cc";
68    child.location.function_name = "FizzBoom";
69    child.location.line_number = 433;
70    child.thread_name = "Chrome_IOThread";
71
72
73    // Add a snapshot.
74    process_data.tasks.push_back(tracked_objects::TaskSnapshot());
75    process_data.tasks.back().birth = parent;
76    process_data.tasks.back().death_data.count = 37;
77    process_data.tasks.back().death_data.run_duration_max = 5;
78    process_data.tasks.back().death_data.run_duration_sample = 3;
79    process_data.tasks.back().death_data.run_duration_sum = 17;
80    process_data.tasks.back().death_data.queue_duration_max = 53;
81    process_data.tasks.back().death_data.queue_duration_sample = 13;
82    process_data.tasks.back().death_data.queue_duration_sum = 79;
83    process_data.tasks.back().death_thread_name = "WorkerPool/-1340960768";
84
85    // Add a second snapshot.
86    process_data.tasks.push_back(tracked_objects::TaskSnapshot());
87    process_data.tasks.back().birth = child;
88    process_data.tasks.back().death_data.count = 41;
89    process_data.tasks.back().death_data.run_duration_max = 205;
90    process_data.tasks.back().death_data.run_duration_sample = 203;
91    process_data.tasks.back().death_data.run_duration_sum = 2017;
92    process_data.tasks.back().death_data.queue_duration_max = 2053;
93    process_data.tasks.back().death_data.queue_duration_sample = 2013;
94    process_data.tasks.back().death_data.queue_duration_sum = 2079;
95    process_data.tasks.back().death_thread_name = "PAC thread #3";
96
97    // Add a parent-child pair.
98    process_data.descendants.push_back(
99        tracked_objects::ParentChildPairSnapshot());
100    process_data.descendants.back().parent = parent;
101    process_data.descendants.back().child = child;
102
103    int process_type = content::PROCESS_TYPE_RENDERER;
104    ExpectSerialization(process_data, process_type,
105                       "{"
106                          "\"descendants\":["
107                             "{"
108                               "\"child_location\":{"
109                                  "\"file_name\":\"path/to/bar.cc\","
110                                  "\"function_name\":\"FizzBoom\","
111                                 "\"line_number\":433"
112                               "},"
113                               "\"child_thread\":\"Chrome_IOThread\","
114                               "\"parent_location\":{"
115                                  "\"file_name\":\"path/to/foo.cc\","
116                                  "\"function_name\":\"WhizBang\","
117                                  "\"line_number\":101"
118                               "},"
119                               "\"parent_thread\":\"CrBrowserMain\""
120                             "}"
121                          "],"
122                          "\"list\":[{"
123                             "\"birth_location\":{"
124                                "\"file_name\":\"path/to/foo.cc\","
125                                "\"function_name\":\"WhizBang\","
126                                "\"line_number\":101"
127                             "},"
128                             "\"birth_thread\":\"CrBrowserMain\","
129                             "\"death_data\":{"
130                                "\"count\":37,"
131                                "\"queue_ms\":79,"
132                                "\"queue_ms_max\":53,"
133                                "\"queue_ms_sample\":13,"
134                                "\"run_ms\":17,"
135                                "\"run_ms_max\":5,"
136                                "\"run_ms_sample\":3"
137                             "},"
138                             "\"death_thread\":\"WorkerPool/-1340960768\""
139                          "},{"
140                             "\"birth_location\":{"
141                                "\"file_name\":\"path/to/bar.cc\","
142                                "\"function_name\":\"FizzBoom\","
143                                "\"line_number\":433"
144                             "},"
145                             "\"birth_thread\":\"Chrome_IOThread\","
146                             "\"death_data\":{"
147                                "\"count\":41,"
148                                "\"queue_ms\":2079,"
149                                "\"queue_ms_max\":2053,"
150                                "\"queue_ms_sample\":2013,"
151                                "\"run_ms\":2017,"
152                                "\"run_ms_max\":205,"
153                                "\"run_ms_sample\":203"
154                             "},"
155                             "\"death_thread\":\"PAC thread #3\""
156                          "}],"
157                          "\"process_id\":" + GetProcessIdString() + ","
158                          "\"process_type\":\"Tab\""
159                        "}");
160  }
161}
162