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

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: Removed preexisting race condition 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
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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 mutable int visit_count_; 243 mutable int visit_count_;
244 244
245 int creation_flags_; 245 int creation_flags_;
246 246
247 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); 247 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
248 }; 248 };
249 249
250 class MockProviderVisitor 250 class MockProviderVisitor
251 : public ExternalExtensionProviderInterface::VisitorInterface { 251 : public ExternalExtensionProviderInterface::VisitorInterface {
252 public: 252 public:
253
254 // The provider will return |fake_base_path| from 253 // The provider will return |fake_base_path| from
255 // GetBaseCrxFilePath(). User can test the behavior with 254 // GetBaseCrxFilePath(). User can test the behavior with
256 // and without an empty path using this parameter. 255 // and without an empty path using this parameter.
257 explicit MockProviderVisitor(FilePath fake_base_path) 256 explicit MockProviderVisitor(FilePath fake_base_path)
258 : ids_found_(0), 257 : ids_found_(0),
259 fake_base_path_(fake_base_path) { 258 fake_base_path_(fake_base_path) {
260 } 259 }
261 260
262 int Visit(const std::string& json_data) { 261 int Visit(const std::string& json_data) {
263 // Give the test json file to the provider for parsing. 262 // Give the test json file to the provider for parsing.
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 ASSERT_TRUE(file_util::PathExists(private_key_path)); 998 ASSERT_TRUE(file_util::PathExists(private_key_path));
1000 } 999 }
1001 1000
1002 // The tests are designed so that we never expect to see a packing error. 1001 // The tests are designed so that we never expect to see a packing error.
1003 void PackExtensionTestClient::OnPackFailure(const std::string& error_message, 1002 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1004 ExtensionCreator::ErrorType type) { 1003 ExtensionCreator::ErrorType type) {
1005 if (type == ExtensionCreator::kCRXExists) 1004 if (type == ExtensionCreator::kCRXExists)
1006 FAIL() << "Packing should not fail."; 1005 FAIL() << "Packing should not fail.";
1007 else 1006 else
1008 FAIL() << "Existing CRX should have been overwritten."; 1007 FAIL() << "Existing CRX should have been overwritten.";
1009
1010 } 1008 }
1011 1009
1012 // Test loading good extensions from the profile directory. 1010 // Test loading good extensions from the profile directory.
1013 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { 1011 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1014 PluginService::GetInstance()->Init(); 1012 PluginService::GetInstance()->Init();
1015 1013
1016 // Initialize the test dir with a good Preferences/extensions. 1014 // Initialize the test dir with a good Preferences/extensions.
1017 FilePath source_install_dir = data_dir_ 1015 FilePath source_install_dir = data_dir_
1018 .AppendASCII("good") 1016 .AppendASCII("good")
1019 .AppendASCII("Extensions"); 1017 .AppendASCII("Extensions");
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 std::string("Could not load extension from '*'. ") + 1141 std::string("Could not load extension from '*'. ") +
1144 extension_manifest_errors::kMissingFile)) << 1142 extension_manifest_errors::kMissingFile)) <<
1145 UTF16ToUTF8(GetErrors()[2]); 1143 UTF16ToUTF8(GetErrors()[2]);
1146 1144
1147 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]), 1145 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
1148 std::string("Could not load extension from '*'. ") + 1146 std::string("Could not load extension from '*'. ") +
1149 extension_manifest_errors::kManifestUnreadable)) << 1147 extension_manifest_errors::kManifestUnreadable)) <<
1150 UTF16ToUTF8(GetErrors()[3]); 1148 UTF16ToUTF8(GetErrors()[3]);
1151 }; 1149 };
1152 1150
1153 // Test that partially deleted extensions are cleaned up during startup 1151 // Test that old versions of extensions are deleted during garbage collection.
1154 // Test loading bad extensions from the profile directory. 1152 TEST_F(ExtensionServiceTest, GarbageCollectOldVersions) {
1155 TEST_F(ExtensionServiceTest, CleanupOnStartup) {
1156 PluginService::GetInstance()->Init(); 1153 PluginService::GetInstance()->Init();
1157 1154
1158 FilePath source_install_dir = data_dir_ 1155 FilePath source_install_dir = data_dir_
1156 .AppendASCII("garbage_collection")
1157 .AppendASCII("Extensions");
1158
1159 FilePath pref_path = source_install_dir
1160 .DirName()
1161 .AppendASCII("Preferences");
1162
1163 InitializeInstalledExtensionService(pref_path, source_install_dir);
1164
1165 // Verify that there are two versions present initially.
1166 ASSERT_TRUE(file_util::PathExists(
1167 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1168 .AppendASCII("1.0_0")));
1169 ASSERT_TRUE(file_util::PathExists(
1170 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1171 .AppendASCII("1.1_0")));
1172 service_->Init();
1173 loop_.RunAllPending();
1174
1175 // Garbage collection should have deleted the old version.
1176 ASSERT_FALSE(file_util::PathExists(
1177 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1178 .AppendASCII("1.0_0")));
1179 ASSERT_TRUE(file_util::PathExists(
1180 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff")
1181 .AppendASCII("1.1_0")));
1182 }
1183
1184 // Test that extensions which were deleted from the preferences are cleaned up
1185 // during startup.
1186 // Test loading bad extensions from the profile directory.
1187 TEST_F(ExtensionServiceTest, GarbageCollectOnStartup) {
1188 PluginService::GetInstance()->Init();
1189
1190 FilePath source_install_dir = data_dir_
1159 .AppendASCII("good") 1191 .AppendASCII("good")
1160 .AppendASCII("Extensions"); 1192 .AppendASCII("Extensions");
1161 FilePath pref_path = source_install_dir 1193 FilePath pref_path = source_install_dir
1162 .DirName() 1194 .DirName()
1163 .AppendASCII("Preferences"); 1195 .AppendASCII("Preferences");
1164 1196
1165 InitializeInstalledExtensionService(pref_path, source_install_dir); 1197 InitializeInstalledExtensionService(pref_path, source_install_dir);
1166 1198
1167 // Simulate that one of them got partially deleted by clearing its pref. 1199 // Simulate that one of them got partially deleted by clearing its pref.
1168 { 1200 {
1169 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); 1201 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1170 DictionaryValue* dict = update.Get(); 1202 DictionaryValue* dict = update.Get();
1171 ASSERT_TRUE(dict != NULL); 1203 ASSERT_TRUE(dict);
1172 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL); 1204 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1173 } 1205 }
1174 1206
1175 service_->Init(); 1207 service_->Init();
1176 // Wait for GarbageCollectExtensions task to complete. 1208 // Wait for GarbageCollectExtensions task to complete.
1177 loop_.RunAllPending(); 1209 loop_.RunAllPending();
1178 1210
1179 file_util::FileEnumerator dirs(extensions_install_dir_, false, 1211 file_util::FileEnumerator dirs(extensions_install_dir_, false,
1180 file_util::FileEnumerator::DIRECTORIES); 1212 file_util::FileEnumerator::DIRECTORIES);
1181 size_t count = 0; 1213 size_t count = 0;
1182 while (!dirs.Next().empty()) 1214 while (!dirs.Next().empty())
1183 count++; 1215 count++;
1184 1216
1185 // We should have only gotten two extensions now. 1217 // We should have only gotten two extensions now.
1186 EXPECT_EQ(2u, count); 1218 EXPECT_EQ(2u, count);
1187 1219
1188 // And extension1 dir should now be toast. 1220 // And extension1 dir should now be toast.
1189 FilePath extension_dir = extensions_install_dir_ 1221 FilePath extension_dir = extensions_install_dir_
1190 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); 1222 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1191 ASSERT_FALSE(file_util::PathExists(extension_dir)); 1223 ASSERT_FALSE(file_util::PathExists(extension_dir));
1192 } 1224 }
1193 1225
1226 // Test that internal extensions which are referenced in the preferences but
1227 // had their content deleted are cleaned up during startup.
1228 TEST_F(ExtensionServiceTest, GarbageCollectInternalExtensionsMissingContent) {
1229 PluginService::GetInstance()->Init();
1230
1231 FilePath source_dir = data_dir_.AppendASCII("good").AppendASCII("Extensions");
1232 FilePath pref_path = source_dir.DirName().AppendASCII("Preferences");
1233
1234 InitializeInstalledExtensionService(pref_path, source_dir);
1235
1236 // Delete the extension's directory.
1237 FilePath extension_dir = extensions_install_dir_
1238 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1239 ASSERT_TRUE(file_util::Delete(extension_dir, true));
1240
1241 // Run GarbageCollectExtensions.
1242 service_->Init();
1243 loop_.RunAllPending();
1244
1245 file_util::FileEnumerator dirs(extensions_install_dir_, false,
1246 file_util::FileEnumerator::DIRECTORIES);
1247 size_t count = 0;
1248 while (!dirs.Next().empty())
1249 count++;
1250
1251 // We should have only gotten two extensions now.
1252 EXPECT_EQ(2u, count);
1253
1254 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1255 DictionaryValue* dictionary = update.Get();
1256 ASSERT_TRUE(dictionary);
1257 ASSERT_FALSE(dictionary->HasKey("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1258 }
1259
1260 // Test that unpacked extensions which are referenced in the preferences but
1261 // had their content deleted are cleaned up during startup.
1262 TEST_F(ExtensionServiceTest, GarbageCollectUnpackedExtensionsMissingContent) {
1263 InitializeEmptyExtensionService();
1264
1265 ScopedTempDir temp;
1266 ASSERT_TRUE(temp.CreateUniqueTempDir());
1267
1268 // Write the manifest dynamically, since we have to delete the file anyway.
1269 FilePath extension_path = temp.path();
1270 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
1271 ASSERT_FALSE(file_util::PathExists(manifest_path));
1272
1273 // Construct a simple manifest and install it.
1274 DictionaryValue manifest;
1275 manifest.SetString("version", "1.0");
1276 manifest.SetString("name", "Cleanup Unpacked Extensions Missing Content");
1277 manifest.SetInteger("manifest_version", 2);
1278
1279 JSONFileValueSerializer serializer(manifest_path);
1280 ASSERT_TRUE(serializer.Serialize(manifest));
1281
1282 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
1283 loop_.RunAllPending();
1284
1285 // Make sure it installed correctly.
1286 EXPECT_EQ(0u, GetErrors().size());
1287 ASSERT_EQ(1u, loaded_.size());
1288 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
1289 EXPECT_EQ(1u, service_->extensions()->size());
1290
1291 std::string extension_id = loaded_[0]->id();
1292
1293 // Make sure it is in the preferences at this point.
1294 DictionaryPrefUpdate initial_update(
1295 profile_->GetPrefs(), "extensions.settings");
1296 DictionaryValue* initial_dictionary = initial_update.Get();
1297 ASSERT_TRUE(initial_dictionary);
1298 ASSERT_TRUE(initial_dictionary->HasKey(extension_id));
1299
1300 // Delete local content, GarbageCollectExtensions, and test whether the key
1301 // is still in the preferences.
1302 ASSERT_TRUE(file_util::Delete(extension_path, true));
1303 service_->GarbageCollectExtensions();
1304 loop_.RunAllPending();
1305
1306 DictionaryPrefUpdate final_update(
1307 profile_->GetPrefs(), "extensions.settings");
1308 DictionaryValue* final_dictionary = final_update.Get();
1309 ASSERT_TRUE(final_dictionary);
1310 ASSERT_FALSE(final_dictionary->HasKey(extension_id));
1311 }
1312
1194 // Test installing extensions. This test tries to install few extensions using 1313 // Test installing extensions. This test tries to install few extensions using
1195 // crx files. If you need to change those crx files, feel free to repackage 1314 // crx files. If you need to change those crx files, feel free to repackage
1196 // them, throw away the key used and change the id's above. 1315 // them, throw away the key used and change the id's above.
1197 TEST_F(ExtensionServiceTest, InstallExtension) { 1316 TEST_F(ExtensionServiceTest, InstallExtension) {
1198 InitializeEmptyExtensionService(); 1317 InitializeEmptyExtensionService();
1199 1318
1200 // Extensions not enabled. 1319 // Extensions not enabled.
1201 set_extensions_enabled(false); 1320 set_extensions_enabled(false);
1202 FilePath path = data_dir_.AppendASCII("good.crx"); 1321 FilePath path = data_dir_.AppendASCII("good.crx");
1203 InstallCRX(path, INSTALL_FAILED); 1322 InstallCRX(path, INSTALL_FAILED);
(...skipping 3657 matching lines...) Expand 10 before | Expand all | Expand 10 after
4861 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0", 4980 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
4862 data_dir_.AppendASCII("hosted_app.crx")); 4981 data_dir_.AppendASCII("hosted_app.crx"));
4863 4982
4864 service_->CheckForExternalUpdates(); 4983 service_->CheckForExternalUpdates();
4865 loop_.RunAllPending(); 4984 loop_.RunAllPending();
4866 4985
4867 ASSERT_TRUE(service_->PopulateExtensionGlobalError( 4986 ASSERT_TRUE(service_->PopulateExtensionGlobalError(
4868 extension_global_error.get())); 4987 extension_global_error.get()));
4869 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size()); 4988 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size());
4870 } 4989 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698