1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/sync/glue/extensions_activity_monitor.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h" 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "sync/util/extensions_activity.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace keys = extensions::manifest_keys; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Create and return an extension with the given path. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> MakeExtension(const std::string& name) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = path.AppendASCII(name); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue value; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.SetString(keys::kVersion, "1.0.0.0"); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.SetString(keys::kName, name); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(Extension::Create( 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path, extensions::Manifest::INVALID_LOCATION, value, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Extension::NO_FLAGS, &error)); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(error.empty()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fire a bookmarks API event from the given extension the given 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number of times. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FireBookmarksApiEvent( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<Extension>& extension, int repeats) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<T> bookmarks_function(new T()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_function->set_name(T::function_name()); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < repeats; i++) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Extension>(extension.get()), 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<const extensions::BookmarksFunction>( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmarks_function.get())); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncChromeExtensionsActivityMonitorTest : public testing::Test { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChromeExtensionsActivityMonitorTest() 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ui_thread_(BrowserThread::UI, &ui_loop_), 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension1_(MakeExtension("extension1")), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension2_(MakeExtension("extension2")), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id1_(extension1_->id()), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id2_(extension2_->id()) {} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SyncChromeExtensionsActivityMonitorTest() {} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop ui_loop_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ExtensionsActivityMonitor monitor_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension1_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension2_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IDs of |extension{1,2}_|. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id1_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id2_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NOTE: The tests below are DISABLED because they're flaky: 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://code.google.com/p/chromium/issues/detail?id=172002 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fire some mutating bookmark API events with extension 1, then fire 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// some mutating and non-mutating bookmark API events with extension 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. Only the mutating events should be recorded by the 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// syncer::ExtensionsActivityMonitor. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncChromeExtensionsActivityMonitorTest, DISABLED_Basic) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksRemoveFunction>(extension1_, 1); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksMoveFunction>(extension1_, 1); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksUpdateFunction>(extension1_, 2); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksCreateFunction>(extension1_, 3); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksSearchFunction>(extension1_, 5); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 writes_by_extension1 = 1 + 1 + 2 + 3; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksRemoveTreeFunction>( 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension2_, 8); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksGetSubTreeFunction>( 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension2_, 13); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksGetChildrenFunction>( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension2_, 21); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksGetTreeFunction>(extension2_, 33); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 writes_by_extension2 = 8; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ExtensionsActivity::Records results; 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->GetAndClearRecords(&results); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, results.size()); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(results.find(id1_) != results.end()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(results.find(id2_) != results.end()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(writes_by_extension1, results[id1_].bookmark_write_count); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(writes_by_extension2, results[id2_].bookmark_write_count); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fire some mutating bookmark API events with both extensions. Then 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get the records, fire some more mutating and non-mutating events, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and put the old records back. Those should be merged with the new 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// records correctly. 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncChromeExtensionsActivityMonitorTest, DISABLED_Put) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksCreateFunction>(extension1_, 5); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksMoveFunction>(extension2_, 8); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ExtensionsActivity::Records results; 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->GetAndClearRecords(&results); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, results.size()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, results[id1_].bookmark_write_count); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8U, results[id2_].bookmark_write_count); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksGetTreeFunction>(extension2_, 3); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksUpdateFunction>(extension2_, 2); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simulate a commit failure, which augments the active record set with the 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // refugee records. 140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->PutRecords(results); 141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ExtensionsActivity::Records new_records; 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->GetAndClearRecords(&new_records); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, results.size()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(id1_, new_records[id1_].extension_id); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(id2_, new_records[id2_].extension_id); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, new_records[id1_].bookmark_write_count); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8U + 2U, new_records[id2_].bookmark_write_count); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fire some mutating bookmark API events and get the records multiple 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// times. The mintor should correctly clear its records every time 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// they're returned. 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncChromeExtensionsActivityMonitorTest, DISABLED_MultiGet) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksCreateFunction>(extension1_, 5); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ExtensionsActivity::Records results; 158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->GetAndClearRecords(&results); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, results.size()); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, results[id1_].bookmark_write_count); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->GetAndClearRecords(&results); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(results.empty()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FireBookmarksApiEvent<extensions::BookmarksCreateFunction>(extension1_, 3); 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) monitor_.GetExtensionsActivity()->GetAndClearRecords(&results); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, results.size()); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, results[id1_].bookmark_write_count); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 176