Home | History | Annotate | Download | only in glue
      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 "chrome/browser/sync/glue/extensions_activity_monitor.h"
      6 
      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"
     20 
     21 using extensions::Extension;
     22 
     23 namespace browser_sync {
     24 
     25 namespace {
     26 
     27 namespace keys = extensions::manifest_keys;
     28 
     29 // Create and return an extension with the given path.
     30 scoped_refptr<Extension> MakeExtension(const std::string& name) {
     31   base::FilePath path;
     32   EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
     33   path = path.AppendASCII(name);
     34 
     35   base::DictionaryValue value;
     36   value.SetString(keys::kVersion, "1.0.0.0");
     37   value.SetString(keys::kName, name);
     38   std::string error;
     39   scoped_refptr<Extension> extension(Extension::Create(
     40       path, extensions::Manifest::INVALID_LOCATION, value,
     41       Extension::NO_FLAGS, &error));
     42   EXPECT_TRUE(error.empty());
     43   return extension;
     44 }
     45 
     46 // Fire a bookmarks API event from the given extension the given
     47 // number of times.
     48 template <class T>
     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         chrome::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED,
     56         content::Source<Extension>(extension.get()),
     57         content::Details<const extensions::BookmarksFunction>(
     58             bookmarks_function.get()));
     59   }
     60 }
     61 
     62 class SyncChromeExtensionsActivityMonitorTest : public testing::Test {
     63  public:
     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   virtual ~SyncChromeExtensionsActivityMonitorTest() {}
     71 
     72  private:
     73   content::TestBrowserThreadBundle thread_bundle_;
     74 
     75  protected:
     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_;
     82 };
     83 
     84 // NOTE: The tests below are DISABLED because they're flaky:
     85 // https://code.google.com/p/chromium/issues/detail?id=172002
     86 
     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;
     98 
     99   FireBookmarksApiEvent<extensions::BookmarksRemoveTreeFunction>(
    100       extension2_, 8);
    101   FireBookmarksApiEvent<extensions::BookmarksGetSubTreeFunction>(
    102       extension2_, 13);
    103   FireBookmarksApiEvent<extensions::BookmarksGetChildrenFunction>(
    104       extension2_, 21);
    105   FireBookmarksApiEvent<extensions::BookmarksGetTreeFunction>(extension2_, 33);
    106   const uint32 writes_by_extension2 = 8;
    107 
    108   syncer::ExtensionsActivity::Records results;
    109   monitor_.GetExtensionsActivity()->GetAndClearRecords(&results);
    110 
    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);
    116 }
    117 
    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);
    125 
    126   syncer::ExtensionsActivity::Records results;
    127   monitor_.GetExtensionsActivity()->GetAndClearRecords(&results);
    128 
    129   EXPECT_EQ(2U, results.size());
    130   EXPECT_EQ(5U, results[id1_].bookmark_write_count);
    131   EXPECT_EQ(8U, results[id2_].bookmark_write_count);
    132 
    133   FireBookmarksApiEvent<extensions::BookmarksGetTreeFunction>(extension2_, 3);
    134   FireBookmarksApiEvent<extensions::BookmarksUpdateFunction>(extension2_, 2);
    135 
    136   // Simulate a commit failure, which augments the active record set with the
    137   // refugee records.
    138   monitor_.GetExtensionsActivity()->PutRecords(results);
    139   syncer::ExtensionsActivity::Records new_records;
    140   monitor_.GetExtensionsActivity()->GetAndClearRecords(&new_records);
    141 
    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);
    147 }
    148 
    149 // Fire some mutating bookmark API events and get the records multiple
    150 // times.  The mintor should correctly clear its records every time
    151 // they're returned.
    152 TEST_F(SyncChromeExtensionsActivityMonitorTest, DISABLED_MultiGet) {
    153   FireBookmarksApiEvent<extensions::BookmarksCreateFunction>(extension1_, 5);
    154 
    155   syncer::ExtensionsActivity::Records results;
    156   monitor_.GetExtensionsActivity()->GetAndClearRecords(&results);
    157 
    158   EXPECT_EQ(1U, results.size());
    159   EXPECT_EQ(5U, results[id1_].bookmark_write_count);
    160 
    161   monitor_.GetExtensionsActivity()->GetAndClearRecords(&results);
    162   EXPECT_TRUE(results.empty());
    163 
    164   FireBookmarksApiEvent<extensions::BookmarksCreateFunction>(extension1_, 3);
    165   monitor_.GetExtensionsActivity()->GetAndClearRecords(&results);
    166 
    167   EXPECT_EQ(1U, results.size());
    168   EXPECT_EQ(3U, results[id1_].bookmark_write_count);
    169 }
    170 
    171 }  // namespace
    172 
    173 }  // namespace browser_sync
    174