OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |