1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/util/extensions_activity_monitor.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/waitable_event.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/values.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_bookmarks_module.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_constants.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::ExtensionsActivityMonitor;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace keys = extension_manifest_keys;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst FilePath::CharType kTestExtensionPath1[] =
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_POSIX)
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FILE_PATH_LITERAL("/testextension1");
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN)
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FILE_PATH_LITERAL("c:\\testextension1");
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst FilePath::CharType kTestExtensionPath2[] =
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_POSIX)
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FILE_PATH_LITERAL("/testextension2");
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN)
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FILE_PATH_LITERAL("c:\\testextension2");
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* kTestExtensionVersion = "1.0.0.0";
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* kTestExtensionName = "foo extension";
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class FunctionType>
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BookmarkAPIEventTask : public Task {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkAPIEventTask(FunctionType* t, Extension* e, size_t repeats,
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       base::WaitableEvent* done) :
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       extension_(e), function_(t), repeats_(repeats), done_(done) {}
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   virtual void Run() {
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     for (size_t i = 0; i < repeats_; i++) {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       NotificationService::current()->Notify(
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           NotificationType::EXTENSION_BOOKMARKS_API_INVOKED,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           Source<Extension>(extension_.get()),
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           Details<const BookmarksFunction>(function_.get()));
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     }
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     done_->Signal();
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   }
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<Extension> extension_;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<FunctionType> function_;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t repeats_;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::WaitableEvent* done_;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BookmarkAPIEventTask);
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BookmarkAPIEventGenerator {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkAPIEventGenerator() {}
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~BookmarkAPIEventGenerator() {}
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  template <class T>
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void NewEvent(const FilePath::StringType& extension_path,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      T* bookmarks_function, size_t repeats) {
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string error;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue input;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    input.SetString(keys::kVersion, kTestExtensionVersion);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    input.SetString(keys::kName, kTestExtensionName);
75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<Extension> extension(Extension::Create(
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        FilePath(extension_path), Extension::INVALID, input,
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        Extension::STRICT_ERROR_CHECKS, &error));
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bookmarks_function->set_name(T::function_name());
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::WaitableEvent done_event(false, false);
80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new BookmarkAPIEventTask<T>(bookmarks_function, extension,
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    repeats, &done_event));
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    done_event.Wait();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BookmarkAPIEventGenerator);
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DoUIThreadSetupTask : public Task {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DoUIThreadSetupTask(NotificationService** service,
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      base::WaitableEvent* done)
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : service_(service), signal_when_done_(done) {}
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~DoUIThreadSetupTask() {}
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Run() {
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *service_ = new NotificationService();
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    signal_when_done_->Signal();
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService** service_;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::WaitableEvent* signal_when_done_;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(DoUIThreadSetupTask);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionsActivityMonitorTest : public testing::Test {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitorTest() : service_(NULL),
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ui_thread_(BrowserThread::UI) { }
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~ExtensionsActivityMonitorTest() {}
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_thread_.Start();
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::WaitableEvent service_created(false, false);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_thread_.message_loop()->PostTask(FROM_HERE,
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new DoUIThreadSetupTask(&service_, &service_created));
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_created.Wait();
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_thread_.message_loop()->DeleteSoon(FROM_HERE, service_);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_thread_.Stop();
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop* ui_loop() { return ui_thread_.message_loop(); }
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static std::string GetExtensionIdForPath(
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const FilePath::StringType& extension_path) {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string error;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue input;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    input.SetString(keys::kVersion, kTestExtensionVersion);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    input.SetString(keys::kName, kTestExtensionName);
134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<Extension> extension(Extension::Create(
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        FilePath(extension_path), Extension::INVALID, input,
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        Extension::STRICT_ERROR_CHECKS, &error));
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("", error);
138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return extension->id();
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService* service_;
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread ui_thread_;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ExtensionsActivityMonitorTest, Basic) {
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor* monitor = new ExtensionsActivityMonitor();
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkAPIEventGenerator generator;
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<RemoveBookmarkFunction>(kTestExtensionPath1,
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new RemoveBookmarkFunction(), 1);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<MoveBookmarkFunction>(kTestExtensionPath1,
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new MoveBookmarkFunction(), 1);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<UpdateBookmarkFunction>(kTestExtensionPath1,
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new UpdateBookmarkFunction(), 2);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<CreateBookmarkFunction>(kTestExtensionPath1,
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new CreateBookmarkFunction(), 3);
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<SearchBookmarksFunction>(kTestExtensionPath1,
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new SearchBookmarksFunction(), 5);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const uint32 writes_by_extension1 = 1 + 1 + 2 + 3;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<RemoveTreeBookmarkFunction>(kTestExtensionPath2,
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new RemoveTreeBookmarkFunction(), 8);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<GetBookmarkTreeFunction>(kTestExtensionPath2,
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new GetBookmarkTreeFunction(), 13);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<GetBookmarkChildrenFunction>(kTestExtensionPath2,
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new GetBookmarkChildrenFunction(), 21);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<GetBookmarksFunction>(kTestExtensionPath2,
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new GetBookmarksFunction(), 33);
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const uint32 writes_by_extension2 = 8;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor::Records results;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->GetAndClearRecords(&results);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id1 = GetExtensionIdForPath(kTestExtensionPath1);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id2 = GetExtensionIdForPath(kTestExtensionPath2);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, results.size());
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(results.end() != results.find(id1));
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(results.end() != results.find(id2));
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(writes_by_extension1, results[id1].bookmark_write_count);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(writes_by_extension2, results[id2].bookmark_write_count);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_loop()->DeleteSoon(FROM_HERE, monitor);
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ExtensionsActivityMonitorTest, Put) {
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor* monitor = new ExtensionsActivityMonitor();
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkAPIEventGenerator generator;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id1 = GetExtensionIdForPath(kTestExtensionPath1);
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id2 = GetExtensionIdForPath(kTestExtensionPath2);
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<CreateBookmarkFunction>(kTestExtensionPath1,
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new CreateBookmarkFunction(), 5);
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<MoveBookmarkFunction>(kTestExtensionPath2,
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new MoveBookmarkFunction(), 8);
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor::Records results;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->GetAndClearRecords(&results);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, results.size());
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5U, results[id1].bookmark_write_count);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(8U, results[id2].bookmark_write_count);
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<GetBookmarksFunction>(kTestExtensionPath2,
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new GetBookmarksFunction(), 3);
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<UpdateBookmarkFunction>(kTestExtensionPath2,
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new UpdateBookmarkFunction(), 2);
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate a commit failure, which augments the active record set with the
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // refugee records.
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->PutRecords(results);
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor::Records new_records;
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->GetAndClearRecords(&new_records);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, results.size());
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(id1, new_records[id1].extension_id);
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(id2, new_records[id2].extension_id);
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5U, new_records[id1].bookmark_write_count);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(8U + 2U, new_records[id2].bookmark_write_count);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_loop()->DeleteSoon(FROM_HERE, monitor);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ExtensionsActivityMonitorTest, MultiGet) {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor* monitor = new ExtensionsActivityMonitor();
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkAPIEventGenerator generator;
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id1 = GetExtensionIdForPath(kTestExtensionPath1);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<CreateBookmarkFunction>(kTestExtensionPath1,
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new CreateBookmarkFunction(), 5);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor::Records results;
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->GetAndClearRecords(&results);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, results.size());
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5U, results[id1].bookmark_write_count);
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->GetAndClearRecords(&results);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(results.empty());
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  generator.NewEvent<CreateBookmarkFunction>(kTestExtensionPath1,
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new CreateBookmarkFunction(), 3);
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  monitor->GetAndClearRecords(&results);
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, results.size());
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3U, results[id1].bookmark_write_count);
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_loop()->DeleteSoon(FROM_HERE, monitor);
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
249