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

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

Issue 10541126: Cleaning Up Extensions When Local Content Removed (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Latest master merge Created 8 years, 6 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
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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // VisitRegisteredExtension(), which must be a const method to inherit 228 // VisitRegisteredExtension(), which must be a const method to inherit
229 // from the class being mocked. 229 // from the class being mocked.
230 mutable int visit_count_; 230 mutable int visit_count_;
231 231
232 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); 232 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
233 }; 233 };
234 234
235 class MockProviderVisitor 235 class MockProviderVisitor
236 : public ExternalExtensionProviderInterface::VisitorInterface { 236 : public ExternalExtensionProviderInterface::VisitorInterface {
237 public: 237 public:
238
239 // The provider will return |fake_base_path| from 238 // The provider will return |fake_base_path| from
240 // GetBaseCrxFilePath(). User can test the behavior with 239 // GetBaseCrxFilePath(). User can test the behavior with
241 // and without an empty path using this parameter. 240 // and without an empty path using this parameter.
242 explicit MockProviderVisitor(FilePath fake_base_path) 241 explicit MockProviderVisitor(FilePath fake_base_path)
243 : ids_found_(0), 242 : ids_found_(0),
244 fake_base_path_(fake_base_path), 243 fake_base_path_(fake_base_path),
245 expected_creation_flags_(Extension::NO_FLAGS) { 244 expected_creation_flags_(Extension::NO_FLAGS) {
246 } 245 }
247 246
248 MockProviderVisitor(FilePath fake_base_path, int expected_creation_flags) 247 MockProviderVisitor(FilePath fake_base_path, int expected_creation_flags)
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 ASSERT_TRUE(file_util::PathExists(private_key_path)); 999 ASSERT_TRUE(file_util::PathExists(private_key_path));
1001 } 1000 }
1002 1001
1003 // The tests are designed so that we never expect to see a packing error. 1002 // The tests are designed so that we never expect to see a packing error.
1004 void PackExtensionTestClient::OnPackFailure(const std::string& error_message, 1003 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1005 ExtensionCreator::ErrorType type) { 1004 ExtensionCreator::ErrorType type) {
1006 if (type == ExtensionCreator::kCRXExists) 1005 if (type == ExtensionCreator::kCRXExists)
1007 FAIL() << "Packing should not fail."; 1006 FAIL() << "Packing should not fail.";
1008 else 1007 else
1009 FAIL() << "Existing CRX should have been overwritten."; 1008 FAIL() << "Existing CRX should have been overwritten.";
1010
1011 } 1009 }
1012 1010
1013 // Test loading good extensions from the profile directory. 1011 // Test loading good extensions from the profile directory.
1014 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { 1012 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1015 PluginService::GetInstance()->Init(); 1013 PluginService::GetInstance()->Init();
1016 1014
1017 // Initialize the test dir with a good Preferences/extensions. 1015 // Initialize the test dir with a good Preferences/extensions.
1018 FilePath source_install_dir = data_dir_ 1016 FilePath source_install_dir = data_dir_
1019 .AppendASCII("good") 1017 .AppendASCII("good")
1020 .AppendASCII("Extensions"); 1018 .AppendASCII("Extensions");
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 std::string("Could not load extension from '*'. ") + 1142 std::string("Could not load extension from '*'. ") +
1145 extension_manifest_errors::kMissingFile)) << 1143 extension_manifest_errors::kMissingFile)) <<
1146 UTF16ToUTF8(GetErrors()[2]); 1144 UTF16ToUTF8(GetErrors()[2]);
1147 1145
1148 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]), 1146 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
1149 std::string("Could not load extension from '*'. ") + 1147 std::string("Could not load extension from '*'. ") +
1150 extension_manifest_errors::kManifestUnreadable)) << 1148 extension_manifest_errors::kManifestUnreadable)) <<
1151 UTF16ToUTF8(GetErrors()[3]); 1149 UTF16ToUTF8(GetErrors()[3]);
1152 }; 1150 };
1153 1151
1154 // Test that partially deleted extensions are cleaned up during startup 1152 // Test that old versions of extensions are deleted during garbage collection.
1155 // Test loading bad extensions from the profile directory. 1153 TEST_F(ExtensionServiceTest, GarbageCollectOldVersions) {
1156 TEST_F(ExtensionServiceTest, CleanupOnStartup) {
1157 PluginService::GetInstance()->Init(); 1154 PluginService::GetInstance()->Init();
1158 1155
1159 FilePath source_install_dir = data_dir_ 1156 FilePath source_install_dir = data_dir_
1157 .AppendASCII("garbage_collection")
1158 .AppendASCII("Extensions");
1159
1160 FilePath pref_path = source_install_dir
1161 .DirName()
1162 .AppendASCII("Preferences");
1163
1164 InitializeInstalledExtensionService(pref_path, source_install_dir);
1165
1166 // Verify that there are two versions present initially.
1167 ASSERT_TRUE(file_util::PathExists(
1168 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1169 .AppendASCII("1.0_0")));
1170 ASSERT_TRUE(file_util::PathExists(
1171 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1172 .AppendASCII("1.1_0")));
1173
1174 ValidatePrefKeyCount(1u);
1175
1176 service_->Init();
1177 loop_.RunAllPending();
1178
1179 // Garbage collection should have deleted the old version.
1180 ASSERT_FALSE(file_util::PathExists(
1181 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1182 .AppendASCII("1.0_0")));
1183 ASSERT_TRUE(file_util::PathExists(
1184 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1185 .AppendASCII("1.1_0")));
1186 }
1187
1188 // Test that extensions which were deleted from the preferences are cleaned up
1189 // during startup.
1190 // Test loading bad extensions from the profile directory.
1191 TEST_F(ExtensionServiceTest, GarbageCollectOnStartup) {
1192 PluginService::GetInstance()->Init();
1193
1194 FilePath source_install_dir = data_dir_
1160 .AppendASCII("good") 1195 .AppendASCII("good")
1161 .AppendASCII("Extensions"); 1196 .AppendASCII("Extensions");
1162 FilePath pref_path = source_install_dir 1197 FilePath pref_path = source_install_dir
1163 .DirName() 1198 .DirName()
1164 .AppendASCII("Preferences"); 1199 .AppendASCII("Preferences");
1165 1200
1166 InitializeInstalledExtensionService(pref_path, source_install_dir); 1201 InitializeInstalledExtensionService(pref_path, source_install_dir);
1167 1202
1203 ValidatePrefKeyCount(3u);
1204
1168 // Simulate that one of them got partially deleted by clearing its pref. 1205 // Simulate that one of them got partially deleted by clearing its pref.
1169 { 1206 {
1170 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); 1207 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1171 DictionaryValue* dict = update.Get(); 1208 DictionaryValue* dict = update.Get();
1172 ASSERT_TRUE(dict != NULL); 1209 ASSERT_TRUE(dict);
1173 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL); 1210 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1174 } 1211 }
1175 1212
1176 service_->Init(); 1213 service_->Init();
1177 // Wait for GarbageCollectExtensions task to complete. 1214 // Wait for GarbageCollectExtensions task to complete.
1178 loop_.RunAllPending(); 1215 loop_.RunAllPending();
1179 1216
1180 file_util::FileEnumerator dirs(extensions_install_dir_, false, 1217 file_util::FileEnumerator dirs(extensions_install_dir_, false,
1181 file_util::FileEnumerator::DIRECTORIES); 1218 file_util::FileEnumerator::DIRECTORIES);
1182 size_t count = 0; 1219 size_t count = 0;
1183 while (!dirs.Next().empty()) 1220 while (!dirs.Next().empty())
1184 count++; 1221 count++;
1185 1222
1186 // We should have only gotten two extensions now. 1223 // We should have only gotten two extensions now.
1187 EXPECT_EQ(2u, count); 1224 EXPECT_EQ(2u, count);
1188 1225
1189 // And extension1 dir should now be toast. 1226 // And extension1 dir should now be toast.
1190 FilePath extension_dir = extensions_install_dir_ 1227 FilePath extension_dir = extensions_install_dir_
1191 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); 1228 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1192 ASSERT_FALSE(file_util::PathExists(extension_dir)); 1229 ASSERT_FALSE(file_util::PathExists(extension_dir));
1193 } 1230 }
1194 1231
1232 // Test that internal extensions which are referenced in the preferences but
1233 // had their content deleted are cleaned up during startup.
1234 TEST_F(ExtensionServiceTest, GarbageCollectInternalExtensionsMissingContent) {
1235 PluginService::GetInstance()->Init();
1236
1237 FilePath source_dir = data_dir_.AppendASCII("good").AppendASCII("Extensions");
1238 FilePath pref_path = source_dir.DirName().AppendASCII("Preferences");
1239
1240 InitializeInstalledExtensionService(pref_path, source_dir);
1241
1242 ValidatePrefKeyCount(3u);
1243
1244 // Delete the extension's directory.
1245 FilePath extension_dir = extensions_install_dir_
1246 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1247 ASSERT_TRUE(file_util::Delete(extension_dir, true));
1248
1249 // Run GarbageCollectExtensions.
1250 service_->Init();
1251 loop_.RunAllPending();
1252
1253 file_util::FileEnumerator dirs(extensions_install_dir_, false,
1254 file_util::FileEnumerator::DIRECTORIES);
1255 size_t count = 0;
1256 while (!dirs.Next().empty())
1257 count++;
1258
1259 // We should have only gotten two extensions now.
1260 EXPECT_EQ(2u, count);
1261
1262 const DictionaryValue* dictionary =
1263 profile_->GetPrefs()->GetDictionary("extensions.settings");
1264 ASSERT_TRUE(dictionary);
1265 ASSERT_FALSE(dictionary->HasKey("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1266 }
1267
1268 // Test that unpacked extensions which are referenced in the preferences but
1269 // had their content deleted are cleaned up during startup.
1270 TEST_F(ExtensionServiceTest, GarbageCollectUnpackedExtensionsMissingContent) {
1271 InitializeEmptyExtensionService();
1272
1273 ScopedTempDir temp;
1274 ASSERT_TRUE(temp.CreateUniqueTempDir());
1275
1276 // Write the manifest dynamically, since we have to delete the file anyway.
1277 FilePath extension_path = temp.path();
1278 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
1279 ASSERT_FALSE(file_util::PathExists(manifest_path));
1280
1281 // Construct a simple manifest and install it.
1282 DictionaryValue manifest;
1283 manifest.SetString("version", "1.0");
1284 manifest.SetString("name", "Cleanup Unpacked Extensions Missing Content");
1285 manifest.SetInteger("manifest_version", 2);
1286
1287 JSONFileValueSerializer serializer(manifest_path);
1288 ASSERT_TRUE(serializer.Serialize(manifest));
1289
1290 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
1291 loop_.RunAllPending();
1292
1293 // Make sure it installed correctly.
1294 EXPECT_EQ(0u, GetErrors().size());
1295 ASSERT_EQ(1u, loaded_.size());
1296 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
1297 EXPECT_EQ(1u, service_->extensions()->size());
1298
1299 std::string extension_id = loaded_[0]->id();
1300
1301 // Make sure it is in the preferences at this point.
1302 const DictionaryValue* initial_dictionary =
1303 profile_->GetPrefs()->GetDictionary("extensions.settings");
1304 ASSERT_TRUE(initial_dictionary);
1305 ASSERT_TRUE(initial_dictionary->HasKey(extension_id));
1306
1307 // Delete local content, GarbageCollectExtensions, and test whether the key
1308 // is still in the preferences.
1309 ASSERT_TRUE(file_util::Delete(extension_path, true));
1310 service_->GarbageCollectExtensions();
1311 loop_.RunAllPending();
1312
1313 const DictionaryValue* final_dictionary =
1314 profile_->GetPrefs()->GetDictionary("extensions.settings");
1315 ASSERT_TRUE(final_dictionary);
1316 ASSERT_FALSE(final_dictionary->HasKey(extension_id));
1317 }
1318
1195 // Test installing extensions. This test tries to install few extensions using 1319 // Test installing extensions. This test tries to install few extensions using
1196 // crx files. If you need to change those crx files, feel free to repackage 1320 // crx files. If you need to change those crx files, feel free to repackage
1197 // them, throw away the key used and change the id's above. 1321 // them, throw away the key used and change the id's above.
1198 TEST_F(ExtensionServiceTest, InstallExtension) { 1322 TEST_F(ExtensionServiceTest, InstallExtension) {
1199 InitializeEmptyExtensionService(); 1323 InitializeEmptyExtensionService();
1200 1324
1201 // Extensions not enabled. 1325 // Extensions not enabled.
1202 set_extensions_enabled(false); 1326 set_extensions_enabled(false);
1203 FilePath path = data_dir_.AppendASCII("good.crx"); 1327 FilePath path = data_dir_.AppendASCII("good.crx");
1204 InstallCRX(path, INSTALL_FAILED); 1328 InstallCRX(path, INSTALL_FAILED);
(...skipping 3983 matching lines...) Expand 10 before | Expand all | Expand 10 after
5188 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0", 5312 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
5189 data_dir_.AppendASCII("hosted_app.crx")); 5313 data_dir_.AppendASCII("hosted_app.crx"));
5190 5314
5191 service_->CheckForExternalUpdates(); 5315 service_->CheckForExternalUpdates();
5192 loop_.RunAllPending(); 5316 loop_.RunAllPending();
5193 5317
5194 ASSERT_TRUE(service_->PopulateExtensionGlobalError( 5318 ASSERT_TRUE(service_->PopulateExtensionGlobalError(
5195 extension_global_error.get())); 5319 extension_global_error.get()));
5196 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size()); 5320 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size());
5197 } 5321 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_service.cc ('k') | chrome/browser/sync/test/integration/sync_extension_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698