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

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

Issue 9817018: Cleaning Up Extensions When Local Content Removed (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Updated with newest master Created 8 years, 8 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
« no previous file with comments | « chrome/browser/extensions/extension_service.cc ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_service_unittest.h" 5 #include "chrome/browser/extensions/extension_service_unittest.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 mutable int visit_count_; 245 mutable int visit_count_;
246 246
247 int creation_flags_; 247 int creation_flags_;
248 248
249 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); 249 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
250 }; 250 };
251 251
252 class MockProviderVisitor 252 class MockProviderVisitor
253 : public ExternalExtensionProviderInterface::VisitorInterface { 253 : public ExternalExtensionProviderInterface::VisitorInterface {
254 public: 254 public:
255
256 // The provider will return |fake_base_path| from 255 // The provider will return |fake_base_path| from
257 // GetBaseCrxFilePath(). User can test the behavior with 256 // GetBaseCrxFilePath(). User can test the behavior with
258 // and without an empty path using this parameter. 257 // and without an empty path using this parameter.
259 explicit MockProviderVisitor(FilePath fake_base_path) 258 explicit MockProviderVisitor(FilePath fake_base_path)
260 : ids_found_(0), 259 : ids_found_(0),
261 fake_base_path_(fake_base_path) { 260 fake_base_path_(fake_base_path) {
262 } 261 }
263 262
264 int Visit(const std::string& json_data) { 263 int Visit(const std::string& json_data) {
265 // Give the test json file to the provider for parsing. 264 // Give the test json file to the provider for parsing.
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 ASSERT_TRUE(file_util::PathExists(private_key_path)); 1000 ASSERT_TRUE(file_util::PathExists(private_key_path));
1002 } 1001 }
1003 1002
1004 // The tests are designed so that we never expect to see a packing error. 1003 // The tests are designed so that we never expect to see a packing error.
1005 void PackExtensionTestClient::OnPackFailure(const std::string& error_message, 1004 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1006 ExtensionCreator::ErrorType type) { 1005 ExtensionCreator::ErrorType type) {
1007 if (type == ExtensionCreator::kCRXExists) 1006 if (type == ExtensionCreator::kCRXExists)
1008 FAIL() << "Packing should not fail."; 1007 FAIL() << "Packing should not fail.";
1009 else 1008 else
1010 FAIL() << "Existing CRX should have been overwritten."; 1009 FAIL() << "Existing CRX should have been overwritten.";
1011
1012 } 1010 }
1013 1011
1014 // Test loading good extensions from the profile directory. 1012 // Test loading good extensions from the profile directory.
1015 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { 1013 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1016 PluginService::GetInstance()->Init(); 1014 PluginService::GetInstance()->Init();
1017 1015
1018 // Initialize the test dir with a good Preferences/extensions. 1016 // Initialize the test dir with a good Preferences/extensions.
1019 FilePath source_install_dir = data_dir_ 1017 FilePath source_install_dir = data_dir_
1020 .AppendASCII("good") 1018 .AppendASCII("good")
1021 .AppendASCII("Extensions"); 1019 .AppendASCII("Extensions");
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 std::string("Could not load extension from '*'. ") + 1143 std::string("Could not load extension from '*'. ") +
1146 extension_manifest_errors::kMissingFile)) << 1144 extension_manifest_errors::kMissingFile)) <<
1147 UTF16ToUTF8(GetErrors()[2]); 1145 UTF16ToUTF8(GetErrors()[2]);
1148 1146
1149 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]), 1147 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
1150 std::string("Could not load extension from '*'. ") + 1148 std::string("Could not load extension from '*'. ") +
1151 extension_manifest_errors::kManifestUnreadable)) << 1149 extension_manifest_errors::kManifestUnreadable)) <<
1152 UTF16ToUTF8(GetErrors()[3]); 1150 UTF16ToUTF8(GetErrors()[3]);
1153 }; 1151 };
1154 1152
1155 // Test that partially deleted extensions are cleaned up during startup 1153 // Test that old versions of extensions are deleted during garbage collection.
1156 // Test loading bad extensions from the profile directory. 1154 TEST_F(ExtensionServiceTest, GarbageCollectOldVersions) {
1157 TEST_F(ExtensionServiceTest, CleanupOnStartup) {
1158 PluginService::GetInstance()->Init(); 1155 PluginService::GetInstance()->Init();
1159 1156
1160 FilePath source_install_dir = data_dir_ 1157 FilePath source_install_dir = data_dir_
1158 .AppendASCII("garbage_collection")
1159 .AppendASCII("Extensions");
1160
1161 FilePath pref_path = source_install_dir
1162 .DirName()
1163 .AppendASCII("Preferences");
1164
1165 InitializeInstalledExtensionService(pref_path, source_install_dir);
1166
1167 // Verify that there are two versions present initially.
1168 ASSERT_TRUE(file_util::PathExists(
1169 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1170 .AppendASCII("1.0_0")));
1171 ASSERT_TRUE(file_util::PathExists(
1172 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1173 .AppendASCII("1.1_0")));
1174
1175 ValidatePrefKeyCount(1u);
1176
1177 service_->Init();
1178 loop_.RunAllPending();
1179
1180 // Garbage collection should have deleted the old version.
1181 ASSERT_FALSE(file_util::PathExists(
1182 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1183 .AppendASCII("1.0_0")));
1184 ASSERT_TRUE(file_util::PathExists(
1185 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1186 .AppendASCII("1.1_0")));
1187 }
1188
1189 // Test that extensions which were deleted from the preferences are cleaned up
1190 // during startup.
1191 // Test loading bad extensions from the profile directory.
1192 TEST_F(ExtensionServiceTest, GarbageCollectOnStartup) {
1193 PluginService::GetInstance()->Init();
1194
1195 FilePath source_install_dir = data_dir_
1161 .AppendASCII("good") 1196 .AppendASCII("good")
1162 .AppendASCII("Extensions"); 1197 .AppendASCII("Extensions");
1163 FilePath pref_path = source_install_dir 1198 FilePath pref_path = source_install_dir
1164 .DirName() 1199 .DirName()
1165 .AppendASCII("Preferences"); 1200 .AppendASCII("Preferences");
1166 1201
1167 InitializeInstalledExtensionService(pref_path, source_install_dir); 1202 InitializeInstalledExtensionService(pref_path, source_install_dir);
1168 1203
1204 ValidatePrefKeyCount(3u);
1205
1169 // Simulate that one of them got partially deleted by clearing its pref. 1206 // Simulate that one of them got partially deleted by clearing its pref.
1170 { 1207 {
1171 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); 1208 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1172 DictionaryValue* dict = update.Get(); 1209 DictionaryValue* dict = update.Get();
1173 ASSERT_TRUE(dict != NULL); 1210 ASSERT_TRUE(dict);
1174 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL); 1211 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1175 } 1212 }
1176 1213
1177 service_->Init(); 1214 service_->Init();
1178 // Wait for GarbageCollectExtensions task to complete. 1215 // Wait for GarbageCollectExtensions task to complete.
1179 loop_.RunAllPending(); 1216 loop_.RunAllPending();
1180 1217
1181 file_util::FileEnumerator dirs(extensions_install_dir_, false, 1218 file_util::FileEnumerator dirs(extensions_install_dir_, false,
1182 file_util::FileEnumerator::DIRECTORIES); 1219 file_util::FileEnumerator::DIRECTORIES);
1183 size_t count = 0; 1220 size_t count = 0;
1184 while (!dirs.Next().empty()) 1221 while (!dirs.Next().empty())
1185 count++; 1222 count++;
1186 1223
1187 // We should have only gotten two extensions now. 1224 // We should have only gotten two extensions now.
1188 EXPECT_EQ(2u, count); 1225 EXPECT_EQ(2u, count);
1189 1226
1190 // And extension1 dir should now be toast. 1227 // And extension1 dir should now be toast.
1191 FilePath extension_dir = extensions_install_dir_ 1228 FilePath extension_dir = extensions_install_dir_
1192 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); 1229 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1193 ASSERT_FALSE(file_util::PathExists(extension_dir)); 1230 ASSERT_FALSE(file_util::PathExists(extension_dir));
1194 } 1231 }
1195 1232
1233 // Test that internal extensions which are referenced in the preferences but
1234 // had their content deleted are cleaned up during startup.
1235 TEST_F(ExtensionServiceTest, GarbageCollectInternalExtensionsMissingContent) {
1236 PluginService::GetInstance()->Init();
1237
1238 FilePath source_dir = data_dir_.AppendASCII("good").AppendASCII("Extensions");
1239 FilePath pref_path = source_dir.DirName().AppendASCII("Preferences");
1240
1241 InitializeInstalledExtensionService(pref_path, source_dir);
1242
1243 ValidatePrefKeyCount(3u);
1244
1245 // Delete the extension's directory.
1246 FilePath extension_dir = extensions_install_dir_
1247 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1248 ASSERT_TRUE(file_util::Delete(extension_dir, true));
1249
1250 // Run GarbageCollectExtensions.
1251 service_->Init();
1252 loop_.RunAllPending();
1253
1254 file_util::FileEnumerator dirs(extensions_install_dir_, false,
1255 file_util::FileEnumerator::DIRECTORIES);
1256 size_t count = 0;
1257 while (!dirs.Next().empty())
1258 count++;
1259
1260 // We should have only gotten two extensions now.
1261 EXPECT_EQ(2u, count);
1262
1263 const DictionaryValue* dictionary =
1264 profile_->GetPrefs()->GetDictionary("extensions.settings");
1265 ASSERT_TRUE(dictionary);
1266 ASSERT_FALSE(dictionary->HasKey("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1267 }
1268
1269 // Test that unpacked extensions which are referenced in the preferences but
1270 // had their content deleted are cleaned up during startup.
1271 TEST_F(ExtensionServiceTest, GarbageCollectUnpackedExtensionsMissingContent) {
1272 InitializeEmptyExtensionService();
1273
1274 ScopedTempDir temp;
1275 ASSERT_TRUE(temp.CreateUniqueTempDir());
1276
1277 // Write the manifest dynamically, since we have to delete the file anyway.
1278 FilePath extension_path = temp.path();
1279 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
1280 ASSERT_FALSE(file_util::PathExists(manifest_path));
1281
1282 // Construct a simple manifest and install it.
1283 DictionaryValue manifest;
1284 manifest.SetString("version", "1.0");
1285 manifest.SetString("name", "Cleanup Unpacked Extensions Missing Content");
1286 manifest.SetInteger("manifest_version", 2);
1287
1288 JSONFileValueSerializer serializer(manifest_path);
1289 ASSERT_TRUE(serializer.Serialize(manifest));
1290
1291 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
1292 loop_.RunAllPending();
1293
1294 // Make sure it installed correctly.
1295 EXPECT_EQ(0u, GetErrors().size());
1296 ASSERT_EQ(1u, loaded_.size());
1297 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
1298 EXPECT_EQ(1u, service_->extensions()->size());
1299
1300 std::string extension_id = loaded_[0]->id();
1301
1302 // Make sure it is in the preferences at this point.
1303 const DictionaryValue* initial_dictionary =
1304 profile_->GetPrefs()->GetDictionary("extensions.settings");
1305 ASSERT_TRUE(initial_dictionary);
1306 ASSERT_TRUE(initial_dictionary->HasKey(extension_id));
1307
1308 // Delete local content, GarbageCollectExtensions, and test whether the key
1309 // is still in the preferences.
1310 ASSERT_TRUE(file_util::Delete(extension_path, true));
1311 service_->GarbageCollectExtensions();
1312 loop_.RunAllPending();
1313
1314 const DictionaryValue* final_dictionary =
1315 profile_->GetPrefs()->GetDictionary("extensions.settings");
1316 ASSERT_TRUE(final_dictionary);
1317 ASSERT_FALSE(final_dictionary->HasKey(extension_id));
1318 }
1319
1196 // Test installing extensions. This test tries to install few extensions using 1320 // Test installing extensions. This test tries to install few extensions using
1197 // crx files. If you need to change those crx files, feel free to repackage 1321 // crx files. If you need to change those crx files, feel free to repackage
1198 // them, throw away the key used and change the id's above. 1322 // them, throw away the key used and change the id's above.
1199 TEST_F(ExtensionServiceTest, InstallExtension) { 1323 TEST_F(ExtensionServiceTest, InstallExtension) {
1200 InitializeEmptyExtensionService(); 1324 InitializeEmptyExtensionService();
1201 1325
1202 // Extensions not enabled. 1326 // Extensions not enabled.
1203 set_extensions_enabled(false); 1327 set_extensions_enabled(false);
1204 FilePath path = data_dir_.AppendASCII("good.crx"); 1328 FilePath path = data_dir_.AppendASCII("good.crx");
1205 InstallCRX(path, INSTALL_FAILED); 1329 InstallCRX(path, INSTALL_FAILED);
(...skipping 3676 matching lines...) Expand 10 before | Expand all | Expand 10 after
4882 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0", 5006 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
4883 data_dir_.AppendASCII("hosted_app.crx")); 5007 data_dir_.AppendASCII("hosted_app.crx"));
4884 5008
4885 service_->CheckForExternalUpdates(); 5009 service_->CheckForExternalUpdates();
4886 loop_.RunAllPending(); 5010 loop_.RunAllPending();
4887 5011
4888 ASSERT_TRUE(service_->PopulateExtensionGlobalError( 5012 ASSERT_TRUE(service_->PopulateExtensionGlobalError(
4889 extension_global_error.get())); 5013 extension_global_error.get()));
4890 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size()); 5014 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size());
4891 } 5015 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_service.cc ('k') | chrome/chrome_browser_extensions.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698