- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / chromedriver / chrome / heap_snapshot_taker_unittest.cc
1 // Copyright 2013 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 <list>
6 #include <string>
7
8 #include "base/memory/scoped_ptr.h"
9 #include "base/values.h"
10 #include "chrome/test/chromedriver/chrome/heap_snapshot_taker.h"
11 #include "chrome/test/chromedriver/chrome/status.h"
12 #include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace {
16
17 const char* chunks[] = {"{\"a\": 1,", "\"b\": 2}"};
18
19 scoped_ptr<base::Value> GetSnapshotAsValue() {
20   scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
21   dict->SetInteger("a", 1);
22   dict->SetInteger("b", 2);
23   return dict.PassAs<base::Value>();
24 }
25
26 class DummyDevToolsClient : public StubDevToolsClient {
27  public:
28   DummyDevToolsClient(const std::string& method, bool error_after_events)
29       : method_(method),
30         error_after_events_(error_after_events),
31         uid_(1),
32         cleared_(false),
33         disabled_(false) {}
34   virtual ~DummyDevToolsClient() {}
35
36   bool IsCleared() { return cleared_; }
37
38   bool IsDisabled() { return disabled_; }
39
40   virtual Status SendAddProfileHeaderEvent() {
41     base::DictionaryValue event_params;
42     event_params.SetInteger("header.uid", uid_);
43     return listeners_.front()->OnEvent(
44         this, "HeapProfiler.addProfileHeader", event_params);
45   }
46
47   virtual Status SendAddHeapSnapshotChunkEvent() {
48     base::DictionaryValue event_params;
49     event_params.SetInteger("uid", uid_);
50     for (size_t i = 0; i < arraysize(chunks); ++i) {
51       event_params.SetString("chunk", chunks[i]);
52       Status status = listeners_.front()->OnEvent(
53           this, "HeapProfiler.addHeapSnapshotChunk", event_params);
54       if (status.IsError())
55         return status;
56     }
57     return Status(kOk);
58   }
59
60   // Overridden from DevToolsClient:
61   virtual Status SendCommand(const std::string& method,
62                              const base::DictionaryValue& params) OVERRIDE {
63     if (!cleared_)
64       cleared_ = method == "HeapProfiler.clearProfiles";
65     if (!disabled_)
66       disabled_ = method == "Debugger.disable";
67     if (method == method_ && !error_after_events_)
68       return Status(kUnknownError);
69
70     if (method == "HeapProfiler.takeHeapSnapshot") {
71       Status status = SendAddProfileHeaderEvent();
72       if (status.IsError())
73         return status;
74     } else if (method == "HeapProfiler.getHeapSnapshot") {
75       Status status = SendAddHeapSnapshotChunkEvent();
76       if (status.IsError())
77         return status;
78     }
79
80     if (method == method_ && error_after_events_)
81       return Status(kUnknownError);
82     return StubDevToolsClient::SendCommand(method, params);
83   }
84
85  protected:
86   std::string method_;  // Throw error on command with this method.
87   bool error_after_events_;
88   int uid_;
89   bool cleared_;  // True if HeapProfiler.clearProfiles was issued.
90   bool disabled_;  // True if Debugger.disable was issued.
91 };
92
93 }  // namespace
94
95 TEST(HeapSnapshotTaker, SuccessfulCase) {
96   DummyDevToolsClient client("", false);
97   HeapSnapshotTaker taker(&client);
98   scoped_ptr<base::Value> snapshot;
99   Status status = taker.TakeSnapshot(&snapshot);
100   ASSERT_EQ(kOk, status.code());
101   ASSERT_TRUE(GetSnapshotAsValue()->Equals(snapshot.get()));
102   ASSERT_TRUE(client.IsCleared());
103   ASSERT_TRUE(client.IsDisabled());
104 }
105
106 TEST(HeapSnapshotTaker, FailIfErrorOnDebuggerEnable) {
107   DummyDevToolsClient client("Debugger.enable", false);
108   HeapSnapshotTaker taker(&client);
109   scoped_ptr<base::Value> snapshot;
110   Status status = taker.TakeSnapshot(&snapshot);
111   ASSERT_TRUE(status.IsError());
112   ASSERT_FALSE(snapshot.get());
113   ASSERT_FALSE(client.IsCleared());
114   ASSERT_TRUE(client.IsDisabled());
115 }
116
117 TEST(HeapSnapshotTaker, FailIfErrorOnCollectGarbage) {
118   DummyDevToolsClient client("HeapProfiler.collectGarbage", false);
119   HeapSnapshotTaker taker(&client);
120   scoped_ptr<base::Value> snapshot;
121   Status status = taker.TakeSnapshot(&snapshot);
122   ASSERT_TRUE(status.IsError());
123   ASSERT_FALSE(snapshot.get());
124   ASSERT_FALSE(client.IsCleared());
125   ASSERT_TRUE(client.IsDisabled());
126 }
127
128 TEST(HeapSnapshotTaker, ErrorBeforeReceivingUid) {
129   DummyDevToolsClient client("HeapProfiler.takeHeapSnapshot", false);
130   HeapSnapshotTaker taker(&client);
131   scoped_ptr<base::Value> snapshot;
132   Status status = taker.TakeSnapshot(&snapshot);
133   ASSERT_TRUE(status.IsError());
134   ASSERT_FALSE(snapshot.get());
135   ASSERT_FALSE(client.IsCleared());
136   ASSERT_TRUE(client.IsDisabled());
137 }
138
139 TEST(HeapSnapshotTaker, ErrorAfterReceivingUid) {
140   DummyDevToolsClient client("HeapProfiler.takeHeapSnapshot", true);
141   HeapSnapshotTaker taker(&client);
142   scoped_ptr<base::Value> snapshot;
143   Status status = taker.TakeSnapshot(&snapshot);
144   ASSERT_TRUE(status.IsError());
145   ASSERT_FALSE(snapshot.get());
146   ASSERT_TRUE(client.IsCleared());
147   ASSERT_TRUE(client.IsDisabled());
148 }
149
150 namespace {
151
152 class TwoUidEventClient : public DummyDevToolsClient {
153  public:
154   TwoUidEventClient() : DummyDevToolsClient("", false) {}
155   virtual ~TwoUidEventClient() {}
156
157   // Overridden from DummyDevToolsClient:
158   virtual Status SendAddProfileHeaderEvent() OVERRIDE {
159     Status status = DummyDevToolsClient::SendAddProfileHeaderEvent();
160     if (status.IsError())
161       return status;
162     uid_ = 2;
163     status = DummyDevToolsClient::SendAddProfileHeaderEvent();
164     uid_ = 1;
165     return status;
166   }
167 };
168
169 }  // namespace
170
171 TEST(HeapSnapshotTaker, MuiltipleUidEvents) {
172   TwoUidEventClient client;
173   HeapSnapshotTaker taker(&client);
174   scoped_ptr<base::Value> snapshot;
175   Status status = taker.TakeSnapshot(&snapshot);
176   ASSERT_EQ(kOk, status.code());
177   ASSERT_TRUE(GetSnapshotAsValue()->Equals(snapshot.get()));
178   ASSERT_TRUE(client.IsCleared());
179   ASSERT_TRUE(client.IsDisabled());
180 }
181
182 namespace {
183
184 class ChunkWithDifferentUidClient : public DummyDevToolsClient {
185  public:
186   ChunkWithDifferentUidClient() : DummyDevToolsClient("", false) {}
187   virtual ~ChunkWithDifferentUidClient() {}
188
189   // Overridden from DummyDevToolsClient:
190   virtual Status SendAddHeapSnapshotChunkEvent() OVERRIDE {
191     Status status = DummyDevToolsClient::SendAddHeapSnapshotChunkEvent();
192     if (status.IsError())
193       return status;
194     uid_ = 2;
195     status = DummyDevToolsClient::SendAddHeapSnapshotChunkEvent();
196     uid_ = 1;
197     return status;
198   }
199 };
200
201 }  // namespace
202
203 TEST(HeapSnapshotTaker, IgnoreChunkWithDifferentUid) {
204   ChunkWithDifferentUidClient client;
205   HeapSnapshotTaker taker(&client);
206   scoped_ptr<base::Value> snapshot;
207   Status status = taker.TakeSnapshot(&snapshot);
208   ASSERT_EQ(kOk, status.code());
209   ASSERT_TRUE(GetSnapshotAsValue()->Equals(snapshot.get()));
210   ASSERT_TRUE(client.IsCleared());
211   ASSERT_TRUE(client.IsDisabled());
212 }
213
214 TEST(HeapSnapshotTaker, ErrorAfterFinishEvent) {
215   DummyDevToolsClient client("HeapProfiler.getHeapSnapshot", true);
216   HeapSnapshotTaker taker(&client);
217   scoped_ptr<base::Value> snapshot;
218   Status status = taker.TakeSnapshot(&snapshot);
219   ASSERT_TRUE(status.IsError());
220   ASSERT_FALSE(snapshot.get());
221   ASSERT_TRUE(client.IsCleared());
222   ASSERT_TRUE(client.IsDisabled());
223 }