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.
5 #include "chrome/browser/sync/glue/extensions_activity_monitor.h"
7 #include "base/files/file_path.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.h"
10 #include "base/values.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/test/test_browser_thread.h"
16 #include "extensions/common/extension.h"
17 #include "extensions/common/manifest_constants.h"
18 #include "sync/util/extensions_activity.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using extensions::Extension
;
23 namespace browser_sync
{
27 using content::BrowserThread
;
28 namespace keys
= extensions::manifest_keys
;
30 // Create and return an extension with the given path.
31 scoped_refptr
<Extension
> MakeExtension(const std::string
& name
) {
33 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &path
));
34 path
= path
.AppendASCII(name
);
36 base::DictionaryValue value
;
37 value
.SetString(keys::kVersion
, "1.0.0.0");
38 value
.SetString(keys::kName
, name
);
40 scoped_refptr
<Extension
> extension(Extension::Create(
41 path
, extensions::Manifest::INVALID_LOCATION
, value
,
42 Extension::NO_FLAGS
, &error
));
43 EXPECT_TRUE(error
.empty());
47 // Fire a bookmarks API event from the given extension the given
50 void FireBookmarksApiEvent(
51 const scoped_refptr
<Extension
>& extension
, int repeats
) {
52 scoped_refptr
<T
> bookmarks_function(new T());
53 bookmarks_function
->set_name(T::function_name());
54 for (int i
= 0; i
< repeats
; i
++) {
55 content::NotificationService::current()->Notify(
56 chrome::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED
,
57 content::Source
<Extension
>(extension
.get()),
58 content::Details
<const extensions::BookmarksFunction
>(
59 bookmarks_function
.get()));
63 class SyncChromeExtensionsActivityMonitorTest
: public testing::Test
{
65 SyncChromeExtensionsActivityMonitorTest()
66 : ui_thread_(BrowserThread::UI
, &ui_loop_
),
67 extension1_(MakeExtension("extension1")),
68 extension2_(MakeExtension("extension2")),
69 id1_(extension1_
->id()),
70 id2_(extension2_
->id()) {}
71 virtual ~SyncChromeExtensionsActivityMonitorTest() {}
74 base::MessageLoop ui_loop_
;
75 content::TestBrowserThread ui_thread_
;
78 ExtensionsActivityMonitor monitor_
;
79 scoped_refptr
<Extension
> extension1_
;
80 scoped_refptr
<Extension
> extension2_
;
81 // IDs of |extension{1,2}_|.
82 const std::string
& id1_
;
83 const std::string
& id2_
;
86 // NOTE: The tests below are DISABLED because they're flaky:
87 // https://code.google.com/p/chromium/issues/detail?id=172002
89 // Fire some mutating bookmark API events with extension 1, then fire
90 // some mutating and non-mutating bookmark API events with extension
91 // 2. Only the mutating events should be recorded by the
92 // syncer::ExtensionsActivityMonitor.
93 TEST_F(SyncChromeExtensionsActivityMonitorTest
, DISABLED_Basic
) {
94 FireBookmarksApiEvent
<extensions::BookmarksRemoveFunction
>(extension1_
, 1);
95 FireBookmarksApiEvent
<extensions::BookmarksMoveFunction
>(extension1_
, 1);
96 FireBookmarksApiEvent
<extensions::BookmarksUpdateFunction
>(extension1_
, 2);
97 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 3);
98 FireBookmarksApiEvent
<extensions::BookmarksSearchFunction
>(extension1_
, 5);
99 const uint32 writes_by_extension1
= 1 + 1 + 2 + 3;
101 FireBookmarksApiEvent
<extensions::BookmarksRemoveTreeFunction
>(
103 FireBookmarksApiEvent
<extensions::BookmarksGetSubTreeFunction
>(
105 FireBookmarksApiEvent
<extensions::BookmarksGetChildrenFunction
>(
107 FireBookmarksApiEvent
<extensions::BookmarksGetTreeFunction
>(extension2_
, 33);
108 const uint32 writes_by_extension2
= 8;
110 syncer::ExtensionsActivity::Records results
;
111 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
113 EXPECT_EQ(2U, results
.size());
114 EXPECT_TRUE(results
.find(id1_
) != results
.end());
115 EXPECT_TRUE(results
.find(id2_
) != results
.end());
116 EXPECT_EQ(writes_by_extension1
, results
[id1_
].bookmark_write_count
);
117 EXPECT_EQ(writes_by_extension2
, results
[id2_
].bookmark_write_count
);
120 // Fire some mutating bookmark API events with both extensions. Then
121 // get the records, fire some more mutating and non-mutating events,
122 // and put the old records back. Those should be merged with the new
123 // records correctly.
124 TEST_F(SyncChromeExtensionsActivityMonitorTest
, DISABLED_Put
) {
125 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 5);
126 FireBookmarksApiEvent
<extensions::BookmarksMoveFunction
>(extension2_
, 8);
128 syncer::ExtensionsActivity::Records results
;
129 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
131 EXPECT_EQ(2U, results
.size());
132 EXPECT_EQ(5U, results
[id1_
].bookmark_write_count
);
133 EXPECT_EQ(8U, results
[id2_
].bookmark_write_count
);
135 FireBookmarksApiEvent
<extensions::BookmarksGetTreeFunction
>(extension2_
, 3);
136 FireBookmarksApiEvent
<extensions::BookmarksUpdateFunction
>(extension2_
, 2);
138 // Simulate a commit failure, which augments the active record set with the
140 monitor_
.GetExtensionsActivity()->PutRecords(results
);
141 syncer::ExtensionsActivity::Records new_records
;
142 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&new_records
);
144 EXPECT_EQ(2U, results
.size());
145 EXPECT_EQ(id1_
, new_records
[id1_
].extension_id
);
146 EXPECT_EQ(id2_
, new_records
[id2_
].extension_id
);
147 EXPECT_EQ(5U, new_records
[id1_
].bookmark_write_count
);
148 EXPECT_EQ(8U + 2U, new_records
[id2_
].bookmark_write_count
);
151 // Fire some mutating bookmark API events and get the records multiple
152 // times. The mintor should correctly clear its records every time
154 TEST_F(SyncChromeExtensionsActivityMonitorTest
, DISABLED_MultiGet
) {
155 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 5);
157 syncer::ExtensionsActivity::Records results
;
158 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
160 EXPECT_EQ(1U, results
.size());
161 EXPECT_EQ(5U, results
[id1_
].bookmark_write_count
);
163 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
164 EXPECT_TRUE(results
.empty());
166 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 3);
167 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
169 EXPECT_EQ(1U, results
.size());
170 EXPECT_EQ(3U, results
[id1_
].bookmark_write_count
);
175 } // namespace browser_sync