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 15namespace { 16 17const char* chunks[] = {"{\"a\": 1,", "\"b\": 2}"}; 18 19scoped_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 26class 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 disabled_(false) {} 33 virtual ~DummyDevToolsClient() {} 34 35 bool IsDisabled() { return disabled_; } 36 37 Status SendAddHeapSnapshotChunkEvent() { 38 base::DictionaryValue event_params; 39 event_params.SetInteger("uid", uid_); 40 for (size_t i = 0; i < arraysize(chunks); ++i) { 41 event_params.SetString("chunk", chunks[i]); 42 Status status = listeners_.front()->OnEvent( 43 this, "HeapProfiler.addHeapSnapshotChunk", event_params); 44 if (status.IsError()) 45 return status; 46 } 47 return Status(kOk); 48 } 49 50 // Overridden from DevToolsClient: 51 virtual Status SendCommand(const std::string& method, 52 const base::DictionaryValue& params) OVERRIDE { 53 if (!disabled_) 54 disabled_ = method == "Debugger.disable"; 55 if (method == method_ && !error_after_events_) 56 return Status(kUnknownError); 57 58 if (method == "HeapProfiler.takeHeapSnapshot") { 59 Status status = SendAddHeapSnapshotChunkEvent(); 60 if (status.IsError()) 61 return status; 62 } 63 64 if (method == method_ && error_after_events_) 65 return Status(kUnknownError); 66 return StubDevToolsClient::SendCommand(method, params); 67 } 68 69 protected: 70 std::string method_; // Throw error on command with this method. 71 bool error_after_events_; 72 int uid_; 73 bool disabled_; // True if Debugger.disable was issued. 74}; 75 76} // namespace 77 78TEST(HeapSnapshotTaker, SuccessfulCase) { 79 DummyDevToolsClient client("", false); 80 HeapSnapshotTaker taker(&client); 81 scoped_ptr<base::Value> snapshot; 82 Status status = taker.TakeSnapshot(&snapshot); 83 ASSERT_EQ(kOk, status.code()); 84 ASSERT_TRUE(GetSnapshotAsValue()->Equals(snapshot.get())); 85 ASSERT_TRUE(client.IsDisabled()); 86} 87 88TEST(HeapSnapshotTaker, FailIfErrorOnDebuggerEnable) { 89 DummyDevToolsClient client("Debugger.enable", false); 90 HeapSnapshotTaker taker(&client); 91 scoped_ptr<base::Value> snapshot; 92 Status status = taker.TakeSnapshot(&snapshot); 93 ASSERT_TRUE(status.IsError()); 94 ASSERT_FALSE(snapshot.get()); 95 ASSERT_TRUE(client.IsDisabled()); 96} 97 98TEST(HeapSnapshotTaker, FailIfErrorOnCollectGarbage) { 99 DummyDevToolsClient client("HeapProfiler.collectGarbage", false); 100 HeapSnapshotTaker taker(&client); 101 scoped_ptr<base::Value> snapshot; 102 Status status = taker.TakeSnapshot(&snapshot); 103 ASSERT_TRUE(status.IsError()); 104 ASSERT_FALSE(snapshot.get()); 105 ASSERT_TRUE(client.IsDisabled()); 106} 107 108TEST(HeapSnapshotTaker, ErrorBeforeWhenReceivingSnapshot) { 109 DummyDevToolsClient client("HeapProfiler.takeHeapSnapshot", false); 110 HeapSnapshotTaker taker(&client); 111 scoped_ptr<base::Value> snapshot; 112 Status status = taker.TakeSnapshot(&snapshot); 113 ASSERT_TRUE(status.IsError()); 114 ASSERT_FALSE(snapshot.get()); 115 ASSERT_TRUE(client.IsDisabled()); 116} 117 118