Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: chrome/browser/extensions/external_extension_provider_impl_unittest.cc

Issue 8245018: Remove race condition when installing default apps into a new profile. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix more trybot breaks Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 <string>
6
7 #include "base/logging.h"
8 #include "base/message_loop.h"
9 #include "base/values.h"
10 #include "base/version.h"
11 #include "chrome/browser/extensions/crx_installer.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/external_extension_provider_interface.h"
14 #include "chrome/browser/extensions/external_extension_provider_impl.h"
15 #include "chrome/browser/extensions/external_policy_extension_loader.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/extensions/extension.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_pref_service.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "content/browser/browser_thread.h"
22 #include "content/common/notification_details.h"
23 #include "content/common/notification_service.h"
24 #include "content/common/notification_source.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace {
28
29 class MockExternalExtensionLoader : public ExternalExtensionLoader {
30 public:
31 MockExternalExtensionLoader() {}
32
33 void SetPrefs(const base::DictionaryValue& prefs) {
34 prefs_.reset(prefs.DeepCopy());
35 }
36
37 private:
38 virtual void StartLoading() {
39 // No actual loading to be done, simple use the prefs given.
Finnur 2011/10/19 10:01:29 nit: simple -> simply?
Roger Tawa OOO till Jul 10th 2011/10/19 20:48:25 Done.
40 LoadFinished();
41 }
42
43 virtual const FilePath GetBaseCrxFilePath() {
44 return FilePath(FILE_PATH_LITERAL("/tmp"));
45 }
46
47 DISALLOW_COPY_AND_ASSIGN(MockExternalExtensionLoader);
48 };
49
50 class MockExternalPolicyExtensionProviderVisitor
51 : public ExternalExtensionProviderInterface::VisitorInterface {
52 public:
53 MockExternalPolicyExtensionProviderVisitor() {
54 profile_.reset(new TestingProfile);
55 profile_->CreateExtensionService(CommandLine::ForCurrentProcess(),
56 FilePath(FILE_PATH_LITERAL("/tmp")), false);
57
58 // The provider owns the loader.
59 loader_ = new MockExternalExtensionLoader();
60 provider_.reset(new DefaultAppsProvider(this, loader_, profile_.get()));
61 }
62
63 virtual void OnExternalExtensionFileFound(const std::string& id,
64 const Version* version,
65 const FilePath& path,
66 Extension::Location unused) {
67 }
68
69 virtual void OnExternalExtensionUpdateUrlFound(
70 const std::string& id, const GURL& update_url,
71 Extension::Location location) {
72 ADD_FAILURE() << "There should be no external extensions from URLs.";
73 }
74
75 virtual void OnExternalProviderReady() {
76 EXPECT_TRUE(provider_->IsReady());
77 }
78
79 TestingProfile* profile() const { return profile_.get(); }
80 DefaultAppsProvider* provider() const { return provider_.get(); }
81 MockExternalExtensionLoader* loader() const { return loader_; }
82
83 private:
84 scoped_ptr<TestingProfile> profile_;
85 scoped_ptr<DefaultAppsProvider> provider_;
86 MockExternalExtensionLoader* loader_;
87
88 DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyExtensionProviderVisitor);
89 };
90
91 class DefaultAppsProviderTest : public testing::Test {
92 public:
93 DefaultAppsProviderTest()
94 : loop_(MessageLoop::TYPE_IO),
95 ui_thread_(BrowserThread::UI, &loop_) {
96 }
97
98 virtual ~DefaultAppsProviderTest() {}
99
100 MockExternalPolicyExtensionProviderVisitor* visitor() {
101 return &visitor_;
102 }
103
104 int GetProviderState();
105
106 void AddExtensionToDictionary(base::DictionaryValue* prefs,
107 const char* id,
108 const char* name,
109 const char* version);
110
111 private:
112 // We need these to satisfy BrowserThread::CurrentlyOn(BrowserThread::UI)
113 // checks in ExternalExtensionProviderImpl.
114 MessageLoop loop_;
115 BrowserThread ui_thread_;
116 MockExternalPolicyExtensionProviderVisitor visitor_;
117 };
118
119 int DefaultAppsProviderTest::GetProviderState() {
120 return visitor()->profile()->GetPrefs()->GetInteger(
121 prefs::kDefaultAppsInstallState);
122 }
123
124 void DefaultAppsProviderTest::AddExtensionToDictionary(
125 base::DictionaryValue* prefs,
126 const char* id,
127 const char* name,
128 const char* version) {
129 scoped_ptr<base::DictionaryValue> extension(new base::DictionaryValue);
130
131 extension->SetString("external_crx", name);
132 extension->SetString("external_version", version);
133
134 prefs->Set(id, extension.release());
135 }
136
137 } // anonymous namespace
138
139 TEST_F(DefaultAppsProviderTest, NoExtensions) {
140 // Setup the loader to provide nothing.
141 base::DictionaryValue prefs;
142 visitor()->loader()->SetPrefs(prefs);
143
144 visitor()->provider()->VisitRegisteredExtension();
145
146 EXPECT_EQ(0u, visitor()->provider()->invalid_extensions().size());
147 EXPECT_EQ(0u, visitor()->provider()->install_error_extensions().size());
148 EXPECT_EQ(DefaultAppsProvider::kInstallDone, GetProviderState());
149 }
150
151 TEST_F(DefaultAppsProviderTest, InvalidExtension) {
152 // Setup the loader to one invalid extension.
153 base::DictionaryValue prefs;
154 prefs.SetInteger("bad_id", 0);
155 visitor()->loader()->SetPrefs(prefs);
156
157 // Run the provider.
158 visitor()->provider()->VisitRegisteredExtension();
159
160 // Make sure state is "done".
161 EXPECT_EQ(1u, visitor()->provider()->invalid_extensions().size());
162 EXPECT_EQ(0u, visitor()->provider()->install_error_extensions().size());
163 EXPECT_EQ(DefaultAppsProvider::kInstallDone, GetProviderState());
164 }
165
166 TEST_F(DefaultAppsProviderTest, InstallErrorExtension) {
167 // Setup the loader to one valid extension that fails to load.
168 base::DictionaryValue prefs;
169 AddExtensionToDictionary(&prefs, "blpcfgokakmgnkcojhhkbfbldkacnbeo",
170 "dummy.crx", "1.0.0.0");
171 visitor()->loader()->SetPrefs(prefs);
172
173 // Run the provider.
174 visitor()->provider()->VisitRegisteredExtension();
175
176 EXPECT_EQ(0u, visitor()->provider()->invalid_extensions().size());
177 EXPECT_EQ(0u, visitor()->provider()->install_error_extensions().size());
178 EXPECT_EQ(DefaultAppsProvider::kInstalling, GetProviderState());
179
180 // Pretend the load failed.
181 ExtensionService* service = visitor()->profile()->GetExtensionService();
182 scoped_refptr<CrxInstaller> crx_installer(service->MakeCrxInstaller(NULL));
183 crx_installer->set_expected_id("blpcfgokakmgnkcojhhkbfbldkacnbeo");
184 visitor()->provider()->Observe(chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
185 Source<CrxInstaller>(crx_installer.get()),
186 NotificationService::NoDetails());
187
188 EXPECT_EQ(0u, visitor()->provider()->invalid_extensions().size());
189 EXPECT_EQ(1u, visitor()->provider()->install_error_extensions().size());
190 EXPECT_EQ(DefaultAppsProvider::kInstallDone, GetProviderState());
191 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698