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_bundle.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 namespace keys
= extensions::manifest_keys
;
29 // Create and return an extension with the given path.
30 scoped_refptr
<Extension
> MakeExtension(const std::string
& name
) {
32 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &path
));
33 path
= path
.AppendASCII(name
);
35 base::DictionaryValue value
;
36 value
.SetString(keys::kVersion
, "1.0.0.0");
37 value
.SetString(keys::kName
, name
);
39 scoped_refptr
<Extension
> extension(Extension::Create(
40 path
, extensions::Manifest::INVALID_LOCATION
, value
,
41 Extension::NO_FLAGS
, &error
));
42 EXPECT_TRUE(error
.empty());
46 // Fire a bookmarks API event from the given extension the given
49 void FireBookmarksApiEvent(
50 const scoped_refptr
<Extension
>& extension
, int repeats
) {
51 scoped_refptr
<T
> bookmarks_function(new T());
52 bookmarks_function
->set_name(T::function_name());
53 for (int i
= 0; i
< repeats
; i
++) {
54 content::NotificationService::current()->Notify(
55 extensions::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED
,
56 content::Source
<Extension
>(extension
.get()),
57 content::Details
<const extensions::BookmarksFunction
>(
58 bookmarks_function
.get()));
62 class SyncChromeExtensionsActivityMonitorTest
: public testing::Test
{
64 SyncChromeExtensionsActivityMonitorTest()
65 : thread_bundle_(content::TestBrowserThreadBundle::DEFAULT
),
66 extension1_(MakeExtension("extension1")),
67 extension2_(MakeExtension("extension2")),
68 id1_(extension1_
->id()),
69 id2_(extension2_
->id()) {}
70 ~SyncChromeExtensionsActivityMonitorTest() override
{}
73 content::TestBrowserThreadBundle thread_bundle_
;
76 ExtensionsActivityMonitor monitor_
;
77 scoped_refptr
<Extension
> extension1_
;
78 scoped_refptr
<Extension
> extension2_
;
79 // IDs of |extension{1,2}_|.
80 const std::string
& id1_
;
81 const std::string
& id2_
;
84 // NOTE: The tests below are DISABLED because they're flaky:
85 // https://code.google.com/p/chromium/issues/detail?id=172002
87 // Fire some mutating bookmark API events with extension 1, then fire
88 // some mutating and non-mutating bookmark API events with extension
89 // 2. Only the mutating events should be recorded by the
90 // syncer::ExtensionsActivityMonitor.
91 TEST_F(SyncChromeExtensionsActivityMonitorTest
, DISABLED_Basic
) {
92 FireBookmarksApiEvent
<extensions::BookmarksRemoveFunction
>(extension1_
, 1);
93 FireBookmarksApiEvent
<extensions::BookmarksMoveFunction
>(extension1_
, 1);
94 FireBookmarksApiEvent
<extensions::BookmarksUpdateFunction
>(extension1_
, 2);
95 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 3);
96 FireBookmarksApiEvent
<extensions::BookmarksSearchFunction
>(extension1_
, 5);
97 const uint32 writes_by_extension1
= 1 + 1 + 2 + 3;
99 FireBookmarksApiEvent
<extensions::BookmarksRemoveTreeFunction
>(
101 FireBookmarksApiEvent
<extensions::BookmarksGetSubTreeFunction
>(
103 FireBookmarksApiEvent
<extensions::BookmarksGetChildrenFunction
>(
105 FireBookmarksApiEvent
<extensions::BookmarksGetTreeFunction
>(extension2_
, 33);
106 const uint32 writes_by_extension2
= 8;
108 syncer::ExtensionsActivity::Records results
;
109 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
111 EXPECT_EQ(2U, results
.size());
112 EXPECT_TRUE(results
.find(id1_
) != results
.end());
113 EXPECT_TRUE(results
.find(id2_
) != results
.end());
114 EXPECT_EQ(writes_by_extension1
, results
[id1_
].bookmark_write_count
);
115 EXPECT_EQ(writes_by_extension2
, results
[id2_
].bookmark_write_count
);
118 // Fire some mutating bookmark API events with both extensions. Then
119 // get the records, fire some more mutating and non-mutating events,
120 // and put the old records back. Those should be merged with the new
121 // records correctly.
122 TEST_F(SyncChromeExtensionsActivityMonitorTest
, DISABLED_Put
) {
123 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 5);
124 FireBookmarksApiEvent
<extensions::BookmarksMoveFunction
>(extension2_
, 8);
126 syncer::ExtensionsActivity::Records results
;
127 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
129 EXPECT_EQ(2U, results
.size());
130 EXPECT_EQ(5U, results
[id1_
].bookmark_write_count
);
131 EXPECT_EQ(8U, results
[id2_
].bookmark_write_count
);
133 FireBookmarksApiEvent
<extensions::BookmarksGetTreeFunction
>(extension2_
, 3);
134 FireBookmarksApiEvent
<extensions::BookmarksUpdateFunction
>(extension2_
, 2);
136 // Simulate a commit failure, which augments the active record set with the
138 monitor_
.GetExtensionsActivity()->PutRecords(results
);
139 syncer::ExtensionsActivity::Records new_records
;
140 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&new_records
);
142 EXPECT_EQ(2U, results
.size());
143 EXPECT_EQ(id1_
, new_records
[id1_
].extension_id
);
144 EXPECT_EQ(id2_
, new_records
[id2_
].extension_id
);
145 EXPECT_EQ(5U, new_records
[id1_
].bookmark_write_count
);
146 EXPECT_EQ(8U + 2U, new_records
[id2_
].bookmark_write_count
);
149 // Fire some mutating bookmark API events and get the records multiple
150 // times. The mintor should correctly clear its records every time
152 TEST_F(SyncChromeExtensionsActivityMonitorTest
, DISABLED_MultiGet
) {
153 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 5);
155 syncer::ExtensionsActivity::Records results
;
156 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
158 EXPECT_EQ(1U, results
.size());
159 EXPECT_EQ(5U, results
[id1_
].bookmark_write_count
);
161 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
162 EXPECT_TRUE(results
.empty());
164 FireBookmarksApiEvent
<extensions::BookmarksCreateFunction
>(extension1_
, 3);
165 monitor_
.GetExtensionsActivity()->GetAndClearRecords(&results
);
167 EXPECT_EQ(1U, results
.size());
168 EXPECT_EQ(3U, results
[id1_
].bookmark_write_count
);
173 } // namespace browser_sync